Skip to main content
The developer preview supports three end-to-end flows: receiving a Lightning payment and paying a Lightning invoice on mainnet, and exchanging BTC for USDT on mutinynet. Lightning uses one pinned solver, reached with an addressed RFQ over Nostr. Asset exchange selects a market from the mutinynet solver registry. The solver card publishes the current limits and fee for each swap.
Every funded Lightning swap moves real bitcoin. Use small amounts. The setup below keeps the wallet and its swaps in SQLite files, so a restarted process resumes its claims and refunds.

Setup

You need Node.js 22.13 to 26, with "type": "module" in package.json. Install the SDK, the swap client, an EventSource for Node, and the Nostr transport peer dependency:
Save the Lightning solver card as beta-solver.card.json beside your code. The snippets load the wallet’s mnemonic from the ARKADE_MNEMONIC environment variable. Add the two Lightning snippets below after this one, in the same file:
Fund enough BTC to cover more than one test. An unresolved swap holds its funds in the contract until its cancellation or refund path becomes available, so a wallet funded for exactly one swap may be unable to start another. Receiving over Lightning, below, is the quickest way to fund the wallet.

Lightning Receive

This flow creates a Lightning invoice that pays into your Arkade wallet. amount is how many sats you receive in your Arkade wallet. The invoice asks the payer for a little more. The difference is the solver’s fee. Keep the client running while the payer pays. The client claims the payment, and the claim reveals the secret that lets the solver collect on Lightning.
The snippet prints each outcome as it changes: accepted, then open while the invoice waits for payment, then funded once the solver locks the sats for you, then claimed. claimed means the sats are in your Arkade wallet. If nobody pays before the claim window closes, the outcome is lapsed. Nothing left your wallet, so nothing comes back. If the application closes before the claim, create the client again on the next start and await client.ready. That resumes pending claims. To receive while the application is offline, see Lightning Services. To receive at a Lightning address, see LNURL and Lightning Addresses.

Pay a Lightning Invoice

Lightning send is exact-out: the invoice amount is the quote’s take, and your lockup carries the quote’s give. The client refunds automatically. If the solver does not pay the invoice, the client refunds the lockup after the quote’s refundLocktime, and the outcome is refunded. If the client is not running then, it refunds on its next start.
paid means the solver paid the invoice and claimed your lockup. The solver completes the payment without your application staying online. The card currently accepts Lightning payments from 335 to 200,000 sats and sets fee_bps: 30. A 10,000-sat invoice locks 10,031 sats; the difference between give and take is the fee.

Exchange BTC for an Asset

Asset exchange runs on mutinynet, a Bitcoin test network: the mainnet registry lists no asset market, and the mutinynet registry lists BTC/USDT. It needs a second wallet and client on mutinynet. Fund that wallet with mutinynet bitcoin: send coins from the mutinynet faucet to its boarding address, then board them (Boarding & Offboarding). The client calculates the quote from the solver card’s feed and fee, and funds the swap. This flow uses its own wallet, so put it in its own file.
  • Keep what you receive within the card’s bounds. With amountOn: 'give', the client does not check them. A swap outside them is funded, the solver does not fill it, and you must cancel it to get the deposit back.
  • The fee is charged in USDT, so maxFee names USDT in its smallest unit (2 decimals).
  • The client fetches the price feed itself, so it must be able to reach it. If the feed is unreachable, quoting fails before anything is funded.
The snippet prints each outcome as it changes. open means the swap is funded and waits for the solver. filled means the USDT is in your Arkade wallet. An unfilled swap has no fill deadline, but the virtual output that holds your deposit still expires with its batch. If the deposit stays unfilled past that, the operator sweeps it, and the swap reports needs_recovery. Recover a Swept Swap brings it back. cancel submits the cancellation without a solver signature. Keep that action available until your application sees a fill or a cancellation, because the deposit stays locked until then:
A cancel can race a fill. If the fill wins, cancel reports filled and does not throw.

Preview Availability

Lightning Solver Card

The Lightning preview solver is not listed in the registry. Its signed card publishes the connection details and current terms. Save it as beta-solver.card.json and pin it with discovery.localCards.
The min_* and max_* fields are the card’s bounds, in sats: the quote fields for an invoice you pay, and the base fields for what you receive in Arkade. This card opens both directions.The card is signed, and sig covers the connection data it advertises. Pinning the card makes this solver and its advertised connection data part of the application’s trust boundary. Load the latest signed card before deployment because its limits, fee, relay, and key may change.

Lightning Payments

Request, fund, claim, and recover Lightning swaps.

Exchange Assets

Integrate asset discovery, exchange, and cancellation.

Implementation Status

Check solver, client, and route readiness.

Trust and Limitations

Review settlement guarantees, external dependencies, and recovery conditions.