Skip to main content
This guide takes a new integrator from zero to a working RGB transfer with two RGB Lightning Nodes (RLN): launch the receiver, top it up, launch a sender, issue an asset, send a small blinded transfer, then create and pay another invoice. The on-chain path is the one available on mainnet today; the Lightning path runs on testnet.
This guide uses testnet3 and disables authentication to keep the steps short. Never use --disable-authentication in production, and never use mainnet keys or real funds while following this guide.
New to RGB? Read Getting Started with RGB first — it explains invoices, colored UTXOs, and consignments used below. Request and response schemas for every call are in the API reference.

1. Launch the node

Build RLN (see Self-Hosted RGB Lightning Node for Docker and other options):
Start the receiving node on testnet3:
Initialise the node once. The response contains the mnemonic — store it securely; it is the only way to recover the wallet.
Unlock it (required after every start), using the public testnet3 services:
Check that the node is up:

2. Top up

Get a Bitcoin address and send testnet3 BTC to it. The Bitcoin Wiki keeps a list of testnet faucets; make sure the faucet supports testnet3 before using the address.
Check the balance once the transaction confirms. vanilla is spendable BTC; colored holds the UTXOs that carry RGB assets.
Create colored UTXOs. RGB allocations are bound to Bitcoin UTXOs, so the node needs some before it can receive or hold assets:

3. Launch and top up a sender node

Open a second terminal and start another node on different ports. This node will issue and send the test asset.
Initialise and unlock the sender with the same testnet3 services:
Repeat the top-up steps from the previous section for the sender: request a Bitcoin address, fund it with testnet3 BTC, check the BTC balance, and create colored UTXOs.

4. Issue an asset on the sender

Issue a test NIA asset from the sender node:
The response contains the asset ID. Confirm that the sender can list the new asset:
Use this value as rgb:<ASSET_ID> when the sender selects which asset to transfer.

5. Send a first blinded transfer to the receiver

Create a blinded RGB invoice on the receiver. Do not include asset_id here: the receiver does not know the contract yet, and the sender will choose the asset when it pays the invoice.
The response contains an invoice string and a recipient_id. Send 1 base unit of rgb:<ASSET_ID> from the sender to that blinded invoice. This first transfer makes the receiver aware of the asset before it creates later invoices for the same contract.
Refresh the receiver, then verify that it now lists the asset:
The examples above use blinded RGB invoices ("witness": false). For non-blinded witness invoices, both the receiver and the sender should already know the asset because the invoice exposes the asset being requested.

6. Create an invoice

On the receiving node, create a new RGB invoice for the asset and amount you expect. The receiver can now use the asset ID from its own POST /listassets response.
The response contains the invoice string to share with the sender and its recipient_id.
Amounts are integer base units. One displayed unit is 10 ** precision base units.

7. Pay the invoice

On the sending node, pay the invoice with POST /sendrgb, using the recipient_id from the invoice:
Use POST /decodergbinvoice to read the recipient_id, asset, amount, and transport endpoints from an invoice string.

8. Confirm settlement

Both nodes refresh their transfers while the transfer moves through the RGB and Bitcoin confirmation flow:
Then check the receiver’s balance:
settled shows confirmed balance; future includes pending incoming transfers. Use POST /listtransfers to inspect individual transfers.

9. Try RGB over Lightning (testnet only)

The same node also handles RGB-enabled Lightning payments. On testnet:
  1. POST /connectpeer with peer_pubkey_and_addr (<pubkey>@<host>:<port>).
Use GET /nodeinfo on the receiver to get <RECEIVER_PUBKEY>:
  1. POST /openchannel with the peer, capacity_sat, asset_id, and asset_amount to open an RGB channel. RGB channels require anchor outputs, so set with_anchors to true.
Make sure the sender still has available UTXOs before opening the channel. If POST /openchannel returns NoAvailableUtxos, create more UTXOs on the sender and retry after they confirm:
Do not continue if POST /openchannel returns an error. A successful response means the funding transaction was submitted; keep both nodes running and wait for the funding transaction to confirm on testnet. Check GET /listchannels on both nodes until the channel appears and is usable:
You can also check the sender’s node info while waiting:
If both nodes keep returning {"channels":[]}, the channel has not been opened or persisted yet. Re-check the POST /openchannel response first, then wait for the funding transaction confirmation before retrying GET /listchannels.
  1. On the receiver, POST /lninvoice with amt_msat, expiry_sec, asset_id, and asset_amount. For RGB asset payments, amt_msat must be at least 3000000. This is the node’s default minimum, reported as rgb_htlc_min_msat by GET /nodeinfo.
  1. On the sender, POST /sendpayment with the invoice from the receiver.
Lightning on mainnet is not supported yet. Integrations built on the on-chain path keep working unchanged when Lightning reaches mainnet.

Next steps