BondL1LockupOutput
The SPV proof for one L1 BTC lockup output, in the tuple shape pox-5 register-for-bond expects. buildLockProof and buildLockProofFromBlock return it, and a BondLockup with kind: 'btc' carries a list of them to buildRegisterForBond.
Usage
import { buildLockProof, buildRegisterForBond } from '@stacks/bitcoin-staking';
const output = buildLockProof({
txHex: await (await fetch(`${esplora}/tx/${txid}/hex`)).text(),
header: await (await fetch(`${esplora}/block/${blockHash}/header`)).text(),
merkleProof: await (await fetch(`${esplora}/tx/${txid}/merkle-proof`)).json(),
txCount: (await (await fetch(`${esplora}/block/${blockHash}`)).json()).tx_count,
unlockHeight: meta.unlockHeight,
lockScript: meta.lockScript, // from buildRegisterMetadata
});
const tx = await buildRegisterForBond({
bondIndex: 2,
signerManager: 'SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.my-signer-manager',
amountUstx,
lockup: { kind: 'btc', outputs: [output], unlockBytes: meta.unlockBytes },
publicKey,
fee: 10_000n,
nonce,
network: 'mainnet',
});Notes
Build the tuple with
buildLockProoforbuildLockProofFromBlockwhere you can. They strip the witness fromtxand reverse the sibling hashes, the two steps that otherwise fail the merkle check.buildRegisterForBond throws before building if
outputsis empty, has more than 10 entries, or an entry has more than 14leafHashes.pox-5 checks each output in
validate-l1-lockup, in the order of this table, and the first failure abortsregister-for-bond:
unlockBurnHeight is below get-bond-l1-unlock-height for the bond, or at or above 500,000,000
ERR_INVALID_UNLOCK_HEIGHT (u52)
The output's script differs from the P2WSH script re-derived from the staker, unlockBurnHeight, the lockup's unlockBytes and the bond's earlyUnlockBytes
ERR_INVALID_LOCKUP_SCRIPT (u42)
amount differs from the output's value
ERR_INVALID_LOCKUP_AMOUNT (u45)
The same txid and output index appear twice in outputs
ERR_DUPLICATE_LOCKUP_OUTPOINT (u46)
header does not hash to the Bitcoin block hash at height
ERR_INVALID_BTC_HEADER (u40)
The merkle path does not fold to the header's merkle root
ERR_INVALID_MERKLE_PROOF (u41)
Definition
Properties
height
number
Bitcoin block height of the block containing the transaction. Sent as height
tx
Uint8Array | string
Raw transaction in legacy serialization, without witness data, as bytes or hex. Sent as tx (buff 100000)
outputIndex
number
Index of the lockup output in the transaction. Sent as output-index
header
Uint8Array | string
80-byte block header, as bytes or hex. Sent as header (buff 80)
leafHashes
(Uint8Array | string)[]
Merkle siblings from leaf to root, 32 bytes each in internal little-endian order. At most 14. Sent as leaf-hashes
txCount
number
Number of transactions in the block. Sent as tx-count
txIndex
number
Zero-based position of the transaction in the block. Sent as tx-index
amount
bigint
Output value in sats. Sent as amount
unlockBurnHeight
number
Bitcoin block height the lockup script's OP_CHECKLOCKTIMEVERIFY commits to. Sent as unlock-burn-height
Was this helpful?