β‘οΈfulmine


Fulmine is a Bitcoin wallet daemon built on Arkade. It can be used as a general-purpose Arkade wallet or as an infrastructure node for Arkade-native services β such as serving VHTLCs or acting as a delegate for automated VTXO refresh.
π Usage
π³ Using Docker (Recommended)
The easiest way to run fulmine is using Docker. Make sure you have Docker installed on your machine.
docker run -d \
--name fulmine \
-p 7000:7000 \
-p 7001:7001 \
-v fulmine-data:/app/data \
ghcr.io/arklabshq/fulmine:latest
Once the container is running, you can access the web UI at http://localhost:7001.
To view logs:
docker logs -f fulmine
To stop the container:
docker stop fulmine
To update to the latest version:
docker pull ghcr.io/arklabshq/fulmine:latest
docker stop fulmine && docker rm fulmine
docker run -d \
--name fulmine \
-p 7000:7000 \
-p 7001:7001 \
-v fulmine-data:/app/data \
ghcr.io/arklabshq/fulmine:latest
π» Using the Binary
Alternatively, you can download the latest release from the releases page for your platform. After downloading:
- Extract the binary
- Make it executable (on Linux/macOS):
chmod +x fulmine
- Run the binary:
./fulmine
π§ Environment Variables
The following environment variables can be configured:
| Variable |
Description |
Default |
FULMINE_DATADIR |
Directory to store wallet data |
/app/data in Docker, ~/.fulmine otherwise |
FULMINE_HTTP_PORT |
HTTP port for the web UI and REST API |
7001 |
FULMINE_GRPC_PORT |
gRPC port for service communication |
7000 |
FULMINE_ARK_SERVER |
URL of the Ark server to connect to |
It pre-fills with the default Ark server |
FULMINE_ESPLORA_URL |
URL of the Esplora server to connect to |
It pre-fills with the default Esplora server |
FULMINE_UNLOCKER_TYPE |
Type of unlocker to use for auto-unlock (file or env) |
Not set by default (no auto-unlock) |
FULMINE_UNLOCKER_FILE_PATH |
Path to the file containing the wallet password (when using file unlocker) |
Not set by default |
FULMINE_UNLOCKER_PASSWORD |
Password string to use for unlocking (when using env unlocker) |
Not set by default |
FULMINE_BOLTZ_URL |
URL of the custom Boltz backend to connect to for swaps |
Not set by default |
FULMINE_BOLTZ_WS_URL |
URL of the custom Boltz WebSocket backend to connect to for swap events |
Not set by default |
FULMINE_DISABLE_TELEMETRY |
Opt out of telemetry logs |
False by default |
When using Docker, you can set these variables using the -e flag:
docker run -d \
--name fulmine \
-p 7001:7001 \
-e FULMINE_HTTP_PORT=7001 \
-e FULMINE_ARK_SERVER="https://server.example.com" \
-e FULMINE_ESPLORA_URL="https://mempool.space/api" \
-e FULMINE_UNLOCKER_TYPE="file" \
-e FULMINE_UNLOCKER_FILE_PATH="/app/password.txt" \
-v fulmine-data:/app/data \
-v /path/to/password.txt:/app/password.txt \
ghcr.io/arklabshq/fulmine:latest
π Auto-Unlock Feature
Fulmine supports automatic wallet unlocking on startup, which is useful for unattended operation or when running as a service. Two methods are available:
-
File-based unlocker: Reads the wallet password from a file
FULMINE_UNLOCKER_TYPE=file
FULMINE_UNLOCKER_FILE_PATH=/path/to/password/file
-
Environment-based unlocker: Uses a password directly from an environment variable
FULMINE_UNLOCKER_TYPE=env
FULMINE_UNLOCKER_PASSWORD=your_wallet_password
β οΈ Security Warning: When using the auto-unlock feature, ensure your password is stored securely:
- For file-based unlocking, use appropriate file permissions (chmod 600)
- For environment-based unlocking, be cautious about environment variable visibility
- Consider using Docker secrets or similar tools in production environments
π API Documentation
β οΈ Security Notice
IMPORTANT: The REST API and gRPC interfaces are currently not protected by authentication. This is a known limitation and is being tracked in issue #98.
DO NOT expose these interfaces over the public internet until authentication is implemented. The interfaces should only be accessed from trusted networks or localhost.
While the wallet seed is encrypted using AES-256 with a password that the user set, the API endpoints themselves are not protected.
π API Interfaces
Fulmine provides three main interfaces:
- Web UI - Available at http://localhost:7001 by default
- REST API - Available at http://localhost:7001/api
- gRPC Service - Available at
localhost:7000
π Wallet Setup & Basic Usage
Before using any wallet-dependent features, you need to set up and unlock your wallet.
-
Generate Seed
curl -X GET http://localhost:7001/api/v1/wallet/genseed
-
Create Wallet
Password must:
- Be 8 chars or longer
- Have at least one number
- Have at least one special char
Private key supported formats:
- 64 chars hexadecimal
- Nostr nsec (NIP-19)
curl -X POST http://localhost:7001/api/v1/wallet/create \
-H "Content-Type: application/json" \
-d '{"privateKey": "<hex or nsec>", "password": "<strong password>", "serverUrl": "https://server.example.com"}'
-
Unlock Wallet
curl -X POST http://localhost:7001/api/v1/wallet/unlock \
-H "Content-Type: application/json" \
-d '{"password": "<strong password>"}'
-
Lock Wallet
curl -X POST http://localhost:7001/api/v1/wallet/lock \
-H "Content-Type: application/json"
-
Get Wallet Status
curl -X GET http://localhost:7001/api/v1/wallet/status
-
Get Arkade Address
curl -X GET http://localhost:7001/api/v1/address
-
Get Onboard Address
curl -X GET http://localhost:7001/api/v1/onboard
-
Send funds offchain
curl -X POST http://localhost:7001/api/v1/send/offchain \
-H "Content-Type: application/json" \
-d '{"address": "<ark address>", "amount": <amount in sats>}'
-
Send funds onchain
curl -X POST http://localhost:7001/api/v1/send/onchain \
-H "Content-Type: application/json" \
-d '{"address": "<bitcoin address>", "amount": <amount in sats>}'
π Notification API
Note: Wallet setup is not required to use the Notification API.
Fulmine can track off-chain addresses on behalf of external services and deliver notifications whenever funds are received or spent.
-
Subscribe to Addresses
Ask Fulmine to watch one or more off-chain addresses.
curl -X POST http://localhost:7001/api/v1/subscribe \
-H "Content-Type: application/json" \
-d '{"addresses": ["<ark address>", "<ark address>"]}'
-
Unsubscribe from Addresses
Stop watching one or more addresses.
curl -X POST http://localhost:7001/api/v1/unsubscribe \
-H "Content-Type: application/json" \
-d '{"addresses": ["<ark address>"]}'
-
Stream Notifications
Open a server-sent event stream to receive real-time notifications for all subscribed addresses. Each event contains the affected addresses, newly received VTXOs (newVtxos), and spent VTXOs (spentVtxos).
curl -X GET http://localhost:7001/api/v1/notifications
β‘ VHTLC API
Note: Wallet setup is required before using the VHTLC APIs.
Virtual Hash Time-Locked Contracts (VHTLCs) are Arkade-native HTLCs that live off-chain. They enable atomic swaps and conditional payments without touching the base layer.
-
Create VHTLC
Computes a VHTLC address from:
- a preimage hash
- sender or receiver pubkeys. The missing key (depending on whether fulmine has to fund or claim the VHTLC) is added by fulmine using one of its internal wallet.
- optional locktimes, if not provided fulmine uses the following default values:
refundLocktime: 24hrs. This is the offchain (absolute) locktime the sender must wait to refund the VHTLC offchain (can be expressed in blocks only on regtest)
unilateralClaimDelay: 8 mins. This is the locktime the receiver has to wait to claim the VHTLC after it's been unrolled onchain
unilateralRefundDelay: 16 mins. This is the locktime sender and Boltz have to wait to refund the VHTLC collaboratively after it's been unrolled onchain
unilateralRefundWithoutEeceiverDelay: 32 mins. This is the locktime the sender has to wait to refund alone the VHTLC after it's been unrolled onchain
curl -X POST http://localhost:7001/api/v1/vhtlc \
-H "Content-Type: application/json" \
-d '{
"preimageHash": "<hex preimage hash>",
"senderPubkey": "<hex sender pubkey>",
"receiverPubkey": "<hex receiver pubkey>",
"refundLocktime": 1024,
"unilateralClaimDelay": {"type": "LOCKTIME_TYPE_SECONDS", "value": 2048},
"unilateralRefundDelay": {"type": "LOCKTIME_TYPE_SECONDS", "value": 4096},
"unilateralRefundWithoutEeceiverDelay": {"type": "LOCKTIME_TYPE_SECONDS", "value": 8192}
}'
Returns: VHTLC id, address, claimPubkey, refundPubkey, serverPubkey, swapTree, and the resolved locktime values.
The vhtlcId is the sha256 hash of preimage hash + sender ec pubkey + receiver ec pubkey.
-
List VHTLCs
Returns VHTLCs by their vhtlcIds.
curl -X GET "http://localhost:7001/api/v1/vhtlcs?vhtlcIds=id1,id2"
-
ListVHTLC
Returns a VHTLC by its vhtlcId.
curl -X GET "http://localhost:7001/api/v1/vhtlc?vhtlcId=id1"
-
Claim VHTLC
Claims a VHTLC by revealing the preimage. Moves the funds into a regular VTXO.
curl -X POST http://localhost:7001/api/v1/vhtlc/claim \
-H "Content-Type: application/json" \
-d '{"vhtlcId": "<vhtlc id>", "preimage": "<hex preimage>"}'
Returns: { "claimTxid": "<txid>" }
-
Settle VHTLC
Settles a VHTLC via either the claim path (reveal preimage) or the collaborative refund path (delegate params).
Claim path:
curl -X POST http://localhost:7001/api/v1/vhtlc/settle \
-H "Content-Type: application/json" \
-d '{"vhtlcId": "<vhtlc id>", "claim": {"preimage": "<hex preimage>"}}'
Refund path:
curl -X POST http://localhost:7001/api/v1/vhtlc/settle \
-H "Content-Type: application/json" \
-d '{
"vhtlcId": "<vhtlc id>",
"refund": {
"delegateParams": {
"signedIntentProof": "<base64>",
"intentMessage": "<json string>",
"partialForfeitTx": "<base64 psbt>"
}
}
}'
Returns: { "commitmentTxid": "<txid>" }
-
Refund VHTLC Without Receiver
Unilaterally refunds a VHTLC after the timeout has expired, without requiring the receiver's cooperation.
curl -X POST http://localhost:7001/api/v1/vhtlc/refundWithoutReceiver \
-H "Content-Type: application/json" \
-d '{"vhtlcId": "<vhtlc id>"}'
Returns: { "refundTxid": "<txid>" }
π€ Delegate API
Note: Wallet setup is not required to use the Delegator API.
Fulmine can act as a delegate: it monitors VTXO expiry on behalf of clients and automatically refreshes them before they expire. Clients submit a signed intent and pre-signed forfeit transactions; Fulmine handles the rest.
-
Get Delegate Info
Returns the delegate's pubkey (to include in VTXO scripts), service fee, and fee address.
curl -X GET http://localhost:7001/api/v1/delegator/info
Returns: { "pubkey": "<hex>", "fee": "<amount>", "delegatorAddress": "<ark address>" }
-
Delegate
Submit a delegation request. The intent.message is a stringified JSON describing the VTXOs to refresh. The intent.proof is a partially signed PSBT (base64). forfeitTxs are partially signed forfeit transactions (base64), one per VTXO input.
curl -X POST http://localhost:7001/api/v1/delegate \
-H "Content-Type: application/json" \
-d '{
"intent": {
"message": "{\"vtxos\": [...]}",
"proof": "<base64 psbt>"
},
"forfeitTxs": ["<base64 psbt>"],
"rejectReplace": false
}'
-
List Delegates
Returns delegate tasks filtered by status, paginated.
curl -X GET "http://localhost:7001/api/v1/delegates?status=<pending|completed|failed>&limit=10&offset=0"
Note: Replace http://localhost:7001 with the appropriate host and port where your Fulmine is running.
For more detailed information about request and response structures, please refer to the proto files in the api-spec/protobuf/fulmine/v1/ directory.
π¨βπ» Development
To get started with fulmine development you need Go 1.26.2 or higher and Node.js 18.17.1 or higher.
git clone https://github.com/ArkLabsHQ/fulmine.git
cd fulmine
go mod download
make run
Now navigate to http://localhost:7001/ to see the web UI.
Testing
Run all unit tests:
make test
Run integration tests:
make build-test-env
make setup-test-env
make integrationtest
make down-test-env
π€ Contributing
We welcome contributions to fulmine! Here's how you can help:
- Fork the repository and create your branch from
main
- Install dependencies:
go mod download
- Make your changes and ensure tests pass:
make test4. Run the linter to ensure code quality: make lint
- Submit a pull request
For major changes, please open an issue first to discuss what you would like to change.
π οΈ Development Commands
The Makefile contains several useful commands for development:
make run: Run in development mode
make build: Build the binary for your platform
make test: Run unit tests
make lint: Lint the codebase
make proto: Generate protobuf stubs (requires Docker)
Support
If you encounter any issues or have questions, please file an issue on our GitHub Issues page.
Security
We take the security of Ark seriously. If you discover a security vulnerability, we appreciate your responsible disclosure.
Currently, we do not have an official bug bounty program. However, we value the efforts of security researchers and will consider offering appropriate compensation for significant, responsibly disclosed vulnerabilities.
License
This project is licensed under the MIT License - see the LICENSE file for details.