Overview
Bitcoin deposits use a UTXO-based model. Thecall_data from the deposit action is a numeric memo that must be embedded in the transaction as an OP_RETURN output. This memo is how Layerswap identifies and matches your deposit.
Prerequisites:
- bitcoinjs-lib for PSBT construction
- @bitcoinerlab/secp256k1 for elliptic curve operations
- Access to a Bitcoin node or the Mempool.space API for UTXO data and fee estimates
call_data Format
For Bitcoin,call_data is a numeric string representing a memo identifier. Before embedding it into the transaction, convert it to a hex string:
OP_RETURN output in the transaction.
Transaction Construction
1
Fetch UTXOs
Retrieve unspent transaction outputs for the sender’s address. You can use the Mempool.space API or your own Bitcoin node.
2
Fetch raw transactions
For each UTXO, fetch the full raw transaction hex. This is needed to populate the
witnessUtxo field in the PSBT inputs.3
Select UTXOs
Select enough UTXOs to cover the deposit amount plus estimated fees.
4
Build the PSBT
Create a PSBT with:
- Inputs: Selected UTXOs with witness data
- Output 1: Payment to
to_addressfor the depositamount - Output 2:
OP_RETURNwith the hex-encoded memo - Output 3 (if needed): Change back to the sender’s address
5
Estimate fees
Fetch the recommended fee rate from Mempool.space and calculate the transaction fee based on input/output count. Re-select UTXOs if the initial selection doesn’t cover the fee.
6
Sign and broadcast
Sign the PSBT with your private key and broadcast the raw transaction.
Full Example
Signing for Different Address Types
Bitcoin has several address formats, each with different signing requirements:Hardware / Browser Wallet Signing
If you’re using a wallet provider (e.g., Xverse, Unisat, Leather) instead of a raw private key, the flow changes at the signing step. Instead of signing locally, you pass the unsigned PSBT hex to the wallet’ssignPsbt method: