@babylonlabs-io/ts-sdk 0.79.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -5
- package/dist/{PeginManager-BuVSknB0.cjs → PeginManager-BCJWwV05.cjs} +2 -2
- package/dist/{PeginManager-BuVSknB0.cjs.map → PeginManager-BCJWwV05.cjs.map} +1 -1
- package/dist/{PeginManager-BXlh3ar0.js → PeginManager-BH_AKu4l.js} +5 -5
- package/dist/{PeginManager-BXlh3ar0.js.map → PeginManager-BH_AKu4l.js.map} +1 -1
- package/dist/{buildAndBroadcastReclaim-N9dXH9dm.cjs → buildAndBroadcastReclaim-DLsf5hjO.cjs} +2 -2
- package/dist/{buildAndBroadcastReclaim-N9dXH9dm.cjs.map → buildAndBroadcastReclaim-DLsf5hjO.cjs.map} +1 -1
- package/dist/{buildAndBroadcastReclaim-O6z9kvc4.js → buildAndBroadcastReclaim-OMvihzJg.js} +4 -4
- package/dist/{buildAndBroadcastReclaim-O6z9kvc4.js.map → buildAndBroadcastReclaim-OMvihzJg.js.map} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +8 -8
- package/dist/noPayout-DAWBQ0eG.cjs +2 -0
- package/dist/noPayout-DAWBQ0eG.cjs.map +1 -0
- package/dist/{noPayout-DiGr4eas.js → noPayout-qBXWKwav.js} +3 -3
- package/dist/noPayout-qBXWKwav.js.map +1 -0
- package/dist/{parseFundingOutpoints-B4iQeX6q.cjs → parseFundingOutpoints-BwC3foxS.cjs} +2 -2
- package/dist/parseFundingOutpoints-BwC3foxS.cjs.map +1 -0
- package/dist/{parseFundingOutpoints-BQWvINfm.js → parseFundingOutpoints-CC4NKYz2.js} +19 -19
- package/dist/parseFundingOutpoints-CC4NKYz2.js.map +1 -0
- package/dist/shared/index.cjs.map +1 -1
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/wallets/interfaces/BitcoinWallet.d.ts +6 -3
- package/dist/shared/wallets/interfaces/BitcoinWallet.d.ts.map +1 -1
- package/dist/{signPsbtsWithFallback-f7QLp0q8.js → signPsbtsWithFallback-DoRbHHua.js} +2 -2
- package/dist/{signPsbtsWithFallback-f7QLp0q8.js.map → signPsbtsWithFallback-DoRbHHua.js.map} +1 -1
- package/dist/{signPsbtsWithFallback-DtwzL5AA.cjs → signPsbtsWithFallback-FwrTYZS4.cjs} +2 -2
- package/dist/{signPsbtsWithFallback-DtwzL5AA.cjs.map → signPsbtsWithFallback-FwrTYZS4.cjs.map} +1 -1
- package/dist/tbv/core/index.cjs +1 -1
- package/dist/tbv/core/index.d.ts +1 -1
- package/dist/tbv/core/index.js +8 -8
- package/dist/tbv/core/managers/index.cjs +1 -1
- package/dist/tbv/core/managers/index.js +2 -2
- package/dist/tbv/core/primitives/index.cjs +1 -1
- package/dist/tbv/core/primitives/index.js +3 -3
- package/dist/tbv/core/primitives/psbt/__tests__/assertPeginTxShape.test.d.ts +5 -3
- package/dist/tbv/core/primitives/psbt/__tests__/assertPeginTxShape.test.d.ts.map +1 -1
- package/dist/tbv/core/primitives/psbt/__tests__/deriveExpectedPeginPayoutScriptPubKey.test.d.ts +8 -0
- package/dist/tbv/core/primitives/psbt/__tests__/deriveExpectedPeginPayoutScriptPubKey.test.d.ts.map +1 -0
- package/dist/tbv/core/primitives/psbt/assertWasmPeginSizing.d.ts +6 -0
- package/dist/tbv/core/primitives/psbt/assertWasmPeginSizing.d.ts.map +1 -1
- package/dist/tbv/core/primitives/psbt/pegin.d.ts +4 -1
- package/dist/tbv/core/primitives/psbt/pegin.d.ts.map +1 -1
- package/dist/tbv/core/recovery/recoveryErrors.d.ts +1 -1
- package/dist/tbv/core/services/index.cjs +1 -1
- package/dist/tbv/core/services/index.js +2 -2
- package/dist/tbv/core/vault-secrets/__tests__/context.golden.test.d.ts +4 -4
- package/dist/tbv/core/vault-secrets/__tests__/context.test.d.ts +1 -2
- package/dist/tbv/core/vault-secrets/__tests__/context.test.d.ts.map +1 -1
- package/dist/tbv/core/vault-secrets/__tests__/deriveContextHash.vectors.test.d.ts +40 -0
- package/dist/tbv/core/vault-secrets/__tests__/deriveContextHash.vectors.test.d.ts.map +1 -0
- package/dist/tbv/core/vault-secrets/context.d.ts +2 -2
- package/dist/tbv/core/vault-secrets/deriveVaultRoot.d.ts +5 -6
- package/dist/tbv/core/vault-secrets/deriveVaultRoot.d.ts.map +1 -1
- package/dist/tbv/core/vault-secrets/index.cjs +1 -1
- package/dist/tbv/core/vault-secrets/index.d.ts +2 -2
- package/dist/tbv/core/vault-secrets/index.js +1 -1
- package/dist/tbv/core/wasm/index.cjs +1 -1
- package/dist/tbv/core/wasm/index.cjs.map +1 -1
- package/dist/tbv/core/wasm/index.d.ts +11 -9
- package/dist/tbv/core/wasm/index.d.ts.map +1 -1
- package/dist/tbv/core/wasm/index.js +68 -79
- package/dist/tbv/core/wasm/index.js.map +1 -1
- package/dist/tbv/index.cjs +1 -1
- package/dist/tbv/index.js +8 -8
- package/dist/tbv/integrations/aave/clients/index.d.ts +1 -1
- package/dist/tbv/integrations/aave/clients/index.d.ts.map +1 -1
- package/dist/tbv/integrations/aave/clients/spoke.d.ts +13 -0
- package/dist/tbv/integrations/aave/clients/spoke.d.ts.map +1 -1
- package/dist/tbv/integrations/aave/index.cjs +1 -1
- package/dist/tbv/integrations/aave/index.cjs.map +1 -1
- package/dist/tbv/integrations/aave/index.d.ts +1 -1
- package/dist/tbv/integrations/aave/index.d.ts.map +1 -1
- package/dist/tbv/integrations/aave/index.js +137 -125
- package/dist/tbv/integrations/aave/index.js.map +1 -1
- package/dist/testing/MockBitcoinWallet.d.ts +1 -1
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/{toRefundInputs-9inv4Ai4.js → toRefundInputs-BEulLgN_.js} +5 -5
- package/dist/toRefundInputs-BEulLgN_.js.map +1 -0
- package/dist/{toRefundInputs-DitGWAnz.cjs → toRefundInputs-DEPXcrgO.cjs} +2 -2
- package/dist/toRefundInputs-DEPXcrgO.cjs.map +1 -0
- package/dist/{verifyKeyPathSchnorrSignature-BVtNwgK6.js → verifyKeyPathSchnorrSignature-BQHNhRj6.js} +2 -2
- package/dist/{verifyKeyPathSchnorrSignature-BVtNwgK6.js.map → verifyKeyPathSchnorrSignature-BQHNhRj6.js.map} +1 -1
- package/dist/{verifyKeyPathSchnorrSignature-BjB8Znly.cjs → verifyKeyPathSchnorrSignature-Gm9EmZkx.cjs} +2 -2
- package/dist/{verifyKeyPathSchnorrSignature-BjB8Znly.cjs.map → verifyKeyPathSchnorrSignature-Gm9EmZkx.cjs.map} +1 -1
- package/dist/verifyScriptPathSchnorrSignature-BKZihCjk.cjs +2 -0
- package/dist/verifyScriptPathSchnorrSignature-BKZihCjk.cjs.map +1 -0
- package/dist/{verifyScriptPathSchnorrSignature-D_epga4j.js → verifyScriptPathSchnorrSignature-CpjSTfMj.js} +371 -330
- package/dist/verifyScriptPathSchnorrSignature-CpjSTfMj.js.map +1 -0
- package/package.json +4 -4
- package/dist/noPayout-4RZB2g1e.cjs +0 -2
- package/dist/noPayout-4RZB2g1e.cjs.map +0 -1
- package/dist/noPayout-DiGr4eas.js.map +0 -1
- package/dist/parseFundingOutpoints-B4iQeX6q.cjs.map +0 -1
- package/dist/parseFundingOutpoints-BQWvINfm.js.map +0 -1
- package/dist/toRefundInputs-9inv4Ai4.js.map +0 -1
- package/dist/toRefundInputs-DitGWAnz.cjs.map +0 -1
- package/dist/verifyScriptPathSchnorrSignature-D_epga4j.js.map +0 -1
- package/dist/verifyScriptPathSchnorrSignature-DaRqvEgW.cjs +0 -2
- package/dist/verifyScriptPathSchnorrSignature-DaRqvEgW.cjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseFundingOutpoints-CC4NKYz2.js","sources":["../src/tbv/core/vault-secrets/context.ts","../src/tbv/core/vault-secrets/deriveVaultRoot.ts","../src/tbv/core/vault-secrets/parseFundingOutpoints.ts"],"sourcesContent":["/**\n * Canonical `vaultContext` byte encoding, pinned by\n * `__tests__/context.golden.test.ts`.\n *\n * ```\n * vaultContext :=\n * I2OSP(32, 4) || depositorBtcPubkey // 32B x-only\n * || I2OSP(32, 4) || fundingOutpointsCommitment // 32B SHA-256\n * ```\n *\n * `fundingOutpointsCommitment` is SHA-256 over the canonically-sorted\n * funding outpoints of the Pre-PegIn transaction, serialized as\n * `txid (32B display/RPC order) || vout (4B u32 big-endian)` per\n * outpoint. Sorting by 36-byte lex order makes the commitment\n * invariant under tx-level input reordering, so same-inputs RBF and\n * reorg rebroadcasts yield the same context.\n *\n * @module vault-secrets/context\n */\n\nimport { sha256 } from \"@noble/hashes/sha2.js\";\n\nconst DEPOSITOR_PUBKEY_SIZE = 32;\nconst TXID_SIZE = 32;\nconst OUTPOINT_SIZE = 36;\nconst COMMITMENT_SIZE = 32;\nconst FIELD_LEN_PREFIX_SIZE = 4;\nconst VAULT_CONTEXT_SIZE =\n FIELD_LEN_PREFIX_SIZE +\n DEPOSITOR_PUBKEY_SIZE +\n FIELD_LEN_PREFIX_SIZE +\n COMMITMENT_SIZE;\n\nexport interface FundingOutpoint {\n /**\n * Bitcoin txid in **display / RPC order** (byte-reversed from the\n * internal little-endian wire form used when hashing a raw tx).\n */\n txid: Uint8Array;\n /** Output index within the referenced transaction (u32). */\n vout: number;\n}\n\nexport interface VaultContextInput {\n /** Depositor's x-only BTC public key (32 bytes). */\n depositorBtcPubkey: Uint8Array;\n /** Funding outpoints of the Pre-PegIn transaction. MUST be non-empty. */\n fundingOutpoints: readonly FundingOutpoint[];\n}\n\nfunction writeUint32BE(out: Uint8Array, offset: number, value: number): void {\n out[offset] = (value >>> 24) & 0xff;\n out[offset + 1] = (value >>> 16) & 0xff;\n out[offset + 2] = (value >>> 8) & 0xff;\n out[offset + 3] = value & 0xff;\n}\n\nfunction serializeOutpoint(outpoint: FundingOutpoint): Uint8Array {\n if (outpoint.txid.length !== TXID_SIZE) {\n throw new Error(\n `outpoint.txid must be exactly ${TXID_SIZE} bytes, got ${outpoint.txid.length}`,\n );\n }\n if (\n !Number.isInteger(outpoint.vout) ||\n outpoint.vout < 0 ||\n outpoint.vout > 0xffffffff\n ) {\n throw new Error(`outpoint.vout must be a u32, got ${outpoint.vout}`);\n }\n const out = new Uint8Array(OUTPOINT_SIZE);\n out.set(outpoint.txid, 0);\n writeUint32BE(out, TXID_SIZE, outpoint.vout);\n return out;\n}\n\nfunction compareBytes(a: Uint8Array, b: Uint8Array): number {\n const len = Math.min(a.length, b.length);\n for (let i = 0; i < len; i++) {\n if (a[i] !== b[i]) return a[i] - b[i];\n }\n return a.length - b.length;\n}\n\n/**\n * Compute SHA-256 over canonically-sorted funding outpoints.\n *\n * Outpoints are serialized as 36-byte `txid || vout_BE`, sorted\n * ascending lexicographically, concatenated, then hashed.\n *\n * @stability frozen — on-chain-binding. Any change to layout, sort\n * order, or serialization is a hard fork; existing deposits would no\n * longer match their committed `depositorWotsPkHash`.\n *\n * @throws If `outpoints` is empty or contains duplicates.\n */\nexport function buildFundingOutpointsCommitment(\n outpoints: readonly FundingOutpoint[],\n): Uint8Array {\n if (outpoints.length === 0) {\n throw new Error(\n \"buildFundingOutpointsCommitment: outpoints must be non-empty\",\n );\n }\n const serialized = outpoints.map(serializeOutpoint);\n serialized.sort(compareBytes);\n\n for (let i = 1; i < serialized.length; i++) {\n if (compareBytes(serialized[i - 1], serialized[i]) === 0) {\n throw new Error(\n \"buildFundingOutpointsCommitment: duplicate outpoint detected\",\n );\n }\n }\n\n const flat = new Uint8Array(serialized.length * OUTPOINT_SIZE);\n for (let i = 0; i < serialized.length; i++) {\n flat.set(serialized[i], i * OUTPOINT_SIZE);\n }\n return sha256(flat);\n}\n\n/**\n * Build the canonical `vaultContext` byte string fed into the wallet's\n * `deriveContextHash` (or a locally-implemented equivalent on the\n * app side).\n *\n * Output length is always 72 bytes.\n *\n * @stability frozen — on-chain-binding. The 72-byte layout is the\n * input to `deriveContextHash`; any change rotates the vault root and\n * therefore every WOTS key, hashlock secret, and auth anchor derived\n * from it. Existing deposits cannot be recovered after a layout change.\n */\nexport function buildVaultContext(input: VaultContextInput): Uint8Array {\n if (input.depositorBtcPubkey.length !== DEPOSITOR_PUBKEY_SIZE) {\n throw new Error(\n `vaultContext: depositorBtcPubkey must be exactly ${DEPOSITOR_PUBKEY_SIZE} bytes, got ${input.depositorBtcPubkey.length}`,\n );\n }\n const commitment = buildFundingOutpointsCommitment(input.fundingOutpoints);\n\n const out = new Uint8Array(VAULT_CONTEXT_SIZE);\n let offset = 0;\n\n writeUint32BE(out, offset, DEPOSITOR_PUBKEY_SIZE);\n offset += FIELD_LEN_PREFIX_SIZE;\n out.set(input.depositorBtcPubkey, offset);\n offset += DEPOSITOR_PUBKEY_SIZE;\n\n writeUint32BE(out, offset, COMMITMENT_SIZE);\n offset += FIELD_LEN_PREFIX_SIZE;\n out.set(commitment, offset);\n\n return out;\n}\n","/**\n * Vault-root derivation via the wallet's `deriveContextHash` API.\n *\n * Implements the canonical root source:\n *\n * ```\n * rootDerivation = deriveContextHash(\"babylon-btc-vault\", hex(vaultContext))\n * ```\n *\n * The 32-byte output is fed directly into the {@link expandAuthAnchor},\n * {@link expandHashlockSecret}, and {@link expandWotsSeed} functions in\n * this module.\n *\n * @module vault-secrets/deriveVaultRoot\n */\n\nimport { hexToUint8Array, uint8ArrayToHex } from \"../primitives/utils/bitcoin\";\n\nimport { buildVaultContext, type VaultContextInput } from \"./context\";\n\n/**\n * The fixed `appName` passed to the wallet's `deriveContextHash` for\n * Babylon vault derivations. The wallet displays this in its approval\n * dialog. Frozen — must not be changed without a downstream\n * migration plan, as it provides app-level domain separation across\n * applications using the same wallet.\n */\nexport const VAULT_APP_NAME = \"babylon-btc-vault\";\n\n/** Expected length of the wallet output in bytes (`deriveContextHash` returns 32 bytes). */\nconst ROOT_OUTPUT_BYTES = 32;\n\n/** Expected length of the wallet output in lowercase hex chars. */\nconst ROOT_OUTPUT_HEX_LEN = ROOT_OUTPUT_BYTES * 2;\n\nconst LOWERCASE_HEX_RE = /^[0-9a-f]+$/;\n\n/**\n * Minimal structural shape for the wallet capability needed by this\n * helper. Typed against the method directly so callers can pass any\n * value that implements `deriveContextHash` — `BitcoinWallet` from\n * this SDK, `IBTCProvider` from `@babylonlabs-io/wallet-connector`,\n * or a test mock — without depending on the rest of either interface.\n */\nexport interface DeriveContextHashCapableWallet {\n deriveContextHash(appName: string, context: string): Promise<string>;\n}\n\n/** Forward the deriveContextHash capability only when the wallet actually has it,\n * so seam guards (ensurePrePeginTermsApproval) can fire their typed error instead\n * of a mid-ceremony TypeError. */\nexport function forwardDeriveContextHash(\n wallet: Partial<DeriveContextHashCapableWallet>,\n): Partial<DeriveContextHashCapableWallet> {\n // Captured before the closure so the narrowing survives it. The property\n // read cannot be narrowed across a closure boundary, which is what forced\n // the non-null assertion this replaces; forwarding is otherwise unchanged.\n const deriveContextHash = wallet.deriveContextHash;\n return typeof deriveContextHash === \"function\"\n ? {\n deriveContextHash: (appName, context) =>\n deriveContextHash.call(wallet, appName, context),\n }\n : {};\n}\n\n/**\n * Derive the 32-byte vault root from a wallet by encoding the\n * canonical {@link VaultContextInput} and forwarding to\n * `wallet.deriveContextHash`.\n *\n * Validates the wallet's output strictly: must be exactly 64\n * lowercase hex characters, as the `deriveContextHash` contract requires. A\n * conformant wallet always satisfies this, but we re-check at the\n * SDK boundary so a non-conformant wallet (or a wallet returning a\n * malformed value through a buggy adapter) fails loud here rather\n * than producing silently-wrong derived secrets downstream.\n *\n * The helper itself produces only valid `deriveContextHash` inputs (`appName` is\n * the hardcoded `VAULT_APP_NAME`; `context` is hex of the 72-byte\n * `vaultContext`, always 144 chars lowercase), so input-side\n * validation is unnecessary.\n *\n * @param wallet - Any value implementing `deriveContextHash`.\n * @param input - The canonical {@link VaultContextInput} that\n * uniquely identifies the vault. Encoded by\n * {@link buildVaultContext} into a 72-byte structure\n * before being hex-encoded for the wallet.\n * @stability frozen — on-chain-binding. The pair (`VAULT_APP_NAME`,\n * `vaultContext` encoding) is the wallet's input space; changing\n * either rotates the root and invalidates every secret derived from\n * it. `VAULT_APP_NAME` is frozen and must never change without a\n * downstream migration plan.\n *\n * @returns 32-byte root suitable for {@link expandAuthAnchor},\n * {@link expandHashlockSecret}, {@link expandWotsSeed}.\n * @throws If the wallet returns a non-64-char or non-lowercase-hex\n * string. Errors from the wallet (user rejection,\n * method-not-supported, etc.) propagate unchanged.\n */\nexport async function deriveVaultRoot(\n wallet: DeriveContextHashCapableWallet,\n input: VaultContextInput,\n): Promise<Uint8Array> {\n const vaultContext = buildVaultContext(input);\n const contextHex = uint8ArrayToHex(vaultContext);\n\n const rootHex = await wallet.deriveContextHash(VAULT_APP_NAME, contextHex);\n\n if (typeof rootHex !== \"string\") {\n throw new Error(\n `deriveVaultRoot: wallet must return a string, got ${typeof rootHex}`,\n );\n }\n if (rootHex.length !== ROOT_OUTPUT_HEX_LEN) {\n throw new Error(\n `deriveVaultRoot: wallet must return a ${ROOT_OUTPUT_HEX_LEN}-character hex string (${ROOT_OUTPUT_BYTES} bytes), got length ${rootHex.length}`,\n );\n }\n if (!LOWERCASE_HEX_RE.test(rootHex)) {\n throw new Error(\n \"deriveVaultRoot: wallet must return 64 lowercase hex characters; got value with non-lowercase or non-hex characters\",\n );\n }\n\n return hexToUint8Array(rootHex);\n}\n","/**\n * Parse a Pre-PegIn transaction's inputs into the vault-context\n * `fundingOutpoints` shape consumed by `deriveVaultRoot`. Reverses\n * the prev-txid bytes from wire-internal little-endian to display\n * order so the derivation is byte-for-byte identical to the\n * deposit-time computation.\n *\n * @module vault-secrets/parseFundingOutpoints\n */\n\nimport { Transaction } from \"bitcoinjs-lib\";\nimport { Buffer } from \"buffer\";\n\nimport type { FundingOutpoint } from \"./context\";\n\nexport function parseFundingOutpointsFromTx(\n unsignedTxHex: string,\n): FundingOutpoint[] {\n if (!unsignedTxHex) {\n throw new Error(\"Pre-pegin transaction hex is empty\");\n }\n const cleanHex = unsignedTxHex.startsWith(\"0x\")\n ? unsignedTxHex.slice(2)\n : unsignedTxHex;\n const tx = Transaction.fromHex(cleanHex);\n if (tx.ins.length === 0) {\n throw new Error(\"Pre-pegin transaction has no inputs\");\n }\n return tx.ins.map((input) => ({\n txid: Uint8Array.from(Buffer.from(input.hash).reverse()),\n vout: input.index,\n }));\n}\n"],"names":["DEPOSITOR_PUBKEY_SIZE","TXID_SIZE","OUTPOINT_SIZE","COMMITMENT_SIZE","FIELD_LEN_PREFIX_SIZE","VAULT_CONTEXT_SIZE","writeUint32BE","out","offset","value","serializeOutpoint","outpoint","compareBytes","a","b","len","i","buildFundingOutpointsCommitment","outpoints","serialized","flat","sha256","buildVaultContext","input","commitment","VAULT_APP_NAME","ROOT_OUTPUT_BYTES","ROOT_OUTPUT_HEX_LEN","LOWERCASE_HEX_RE","forwardDeriveContextHash","wallet","deriveContextHash","appName","context","deriveVaultRoot","vaultContext","contextHex","uint8ArrayToHex","rootHex","hexToUint8Array","parseFundingOutpointsFromTx","unsignedTxHex","cleanHex","tx","Transaction","Buffer"],"mappings":";;;;AAsBA,MAAMA,IAAwB,IACxBC,IAAY,IACZC,IAAgB,IAChBC,IAAkB,IAClBC,IAAwB,GACxBC,IACJD,IACAJ,IACAI,IACAD;AAmBF,SAASG,EAAcC,GAAiBC,GAAgBC,GAAqB;AAC3E,EAAAF,EAAIC,CAAM,IAAKC,MAAU,KAAM,KAC/BF,EAAIC,IAAS,CAAC,IAAKC,MAAU,KAAM,KACnCF,EAAIC,IAAS,CAAC,IAAKC,MAAU,IAAK,KAClCF,EAAIC,IAAS,CAAC,IAAIC,IAAQ;AAC5B;AAEA,SAASC,EAAkBC,GAAuC;AAChE,MAAIA,EAAS,KAAK,WAAWV;AAC3B,UAAM,IAAI;AAAA,MACR,iCAAiCA,CAAS,eAAeU,EAAS,KAAK,MAAM;AAAA,IAAA;AAGjF,MACE,CAAC,OAAO,UAAUA,EAAS,IAAI,KAC/BA,EAAS,OAAO,KAChBA,EAAS,OAAO;AAEhB,UAAM,IAAI,MAAM,oCAAoCA,EAAS,IAAI,EAAE;AAErE,QAAMJ,IAAM,IAAI,WAAWL,CAAa;AACxC,SAAAK,EAAI,IAAII,EAAS,MAAM,CAAC,GACxBL,EAAcC,GAAKN,GAAWU,EAAS,IAAI,GACpCJ;AACT;AAEA,SAASK,EAAaC,GAAeC,GAAuB;AAC1D,QAAMC,IAAM,KAAK,IAAIF,EAAE,QAAQC,EAAE,MAAM;AACvC,WAASE,IAAI,GAAGA,IAAID,GAAKC;AACvB,QAAIH,EAAEG,CAAC,MAAMF,EAAEE,CAAC,EAAG,QAAOH,EAAEG,CAAC,IAAIF,EAAEE,CAAC;AAEtC,SAAOH,EAAE,SAASC,EAAE;AACtB;AAcO,SAASG,EACdC,GACY;AACZ,MAAIA,EAAU,WAAW;AACvB,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAGJ,QAAMC,IAAaD,EAAU,IAAIR,CAAiB;AAClD,EAAAS,EAAW,KAAKP,CAAY;AAE5B,WAASI,IAAI,GAAGA,IAAIG,EAAW,QAAQH;AACrC,QAAIJ,EAAaO,EAAWH,IAAI,CAAC,GAAGG,EAAWH,CAAC,CAAC,MAAM;AACrD,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAKN,QAAMI,IAAO,IAAI,WAAWD,EAAW,SAASjB,CAAa;AAC7D,WAASc,IAAI,GAAGA,IAAIG,EAAW,QAAQH;AACrC,IAAAI,EAAK,IAAID,EAAWH,CAAC,GAAGA,IAAId,CAAa;AAE3C,SAAOmB,EAAOD,CAAI;AACpB;AAcO,SAASE,EAAkBC,GAAsC;AACtE,MAAIA,EAAM,mBAAmB,WAAWvB;AACtC,UAAM,IAAI;AAAA,MACR,oDAAoDA,CAAqB,eAAeuB,EAAM,mBAAmB,MAAM;AAAA,IAAA;AAG3H,QAAMC,IAAaP,EAAgCM,EAAM,gBAAgB,GAEnEhB,IAAM,IAAI,WAAWF,CAAkB;AAC7C,MAAIG,IAAS;AAEb,SAAAF,EAAcC,GAAKC,GAAQR,CAAqB,GAChDQ,KAAUJ,GACVG,EAAI,IAAIgB,EAAM,oBAAoBf,CAAM,GACxCA,KAAUR,GAEVM,EAAcC,GAAKC,GAAQL,CAAe,GAC1CK,KAAUJ,GACVG,EAAI,IAAIiB,GAAYhB,CAAM,GAEnBD;AACT;AChIO,MAAMkB,IAAiB,qBAGxBC,IAAoB,IAGpBC,IAAsBD,IAAoB,GAE1CE,IAAmB;AAgBlB,SAASC,EACdC,GACyC;AAIzC,QAAMC,IAAoBD,EAAO;AACjC,SAAO,OAAOC,KAAsB,aAChC;AAAA,IACE,mBAAmB,CAACC,GAASC,MAC3BF,EAAkB,KAAKD,GAAQE,GAASC,CAAO;AAAA,EAAA,IAEnD,CAAA;AACN;AAoCA,eAAsBC,EACpBJ,GACAP,GACqB;AACrB,QAAMY,IAAeb,EAAkBC,CAAK,GACtCa,IAAaC,EAAgBF,CAAY,GAEzCG,IAAU,MAAMR,EAAO,kBAAkBL,GAAgBW,CAAU;AAEzE,MAAI,OAAOE,KAAY;AACrB,UAAM,IAAI;AAAA,MACR,qDAAqD,OAAOA,CAAO;AAAA,IAAA;AAGvE,MAAIA,EAAQ,WAAWX;AACrB,UAAM,IAAI;AAAA,MACR,yCAAyCA,CAAmB,0BAA0BD,CAAiB,uBAAuBY,EAAQ,MAAM;AAAA,IAAA;AAGhJ,MAAI,CAACV,EAAiB,KAAKU,CAAO;AAChC,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAIJ,SAAOC,EAAgBD,CAAO;AAChC;AC/GO,SAASE,EACdC,GACmB;AACnB,MAAI,CAACA;AACH,UAAM,IAAI,MAAM,oCAAoC;AAEtD,QAAMC,IAAWD,EAAc,WAAW,IAAI,IAC1CA,EAAc,MAAM,CAAC,IACrBA,GACEE,IAAKC,EAAY,QAAQF,CAAQ;AACvC,MAAIC,EAAG,IAAI,WAAW;AACpB,UAAM,IAAI,MAAM,qCAAqC;AAEvD,SAAOA,EAAG,IAAI,IAAI,CAACpB,OAAW;AAAA,IAC5B,MAAM,WAAW,KAAKsB,EAAO,KAAKtB,EAAM,IAAI,EAAE,SAAS;AAAA,IACvD,MAAMA,EAAM;AAAA,EAAA,EACZ;AACJ;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/shared/wallets/interfaces/BitcoinWallet.ts"],"sourcesContent":["/**\n * Bitcoin network types.\n * Using string literal union for maximum compatibility with wallet providers.\n */\nexport type BitcoinNetwork = \"mainnet\" | \"testnet\" | \"signet\";\n\n/**\n * Bitcoin network constants\n */\nexport const BitcoinNetworks = {\n MAINNET: \"mainnet\",\n TESTNET: \"testnet\",\n SIGNET: \"signet\",\n} as const;\n\n/**\n * Options for signing a specific input in a PSBT.\n */\nexport interface SignInputOptions {\n /** Input index to sign */\n index: number;\n /** Address for signing (optional) */\n address?: string;\n /** Public key for signing (optional, hex string) */\n publicKey?: string;\n /** Sighash types (optional) */\n sighashTypes?: number[];\n /**\n * Whether the wallet should sign with the tweaked (key-path) signer.\n * Set `false` for Taproot script-path spends, where signing uses the\n * untweaked internal key. If omitted, the wallet's default behavior\n * applies.\n */\n useTweakedSigner?: boolean;\n /**\n * @deprecated Use `useTweakedSigner` instead. `disableTweakSigner: true`\n * is equivalent to `useTweakedSigner: false`; `useTweakedSigner` takes\n * precedence when both are set.\n *\n * `useTweakedSigner` is the canonical field used by UniSat and newer OKX\n * wallet versions. Migrating aligns our interface with the wallet-side\n * convention and avoids the historical divergence in OKX's\n * `disableTweakSigner` implementation.\n */\n disableTweakSigner?: boolean;\n}\n\n/**\n * SignPsbt options for advanced signing scenarios.\n */\nexport interface SignPsbtOptions {\n /** Whether to automatically finalize the PSBT after signing */\n autoFinalized?: boolean;\n /**\n * Specific inputs to sign.\n * If not provided, wallet will attempt to sign all inputs it can.\n * Use this to restrict signing to specific inputs (e.g., only depositor's input).\n */\n signInputs?: SignInputOptions[];\n /** Contract information for the signing operation. */\n contracts?: Array<{\n /** Contract identifier. */\n id: string;\n /** Contract parameters. */\n params: Record<string, string | number | string[] | number[]>;\n }>;\n /** Action metadata. */\n action?: {\n /** Action name for tracking. */\n name: string;\n };\n}\n\n/**\n * This interface is designed to be compatible with @babylonlabs-io/wallet-connector's IBTCProvider\n *\n * Supports Unisat, Ledger, OKX, OneKey, Keystone, and other Bitcoin wallets.\n */\nexport interface BitcoinWallet {\n /**\n * Returns the wallet's public key as a hex string.\n *\n * For Taproot addresses, this should return the x-only public key\n * (32 bytes = 64 hex characters without 0x prefix).\n *\n * For compressed public keys (33 bytes = 66 hex characters),\n * consumers should strip the first byte to get x-only format.\n */\n getPublicKeyHex(): Promise<string>;\n\n /**\n * Returns the wallet's Bitcoin address.\n */\n getAddress(): Promise<string>;\n\n /**\n * Signs a PSBT and returns the signed PSBT as hex.\n *\n * @param psbtHex - The PSBT to sign in hex format\n * @param options - Optional signing parameters (e.g., autoFinalized, contracts)\n * @throws {Error} If the PSBT is invalid or signing fails\n */\n signPsbt(psbtHex: string, options?: SignPsbtOptions): Promise<string>;\n\n /**\n * Signs multiple PSBTs and returns the signed PSBTs as hex.\n * This allows batch signing with a single wallet interaction.\n *\n * @param psbtsHexes - Array of PSBTs to sign in hex format\n * @param options - Optional array of signing parameters for each PSBT\n * @throws {Error} If any PSBT is invalid or signing fails\n */\n signPsbts(\n psbtsHexes: string[],\n options?: SignPsbtOptions[],\n ): Promise<string[]>;\n\n /**\n * Signs a message for authentication or proof of ownership.\n *\n * @param message - The message to sign\n * @param type - The signing method: \"ecdsa\" for standard signatures, \"bip322-simple\" for BIP-322\n * @returns Base64-encoded signature\n */\n signMessage(\n message: string,\n type: \"bip322-simple\" | \"ecdsa\",\n ): Promise<string>;\n\n /**\n * Returns the Bitcoin network the wallet is connected to.\n *\n * @returns BitcoinNetwork enum value (MAINNET, TESTNET, SIGNET)\n */\n getNetwork(): Promise<BitcoinNetwork>;\n\n /**\n * Derives a deterministic 32-byte value
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/shared/wallets/interfaces/BitcoinWallet.ts"],"sourcesContent":["/**\n * Bitcoin network types.\n * Using string literal union for maximum compatibility with wallet providers.\n */\nexport type BitcoinNetwork = \"mainnet\" | \"testnet\" | \"signet\";\n\n/**\n * Bitcoin network constants\n */\nexport const BitcoinNetworks = {\n MAINNET: \"mainnet\",\n TESTNET: \"testnet\",\n SIGNET: \"signet\",\n} as const;\n\n/**\n * Options for signing a specific input in a PSBT.\n */\nexport interface SignInputOptions {\n /** Input index to sign */\n index: number;\n /** Address for signing (optional) */\n address?: string;\n /** Public key for signing (optional, hex string) */\n publicKey?: string;\n /** Sighash types (optional) */\n sighashTypes?: number[];\n /**\n * Whether the wallet should sign with the tweaked (key-path) signer.\n * Set `false` for Taproot script-path spends, where signing uses the\n * untweaked internal key. If omitted, the wallet's default behavior\n * applies.\n */\n useTweakedSigner?: boolean;\n /**\n * @deprecated Use `useTweakedSigner` instead. `disableTweakSigner: true`\n * is equivalent to `useTweakedSigner: false`; `useTweakedSigner` takes\n * precedence when both are set.\n *\n * `useTweakedSigner` is the canonical field used by UniSat and newer OKX\n * wallet versions. Migrating aligns our interface with the wallet-side\n * convention and avoids the historical divergence in OKX's\n * `disableTweakSigner` implementation.\n */\n disableTweakSigner?: boolean;\n}\n\n/**\n * SignPsbt options for advanced signing scenarios.\n */\nexport interface SignPsbtOptions {\n /** Whether to automatically finalize the PSBT after signing */\n autoFinalized?: boolean;\n /**\n * Specific inputs to sign.\n * If not provided, wallet will attempt to sign all inputs it can.\n * Use this to restrict signing to specific inputs (e.g., only depositor's input).\n */\n signInputs?: SignInputOptions[];\n /** Contract information for the signing operation. */\n contracts?: Array<{\n /** Contract identifier. */\n id: string;\n /** Contract parameters. */\n params: Record<string, string | number | string[] | number[]>;\n }>;\n /** Action metadata. */\n action?: {\n /** Action name for tracking. */\n name: string;\n };\n}\n\n/**\n * This interface is designed to be compatible with @babylonlabs-io/wallet-connector's IBTCProvider\n *\n * Supports Unisat, Ledger, OKX, OneKey, Keystone, and other Bitcoin wallets.\n */\nexport interface BitcoinWallet {\n /**\n * Returns the wallet's public key as a hex string.\n *\n * For Taproot addresses, this should return the x-only public key\n * (32 bytes = 64 hex characters without 0x prefix).\n *\n * For compressed public keys (33 bytes = 66 hex characters),\n * consumers should strip the first byte to get x-only format.\n */\n getPublicKeyHex(): Promise<string>;\n\n /**\n * Returns the wallet's Bitcoin address.\n */\n getAddress(): Promise<string>;\n\n /**\n * Signs a PSBT and returns the signed PSBT as hex.\n *\n * @param psbtHex - The PSBT to sign in hex format\n * @param options - Optional signing parameters (e.g., autoFinalized, contracts)\n * @throws {Error} If the PSBT is invalid or signing fails\n */\n signPsbt(psbtHex: string, options?: SignPsbtOptions): Promise<string>;\n\n /**\n * Signs multiple PSBTs and returns the signed PSBTs as hex.\n * This allows batch signing with a single wallet interaction.\n *\n * @param psbtsHexes - Array of PSBTs to sign in hex format\n * @param options - Optional array of signing parameters for each PSBT\n * @throws {Error} If any PSBT is invalid or signing fails\n */\n signPsbts(\n psbtsHexes: string[],\n options?: SignPsbtOptions[],\n ): Promise<string[]>;\n\n /**\n * Signs a message for authentication or proof of ownership.\n *\n * @param message - The message to sign\n * @param type - The signing method: \"ecdsa\" for standard signatures, \"bip322-simple\" for BIP-322\n * @returns Base64-encoded signature\n */\n signMessage(\n message: string,\n type: \"bip322-simple\" | \"ecdsa\",\n ): Promise<string>;\n\n /**\n * Returns the Bitcoin network the wallet is connected to.\n *\n * @returns BitcoinNetwork enum value (MAINNET, TESTNET, SIGNET)\n */\n getNetwork(): Promise<BitcoinNetwork>;\n\n /**\n * Derives a deterministic 32-byte value from the wallet's key material,\n * its network, the connected key, `appName` and `context` (HKDF-SHA-256\n * for HD wallets). The conformance vectors in\n * `tbv/core/vault-secrets/__tests__/deriveContextHash.vectors.test.ts`\n * pin the derivation. Throws with code `WALLET_METHOD_NOT_SUPPORTED` if\n * unimplemented.\n *\n * @returns 64-char lowercase hex (32 bytes).\n */\n deriveContextHash(appName: string, context: string): Promise<string>;\n}\n"],"names":["BitcoinNetworks"],"mappings":"gFASO,MAAMA,EAAkB,CAC7B,QAAS,UACT,QAAS,UACT,OAAQ,QACV"}
|
package/dist/shared/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/shared/wallets/interfaces/BitcoinWallet.ts"],"sourcesContent":["/**\n * Bitcoin network types.\n * Using string literal union for maximum compatibility with wallet providers.\n */\nexport type BitcoinNetwork = \"mainnet\" | \"testnet\" | \"signet\";\n\n/**\n * Bitcoin network constants\n */\nexport const BitcoinNetworks = {\n MAINNET: \"mainnet\",\n TESTNET: \"testnet\",\n SIGNET: \"signet\",\n} as const;\n\n/**\n * Options for signing a specific input in a PSBT.\n */\nexport interface SignInputOptions {\n /** Input index to sign */\n index: number;\n /** Address for signing (optional) */\n address?: string;\n /** Public key for signing (optional, hex string) */\n publicKey?: string;\n /** Sighash types (optional) */\n sighashTypes?: number[];\n /**\n * Whether the wallet should sign with the tweaked (key-path) signer.\n * Set `false` for Taproot script-path spends, where signing uses the\n * untweaked internal key. If omitted, the wallet's default behavior\n * applies.\n */\n useTweakedSigner?: boolean;\n /**\n * @deprecated Use `useTweakedSigner` instead. `disableTweakSigner: true`\n * is equivalent to `useTweakedSigner: false`; `useTweakedSigner` takes\n * precedence when both are set.\n *\n * `useTweakedSigner` is the canonical field used by UniSat and newer OKX\n * wallet versions. Migrating aligns our interface with the wallet-side\n * convention and avoids the historical divergence in OKX's\n * `disableTweakSigner` implementation.\n */\n disableTweakSigner?: boolean;\n}\n\n/**\n * SignPsbt options for advanced signing scenarios.\n */\nexport interface SignPsbtOptions {\n /** Whether to automatically finalize the PSBT after signing */\n autoFinalized?: boolean;\n /**\n * Specific inputs to sign.\n * If not provided, wallet will attempt to sign all inputs it can.\n * Use this to restrict signing to specific inputs (e.g., only depositor's input).\n */\n signInputs?: SignInputOptions[];\n /** Contract information for the signing operation. */\n contracts?: Array<{\n /** Contract identifier. */\n id: string;\n /** Contract parameters. */\n params: Record<string, string | number | string[] | number[]>;\n }>;\n /** Action metadata. */\n action?: {\n /** Action name for tracking. */\n name: string;\n };\n}\n\n/**\n * This interface is designed to be compatible with @babylonlabs-io/wallet-connector's IBTCProvider\n *\n * Supports Unisat, Ledger, OKX, OneKey, Keystone, and other Bitcoin wallets.\n */\nexport interface BitcoinWallet {\n /**\n * Returns the wallet's public key as a hex string.\n *\n * For Taproot addresses, this should return the x-only public key\n * (32 bytes = 64 hex characters without 0x prefix).\n *\n * For compressed public keys (33 bytes = 66 hex characters),\n * consumers should strip the first byte to get x-only format.\n */\n getPublicKeyHex(): Promise<string>;\n\n /**\n * Returns the wallet's Bitcoin address.\n */\n getAddress(): Promise<string>;\n\n /**\n * Signs a PSBT and returns the signed PSBT as hex.\n *\n * @param psbtHex - The PSBT to sign in hex format\n * @param options - Optional signing parameters (e.g., autoFinalized, contracts)\n * @throws {Error} If the PSBT is invalid or signing fails\n */\n signPsbt(psbtHex: string, options?: SignPsbtOptions): Promise<string>;\n\n /**\n * Signs multiple PSBTs and returns the signed PSBTs as hex.\n * This allows batch signing with a single wallet interaction.\n *\n * @param psbtsHexes - Array of PSBTs to sign in hex format\n * @param options - Optional array of signing parameters for each PSBT\n * @throws {Error} If any PSBT is invalid or signing fails\n */\n signPsbts(\n psbtsHexes: string[],\n options?: SignPsbtOptions[],\n ): Promise<string[]>;\n\n /**\n * Signs a message for authentication or proof of ownership.\n *\n * @param message - The message to sign\n * @param type - The signing method: \"ecdsa\" for standard signatures, \"bip322-simple\" for BIP-322\n * @returns Base64-encoded signature\n */\n signMessage(\n message: string,\n type: \"bip322-simple\" | \"ecdsa\",\n ): Promise<string>;\n\n /**\n * Returns the Bitcoin network the wallet is connected to.\n *\n * @returns BitcoinNetwork enum value (MAINNET, TESTNET, SIGNET)\n */\n getNetwork(): Promise<BitcoinNetwork>;\n\n /**\n * Derives a deterministic 32-byte value
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/shared/wallets/interfaces/BitcoinWallet.ts"],"sourcesContent":["/**\n * Bitcoin network types.\n * Using string literal union for maximum compatibility with wallet providers.\n */\nexport type BitcoinNetwork = \"mainnet\" | \"testnet\" | \"signet\";\n\n/**\n * Bitcoin network constants\n */\nexport const BitcoinNetworks = {\n MAINNET: \"mainnet\",\n TESTNET: \"testnet\",\n SIGNET: \"signet\",\n} as const;\n\n/**\n * Options for signing a specific input in a PSBT.\n */\nexport interface SignInputOptions {\n /** Input index to sign */\n index: number;\n /** Address for signing (optional) */\n address?: string;\n /** Public key for signing (optional, hex string) */\n publicKey?: string;\n /** Sighash types (optional) */\n sighashTypes?: number[];\n /**\n * Whether the wallet should sign with the tweaked (key-path) signer.\n * Set `false` for Taproot script-path spends, where signing uses the\n * untweaked internal key. If omitted, the wallet's default behavior\n * applies.\n */\n useTweakedSigner?: boolean;\n /**\n * @deprecated Use `useTweakedSigner` instead. `disableTweakSigner: true`\n * is equivalent to `useTweakedSigner: false`; `useTweakedSigner` takes\n * precedence when both are set.\n *\n * `useTweakedSigner` is the canonical field used by UniSat and newer OKX\n * wallet versions. Migrating aligns our interface with the wallet-side\n * convention and avoids the historical divergence in OKX's\n * `disableTweakSigner` implementation.\n */\n disableTweakSigner?: boolean;\n}\n\n/**\n * SignPsbt options for advanced signing scenarios.\n */\nexport interface SignPsbtOptions {\n /** Whether to automatically finalize the PSBT after signing */\n autoFinalized?: boolean;\n /**\n * Specific inputs to sign.\n * If not provided, wallet will attempt to sign all inputs it can.\n * Use this to restrict signing to specific inputs (e.g., only depositor's input).\n */\n signInputs?: SignInputOptions[];\n /** Contract information for the signing operation. */\n contracts?: Array<{\n /** Contract identifier. */\n id: string;\n /** Contract parameters. */\n params: Record<string, string | number | string[] | number[]>;\n }>;\n /** Action metadata. */\n action?: {\n /** Action name for tracking. */\n name: string;\n };\n}\n\n/**\n * This interface is designed to be compatible with @babylonlabs-io/wallet-connector's IBTCProvider\n *\n * Supports Unisat, Ledger, OKX, OneKey, Keystone, and other Bitcoin wallets.\n */\nexport interface BitcoinWallet {\n /**\n * Returns the wallet's public key as a hex string.\n *\n * For Taproot addresses, this should return the x-only public key\n * (32 bytes = 64 hex characters without 0x prefix).\n *\n * For compressed public keys (33 bytes = 66 hex characters),\n * consumers should strip the first byte to get x-only format.\n */\n getPublicKeyHex(): Promise<string>;\n\n /**\n * Returns the wallet's Bitcoin address.\n */\n getAddress(): Promise<string>;\n\n /**\n * Signs a PSBT and returns the signed PSBT as hex.\n *\n * @param psbtHex - The PSBT to sign in hex format\n * @param options - Optional signing parameters (e.g., autoFinalized, contracts)\n * @throws {Error} If the PSBT is invalid or signing fails\n */\n signPsbt(psbtHex: string, options?: SignPsbtOptions): Promise<string>;\n\n /**\n * Signs multiple PSBTs and returns the signed PSBTs as hex.\n * This allows batch signing with a single wallet interaction.\n *\n * @param psbtsHexes - Array of PSBTs to sign in hex format\n * @param options - Optional array of signing parameters for each PSBT\n * @throws {Error} If any PSBT is invalid or signing fails\n */\n signPsbts(\n psbtsHexes: string[],\n options?: SignPsbtOptions[],\n ): Promise<string[]>;\n\n /**\n * Signs a message for authentication or proof of ownership.\n *\n * @param message - The message to sign\n * @param type - The signing method: \"ecdsa\" for standard signatures, \"bip322-simple\" for BIP-322\n * @returns Base64-encoded signature\n */\n signMessage(\n message: string,\n type: \"bip322-simple\" | \"ecdsa\",\n ): Promise<string>;\n\n /**\n * Returns the Bitcoin network the wallet is connected to.\n *\n * @returns BitcoinNetwork enum value (MAINNET, TESTNET, SIGNET)\n */\n getNetwork(): Promise<BitcoinNetwork>;\n\n /**\n * Derives a deterministic 32-byte value from the wallet's key material,\n * its network, the connected key, `appName` and `context` (HKDF-SHA-256\n * for HD wallets). The conformance vectors in\n * `tbv/core/vault-secrets/__tests__/deriveContextHash.vectors.test.ts`\n * pin the derivation. Throws with code `WALLET_METHOD_NOT_SUPPORTED` if\n * unimplemented.\n *\n * @returns 64-char lowercase hex (32 bytes).\n */\n deriveContextHash(appName: string, context: string): Promise<string>;\n}\n"],"names":["BitcoinNetworks"],"mappings":"AASO,MAAMA,IAAkB;AAAA,EAC7B,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AACV;"}
|
|
@@ -119,9 +119,12 @@ export interface BitcoinWallet {
|
|
|
119
119
|
*/
|
|
120
120
|
getNetwork(): Promise<BitcoinNetwork>;
|
|
121
121
|
/**
|
|
122
|
-
* Derives a deterministic 32-byte value
|
|
123
|
-
* `
|
|
124
|
-
*
|
|
122
|
+
* Derives a deterministic 32-byte value from the wallet's key material,
|
|
123
|
+
* its network, the connected key, `appName` and `context` (HKDF-SHA-256
|
|
124
|
+
* for HD wallets). The conformance vectors in
|
|
125
|
+
* `tbv/core/vault-secrets/__tests__/deriveContextHash.vectors.test.ts`
|
|
126
|
+
* pin the derivation. Throws with code `WALLET_METHOD_NOT_SUPPORTED` if
|
|
127
|
+
* unimplemented.
|
|
125
128
|
*
|
|
126
129
|
* @returns 64-char lowercase hex (32 bytes).
|
|
127
130
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitcoinWallet.d.ts","sourceRoot":"","sources":["../../../../src/shared/wallets/interfaces/BitcoinWallet.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,eAAe;;;;CAIlB,CAAC;AAEX;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;;;;OASG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAChC,sDAAsD;IACtD,SAAS,CAAC,EAAE,KAAK,CAAC;QAChB,2BAA2B;QAC3B,EAAE,EAAE,MAAM,CAAC;QACX,2BAA2B;QAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;KAC/D,CAAC,CAAC;IACH,uBAAuB;IACvB,MAAM,CAAC,EAAE;QACP,gCAAgC;QAChC,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;;;;OAQG;IACH,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnC;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAE9B;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEtE;;;;;;;OAOG;IACH,SAAS,CACP,UAAU,EAAE,MAAM,EAAE,EACpB,OAAO,CAAC,EAAE,eAAe,EAAE,GAC1B,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAErB;;;;;;OAMG;IACH,WAAW,CACT,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,eAAe,GAAG,OAAO,GAC9B,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnB;;;;OAIG;IACH,UAAU,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IAEtC
|
|
1
|
+
{"version":3,"file":"BitcoinWallet.d.ts","sourceRoot":"","sources":["../../../../src/shared/wallets/interfaces/BitcoinWallet.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,eAAe;;;;CAIlB,CAAC;AAEX;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;;;;OASG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAChC,sDAAsD;IACtD,SAAS,CAAC,EAAE,KAAK,CAAC;QAChB,2BAA2B;QAC3B,EAAE,EAAE,MAAM,CAAC;QACX,2BAA2B;QAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;KAC/D,CAAC,CAAC;IACH,uBAAuB;IACvB,MAAM,CAAC,EAAE;QACP,gCAAgC;QAChC,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;;;;OAQG;IACH,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnC;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAE9B;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEtE;;;;;;;OAOG;IACH,SAAS,CACP,UAAU,EAAE,MAAM,EAAE,EACpB,OAAO,CAAC,EAAE,eAAe,EAAE,GAC1B,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAErB;;;;;;OAMG;IACH,WAAW,CACT,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,eAAe,GAAG,OAAO,GAC9B,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnB;;;;OAIG;IACH,UAAU,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IAEtC;;;;;;;;;OASG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACtE"}
|
|
@@ -4,7 +4,7 @@ var p = (t, e, s) => R(t, typeof e != "symbol" ? e + "" : e, s);
|
|
|
4
4
|
import * as T from "bitcoinjs-lib";
|
|
5
5
|
import { s as w, v as h } from "./bitcoin-C-TuHb-v.js";
|
|
6
6
|
import { s as C } from "./sha2-CLpQd0Rd.js";
|
|
7
|
-
import { f as b, i as y, g as d, j as f } from "./verifyScriptPathSchnorrSignature-
|
|
7
|
+
import { f as b, i as y, g as d, j as f } from "./verifyScriptPathSchnorrSignature-CpjSTfMj.js";
|
|
8
8
|
import { D as x } from "./constants-D5vORbQE.js";
|
|
9
9
|
import { a as m } from "./signing-Cm-McVR2.js";
|
|
10
10
|
const S = 106, H = 32, l = 34;
|
|
@@ -308,4 +308,4 @@ export {
|
|
|
308
308
|
_ as s,
|
|
309
309
|
M as v
|
|
310
310
|
};
|
|
311
|
-
//# sourceMappingURL=signPsbtsWithFallback-
|
|
311
|
+
//# sourceMappingURL=signPsbtsWithFallback-DoRbHHua.js.map
|
package/dist/{signPsbtsWithFallback-f7QLp0q8.js.map → signPsbtsWithFallback-DoRbHHua.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signPsbtsWithFallback-f7QLp0q8.js","sources":["../src/tbv/core/managers/pegin/assertAuthAnchorOpReturn.ts","../src/tbv/core/services/htlc/index.ts","../src/tbv/core/deposit-terms/depositTerms.ts","../src/tbv/core/managers/PayoutManager.ts","../src/tbv/core/managers/pegin/signPsbtsWithFallback.ts"],"sourcesContent":["/**\n * Structural verifier for the auth-anchor OP_RETURN in a funded\n * Pre-PegIn transaction.\n *\n * @module managers/pegin/assertAuthAnchorOpReturn\n */\n\nimport * as bitcoin from \"bitcoinjs-lib\";\n\nimport { stripHexPrefix } from \"../../primitives/utils/bitcoin\";\n\n/** OP_RETURN opcode. */\nconst OP_RETURN = 0x6a;\n/** Push-32-bytes opcode (raw push, not OP_PUSHDATA1). */\nconst OP_PUSH32 = 0x20;\n/** Encoded length of a standard OP_RETURN script with a 32-byte payload. */\nconst OP_RETURN_PUSH32_SCRIPT_LEN = 1 + 1 + 32;\n\n/**\n * Verify the broadcast Pre-PegIn carries the expected OP_RETURN\n * commitment to the auth anchor.\n *\n * The OP_RETURN sits at `vout = vaultCount` (right after the per-vault\n * HTLC outputs and before the depositor-claim/change outputs) and\n * pushes the 32-byte `SHA256(authAnchor)`. The script encoding is\n * exactly `OP_RETURN || PUSH32 || <32 bytes>` (34 bytes). A\n * non-conformant WASM build that omitted the OP_RETURN, swapped its\n * position, or changed its push payload would let the depositor\n * obtain a valid bearer token for a Pre-PegIn whose on-chain\n * commitment doesn't actually bind the anchor — degrading the auth\n * from on-chain-bound to a shared secret. Fail closed.\n *\n * @throws If the OP_RETURN is missing, mis-located, mis-encoded, or\n * pushes a payload other than `expectedAuthAnchorHashHex`.\n */\nexport function assertAuthAnchorOpReturn(\n fundedPrePeginTxHex: string,\n vaultCount: number,\n expectedAuthAnchorHashHex: string,\n): void {\n const cleanHex = stripHexPrefix(fundedPrePeginTxHex);\n const tx = bitcoin.Transaction.fromHex(cleanHex);\n\n if (tx.outs.length <= vaultCount) {\n throw new Error(\n `Pre-PegIn auth-anchor OP_RETURN missing: tx has ${tx.outs.length} ` +\n `outputs, expected at least ${vaultCount + 1} (vault outputs + OP_RETURN)`,\n );\n }\n\n const opReturnOutput = tx.outs[vaultCount];\n const script = opReturnOutput.script;\n if (\n script.length !== OP_RETURN_PUSH32_SCRIPT_LEN ||\n script[0] !== OP_RETURN ||\n script[1] !== OP_PUSH32\n ) {\n throw new Error(\n `Pre-PegIn auth-anchor OP_RETURN at vout ${vaultCount} has unexpected ` +\n `script encoding (got ${script.length}-byte script with prefix ` +\n `0x${script.slice(0, Math.min(2, script.length)).toString(\"hex\")}; ` +\n `expected ${OP_RETURN_PUSH32_SCRIPT_LEN}-byte OP_RETURN + PUSH32 layout)`,\n );\n }\n\n const pushedHex = script.slice(2).toString(\"hex\").toLowerCase();\n if (pushedHex !== expectedAuthAnchorHashHex.toLowerCase()) {\n throw new Error(\n `Pre-PegIn auth-anchor OP_RETURN payload mismatch at vout ${vaultCount}: ` +\n `tx pushes ${pushedHex}, expected ${expectedAuthAnchorHashHex}`,\n );\n }\n\n if (opReturnOutput.value !== 0) {\n throw new Error(\n `Pre-PegIn auth-anchor OP_RETURN at vout ${vaultCount} has non-zero ` +\n `value ${opReturnOutput.value}; OP_RETURN outputs must be 0-value`,\n );\n }\n}\n\n/**\n * Scan a funded Pre-PegIn transaction for its auth-anchor commitment\n * (an `OP_RETURN || PUSH32 || <32 bytes>` output with value 0).\n *\n * Returns `{ vout, hash }` when exactly one such output is found.\n * Returns `undefined` when:\n * - the hex is unparseable,\n * - no matching output exists (legacy non-auth-anchored Pre-PegIn),\n * - more than one matching output exists (ambiguous / malformed).\n *\n * Used by the refund orchestrator to (a) locate the on-chain anchor\n * regardless of how many HTLCs preceded it and (b) detect multi-vault\n * funded transactions structurally: the single-vault refund path\n * reconstructs only one hashlock and expects the anchor at vout 1, so\n * any other vout signals a layout this call cannot safely refund.\n */\nexport function findAuthAnchorOpReturn(\n fundedPrePeginTxHex: string,\n): { vout: number; hash: string } | undefined {\n let tx: bitcoin.Transaction;\n try {\n tx = bitcoin.Transaction.fromHex(stripHexPrefix(fundedPrePeginTxHex));\n } catch {\n return undefined;\n }\n\n const hits: { vout: number; hash: string }[] = [];\n for (let i = 0; i < tx.outs.length; i++) {\n const output = tx.outs[i];\n const script = output.script;\n if (\n script.length === OP_RETURN_PUSH32_SCRIPT_LEN &&\n script[0] === OP_RETURN &&\n script[1] === OP_PUSH32 &&\n output.value === 0\n ) {\n hits.push({\n vout: i,\n hash: script.slice(2).toString(\"hex\").toLowerCase(),\n });\n }\n }\n\n return hits.length === 1 ? hits[0] : undefined;\n}\n","/**\n * HTLC Secret / Hashlock Utilities\n *\n * Pure functions for computing and validating SHA-256 hashlocks used in the\n * vault deposit protocol's HTLC (Hash Time Lock Contract).\n *\n * The SDK does NOT generate secrets — that is the caller's responsibility.\n * Today callers use `crypto.getRandomValues(32)`; when the `deriveContextHash`\n * wallet API ships, callers will use `wallet.deriveContextHash(\"babylon-btc-vault\", ctx)`.\n * These utilities work identically regardless of how the secret was produced.\n *\n * On-chain contract validation (BTCVaultRegistry.activateVaultWithSecret):\n * if (sha256(abi.encodePacked(s)) != hashlock) revert InvalidSecret();\n *\n * @module htlc\n */\n\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport type { Hex } from \"viem\";\n\n/** Expected hex length for a 0x-prefixed bytes32 value. */\nconst HEX_BYTES32_LENGTH = 66; // \"0x\" + 64 hex chars\n\n/**\n * Decode a 0x-prefixed hex string to bytes, with strict validation.\n * @throws if the input is not a valid 0x-prefixed hex string\n */\nfunction hexToBytes(hex: Hex): Uint8Array {\n if (!hex.startsWith(\"0x\") && !hex.startsWith(\"0X\")) {\n throw new Error(\"Expected 0x-prefixed hex string\");\n }\n const clean = hex.slice(2);\n if (clean.length % 2 !== 0) {\n throw new Error(`Hex string has odd length: ${clean.length}`);\n }\n if (!/^[0-9a-fA-F]*$/.test(clean)) {\n throw new Error(\"Hex string contains non-hex characters\");\n }\n const bytes = new Uint8Array(clean.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\n/**\n * Encode a Uint8Array as a 0x-prefixed lowercase hex string.\n */\nfunction bytesToHex(bytes: Uint8Array): Hex {\n return `0x${Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\")}`;\n}\n\n/**\n * Validate that a value is a 0x-prefixed bytes32 (exactly 32 bytes).\n * @throws if the value is not exactly 32 bytes\n */\nfunction assertBytes32(value: Hex, label: string): void {\n if (value.length !== HEX_BYTES32_LENGTH) {\n throw new Error(\n `${label} must be exactly 32 bytes (${HEX_BYTES32_LENGTH} hex chars with 0x prefix), got ${value.length}`,\n );\n }\n}\n\n/**\n * Compute the SHA-256 hashlock from a secret preimage.\n *\n * Matches the on-chain validation: `sha256(abi.encodePacked(s))` where `s` is a `bytes32`.\n * `abi.encodePacked(bytes32)` is just the raw 32 bytes — no ABI padding.\n *\n * @param secret - 0x-prefixed bytes32 secret (66 hex chars)\n * @returns 0x-prefixed bytes32 SHA-256 hash\n * @throws if secret is not exactly 32 bytes\n */\nexport function computeHashlock(secret: Hex): Hex {\n assertBytes32(secret, \"Secret\");\n const secretBytes = hexToBytes(secret);\n const hash = sha256(secretBytes);\n return bytesToHex(hash);\n}\n\n/**\n * Validate that a secret's SHA-256 hash matches the expected hashlock.\n *\n * Use this for client-side pre-validation before sending the activation\n * transaction to avoid wasting gas on a contract revert.\n *\n * @param secret - 0x-prefixed bytes32 secret (66 hex chars)\n * @param hashlock - 0x-prefixed bytes32 expected hashlock from the vault\n * @returns true if SHA-256(secret) matches the hashlock\n * @throws if secret or hashlock is not exactly 32 bytes\n */\nexport function validateSecretAgainstHashlock(\n secret: Hex,\n hashlock: Hex,\n): boolean {\n assertBytes32(secret, \"Secret\");\n assertBytes32(hashlock, \"Hashlock\");\n // Validate hashlock is valid hex (secret is validated inside computeHashlock)\n hexToBytes(hashlock);\n\n const computed = computeHashlock(secret);\n return computed.toLowerCase() === hashlock.toLowerCase();\n}\n","import type { BitcoinWallet } from \"../../../shared/wallets/interfaces\";\n\n// Field docs use /** */ so they survive into the emitted .d.ts — the published\n// package is the only contract the external provider author (#2109) sees.\n\nexport interface DepositTermsVaultGroup {\n /** 0-based; equals the group's position (groups are ascending by vout). */\n readonly htlcVout: number;\n /** x-only hex (64 chars), as validated on-chain upstream. */\n readonly vaultProviderBtcPubkey: string;\n /** sats */\n readonly peginAmount: bigint;\n /**\n * sats; the MAXIMUM commission the depositor accepts —\n * floor(peginAmount * maxAcceptableCommissionBps / 10_000), the same\n * ceiling the registration calldata carries. An approving wallet MUST\n * enforce the VP payout commission output `<= commissionFee` (e.g. the\n * Ledger vault app does, firmware >= c8db53e), and every commission the\n * contract admits stays under this ceiling (floor is monotonic in bps),\n * so no contract-admitted deposit can be refused at payout. The actual\n * stamped commission may be lower. Display the quoted value in UI, not this.\n */\n readonly commissionFee: bigint;\n /** sats; the same value for every vault. */\n readonly depositorClaimValue: bigint;\n /**\n * sats; the cap an approving wallet enforces on the PegIn tx fee. Equals\n * the graph's exact (minimum) PegIn fee, which is deterministic — so the\n * cap is satisfied exact-by-construction.\n */\n readonly peginMaxFee: bigint;\n}\n\n/**\n * Field names follow btc-vault vocabulary (the protocol source of truth);\n * a device-wire encoder maps them to its intent fields (e.g. the Ledger TLV:\n * protocolFeeRate -> base_fee_rate, timelockPegin -> pegin_csv_timelock,\n * timelockAssert -> payout_timelock, peginAmount -> vault_amount).\n */\nexport interface DepositTerms {\n /**\n * btc-vault tx-graph version (`vaultCoreVersion`) these terms describe —\n * the vault's stamped on-chain version for resumes, the chain's\n * `activeVaultCoreVersion` for fresh deposits. It selects the PegIn shape\n * an approving wallet must expect: v1 = 2 outputs, no anchor; v2/v3 = TRUC\n * nVersion 3, 3 outputs with a 240-sat P2A anchor at vout 2, and an\n * Assert OP_RETURN marker that raises the claim value\n * (btc-vault `transactions/pegin.rs`, `assert_marker.rs`). A provider that\n * supports only one shape MUST reject the others here rather than\n * mis-validating the PSBTs later.\n */\n vaultCoreVersion: number;\n /**\n * sat/vB; the tx-graph fee rate (protocolFeeRate), NOT the mempool funding\n * rate. Approving wallets bound each payout's fee against this rate —\n * pass the exact graph rate, not an inflated ceiling.\n */\n protocolFeeRate: bigint;\n /** Vault-UTXO CSV timelock (blocks). */\n timelockPegin: number;\n /**\n * btc-vault `timelock_assert` (t2) — the CSV on Assert output 0. Its own\n * param, though production derives it and `timelockPegin` from one value.\n */\n timelockAssert: number;\n /** HTLC refund CSV timelock (blocks). */\n timelockRefund: number;\n /**\n * 64-char hex in display order. A device-wire encoder may need the\n * little-endian form — some hardware byte-compares it against\n * PSBT_IN_PREVIOUS_TXID rather than recomputing the txid.\n */\n prepeginTxid: string;\n /** sats; the funded Pre-PegIn fee (an approving wallet caps the signed fee at this). */\n prepeginMaxFee: bigint;\n /**\n * x-only hex. Sorted ascending by the upstream on-chain validation\n * (validateOnChainParticipantKeys); the builder passes them through\n * unasserted — approving devices may reject unsorted lists at load.\n */\n vaultKeeperBtcPubkeys: readonly string[];\n /**\n * x-only hex, sorted ascending upstream independently of vaultKeeperBtcPubkeys (same\n * pass-through contract). Universal challengers only — the full graph\n * challenger set is vaultKeeperBtcPubkeys ∪ universalChallengerBtcPubkeys (vault keepers are the local\n * challengers).\n */\n universalChallengerBtcPubkeys: readonly string[];\n /** Per-vault groups, ordered by ascending htlcVout. */\n vaults: readonly DepositTermsVaultGroup[];\n}\n\n/**\n * Implemented only by depositor-approval wallets (e.g. a Ledger vault\n * provider). Provider obligations:\n *\n * - Envelope: validate terms against the device's envelope BEFORE the\n * ceremony, rejecting with the shape `{ name: \"DepositTermsRejectedError\",\n * reason: \"device-envelope\", message }` (matched structurally, not by class).\n * - Idempotence: a byte-equal re-approval MUST be a no-op while the\n * device-side approval is live; anything that invalidates it (a later\n * `deriveContextHash`, a signing failure) MUST clear the memo.\n *\n * Seam invariant: any derive invalidates a prior approval, so the SDK\n * re-approves after every derive and before the next terms-bound signature.\n * The re-approval sites are `PeginManager.preparePegin`,\n * `runDepositorPresignFlow`, and `signAndBroadcast` (the Pre-PegIn broadcast,\n * which re-derives before approving unless `holdsApprovedDepositTerms`\n * reports the byte-equal intent still live — see `ensurePrePeginTermsApproval`).\n */\nexport interface DepositTermsApprover {\n approveDepositTerms(terms: DepositTerms): Promise<void>;\n /**\n * OPTIONAL fast-path probe: can the Pre-PegIn signature for exactly these\n * terms proceed under the connection's held approval without a new\n * ceremony? MUST report false once that Pre-PegIn was signed (one-shot),\n * MUST answer from host state without device I/O, MUST return false on any\n * doubt, and MUST never throw. A stale true fails closed at the next\n * signature — this is a UX optimization, never an authorization.\n */\n holdsApprovedDepositTerms?(terms: DepositTerms): Promise<boolean>;\n /**\n * OPTIONAL validate-only pre-check (#2110): reject terms the device\n * envelope would refuse, with the same `{ name:\n * \"DepositTermsRejectedError\", reason: \"device-envelope\", message }` shape\n * as `approveDepositTerms`, WITHOUT any device I/O and WITHOUT touching a\n * held approval — the SDK calls it before the first derive screen, so a\n * side effect here would cost or invalidate a physical ceremony. Success\n * is NOT an approval: `approveDepositTerms` still runs its own envelope\n * gate before the ceremony. Callers may pass provisional terms whose\n * `prepeginTxid` is a placeholder (the real txid exists only post-derive),\n * so implementations MUST NOT validate or bind `prepeginTxid` here.\n */\n validateDepositTerms?(terms: DepositTerms): Promise<void>;\n}\n\n/**\n * Where Pre-PegIn change must pay. Approval (policy) wallets sign key-path\n * under a wallet policy whose change branch the device alone can derive and\n * mark internal — the receive address is NOT acceptable change\n * (`process_in_outs.c:114-117` @ e400d8d8).\n *\n * Separate from {@link DepositTermsApprover} because only the Pre-PegIn build\n * needs it: the presign/payout ceremonies approve terms without ever creating\n * change, so they must not require a wallet to implement this.\n *\n * MUST be stable across a deposit flow: the app reads it to build the tx and\n * `preparePegin` re-reads it to verify, so mid-flow rotation fails that gate.\n */\nexport interface PrePeginChangeSource {\n getChangeAddress(): Promise<string>;\n}\n\n/** Probes {@link DepositTermsApprover.approveDepositTerms}. */\nexport function supportsDepositApproval(\n wallet: BitcoinWallet,\n): wallet is BitcoinWallet & DepositTermsApprover {\n return (\n typeof (wallet as Partial<DepositTermsApprover>).approveDepositTerms ===\n \"function\"\n );\n}\n\n/**\n * The wallet's change address, for the one caller that needs it.\n *\n * Narrowing on `approveDepositTerms` alone cannot promise this method, so\n * calling it off the narrowed value would die on `is not a function` in the\n * middle of `preparePegin`, after the pubkey read. Ask here instead and fail\n * with something a provider author can act on.\n *\n * @throws If the wallet cannot report a change address.\n */\nexport async function requireChangeAddress(\n wallet: BitcoinWallet,\n): Promise<string> {\n const changeSource = wallet as Partial<PrePeginChangeSource>;\n if (typeof changeSource.getChangeAddress !== \"function\") {\n throw new Error(\n \"Approval wallet does not implement getChangeAddress; it must expose its change branch, \" +\n \"because the signing device accepts Pre-PegIn change only there.\",\n );\n }\n return changeSource.getChangeAddress();\n}\n\n/**\n * Spreadable forward of the approval capability for wallet-wrapper objects.\n * Object spread drops prototype methods, so every `{...wallet}` wrapper site\n * must re-attach the capability explicitly: `...forwardDepositApproval(wallet)`.\n */\nexport function forwardDepositApproval(\n wallet: BitcoinWallet,\n): Partial<DepositTermsApprover & PrePeginChangeSource> {\n if (!supportsDepositApproval(wallet)) {\n return {};\n }\n const holdsApprovedDepositTerms = wallet.holdsApprovedDepositTerms;\n const validateDepositTerms = wallet.validateDepositTerms;\n const getChangeAddress = (wallet as Partial<PrePeginChangeSource>)\n .getChangeAddress;\n return {\n approveDepositTerms: (terms) => wallet.approveDepositTerms(terms),\n // All optional in the seam: forward only what the provider implements, so\n // wrapper consumers can keep probing by typeof.\n ...(typeof getChangeAddress === \"function\"\n ? { getChangeAddress: () => getChangeAddress.call(wallet) }\n : {}),\n ...(typeof holdsApprovedDepositTerms === \"function\"\n ? {\n holdsApprovedDepositTerms: (terms: DepositTerms) =>\n holdsApprovedDepositTerms.call(wallet, terms),\n }\n : {}),\n ...(typeof validateDepositTerms === \"function\"\n ? {\n validateDepositTerms: (terms: DepositTerms) =>\n validateDepositTerms.call(wallet, terms),\n }\n : {}),\n };\n}\n\nexport interface BuildDepositTermsInputs {\n /** btc-vault tx-graph version the graph is built under. */\n vaultCoreVersion: number;\n protocolFeeRate: bigint;\n timelockPegin: number;\n /** btc-vault `timelock_assert` (t2) — its own param; NOT derived from timelockPegin here. */\n timelockAssert: number;\n timelockRefund: number;\n prepeginTxid: string;\n prepeginMaxFee: bigint;\n vaultProviderBtcPubkey: string;\n vaultKeeperBtcPubkeys: readonly string[];\n universalChallengerBtcPubkeys: readonly string[];\n /** Ceiling bps, not the quote — see {@link DepositTermsVaultGroup.commissionFee}. */\n maxAcceptableCommissionBps: number;\n peginAmounts: readonly bigint[];\n depositorClaimValue: bigint;\n peginMaxFee: bigint;\n}\n","/**\n * Payout Manager\n *\n * High-level manager that orchestrates the payout signing flow by coordinating\n * SDK primitives ({@link buildPayoutPsbt}, {@link extractPayoutSignature})\n * with a user-provided Bitcoin wallet.\n *\n * The Payout transaction references the Assert transaction (input 1).\n *\n * @see {@link PeginManager} - For Steps 1–4 of the peg-in flow\n * @see {@link buildPayoutPsbt} - Lower-level primitive for custom implementations\n * @see {@link extractPayoutSignature} - Extract signatures from signed PSBTs\n *\n * @module managers/PayoutManager\n */\n\nimport type { BitcoinWallet, SignPsbtOptions } from \"../../../shared/wallets\";\nimport {\n assertPsbtUnsignedTxMatches,\n assertScriptPathSchnorrSignature,\n buildPayoutPsbt,\n extractPayoutSignature,\n validateWalletPubkey,\n type Network,\n} from \"../primitives\";\nimport { DEPOSITOR_SIGNED_INPUT_COUNT } from \"../primitives/psbt/constants\";\nimport { createTaprootScriptPathSignOptions } from \"../utils/signing\";\n\n/** Payout PSBTs are signed by the depositor on input 0 (Taproot script-path). */\nconst PAYOUT_SIGNED_INPUT_INDEX = 0;\n\n/**\n * Configuration for the PayoutManager.\n */\nexport interface PayoutManagerConfig {\n /**\n * Bitcoin network to use for transactions.\n */\n network: Network;\n\n /**\n * Bitcoin wallet for signing payout transactions.\n */\n btcWallet: BitcoinWallet;\n}\n\n/**\n * Base parameters shared by both payout transaction types.\n */\ninterface SignPayoutBaseParams {\n /**\n * Vault core (tx-graph) version the vault was registered under — the\n * vault's stamped on-chain `vaultCoreVersion`. Forwarded to\n * {@link buildPayoutPsbt} to derive the matching graph's payout scripts.\n */\n vaultCoreVersion: number;\n\n /**\n * Peg-in transaction hex.\n * The original transaction that created the vault output being spent.\n */\n peginTxHex: string;\n\n /**\n * Vault provider's BTC public key (x-only, 64-char hex).\n */\n vaultProviderBtcPubkey: string;\n\n /**\n * Vault keeper BTC public keys (x-only, 64-char hex).\n */\n vaultKeeperBtcPubkeys: string[];\n\n /**\n * Universal challenger BTC public keys (x-only, 64-char hex).\n */\n universalChallengerBtcPubkeys: string[];\n\n /**\n * CSV timelock in blocks for the PegIn output.\n */\n timelockPegin: number;\n /** btc-vault `timelock_assert`; payout input 1's sequence. */\n timelockAssert: number;\n\n /**\n * Depositor's BTC public key (x-only, 64-char hex). This MUST be the\n * key registered on-chain for the vault — typically read from\n * `BTCVaultRegistry.getBtcVaultBasicInfo(...).depositorBtcPubKey`.\n *\n * Required: omitting it would degrade `validateWalletPubkey` to a\n * self-comparison, allowing the wrong wallet to produce a signature\n * over a script tree that doesn't match the on-chain UTXO.\n */\n depositorBtcPubkey: string;\n\n /**\n * The on-chain registered depositor payout scriptPubKey (hex, with or without 0x prefix).\n * Used to validate that the VP-provided payout transaction actually pays to the\n * correct depositor payout address before signing.\n */\n registeredPayoutScriptPubKey: string;\n\n /**\n * The claimer's x-only BTC public key for this payout (64-char hex, no prefix).\n * Forwarded to {@link buildPayoutPsbt} for per-role output validation.\n */\n claimerBtcPubkey: string;\n\n /**\n * VP commission in basis points (`1..=9999`). Forwarded to {@link buildPayoutPsbt}.\n */\n commissionBps: number;\n\n /**\n * Version-locked tx-graph fee rate (sat/vB) the graph was built with.\n * Forwarded to {@link buildPayoutPsbt} for the fee band.\n */\n protocolFeeRate: bigint;\n\n /**\n * Security council member x-only pubkeys (hex); forwarded to\n * {@link buildPayoutPsbt} to rebuild the Assert:0 payout leaf and to size the\n * fee floor (see PayoutParams).\n */\n councilMembers: string[];\n\n /** M-of-N council quorum; shapes the Assert:0 council leaf (see PayoutParams). */\n councilQuorum: number;\n\n /**\n * RFC-006 resolved payout destinations, keyed by lowercased x-only operation\n * pubkey. Forwarded verbatim to {@link buildPayoutPsbt}; every VK claimer\n * must be present.\n */\n vkClaimerPayoutScriptPubKeys: Readonly<Record<string, string>>;\n /** RFC-006 VP commission destination. Forwarded to {@link buildPayoutPsbt}. */\n vpCommissionScriptPubKey: string;\n}\n\n/**\n * Parameters for signing a Payout transaction.\n *\n * Payout is used in the challenge path after Assert, when the claimer proves validity.\n * Input 1 references the Assert transaction.\n */\nexport interface SignPayoutParams extends SignPayoutBaseParams {\n /**\n * Payout transaction hex (unsigned).\n * This is the transaction from the vault provider that needs depositor signature.\n */\n payoutTxHex: string;\n\n /**\n * Assert transaction hex.\n * Payout input 1 references Assert output 0.\n */\n assertTxHex: string;\n}\n\n/**\n * Result of signing a payout transaction.\n */\nexport interface PayoutSignatureResult {\n /**\n * 64-byte Schnorr signature (128 hex characters).\n */\n signature: string;\n\n /**\n * Depositor's BTC public key used for signing.\n */\n depositorBtcPubkey: string;\n}\n\n/**\n * High-level manager for payout transaction signing.\n *\n * @remarks\n * After registering your peg-in on Ethereum (Step 3), the vault provider prepares\n * claim/payout transaction pairs. You must sign each payout transaction using this\n * manager and submit the signatures to the vault provider's RPC API.\n *\n * **What happens internally:**\n * 1. Validates your wallet's public key matches the vault's depositor\n * 2. Builds an unsigned PSBT with taproot script path spend info\n * 3. Signs input 0 (the vault UTXO) with your wallet\n * 4. Extracts the 64-byte Schnorr signature\n *\n * **Note:** The payout transaction has 2 inputs. PayoutManager only signs input 0\n * (from the peg-in tx). Input 1 (from the assert tx) is signed by the vault provider.\n *\n * @see {@link PeginManager} - For the complete peg-in flow context\n * @see {@link buildPayoutPsbt} - Lower-level primitive used internally\n * @see {@link extractPayoutSignature} - Signature extraction primitive\n */\nexport class PayoutManager {\n private readonly config: PayoutManagerConfig;\n\n /**\n * Creates a new PayoutManager instance.\n *\n * @param config - Manager configuration including wallet\n */\n constructor(config: PayoutManagerConfig) {\n this.config = config;\n }\n\n /**\n * Signs a Payout transaction and extracts the Schnorr signature.\n *\n * Flow:\n * 1. Vault provider submits Claim transaction\n * 2. Claimer submits Assert transaction to prove validity\n * 3. Payout can be executed (references Assert tx)\n *\n * This method orchestrates the following steps:\n * 1. Get wallet's public key and convert to x-only format\n * 2. Validate wallet pubkey matches on-chain depositor pubkey (if provided)\n * 3. Build unsigned PSBT using primitives\n * 4. Sign PSBT via btcWallet.signPsbt()\n * 5. Extract 64-byte Schnorr signature using primitives\n *\n * The returned signature can be submitted to the vault provider API.\n *\n * @param params - Payout signing parameters\n * @returns Signature result with 64-byte Schnorr signature and depositor pubkey\n * @throws Error if wallet pubkey doesn't match depositor pubkey\n * @throws Error if wallet operations fail or signature extraction fails\n */\n async signPayoutTransaction(\n params: SignPayoutParams,\n ): Promise<PayoutSignatureResult> {\n // Validate wallet pubkey matches depositor and get both formats\n const walletPubkeyRaw = await this.config.btcWallet.getPublicKeyHex();\n const { depositorPubkey } = validateWalletPubkey(\n walletPubkeyRaw,\n params.depositorBtcPubkey,\n );\n\n // Build unsigned PSBT for Payout (uses Assert tx). Per-role output\n // validation happens inside buildPayoutPsbt against the resolved input\n // values.\n const payoutPsbt = await buildPayoutPsbt({\n vaultCoreVersion: params.vaultCoreVersion,\n payoutTxHex: params.payoutTxHex,\n peginTxHex: params.peginTxHex,\n assertTxHex: params.assertTxHex,\n depositorBtcPubkey: depositorPubkey,\n vaultProviderBtcPubkey: params.vaultProviderBtcPubkey,\n vaultKeeperBtcPubkeys: params.vaultKeeperBtcPubkeys,\n universalChallengerBtcPubkeys: params.universalChallengerBtcPubkeys,\n timelockPegin: params.timelockPegin,\n timelockAssert: params.timelockAssert,\n network: this.config.network,\n claimerBtcPubkey: params.claimerBtcPubkey,\n registeredPayoutScriptPubKey: params.registeredPayoutScriptPubKey,\n commissionBps: params.commissionBps,\n protocolFeeRate: params.protocolFeeRate,\n councilMembers: params.councilMembers,\n councilQuorum: params.councilQuorum,\n vkClaimerPayoutScriptPubKeys: params.vkClaimerPayoutScriptPubKeys,\n vpCommissionScriptPubKey: params.vpCommissionScriptPubKey,\n });\n\n // Sign PSBT via wallet (Taproot script-path spend, input 0 only)\n const signedPsbtHex = await this.config.btcWallet.signPsbt(\n payoutPsbt.psbtHex,\n createTaprootScriptPathSignOptions(\n walletPubkeyRaw,\n DEPOSITOR_SIGNED_INPUT_COUNT,\n ),\n );\n\n assertPsbtUnsignedTxMatches({\n requestedPsbtHex: payoutPsbt.psbtHex,\n returnedPsbtHex: signedPsbtHex,\n });\n\n // Extract Schnorr signature\n const signature = extractPayoutSignature(signedPsbtHex, depositorPubkey);\n // Critical Path #7: verify the signature against a sighash recomputed from\n // the PSBT we built, not the wallet-returned one.\n assertScriptPathSchnorrSignature({\n requestedPsbtHex: payoutPsbt.psbtHex,\n signatureHex: signature,\n signerXOnlyPubkeyHex: depositorPubkey,\n inputIndex: PAYOUT_SIGNED_INPUT_INDEX,\n });\n\n return {\n signature,\n depositorBtcPubkey: depositorPubkey,\n };\n }\n\n /**\n * Gets the configured Bitcoin network.\n *\n * @returns The Bitcoin network (mainnet, testnet, signet, regtest)\n */\n getNetwork(): Network {\n return this.config.network;\n }\n\n /**\n * Checks if the wallet supports batch signing (signPsbts).\n *\n * @returns true if batch signing is supported\n */\n supportsBatchSigning(): boolean {\n return typeof this.config.btcWallet.signPsbts === \"function\";\n }\n\n /**\n * Batch signs multiple payout transactions (1 per claimer).\n * This allows signing all transactions with a single wallet interaction.\n *\n * @param transactions - Array of payout params to sign\n * @returns Array of signature results matching input order\n * @throws Error if wallet doesn't support batch signing\n * @throws Error if any signing operation fails\n */\n async signPayoutTransactionsBatch(transactions: SignPayoutParams[]): Promise<\n Array<{\n payoutSignature: string;\n depositorBtcPubkey: string;\n }>\n > {\n if (!this.supportsBatchSigning()) {\n throw new Error(\n \"Wallet does not support batch signing (signPsbts method not available)\",\n );\n }\n\n // Get wallet pubkey once\n const walletPubkeyRaw = await this.config.btcWallet.getPublicKeyHex();\n\n // Build all PSBTs (1 per claimer)\n const psbtsToSign: string[] = [];\n const signOptions: SignPsbtOptions[] = [];\n const depositorPubkeys: string[] = [];\n\n for (const tx of transactions) {\n // Validate wallet pubkey matches depositor\n const { depositorPubkey } = validateWalletPubkey(\n walletPubkeyRaw,\n tx.depositorBtcPubkey,\n );\n depositorPubkeys.push(depositorPubkey);\n\n // Build Payout PSBT (output validation runs inside buildPayoutPsbt\n // against resolved input values).\n const payoutPsbt = await buildPayoutPsbt({\n vaultCoreVersion: tx.vaultCoreVersion,\n payoutTxHex: tx.payoutTxHex,\n peginTxHex: tx.peginTxHex,\n assertTxHex: tx.assertTxHex,\n depositorBtcPubkey: depositorPubkey,\n vaultProviderBtcPubkey: tx.vaultProviderBtcPubkey,\n vaultKeeperBtcPubkeys: tx.vaultKeeperBtcPubkeys,\n universalChallengerBtcPubkeys: tx.universalChallengerBtcPubkeys,\n timelockPegin: tx.timelockPegin,\n timelockAssert: tx.timelockAssert,\n network: this.config.network,\n claimerBtcPubkey: tx.claimerBtcPubkey,\n registeredPayoutScriptPubKey: tx.registeredPayoutScriptPubKey,\n commissionBps: tx.commissionBps,\n protocolFeeRate: tx.protocolFeeRate,\n councilMembers: tx.councilMembers,\n councilQuorum: tx.councilQuorum,\n vkClaimerPayoutScriptPubKeys: tx.vkClaimerPayoutScriptPubKeys,\n vpCommissionScriptPubKey: tx.vpCommissionScriptPubKey,\n });\n psbtsToSign.push(payoutPsbt.psbtHex);\n signOptions.push(\n createTaprootScriptPathSignOptions(\n walletPubkeyRaw,\n DEPOSITOR_SIGNED_INPUT_COUNT,\n ),\n );\n }\n\n // Batch sign all PSBTs with single wallet interaction\n const signedPsbts = await this.config.btcWallet.signPsbts!(\n psbtsToSign,\n signOptions,\n );\n\n // Validate that wallet returned the expected number of signed PSBTs\n if (signedPsbts.length !== transactions.length) {\n throw new Error(\n `Expected ${transactions.length} signed PSBTs but received ${signedPsbts.length}`,\n );\n }\n\n // Extract signatures from signed PSBTs\n const results: Array<{\n payoutSignature: string;\n depositorBtcPubkey: string;\n }> = [];\n\n for (let i = 0; i < transactions.length; i++) {\n const depositorPubkey = depositorPubkeys[i];\n assertPsbtUnsignedTxMatches({\n requestedPsbtHex: psbtsToSign[i],\n returnedPsbtHex: signedPsbts[i],\n });\n const payoutSignature = extractPayoutSignature(\n signedPsbts[i],\n depositorPubkey,\n );\n assertScriptPathSchnorrSignature({\n requestedPsbtHex: psbtsToSign[i],\n signatureHex: payoutSignature,\n signerXOnlyPubkeyHex: depositorPubkey,\n inputIndex: PAYOUT_SIGNED_INPUT_INDEX,\n });\n\n results.push({\n payoutSignature,\n depositorBtcPubkey: depositorPubkey,\n });\n }\n\n return results;\n }\n}\n","/**\n * Wallet-signing helper that routes a lone PSBT to `signPsbt`, prefers native\n * `signPsbts` for real batches, and falls back to sequential `signPsbt` for\n * wallets that don't implement batch signing.\n *\n * @module managers/pegin/signPsbtsWithFallback\n */\n\nimport type {\n BitcoinWallet,\n SignPsbtOptions,\n} from \"../../../../shared/wallets\";\n\n/**\n * Sign one or more PSBTs against a wallet.\n *\n * A single PSBT is always signed via `signPsbt`, never the batch endpoint: it's\n * one wallet interaction either way, and `signPsbt` is the universally-required\n * wallet method (batch `signPsbts` is optional), so single-sign is the portable\n * choice — some integrations (notably MPC / institutional wallets) prefer it.\n * For a real batch (>1), wallets exposing native `signPsbts` (e.g. UniSat) sign\n * in one interaction; others loop `signPsbt`.\n *\n * @throws If native `signPsbts` returns a different number of signed PSBTs\n * than were submitted.\n */\nexport async function signPsbtsWithFallback(\n wallet: BitcoinWallet,\n psbtsHexes: string[],\n options?: SignPsbtOptions[],\n): Promise<string[]> {\n if (psbtsHexes.length === 1) {\n return [await wallet.signPsbt(psbtsHexes[0], options?.[0])];\n }\n\n if (typeof wallet.signPsbts === \"function\") {\n const signedPsbts = await wallet.signPsbts(psbtsHexes, options);\n if (signedPsbts.length !== psbtsHexes.length) {\n throw new Error(\n `Expected ${psbtsHexes.length} signed PSBTs but received ${signedPsbts.length}`,\n );\n }\n return signedPsbts;\n }\n\n const signedPsbts: string[] = [];\n for (let i = 0; i < psbtsHexes.length; i++) {\n signedPsbts.push(await wallet.signPsbt(psbtsHexes[i], options?.[i]));\n }\n return signedPsbts;\n}\n"],"names":["OP_RETURN","OP_PUSH32","OP_RETURN_PUSH32_SCRIPT_LEN","assertAuthAnchorOpReturn","fundedPrePeginTxHex","vaultCount","expectedAuthAnchorHashHex","cleanHex","stripHexPrefix","tx","bitcoin","opReturnOutput","script","pushedHex","findAuthAnchorOpReturn","hits","i","output","HEX_BYTES32_LENGTH","hexToBytes","hex","clean","bytes","bytesToHex","b","assertBytes32","value","label","computeHashlock","secret","secretBytes","hash","sha256","validateSecretAgainstHashlock","hashlock","supportsDepositApproval","wallet","requireChangeAddress","changeSource","forwardDepositApproval","holdsApprovedDepositTerms","validateDepositTerms","getChangeAddress","terms","PAYOUT_SIGNED_INPUT_INDEX","PayoutManager","config","__publicField","params","walletPubkeyRaw","depositorPubkey","validateWalletPubkey","payoutPsbt","buildPayoutPsbt","signedPsbtHex","createTaprootScriptPathSignOptions","DEPOSITOR_SIGNED_INPUT_COUNT","assertPsbtUnsignedTxMatches","signature","extractPayoutSignature","assertScriptPathSchnorrSignature","transactions","psbtsToSign","signOptions","depositorPubkeys","signedPsbts","results","payoutSignature","signPsbtsWithFallback","psbtsHexes","options"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"signPsbtsWithFallback-DoRbHHua.js","sources":["../src/tbv/core/managers/pegin/assertAuthAnchorOpReturn.ts","../src/tbv/core/services/htlc/index.ts","../src/tbv/core/deposit-terms/depositTerms.ts","../src/tbv/core/managers/PayoutManager.ts","../src/tbv/core/managers/pegin/signPsbtsWithFallback.ts"],"sourcesContent":["/**\n * Structural verifier for the auth-anchor OP_RETURN in a funded\n * Pre-PegIn transaction.\n *\n * @module managers/pegin/assertAuthAnchorOpReturn\n */\n\nimport * as bitcoin from \"bitcoinjs-lib\";\n\nimport { stripHexPrefix } from \"../../primitives/utils/bitcoin\";\n\n/** OP_RETURN opcode. */\nconst OP_RETURN = 0x6a;\n/** Push-32-bytes opcode (raw push, not OP_PUSHDATA1). */\nconst OP_PUSH32 = 0x20;\n/** Encoded length of a standard OP_RETURN script with a 32-byte payload. */\nconst OP_RETURN_PUSH32_SCRIPT_LEN = 1 + 1 + 32;\n\n/**\n * Verify the broadcast Pre-PegIn carries the expected OP_RETURN\n * commitment to the auth anchor.\n *\n * The OP_RETURN sits at `vout = vaultCount` (right after the per-vault\n * HTLC outputs and before the depositor-claim/change outputs) and\n * pushes the 32-byte `SHA256(authAnchor)`. The script encoding is\n * exactly `OP_RETURN || PUSH32 || <32 bytes>` (34 bytes). A\n * non-conformant WASM build that omitted the OP_RETURN, swapped its\n * position, or changed its push payload would let the depositor\n * obtain a valid bearer token for a Pre-PegIn whose on-chain\n * commitment doesn't actually bind the anchor — degrading the auth\n * from on-chain-bound to a shared secret. Fail closed.\n *\n * @throws If the OP_RETURN is missing, mis-located, mis-encoded, or\n * pushes a payload other than `expectedAuthAnchorHashHex`.\n */\nexport function assertAuthAnchorOpReturn(\n fundedPrePeginTxHex: string,\n vaultCount: number,\n expectedAuthAnchorHashHex: string,\n): void {\n const cleanHex = stripHexPrefix(fundedPrePeginTxHex);\n const tx = bitcoin.Transaction.fromHex(cleanHex);\n\n if (tx.outs.length <= vaultCount) {\n throw new Error(\n `Pre-PegIn auth-anchor OP_RETURN missing: tx has ${tx.outs.length} ` +\n `outputs, expected at least ${vaultCount + 1} (vault outputs + OP_RETURN)`,\n );\n }\n\n const opReturnOutput = tx.outs[vaultCount];\n const script = opReturnOutput.script;\n if (\n script.length !== OP_RETURN_PUSH32_SCRIPT_LEN ||\n script[0] !== OP_RETURN ||\n script[1] !== OP_PUSH32\n ) {\n throw new Error(\n `Pre-PegIn auth-anchor OP_RETURN at vout ${vaultCount} has unexpected ` +\n `script encoding (got ${script.length}-byte script with prefix ` +\n `0x${script.slice(0, Math.min(2, script.length)).toString(\"hex\")}; ` +\n `expected ${OP_RETURN_PUSH32_SCRIPT_LEN}-byte OP_RETURN + PUSH32 layout)`,\n );\n }\n\n const pushedHex = script.slice(2).toString(\"hex\").toLowerCase();\n if (pushedHex !== expectedAuthAnchorHashHex.toLowerCase()) {\n throw new Error(\n `Pre-PegIn auth-anchor OP_RETURN payload mismatch at vout ${vaultCount}: ` +\n `tx pushes ${pushedHex}, expected ${expectedAuthAnchorHashHex}`,\n );\n }\n\n if (opReturnOutput.value !== 0) {\n throw new Error(\n `Pre-PegIn auth-anchor OP_RETURN at vout ${vaultCount} has non-zero ` +\n `value ${opReturnOutput.value}; OP_RETURN outputs must be 0-value`,\n );\n }\n}\n\n/**\n * Scan a funded Pre-PegIn transaction for its auth-anchor commitment\n * (an `OP_RETURN || PUSH32 || <32 bytes>` output with value 0).\n *\n * Returns `{ vout, hash }` when exactly one such output is found.\n * Returns `undefined` when:\n * - the hex is unparseable,\n * - no matching output exists (legacy non-auth-anchored Pre-PegIn),\n * - more than one matching output exists (ambiguous / malformed).\n *\n * Used by the refund orchestrator to (a) locate the on-chain anchor\n * regardless of how many HTLCs preceded it and (b) detect multi-vault\n * funded transactions structurally: the single-vault refund path\n * reconstructs only one hashlock and expects the anchor at vout 1, so\n * any other vout signals a layout this call cannot safely refund.\n */\nexport function findAuthAnchorOpReturn(\n fundedPrePeginTxHex: string,\n): { vout: number; hash: string } | undefined {\n let tx: bitcoin.Transaction;\n try {\n tx = bitcoin.Transaction.fromHex(stripHexPrefix(fundedPrePeginTxHex));\n } catch {\n return undefined;\n }\n\n const hits: { vout: number; hash: string }[] = [];\n for (let i = 0; i < tx.outs.length; i++) {\n const output = tx.outs[i];\n const script = output.script;\n if (\n script.length === OP_RETURN_PUSH32_SCRIPT_LEN &&\n script[0] === OP_RETURN &&\n script[1] === OP_PUSH32 &&\n output.value === 0\n ) {\n hits.push({\n vout: i,\n hash: script.slice(2).toString(\"hex\").toLowerCase(),\n });\n }\n }\n\n return hits.length === 1 ? hits[0] : undefined;\n}\n","/**\n * HTLC Secret / Hashlock Utilities\n *\n * Pure functions for computing and validating SHA-256 hashlocks used in the\n * vault deposit protocol's HTLC (Hash Time Lock Contract).\n *\n * The SDK does NOT generate secrets — that is the caller's responsibility.\n * Today callers use `crypto.getRandomValues(32)`; when the `deriveContextHash`\n * wallet API ships, callers will use `wallet.deriveContextHash(\"babylon-btc-vault\", ctx)`.\n * These utilities work identically regardless of how the secret was produced.\n *\n * On-chain contract validation (BTCVaultRegistry.activateVaultWithSecret):\n * if (sha256(abi.encodePacked(s)) != hashlock) revert InvalidSecret();\n *\n * @module htlc\n */\n\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport type { Hex } from \"viem\";\n\n/** Expected hex length for a 0x-prefixed bytes32 value. */\nconst HEX_BYTES32_LENGTH = 66; // \"0x\" + 64 hex chars\n\n/**\n * Decode a 0x-prefixed hex string to bytes, with strict validation.\n * @throws if the input is not a valid 0x-prefixed hex string\n */\nfunction hexToBytes(hex: Hex): Uint8Array {\n if (!hex.startsWith(\"0x\") && !hex.startsWith(\"0X\")) {\n throw new Error(\"Expected 0x-prefixed hex string\");\n }\n const clean = hex.slice(2);\n if (clean.length % 2 !== 0) {\n throw new Error(`Hex string has odd length: ${clean.length}`);\n }\n if (!/^[0-9a-fA-F]*$/.test(clean)) {\n throw new Error(\"Hex string contains non-hex characters\");\n }\n const bytes = new Uint8Array(clean.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\n/**\n * Encode a Uint8Array as a 0x-prefixed lowercase hex string.\n */\nfunction bytesToHex(bytes: Uint8Array): Hex {\n return `0x${Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\")}`;\n}\n\n/**\n * Validate that a value is a 0x-prefixed bytes32 (exactly 32 bytes).\n * @throws if the value is not exactly 32 bytes\n */\nfunction assertBytes32(value: Hex, label: string): void {\n if (value.length !== HEX_BYTES32_LENGTH) {\n throw new Error(\n `${label} must be exactly 32 bytes (${HEX_BYTES32_LENGTH} hex chars with 0x prefix), got ${value.length}`,\n );\n }\n}\n\n/**\n * Compute the SHA-256 hashlock from a secret preimage.\n *\n * Matches the on-chain validation: `sha256(abi.encodePacked(s))` where `s` is a `bytes32`.\n * `abi.encodePacked(bytes32)` is just the raw 32 bytes — no ABI padding.\n *\n * @param secret - 0x-prefixed bytes32 secret (66 hex chars)\n * @returns 0x-prefixed bytes32 SHA-256 hash\n * @throws if secret is not exactly 32 bytes\n */\nexport function computeHashlock(secret: Hex): Hex {\n assertBytes32(secret, \"Secret\");\n const secretBytes = hexToBytes(secret);\n const hash = sha256(secretBytes);\n return bytesToHex(hash);\n}\n\n/**\n * Validate that a secret's SHA-256 hash matches the expected hashlock.\n *\n * Use this for client-side pre-validation before sending the activation\n * transaction to avoid wasting gas on a contract revert.\n *\n * @param secret - 0x-prefixed bytes32 secret (66 hex chars)\n * @param hashlock - 0x-prefixed bytes32 expected hashlock from the vault\n * @returns true if SHA-256(secret) matches the hashlock\n * @throws if secret or hashlock is not exactly 32 bytes\n */\nexport function validateSecretAgainstHashlock(\n secret: Hex,\n hashlock: Hex,\n): boolean {\n assertBytes32(secret, \"Secret\");\n assertBytes32(hashlock, \"Hashlock\");\n // Validate hashlock is valid hex (secret is validated inside computeHashlock)\n hexToBytes(hashlock);\n\n const computed = computeHashlock(secret);\n return computed.toLowerCase() === hashlock.toLowerCase();\n}\n","import type { BitcoinWallet } from \"../../../shared/wallets/interfaces\";\n\n// Field docs use /** */ so they survive into the emitted .d.ts — the published\n// package is the only contract the external provider author (#2109) sees.\n\nexport interface DepositTermsVaultGroup {\n /** 0-based; equals the group's position (groups are ascending by vout). */\n readonly htlcVout: number;\n /** x-only hex (64 chars), as validated on-chain upstream. */\n readonly vaultProviderBtcPubkey: string;\n /** sats */\n readonly peginAmount: bigint;\n /**\n * sats; the MAXIMUM commission the depositor accepts —\n * floor(peginAmount * maxAcceptableCommissionBps / 10_000), the same\n * ceiling the registration calldata carries. An approving wallet MUST\n * enforce the VP payout commission output `<= commissionFee` (e.g. the\n * Ledger vault app does, firmware >= c8db53e), and every commission the\n * contract admits stays under this ceiling (floor is monotonic in bps),\n * so no contract-admitted deposit can be refused at payout. The actual\n * stamped commission may be lower. Display the quoted value in UI, not this.\n */\n readonly commissionFee: bigint;\n /** sats; the same value for every vault. */\n readonly depositorClaimValue: bigint;\n /**\n * sats; the cap an approving wallet enforces on the PegIn tx fee. Equals\n * the graph's exact (minimum) PegIn fee, which is deterministic — so the\n * cap is satisfied exact-by-construction.\n */\n readonly peginMaxFee: bigint;\n}\n\n/**\n * Field names follow btc-vault vocabulary (the protocol source of truth);\n * a device-wire encoder maps them to its intent fields (e.g. the Ledger TLV:\n * protocolFeeRate -> base_fee_rate, timelockPegin -> pegin_csv_timelock,\n * timelockAssert -> payout_timelock, peginAmount -> vault_amount).\n */\nexport interface DepositTerms {\n /**\n * btc-vault tx-graph version (`vaultCoreVersion`) these terms describe —\n * the vault's stamped on-chain version for resumes, the chain's\n * `activeVaultCoreVersion` for fresh deposits. It selects the PegIn shape\n * an approving wallet must expect: v1 = 2 outputs, no anchor; v2/v3 = TRUC\n * nVersion 3, 3 outputs with a 240-sat P2A anchor at vout 2, and an\n * Assert OP_RETURN marker that raises the claim value\n * (btc-vault `transactions/pegin.rs`, `assert_marker.rs`). A provider that\n * supports only one shape MUST reject the others here rather than\n * mis-validating the PSBTs later.\n */\n vaultCoreVersion: number;\n /**\n * sat/vB; the tx-graph fee rate (protocolFeeRate), NOT the mempool funding\n * rate. Approving wallets bound each payout's fee against this rate —\n * pass the exact graph rate, not an inflated ceiling.\n */\n protocolFeeRate: bigint;\n /** Vault-UTXO CSV timelock (blocks). */\n timelockPegin: number;\n /**\n * btc-vault `timelock_assert` (t2) — the CSV on Assert output 0. Its own\n * param, though production derives it and `timelockPegin` from one value.\n */\n timelockAssert: number;\n /** HTLC refund CSV timelock (blocks). */\n timelockRefund: number;\n /**\n * 64-char hex in display order. A device-wire encoder may need the\n * little-endian form — some hardware byte-compares it against\n * PSBT_IN_PREVIOUS_TXID rather than recomputing the txid.\n */\n prepeginTxid: string;\n /** sats; the funded Pre-PegIn fee (an approving wallet caps the signed fee at this). */\n prepeginMaxFee: bigint;\n /**\n * x-only hex. Sorted ascending by the upstream on-chain validation\n * (validateOnChainParticipantKeys); the builder passes them through\n * unasserted — approving devices may reject unsorted lists at load.\n */\n vaultKeeperBtcPubkeys: readonly string[];\n /**\n * x-only hex, sorted ascending upstream independently of vaultKeeperBtcPubkeys (same\n * pass-through contract). Universal challengers only — the full graph\n * challenger set is vaultKeeperBtcPubkeys ∪ universalChallengerBtcPubkeys (vault keepers are the local\n * challengers).\n */\n universalChallengerBtcPubkeys: readonly string[];\n /** Per-vault groups, ordered by ascending htlcVout. */\n vaults: readonly DepositTermsVaultGroup[];\n}\n\n/**\n * Implemented only by depositor-approval wallets (e.g. a Ledger vault\n * provider). Provider obligations:\n *\n * - Envelope: validate terms against the device's envelope BEFORE the\n * ceremony, rejecting with the shape `{ name: \"DepositTermsRejectedError\",\n * reason: \"device-envelope\", message }` (matched structurally, not by class).\n * - Idempotence: a byte-equal re-approval MUST be a no-op while the\n * device-side approval is live; anything that invalidates it (a later\n * `deriveContextHash`, a signing failure) MUST clear the memo.\n *\n * Seam invariant: any derive invalidates a prior approval, so the SDK\n * re-approves after every derive and before the next terms-bound signature.\n * The re-approval sites are `PeginManager.preparePegin`,\n * `runDepositorPresignFlow`, and `signAndBroadcast` (the Pre-PegIn broadcast,\n * which re-derives before approving unless `holdsApprovedDepositTerms`\n * reports the byte-equal intent still live — see `ensurePrePeginTermsApproval`).\n */\nexport interface DepositTermsApprover {\n approveDepositTerms(terms: DepositTerms): Promise<void>;\n /**\n * OPTIONAL fast-path probe: can the Pre-PegIn signature for exactly these\n * terms proceed under the connection's held approval without a new\n * ceremony? MUST report false once that Pre-PegIn was signed (one-shot),\n * MUST answer from host state without device I/O, MUST return false on any\n * doubt, and MUST never throw. A stale true fails closed at the next\n * signature — this is a UX optimization, never an authorization.\n */\n holdsApprovedDepositTerms?(terms: DepositTerms): Promise<boolean>;\n /**\n * OPTIONAL validate-only pre-check (#2110): reject terms the device\n * envelope would refuse, with the same `{ name:\n * \"DepositTermsRejectedError\", reason: \"device-envelope\", message }` shape\n * as `approveDepositTerms`, WITHOUT any device I/O and WITHOUT touching a\n * held approval — the SDK calls it before the first derive screen, so a\n * side effect here would cost or invalidate a physical ceremony. Success\n * is NOT an approval: `approveDepositTerms` still runs its own envelope\n * gate before the ceremony. Callers may pass provisional terms whose\n * `prepeginTxid` is a placeholder (the real txid exists only post-derive),\n * so implementations MUST NOT validate or bind `prepeginTxid` here.\n */\n validateDepositTerms?(terms: DepositTerms): Promise<void>;\n}\n\n/**\n * Where Pre-PegIn change must pay. Approval (policy) wallets sign key-path\n * under a wallet policy whose change branch the device alone can derive and\n * mark internal — the receive address is NOT acceptable change\n * (`process_in_outs.c:114-117` @ e400d8d8).\n *\n * Separate from {@link DepositTermsApprover} because only the Pre-PegIn build\n * needs it: the presign/payout ceremonies approve terms without ever creating\n * change, so they must not require a wallet to implement this.\n *\n * MUST be stable across a deposit flow: the app reads it to build the tx and\n * `preparePegin` re-reads it to verify, so mid-flow rotation fails that gate.\n */\nexport interface PrePeginChangeSource {\n getChangeAddress(): Promise<string>;\n}\n\n/** Probes {@link DepositTermsApprover.approveDepositTerms}. */\nexport function supportsDepositApproval(\n wallet: BitcoinWallet,\n): wallet is BitcoinWallet & DepositTermsApprover {\n return (\n typeof (wallet as Partial<DepositTermsApprover>).approveDepositTerms ===\n \"function\"\n );\n}\n\n/**\n * The wallet's change address, for the one caller that needs it.\n *\n * Narrowing on `approveDepositTerms` alone cannot promise this method, so\n * calling it off the narrowed value would die on `is not a function` in the\n * middle of `preparePegin`, after the pubkey read. Ask here instead and fail\n * with something a provider author can act on.\n *\n * @throws If the wallet cannot report a change address.\n */\nexport async function requireChangeAddress(\n wallet: BitcoinWallet,\n): Promise<string> {\n const changeSource = wallet as Partial<PrePeginChangeSource>;\n if (typeof changeSource.getChangeAddress !== \"function\") {\n throw new Error(\n \"Approval wallet does not implement getChangeAddress; it must expose its change branch, \" +\n \"because the signing device accepts Pre-PegIn change only there.\",\n );\n }\n return changeSource.getChangeAddress();\n}\n\n/**\n * Spreadable forward of the approval capability for wallet-wrapper objects.\n * Object spread drops prototype methods, so every `{...wallet}` wrapper site\n * must re-attach the capability explicitly: `...forwardDepositApproval(wallet)`.\n */\nexport function forwardDepositApproval(\n wallet: BitcoinWallet,\n): Partial<DepositTermsApprover & PrePeginChangeSource> {\n if (!supportsDepositApproval(wallet)) {\n return {};\n }\n const holdsApprovedDepositTerms = wallet.holdsApprovedDepositTerms;\n const validateDepositTerms = wallet.validateDepositTerms;\n const getChangeAddress = (wallet as Partial<PrePeginChangeSource>)\n .getChangeAddress;\n return {\n approveDepositTerms: (terms) => wallet.approveDepositTerms(terms),\n // All optional in the seam: forward only what the provider implements, so\n // wrapper consumers can keep probing by typeof.\n ...(typeof getChangeAddress === \"function\"\n ? { getChangeAddress: () => getChangeAddress.call(wallet) }\n : {}),\n ...(typeof holdsApprovedDepositTerms === \"function\"\n ? {\n holdsApprovedDepositTerms: (terms: DepositTerms) =>\n holdsApprovedDepositTerms.call(wallet, terms),\n }\n : {}),\n ...(typeof validateDepositTerms === \"function\"\n ? {\n validateDepositTerms: (terms: DepositTerms) =>\n validateDepositTerms.call(wallet, terms),\n }\n : {}),\n };\n}\n\nexport interface BuildDepositTermsInputs {\n /** btc-vault tx-graph version the graph is built under. */\n vaultCoreVersion: number;\n protocolFeeRate: bigint;\n timelockPegin: number;\n /** btc-vault `timelock_assert` (t2) — its own param; NOT derived from timelockPegin here. */\n timelockAssert: number;\n timelockRefund: number;\n prepeginTxid: string;\n prepeginMaxFee: bigint;\n vaultProviderBtcPubkey: string;\n vaultKeeperBtcPubkeys: readonly string[];\n universalChallengerBtcPubkeys: readonly string[];\n /** Ceiling bps, not the quote — see {@link DepositTermsVaultGroup.commissionFee}. */\n maxAcceptableCommissionBps: number;\n peginAmounts: readonly bigint[];\n depositorClaimValue: bigint;\n peginMaxFee: bigint;\n}\n","/**\n * Payout Manager\n *\n * High-level manager that orchestrates the payout signing flow by coordinating\n * SDK primitives ({@link buildPayoutPsbt}, {@link extractPayoutSignature})\n * with a user-provided Bitcoin wallet.\n *\n * The Payout transaction references the Assert transaction (input 1).\n *\n * @see {@link PeginManager} - For Steps 1–4 of the peg-in flow\n * @see {@link buildPayoutPsbt} - Lower-level primitive for custom implementations\n * @see {@link extractPayoutSignature} - Extract signatures from signed PSBTs\n *\n * @module managers/PayoutManager\n */\n\nimport type { BitcoinWallet, SignPsbtOptions } from \"../../../shared/wallets\";\nimport {\n assertPsbtUnsignedTxMatches,\n assertScriptPathSchnorrSignature,\n buildPayoutPsbt,\n extractPayoutSignature,\n validateWalletPubkey,\n type Network,\n} from \"../primitives\";\nimport { DEPOSITOR_SIGNED_INPUT_COUNT } from \"../primitives/psbt/constants\";\nimport { createTaprootScriptPathSignOptions } from \"../utils/signing\";\n\n/** Payout PSBTs are signed by the depositor on input 0 (Taproot script-path). */\nconst PAYOUT_SIGNED_INPUT_INDEX = 0;\n\n/**\n * Configuration for the PayoutManager.\n */\nexport interface PayoutManagerConfig {\n /**\n * Bitcoin network to use for transactions.\n */\n network: Network;\n\n /**\n * Bitcoin wallet for signing payout transactions.\n */\n btcWallet: BitcoinWallet;\n}\n\n/**\n * Base parameters shared by both payout transaction types.\n */\ninterface SignPayoutBaseParams {\n /**\n * Vault core (tx-graph) version the vault was registered under — the\n * vault's stamped on-chain `vaultCoreVersion`. Forwarded to\n * {@link buildPayoutPsbt} to derive the matching graph's payout scripts.\n */\n vaultCoreVersion: number;\n\n /**\n * Peg-in transaction hex.\n * The original transaction that created the vault output being spent.\n */\n peginTxHex: string;\n\n /**\n * Vault provider's BTC public key (x-only, 64-char hex).\n */\n vaultProviderBtcPubkey: string;\n\n /**\n * Vault keeper BTC public keys (x-only, 64-char hex).\n */\n vaultKeeperBtcPubkeys: string[];\n\n /**\n * Universal challenger BTC public keys (x-only, 64-char hex).\n */\n universalChallengerBtcPubkeys: string[];\n\n /**\n * CSV timelock in blocks for the PegIn output.\n */\n timelockPegin: number;\n /** btc-vault `timelock_assert`; payout input 1's sequence. */\n timelockAssert: number;\n\n /**\n * Depositor's BTC public key (x-only, 64-char hex). This MUST be the\n * key registered on-chain for the vault — typically read from\n * `BTCVaultRegistry.getBtcVaultBasicInfo(...).depositorBtcPubKey`.\n *\n * Required: omitting it would degrade `validateWalletPubkey` to a\n * self-comparison, allowing the wrong wallet to produce a signature\n * over a script tree that doesn't match the on-chain UTXO.\n */\n depositorBtcPubkey: string;\n\n /**\n * The on-chain registered depositor payout scriptPubKey (hex, with or without 0x prefix).\n * Used to validate that the VP-provided payout transaction actually pays to the\n * correct depositor payout address before signing.\n */\n registeredPayoutScriptPubKey: string;\n\n /**\n * The claimer's x-only BTC public key for this payout (64-char hex, no prefix).\n * Forwarded to {@link buildPayoutPsbt} for per-role output validation.\n */\n claimerBtcPubkey: string;\n\n /**\n * VP commission in basis points (`1..=9999`). Forwarded to {@link buildPayoutPsbt}.\n */\n commissionBps: number;\n\n /**\n * Version-locked tx-graph fee rate (sat/vB) the graph was built with.\n * Forwarded to {@link buildPayoutPsbt} for the fee band.\n */\n protocolFeeRate: bigint;\n\n /**\n * Security council member x-only pubkeys (hex); forwarded to\n * {@link buildPayoutPsbt} to rebuild the Assert:0 payout leaf and to size the\n * fee floor (see PayoutParams).\n */\n councilMembers: string[];\n\n /** M-of-N council quorum; shapes the Assert:0 council leaf (see PayoutParams). */\n councilQuorum: number;\n\n /**\n * RFC-006 resolved payout destinations, keyed by lowercased x-only operation\n * pubkey. Forwarded verbatim to {@link buildPayoutPsbt}; every VK claimer\n * must be present.\n */\n vkClaimerPayoutScriptPubKeys: Readonly<Record<string, string>>;\n /** RFC-006 VP commission destination. Forwarded to {@link buildPayoutPsbt}. */\n vpCommissionScriptPubKey: string;\n}\n\n/**\n * Parameters for signing a Payout transaction.\n *\n * Payout is used in the challenge path after Assert, when the claimer proves validity.\n * Input 1 references the Assert transaction.\n */\nexport interface SignPayoutParams extends SignPayoutBaseParams {\n /**\n * Payout transaction hex (unsigned).\n * This is the transaction from the vault provider that needs depositor signature.\n */\n payoutTxHex: string;\n\n /**\n * Assert transaction hex.\n * Payout input 1 references Assert output 0.\n */\n assertTxHex: string;\n}\n\n/**\n * Result of signing a payout transaction.\n */\nexport interface PayoutSignatureResult {\n /**\n * 64-byte Schnorr signature (128 hex characters).\n */\n signature: string;\n\n /**\n * Depositor's BTC public key used for signing.\n */\n depositorBtcPubkey: string;\n}\n\n/**\n * High-level manager for payout transaction signing.\n *\n * @remarks\n * After registering your peg-in on Ethereum (Step 3), the vault provider prepares\n * claim/payout transaction pairs. You must sign each payout transaction using this\n * manager and submit the signatures to the vault provider's RPC API.\n *\n * **What happens internally:**\n * 1. Validates your wallet's public key matches the vault's depositor\n * 2. Builds an unsigned PSBT with taproot script path spend info\n * 3. Signs input 0 (the vault UTXO) with your wallet\n * 4. Extracts the 64-byte Schnorr signature\n *\n * **Note:** The payout transaction has 2 inputs. PayoutManager only signs input 0\n * (from the peg-in tx). Input 1 (from the assert tx) is signed by the vault provider.\n *\n * @see {@link PeginManager} - For the complete peg-in flow context\n * @see {@link buildPayoutPsbt} - Lower-level primitive used internally\n * @see {@link extractPayoutSignature} - Signature extraction primitive\n */\nexport class PayoutManager {\n private readonly config: PayoutManagerConfig;\n\n /**\n * Creates a new PayoutManager instance.\n *\n * @param config - Manager configuration including wallet\n */\n constructor(config: PayoutManagerConfig) {\n this.config = config;\n }\n\n /**\n * Signs a Payout transaction and extracts the Schnorr signature.\n *\n * Flow:\n * 1. Vault provider submits Claim transaction\n * 2. Claimer submits Assert transaction to prove validity\n * 3. Payout can be executed (references Assert tx)\n *\n * This method orchestrates the following steps:\n * 1. Get wallet's public key and convert to x-only format\n * 2. Validate wallet pubkey matches on-chain depositor pubkey (if provided)\n * 3. Build unsigned PSBT using primitives\n * 4. Sign PSBT via btcWallet.signPsbt()\n * 5. Extract 64-byte Schnorr signature using primitives\n *\n * The returned signature can be submitted to the vault provider API.\n *\n * @param params - Payout signing parameters\n * @returns Signature result with 64-byte Schnorr signature and depositor pubkey\n * @throws Error if wallet pubkey doesn't match depositor pubkey\n * @throws Error if wallet operations fail or signature extraction fails\n */\n async signPayoutTransaction(\n params: SignPayoutParams,\n ): Promise<PayoutSignatureResult> {\n // Validate wallet pubkey matches depositor and get both formats\n const walletPubkeyRaw = await this.config.btcWallet.getPublicKeyHex();\n const { depositorPubkey } = validateWalletPubkey(\n walletPubkeyRaw,\n params.depositorBtcPubkey,\n );\n\n // Build unsigned PSBT for Payout (uses Assert tx). Per-role output\n // validation happens inside buildPayoutPsbt against the resolved input\n // values.\n const payoutPsbt = await buildPayoutPsbt({\n vaultCoreVersion: params.vaultCoreVersion,\n payoutTxHex: params.payoutTxHex,\n peginTxHex: params.peginTxHex,\n assertTxHex: params.assertTxHex,\n depositorBtcPubkey: depositorPubkey,\n vaultProviderBtcPubkey: params.vaultProviderBtcPubkey,\n vaultKeeperBtcPubkeys: params.vaultKeeperBtcPubkeys,\n universalChallengerBtcPubkeys: params.universalChallengerBtcPubkeys,\n timelockPegin: params.timelockPegin,\n timelockAssert: params.timelockAssert,\n network: this.config.network,\n claimerBtcPubkey: params.claimerBtcPubkey,\n registeredPayoutScriptPubKey: params.registeredPayoutScriptPubKey,\n commissionBps: params.commissionBps,\n protocolFeeRate: params.protocolFeeRate,\n councilMembers: params.councilMembers,\n councilQuorum: params.councilQuorum,\n vkClaimerPayoutScriptPubKeys: params.vkClaimerPayoutScriptPubKeys,\n vpCommissionScriptPubKey: params.vpCommissionScriptPubKey,\n });\n\n // Sign PSBT via wallet (Taproot script-path spend, input 0 only)\n const signedPsbtHex = await this.config.btcWallet.signPsbt(\n payoutPsbt.psbtHex,\n createTaprootScriptPathSignOptions(\n walletPubkeyRaw,\n DEPOSITOR_SIGNED_INPUT_COUNT,\n ),\n );\n\n assertPsbtUnsignedTxMatches({\n requestedPsbtHex: payoutPsbt.psbtHex,\n returnedPsbtHex: signedPsbtHex,\n });\n\n // Extract Schnorr signature\n const signature = extractPayoutSignature(signedPsbtHex, depositorPubkey);\n // Critical Path #7: verify the signature against a sighash recomputed from\n // the PSBT we built, not the wallet-returned one.\n assertScriptPathSchnorrSignature({\n requestedPsbtHex: payoutPsbt.psbtHex,\n signatureHex: signature,\n signerXOnlyPubkeyHex: depositorPubkey,\n inputIndex: PAYOUT_SIGNED_INPUT_INDEX,\n });\n\n return {\n signature,\n depositorBtcPubkey: depositorPubkey,\n };\n }\n\n /**\n * Gets the configured Bitcoin network.\n *\n * @returns The Bitcoin network (mainnet, testnet, signet, regtest)\n */\n getNetwork(): Network {\n return this.config.network;\n }\n\n /**\n * Checks if the wallet supports batch signing (signPsbts).\n *\n * @returns true if batch signing is supported\n */\n supportsBatchSigning(): boolean {\n return typeof this.config.btcWallet.signPsbts === \"function\";\n }\n\n /**\n * Batch signs multiple payout transactions (1 per claimer).\n * This allows signing all transactions with a single wallet interaction.\n *\n * @param transactions - Array of payout params to sign\n * @returns Array of signature results matching input order\n * @throws Error if wallet doesn't support batch signing\n * @throws Error if any signing operation fails\n */\n async signPayoutTransactionsBatch(transactions: SignPayoutParams[]): Promise<\n Array<{\n payoutSignature: string;\n depositorBtcPubkey: string;\n }>\n > {\n if (!this.supportsBatchSigning()) {\n throw new Error(\n \"Wallet does not support batch signing (signPsbts method not available)\",\n );\n }\n\n // Get wallet pubkey once\n const walletPubkeyRaw = await this.config.btcWallet.getPublicKeyHex();\n\n // Build all PSBTs (1 per claimer)\n const psbtsToSign: string[] = [];\n const signOptions: SignPsbtOptions[] = [];\n const depositorPubkeys: string[] = [];\n\n for (const tx of transactions) {\n // Validate wallet pubkey matches depositor\n const { depositorPubkey } = validateWalletPubkey(\n walletPubkeyRaw,\n tx.depositorBtcPubkey,\n );\n depositorPubkeys.push(depositorPubkey);\n\n // Build Payout PSBT (output validation runs inside buildPayoutPsbt\n // against resolved input values).\n const payoutPsbt = await buildPayoutPsbt({\n vaultCoreVersion: tx.vaultCoreVersion,\n payoutTxHex: tx.payoutTxHex,\n peginTxHex: tx.peginTxHex,\n assertTxHex: tx.assertTxHex,\n depositorBtcPubkey: depositorPubkey,\n vaultProviderBtcPubkey: tx.vaultProviderBtcPubkey,\n vaultKeeperBtcPubkeys: tx.vaultKeeperBtcPubkeys,\n universalChallengerBtcPubkeys: tx.universalChallengerBtcPubkeys,\n timelockPegin: tx.timelockPegin,\n timelockAssert: tx.timelockAssert,\n network: this.config.network,\n claimerBtcPubkey: tx.claimerBtcPubkey,\n registeredPayoutScriptPubKey: tx.registeredPayoutScriptPubKey,\n commissionBps: tx.commissionBps,\n protocolFeeRate: tx.protocolFeeRate,\n councilMembers: tx.councilMembers,\n councilQuorum: tx.councilQuorum,\n vkClaimerPayoutScriptPubKeys: tx.vkClaimerPayoutScriptPubKeys,\n vpCommissionScriptPubKey: tx.vpCommissionScriptPubKey,\n });\n psbtsToSign.push(payoutPsbt.psbtHex);\n signOptions.push(\n createTaprootScriptPathSignOptions(\n walletPubkeyRaw,\n DEPOSITOR_SIGNED_INPUT_COUNT,\n ),\n );\n }\n\n // Batch sign all PSBTs with single wallet interaction\n const signedPsbts = await this.config.btcWallet.signPsbts!(\n psbtsToSign,\n signOptions,\n );\n\n // Validate that wallet returned the expected number of signed PSBTs\n if (signedPsbts.length !== transactions.length) {\n throw new Error(\n `Expected ${transactions.length} signed PSBTs but received ${signedPsbts.length}`,\n );\n }\n\n // Extract signatures from signed PSBTs\n const results: Array<{\n payoutSignature: string;\n depositorBtcPubkey: string;\n }> = [];\n\n for (let i = 0; i < transactions.length; i++) {\n const depositorPubkey = depositorPubkeys[i];\n assertPsbtUnsignedTxMatches({\n requestedPsbtHex: psbtsToSign[i],\n returnedPsbtHex: signedPsbts[i],\n });\n const payoutSignature = extractPayoutSignature(\n signedPsbts[i],\n depositorPubkey,\n );\n assertScriptPathSchnorrSignature({\n requestedPsbtHex: psbtsToSign[i],\n signatureHex: payoutSignature,\n signerXOnlyPubkeyHex: depositorPubkey,\n inputIndex: PAYOUT_SIGNED_INPUT_INDEX,\n });\n\n results.push({\n payoutSignature,\n depositorBtcPubkey: depositorPubkey,\n });\n }\n\n return results;\n }\n}\n","/**\n * Wallet-signing helper that routes a lone PSBT to `signPsbt`, prefers native\n * `signPsbts` for real batches, and falls back to sequential `signPsbt` for\n * wallets that don't implement batch signing.\n *\n * @module managers/pegin/signPsbtsWithFallback\n */\n\nimport type {\n BitcoinWallet,\n SignPsbtOptions,\n} from \"../../../../shared/wallets\";\n\n/**\n * Sign one or more PSBTs against a wallet.\n *\n * A single PSBT is always signed via `signPsbt`, never the batch endpoint: it's\n * one wallet interaction either way, and `signPsbt` is the universally-required\n * wallet method (batch `signPsbts` is optional), so single-sign is the portable\n * choice — some integrations (notably MPC / institutional wallets) prefer it.\n * For a real batch (>1), wallets exposing native `signPsbts` (e.g. UniSat) sign\n * in one interaction; others loop `signPsbt`.\n *\n * @throws If native `signPsbts` returns a different number of signed PSBTs\n * than were submitted.\n */\nexport async function signPsbtsWithFallback(\n wallet: BitcoinWallet,\n psbtsHexes: string[],\n options?: SignPsbtOptions[],\n): Promise<string[]> {\n if (psbtsHexes.length === 1) {\n return [await wallet.signPsbt(psbtsHexes[0], options?.[0])];\n }\n\n if (typeof wallet.signPsbts === \"function\") {\n const signedPsbts = await wallet.signPsbts(psbtsHexes, options);\n if (signedPsbts.length !== psbtsHexes.length) {\n throw new Error(\n `Expected ${psbtsHexes.length} signed PSBTs but received ${signedPsbts.length}`,\n );\n }\n return signedPsbts;\n }\n\n const signedPsbts: string[] = [];\n for (let i = 0; i < psbtsHexes.length; i++) {\n signedPsbts.push(await wallet.signPsbt(psbtsHexes[i], options?.[i]));\n }\n return signedPsbts;\n}\n"],"names":["OP_RETURN","OP_PUSH32","OP_RETURN_PUSH32_SCRIPT_LEN","assertAuthAnchorOpReturn","fundedPrePeginTxHex","vaultCount","expectedAuthAnchorHashHex","cleanHex","stripHexPrefix","tx","bitcoin","opReturnOutput","script","pushedHex","findAuthAnchorOpReturn","hits","i","output","HEX_BYTES32_LENGTH","hexToBytes","hex","clean","bytes","bytesToHex","b","assertBytes32","value","label","computeHashlock","secret","secretBytes","hash","sha256","validateSecretAgainstHashlock","hashlock","supportsDepositApproval","wallet","requireChangeAddress","changeSource","forwardDepositApproval","holdsApprovedDepositTerms","validateDepositTerms","getChangeAddress","terms","PAYOUT_SIGNED_INPUT_INDEX","PayoutManager","config","__publicField","params","walletPubkeyRaw","depositorPubkey","validateWalletPubkey","payoutPsbt","buildPayoutPsbt","signedPsbtHex","createTaprootScriptPathSignOptions","DEPOSITOR_SIGNED_INPUT_COUNT","assertPsbtUnsignedTxMatches","signature","extractPayoutSignature","assertScriptPathSchnorrSignature","transactions","psbtsToSign","signOptions","depositorPubkeys","signedPsbts","results","payoutSignature","signPsbtsWithFallback","psbtsHexes","options"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var H=Object.defineProperty;var B=(t,e,r)=>e in t?H(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var b=(t,e,r)=>B(t,typeof e!="symbol"?e+"":e,r);const E=require("bitcoinjs-lib"),p=require("./bitcoin-D-O2GjbC.cjs"),A=require("./sha2-DI0-0SHr.cjs"),u=require("./verifyScriptPathSchnorrSignature-
|
|
2
|
-
//# sourceMappingURL=signPsbtsWithFallback-
|
|
1
|
+
"use strict";var H=Object.defineProperty;var B=(t,e,r)=>e in t?H(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var b=(t,e,r)=>B(t,typeof e!="symbol"?e+"":e,r);const E=require("bitcoinjs-lib"),p=require("./bitcoin-D-O2GjbC.cjs"),A=require("./sha2-DI0-0SHr.cjs"),u=require("./verifyScriptPathSchnorrSignature-BKZihCjk.cjs"),y=require("./constants-BTZdyOuk.cjs"),d=require("./signing-BJ3X66b-.cjs");function O(t){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const r in t)if(r!=="default"){const o=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(e,r,o.get?o:{enumerable:!0,get:()=>t[r]})}}return e.default=t,Object.freeze(e)}const v=O(E),k=106,S=32,P=34;function R(t,e,r){const o=p.stripHexPrefix(t),s=v.Transaction.fromHex(o);if(s.outs.length<=e)throw new Error(`Pre-PegIn auth-anchor OP_RETURN missing: tx has ${s.outs.length} outputs, expected at least ${e+1} (vault outputs + OP_RETURN)`);const c=s.outs[e],i=c.script;if(i.length!==P||i[0]!==k||i[1]!==S)throw new Error(`Pre-PegIn auth-anchor OP_RETURN at vout ${e} has unexpected script encoding (got ${i.length}-byte script with prefix 0x${i.slice(0,Math.min(2,i.length)).toString("hex")}; expected ${P}-byte OP_RETURN + PUSH32 layout)`);const l=i.slice(2).toString("hex").toLowerCase();if(l!==r.toLowerCase())throw new Error(`Pre-PegIn auth-anchor OP_RETURN payload mismatch at vout ${e}: tx pushes ${l}, expected ${r}`);if(c.value!==0)throw new Error(`Pre-PegIn auth-anchor OP_RETURN at vout ${e} has non-zero value ${c.value}; OP_RETURN outputs must be 0-value`)}function C(t){let e;try{e=v.Transaction.fromHex(p.stripHexPrefix(t))}catch{return}const r=[];for(let o=0;o<e.outs.length;o++){const s=e.outs[o],c=s.script;c.length===P&&c[0]===k&&c[1]===S&&s.value===0&&r.push({vout:o,hash:c.slice(2).toString("hex").toLowerCase()})}return r.length===1?r[0]:void 0}const f=66;function T(t){if(!t.startsWith("0x")&&!t.startsWith("0X"))throw new Error("Expected 0x-prefixed hex string");const e=t.slice(2);if(e.length%2!==0)throw new Error(`Hex string has odd length: ${e.length}`);if(!/^[0-9a-fA-F]*$/.test(e))throw new Error("Hex string contains non-hex characters");const r=new Uint8Array(e.length/2);for(let o=0;o<r.length;o++)r[o]=parseInt(e.slice(o*2,o*2+2),16);return r}function _(t){return`0x${Array.from(t).map(e=>e.toString(16).padStart(2,"0")).join("")}`}function h(t,e){if(t.length!==f)throw new Error(`${e} must be exactly 32 bytes (${f} hex chars with 0x prefix), got ${t.length}`)}function m(t){h(t,"Secret");const e=T(t),r=A.sha256(e);return _(r)}function N(t,e){return h(t,"Secret"),h(e,"Hashlock"),T(e),m(t).toLowerCase()===e.toLowerCase()}function w(t){return typeof t.approveDepositTerms=="function"}async function $(t){const e=t;if(typeof e.getChangeAddress!="function")throw new Error("Approval wallet does not implement getChangeAddress; it must expose its change branch, because the signing device accepts Pre-PegIn change only there.");return e.getChangeAddress()}function D(t){if(!w(t))return{};const e=t.holdsApprovedDepositTerms,r=t.validateDepositTerms,o=t.getChangeAddress;return{approveDepositTerms:s=>t.approveDepositTerms(s),...typeof o=="function"?{getChangeAddress:()=>o.call(t)}:{},...typeof e=="function"?{holdsApprovedDepositTerms:s=>e.call(t,s)}:{},...typeof r=="function"?{validateDepositTerms:s=>r.call(t,s)}:{}}}const x=0;class U{constructor(e){b(this,"config");this.config=e}async signPayoutTransaction(e){const r=await this.config.btcWallet.getPublicKeyHex(),{depositorPubkey:o}=p.validateWalletPubkey(r,e.depositorBtcPubkey),s=await u.buildPayoutPsbt({vaultCoreVersion:e.vaultCoreVersion,payoutTxHex:e.payoutTxHex,peginTxHex:e.peginTxHex,assertTxHex:e.assertTxHex,depositorBtcPubkey:o,vaultProviderBtcPubkey:e.vaultProviderBtcPubkey,vaultKeeperBtcPubkeys:e.vaultKeeperBtcPubkeys,universalChallengerBtcPubkeys:e.universalChallengerBtcPubkeys,timelockPegin:e.timelockPegin,timelockAssert:e.timelockAssert,network:this.config.network,claimerBtcPubkey:e.claimerBtcPubkey,registeredPayoutScriptPubKey:e.registeredPayoutScriptPubKey,commissionBps:e.commissionBps,protocolFeeRate:e.protocolFeeRate,councilMembers:e.councilMembers,councilQuorum:e.councilQuorum,vkClaimerPayoutScriptPubKeys:e.vkClaimerPayoutScriptPubKeys,vpCommissionScriptPubKey:e.vpCommissionScriptPubKey}),c=await this.config.btcWallet.signPsbt(s.psbtHex,d.createTaprootScriptPathSignOptions(r,y.DEPOSITOR_SIGNED_INPUT_COUNT));u.assertPsbtUnsignedTxMatches({requestedPsbtHex:s.psbtHex,returnedPsbtHex:c});const i=u.extractPayoutSignature(c,o);return u.assertScriptPathSchnorrSignature({requestedPsbtHex:s.psbtHex,signatureHex:i,signerXOnlyPubkeyHex:o,inputIndex:x}),{signature:i,depositorBtcPubkey:o}}getNetwork(){return this.config.network}supportsBatchSigning(){return typeof this.config.btcWallet.signPsbts=="function"}async signPayoutTransactionsBatch(e){if(!this.supportsBatchSigning())throw new Error("Wallet does not support batch signing (signPsbts method not available)");const r=await this.config.btcWallet.getPublicKeyHex(),o=[],s=[],c=[];for(const n of e){const{depositorPubkey:a}=p.validateWalletPubkey(r,n.depositorBtcPubkey);c.push(a);const g=await u.buildPayoutPsbt({vaultCoreVersion:n.vaultCoreVersion,payoutTxHex:n.payoutTxHex,peginTxHex:n.peginTxHex,assertTxHex:n.assertTxHex,depositorBtcPubkey:a,vaultProviderBtcPubkey:n.vaultProviderBtcPubkey,vaultKeeperBtcPubkeys:n.vaultKeeperBtcPubkeys,universalChallengerBtcPubkeys:n.universalChallengerBtcPubkeys,timelockPegin:n.timelockPegin,timelockAssert:n.timelockAssert,network:this.config.network,claimerBtcPubkey:n.claimerBtcPubkey,registeredPayoutScriptPubKey:n.registeredPayoutScriptPubKey,commissionBps:n.commissionBps,protocolFeeRate:n.protocolFeeRate,councilMembers:n.councilMembers,councilQuorum:n.councilQuorum,vkClaimerPayoutScriptPubKeys:n.vkClaimerPayoutScriptPubKeys,vpCommissionScriptPubKey:n.vpCommissionScriptPubKey});o.push(g.psbtHex),s.push(d.createTaprootScriptPathSignOptions(r,y.DEPOSITOR_SIGNED_INPUT_COUNT))}const i=await this.config.btcWallet.signPsbts(o,s);if(i.length!==e.length)throw new Error(`Expected ${e.length} signed PSBTs but received ${i.length}`);const l=[];for(let n=0;n<e.length;n++){const a=c[n];u.assertPsbtUnsignedTxMatches({requestedPsbtHex:o[n],returnedPsbtHex:i[n]});const g=u.extractPayoutSignature(i[n],a);u.assertScriptPathSchnorrSignature({requestedPsbtHex:o[n],signatureHex:g,signerXOnlyPubkeyHex:a,inputIndex:x}),l.push({payoutSignature:g,depositorBtcPubkey:a})}return l}}async function I(t,e,r){if(e.length===1)return[await t.signPsbt(e[0],r==null?void 0:r[0])];if(typeof t.signPsbts=="function"){const s=await t.signPsbts(e,r);if(s.length!==e.length)throw new Error(`Expected ${e.length} signed PSBTs but received ${s.length}`);return s}const o=[];for(let s=0;s<e.length;s++)o.push(await t.signPsbt(e[s],r==null?void 0:r[s]));return o}exports.PayoutManager=U;exports.assertAuthAnchorOpReturn=R;exports.computeHashlock=m;exports.findAuthAnchorOpReturn=C;exports.forwardDepositApproval=D;exports.requireChangeAddress=$;exports.signPsbtsWithFallback=I;exports.supportsDepositApproval=w;exports.validateSecretAgainstHashlock=N;
|
|
2
|
+
//# sourceMappingURL=signPsbtsWithFallback-FwrTYZS4.cjs.map
|