@arkade-os/boltz-swap 0.3.39 → 0.3.41

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 CHANGED
@@ -61,6 +61,35 @@ console.log('Paid:', result.txid);
61
61
  // SwapManager auto-refunds if payment fails
62
62
  ```
63
63
 
64
+ By default the call resolves only once the swap fully settles (`transaction.claimed`),
65
+ i.e. after Boltz has swept the HTLC. To show an optimistic "sent" state as soon as the
66
+ payment is in flight — like most Lightning wallets — pass `waitFor: 'funded'`:
67
+
68
+ ```typescript
69
+ const result = await swaps.sendLightningPayment({
70
+ invoice: 'lnbc500u1pj...',
71
+ waitFor: 'funded',
72
+ });
73
+ // Resolves as soon as the lockup transaction is observed: the funds are
74
+ // committed and the swap is refundable from here. result.preimage is not
75
+ // reported on this path — the proof of payment is persisted to the stored
76
+ // swap once it settles. Monitoring continues in the
77
+ // background and keeps the stored swap up to date until a terminal status,
78
+ // but a late failure no longer rejects — keep the SwapManager enabled so
79
+ // auto-refunds are handled for you. With the SwapManager disabled, a late
80
+ // failure is only persisted as refundable and the funds stay locked until
81
+ // you recover them via restoreSwaps()/recoverSubmarineFunds().
82
+ ```
83
+
84
+ The same milestone is exposed for a swap you already hold as
85
+ `waitForSwapFunded(pendingSwap)`, alongside `waitForSwapSettlement(pendingSwap)`.
86
+
87
+ If the app restarts before the swap settles, the in-process monitoring is gone — call
88
+ `refreshSwapsStatus()` on startup to reconcile: it polls every pending swap and persists
89
+ the latest status, including the preimage for swaps that settled while the app was
90
+ closed. Read the swap back from the repository (e.g. `getSwapHistory()`) to flip a
91
+ pending UI row to "completed".
92
+
64
93
  ### ARK to BTC
65
94
 
66
95
  ```typescript
@@ -1,5 +1,5 @@
1
1
  import { IWallet, ArkProvider, IndexerProvider, ArkInfo, Identity, ArkTxInput, VHTLC } from '@arkade-os/sdk';
2
- import { r as BoltzSwapProvider, x as SwapManager, n as SwapRepository, q as ArkadeSwapsCreateConfig, A as ArkadeSwapsConfig, o as SwapManagerClient, C as CreateLightningInvoiceRequest, e as CreateLightningInvoiceResponse, b as BoltzReverseSwap, S as SendLightningPaymentRequest, f as SendLightningPaymentResponse, c as BoltzSubmarineSwap, g as SubmarineRefundOutcome, h as SubmarineRecoveryInfo, i as SubmarineRecoveryResult, k as ArkToBtcResponse, a as BoltzChainSwap, m as ChainArkRefundOutcome, l as BtcToArkResponse, d as Chain, F as FeesResponse, j as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, B as BoltzSwap } from './types-D97i1LFu.js';
2
+ import { r as BoltzSwapProvider, y as SwapManager, m as SwapRepository, q as ArkadeSwapsCreateConfig, A as ArkadeSwapsConfig, n as SwapManagerClient, C as CreateLightningInvoiceRequest, e as CreateLightningInvoiceResponse, b as BoltzReverseSwap, S as SendLightningPaymentRequest, o as SendLightningPaymentResponse, O as OptimisticSendLightningPaymentResponse, c as BoltzSubmarineSwap, f as SubmarineRefundOutcome, g as SubmarineRecoveryInfo, h as SubmarineRecoveryResult, j as ArkToBtcResponse, a as BoltzChainSwap, l as ChainArkRefundOutcome, k as BtcToArkResponse, d as Chain, F as FeesResponse, i as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, B as BoltzSwap } from './types-8NrCdOpS.cjs';
3
3
  import { TransactionOutput } from '@scure/btc-signer/psbt.js';
4
4
 
