@satora/swap 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/bitcoin-reader-electrum-PY7DHD6T.js +7 -0
- package/dist/{bitcoin-reader-esplora-HV6CANAA.js → bitcoin-reader-esplora-ZLPMM5FF.js} +2 -2
- package/dist/{chunk-VHXEU534.js → chunk-FTPIQSRW.js} +12 -5
- package/dist/chunk-FTPIQSRW.js.map +1 -0
- package/dist/{chunk-EIWELJJK.js → chunk-THI4UO6R.js} +11 -5
- package/dist/chunk-THI4UO6R.js.map +1 -0
- package/dist/index.cjs +187 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +119 -4
- package/dist/index.d.ts +119 -4
- package/dist/index.js +169 -12
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/bitcoin-reader-electrum-4DOJ7NGH.js +0 -7
- package/dist/chunk-EIWELJJK.js.map +0 -1
- package/dist/chunk-VHXEU534.js.map +0 -1
- /package/dist/{bitcoin-reader-electrum-4DOJ7NGH.js.map → bitcoin-reader-electrum-PY7DHD6T.js.map} +0 -0
- /package/dist/{bitcoin-reader-esplora-HV6CANAA.js.map → bitcoin-reader-esplora-ZLPMM5FF.js.map} +0 -0
package/dist/index.d.cts
CHANGED
|
@@ -379,6 +379,20 @@ interface ContractManager {
|
|
|
379
379
|
dispose(): void;
|
|
380
380
|
}
|
|
381
381
|
|
|
382
|
+
/**
|
|
383
|
+
* The reactive orchestration.
|
|
384
|
+
*
|
|
385
|
+
* A {@link SwapTracker} watches each tracked swap's on-chain HTLC leg(s) via
|
|
386
|
+
* per-ledger {@link ContractManager}s (two legs for chain↔chain swaps, one for
|
|
387
|
+
* Lightning). On any change it recomputes the next action
|
|
388
|
+
* (`deriveSwapStatus` → `deriveSwapActions`), and — deduped — notifies
|
|
389
|
+
* subscribers, dropping a swap once it reaches a terminal state.
|
|
390
|
+
*
|
|
391
|
+
* This is the observe-mode layer: it *notifies*. Auto-execution (recover/auto
|
|
392
|
+
* mode running the action) is a policy layer built on top of these same
|
|
393
|
+
* notifications, gated by each action's `automation`.
|
|
394
|
+
*/
|
|
395
|
+
|
|
382
396
|
/**
|
|
383
397
|
* A swap the tracker watches: its HTLC legs + refund locktimes (from the recovery
|
|
384
398
|
* bundle). Chain↔chain swaps have both legs; Lightning swaps have exactly one
|
|
@@ -391,6 +405,12 @@ type TrackedSwap = {
|
|
|
391
405
|
serverHtlc?: HtlcRef;
|
|
392
406
|
clientRefundLocktime: number;
|
|
393
407
|
serverRefundLocktime: number;
|
|
408
|
+
/**
|
|
409
|
+
* The swap's last STORED server status, seeding hints-only tracking
|
|
410
|
+
* (`HintTracker`) with a first derivation before any hint arrives. Ignored by
|
|
411
|
+
* {@link SwapTracker}, which derives from chain observations only.
|
|
412
|
+
*/
|
|
413
|
+
storedStatus?: SwapStatus;
|
|
394
414
|
};
|
|
395
415
|
type ActionSubscriber = (swapId: string, actions: SwapActions) => void;
|
|
396
416
|
type SwapTrackerOptions = {
|
|
@@ -528,6 +548,14 @@ type TrackingConfig = {
|
|
|
528
548
|
refreshIntervalMs?: number;
|
|
529
549
|
/** Opt-in hint-driven auto-claim; unset leaves tracking observe-only. */
|
|
530
550
|
autoClaim?: AutoClaimConfig;
|
|
551
|
+
/**
|
|
552
|
+
* Verify against the chain instead of trusting server hints. Off by default
|
|
553
|
+
* (TEMP while the chain monitors are buggy): tracking then runs a
|
|
554
|
+
* {@link HintTracker} that derives actions from the server's pushed status,
|
|
555
|
+
* with zero chain access. Setting explicit `managers` implies chain-verified
|
|
556
|
+
* tracking (they exist for nothing else).
|
|
557
|
+
*/
|
|
558
|
+
chainVerified?: boolean;
|
|
531
559
|
};
|
|
532
560
|
declare class Client {
|
|
533
561
|
#private;
|
|
@@ -648,6 +676,8 @@ declare class Client {
|
|
|
648
676
|
/** Delegated to the legacy client (migration checkpoint). */
|
|
649
677
|
createLightningToArkadeSwap(...args: Parameters<Client$1["createLightningToArkadeSwap"]>): ReturnType<Client$1["createLightningToArkadeSwap"]>;
|
|
650
678
|
/** Delegated to the legacy client (migration checkpoint). */
|
|
679
|
+
createArkadeToLightningSwap(...args: Parameters<Client$1["createArkadeToLightningSwap"]>): ReturnType<Client$1["createArkadeToLightningSwap"]>;
|
|
680
|
+
/** Delegated to the legacy client (migration checkpoint). */
|
|
651
681
|
createEvmToArkadeSwapGeneric(...args: Parameters<Client$1["createEvmToArkadeSwapGeneric"]>): ReturnType<Client$1["createEvmToArkadeSwapGeneric"]>;
|
|
652
682
|
/** Delegated to the legacy client (migration checkpoint). */
|
|
653
683
|
createEvmToBitcoinSwap(...args: Parameters<Client$1["createEvmToBitcoinSwap"]>): ReturnType<Client$1["createEvmToBitcoinSwap"]>;
|
|
@@ -678,8 +708,11 @@ declare class Client {
|
|
|
678
708
|
/**
|
|
679
709
|
* Start observing the user's active swaps and deriving each one's next action.
|
|
680
710
|
*
|
|
681
|
-
* Loads stored swaps, maps
|
|
682
|
-
*
|
|
711
|
+
* Loads stored swaps, maps them to {@link TrackedSwap}s, and derives each
|
|
712
|
+
* one's actions — by default from the server's status hints alone (TEMP while
|
|
713
|
+
* the chain monitors are buggy; see
|
|
714
|
+
* {@link ClientBuilder.withChainVerifiedTracking} to re-enable the per-ledger
|
|
715
|
+
* chain monitors). Idempotent. Requires
|
|
683
716
|
* the client to have been built with {@link ClientBuilder.withTracking}.
|
|
684
717
|
* Subscribe with {@link subscribeToActions}; release with
|
|
685
718
|
* {@link stopTracking}.
|
|
@@ -719,6 +752,13 @@ declare class ClientBuilder {
|
|
|
719
752
|
}): this;
|
|
720
753
|
/** Turn observe-mode tracking off. */
|
|
721
754
|
withoutTracking(): this;
|
|
755
|
+
/**
|
|
756
|
+
* Verify swap state against the chain (per-ledger contract managers) instead
|
|
757
|
+
* of trusting the server's status hints. TEMPORARILY off by default while the
|
|
758
|
+
* chain monitors are being fixed — without it, tracking derives actions from
|
|
759
|
+
* the server's pushed status alone, with zero chain access.
|
|
760
|
+
*/
|
|
761
|
+
withChainVerifiedTracking(): this;
|
|
722
762
|
/**
|
|
723
763
|
* Advanced: supply per-ledger {@link ContractManager}s explicitly instead of
|
|
724
764
|
* letting the client auto-build them from config (useful for tests or custom
|
|
@@ -1291,6 +1331,74 @@ declare function createEvmRpcReader(rpcUrls: string | string[]): EvmChainReader;
|
|
|
1291
1331
|
*/
|
|
1292
1332
|
declare function defaultEvmReaders(overrides?: Record<number, string>): Map<number, EvmChainReader>;
|
|
1293
1333
|
|
|
1334
|
+
/**
|
|
1335
|
+
* A server-trusting stand-in for {@link SwapTracker}: derives each swap's next
|
|
1336
|
+
* action from the SERVER's status instead of chain observations — zero chain
|
|
1337
|
+
* access (no EVM RPCs, no Esplora/Electrum, no Arkade reads).
|
|
1338
|
+
*
|
|
1339
|
+
* TEMPORARY default while the chain monitors are being fixed. Unlike
|
|
1340
|
+
* {@link SwapTracker} there is no independent verification: the client acts on
|
|
1341
|
+
* the server's word. The pushed status is the same `SwapStatus` enum the chain
|
|
1342
|
+
* derivation produces, so it feeds straight into {@link deriveSwapActions}.
|
|
1343
|
+
* Failure containment: a claim run on a false `serverfunded` fails locally
|
|
1344
|
+
* (nothing to spend / gas estimation reverts) rather than losing funds.
|
|
1345
|
+
*
|
|
1346
|
+
* Timelocks are evaluated against the wall clock, not chain clocks. The wall
|
|
1347
|
+
* clock runs AHEAD of Bitcoin's MTP (by up to ~an hour), so a refund can look
|
|
1348
|
+
* unlocked slightly early — the broadcast simply fails until the chain agrees,
|
|
1349
|
+
* and refunds are user-confirmed anyway — while the claim window closes
|
|
1350
|
+
* conservatively early, which is the safe direction.
|
|
1351
|
+
*/
|
|
1352
|
+
|
|
1353
|
+
type HintTrackerOptions = {
|
|
1354
|
+
/**
|
|
1355
|
+
* Fetch a swap's current status from the server — the fallback for hints
|
|
1356
|
+
* that don't carry one (the worker's retry re-verifies and its
|
|
1357
|
+
* post-reconnect sweep).
|
|
1358
|
+
*/
|
|
1359
|
+
fetchStatus: (swapId: string) => Promise<SwapStatus>;
|
|
1360
|
+
/**
|
|
1361
|
+
* Local tick interval (ms): recomputes every swap against the wall clock so
|
|
1362
|
+
* timelock flips (a refund unlocking, a stale pending swap turning reapable)
|
|
1363
|
+
* surface between hints. Pure local work. `0` disables the timer (tests
|
|
1364
|
+
* drive recomputes via {@link applyHint}).
|
|
1365
|
+
*/
|
|
1366
|
+
refreshIntervalMs?: number;
|
|
1367
|
+
};
|
|
1368
|
+
declare class HintTracker {
|
|
1369
|
+
#private;
|
|
1370
|
+
constructor(options: HintTrackerOptions);
|
|
1371
|
+
/**
|
|
1372
|
+
* Always `true`: with no chain readers there is no reachability constraint.
|
|
1373
|
+
* (Claim/refund execution has its own chain configuration, independent of
|
|
1374
|
+
* tracking.)
|
|
1375
|
+
*/
|
|
1376
|
+
canObserve(_swap: TrackedSwap): boolean;
|
|
1377
|
+
/** Register the swaps, derive each one's first action from its stored status. */
|
|
1378
|
+
startTracking(swaps: TrackedSwap[]): Promise<void>;
|
|
1379
|
+
/**
|
|
1380
|
+
* Track one more swap after {@link startTracking}. Idempotent: a swap already
|
|
1381
|
+
* tracked, or one already seen through to a terminal action, is ignored.
|
|
1382
|
+
*/
|
|
1383
|
+
track(swap: TrackedSwap): Promise<void>;
|
|
1384
|
+
/** The swap ids currently tracked — e.g. to subscribe them to the hint feed. */
|
|
1385
|
+
trackedSwapIds(): string[];
|
|
1386
|
+
/**
|
|
1387
|
+
* Apply a server status to one swap and recompute its action. A hint that
|
|
1388
|
+
* carries the pushed `status` is applied as-is; without one (the worker's
|
|
1389
|
+
* retry and post-reconnect paths) the status is re-fetched from the server.
|
|
1390
|
+
* A no-op for an untracked swap.
|
|
1391
|
+
*/
|
|
1392
|
+
applyHint(swapId: string, opts?: {
|
|
1393
|
+
force?: boolean;
|
|
1394
|
+
status?: SwapStatus;
|
|
1395
|
+
}): Promise<void>;
|
|
1396
|
+
/** Notify `cb` of the current action for each tracked swap, then on every change. */
|
|
1397
|
+
subscribeToActions(cb: ActionSubscriber): () => void;
|
|
1398
|
+
/** Stop tracking: drop the tick timer, tracked swaps, and subscribers. */
|
|
1399
|
+
stop(): void;
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1294
1402
|
/**
|
|
1295
1403
|
* Ties the hint feed and the action model together into auto-execution.
|
|
1296
1404
|
*
|
|
@@ -1311,9 +1419,15 @@ declare function defaultEvmReaders(overrides?: Record<number, string>): Map<numb
|
|
|
1311
1419
|
/** The tracker surface the worker drives. */
|
|
1312
1420
|
interface WorkerTracker {
|
|
1313
1421
|
trackedSwapIds(): string[];
|
|
1314
|
-
/**
|
|
1422
|
+
/**
|
|
1423
|
+
* Re-verify a swap, then recompute. `force` re-emits even if unchanged.
|
|
1424
|
+
* `status` is the hint's pushed status: a chain-verifying tracker ignores it
|
|
1425
|
+
* (the chain stays its source of truth); a hints-only tracker applies it
|
|
1426
|
+
* directly, saving a server round-trip.
|
|
1427
|
+
*/
|
|
1315
1428
|
applyHint(swapId: string, opts?: {
|
|
1316
1429
|
force?: boolean;
|
|
1430
|
+
status?: SwapStatus;
|
|
1317
1431
|
}): Promise<void>;
|
|
1318
1432
|
subscribeToActions(cb: (swapId: string, actions: SwapActions) => void): () => void;
|
|
1319
1433
|
}
|
|
@@ -1325,6 +1439,7 @@ interface WorkerHintSource {
|
|
|
1325
1439
|
unsubscribe(swapIds: string[]): void;
|
|
1326
1440
|
onStatus(cb: (update: {
|
|
1327
1441
|
swapId: string;
|
|
1442
|
+
status?: SwapStatus;
|
|
1328
1443
|
}) => void): () => void;
|
|
1329
1444
|
/**
|
|
1330
1445
|
* Optional: fires when the feed comes back up after an outage, during which
|
|
@@ -1460,4 +1575,4 @@ declare class WsStatusSource {
|
|
|
1460
1575
|
|
|
1461
1576
|
declare function swapToTracked(stored: StoredSwap): TrackedSwap | undefined;
|
|
1462
1577
|
|
|
1463
|
-
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, 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 };
|
|
1578
|
+
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -379,6 +379,20 @@ interface ContractManager {
|
|
|
379
379
|
dispose(): void;
|
|
380
380
|
}
|
|
381
381
|
|
|
382
|
+
/**
|
|
383
|
+
* The reactive orchestration.
|
|
384
|
+
*
|
|
385
|
+
* A {@link SwapTracker} watches each tracked swap's on-chain HTLC leg(s) via
|
|
386
|
+
* per-ledger {@link ContractManager}s (two legs for chain↔chain swaps, one for
|
|
387
|
+
* Lightning). On any change it recomputes the next action
|
|
388
|
+
* (`deriveSwapStatus` → `deriveSwapActions`), and — deduped — notifies
|
|
389
|
+
* subscribers, dropping a swap once it reaches a terminal state.
|
|
390
|
+
*
|
|
391
|
+
* This is the observe-mode layer: it *notifies*. Auto-execution (recover/auto
|
|
392
|
+
* mode running the action) is a policy layer built on top of these same
|
|
393
|
+
* notifications, gated by each action's `automation`.
|
|
394
|
+
*/
|
|
395
|
+
|
|
382
396
|
/**
|
|
383
397
|
* A swap the tracker watches: its HTLC legs + refund locktimes (from the recovery
|
|
384
398
|
* bundle). Chain↔chain swaps have both legs; Lightning swaps have exactly one
|
|
@@ -391,6 +405,12 @@ type TrackedSwap = {
|
|
|
391
405
|
serverHtlc?: HtlcRef;
|
|
392
406
|
clientRefundLocktime: number;
|
|
393
407
|
serverRefundLocktime: number;
|
|
408
|
+
/**
|
|
409
|
+
* The swap's last STORED server status, seeding hints-only tracking
|
|
410
|
+
* (`HintTracker`) with a first derivation before any hint arrives. Ignored by
|
|
411
|
+
* {@link SwapTracker}, which derives from chain observations only.
|
|
412
|
+
*/
|
|
413
|
+
storedStatus?: SwapStatus;
|
|
394
414
|
};
|
|
395
415
|
type ActionSubscriber = (swapId: string, actions: SwapActions) => void;
|
|
396
416
|
type SwapTrackerOptions = {
|
|
@@ -528,6 +548,14 @@ type TrackingConfig = {
|
|
|
528
548
|
refreshIntervalMs?: number;
|
|
529
549
|
/** Opt-in hint-driven auto-claim; unset leaves tracking observe-only. */
|
|
530
550
|
autoClaim?: AutoClaimConfig;
|
|
551
|
+
/**
|
|
552
|
+
* Verify against the chain instead of trusting server hints. Off by default
|
|
553
|
+
* (TEMP while the chain monitors are buggy): tracking then runs a
|
|
554
|
+
* {@link HintTracker} that derives actions from the server's pushed status,
|
|
555
|
+
* with zero chain access. Setting explicit `managers` implies chain-verified
|
|
556
|
+
* tracking (they exist for nothing else).
|
|
557
|
+
*/
|
|
558
|
+
chainVerified?: boolean;
|
|
531
559
|
};
|
|
532
560
|
declare class Client {
|
|
533
561
|
#private;
|
|
@@ -648,6 +676,8 @@ declare class Client {
|
|
|
648
676
|
/** Delegated to the legacy client (migration checkpoint). */
|
|
649
677
|
createLightningToArkadeSwap(...args: Parameters<Client$1["createLightningToArkadeSwap"]>): ReturnType<Client$1["createLightningToArkadeSwap"]>;
|
|
650
678
|
/** Delegated to the legacy client (migration checkpoint). */
|
|
679
|
+
createArkadeToLightningSwap(...args: Parameters<Client$1["createArkadeToLightningSwap"]>): ReturnType<Client$1["createArkadeToLightningSwap"]>;
|
|
680
|
+
/** Delegated to the legacy client (migration checkpoint). */
|
|
651
681
|
createEvmToArkadeSwapGeneric(...args: Parameters<Client$1["createEvmToArkadeSwapGeneric"]>): ReturnType<Client$1["createEvmToArkadeSwapGeneric"]>;
|
|
652
682
|
/** Delegated to the legacy client (migration checkpoint). */
|
|
653
683
|
createEvmToBitcoinSwap(...args: Parameters<Client$1["createEvmToBitcoinSwap"]>): ReturnType<Client$1["createEvmToBitcoinSwap"]>;
|
|
@@ -678,8 +708,11 @@ declare class Client {
|
|
|
678
708
|
/**
|
|
679
709
|
* Start observing the user's active swaps and deriving each one's next action.
|
|
680
710
|
*
|
|
681
|
-
* Loads stored swaps, maps
|
|
682
|
-
*
|
|
711
|
+
* Loads stored swaps, maps them to {@link TrackedSwap}s, and derives each
|
|
712
|
+
* one's actions — by default from the server's status hints alone (TEMP while
|
|
713
|
+
* the chain monitors are buggy; see
|
|
714
|
+
* {@link ClientBuilder.withChainVerifiedTracking} to re-enable the per-ledger
|
|
715
|
+
* chain monitors). Idempotent. Requires
|
|
683
716
|
* the client to have been built with {@link ClientBuilder.withTracking}.
|
|
684
717
|
* Subscribe with {@link subscribeToActions}; release with
|
|
685
718
|
* {@link stopTracking}.
|
|
@@ -719,6 +752,13 @@ declare class ClientBuilder {
|
|
|
719
752
|
}): this;
|
|
720
753
|
/** Turn observe-mode tracking off. */
|
|
721
754
|
withoutTracking(): this;
|
|
755
|
+
/**
|
|
756
|
+
* Verify swap state against the chain (per-ledger contract managers) instead
|
|
757
|
+
* of trusting the server's status hints. TEMPORARILY off by default while the
|
|
758
|
+
* chain monitors are being fixed — without it, tracking derives actions from
|
|
759
|
+
* the server's pushed status alone, with zero chain access.
|
|
760
|
+
*/
|
|
761
|
+
withChainVerifiedTracking(): this;
|
|
722
762
|
/**
|
|
723
763
|
* Advanced: supply per-ledger {@link ContractManager}s explicitly instead of
|
|
724
764
|
* letting the client auto-build them from config (useful for tests or custom
|
|
@@ -1291,6 +1331,74 @@ declare function createEvmRpcReader(rpcUrls: string | string[]): EvmChainReader;
|
|
|
1291
1331
|
*/
|
|
1292
1332
|
declare function defaultEvmReaders(overrides?: Record<number, string>): Map<number, EvmChainReader>;
|
|
1293
1333
|
|
|
1334
|
+
/**
|
|
1335
|
+
* A server-trusting stand-in for {@link SwapTracker}: derives each swap's next
|
|
1336
|
+
* action from the SERVER's status instead of chain observations — zero chain
|
|
1337
|
+
* access (no EVM RPCs, no Esplora/Electrum, no Arkade reads).
|
|
1338
|
+
*
|
|
1339
|
+
* TEMPORARY default while the chain monitors are being fixed. Unlike
|
|
1340
|
+
* {@link SwapTracker} there is no independent verification: the client acts on
|
|
1341
|
+
* the server's word. The pushed status is the same `SwapStatus` enum the chain
|
|
1342
|
+
* derivation produces, so it feeds straight into {@link deriveSwapActions}.
|
|
1343
|
+
* Failure containment: a claim run on a false `serverfunded` fails locally
|
|
1344
|
+
* (nothing to spend / gas estimation reverts) rather than losing funds.
|
|
1345
|
+
*
|
|
1346
|
+
* Timelocks are evaluated against the wall clock, not chain clocks. The wall
|
|
1347
|
+
* clock runs AHEAD of Bitcoin's MTP (by up to ~an hour), so a refund can look
|
|
1348
|
+
* unlocked slightly early — the broadcast simply fails until the chain agrees,
|
|
1349
|
+
* and refunds are user-confirmed anyway — while the claim window closes
|
|
1350
|
+
* conservatively early, which is the safe direction.
|
|
1351
|
+
*/
|
|
1352
|
+
|
|
1353
|
+
type HintTrackerOptions = {
|
|
1354
|
+
/**
|
|
1355
|
+
* Fetch a swap's current status from the server — the fallback for hints
|
|
1356
|
+
* that don't carry one (the worker's retry re-verifies and its
|
|
1357
|
+
* post-reconnect sweep).
|
|
1358
|
+
*/
|
|
1359
|
+
fetchStatus: (swapId: string) => Promise<SwapStatus>;
|
|
1360
|
+
/**
|
|
1361
|
+
* Local tick interval (ms): recomputes every swap against the wall clock so
|
|
1362
|
+
* timelock flips (a refund unlocking, a stale pending swap turning reapable)
|
|
1363
|
+
* surface between hints. Pure local work. `0` disables the timer (tests
|
|
1364
|
+
* drive recomputes via {@link applyHint}).
|
|
1365
|
+
*/
|
|
1366
|
+
refreshIntervalMs?: number;
|
|
1367
|
+
};
|
|
1368
|
+
declare class HintTracker {
|
|
1369
|
+
#private;
|
|
1370
|
+
constructor(options: HintTrackerOptions);
|
|
1371
|
+
/**
|
|
1372
|
+
* Always `true`: with no chain readers there is no reachability constraint.
|
|
1373
|
+
* (Claim/refund execution has its own chain configuration, independent of
|
|
1374
|
+
* tracking.)
|
|
1375
|
+
*/
|
|
1376
|
+
canObserve(_swap: TrackedSwap): boolean;
|
|
1377
|
+
/** Register the swaps, derive each one's first action from its stored status. */
|
|
1378
|
+
startTracking(swaps: TrackedSwap[]): Promise<void>;
|
|
1379
|
+
/**
|
|
1380
|
+
* Track one more swap after {@link startTracking}. Idempotent: a swap already
|
|
1381
|
+
* tracked, or one already seen through to a terminal action, is ignored.
|
|
1382
|
+
*/
|
|
1383
|
+
track(swap: TrackedSwap): Promise<void>;
|
|
1384
|
+
/** The swap ids currently tracked — e.g. to subscribe them to the hint feed. */
|
|
1385
|
+
trackedSwapIds(): string[];
|
|
1386
|
+
/**
|
|
1387
|
+
* Apply a server status to one swap and recompute its action. A hint that
|
|
1388
|
+
* carries the pushed `status` is applied as-is; without one (the worker's
|
|
1389
|
+
* retry and post-reconnect paths) the status is re-fetched from the server.
|
|
1390
|
+
* A no-op for an untracked swap.
|
|
1391
|
+
*/
|
|
1392
|
+
applyHint(swapId: string, opts?: {
|
|
1393
|
+
force?: boolean;
|
|
1394
|
+
status?: SwapStatus;
|
|
1395
|
+
}): Promise<void>;
|
|
1396
|
+
/** Notify `cb` of the current action for each tracked swap, then on every change. */
|
|
1397
|
+
subscribeToActions(cb: ActionSubscriber): () => void;
|
|
1398
|
+
/** Stop tracking: drop the tick timer, tracked swaps, and subscribers. */
|
|
1399
|
+
stop(): void;
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1294
1402
|
/**
|
|
1295
1403
|
* Ties the hint feed and the action model together into auto-execution.
|
|
1296
1404
|
*
|
|
@@ -1311,9 +1419,15 @@ declare function defaultEvmReaders(overrides?: Record<number, string>): Map<numb
|
|
|
1311
1419
|
/** The tracker surface the worker drives. */
|
|
1312
1420
|
interface WorkerTracker {
|
|
1313
1421
|
trackedSwapIds(): string[];
|
|
1314
|
-
/**
|
|
1422
|
+
/**
|
|
1423
|
+
* Re-verify a swap, then recompute. `force` re-emits even if unchanged.
|
|
1424
|
+
* `status` is the hint's pushed status: a chain-verifying tracker ignores it
|
|
1425
|
+
* (the chain stays its source of truth); a hints-only tracker applies it
|
|
1426
|
+
* directly, saving a server round-trip.
|
|
1427
|
+
*/
|
|
1315
1428
|
applyHint(swapId: string, opts?: {
|
|
1316
1429
|
force?: boolean;
|
|
1430
|
+
status?: SwapStatus;
|
|
1317
1431
|
}): Promise<void>;
|
|
1318
1432
|
subscribeToActions(cb: (swapId: string, actions: SwapActions) => void): () => void;
|
|
1319
1433
|
}
|
|
@@ -1325,6 +1439,7 @@ interface WorkerHintSource {
|
|
|
1325
1439
|
unsubscribe(swapIds: string[]): void;
|
|
1326
1440
|
onStatus(cb: (update: {
|
|
1327
1441
|
swapId: string;
|
|
1442
|
+
status?: SwapStatus;
|
|
1328
1443
|
}) => void): () => void;
|
|
1329
1444
|
/**
|
|
1330
1445
|
* Optional: fires when the feed comes back up after an outage, during which
|
|
@@ -1460,4 +1575,4 @@ declare class WsStatusSource {
|
|
|
1460
1575
|
|
|
1461
1576
|
declare function swapToTracked(stored: StoredSwap): TrackedSwap | undefined;
|
|
1462
1577
|
|
|
1463
|
-
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, 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 };
|
|
1578
|
+
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 };
|
package/dist/index.js
CHANGED
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
DEFAULT_ESPLORA_URLS,
|
|
3
3
|
esploraReader,
|
|
4
4
|
htlcFactsFromEsploraTxs
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-THI4UO6R.js";
|
|
6
6
|
import {
|
|
7
7
|
electrumReader
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-FTPIQSRW.js";
|
|
9
9
|
|
|
10
10
|
// src/index.ts
|
|
11
11
|
export * from "@lendasat/lendaswap-sdk-pure";
|
|
@@ -570,7 +570,7 @@ var BitcoinContractManager = class _BitcoinContractManager {
|
|
|
570
570
|
return new _BitcoinContractManager(deps);
|
|
571
571
|
}
|
|
572
572
|
static async create(config) {
|
|
573
|
-
const { esploraReader: esploraReader2 } = await import("./bitcoin-reader-esplora-
|
|
573
|
+
const { esploraReader: esploraReader2 } = await import("./bitcoin-reader-esplora-ZLPMM5FF.js");
|
|
574
574
|
let reader = esploraReader2(
|
|
575
575
|
config.esploraUrl,
|
|
576
576
|
void 0,
|
|
@@ -578,7 +578,7 @@ var BitcoinContractManager = class _BitcoinContractManager {
|
|
|
578
578
|
);
|
|
579
579
|
if (config.electrumWsUrl) {
|
|
580
580
|
const [{ electrumReader: electrumReader2 }, { ElectrumWsClient }] = await Promise.all([
|
|
581
|
-
import("./bitcoin-reader-electrum-
|
|
581
|
+
import("./bitcoin-reader-electrum-PY7DHD6T.js"),
|
|
582
582
|
import("@lendasat/lendaswap-sdk-pure")
|
|
583
583
|
]);
|
|
584
584
|
reader = electrumReader2(new ElectrumWsClient(config.electrumWsUrl), {
|
|
@@ -1216,6 +1216,113 @@ function defaultEvmReaders(overrides) {
|
|
|
1216
1216
|
return readers;
|
|
1217
1217
|
}
|
|
1218
1218
|
|
|
1219
|
+
// src/hints/hint-tracker.ts
|
|
1220
|
+
var HintTracker = class {
|
|
1221
|
+
#fetchStatus;
|
|
1222
|
+
#refreshIntervalMs;
|
|
1223
|
+
#swaps = /* @__PURE__ */ new Map();
|
|
1224
|
+
/** Last server-reported status per swap (seeded from storage, updated by hints). */
|
|
1225
|
+
#statuses = /* @__PURE__ */ new Map();
|
|
1226
|
+
/** Last actions emitted per swap — for dedupe and the subscribe-time snapshot. */
|
|
1227
|
+
#lastActions = /* @__PURE__ */ new Map();
|
|
1228
|
+
#subscribers = /* @__PURE__ */ new Set();
|
|
1229
|
+
#timer;
|
|
1230
|
+
constructor(options) {
|
|
1231
|
+
this.#fetchStatus = options.fetchStatus;
|
|
1232
|
+
this.#refreshIntervalMs = options.refreshIntervalMs ?? 5e3;
|
|
1233
|
+
}
|
|
1234
|
+
/**
|
|
1235
|
+
* Always `true`: with no chain readers there is no reachability constraint.
|
|
1236
|
+
* (Claim/refund execution has its own chain configuration, independent of
|
|
1237
|
+
* tracking.)
|
|
1238
|
+
*/
|
|
1239
|
+
canObserve(_swap) {
|
|
1240
|
+
return true;
|
|
1241
|
+
}
|
|
1242
|
+
/** Register the swaps, derive each one's first action from its stored status. */
|
|
1243
|
+
async startTracking(swaps) {
|
|
1244
|
+
for (const swap of swaps) this.#admit(swap);
|
|
1245
|
+
this.#recomputeAll();
|
|
1246
|
+
if (this.#refreshIntervalMs > 0)
|
|
1247
|
+
this.#timer = setInterval(
|
|
1248
|
+
() => this.#recomputeAll(),
|
|
1249
|
+
this.#refreshIntervalMs
|
|
1250
|
+
);
|
|
1251
|
+
}
|
|
1252
|
+
/**
|
|
1253
|
+
* Track one more swap after {@link startTracking}. Idempotent: a swap already
|
|
1254
|
+
* tracked, or one already seen through to a terminal action, is ignored.
|
|
1255
|
+
*/
|
|
1256
|
+
async track(swap) {
|
|
1257
|
+
if (this.#swaps.has(swap.swapId) || this.#lastActions.has(swap.swapId))
|
|
1258
|
+
return;
|
|
1259
|
+
this.#admit(swap);
|
|
1260
|
+
this.#recompute(swap);
|
|
1261
|
+
}
|
|
1262
|
+
#admit(swap) {
|
|
1263
|
+
this.#swaps.set(swap.swapId, swap);
|
|
1264
|
+
if (swap.storedStatus !== void 0 && !this.#statuses.has(swap.swapId))
|
|
1265
|
+
this.#statuses.set(swap.swapId, swap.storedStatus);
|
|
1266
|
+
}
|
|
1267
|
+
/** The swap ids currently tracked — e.g. to subscribe them to the hint feed. */
|
|
1268
|
+
trackedSwapIds() {
|
|
1269
|
+
return [...this.#swaps.keys()];
|
|
1270
|
+
}
|
|
1271
|
+
/**
|
|
1272
|
+
* Apply a server status to one swap and recompute its action. A hint that
|
|
1273
|
+
* carries the pushed `status` is applied as-is; without one (the worker's
|
|
1274
|
+
* retry and post-reconnect paths) the status is re-fetched from the server.
|
|
1275
|
+
* A no-op for an untracked swap.
|
|
1276
|
+
*/
|
|
1277
|
+
async applyHint(swapId, opts) {
|
|
1278
|
+
const swap = this.#swaps.get(swapId);
|
|
1279
|
+
if (!swap) return;
|
|
1280
|
+
const status = opts?.status ?? await this.#fetchStatus(swapId);
|
|
1281
|
+
if (!this.#swaps.has(swapId)) return;
|
|
1282
|
+
this.#statuses.set(swapId, status);
|
|
1283
|
+
this.#recompute(swap, opts?.force ?? false);
|
|
1284
|
+
}
|
|
1285
|
+
/** Notify `cb` of the current action for each tracked swap, then on every change. */
|
|
1286
|
+
subscribeToActions(cb) {
|
|
1287
|
+
this.#subscribers.add(cb);
|
|
1288
|
+
for (const [swapId, actions] of this.#lastActions) cb(swapId, actions);
|
|
1289
|
+
return () => this.#subscribers.delete(cb);
|
|
1290
|
+
}
|
|
1291
|
+
/** Stop tracking: drop the tick timer, tracked swaps, and subscribers. */
|
|
1292
|
+
stop() {
|
|
1293
|
+
if (this.#timer) clearInterval(this.#timer);
|
|
1294
|
+
this.#timer = void 0;
|
|
1295
|
+
this.#swaps.clear();
|
|
1296
|
+
this.#subscribers.clear();
|
|
1297
|
+
}
|
|
1298
|
+
#recomputeAll() {
|
|
1299
|
+
for (const swap of this.#swaps.values()) this.#recompute(swap);
|
|
1300
|
+
}
|
|
1301
|
+
#recompute(swap, force = false) {
|
|
1302
|
+
const status = this.#statuses.get(swap.swapId);
|
|
1303
|
+
if (status === void 0) return;
|
|
1304
|
+
const now = Date.now();
|
|
1305
|
+
const actions = deriveSwapActions({
|
|
1306
|
+
status,
|
|
1307
|
+
clientChainNow: now,
|
|
1308
|
+
serverChainNow: now,
|
|
1309
|
+
clientRefundLocktime: swap.clientRefundLocktime,
|
|
1310
|
+
serverRefundLocktime: swap.serverRefundLocktime,
|
|
1311
|
+
// Pay-on-Lightning swaps have no client-funded on-chain leg.
|
|
1312
|
+
clientFunds: swap.clientHtlc !== void 0
|
|
1313
|
+
});
|
|
1314
|
+
const previous = this.#lastActions.get(swap.swapId);
|
|
1315
|
+
if (!force && previous && JSON.stringify(previous) === JSON.stringify(actions))
|
|
1316
|
+
return;
|
|
1317
|
+
this.#lastActions.set(swap.swapId, actions);
|
|
1318
|
+
for (const cb of this.#subscribers) cb(swap.swapId, actions);
|
|
1319
|
+
if (actions.recommended === "none") {
|
|
1320
|
+
this.#swaps.delete(swap.swapId);
|
|
1321
|
+
this.#statuses.delete(swap.swapId);
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
};
|
|
1325
|
+
|
|
1219
1326
|
// src/hints/swap-worker.ts
|
|
1220
1327
|
var AUTO_EXECUTABLE = /* @__PURE__ */ new Set([
|
|
1221
1328
|
"claim"
|
|
@@ -1249,8 +1356,8 @@ var SwapWorker = class {
|
|
|
1249
1356
|
this.#started = true;
|
|
1250
1357
|
this.#hintSource.subscribe(this.#tracker.trackedSwapIds());
|
|
1251
1358
|
this.#unsubs.push(
|
|
1252
|
-
this.#hintSource.onStatus(({ swapId }) => {
|
|
1253
|
-
void this.#tracker.applyHint(swapId).catch((error) => {
|
|
1359
|
+
this.#hintSource.onStatus(({ swapId, status }) => {
|
|
1360
|
+
void this.#tracker.applyHint(swapId, { status }).catch((error) => {
|
|
1254
1361
|
console.warn(`SwapWorker: applyHint(${swapId}) failed:`, error);
|
|
1255
1362
|
});
|
|
1256
1363
|
})
|
|
@@ -1807,6 +1914,21 @@ function swapToTracked(stored) {
|
|
|
1807
1914
|
// no on-chain client leg
|
|
1808
1915
|
serverRefundLocktime: ms(r.vhtlc_refund_locktime)
|
|
1809
1916
|
};
|
|
1917
|
+
// Client funds the Arkade VHTLC (source_amount); the server pays the
|
|
1918
|
+
// Lightning invoice off-chain and claims the VHTLC — no server leg to
|
|
1919
|
+
// watch.
|
|
1920
|
+
case "arkade_to_lightning":
|
|
1921
|
+
return {
|
|
1922
|
+
swapId: r.id,
|
|
1923
|
+
clientHtlc: arkadeLeg(
|
|
1924
|
+
r,
|
|
1925
|
+
r.arkade_vhtlc_address,
|
|
1926
|
+
Number(r.source_amount)
|
|
1927
|
+
),
|
|
1928
|
+
clientRefundLocktime: ms(r.vhtlc_refund_locktime),
|
|
1929
|
+
serverRefundLocktime: 0
|
|
1930
|
+
// no on-chain server leg
|
|
1931
|
+
};
|
|
1810
1932
|
default:
|
|
1811
1933
|
return void 0;
|
|
1812
1934
|
}
|
|
@@ -2333,6 +2455,12 @@ var Client = class {
|
|
|
2333
2455
|
);
|
|
2334
2456
|
}
|
|
2335
2457
|
/** Delegated to the legacy client (migration checkpoint). */
|
|
2458
|
+
createArkadeToLightningSwap(...args) {
|
|
2459
|
+
return this.#trackAfterCreate(
|
|
2460
|
+
this.#legacy.createArkadeToLightningSwap(...args)
|
|
2461
|
+
);
|
|
2462
|
+
}
|
|
2463
|
+
/** Delegated to the legacy client (migration checkpoint). */
|
|
2336
2464
|
createEvmToArkadeSwapGeneric(...args) {
|
|
2337
2465
|
return this.#trackAfterCreate(
|
|
2338
2466
|
this.#legacy.createEvmToArkadeSwapGeneric(...args)
|
|
@@ -2394,8 +2522,11 @@ var Client = class {
|
|
|
2394
2522
|
/**
|
|
2395
2523
|
* Start observing the user's active swaps and deriving each one's next action.
|
|
2396
2524
|
*
|
|
2397
|
-
* Loads stored swaps, maps
|
|
2398
|
-
*
|
|
2525
|
+
* Loads stored swaps, maps them to {@link TrackedSwap}s, and derives each
|
|
2526
|
+
* one's actions — by default from the server's status hints alone (TEMP while
|
|
2527
|
+
* the chain monitors are buggy; see
|
|
2528
|
+
* {@link ClientBuilder.withChainVerifiedTracking} to re-enable the per-ledger
|
|
2529
|
+
* chain monitors). Idempotent. Requires
|
|
2399
2530
|
* the client to have been built with {@link ClientBuilder.withTracking}.
|
|
2400
2531
|
* Subscribe with {@link subscribeToActions}; release with
|
|
2401
2532
|
* {@link stopTracking}.
|
|
@@ -2415,7 +2546,11 @@ var Client = class {
|
|
|
2415
2546
|
}
|
|
2416
2547
|
async #doStartTracking() {
|
|
2417
2548
|
try {
|
|
2418
|
-
const
|
|
2549
|
+
const chainVerified = this.#tracking.chainVerified || this.#tracking.managers !== void 0;
|
|
2550
|
+
const tracker = chainVerified ? new SwapTracker(await this.#ensureManagers(), {
|
|
2551
|
+
refreshIntervalMs: this.#tracking.refreshIntervalMs ?? 5e3
|
|
2552
|
+
}) : new HintTracker({
|
|
2553
|
+
fetchStatus: async (swapId) => (await this.getSwap(swapId, { updateStorage: true })).status,
|
|
2419
2554
|
refreshIntervalMs: this.#tracking.refreshIntervalMs ?? 5e3
|
|
2420
2555
|
});
|
|
2421
2556
|
this.#tracker = tracker;
|
|
@@ -2464,7 +2599,9 @@ var Client = class {
|
|
|
2464
2599
|
const swaps = await this.listAllSwaps();
|
|
2465
2600
|
return swaps.filter((s) => !SETTLED_STORED_STATUSES.has(s.response.status)).map((s) => {
|
|
2466
2601
|
try {
|
|
2467
|
-
|
|
2602
|
+
const tracked = swapToTracked(s);
|
|
2603
|
+
if (!tracked) return void 0;
|
|
2604
|
+
return { ...tracked, storedStatus: s.response.status };
|
|
2468
2605
|
} catch (error) {
|
|
2469
2606
|
console.warn(
|
|
2470
2607
|
`Client: skipping untrackable stored swap ${s.response.id}:`,
|
|
@@ -2542,7 +2679,7 @@ var Client = class {
|
|
|
2542
2679
|
* otherwise it runs observe-only, hints in, no spends.
|
|
2543
2680
|
*/
|
|
2544
2681
|
#startWorker(tracker) {
|
|
2545
|
-
const serverUrl = this.#tracking.serverUrl;
|
|
2682
|
+
const serverUrl = this.#tracking.serverUrl ?? legacyBaseUrl(this.#legacy);
|
|
2546
2683
|
if (!serverUrl) return;
|
|
2547
2684
|
const autoClaim = this.#tracking.autoClaim;
|
|
2548
2685
|
const hintSource = new WsStatusSource({ serverUrl });
|
|
@@ -2640,6 +2777,7 @@ var ClientBuilder = class {
|
|
|
2640
2777
|
#evmRpcUrls;
|
|
2641
2778
|
#managers;
|
|
2642
2779
|
#autoClaim;
|
|
2780
|
+
#chainVerified = false;
|
|
2643
2781
|
/**
|
|
2644
2782
|
* Override the EVM JSON-RPC endpoint per chainId. Optional — tracking uses
|
|
2645
2783
|
* tested public defaults otherwise; an override is tried first, with the
|
|
@@ -2666,6 +2804,16 @@ var ClientBuilder = class {
|
|
|
2666
2804
|
this.#trackingEnabled = false;
|
|
2667
2805
|
return this;
|
|
2668
2806
|
}
|
|
2807
|
+
/**
|
|
2808
|
+
* Verify swap state against the chain (per-ledger contract managers) instead
|
|
2809
|
+
* of trusting the server's status hints. TEMPORARILY off by default while the
|
|
2810
|
+
* chain monitors are being fixed — without it, tracking derives actions from
|
|
2811
|
+
* the server's pushed status alone, with zero chain access.
|
|
2812
|
+
*/
|
|
2813
|
+
withChainVerifiedTracking() {
|
|
2814
|
+
this.#chainVerified = true;
|
|
2815
|
+
return this;
|
|
2816
|
+
}
|
|
2669
2817
|
/**
|
|
2670
2818
|
* Advanced: supply per-ledger {@link ContractManager}s explicitly instead of
|
|
2671
2819
|
* letting the client auto-build them from config (useful for tests or custom
|
|
@@ -2783,10 +2931,18 @@ var ClientBuilder = class {
|
|
|
2783
2931
|
bitcoinNetwork: this.#bitcoinNetwork,
|
|
2784
2932
|
bitcoinMinConfirmations: this.#bitcoinMinConfirmations,
|
|
2785
2933
|
evmRpcUrls: this.#evmRpcUrls,
|
|
2786
|
-
autoClaim: this.#autoClaim
|
|
2934
|
+
autoClaim: this.#autoClaim,
|
|
2935
|
+
chainVerified: this.#chainVerified
|
|
2787
2936
|
});
|
|
2788
2937
|
}
|
|
2789
2938
|
};
|
|
2939
|
+
function legacyBaseUrl(legacy) {
|
|
2940
|
+
try {
|
|
2941
|
+
return legacy.baseUrl;
|
|
2942
|
+
} catch {
|
|
2943
|
+
return void 0;
|
|
2944
|
+
}
|
|
2945
|
+
}
|
|
2790
2946
|
var SETTLED_STORED_STATUSES = /* @__PURE__ */ new Set([
|
|
2791
2947
|
"serverredeemed",
|
|
2792
2948
|
"clientrefunded",
|
|
@@ -2807,6 +2963,7 @@ export {
|
|
|
2807
2963
|
DEFAULT_ESPLORA_URLS,
|
|
2808
2964
|
DEFAULT_EVM_RPCS,
|
|
2809
2965
|
EvmContractManager,
|
|
2966
|
+
HintTracker,
|
|
2810
2967
|
SwapTracker,
|
|
2811
2968
|
SwapWorker,
|
|
2812
2969
|
WsStatusSource,
|