Skip to main content
USDT on Bitcoin is an RGB asset. When a user swaps from RGB USDT, the user’s asset is locked in the same kind of Taproot HTLC used for Bitcoin settlement. The difference is that the lock also carries the RGB allocation, so the user pays an RGB witness invoice instead of sending plain BTC.
Draft. This page covers swaps where RGB USDT is the source asset. Swaps where the user receives RGB USDT, and the final affiliate signing flow, are still being confirmed.

For affiliates

To support RGB USDT, the user needs an RGB-capable wallet. See Getting Started with RGB, the RLN Quick Start, or the Utexo SDK. The swap integration itself adds one step: the user pays the invoice returned with the intent.
1

Quote and intent

Quote and create the intent as for any swap, with deposit_type: "escrowed". user_source_public_key is required, as for other Bitcoin sources.
2

Read the rgblock approval

The intent response returns approval_mechanism: "rgblock":
3

Pay the invoice

The user’s wallet pays witness_invoice for asset_amount of asset_id, and signs the resulting PSBT without broadcasting it. Submit it as a psbt approval:
Utexo accepts either the provided psbt signed by the user, or a PSBT built by the user’s wallet that pays the lock address.
4

Track the swap

Track the intent as usual with Intent Status. If the swap is not fulfilled before the deadline, the RGB USDT is refunded to the user.

For resolvers

An RGB-source swap follows the Bitcoin settlement lifecycle — lock, fulfill, claim — with RGB-specific work in the lock and the claim. It happens in two phases:
  1. Escrow: the RGB allocation is bound to the HTLC output. It is not in your wallet yet.
  2. Ownership: after fulfillment, you spend the HTLC into an RGB receive output of your own wallet, which moves the allocation to you.
You need an RGB wallet that can create witness invoices, accept consignments, and color HTLC spends. Utexo’s rgb-lib exposes the required calls (htlc_prepare, htlc_apply, htlc_abort), with Go bindings in rgb-lib-go.

1. Lock: answer the deposit PSBT callback

Utexo calls your Bitcoin deposit PSBT callback as for a BTC swap.
  1. Build the HTLC exactly as for Bitcoin: NUMS internal key and the three leaves (resolver withdraw with OP_HASH256, timelock refund, fast refund).
  2. Load the asset and amount from the quote. The callback request does not include them.
  3. Create your claim destination: call witness_receive for the asset and amount, then convert the recipient ID into a script with script_hex_from_recipient_id. It must be a witness receive; a blinded receive cannot be used as a claim destination.
  4. Build the lock PSBT with OP_RETURN (intent tag) at output 0 and the P2TR HTLC at output 1, at least dust.
  5. Return the usual fields plus destination_script_hex (the claim destination script, not the HTLC).
Persist the lock address, Taproot spend info, and the withdraw leaf. Do not assume a fixed leaf order when rebuilding the tree later. The lock is one transaction that carries both the BTC and the RGB allocation. Do not lock BTC first and send RGB to the HTLC in a second transaction.

2. Fulfill

Unchanged from Bitcoin settlement: deliver the destination asset and report the fulfillment. Nothing RGB-specific happens in this step.

3. Claim: move the RGB into your wallet

After the swap is fulfilled and the secret is revealed:
1

Accept the lock consignment

Call fetch_and_accept_transfer_by_recipient_id for the lock invoice, then check the amount on the HTLC outpoint with contract_assignments_for_outpoints. The HTLC is not a wallet UTXO, so accept first, then read.
2

Build the claim PSBT

Input: the HTLC outpoint, with the withdraw leaf, control block, and witness UTXO. Outputs: an empty OP_RETURN at 0, and your claim destination (destination_script_hex) at 1. Do not sign yet.
3

Color it

Call htlc_prepare with the PSBT, the asset mapped to output 1, and the HTLC as the input carrying RGB. Color before signing.
4

Post, sign, broadcast, apply

Post the consignment produced by htlc_prepare to the RGB proxy, sign the HTLC input with [signature, secret, script, control block], broadcast, then call htlc_apply and refresh. If you never broadcast, call htlc_abort.

Coloring rules

Do not register the HTLC as a wallet output and do not treat the lock as a wallet UTXO.

Refunds

If the swap is not fulfilled before the deadline, the locked RGB USDT goes back to the user through the timelock refund leaf, as in Bitcoin settlement. To start a resolver integration that includes RGB USDT, contact the Utexo team.