@atomiqlabs/sdk 8.7.7 → 8.9.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.
Files changed (152) hide show
  1. package/api/index.d.ts +1 -0
  2. package/api/index.js +3 -0
  3. package/dist/ApiList.d.ts +37 -0
  4. package/dist/ApiList.js +30 -0
  5. package/dist/api/ApiEndpoints.d.ts +393 -0
  6. package/dist/api/ApiEndpoints.js +2 -0
  7. package/dist/api/ApiParser.d.ts +10 -0
  8. package/dist/api/ApiParser.js +134 -0
  9. package/dist/api/ApiTypes.d.ts +157 -0
  10. package/dist/api/ApiTypes.js +75 -0
  11. package/dist/api/SerializedAction.d.ts +40 -0
  12. package/dist/api/SerializedAction.js +59 -0
  13. package/dist/api/SwapperApi.d.ts +50 -0
  14. package/dist/api/SwapperApi.js +431 -0
  15. package/dist/api/index.d.ts +5 -0
  16. package/dist/api/index.js +24 -0
  17. package/dist/bitcoin/coinselect2/accumulative.d.ts +1 -0
  18. package/dist/bitcoin/coinselect2/accumulative.js +1 -1
  19. package/dist/bitcoin/coinselect2/blackjack.d.ts +1 -0
  20. package/dist/bitcoin/coinselect2/blackjack.js +1 -1
  21. package/dist/bitcoin/coinselect2/index.d.ts +3 -2
  22. package/dist/bitcoin/coinselect2/index.js +2 -2
  23. package/dist/bitcoin/coinselect2/utils.d.ts +7 -2
  24. package/dist/bitcoin/coinselect2/utils.js +45 -10
  25. package/dist/bitcoin/wallet/BitcoinWallet.d.ts +8 -25
  26. package/dist/bitcoin/wallet/BitcoinWallet.js +31 -18
  27. package/dist/bitcoin/wallet/IBitcoinWallet.d.ts +40 -2
  28. package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.d.ts +7 -2
  29. package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.js +10 -4
  30. package/dist/events/UnifiedSwapEventListener.d.ts +4 -3
  31. package/dist/events/UnifiedSwapEventListener.js +8 -2
  32. package/dist/http/HttpUtils.d.ts +4 -2
  33. package/dist/http/HttpUtils.js +10 -4
  34. package/dist/http/paramcoders/client/StreamingFetchPromise.d.ts +2 -1
  35. package/dist/http/paramcoders/client/StreamingFetchPromise.js +3 -2
  36. package/dist/index.d.ts +1 -0
  37. package/dist/index.js +1 -0
  38. package/dist/intermediaries/IntermediaryDiscovery.d.ts +7 -2
  39. package/dist/intermediaries/IntermediaryDiscovery.js +4 -4
  40. package/dist/intermediaries/apis/IntermediaryAPI.d.ts +182 -15
  41. package/dist/intermediaries/apis/IntermediaryAPI.js +192 -31
  42. package/dist/intermediaries/auth/SignedKeyBasedAuth.d.ts +14 -0
  43. package/dist/intermediaries/auth/SignedKeyBasedAuth.js +68 -0
  44. package/dist/storage/IUnifiedStorage.d.ts +45 -3
  45. package/dist/storage/UnifiedSwapStorage.d.ts +8 -2
  46. package/dist/storage/UnifiedSwapStorage.js +46 -8
  47. package/dist/swapper/Swapper.d.ts +77 -4
  48. package/dist/swapper/Swapper.js +117 -25
  49. package/dist/swapper/SwapperUtils.d.ts +18 -2
  50. package/dist/swapper/SwapperUtils.js +39 -1
  51. package/dist/swaps/ISwap.d.ts +70 -9
  52. package/dist/swaps/ISwap.js +28 -6
  53. package/dist/swaps/ISwapWrapper.d.ts +11 -1
  54. package/dist/swaps/ISwapWrapper.js +23 -3
  55. package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +1 -1
  56. package/dist/swaps/escrow_swaps/IEscrowSwap.js +4 -2
  57. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +2 -1
  58. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +2 -2
  59. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +3 -1
  60. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +3 -2
  61. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +47 -31
  62. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +201 -67
  63. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +3 -1
  64. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +6 -6
  65. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +82 -15
  66. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +304 -98
  67. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +3 -1
  68. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +6 -6
  69. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +75 -42
  70. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +424 -87
  71. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +3 -1
  72. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +7 -7
  73. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +54 -11
  74. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +214 -41
  75. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +2 -1
  76. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +7 -8
  77. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +3 -1
  78. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +5 -5
  79. package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +85 -22
  80. package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +299 -56
  81. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +41 -7
  82. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +183 -58
  83. package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +53 -12
  84. package/dist/swaps/trusted/ln/LnForGasSwap.js +163 -49
  85. package/dist/swaps/trusted/ln/LnForGasWrapper.js +1 -2
  86. package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +14 -13
  87. package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +30 -47
  88. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +3 -1
  89. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +4 -4
  90. package/dist/types/SwapExecutionAction.d.ts +141 -34
  91. package/dist/types/SwapExecutionAction.js +104 -0
  92. package/dist/types/SwapExecutionStep.d.ts +144 -0
  93. package/dist/types/SwapExecutionStep.js +87 -0
  94. package/dist/types/TokenAmount.d.ts +6 -0
  95. package/dist/types/TokenAmount.js +26 -1
  96. package/dist/utils/BitcoinUtils.d.ts +4 -0
  97. package/dist/utils/BitcoinUtils.js +73 -1
  98. package/dist/utils/BitcoinWalletUtils.d.ts +2 -2
  99. package/dist/utils/Utils.d.ts +3 -1
  100. package/dist/utils/Utils.js +7 -1
  101. package/package.json +7 -4
  102. package/src/api/ApiEndpoints.ts +427 -0
  103. package/src/api/ApiParser.ts +138 -0
  104. package/src/api/ApiTypes.ts +229 -0
  105. package/src/api/SerializedAction.ts +97 -0
  106. package/src/api/SwapperApi.ts +545 -0
  107. package/src/api/index.ts +5 -0
  108. package/src/bitcoin/coinselect2/accumulative.ts +2 -1
  109. package/src/bitcoin/coinselect2/blackjack.ts +2 -1
  110. package/src/bitcoin/coinselect2/index.ts +5 -4
  111. package/src/bitcoin/coinselect2/utils.ts +55 -14
  112. package/src/bitcoin/wallet/BitcoinWallet.ts +69 -57
  113. package/src/bitcoin/wallet/IBitcoinWallet.ts +44 -3
  114. package/src/bitcoin/wallet/SingleAddressBitcoinWallet.ts +12 -4
  115. package/src/events/UnifiedSwapEventListener.ts +11 -3
  116. package/src/http/HttpUtils.ts +10 -4
  117. package/src/http/paramcoders/client/StreamingFetchPromise.ts +4 -2
  118. package/src/index.ts +1 -0
  119. package/src/intermediaries/IntermediaryDiscovery.ts +9 -2
  120. package/src/intermediaries/apis/IntermediaryAPI.ts +335 -35
  121. package/src/intermediaries/auth/SignedKeyBasedAuth.ts +69 -0
  122. package/src/storage/IUnifiedStorage.ts +45 -4
  123. package/src/storage/UnifiedSwapStorage.ts +42 -8
  124. package/src/swapper/Swapper.ts +165 -24
  125. package/src/swapper/SwapperUtils.ts +42 -2
  126. package/src/swaps/ISwap.ts +88 -16
  127. package/src/swaps/ISwapWrapper.ts +28 -3
  128. package/src/swaps/escrow_swaps/IEscrowSwap.ts +5 -3
  129. package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +3 -1
  130. package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +4 -1
  131. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +264 -67
  132. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +6 -4
  133. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +390 -89
  134. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +6 -4
  135. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +548 -94
  136. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +7 -5
  137. package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +276 -45
  138. package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +7 -6
  139. package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +5 -3
  140. package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +413 -64
  141. package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +239 -61
  142. package/src/swaps/trusted/ln/LnForGasSwap.ts +211 -47
  143. package/src/swaps/trusted/ln/LnForGasWrapper.ts +1 -2
  144. package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +32 -51
  145. package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +5 -3
  146. package/src/types/SwapExecutionAction.ts +266 -43
  147. package/src/types/SwapExecutionStep.ts +224 -0
  148. package/src/types/TokenAmount.ts +36 -2
  149. package/src/utils/BitcoinUtils.ts +73 -0
  150. package/src/utils/BitcoinWalletUtils.ts +2 -2
  151. package/src/utils/Utils.ts +10 -1
  152. package/src/intermediaries/apis/TrustedIntermediaryAPI.ts +0 -258