5
5
  /**
@@ -134,12 +134,33 @@ declare class ArkadeSwaps {
134
134
  }>;
135
135
  /**
136
136
  * Sends a Lightning payment via a submarine swap (Arkade → Lightning).
137
- * Creates the swap, sends funds, and waits for settlement. Auto-refunds on failure.
137
+ * Creates the swap, sends funds, and waits for settlement (or, with
138
+ * `waitFor: "funded"`, only until the lockup transaction is observed —
139
+ * see {@link SendLightningPaymentRequest.waitFor}). Auto-refunds on
140
+ * failures observed before the promise resolves.
138
141
  * @param args.invoice - BOLT11 Lightning invoice to pay.
139
- * @returns The amount paid, preimage (proof of payment), and transaction ID.
142
+ * @param args.waitFor - "settled" (default) resolves with the preimage at
143
+ * "transaction.claimed"; "funded" resolves without a preimage as soon as
144
+ * the payment is in flight.
145
+ * @returns The amount paid, preimage (proof of payment, unless resolved
146
+ * at "funded"), and transaction ID.
140
147
  * @throws {TransactionFailedError} If the payment fails (auto-refunds if possible).
148
+ * @remarks With `waitFor: "funded"`, failures observed *after* the promise
149
+ * resolves are only persisted to the repository (refundable flag) — the
150
+ * active auto-refund in this method is no longer reachable. Keep the
151
+ * SwapManager enabled so late failures are refunded automatically;
152
+ * without it the caller must recover via {@link restoreSwaps} /
153
+ * {@link recoverSubmarineFunds}.
154
+ *
155
+ * Note on types: the overloads narrow on the `waitFor` literal, so a
156
+ * request stored in a variable typed as `SendLightningPaymentRequest`
157
+ * widens the result to {@link OptimisticSendLightningPaymentResponse}
158
+ * (optional preimage) even on the default settled path.
141
159
  */
