Skip to main content
Your user holds USDT on RGB, or wants to. RGB assets live in Bitcoin outputs, but their ownership is checked by RGB wallets, not by Bitcoin itself. So every RGB swap has two parts:
  • The Swap SDK handles the Bitcoin side: it checks the maker’s contract and builds the transaction.
  • Your rgb-lib wallet handles the asset: it moves it, validates its history, and marks (“colors”) the transaction with the asset. The SDK does not bundle rgb-lib.

Which swap to use

Setup

The code on this page assumes this setup. It connects to the signet maker and loads your swap mnemonic. See Installation and Keys and recovery if you have neither yet.

HTLC swaps over Lightning

Pin the contract

Pass the expected RGB contract ID when you create the swap. It is required for RGB, checked locally against the response, and never sent to the maker. Pair cards do not identify the contract, so take the ID from your trusted wallet or asset registry.
Amounts: rgb.amount is in contract units (six decimals for USDT-RGB); rgb.htlcSat and fees are in sats. A submarine lockup carries a small amount of BTC collateral, capped at 1,000 sats unless you raise the cap. The maker receives all of it on a successful claim.

Fund or accept the lock

  • Submarine: your rgb-lib wallet funds the HTLC with the asset.
  • Reverse: your rgb-lib wallet accepts the maker’s lock consignment and validates the asset proofs. There is no transaction.confirmed event for reverse RGB swaps: enforce lock confirmations through your chain backend and rgb-lib before claiming. Before you pay the invoice, compare the response’s claimFeeRate with current fees and the remaining timeout.

Claim or refund

The SDK prepares the spend, your wallet colors it, and the SDK signs the HTLC input:
TypeScript
  • If the HTLC’s sats cannot cover the fee, preparation fails with rgb_fee_input_required. Use funding: { kind: "callerInputs" }, add BTC inputs and change, and keep the new spend from spend.fund(fundedPsbt). Fund before coloring or signing.
  • Refunds use prepareRgbRefund and finalizeRefund after the timeout, with the original colored lock transaction.
  • A Bitcoin broadcast alone does not complete the RGB receive. Finish the rgb-lib operation.

Cooperative refunds

When the response advertises rgb.cooperativeRefund === "rgb-coop-refund-v1", the maker can co-sign an early refund of a submarine swap with prepareRgbCooperativeRefund and getRgbRefundPartialSig. The CLTV refund remains the fallback. Without that capability the SDK refuses the cooperative path.

Atomic swaps on L1

The signet maker does not offer atomic pairs yet; atomic.pairs() returns them empty. Test against a regtest maker.
An atomic swap moves both legs in one Bitcoin transaction. There is no HTLC and no refund. The SDK quotes, verifies, and tracks; rgb-lib accepts the offer, signs the proposal, and accepts the transfers.
TypeScript
What the SDK checks for you:
  • The quote answers your pair, direction, amount, asset, and network, stays within your fee and offer-lifetime limits, and has not passed its deadline. The rgb-lib offer inside it moves the same amounts and asset as the quote, so what your wallet signs is what you were shown.
  • The proposal lists none of your own coins as the maker’s, and no coin twice.
  • The completion broadcasts the transaction you agreed to.
Expectations are in base units: sats, or the contract’s smallest unit (six decimals for USDT-RGB), never the pair card’s display units. maxServiceFee bounds only the fee the maker declares; minToAmount and maxFromAmount bound the price. rgb-lib messages cross the JavaScript and Python boundaries as JSON text, because their 64-bit values do not survive JavaScript numbers.

If something goes wrong

  • HTLC swap, maker never pays (USDT-RGB → Lightning): refund with prepareRgbRefund and finalizeRefund after the deadline, or earlier through a cooperative refund if the maker offers it.
  • HTLC swap, maker never locks (Lightning → USDT-RGB): your Lightning payment is released. Nothing to do.
  • Atomic swap stops before complete: the maker signs last and broadcasts, so before that nothing has moved.
  • Any RGB spend: a Bitcoin broadcast alone does not finish the RGB transfer. Complete the rgb-lib operation, or the wallet will not show the asset.