@@ -2,9 +2,9 @@ import {decode as bolt11Decode} from "@atomiqlabs/bolt11";
2
2
  import {SwapType} from "../../../enums/SwapType";
3
3
  import {ChainType} from "@atomiqlabs/base";
4
4
  import {LnForGasSwapTypeDefinition, LnForGasWrapper} from "./LnForGasWrapper";
5
- import {toBigInt} from "../../../utils/Utils";
5
+ import {extendAbortController, toBigInt} from "../../../utils/Utils";
6
6
  import {isISwapInit, ISwap, ISwapInit} from "../../ISwap";
7
- import {InvoiceStatusResponseCodes, TrustedIntermediaryAPI} from "../../../intermediaries/apis/TrustedIntermediaryAPI";
7
+ import {TrustedInvoiceStatusResponseCodes} from "../../../intermediaries/apis/IntermediaryAPI";
8
8
  import {Fee} from "../../../types/fees/Fee";
9
9
  import {IAddressSwap} from "../../IAddressSwap";
10
10
  import {FeeType} from "../../../enums/FeeType";
@@ -13,7 +13,15 @@ import {TokenAmount, toTokenAmount} from "../../../types/TokenAmount";
13
13
  import {BitcoinTokens, BtcToken, SCToken} from "../../../types/Token";