142
- sendLightningPayment(args: SendLightningPaymentRequest): Promise<SendLightningPaymentResponse>;
160
+ sendLightningPayment(args: SendLightningPaymentRequest & {
161
+ waitFor?: "settled";
162
+ }): Promise<SendLightningPaymentResponse>;
163
+ sendLightningPayment(args: SendLightningPaymentRequest): Promise<OptimisticSendLightningPaymentResponse>;
143
164
  /**
144
165
  * Creates a submarine swap (Arkade → Lightning) and saves it to storage.
145
166
  * @param args.invoice - BOLT11 Lightning invoice to pay.
@@ -229,6 +250,9 @@ declare class ArkadeSwaps {
229
250
  recoverAllSubmarineFunds(swaps: BoltzSubmarineSwap[]): Promise<SubmarineRecoveryResult[]>;
230
251
  /**
231
252
  * Waits for a submarine swap's Lightning payment to settle.
253
+ * Resolves only at the terminal "transaction.claimed" status, once Boltz
254
+ * has swept the HTLC. To resolve as soon as the payment is in flight, use
255
+ * {@link waitForSwapFunded} instead.
232
256
  * @param pendingSwap - The submarine swap to monitor.
233
257
  * @returns The preimage from the settled Lightning payment (proof of payment).
234
258
  * @throws {SwapExpiredError} If the swap expires.
@@ -238,6 +262,32 @@ declare class ArkadeSwaps {
238
262
  waitForSwapSettlement(pendingSwap: BoltzSubmarineSwap): Promise<{
239
263
  preimage: string;
240
264
  }>;
265
+ /**
266
+ * Waits until a submarine swap is funded: resolves as soon as the lockup
267
+ * transaction is observed ("transaction.mempool" or any later status in
268
+ * the lifecycle — statuses can be skipped since subscriptions report only
269
+ * the current one). The sender's funds are committed and the swap is
270
+ * refundable from this point, which is when most Lightning wallets show
271
+ * a payment as "sent".
272
+ *
273
+ * Monitoring continues in the background until the swap reaches a
274
+ * terminal status, persisting updates to the repository (the preimage on
275
+ * claim, the refundable flag on failure), but this promise no longer
276
+ * rejects once resolved — acting on a late failure is the caller's
277
+ * responsibility (the SwapManager handles it automatically when enabled).
278
+ * @param pendingSwap - The submarine swap to monitor.
279
+ * @throws {SwapExpiredError} If the swap expires before funding.
280
+ * @throws {InvoiceFailedToPayError} If Boltz fails to route the payment.
281
+ * @throws {TransactionLockupFailedError} If the lockup transaction fails.
282
+ */
283
+ waitForSwapFunded(pendingSwap: BoltzSubmarineSwap): Promise<void>;
284
+ /**
285
+ * Shared wait machinery: monitors the swap and resolves at the terminal
286
+ * "transaction.claimed" status (with the preimage) or, when `resolveAt`
287
+ * is given, as soon as that status — or any later one in the successful
288
+ * progression — is observed (without a preimage).
289
+ */
290
+ private waitForSubmarineSwap;
241
291
  /**
242
292
  * Creates a chain swap from ARK to BTC.
243
293
  * @param args.btcAddress - Destination Bitcoin address.
@@ -428,6 +478,23 @@ declare class ArkadeSwaps {
428
478
  vhtlcScript: VHTLC.Script;
429
479
  vhtlcAddress: string;
430
480
  };
481
+ /**
482
+ * Reconstruct a swap's VHTLC by matching the persisted `lockupAddress`
483
+ * against the current and deprecated server signers, returning the matched
484
+ * script together with the server key it was minted under.
485
+ *
486
+ * Recovery paths (claim/refund/lookup) must use this instead of building the
487
+ * VHTLC from the current signer alone: a swap created before a planned arkd
488
+ * signer rotation is locked to a now-deprecated signer, so the current key
489
+ * would yield the wrong address and strand the funds. The returned
490
+ * `serverXOnlyPublicKey` is the original (possibly deprecated) key and MUST
491
+ * be threaded into downstream signing/verification.
492
+ *
493
+ * Throws a descriptive mismatch error when no candidate reproduces the
494
+ * lockup address (e.g. the swap predates an already-pruned deprecated
495
+ * signer) — replacing the previous current-signer-only equality check.
496
+ */
497
+ private resolveVHTLCForLockup;
431
498
  /**
432
499
  * Retrieves fees for swaps.
433
500
  * - No arguments: returns lightning (submarine/reverse) fees
@@ -511,7 +578,10 @@ interface IArkadeSwaps extends AsyncDisposable {
511
578
  stopSwapManager(): Promise<void>;
512
579
  getSwapManager(): SwapManagerClient | null;
513
580
  createLightningInvoice(args: CreateLightningInvoiceRequest): Promise<CreateLightningInvoiceResponse>;
514
- sendLightningPayment(args: SendLightningPaymentRequest): Promise<SendLightningPaymentResponse>;
581
+ sendLightningPayment(args: SendLightningPaymentRequest & {
582
+ waitFor?: "settled";
583
+ }): Promise<SendLightningPaymentResponse>;
584
+ sendLightningPayment(args: SendLightningPaymentRequest): Promise<OptimisticSendLightningPaymentResponse>;
515
585
  createSubmarineSwap(args: SendLightningPaymentRequest): Promise<BoltzSubmarineSwap>;
516
586
  createReverseSwap(args: CreateLightningInvoiceRequest): Promise<BoltzReverseSwap>;
517
587
  claimVHTLC(pendingSwap: BoltzReverseSwap): Promise<void>;
@@ -526,6 +596,7 @@ interface IArkadeSwaps extends AsyncDisposable {
526
596
  waitForSwapSettlement(pendingSwap: BoltzSubmarineSwap): Promise<{
527
597
  preimage: string;
528
598
  }>;
599
+ waitForSwapFunded(pendingSwap: BoltzSubmarineSwap): Promise<void>;
529
600
  restoreSwaps(boltzFees?: FeesResponse): Promise<{
530
601
  chainSwaps: BoltzChainSwap[];
531
602
  reverseSwaps: BoltzReverseSwap[];
@@ -1,5 +1,5 @@
1
1
  import { IWallet, ArkProvider, IndexerProvider, ArkInfo, Identity, ArkTxInput, VHTLC } from '@arkade-os/sdk';
2
- import { r as BoltzSwapProvider, x as SwapManager, n as SwapRepository, q as ArkadeSwapsCreateConfig, A as ArkadeSwapsConfig, o as SwapManagerClient, C as CreateLightningInvoiceRequest, e as CreateLightningInvoiceResponse, b as BoltzReverseSwap, S as SendLightningPaymentRequest, f as SendLightningPaymentResponse, c as BoltzSubmarineSwap, g as SubmarineRefundOutcome, h as SubmarineRecoveryInfo, i as SubmarineRecoveryResult, k as ArkToBtcResponse, a as BoltzChainSwap, m as ChainArkRefundOutcome, l as BtcToArkResponse, d as Chain, F as FeesResponse, j as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, B as BoltzSwap } from './types-D97i1LFu.cjs';
2
+ import { r as BoltzSwapProvider, y as SwapManager, m as SwapRepository, q as ArkadeSwapsCreateConfig, A as ArkadeSwapsConfig, n as SwapManagerClient, C as CreateLightningInvoiceRequest, e as CreateLightningInvoiceResponse, b as BoltzReverseSwap, S as SendLightningPaymentRequest, o as SendLightningPaymentResponse, O as OptimisticSendLightningPaymentResponse, c as BoltzSubmarineSwap, f as SubmarineRefundOutcome, g as SubmarineRecoveryInfo, h as SubmarineRecoveryResult, j as ArkToBtcResponse, a as BoltzChainSwap, l as ChainArkRefundOutcome, k as BtcToArkResponse, d as Chain, F as FeesResponse, i as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, B as BoltzSwap } from './types-8NrCdOpS.js';
3
3
  import { TransactionOutput } from '@scure/btc-signer/psbt.js';
4
4
 
5
5
  /**
@@ -134,12 +134,33 @@ declare class ArkadeSwaps {
134
134
  }>;
135
135
  /**
136
136
  * Sends a Lightning payment via a submarine swap (Arkade → Lightning).
137
- * Creates the swap, sends funds, and waits for settlement. Auto-refunds on failure.
137
+ * Creates the swap, sends funds, and waits for settlement (or, with
138
+ * `waitFor: "funded"`, only until the lockup transaction is observed —
139
+ * see {@link SendLightningPaymentRequest.waitFor}). Auto-refunds on
140
+ * failures observed before the promise resolves.
138
141
  * @param args.invoice - BOLT11 Lightning invoice to pay.
139
- * @returns The amount paid, preimage (proof of payment), and transaction ID.
142
+ * @param args.waitFor - "settled" (default) resolves with the preimage at
143
+ * "transaction.claimed"; "funded" resolves without a preimage as soon as
144
+ * the payment is in flight.
145
+ * @returns The amount paid, preimage (proof of payment, unless resolved
146
+ * at "funded"), and transaction ID.
140
147
  * @throws {TransactionFailedError} If the payment fails (auto-refunds if possible).
148
+ * @remarks With `waitFor: "funded"`, failures observed *after* the promise
149
+ * resolves are only persisted to the repository (refundable flag) — the
150
+ * active auto-refund in this method is no longer reachable. Keep the
151
+ * SwapManager enabled so late failures are refunded automatically;
152
+ * without it the caller must recover via {@link restoreSwaps} /
153
+ * {@link recoverSubmarineFunds}.
154
+ *
155
+ * Note on types: the overloads narrow on the `waitFor` literal, so a
156
+ * request stored in a variable typed as `SendLightningPaymentRequest`
157
+ * widens the result to {@link OptimisticSendLightningPaymentResponse}
158
+ * (optional preimage) even on the default settled path.
141
159
  */
