@babylonlabs-io/ts-sdk 3.0.0 → 3.0.2
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/dist/{PeginManager-CKf7Bjmj.js → PeginManager-D8WGB8eN.js} +2 -2
- package/dist/{PeginManager-CKf7Bjmj.js.map → PeginManager-D8WGB8eN.js.map} +1 -1
- package/dist/{PeginManager-Dt2Z5ljw.cjs → PeginManager-IgDHy_eU.cjs} +2 -2
- package/dist/{PeginManager-Dt2Z5ljw.cjs.map → PeginManager-IgDHy_eU.cjs.map} +1 -1
- package/dist/buildAndBroadcastReclaim-B8aFMGf-.cjs +2 -0
- package/dist/buildAndBroadcastReclaim-B8aFMGf-.cjs.map +1 -0
- package/dist/{buildAndBroadcastReclaim-T5ZFPUpM.js → buildAndBroadcastReclaim-D5520lbL.js} +1015 -935
- package/dist/buildAndBroadcastReclaim-D5520lbL.js.map +1 -0
- package/dist/index-D2mybjXD.js +522 -0
- package/dist/index-D2mybjXD.js.map +1 -0
- package/dist/index-MRdle0fs.cjs +2 -0
- package/dist/index-MRdle0fs.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +215 -214
- package/dist/pegin-registration-client-B0j6ugt9.cjs +2 -0
- package/dist/pegin-registration-client-B0j6ugt9.cjs.map +1 -0
- package/dist/{pegin-registration-client-C5Hktrja.js → pegin-registration-client-ilkV1mLP.js} +103 -88
- package/dist/pegin-registration-client-ilkV1mLP.js.map +1 -0
- package/dist/primeVpAuth-BDWBKYhv.cjs +2 -0
- package/dist/primeVpAuth-BDWBKYhv.cjs.map +1 -0
- package/dist/primeVpAuth-D0ZnsjRi.js +805 -0
- package/dist/primeVpAuth-D0ZnsjRi.js.map +1 -0
- package/dist/state-C4WoNCy1.cjs +2 -0
- package/dist/state-C4WoNCy1.cjs.map +1 -0
- package/dist/{state-mE-QfITd.js → state-CFn1rT74.js} +128 -101
- package/dist/state-CFn1rT74.js.map +1 -0
- package/dist/tbv/core/clients/eth/index.cjs +1 -1
- package/dist/tbv/core/clients/eth/index.js +2 -2
- package/dist/tbv/core/clients/eth/types.d.ts +12 -5
- package/dist/tbv/core/clients/eth/types.d.ts.map +1 -1
- package/dist/tbv/core/clients/eth/vault-registry-reader.d.ts +12 -3
- package/dist/tbv/core/clients/eth/vault-registry-reader.d.ts.map +1 -1
- package/dist/tbv/core/clients/index.cjs +1 -1
- package/dist/tbv/core/clients/index.js +52 -51
- package/dist/tbv/core/clients/mempool/index.cjs +1 -1
- package/dist/tbv/core/clients/mempool/index.cjs.map +1 -1
- package/dist/tbv/core/clients/mempool/index.d.ts +1 -1
- package/dist/tbv/core/clients/mempool/index.d.ts.map +1 -1
- package/dist/tbv/core/clients/mempool/index.js +85 -71
- package/dist/tbv/core/clients/mempool/index.js.map +1 -1
- package/dist/tbv/core/clients/mempool/mempoolApi.d.ts +10 -0
- package/dist/tbv/core/clients/mempool/mempoolApi.d.ts.map +1 -1
- package/dist/tbv/core/clients/vault-provider/api.d.ts +17 -14
- package/dist/tbv/core/clients/vault-provider/api.d.ts.map +1 -1
- package/dist/tbv/core/clients/vault-provider/auth/createAuthenticatedVpClient.d.ts +8 -0
- package/dist/tbv/core/clients/vault-provider/auth/createAuthenticatedVpClient.d.ts.map +1 -1
- package/dist/tbv/core/clients/vault-provider/auth/index.d.ts +1 -1
- package/dist/tbv/core/clients/vault-provider/auth/index.d.ts.map +1 -1
- package/dist/tbv/core/clients/vault-provider/auth/primeVpAuth.d.ts +8 -0
- package/dist/tbv/core/clients/vault-provider/auth/primeVpAuth.d.ts.map +1 -1
- package/dist/tbv/core/clients/vault-provider/auth/tokenProvider.d.ts +18 -2
- package/dist/tbv/core/clients/vault-provider/auth/tokenProvider.d.ts.map +1 -1
- package/dist/tbv/core/clients/vault-provider/auth/tokenRegistry.d.ts +26 -6
- package/dist/tbv/core/clients/vault-provider/auth/tokenRegistry.d.ts.map +1 -1
- package/dist/tbv/core/clients/vault-provider/batchAttribution.d.ts +17 -15
- package/dist/tbv/core/clients/vault-provider/batchAttribution.d.ts.map +1 -1
- package/dist/tbv/core/clients/vault-provider/batchPoll.d.ts +15 -9
- package/dist/tbv/core/clients/vault-provider/batchPoll.d.ts.map +1 -1
- package/dist/tbv/core/clients/vault-provider/json-rpc-client.d.ts +3 -2
- package/dist/tbv/core/clients/vault-provider/json-rpc-client.d.ts.map +1 -1
- package/dist/tbv/core/clients/vault-provider/status/index.cjs +1 -1
- package/dist/tbv/core/clients/vault-provider/status/index.js +2 -2
- package/dist/tbv/core/clients/vault-provider/types.d.ts +36 -23
- package/dist/tbv/core/clients/vault-provider/types.d.ts.map +1 -1
- package/dist/tbv/core/clients/vault-provider/validators.d.ts +12 -4
- package/dist/tbv/core/clients/vault-provider/validators.d.ts.map +1 -1
- package/dist/tbv/core/index.cjs +1 -1
- package/dist/tbv/core/index.js +213 -212
- package/dist/tbv/core/managers/index.cjs +1 -1
- package/dist/tbv/core/managers/index.js +1 -1
- package/dist/tbv/core/services/deposit/graphFingerprint.d.ts +39 -0
- package/dist/tbv/core/services/deposit/graphFingerprint.d.ts.map +1 -1
- package/dist/tbv/core/services/deposit/interfaces.d.ts +2 -2
- package/dist/tbv/core/services/deposit/interfaces.d.ts.map +1 -1
- package/dist/tbv/core/services/deposit/runDepositorPresignFlow.d.ts +3 -1
- package/dist/tbv/core/services/deposit/runDepositorPresignFlow.d.ts.map +1 -1
- package/dist/tbv/core/services/deposit/signDepositorGraph.d.ts.map +1 -1
- package/dist/tbv/core/services/deposit/submitWotsPublicKey.d.ts +3 -1
- package/dist/tbv/core/services/deposit/submitWotsPublicKey.d.ts.map +1 -1
- package/dist/tbv/core/services/deposit/waitForPeginStatus.d.ts +11 -2
- package/dist/tbv/core/services/deposit/waitForPeginStatus.d.ts.map +1 -1
- package/dist/tbv/core/services/index.cjs +1 -1
- package/dist/tbv/core/services/index.js +2 -2
- package/dist/tbv/core/services/pegout/state.d.ts +2 -2
- package/dist/tbv/index.cjs +1 -1
- package/dist/tbv/index.js +213 -212
- package/dist/{toRefundInputs-DIIdhjvu.js → toRefundInputs-10RYIfh1.js} +2 -2
- package/dist/{toRefundInputs-DIIdhjvu.js.map → toRefundInputs-10RYIfh1.js.map} +1 -1
- package/dist/{toRefundInputs-B_GlIXjk.cjs → toRefundInputs-a-0HRyrl.cjs} +2 -2
- package/dist/{toRefundInputs-B_GlIXjk.cjs.map → toRefundInputs-a-0HRyrl.cjs.map} +1 -1
- package/dist/{types-DJxOEU3P.cjs → types-BueQoMjO.cjs} +2 -2
- package/dist/{types-DJxOEU3P.cjs.map → types-BueQoMjO.cjs.map} +1 -1
- package/dist/{types-Dz1kVqn6.js → types-DGkejGZH.js} +2 -2
- package/dist/{types-Dz1kVqn6.js.map → types-DGkejGZH.js.map} +1 -1
- package/package.json +3 -3
- package/dist/buildAndBroadcastReclaim-BDc-SK9i.cjs +0 -2
- package/dist/buildAndBroadcastReclaim-BDc-SK9i.cjs.map +0 -1
- package/dist/buildAndBroadcastReclaim-T5ZFPUpM.js.map +0 -1
- package/dist/index-B6w5MM-8.js +0 -528
- package/dist/index-B6w5MM-8.js.map +0 -1
- package/dist/index-EHLYplSd.cjs +0 -2
- package/dist/index-EHLYplSd.cjs.map +0 -1
- package/dist/pegin-registration-client-BdJ6c7si.cjs +0 -2
- package/dist/pegin-registration-client-BdJ6c7si.cjs.map +0 -1
- package/dist/pegin-registration-client-C5Hktrja.js.map +0 -1
- package/dist/primeVpAuth-Bdy_B_Sq.js +0 -745
- package/dist/primeVpAuth-Bdy_B_Sq.js.map +0 -1
- package/dist/primeVpAuth-CQRsu6VB.cjs +0 -2
- package/dist/primeVpAuth-CQRsu6VB.cjs.map +0 -1
- package/dist/state-DMFlvLL3.cjs +0 -2
- package/dist/state-DMFlvLL3.cjs.map +0 -1
- package/dist/state-mE-QfITd.js.map +0 -1
package/dist/index-EHLYplSd.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";var O=Object.defineProperty;var H=(s,e,t)=>e in s?O(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t;var S=(s,e,t)=>H(s,typeof e!="symbol"?e+"":e,t);const E=require("./state-DMFlvLL3.cjs"),C=require("./constants-BTZdyOuk.cjs"),m=require("./validation-C6XTfZak.cjs"),D=new Set(Object.values(E.DaemonStatus)),U=200;function a(s){var e;return((e=JSON.stringify(s))==null?void 0:e.slice(0,U))??"undefined"}const T="VP response validation failed: unrecognized status";function q(s){return s.startsWith(T)}const X="The vault provider returned an unexpected response. Please try again or contact support.";class r extends Error{constructor(t){super(X);S(this,"detail");this.name="VpResponseValidationError",this.detail=t}}const y=64,k=64;function f(s){return typeof s=="string"&&s.length>0&&m.HEX_RE.test(s)}function L(s){return typeof s=="string"&&s.length>0}function I(s,e){if(!f(s))throw new r(`VP response validation failed: "${e}" must be a non-empty hex string, got ${a(s)}`)}function u(s,e){if(!L(s))throw new r(`VP response validation failed: "${e}" must be a non-empty string, got ${a(s)}`)}function j(s,e){if(!f(s)||s.length!==m.X_ONLY_PUBKEY_HEX_LEN&&s.length!==m.COMPRESSED_PUBKEY_HEX_LEN)throw new r(`VP response validation failed: "${e}" must be a ${m.X_ONLY_PUBKEY_HEX_LEN} or ${m.COMPRESSED_PUBKEY_HEX_LEN}-char hex string (BTC pubkey), got ${a(s)}`)}function M(s){const e=s.presigning;if(e==null)return;if(typeof e!="object"||Array.isArray(e))throw new r('VP response validation failed: "progress.presigning" must be an object if present');const t=e;if(t.depositor_graph_created!==void 0&&typeof t.depositor_graph_created!="boolean")throw new r(`VP response validation failed: "progress.presigning.depositor_graph_created" must be a boolean if present, got ${a(t.depositor_graph_created)}`);if(t.vk_challenger_presigning_completed!==void 0&&typeof t.vk_challenger_presigning_completed!="number")throw new r(`VP response validation failed: "progress.presigning.vk_challenger_presigning_completed" must be a number if present, got ${a(t.vk_challenger_presigning_completed)}`);if(t.vk_challenger_presigning_total!==void 0&&typeof t.vk_challenger_presigning_total!="number")throw new r(`VP response validation failed: "progress.presigning.vk_challenger_presigning_total" must be a number if present, got ${a(t.vk_challenger_presigning_total)}`)}function N(s){if(s===null||typeof s!="object")throw new r("VP response validation failed: getPeginStatus response is not an object");const e=s;if(!f(e.pegin_txid)||e.pegin_txid.length!==y)throw new r(`VP response validation failed: "pegin_txid" must be a ${y}-char hex string (txid), got ${a(e.pegin_txid)}`);if(typeof e.status!="string")throw new r('VP response validation failed: "status" must be a string');if(!D.has(e.status))throw new r(`${T} ${a(e.status)}. Expected one of: ${[...D].join(", ")}`);if(e.progress===null||typeof e.progress!="object"||Array.isArray(e.progress))throw new r('VP response validation failed: "progress" must be an object');if(M(e.progress),typeof e.health_info!="string")throw new r('VP response validation failed: "health_info" must be a string');if(e.last_error!==void 0&&typeof e.last_error!="string")throw new r(`VP response validation failed: "last_error" must be a string if present, got ${a(e.last_error)}`)}function z(s){if(s===null||typeof s!="object")throw new r("VP response validation failed: requestDepositorPresignTransactions response is not an object");const e=s;if(!Array.isArray(e.txs))throw new r('VP response validation failed: "txs" must be an array');for(let t=0;t<e.txs.length;t++)K(e.txs[t],`txs[${t}]`);if(e.depositor_graph===null||typeof e.depositor_graph!="object")throw new r('VP response validation failed: "depositor_graph" must be an object');te(e.depositor_graph)}function h(s,e){if(s===null||typeof s!="object")throw new r(`VP response validation failed: "${e}" must be an object`);I(s.tx_hex,`${e}.tx_hex`)}function K(s,e){if(s===null||typeof s!="object")throw new r(`VP response validation failed: "${e}" must be an object`);const t=s;j(t.claimer_pubkey,`${e}.claimer_pubkey`),h(t.claim_tx,`${e}.claim_tx`),h(t.assert_tx,`${e}.assert_tx`),h(t.payout_tx,`${e}.payout_tx`),u(t.payout_psbt,`${e}.payout_psbt`)}function Y(s,e){if(s===null||typeof s!="object")throw new r(`VP response validation failed: "${e}" must be an object`);const t=s;u(t.wots_pks_json,`${e}.wots_pks_json`),u(t.gc_wots_keys_json,`${e}.gc_wots_keys_json`)}function F(s,e){if(s===null||typeof s!="object")throw new r(`VP response validation failed: "${e}" must be an object`);const t=s;if(j(t.challenger_pubkey,`${e}.challenger_pubkey`),h(t.challenge_assert_x_tx,`${e}.challenge_assert_x_tx`),h(t.challenge_assert_y_tx,`${e}.challenge_assert_y_tx`),h(t.nopayout_tx,`${e}.nopayout_tx`),u(t.nopayout_psbt,`${e}.nopayout_psbt`),!Array.isArray(t.challenge_assert_connectors))throw new r(`VP response validation failed: "${e}.challenge_assert_connectors" must be an array`);if(t.challenge_assert_connectors.length!==C.CHALLENGE_ASSERT_CONNECTORS_PER_CHALLENGER)throw new r(`VP response validation failed: "${e}.challenge_assert_connectors" must have exactly ${C.CHALLENGE_ASSERT_CONNECTORS_PER_CHALLENGER} entries, got ${t.challenge_assert_connectors.length}`);for(let n=0;n<t.challenge_assert_connectors.length;n++)Y(t.challenge_assert_connectors[n],`${e}.challenge_assert_connectors[${n}]`);if(!Array.isArray(t.output_label_hashes))throw new r(`VP response validation failed: "${e}.output_label_hashes" must be an array`);for(let n=0;n<t.output_label_hashes.length;n++){const o=t.output_label_hashes[n];if(!f(o)||o.length!==k)throw new r(`VP response validation failed: "${e}.output_label_hashes[${n}]" must be a ${k}-char hex string, got ${a(o)}`)}}function B(s){if(s===null||typeof s!="object")throw new r("VP response validation failed: requestDepositorClaimerArtifacts response is not an object");const e=s;if(!L(e.tx_graph_json))throw new r(`VP response validation failed: "tx_graph_json" must be a non-empty string, got ${a(e.tx_graph_json)}`);if(!f(e.verifying_key_hex))throw new r(`VP response validation failed: "verifying_key_hex" must be a non-empty hex string, got ${a(e.verifying_key_hex)}`);if(e.babe_sessions===null||typeof e.babe_sessions!="object"||Array.isArray(e.babe_sessions))throw new r('VP response validation failed: "babe_sessions" must be an object');const t=Object.entries(e.babe_sessions);if(t.length===0)throw new r('VP response validation failed: "babe_sessions" must contain at least one challenger entry');for(const[n,o]of t){if(j(n,`babe_sessions["${n}"]`),o===null||typeof o!="object")throw new r(`VP response validation failed: "babe_sessions.${n}" must be an object`);const l=o;if(!f(l.decryptor_artifacts_hex))throw new r(`VP response validation failed: "babe_sessions.${n}.decryptor_artifacts_hex" must be a non-empty hex string, got ${a(l.decryptor_artifacts_hex)}`)}}function W(s){if(s===null||typeof s!="object")throw new r("VP response validation failed: pegout status payload is not an object");const e=s;if(!f(e.pegin_txid)||e.pegin_txid.length!==y)throw new r(`VP response validation failed: "pegin_txid" must be a ${y}-char hex string (txid), got ${a(e.pegin_txid)}`);if(typeof e.found!="boolean")throw new r(`VP response validation failed: "found" must be a boolean, got ${a(e.found)}`);if(e.claimer!==null){if(typeof e.claimer!="object")throw new r(`VP response validation failed: "claimer" must be an object or null, got ${a(e.claimer)}`);J(e.claimer)}if(!Array.isArray(e.challengers))throw new r(`VP response validation failed: "challengers" must be an array, got ${a(e.challengers)}`);for(let t=0;t<e.challengers.length;t++)Z(e.challengers[t],t)}function J(s){if(u(s.status,"claimer.status"),typeof s.failed!="boolean")throw new r(`VP response validation failed: "claimer.failed" must be a boolean, got ${a(s.failed)}`);if(u(s.claim_txid,"claimer.claim_txid"),u(s.claimer_pubkey,"claimer.claimer_pubkey"),u(s.assert_txid,"claimer.assert_txid"),typeof s.created_at!="number")throw new r(`VP response validation failed: "claimer.created_at" must be a number, got ${a(s.created_at)}`);if(typeof s.updated_at!="number")throw new r(`VP response validation failed: "claimer.updated_at" must be a number, got ${a(s.updated_at)}`)}function Z(s,e){if(s===null||typeof s!="object")throw new r(`VP response validation failed: "challengers[${e}]" must be an object, got ${a(s)}`);const t=s;if(u(t.status,`challengers[${e}].status`),u(t.claim_txid,`challengers[${e}].claim_txid`),u(t.claimer_pubkey,`challengers[${e}].claimer_pubkey`),v(t.assert_txid,`challengers[${e}].assert_txid`),v(t.challenge_assert_x_txid,`challengers[${e}].challenge_assert_x_txid`),v(t.challenge_assert_y_txid,`challengers[${e}].challenge_assert_y_txid`),v(t.nopayout_txid,`challengers[${e}].nopayout_txid`),typeof t.created_at!="number")throw new r(`VP response validation failed: "challengers[${e}].created_at" must be a number, got ${a(t.created_at)}`);if(typeof t.updated_at!="number")throw new r(`VP response validation failed: "challengers[${e}].updated_at" must be a number, got ${a(t.updated_at)}`)}function v(s,e){if(s!==null&&typeof s!="string")throw new r(`VP response validation failed: "${e}" must be a string or null, got ${a(s)}`)}function Q(s){G(s,"batchGetPeginStatus",e=>{e.result!==null&&N(e.result)})}function ee(s){G(s,"batchGetPegoutStatus",e=>{e.result!==null&&W(e.result)})}function G(s,e,t){if(s===null||typeof s!="object")throw new r(`VP response validation failed: ${e} response is not an object`);const n=s;if(!Array.isArray(n.results))throw new r(`VP response validation failed: "${e}.results" must be an array, got ${a(n.results)}`);for(let o=0;o<n.results.length;o++){const l=n.results[o];if(l===null||typeof l!="object")throw new r(`VP response validation failed: "${e}.results[${o}]" must be an object, got ${a(l)}`);const i=l;if(!f(i.pegin_txid)||i.pegin_txid.length!==y)throw new r(`VP response validation failed: "${e}.results[${o}].pegin_txid" must be a ${y}-char hex string, got ${a(i.pegin_txid)}`);if(i.error!==null&&typeof i.error!="string")throw new r(`VP response validation failed: "${e}.results[${o}].error" must be a string or null, got ${a(i.error)}`);if(i.result===null&&i.error===null)throw new r(`VP response validation failed: "${e}.results[${o}]" has neither "result" nor "error" populated`);if(i.result!==null&&i.error!==null)throw new r(`VP response validation failed: "${e}.results[${o}]" has both "result" and "error" populated`);try{t(i,o)}catch(p){if(!(p instanceof r))throw p;n.results[o]={pegin_txid:i.pegin_txid,result:null,error:p.detail}}}}function te(s){if(h(s.claim_tx,"depositor_graph.claim_tx"),h(s.assert_tx,"depositor_graph.assert_tx"),h(s.payout_tx,"depositor_graph.payout_tx"),u(s.payout_psbt,"depositor_graph.payout_psbt"),!Array.isArray(s.challenger_presign_data))throw new r('VP response validation failed: "depositor_graph.challenger_presign_data" must be an array');for(let e=0;e<s.challenger_presign_data.length;e++)F(s.challenger_presign_data[e],`depositor_graph.challenger_presign_data[${e}]`);if(typeof s.offchain_params_version!="number")throw new r('VP response validation failed: "depositor_graph.offchain_params_version" must be a number')}const se=6e4;class re{constructor(e,t){S(this,"client");const n={baseUrl:e,timeout:(t==null?void 0:t.timeout)??se,retries:t==null?void 0:t.retries,retryDelay:t==null?void 0:t.retryDelay,retryableFor:t==null?void 0:t.retryableFor,headers:t==null?void 0:t.headers,tokenProvider:t==null?void 0:t.tokenProvider,maxResponseBytes:t==null?void 0:t.maxResponseBytes};this.client=new E.JsonRpcClient(n)}async requestDepositorPresignTransactions(e,t){const n=await this.client.call("vaultProvider_requestDepositorPresignTransactions",e,t);return z(n),n}async submitDepositorPresignatures(e,t){return this.client.call("vaultProvider_submitDepositorPresignatures",e,t)}async submitDepositorWotsKey(e,t){return this.client.call("vaultProvider_submitDepositorWotsKey",e,t)}async requestDepositorClaimerArtifacts(e,t){const n=await this.client.call("vaultProvider_requestDepositorClaimerArtifacts",e,t);return B(n),n}async getPeginStatus(e,t){const n=await this.client.call("vaultProvider_getPeginStatus",e,t);return N(n),n}async batchGetPeginStatus(e,t){const n=await this.client.call("vaultProvider_batchGetPeginStatus",e,t);return Q(n),n}async batchGetPegoutStatus(e,t){var o;const n=await this.client.call("vaultProvider_batchGetPegoutStatus",e,t);ee(n);for(const l of n.results){const i=(o=l.result)==null?void 0:o.claimer;i&&(i.status=E.normalizeClaimerPegoutStatus(i.status))}return n}}function ne(s,e){const t=new Set;for(const d of s)t.add(d.toLowerCase());const n=new Map,o=new Set,l=[],i=[];for(const d of e){const g=d.pegin_txid.toLowerCase();if(!t.has(g)){i.push(g);continue}if(o.has(g)){l.push(g);continue}o.add(g),n.set(g,{result:d.result,error:d.error})}const p=[];for(const d of t)o.has(d)||p.push(d);return{byTxid:n,missing:p,unexpected:i,duplicate:l}}async function ae(s){const{items:e,getTxid:t,batchCall:n,onItem:o,onMissing:l,onDuplicate:i,onDuplicateBatch:p,onWholeBatchError:d,onUnexpected:g,batchSize:w=E.VP_BATCH_MAX_SIZE}=s;if(!Number.isInteger(w)||w<=0)throw new Error(`batchPollByProvider: batchSize must be a positive integer, got ${w}`);for(let P=0;P<e.length;P+=w){const A=e.slice(P,P+w),x=new Map,V=[];for(const c of A){const _=t(c).toLowerCase();x.set(_,c),V.push(_)}let b;try{const c=await n(V);b=ne(V,c.results)}catch(c){d(A,c);continue}g&&b.unexpected.length>0&&g(b.unexpected);const $=new Set(b.duplicate);for(const c of $){const _=x.get(c);_&&i(_)}p&&$.size>0&&p($.size);for(const c of b.missing){const _=x.get(c);_&&l(_)}for(const[c,_]of b.byTxid){if($.has(c))continue;const R=x.get(c);R&&o(R,{pegin_txid:c,result:_.result,error:_.error})}}}exports.VaultProviderRpcClient=re;exports.VpResponseValidationError=r;exports.batchPollByProvider=ae;exports.isUnrecognizedDaemonStatusError=q;exports.validateRequestDepositorClaimerArtifactsResponse=B;
|
|
2
|
-
//# sourceMappingURL=index-EHLYplSd.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-EHLYplSd.cjs","sources":["../src/tbv/core/clients/vault-provider/validators.ts","../src/tbv/core/clients/vault-provider/api.ts","../src/tbv/core/clients/vault-provider/batchAttribution.ts","../src/tbv/core/clients/vault-provider/batchPoll.ts"],"sourcesContent":["/**\n * Runtime validation for vault provider RPC responses.\n *\n * All VP RPC methods return untyped JSON that TypeScript generics cast without\n * inspection. These validators check the critical top-level fields and\n * security-relevant values (status, txids, pubkeys). Optional progress\n * sub-fields (gc_data, ack_collection, claimer_graphs) are NOT validated\n * since they are informational and not used for signing or transaction\n * construction. Only `progress.presigning` sub-fields are checked.\n */\n\nimport { CHALLENGE_ASSERT_CONNECTORS_PER_CHALLENGER } from \"../../primitives/psbt/constants\";\nimport {\n COMPRESSED_PUBKEY_HEX_LEN,\n HEX_RE,\n X_ONLY_PUBKEY_HEX_LEN,\n} from \"../../utils/validation\";\n\nimport type {\n BatchGetPeginStatusResponse,\n BatchGetPegoutStatusResponse,\n GetPeginStatusResponse,\n GetPegoutStatusResponse,\n RequestDepositorClaimerArtifactsResponse,\n RequestDepositorPresignTransactionsResponse,\n} from \"./types\";\nimport { DaemonStatus } from \"./types\";\n\nconst DAEMON_STATUS_VALUES = new Set<string>(Object.values(DaemonStatus));\n\nconst VP_ERROR_PREVIEW_MAX_LEN = 200;\n\nfunction preview(value: unknown): string {\n return (\n JSON.stringify(value)?.slice(0, VP_ERROR_PREVIEW_MAX_LEN) ?? \"undefined\"\n );\n}\n\nconst UNRECOGNIZED_STATUS_ERROR_PREFIX =\n \"VP response validation failed: unrecognized status\";\n\n/**\n * Whether a batch status entry's `error` reports a pegin status outside\n * {@link DaemonStatus}. The batch validator moves such an entry to its\n * `error` slot, so one unknown status does not fail the whole reply.\n */\nexport function isUnrecognizedDaemonStatusError(error: string): boolean {\n return error.startsWith(UNRECOGNIZED_STATUS_ERROR_PREFIX);\n}\n\nconst VP_VALIDATION_USER_MESSAGE =\n \"The vault provider returned an unexpected response. Please try again or contact support.\";\n\n/**\n * Thrown when a VP RPC response fails runtime validation.\n *\n * `.message` is a user-facing string safe to display in the UI.\n * `.detail` contains the technical reason, suitable for logging.\n */\nexport class VpResponseValidationError extends Error {\n readonly detail: string;\n\n constructor(detail: string) {\n super(VP_VALIDATION_USER_MESSAGE);\n this.name = \"VpResponseValidationError\";\n this.detail = detail;\n }\n}\n\n/** Expected length (in hex chars) of a Bitcoin transaction ID (32 bytes). */\nconst TXID_HEX_LEN = 64;\n\n/** Expected length (in hex chars) of a GC output label hash (SHA-256). */\nconst LABEL_HASH_HEX_LEN = 64;\n\nfunction isNonEmptyHex(value: unknown): value is string {\n return typeof value === \"string\" && value.length > 0 && HEX_RE.test(value);\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.length > 0;\n}\n\nfunction assertNonEmptyHex(value: unknown, field: string): void {\n if (!isNonEmptyHex(value)) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${field}\" must be a non-empty hex string, got ${preview(value)}`,\n );\n }\n}\n\nfunction assertNonEmptyString(value: unknown, field: string): void {\n if (!isNonEmptyString(value)) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${field}\" must be a non-empty string, got ${preview(value)}`,\n );\n }\n}\n\n/**\n * Accept both x-only (64-char) and compressed (66-char) pubkeys from VP responses.\n * The signing code normalizes to x-only via processPublicKeyToXOnly().\n */\nfunction assertBtcPubkey(value: unknown, field: string): void {\n if (\n !isNonEmptyHex(value) ||\n (value.length !== X_ONLY_PUBKEY_HEX_LEN &&\n value.length !== COMPRESSED_PUBKEY_HEX_LEN)\n ) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${field}\" must be a ${X_ONLY_PUBKEY_HEX_LEN} or ${COMPRESSED_PUBKEY_HEX_LEN}-char hex string (BTC pubkey), got ${preview(value)}`,\n );\n }\n}\n\n/**\n * Validate the optional presigning progress fields returned inside PeginProgressDetails.\n */\nfunction validatePresigningProgressFields(\n progress: Record<string, unknown>,\n): void {\n const presigning = progress.presigning;\n if (presigning === undefined || presigning === null) return;\n if (typeof presigning !== \"object\" || Array.isArray(presigning)) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"progress.presigning\" must be an object if present`,\n );\n }\n\n const p = presigning as Record<string, unknown>;\n\n if (\n p.depositor_graph_created !== undefined &&\n typeof p.depositor_graph_created !== \"boolean\"\n ) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"progress.presigning.depositor_graph_created\" must be a boolean if present, got ${preview(p.depositor_graph_created)}`,\n );\n }\n\n if (\n p.vk_challenger_presigning_completed !== undefined &&\n typeof p.vk_challenger_presigning_completed !== \"number\"\n ) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"progress.presigning.vk_challenger_presigning_completed\" must be a number if present, got ${preview(p.vk_challenger_presigning_completed)}`,\n );\n }\n\n if (\n p.vk_challenger_presigning_total !== undefined &&\n typeof p.vk_challenger_presigning_total !== \"number\"\n ) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"progress.presigning.vk_challenger_presigning_total\" must be a number if present, got ${preview(p.vk_challenger_presigning_total)}`,\n );\n }\n}\n\n/**\n * Validate a getPeginStatus response.\n *\n * Throws if the status field is not a recognized DaemonStatus value.\n */\nexport function validateGetPeginStatusResponse(\n response: unknown,\n): asserts response is GetPeginStatusResponse {\n if (response === null || typeof response !== \"object\") {\n throw new VpResponseValidationError(\n `VP response validation failed: getPeginStatus response is not an object`,\n );\n }\n\n const r = response as Record<string, unknown>;\n\n if (!isNonEmptyHex(r.pegin_txid) || r.pegin_txid.length !== TXID_HEX_LEN) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"pegin_txid\" must be a ${TXID_HEX_LEN}-char hex string (txid), got ${preview(r.pegin_txid)}`,\n );\n }\n\n if (typeof r.status !== \"string\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"status\" must be a string`,\n );\n }\n\n if (!DAEMON_STATUS_VALUES.has(r.status)) {\n throw new VpResponseValidationError(\n `${UNRECOGNIZED_STATUS_ERROR_PREFIX} ${preview(r.status)}. Expected one of: ${[...DAEMON_STATUS_VALUES].join(\", \")}`,\n );\n }\n\n if (\n r.progress === null ||\n typeof r.progress !== \"object\" ||\n Array.isArray(r.progress)\n ) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"progress\" must be an object`,\n );\n }\n\n validatePresigningProgressFields(r.progress as Record<string, unknown>);\n\n if (typeof r.health_info !== \"string\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"health_info\" must be a string`,\n );\n }\n\n if (r.last_error !== undefined && typeof r.last_error !== \"string\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"last_error\" must be a string if present, got ${preview(r.last_error)}`,\n );\n }\n}\n\n/**\n * Validate a requestDepositorPresignTransactions response.\n */\nexport function validateRequestDepositorPresignTransactionsResponse(\n response: unknown,\n): asserts response is RequestDepositorPresignTransactionsResponse {\n if (response === null || typeof response !== \"object\") {\n throw new VpResponseValidationError(\n `VP response validation failed: requestDepositorPresignTransactions response is not an object`,\n );\n }\n\n const r = response as Record<string, unknown>;\n\n if (!Array.isArray(r.txs)) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"txs\" must be an array`,\n );\n }\n\n for (let i = 0; i < r.txs.length; i++) {\n validateClaimerTransactions(r.txs[i], `txs[${i}]`);\n }\n\n if (r.depositor_graph === null || typeof r.depositor_graph !== \"object\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"depositor_graph\" must be an object`,\n );\n }\n\n validateDepositorGraphTransactions(\n r.depositor_graph as Record<string, unknown>,\n );\n}\n\nfunction validateTransactionData(value: unknown, field: string): void {\n if (value === null || typeof value !== \"object\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${field}\" must be an object`,\n );\n }\n const tx = value as Record<string, unknown>;\n assertNonEmptyHex(tx.tx_hex, `${field}.tx_hex`);\n}\n\nfunction validateClaimerTransactions(value: unknown, field: string): void {\n if (value === null || typeof value !== \"object\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${field}\" must be an object`,\n );\n }\n\n const tx = value as Record<string, unknown>;\n\n assertBtcPubkey(tx.claimer_pubkey, `${field}.claimer_pubkey`);\n validateTransactionData(tx.claim_tx, `${field}.claim_tx`);\n validateTransactionData(tx.assert_tx, `${field}.assert_tx`);\n validateTransactionData(tx.payout_tx, `${field}.payout_tx`);\n assertNonEmptyString(tx.payout_psbt, `${field}.payout_psbt`);\n}\n\nfunction validateChallengeAssertConnectorData(\n value: unknown,\n field: string,\n): void {\n if (value === null || typeof value !== \"object\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${field}\" must be an object`,\n );\n }\n\n const c = value as Record<string, unknown>;\n assertNonEmptyString(c.wots_pks_json, `${field}.wots_pks_json`);\n assertNonEmptyString(c.gc_wots_keys_json, `${field}.gc_wots_keys_json`);\n}\n\nfunction validatePresignDataPerChallenger(value: unknown, field: string): void {\n if (value === null || typeof value !== \"object\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${field}\" must be an object`,\n );\n }\n\n const d = value as Record<string, unknown>;\n\n assertBtcPubkey(d.challenger_pubkey, `${field}.challenger_pubkey`);\n validateTransactionData(\n d.challenge_assert_x_tx,\n `${field}.challenge_assert_x_tx`,\n );\n validateTransactionData(\n d.challenge_assert_y_tx,\n `${field}.challenge_assert_y_tx`,\n );\n validateTransactionData(d.nopayout_tx, `${field}.nopayout_tx`);\n assertNonEmptyString(d.nopayout_psbt, `${field}.nopayout_psbt`);\n\n if (!Array.isArray(d.challenge_assert_connectors)) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${field}.challenge_assert_connectors\" must be an array`,\n );\n }\n\n if (\n d.challenge_assert_connectors.length !==\n CHALLENGE_ASSERT_CONNECTORS_PER_CHALLENGER\n ) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${field}.challenge_assert_connectors\" must have exactly ${CHALLENGE_ASSERT_CONNECTORS_PER_CHALLENGER} entries, got ${d.challenge_assert_connectors.length}`,\n );\n }\n\n for (let i = 0; i < d.challenge_assert_connectors.length; i++) {\n validateChallengeAssertConnectorData(\n d.challenge_assert_connectors[i],\n `${field}.challenge_assert_connectors[${i}]`,\n );\n }\n\n if (!Array.isArray(d.output_label_hashes)) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${field}.output_label_hashes\" must be an array`,\n );\n }\n\n // Each entry is a SHA-256 digest. The presign fingerprint hashes these\n // unframed, so a wrong length must fail here, before any signing prompt.\n for (let i = 0; i < d.output_label_hashes.length; i++) {\n const hash: unknown = d.output_label_hashes[i];\n if (!isNonEmptyHex(hash) || hash.length !== LABEL_HASH_HEX_LEN) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${field}.output_label_hashes[${i}]\" must be a ${LABEL_HASH_HEX_LEN}-char hex string, got ${preview(hash)}`,\n );\n }\n }\n}\n\n/**\n * Validate a requestDepositorClaimerArtifacts response.\n */\nexport function validateRequestDepositorClaimerArtifactsResponse(\n response: unknown,\n): asserts response is RequestDepositorClaimerArtifactsResponse {\n if (response === null || typeof response !== \"object\") {\n throw new VpResponseValidationError(\n `VP response validation failed: requestDepositorClaimerArtifacts response is not an object`,\n );\n }\n\n const r = response as Record<string, unknown>;\n\n if (!isNonEmptyString(r.tx_graph_json)) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"tx_graph_json\" must be a non-empty string, got ${preview(r.tx_graph_json)}`,\n );\n }\n\n if (!isNonEmptyHex(r.verifying_key_hex)) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"verifying_key_hex\" must be a non-empty hex string, got ${preview(r.verifying_key_hex)}`,\n );\n }\n\n if (\n r.babe_sessions === null ||\n typeof r.babe_sessions !== \"object\" ||\n Array.isArray(r.babe_sessions)\n ) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"babe_sessions\" must be an object`,\n );\n }\n\n const sessionEntries = Object.entries(\n r.babe_sessions as Record<string, unknown>,\n );\n if (sessionEntries.length === 0) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"babe_sessions\" must contain at least one challenger entry`,\n );\n }\n\n for (const [key, session] of sessionEntries) {\n assertBtcPubkey(key, `babe_sessions[\"${key}\"]`);\n if (session === null || typeof session !== \"object\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"babe_sessions.${key}\" must be an object`,\n );\n }\n const s = session as Record<string, unknown>;\n if (!isNonEmptyHex(s.decryptor_artifacts_hex)) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"babe_sessions.${key}.decryptor_artifacts_hex\" must be a non-empty hex string, got ${preview(s.decryptor_artifacts_hex)}`,\n );\n }\n }\n}\n\n/**\n * Validate a single pegout status payload. Embedded by\n * `validateBatchGetPegoutStatusResponse`. Mirrors btc-vault\n * `crates/vaultd/src/rpc/server/pegout_status.rs::GetPegoutStatusResponse`.\n */\nexport function validateGetPegoutStatusResponse(\n response: unknown,\n): asserts response is GetPegoutStatusResponse {\n if (response === null || typeof response !== \"object\") {\n throw new VpResponseValidationError(\n `VP response validation failed: pegout status payload is not an object`,\n );\n }\n\n const r = response as Record<string, unknown>;\n\n if (!isNonEmptyHex(r.pegin_txid) || r.pegin_txid.length !== TXID_HEX_LEN) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"pegin_txid\" must be a ${TXID_HEX_LEN}-char hex string (txid), got ${preview(r.pegin_txid)}`,\n );\n }\n\n if (typeof r.found !== \"boolean\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"found\" must be a boolean, got ${preview(r.found)}`,\n );\n }\n\n // `claimer` is `Option<ClaimerPegoutStatus>` server-side; null when absent.\n if (r.claimer !== null) {\n if (typeof r.claimer !== \"object\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"claimer\" must be an object or null, got ${preview(r.claimer)}`,\n );\n }\n validateClaimerPegoutStatus(r.claimer as Record<string, unknown>);\n }\n\n // `challengers: Vec<ChallengerStatus>` server-side; always present (possibly empty).\n if (!Array.isArray(r.challengers)) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"challengers\" must be an array, got ${preview(r.challengers)}`,\n );\n }\n for (let i = 0; i < r.challengers.length; i++) {\n validateChallengerStatus(r.challengers[i], i);\n }\n}\n\nfunction validateClaimerPegoutStatus(value: Record<string, unknown>): void {\n assertNonEmptyString(value.status, \"claimer.status\");\n if (typeof value.failed !== \"boolean\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"claimer.failed\" must be a boolean, got ${preview(value.failed)}`,\n );\n }\n assertNonEmptyString(value.claim_txid, \"claimer.claim_txid\");\n assertNonEmptyString(value.claimer_pubkey, \"claimer.claimer_pubkey\");\n assertNonEmptyString(value.assert_txid, \"claimer.assert_txid\");\n if (typeof value.created_at !== \"number\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"claimer.created_at\" must be a number, got ${preview(value.created_at)}`,\n );\n }\n if (typeof value.updated_at !== \"number\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"claimer.updated_at\" must be a number, got ${preview(value.updated_at)}`,\n );\n }\n}\n\nfunction validateChallengerStatus(value: unknown, index: number): void {\n if (value === null || typeof value !== \"object\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"challengers[${index}]\" must be an object, got ${preview(value)}`,\n );\n }\n const c = value as Record<string, unknown>;\n assertNonEmptyString(c.status, `challengers[${index}].status`);\n assertNonEmptyString(c.claim_txid, `challengers[${index}].claim_txid`);\n assertNonEmptyString(c.claimer_pubkey, `challengers[${index}].claimer_pubkey`);\n assertNullableString(c.assert_txid, `challengers[${index}].assert_txid`);\n assertNullableString(\n c.challenge_assert_x_txid,\n `challengers[${index}].challenge_assert_x_txid`,\n );\n assertNullableString(\n c.challenge_assert_y_txid,\n `challengers[${index}].challenge_assert_y_txid`,\n );\n assertNullableString(c.nopayout_txid, `challengers[${index}].nopayout_txid`);\n if (typeof c.created_at !== \"number\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"challengers[${index}].created_at\" must be a number, got ${preview(c.created_at)}`,\n );\n }\n if (typeof c.updated_at !== \"number\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"challengers[${index}].updated_at\" must be a number, got ${preview(c.updated_at)}`,\n );\n }\n}\n\nfunction assertNullableString(value: unknown, field: string): void {\n if (value !== null && typeof value !== \"string\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${field}\" must be a string or null, got ${preview(value)}`,\n );\n }\n}\n\n/**\n * Validate a `batchGetPeginStatus` response. Per-result envelope shape:\n * `{ pegin_txid, result: GetPeginStatusResponse | null, error: string | null }`.\n * The inner result (when non-null) is validated via the single-item validator.\n * An entry whose inner result fails validation is replaced by an error entry;\n * the other entries are kept.\n */\nexport function validateBatchGetPeginStatusResponse(\n response: unknown,\n): asserts response is BatchGetPeginStatusResponse {\n validateBatchEnvelope(response, \"batchGetPeginStatus\", (entry) => {\n if (entry.result !== null) {\n validateGetPeginStatusResponse(entry.result);\n }\n });\n}\n\n/** Validate a `batchGetPegoutStatus` response. Same envelope as peginStatus. */\nexport function validateBatchGetPegoutStatusResponse(\n response: unknown,\n): asserts response is BatchGetPegoutStatusResponse {\n validateBatchEnvelope(response, \"batchGetPegoutStatus\", (entry) => {\n if (entry.result !== null) {\n validateGetPegoutStatusResponse(entry.result);\n }\n });\n}\n\ninterface BatchResultEnvelope {\n pegin_txid: string;\n result: unknown;\n error: string | null;\n}\n\nfunction validateBatchEnvelope(\n response: unknown,\n rpcName: string,\n validateInnerResult: (entry: BatchResultEnvelope, index: number) => void,\n): void {\n if (response === null || typeof response !== \"object\") {\n throw new VpResponseValidationError(\n `VP response validation failed: ${rpcName} response is not an object`,\n );\n }\n const r = response as Record<string, unknown>;\n if (!Array.isArray(r.results)) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${rpcName}.results\" must be an array, got ${preview(r.results)}`,\n );\n }\n for (let i = 0; i < r.results.length; i++) {\n const entry = r.results[i];\n if (entry === null || typeof entry !== \"object\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${rpcName}.results[${i}]\" must be an object, got ${preview(entry)}`,\n );\n }\n const e = entry as Record<string, unknown>;\n if (\n !isNonEmptyHex(e.pegin_txid) ||\n e.pegin_txid.length !== TXID_HEX_LEN\n ) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${rpcName}.results[${i}].pegin_txid\" must be a ${TXID_HEX_LEN}-char hex string, got ${preview(e.pegin_txid)}`,\n );\n }\n if (e.error !== null && typeof e.error !== \"string\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${rpcName}.results[${i}].error\" must be a string or null, got ${preview(e.error)}`,\n );\n }\n // Exactly one of `result` / `error` must be populated. The server only\n // ever sets one per item; treating both-null as a protocol violation\n // surfaces server bugs early instead of letting them silently degrade.\n if (e.result === null && e.error === null) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${rpcName}.results[${i}]\" has neither \"result\" nor \"error\" populated`,\n );\n }\n if (e.result !== null && e.error !== null) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"${rpcName}.results[${i}]\" has both \"result\" and \"error\" populated`,\n );\n }\n // Isolate a bad inner result to its own entry, so one malformed or\n // unknown-status entry does not void the status of its siblings.\n try {\n validateInnerResult(e as unknown as BatchResultEnvelope, i);\n } catch (error) {\n if (!(error instanceof VpResponseValidationError)) throw error;\n r.results[i] = {\n pegin_txid: e.pegin_txid,\n result: null,\n error: error.detail,\n };\n }\n }\n}\n\nfunction validateDepositorGraphTransactions(\n graph: Record<string, unknown>,\n): void {\n validateTransactionData(graph.claim_tx, \"depositor_graph.claim_tx\");\n validateTransactionData(graph.assert_tx, \"depositor_graph.assert_tx\");\n validateTransactionData(graph.payout_tx, \"depositor_graph.payout_tx\");\n assertNonEmptyString(graph.payout_psbt, \"depositor_graph.payout_psbt\");\n\n if (!Array.isArray(graph.challenger_presign_data)) {\n throw new VpResponseValidationError(\n `VP response validation failed: \"depositor_graph.challenger_presign_data\" must be an array`,\n );\n }\n\n for (let i = 0; i < graph.challenger_presign_data.length; i++) {\n validatePresignDataPerChallenger(\n graph.challenger_presign_data[i],\n `depositor_graph.challenger_presign_data[${i}]`,\n );\n }\n\n if (typeof graph.offchain_params_version !== \"number\") {\n throw new VpResponseValidationError(\n `VP response validation failed: \"depositor_graph.offchain_params_version\" must be a number`,\n );\n }\n}\n","/**\n * JSON-RPC client for the Vault Provider API.\n *\n * Wraps {@link JsonRpcClient} with typed methods matching the\n * `vaultProvider_*` RPC namespace defined in the btc-vault pegin spec.\n *\n * Implements the narrow service interfaces (PeginStatusReader, WotsKeySubmitter,\n * PresignClient, ClaimerArtifactsReader) so it can be passed directly to\n * any deposit protocol service function.\n *\n * @see https://github.com/babylonlabs-io/btc-vault/blob/main/docs/pegin.md\n */\n\nimport type { PeginStatusReader, WotsKeySubmitter, PresignClient, ClaimerArtifactsReader } from \"../../services/deposit/interfaces\";\nimport { normalizeClaimerPegoutStatus } from \"../../services/pegout/state\";\n\nimport {\n type BearerTokenProvider,\n JsonRpcClient,\n type JsonRpcClientConfig,\n} from \"./json-rpc-client\";\nimport type {\n BatchGetPeginStatusParams,\n BatchGetPeginStatusResponse,\n BatchGetPegoutStatusParams,\n BatchGetPegoutStatusResponse,\n GetPeginStatusParams,\n GetPeginStatusResponse,\n RequestDepositorClaimerArtifactsParams,\n RequestDepositorClaimerArtifactsResponse,\n RequestDepositorPresignTransactionsParams,\n RequestDepositorPresignTransactionsResponse,\n SubmitDepositorPresignaturesParams,\n SubmitDepositorWotsKeyParams,\n} from \"./types\";\nimport {\n validateBatchGetPeginStatusResponse,\n validateBatchGetPegoutStatusResponse,\n validateGetPeginStatusResponse,\n validateRequestDepositorClaimerArtifactsResponse,\n validateRequestDepositorPresignTransactionsResponse,\n} from \"./validators\";\n\nexport interface VaultProviderRpcClientOptions {\n /** Timeout in milliseconds per request (default: 60000) */\n timeout?: number;\n /** Number of retry attempts for safe methods (default: 3) */\n retries?: number;\n /** Initial retry delay in milliseconds (default: 1000) */\n retryDelay?: number;\n /**\n * Custom retry predicate. Default retries only the idempotent read\n * methods: `getPeginStatus`, `batchGetPeginStatus`, `batchGetPegoutStatus`,\n * `requestDepositorPresignTransactions`.\n */\n retryableFor?: (method: string) => boolean;\n /** Custom headers. */\n headers?: Record<string, string>;\n /**\n * Per-request bearer-token source. A non-null return attaches\n * `Authorization: Bearer <token>`; `null` skips auth. Wire a\n * {@link VpTokenProvider} for depositor-gated methods.\n */\n tokenProvider?: BearerTokenProvider;\n /** Maximum response body size, in bytes, for typed JSON-RPC calls */\n maxResponseBytes?: number;\n}\n\nconst DEFAULT_TIMEOUT_MS = 60_000;\n\n/**\n * Concrete VP RPC client implementing all service interfaces.\n *\n * Usage:\n * ```ts\n * const client = new VaultProviderRpcClient(\"https://vp.example.com/rpc\");\n * const status = await client.getPeginStatus({ pegin_txid: \"abc...\" });\n * ```\n */\nexport class VaultProviderRpcClient\n implements PeginStatusReader, WotsKeySubmitter, PresignClient, ClaimerArtifactsReader\n{\n private client: JsonRpcClient;\n\n constructor(baseUrl: string, options?: VaultProviderRpcClientOptions) {\n const config: JsonRpcClientConfig = {\n baseUrl,\n timeout: options?.timeout ?? DEFAULT_TIMEOUT_MS,\n retries: options?.retries,\n retryDelay: options?.retryDelay,\n retryableFor: options?.retryableFor,\n headers: options?.headers,\n tokenProvider: options?.tokenProvider,\n maxResponseBytes: options?.maxResponseBytes,\n };\n this.client = new JsonRpcClient(config);\n }\n\n /**\n * Request the payout/claim/assert transactions that the depositor\n * needs to pre-sign before the vault can be activated on Bitcoin.\n */\n async requestDepositorPresignTransactions(\n params: RequestDepositorPresignTransactionsParams,\n signal?: AbortSignal,\n ): Promise<RequestDepositorPresignTransactionsResponse> {\n const response = await this.client.call<\n RequestDepositorPresignTransactionsParams,\n unknown\n >(\"vaultProvider_requestDepositorPresignTransactions\", params, signal);\n validateRequestDepositorPresignTransactionsResponse(response);\n return response;\n }\n\n /**\n * Submit the depositor's pre-signatures for the payout transactions\n * and the depositor-as-claimer graph.\n */\n async submitDepositorPresignatures(\n params: SubmitDepositorPresignaturesParams,\n signal?: AbortSignal,\n ): Promise<void> {\n return this.client.call<SubmitDepositorPresignaturesParams, void>(\n \"vaultProvider_submitDepositorPresignatures\",\n params,\n signal,\n );\n }\n\n /**\n * Submit the depositor's WOTS public key to the vault provider.\n * Called after the pegin is finalized on Ethereum, when the VP is in\n * `PendingDepositorWotsPK` status.\n */\n async submitDepositorWotsKey(\n params: SubmitDepositorWotsKeyParams,\n signal?: AbortSignal,\n ): Promise<void> {\n return this.client.call<SubmitDepositorWotsKeyParams, void>(\n \"vaultProvider_submitDepositorWotsKey\",\n params,\n signal,\n );\n }\n\n /**\n * Request the BaBe DecryptorArtifacts needed for the depositor to\n * independently evaluate garbled circuits during a challenge.\n */\n async requestDepositorClaimerArtifacts(\n params: RequestDepositorClaimerArtifactsParams,\n signal?: AbortSignal,\n ): Promise<RequestDepositorClaimerArtifactsResponse> {\n const response = await this.client.call<\n RequestDepositorClaimerArtifactsParams,\n unknown\n >(\"vaultProvider_requestDepositorClaimerArtifacts\", params, signal);\n validateRequestDepositorClaimerArtifactsResponse(response);\n return response;\n }\n\n /** Get the current pegin status from the vault provider daemon. */\n async getPeginStatus(\n params: GetPeginStatusParams,\n signal?: AbortSignal,\n ): Promise<GetPeginStatusResponse> {\n const response = await this.client.call<GetPeginStatusParams, unknown>(\n \"vaultProvider_getPeginStatus\",\n params,\n signal,\n );\n validateGetPeginStatusResponse(response);\n return response;\n }\n\n /**\n * Get pegin status for many txids in one round trip. Per-result envelope\n * isolates per-pegin failures from the overall RPC. Caller must chunk\n * inputs at `VP_BATCH_MAX_SIZE`.\n */\n async batchGetPeginStatus(\n params: BatchGetPeginStatusParams,\n signal?: AbortSignal,\n ): Promise<BatchGetPeginStatusResponse> {\n const response = await this.client.call<\n BatchGetPeginStatusParams,\n unknown\n >(\"vaultProvider_batchGetPeginStatus\", params, signal);\n validateBatchGetPeginStatusResponse(response);\n return response;\n }\n\n /**\n * Get pegout status for many txids in one round trip. Same per-result\n * envelope semantics as `batchGetPeginStatus`. A legacy claimer status\n * from an older daemon is replaced with its current name.\n */\n async batchGetPegoutStatus(\n params: BatchGetPegoutStatusParams,\n signal?: AbortSignal,\n ): Promise<BatchGetPegoutStatusResponse> {\n const response = await this.client.call<\n BatchGetPegoutStatusParams,\n unknown\n >(\"vaultProvider_batchGetPegoutStatus\", params, signal);\n validateBatchGetPegoutStatusResponse(response);\n for (const entry of response.results) {\n const claimer = entry.result?.claimer;\n if (claimer) claimer.status = normalizeClaimerPegoutStatus(claimer.status);\n }\n return response;\n }\n}\n","/**\n * Defensive helper for attributing per-item results in a VP batch RPC\n * response back to the requested txids. The server promises 1:1 ordered\n * results, but we don't trust that promise — a server bug could duplicate,\n * skip, or scramble items, and silent attribution-by-array-index would\n * mask the bug.\n *\n * Lowercases all txids on both sides to absorb case mismatch (the FE\n * strips `0x` but doesn't otherwise normalize).\n *\n * @module tbv/core/clients/vault-provider/batchAttribution\n */\n\n/** Per-item entry in a VP batch response. */\nexport interface BatchResultEntry<T> {\n pegin_txid: string;\n result: T | null;\n error: string | null;\n}\n\n/** Output of {@link attributeBatchResults}. */\nexport interface BatchAttributionResult<T> {\n /** Lowercase requested txid -> per-item envelope. */\n byTxid: Map<string, { result: T | null; error: string | null }>;\n /** Requested txids that did not appear in the response. */\n missing: string[];\n /** Echoed txids that were not in the request — logged + dropped. */\n unexpected: string[];\n /** Echoed txids that appeared more than once — first kept, rest dropped. */\n duplicate: string[];\n}\n\n/**\n * Attribute batch results to requested txids defensively.\n *\n * Both `requestedTxids` and the echoed `pegin_txid` field on each result\n * are lowercased before lookup. Duplicates and unexpected echoes are\n * surfaced so callers can flag the affected items as errored rather than\n * silently overwriting state.\n *\n * `requestedTxids` may contain duplicates; they are de-duplicated for the\n * purposes of map keys (each unique txid becomes a single map entry).\n */\nexport function attributeBatchResults<T>(\n requestedTxids: string[],\n results: ReadonlyArray<BatchResultEntry<T>>,\n): BatchAttributionResult<T> {\n const requestedSet = new Set<string>();\n for (const txid of requestedTxids) {\n requestedSet.add(txid.toLowerCase());\n }\n\n const byTxid = new Map<\n string,\n { result: T | null; error: string | null }\n >();\n const seen = new Set<string>();\n const duplicate: string[] = [];\n const unexpected: string[] = [];\n\n for (const entry of results) {\n const lower = entry.pegin_txid.toLowerCase();\n if (!requestedSet.has(lower)) {\n unexpected.push(lower);\n continue;\n }\n if (seen.has(lower)) {\n duplicate.push(lower);\n continue;\n }\n seen.add(lower);\n byTxid.set(lower, { result: entry.result, error: entry.error });\n }\n\n const missing: string[] = [];\n for (const txid of requestedSet) {\n if (!seen.has(txid)) missing.push(txid);\n }\n\n return { byTxid, missing, unexpected, duplicate };\n}\n","/**\n * Generic chunk + attribute + dispatch loop for VP batch RPCs.\n *\n * Wraps {@link attributeBatchResults} with chunking and per-callback\n * dispatch so the FE polling hooks (and any future SDK consumer) only\n * have to declare per-item handlers — chunking by `VP_BATCH_MAX_SIZE`,\n * lowercase txid normalization, missing/duplicate/unexpected\n * surfacing, and the duplicate-skip invariant in the byTxid loop are\n * all owned here.\n *\n * @module tbv/core/clients/vault-provider/batchPoll\n */\n\nimport {\n attributeBatchResults,\n type BatchResultEntry,\n} from \"./batchAttribution\";\nimport { VP_BATCH_MAX_SIZE } from \"./types\";\n\nexport interface BatchPollByProviderOptions<TItem, TResult> {\n /** Items to poll for this provider, e.g. `DepositToPoll[]`. */\n items: TItem[];\n /** Extract the canonical txid for each item. Helper lowercases it. */\n getTxid: (item: TItem) => string;\n /**\n * Per-chunk RPC call. Receives lowercased txids; returns the batch\n * envelope. Caller wraps `rpcClient.batchGet*Status({ pegin_txids })`.\n */\n batchCall: (\n txids: string[],\n ) => Promise<{ results: ReadonlyArray<BatchResultEntry<TResult>> }>;\n /**\n * Handle a per-item envelope. Exactly one of `result` / `error` is\n * populated (validator invariant). Caller decides UI state, logging,\n * etc. Not invoked for txids surfaced via {@link onDuplicate}.\n *\n * Note: `envelope.pegin_txid` is the lowercased txid the helper\n * sent in the request, not whatever case/encoding the server echoed.\n */\n onItem: (item: TItem, envelope: BatchResultEntry<TResult>) => void;\n /** Server omitted this item from the response. */\n onMissing: (item: TItem) => void;\n /** Server returned this item more than once. Caller picks UI state. */\n onDuplicate: (item: TItem) => void;\n /**\n * Optional aggregate signal for an entire chunk where the server\n * returned duplicates. Fires once per chunk (only if `count > 0`)\n * AFTER all per-item `onDuplicate` dispatches. Caller typically logs\n * the count alongside the provider name.\n */\n onDuplicateBatch?: (count: number) => void;\n /**\n * The whole chunk's RPC call failed (transport or response\n * validation). Receives the chunk and the error. Caller decides how\n * to project that onto per-item state.\n */\n onWholeBatchError: (chunk: TItem[], error: unknown) => void;\n /**\n * Server returned txids that were not in the request. Caller\n * typically logs the count for observability — there's no recovery\n * action since the original request items are unaffected. Optional;\n * defaults to no-op.\n */\n onUnexpected?: (echoedTxids: string[]) => void;\n /**\n * Maximum items per RPC call. Defaults to {@link VP_BATCH_MAX_SIZE}.\n * Exposed for tests so chunking can be exercised without 50+\n * fixtures.\n */\n batchSize?: number;\n}\n\nexport async function batchPollByProvider<TItem, TResult>(\n options: BatchPollByProviderOptions<TItem, TResult>,\n): Promise<void> {\n const {\n items,\n getTxid,\n batchCall,\n onItem,\n onMissing,\n onDuplicate,\n onDuplicateBatch,\n onWholeBatchError,\n onUnexpected,\n batchSize = VP_BATCH_MAX_SIZE,\n } = options;\n\n if (!Number.isInteger(batchSize) || batchSize <= 0) {\n throw new Error(\n `batchPollByProvider: batchSize must be a positive integer, got ${batchSize}`,\n );\n }\n\n for (let i = 0; i < items.length; i += batchSize) {\n const chunk = items.slice(i, i + batchSize);\n const txidToItem = new Map<string, TItem>();\n const txids: string[] = [];\n for (const item of chunk) {\n const lowerTxid = getTxid(item).toLowerCase();\n txidToItem.set(lowerTxid, item);\n txids.push(lowerTxid);\n }\n\n // Both the RPC call and attribution sit inside the same try/catch\n // so a malformed-batch validator throw is routed through\n // `onWholeBatchError` rather than aborting the polling pass.\n let attribution;\n try {\n const response = await batchCall(txids);\n attribution = attributeBatchResults<TResult>(txids, response.results);\n } catch (error) {\n onWholeBatchError(chunk, error);\n continue;\n }\n\n if (onUnexpected && attribution.unexpected.length > 0) {\n onUnexpected(attribution.unexpected);\n }\n\n const duplicateTxids = new Set(attribution.duplicate);\n for (const txid of duplicateTxids) {\n const item = txidToItem.get(txid);\n if (item) onDuplicate(item);\n }\n if (onDuplicateBatch && duplicateTxids.size > 0) {\n onDuplicateBatch(duplicateTxids.size);\n }\n for (const txid of attribution.missing) {\n const item = txidToItem.get(txid);\n if (item) onMissing(item);\n }\n for (const [txid, envelope] of attribution.byTxid) {\n // Skip duplicates — already dispatched via onDuplicate above.\n if (duplicateTxids.has(txid)) continue;\n const item = txidToItem.get(txid);\n if (!item) continue;\n onItem(item, {\n pegin_txid: txid,\n result: envelope.result,\n error: envelope.error,\n });\n }\n }\n}\n"],"names":["DAEMON_STATUS_VALUES","DaemonStatus","VP_ERROR_PREVIEW_MAX_LEN","preview","value","_a","UNRECOGNIZED_STATUS_ERROR_PREFIX","isUnrecognizedDaemonStatusError","error","VP_VALIDATION_USER_MESSAGE","VpResponseValidationError","detail","__publicField","TXID_HEX_LEN","LABEL_HASH_HEX_LEN","isNonEmptyHex","HEX_RE","isNonEmptyString","assertNonEmptyHex","field","assertNonEmptyString","assertBtcPubkey","X_ONLY_PUBKEY_HEX_LEN","COMPRESSED_PUBKEY_HEX_LEN","validatePresigningProgressFields","progress","presigning","p","validateGetPeginStatusResponse","response","r","validateRequestDepositorPresignTransactionsResponse","i","validateClaimerTransactions","validateDepositorGraphTransactions","validateTransactionData","tx","validateChallengeAssertConnectorData","c","validatePresignDataPerChallenger","d","CHALLENGE_ASSERT_CONNECTORS_PER_CHALLENGER","hash","validateRequestDepositorClaimerArtifactsResponse","sessionEntries","key","session","s","validateGetPegoutStatusResponse","validateClaimerPegoutStatus","validateChallengerStatus","index","assertNullableString","validateBatchGetPeginStatusResponse","validateBatchEnvelope","entry","validateBatchGetPegoutStatusResponse","rpcName","validateInnerResult","e","graph","DEFAULT_TIMEOUT_MS","VaultProviderRpcClient","baseUrl","options","config","JsonRpcClient","params","signal","claimer","normalizeClaimerPegoutStatus","attributeBatchResults","requestedTxids","results","requestedSet","txid","byTxid","seen","duplicate","unexpected","lower","missing","batchPollByProvider","items","getTxid","batchCall","onItem","onMissing","onDuplicate","onDuplicateBatch","onWholeBatchError","onUnexpected","batchSize","VP_BATCH_MAX_SIZE","chunk","txidToItem","txids","item","lowerTxid","attribution","duplicateTxids","envelope"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";var lt=Object.defineProperty;var gt=(t,e,o)=>e in t?lt(t,e,{enumerable:!0,configurable:!0,writable:!0,value:o}):t[e]=o;var b=(t,e,o)=>gt(t,typeof e!="symbol"?e+"":e,o);const E=require("viem"),h=require("./BTCVaultRegistry.abi-BQ5tFNSu.cjs"),I=require("./BTCVaultRegistryKeyEpochs.abi-DCJnzKer.cjs"),V=require("./constants-BTZdyOuk.cjs"),dt=require("./tbv/core/utils/eth/index.cjs"),C=require("./onChainBtcPubkey-BlzxYImF.cjs"),P=require("./secp256k1-DDHQ1_za.cjs"),l=require("./sha2-Ce6KewYx.cjs"),A=25,X=9999;function $(t){if(!Number.isInteger(t)||t<0||t>=V.MAX_VP_COMMISSION_BPS_EXCLUSIVE)throw new Error(`Quoted commissionBps must be an integer in [0, ${V.MAX_VP_COMMISSION_BPS_EXCLUSIVE}), got ${t}`);return Math.min(t+A,X)}const pt=Uint8Array.from([7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8]),z=Uint8Array.from(new Array(16).fill(0).map((t,e)=>e)),ft=z.map(t=>(9*t+5)%16),G=(()=>{const o=[[z],[ft]];for(let n=0;n<4;n++)for(let i of o)i.push(i[n].map(s=>pt[s]));return o})(),Q=G[0],Y=G[1],j=[[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)),Pt=Q.map((t,e)=>t.map(o=>j[e][o])),mt=Y.map((t,e)=>t.map(o=>j[e][o])),bt=Uint32Array.from([0,1518500249,1859775393,2400959708,2840853838]),yt=Uint32Array.from([1352829926,1548603684,1836072691,2053994217,0]);function M(t,e,o,n){return t===0?e^o^n:t===1?e&o|~e&n:t===2?(e|~o)^n:t===3?e&n|o&~n:e^(o|~n)}const T=new Uint32Array(16);class Ct extends l.HashMD{constructor(){super(64,20,8,!0);b(this,"h0",1732584193);b(this,"h1",-271733879);b(this,"h2",-1732584194);b(this,"h3",271733878);b(this,"h4",-1009589776)}get(){const{h0:o,h1:n,h2:i,h3:s,h4:r}=this;return[o,n,i,s,r]}set(o,n,i,s,r){this.h0=o|0,this.h1=n|0,this.h2=i|0,this.h3=s|0,this.h4=r|0}process(o,n){for(let a=0;a<16;a++,n+=4)T[a]=o.getUint32(n,!0);let i=this.h0|0,s=i,r=this.h1|0,c=r,u=this.h2|0,g=u,f=this.h3|0,B=f,m=this.h4|0,w=m;for(let a=0;a<5;a++){const d=4-a,st=bt[a],rt=yt[a],at=Q[a],ct=Y[a],ut=Pt[a],ht=mt[a];for(let p=0;p<16;p++){const S=l.rotl(i+M(a,r,u,f)+T[at[p]]+st,ut[p])+m|0;i=m,m=f,f=l.rotl(u,10)|0,u=r,r=S}for(let p=0;p<16;p++){const S=l.rotl(s+M(d,c,g,B)+T[ct[p]]+rt,ht[p])+w|0;s=w,w=B,B=l.rotl(g,10)|0,g=c,c=S}}this.set(this.h1+u+B|0,this.h2+f+w|0,this.h3+m+s|0,this.h4+i+c|0,this.h0+r+g|0)}roundClean(){l.clean(T)}destroy(){this.destroyed=!0,l.clean(this.buffer),this.set(0,0,0,0,0)}}const Z=l.createHasher(()=>new Ct),Bt="5120",_="0014",Et=20,K=33,wt=65,It=2,Tt=3,Vt=4;function J(t,e){const o=t.startsWith("0x")||t.startsWith("0X")?t.slice(2):t;if(!/^(?:[0-9a-fA-F]{2})+$/.test(o))throw new Error(`${e} must be non-empty, even-length hex`);return`0x${o.toLowerCase()}`}function At(t){const e=l.hexToBytes(t),o=P.schnorr.utils.lift_x(BigInt(`0x${t}`)),n=P.schnorr.utils.bytesToNumberBE(P.schnorr.utils.taggedHash("TapTweak",e));if(n>=P.secp256k1.CURVE.n)throw new Error("Proof of possession BTC pubkey has an invalid TapTweak");const i=n===0n?o:o.add(P.schnorr.Point.BASE.multiply(n));return`0x${Bt}${l.bytesToHex(P.schnorr.utils.pointToBytes(i))}`}function xt(t){const e=J(t,"depositorBtcPubkeyRaw"),o=l.hexToBytes(e.slice(2));if(o.length===32)return{xOnlyPubkey:C.assertOnChainBtcPubkey(e,"Payout BTC pubkey")};const n=o.length===K&&(o[0]===It||o[0]===Tt),i=o.length===wt&&o[0]===Vt;if(!n&&!i)throw new Error("depositorBtcPubkeyRaw must be x-only, compressed, or uncompressed");try{P.secp256k1.Point.fromBytes(o)}catch{throw new Error("depositorBtcPubkeyRaw is not a valid BTC pubkey")}return{xOnlyPubkey:l.bytesToHex(o.subarray(1,K)),compressedPubkey:n?o:void 0}}function St(t){return`0x${_}${l.bytesToHex(Z(l.sha256(t)))}`}function Rt(t,e,o){const n=J(t,"depositorPayoutScriptPubKey");if((n.length-2)/2>V.MAX_PAYOUT_SCRIPT_LEN)throw new Error(`depositorPayoutScriptPubKey exceeds ${V.MAX_PAYOUT_SCRIPT_LEN} bytes`);const i=e.startsWith("0x")||e.startsWith("0X")?e.slice(2):e,s=C.assertOnChainBtcPubkey(`0x${i}`,"Proof of possession BTC pubkey"),r=xt(o);if(r.xOnlyPubkey!==s)throw new Error("depositorBtcPubkeyRaw does not match the proof of possession BTC pubkey");if(n===At(s))return n;if(n.startsWith(`0x${_}`)&&n.length===2+_.length+Et*2){if(!r.compressedPubkey)throw new Error("A P2WPKH payout requires a compressed BTC pubkey");if(n===St(r.compressedPubkey))return n}throw new Error("depositorPayoutScriptPubKey does not match the proof of possession BTC pubkey")}const R=65535,H=1e4,x=4294967295,F=255;function tt(t){if(!Number.isInteger(t)||t<0||t>x)throw new Error(`Invalid offchainParamsVersion from contract: must be a uint32, got ${t}`)}function et(t){const e=[];if(t.timelockAssert<=0n&&e.push(`timelockAssert must be positive, got ${t.timelockAssert}`),t.timelockAssert>BigInt(R)&&e.push(`timelockAssert ${t.timelockAssert} exceeds uint16 max (${R})`),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>R)&&e.push(`proverCircuitVersion must be a uint16, got ${t.proverCircuitVersion}`),(!Number.isInteger(t.minPrepeginDepth)||t.minPrepeginDepth<=0||t.minPrepeginDepth>x)&&e.push(`minPrepeginDepth must be a uint32 in [1, ${x}], 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>H)&&e.push(`minVpCommissionBps must be in [0, ${H}], got ${t.minVpCommissionBps}`),e.length>0)throw new Error(`Invalid offchain protocol parameters: ${e.join("; ")}`)}function ot(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>F)&&e.push(`maxHtlcOutputCount must be an integer in [1, ${F}], 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 vt(t){if(ot(t),et(t.offchainParams),!Number.isInteger(t.offchainParamsVersion)||t.offchainParamsVersion<0||t.offchainParamsVersion>x)throw new Error(`Invalid peg-in configuration: offchainParamsVersion must be a uint32, got ${t.offchainParamsVersion}`);P.assertValidVaultCoreVersion(t.activeVaultCoreVersion,"ProtocolParams.activeVaultCoreVersion()")}const nt="RegistrationLogsUnavailableError";class N extends Error{constructor(o){super(`The Ethereum node returned no registration logs for block ${o}, which holds a vault registration; the node may not have indexed that block yet. Try again.`);b(this,"blockNumber");this.name=nt,this.blockNumber=o}}function kt(t){return t instanceof N?!0:typeof t!="object"||t===null?!1:t.name===nt}const q=9999;function U(t){return{depositor:t.depositor,depositorBtcPubKey:t.depositorBtcPubKey,amount:t.amount,vaultProvider:t.vaultProvider,status:t.status,applicationEntryPoint:t.applicationEntryPoint,createdAt:t.createdAt}}function v(t){const e=Number(t.offchainParamsVersion);return tt(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 $t=1n<<64n,D=0n,_t=[E.getAbiItem({abi:h.BTCVaultRegistryABI,name:"PegInSubmitted"}),E.getAbiItem({abi:h.BTCVaultRegistryABI,name:"PegInSubmittedV2"})];function k(t,e,o){if(t<0n||t>=$t)throw new Error(`getBtcVaultProtocolInfo returned ${e}=${t} for vault ${o}, outside the uint64 range — the registry may predate RFC-006`);return t}function L(t,e){return{vpKeyEpoch:k(t.vpKeyEpoch,"vpKeyEpoch",e),appKeeperKeyEpoch:k(t.appKeeperKeyEpoch,"appKeeperKeyEpoch",e),ucKeyEpoch:k(t.ucKeyEpoch,"ucKeyEpoch",e)}}class it{constructor(e,o){this.publicClient=e,this.contractAddress=o}async getVaultProviderGenesisBtcPubKey(e,o){const n=await this.publicClient.readContract({address:this.contractAddress,abi:h.BTCVaultRegistryABI,functionName:"getOperationBtcKeyAtEpoch",args:[e,D],blockNumber:o});return C.assertOnChainBtcPubkey(n,`getOperationBtcKeyAtEpoch (vp=${e}, epoch=${D})`)}async getVaultProviderApplication(e,o){return await this.publicClient.readContract({address:this.contractAddress,abi:h.BTCVaultRegistryABI,functionName:"getVaultProviderApplication",args:[e],blockNumber:o})}async getCurrentVaultProviderOperationBtcKey(e){const o=await this.publicClient.readContract({address:this.contractAddress,abi:h.BTCVaultRegistryABI,functionName:"getCurrentOperationBtcKey",args:[e]});return C.assertOnChainBtcPubkey(o,`getCurrentOperationBtcKey (vp=${e})`)}async getVaultKeyEpochs(e){const o=await this.publicClient.readContract({address:this.contractAddress,abi:I.BTCVaultRegistryKeyEpochsABI,functionName:"getBtcVaultProtocolInfo",args:[e]});return L(o,e)}async getVaultKeyEpochsBatch(e){return e.length===0?[]:(await this.publicClient.multicall({contracts:e.map(n=>({address:this.contractAddress,abi:I.BTCVaultRegistryKeyEpochsABI,functionName:"getBtcVaultProtocolInfo",args:[n]})),allowFailure:!1})).map((n,i)=>L(n,e[i]))}async getVaultBasicInfo(e){const o=await this.publicClient.readContract({address:this.contractAddress,abi:h.BTCVaultRegistryABI,functionName:"getBtcVaultBasicInfo",args:[e]});return U(o)}async getVaultProtocolInfo(e){const o=await this.publicClient.readContract({address:this.contractAddress,abi:h.BTCVaultRegistryABI,functionName:"getBtcVaultProtocolInfo",args:[e]});return v(o)}async getProtocolInfoBatch(e){return e.length===0?[]:(await this.publicClient.multicall({contracts:e.map(n=>({address:this.contractAddress,abi:h.BTCVaultRegistryABI,functionName:"getBtcVaultProtocolInfo",args:[n]})),allowFailure:!1})).map((n,i)=>{const s=n;if(!s.depositorSignedPeginTx||s.depositorSignedPeginTx==="0x")throw new Error(`Vault ${e[i]} not found on-chain or has no pegin transaction`);return v(s)})}async getPegInFee(e){return await this.publicClient.readContract({address:this.contractAddress,abi:h.BTCVaultRegistryABI,functionName:"getPegInFee",args:[e]})}async getVaultProviderCommission(e){const o=await this.publicClient.readContract({address:this.contractAddress,abi:h.BTCVaultRegistryABI,functionName:"getVaultProviderCommission",args:[e]});if(!Number.isInteger(o)||o<0||o>q)throw new Error(`getVaultProviderCommission returned ${o} bps for ${e}, outside the protocol range [0, ${q}]`);return o}async getVaultData(e){const[o,n]=await this.publicClient.multicall({contracts:[{address:this.contractAddress,abi:h.BTCVaultRegistryABI,functionName:"getBtcVaultBasicInfo",args:[e]},{address:this.contractAddress,abi:h.BTCVaultRegistryABI,functionName:"getBtcVaultProtocolInfo",args:[e]}],allowFailure:!1}),i=U(o),s=v(n);if(!s.depositorSignedPeginTx||s.depositorSignedPeginTx==="0x")throw new Error(`Vault ${e} not found on-chain or has no pegin transaction`);return{basic:i,protocol:s}}async getMaxAcceptableCommissionBpsBatch(e,o){if(e.length===0)return[];const n=await this.publicClient.getLogs({address:this.contractAddress,events:_t,fromBlock:o,toBlock:o,strict:!0});if(n.length===0)throw new N(o);return e.map(i=>{const s=i.toLowerCase();let r=!1;const c=[];for(const u of n)u.args.vaultId.toLowerCase()===s&&(r=!0,u.eventName==="PegInSubmittedV2"&&c.push(u.args.maxAcceptableCommissionBps));if(c.length===1)return c[0];throw c.length>1?new Error(`Expected one PegInSubmittedV2 log for vault ${i} at block ${o}, found ${c.length} PegInSubmittedV2 logs`):r?new Error(`Vault ${i} was registered before the registry emitted the depositor's commission ceiling (no PegInSubmittedV2 log at block ${o}), so the ceiling cannot be recovered on-chain`):new Error(`Vault ${i} has no registration log at its on-chain registration block ${o}`)})}}const Ot=0,Nt=255,Mt=12e4;function y(t,e){const o=t.startsWith("0x")?t:t.startsWith("0X")?`0x${t.slice(2)}`:`0x${t}`;if(!/^0x(?:[0-9a-fA-F]{2})+$/.test(o))throw new Error(`${e} must be non-empty, even-length hex`);return o}function O(t,e){if(!/^0x[0-9a-fA-F]{64}$/.test(t))throw new Error(`${e} must be a 32-byte hex value`)}const Kt="0x0000000000000000000000000000000000000000000000000000000000000000";function W(t){if(O(t,"expectedFingerprint"),t.toLowerCase()===Kt)throw new Error("expectedFingerprint must not be zero: the registry cannot resolve a zero fingerprint, so this submission would always revert")}function Ht(t){if(!Number.isInteger(t)||t<0||t>Nt)throw new Error(`htlcVout must be a uint8, got ${t}`)}class Ft{constructor(e){this.config=e}async registerPeginOnChain(e){const o={...e,popSignature:{...e.popSignature}};this.assertQuotedCommissionPresentWhenRequired(o.quotedCommissionBps),W(o.expectedFingerprint);const n=this.assertPopMatchesEthAccount(o.popSignature),i=this.normalizeBtcPubkey(o.popSignature),s=y(o.popSignature.btcPopSignature,"btcPopSignature"),r=this.normalizeRequest(o,n,i);await this.assertVaultDoesNotExist(r.vaultId,r.peginTxHash);const c=await this.readPeginFee(o.vaultProvider),u=await this.resolveMaxAcceptableCommissionBps(o.vaultProvider,o.quotedCommissionBps),g=E.encodeFunctionData({abi:h.BTCVaultRegistryABI,functionName:"submitPeginRequest",args:[n,i,s,r.unsignedPrePeginTx,r.depositorSignedPeginTx,o.vaultProvider,u,o.hashlock,o.htlcVout,r.payoutScript,o.depositorWotsPkHash,o.expectedFingerprint]});return{ethTxHash:await this.sendAndWait(g,c,!1,n),vaultId:r.vaultId,peginTxHash:r.peginTxHash}}async registerPeginBatchOnChain(e){const o={...e,popSignature:{...e.popSignature},requests:e.requests.map(a=>({...a}))};if(o.requests.length===0)throw new Error("Batch pegin requires at least one request");this.assertQuotedCommissionPresentWhenRequired(o.quotedCommissionBps),W(o.expectedFingerprint);const n=this.assertPopMatchesEthAccount(o.popSignature),i=y(o.unsignedPrePeginTx,"unsignedPrePeginTx"),s=this.normalizeBtcPubkey(o.popSignature),r=y(o.popSignature.btcPopSignature,"btcPopSignature"),c=[],u=[],g=new Set;for(const a of o.requests){const d=this.normalizeRequest({...a,unsignedPrePeginTx:o.unsignedPrePeginTx,vaultProvider:o.vaultProvider,depositorBtcPubkeyRaw:o.depositorBtcPubkeyRaw},n,s);if(g.has(d.vaultId))throw new Error(`Duplicate vault in batch: ${d.vaultId}`);g.add(d.vaultId),c.push({vaultId:d.vaultId,peginTxHash:d.peginTxHash}),u.push({depositorBtcPubKey:s,btcPopSignature:r,unsignedPrePeginTx:i,depositorSignedPeginTx:d.depositorSignedPeginTx,hashlock:a.hashlock,htlcVout:a.htlcVout,referralCode:Ot,depositorPayoutBtcAddress:d.payoutScript,depositorWotsPkHash:a.depositorWotsPkHash})}for(const a of c)await this.assertVaultDoesNotExist(a.vaultId,a.peginTxHash);const f=await this.readPeginFee(o.vaultProvider),B=await this.resolveMaxAcceptableCommissionBps(o.vaultProvider,o.quotedCommissionBps),m=E.encodeFunctionData({abi:h.BTCVaultRegistryABI,functionName:"submitPeginRequestBatch",args:[n,o.vaultProvider,B,o.expectedFingerprint,u]});return{ethTxHash:await this.sendAndWait(m,f*BigInt(o.requests.length),!0,n),vaults:c}}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 o=this.config.ethWallet.account;if(!o)throw new Error("Ethereum wallet account not found");if(!E.isAddressEqual(e,o.address))throw new Error(`Proof of possession was signed for ${e} but the Ethereum wallet is currently connected to ${o.address}. Reconnect the original account or sign a new proof of possession.`);return o.address}normalizeBtcPubkey(e){return`0x${C.assertOnChainBtcPubkey(y(e.depositorBtcPubkey,"Proof of possession BTC pubkey"),"Proof of possession BTC pubkey")}`}normalizeRequest(e,o,n){O(e.hashlock,"hashlock"),O(e.depositorWotsPkHash,"depositorWotsPkHash"),Ht(e.htlcVout);const i=y(e.unsignedPrePeginTx,"unsignedPrePeginTx"),s=y(e.depositorSignedPeginTx,"depositorSignedPeginTx"),r=C.calculateBtcTxHash(s);return{unsignedPrePeginTx:i,depositorSignedPeginTx:s,payoutScript:Rt(e.depositorPayoutScriptPubKey,n,e.depositorBtcPubkeyRaw),peginTxHash:r,vaultId:y(C.derivePeginVaultId(r,o),"vaultId")}}async assertVaultDoesNotExist(e,o){if((await this.config.publicClient.readContract({address:this.config.btcVaultRegistry,abi:h.BTCVaultRegistryABI,functionName:"getBtcVaultBasicInfo",args:[e]})).depositor!==E.zeroAddress)throw new Error(`Vault already exists (ID: ${e}, peginTxHash: ${o}). 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:h.BTCVaultRegistryABI,functionName:"getPegInFee",args:[e]})}catch(o){throw new Error("Failed to query pegin fee from the contract. Please check your network connection and contract address.",{cause:o})}}async resolveMaxAcceptableCommissionBps(e,o){let n;try{n=await new it(this.config.publicClient,this.config.btcVaultRegistry).getVaultProviderCommission(e)}catch(i){throw new Error("Failed to query vault provider commission from the contract. Please check your network connection and contract address.",{cause:i})}if(o!==void 0){if(n>o+A)throw new Error(`Vault provider commission changed since quote: quoted ${o} bps, chain currently reports ${n} bps (allowed drift ${A} bps). Please refresh and try again.`);return $(o)}return $(n)}async sendAndWait(e,o,n,i){let s=this.assertEthAccount(i),r;try{r=await this.config.publicClient.estimateGas({to:this.config.btcVaultRegistry,data:e,value:o,account:s})}catch(g){I.handleContractError(g)}s=this.assertEthAccount(i);let c;try{c=await this.config.ethWallet.sendTransaction({to:this.config.btcVaultRegistry,data:e,value:o,gas:r,account:s,chain:this.config.ethChain})}catch(g){I.handleContractError(g)}const u=await dt.waitForTransactionReceiptSmartAware({publicClient:this.config.publicClient,walletAddress:i,hash:c,timeout:this.config.receiptTimeoutMs??Mt});return u.status==="reverted"&&I.handleContractError(new Error(`${n?"Batch transaction":"Transaction"} reverted. Hash: ${u.transactionHash}. Check a block explorer for details.`)),u.transactionHash}}exports.COMMISSION_BPS_HEADROOM=A;exports.MAX_ACCEPTABLE_COMMISSION_BPS_CAP=X;exports.RegistrationLogsUnavailableError=N;exports.ViemPeginRegistrationClient=Ft;exports.ViemVaultRegistryReader=it;exports.assertValidOffchainParamsVersion=tt;exports.capMaxAcceptableCommissionBps=$;exports.isRegistrationLogsUnavailableError=kt;exports.ripemd160=Z;exports.validateOffchainParams=et;exports.validatePegInConfiguration=vt;exports.validateTBVProtocolParams=ot;
|
|
2
|
-
//# sourceMappingURL=pegin-registration-client-BdJ6c7si.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pegin-registration-client-BdJ6c7si.cjs","sources":["../src/tbv/core/deposit-terms/commissionCeiling.ts","../../../node_modules/.pnpm/@noble+hashes@2.0.1/node_modules/@noble/hashes/legacy.js","../src/tbv/core/clients/eth/payout-script.ts","../src/tbv/core/clients/eth/protocol-params-validation.ts","../src/tbv/core/clients/eth/registration-logs-error.ts","../src/tbv/core/clients/eth/vault-registry-reader.ts","../src/tbv/core/clients/eth/pegin-registration-client.ts"],"sourcesContent":["/**\n * The depositor's commission ceiling (`maxAcceptableCommissionBps`) policy:\n * quoted VP commission + drift headroom, capped below the contract's\n * exclusive bound. Shared by `PeginManager` (the approved terms) and the\n * registration calldata so both carry the same ceiling; a resume rebuild reads\n * that submitted value back from the `PegInSubmittedV2` log instead.\n *\n * @module deposit-terms/commissionCeiling\n */\n\n/*\n * Commission-check map (each guards a DIFFERENT boundary — do not consolidate):\n * 1. assertVpCommissionInProtocolRange (vault app, vaultPayoutSignatureService)\n * — chain-read trust boundary; mirrors VPKeyRegistryLogic.sol bounds.\n * 2. capMaxAcceptableCommissionBps (here) — depositor quote → ceiling policy;\n * mirrors PeginLogic.sol's strict > check via the +25bps headroom.\n * 3. buildDepositTerms range check — public-API precondition on the projection\n * that mints the device-enforced commissionFee.\n * 4. payout.ts commission cap — the VP-built tx's output value vs bps at the\n * signing site (CLAUDE.md Critical Path #3).\n * 5. envelope.ts dust/cross-field gates (ledger-vault-signer) — firmware-only\n * constants, pre-device-I/O (Critical Path #7).\n */\n\nimport { MAX_VP_COMMISSION_BPS_EXCLUSIVE } from \"../primitives/psbt/constants\";\n\n/**\n * Headroom (in basis points) added to the current VP commission to compute\n * `maxAcceptableCommissionBps` at submit time. Lets the VP raise its\n * commission by up to this amount between read and submit without forcing\n * a re-quote. Capped by {@link MAX_ACCEPTABLE_COMMISSION_BPS_CAP}.\n *\n * Contract check is strict `>` (PeginLogic.sol `VaultProviderCommissionExceeded`\n * revert), so +25 allows up\n * to +25 bps of drift.\n */\nexport const COMMISSION_BPS_HEADROOM = 25;\n\n/**\n * Hard ceiling for `maxAcceptableCommissionBps`. The contract enforces\n * `commissionBps < 10000`, so any value at/above that is unreachable;\n * `9999` is the maximum useful cap.\n */\nexport const MAX_ACCEPTABLE_COMMISSION_BPS_CAP = 9999;\n\n/**\n * The commission ceiling submitted as registration calldata and mirrored\n * into `DepositTerms.commissionFee`: quoted + drift headroom, capped.\n * Single source for both consumers — feed it the SAME quoted bps at prepare\n * and register time so device-accept stays coextensive with contract-accept.\n */\nexport function capMaxAcceptableCommissionBps(bps: number): number {\n // Validate the raw quote before headroom shifts its domain — a negative\n // quote must throw here, not become a small \"legal\" ceiling.\n // Reject an out-of-range quote outright — clamping it to 9999 would turn a\n // bad read into a 99.99% ceiling, the exact failure the cap exists to stop.\n if (\n !Number.isInteger(bps) ||\n bps < 0 ||\n bps >= MAX_VP_COMMISSION_BPS_EXCLUSIVE\n ) {\n throw new Error(\n `Quoted commissionBps must be an integer in ` +\n `[0, ${MAX_VP_COMMISSION_BPS_EXCLUSIVE}), got ${bps}`,\n );\n }\n return Math.min(\n bps + COMMISSION_BPS_HEADROOM,\n MAX_ACCEPTABLE_COMMISSION_BPS_CAP,\n );\n}\n","/**\n\nSHA1 (RFC 3174), MD5 (RFC 1321) and RIPEMD160 (RFC 2286) legacy, weak hash functions.\nDon't use them in a new protocol. What \"weak\" means:\n\n- Collisions can be made with 2^18 effort in MD5, 2^60 in SHA1, 2^80 in RIPEMD160.\n- No practical pre-image attacks (only theoretical, 2^123.4)\n- HMAC seems kinda ok: https://www.rfc-editor.org/rfc/rfc6151\n * @module\n */\nimport { Chi, HashMD, Maj } from \"./_md.js\";\nimport { clean, createHasher, rotl } from \"./utils.js\";\n/** Initial SHA1 state */\nconst SHA1_IV = /* @__PURE__ */ Uint32Array.from([\n 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0,\n]);\n// Reusable temporary buffer\nconst SHA1_W = /* @__PURE__ */ new Uint32Array(80);\n/** Internal SHA1 legacy hash class. */\nexport class _SHA1 extends HashMD {\n A = SHA1_IV[0] | 0;\n B = SHA1_IV[1] | 0;\n C = SHA1_IV[2] | 0;\n D = SHA1_IV[3] | 0;\n E = SHA1_IV[4] | 0;\n constructor() {\n super(64, 20, 8, false);\n }\n get() {\n const { A, B, C, D, E } = this;\n return [A, B, C, D, E];\n }\n set(A, B, C, D, E) {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n this.E = E | 0;\n }\n process(view, offset) {\n for (let i = 0; i < 16; i++, offset += 4)\n SHA1_W[i] = view.getUint32(offset, false);\n for (let i = 16; i < 80; i++)\n SHA1_W[i] = rotl(SHA1_W[i - 3] ^ SHA1_W[i - 8] ^ SHA1_W[i - 14] ^ SHA1_W[i - 16], 1);\n // Compression function main loop, 80 rounds\n let { A, B, C, D, E } = this;\n for (let i = 0; i < 80; i++) {\n let F, K;\n if (i < 20) {\n F = Chi(B, C, D);\n K = 0x5a827999;\n }\n else if (i < 40) {\n F = B ^ C ^ D;\n K = 0x6ed9eba1;\n }\n else if (i < 60) {\n F = Maj(B, C, D);\n K = 0x8f1bbcdc;\n }\n else {\n F = B ^ C ^ D;\n K = 0xca62c1d6;\n }\n const T = (rotl(A, 5) + F + E + K + SHA1_W[i]) | 0;\n E = D;\n D = C;\n C = rotl(B, 30);\n B = A;\n A = T;\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n E = (E + this.E) | 0;\n this.set(A, B, C, D, E);\n }\n roundClean() {\n clean(SHA1_W);\n }\n destroy() {\n this.set(0, 0, 0, 0, 0);\n clean(this.buffer);\n }\n}\n/** SHA1 (RFC 3174) legacy hash function. It was cryptographically broken. */\nexport const sha1 = /* @__PURE__ */ createHasher(() => new _SHA1());\n/** Per-round constants */\nconst p32 = /* @__PURE__ */ Math.pow(2, 32);\nconst K = /* @__PURE__ */ Array.from({ length: 64 }, (_, i) => Math.floor(p32 * Math.abs(Math.sin(i + 1))));\n/** md5 initial state: same as sha1, but 4 u32 instead of 5. */\nconst MD5_IV = /* @__PURE__ */ SHA1_IV.slice(0, 4);\n// Reusable temporary buffer\nconst MD5_W = /* @__PURE__ */ new Uint32Array(16);\n/** Internal MD5 legacy hash class. */\nexport class _MD5 extends HashMD {\n A = MD5_IV[0] | 0;\n B = MD5_IV[1] | 0;\n C = MD5_IV[2] | 0;\n D = MD5_IV[3] | 0;\n constructor() {\n super(64, 16, 8, true);\n }\n get() {\n const { A, B, C, D } = this;\n return [A, B, C, D];\n }\n set(A, B, C, D) {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n }\n process(view, offset) {\n for (let i = 0; i < 16; i++, offset += 4)\n MD5_W[i] = view.getUint32(offset, true);\n // Compression function main loop, 64 rounds\n let { A, B, C, D } = this;\n for (let i = 0; i < 64; i++) {\n let F, g, s;\n if (i < 16) {\n F = Chi(B, C, D);\n g = i;\n s = [7, 12, 17, 22];\n }\n else if (i < 32) {\n F = Chi(D, B, C);\n g = (5 * i + 1) % 16;\n s = [5, 9, 14, 20];\n }\n else if (i < 48) {\n F = B ^ C ^ D;\n g = (3 * i + 5) % 16;\n s = [4, 11, 16, 23];\n }\n else {\n F = C ^ (B | ~D);\n g = (7 * i) % 16;\n s = [6, 10, 15, 21];\n }\n F = F + A + K[i] + MD5_W[g];\n A = D;\n D = C;\n C = B;\n B = B + rotl(F, s[i % 4]);\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n this.set(A, B, C, D);\n }\n roundClean() {\n clean(MD5_W);\n }\n destroy() {\n this.set(0, 0, 0, 0);\n clean(this.buffer);\n }\n}\n/**\n * MD5 (RFC 1321) legacy hash function. It was cryptographically broken.\n * MD5 architecture is similar to SHA1, with some differences:\n * - Reduced output length: 16 bytes (128 bit) instead of 20\n * - 64 rounds, instead of 80\n * - Little-endian: could be faster, but will require more code\n * - Non-linear index selection: huge speed-up for unroll\n * - Per round constants: more memory accesses, additional speed-up for unroll\n */\nexport const md5 = /* @__PURE__ */ createHasher(() => new _MD5());\n// RIPEMD-160\nconst Rho160 = /* @__PURE__ */ Uint8Array.from([\n 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,\n]);\nconst Id160 = /* @__PURE__ */ (() => Uint8Array.from(new Array(16).fill(0).map((_, i) => i)))();\nconst Pi160 = /* @__PURE__ */ (() => Id160.map((i) => (9 * i + 5) % 16))();\nconst idxLR = /* @__PURE__ */ (() => {\n const L = [Id160];\n const R = [Pi160];\n const res = [L, R];\n for (let i = 0; i < 4; i++)\n for (let j of res)\n j.push(j[i].map((k) => Rho160[k]));\n return res;\n})();\nconst idxL = /* @__PURE__ */ (() => idxLR[0])();\nconst idxR = /* @__PURE__ */ (() => idxLR[1])();\n// const [idxL, idxR] = idxLR;\nconst shifts160 = /* @__PURE__ */ [\n [11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8],\n [12, 13, 11, 15, 6, 9, 9, 7, 12, 15, 11, 13, 7, 8, 7, 7],\n [13, 15, 14, 11, 7, 7, 6, 8, 13, 14, 13, 12, 5, 5, 6, 9],\n [14, 11, 12, 14, 8, 6, 5, 5, 15, 12, 15, 14, 9, 9, 8, 6],\n [15, 12, 13, 13, 9, 5, 8, 6, 14, 11, 12, 11, 8, 6, 5, 5],\n].map((i) => Uint8Array.from(i));\nconst shiftsL160 = /* @__PURE__ */ idxL.map((idx, i) => idx.map((j) => shifts160[i][j]));\nconst shiftsR160 = /* @__PURE__ */ idxR.map((idx, i) => idx.map((j) => shifts160[i][j]));\nconst Kl160 = /* @__PURE__ */ Uint32Array.from([\n 0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e,\n]);\nconst Kr160 = /* @__PURE__ */ Uint32Array.from([\n 0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000,\n]);\n// It's called f() in spec.\nfunction ripemd_f(group, x, y, z) {\n if (group === 0)\n return x ^ y ^ z;\n if (group === 1)\n return (x & y) | (~x & z);\n if (group === 2)\n return (x | ~y) ^ z;\n if (group === 3)\n return (x & z) | (y & ~z);\n return x ^ (y | ~z);\n}\n// Reusable temporary buffer\nconst BUF_160 = /* @__PURE__ */ new Uint32Array(16);\nexport class _RIPEMD160 extends HashMD {\n h0 = 0x67452301 | 0;\n h1 = 0xefcdab89 | 0;\n h2 = 0x98badcfe | 0;\n h3 = 0x10325476 | 0;\n h4 = 0xc3d2e1f0 | 0;\n constructor() {\n super(64, 20, 8, true);\n }\n get() {\n const { h0, h1, h2, h3, h4 } = this;\n return [h0, h1, h2, h3, h4];\n }\n set(h0, h1, h2, h3, h4) {\n this.h0 = h0 | 0;\n this.h1 = h1 | 0;\n this.h2 = h2 | 0;\n this.h3 = h3 | 0;\n this.h4 = h4 | 0;\n }\n process(view, offset) {\n for (let i = 0; i < 16; i++, offset += 4)\n BUF_160[i] = view.getUint32(offset, true);\n // prettier-ignore\n let al = this.h0 | 0, ar = al, bl = this.h1 | 0, br = bl, cl = this.h2 | 0, cr = cl, dl = this.h3 | 0, dr = dl, el = this.h4 | 0, er = el;\n // Instead of iterating 0 to 80, we split it into 5 groups\n // And use the groups in constants, functions, etc. Much simpler\n for (let group = 0; group < 5; group++) {\n const rGroup = 4 - group;\n const hbl = Kl160[group], hbr = Kr160[group]; // prettier-ignore\n const rl = idxL[group], rr = idxR[group]; // prettier-ignore\n const sl = shiftsL160[group], sr = shiftsR160[group]; // prettier-ignore\n for (let i = 0; i < 16; i++) {\n const tl = (rotl(al + ripemd_f(group, bl, cl, dl) + BUF_160[rl[i]] + hbl, sl[i]) + el) | 0;\n al = el, el = dl, dl = rotl(cl, 10) | 0, cl = bl, bl = tl; // prettier-ignore\n }\n // 2 loops are 10% faster\n for (let i = 0; i < 16; i++) {\n const tr = (rotl(ar + ripemd_f(rGroup, br, cr, dr) + BUF_160[rr[i]] + hbr, sr[i]) + er) | 0;\n ar = er, er = dr, dr = rotl(cr, 10) | 0, cr = br, br = tr; // prettier-ignore\n }\n }\n // Add the compressed chunk to the current hash value\n this.set((this.h1 + cl + dr) | 0, (this.h2 + dl + er) | 0, (this.h3 + el + ar) | 0, (this.h4 + al + br) | 0, (this.h0 + bl + cr) | 0);\n }\n roundClean() {\n clean(BUF_160);\n }\n destroy() {\n this.destroyed = true;\n clean(this.buffer);\n this.set(0, 0, 0, 0, 0);\n }\n}\n/**\n * RIPEMD-160 - a legacy hash function from 1990s.\n * * https://homes.esat.kuleuven.be/~bosselae/ripemd160.html\n * * https://homes.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf\n */\nexport const ripemd160 = /* @__PURE__ */ createHasher(() => new _RIPEMD160());\n//# sourceMappingURL=legacy.js.map","import { schnorr, secp256k1 } from \"@noble/curves/secp256k1.js\";\nimport { ripemd160 } from \"@noble/hashes/legacy.js\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport { bytesToHex, hexToBytes } from \"@noble/hashes/utils.js\";\nimport type { Hex } from \"viem\";\n\nimport { MAX_PAYOUT_SCRIPT_LEN } from \"../../primitives/psbt/constants\";\nimport { assertOnChainBtcPubkey } from \"./onChainBtcPubkey\";\n\nconst P2TR_SCRIPT_PREFIX = \"5120\";\nconst P2WPKH_SCRIPT_PREFIX = \"0014\";\nconst HASH160_BYTES = 20;\nconst COMPRESSED_PUBKEY_BYTES = 33;\nconst UNCOMPRESSED_PUBKEY_BYTES = 65;\nconst SEC1_EVEN_Y_PREFIX = 0x02;\nconst SEC1_ODD_Y_PREFIX = 0x03;\nconst SEC1_UNCOMPRESSED_PREFIX = 0x04;\n\nfunction normalizeHex(value: string, label: string): Hex {\n const body =\n value.startsWith(\"0x\") || value.startsWith(\"0X\") ? value.slice(2) : value;\n if (!/^(?:[0-9a-fA-F]{2})+$/.test(body)) {\n throw new Error(`${label} must be non-empty, even-length hex`);\n }\n return `0x${body.toLowerCase()}`;\n}\n\nfunction deriveP2trScript(xOnlyPubkey: string): Hex {\n const pubkeyBytes = hexToBytes(xOnlyPubkey);\n const internalKey = schnorr.utils.lift_x(BigInt(`0x${xOnlyPubkey}`));\n const tweak = schnorr.utils.bytesToNumberBE(\n schnorr.utils.taggedHash(\"TapTweak\", pubkeyBytes),\n );\n if (tweak >= secp256k1.CURVE.n) {\n throw new Error(\"Proof of possession BTC pubkey has an invalid TapTweak\");\n }\n const outputKey =\n tweak === 0n\n ? internalKey\n : internalKey.add(schnorr.Point.BASE.multiply(tweak));\n return `0x${P2TR_SCRIPT_PREFIX}${bytesToHex(\n schnorr.utils.pointToBytes(outputKey),\n )}`;\n}\n\nfunction normalizePayoutPubkey(value: string): {\n xOnlyPubkey: string;\n compressedPubkey?: Uint8Array;\n} {\n const normalized = normalizeHex(value, \"depositorBtcPubkeyRaw\");\n const pubkey = hexToBytes(normalized.slice(2));\n if (pubkey.length === 32) {\n return {\n xOnlyPubkey: assertOnChainBtcPubkey(normalized, \"Payout BTC pubkey\"),\n };\n }\n const isCompressed =\n pubkey.length === COMPRESSED_PUBKEY_BYTES &&\n (pubkey[0] === SEC1_EVEN_Y_PREFIX || pubkey[0] === SEC1_ODD_Y_PREFIX);\n const isUncompressed =\n pubkey.length === UNCOMPRESSED_PUBKEY_BYTES &&\n pubkey[0] === SEC1_UNCOMPRESSED_PREFIX;\n if (!isCompressed && !isUncompressed) {\n throw new Error(\n \"depositorBtcPubkeyRaw must be x-only, compressed, or uncompressed\",\n );\n }\n try {\n secp256k1.Point.fromBytes(pubkey);\n } catch {\n throw new Error(\"depositorBtcPubkeyRaw is not a valid BTC pubkey\");\n }\n return {\n xOnlyPubkey: bytesToHex(pubkey.subarray(1, COMPRESSED_PUBKEY_BYTES)),\n compressedPubkey: isCompressed ? pubkey : undefined,\n };\n}\n\nfunction deriveP2wpkhScript(pubkey: Uint8Array): Hex {\n return `0x${P2WPKH_SCRIPT_PREFIX}${bytesToHex(ripemd160(sha256(pubkey)))}`;\n}\n\n/** Verify the irreversible payout script at the final submission boundary. */\nexport function assertPayoutScriptMatchesPopKey(\n scriptPubKey: string,\n depositorBtcPubkey: string,\n depositorBtcPubkeyRaw: string,\n): Hex {\n const payoutScript = normalizeHex(\n scriptPubKey,\n \"depositorPayoutScriptPubKey\",\n );\n if ((payoutScript.length - 2) / 2 > MAX_PAYOUT_SCRIPT_LEN) {\n throw new Error(\n `depositorPayoutScriptPubKey exceeds ${MAX_PAYOUT_SCRIPT_LEN} bytes`,\n );\n }\n const keyBody =\n depositorBtcPubkey.startsWith(\"0x\") || depositorBtcPubkey.startsWith(\"0X\")\n ? depositorBtcPubkey.slice(2)\n : depositorBtcPubkey;\n const xOnlyPubkey = assertOnChainBtcPubkey(\n `0x${keyBody}` as Hex,\n \"Proof of possession BTC pubkey\",\n );\n const payoutPubkey = normalizePayoutPubkey(depositorBtcPubkeyRaw);\n if (payoutPubkey.xOnlyPubkey !== xOnlyPubkey) {\n throw new Error(\n \"depositorBtcPubkeyRaw does not match the proof of possession BTC pubkey\",\n );\n }\n\n if (payoutScript === deriveP2trScript(xOnlyPubkey)) {\n return payoutScript;\n }\n if (\n payoutScript.startsWith(`0x${P2WPKH_SCRIPT_PREFIX}`) &&\n payoutScript.length ===\n 2 + P2WPKH_SCRIPT_PREFIX.length + HASH160_BYTES * 2\n ) {\n if (!payoutPubkey.compressedPubkey) {\n throw new Error(\"A P2WPKH payout requires a compressed BTC pubkey\");\n }\n if (payoutScript === deriveP2wpkhScript(payoutPubkey.compressedPubkey)) {\n return payoutScript;\n }\n }\n throw new Error(\n \"depositorPayoutScriptPubKey does not match the proof of possession BTC pubkey\",\n );\n}\n","/**\n * Validation for protocol parameters fetched from the ProtocolParams contract.\n *\n * These values feed Bitcoin script construction and deposit validation.\n * Invalid params must be caught before they reach transaction-building code,\n * since errors after wallet signing prompts are unrecoverable.\n *\n * The {@link ViemProtocolParamsReader} runs these on every read; consumers\n * implementing their own reader against the same `ProtocolParamsReader`\n * interface should call them too.\n */\n\nimport { assertValidVaultCoreVersion } from \"../../primitives/vaultCoreVersion\";\n\nimport type {\n PegInConfiguration,\n TBVProtocolParams,\n VersionedOffchainParams,\n} from \"./types\";\n\n/**\n * Maximum value for a Solidity uint16.\n * PeginLogic.sol casts timelockAssert to uint16, so values above this are invalid.\n */\nconst UINT16_MAX = 65535;\n\n/** Maximum valid value for basis points (100%) */\nconst MAX_BASIS_POINTS = 10000;\n\n/** Maximum value for a Solidity uint32. */\nconst UINT32_MAX = 4_294_967_295;\n\n/** Maximum valid value for a uint8 (e.g. maxHtlcOutputCount). */\nconst UINT8_MAX = 255;\n\n/**\n * Validate an `offchainParamsVersion` value sourced from a contract read.\n * `Number()` on a malformed payload yields `NaN` or a non-integer; both\n * silently break consumers that loop `1..version` or use the value as a\n * map key. Used by reader entry points that surface the version to JS.\n */\nexport function assertValidOffchainParamsVersion(version: number): void {\n if (\n !Number.isInteger(version) ||\n version < 0 ||\n version > UINT32_MAX\n ) {\n throw new Error(\n `Invalid offchainParamsVersion from contract: must be a uint32, got ${version}`,\n );\n }\n}\n\n/**\n * Validate offchain params consistency and bounds.\n * @throws Error on invalid values to prevent constructing invalid Bitcoin scripts.\n */\nexport function validateOffchainParams(params: VersionedOffchainParams): void {\n const errors: string[] = [];\n\n if (params.timelockAssert <= 0n) {\n errors.push(\n `timelockAssert must be positive, got ${params.timelockAssert}`,\n );\n }\n if (params.timelockAssert > BigInt(UINT16_MAX)) {\n errors.push(\n `timelockAssert ${params.timelockAssert} exceeds uint16 max (${UINT16_MAX})`,\n );\n }\n\n if (params.timelockChallengeAssert <= 0n) {\n errors.push(\n `timelockChallengeAssert must be positive, got ${params.timelockChallengeAssert}`,\n );\n }\n\n if (params.tRefund <= 0) {\n errors.push(`tRefund must be positive, got ${params.tRefund}`);\n }\n\n if (params.tStale <= 0) {\n errors.push(`tStale must be positive, got ${params.tStale}`);\n }\n\n if (params.securityCouncilKeys.length === 0) {\n errors.push(\"securityCouncilKeys must not be empty\");\n }\n\n if (params.councilQuorum <= 0) {\n errors.push(`councilQuorum must be positive, got ${params.councilQuorum}`);\n }\n if (params.councilQuorum > params.securityCouncilKeys.length) {\n errors.push(\n `councilQuorum (${params.councilQuorum}) exceeds securityCouncilKeys count (${params.securityCouncilKeys.length})`,\n );\n }\n\n if (params.feeRate <= 0n) {\n errors.push(`feeRate must be positive, got ${params.feeRate}`);\n }\n\n if (params.minPeginFeeRate <= 0n) {\n errors.push(\n `minPeginFeeRate must be positive, got ${params.minPeginFeeRate}`,\n );\n }\n\n if (\n !Number.isInteger(params.proverCircuitVersion) ||\n params.proverCircuitVersion < 0 ||\n params.proverCircuitVersion > UINT16_MAX\n ) {\n errors.push(\n `proverCircuitVersion must be a uint16, got ${params.proverCircuitVersion}`,\n );\n }\n\n if (\n !Number.isInteger(params.minPrepeginDepth) ||\n params.minPrepeginDepth <= 0 ||\n params.minPrepeginDepth > UINT32_MAX\n ) {\n errors.push(\n `minPrepeginDepth must be a uint32 in [1, ${UINT32_MAX}], got ${params.minPrepeginDepth}`,\n );\n }\n\n if (params.babeTotalInstances <= 0) {\n errors.push(\n `babeTotalInstances must be positive, got ${params.babeTotalInstances}`,\n );\n }\n if (params.babeInstancesToFinalize <= 0) {\n errors.push(\n `babeInstancesToFinalize must be positive, got ${params.babeInstancesToFinalize}`,\n );\n }\n if (params.babeInstancesToFinalize > params.babeTotalInstances) {\n errors.push(\n `babeInstancesToFinalize (${params.babeInstancesToFinalize}) exceeds babeTotalInstances (${params.babeTotalInstances})`,\n );\n }\n\n if (\n params.minVpCommissionBps < 0 ||\n params.minVpCommissionBps > MAX_BASIS_POINTS\n ) {\n errors.push(\n `minVpCommissionBps must be in [0, ${MAX_BASIS_POINTS}], got ${params.minVpCommissionBps}`,\n );\n }\n\n if (errors.length > 0) {\n throw new Error(\n `Invalid offchain protocol parameters: ${errors.join(\"; \")}`,\n );\n }\n}\n\n/**\n * Validate TBV protocol params returned from the contract.\n * @throws Error on invalid amounts or out-of-range bounded fields.\n */\nexport function validateTBVProtocolParams(params: TBVProtocolParams): void {\n const errors: string[] = [];\n\n if (params.minimumPegInAmount <= 0n) {\n errors.push(\n `minimumPegInAmount must be positive, got ${params.minimumPegInAmount}`,\n );\n }\n\n if (params.maxPegInAmount < params.minimumPegInAmount) {\n errors.push(\n `maxPegInAmount (${params.maxPegInAmount}) must be >= minimumPegInAmount (${params.minimumPegInAmount})`,\n );\n }\n\n if (params.pegInAckTimeout <= 0n) {\n errors.push(\n `pegInAckTimeout must be positive, got ${params.pegInAckTimeout}`,\n );\n }\n\n if (params.pegInActivationTimeout <= 0n) {\n errors.push(\n `pegInActivationTimeout must be positive, got ${params.pegInActivationTimeout}`,\n );\n }\n\n if (\n !Number.isInteger(params.maxHtlcOutputCount) ||\n params.maxHtlcOutputCount <= 0 ||\n params.maxHtlcOutputCount > UINT8_MAX\n ) {\n errors.push(\n `maxHtlcOutputCount must be an integer in [1, ${UINT8_MAX}], got ${params.maxHtlcOutputCount}`,\n );\n }\n\n if (\n typeof params.expiredPegInGraceBlocks !== \"bigint\" ||\n params.expiredPegInGraceBlocks <= 0n\n ) {\n errors.push(\n `expiredPegInGraceBlocks must be a positive bigint, got ${params.expiredPegInGraceBlocks}`,\n );\n }\n\n if (errors.length > 0) {\n throw new Error(`Invalid TBV protocol parameters: ${errors.join(\"; \")}`);\n }\n}\n\n/**\n * Validate the full peg-in configuration after assembly.\n * Checks both TBV params and offchain params consistency, and the\n * top-level `offchainParamsVersion` (which originates from a separate\n * multicall result and so must be range-checked alongside the params it\n * names).\n */\nexport function validatePegInConfiguration(config: PegInConfiguration): void {\n validateTBVProtocolParams(config);\n validateOffchainParams(config.offchainParams);\n\n if (\n !Number.isInteger(config.offchainParamsVersion) ||\n config.offchainParamsVersion < 0 ||\n config.offchainParamsVersion > UINT32_MAX\n ) {\n throw new Error(\n `Invalid peg-in configuration: offchainParamsVersion must be a uint32, got ${config.offchainParamsVersion}`,\n );\n }\n\n // The contract enforces ≥ 1 (setter rejects 0); a 0 here means a\n // mis-decoded read or a pre-vaultCoreVersion contract — fail closed.\n assertValidVaultCoreVersion(\n config.activeVaultCoreVersion,\n \"ProtocolParams.activeVaultCoreVersion()\",\n );\n}\n","/**\n * Transient failure of a registration-log read.\n *\n * Every registered vault has its `PegInSubmitted` log in its `createdAt`\n * block, so an Ethereum node answering that block's registration-log query\n * with no logs at all did not serve the block — load-balanced public RPCs\n * answer `[]` for a block a backend lacks instead of erroring, which viem's\n * transport retry cannot see (it retries errors only). Callers may retry.\n *\n * @module clients/eth/registration-logs-error\n */\n\n/** The `name` this error carries, so a foreign module instance still matches. */\nexport const REGISTRATION_LOGS_UNAVAILABLE_ERROR_NAME =\n \"RegistrationLogsUnavailableError\";\n\nexport class RegistrationLogsUnavailableError extends Error {\n readonly blockNumber: bigint;\n\n constructor(blockNumber: bigint) {\n super(\n `The Ethereum node returned no registration logs for block ${blockNumber}, ` +\n `which holds a vault registration; the node may not have indexed that ` +\n `block yet. Try again.`,\n );\n this.name = REGISTRATION_LOGS_UNAVAILABLE_ERROR_NAME;\n this.blockNumber = blockNumber;\n }\n}\n\n/** Matches `instanceof` OR the documented `name` (dual module instances). */\nexport function isRegistrationLogsUnavailableError(\n err: unknown,\n): err is RegistrationLogsUnavailableError {\n if (err instanceof RegistrationLogsUnavailableError) return true;\n if (typeof err !== \"object\" || err === null) return false;\n return (\n (err as { name?: unknown }).name ===\n REGISTRATION_LOGS_UNAVAILABLE_ERROR_NAME\n );\n}\n","/**\n * Concrete BTCVaultRegistry reader using viem's readContract.\n *\n * This is an optional utility — callers can use their own implementation\n * of the VaultRegistryReader interface.\n */\n\nimport type { Abi, Address, Hex, PublicClient } from \"viem\";\nimport { getAbiItem } from \"viem\";\n\nimport { BTCVaultRegistryABI } from \"../../contracts/abis/BTCVaultRegistry.abi\";\nimport { BTCVaultRegistryKeyEpochsABI } from \"../../contracts/abis/BTCVaultRegistryKeyEpochs.abi\";\nimport { assertOnChainBtcPubkey } from \"./onChainBtcPubkey\";\nimport { assertValidOffchainParamsVersion } from \"./protocol-params-validation\";\nimport { RegistrationLogsUnavailableError } from \"./registration-logs-error\";\nimport type {\n KeyEpochs,\n OnChainBtcPubkey,\n VaultBasicInfo,\n VaultData,\n VaultProtocolInfo,\n VaultRegistryReader,\n} from \"./types\";\n\n/**\n * Inclusive upper bound the BTCVaultRegistry contract enforces on a vault\n * provider's commission (the contract check is `< 10000`).\n */\nconst MAX_VP_COMMISSION_BPS = 9999;\n\n/** Raw `getBtcVaultBasicInfo` tuple as decoded by viem. */\ntype RawVaultBasicInfo = {\n depositor: Address;\n depositorBtcPubKey: Hex;\n amount: bigint;\n vaultProvider: Address;\n status: number;\n applicationEntryPoint: Address;\n createdAt: bigint;\n};\n\n/**\n * Raw `getBtcVaultProtocolInfo` tuple as decoded by viem.\n *\n * Mirrors the ABI's components except `claimExpiredUntil`, which nothing\n * consumes: it is the post-expiry grace deadline for `claimExpired`, scoped to\n * vaults that expired without activating, and it is not a deadline on the\n * depositor's claim right. The ABI still declares it — the decode is\n * positional, so removing it there would shift `vaultCoreVersion`.\n */\ntype RawVaultProtocolInfo = {\n depositorSignedPeginTx: Hex;\n universalChallengersVersion: number;\n appVaultKeepersVersion: number;\n offchainParamsVersion: number;\n verifiedAt: bigint;\n depositorWotsPkHash: Hex;\n hashlock: Hex;\n htlcVout: number;\n depositorPopSignature: Hex;\n prePeginTxHash: Hex;\n vaultProviderCommissionBps: number;\n vaultCoreVersion: number;\n};\n\nfunction mapVaultBasicInfo(result: RawVaultBasicInfo): VaultBasicInfo {\n return {\n depositor: result.depositor,\n depositorBtcPubKey: result.depositorBtcPubKey,\n amount: result.amount,\n vaultProvider: result.vaultProvider,\n status: result.status,\n applicationEntryPoint: result.applicationEntryPoint,\n createdAt: result.createdAt,\n };\n}\n\nfunction mapVaultProtocolInfo(result: RawVaultProtocolInfo): VaultProtocolInfo {\n const offchainParamsVersion = Number(result.offchainParamsVersion);\n assertValidOffchainParamsVersion(offchainParamsVersion);\n return {\n depositorSignedPeginTx: result.depositorSignedPeginTx,\n universalChallengersVersion: result.universalChallengersVersion,\n appVaultKeepersVersion: result.appVaultKeepersVersion,\n offchainParamsVersion,\n verifiedAt: result.verifiedAt,\n depositorWotsPkHash: result.depositorWotsPkHash,\n hashlock: result.hashlock,\n htlcVout: result.htlcVout,\n depositorPopSignature: result.depositorPopSignature,\n prePeginTxHash: result.prePeginTxHash,\n vaultProviderCommissionBps: result.vaultProviderCommissionBps,\n vaultCoreVersion: result.vaultCoreVersion,\n };\n}\n\n/**\n * Exclusive upper bound for a `uint64` epoch.\n *\n * viem does not range-check a decoded `uint64`, so a misaligned decode can\n * hand back a value far larger than the field can hold. Rejecting those is\n * cheap defence in depth against a mis-decode of the extended ABI.\n *\n * The state this is load-bearing for is narrower than \"a registry that predates\n * RFC-006\". Against a *fully* pre-RFC-006 registry the path fails closed on its\n * own: `resolveParticipantKeysAtEpochs` goes on to call\n * `getOperationBtcKeyAtEpochOrGenesis` on ApplicationRegistry and\n * ProtocolParams, which do not exist there, so the multicall reverts and these\n * epochs are never used. The reachable gap is a registry that *has* the\n * operation-key getters but whose `BTCVaultProtocolInfo` struct is not\n * extended — there the tail-data epochs resolve with no error at all, and this\n * range check is the only thing looking at them.\n *\n * Even for that case it is only a backstop, and a weak one: a misaligned decode\n * can land on a small, plausible-looking integer this range accepts. Correctness\n * rests on only ever pointing at an RFC-006 registry, which is a deployment\n * precondition rather than something this call can establish — see\n * https://github.com/babylonlabs-io/babylon-toolkit/issues/2192 for where that\n * check is owned, and `BTCVaultRegistryKeyEpochs.abi.ts` for the decode hazard.\n */\nconst UINT64_EXCLUSIVE_UPPER_BOUND = 1n << 64n;\n\n/**\n * The epoch a vault provider's registration key is bonded at.\n *\n * A provider's operation-key history is append-only and every appended version\n * is stamped at epoch 1 or later, so epoch 0 always resolves to the key set at\n * registration. This is what lets `getOperationBtcKeyAtEpoch` stand in for the\n * removed `getVaultProviderBTCKey` getter.\n */\nconst VP_GENESIS_KEY_EPOCH = 0n;\n\n/**\n * Both registration events, queried together so one answer settles whether a\n * vault's V2 log is missing (pre-upgrade registration) or the node served no\n * logs for the block at all.\n */\nconst PEGIN_SUBMITTED_EVENTS = [\n getAbiItem({ abi: BTCVaultRegistryABI, name: \"PegInSubmitted\" }),\n getAbiItem({ abi: BTCVaultRegistryABI, name: \"PegInSubmittedV2\" }),\n] as const;\n\nfunction assertEpochInRange(\n value: bigint,\n field: string,\n vaultId: Hex,\n): bigint {\n if (value < 0n || value >= UINT64_EXCLUSIVE_UPPER_BOUND) {\n throw new Error(\n `getBtcVaultProtocolInfo returned ${field}=${value} for vault ${vaultId}, ` +\n `outside the uint64 range — the registry may predate RFC-006`,\n );\n }\n return value;\n}\n\nfunction mapKeyEpochs(result: KeyEpochs, vaultId: Hex): KeyEpochs {\n return {\n vpKeyEpoch: assertEpochInRange(result.vpKeyEpoch, \"vpKeyEpoch\", vaultId),\n appKeeperKeyEpoch: assertEpochInRange(\n result.appKeeperKeyEpoch,\n \"appKeeperKeyEpoch\",\n vaultId,\n ),\n ucKeyEpoch: assertEpochInRange(result.ucKeyEpoch, \"ucKeyEpoch\", vaultId),\n };\n}\n\n/**\n * Concrete vault registry reader using viem.\n *\n * Usage:\n * ```ts\n * const reader = new ViemVaultRegistryReader(publicClient, registryAddress);\n * const data = await reader.getVaultData(vaultId);\n * ```\n */\nexport class ViemVaultRegistryReader implements VaultRegistryReader {\n constructor(\n private publicClient: PublicClient,\n private contractAddress: Address,\n ) {}\n\n /**\n * Read the VP's **genesis** (registration) x-only BTC pubkey — the key bonded\n * at version 0, which never moves when the operator rotates.\n *\n * Resolved as \"the operation key at epoch 0\" rather than through the\n * dedicated `getVaultProviderBTCKey` getter, which\n * https://github.com/babylonlabs-io/vault-contracts-aave-v4/pull/539 removes.\n * Epoch 0 predates any rotation — appended versions are stamped at epoch 1 or\n * later — so it resolves to the registration key, and the contracts team has\n * confirmed that is a property we can rely on rather than an implementation\n * detail. The devnet comparison behind that claim — both getters returning the\n * identical key for a provider that *has* rotated, while\n * `getCurrentOperationBtcKey` differed — is recorded in\n * https://github.com/babylonlabs-io/babylon-toolkit/issues/2188.\n *\n * This makes the read RFC-006-only, where the removed getter also existed on a\n * legacy registry. That costs nothing: every caller of this method already\n * resolves participant keys through `OperationKeyReader`, so all of them\n * require an RFC-006 registry regardless.\n *\n * Validates length, hex form, and secp256k1 curve membership before minting\n * the brand. Returns 64-char lowercase hex without the `0x` prefix.\n */\n async getVaultProviderGenesisBtcPubKey(\n vpAddress: Address,\n blockNumber?: bigint,\n ): Promise<OnChainBtcPubkey> {\n const result = (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getOperationBtcKeyAtEpoch\",\n args: [vpAddress, VP_GENESIS_KEY_EPOCH],\n blockNumber,\n })) as Hex;\n return assertOnChainBtcPubkey(\n result,\n `getOperationBtcKeyAtEpoch (vp=${vpAddress}, epoch=${VP_GENESIS_KEY_EPOCH})`,\n );\n }\n\n /**\n * Read the application entry point a vault provider is registered for.\n *\n * This is the registry's own `vaultProviders[vp].applicationEntryPoint`, and\n * it is the value the peg-in submit path resolves internally — it selects\n * which application's vault-keeper roster, roster version and keeper key\n * epoch a deposit is bonded to. The dApp separately carries an entry point\n * from its own configuration; the two agree today, but they are different\n * sources of truth, so the build path reads this one and asserts the\n * configured value matches it rather than trusting either alone.\n */\n async getVaultProviderApplication(\n vpAddress: Address,\n blockNumber?: bigint,\n ): Promise<Address> {\n return (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getVaultProviderApplication\",\n args: [vpAddress],\n blockNumber,\n })) as Address;\n }\n\n /**\n * Read a vault provider's *current* RFC-006 operation BTC key.\n *\n * Falls back on-chain to the registration key when the provider has never\n * rotated, so this returns the same value as\n * `getVaultProviderGenesisBtcPubKey` until the first rotation.\n *\n * This is the key the VP's server signs its BIP-322 auth tokens with — a\n * live per-operator identity, not a per-vault binding, so the auth pin uses\n * the current key rather than any vault's frozen epoch.\n */\n async getCurrentVaultProviderOperationBtcKey(\n vpAddress: Address,\n ): Promise<OnChainBtcPubkey> {\n const result = (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getCurrentOperationBtcKey\",\n args: [vpAddress],\n })) as Hex;\n return assertOnChainBtcPubkey(\n result,\n `getCurrentOperationBtcKey (vp=${vpAddress})`,\n );\n }\n\n /**\n * Read a vault's frozen RFC-006 operation-key epochs.\n *\n * Reads `getBtcVaultProtocolInfo` through the **extended** ABI, which is only\n * valid against an RFC-006 registry: against one whose `BTCVaultProtocolInfo`\n * struct is not extended this call does not fail for a populated vault, it\n * silently returns three words of tail data as epochs. Nothing here can detect\n * that, so the guarantee is a deployment one — every network this ships to has\n * the RFC-006 getters, and mainnet is a fresh RFC-006 deploy.\n *\n * A registry missing the operation-key getters entirely is the *safer* of the\n * two cases: `resolveParticipantKeysAtEpochs` reverts downstream and these\n * epochs never reach key resolution. See {@link UINT64_EXCLUSIVE_UPPER_BOUND}\n * for which state the range check actually guards, and\n * `BTCVaultRegistryKeyEpochs.abi.ts` for the decode hazard.\n */\n async getVaultKeyEpochs(vaultId: Hex): Promise<KeyEpochs> {\n const result = (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryKeyEpochsABI,\n functionName: \"getBtcVaultProtocolInfo\",\n args: [vaultId],\n })) as unknown as KeyEpochs;\n\n return mapKeyEpochs(result, vaultId);\n }\n\n async getVaultKeyEpochsBatch(vaultIds: readonly Hex[]): Promise<KeyEpochs[]> {\n if (vaultIds.length === 0) return [];\n\n const results = await this.publicClient.multicall({\n contracts: vaultIds.map((vaultId) => ({\n address: this.contractAddress,\n abi: BTCVaultRegistryKeyEpochsABI as Abi,\n functionName: \"getBtcVaultProtocolInfo\" as const,\n args: [vaultId] as const,\n })),\n allowFailure: false,\n });\n\n return results.map((info, i) =>\n mapKeyEpochs(info as unknown as KeyEpochs, vaultIds[i]),\n );\n }\n\n async getVaultBasicInfo(vaultId: Hex): Promise<VaultBasicInfo> {\n const result = (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getBtcVaultBasicInfo\",\n args: [vaultId],\n })) as RawVaultBasicInfo;\n\n return mapVaultBasicInfo(result);\n }\n\n async getVaultProtocolInfo(vaultId: Hex): Promise<VaultProtocolInfo> {\n const result = (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getBtcVaultProtocolInfo\",\n args: [vaultId],\n })) as RawVaultProtocolInfo;\n\n return mapVaultProtocolInfo(result);\n }\n\n async getProtocolInfoBatch(\n vaultIds: readonly Hex[],\n ): Promise<VaultProtocolInfo[]> {\n if (vaultIds.length === 0) return [];\n\n const results = await this.publicClient.multicall({\n contracts: vaultIds.map((vaultId) => ({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI as Abi,\n functionName: \"getBtcVaultProtocolInfo\" as const,\n args: [vaultId] as const,\n })),\n allowFailure: false,\n });\n\n return results.map((info, i) => {\n const result = info as unknown as RawVaultProtocolInfo;\n if (\n !result.depositorSignedPeginTx ||\n result.depositorSignedPeginTx === \"0x\"\n ) {\n // An empty record is not proof the vault is absent: a lagging RPC\n // node returns HTTP 200 with a zero struct, so no retry below this\n // layer can see it. Single-shot is only safe because the finality\n // gate (`waitForPeginRegistrationDepth`) runs first on the deposit\n // path — move this ahead of it and the read-after-write race returns.\n // The vault app matches this message to render \"still confirming\".\n throw new Error(\n `Vault ${vaultIds[i]} not found on-chain or has no pegin transaction`,\n );\n }\n return mapVaultProtocolInfo(result);\n });\n }\n\n /**\n * Read the protocol pegin fee (in wei) for a given vault provider.\n * Mirrors the `getPegInFee(address)` view on BTCVaultRegistry.\n */\n async getPegInFee(vaultProvider: Address): Promise<bigint> {\n return (await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getPegInFee\",\n args: [vaultProvider],\n })) as bigint;\n }\n\n /**\n * Read a vault provider's current commission in basis points from\n * BTCVaultRegistry. The contract enforces `commissionBps < 10000`, so the\n * legitimate range is `[0, 9999]`; anything outside indicates a wrong\n * contract address or ABI drift and is surfaced as an error rather than\n * trusted.\n */\n async getVaultProviderCommission(vaultProvider: Address): Promise<number> {\n // viem infers `number` from the `uint16` return in the `as const` ABI.\n const bps = await this.publicClient.readContract({\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getVaultProviderCommission\",\n args: [vaultProvider],\n });\n\n if (!Number.isInteger(bps) || bps < 0 || bps > MAX_VP_COMMISSION_BPS) {\n throw new Error(\n `getVaultProviderCommission returned ${bps} bps for ${vaultProvider}, ` +\n `outside the protocol range [0, ${MAX_VP_COMMISSION_BPS}]`,\n );\n }\n\n return bps;\n }\n\n async getVaultData(vaultId: Hex): Promise<VaultData> {\n // One round-trip for both structs (hard-fail): they feed signing/refund/\n // broadcast rebinds, so reading them in a single multicall also pins both\n // to the same block — no basic/protocol skew across two `eth_call`s.\n const [basicRaw, protocolRaw] = await this.publicClient.multicall({\n contracts: [\n {\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getBtcVaultBasicInfo\",\n args: [vaultId],\n },\n {\n address: this.contractAddress,\n abi: BTCVaultRegistryABI,\n functionName: \"getBtcVaultProtocolInfo\",\n args: [vaultId],\n },\n ],\n allowFailure: false,\n });\n\n const basic = mapVaultBasicInfo(basicRaw);\n const protocol = mapVaultProtocolInfo(protocolRaw);\n\n if (\n !protocol.depositorSignedPeginTx ||\n protocol.depositorSignedPeginTx === \"0x\"\n ) {\n throw new Error(\n `Vault ${vaultId} not found on-chain or has no pegin transaction`,\n );\n }\n\n return { basic, protocol };\n }\n\n /**\n * Read the depositor's commission ceiling (`maxAcceptableCommissionBps`)\n * for vaults registered in the same block, from their `PegInSubmittedV2`\n * logs. Returned in `vaultIds` order.\n *\n * The contract bound-checks the ceiling and discards it (PeginLogic.sol,\n * `VaultProviderCommissionExceeded`), so the registration log is its only\n * on-chain source. One query at exactly `createdAt` — the `block.number`\n * stamped at registration — so no block-range scan is needed and public-RPC\n * range caps do not apply. Vault ids are matched case-insensitively.\n *\n * @throws {RegistrationLogsUnavailableError} (transient, retry) when the\n * node answers with no registration logs for the block at all.\n * @throws when a vault has only its `PegInSubmitted` log — registrations\n * that predate the V2 event (vault-contracts-aave-v4 #548) never emitted\n * the ceiling — no registration log in its own `createdAt` block, or more\n * than one V2 log.\n */\n async getMaxAcceptableCommissionBpsBatch(\n vaultIds: readonly Hex[],\n createdAt: bigint,\n ): Promise<number[]> {\n if (vaultIds.length === 0) return [];\n\n // Deliberately no `vaultId` topic filter: both events must come back in\n // ONE answer for the empty-vs-missing discriminator below to hold, and\n // viem's multi-event form takes no `args` — so the block's registration\n // logs are fetched whole and ids are matched client-side. strict: a log\n // whose data does not decode against the ABI is dropped (viem\n // parseEventLogs) instead of surfacing as `args: {}`.\n const logs = await this.publicClient.getLogs({\n address: this.contractAddress,\n events: PEGIN_SUBMITTED_EVENTS,\n fromBlock: createdAt,\n toBlock: createdAt,\n strict: true,\n });\n if (logs.length === 0) {\n throw new RegistrationLogsUnavailableError(createdAt);\n }\n\n return vaultIds.map((vaultId) => {\n const vaultIdLower = vaultId.toLowerCase();\n let registered = false;\n const ceilings: number[] = [];\n for (const log of logs) {\n if (log.args.vaultId.toLowerCase() !== vaultIdLower) continue;\n registered = true;\n if (log.eventName === \"PegInSubmittedV2\") {\n ceilings.push(log.args.maxAcceptableCommissionBps);\n }\n }\n\n if (ceilings.length === 1) return ceilings[0];\n if (ceilings.length > 1) {\n throw new Error(\n `Expected one PegInSubmittedV2 log for vault ${vaultId} at block ${createdAt}, ` +\n `found ${ceilings.length} PegInSubmittedV2 logs`,\n );\n }\n if (registered) {\n throw new Error(\n `Vault ${vaultId} was registered before the registry emitted the depositor's ` +\n `commission ceiling (no PegInSubmittedV2 log at block ${createdAt}), so the ` +\n `ceiling cannot be recovered on-chain`,\n );\n }\n throw new Error(\n `Vault ${vaultId} has no registration log at its on-chain registration block ${createdAt}`,\n );\n });\n }\n}\n","import {\n encodeFunctionData,\n isAddressEqual,\n zeroAddress,\n type Address,\n type Chain,\n type Hex,\n type PublicClient,\n type WalletClient,\n} from \"viem\";\n\nimport { BTCVaultRegistryABI } from \"../../contracts/abis/BTCVaultRegistry.abi\";\nimport { handleContractError } from \"../../contracts/errors\";\nimport {\n capMaxAcceptableCommissionBps,\n COMMISSION_BPS_HEADROOM,\n} from \"../../deposit-terms/commissionCeiling\";\nimport { waitForTransactionReceiptSmartAware } from \"../../utils/eth\";\nimport { assertOnChainBtcPubkey } from \"./onChainBtcPubkey\";\nimport { assertPayoutScriptMatchesPopKey } from \"./payout-script\";\nimport { calculateBtcTxHash, derivePeginVaultId } from \"./pegin-transaction\";\nimport { ViemVaultRegistryReader } from \"./vault-registry-reader\";\n\n/** Referral code sent with peg-in registration. Zero means no referral. */\nexport const NO_REFERRAL_CODE = 0;\nconst UINT8_MAX = 255;\n// Match the prior vault-service timeout. A dropped transaction must not wait forever.\nconst RECEIPT_TIMEOUT_MS = 120_000;\n\nfunction ensureHex(value: string, label: string): Hex {\n const prefixed = value.startsWith(\"0x\")\n ? value\n : value.startsWith(\"0X\")\n ? `0x${value.slice(2)}`\n : `0x${value}`;\n if (!/^0x(?:[0-9a-fA-F]{2})+$/.test(prefixed)) {\n throw new Error(`${label} must be non-empty, even-length hex`);\n }\n return prefixed as Hex;\n}\n\nfunction assertBytes32(value: Hex, label: string): void {\n if (!/^0x[0-9a-fA-F]{64}$/.test(value)) {\n throw new Error(`${label} must be a 32-byte hex value`);\n }\n}\n\n/** All-zero `bytes32` — the shape an unresolved fingerprint takes. */\nconst ZERO_BYTES32 =\n \"0x0000000000000000000000000000000000000000000000000000000000000000\";\n\n/**\n * The single validation point for `expectedFingerprint`, on both the singular\n * and batch paths.\n *\n * Zero is rejected separately from the shape check because it is a *well-formed*\n * `bytes32` that the registry can never accept — the live fingerprint is a\n * keccak256 over a domain-separated preimage — so it can only ever mean the\n * caller had no value and filled the slot. Catching it here turns a defaulted\n * field into a named error instead of an opaque on-chain revert with two\n * hashes and no hint.\n */\nfunction assertFingerprint(value: Hex): void {\n assertBytes32(value, \"expectedFingerprint\");\n if (value.toLowerCase() === ZERO_BYTES32) {\n throw new Error(\n \"expectedFingerprint must not be zero: the registry cannot resolve a \" +\n \"zero fingerprint, so this submission would always revert\",\n );\n }\n}\n\nfunction assertHtlcVout(value: number): void {\n if (!Number.isInteger(value) || value < 0 || value > UINT8_MAX) {\n throw new Error(`htlcVout must be a uint8, got ${value}`);\n }\n}\n\n/** A PoP prepared by a Bitcoin wallet, reusable by the ETH submit client. */\nexport interface PopSignature {\n btcPopSignature: Hex;\n depositorEthAddress: Address;\n /** x-only secp256k1 public key, 64 hex chars without `0x`. */\n depositorBtcPubkey: string;\n}\n\nexport interface ViemPeginRegistrationClientConfig {\n ethWallet: WalletClient;\n ethChain: Chain;\n publicClient: PublicClient;\n btcVaultRegistry: Address;\n receiptTimeoutMs?: number;\n /**\n * Refuse to register without a `quotedCommissionBps`. Set it to `true` when\n * the depositor approved deposit terms on a device: approval froze the\n * commission ceiling from the quote, so the chain-current fallback could\n * admit a commission the device would later refuse to pay out.\n *\n * Required, with no default: an omitted flag would silently pick the unsafe\n * direction for the integrator least able to probe the wallet capability.\n */\n requireQuotedCommissionBps: boolean;\n}\n\nexport interface RegisterPeginOnChainParams {\n unsignedPrePeginTx: string;\n depositorSignedPeginTx: string;\n vaultProvider: Address;\n hashlock: Hex;\n depositorWotsPkHash: Hex;\n popSignature: PopSignature;\n /** Raw x-only, compressed, or uncompressed BTC pubkey from the PoP wallet. */\n depositorBtcPubkeyRaw: string;\n htlcVout: number;\n /**\n * Bitcoin output script bytes, not an address. The client verifies that the\n * script pays the proof-of-possession key before it submits the transaction.\n */\n depositorPayoutScriptPubKey: string;\n quotedCommissionBps?: number;\n /**\n * `keccak256(abi.encode(...))` over the protocol state the Pre-PegIn was\n * built against — see the SDK's `pegin-fingerprint` module.\n *\n * The registry recomputes it live at inclusion and reverts with\n * `PeginFingerprintChanged` on any difference, so it must be computed from\n * the same block-pinned snapshot that shaped the Bitcoin scripts. Required,\n * with no default: a fingerprint the caller did not resolve is not a\n * fingerprint, and the registry has no way to tell the two apart.\n */\n expectedFingerprint: Hex;\n}\n\nexport interface PeginRegistrationResult {\n ethTxHash: Hex;\n vaultId: Hex;\n peginTxHash: Hex;\n}\n\nexport interface BatchPeginRegistrationItem {\n depositorSignedPeginTx: string;\n hashlock: Hex;\n htlcVout: number;\n /**\n * Bitcoin output script bytes, not an address. The client verifies that the\n * script pays the proof-of-possession key before it submits the transaction.\n */\n depositorPayoutScriptPubKey: string;\n depositorWotsPkHash: Hex;\n}\n\nexport interface RegisterPeginBatchOnChainParams {\n vaultProvider: Address;\n unsignedPrePeginTx: string;\n requests: BatchPeginRegistrationItem[];\n popSignature: PopSignature;\n /** Raw x-only, compressed, or uncompressed BTC pubkey from the PoP wallet. */\n depositorBtcPubkeyRaw: string;\n quotedCommissionBps?: number;\n /**\n * See {@link RegisterPeginOnChainParams.expectedFingerprint}. One value for\n * the whole batch: the fingerprint takes no per-request input and a batch\n * fixes one vault provider, so every entry would resolve the same value.\n */\n expectedFingerprint: Hex;\n}\n\nexport interface BatchPeginRegistrationResultItem {\n vaultId: Hex;\n peginTxHash: Hex;\n}\n\nexport interface PeginBatchRegistrationResult {\n ethTxHash: Hex;\n vaults: BatchPeginRegistrationResultItem[];\n}\n\n/**\n * Ethereum-only client for the on-chain half of peg-in registration.\n *\n * It consumes Bitcoin artifacts that were prepared earlier, but owns no BTC\n * wallet and imports neither Bitcoin libraries nor the Rust/WASM package.\n */\nexport class ViemPeginRegistrationClient {\n constructor(private readonly config: ViemPeginRegistrationClientConfig) {}\n\n async registerPeginOnChain(\n params: RegisterPeginOnChainParams,\n ): Promise<PeginRegistrationResult> {\n const request = {\n ...params,\n popSignature: { ...params.popSignature },\n };\n this.assertQuotedCommissionPresentWhenRequired(request.quotedCommissionBps);\n // Second, matching the batch path, so the two public entry points validate\n // in the same order and neither can drift behind a chain call.\n assertFingerprint(request.expectedFingerprint);\n const depositor = this.assertPopMatchesEthAccount(request.popSignature);\n const depositorBtcPubkey = this.normalizeBtcPubkey(request.popSignature);\n const btcPopSignature = ensureHex(\n request.popSignature.btcPopSignature,\n \"btcPopSignature\",\n );\n const normalized = this.normalizeRequest(\n request,\n depositor,\n depositorBtcPubkey,\n );\n\n await this.assertVaultDoesNotExist(\n normalized.vaultId,\n normalized.peginTxHash,\n );\n const peginFee = await this.readPeginFee(request.vaultProvider);\n const maxCommission = await this.resolveMaxAcceptableCommissionBps(\n request.vaultProvider,\n request.quotedCommissionBps,\n );\n const callData = encodeFunctionData({\n abi: BTCVaultRegistryABI,\n functionName: \"submitPeginRequest\",\n args: [\n depositor,\n depositorBtcPubkey,\n btcPopSignature,\n normalized.unsignedPrePeginTx,\n normalized.depositorSignedPeginTx,\n request.vaultProvider,\n maxCommission,\n request.hashlock,\n request.htlcVout,\n normalized.payoutScript,\n request.depositorWotsPkHash,\n // Appended last on the singular overload; the batch takes it at\n // position 4 instead. Order is the selector, so do not \"tidy\" either.\n request.expectedFingerprint,\n ],\n });\n\n const ethTxHash = await this.sendAndWait(\n callData,\n peginFee,\n false,\n depositor,\n );\n return {\n ethTxHash,\n vaultId: normalized.vaultId,\n peginTxHash: normalized.peginTxHash,\n };\n }\n\n async registerPeginBatchOnChain(\n params: RegisterPeginBatchOnChainParams,\n ): Promise<PeginBatchRegistrationResult> {\n const batch = {\n ...params,\n popSignature: { ...params.popSignature },\n requests: params.requests.map((request) => ({ ...request })),\n };\n if (batch.requests.length === 0) {\n throw new Error(\"Batch pegin requires at least one request\");\n }\n this.assertQuotedCommissionPresentWhenRequired(batch.quotedCommissionBps);\n assertFingerprint(batch.expectedFingerprint);\n const depositor = this.assertPopMatchesEthAccount(batch.popSignature);\n const unsignedPrePeginTx = ensureHex(\n batch.unsignedPrePeginTx,\n \"unsignedPrePeginTx\",\n );\n const depositorBtcPubkey = this.normalizeBtcPubkey(batch.popSignature);\n const btcPopSignature = ensureHex(\n batch.popSignature.btcPopSignature,\n \"btcPopSignature\",\n );\n\n const vaults: BatchPeginRegistrationResultItem[] = [];\n const requests = [];\n const seenVaultIds = new Set<string>();\n for (const request of batch.requests) {\n const normalized = this.normalizeRequest(\n {\n ...request,\n unsignedPrePeginTx: batch.unsignedPrePeginTx,\n vaultProvider: batch.vaultProvider,\n depositorBtcPubkeyRaw: batch.depositorBtcPubkeyRaw,\n },\n depositor,\n depositorBtcPubkey,\n );\n if (seenVaultIds.has(normalized.vaultId)) {\n throw new Error(`Duplicate vault in batch: ${normalized.vaultId}`);\n }\n seenVaultIds.add(normalized.vaultId);\n vaults.push({\n vaultId: normalized.vaultId,\n peginTxHash: normalized.peginTxHash,\n });\n requests.push({\n depositorBtcPubKey: depositorBtcPubkey,\n btcPopSignature,\n unsignedPrePeginTx,\n depositorSignedPeginTx: normalized.depositorSignedPeginTx,\n hashlock: request.hashlock,\n htlcVout: request.htlcVout,\n referralCode: NO_REFERRAL_CODE,\n depositorPayoutBtcAddress: normalized.payoutScript,\n depositorWotsPkHash: request.depositorWotsPkHash,\n });\n }\n for (const vault of vaults) {\n await this.assertVaultDoesNotExist(vault.vaultId, vault.peginTxHash);\n }\n\n const peginFee = await this.readPeginFee(batch.vaultProvider);\n const maxCommission = await this.resolveMaxAcceptableCommissionBps(\n batch.vaultProvider,\n batch.quotedCommissionBps,\n );\n const callData = encodeFunctionData({\n abi: BTCVaultRegistryABI,\n functionName: \"submitPeginRequestBatch\",\n // `expectedFingerprint` sits BEFORE `requests`, not appended. Reordering\n // these five changes the selector and the call stops existing.\n args: [\n depositor,\n batch.vaultProvider,\n maxCommission,\n batch.expectedFingerprint,\n requests,\n ],\n });\n const ethTxHash = await this.sendAndWait(\n callData,\n peginFee * BigInt(batch.requests.length),\n true,\n depositor,\n );\n return { ethTxHash, vaults };\n }\n\n private assertQuotedCommissionPresentWhenRequired(\n quotedCommissionBps?: number,\n ): void {\n if (\n quotedCommissionBps === undefined &&\n this.config.requireQuotedCommissionBps\n ) {\n throw new Error(\n \"quotedCommissionBps is required when the wallet approved deposit \" +\n \"terms: the registration ceiling must anchor to the approved quote.\",\n );\n }\n }\n\n private assertPopMatchesEthAccount(pop: PopSignature): Address {\n return this.assertEthAccount(pop.depositorEthAddress);\n }\n\n private assertEthAccount(expectedDepositor: Address): Address {\n const account = this.config.ethWallet.account;\n if (!account) throw new Error(\"Ethereum wallet account not found\");\n if (!isAddressEqual(expectedDepositor, account.address)) {\n throw new Error(\n `Proof of possession was signed for ${expectedDepositor} ` +\n `but the Ethereum wallet is currently connected to ${account.address}. ` +\n `Reconnect the original account or sign a new proof of possession.`,\n );\n }\n return account.address;\n }\n\n private normalizeBtcPubkey(pop: PopSignature): Hex {\n return `0x${assertOnChainBtcPubkey(\n ensureHex(pop.depositorBtcPubkey, \"Proof of possession BTC pubkey\"),\n \"Proof of possession BTC pubkey\",\n )}`;\n }\n\n // `expectedFingerprint` is omitted rather than accepted and ignored: nothing\n // here normalizes it, and requiring it would force the batch loop to thread a\n // value through a per-request helper that has no use for it. It is validated\n // once per call, at the top of each public method.\n private normalizeRequest(\n params: Omit<\n RegisterPeginOnChainParams,\n \"popSignature\" | \"expectedFingerprint\"\n >,\n depositor: Address,\n depositorBtcPubkey: Hex,\n ) {\n assertBytes32(params.hashlock, \"hashlock\");\n assertBytes32(params.depositorWotsPkHash, \"depositorWotsPkHash\");\n assertHtlcVout(params.htlcVout);\n const unsignedPrePeginTx = ensureHex(\n params.unsignedPrePeginTx,\n \"unsignedPrePeginTx\",\n );\n const depositorSignedPeginTx = ensureHex(\n params.depositorSignedPeginTx,\n \"depositorSignedPeginTx\",\n );\n const peginTxHash = calculateBtcTxHash(depositorSignedPeginTx);\n return {\n unsignedPrePeginTx,\n depositorSignedPeginTx,\n payoutScript: assertPayoutScriptMatchesPopKey(\n params.depositorPayoutScriptPubKey,\n depositorBtcPubkey,\n params.depositorBtcPubkeyRaw,\n ),\n peginTxHash,\n vaultId: ensureHex(derivePeginVaultId(peginTxHash, depositor), \"vaultId\"),\n };\n }\n\n private async assertVaultDoesNotExist(\n vaultId: Hex,\n peginTxHash: Hex,\n ): Promise<void> {\n const result = (await this.config.publicClient.readContract({\n address: this.config.btcVaultRegistry,\n abi: BTCVaultRegistryABI,\n functionName: \"getBtcVaultBasicInfo\",\n args: [vaultId],\n })) as { depositor: Address };\n if (result.depositor !== zeroAddress) {\n throw new Error(\n `Vault already exists (ID: ${vaultId}, peginTxHash: ${peginTxHash}). ` +\n `Vault IDs are derived from the pegin transaction hash and depositor address. ` +\n `To create a new vault, use different UTXOs or a different amount to generate a unique transaction.`,\n );\n }\n }\n\n private async readPeginFee(vaultProvider: Address): Promise<bigint> {\n try {\n return (await this.config.publicClient.readContract({\n address: this.config.btcVaultRegistry,\n abi: BTCVaultRegistryABI,\n functionName: \"getPegInFee\",\n args: [vaultProvider],\n })) as bigint;\n } catch (error) {\n throw new Error(\n \"Failed to query pegin fee from the contract. \" +\n \"Please check your network connection and contract address.\",\n { cause: error },\n );\n }\n }\n\n private async resolveMaxAcceptableCommissionBps(\n vaultProvider: Address,\n quotedCommissionBps?: number,\n ): Promise<number> {\n let currentBps: number;\n try {\n currentBps = await new ViemVaultRegistryReader(\n this.config.publicClient,\n this.config.btcVaultRegistry,\n ).getVaultProviderCommission(vaultProvider);\n } catch (error) {\n throw new Error(\n \"Failed to query vault provider commission from the contract. \" +\n \"Please check your network connection and contract address.\",\n { cause: error },\n );\n }\n if (quotedCommissionBps !== undefined) {\n if (currentBps > quotedCommissionBps + COMMISSION_BPS_HEADROOM) {\n throw new Error(\n `Vault provider commission changed since quote: quoted ${quotedCommissionBps} bps, ` +\n `chain currently reports ${currentBps} bps (allowed drift ${COMMISSION_BPS_HEADROOM} bps). ` +\n `Please refresh and try again.`,\n );\n }\n return capMaxAcceptableCommissionBps(quotedCommissionBps);\n }\n return capMaxAcceptableCommissionBps(currentBps);\n }\n\n private async sendAndWait(\n data: Hex,\n value: bigint,\n batch: boolean,\n depositor: Address,\n ): Promise<Hex> {\n let account = this.assertEthAccount(depositor);\n let gas: bigint;\n try {\n gas = await this.config.publicClient.estimateGas({\n to: this.config.btcVaultRegistry,\n data,\n value,\n account,\n });\n } catch (error) {\n handleContractError(error);\n }\n\n account = this.assertEthAccount(depositor);\n let submittedHash: Hex;\n try {\n submittedHash = await this.config.ethWallet.sendTransaction({\n to: this.config.btcVaultRegistry,\n data,\n value,\n gas,\n account,\n chain: this.config.ethChain,\n });\n } catch (error) {\n handleContractError(error);\n }\n const receipt = await waitForTransactionReceiptSmartAware({\n publicClient: this.config.publicClient,\n walletAddress: depositor,\n hash: submittedHash,\n timeout: this.config.receiptTimeoutMs ?? RECEIPT_TIMEOUT_MS,\n });\n if (receipt.status === \"reverted\") {\n handleContractError(\n new Error(\n `${batch ? \"Batch transaction\" : \"Transaction\"} reverted. ` +\n `Hash: ${receipt.transactionHash}. Check a block explorer for details.`,\n ),\n );\n }\n return receipt.transactionHash;\n }\n}\n"],"names":["COMMISSION_BPS_HEADROOM","MAX_ACCEPTABLE_COMMISSION_BPS_CAP","capMaxAcceptableCommissionBps","bps","MAX_VP_COMMISSION_BPS_EXCLUSIVE","Rho160","Id160","_","i","Pi160","idxLR","res","j","k","idxL","idxR","shifts160","shiftsL160","idx","shiftsR160","Kl160","Kr160","ripemd_f","group","x","y","z","BUF_160","_RIPEMD160","HashMD","__publicField","h0","h1","h2","h3","h4","view","offset","al","ar","bl","br","cl","cr","dl","dr","el","er","rGroup","hbl","hbr","rl","rr","sl","sr","tl","rotl","tr","clean","ripemd160","createHasher","P2TR_SCRIPT_PREFIX","P2WPKH_SCRIPT_PREFIX","HASH160_BYTES","COMPRESSED_PUBKEY_BYTES","UNCOMPRESSED_PUBKEY_BYTES","SEC1_EVEN_Y_PREFIX","SEC1_ODD_Y_PREFIX","SEC1_UNCOMPRESSED_PREFIX","normalizeHex","value","label","body","deriveP2trScript","xOnlyPubkey","pubkeyBytes","hexToBytes","internalKey","schnorr","tweak","secp256k1","outputKey","bytesToHex","normalizePayoutPubkey","normalized","pubkey","assertOnChainBtcPubkey","isCompressed","isUncompressed","deriveP2wpkhScript","sha256","assertPayoutScriptMatchesPopKey","scriptPubKey","depositorBtcPubkey","depositorBtcPubkeyRaw","payoutScript","MAX_PAYOUT_SCRIPT_LEN","keyBody","payoutPubkey","UINT16_MAX","MAX_BASIS_POINTS","UINT32_MAX","UINT8_MAX","assertValidOffchainParamsVersion","version","validateOffchainParams","params","errors","validateTBVProtocolParams","validatePegInConfiguration","config","assertValidVaultCoreVersion","REGISTRATION_LOGS_UNAVAILABLE_ERROR_NAME","RegistrationLogsUnavailableError","blockNumber","isRegistrationLogsUnavailableError","err","MAX_VP_COMMISSION_BPS","mapVaultBasicInfo","result","mapVaultProtocolInfo","offchainParamsVersion","UINT64_EXCLUSIVE_UPPER_BOUND","VP_GENESIS_KEY_EPOCH","PEGIN_SUBMITTED_EVENTS","getAbiItem","BTCVaultRegistryABI","assertEpochInRange","field","vaultId","mapKeyEpochs","ViemVaultRegistryReader","publicClient","contractAddress","vpAddress","BTCVaultRegistryKeyEpochsABI","vaultIds","info","vaultProvider","basicRaw","protocolRaw","basic","protocol","createdAt","logs","vaultIdLower","registered","ceilings","log","NO_REFERRAL_CODE","RECEIPT_TIMEOUT_MS","ensureHex","prefixed","assertBytes32","ZERO_BYTES32","assertFingerprint","assertHtlcVout","ViemPeginRegistrationClient","request","depositor","btcPopSignature","peginFee","maxCommission","callData","encodeFunctionData","batch","unsignedPrePeginTx","vaults","requests","seenVaultIds","vault","quotedCommissionBps","pop","expectedDepositor","account","isAddressEqual","depositorSignedPeginTx","peginTxHash","calculateBtcTxHash","derivePeginVaultId","zeroAddress","error","currentBps","data","gas","handleContractError","submittedHash","receipt","waitForTransactionReceiptSmartAware"],"mappings":"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","x_google_ignoreList":[1]}
|