@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
|
@@ -37,6 +37,15 @@ export declare class ViemVaultRegistryReader implements VaultRegistryReader {
|
|
|
37
37
|
* the brand. Returns 64-char lowercase hex without the `0x` prefix.
|
|
38
38
|
*/
|
|
39
39
|
getVaultProviderGenesisBtcPubKey(vpAddress: Address, blockNumber?: bigint): Promise<OnChainBtcPubkey>;
|
|
40
|
+
/**
|
|
41
|
+
* Read the VP operation key selected by `epoch`.
|
|
42
|
+
*
|
|
43
|
+
* This is public rather than hidden inside `OperationKeyReader` because
|
|
44
|
+
* subject-specific VP authentication needs exactly one participant: the
|
|
45
|
+
* gRPC bootstrap is signed by the key frozen into the vault, while the
|
|
46
|
+
* JSON-RPC bootstrap is signed by the provider's live key.
|
|
47
|
+
*/
|
|
48
|
+
getVaultProviderOperationBtcKeyAtEpoch(vpAddress: Address, epoch: bigint, blockNumber?: bigint): Promise<OnChainBtcPubkey>;
|
|
40
49
|
/**
|
|
41
50
|
* Read the application entry point a vault provider is registered for.
|
|
42
51
|
*
|
|
@@ -56,9 +65,9 @@ export declare class ViemVaultRegistryReader implements VaultRegistryReader {
|
|
|
56
65
|
* rotated, so this returns the same value as
|
|
57
66
|
* `getVaultProviderGenesisBtcPubKey` until the first rotation.
|
|
58
67
|
*
|
|
59
|
-
* This is the key the VP's server
|
|
60
|
-
*
|
|
61
|
-
*
|
|
68
|
+
* This is the key the VP's server uses for JSON-RPC-subject authentication.
|
|
69
|
+
* The gRPC-subject bootstrap is instead bound to the existing vault's frozen
|
|
70
|
+
* epoch and resolves through `getVaultProviderOperationBtcKeyAtEpoch`.
|
|
62
71
|
*/
|
|
63
72
|
getCurrentVaultProviderOperationBtcKey(vpAddress: Address): Promise<OnChainBtcPubkey>;
|
|
64
73
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vault-registry-reader.d.ts","sourceRoot":"","sources":["../../../../../src/tbv/core/clients/eth/vault-registry-reader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAO,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAQ5D,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,SAAS,EACT,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAkJjB;;;;;;;;GAQG;AACH,qBAAa,uBAAwB,YAAW,mBAAmB;IAE/D,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,eAAe;gBADf,YAAY,EAAE,YAAY,EAC1B,eAAe,EAAE,OAAO;IAGlC;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACG,gCAAgC,CACpC,SAAS,EAAE,OAAO,EAClB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,gBAAgB,CAAC;IAc5B;;;;;;;;;;OAUG;IACG,2BAA2B,CAC/B,SAAS,EAAE,OAAO,EAClB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,OAAO,CAAC;IAUnB;;;;;;;;;;OAUG;IACG,sCAAsC,CAC1C,SAAS,EAAE,OAAO,GACjB,OAAO,CAAC,gBAAgB,CAAC;IAa5B;;;;;;;;;;;;;;;OAeG;IACG,iBAAiB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC;IAWnD,sBAAsB,CAAC,QAAQ,EAAE,SAAS,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAkBtE,iBAAiB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,cAAc,CAAC;IAWxD,oBAAoB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAW9D,oBAAoB,CACxB,QAAQ,EAAE,SAAS,GAAG,EAAE,GACvB,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAiC/B;;;OAGG;IACG,WAAW,CAAC,aAAa,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAS1D;;;;;;OAMG;IACG,0BAA0B,CAAC,aAAa,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBnE,YAAY,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC;IAqCpD;;;;;;;;;;;;;;;;;OAiBG;IACG,kCAAkC,CACtC,QAAQ,EAAE,SAAS,GAAG,EAAE,EACxB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC;CAmDrB"}
|
|
1
|
+
{"version":3,"file":"vault-registry-reader.d.ts","sourceRoot":"","sources":["../../../../../src/tbv/core/clients/eth/vault-registry-reader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAO,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAQ5D,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,SAAS,EACT,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAkJjB;;;;;;;;GAQG;AACH,qBAAa,uBAAwB,YAAW,mBAAmB;IAE/D,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,eAAe;gBADf,YAAY,EAAE,YAAY,EAC1B,eAAe,EAAE,OAAO;IAGlC;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACG,gCAAgC,CACpC,SAAS,EAAE,OAAO,EAClB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,gBAAgB,CAAC;IAQ5B;;;;;;;OAOG;IACG,sCAAsC,CAC1C,SAAS,EAAE,OAAO,EAClB,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,gBAAgB,CAAC;IAc5B;;;;;;;;;;OAUG;IACG,2BAA2B,CAC/B,SAAS,EAAE,OAAO,EAClB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,OAAO,CAAC;IAUnB;;;;;;;;;;OAUG;IACG,sCAAsC,CAC1C,SAAS,EAAE,OAAO,GACjB,OAAO,CAAC,gBAAgB,CAAC;IAa5B;;;;;;;;;;;;;;;OAeG;IACG,iBAAiB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC;IAWnD,sBAAsB,CAAC,QAAQ,EAAE,SAAS,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAkBtE,iBAAiB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,cAAc,CAAC;IAWxD,oBAAoB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAW9D,oBAAoB,CACxB,QAAQ,EAAE,SAAS,GAAG,EAAE,GACvB,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAiC/B;;;OAGG;IACG,WAAW,CAAC,aAAa,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAS1D;;;;;;OAMG;IACG,0BAA0B,CAAC,aAAa,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBnE,YAAY,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC;IAqCpD;;;;;;;;;;;;;;;;;OAiBG;IACG,kCAAkC,CACtC,QAAQ,EAAE,SAAS,GAAG,EAAE,EACxB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC;CAmDrB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./mempool/index.cjs"),i=require("../../../types-BueQoMjO.cjs"),s=require("../../../onChainBtcPubkey-BlzxYImF.cjs"),t=require("../../../pegin-registration-client-B0j6ugt9.cjs"),n=require("../../../secp256k1-DDHQ1_za.cjs"),a=require("../../../index-MRdle0fs.cjs"),r=require("../../../state-C4WoNCy1.cjs"),o=require("../../../primeVpAuth-BDWBKYhv.cjs");exports.MEMPOOL_API_URLS=e.MEMPOOL_API_URLS;exports.MempoolNotFoundError=e.MempoolNotFoundError;exports.getAddressTxs=e.getAddressTxs;exports.getAddressUtxos=e.getAddressUtxos;exports.getMempoolApiUrl=e.getMempoolApiUrl;exports.getNetworkFees=e.getNetworkFees;exports.getOutspend=e.getOutspend;exports.getTipHeight=e.getTipHeight;exports.getTxHex=e.getTxHex;exports.getTxInfo=e.getTxInfo;exports.getUtxoInfo=e.getUtxoInfo;exports.pushTx=e.pushTx;exports.OnChainBtcVaultStatus=i.OnChainBtcVaultStatus;exports.ViemOperationKeyReader=i.ViemOperationKeyReader;exports.ViemProtocolParamsReader=i.ViemProtocolParamsReader;exports.ViemUniversalChallengerReader=i.ViemUniversalChallengerReader;exports.ViemVaultKeeperReader=i.ViemVaultKeeperReader;exports.resolveProtocolAddresses=i.resolveProtocolAddresses;exports.assertOnChainBtcPubkey=s.assertOnChainBtcPubkey;exports.calculateBtcTxHash=s.calculateBtcTxHash;exports.derivePeginVaultId=s.derivePeginVaultId;exports.RegistrationLogsUnavailableError=t.RegistrationLogsUnavailableError;exports.ViemPeginRegistrationClient=t.ViemPeginRegistrationClient;exports.ViemVaultRegistryReader=t.ViemVaultRegistryReader;exports.isRegistrationLogsUnavailableError=t.isRegistrationLogsUnavailableError;exports.validateOffchainParams=t.validateOffchainParams;exports.validatePegInConfiguration=t.validatePegInConfiguration;exports.validateTBVProtocolParams=t.validateTBVProtocolParams;exports.assertValidVaultCoreVersion=n.assertValidVaultCoreVersion;exports.VaultProviderRpcClient=a.VaultProviderRpcClient;exports.VpResponseValidationError=a.VpResponseValidationError;exports.batchPollByProvider=a.batchPollByProvider;exports.isUnrecognizedDaemonStatusError=a.isUnrecognizedDaemonStatusError;exports.validateRequestDepositorClaimerArtifactsResponse=a.validateRequestDepositorClaimerArtifactsResponse;exports.AUTH_REJECTED_RPC_CODE=r.AUTH_REJECTED_RPC_CODE;exports.DaemonStatus=r.DaemonStatus;exports.JSON_RPC_ERROR_CODES=r.JSON_RPC_ERROR_CODES;exports.JsonRpcClient=r.JsonRpcClient;exports.JsonRpcError=r.JsonRpcError;exports.POST_WOTS_STATUSES=r.POST_WOTS_STATUSES;exports.PRE_DEPOSITOR_SIGNATURES_STATES=r.PRE_DEPOSITOR_SIGNATURES_STATES;exports.RpcErrorCode=r.RpcErrorCode;exports.VP_BATCH_MAX_SIZE=r.VP_BATCH_MAX_SIZE;exports.VP_TERMINAL_FAILURE_STATUSES=r.VP_TERMINAL_FAILURE_STATUSES;exports.VP_TRANSIENT_STATUSES=r.VP_TRANSIENT_STATUSES;exports.isAuthRejectedError=r.isAuthRejectedError;exports.ServerIdentityError=o.ServerIdentityError;exports.VpTokenRegistry=o.VpTokenRegistry;exports.createAuthenticatedVpClient=o.createAuthenticatedVpClient;exports.primeVpTokenRegistry=o.primeVpTokenRegistry;exports.verifyServerIdentity=o.verifyServerIdentity;exports.vpTokenRegistry=o.vpTokenRegistry;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1,62 +1,63 @@
|
|
|
1
|
-
import { MEMPOOL_API_URLS as r,
|
|
2
|
-
import { O as S, V as
|
|
3
|
-
import { a as
|
|
4
|
-
import { R as
|
|
5
|
-
import { a as
|
|
6
|
-
import { V as L, a as
|
|
7
|
-
import { A as
|
|
8
|
-
import { S as
|
|
1
|
+
import { MEMPOOL_API_URLS as r, MempoolNotFoundError as s, getAddressTxs as t, getAddressUtxos as o, getMempoolApiUrl as i, getNetworkFees as n, getOutspend as l, getTipHeight as R, getTxHex as d, getTxInfo as p, getUtxoInfo as T, pushTx as V } from "./mempool/index.js";
|
|
2
|
+
import { O as S, V as g, a as c, b as P, c as m, r as _ } from "../../../types-DGkejGZH.js";
|
|
3
|
+
import { a as u, c as v, d as C } from "../../../onChainBtcPubkey-CCTdl53s.js";
|
|
4
|
+
import { R as O, V as f, c as U, i as I, v as h, a as y, b } from "../../../pegin-registration-client-ilkV1mLP.js";
|
|
5
|
+
import { a as N } from "../../../secp256k1-D-H9jmd7.js";
|
|
6
|
+
import { V as L, a as M, b as k, i as H, v as J } from "../../../index-D2mybjXD.js";
|
|
7
|
+
import { A as K, D as j, J as q, a as w, b as z, d as G, P as W, R as X, e as Z, c as Q, V as Y, i as $ } from "../../../state-CFn1rT74.js";
|
|
8
|
+
import { S as ae, V as re, c as se, p as te, v as oe, a as ie } from "../../../primeVpAuth-D0ZnsjRi.js";
|
|
9
9
|
export {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
K as AUTH_REJECTED_RPC_CODE,
|
|
11
|
+
j as DaemonStatus,
|
|
12
|
+
q as JSON_RPC_ERROR_CODES,
|
|
13
|
+
w as JsonRpcClient,
|
|
14
|
+
z as JsonRpcError,
|
|
15
15
|
r as MEMPOOL_API_URLS,
|
|
16
|
+
s as MempoolNotFoundError,
|
|
16
17
|
S as OnChainBtcVaultStatus,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
G as POST_WOTS_STATUSES,
|
|
19
|
+
W as PRE_DEPOSITOR_SIGNATURES_STATES,
|
|
20
|
+
O as RegistrationLogsUnavailableError,
|
|
21
|
+
X as RpcErrorCode,
|
|
22
|
+
ae as ServerIdentityError,
|
|
23
|
+
Z as VP_BATCH_MAX_SIZE,
|
|
24
|
+
Q as VP_TERMINAL_FAILURE_STATUSES,
|
|
25
|
+
Y as VP_TRANSIENT_STATUSES,
|
|
25
26
|
L as VaultProviderRpcClient,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
g as ViemOperationKeyReader,
|
|
28
|
+
f as ViemPeginRegistrationClient,
|
|
29
|
+
c as ViemProtocolParamsReader,
|
|
30
|
+
P as ViemUniversalChallengerReader,
|
|
31
|
+
m as ViemVaultKeeperReader,
|
|
32
|
+
U as ViemVaultRegistryReader,
|
|
33
|
+
M as VpResponseValidationError,
|
|
34
|
+
re as VpTokenRegistry,
|
|
35
|
+
u as assertOnChainBtcPubkey,
|
|
36
|
+
N as assertValidVaultCoreVersion,
|
|
36
37
|
k as batchPollByProvider,
|
|
37
38
|
v as calculateBtcTxHash,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
se as createAuthenticatedVpClient,
|
|
40
|
+
C as derivePeginVaultId,
|
|
41
|
+
t as getAddressTxs,
|
|
42
|
+
o as getAddressUtxos,
|
|
43
|
+
i as getMempoolApiUrl,
|
|
44
|
+
n as getNetworkFees,
|
|
45
|
+
l as getOutspend,
|
|
45
46
|
R as getTipHeight,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
d as getTxHex,
|
|
48
|
+
p as getTxInfo,
|
|
49
|
+
T as getUtxoInfo,
|
|
50
|
+
$ as isAuthRejectedError,
|
|
51
|
+
I as isRegistrationLogsUnavailableError,
|
|
51
52
|
H as isUnrecognizedDaemonStatusError,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
te as primeVpTokenRegistry,
|
|
54
|
+
V as pushTx,
|
|
55
|
+
_ as resolveProtocolAddresses,
|
|
56
|
+
h as validateOffchainParams,
|
|
57
|
+
y as validatePegInConfiguration,
|
|
57
58
|
J as validateRequestDepositorClaimerArtifactsResponse,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
b as validateTBVProtocolParams,
|
|
60
|
+
oe as verifyServerIdentity,
|
|
61
|
+
ie as vpTokenRegistry
|
|
61
62
|
};
|
|
62
63
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";var I=Object.defineProperty;var y=(e,r,t)=>r in e?I(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t;var w=(e,r,t)=>y(e,typeof r!="symbol"?r+"":r,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const x=require("../../../../abortSignals-msbmbqFe.cjs"),f=require("../../../../validation-C6XTfZak.cjs"),v=21e6*1e8,h=3e4,d=404;async function l(e,r){const t=new AbortController,o=setTimeout(()=>t.abort(),h),s=[t.signal,r==null?void 0:r.signal].filter(Boolean),n=x.combineAbortSignals(s);try{return await fetch(e,{...r,signal:n.signal})}catch(a){throw clearTimeout(o),n.cleanup(),a!=null&&typeof a=="object"&&"name"in a&&a.name==="AbortError"?new Error(`Mempool API request timed out after ${h}ms: ${e}`):a}}const p=1e4;function $(e){return Number.isInteger(e)&&e>0&&e<=v}function b(e){return Number.isInteger(e)&&e>0&&e<=p}function m(e,r){return!Number.isInteger(e)||e<0?!1:r===void 0||e<r}function c(e){if(!f.TXID_RE.test(e))throw new Error(`Invalid transaction ID format: ${e}`)}function g(e){if(!f.BITCOIN_ADDRESS_RE.test(e))throw new Error(`Invalid Bitcoin address format: ${e}`)}function E(e,r){if(!f.HEX_RE.test(e))throw new Error(`Invalid scriptPubKey: not valid hex for ${r}`);if(!f.KNOWN_SCRIPT_PREFIXES.some(o=>e.toLowerCase().startsWith(o)))throw new Error(`Unrecognized scriptPubKey type for ${r}: prefix ${e.slice(0,6)} does not match any known Bitcoin script type`)}const F={mainnet:"https://mempool.space/api",testnet:"https://mempool.space/testnet/api",signet:"https://mempool.space/signet/api"};class u extends Error{constructor(t){super(t);w(this,"status",d);this.name="MempoolNotFoundError"}}async function i(e,r){try{const t=await l(e,r);if(!t.ok){const s=await t.text(),n=t.status===d?u:Error;throw new n(`Mempool API error (${t.status}): ${s||t.statusText}`)}const o=t.headers.get("content-type");return o!=null&&o.includes("application/json")?await t.json():await t.text()}catch(t){throw t instanceof u?new u(`Failed to fetch from mempool API: ${t.message}`):t instanceof Error?new Error(`Failed to fetch from mempool API: ${t.message}`):new Error("Failed to fetch from mempool API: Unknown error")}}async function A(e,r){try{const t=await l(`${r}/tx`,{method:"POST",body:e,headers:{"Content-Type":"text/plain"}});if(!t.ok){const s=await t.text();let n;try{const a=JSON.parse(s);n=a.message??a.error}catch{n=s}throw new Error(n||`Failed to broadcast transaction: ${t.statusText}`)}return await t.text()}catch(t){throw t instanceof Error?new Error(`Failed to broadcast BTC transaction: ${t.message}`):new Error("Failed to broadcast BTC transaction: Unknown error")}}async function T(e,r){return c(e),i(`${r}/tx/${e}`)}async function P(e){const r=await i(`${e}/blocks/tip/height`),t=r.trim(),o=/^\d+$/.test(t)?Number.parseInt(t,10):NaN;if(!Number.isSafeInteger(o)||o<0)throw new Error(`Mempool API returned an invalid block tip height: "${r}"`);return o}async function O(e,r,t){if(c(e),!m(r))throw new Error(`Invalid vout ${r} for transaction ${e}`);return i(`${t}/tx/${e}/outspend/${r}`)}async function M(e,r){c(e);try{const t=await l(`${r}/tx/${e}/hex`);if(!t.ok){const o=await t.text();throw new Error(`Mempool API error (${t.status}): ${o||t.statusText}`)}return await t.text()}catch(t){throw t instanceof Error?new Error(`Failed to get transaction hex for ${e}: ${t.message}`):new Error(`Failed to get transaction hex for ${e}: Unknown error`)}}async function U(e,r,t){c(e);const o=await T(e,t);if(!m(r,o.vout.length))throw new Error(`Invalid vout ${r} for transaction ${e} (has ${o.vout.length} outputs)`);const s=o.vout[r];if(!$(s.value))throw new Error(`Invalid UTXO value ${s.value} for ${e}:${r}`);return E(s.scriptpubkey,`${e}:${r}`),{txid:e,vout:r,value:s.value,scriptPubKey:s.scriptpubkey}}async function S(e,r){g(e);try{const t=await i(`${r}/address/${e}/utxo`),o=await i(`${r}/v1/validate-address/${e}`);if(!o.isvalid)throw new Error(`Invalid Bitcoin address: ${e}. Mempool API validation failed.`);E(o.scriptPubKey,e);for(const n of t){if(c(n.txid),!m(n.vout))throw new Error(`Invalid vout ${n.vout} for ${n.txid}`);if(!$(n.value))throw new Error(`Invalid UTXO value ${n.value} for ${n.txid}:${n.vout}`)}return t.sort((n,a)=>a.value-n.value).map(n=>({txid:n.txid,vout:n.vout,value:n.value,scriptPubKey:o.scriptPubKey,confirmed:n.status.confirmed}))}catch(t){throw t instanceof Error?new Error(`Failed to get UTXOs for address ${e}: ${t.message}`):new Error(`Failed to get UTXOs for address ${e}: Unknown error`)}}function N(e){return F[e]}async function _(e,r){return g(e),i(`${r}/address/${e}/txs`)}async function k(e){const r=await l(`${e}/v1/fees/recommended`);if(!r.ok)throw new Error(`Failed to fetch network fees: ${r.status} ${r.statusText}`);const t=await r.json(),o=["fastestFee","halfHourFee","hourFee","economyFee","minimumFee"];for(const s of o)if(!b(t[s]))throw new Error(`Invalid fee rate ${s}=${t[s]} from mempool API: expected a positive number ≤ ${p}`);if(t.minimumFee>t.economyFee||t.economyFee>t.hourFee||t.hourFee>t.halfHourFee||t.halfHourFee>t.fastestFee)throw new Error(`Fee rate ordering violation from mempool API: expected minimumFee (${t.minimumFee}) <= economyFee (${t.economyFee}) <= hourFee (${t.hourFee}) <= halfHourFee (${t.halfHourFee}) <= fastestFee (${t.fastestFee}).`);return t}exports.MEMPOOL_API_URLS=F;exports.MempoolNotFoundError=u;exports.getAddressTxs=_;exports.getAddressUtxos=S;exports.getMempoolApiUrl=N;exports.getNetworkFees=k;exports.getOutspend=O;exports.getTipHeight=P;exports.getTxHex=M;exports.getTxInfo=T;exports.getUtxoInfo=U;exports.pushTx=A;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../../../src/tbv/core/clients/mempool/mempoolApi.ts"],"sourcesContent":["/**\n * Mempool API Client\n *\n * Client for interacting with mempool.space API for Bitcoin network operations.\n * Used for broadcasting transactions and fetching UTXO data.\n *\n * @module clients/mempool/mempoolApi\n */\n\nimport { combineAbortSignals } from \"../../utils/abortSignals\";\nimport {\n BITCOIN_ADDRESS_RE,\n HEX_RE,\n KNOWN_SCRIPT_PREFIXES,\n TXID_RE,\n} from \"../../utils/validation\";\n\nimport type {\n MempoolUTXO,\n NetworkFees,\n OutspendStatus,\n TxInfo,\n UtxoInfo,\n} from \"./types\";\n\n/** Maximum valid satoshi value: 21 million BTC × 10^8 sats/BTC */\nconst MAX_SATOSHIS = 21_000_000 * 1e8;\n\n/** Timeout for mempool API requests — prevents indefinite hangs from stalled endpoints */\nconst MEMPOOL_REQUEST_TIMEOUT_MS = 30_000;\n\n/**\n * Fetch wrapper with AbortController-based timeout.\n * Ensures all mempool API requests fail bounded rather than hanging indefinitely.\n */\nasync function fetchWithTimeout(\n url: string,\n options?: RequestInit,\n): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(\n () => controller.abort(),\n MEMPOOL_REQUEST_TIMEOUT_MS,\n );\n\n // Compose timeout signal with any caller-supplied signal so both can cancel\n const signals = [controller.signal, options?.signal].filter(\n Boolean,\n ) as AbortSignal[];\n const combined = combineAbortSignals(signals);\n\n try {\n // Don't clear timeout here — let it cover body consumption by callers.\n // For the same reason the composed signal keeps its listeners attached on\n // the success path: detaching them would stop the timeout from aborting a\n // stalled body read.\n return await fetch(url, {\n ...options,\n signal: combined.signal,\n });\n } catch (error) {\n clearTimeout(timeoutId);\n combined.cleanup();\n if (\n error != null &&\n typeof error === \"object\" &&\n \"name\" in error &&\n error.name === \"AbortError\"\n ) {\n throw new Error(\n `Mempool API request timed out after ${MEMPOOL_REQUEST_TIMEOUT_MS}ms: ${url}`,\n );\n }\n throw error;\n }\n}\n\n/**\n * Maximum sane fee rate in sat/vByte.\n * The April 2024 Runes spike peaked around 1,805 sat/vB — 10,000 provides ample headroom.\n */\nconst MAX_FEE_RATE = 10_000;\n\nfunction isValidSatoshiValue(value: number): boolean {\n return Number.isInteger(value) && value > 0 && value <= MAX_SATOSHIS;\n}\n\nfunction isValidFeeRate(value: number): boolean {\n return Number.isInteger(value) && value > 0 && value <= MAX_FEE_RATE;\n}\n\nfunction isValidVout(vout: number, outputCount?: number): boolean {\n if (!Number.isInteger(vout) || vout < 0) return false;\n return outputCount === undefined || vout < outputCount;\n}\n\n\nfunction assertValidTxid(txid: string): void {\n if (!TXID_RE.test(txid)) {\n throw new Error(`Invalid transaction ID format: ${txid}`);\n }\n}\n\nfunction assertValidAddress(address: string): void {\n if (!BITCOIN_ADDRESS_RE.test(address)) {\n throw new Error(`Invalid Bitcoin address format: ${address}`);\n }\n}\n\nfunction assertValidScriptPubKey(scriptPubKey: string, context: string): void {\n if (!HEX_RE.test(scriptPubKey)) {\n throw new Error(\n `Invalid scriptPubKey: not valid hex for ${context}`,\n );\n }\n const matchesKnownType = KNOWN_SCRIPT_PREFIXES.some((prefix) =>\n scriptPubKey.toLowerCase().startsWith(prefix),\n );\n if (!matchesKnownType) {\n throw new Error(\n `Unrecognized scriptPubKey type for ${context}: ` +\n `prefix ${scriptPubKey.slice(0, 6)} does not match any known Bitcoin script type`,\n );\n }\n}\n\n/**\n * Default mempool API URLs by network.\n */\nexport const MEMPOOL_API_URLS = {\n mainnet: \"https://mempool.space/api\",\n testnet: \"https://mempool.space/testnet/api\",\n signet: \"https://mempool.space/signet/api\",\n} as const;\n\n/**\n * Fetch wrapper with error handling.\n */\nasync function fetchApi<T>(\n url: string,\n options?: RequestInit,\n): Promise<T> {\n try {\n const response = await fetchWithTimeout(url, options);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `Mempool API error (${response.status}): ${errorText || response.statusText}`,\n );\n }\n\n const contentType = response.headers.get(\"content-type\");\n if (contentType?.includes(\"application/json\")) {\n return (await response.json()) as T;\n } else {\n return (await response.text()) as T;\n }\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to fetch from mempool API: ${error.message}`);\n }\n throw new Error(\"Failed to fetch from mempool API: Unknown error\");\n }\n}\n\n/**\n * Push a signed transaction to the Bitcoin network.\n *\n * @param txHex - The signed transaction hex string\n * @param apiUrl - Mempool API base URL\n * @returns The transaction ID\n * @throws Error if broadcasting fails\n */\nexport async function pushTx(txHex: string, apiUrl: string): Promise<string> {\n try {\n const response = await fetchWithTimeout(`${apiUrl}/tx`, {\n method: \"POST\",\n body: txHex,\n headers: {\n \"Content-Type\": \"text/plain\",\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n // Try to extract error message from response using robust JSON parsing\n let message: string | undefined;\n try {\n const errorJson = JSON.parse(errorText);\n message = errorJson.message ?? errorJson.error;\n } catch {\n // Not JSON, use raw text\n message = errorText;\n }\n throw new Error(\n message || `Failed to broadcast transaction: ${response.statusText}`,\n );\n }\n\n // Response is the transaction ID (plain text)\n const txId = await response.text();\n return txId;\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to broadcast BTC transaction: ${error.message}`);\n }\n throw new Error(\"Failed to broadcast BTC transaction: Unknown error\");\n }\n}\n\n/**\n * Get transaction information from mempool.\n *\n * @param txid - The transaction ID\n * @param apiUrl - Mempool API base URL\n * @returns Transaction information\n */\nexport async function getTxInfo(txid: string, apiUrl: string): Promise<TxInfo> {\n assertValidTxid(txid);\n return fetchApi<TxInfo>(`${apiUrl}/tx/${txid}`);\n}\n\n/**\n * Get the current block tip height.\n *\n * Source: mempool.space API — `GET /api/blocks/tip/height` returns the height\n * of the most recent block as a plain-text integer.\n *\n * The digit check alone is not enough to honour the contract below. A long\n * enough run of digits passes `/^\\d+$/` and then parses to a value no caller\n * can use: 400 digits yields `Infinity`, and 20 digits yields a finite but\n * unsafe integer. Callers subtract this from a confirmed block height to get a\n * confirmation depth, so either one produces an enormous depth and clears any\n * threshold it is compared against. Bound it to a safe integer here rather\n * than leaving each caller to discover the gap.\n *\n * @param apiUrl - Mempool API base URL\n * @returns The height of the most recent block\n * @throws Error if the response is not a whole number a caller can compute on\n */\nexport async function getTipHeight(apiUrl: string): Promise<number> {\n const raw = await fetchApi<string>(`${apiUrl}/blocks/tip/height`);\n const trimmed = raw.trim();\n const height = /^\\d+$/.test(trimmed) ? Number.parseInt(trimmed, 10) : NaN;\n if (!Number.isSafeInteger(height) || height < 0) {\n throw new Error(\n `Mempool API returned an invalid block tip height: \"${raw}\"`,\n );\n }\n return height;\n}\n\n/**\n * Get the spend status of a specific transaction output.\n *\n * Calls the esplora-compatible `GET /tx/{txid}/outspend/{vout}` endpoint\n * (mempool.space backend, mempool/electrs `rest.rs`). Returns\n * `{ spent: false }` for an unspent output, or\n * `{ spent: true, txid, vin, status }` when the output has been spent.\n *\n * @param txid - The transaction id whose output is being checked (no 0x prefix)\n * @param vout - The output index\n * @param apiUrl - Mempool API base URL\n * @returns The output's spend status\n */\nexport async function getOutspend(\n txid: string,\n vout: number,\n apiUrl: string,\n): Promise<OutspendStatus> {\n assertValidTxid(txid);\n if (!isValidVout(vout)) {\n throw new Error(`Invalid vout ${vout} for transaction ${txid}`);\n }\n return fetchApi<OutspendStatus>(`${apiUrl}/tx/${txid}/outspend/${vout}`);\n}\n\n/**\n * Get the hex representation of a transaction.\n *\n * @param txid - The transaction ID\n * @param apiUrl - Mempool API base URL\n * @returns The transaction hex string\n * @throws Error if the request fails or transaction is not found\n */\nexport async function getTxHex(txid: string, apiUrl: string): Promise<string> {\n assertValidTxid(txid);\n try {\n const response = await fetchWithTimeout(`${apiUrl}/tx/${txid}/hex`);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `Mempool API error (${response.status}): ${errorText || response.statusText}`,\n );\n }\n\n return await response.text();\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to get transaction hex for ${txid}: ${error.message}`);\n }\n throw new Error(`Failed to get transaction hex for ${txid}: Unknown error`);\n }\n}\n\n/**\n * Get UTXO information for a specific transaction output.\n *\n * This is used for constructing PSBTs where we need the witnessUtxo data.\n * Only supports Taproot (P2TR) and native SegWit (P2WPKH, P2WSH) script types.\n *\n * @param txid - The transaction ID containing the UTXO\n * @param vout - The output index\n * @param apiUrl - Mempool API base URL\n * @returns UTXO information with value and scriptPubKey\n */\nexport async function getUtxoInfo(\n txid: string,\n vout: number,\n apiUrl: string,\n): Promise<UtxoInfo> {\n assertValidTxid(txid);\n const txInfo = await getTxInfo(txid, apiUrl);\n\n if (!isValidVout(vout, txInfo.vout.length)) {\n throw new Error(\n `Invalid vout ${vout} for transaction ${txid} (has ${txInfo.vout.length} outputs)`,\n );\n }\n\n const output = txInfo.vout[vout];\n if (!isValidSatoshiValue(output.value)) {\n throw new Error(`Invalid UTXO value ${output.value} for ${txid}:${vout}`);\n }\n assertValidScriptPubKey(output.scriptpubkey, `${txid}:${vout}`);\n\n return {\n txid,\n vout,\n value: output.value,\n scriptPubKey: output.scriptpubkey,\n };\n}\n\n/**\n * Get all UTXOs for a Bitcoin address.\n *\n * @param address - The Bitcoin address\n * @param apiUrl - Mempool API base URL\n * @returns Array of UTXOs sorted by value (largest first)\n */\nexport async function getAddressUtxos(\n address: string,\n apiUrl: string,\n): Promise<MempoolUTXO[]> {\n assertValidAddress(address);\n try {\n // Fetch UTXOs for the address\n const utxos = await fetchApi<\n {\n txid: string;\n vout: number;\n value: number;\n status: {\n confirmed: boolean;\n };\n }[]\n >(`${apiUrl}/address/${address}/utxo`);\n\n // Fetch scriptPubKey for the address\n const addressInfo = await fetchApi<{\n isvalid: boolean;\n scriptPubKey: string;\n }>(`${apiUrl}/v1/validate-address/${address}`);\n\n if (!addressInfo.isvalid) {\n throw new Error(\n `Invalid Bitcoin address: ${address}. Mempool API validation failed.`,\n );\n }\n assertValidScriptPubKey(addressInfo.scriptPubKey, address);\n\n // Validate UTXO fields from the listing endpoint.\n // Per-UTXO cross-verification against /tx/{txid} is intentionally NOT done\n // here — it would be expensive (N API calls) and redundant: the broadcast\n // path already verifies each selected input via getUtxoInfo before signing.\n // Both endpoints come from the same mempool API, so cross-checking one\n // against the other on the same server does not add real security.\n for (const utxo of utxos) {\n assertValidTxid(utxo.txid);\n if (!isValidVout(utxo.vout)) {\n throw new Error(`Invalid vout ${utxo.vout} for ${utxo.txid}`);\n }\n if (!isValidSatoshiValue(utxo.value)) {\n throw new Error(\n `Invalid UTXO value ${utxo.value} for ${utxo.txid}:${utxo.vout}`,\n );\n }\n }\n\n // Sort by value (largest first) and map to our UTXO format\n const sortedUTXOs = utxos.sort((a, b) => b.value - a.value);\n\n return sortedUTXOs.map((utxo) => ({\n txid: utxo.txid,\n vout: utxo.vout,\n value: utxo.value,\n scriptPubKey: addressInfo.scriptPubKey,\n confirmed: utxo.status.confirmed,\n }));\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(\n `Failed to get UTXOs for address ${address}: ${error.message}`,\n );\n }\n throw new Error(\n `Failed to get UTXOs for address ${address}: Unknown error`,\n );\n }\n}\n\n/**\n * Get the mempool API URL for a given network.\n *\n * @param network - Bitcoin network (mainnet, testnet, signet)\n * @returns The mempool API URL\n */\nexport function getMempoolApiUrl(\n network: \"mainnet\" | \"testnet\" | \"signet\",\n): string {\n return MEMPOOL_API_URLS[network];\n}\n\n/**\n * Transaction summary from address transactions endpoint.\n */\nexport interface AddressTx {\n txid: string;\n status: {\n confirmed: boolean;\n block_height?: number;\n };\n}\n\n/**\n * Get recent transactions for a Bitcoin address.\n *\n * Returns the last 25 confirmed transactions plus any unconfirmed (mempool) transactions.\n * This is useful for checking if a specific transaction has been broadcast.\n *\n * @param address - The Bitcoin address\n * @param apiUrl - Mempool API base URL\n * @returns Array of recent transactions\n */\nexport async function getAddressTxs(\n address: string,\n apiUrl: string,\n): Promise<AddressTx[]> {\n assertValidAddress(address);\n return fetchApi<AddressTx[]>(`${apiUrl}/address/${address}/txs`);\n}\n\n/**\n * Fetches Bitcoin network fee recommendations from mempool.space API.\n *\n * @param apiUrl - Mempool API base URL\n * @returns Fee rates in sat/vbyte for different confirmation times\n * @throws Error if request fails or returns invalid data\n *\n * @see https://mempool.space/docs/api/rest#get-recommended-fees\n */\nexport async function getNetworkFees(apiUrl: string): Promise<NetworkFees> {\n const response = await fetchWithTimeout(`${apiUrl}/v1/fees/recommended`);\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch network fees: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n\n const feeFields = [\n \"fastestFee\",\n \"halfHourFee\",\n \"hourFee\",\n \"economyFee\",\n \"minimumFee\",\n ] as const;\n\n for (const field of feeFields) {\n if (!isValidFeeRate(data[field])) {\n throw new Error(\n `Invalid fee rate ${field}=${data[field]} from mempool API: expected a positive number ≤ ${MAX_FEE_RATE}`,\n );\n }\n }\n\n if (\n data.minimumFee > data.economyFee ||\n data.economyFee > data.hourFee ||\n data.hourFee > data.halfHourFee ||\n data.halfHourFee > data.fastestFee\n ) {\n throw new Error(\n `Fee rate ordering violation from mempool API: expected ` +\n `minimumFee (${data.minimumFee}) <= economyFee (${data.economyFee}) <= ` +\n `hourFee (${data.hourFee}) <= halfHourFee (${data.halfHourFee}) <= ` +\n `fastestFee (${data.fastestFee}).`,\n );\n }\n\n return data as NetworkFees;\n}\n\n"],"names":["MAX_SATOSHIS","MEMPOOL_REQUEST_TIMEOUT_MS","fetchWithTimeout","url","options","controller","timeoutId","signals","combined","combineAbortSignals","error","MAX_FEE_RATE","isValidSatoshiValue","value","isValidFeeRate","isValidVout","vout","outputCount","assertValidTxid","txid","TXID_RE","assertValidAddress","address","BITCOIN_ADDRESS_RE","assertValidScriptPubKey","scriptPubKey","context","HEX_RE","KNOWN_SCRIPT_PREFIXES","prefix","MEMPOOL_API_URLS","fetchApi","response","errorText","contentType","pushTx","txHex","apiUrl","message","errorJson","getTxInfo","getTipHeight","raw","trimmed","height","getOutspend","getTxHex","getUtxoInfo","txInfo","output","getAddressUtxos","utxos","addressInfo","utxo","a","b","getMempoolApiUrl","network","getAddressTxs","getNetworkFees","data","feeFields","field"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../../src/tbv/core/clients/mempool/mempoolApi.ts"],"sourcesContent":["/**\n * Mempool API Client\n *\n * Client for interacting with mempool.space API for Bitcoin network operations.\n * Used for broadcasting transactions and fetching UTXO data.\n *\n * @module clients/mempool/mempoolApi\n */\n\nimport { combineAbortSignals } from \"../../utils/abortSignals\";\nimport {\n BITCOIN_ADDRESS_RE,\n HEX_RE,\n KNOWN_SCRIPT_PREFIXES,\n TXID_RE,\n} from \"../../utils/validation\";\n\nimport type {\n MempoolUTXO,\n NetworkFees,\n OutspendStatus,\n TxInfo,\n UtxoInfo,\n} from \"./types\";\n\n/** Maximum valid satoshi value: 21 million BTC × 10^8 sats/BTC */\nconst MAX_SATOSHIS = 21_000_000 * 1e8;\n\n/** Timeout for mempool API requests — prevents indefinite hangs from stalled endpoints */\nconst MEMPOOL_REQUEST_TIMEOUT_MS = 30_000;\n\n/** HTTP status the mempool API answers for an unknown transaction or resource */\nconst HTTP_NOT_FOUND = 404;\n\n/**\n * Fetch wrapper with AbortController-based timeout.\n * Ensures all mempool API requests fail bounded rather than hanging indefinitely.\n */\nasync function fetchWithTimeout(\n url: string,\n options?: RequestInit,\n): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(\n () => controller.abort(),\n MEMPOOL_REQUEST_TIMEOUT_MS,\n );\n\n // Compose timeout signal with any caller-supplied signal so both can cancel\n const signals = [controller.signal, options?.signal].filter(\n Boolean,\n ) as AbortSignal[];\n const combined = combineAbortSignals(signals);\n\n try {\n // Don't clear timeout here — let it cover body consumption by callers.\n // For the same reason the composed signal keeps its listeners attached on\n // the success path: detaching them would stop the timeout from aborting a\n // stalled body read.\n return await fetch(url, {\n ...options,\n signal: combined.signal,\n });\n } catch (error) {\n clearTimeout(timeoutId);\n combined.cleanup();\n if (\n error != null &&\n typeof error === \"object\" &&\n \"name\" in error &&\n error.name === \"AbortError\"\n ) {\n throw new Error(\n `Mempool API request timed out after ${MEMPOOL_REQUEST_TIMEOUT_MS}ms: ${url}`,\n );\n }\n throw error;\n }\n}\n\n/**\n * Maximum sane fee rate in sat/vByte.\n * The April 2024 Runes spike peaked around 1,805 sat/vB — 10,000 provides ample headroom.\n */\nconst MAX_FEE_RATE = 10_000;\n\nfunction isValidSatoshiValue(value: number): boolean {\n return Number.isInteger(value) && value > 0 && value <= MAX_SATOSHIS;\n}\n\nfunction isValidFeeRate(value: number): boolean {\n return Number.isInteger(value) && value > 0 && value <= MAX_FEE_RATE;\n}\n\nfunction isValidVout(vout: number, outputCount?: number): boolean {\n if (!Number.isInteger(vout) || vout < 0) return false;\n return outputCount === undefined || vout < outputCount;\n}\n\n\nfunction assertValidTxid(txid: string): void {\n if (!TXID_RE.test(txid)) {\n throw new Error(`Invalid transaction ID format: ${txid}`);\n }\n}\n\nfunction assertValidAddress(address: string): void {\n if (!BITCOIN_ADDRESS_RE.test(address)) {\n throw new Error(`Invalid Bitcoin address format: ${address}`);\n }\n}\n\nfunction assertValidScriptPubKey(scriptPubKey: string, context: string): void {\n if (!HEX_RE.test(scriptPubKey)) {\n throw new Error(\n `Invalid scriptPubKey: not valid hex for ${context}`,\n );\n }\n const matchesKnownType = KNOWN_SCRIPT_PREFIXES.some((prefix) =>\n scriptPubKey.toLowerCase().startsWith(prefix),\n );\n if (!matchesKnownType) {\n throw new Error(\n `Unrecognized scriptPubKey type for ${context}: ` +\n `prefix ${scriptPubKey.slice(0, 6)} does not match any known Bitcoin script type`,\n );\n }\n}\n\n/**\n * Default mempool API URLs by network.\n */\nexport const MEMPOOL_API_URLS = {\n mainnet: \"https://mempool.space/api\",\n testnet: \"https://mempool.space/testnet/api\",\n signet: \"https://mempool.space/signet/api\",\n} as const;\n\n/**\n * Thrown by `getTxInfo`, `getUtxoInfo`, `getTipHeight`, `getOutspend` and\n * `getAddressTxs` when the mempool API answers HTTP 404, for example for a\n * transaction it does not know. Their other failures throw a plain `Error`.\n */\nexport class MempoolNotFoundError extends Error {\n /** HTTP status of the failed response. */\n readonly status = HTTP_NOT_FOUND;\n\n constructor(message: string) {\n super(message);\n this.name = \"MempoolNotFoundError\";\n }\n}\n\n/**\n * Fetch wrapper with error handling.\n */\nasync function fetchApi<T>(\n url: string,\n options?: RequestInit,\n): Promise<T> {\n try {\n const response = await fetchWithTimeout(url, options);\n\n if (!response.ok) {\n const errorText = await response.text();\n const ErrorType =\n response.status === HTTP_NOT_FOUND ? MempoolNotFoundError : Error;\n throw new ErrorType(\n `Mempool API error (${response.status}): ${errorText || response.statusText}`,\n );\n }\n\n const contentType = response.headers.get(\"content-type\");\n if (contentType?.includes(\"application/json\")) {\n return (await response.json()) as T;\n } else {\n return (await response.text()) as T;\n }\n } catch (error) {\n if (error instanceof MempoolNotFoundError) {\n throw new MempoolNotFoundError(\n `Failed to fetch from mempool API: ${error.message}`,\n );\n }\n if (error instanceof Error) {\n throw new Error(`Failed to fetch from mempool API: ${error.message}`);\n }\n throw new Error(\"Failed to fetch from mempool API: Unknown error\");\n }\n}\n\n/**\n * Push a signed transaction to the Bitcoin network.\n *\n * @param txHex - The signed transaction hex string\n * @param apiUrl - Mempool API base URL\n * @returns The transaction ID\n * @throws Error if broadcasting fails\n */\nexport async function pushTx(txHex: string, apiUrl: string): Promise<string> {\n try {\n const response = await fetchWithTimeout(`${apiUrl}/tx`, {\n method: \"POST\",\n body: txHex,\n headers: {\n \"Content-Type\": \"text/plain\",\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n // Try to extract error message from response using robust JSON parsing\n let message: string | undefined;\n try {\n const errorJson = JSON.parse(errorText);\n message = errorJson.message ?? errorJson.error;\n } catch {\n // Not JSON, use raw text\n message = errorText;\n }\n throw new Error(\n message || `Failed to broadcast transaction: ${response.statusText}`,\n );\n }\n\n // Response is the transaction ID (plain text)\n const txId = await response.text();\n return txId;\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to broadcast BTC transaction: ${error.message}`);\n }\n throw new Error(\"Failed to broadcast BTC transaction: Unknown error\");\n }\n}\n\n/**\n * Get transaction information from mempool.\n *\n * @param txid - The transaction ID\n * @param apiUrl - Mempool API base URL\n * @returns Transaction information\n */\nexport async function getTxInfo(txid: string, apiUrl: string): Promise<TxInfo> {\n assertValidTxid(txid);\n return fetchApi<TxInfo>(`${apiUrl}/tx/${txid}`);\n}\n\n/**\n * Get the current block tip height.\n *\n * Source: mempool.space API — `GET /api/blocks/tip/height` returns the height\n * of the most recent block as a plain-text integer.\n *\n * The digit check alone is not enough to honour the contract below. A long\n * enough run of digits passes `/^\\d+$/` and then parses to a value no caller\n * can use: 400 digits yields `Infinity`, and 20 digits yields a finite but\n * unsafe integer. Callers subtract this from a confirmed block height to get a\n * confirmation depth, so either one produces an enormous depth and clears any\n * threshold it is compared against. Bound it to a safe integer here rather\n * than leaving each caller to discover the gap.\n *\n * @param apiUrl - Mempool API base URL\n * @returns The height of the most recent block\n * @throws Error if the response is not a whole number a caller can compute on\n */\nexport async function getTipHeight(apiUrl: string): Promise<number> {\n const raw = await fetchApi<string>(`${apiUrl}/blocks/tip/height`);\n const trimmed = raw.trim();\n const height = /^\\d+$/.test(trimmed) ? Number.parseInt(trimmed, 10) : NaN;\n if (!Number.isSafeInteger(height) || height < 0) {\n throw new Error(\n `Mempool API returned an invalid block tip height: \"${raw}\"`,\n );\n }\n return height;\n}\n\n/**\n * Get the spend status of a specific transaction output.\n *\n * Calls the esplora-compatible `GET /tx/{txid}/outspend/{vout}` endpoint\n * (mempool.space backend, mempool/electrs `rest.rs`). Returns\n * `{ spent: false }` for an unspent output, or\n * `{ spent: true, txid, vin, status }` when the output has been spent.\n *\n * @param txid - The transaction id whose output is being checked (no 0x prefix)\n * @param vout - The output index\n * @param apiUrl - Mempool API base URL\n * @returns The output's spend status\n */\nexport async function getOutspend(\n txid: string,\n vout: number,\n apiUrl: string,\n): Promise<OutspendStatus> {\n assertValidTxid(txid);\n if (!isValidVout(vout)) {\n throw new Error(`Invalid vout ${vout} for transaction ${txid}`);\n }\n return fetchApi<OutspendStatus>(`${apiUrl}/tx/${txid}/outspend/${vout}`);\n}\n\n/**\n * Get the hex representation of a transaction.\n *\n * @param txid - The transaction ID\n * @param apiUrl - Mempool API base URL\n * @returns The transaction hex string\n * @throws Error if the request fails or transaction is not found\n */\nexport async function getTxHex(txid: string, apiUrl: string): Promise<string> {\n assertValidTxid(txid);\n try {\n const response = await fetchWithTimeout(`${apiUrl}/tx/${txid}/hex`);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `Mempool API error (${response.status}): ${errorText || response.statusText}`,\n );\n }\n\n return await response.text();\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to get transaction hex for ${txid}: ${error.message}`);\n }\n throw new Error(`Failed to get transaction hex for ${txid}: Unknown error`);\n }\n}\n\n/**\n * Get UTXO information for a specific transaction output.\n *\n * This is used for constructing PSBTs where we need the witnessUtxo data.\n * Only supports Taproot (P2TR) and native SegWit (P2WPKH, P2WSH) script types.\n *\n * @param txid - The transaction ID containing the UTXO\n * @param vout - The output index\n * @param apiUrl - Mempool API base URL\n * @returns UTXO information with value and scriptPubKey\n */\nexport async function getUtxoInfo(\n txid: string,\n vout: number,\n apiUrl: string,\n): Promise<UtxoInfo> {\n assertValidTxid(txid);\n const txInfo = await getTxInfo(txid, apiUrl);\n\n if (!isValidVout(vout, txInfo.vout.length)) {\n throw new Error(\n `Invalid vout ${vout} for transaction ${txid} (has ${txInfo.vout.length} outputs)`,\n );\n }\n\n const output = txInfo.vout[vout];\n if (!isValidSatoshiValue(output.value)) {\n throw new Error(`Invalid UTXO value ${output.value} for ${txid}:${vout}`);\n }\n assertValidScriptPubKey(output.scriptpubkey, `${txid}:${vout}`);\n\n return {\n txid,\n vout,\n value: output.value,\n scriptPubKey: output.scriptpubkey,\n };\n}\n\n/**\n * Get all UTXOs for a Bitcoin address.\n *\n * @param address - The Bitcoin address\n * @param apiUrl - Mempool API base URL\n * @returns Array of UTXOs sorted by value (largest first)\n */\nexport async function getAddressUtxos(\n address: string,\n apiUrl: string,\n): Promise<MempoolUTXO[]> {\n assertValidAddress(address);\n try {\n // Fetch UTXOs for the address\n const utxos = await fetchApi<\n {\n txid: string;\n vout: number;\n value: number;\n status: {\n confirmed: boolean;\n };\n }[]\n >(`${apiUrl}/address/${address}/utxo`);\n\n // Fetch scriptPubKey for the address\n const addressInfo = await fetchApi<{\n isvalid: boolean;\n scriptPubKey: string;\n }>(`${apiUrl}/v1/validate-address/${address}`);\n\n if (!addressInfo.isvalid) {\n throw new Error(\n `Invalid Bitcoin address: ${address}. Mempool API validation failed.`,\n );\n }\n assertValidScriptPubKey(addressInfo.scriptPubKey, address);\n\n // Validate UTXO fields from the listing endpoint.\n // Per-UTXO cross-verification against /tx/{txid} is intentionally NOT done\n // here — it would be expensive (N API calls) and redundant: the broadcast\n // path already verifies each selected input via getUtxoInfo before signing.\n // Both endpoints come from the same mempool API, so cross-checking one\n // against the other on the same server does not add real security.\n for (const utxo of utxos) {\n assertValidTxid(utxo.txid);\n if (!isValidVout(utxo.vout)) {\n throw new Error(`Invalid vout ${utxo.vout} for ${utxo.txid}`);\n }\n if (!isValidSatoshiValue(utxo.value)) {\n throw new Error(\n `Invalid UTXO value ${utxo.value} for ${utxo.txid}:${utxo.vout}`,\n );\n }\n }\n\n // Sort by value (largest first) and map to our UTXO format\n const sortedUTXOs = utxos.sort((a, b) => b.value - a.value);\n\n return sortedUTXOs.map((utxo) => ({\n txid: utxo.txid,\n vout: utxo.vout,\n value: utxo.value,\n scriptPubKey: addressInfo.scriptPubKey,\n confirmed: utxo.status.confirmed,\n }));\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(\n `Failed to get UTXOs for address ${address}: ${error.message}`,\n );\n }\n throw new Error(\n `Failed to get UTXOs for address ${address}: Unknown error`,\n );\n }\n}\n\n/**\n * Get the mempool API URL for a given network.\n *\n * @param network - Bitcoin network (mainnet, testnet, signet)\n * @returns The mempool API URL\n */\nexport function getMempoolApiUrl(\n network: \"mainnet\" | \"testnet\" | \"signet\",\n): string {\n return MEMPOOL_API_URLS[network];\n}\n\n/**\n * Transaction summary from address transactions endpoint.\n */\nexport interface AddressTx {\n txid: string;\n status: {\n confirmed: boolean;\n block_height?: number;\n };\n}\n\n/**\n * Get recent transactions for a Bitcoin address.\n *\n * Returns the last 25 confirmed transactions plus any unconfirmed (mempool) transactions.\n * This is useful for checking if a specific transaction has been broadcast.\n *\n * @param address - The Bitcoin address\n * @param apiUrl - Mempool API base URL\n * @returns Array of recent transactions\n */\nexport async function getAddressTxs(\n address: string,\n apiUrl: string,\n): Promise<AddressTx[]> {\n assertValidAddress(address);\n return fetchApi<AddressTx[]>(`${apiUrl}/address/${address}/txs`);\n}\n\n/**\n * Fetches Bitcoin network fee recommendations from mempool.space API.\n *\n * @param apiUrl - Mempool API base URL\n * @returns Fee rates in sat/vbyte for different confirmation times\n * @throws Error if request fails or returns invalid data\n *\n * @see https://mempool.space/docs/api/rest#get-recommended-fees\n */\nexport async function getNetworkFees(apiUrl: string): Promise<NetworkFees> {\n const response = await fetchWithTimeout(`${apiUrl}/v1/fees/recommended`);\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch network fees: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n\n const feeFields = [\n \"fastestFee\",\n \"halfHourFee\",\n \"hourFee\",\n \"economyFee\",\n \"minimumFee\",\n ] as const;\n\n for (const field of feeFields) {\n if (!isValidFeeRate(data[field])) {\n throw new Error(\n `Invalid fee rate ${field}=${data[field]} from mempool API: expected a positive number ≤ ${MAX_FEE_RATE}`,\n );\n }\n }\n\n if (\n data.minimumFee > data.economyFee ||\n data.economyFee > data.hourFee ||\n data.hourFee > data.halfHourFee ||\n data.halfHourFee > data.fastestFee\n ) {\n throw new Error(\n `Fee rate ordering violation from mempool API: expected ` +\n `minimumFee (${data.minimumFee}) <= economyFee (${data.economyFee}) <= ` +\n `hourFee (${data.hourFee}) <= halfHourFee (${data.halfHourFee}) <= ` +\n `fastestFee (${data.fastestFee}).`,\n );\n }\n\n return data as NetworkFees;\n}\n\n"],"names":["MAX_SATOSHIS","MEMPOOL_REQUEST_TIMEOUT_MS","HTTP_NOT_FOUND","fetchWithTimeout","url","options","controller","timeoutId","signals","combined","combineAbortSignals","error","MAX_FEE_RATE","isValidSatoshiValue","value","isValidFeeRate","isValidVout","vout","outputCount","assertValidTxid","txid","TXID_RE","assertValidAddress","address","BITCOIN_ADDRESS_RE","assertValidScriptPubKey","scriptPubKey","context","HEX_RE","KNOWN_SCRIPT_PREFIXES","prefix","MEMPOOL_API_URLS","MempoolNotFoundError","message","__publicField","fetchApi","response","errorText","ErrorType","contentType","pushTx","txHex","apiUrl","errorJson","getTxInfo","getTipHeight","raw","trimmed","height","getOutspend","getTxHex","getUtxoInfo","txInfo","output","getAddressUtxos","utxos","addressInfo","utxo","a","b","getMempoolApiUrl","network","getAddressTxs","getNetworkFees","data","feeFields","field"],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module clients/mempool
|
|
7
7
|
*/
|
|
8
|
-
export { getAddressTxs, getAddressUtxos, getMempoolApiUrl, getNetworkFees, getOutspend, getTipHeight, getTxHex, getTxInfo, getUtxoInfo, MEMPOOL_API_URLS, pushTx, } from './mempoolApi';
|
|
8
|
+
export { getAddressTxs, getAddressUtxos, getMempoolApiUrl, getNetworkFees, getOutspend, getTipHeight, getTxHex, getTxInfo, getUtxoInfo, MEMPOOL_API_URLS, MempoolNotFoundError, pushTx, } from './mempoolApi';
|
|
9
9
|
export type { AddressTx } from './mempoolApi';
|
|
10
10
|
export type { MempoolUTXO, NetworkFees, OutspendStatus, TxInfo, TxInput, TxOutput, TxStatus, UtxoInfo, } from './types';
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/tbv/core/clients/mempool/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,MAAM,GACP,MAAM,cAAc,CAAC;AAEtB,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,YAAY,EACV,WAAW,EACX,WAAW,EACX,cAAc,EACd,MAAM,EACN,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,QAAQ,GACT,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/tbv/core/clients/mempool/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,MAAM,GACP,MAAM,cAAc,CAAC;AAEtB,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,YAAY,EACV,WAAW,EACX,WAAW,EACX,cAAc,EACd,MAAM,EACN,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,QAAQ,GACT,MAAM,SAAS,CAAC"}
|
|
@@ -1,75 +1,88 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
var F = Object.defineProperty;
|
|
2
|
+
var g = (e, r, t) => r in e ? F(e, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[r] = t;
|
|
3
|
+
var m = (e, r, t) => g(e, typeof r != "symbol" ? r + "" : r, t);
|
|
4
|
+
import { c as I } from "../../../../abortSignals-BPpAUL1Z.js";
|
|
5
|
+
import { B as T, H as y, K as x, T as v } from "../../../../validation-OSC0xTHB.js";
|
|
6
|
+
const b = 21e6 * 1e8, w = 3e4, h = 404;
|
|
4
7
|
async function f(e, r) {
|
|
5
8
|
const t = new AbortController(), o = setTimeout(
|
|
6
9
|
() => t.abort(),
|
|
7
|
-
|
|
8
|
-
),
|
|
10
|
+
w
|
|
11
|
+
), s = [t.signal, r == null ? void 0 : r.signal].filter(
|
|
9
12
|
Boolean
|
|
10
|
-
), n =
|
|
13
|
+
), n = I(s);
|
|
11
14
|
try {
|
|
12
15
|
return await fetch(e, {
|
|
13
16
|
...r,
|
|
14
17
|
signal: n.signal
|
|
15
18
|
});
|
|
16
|
-
} catch (
|
|
17
|
-
throw clearTimeout(o), n.cleanup(),
|
|
18
|
-
`Mempool API request timed out after ${
|
|
19
|
-
) :
|
|
19
|
+
} catch (a) {
|
|
20
|
+
throw clearTimeout(o), n.cleanup(), a != null && typeof a == "object" && "name" in a && a.name === "AbortError" ? new Error(
|
|
21
|
+
`Mempool API request timed out after ${w}ms: ${e}`
|
|
22
|
+
) : a;
|
|
20
23
|
}
|
|
21
24
|
}
|
|
22
|
-
const
|
|
23
|
-
function
|
|
24
|
-
return Number.isInteger(e) && e > 0 && e <=
|
|
25
|
+
const d = 1e4;
|
|
26
|
+
function $(e) {
|
|
27
|
+
return Number.isInteger(e) && e > 0 && e <= b;
|
|
25
28
|
}
|
|
26
|
-
function
|
|
27
|
-
return Number.isInteger(e) && e > 0 && e <=
|
|
29
|
+
function A(e) {
|
|
30
|
+
return Number.isInteger(e) && e > 0 && e <= d;
|
|
28
31
|
}
|
|
29
|
-
function
|
|
32
|
+
function l(e, r) {
|
|
30
33
|
return !Number.isInteger(e) || e < 0 ? !1 : r === void 0 || e < r;
|
|
31
34
|
}
|
|
32
35
|
function c(e) {
|
|
33
|
-
if (!
|
|
36
|
+
if (!v.test(e))
|
|
34
37
|
throw new Error(`Invalid transaction ID format: ${e}`);
|
|
35
38
|
}
|
|
36
|
-
function
|
|
37
|
-
if (!
|
|
39
|
+
function p(e) {
|
|
40
|
+
if (!T.test(e))
|
|
38
41
|
throw new Error(`Invalid Bitcoin address format: ${e}`);
|
|
39
42
|
}
|
|
40
|
-
function
|
|
41
|
-
if (!
|
|
43
|
+
function E(e, r) {
|
|
44
|
+
if (!y.test(e))
|
|
42
45
|
throw new Error(
|
|
43
46
|
`Invalid scriptPubKey: not valid hex for ${r}`
|
|
44
47
|
);
|
|
45
|
-
if (!
|
|
48
|
+
if (!x.some(
|
|
46
49
|
(o) => e.toLowerCase().startsWith(o)
|
|
47
50
|
))
|
|
48
51
|
throw new Error(
|
|
49
52
|
`Unrecognized scriptPubKey type for ${r}: prefix ${e.slice(0, 6)} does not match any known Bitcoin script type`
|
|
50
53
|
);
|
|
51
54
|
}
|
|
52
|
-
const
|
|
55
|
+
const P = {
|
|
53
56
|
mainnet: "https://mempool.space/api",
|
|
54
57
|
testnet: "https://mempool.space/testnet/api",
|
|
55
58
|
signet: "https://mempool.space/signet/api"
|
|
56
59
|
};
|
|
60
|
+
class u extends Error {
|
|
61
|
+
constructor(t) {
|
|
62
|
+
super(t);
|
|
63
|
+
/** HTTP status of the failed response. */
|
|
64
|
+
m(this, "status", h);
|
|
65
|
+
this.name = "MempoolNotFoundError";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
57
68
|
async function i(e, r) {
|
|
58
69
|
try {
|
|
59
70
|
const t = await f(e, r);
|
|
60
71
|
if (!t.ok) {
|
|
61
|
-
const
|
|
62
|
-
throw new
|
|
63
|
-
`Mempool API error (${t.status}): ${
|
|
72
|
+
const s = await t.text(), n = t.status === h ? u : Error;
|
|
73
|
+
throw new n(
|
|
74
|
+
`Mempool API error (${t.status}): ${s || t.statusText}`
|
|
64
75
|
);
|
|
65
76
|
}
|
|
66
77
|
const o = t.headers.get("content-type");
|
|
67
78
|
return o != null && o.includes("application/json") ? await t.json() : await t.text();
|
|
68
79
|
} catch (t) {
|
|
69
|
-
throw t instanceof
|
|
80
|
+
throw t instanceof u ? new u(
|
|
81
|
+
`Failed to fetch from mempool API: ${t.message}`
|
|
82
|
+
) : t instanceof Error ? new Error(`Failed to fetch from mempool API: ${t.message}`) : new Error("Failed to fetch from mempool API: Unknown error");
|
|
70
83
|
}
|
|
71
84
|
}
|
|
72
|
-
async function
|
|
85
|
+
async function S(e, r) {
|
|
73
86
|
try {
|
|
74
87
|
const t = await f(`${r}/tx`, {
|
|
75
88
|
method: "POST",
|
|
@@ -79,13 +92,13 @@ async function A(e, r) {
|
|
|
79
92
|
}
|
|
80
93
|
});
|
|
81
94
|
if (!t.ok) {
|
|
82
|
-
const
|
|
95
|
+
const s = await t.text();
|
|
83
96
|
let n;
|
|
84
97
|
try {
|
|
85
|
-
const
|
|
86
|
-
n =
|
|
98
|
+
const a = JSON.parse(s);
|
|
99
|
+
n = a.message ?? a.error;
|
|
87
100
|
} catch {
|
|
88
|
-
n =
|
|
101
|
+
n = s;
|
|
89
102
|
}
|
|
90
103
|
throw new Error(
|
|
91
104
|
n || `Failed to broadcast transaction: ${t.statusText}`
|
|
@@ -96,10 +109,10 @@ async function A(e, r) {
|
|
|
96
109
|
throw t instanceof Error ? new Error(`Failed to broadcast BTC transaction: ${t.message}`) : new Error("Failed to broadcast BTC transaction: Unknown error");
|
|
97
110
|
}
|
|
98
111
|
}
|
|
99
|
-
async function
|
|
112
|
+
async function O(e, r) {
|
|
100
113
|
return c(e), i(`${r}/tx/${e}`);
|
|
101
114
|
}
|
|
102
|
-
async function
|
|
115
|
+
async function _(e) {
|
|
103
116
|
const r = await i(`${e}/blocks/tip/height`), t = r.trim(), o = /^\d+$/.test(t) ? Number.parseInt(t, 10) : NaN;
|
|
104
117
|
if (!Number.isSafeInteger(o) || o < 0)
|
|
105
118
|
throw new Error(
|
|
@@ -107,12 +120,12 @@ async function P(e) {
|
|
|
107
120
|
);
|
|
108
121
|
return o;
|
|
109
122
|
}
|
|
110
|
-
async function
|
|
111
|
-
if (c(e), !
|
|
123
|
+
async function k(e, r, t) {
|
|
124
|
+
if (c(e), !l(r))
|
|
112
125
|
throw new Error(`Invalid vout ${r} for transaction ${e}`);
|
|
113
126
|
return i(`${t}/tx/${e}/outspend/${r}`);
|
|
114
127
|
}
|
|
115
|
-
async function
|
|
128
|
+
async function H(e, r) {
|
|
116
129
|
c(e);
|
|
117
130
|
try {
|
|
118
131
|
const t = await f(`${r}/tx/${e}/hex`);
|
|
@@ -127,41 +140,41 @@ async function S(e, r) {
|
|
|
127
140
|
throw t instanceof Error ? new Error(`Failed to get transaction hex for ${e}: ${t.message}`) : new Error(`Failed to get transaction hex for ${e}: Unknown error`);
|
|
128
141
|
}
|
|
129
142
|
}
|
|
130
|
-
async function
|
|
143
|
+
async function X(e, r, t) {
|
|
131
144
|
c(e);
|
|
132
|
-
const o = await
|
|
133
|
-
if (!
|
|
145
|
+
const o = await O(e, t);
|
|
146
|
+
if (!l(r, o.vout.length))
|
|
134
147
|
throw new Error(
|
|
135
148
|
`Invalid vout ${r} for transaction ${e} (has ${o.vout.length} outputs)`
|
|
136
149
|
);
|
|
137
|
-
const
|
|
138
|
-
if (
|
|
139
|
-
throw new Error(`Invalid UTXO value ${
|
|
140
|
-
return
|
|
150
|
+
const s = o.vout[r];
|
|
151
|
+
if (!$(s.value))
|
|
152
|
+
throw new Error(`Invalid UTXO value ${s.value} for ${e}:${r}`);
|
|
153
|
+
return E(s.scriptpubkey, `${e}:${r}`), {
|
|
141
154
|
txid: e,
|
|
142
155
|
vout: r,
|
|
143
|
-
value:
|
|
144
|
-
scriptPubKey:
|
|
156
|
+
value: s.value,
|
|
157
|
+
scriptPubKey: s.scriptpubkey
|
|
145
158
|
};
|
|
146
159
|
}
|
|
147
|
-
async function
|
|
148
|
-
|
|
160
|
+
async function R(e, r) {
|
|
161
|
+
p(e);
|
|
149
162
|
try {
|
|
150
163
|
const t = await i(`${r}/address/${e}/utxo`), o = await i(`${r}/v1/validate-address/${e}`);
|
|
151
164
|
if (!o.isvalid)
|
|
152
165
|
throw new Error(
|
|
153
166
|
`Invalid Bitcoin address: ${e}. Mempool API validation failed.`
|
|
154
167
|
);
|
|
155
|
-
|
|
168
|
+
E(o.scriptPubKey, e);
|
|
156
169
|
for (const n of t) {
|
|
157
|
-
if (c(n.txid), !
|
|
170
|
+
if (c(n.txid), !l(n.vout))
|
|
158
171
|
throw new Error(`Invalid vout ${n.vout} for ${n.txid}`);
|
|
159
|
-
if (
|
|
172
|
+
if (!$(n.value))
|
|
160
173
|
throw new Error(
|
|
161
174
|
`Invalid UTXO value ${n.value} for ${n.txid}:${n.vout}`
|
|
162
175
|
);
|
|
163
176
|
}
|
|
164
|
-
return t.sort((n,
|
|
177
|
+
return t.sort((n, a) => a.value - n.value).map((n) => ({
|
|
165
178
|
txid: n.txid,
|
|
166
179
|
vout: n.vout,
|
|
167
180
|
value: n.value,
|
|
@@ -176,13 +189,13 @@ async function k(e, r) {
|
|
|
176
189
|
);
|
|
177
190
|
}
|
|
178
191
|
}
|
|
179
|
-
function
|
|
180
|
-
return
|
|
192
|
+
function K(e) {
|
|
193
|
+
return P[e];
|
|
181
194
|
}
|
|
182
|
-
async function
|
|
183
|
-
return
|
|
195
|
+
async function B(e, r) {
|
|
196
|
+
return p(e), i(`${r}/address/${e}/txs`);
|
|
184
197
|
}
|
|
185
|
-
async function
|
|
198
|
+
async function V(e) {
|
|
186
199
|
const r = await f(`${e}/v1/fees/recommended`);
|
|
187
200
|
if (!r.ok)
|
|
188
201
|
throw new Error(
|
|
@@ -195,10 +208,10 @@ async function N(e) {
|
|
|
195
208
|
"economyFee",
|
|
196
209
|
"minimumFee"
|
|
197
210
|
];
|
|
198
|
-
for (const
|
|
199
|
-
if (!
|
|
211
|
+
for (const s of o)
|
|
212
|
+
if (!A(t[s]))
|
|
200
213
|
throw new Error(
|
|
201
|
-
`Invalid fee rate ${
|
|
214
|
+
`Invalid fee rate ${s}=${t[s]} from mempool API: expected a positive number ≤ ${d}`
|
|
202
215
|
);
|
|
203
216
|
if (t.minimumFee > t.economyFee || t.economyFee > t.hourFee || t.hourFee > t.halfHourFee || t.halfHourFee > t.fastestFee)
|
|
204
217
|
throw new Error(
|
|
@@ -207,16 +220,17 @@ async function N(e) {
|
|
|
207
220
|
return t;
|
|
208
221
|
}
|
|
209
222
|
export {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
223
|
+
P as MEMPOOL_API_URLS,
|
|
224
|
+
u as MempoolNotFoundError,
|
|
225
|
+
B as getAddressTxs,
|
|
226
|
+
R as getAddressUtxos,
|
|
227
|
+
K as getMempoolApiUrl,
|
|
228
|
+
V as getNetworkFees,
|
|
229
|
+
k as getOutspend,
|
|
230
|
+
_ as getTipHeight,
|
|
231
|
+
H as getTxHex,
|
|
232
|
+
O as getTxInfo,
|
|
233
|
+
X as getUtxoInfo,
|
|
234
|
+
S as pushTx
|
|
221
235
|
};
|
|
222
236
|
//# sourceMappingURL=index.js.map
|