142
- sendLightningPayment(args: SendLightningPaymentRequest): Promise<SendLightningPaymentResponse>;
160
+ sendLightningPayment(args: SendLightningPaymentRequest & {
161
+ waitFor?: "settled";
162
+ }): Promise<SendLightningPaymentResponse>;
163
+ sendLightningPayment(args: SendLightningPaymentRequest): Promise<OptimisticSendLightningPaymentResponse>;
143
164
  /**
144
165
  * Creates a submarine swap (Arkade → Lightning) and saves it to storage.
145
166
  * @param args.invoice - BOLT11 Lightning invoice to pay.
@@ -229,6 +250,9 @@ declare class ArkadeSwaps {
229
250
  recoverAllSubmarineFunds(swaps: BoltzSubmarineSwap[]): Promise<SubmarineRecoveryResult[]>;
230
251
  /**
231
252
  * Waits for a submarine swap's Lightning payment to settle.
253
+ * Resolves only at the terminal "transaction.claimed" status, once Boltz
254
+ * has swept the HTLC. To resolve as soon as the payment is in flight, use
255
+ * {@link waitForSwapFunded} instead.
232
256
  * @param pendingSwap - The submarine swap to monitor.
233
257
  * @returns The preimage from the settled Lightning payment (proof of payment).
234
258
  * @throws {SwapExpiredError} If the swap expires.
@@ -238,6 +262,32 @@ declare class ArkadeSwaps {
238
262
  waitForSwapSettlement(pendingSwap: BoltzSubmarineSwap): Promise<{
239
263
  preimage: string;
240
264
  }>;
265
+ /**
266
+ * Waits until a submarine swap is funded: resolves as soon as the lockup
267
+ * transaction is observed ("transaction.mempool" or any later status in
268
+ * the lifecycle — statuses can be skipped since subscriptions report only
269
+ * the current one). The sender's funds are committed and the swap is
270
+ * refundable from this point, which is when most Lightning wallets show
271
+ * a payment as "sent".
272
+ *
273
+ * Monitoring continues in the background until the swap reaches a
274
+ * terminal status, persisting updates to the repository (the preimage on
275
+ * claim, the refundable flag on failure), but this promise no longer
276
+ * rejects once resolved — acting on a late failure is the caller's
277
+ * responsibility (the SwapManager handles it automatically when enabled).
278
+ * @param pendingSwap - The submarine swap to monitor.
279
+ * @throws {SwapExpiredError} If the swap expires before funding.
280
+ * @throws {InvoiceFailedToPayError} If Boltz fails to route the payment.
281
+ * @throws {TransactionLockupFailedError} If the lockup transaction fails.
282
+ */
283
+ waitForSwapFunded(pendingSwap: BoltzSubmarineSwap): Promise<void>;
284
+ /**
285
+ * Shared wait machinery: monitors the swap and resolves at the terminal
286
+ * "transaction.claimed" status (with the preimage) or, when `resolveAt`
287
+ * is given, as soon as that status — or any later one in the successful
288
+ * progression — is observed (without a preimage).
289
+ */
290
+ private waitForSubmarineSwap;
241
291
  /**
242
292
  * Creates a chain swap from ARK to BTC.
243
293
  * @param args.btcAddress - Destination Bitcoin address.
@@ -428,6 +478,23 @@ declare class ArkadeSwaps {
428
478
  vhtlcScript: VHTLC.Script;
429
479
  vhtlcAddress: string;
430
480
  };
481
+ /**
482
+ * Reconstruct a swap's VHTLC by matching the persisted `lockupAddress`
483
+ * against the current and deprecated server signers, returning the matched
484
+ * script together with the server key it was minted under.
485
+ *
486
+ * Recovery paths (claim/refund/lookup) must use this instead of building the
487
+ * VHTLC from the current signer alone: a swap created before a planned arkd
488
+ * signer rotation is locked to a now-deprecated signer, so the current key
489
+ * would yield the wrong address and strand the funds. The returned
490
+ * `serverXOnlyPublicKey` is the original (possibly deprecated) key and MUST
491
+ * be threaded into downstream signing/verification.
492
+ *
493
+ * Throws a descriptive mismatch error when no candidate reproduces the
494
+ * lockup address (e.g. the swap predates an already-pruned deprecated
495
+ * signer) — replacing the previous current-signer-only equality check.
496
+ */
497
+ private resolveVHTLCForLockup;
431
498
  /**
432
499
  * Retrieves fees for swaps.
433
500
  * - No arguments: returns lightning (submarine/reverse) fees
@@ -511,7 +578,10 @@ interface IArkadeSwaps extends AsyncDisposable {
511
578
  stopSwapManager(): Promise<void>;
512
579
  getSwapManager(): SwapManagerClient | null;
513
580
  createLightningInvoice(args: CreateLightningInvoiceRequest): Promise<CreateLightningInvoiceResponse>;
514
- sendLightningPayment(args: SendLightningPaymentRequest): Promise<SendLightningPaymentResponse>;
581
+ sendLightningPayment(args: SendLightningPaymentRequest & {
582
+ waitFor?: "settled";
583
+ }): Promise<SendLightningPaymentResponse>;
584
+ sendLightningPayment(args: SendLightningPaymentRequest): Promise<OptimisticSendLightningPaymentResponse>;
515
585
  createSubmarineSwap(args: SendLightningPaymentRequest): Promise<BoltzSubmarineSwap>;
516
586
  createReverseSwap(args: CreateLightningInvoiceRequest): Promise<BoltzReverseSwap>;
517
587
  claimVHTLC(pendingSwap: BoltzReverseSwap): Promise<void>;
@@ -526,6 +596,7 @@ interface IArkadeSwaps extends AsyncDisposable {
526
596
  waitForSwapSettlement(pendingSwap: BoltzSubmarineSwap): Promise<{
527
597
  preimage: string;
528
598
  }>;
599
+ waitForSwapFunded(pendingSwap: BoltzSubmarineSwap): Promise<void>;
529
600
  restoreSwaps(boltzFees?: FeesResponse): Promise<{
530
601
  chainSwaps: BoltzChainSwap[];
531
602
  reverseSwaps: BoltzReverseSwap[];
@@ -7,7 +7,7 @@ import {
7
7
  isSubmarineFinalStatus,
8
8
  isSubmarineSwapRefundable,
9
9
  logger
10
- } from "./chunk-CFB2NNGT.js";
10
+ } from "./chunk-UXYHW7KV.js";
11
11
 
12
12
  // src/expo/swapsPollProcessor.ts
13
13
  var SWAP_POLL_TASK_TYPE = "swap-poll";