14
14
  import {getLogger, LoggerType} from "../../../utils/Logger";
15
15
  import {timeoutPromise} from "../../../utils/TimeoutUtils";
16
- import {SwapExecutionAction, SwapExecutionActionLightning} from "../../../types/SwapExecutionAction";
16
+ import {
17
+ SwapExecutionActionSendToAddress,
18
+ SwapExecutionActionWait
19
+ } from "../../../types/SwapExecutionAction";
20
+ import {
21
+ SwapExecutionStepPayment,
22
+ SwapExecutionStepSettlement
23
+ } from "../../../types/SwapExecutionStep";
24
+ import {SwapStateInfo} from "../../../types/SwapStateInfo";
17
25
 
18
26
  /**
19
27
  * State enum for trusted Lightning gas swaps
@@ -22,38 +30,38 @@ import {SwapExecutionAction, SwapExecutionActionLightning} from "../../../types/
22
30
  */
23
31
  export enum LnForGasSwapState {
24
32
  /**
25
- * The swap quote expired without user sending in the lightning network payment
33
+ * The swap quote expired before the user paid the Lightning invoice
26
34
  */
27
35
  EXPIRED = -2,
28
36
  /**
29
- * The swap has failed after the intermediary already received a lightning network payment on the source
37
+ * The swap has failed before the destination payout completed, and the held Lightning invoice was released
30
38
  */
31
39
  FAILED = -1,
32
40
  /**
33
- * Swap was created, pay the provided lightning network invoice
41
+ * Swap was created, pay the provided Lightning invoice which will remain held until destination payout succeeds
34
42
  */
35
43
  PR_CREATED = 0,
36
44
  /**
37
- * User paid the lightning network invoice on the source
45
+ * The Lightning invoice was paid and is currently held until the user receives the destination funds
38
46
  */
39
47
  PR_PAID = 1,
40
48
  /**
41
- * The swap is finished after the intermediary sent funds on the destination chain
49
+ * The swap is finished after the destination payout succeeded and the held Lightning invoice was settled
42
50
  */
43
51
  FINISHED = 2
44
52
  }
45
53
 
46
54
  const LnForGasSwapStateDescription = {
47
55
  [LnForGasSwapState.EXPIRED]:
48
- "The swap quote expired without user sending in the lightning network payment",
56
+ "The swap quote expired before the user paid the Lightning invoice",
49
57
  [LnForGasSwapState.FAILED]:
50
- "The swap has failed after the intermediary already received a lightning network payment on the source",
58
+ "The swap failed before destination payout completed, and the held Lightning invoice was released back to the user",
51
59
  [LnForGasSwapState.PR_CREATED]:
52
- "Swap was created, pay the provided lightning network invoice",
60
+ "Swap was created, pay the provided Lightning invoice. The invoice will remain held until destination payout succeeds",
53
61
  [LnForGasSwapState.PR_PAID]:
54
- "User paid the lightning network invoice on the source",
62
+ "The Lightning invoice was paid and is currently held. It will only settle once the user receives the destination funds",
55
63
  [LnForGasSwapState.FINISHED]:
56
- "The swap is finished after the intermediary sent funds on the destination chain"
64
+ "The swap is finished after the destination payout succeeded and the held Lightning invoice was settled"
57
65
  }
58
66
 
