For the complete documentation index, see llms.txt. This page is also available as Markdown.

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 buildLockProof or buildLockProofFromBlock where you can. They strip the witness from tx and reverse the sibling hashes, the two steps that otherwise fail the merkle check.

  • buildRegisterForBond throws before building if outputs is empty, has more than 10 entries, or an entry has more than 14 leafHashes.

  • pox-5 checks each output in validate-l1-lockup, in the order of this table, and the first failure aborts register-for-bond:

Failing condition
Error

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

Property
Type
Description

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?