@satora/swap 1.3.3 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -161,6 +161,16 @@ type SwapActionInput = {
161
161
  * `false`, `pending` resolves to `wait` (not `fund`) and no refund is offered.
162
162
  */
163
163
  clientFunds?: boolean;
164
+ /**
165
+ * Whether the server's leg is an on-chain HTLC the client claims (the
166
+ * default). `false` for receive-on-Lightning swaps (`*_to_lightning`): there
167
+ * the server "funds" by paying the client's invoice off-chain, so there is
168
+ * nothing to claim and no claim window — {@link serverRefundLocktime} is
169
+ * meaningless. When `false`, `serverfunded` (the payment is in flight)
170
+ * resolves to `wait`, with the unilateral refund listed but blocked until
171
+ * the client's own timelock, exactly like `clientfunded`.
172
+ */
173
+ serverFunds?: boolean;
164
174
  };
165
175
  /** On-chain state of one HTLC in a swap. */
166
176
  type HtlcObservation = "absent" | "mempool" | "confirmed" | "invalid" | "spent_claim" | "spent_refund";
@@ -426,9 +436,10 @@ type SwapTrackerOptions = {
426
436
  * leg holds funds on-chain (≥ clientfunded, unresolved), where refund safety
427
437
  * must not depend on the server. Everything else advances on server hints
428
438
  * only ({@link applyHint}); a swap with nothing at stake costs zero chain
429
- * reads. Default 60s.
439
+ * reads. A getter is read on every tick, so the cadence can follow a
440
+ * setting that changes on a live client. Default 60s.
430
441
  */
431
- atRiskReconcileIntervalMs?: number;
442
+ atRiskReconcileIntervalMs?: number | (() => number);
432
443
  };