59
67
  export type LnForGasSwapInit = ISwapInit & {
@@ -403,46 +411,191 @@ export class LnForGasSwap<T extends ChainType = ChainType> extends ISwap<T, LnFo
403
411
  //// Payment
404
412
 
405
413
  /**
406
- * @inheritDoc
414
+ * @remarks Not supported
407
415
  */
408
- async txsExecute(): Promise<[SwapExecutionActionLightning]> {
409
- if(this._state===LnForGasSwapState.PR_CREATED) {
410
- if (!await this._verifyQuoteValid()) throw new Error("Quote already expired or close to expiry!");
411
- return [
416
+ async execute(): Promise<boolean> {
417
+ throw new Error("Not supported");
418
+ }
419
+
420
+ /**
421
+ * @internal
422
+ */
423
+ protected async _getExecutionStatus() {
424
+ const state = this._state;
425
+
426
+ let lightningPaymentStatus: SwapExecutionStepPayment<"LIGHTNING">["status"] = "inactive";
427
+ let destinationSettlementStatus: SwapExecutionStepSettlement<T["ChainId"]>["status"] = "inactive";
428
+ let buildCurrentAction: () => Promise<
429
+ SwapExecutionActionSendToAddress<true> |
430
+ SwapExecutionActionWait<"LP"> |
431
+ undefined
432
+ > = async () => undefined;
433
+
434
+ switch(state) {
435
+ case LnForGasSwapState.PR_CREATED: {
436
+ const quoteValid = await this._verifyQuoteValid();
437
+ lightningPaymentStatus = quoteValid ? "awaiting" : "soft_expired";
438
+ if(quoteValid) {
439
+ buildCurrentAction = this._buildLightningPaymentAction.bind(this);
440
+ }
441
+ break;
442
+ }
443
+ case LnForGasSwapState.EXPIRED:
444
+ lightningPaymentStatus = "expired";
445
+ break;
446
+ case LnForGasSwapState.PR_PAID:
447
+ lightningPaymentStatus = "received";
448
+ destinationSettlementStatus = "waiting_lp";
449
+ buildCurrentAction = this._buildWaitLpAction.bind(this);
450
+ break;
451
+ case LnForGasSwapState.FAILED:
452
+ lightningPaymentStatus = "expired";
453
+ destinationSettlementStatus = "expired";
454
+ break;
455
+ case LnForGasSwapState.FINISHED:
456
+ lightningPaymentStatus = "confirmed";
457
+ destinationSettlementStatus = "settled";
458
+ break;
459
+ }
460
+
461
+ return {
462
+ steps: [
412
463
  {
413
- name: "Payment" as const,
414
- description: "Initiates the swap by paying up the lightning network invoice",
464
+ type: "Payment",
465
+ side: "source",
415
466
  chain: "LIGHTNING",
416
- txs: [
417
- {
418
- type: "BOLT11_PAYMENT_REQUEST",
419
- address: this.pr,
420
- hyperlink: this.getHyperlink()
467
+ title: "Lightning payment",
468
+ description: "Pay the Lightning network invoice to initiate the swap",
469
+ status: lightningPaymentStatus
470
+ },
471
+ {
472
+ type: "Settlement",
473
+ side: "destination",
474
+ chain: this.chainIdentifier,
475
+ title: "Destination payout",
476
+ description: "Wait for the intermediary to send the gas tokens on the destination smart chain",
477
+ status: destinationSettlementStatus
478
+ }
479
+ ] as [
480
+ SwapExecutionStepPayment<"LIGHTNING">,
481
+ SwapExecutionStepSettlement<T["ChainId"], never>
482
+ ],
483
+ buildCurrentAction,
484
+ state
485
+ };
486
+ }
487
+
488
+ /**
489
+ * @internal
490
+ * @inheritDoc
491
+ */
492
+ _submitExecutionTransactions(): Promise<string[]> {
493
+ throw new Error("Invalid swap state for transaction submission!");
494
+ }
495
+
496
+ /**
497
+ * @internal
498
+ */
499
+ private async _buildLightningPaymentAction(): Promise<SwapExecutionActionSendToAddress<true>> {
500
+ return {
501
+ type: "SendToAddress",
502
+ name: "Deposit on Lightning",
503
+ description: "Pay the lightning network invoice to initiate the swap",
504
+ chain: "LIGHTNING",
505
+ txs: [{
506
+ type: "BOLT11_PAYMENT_REQUEST",
507
+ address: this.pr,
508
+ hyperlink: this.getHyperlink(),
509
+ amount: this.getInput()
510
+ }],
511
+ waitForTransactions: async (
512
+ maxWaitTimeSeconds?: number, pollIntervalSeconds?: number, abortSignal?: AbortSignal
513
+ ) => {
514
+ const abortController = extendAbortController(
515
+ abortSignal, maxWaitTimeSeconds, "Timed out waiting for lightning payment"
516
+ );
517
+ let lightningTxId: string | undefined;
518
+ try {
519
+ const success = await this.waitForPayment(
520
+ pollIntervalSeconds, abortController.signal,
521
+ (txId: string) => {
522
+ lightningTxId = txId;
523
+ abortController.abort();
421
524
  }
422
- ]
525
+ );
526
+ if(!success) throw new Error("Quote expired while waiting for lightning payment");
527
+ } catch (e) {
528
+ if(lightningTxId!=null) return lightningTxId;
529
+ throw e;
423
530
  }
424
- ];
425
- }
531
+ return this.getInputTxId()!;
532
+ }
533
+ } as SwapExecutionActionSendToAddress<true>;
534
+ }
426
535
 
427
- throw new Error("Invalid swap state to obtain execution txns, required PR_CREATED");
536
+ /**
537
+ * @internal
538
+ */
539
+ private async _buildWaitLpAction(): Promise<SwapExecutionActionWait<"LP">> {
540
+ return {
541
+ type: "Wait",
542
+ name: "Awaiting LP payout",
543
+ description: "Wait for the intermediary to send the gas tokens on the destination smart chain",
544
+ pollTimeSeconds: 5,
545
+ expectedTimeSeconds: 10,
546
+ wait: async (
547
+ maxWaitTimeSeconds?: number, pollIntervalSeconds?: number, abortSignal?: AbortSignal
548
+ ) => {
549
+ const abortController = extendAbortController(
550
+ abortSignal, maxWaitTimeSeconds, "Timed out waiting for LP payout"
551
+ );
552
+ await this.waitForPayment(pollIntervalSeconds, abortController.signal);
553
+ }
554
+ } as SwapExecutionActionWait<"LP">;
428
555
  }
429
556
 
430
557
  /**
431
- * @remark Not supported
558
+ * @inheritDoc
432
559
  */
433
- async execute(): Promise<boolean> {
434
- throw new Error("Not supported");
560
+ async getExecutionAction(): Promise<
561
+ SwapExecutionActionSendToAddress<true> |
562
+ SwapExecutionActionWait<"LP"> |
563
+ undefined
564
+ > {
565
+ const executionStatus = await this._getExecutionStatus();
566
+ return executionStatus.buildCurrentAction();
435
567
  }
436
568
 
437
569
  /**
438
570
  * @inheritDoc
439
571
  */
440
- async getCurrentActions(): Promise<SwapExecutionAction<T>[]> {
441
- try {
442
- return await this.txsExecute();
443
- } catch (e) {
444
- return [];
445
- }
572
+ async getExecutionStatus(options?: {skipBuildingAction?: boolean}): Promise<{
573
+ steps: [
574
+ SwapExecutionStepPayment<"LIGHTNING">,
575
+ SwapExecutionStepSettlement<T["ChainId"], never>
576
+ ],
577
+ currentAction:
578
+ SwapExecutionActionSendToAddress<true> |
579
+ SwapExecutionActionWait<"LP"> |
580
+ undefined,
581
+ stateInfo: SwapStateInfo<LnForGasSwapState>
582
+ }> {
583
+ const executionStatus = await this._getExecutionStatus();
584
+ return {
585
+ steps: executionStatus.steps,
586
+ currentAction: options?.skipBuildingAction ? undefined : await executionStatus.buildCurrentAction(),
587
+ stateInfo: this._getStateInfo(executionStatus.state)
588
+ };
589
+ }
590
+
591
+ /**
592
+ * @inheritDoc
593
+ */
594
+ async getExecutionSteps(): Promise<[
595
+ SwapExecutionStepPayment<"LIGHTNING">,
596
+ SwapExecutionStepSettlement<T["ChainId"], never>
597
+ ]> {
598
+ return (await this._getExecutionStatus()).steps;
446
599
  }
447
600
 
448
601
  /**
@@ -462,12 +615,12 @@ export class LnForGasSwap<T extends ChainType = ChainType> extends ISwap<T, LnFo
462
615
  const paymentHash = decodedPR.tagsObject.payment_hash;
463
616
  if(paymentHash==null) throw new Error("Invalid swap invoice, payment hash not found!");
464
617
 
465
- const response = await TrustedIntermediaryAPI.getInvoiceStatus(
618
+ const response = await this.wrapper._lpApi.getTrustedInvoiceStatus(
466
619
  this.url, paymentHash, this.wrapper._options.getRequestTimeout
467
620
  );
468
621
  this.logger.debug("checkInvoicePaid(): LP response: ", response);
469
622
  switch(response.code) {
470
- case InvoiceStatusResponseCodes.PAID:
623
+ case TrustedInvoiceStatusResponseCodes.PAID:
471
624
  this.scTxId = response.data.txId;
472
625
  const txStatus = await this.wrapper._chain.getTxIdStatus(this.scTxId);
473
626
  if(txStatus==="success") {
@@ -476,7 +629,7 @@ export class LnForGasSwap<T extends ChainType = ChainType> extends ISwap<T, LnFo
476
629
  return true;
477
630
  }
478
631
  return null;
479
- case InvoiceStatusResponseCodes.EXPIRED:
632
+ case TrustedInvoiceStatusResponseCodes.EXPIRED:
480
633
  if(this._state===LnForGasSwapState.PR_CREATED) {
481
634
  this._state = LnForGasSwapState.EXPIRED;
482
635
  } else {
@@ -484,20 +637,20 @@ export class LnForGasSwap<T extends ChainType = ChainType> extends ISwap<T, LnFo
484
637
  }
485
638
  if(save) await this._saveAndEmit();
486
639
  return false;
487
- case InvoiceStatusResponseCodes.TX_SENT:
640
+ case TrustedInvoiceStatusResponseCodes.TX_SENT:
488
641
  this.scTxId = response.data.txId;
489
642
  if(this._state===LnForGasSwapState.PR_CREATED) {
490
643
  this._state = LnForGasSwapState.PR_PAID;
491
644
  if(save) await this._saveAndEmit();
492
645
  }
493
646
  return null;
494
- case InvoiceStatusResponseCodes.PENDING:
647
+ case TrustedInvoiceStatusResponseCodes.PENDING:
495
648
  if(this._state===LnForGasSwapState.PR_CREATED) {
496
649
  this._state = LnForGasSwapState.PR_PAID;
497
650
  if(save) await this._saveAndEmit();
498
651
  }
499
652
  return null;
500
- case InvoiceStatusResponseCodes.AWAIT_PAYMENT:
653
+ case TrustedInvoiceStatusResponseCodes.AWAIT_PAYMENT:
501
654
  return null;
502
655
  default:
503
656
  this._state = LnForGasSwapState.FAILED;
@@ -508,14 +661,17 @@ export class LnForGasSwap<T extends ChainType = ChainType> extends ISwap<T, LnFo
508
661
 
509
662
  /**
510
663
  * A blocking promise resolving when payment was received by the intermediary and client can continue,
511
- * rejecting in case of failure. The swap must be in {@link LnForGasSwapState.PR_CREATED} state!
664
+ * rejecting in case of failure. The swap must be in {@link LnForGasSwapState.PR_CREATED} or
665
+ * {@link LnForGasSwapState.PR_PAID} state!
512
666
  *
513
667
  * @param checkIntervalSeconds How often to poll the intermediary for answer (default 5 seconds)
514
668
  * @param abortSignal Abort signal
669
+ * @param onPaymentReceived Callback as for when the LP reports having received the ln payment
515
670
  * @throws {Error} When in invalid state (not PR_CREATED)
516
671
  */
517
- async waitForPayment(checkIntervalSeconds?: number, abortSignal?: AbortSignal): Promise<boolean> {
518
- if(this._state!==LnForGasSwapState.PR_CREATED) throw new Error("Must be in PR_CREATED state!");
672
+ async waitForPayment(checkIntervalSeconds?: number, abortSignal?: AbortSignal, onPaymentReceived?: (txId: string) => void): Promise<boolean> {
673
+ if(this._state!==LnForGasSwapState.PR_CREATED && this._state!==LnForGasSwapState.PR_PAID)
674
+ throw new Error("Must be in PR_CREATED or PR_PAID state!");
519
675
 
520
676
  if(!this.initiated) {
521
677
  this.initiated = true;
@@ -524,9 +680,17 @@ export class LnForGasSwap<T extends ChainType = ChainType> extends ISwap<T, LnFo
524
680
 
525
681
  while(!abortSignal?.aborted && (this._state===LnForGasSwapState.PR_CREATED || this._state===LnForGasSwapState.PR_PAID)) {
526
682
  await this.checkInvoicePaid(true);
683
+ if((this._state as LnForGasSwapState)===LnForGasSwapState.PR_PAID) {
684
+ if(onPaymentReceived!=null) {
685
+ onPaymentReceived(this.getInputTxId()!);
686
+ onPaymentReceived = undefined; // Set to null so it only triggers once
687
+ }
688
+ }
527
689
  if(this._state===LnForGasSwapState.PR_CREATED || this._state===LnForGasSwapState.PR_PAID) await timeoutPromise((checkIntervalSeconds ?? 5)*1000, abortSignal);
528
690
  }
529
691
 
692
+ if(abortSignal!=null) abortSignal.throwIfAborted();
693
+
530
694
  if(this.isFailed()) throw new Error("Swap failed");
531
695
  return !this.isQuoteExpired();
532
696
 
@@ -1,6 +1,5 @@
1
1
  import {LnForGasSwap, LnForGasSwapInit, LnForGasSwapState} from "./LnForGasSwap";
2
2
  import {ISwapWrapper, SwapTypeDefinition} from "../../ISwapWrapper";
3
- import {TrustedIntermediaryAPI} from "../../../intermediaries/apis/TrustedIntermediaryAPI";
4
3
  import {decode as bolt11Decode} from "@atomiqlabs/bolt11";
5
4
  import {IntermediaryError} from "../../../errors/IntermediaryError";
6
5
  import {ChainType} from "@atomiqlabs/base";
@@ -50,7 +49,7 @@ export class LnForGasWrapper<T extends ChainType> extends ISwapWrapper<T, LnForG
50
49
 
51
50
  const token = this._chain.getNativeCurrencyAddress();
52
51
 
53
- const resp = await TrustedIntermediaryAPI.initTrustedFromBTCLN(this.chainIdentifier, lpUrl, {
52
+ const resp = await this._lpApi.initTrustedFromBTCLN(this.chainIdentifier, lpUrl, {
54
53
  address: recipient,
55
54
  amount,
56
55
  token
@@ -3,7 +3,7 @@ import {ChainType} from "@atomiqlabs/base";
3
3
  import {toBigInt} from "../../../utils/Utils";
4
4
  import {parsePsbtTransaction, toOutputScript} from "../../../utils/BitcoinUtils";
5
5
  import {isISwapInit, ISwap, ISwapInit} from "../../ISwap";
6
- import {AddressStatusResponseCodes, TrustedIntermediaryAPI} from "../../../intermediaries/apis/TrustedIntermediaryAPI";
6
+ import {TrustedAddressStatusResponseCodes} from "../../../intermediaries/apis/IntermediaryAPI";
7
7
  import {OnchainForGasSwapTypeDefinition, OnchainForGasWrapper} from "./OnchainForGasWrapper";
8
8
  import {Fee} from "../../../types/fees/Fee";
9
9
  import {IBitcoinWallet, isIBitcoinWallet} from "../../../bitcoin/wallet/IBitcoinWallet";
@@ -23,7 +23,6 @@ import {BitcoinTokens, BtcToken, SCToken} from "../../../types/Token";
23
23
  import {getLogger, LoggerType} from "../../../utils/Logger";
24
24
  import {timeoutPromise} from "../../../utils/TimeoutUtils";
25
25
  import {toBitcoinWallet} from "../../../utils/BitcoinWalletUtils";
26
- import {SwapExecutionAction, SwapExecutionActionBitcoin} from "../../../types/SwapExecutionAction";
27
26
 
28
27
  /**
29
28
  * State enum for trusted on-chain gas swaps
@@ -562,57 +561,39 @@ export class OnchainForGasSwap<T extends ChainType = ChainType> extends ISwap<T,
562
561
  * @param options.bitcoinWallet Optional bitcoin wallet address specification to return a funded PSBT,
563
562
  * if not provided an address is returned instead.
564
563
  */
565
- async txsExecute(options?: {
564
+ async getExecutionAction(options?: {
566
565
  bitcoinWallet?: MinimalBitcoinWalletInterface
567
- }): Promise<[
568
- SwapExecutionActionBitcoin<"ADDRESS" | "FUNDED_PSBT">
569
- ]> {
570
- if(this._state===OnchainForGasSwapState.PR_CREATED) {
571
- if(!await this._verifyQuoteValid()) throw new Error("Quote already expired or close to expiry!");
572
- return [
573
- {
574
- name: "Payment" as const,
575
- description: "Send funds to the bitcoin swap address",
576
- chain: "BITCOIN",
577
- txs: [
578
- options?.bitcoinWallet==null ? {
579
- address: this.address,
580
- amount: Number(this.inputAmount),
581
- hyperlink: this.getHyperlink(),
582
- type: "ADDRESS"
583
- } : {
584
- ...await this.getFundedPsbt(options.bitcoinWallet),
585
- type: "FUNDED_PSBT"
586
- }
587
- ]
588
- }
589
- ];
590
- }
566
+ }): Promise<never> {
567
+ throw new Error("Not supported");
568
+ }
591
569
 
592
- throw new Error("Invalid swap state to obtain execution txns, required PR_CREATED or CLAIM_COMMITED");
570
+ /**
571
+ * @inheritDoc
572
+ */
573
+ async getExecutionSteps(): Promise<never> {
574
+ throw new Error("Not supported");
593
575
  }
594
576
 
595
577
  /**
596
- * @remark Not supported
578
+ * @inheritDoc
597
579
  */
598
- async execute(): Promise<boolean> {
580
+ async getExecutionStatus(): Promise<never> {
599
581
  throw new Error("Not supported");
600
582
  }
601
583
 
602
584
  /**
585
+ * @internal
603
586
  * @inheritDoc
604
- *
605
- * @param options.bitcoinWallet Optional bitcoin wallet address specification to return a funded PSBT,
606
- * if not provided an address is returned instead.
607
587
  */
608
- async getCurrentActions(options?: {
609
- bitcoinWallet?: MinimalBitcoinWalletInterface
610
- }): Promise<SwapExecutionAction<T>[]> {
611
- try {
612
- return await this.txsExecute(options);
613
- } catch (e) {
614
- return [];
615
- }
588
+ _submitExecutionTransactions(): Promise<string[]> {
589
+ throw new Error("Not supported");
590
+ }
591
+
592
+ /**
593
+ * @remarks Not supported
594
+ */
595
+ async execute(): Promise<boolean> {
596
+ throw new Error("Not supported");
616
597
  }
617
598
 
618
599
  //////////////////////////////
@@ -635,20 +616,20 @@ export class OnchainForGasSwap<T extends ChainType = ChainType> extends ISwap<T,
635
616
  if(this._state===OnchainForGasSwapState.FINISHED) return false;
636
617
  if(this.url==null) return false;
637
618
 
638
- const response = await TrustedIntermediaryAPI.getAddressStatus(
619
+ const response = await this.wrapper._lpApi.getTrustedAddressStatus(
639
620
  this.url, this.paymentHash, this.sequence, this.wrapper._options.getRequestTimeout
640
621
  );
641
622
  switch(response.code) {
642
- case AddressStatusResponseCodes.AWAIT_PAYMENT:
623
+ case TrustedAddressStatusResponseCodes.AWAIT_PAYMENT:
643
624
  if(this.txId!=null) {
644
625
  this.txId = undefined;
645
626
  if(save) await this._save();
646
627
  return true;
647
628
  }
648
629
  return false;
649
- case AddressStatusResponseCodes.AWAIT_CONFIRMATION:
650
- case AddressStatusResponseCodes.PENDING:
651
- case AddressStatusResponseCodes.TX_SENT:
630
+ case TrustedAddressStatusResponseCodes.AWAIT_CONFIRMATION:
631
+ case TrustedAddressStatusResponseCodes.PENDING:
632
+ case TrustedAddressStatusResponseCodes.TX_SENT:
652
633
  const inputAmount = BigInt(response.data.adjustedAmount);
653
634
  const outputAmount = BigInt(response.data.adjustedTotal);
654
635
  const adjustedFee = response.data.adjustedFee==null ? null : BigInt(response.data.adjustedFee);
@@ -668,7 +649,7 @@ export class OnchainForGasSwap<T extends ChainType = ChainType> extends ISwap<T,
668
649
  return true;
669
650
  }
670
651
  return false;
671
- case AddressStatusResponseCodes.PAID:
652
+ case TrustedAddressStatusResponseCodes.PAID:
672
653
  const txStatus = await this.wrapper._chain.getTxIdStatus(response.data.txId);
673
654
  if(txStatus==="success") {
674
655
  this._state = OnchainForGasSwapState.FINISHED;
@@ -677,16 +658,16 @@ export class OnchainForGasSwap<T extends ChainType = ChainType> extends ISwap<T,
677
658
  return true;
678
659
  }
679
660
  return false;
680
- case AddressStatusResponseCodes.EXPIRED:
661
+ case TrustedAddressStatusResponseCodes.EXPIRED:
681
662
  this._state = OnchainForGasSwapState.EXPIRED;
682
663
  if(save) await this._saveAndEmit();
683
664
  return true;
684
- case AddressStatusResponseCodes.REFUNDABLE:
665
+ case TrustedAddressStatusResponseCodes.REFUNDABLE:
685
666
  if(this._state===OnchainForGasSwapState.REFUNDABLE) return null;
686
667
  this._state = OnchainForGasSwapState.REFUNDABLE;
687
668
  if(save) await this._saveAndEmit();
688
669
  return true;
689
- case AddressStatusResponseCodes.REFUNDED:
670
+ case TrustedAddressStatusResponseCodes.REFUNDED:
690
671
  this._state = OnchainForGasSwapState.REFUNDED;
691
672
  this.refundTxId = response.data.txId;
692
673
  if(save) await this._saveAndEmit();
@@ -710,7 +691,7 @@ export class OnchainForGasSwap<T extends ChainType = ChainType> extends ISwap<T,
710
691
  return;
711
692
  }
712
693
  if(this.url==null) throw new Error("LP URL not known, cannot set refund address!");
713
- await TrustedIntermediaryAPI.setRefundAddress(
694
+ await this.wrapper._lpApi.setTrustedRefundAddress(
714
695
  this.url, this.paymentHash, this.sequence, refundAddress, this.wrapper._options.getRequestTimeout
715
696
  );
716
697
  this.refundAddress = refundAddress;
@@ -1,5 +1,4 @@
1
1
  import {ISwapWrapper, ISwapWrapperOptions, SwapTypeDefinition, WrapperCtorTokens} from "../../ISwapWrapper";
2
- import {TrustedIntermediaryAPI} from "../../../intermediaries/apis/TrustedIntermediaryAPI";
3
2
  import {IntermediaryError} from "../../../errors/IntermediaryError";
4
3
  import {BitcoinRpcWithAddressIndex, ChainType} from "@atomiqlabs/base";
5
4
  import {OnchainForGasSwap, OnchainForGasSwapInit, OnchainForGasSwapState} from "./OnchainForGasSwap";
@@ -11,6 +10,7 @@ import {UnifiedSwapEventListener} from "../../../events/UnifiedSwapEventListener
11
10
  import {UnifiedSwapStorage} from "../../../storage/UnifiedSwapStorage";
12
11
  import {ISwap} from "../../ISwap";
13
12
  import {BTC_NETWORK} from "@scure/btc-signer/utils";
13
+ import {IntermediaryAPI} from "../../../intermediaries/apis/IntermediaryAPI";
14
14
 
15
15
  export type OnchainForGasWrapperOptions = ISwapWrapperOptions & {
16
16
  bitcoinNetwork: BTC_NETWORK
@@ -57,6 +57,7 @@ export class OnchainForGasWrapper<T extends ChainType> extends ISwapWrapper<T, O
57
57
  * @param prices Pricing to use
58
58
  * @param tokens
59
59
  * @param btcRpc Bitcoin RPC which also supports getting transactions by txoHash
60
+ * @param lpApi
60
61
  * @param options
61
62
  * @param events Instance to use for emitting events
62
63
  */
@@ -68,10 +69,11 @@ export class OnchainForGasWrapper<T extends ChainType> extends ISwapWrapper<T, O
68
69
  prices: ISwapPrice,
69
70
  tokens: WrapperCtorTokens,
70
71
  btcRpc: BitcoinRpcWithAddressIndex<any>,
72
+ lpApi: IntermediaryAPI,
71
73
  options: OnchainForGasWrapperOptions,
72
74
  events?: EventEmitter<{swapState: [ISwap]}>
73
75
  ) {
74
- super(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, prices, tokens, options, events);
76
+ super(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, prices, tokens, lpApi, options, events);
75
77
  this._btcRpc = btcRpc;
76
78
  }
77
79
 
@@ -91,7 +93,7 @@ export class OnchainForGasWrapper<T extends ChainType> extends ISwapWrapper<T, O
91
93
 
92
94
  const token = this._chain.getNativeCurrencyAddress();
93
95
 
94
- const resp = await TrustedIntermediaryAPI.initTrustedFromBTC(this.chainIdentifier, lpUrl, {
96
+ const resp = await this._lpApi.initTrustedFromBTC(this.chainIdentifier, lpUrl, {
95
97
  address: recipient,
96
98
  amount,
97
99
  refundAddress,