@babylonlabs-io/ts-sdk 0.72.1 → 0.73.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 +56 -13
- package/dist/BTCVaultRegistryKeyEpochs.abi-CrQiTLfA.cjs +2 -0
- package/dist/BTCVaultRegistryKeyEpochs.abi-CrQiTLfA.cjs.map +1 -0
- package/dist/BTCVaultRegistryKeyEpochs.abi-D8cIbMtH.js +229 -0
- package/dist/BTCVaultRegistryKeyEpochs.abi-D8cIbMtH.js.map +1 -0
- package/dist/PeginManager-C9RPOd0L.js +1216 -0
- package/dist/PeginManager-C9RPOd0L.js.map +1 -0
- package/dist/PeginManager-E-UHA1un.cjs +2 -0
- package/dist/PeginManager-E-UHA1un.cjs.map +1 -0
- package/dist/bip322Verify-B7_gIhRk.cjs +2 -0
- package/dist/bip322Verify-B7_gIhRk.cjs.map +1 -0
- package/dist/bip322Verify-D6sBBUHE.js +79 -0
- package/dist/bip322Verify-D6sBBUHE.js.map +1 -0
- package/dist/{buildAndBroadcastReclaim-QIN8Mcwq.js → buildAndBroadcastReclaim-BXclIcu_.js} +3 -3
- package/dist/{buildAndBroadcastReclaim-QIN8Mcwq.js.map → buildAndBroadcastReclaim-BXclIcu_.js.map} +1 -1
- package/dist/{buildAndBroadcastReclaim-HX2xQlbM.cjs → buildAndBroadcastReclaim-U-PyFfDg.cjs} +2 -2
- package/dist/{buildAndBroadcastReclaim-HX2xQlbM.cjs.map → buildAndBroadcastReclaim-U-PyFfDg.cjs.map} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +209 -205
- package/dist/index.js.map +1 -1
- package/dist/onChainBtcPubkey-BbxRrbvg.cjs +2 -0
- package/dist/onChainBtcPubkey-BbxRrbvg.cjs.map +1 -0
- package/dist/onChainBtcPubkey-C-6UWpD8.js +34 -0
- package/dist/onChainBtcPubkey-C-6UWpD8.js.map +1 -0
- package/dist/{parseFundingOutpoints-BkgGihaY.cjs → parseFundingOutpoints-B4iQeX6q.cjs} +2 -2
- package/dist/{parseFundingOutpoints-BkgGihaY.cjs.map → parseFundingOutpoints-B4iQeX6q.cjs.map} +1 -1
- package/dist/{parseFundingOutpoints-DlINgQ3X.js → parseFundingOutpoints-B67CoXpF.js} +2 -2
- package/dist/{parseFundingOutpoints-DlINgQ3X.js.map → parseFundingOutpoints-B67CoXpF.js.map} +1 -1
- package/dist/pegin-registration-client-6vLk2itL.cjs +2 -0
- package/dist/pegin-registration-client-6vLk2itL.cjs.map +1 -0
- package/dist/pegin-registration-client-BdRiR8br.js +2635 -0
- package/dist/pegin-registration-client-BdRiR8br.js.map +1 -0
- package/dist/primeVpAuth-DBHohVKM.cjs +2 -0
- package/dist/primeVpAuth-DBHohVKM.cjs.map +1 -0
- package/dist/primeVpAuth-DvaD45q_.js +745 -0
- package/dist/primeVpAuth-DvaD45q_.js.map +1 -0
- package/dist/psbtInputFields-B3e05Xe6.js +171 -0
- package/dist/psbtInputFields-B3e05Xe6.js.map +1 -0
- package/dist/psbtInputFields-BIxBpPj2.cjs +2 -0
- package/dist/psbtInputFields-BIxBpPj2.cjs.map +1 -0
- package/dist/sha2-CrlWM5S8.js +312 -0
- package/dist/{sha2-BYVxyZzX.js.map → sha2-CrlWM5S8.js.map} +1 -1
- package/dist/sha2-DI0-0SHr.cjs +2 -0
- package/dist/{sha2-DsrLC4NM.cjs.map → sha2-DI0-0SHr.cjs.map} +1 -1
- package/dist/{signPsbtsWithFallback-CCFTzE0o.js → signPsbtsWithFallback-0VBALhjS.js} +2 -2
- package/dist/{signPsbtsWithFallback-CCFTzE0o.js.map → signPsbtsWithFallback-0VBALhjS.js.map} +1 -1
- package/dist/{signPsbtsWithFallback-CrkvpSJz.cjs → signPsbtsWithFallback-DMSpIQWH.cjs} +2 -2
- package/dist/{signPsbtsWithFallback-CrkvpSJz.cjs.map → signPsbtsWithFallback-DMSpIQWH.cjs.map} +1 -1
- package/dist/tbv/core/clients/eth/__tests__/eth-import-boundary.test.d.ts +2 -0
- package/dist/tbv/core/clients/eth/__tests__/eth-import-boundary.test.d.ts.map +1 -0
- package/dist/tbv/core/clients/eth/__tests__/onChainBtcPubkey.test.d.ts +2 -0
- package/dist/tbv/core/clients/eth/__tests__/onChainBtcPubkey.test.d.ts.map +1 -0
- package/dist/tbv/core/clients/eth/__tests__/payout-script.test.d.ts +2 -0
- package/dist/tbv/core/clients/eth/__tests__/payout-script.test.d.ts.map +1 -0
- package/dist/tbv/core/clients/eth/__tests__/pegin-registration-calldata.test.d.ts +2 -0
- package/dist/tbv/core/clients/eth/__tests__/pegin-registration-calldata.test.d.ts.map +1 -0
- package/dist/tbv/core/clients/eth/__tests__/pegin-registration-client.test.d.ts +2 -0
- package/dist/tbv/core/clients/eth/__tests__/pegin-registration-client.test.d.ts.map +1 -0
- package/dist/tbv/core/clients/eth/__tests__/pegin-transaction.test.d.ts +2 -0
- package/dist/tbv/core/clients/eth/__tests__/pegin-transaction.test.d.ts.map +1 -0
- package/dist/tbv/core/clients/eth/index.cjs +2 -0
- package/dist/tbv/core/clients/eth/index.cjs.map +1 -0
- package/dist/tbv/core/clients/eth/index.d.ts +4 -0
- package/dist/tbv/core/clients/eth/index.d.ts.map +1 -1
- package/dist/tbv/core/clients/eth/index.js +22 -0
- package/dist/tbv/core/clients/eth/index.js.map +1 -0
- package/dist/tbv/core/clients/eth/onChainBtcPubkey.d.ts.map +1 -1
- package/dist/tbv/core/clients/eth/payout-script.d.ts +4 -0
- package/dist/tbv/core/clients/eth/payout-script.d.ts.map +1 -0
- package/dist/tbv/core/clients/eth/pegin-registration-client.d.ts +99 -0
- package/dist/tbv/core/clients/eth/pegin-registration-client.d.ts.map +1 -0
- package/dist/tbv/core/clients/eth/pegin-transaction.d.ts +14 -0
- package/dist/tbv/core/clients/eth/pegin-transaction.d.ts.map +1 -0
- package/dist/tbv/core/clients/index.cjs +1 -1
- package/dist/tbv/core/clients/index.js +55 -48
- package/dist/tbv/core/clients/index.js.map +1 -1
- package/dist/tbv/core/clients/mempool/index.cjs +2 -0
- package/dist/tbv/core/clients/mempool/index.cjs.map +1 -0
- package/dist/tbv/core/clients/mempool/index.js +222 -0
- package/dist/tbv/core/clients/mempool/index.js.map +1 -0
- package/dist/tbv/core/contracts/index.cjs +1 -1
- package/dist/tbv/core/contracts/index.cjs.map +1 -1
- package/dist/tbv/core/contracts/index.js +491 -12
- package/dist/tbv/core/contracts/index.js.map +1 -1
- package/dist/tbv/core/index.cjs +1 -1
- package/dist/tbv/core/index.d.ts +1 -0
- package/dist/tbv/core/index.d.ts.map +1 -1
- package/dist/tbv/core/index.js +207 -203
- package/dist/tbv/core/index.js.map +1 -1
- package/dist/tbv/core/managers/PeginManager.d.ts +38 -30
- package/dist/tbv/core/managers/PeginManager.d.ts.map +1 -1
- package/dist/tbv/core/managers/index.cjs +1 -1
- package/dist/tbv/core/managers/index.d.ts +2 -1
- package/dist/tbv/core/managers/index.d.ts.map +1 -1
- package/dist/tbv/core/managers/index.js +2 -2
- package/dist/tbv/core/services/index.cjs +1 -1
- package/dist/tbv/core/services/index.js +2 -2
- package/dist/tbv/core/utils/eth/index.cjs +2 -0
- package/dist/tbv/core/utils/eth/index.cjs.map +1 -0
- package/dist/tbv/core/utils/eth/index.js +109 -0
- package/dist/tbv/core/utils/eth/index.js.map +1 -0
- package/dist/tbv/core/utils/index.cjs +1 -1
- package/dist/tbv/core/utils/index.js +41 -40
- package/dist/tbv/core/utils/index.js.map +1 -1
- package/dist/tbv/core/vault-secrets/index.cjs +1 -1
- package/dist/tbv/core/vault-secrets/index.js +1 -1
- package/dist/tbv/index.cjs +1 -1
- package/dist/tbv/index.js +207 -203
- package/dist/tbv/index.js.map +1 -1
- package/dist/testing/index.cjs +1 -1
- package/dist/testing/index.js +1 -1
- package/dist/{toRefundInputs-BG-qHCEu.js → toRefundInputs-BkcFhvDp.js} +5 -5
- package/dist/{toRefundInputs-BG-qHCEu.js.map → toRefundInputs-BkcFhvDp.js.map} +1 -1
- package/dist/{toRefundInputs-kVR-3EdD.cjs → toRefundInputs-CatCKniS.cjs} +2 -2
- package/dist/{toRefundInputs-kVR-3EdD.cjs.map → toRefundInputs-CatCKniS.cjs.map} +1 -1
- package/dist/types-CPDLZm3l.js +430 -0
- package/dist/types-CPDLZm3l.js.map +1 -0
- package/dist/types-DSlcXtog.cjs +2 -0
- package/dist/types-DSlcXtog.cjs.map +1 -0
- package/package.json +32 -3
- package/dist/BTCVaultRegistryKeyEpochs.abi-CXjhRZbm.js +0 -111
- package/dist/BTCVaultRegistryKeyEpochs.abi-CXjhRZbm.js.map +0 -1
- package/dist/BTCVaultRegistryKeyEpochs.abi-_NERAdc5.cjs +0 -2
- package/dist/BTCVaultRegistryKeyEpochs.abi-_NERAdc5.cjs.map +0 -1
- package/dist/PeginManager-Bwjqb0_6.cjs +0 -2
- package/dist/PeginManager-Bwjqb0_6.cjs.map +0 -1
- package/dist/PeginManager-DjatPUPS.js +0 -1503
- package/dist/PeginManager-DjatPUPS.js.map +0 -1
- package/dist/ProtocolParams.abi-C0TSRaHV.js +0 -486
- package/dist/ProtocolParams.abi-C0TSRaHV.js.map +0 -1
- package/dist/ProtocolParams.abi-CYZoV2EI.cjs +0 -2
- package/dist/ProtocolParams.abi-CYZoV2EI.cjs.map +0 -1
- package/dist/errors-Blc-JWnI.js +0 -121
- package/dist/errors-Blc-JWnI.js.map +0 -1
- package/dist/errors-CGcNP0rV.cjs +0 -2
- package/dist/errors-CGcNP0rV.cjs.map +0 -1
- package/dist/mempoolApi-BJvC9nPF.cjs +0 -2
- package/dist/mempoolApi-BJvC9nPF.cjs.map +0 -1
- package/dist/mempoolApi-_CoQH5vH.js +0 -612
- package/dist/mempoolApi-_CoQH5vH.js.map +0 -1
- package/dist/onChainBtcPubkey-B5ZvWCCF.cjs +0 -2
- package/dist/onChainBtcPubkey-B5ZvWCCF.cjs.map +0 -1
- package/dist/onChainBtcPubkey-DATNfAAl.js +0 -19
- package/dist/onChainBtcPubkey-DATNfAAl.js.map +0 -1
- package/dist/primeVpAuth-BI63kgdd.js +0 -1171
- package/dist/primeVpAuth-BI63kgdd.js.map +0 -1
- package/dist/primeVpAuth-D3xbar3j.cjs +0 -2
- package/dist/primeVpAuth-D3xbar3j.cjs.map +0 -1
- package/dist/sha2-BYVxyZzX.js +0 -274
- package/dist/sha2-DsrLC4NM.cjs +0 -2
- package/dist/waitForTransactionReceiptSmartAware-DpQ69ySe.cjs +0 -2
- package/dist/waitForTransactionReceiptSmartAware-DpQ69ySe.cjs.map +0 -1
- package/dist/waitForTransactionReceiptSmartAware-z3Xfmo44.js +0 -277
- package/dist/waitForTransactionReceiptSmartAware-z3Xfmo44.js.map +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";const l=require("./bitcoin-D-O2GjbC.cjs"),x=require("./sha2-
|
|
2
|
-
//# sourceMappingURL=parseFundingOutpoints-
|
|
1
|
+
"use strict";const l=require("./bitcoin-D-O2GjbC.cjs"),x=require("./sha2-DI0-0SHr.cjs"),y=require("bitcoinjs-lib"),b=require("buffer"),i=32,u=32,c=36,m=32,s=4,v=s+i+s+m;function a(t,n,r){t[n]=r>>>24&255,t[n+1]=r>>>16&255,t[n+2]=r>>>8&255,t[n+3]=r&255}function O(t){if(t.txid.length!==u)throw new Error(`outpoint.txid must be exactly ${u} bytes, got ${t.txid.length}`);if(!Number.isInteger(t.vout)||t.vout<0||t.vout>4294967295)throw new Error(`outpoint.vout must be a u32, got ${t.vout}`);const n=new Uint8Array(c);return n.set(t.txid,0),a(n,u,t.vout),n}function h(t,n){const r=Math.min(t.length,n.length);for(let e=0;e<r;e++)if(t[e]!==n[e])return t[e]-n[e];return t.length-n.length}function f(t){if(t.length===0)throw new Error("buildFundingOutpointsCommitment: outpoints must be non-empty");const n=t.map(O);n.sort(h);for(let e=1;e<n.length;e++)if(h(n[e-1],n[e])===0)throw new Error("buildFundingOutpointsCommitment: duplicate outpoint detected");const r=new Uint8Array(n.length*c);for(let e=0;e<n.length;e++)r.set(n[e],e*c);return x.sha256(r)}function E(t){if(t.depositorBtcPubkey.length!==i)throw new Error(`vaultContext: depositorBtcPubkey must be exactly ${i} bytes, got ${t.depositorBtcPubkey.length}`);const n=f(t.fundingOutpoints),r=new Uint8Array(v);let e=0;return a(r,e,i),e+=s,r.set(t.depositorBtcPubkey,e),e+=i,a(r,e,m),e+=s,r.set(n,e),r}const g="babylon-btc-vault",w=32,d=w*2,_=/^[0-9a-f]+$/;function T(t){const n=t.deriveContextHash;return typeof n=="function"?{deriveContextHash:(r,e)=>n.call(t,r,e)}:{}}async function p(t,n){const r=E(n),e=l.uint8ArrayToHex(r),o=await t.deriveContextHash(g,e);if(typeof o!="string")throw new Error(`deriveVaultRoot: wallet must return a string, got ${typeof o}`);if(o.length!==d)throw new Error(`deriveVaultRoot: wallet must return a ${d}-character hex string (${w} bytes), got length ${o.length}`);if(!_.test(o))throw new Error("deriveVaultRoot: wallet must return lowercase hex per derive-context-hash.md §2.1; got value with non-lowercase or non-hex characters");return l.hexToUint8Array(o)}function C(t){if(!t)throw new Error("Pre-pegin transaction hex is empty");const n=t.startsWith("0x")?t.slice(2):t,r=y.Transaction.fromHex(n);if(r.ins.length===0)throw new Error("Pre-pegin transaction has no inputs");return r.ins.map(e=>({txid:Uint8Array.from(b.Buffer.from(e.hash).reverse()),vout:e.index}))}exports.VAULT_APP_NAME=g;exports.buildFundingOutpointsCommitment=f;exports.buildVaultContext=E;exports.deriveVaultRoot=p;exports.forwardDeriveContextHash=T;exports.parseFundingOutpointsFromTx=C;
|
|
2
|
+
//# sourceMappingURL=parseFundingOutpoints-B4iQeX6q.cjs.map
|
package/dist/{parseFundingOutpoints-BkgGihaY.cjs.map → parseFundingOutpoints-B4iQeX6q.cjs.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseFundingOutpoints-BkgGihaY.cjs","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 per\n * `derive-vault-secrets.md` §2.3.\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 from `derive-vault-secrets.md`\n * §2.2:\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. Defined by `derive-vault-secrets.md` §2.2 — must not be\n * changed without coordinating a spec revision and 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 per spec §2.1. */\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 per `derive-context-hash.md` §2.1. 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 spec 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 fixed by `derive-vault-secrets.md` §2.2\n * and must never change without a coordinated spec revision.\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 lowercase hex per derive-context-hash.md §2.1; 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":"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"}
|
|
1
|
+
{"version":3,"file":"parseFundingOutpoints-B4iQeX6q.cjs","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 per\n * `derive-vault-secrets.md` §2.3.\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 from `derive-vault-secrets.md`\n * §2.2:\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. Defined by `derive-vault-secrets.md` §2.2 — must not be\n * changed without coordinating a spec revision and 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 per spec §2.1. */\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 per `derive-context-hash.md` §2.1. 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 spec 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 fixed by `derive-vault-secrets.md` §2.2\n * and must never change without a coordinated spec revision.\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 lowercase hex per derive-context-hash.md §2.1; 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":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { u as d, h as E } from "./bitcoin-C-TuHb-v.js";
|
|
2
|
-
import { s as w } from "./sha2-
|
|
2
|
+
import { s as w } from "./sha2-CrlWM5S8.js";
|
|
3
3
|
import { Transaction as g } from "bitcoinjs-lib";
|
|
4
4
|
import { Buffer as x } from "buffer";
|
|
5
5
|
const i = 32, a = 32, c = 36, m = 32, s = 4, y = s + i + s + m;
|
|
@@ -90,4 +90,4 @@ export {
|
|
|
90
90
|
I as f,
|
|
91
91
|
R as p
|
|
92
92
|
};
|
|
93
|
-
//# sourceMappingURL=parseFundingOutpoints-
|
|
93
|
+
//# sourceMappingURL=parseFundingOutpoints-B67CoXpF.js.map
|
package/dist/{parseFundingOutpoints-DlINgQ3X.js.map → parseFundingOutpoints-B67CoXpF.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseFundingOutpoints-DlINgQ3X.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 per\n * `derive-vault-secrets.md` §2.3.\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 from `derive-vault-secrets.md`\n * §2.2:\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. Defined by `derive-vault-secrets.md` §2.2 — must not be\n * changed without coordinating a spec revision and 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 per spec §2.1. */\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 per `derive-context-hash.md` §2.1. 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 spec 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 fixed by `derive-vault-secrets.md` §2.2\n * and must never change without a coordinated spec revision.\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 lowercase hex per derive-context-hash.md §2.1; 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":"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"}
|
|
1
|
+
{"version":3,"file":"parseFundingOutpoints-B67CoXpF.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 per\n * `derive-vault-secrets.md` §2.3.\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 from `derive-vault-secrets.md`\n * §2.2:\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. Defined by `derive-vault-secrets.md` §2.2 — must not be\n * changed without coordinating a spec revision and 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 per spec §2.1. */\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 per `derive-context-hash.md` §2.1. 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 spec 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 fixed by `derive-vault-secrets.md` §2.2\n * and must never change without a coordinated spec revision.\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 lowercase hex per derive-context-hash.md §2.1; 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":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var _n=Object.defineProperty;var Rn=(t,e,r)=>e in t?_n(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var ht=(t,e,r)=>Rn(t,typeof e!="symbol"?e+"":e,r);const it=require("viem"),D=require("./BTCVaultRegistry.abi-z7d_eP22.cjs"),xt=require("./BTCVaultRegistryKeyEpochs.abi-CrQiTLfA.cjs"),Rt=require("./constants-Bh38W9mq.cjs"),$n=require("./tbv/core/utils/eth/index.cjs"),Pt=require("./onChainBtcPubkey-BbxRrbvg.cjs"),K=require("./sha2-DI0-0SHr.cjs"),Nn=require("./vaultCoreVersion-DYfw3qed.cjs"),$t=25,Ue=9999;function ne(t){if(!Number.isInteger(t)||t<0||t>=Rt.MAX_VP_COMMISSION_BPS_EXCLUSIVE)throw new Error(`Quoted commissionBps must be an integer in [0, ${Rt.MAX_VP_COMMISSION_BPS_EXCLUSIVE}), got ${t}`);return Math.min(t+$t,Ue)}const kn=Uint8Array.from([7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8]),Ke=Uint8Array.from(new Array(16).fill(0).map((t,e)=>e)),Hn=Ke.map(t=>(9*t+5)%16),Me=(()=>{const r=[[Ke],[Hn]];for(let n=0;n<4;n++)for(let o of r)o.push(o[n].map(s=>kn[s]));return r})(),Le=Me[0],Fe=Me[1],De=[[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8],[12,13,11,15,6,9,9,7,12,15,11,13,7,8,7,7],[13,15,14,11,7,7,6,8,13,14,13,12,5,5,6,9],[14,11,12,14,8,6,5,5,15,12,15,14,9,9,8,6],[15,12,13,13,9,5,8,6,14,11,12,11,8,6,5,5]].map(t=>Uint8Array.from(t)),On=Le.map((t,e)=>t.map(r=>De[e][r])),qn=Fe.map((t,e)=>t.map(r=>De[e][r])),Un=Uint32Array.from([0,1518500249,1859775393,2400959708,2840853838]),Kn=Uint32Array.from([1352829926,1548603684,1836072691,2053994217,0]);function be(t,e,r,n){return t===0?e^r^n:t===1?e&r|~e&n:t===2?(e|~r)^n:t===3?e&n|r&~n:e^(r|~n)}const Tt=new Uint32Array(16);class Mn extends K.HashMD{constructor(){super(64,20,8,!0);ht(this,"h0",1732584193);ht(this,"h1",-271733879);ht(this,"h2",-1732584194);ht(this,"h3",271733878);ht(this,"h4",-1009589776)}get(){const{h0:r,h1:n,h2:o,h3:s,h4:i}=this;return[r,n,o,s,i]}set(r,n,o,s,i){this.h0=r|0,this.h1=n|0,this.h2=o|0,this.h3=s|0,this.h4=i|0}process(r,n){for(let h=0;h<16;h++,n+=4)Tt[h]=r.getUint32(n,!0);let o=this.h0|0,s=o,i=this.h1|0,a=i,u=this.h2|0,l=u,w=this.h3|0,m=w,c=this.h4|0,f=c;for(let h=0;h<5;h++){const y=4-h,A=Un[h],_=Kn[h],rt=Le[h],R=Fe[h],W=On[h],X=qn[h];for(let q=0;q<16;q++){const tt=K.rotl(o+be(h,i,u,w)+Tt[rt[q]]+A,W[q])+c|0;o=c,c=w,w=K.rotl(u,10)|0,u=i,i=tt}for(let q=0;q<16;q++){const tt=K.rotl(s+be(y,a,l,m)+Tt[R[q]]+_,X[q])+f|0;s=f,f=m,m=K.rotl(l,10)|0,l=a,a=tt}}this.set(this.h1+u+m|0,this.h2+w+f|0,this.h3+c+s|0,this.h4+o+a|0,this.h0+i+l|0)}roundClean(){K.clean(Tt)}destroy(){this.destroyed=!0,K.clean(this.buffer),this.set(0,0,0,0,0)}}const Ze=K.createHasher(()=>new Mn),gt=typeof globalThis=="object"&&"crypto"in globalThis?globalThis.crypto:void 0;function Lt(t){return t instanceof Uint8Array||ArrayBuffer.isView(t)&&t.constructor.name==="Uint8Array"}function re(t){if(!Number.isSafeInteger(t)||t<0)throw new Error("positive integer expected, got "+t)}function lt(t,...e){if(!Lt(t))throw new Error("Uint8Array expected");if(e.length>0&&!e.includes(t.length))throw new Error("Uint8Array expected of length "+e+", got length="+t.length)}function ze(t){if(typeof t!="function"||typeof t.create!="function")throw new Error("Hash should be wrapped by utils.createHasher");re(t.outputLen),re(t.blockLen)}function Nt(t,e=!0){if(t.destroyed)throw new Error("Hash instance has been destroyed");if(e&&t.finished)throw new Error("Hash#digest() has already been called")}function Ln(t,e){lt(t);const r=e.outputLen;if(t.length<r)throw new Error("digestInto() expects output buffer of length at least "+r)}function kt(...t){for(let e=0;e<t.length;e++)t[e].fill(0)}function zt(t){return new DataView(t.buffer,t.byteOffset,t.byteLength)}function Y(t,e){return t<<32-e|t>>>e}const Xe=typeof Uint8Array.from([]).toHex=="function"&&typeof Uint8Array.fromHex=="function",Fn=Array.from({length:256},(t,e)=>e.toString(16).padStart(2,"0"));function pt(t){if(lt(t),Xe)return t.toHex();let e="";for(let r=0;r<t.length;r++)e+=Fn[t[r]];return e}const G={_0:48,_9:57,A:65,F:70,a:97,f:102};function Ee(t){if(t>=G._0&&t<=G._9)return t-G._0;if(t>=G.A&&t<=G.F)return t-(G.A-10);if(t>=G.a&&t<=G.f)return t-(G.a-10)}function Ht(t){if(typeof t!="string")throw new Error("hex string expected, got "+typeof t);if(Xe)return Uint8Array.fromHex(t);const e=t.length,r=e/2;if(e%2)throw new Error("hex string expected, got unpadded hex of length "+e);const n=new Uint8Array(r);for(let o=0,s=0;o<r;o++,s+=2){const i=Ee(t.charCodeAt(s)),a=Ee(t.charCodeAt(s+1));if(i===void 0||a===void 0){const u=t[s]+t[s+1];throw new Error('hex string expected, got non-hex character "'+u+'" at index '+s)}n[o]=i*16+a}return n}function Ye(t){if(typeof t!="string")throw new Error("string expected");return new Uint8Array(new TextEncoder().encode(t))}function le(t){return typeof t=="string"&&(t=Ye(t)),lt(t),t}function j(...t){let e=0;for(let n=0;n<t.length;n++){const o=t[n];lt(o),e+=o.length}const r=new Uint8Array(e);for(let n=0,o=0;n<t.length;n++){const s=t[n];r.set(s,o),o+=s.length}return r}class je{}function Dn(t){const e=n=>t().update(le(n)).digest(),r=t();return e.outputLen=r.outputLen,e.blockLen=r.blockLen,e.create=()=>t(),e}function Ft(t=32){if(gt&&typeof gt.getRandomValues=="function")return gt.getRandomValues(new Uint8Array(t));if(gt&&typeof gt.randomBytes=="function")return Uint8Array.from(gt.randomBytes(t));throw new Error("crypto.getRandomValues must be defined")}function Zn(t,e,r,n){if(typeof t.setBigUint64=="function")return t.setBigUint64(e,r,n);const o=BigInt(32),s=BigInt(4294967295),i=Number(r>>o&s),a=Number(r&s),u=n?4:0,l=n?0:4;t.setUint32(e+u,i,n),t.setUint32(e+l,a,n)}function zn(t,e,r){return t&e^~t&r}function Xn(t,e,r){return t&e^t&r^e&r}class Yn extends je{constructor(e,r,n,o){super(),this.finished=!1,this.length=0,this.pos=0,this.destroyed=!1,this.blockLen=e,this.outputLen=r,this.padOffset=n,this.isLE=o,this.buffer=new Uint8Array(e),this.view=zt(this.buffer)}update(e){Nt(this),e=le(e),lt(e);const{view:r,buffer:n,blockLen:o}=this,s=e.length;for(let i=0;i<s;){const a=Math.min(o-this.pos,s-i);if(a===o){const u=zt(e);for(;o<=s-i;i+=o)this.process(u,i);continue}n.set(e.subarray(i,i+a),this.pos),this.pos+=a,i+=a,this.pos===o&&(this.process(r,0),this.pos=0)}return this.length+=e.length,this.roundClean(),this}digestInto(e){Nt(this),Ln(e,this),this.finished=!0;const{buffer:r,view:n,blockLen:o,isLE:s}=this;let{pos:i}=this;r[i++]=128,kt(this.buffer.subarray(i)),this.padOffset>o-i&&(this.process(n,0),i=0);for(let m=i;m<o;m++)r[m]=0;Zn(n,o-8,BigInt(this.length*8),s),this.process(n,0);const a=zt(e),u=this.outputLen;if(u%4)throw new Error("_sha2: outputLen should be aligned to 32bit");const l=u/4,w=this.get();if(l>w.length)throw new Error("_sha2: outputLen bigger than state");for(let m=0;m<l;m++)a.setUint32(4*m,w[m],s)}digest(){const{buffer:e,outputLen:r}=this;this.digestInto(e);const n=e.slice(0,r);return this.destroy(),n}_cloneInto(e){e||(e=new this.constructor),e.set(...this.get());const{blockLen:r,buffer:n,length:o,finished:s,destroyed:i,pos:a}=this;return e.destroyed=i,e.finished=s,e.length=o,e.pos=a,o%r&&e.buffer.set(n),e}clone(){return this._cloneInto()}}const et=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),jn=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),nt=new Uint32Array(64);class Wn extends Yn{constructor(e=32){super(64,e,8,!1),this.A=et[0]|0,this.B=et[1]|0,this.C=et[2]|0,this.D=et[3]|0,this.E=et[4]|0,this.F=et[5]|0,this.G=et[6]|0,this.H=et[7]|0}get(){const{A:e,B:r,C:n,D:o,E:s,F:i,G:a,H:u}=this;return[e,r,n,o,s,i,a,u]}set(e,r,n,o,s,i,a,u){this.A=e|0,this.B=r|0,this.C=n|0,this.D=o|0,this.E=s|0,this.F=i|0,this.G=a|0,this.H=u|0}process(e,r){for(let m=0;m<16;m++,r+=4)nt[m]=e.getUint32(r,!1);for(let m=16;m<64;m++){const c=nt[m-15],f=nt[m-2],h=Y(c,7)^Y(c,18)^c>>>3,y=Y(f,17)^Y(f,19)^f>>>10;nt[m]=y+nt[m-7]+h+nt[m-16]|0}let{A:n,B:o,C:s,D:i,E:a,F:u,G:l,H:w}=this;for(let m=0;m<64;m++){const c=Y(a,6)^Y(a,11)^Y(a,25),f=w+c+zn(a,u,l)+jn[m]+nt[m]|0,y=(Y(n,2)^Y(n,13)^Y(n,22))+Xn(n,o,s)|0;w=l,l=u,u=a,a=i+f|0,i=s,s=o,o=n,n=f+y|0}n=n+this.A|0,o=o+this.B|0,s=s+this.C|0,i=i+this.D|0,a=a+this.E|0,u=u+this.F|0,l=l+this.G|0,w=w+this.H|0,this.set(n,o,s,i,a,u,l,w)}roundClean(){kt(nt)}destroy(){this.set(0,0,0,0,0,0,0,0),kt(this.buffer)}}const oe=Dn(()=>new Wn);class We extends je{constructor(e,r){super(),this.finished=!1,this.destroyed=!1,ze(e);const n=le(r);if(this.iHash=e.create(),typeof this.iHash.update!="function")throw new Error("Expected instance of class which extends utils.Hash");this.blockLen=this.iHash.blockLen,this.outputLen=this.iHash.outputLen;const o=this.blockLen,s=new Uint8Array(o);s.set(n.length>o?e.create().update(n).digest():n);for(let i=0;i<s.length;i++)s[i]^=54;this.iHash.update(s),this.oHash=e.create();for(let i=0;i<s.length;i++)s[i]^=106;this.oHash.update(s),kt(s)}update(e){return Nt(this),this.iHash.update(e),this}digestInto(e){Nt(this),lt(e,this.outputLen),this.finished=!0,this.iHash.digestInto(e),this.oHash.update(e),this.oHash.digestInto(e),this.destroy()}digest(){const e=new Uint8Array(this.oHash.outputLen);return this.digestInto(e),e}_cloneInto(e){e||(e=Object.create(Object.getPrototypeOf(this),{}));const{oHash:r,iHash:n,finished:o,destroyed:s,blockLen:i,outputLen:a}=this;return e=e,e.finished=o,e.destroyed=s,e.blockLen=i,e.outputLen=a,e.oHash=r._cloneInto(e.oHash),e.iHash=n._cloneInto(e.iHash),e}clone(){return this._cloneInto()}destroy(){this.destroyed=!0,this.oHash.destroy(),this.iHash.destroy()}}const Ge=(t,e,r)=>new We(t,e).update(r).digest();Ge.create=(t,e)=>new We(t,e);const de=BigInt(0),se=BigInt(1);function Ot(t,e=""){if(typeof t!="boolean"){const r=e&&`"${e}"`;throw new Error(r+"expected boolean, got type="+typeof t)}return t}function ct(t,e,r=""){const n=Lt(t),o=t==null?void 0:t.length,s=e!==void 0;if(!n||s&&o!==e){const i=r&&`"${r}" `,a=s?` of length ${e}`:"",u=n?`length=${o}`:`type=${typeof t}`;throw new Error(i+"expected Uint8Array"+a+", got "+u)}return t}function Vt(t){const e=t.toString(16);return e.length&1?"0"+e:e}function Qe(t){if(typeof t!="string")throw new Error("hex string expected, got "+typeof t);return t===""?de:BigInt("0x"+t)}function bt(t){return Qe(pt(t))}function Je(t){return lt(t),Qe(pt(Uint8Array.from(t).reverse()))}function Dt(t,e){return Ht(t.toString(16).padStart(e*2,"0"))}function tn(t,e){return Dt(t,e).reverse()}function O(t,e,r){let n;if(typeof e=="string")try{n=Ht(e)}catch(s){throw new Error(t+" must be hex string or Uint8Array, cause: "+s)}else if(Lt(e))n=Uint8Array.from(e);else throw new Error(t+" must be hex string or Uint8Array");const o=n.length;if(typeof r=="number"&&o!==r)throw new Error(t+" of length "+r+" expected, got "+o);return n}const Xt=t=>typeof t=="bigint"&&de<=t;function ie(t,e,r){return Xt(t)&&Xt(e)&&Xt(r)&&e<=t&&t<r}function Gn(t,e,r,n){if(!ie(e,r,n))throw new Error("expected valid "+t+": "+r+" <= n < "+n+", got "+e)}function en(t){let e;for(e=0;t>de;t>>=se,e+=1);return e}const It=t=>(se<<BigInt(t))-se;function Qn(t,e,r){if(typeof t!="number"||t<2)throw new Error("hashLen must be a number");if(typeof e!="number"||e<2)throw new Error("qByteLen must be a number");if(typeof r!="function")throw new Error("hmacFn must be a function");const n=f=>new Uint8Array(f),o=f=>Uint8Array.of(f);let s=n(t),i=n(t),a=0;const u=()=>{s.fill(1),i.fill(0),a=0},l=(...f)=>r(i,s,...f),w=(f=n(0))=>{i=l(o(0),f),s=l(),f.length!==0&&(i=l(o(1),f),s=l())},m=()=>{if(a++>=1e3)throw new Error("drbg: tried 1000 values");let f=0;const h=[];for(;f<e;){s=l();const y=s.slice();h.push(y),f+=s.length}return j(...h)};return(f,h)=>{u(),w(f);let y;for(;!(y=h(m()));)w();return u(),y}}function he(t,e,r={}){if(!t||typeof t!="object")throw new Error("expected valid options object");function n(o,s,i){const a=t[o];if(i&&a===void 0)return;const u=typeof a;if(u!==s||a===null)throw new Error(`param "${o}" is invalid: expected ${s}, got ${u}`)}Object.entries(e).forEach(([o,s])=>n(o,s,!1)),Object.entries(r).forEach(([o,s])=>n(o,s,!0))}function Be(t){const e=new WeakMap;return(r,...n)=>{const o=e.get(r);if(o!==void 0)return o;const s=t(r,...n);return e.set(r,s),s}}const F=BigInt(0),M=BigInt(1),at=BigInt(2),nn=BigInt(3),rn=BigInt(4),on=BigInt(5),Jn=BigInt(7),sn=BigInt(8),tr=BigInt(9),cn=BigInt(16);function z(t,e){const r=t%e;return r>=F?r:e+r}function Z(t,e,r){let n=t;for(;e-- >F;)n*=n,n%=r;return n}function xe(t,e){if(t===F)throw new Error("invert: expected non-zero number");if(e<=F)throw new Error("invert: expected positive modulus, got "+e);let r=z(t,e),n=e,o=F,s=M;for(;r!==F;){const a=n/r,u=n%r,l=o-s*a;n=r,r=u,o=s,s=l}if(n!==M)throw new Error("invert: does not exist");return z(o,e)}function ge(t,e,r){if(!t.eql(t.sqr(e),r))throw new Error("Cannot find square root")}function an(t,e){const r=(t.ORDER+M)/rn,n=t.pow(e,r);return ge(t,n,e),n}function er(t,e){const r=(t.ORDER-on)/sn,n=t.mul(e,at),o=t.pow(n,r),s=t.mul(e,o),i=t.mul(t.mul(s,at),o),a=t.mul(s,t.sub(i,t.ONE));return ge(t,a,e),a}function nr(t){const e=At(t),r=un(t),n=r(e,e.neg(e.ONE)),o=r(e,n),s=r(e,e.neg(n)),i=(t+Jn)/cn;return(a,u)=>{let l=a.pow(u,i),w=a.mul(l,n);const m=a.mul(l,o),c=a.mul(l,s),f=a.eql(a.sqr(w),u),h=a.eql(a.sqr(m),u);l=a.cmov(l,w,f),w=a.cmov(c,m,h);const y=a.eql(a.sqr(w),u),A=a.cmov(l,w,y);return ge(a,A,u),A}}function un(t){if(t<nn)throw new Error("sqrt is not defined for small field");let e=t-M,r=0;for(;e%at===F;)e/=at,r++;let n=at;const o=At(t);for(;ve(o,n)===1;)if(n++>1e3)throw new Error("Cannot find square root: probably non-prime P");if(r===1)return an;let s=o.pow(n,e);const i=(e+M)/at;return function(u,l){if(u.is0(l))return l;if(ve(u,l)!==1)throw new Error("Cannot find square root");let w=r,m=u.mul(u.ONE,s),c=u.pow(l,e),f=u.pow(l,i);for(;!u.eql(c,u.ONE);){if(u.is0(c))return u.ZERO;let h=1,y=u.sqr(c);for(;!u.eql(y,u.ONE);)if(h++,y=u.sqr(y),h===w)throw new Error("Cannot find square root");const A=M<<BigInt(w-h-1),_=u.pow(m,A);w=h,m=u.sqr(_),c=u.mul(c,m),f=u.mul(f,_)}return f}}function rr(t){return t%rn===nn?an:t%sn===on?er:t%cn===tr?nr(t):un(t)}const or=["create","isValid","is0","neg","inv","sqrt","sqr","eql","add","sub","mul","pow","div","addN","subN","mulN","sqrN"];function sr(t){const e={ORDER:"bigint",MASK:"bigint",BYTES:"number",BITS:"number"},r=or.reduce((n,o)=>(n[o]="function",n),e);return he(t,r),t}function ir(t,e,r){if(r<F)throw new Error("invalid exponent, negatives unsupported");if(r===F)return t.ONE;if(r===M)return e;let n=t.ONE,o=e;for(;r>F;)r&M&&(n=t.mul(n,o)),o=t.sqr(o),r>>=M;return n}function fn(t,e,r=!1){const n=new Array(e.length).fill(r?t.ZERO:void 0),o=e.reduce((i,a,u)=>t.is0(a)?i:(n[u]=i,t.mul(i,a)),t.ONE),s=t.inv(o);return e.reduceRight((i,a,u)=>t.is0(a)?i:(n[u]=t.mul(i,n[u]),t.mul(i,a)),s),n}function ve(t,e){const r=(t.ORDER-M)/at,n=t.pow(e,r),o=t.eql(n,t.ONE),s=t.eql(n,t.ZERO),i=t.eql(n,t.neg(t.ONE));if(!o&&!s&&!i)throw new Error("invalid Legendre symbol result");return o?1:s?0:-1}function ln(t,e){e!==void 0&&re(e);const r=e!==void 0?e:t.toString(2).length,n=Math.ceil(r/8);return{nBitLength:r,nByteLength:n}}function At(t,e,r=!1,n={}){if(t<=F)throw new Error("invalid field: expected ORDER > 0, got "+t);let o,s,i=!1,a;if(typeof e=="object"&&e!=null){if(n.sqrt||r)throw new Error("cannot specify opts in two arguments");const c=e;c.BITS&&(o=c.BITS),c.sqrt&&(s=c.sqrt),typeof c.isLE=="boolean"&&(r=c.isLE),typeof c.modFromBytes=="boolean"&&(i=c.modFromBytes),a=c.allowedLengths}else typeof e=="number"&&(o=e),n.sqrt&&(s=n.sqrt);const{nBitLength:u,nByteLength:l}=ln(t,o);if(l>2048)throw new Error("invalid field: expected ORDER of <= 2048 bytes");let w;const m=Object.freeze({ORDER:t,isLE:r,BITS:u,BYTES:l,MASK:It(u),ZERO:F,ONE:M,allowedLengths:a,create:c=>z(c,t),isValid:c=>{if(typeof c!="bigint")throw new Error("invalid field element: expected bigint, got "+typeof c);return F<=c&&c<t},is0:c=>c===F,isValidNot0:c=>!m.is0(c)&&m.isValid(c),isOdd:c=>(c&M)===M,neg:c=>z(-c,t),eql:(c,f)=>c===f,sqr:c=>z(c*c,t),add:(c,f)=>z(c+f,t),sub:(c,f)=>z(c-f,t),mul:(c,f)=>z(c*f,t),pow:(c,f)=>ir(m,c,f),div:(c,f)=>z(c*xe(f,t),t),sqrN:c=>c*c,addN:(c,f)=>c+f,subN:(c,f)=>c-f,mulN:(c,f)=>c*f,inv:c=>xe(c,t),sqrt:s||(c=>(w||(w=rr(t)),w(m,c))),toBytes:c=>r?tn(c,l):Dt(c,l),fromBytes:(c,f=!0)=>{if(a){if(!a.includes(c.length)||c.length>l)throw new Error("Field.fromBytes: expected "+a+" bytes, got "+c.length);const y=new Uint8Array(l);y.set(c,r?0:y.length-c.length),c=y}if(c.length!==l)throw new Error("Field.fromBytes: expected "+l+" bytes, got "+c.length);let h=r?Je(c):bt(c);if(i&&(h=z(h,t)),!f&&!m.isValid(h))throw new Error("invalid field element: outside of range 0..ORDER");return h},invertBatch:c=>fn(m,c),cmov:(c,f,h)=>h?f:c});return Object.freeze(m)}function dn(t){if(typeof t!="bigint")throw new Error("field order must be bigint");const e=t.toString(2).length;return Math.ceil(e/8)}function hn(t){const e=dn(t);return e+Math.ceil(e/2)}function gn(t,e,r=!1){const n=t.length,o=dn(e),s=hn(e);if(n<16||n<s||n>1024)throw new Error("expected "+s+"-1024 bytes of input, got "+n);const i=r?Je(t):bt(t),a=z(i,e-M)+M;return r?tn(a,o):Dt(a,o)}const yt=BigInt(0),ut=BigInt(1);function qt(t,e){const r=e.negate();return t?r:e}function Yt(t,e){const r=fn(t.Fp,e.map(n=>n.Z));return e.map((n,o)=>t.fromAffine(n.toAffine(r[o])))}function pn(t,e){if(!Number.isSafeInteger(t)||t<=0||t>e)throw new Error("invalid window size, expected [1.."+e+"], got W="+t)}function jt(t,e){pn(t,e);const r=Math.ceil(e/t)+1,n=2**(t-1),o=2**t,s=It(t),i=BigInt(t);return{windows:r,windowSize:n,mask:s,maxNumber:o,shiftBy:i}}function Pe(t,e,r){const{windowSize:n,mask:o,maxNumber:s,shiftBy:i}=r;let a=Number(t&o),u=t>>i;a>n&&(a-=s,u+=ut);const l=e*n,w=l+Math.abs(a)-1,m=a===0,c=a<0,f=e%2!==0;return{nextN:u,offset:w,isZero:m,isNeg:c,isNegF:f,offsetF:l}}function cr(t,e){if(!Array.isArray(t))throw new Error("array expected");t.forEach((r,n)=>{if(!(r instanceof e))throw new Error("invalid point at index "+n)})}function ar(t,e){if(!Array.isArray(t))throw new Error("array of scalars expected");t.forEach((r,n)=>{if(!e.isValid(r))throw new Error("invalid scalar at index "+n)})}const Wt=new WeakMap,wn=new WeakMap;function Gt(t){return wn.get(t)||1}function Ie(t){if(t!==yt)throw new Error("invalid wNAF")}class ur{constructor(e,r){this.BASE=e.BASE,this.ZERO=e.ZERO,this.Fn=e.Fn,this.bits=r}_unsafeLadder(e,r,n=this.ZERO){let o=e;for(;r>yt;)r&ut&&(n=n.add(o)),o=o.double(),r>>=ut;return n}precomputeWindow(e,r){const{windows:n,windowSize:o}=jt(r,this.bits),s=[];let i=e,a=i;for(let u=0;u<n;u++){a=i,s.push(a);for(let l=1;l<o;l++)a=a.add(i),s.push(a);i=a.double()}return s}wNAF(e,r,n){if(!this.Fn.isValid(n))throw new Error("invalid scalar");let o=this.ZERO,s=this.BASE;const i=jt(e,this.bits);for(let a=0;a<i.windows;a++){const{nextN:u,offset:l,isZero:w,isNeg:m,isNegF:c,offsetF:f}=Pe(n,a,i);n=u,w?s=s.add(qt(c,r[f])):o=o.add(qt(m,r[l]))}return Ie(n),{p:o,f:s}}wNAFUnsafe(e,r,n,o=this.ZERO){const s=jt(e,this.bits);for(let i=0;i<s.windows&&n!==yt;i++){const{nextN:a,offset:u,isZero:l,isNeg:w}=Pe(n,i,s);if(n=a,!l){const m=r[u];o=o.add(w?m.negate():m)}}return Ie(n),o}getPrecomputes(e,r,n){let o=Wt.get(r);return o||(o=this.precomputeWindow(r,e),e!==1&&(typeof n=="function"&&(o=n(o)),Wt.set(r,o))),o}cached(e,r,n){const o=Gt(e);return this.wNAF(o,this.getPrecomputes(o,e,n),r)}unsafe(e,r,n,o){const s=Gt(e);return s===1?this._unsafeLadder(e,r,o):this.wNAFUnsafe(s,this.getPrecomputes(s,e,n),r,o)}createCache(e,r){pn(r,this.bits),wn.set(e,r),Wt.delete(e)}hasCache(e){return Gt(e)!==1}}function fr(t,e,r,n){let o=e,s=t.ZERO,i=t.ZERO;for(;r>yt||n>yt;)r&ut&&(s=s.add(o)),n&ut&&(i=i.add(o)),o=o.double(),r>>=ut,n>>=ut;return{p1:s,p2:i}}function lr(t,e,r,n){cr(r,t),ar(n,e);const o=r.length,s=n.length;if(o!==s)throw new Error("arrays of points and scalars must have equal length");const i=t.ZERO,a=en(BigInt(o));let u=1;a>12?u=a-3:a>4?u=a-2:a>0&&(u=2);const l=It(u),w=new Array(Number(l)+1).fill(i),m=Math.floor((e.BITS-1)/u)*u;let c=i;for(let f=m;f>=0;f-=u){w.fill(i);for(let y=0;y<s;y++){const A=n[y],_=Number(A>>BigInt(f)&l);w[_]=w[_].add(r[y])}let h=i;for(let y=w.length-1,A=i;y>0;y--)A=A.add(w[y]),h=h.add(A);if(c=c.add(h),f!==0)for(let y=0;y<u;y++)c=c.double()}return c}function Ae(t,e,r){if(e){if(e.ORDER!==t)throw new Error("Field.ORDER must match order: Fp == p, Fn == n");return sr(e),e}else return At(t,{isLE:r})}function dr(t,e,r={},n){if(n===void 0&&(n=t==="edwards"),!e||typeof e!="object")throw new Error(`expected valid ${t} CURVE object`);for(const u of["p","n","h"]){const l=e[u];if(!(typeof l=="bigint"&&l>yt))throw new Error(`CURVE.${u} must be positive bigint`)}const o=Ae(e.p,r.Fp,n),s=Ae(e.n,r.Fn,n),a=["Gx","Gy","a","b"];for(const u of a)if(!o.isValid(e[u]))throw new Error(`CURVE.${u} must be valid field element of CURVE.Fp`);return e=Object.freeze(Object.assign({},e)),{CURVE:e,Fp:o,Fn:s}}const Se=(t,e)=>(t+(t>=0?e:-e)/yn)/e;function hr(t,e,r){const[[n,o],[s,i]]=e,a=Se(i*t,r),u=Se(-o*t,r);let l=t-a*n-u*s,w=-a*o-u*i;const m=l<J,c=w<J;m&&(l=-l),c&&(w=-w);const f=It(Math.ceil(en(r)/2))+wt;if(l<J||l>=f||w<J||w>=f)throw new Error("splitScalar (endomorphism): failed, k="+t);return{k1neg:m,k1:l,k2neg:c,k2:w}}function ce(t){if(!["compact","recovered","der"].includes(t))throw new Error('Signature format must be "compact", "recovered", or "der"');return t}function Qt(t,e){const r={};for(let n of Object.keys(e))r[n]=t[n]===void 0?e[n]:t[n];return Ot(r.lowS,"lowS"),Ot(r.prehash,"prehash"),r.format!==void 0&&ce(r.format),r}class gr extends Error{constructor(e=""){super(e)}}const Q={Err:gr,_tlv:{encode:(t,e)=>{const{Err:r}=Q;if(t<0||t>256)throw new r("tlv.encode: wrong tag");if(e.length&1)throw new r("tlv.encode: unpadded data");const n=e.length/2,o=Vt(n);if(o.length/2&128)throw new r("tlv.encode: long form length too big");const s=n>127?Vt(o.length/2|128):"";return Vt(t)+s+o+e},decode(t,e){const{Err:r}=Q;let n=0;if(t<0||t>256)throw new r("tlv.encode: wrong tag");if(e.length<2||e[n++]!==t)throw new r("tlv.decode: wrong tlv");const o=e[n++],s=!!(o&128);let i=0;if(!s)i=o;else{const u=o&127;if(!u)throw new r("tlv.decode(long): indefinite length not supported");if(u>4)throw new r("tlv.decode(long): byte length is too big");const l=e.subarray(n,n+u);if(l.length!==u)throw new r("tlv.decode: length bytes not complete");if(l[0]===0)throw new r("tlv.decode(long): zero leftmost byte");for(const w of l)i=i<<8|w;if(n+=u,i<128)throw new r("tlv.decode(long): not minimal encoding")}const a=e.subarray(n,n+i);if(a.length!==i)throw new r("tlv.decode: wrong value length");return{v:a,l:e.subarray(n+i)}}},_int:{encode(t){const{Err:e}=Q;if(t<J)throw new e("integer: negative integers are not allowed");let r=Vt(t);if(Number.parseInt(r[0],16)&8&&(r="00"+r),r.length&1)throw new e("unexpected DER parsing assertion: unpadded hex");return r},decode(t){const{Err:e}=Q;if(t[0]&128)throw new e("invalid signature integer: negative");if(t[0]===0&&!(t[1]&128))throw new e("invalid signature integer: unnecessary leading zero");return bt(t)}},toSig(t){const{Err:e,_int:r,_tlv:n}=Q,o=O("signature",t),{v:s,l:i}=n.decode(48,o);if(i.length)throw new e("invalid signature: left bytes after parsing");const{v:a,l:u}=n.decode(2,s),{v:l,l:w}=n.decode(2,u);if(w.length)throw new e("invalid signature: left bytes after parsing");return{r:r.decode(a),s:r.decode(l)}},hexFromSig(t){const{_tlv:e,_int:r}=Q,n=e.encode(2,r.encode(t.r)),o=e.encode(2,r.encode(t.s)),s=n+o;return e.encode(48,s)}},J=BigInt(0),wt=BigInt(1),yn=BigInt(2),_t=BigInt(3),pr=BigInt(4);function ft(t,e){const{BYTES:r}=t;let n;if(typeof e=="bigint")n=e;else{let o=O("private key",e);try{n=t.fromBytes(o)}catch{throw new Error(`invalid private key: expected ui8a of size ${r}, got ${typeof e}`)}}if(!t.isValidNot0(n))throw new Error("invalid private key: out of range [1..N-1]");return n}function wr(t,e={}){const r=dr("weierstrass",t,e),{Fp:n,Fn:o}=r;let s=r.CURVE;const{h:i,n:a}=s;he(e,{},{allowInfinityPoint:"boolean",clearCofactor:"function",isTorsionFree:"function",fromBytes:"function",toBytes:"function",endo:"object",wrapPrivateKey:"boolean"});const{endo:u}=e;if(u&&(!n.is0(s.a)||typeof u.beta!="bigint"||!Array.isArray(u.basises)))throw new Error('invalid endo: expected "beta": bigint and "basises": array');const l=bn(n,o);function w(){if(!n.isOdd)throw new Error("compression is not supported: Field does not have .isOdd()")}function m(T,p,g){const{x:d,y:b}=p.toAffine(),E=n.toBytes(d);if(Ot(g,"isCompressed"),g){w();const v=!n.isOdd(b);return j(mn(v),E)}else return j(Uint8Array.of(4),E,n.toBytes(b))}function c(T){ct(T,void 0,"Point");const{publicKey:p,publicKeyUncompressed:g}=l,d=T.length,b=T[0],E=T.subarray(1);if(d===p&&(b===2||b===3)){const v=n.fromBytes(E);if(!n.isValid(v))throw new Error("bad point: is not on curve, wrong x");const x=y(v);let B;try{B=n.sqrt(x)}catch(k){const V=k instanceof Error?": "+k.message:"";throw new Error("bad point: is not on curve, sqrt error"+V)}w();const P=n.isOdd(B);return(b&1)===1!==P&&(B=n.neg(B)),{x:v,y:B}}else if(d===g&&b===4){const v=n.BYTES,x=n.fromBytes(E.subarray(0,v)),B=n.fromBytes(E.subarray(v,v*2));if(!A(x,B))throw new Error("bad point: is not on curve");return{x,y:B}}else throw new Error(`bad point: got length ${d}, expected compressed=${p} or uncompressed=${g}`)}const f=e.toBytes||m,h=e.fromBytes||c;function y(T){const p=n.sqr(T),g=n.mul(p,T);return n.add(n.add(g,n.mul(T,s.a)),s.b)}function A(T,p){const g=n.sqr(p),d=y(T);return n.eql(g,d)}if(!A(s.Gx,s.Gy))throw new Error("bad curve params: generator point");const _=n.mul(n.pow(s.a,_t),pr),rt=n.mul(n.sqr(s.b),BigInt(27));if(n.is0(n.add(_,rt)))throw new Error("bad curve params: a or b");function R(T,p,g=!1){if(!n.isValid(p)||g&&n.is0(p))throw new Error(`bad point coordinate ${T}`);return p}function W(T){if(!(T instanceof S))throw new Error("ProjectivePoint expected")}function X(T){if(!u||!u.basises)throw new Error("no endo");return hr(T,u.basises,o.ORDER)}const q=Be((T,p)=>{const{X:g,Y:d,Z:b}=T;if(n.eql(b,n.ONE))return{x:g,y:d};const E=T.is0();p==null&&(p=E?n.ONE:n.inv(b));const v=n.mul(g,p),x=n.mul(d,p),B=n.mul(b,p);if(E)return{x:n.ZERO,y:n.ZERO};if(!n.eql(B,n.ONE))throw new Error("invZ was invalid");return{x:v,y:x}}),tt=Be(T=>{if(T.is0()){if(e.allowInfinityPoint&&!n.is0(T.Y))return;throw new Error("bad point: ZERO")}const{x:p,y:g}=T.toAffine();if(!n.isValid(p)||!n.isValid(g))throw new Error("bad point: x or y not field elements");if(!A(p,g))throw new Error("bad point: equation left != right");if(!T.isTorsionFree())throw new Error("bad point: not in prime-order subgroup");return!0});function dt(T,p,g,d,b){return g=new S(n.mul(g.X,T),g.Y,g.Z),p=qt(d,p),g=qt(b,g),p.add(g)}class S{constructor(p,g,d){this.X=R("x",p),this.Y=R("y",g,!0),this.Z=R("z",d),Object.freeze(this)}static CURVE(){return s}static fromAffine(p){const{x:g,y:d}=p||{};if(!p||!n.isValid(g)||!n.isValid(d))throw new Error("invalid affine point");if(p instanceof S)throw new Error("projective point not allowed");return n.is0(g)&&n.is0(d)?S.ZERO:new S(g,d,n.ONE)}static fromBytes(p){const g=S.fromAffine(h(ct(p,void 0,"point")));return g.assertValidity(),g}static fromHex(p){return S.fromBytes(O("pointHex",p))}get x(){return this.toAffine().x}get y(){return this.toAffine().y}precompute(p=8,g=!0){return ot.createCache(this,p),g||this.multiply(_t),this}assertValidity(){tt(this)}hasEvenY(){const{y:p}=this.toAffine();if(!n.isOdd)throw new Error("Field doesn't support isOdd");return!n.isOdd(p)}equals(p){W(p);const{X:g,Y:d,Z:b}=this,{X:E,Y:v,Z:x}=p,B=n.eql(n.mul(g,x),n.mul(E,b)),P=n.eql(n.mul(d,x),n.mul(v,b));return B&&P}negate(){return new S(this.X,n.neg(this.Y),this.Z)}double(){const{a:p,b:g}=s,d=n.mul(g,_t),{X:b,Y:E,Z:v}=this;let x=n.ZERO,B=n.ZERO,P=n.ZERO,I=n.mul(b,b),k=n.mul(E,E),V=n.mul(v,v),C=n.mul(b,E);return C=n.add(C,C),P=n.mul(b,v),P=n.add(P,P),x=n.mul(p,P),B=n.mul(d,V),B=n.add(x,B),x=n.sub(k,B),B=n.add(k,B),B=n.mul(x,B),x=n.mul(C,x),P=n.mul(d,P),V=n.mul(p,V),C=n.sub(I,V),C=n.mul(p,C),C=n.add(C,P),P=n.add(I,I),I=n.add(P,I),I=n.add(I,V),I=n.mul(I,C),B=n.add(B,I),V=n.mul(E,v),V=n.add(V,V),I=n.mul(V,C),x=n.sub(x,I),P=n.mul(V,k),P=n.add(P,P),P=n.add(P,P),new S(x,B,P)}add(p){W(p);const{X:g,Y:d,Z:b}=this,{X:E,Y:v,Z:x}=p;let B=n.ZERO,P=n.ZERO,I=n.ZERO;const k=s.a,V=n.mul(s.b,_t);let C=n.mul(g,E),$=n.mul(d,v),H=n.mul(b,x),L=n.add(g,d),N=n.add(E,v);L=n.mul(L,N),N=n.add(C,$),L=n.sub(L,N),N=n.add(g,b);let U=n.add(E,x);return N=n.mul(N,U),U=n.add(C,H),N=n.sub(N,U),U=n.add(d,b),B=n.add(v,x),U=n.mul(U,B),B=n.add($,H),U=n.sub(U,B),I=n.mul(k,N),B=n.mul(V,H),I=n.add(B,I),B=n.sub($,I),I=n.add($,I),P=n.mul(B,I),$=n.add(C,C),$=n.add($,C),H=n.mul(k,H),N=n.mul(V,N),$=n.add($,H),H=n.sub(C,H),H=n.mul(k,H),N=n.add(N,H),C=n.mul($,N),P=n.add(P,C),C=n.mul(U,N),B=n.mul(L,B),B=n.sub(B,C),C=n.mul(L,$),I=n.mul(U,I),I=n.add(I,C),new S(B,P,I)}subtract(p){return this.add(p.negate())}is0(){return this.equals(S.ZERO)}multiply(p){const{endo:g}=e;if(!o.isValidNot0(p))throw new Error("invalid scalar: out of range");let d,b;const E=v=>ot.cached(this,v,x=>Yt(S,x));if(g){const{k1neg:v,k1:x,k2neg:B,k2:P}=X(p),{p:I,f:k}=E(x),{p:V,f:C}=E(P);b=k.add(C),d=dt(g.beta,I,V,v,B)}else{const{p:v,f:x}=E(p);d=v,b=x}return Yt(S,[d,b])[0]}multiplyUnsafe(p){const{endo:g}=e,d=this;if(!o.isValid(p))throw new Error("invalid scalar: out of range");if(p===J||d.is0())return S.ZERO;if(p===wt)return d;if(ot.hasCache(this))return this.multiply(p);if(g){const{k1neg:b,k1:E,k2neg:v,k2:x}=X(p),{p1:B,p2:P}=fr(S,d,E,x);return dt(g.beta,B,P,b,v)}else return ot.unsafe(d,p)}multiplyAndAddUnsafe(p,g,d){const b=this.multiplyUnsafe(g).add(p.multiplyUnsafe(d));return b.is0()?void 0:b}toAffine(p){return q(this,p)}isTorsionFree(){const{isTorsionFree:p}=e;return i===wt?!0:p?p(S,this):ot.unsafe(this,a).is0()}clearCofactor(){const{clearCofactor:p}=e;return i===wt?this:p?p(S,this):this.multiplyUnsafe(i)}isSmallOrder(){return this.multiplyUnsafe(i).is0()}toBytes(p=!0){return Ot(p,"isCompressed"),this.assertValidity(),f(S,this,p)}toHex(p=!0){return pt(this.toBytes(p))}toString(){return`<Point ${this.is0()?"ZERO":this.toHex()}>`}get px(){return this.X}get py(){return this.X}get pz(){return this.Z}toRawBytes(p=!0){return this.toBytes(p)}_setWindowSize(p){this.precompute(p)}static normalizeZ(p){return Yt(S,p)}static msm(p,g){return lr(S,o,p,g)}static fromPrivateKey(p){return S.BASE.multiply(ft(o,p))}}S.BASE=new S(s.Gx,s.Gy,n.ONE),S.ZERO=new S(n.ZERO,n.ONE,n.ZERO),S.Fp=n,S.Fn=o;const St=o.BITS,ot=new ur(S,e.endo?Math.ceil(St/2):St);return S.BASE.precompute(8),S}function mn(t){return Uint8Array.of(t?2:3)}function bn(t,e){return{secretKey:e.BYTES,publicKey:1+t.BYTES,publicKeyUncompressed:1+2*t.BYTES,publicKeyHasPrefix:!0,signature:2*e.BYTES}}function yr(t,e={}){const{Fn:r}=t,n=e.randomBytes||Ft,o=Object.assign(bn(t.Fp,r),{seed:hn(r.ORDER)});function s(f){try{return!!ft(r,f)}catch{return!1}}function i(f,h){const{publicKey:y,publicKeyUncompressed:A}=o;try{const _=f.length;return h===!0&&_!==y||h===!1&&_!==A?!1:!!t.fromBytes(f)}catch{return!1}}function a(f=n(o.seed)){return gn(ct(f,o.seed,"seed"),r.ORDER)}function u(f,h=!0){return t.BASE.multiply(ft(r,f)).toBytes(h)}function l(f){const h=a(f);return{secretKey:h,publicKey:u(h)}}function w(f){if(typeof f=="bigint")return!1;if(f instanceof t)return!0;const{secretKey:h,publicKey:y,publicKeyUncompressed:A}=o;if(r.allowedLengths||h===y)return;const _=O("key",f).length;return _===y||_===A}function m(f,h,y=!0){if(w(f)===!0)throw new Error("first arg must be private key");if(w(h)===!1)throw new Error("second arg must be public key");const A=ft(r,f);return t.fromHex(h).multiply(A).toBytes(y)}return Object.freeze({getPublicKey:u,getSharedSecret:m,keygen:l,Point:t,utils:{isValidSecretKey:s,isValidPublicKey:i,randomSecretKey:a,isValidPrivateKey:s,randomPrivateKey:a,normPrivateKeyToScalar:f=>ft(r,f),precompute(f=8,h=t.BASE){return h.precompute(f,!1)}},lengths:o})}function mr(t,e,r={}){ze(e),he(r,{},{hmac:"function",lowS:"boolean",randomBytes:"function",bits2int:"function",bits2int_modN:"function"});const n=r.randomBytes||Ft,o=r.hmac||((g,...d)=>Ge(e,g,j(...d))),{Fp:s,Fn:i}=t,{ORDER:a,BITS:u}=i,{keygen:l,getPublicKey:w,getSharedSecret:m,utils:c,lengths:f}=yr(t,r),h={prehash:!1,lowS:typeof r.lowS=="boolean"?r.lowS:!1,format:void 0,extraEntropy:!1},y="compact";function A(g){const d=a>>wt;return g>d}function _(g,d){if(!i.isValidNot0(d))throw new Error(`invalid signature ${g}: out of range 1..Point.Fn.ORDER`);return d}function rt(g,d){ce(d);const b=f.signature,E=d==="compact"?b:d==="recovered"?b+1:void 0;return ct(g,E,`${d} signature`)}class R{constructor(d,b,E){this.r=_("r",d),this.s=_("s",b),E!=null&&(this.recovery=E),Object.freeze(this)}static fromBytes(d,b=y){rt(d,b);let E;if(b==="der"){const{r:P,s:I}=Q.toSig(ct(d));return new R(P,I)}b==="recovered"&&(E=d[0],b="compact",d=d.subarray(1));const v=i.BYTES,x=d.subarray(0,v),B=d.subarray(v,v*2);return new R(i.fromBytes(x),i.fromBytes(B),E)}static fromHex(d,b){return this.fromBytes(Ht(d),b)}addRecoveryBit(d){return new R(this.r,this.s,d)}recoverPublicKey(d){const b=s.ORDER,{r:E,s:v,recovery:x}=this;if(x==null||![0,1,2,3].includes(x))throw new Error("recovery id invalid");if(a*yn<b&&x>1)throw new Error("recovery id is ambiguous for h>1 curve");const P=x===2||x===3?E+a:E;if(!s.isValid(P))throw new Error("recovery id 2 or 3 invalid");const I=s.toBytes(P),k=t.fromBytes(j(mn((x&1)===0),I)),V=i.inv(P),C=X(O("msgHash",d)),$=i.create(-C*V),H=i.create(v*V),L=t.BASE.multiplyUnsafe($).add(k.multiplyUnsafe(H));if(L.is0())throw new Error("point at infinify");return L.assertValidity(),L}hasHighS(){return A(this.s)}toBytes(d=y){if(ce(d),d==="der")return Ht(Q.hexFromSig(this));const b=i.toBytes(this.r),E=i.toBytes(this.s);if(d==="recovered"){if(this.recovery==null)throw new Error("recovery bit must be present");return j(Uint8Array.of(this.recovery),b,E)}return j(b,E)}toHex(d){return pt(this.toBytes(d))}assertValidity(){}static fromCompact(d){return R.fromBytes(O("sig",d),"compact")}static fromDER(d){return R.fromBytes(O("sig",d),"der")}normalizeS(){return this.hasHighS()?new R(this.r,i.neg(this.s),this.recovery):this}toDERRawBytes(){return this.toBytes("der")}toDERHex(){return pt(this.toBytes("der"))}toCompactRawBytes(){return this.toBytes("compact")}toCompactHex(){return pt(this.toBytes("compact"))}}const W=r.bits2int||function(d){if(d.length>8192)throw new Error("input is too large");const b=bt(d),E=d.length*8-u;return E>0?b>>BigInt(E):b},X=r.bits2int_modN||function(d){return i.create(W(d))},q=It(u);function tt(g){return Gn("num < 2^"+u,g,J,q),i.toBytes(g)}function dt(g,d){return ct(g,void 0,"message"),d?ct(e(g),void 0,"prehashed message"):g}function S(g,d,b){if(["recovered","canonical"].some($=>$ in b))throw new Error("sign() legacy options not supported");const{lowS:E,prehash:v,extraEntropy:x}=Qt(b,h);g=dt(g,v);const B=X(g),P=ft(i,d),I=[tt(P),tt(B)];if(x!=null&&x!==!1){const $=x===!0?n(f.secretKey):x;I.push(O("extraEntropy",$))}const k=j(...I),V=B;function C($){const H=W($);if(!i.isValidNot0(H))return;const L=i.inv(H),N=t.BASE.multiply(H).toAffine(),U=i.create(N.x);if(U===J)return;const Ct=i.create(L*i.create(V+U*P));if(Ct===J)return;let ye=(N.x===U?0:2)|Number(N.y&wt),me=Ct;return E&&A(Ct)&&(me=i.neg(Ct),ye^=1),new R(U,me,ye)}return{seed:k,k2sig:C}}function St(g,d,b={}){g=O("message",g);const{seed:E,k2sig:v}=S(g,d,b);return Qn(e.outputLen,i.BYTES,o)(E,v)}function ot(g){let d;const b=typeof g=="string"||Lt(g),E=!b&&g!==null&&typeof g=="object"&&typeof g.r=="bigint"&&typeof g.s=="bigint";if(!b&&!E)throw new Error("invalid signature, expected Uint8Array, hex string or Signature instance");if(E)d=new R(g.r,g.s);else if(b){try{d=R.fromBytes(O("sig",g),"der")}catch(v){if(!(v instanceof Q.Err))throw v}if(!d)try{d=R.fromBytes(O("sig",g),"compact")}catch{return!1}}return d||!1}function T(g,d,b,E={}){const{lowS:v,prehash:x,format:B}=Qt(E,h);if(b=O("publicKey",b),d=dt(O("message",d),x),"strict"in E)throw new Error("options.strict was renamed to lowS");const P=B===void 0?ot(g):R.fromBytes(O("sig",g),B);if(P===!1)return!1;try{const I=t.fromBytes(b);if(v&&P.hasHighS())return!1;const{r:k,s:V}=P,C=X(d),$=i.inv(V),H=i.create(C*$),L=i.create(k*$),N=t.BASE.multiplyUnsafe(H).add(I.multiplyUnsafe(L));return N.is0()?!1:i.create(N.x)===k}catch{return!1}}function p(g,d,b={}){const{prehash:E}=Qt(b,h);return d=dt(d,E),R.fromBytes(g,"recovered").recoverPublicKey(d).toBytes()}return Object.freeze({keygen:l,getPublicKey:w,getSharedSecret:m,utils:c,lengths:f,Point:t,sign:St,verify:T,recoverPublicKey:p,Signature:R,hash:e})}function br(t){const e={a:t.a,b:t.b,p:t.Fp.ORDER,n:t.n,h:t.h,Gx:t.Gx,Gy:t.Gy},r=t.Fp;let n=t.allowedPrivateKeyLengths?Array.from(new Set(t.allowedPrivateKeyLengths.map(i=>Math.ceil(i/2)))):void 0;const o=At(e.n,{BITS:t.nBitLength,allowedLengths:n,modFromBytes:t.wrapPrivateKey}),s={Fp:r,Fn:o,allowInfinityPoint:t.allowInfinityPoint,endo:t.endo,isTorsionFree:t.isTorsionFree,clearCofactor:t.clearCofactor,fromBytes:t.fromBytes,toBytes:t.toBytes};return{CURVE:e,curveOpts:s}}function Er(t){const{CURVE:e,curveOpts:r}=br(t),n={hmac:t.hmac,randomBytes:t.randomBytes,lowS:t.lowS,bits2int:t.bits2int,bits2int_modN:t.bits2int_modN};return{CURVE:e,curveOpts:r,hash:t.hash,ecdsaOpts:n}}function Br(t,e){const r=e.Point;return Object.assign({},e,{ProjectivePoint:r,CURVE:Object.assign({},t,ln(r.Fn.ORDER,r.Fn.BITS))})}function xr(t){const{CURVE:e,curveOpts:r,hash:n,ecdsaOpts:o}=Er(t),s=wr(e,r),i=mr(s,n,o);return Br(t,i)}function vr(t,e){const r=n=>xr({...t,hash:n});return{...r(e),create:r}}const mt={p:BigInt("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"),n:BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"),h:BigInt(1),a:BigInt(0),b:BigInt(7),Gx:BigInt("0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"),Gy:BigInt("0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8")},Pr={beta:BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"),basises:[[BigInt("0x3086d221a7d46bcde86c90e49284eb15"),-BigInt("0xe4437ed6010e88286f547fa90abfe4c3")],[BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"),BigInt("0x3086d221a7d46bcde86c90e49284eb15")]]},Ir=BigInt(0),Ce=BigInt(1),ae=BigInt(2);function Ar(t){const e=mt.p,r=BigInt(3),n=BigInt(6),o=BigInt(11),s=BigInt(22),i=BigInt(23),a=BigInt(44),u=BigInt(88),l=t*t*t%e,w=l*l*t%e,m=Z(w,r,e)*w%e,c=Z(m,r,e)*w%e,f=Z(c,ae,e)*l%e,h=Z(f,o,e)*f%e,y=Z(h,s,e)*h%e,A=Z(y,a,e)*y%e,_=Z(A,u,e)*A%e,rt=Z(_,a,e)*y%e,R=Z(rt,r,e)*w%e,W=Z(R,i,e)*h%e,X=Z(W,n,e)*l%e,q=Z(X,ae,e);if(!Ut.eql(Ut.sqr(q),t))throw new Error("Cannot find square root");return q}const Ut=At(mt.p,{sqrt:Ar}),Zt=vr({...mt,Fp:Ut,lowS:!0,endo:Pr},oe),Te={};function Kt(t,...e){let r=Te[t];if(r===void 0){const n=oe(Ye(t));r=j(n,n),Te[t]=r}return oe(j(r,...e))}const pe=t=>t.toBytes(!0).slice(1),Et=Zt.Point,we=t=>t%ae===Ir;function ue(t){const{Fn:e,BASE:r}=Et,n=ft(e,t),o=r.multiply(n);return{scalar:we(o.y)?n:e.neg(n),bytes:pe(o)}}function En(t){const e=Ut;if(!e.isValidNot0(t))throw new Error("invalid x: Fail if x ≥ p");const r=e.create(t*t),n=e.create(r*t+BigInt(7));let o=e.sqrt(n);we(o)||(o=e.neg(o));const s=Et.fromAffine({x:t,y:o});return s.assertValidity(),s}const vt=bt;function Bn(...t){return Et.Fn.create(vt(Kt("BIP0340/challenge",...t)))}function Ve(t){return ue(t).bytes}function Sr(t,e,r=Ft(32)){const{Fn:n}=Et,o=O("message",t),{bytes:s,scalar:i}=ue(e),a=O("auxRand",r,32),u=n.toBytes(i^vt(Kt("BIP0340/aux",a))),l=Kt("BIP0340/nonce",u,s,o),{bytes:w,scalar:m}=ue(l),c=Bn(w,s,o),f=new Uint8Array(64);if(f.set(w,0),f.set(n.toBytes(n.create(m+c*i)),32),!xn(f,o,s))throw new Error("sign: Invalid signature produced");return f}function xn(t,e,r){const{Fn:n,BASE:o}=Et,s=O("signature",t,64),i=O("message",e),a=O("publicKey",r,32);try{const u=En(vt(a)),l=vt(s.subarray(0,32));if(!ie(l,Ce,mt.p))return!1;const w=vt(s.subarray(32,64));if(!ie(w,Ce,mt.n))return!1;const m=Bn(n.toBytes(l),pe(u),i),c=o.multiplyUnsafe(w).add(u.multiplyUnsafe(n.neg(m))),{x:f,y:h}=c.toAffine();return!(c.is0()||!we(h)||f!==l)}catch{return!1}}const Bt=(()=>{const r=(o=Ft(48))=>gn(o,mt.n);Zt.utils.randomSecretKey;function n(o){const s=r(o);return{secretKey:s,publicKey:Ve(s)}}return{keygen:n,getPublicKey:Ve,sign:Sr,verify:xn,Point:Et,utils:{randomSecretKey:r,randomPrivateKey:r,taggedHash:Kt,lift_x:En,pointToBytes:pe,numberToBytesBE:Dt,bytesToNumberBE:bt,mod:z},lengths:{secretKey:32,publicKey:32,publicKeyHasPrefix:!1,signature:64,seed:48}}})(),Cr="5120",fe="0014",Tr=20,_e=33,Vr=65,_r=2,Rr=3,$r=4;function vn(t,e){const r=t.startsWith("0x")||t.startsWith("0X")?t.slice(2):t;if(!/^(?:[0-9a-fA-F]{2})+$/.test(r))throw new Error(`${e} must be non-empty, even-length hex`);return`0x${r.toLowerCase()}`}function Nr(t){const e=K.hexToBytes(t),r=Bt.utils.lift_x(BigInt(`0x${t}`)),n=Bt.utils.bytesToNumberBE(Bt.utils.taggedHash("TapTweak",e));if(n>=Zt.CURVE.n)throw new Error("Proof of possession BTC pubkey has an invalid TapTweak");const o=n===0n?r:r.add(Bt.Point.BASE.multiply(n));return`0x${Cr}${K.bytesToHex(Bt.utils.pointToBytes(o))}`}function kr(t){const e=vn(t,"depositorBtcPubkeyRaw"),r=K.hexToBytes(e.slice(2));if(r.length===32)return{xOnlyPubkey:Pt.assertOnChainBtcPubkey(e,"Payout BTC pubkey")};const n=r.length===_e&&(r[0]===_r||r[0]===Rr),o=r.length===Vr&&r[0]===$r;if(!n&&!o)throw new Error("depositorBtcPubkeyRaw must be x-only, compressed, or uncompressed");try{Zt.Point.fromBytes(r)}catch{throw new Error("depositorBtcPubkeyRaw is not a valid BTC pubkey")}return{xOnlyPubkey:K.bytesToHex(r.subarray(1,_e)),compressedPubkey:n?r:void 0}}function Hr(t){return`0x${fe}${K.bytesToHex(Ze(K.sha256(t)))}`}function Or(t,e,r){const n=vn(t,"depositorPayoutScriptPubKey");if((n.length-2)/2>Rt.MAX_PAYOUT_SCRIPT_LEN)throw new Error(`depositorPayoutScriptPubKey exceeds ${Rt.MAX_PAYOUT_SCRIPT_LEN} bytes`);const o=e.startsWith("0x")||e.startsWith("0X")?e.slice(2):e,s=Pt.assertOnChainBtcPubkey(`0x${o}`,"Proof of possession BTC pubkey"),i=kr(r);if(i.xOnlyPubkey!==s)throw new Error("depositorBtcPubkeyRaw does not match the proof of possession BTC pubkey");if(n===Nr(s))return n;if(n.startsWith(`0x${fe}`)&&n.length===2+fe.length+Tr*2){if(!i.compressedPubkey)throw new Error("A P2WPKH payout requires a compressed BTC pubkey");if(n===Hr(i.compressedPubkey))return n}throw new Error("depositorPayoutScriptPubKey does not match the proof of possession BTC pubkey")}function qr(t,e){const r=t.startsWith("0x")?t.slice(2):t;if(r.length===0||r.length%2!==0)throw new Error(`${e} must be non-empty, even-length hex`);if(!/^[0-9a-fA-F]+$/.test(r))throw new Error(`${e} contains non-hex characters`);const n=new Uint8Array(r.length/2);for(let o=0;o<n.length;o++)n[o]=Number.parseInt(r.slice(o*2,o*2+2),16);return n}function Ur(t){return Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}function Kr(t){const e=new Uint8Array(t.reduce((n,o)=>n+o.length,0));let r=0;for(const n of t)e.set(n,r),r+=n.length;return e}function Mr(t){let e=0;const r=(c,f)=>{if(!Number.isSafeInteger(c)||c<0)throw new Error(`Invalid ${f} length ${c}`);if(e+c>t.length)throw new Error(`Truncated Bitcoin transaction while reading ${f}`);const h=t.slice(e,e+c);return e+=c,h},n=(c,f)=>{const h=r(c,f);let y=0n;for(let A=h.length-1;A>=0;A--)y=y<<8n|BigInt(h[A]);return y},o=c=>{const f=e,h=r(1,c)[0];let y;if(h<253)y=BigInt(h);else if(h===253){if(y=n(2,c),y<0xfdn)throw new Error(`Non-canonical ${c}`)}else if(h===254){if(y=n(4,c),y<=0xffffn)throw new Error(`Non-canonical ${c}`)}else if(y=n(8,c),y<=0xffffffffn)throw new Error(`Non-canonical ${c}`);if(y>BigInt(Number.MAX_SAFE_INTEGER))throw new Error(`${c} exceeds JavaScript's safe integer range`);return{encoded:t.slice(f,e),value:Number(y)}},s=r(4,"version"),i=t[e]===0&&t[e+1]===1;i&&(e+=2);const a=o("input count"),u=[];for(let c=0;c<a.value;c++){const f=e;r(32,`input ${c} previous transaction hash`),r(4,`input ${c} previous output index`);const h=o(`input ${c} script length`);r(h.value,`input ${c} script`),r(4,`input ${c} sequence`),u.push(t.slice(f,e))}const l=o("output count"),w=[];for(let c=0;c<l.value;c++){const f=e;r(8,`output ${c} value`);const h=o(`output ${c} script length`);r(h.value,`output ${c} script`),w.push(t.slice(f,e))}if(i){let c=!1;for(let f=0;f<a.value;f++){const h=o(`input ${f} witness item count`);c||(c=h.value>0);for(let y=0;y<h.value;y++){const A=o(`input ${f} witness item ${y} length`);r(A.value,`input ${f} witness item ${y}`)}}if(!c)throw new Error("Bitcoin transaction has superfluous witness marker")}const m=r(4,"locktime");if(e!==t.length)throw new Error(`Bitcoin transaction has ${t.length-e} trailing byte(s)`);return Kr([s,a.encoded,...u,l.encoded,...w,m])}function Pn(t){const e=Mr(qr(t,"transactionHex")),r=K.sha256(K.sha256(e));return r.reverse(),`0x${Ur(r)}`}function In(t,e){const r=t.startsWith("0x")?t:`0x${t}`;if(!/^0x[0-9a-fA-F]{64}$/.test(r))throw new Error("peginTxHash must be a 32-byte hex value");const n=e.startsWith("0x")?e:`0x${e}`;if(!it.isAddress(n,{strict:!0}))throw new Error(`Invalid depositor Ethereum address: ${e}`);return it.keccak256(it.encodeAbiParameters([{type:"bytes32"},{type:"address"}],[r,n])).slice(2)}const Jt=65535,Re=1e4,Mt=4294967295,$e=255;function An(t){if(!Number.isInteger(t)||t<0||t>Mt)throw new Error(`Invalid offchainParamsVersion from contract: must be a uint32, got ${t}`)}function Sn(t){const e=[];if(t.timelockAssert<=0n&&e.push(`timelockAssert must be positive, got ${t.timelockAssert}`),t.timelockAssert>BigInt(Jt)&&e.push(`timelockAssert ${t.timelockAssert} exceeds uint16 max (${Jt})`),t.timelockChallengeAssert<=0n&&e.push(`timelockChallengeAssert must be positive, got ${t.timelockChallengeAssert}`),t.tRefund<=0&&e.push(`tRefund must be positive, got ${t.tRefund}`),t.tStale<=0&&e.push(`tStale must be positive, got ${t.tStale}`),t.securityCouncilKeys.length===0&&e.push("securityCouncilKeys must not be empty"),t.councilQuorum<=0&&e.push(`councilQuorum must be positive, got ${t.councilQuorum}`),t.councilQuorum>t.securityCouncilKeys.length&&e.push(`councilQuorum (${t.councilQuorum}) exceeds securityCouncilKeys count (${t.securityCouncilKeys.length})`),t.feeRate<=0n&&e.push(`feeRate must be positive, got ${t.feeRate}`),t.minPeginFeeRate<=0n&&e.push(`minPeginFeeRate must be positive, got ${t.minPeginFeeRate}`),(!Number.isInteger(t.proverCircuitVersion)||t.proverCircuitVersion<0||t.proverCircuitVersion>Jt)&&e.push(`proverCircuitVersion must be a uint16, got ${t.proverCircuitVersion}`),(!Number.isInteger(t.minPrepeginDepth)||t.minPrepeginDepth<=0||t.minPrepeginDepth>Mt)&&e.push(`minPrepeginDepth must be a uint32 in [1, ${Mt}], got ${t.minPrepeginDepth}`),t.babeTotalInstances<=0&&e.push(`babeTotalInstances must be positive, got ${t.babeTotalInstances}`),t.babeInstancesToFinalize<=0&&e.push(`babeInstancesToFinalize must be positive, got ${t.babeInstancesToFinalize}`),t.babeInstancesToFinalize>t.babeTotalInstances&&e.push(`babeInstancesToFinalize (${t.babeInstancesToFinalize}) exceeds babeTotalInstances (${t.babeTotalInstances})`),(t.minVpCommissionBps<0||t.minVpCommissionBps>Re)&&e.push(`minVpCommissionBps must be in [0, ${Re}], got ${t.minVpCommissionBps}`),e.length>0)throw new Error(`Invalid offchain protocol parameters: ${e.join("; ")}`)}function Cn(t){const e=[];if(t.minimumPegInAmount<=0n&&e.push(`minimumPegInAmount must be positive, got ${t.minimumPegInAmount}`),t.maxPegInAmount<t.minimumPegInAmount&&e.push(`maxPegInAmount (${t.maxPegInAmount}) must be >= minimumPegInAmount (${t.minimumPegInAmount})`),t.pegInAckTimeout<=0n&&e.push(`pegInAckTimeout must be positive, got ${t.pegInAckTimeout}`),t.pegInActivationTimeout<=0n&&e.push(`pegInActivationTimeout must be positive, got ${t.pegInActivationTimeout}`),(!Number.isInteger(t.maxHtlcOutputCount)||t.maxHtlcOutputCount<=0||t.maxHtlcOutputCount>$e)&&e.push(`maxHtlcOutputCount must be an integer in [1, ${$e}], got ${t.maxHtlcOutputCount}`),(typeof t.expiredPegInGraceBlocks!="bigint"||t.expiredPegInGraceBlocks<=0n)&&e.push(`expiredPegInGraceBlocks must be a positive bigint, got ${t.expiredPegInGraceBlocks}`),e.length>0)throw new Error(`Invalid TBV protocol parameters: ${e.join("; ")}`)}function Lr(t){if(Cn(t),Sn(t.offchainParams),!Number.isInteger(t.offchainParamsVersion)||t.offchainParamsVersion<0||t.offchainParamsVersion>Mt)throw new Error(`Invalid peg-in configuration: offchainParamsVersion must be a uint32, got ${t.offchainParamsVersion}`);Nn.assertValidVaultCoreVersion(t.activeVaultCoreVersion,"ProtocolParams.activeVaultCoreVersion()")}const Ne=9999;function ke(t){return{depositor:t.depositor,depositorBtcPubKey:t.depositorBtcPubKey,amount:t.amount,vaultProvider:t.vaultProvider,status:t.status,applicationEntryPoint:t.applicationEntryPoint,createdAt:t.createdAt}}function te(t){const e=Number(t.offchainParamsVersion);return An(e),{depositorSignedPeginTx:t.depositorSignedPeginTx,universalChallengersVersion:t.universalChallengersVersion,appVaultKeepersVersion:t.appVaultKeepersVersion,offchainParamsVersion:e,verifiedAt:t.verifiedAt,depositorWotsPkHash:t.depositorWotsPkHash,hashlock:t.hashlock,htlcVout:t.htlcVout,depositorPopSignature:t.depositorPopSignature,prePeginTxHash:t.prePeginTxHash,vaultProviderCommissionBps:t.vaultProviderCommissionBps,vaultCoreVersion:t.vaultCoreVersion}}const Fr=1n<<64n,He=0n;function ee(t,e,r){if(t<0n||t>=Fr)throw new Error(`getBtcVaultProtocolInfo returned ${e}=${t} for vault ${r}, outside the uint64 range — the registry may predate RFC-006`);return t}function Oe(t,e){return{vpKeyEpoch:ee(t.vpKeyEpoch,"vpKeyEpoch",e),appKeeperKeyEpoch:ee(t.appKeeperKeyEpoch,"appKeeperKeyEpoch",e),ucKeyEpoch:ee(t.ucKeyEpoch,"ucKeyEpoch",e)}}class Tn{constructor(e,r){this.publicClient=e,this.contractAddress=r}async getVaultProviderGenesisBtcPubKey(e,r){const n=await this.publicClient.readContract({address:this.contractAddress,abi:D.BTCVaultRegistryABI,functionName:"getOperationBtcKeyAtEpoch",args:[e,He],blockNumber:r});return Pt.assertOnChainBtcPubkey(n,`getOperationBtcKeyAtEpoch (vp=${e}, epoch=${He})`)}async getCurrentVaultProviderOperationBtcKey(e){const r=await this.publicClient.readContract({address:this.contractAddress,abi:D.BTCVaultRegistryABI,functionName:"getCurrentOperationBtcKey",args:[e]});return Pt.assertOnChainBtcPubkey(r,`getCurrentOperationBtcKey (vp=${e})`)}async getVaultKeyEpochs(e){const r=await this.publicClient.readContract({address:this.contractAddress,abi:xt.BTCVaultRegistryKeyEpochsABI,functionName:"getBtcVaultProtocolInfo",args:[e]});return Oe(r,e)}async getVaultKeyEpochsBatch(e){return e.length===0?[]:(await this.publicClient.multicall({contracts:e.map(n=>({address:this.contractAddress,abi:xt.BTCVaultRegistryKeyEpochsABI,functionName:"getBtcVaultProtocolInfo",args:[n]})),allowFailure:!1})).map((n,o)=>Oe(n,e[o]))}async getVaultBasicInfo(e){const r=await this.publicClient.readContract({address:this.contractAddress,abi:D.BTCVaultRegistryABI,functionName:"getBtcVaultBasicInfo",args:[e]});return ke(r)}async getVaultProtocolInfo(e){const r=await this.publicClient.readContract({address:this.contractAddress,abi:D.BTCVaultRegistryABI,functionName:"getBtcVaultProtocolInfo",args:[e]});return te(r)}async getProtocolInfoBatch(e){return e.length===0?[]:(await this.publicClient.multicall({contracts:e.map(n=>({address:this.contractAddress,abi:D.BTCVaultRegistryABI,functionName:"getBtcVaultProtocolInfo",args:[n]})),allowFailure:!1})).map((n,o)=>{const s=n;if(!s.depositorSignedPeginTx||s.depositorSignedPeginTx==="0x")throw new Error(`Vault ${e[o]} not found on-chain or has no pegin transaction`);return te(s)})}async getPegInFee(e){return await this.publicClient.readContract({address:this.contractAddress,abi:D.BTCVaultRegistryABI,functionName:"getPegInFee",args:[e]})}async getVaultProviderCommission(e){const r=await this.publicClient.readContract({address:this.contractAddress,abi:D.BTCVaultRegistryABI,functionName:"getVaultProviderCommission",args:[e]});if(!Number.isInteger(r)||r<0||r>Ne)throw new Error(`getVaultProviderCommission returned ${r} bps for ${e}, outside the protocol range [0, ${Ne}]`);return r}async getVaultData(e){const[r,n]=await this.publicClient.multicall({contracts:[{address:this.contractAddress,abi:D.BTCVaultRegistryABI,functionName:"getBtcVaultBasicInfo",args:[e]},{address:this.contractAddress,abi:D.BTCVaultRegistryABI,functionName:"getBtcVaultProtocolInfo",args:[e]}],allowFailure:!1}),o=ke(r),s=te(n);if(!s.depositorSignedPeginTx||s.depositorSignedPeginTx==="0x")throw new Error(`Vault ${e} not found on-chain or has no pegin transaction`);return{basic:o,protocol:s}}}const Vn=0,Dr=255,Zr=12e4;function st(t,e){const r=t.startsWith("0x")?t:t.startsWith("0X")?`0x${t.slice(2)}`:`0x${t}`;if(!/^0x(?:[0-9a-fA-F]{2})+$/.test(r))throw new Error(`${e} must be non-empty, even-length hex`);return r}function qe(t,e){if(!/^0x[0-9a-fA-F]{64}$/.test(t))throw new Error(`${e} must be a 32-byte hex value`)}function zr(t){if(!Number.isInteger(t)||t<0||t>Dr)throw new Error(`htlcVout must be a uint8, got ${t}`)}class Xr{constructor(e){this.config=e}async registerPeginOnChain(e){const r={...e,popSignature:{...e.popSignature}};this.assertQuotedCommissionPresentWhenRequired(r.quotedCommissionBps);const n=this.assertPopMatchesEthAccount(r.popSignature),o=this.normalizeBtcPubkey(r.popSignature),s=st(r.popSignature.btcPopSignature,"btcPopSignature"),i=this.normalizeRequest(r,n,o);await this.assertVaultDoesNotExist(i.vaultId,i.peginTxHash);const a=await this.readPeginFee(r.vaultProvider),u=await this.resolveMaxAcceptableCommissionBps(r.vaultProvider,r.quotedCommissionBps),l=it.encodeFunctionData({abi:D.BTCVaultRegistryABI,functionName:"submitPeginRequest",args:[n,o,s,i.unsignedPrePeginTx,i.depositorSignedPeginTx,r.vaultProvider,u,r.hashlock,r.htlcVout,i.payoutScript,r.depositorWotsPkHash]});return{ethTxHash:await this.sendAndWait(l,a,!1,n),vaultId:i.vaultId,peginTxHash:i.peginTxHash}}async registerPeginBatchOnChain(e){const r={...e,popSignature:{...e.popSignature},requests:e.requests.map(h=>({...h}))};if(r.requests.length===0)throw new Error("Batch pegin requires at least one request");this.assertQuotedCommissionPresentWhenRequired(r.quotedCommissionBps);const n=this.assertPopMatchesEthAccount(r.popSignature),o=st(r.unsignedPrePeginTx,"unsignedPrePeginTx"),s=this.normalizeBtcPubkey(r.popSignature),i=st(r.popSignature.btcPopSignature,"btcPopSignature"),a=[],u=[],l=new Set;for(const h of r.requests){const y=this.normalizeRequest({...h,unsignedPrePeginTx:r.unsignedPrePeginTx,vaultProvider:r.vaultProvider,depositorBtcPubkeyRaw:r.depositorBtcPubkeyRaw},n,s);if(l.has(y.vaultId))throw new Error(`Duplicate vault in batch: ${y.vaultId}`);l.add(y.vaultId),a.push({vaultId:y.vaultId,peginTxHash:y.peginTxHash}),u.push({depositorBtcPubKey:s,btcPopSignature:i,unsignedPrePeginTx:o,depositorSignedPeginTx:y.depositorSignedPeginTx,hashlock:h.hashlock,htlcVout:h.htlcVout,referralCode:Vn,depositorPayoutBtcAddress:y.payoutScript,depositorWotsPkHash:h.depositorWotsPkHash})}for(const h of a)await this.assertVaultDoesNotExist(h.vaultId,h.peginTxHash);const w=await this.readPeginFee(r.vaultProvider),m=await this.resolveMaxAcceptableCommissionBps(r.vaultProvider,r.quotedCommissionBps),c=it.encodeFunctionData({abi:D.BTCVaultRegistryABI,functionName:"submitPeginRequestBatch",args:[n,r.vaultProvider,m,u]});return{ethTxHash:await this.sendAndWait(c,w*BigInt(r.requests.length),!0,n),vaults:a}}assertQuotedCommissionPresentWhenRequired(e){if(e===void 0&&this.config.requireQuotedCommissionBps)throw new Error("quotedCommissionBps is required when the wallet approved deposit terms: the registration ceiling must anchor to the approved quote.")}assertPopMatchesEthAccount(e){return this.assertEthAccount(e.depositorEthAddress)}assertEthAccount(e){const r=this.config.ethWallet.account;if(!r)throw new Error("Ethereum wallet account not found");if(!it.isAddressEqual(e,r.address))throw new Error(`Proof of possession was signed for ${e} but the Ethereum wallet is currently connected to ${r.address}. Reconnect the original account or sign a new proof of possession.`);return r.address}normalizeBtcPubkey(e){return`0x${Pt.assertOnChainBtcPubkey(st(e.depositorBtcPubkey,"Proof of possession BTC pubkey"),"Proof of possession BTC pubkey")}`}normalizeRequest(e,r,n){qe(e.hashlock,"hashlock"),qe(e.depositorWotsPkHash,"depositorWotsPkHash"),zr(e.htlcVout);const o=st(e.unsignedPrePeginTx,"unsignedPrePeginTx"),s=st(e.depositorSignedPeginTx,"depositorSignedPeginTx"),i=Pn(s);return{unsignedPrePeginTx:o,depositorSignedPeginTx:s,payoutScript:Or(e.depositorPayoutScriptPubKey,n,e.depositorBtcPubkeyRaw),peginTxHash:i,vaultId:st(In(i,r),"vaultId")}}async assertVaultDoesNotExist(e,r){if((await this.config.publicClient.readContract({address:this.config.btcVaultRegistry,abi:D.BTCVaultRegistryABI,functionName:"getBtcVaultBasicInfo",args:[e]})).depositor!==it.zeroAddress)throw new Error(`Vault already exists (ID: ${e}, peginTxHash: ${r}). Vault IDs are derived from the pegin transaction hash and depositor address. To create a new vault, use different UTXOs or a different amount to generate a unique transaction.`)}async readPeginFee(e){try{return await this.config.publicClient.readContract({address:this.config.btcVaultRegistry,abi:D.BTCVaultRegistryABI,functionName:"getPegInFee",args:[e]})}catch(r){throw new Error("Failed to query pegin fee from the contract. Please check your network connection and contract address.",{cause:r})}}async resolveMaxAcceptableCommissionBps(e,r){let n;try{n=await new Tn(this.config.publicClient,this.config.btcVaultRegistry).getVaultProviderCommission(e)}catch(o){throw new Error("Failed to query vault provider commission from the contract. Please check your network connection and contract address.",{cause:o})}if(r!==void 0){if(n>r+$t)throw new Error(`Vault provider commission changed since quote: quoted ${r} bps, chain currently reports ${n} bps (allowed drift ${$t} bps). Please refresh and try again.`);return ne(r)}return ne(n)}async sendAndWait(e,r,n,o){let s=this.assertEthAccount(o),i;try{i=await this.config.publicClient.estimateGas({to:this.config.btcVaultRegistry,data:e,value:r,account:s})}catch(l){xt.handleContractError(l)}s=this.assertEthAccount(o);let a;try{a=await this.config.ethWallet.sendTransaction({to:this.config.btcVaultRegistry,data:e,value:r,gas:i,account:s,chain:this.config.ethChain})}catch(l){xt.handleContractError(l)}const u=await $n.waitForTransactionReceiptSmartAware({publicClient:this.config.publicClient,walletAddress:o,hash:a,timeout:this.config.receiptTimeoutMs??Zr});return u.status==="reverted"&&xt.handleContractError(new Error(`${n?"Batch transaction":"Transaction"} reverted. Hash: ${u.transactionHash}. Check a block explorer for details.`)),u.transactionHash}}exports.COMMISSION_BPS_HEADROOM=$t;exports.MAX_ACCEPTABLE_COMMISSION_BPS_CAP=Ue;exports.NO_REFERRAL_CODE=Vn;exports.ViemPeginRegistrationClient=Xr;exports.ViemVaultRegistryReader=Tn;exports.assertValidOffchainParamsVersion=An;exports.calculateBtcTxHash=Pn;exports.capMaxAcceptableCommissionBps=ne;exports.derivePeginVaultId=In;exports.ripemd160=Ze;exports.validateOffchainParams=Sn;exports.validatePegInConfiguration=Lr;exports.validateTBVProtocolParams=Cn;
|
|
2
|
+
//# sourceMappingURL=pegin-registration-client-6vLk2itL.cjs.map
|