433
444
  declare class SwapTracker {
434
445
  #private;
@@ -462,6 +473,7 @@ declare class SwapTracker {
462
473
  */
463
474
  applyHint(swapId: string, opts?: {
464
475
  force?: boolean;
476
+ status?: SwapStatus;
465
477
  }): Promise<void>;
466
478
  /** Notify `cb` of the current action for each tracked swap, then on every change. */
467
479
  subscribeToActions(cb: ActionSubscriber): () => void;
@@ -682,6 +694,8 @@ declare class Client {
682
694
  /** Delegated to the legacy client (migration checkpoint). */
683
695
  createArkadeToLightningSwap(...args: Parameters<Client$1["createArkadeToLightningSwap"]>): ReturnType<Client$1["createArkadeToLightningSwap"]>;
684
696
  /** Delegated to the legacy client (migration checkpoint). */
697
+ createEvmToLightningSwap(...args: Parameters<Client$1["createEvmToLightningSwap"]>): ReturnType<Client$1["createEvmToLightningSwap"]>;
698
+ /** Delegated to the legacy client (migration checkpoint). */
685
699
  createEvmToArkadeSwapGeneric(...args: Parameters<Client$1["createEvmToArkadeSwapGeneric"]>): ReturnType<Client$1["createEvmToArkadeSwapGeneric"]>;
686
700
  /** Delegated to the legacy client (migration checkpoint). */
687
701
  createEvmToBitcoinSwap(...args: Parameters<Client$1["createEvmToBitcoinSwap"]>): ReturnType<Client$1["createEvmToBitcoinSwap"]>;
@@ -709,6 +723,17 @@ declare class Client {
709
723
  recoverGaslessFunds(...args: Parameters<Client$1["recoverGaslessFunds"]>): ReturnType<Client$1["recoverGaslessFunds"]>;
710
724
  /** Delegated to the legacy client (migration checkpoint). */
711
725
  hasReceivedVtxo(...args: Parameters<Client$1["hasReceivedVtxo"]>): ReturnType<Client$1["hasReceivedVtxo"]>;
726
+ /** Confirmations a server-funded Bitcoin HTLC needs before it is claimable. */
727
+ getBitcoinMinConfirmations(): number | undefined;
728
+ /**
729
+ * At `0` the claim goes out against a mempool funding, trusting the funder
730
+ * not to replace it once the claim reveals the preimage.
731
+ *
732
+ * Only the chain monitors read a depth, so this does nothing unless the
733
+ * client was built with {@link ClientBuilder.withChainVerifiedTracking}.
734
+ * Takes effect on subsequent reads, including swaps already tracked.
735
+ */
736
+ setBitcoinMinConfirmations(minConfirmations: number | undefined): void;
712
737
  /**
713
738
  * Start observing the user's active swaps and deriving each one's next action.
714
739
  *
@@ -799,7 +824,8 @@ declare class ClientBuilder {
799
824
  * funding hits the mempool, which TRUSTS the funder not to double-spend it
800
825
  * (claiming publishes the preimage, so a funder that then replaced its
801
826
  * funding could take both legs). Set `1` (or more) for a block-depth policy
802
- * that doesn't rely on the funder's good behaviour.
827
+ * that doesn't rely on the funder's good behaviour. Read only by the chain
828
+ * monitors, so it needs {@link withChainVerifiedTracking} to have any effect.
803
829
  */
804
830
  withBitcoinMinConfirmations(minConfirmations: number): this;
805
831
  /**
@@ -962,67 +988,6 @@ type BitcoinHtlcFacts = {
962
988
  spendWitness?: string[];
963
989
  };
964
990
 
965
- /** The chain surface the observer needs (the esplora and electrum readers satisfy it). */
966
- type BitcoinChainReader = {
967
- /**
968
- * Funding + spend facts for an HTLC witness-script address. `minConfirmations`
969
- * overrides the reader's default for this address alone — the two legs of a
970
- * swap do not share one rule.
971
- */
972
- getHtlcFacts(address: string, minConfirmations?: number): Promise<BitcoinHtlcFacts>;
973
- /**
974
- * Optional push capability: invoke `onChange` whenever the address's tx
975
- * history changes (e.g. an Electrum scripthash subscription). Returns an
976
- * unsubscribe function. When present, the manager reconciles on push
977
- * instead of relying solely on the tracker's poll cadence.
978
- */
979
- subscribe?(address: string, onChange: () => void): () => void;
980
- };
981
- type BitcoinCreateConfig = {
982
- /** One or more esplora REST base URLs; several are tried in rotation with failover. */
983
- esploraUrl: string | string[];
984
- /**
985
- * Optional Electrum WebSocket URL (Fulcrum `ws`/`wss` port). When set, the
986
- * manager reads via Electrum (fresher than public explorers) and gets push
987
- * reconciles via scripthash subscriptions; the esplora reader remains the
988
- * fallback on Electrum errors.
989
- */
990
- electrumWsUrl?: string;
991
- /** Network the HTLC addresses live on (for Electrum scripthashes); default mainnet. */
992
- network?: "mainnet" | "testnet" | "signet" | "regtest";
993
- /** The current Bitcoin MTP (ms); typically `async () => (await client.getMtp()).mtp * 1000`. */
994
- chainTime?: () => Promise<number>;
995
- /**
996
- * Confirmations a funding tx needs before it observes as `confirmed`.
997
- * Default `0`: accept an unconfirmed funding, trusting the funder not to
998
- * double-spend it (the claim reveals the preimage against it). `1` = wait
999
- * for a block.
1000
- */
1001
- minConfirmations?: number;
1002
- };
1003
- type BitcoinContractManagerDeps = {
1004
- reader: BitcoinChainReader;
1005
- chainTime?: () => Promise<number>;
1006
- };
1007
- declare class BitcoinContractManager implements ContractManager {
1008
- #private;
1009
- readonly ledger: Ledger;
1010
- private constructor();
1011
- static fromDeps(deps: BitcoinContractManagerDeps): BitcoinContractManager;
1012
- static create(config: BitcoinCreateConfig): Promise<BitcoinContractManager>;
1013
- canObserve(ref: HtlcRef): boolean;
1014
- register(ref: HtlcRef): Promise<void>;
1015
- unregister(ref: HtlcRef): Promise<void>;
1016
- getState(ref: HtlcRef): HtlcObservation | undefined;
1017
- chainNow(_ref: HtlcRef): number | undefined;
1018
- onEvent(cb: (ref: HtlcRef, state: HtlcObservation) => void): () => void;
1019
- refresh(): Promise<void>;
1020
- reconcile(ref: HtlcRef): Promise<void>;
1021
- dispose(): void;
1022
- /** The preimage a claim revealed on this HTLC, if one was seen. */
1023
- getPreimage(ref: HtlcRef): Uint8Array | undefined;
1024
- }
1025
-
1026
991
  /**
1027
992
  * A esplora-backed {@link BitcoinChainReader} — the concrete chain source the
1028
993
  * {@link BitcoinContractManager} uses in production.
@@ -1050,6 +1015,12 @@ type EsploraTx = {
1050
1015
  block_height?: number;
1051
1016
  };
1052
1017
  };
1018
+ /** A depth already resolved to a number, for the pure classifier below. */
1019
+ type BitcoinConfirmationPolicy = {
1020
+ minConfirmations?: number;
1021
+ };
1022
+ /** A depth, or a getter resolved per read so it can change without a rebuild. */
1023
+ type MinConfirmationsSource = number | (() => number | undefined);
1053
1024
  /**
1054
1025
  * When a funding tx counts as `confirmed` for observation purposes.
1055
1026
  *
@@ -1062,9 +1033,10 @@ type EsploraTx = {
1062
1033
  * `1` (or more) for a policy that doesn't rely on the funder's good behaviour;
1063
1034
  * values above 1 make the reader fetch the tip height to compute depth.
1064
1035
  */
1065
- type BitcoinConfirmationPolicy = {
1066
- minConfirmations?: number;
1036
+ type BitcoinReaderPolicy = {
1037
+ minConfirmations?: MinConfirmationsSource;
1067
1038
  };
1039
+ declare function resolveMinConfirmations(source: MinConfirmationsSource | undefined): number;
1068
1040
  /**
1069
1041
  * Reduce an address's esplora tx history to HTLC facts. If a tx spends an output
1070
1042
  * at the address, that's the resolving spend (its witness classifies claim vs
@@ -1086,7 +1058,69 @@ declare const DEFAULT_ESPLORA_URLS: string[];
1086
1058
  * providers) and fails over to the rest on error — so a throttled or failing
1087
1059
  * provider doesn't stall tracking.
1088
1060
  */
1089
- declare function esploraReader(esploraUrls: string | string[], fetchImpl?: typeof fetch, policy?: BitcoinConfirmationPolicy): BitcoinChainReader;
1061
+ declare function esploraReader(esploraUrls: string | string[], fetchImpl?: typeof fetch, policy?: BitcoinReaderPolicy): BitcoinChainReader;
1062
+
1063
+ /** The chain surface the observer needs (the esplora and electrum readers satisfy it). */
1064
+ type BitcoinChainReader = {
1065
+ /**
1066
+ * Funding + spend facts for an HTLC witness-script address. `minConfirmations`
1067
+ * overrides the reader's default for this address alone — the two legs of a
1068
+ * swap do not share one rule.
1069
+ */
1070
+ getHtlcFacts(address: string, minConfirmations?: number): Promise<BitcoinHtlcFacts>;
1071
+ /**
1072
+ * Optional push capability: invoke `onChange` whenever the address's tx
1073
+ * history changes (e.g. an Electrum scripthash subscription). Returns an
1074
+ * unsubscribe function. When present, the manager reconciles on push
1075
+ * instead of relying solely on the tracker's poll cadence.
1076
+ */
1077
+ subscribe?(address: string, onChange: () => void): () => void;
1078
+ };
1079
+ type BitcoinCreateConfig = {
1080
+ /** One or more esplora REST base URLs; several are tried in rotation with failover. */
1081
+ esploraUrl: string | string[];
1082
+ /**
1083
+ * Optional Electrum WebSocket URL (Fulcrum `ws`/`wss` port). When set, the
1084
+ * manager reads via Electrum (fresher than public explorers) and gets push
1085
+ * reconciles via scripthash subscriptions; the esplora reader remains the
1086
+ * fallback on Electrum errors.
1087
+ */
1088
+ electrumWsUrl?: string;
1089
+ /** Network the HTLC addresses live on (for Electrum scripthashes); default mainnet. */
1090
+ network?: "mainnet" | "testnet" | "signet" | "regtest";
1091
+ /** The current Bitcoin MTP (ms); typically `async () => (await client.getMtp()).mtp * 1000`. */
1092
+ chainTime?: () => Promise<number>;
1093
+ /**
1094
+ * Confirmations a funding tx needs before it observes as `confirmed`.
1095
+ * Default `0`: accept an unconfirmed funding, trusting the funder not to
1096
+ * double-spend it (the claim reveals the preimage against it). `1` = wait
1097
+ * for a block. Only the server-funded leg reads it; `swapToTracked` pins the
1098
+ * client-funded leg to 1.
1099
+ */
1100
+ minConfirmations?: MinConfirmationsSource;
1101
+ };
1102
+ type BitcoinContractManagerDeps = {
1103
+ reader: BitcoinChainReader;
1104
+ chainTime?: () => Promise<number>;
1105
+ };
1106
+ declare class BitcoinContractManager implements ContractManager {
1107
+ #private;
1108
+ readonly ledger: Ledger;
1109
+ private constructor();
1110
+ static fromDeps(deps: BitcoinContractManagerDeps): BitcoinContractManager;
1111
+ static create(config: BitcoinCreateConfig): Promise<BitcoinContractManager>;
1112
+ canObserve(ref: HtlcRef): boolean;
1113
+ register(ref: HtlcRef): Promise<void>;
1114
+ unregister(ref: HtlcRef): Promise<void>;
1115
+ getState(ref: HtlcRef): HtlcObservation | undefined;
1116
+ chainNow(_ref: HtlcRef): number | undefined;
1117
+ onEvent(cb: (ref: HtlcRef, state: HtlcObservation) => void): () => void;
1118
+ refresh(): Promise<void>;
1119
+ reconcile(ref: HtlcRef): Promise<void>;
1120
+ dispose(): void;
1121
+ /** The preimage a claim revealed on this HTLC, if one was seen. */
1122
+ getPreimage(ref: HtlcRef): Uint8Array | undefined;
1123
+ }
1090
1124
 
1091
1125
  /**
1092
1126
  * An Electrum-backed {@link BitcoinChainReader} — reads HTLC facts from our own
@@ -1121,7 +1155,7 @@ type ElectrumReaderNetwork = "mainnet" | "testnet" | "signet" | "regtest";
1121
1155
  * Build a {@link BitcoinChainReader} over an Electrum connection, with push
1122
1156
  * support and an optional fallback reader for outages.
1123
1157
  */
1124
- declare function electrumReader(client: ElectrumRpc, opts?: BitcoinConfirmationPolicy & {
1158
+ declare function electrumReader(client: ElectrumRpc, opts?: BitcoinReaderPolicy & {
1125
1159
  /** Network the HTLC addresses live on; defaults to mainnet. */
1126
1160
  network?: ElectrumReaderNetwork;
1127
1161
  /** Reader consulted when the Electrum server errors (e.g. esplora). */
@@ -1305,6 +1339,8 @@ type EvmLogClient = {
1305
1339
  address: `0x${string}`[];
1306
1340
  topics: (`0x${string}`[] | null)[];
1307
1341
  fromBlock: `0x${string}`;
1342
+ /** Set only when the read is chunked (see `maxBlockRange`). */
1343
+ toBlock?: `0x${string}`;
1308
1344
  }
1309
1345
  ];
1310
1346
  }): Promise<RawLog[]>;
@@ -1317,8 +1353,16 @@ type EvmLogClient = {
1317
1353
  }>;
1318
1354
  getBlock(): Promise<Pick<Block, "timestamp" | "number">>;
1319
1355
  };
1356
+ type EvmReaderOptions = {
1357
+ /**
1358
+ * Largest block span one `eth_getLogs` may cover. Some providers cap it
1359
+ * (rpc.rootstock.io: 2000 blocks); a read past the cap is split into
1360
+ * consecutive chunks up to the latest block. Unset means one unbounded call.
1361
+ */
1362
+ maxBlockRange?: bigint;
1363
+ };
1320
1364
  /** Build an {@link EvmChainReader} over an existing viem-like client. */
1321
- declare function evmReaderFromClient(client: EvmLogClient): EvmChainReader;
1365
+ declare function evmReaderFromClient(client: EvmLogClient, options?: EvmReaderOptions): EvmChainReader;
1322
1366
  /**
1323
1367
  * Build an {@link EvmChainReader} over one or more EVM JSON-RPC endpoints. With
1324
1368
  * several, viem's `fallback` tries them in order and fails over on error.
@@ -1327,7 +1371,7 @@ declare function evmReaderFromClient(client: EvmLogClient): EvmChainReader;
1327
1371
  * public RPCs rate-limiting us (publicnode 403s) — and it contradicts this
1328
1372
  * package's near-zero-RPC design.
1329
1373
  */
1330
- declare function createEvmRpcReader(rpcUrls: string | string[]): EvmChainReader;
1374
+ declare function createEvmRpcReader(rpcUrls: string | string[], options?: EvmReaderOptions): EvmChainReader;
1331
1375
  /**
1332
1376
  * Resolve the per-chain readers used for tracking: the tested {@link
1333
1377
  * DEFAULT_EVM_RPCS} by default, with any `overrides` taking priority for their
@@ -1579,4 +1623,4 @@ declare class WsStatusSource {
1579
1623
 
1580
1624
  declare function swapToTracked(stored: StoredSwap): TrackedSwap | undefined;
1581
1625
 
1582
- export { type ActionSubscriber, ArkadeContractManager, type ArkadeContractManagerDeps, type ArkadeCreateConfig, type ArkadeVhtlcInput, type BitcoinChainReader, type BitcoinConfirmationPolicy, BitcoinContractManager, type BitcoinContractManagerDeps, type BitcoinCreateConfig, type BlockedBy, type BlockedReason, type CctpClaimEvidence, type ClaimAction, Client, ClientBuilder, type ContractManager, DEFAULT_ESPLORA_URLS, DEFAULT_EVM_RPCS, type ElectrumReaderNetwork, type ElectrumRpc, type EvmChainReader, EvmContractManager, type EvmContractManagerDeps, type EvmHtlcQuery, type EvmLogClient, type FundAction, HintTracker, type HintTrackerOptions, type HtlcObservation, type HtlcRef, type Ledger, type NoneAction, type RawLog, type RecoverCctpClaimAction, type RefundCollaborativeAction, type RefundUnilateralAction, type SwapAction, type SwapActionAutomation, type SwapActionId, type SwapActionInput, type SwapActions, type SwapObservations, type SwapOutcome, type SwapStatusUpdate, SwapTracker, SwapWorker, type SwapWorkerOptions, type TrackedSwap, type WaitAction, type WaitingOn, type WebSocketLike, type WorkerHintSource, type WorkerTracker, WsStatusSource, type WsStatusSourceOptions, buildArkadeVhtlcRef, createEvmRpcReader, defaultArkadeServerUrl, defaultEvmReaders, deriveSwapActions, deriveSwapStatus, electrumReader, esploraReader, evmReaderFromClient, htlcFactsFromEsploraTxs, htlcKey, htlcQueryKey, swapToTracked };
1626
+ export { type ActionSubscriber, ArkadeContractManager, type ArkadeContractManagerDeps, type ArkadeCreateConfig, type ArkadeVhtlcInput, type BitcoinChainReader, type BitcoinConfirmationPolicy, BitcoinContractManager, type BitcoinContractManagerDeps, type BitcoinCreateConfig, type BitcoinReaderPolicy, type BlockedBy, type BlockedReason, type CctpClaimEvidence, type ClaimAction, Client, ClientBuilder, type ContractManager, DEFAULT_ESPLORA_URLS, DEFAULT_EVM_RPCS, type ElectrumReaderNetwork, type ElectrumRpc, type EvmChainReader, EvmContractManager, type EvmContractManagerDeps, type EvmHtlcQuery, type EvmLogClient, type FundAction, HintTracker, type HintTrackerOptions, type HtlcObservation, type HtlcRef, type Ledger, type MinConfirmationsSource, type NoneAction, type RawLog, type RecoverCctpClaimAction, type RefundCollaborativeAction, type RefundUnilateralAction, type SwapAction, type SwapActionAutomation, type SwapActionId, type SwapActionInput, type SwapActions, type SwapObservations, type SwapOutcome, type SwapStatusUpdate, SwapTracker, SwapWorker, type SwapWorkerOptions, type TrackedSwap, type WaitAction, type WaitingOn, type WebSocketLike, type WorkerHintSource, type WorkerTracker, WsStatusSource, type WsStatusSourceOptions, buildArkadeVhtlcRef, createEvmRpcReader, defaultArkadeServerUrl, defaultEvmReaders, deriveSwapActions, deriveSwapStatus, electrumReader, esploraReader, evmReaderFromClient, htlcFactsFromEsploraTxs, htlcKey, htlcQueryKey, resolveMinConfirmations, swapToTracked };
package/dist/index.d.ts CHANGED
@@ -161,6 +161,16 @@ type SwapActionInput = {
161
161
  * `false`, `pending` resolves to `wait` (not `fund`) and no refund is offered.
162
162
  */
163
163
  clientFunds?: boolean;
164
+ /**
165
+ * Whether the server's leg is an on-chain HTLC the client claims (the
166
+ * default). `false` for receive-on-Lightning swaps (`*_to_lightning`): there
167
+ * the server "funds" by paying the client's invoice off-chain, so there is
168
+ * nothing to claim and no claim window — {@link serverRefundLocktime} is
169
+ * meaningless. When `false`, `serverfunded` (the payment is in flight)
170
+ * resolves to `wait`, with the unilateral refund listed but blocked until
171
+ * the client's own timelock, exactly like `clientfunded`.
172
+ */
173
+ serverFunds?: boolean;
164
174
  };
165
175
  /** On-chain state of one HTLC in a swap. */
166
176
  type HtlcObservation = "absent" | "mempool" | "confirmed" | "invalid" | "spent_claim" | "spent_refund";
@@ -426,9 +436,10 @@ type SwapTrackerOptions = {
426
436
  * leg holds funds on-chain (≥ clientfunded, unresolved), where refund safety
427
437
  * must not depend on the server. Everything else advances on server hints
428
438
  * only ({@link applyHint}); a swap with nothing at stake costs zero chain
429
- * reads. Default 60s.
439
+ * reads. A getter is read on every tick, so the cadence can follow a
440
+ * setting that changes on a live client. Default 60s.
430
441
  */
431
- atRiskReconcileIntervalMs?: number;
442
+ atRiskReconcileIntervalMs?: number | (() => number);
432
443
  };
433
444
  declare class SwapTracker {
434
445
  #private;
@@ -462,6 +473,7 @@ declare class SwapTracker {
462
473
  */
463
474
  applyHint(swapId: string, opts?: {
464
475
  force?: boolean;
476
+ status?: SwapStatus;
465
477
  }): Promise<void>;
466
478
  /** Notify `cb` of the current action for each tracked swap, then on every change. */
467
479
  subscribeToActions(cb: ActionSubscriber): () => void;
@@ -682,6 +694,8 @@ declare class Client {
682
694
  /** Delegated to the legacy client (migration checkpoint). */
683
695
  createArkadeToLightningSwap(...args: Parameters<Client$1["createArkadeToLightningSwap"]>): ReturnType<Client$1["createArkadeToLightningSwap"]>;
684
696
  /** Delegated to the legacy client (migration checkpoint). */
697
+ createEvmToLightningSwap(...args: Parameters<Client$1["createEvmToLightningSwap"]>): ReturnType<Client$1["createEvmToLightningSwap"]>;
698
+ /** Delegated to the legacy client (migration checkpoint). */
685
699
  createEvmToArkadeSwapGeneric(...args: Parameters<Client$1["createEvmToArkadeSwapGeneric"]>): ReturnType<Client$1["createEvmToArkadeSwapGeneric"]>;
686
700
  /** Delegated to the legacy client (migration checkpoint). */
687
701
  createEvmToBitcoinSwap(...args: Parameters<Client$1["createEvmToBitcoinSwap"]>): ReturnType<Client$1["createEvmToBitcoinSwap"]>;
@@ -709,6 +723,17 @@ declare class Client {
709
723
  recoverGaslessFunds(...args: Parameters<Client$1["recoverGaslessFunds"]>): ReturnType<Client$1["recoverGaslessFunds"]>;
710
724
  /** Delegated to the legacy client (migration checkpoint). */
711
725
  hasReceivedVtxo(...args: Parameters<Client$1["hasReceivedVtxo"]>): ReturnType<Client$1["hasReceivedVtxo"]>;
726
+ /** Confirmations a server-funded Bitcoin HTLC needs before it is claimable. */
727
+ getBitcoinMinConfirmations(): number | undefined;
728
+ /**
729
+ * At `0` the claim goes out against a mempool funding, trusting the funder
730
+ * not to replace it once the claim reveals the preimage.
731
+ *
732
+ * Only the chain monitors read a depth, so this does nothing unless the
733
+ * client was built with {@link ClientBuilder.withChainVerifiedTracking}.
734
+ * Takes effect on subsequent reads, including swaps already tracked.
735
+ */
736
+ setBitcoinMinConfirmations(minConfirmations: number | undefined): void;
712
737
  /**
713
738
  * Start observing the user's active swaps and deriving each one's next action.
714
739
  *
@@ -799,7 +824,8 @@ declare class ClientBuilder {
799
824
  * funding hits the mempool, which TRUSTS the funder not to double-spend it
800
825
  * (claiming publishes the preimage, so a funder that then replaced its
801
826
  * funding could take both legs). Set `1` (or more) for a block-depth policy
802
- * that doesn't rely on the funder's good behaviour.
827
+ * that doesn't rely on the funder's good behaviour. Read only by the chain
828
+ * monitors, so it needs {@link withChainVerifiedTracking} to have any effect.
803
829
  */
804
830
  withBitcoinMinConfirmations(minConfirmations: number): this;
805
831
  /**
@@ -962,67 +988,6 @@ type BitcoinHtlcFacts = {
962
988
  spendWitness?: string[];
963
989
  };
964
990
 
965
- /** The chain surface the observer needs (the esplora and electrum readers satisfy it). */
966
- type BitcoinChainReader = {
967
- /**
968
- * Funding + spend facts for an HTLC witness-script address. `minConfirmations`
969
- * overrides the reader's default for this address alone — the two legs of a
970
- * swap do not share one rule.
971
- */
972
- getHtlcFacts(address: string, minConfirmations?: number): Promise<BitcoinHtlcFacts>;
973
- /**
974
- * Optional push capability: invoke `onChange` whenever the address's tx
975
- * history changes (e.g. an Electrum scripthash subscription). Returns an
976
- * unsubscribe function. When present, the manager reconciles on push
977
- * instead of relying solely on the tracker's poll cadence.
978
- */
979
- subscribe?(address: string, onChange: () => void): () => void;
980
- };
981
- type BitcoinCreateConfig = {
982
- /** One or more esplora REST base URLs; several are tried in rotation with failover. */
983
- esploraUrl: string | string[];
984
- /**
985
- * Optional Electrum WebSocket URL (Fulcrum `ws`/`wss` port). When set, the
986
- * manager reads via Electrum (fresher than public explorers) and gets push
987
- * reconciles via scripthash subscriptions; the esplora reader remains the
988
- * fallback on Electrum errors.
989
- */
990
- electrumWsUrl?: string;
991
- /** Network the HTLC addresses live on (for Electrum scripthashes); default mainnet. */
992
- network?: "mainnet" | "testnet" | "signet" | "regtest";
993
- /** The current Bitcoin MTP (ms); typically `async () => (await client.getMtp()).mtp * 1000`. */
994
- chainTime?: () => Promise<number>;
995
- /**
996
- * Confirmations a funding tx needs before it observes as `confirmed`.
997
- * Default `0`: accept an unconfirmed funding, trusting the funder not to
998
- * double-spend it (the claim reveals the preimage against it). `1` = wait
999
- * for a block.
1000
- */
1001
- minConfirmations?: number;
1002
- };
1003
- type BitcoinContractManagerDeps = {
1004
- reader: BitcoinChainReader;
1005
- chainTime?: () => Promise<number>;
1006
- };
1007
- declare class BitcoinContractManager implements ContractManager {
1008
- #private;
1009
- readonly ledger: Ledger;
1010
- private constructor();
1011
- static fromDeps(deps: BitcoinContractManagerDeps): BitcoinContractManager;
1012
- static create(config: BitcoinCreateConfig): Promise<BitcoinContractManager>;
1013
- canObserve(ref: HtlcRef): boolean;
1014
- register(ref: HtlcRef): Promise<void>;
1015
- unregister(ref: HtlcRef): Promise<void>;
1016
- getState(ref: HtlcRef): HtlcObservation | undefined;
1017
- chainNow(_ref: HtlcRef): number | undefined;
1018
- onEvent(cb: (ref: HtlcRef, state: HtlcObservation) => void): () => void;
1019
- refresh(): Promise<void>;
1020
- reconcile(ref: HtlcRef): Promise<void>;
1021
- dispose(): void;
1022
- /** The preimage a claim revealed on this HTLC, if one was seen. */
1023
- getPreimage(ref: HtlcRef): Uint8Array | undefined;
1024
- }
1025
-
1026
991
  /**
1027
992
  * A esplora-backed {@link BitcoinChainReader} — the concrete chain source the
1028
993
  * {@link BitcoinContractManager} uses in production.
@@ -1050,6 +1015,12 @@ type EsploraTx = {
1050
1015
  block_height?: number;
1051
1016
  };
1052
1017
  };
1018
+ /** A depth already resolved to a number, for the pure classifier below. */
1019
+ type BitcoinConfirmationPolicy = {
1020
+ minConfirmations?: number;
1021
+ };
1022
+ /** A depth, or a getter resolved per read so it can change without a rebuild. */
1023
+ type MinConfirmationsSource = number | (() => number | undefined);
1053
1024
  /**
1054
1025
  * When a funding tx counts as `confirmed` for observation purposes.
1055
1026
  *
@@ -1062,9 +1033,10 @@ type EsploraTx = {
1062
1033
  * `1` (or more) for a policy that doesn't rely on the funder's good behaviour;
1063
1034
  * values above 1 make the reader fetch the tip height to compute depth.
1064
1035
  */
1065
- type BitcoinConfirmationPolicy = {
1066
- minConfirmations?: number;
1036
+ type BitcoinReaderPolicy = {
1037
+ minConfirmations?: MinConfirmationsSource;
1067
1038
  };
1039
+ declare function resolveMinConfirmations(source: MinConfirmationsSource | undefined): number;
1068
1040
  /**
1069
1041
  * Reduce an address's esplora tx history to HTLC facts. If a tx spends an output
1070
1042
  * at the address, that's the resolving spend (its witness classifies claim vs
@@ -1086,7 +1058,69 @@ declare const DEFAULT_ESPLORA_URLS: string[];
1086
1058
  * providers) and fails over to the rest on error — so a throttled or failing
1087
1059
  * provider doesn't stall tracking.
1088
1060
  */
1089
- declare function esploraReader(esploraUrls: string | string[], fetchImpl?: typeof fetch, policy?: BitcoinConfirmationPolicy): BitcoinChainReader;
1061
+ declare function esploraReader(esploraUrls: string | string[], fetchImpl?: typeof fetch, policy?: BitcoinReaderPolicy): BitcoinChainReader;
1062
+
1063
+ /** The chain surface the observer needs (the esplora and electrum readers satisfy it). */
1064
+ type BitcoinChainReader = {
1065
+ /**
1066
+ * Funding + spend facts for an HTLC witness-script address. `minConfirmations`
1067
+ * overrides the reader's default for this address alone — the two legs of a
1068
+ * swap do not share one rule.
1069
+ */
1070
+ getHtlcFacts(address: string, minConfirmations?: number): Promise<BitcoinHtlcFacts>;
1071
+ /**
1072
+ * Optional push capability: invoke `onChange` whenever the address's tx
1073
+ * history changes (e.g. an Electrum scripthash subscription). Returns an
1074
+ * unsubscribe function. When present, the manager reconciles on push
1075
+ * instead of relying solely on the tracker's poll cadence.
1076
+ */
1077
+ subscribe?(address: string, onChange: () => void): () => void;
1078
+ };
1079
+ type BitcoinCreateConfig = {
1080
+ /** One or more esplora REST base URLs; several are tried in rotation with failover. */
1081
+ esploraUrl: string | string[];
1082
+ /**
1083
+ * Optional Electrum WebSocket URL (Fulcrum `ws`/`wss` port). When set, the
1084
+ * manager reads via Electrum (fresher than public explorers) and gets push
1085
+ * reconciles via scripthash subscriptions; the esplora reader remains the
1086
+ * fallback on Electrum errors.
1087
+ */
1088
+ electrumWsUrl?: string;
1089
+ /** Network the HTLC addresses live on (for Electrum scripthashes); default mainnet. */
1090
+ network?: "mainnet" | "testnet" | "signet" | "regtest";
1091
+ /** The current Bitcoin MTP (ms); typically `async () => (await client.getMtp()).mtp * 1000`. */
1092
+ chainTime?: () => Promise<number>;
1093
+ /**
1094
+ * Confirmations a funding tx needs before it observes as `confirmed`.
1095
+ * Default `0`: accept an unconfirmed funding, trusting the funder not to
1096
+ * double-spend it (the claim reveals the preimage against it). `1` = wait
1097
+ * for a block. Only the server-funded leg reads it; `swapToTracked` pins the
1098
+ * client-funded leg to 1.
1099
+ */
1100
+ minConfirmations?: MinConfirmationsSource;
1101
+ };
1102
+ type BitcoinContractManagerDeps = {
1103
+ reader: BitcoinChainReader;
1104
+ chainTime?: () => Promise<number>;
1105
+ };
1106
+ declare class BitcoinContractManager implements ContractManager {
1107
+ #private;
1108
+ readonly ledger: Ledger;
1109
+ private constructor();
1110
+ static fromDeps(deps: BitcoinContractManagerDeps): BitcoinContractManager;
1111
+ static create(config: BitcoinCreateConfig): Promise<BitcoinContractManager>;
1112
+ canObserve(ref: HtlcRef): boolean;
1113
+ register(ref: HtlcRef): Promise<void>;
1114
+ unregister(ref: HtlcRef): Promise<void>;
1115
+ getState(ref: HtlcRef): HtlcObservation | undefined;
1116
+ chainNow(_ref: HtlcRef): number | undefined;
1117
+ onEvent(cb: (ref: HtlcRef, state: HtlcObservation) => void): () => void;
1118
+ refresh(): Promise<void>;
1119
+ reconcile(ref: HtlcRef): Promise<void>;
1120
+ dispose(): void;
1121
+ /** The preimage a claim revealed on this HTLC, if one was seen. */
1122
+ getPreimage(ref: HtlcRef): Uint8Array | undefined;
1123
+ }
1090
1124
 
1091
1125
  /**
1092
1126
  * An Electrum-backed {@link BitcoinChainReader} — reads HTLC facts from our own
@@ -1121,7 +1155,7 @@ type ElectrumReaderNetwork = "mainnet" | "testnet" | "signet" | "regtest";
1121
1155
  * Build a {@link BitcoinChainReader} over an Electrum connection, with push
1122
1156
  * support and an optional fallback reader for outages.
1123
1157
  */
1124
- declare function electrumReader(client: ElectrumRpc, opts?: BitcoinConfirmationPolicy & {
1158
+ declare function electrumReader(client: ElectrumRpc, opts?: BitcoinReaderPolicy & {
1125
1159
  /** Network the HTLC addresses live on; defaults to mainnet. */
1126
1160
  network?: ElectrumReaderNetwork;
1127
1161
  /** Reader consulted when the Electrum server errors (e.g. esplora). */
@@ -1305,6 +1339,8 @@ type EvmLogClient = {
1305
1339
  address: `0x${string}`[];
1306
1340
  topics: (`0x${string}`[] | null)[];
1307
1341
  fromBlock: `0x${string}`;
1342
+ /** Set only when the read is chunked (see `maxBlockRange`). */
1343
+ toBlock?: `0x${string}`;
1308
1344
  }
1309
1345
  ];
1310
1346
  }): Promise<RawLog[]>;
@@ -1317,8 +1353,16 @@ type EvmLogClient = {
1317
1353
  }>;
1318
1354
  getBlock(): Promise<Pick<Block, "timestamp" | "number">>;
1319
1355
  };
1356
+ type EvmReaderOptions = {
1357
+ /**
1358
+ * Largest block span one `eth_getLogs` may cover. Some providers cap it
1359
+ * (rpc.rootstock.io: 2000 blocks); a read past the cap is split into
1360
+ * consecutive chunks up to the latest block. Unset means one unbounded call.
1361
+ */
1362
+ maxBlockRange?: bigint;
1363
+ };
1320
1364
  /** Build an {@link EvmChainReader} over an existing viem-like client. */
1321
- declare function evmReaderFromClient(client: EvmLogClient): EvmChainReader;
1365
+ declare function evmReaderFromClient(client: EvmLogClient, options?: EvmReaderOptions): EvmChainReader;
1322
1366
  /**
1323
1367
  * Build an {@link EvmChainReader} over one or more EVM JSON-RPC endpoints. With
1324
1368
  * several, viem's `fallback` tries them in order and fails over on error.
@@ -1327,7 +1371,7 @@ declare function evmReaderFromClient(client: EvmLogClient): EvmChainReader;
1327
1371
  * public RPCs rate-limiting us (publicnode 403s) — and it contradicts this
1328
1372
  * package's near-zero-RPC design.
1329
1373
  */
1330
- declare function createEvmRpcReader(rpcUrls: string | string[]): EvmChainReader;
1374
+ declare function createEvmRpcReader(rpcUrls: string | string[], options?: EvmReaderOptions): EvmChainReader;
1331
1375
  /**
1332
1376
  * Resolve the per-chain readers used for tracking: the tested {@link
1333
1377
  * DEFAULT_EVM_RPCS} by default, with any `overrides` taking priority for their
@@ -1579,4 +1623,4 @@ declare class WsStatusSource {
1579
1623
 
1580
1624
  declare function swapToTracked(stored: StoredSwap): TrackedSwap | undefined;
1581
1625
 
1582
- export { type ActionSubscriber, ArkadeContractManager, type ArkadeContractManagerDeps, type ArkadeCreateConfig, type ArkadeVhtlcInput, type BitcoinChainReader, type BitcoinConfirmationPolicy, BitcoinContractManager, type BitcoinContractManagerDeps, type BitcoinCreateConfig, type BlockedBy, type BlockedReason, type CctpClaimEvidence, type ClaimAction, Client, ClientBuilder, type ContractManager, DEFAULT_ESPLORA_URLS, DEFAULT_EVM_RPCS, type ElectrumReaderNetwork, type ElectrumRpc, type EvmChainReader, EvmContractManager, type EvmContractManagerDeps, type EvmHtlcQuery, type EvmLogClient, type FundAction, HintTracker, type HintTrackerOptions, type HtlcObservation, type HtlcRef, type Ledger, type NoneAction, type RawLog, type RecoverCctpClaimAction, type RefundCollaborativeAction, type RefundUnilateralAction, type SwapAction, type SwapActionAutomation, type SwapActionId, type SwapActionInput, type SwapActions, type SwapObservations, type SwapOutcome, type SwapStatusUpdate, SwapTracker, SwapWorker, type SwapWorkerOptions, type TrackedSwap, type WaitAction, type WaitingOn, type WebSocketLike, type WorkerHintSource, type WorkerTracker, WsStatusSource, type WsStatusSourceOptions, buildArkadeVhtlcRef, createEvmRpcReader, defaultArkadeServerUrl, defaultEvmReaders, deriveSwapActions, deriveSwapStatus, electrumReader, esploraReader, evmReaderFromClient, htlcFactsFromEsploraTxs, htlcKey, htlcQueryKey, swapToTracked };
1626
+ export { type ActionSubscriber, ArkadeContractManager, type ArkadeContractManagerDeps, type ArkadeCreateConfig, type ArkadeVhtlcInput, type BitcoinChainReader, type BitcoinConfirmationPolicy, BitcoinContractManager, type BitcoinContractManagerDeps, type BitcoinCreateConfig, type BitcoinReaderPolicy, type BlockedBy, type BlockedReason, type CctpClaimEvidence, type ClaimAction, Client, ClientBuilder, type ContractManager, DEFAULT_ESPLORA_URLS, DEFAULT_EVM_RPCS, type ElectrumReaderNetwork, type ElectrumRpc, type EvmChainReader, EvmContractManager, type EvmContractManagerDeps, type EvmHtlcQuery, type EvmLogClient, type FundAction, HintTracker, type HintTrackerOptions, type HtlcObservation, type HtlcRef, type Ledger, type MinConfirmationsSource, type NoneAction, type RawLog, type RecoverCctpClaimAction, type RefundCollaborativeAction, type RefundUnilateralAction, type SwapAction, type SwapActionAutomation, type SwapActionId, type SwapActionInput, type SwapActions, type SwapObservations, type SwapOutcome, type SwapStatusUpdate, SwapTracker, SwapWorker, type SwapWorkerOptions, type TrackedSwap, type WaitAction, type WaitingOn, type WebSocketLike, type WorkerHintSource, type WorkerTracker, WsStatusSource, type WsStatusSourceOptions, buildArkadeVhtlcRef, createEvmRpcReader, defaultArkadeServerUrl, defaultEvmReaders, deriveSwapActions, deriveSwapStatus, electrumReader, esploraReader, evmReaderFromClient, htlcFactsFromEsploraTxs, htlcKey, htlcQueryKey, resolveMinConfirmations, swapToTracked };