@atomiqlabs/sdk 8.8.3 → 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 (130) 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/events/UnifiedSwapEventListener.d.ts +4 -3
  18. package/dist/events/UnifiedSwapEventListener.js +8 -2
  19. package/dist/http/HttpUtils.d.ts +4 -2
  20. package/dist/http/HttpUtils.js +10 -4
  21. package/dist/http/paramcoders/client/StreamingFetchPromise.d.ts +2 -1
  22. package/dist/http/paramcoders/client/StreamingFetchPromise.js +3 -2
  23. package/dist/index.d.ts +1 -0
  24. package/dist/index.js +1 -0
  25. package/dist/intermediaries/IntermediaryDiscovery.d.ts +7 -2
  26. package/dist/intermediaries/IntermediaryDiscovery.js +4 -4
  27. package/dist/intermediaries/apis/IntermediaryAPI.d.ts +171 -14
  28. package/dist/intermediaries/apis/IntermediaryAPI.js +174 -28
  29. package/dist/intermediaries/auth/SignedKeyBasedAuth.d.ts +14 -0
  30. package/dist/intermediaries/auth/SignedKeyBasedAuth.js +68 -0
  31. package/dist/storage/IUnifiedStorage.d.ts +45 -3
  32. package/dist/storage/UnifiedSwapStorage.d.ts +8 -2
  33. package/dist/storage/UnifiedSwapStorage.js +46 -8
  34. package/dist/swapper/Swapper.d.ts +36 -3
  35. package/dist/swapper/Swapper.js +54 -18
  36. package/dist/swapper/SwapperUtils.d.ts +18 -2
  37. package/dist/swapper/SwapperUtils.js +39 -1
  38. package/dist/swaps/ISwap.d.ts +70 -9
  39. package/dist/swaps/ISwap.js +28 -6
  40. package/dist/swaps/ISwapWrapper.d.ts +11 -1
  41. package/dist/swaps/ISwapWrapper.js +23 -3
  42. package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +1 -1
  43. package/dist/swaps/escrow_swaps/IEscrowSwap.js +4 -2
  44. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +2 -1
  45. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +2 -2
  46. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +3 -1
  47. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +3 -2
  48. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +47 -31
  49. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +201 -67
  50. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +3 -1
  51. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +6 -6
  52. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +82 -15
  53. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +304 -98
  54. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +3 -1
  55. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +6 -6
  56. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +75 -42
  57. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +424 -87
  58. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +3 -1
  59. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +7 -7
  60. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +54 -11
  61. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +214 -41
  62. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +2 -1
  63. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +7 -8
  64. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +3 -1
  65. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +5 -5
  66. package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +76 -19
  67. package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +290 -51
  68. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +3 -1
  69. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +5 -5
  70. package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +53 -12
  71. package/dist/swaps/trusted/ln/LnForGasSwap.js +163 -49
  72. package/dist/swaps/trusted/ln/LnForGasWrapper.js +1 -2
  73. package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +14 -13
  74. package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +30 -47
  75. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +3 -1
  76. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +4 -4
  77. package/dist/types/SwapExecutionAction.d.ts +141 -34
  78. package/dist/types/SwapExecutionAction.js +104 -0
  79. package/dist/types/SwapExecutionStep.d.ts +144 -0
  80. package/dist/types/SwapExecutionStep.js +87 -0
  81. package/dist/types/TokenAmount.d.ts +6 -0
  82. package/dist/types/TokenAmount.js +26 -1
  83. package/dist/utils/BitcoinUtils.d.ts +2 -0
  84. package/dist/utils/BitcoinUtils.js +34 -1
  85. package/dist/utils/Utils.d.ts +3 -1
  86. package/dist/utils/Utils.js +7 -1
  87. package/package.json +7 -4
  88. package/src/api/ApiEndpoints.ts +427 -0
  89. package/src/api/ApiParser.ts +138 -0
  90. package/src/api/ApiTypes.ts +229 -0
  91. package/src/api/SerializedAction.ts +97 -0
  92. package/src/api/SwapperApi.ts +545 -0
  93. package/src/api/index.ts +5 -0
  94. package/src/events/UnifiedSwapEventListener.ts +11 -3
  95. package/src/http/HttpUtils.ts +10 -4
  96. package/src/http/paramcoders/client/StreamingFetchPromise.ts +4 -2
  97. package/src/index.ts +1 -0
  98. package/src/intermediaries/IntermediaryDiscovery.ts +9 -2
  99. package/src/intermediaries/apis/IntermediaryAPI.ts +314 -30
  100. package/src/intermediaries/auth/SignedKeyBasedAuth.ts +69 -0
  101. package/src/storage/IUnifiedStorage.ts +45 -4
  102. package/src/storage/UnifiedSwapStorage.ts +42 -8
  103. package/src/swapper/Swapper.ts +87 -18
  104. package/src/swapper/SwapperUtils.ts +42 -2
  105. package/src/swaps/ISwap.ts +88 -16
  106. package/src/swaps/ISwapWrapper.ts +28 -3
  107. package/src/swaps/escrow_swaps/IEscrowSwap.ts +5 -3
  108. package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +3 -1
  109. package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +4 -1
  110. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +264 -67
  111. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +6 -4
  112. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +390 -89
  113. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +6 -4
  114. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +548 -94
  115. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +7 -5
  116. package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +276 -45
  117. package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +7 -6
  118. package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +5 -3
  119. package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +393 -57
  120. package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +5 -3
  121. package/src/swaps/trusted/ln/LnForGasSwap.ts +211 -47
  122. package/src/swaps/trusted/ln/LnForGasWrapper.ts +1 -2
  123. package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +32 -51
  124. package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +5 -3
  125. package/src/types/SwapExecutionAction.ts +266 -43
  126. package/src/types/SwapExecutionStep.ts +224 -0
  127. package/src/types/TokenAmount.ts +36 -2
  128. package/src/utils/BitcoinUtils.ts +32 -0
  129. package/src/utils/Utils.ts +10 -1
  130. package/src/intermediaries/apis/TrustedIntermediaryAPI.ts +0 -258
@@ -31,7 +31,15 @@ import {getLogger, LoggerType} from "../../../../utils/Logger";
31
31
  import {timeoutPromise} from "../../../../utils/TimeoutUtils";
32
32
  import {isLNURLWithdraw, LNURLWithdraw, LNURLWithdrawParamsWithUrl} from "../../../../types/lnurl/LNURLWithdraw";
33
33
  import {sha256} from "@noble/hashes/sha2";
34
- import {SwapExecutionAction} from "../../../../types/SwapExecutionAction";
34
+ import {
35
+ SwapExecutionActionSendToAddress,
36
+ SwapExecutionActionSignSmartChainTx
37
+ } from "../../../../types/SwapExecutionAction";
38
+ import {
39
+ SwapExecutionStepPayment,
40
+ SwapExecutionStepSettlement
41
+ } from "../../../../types/SwapExecutionStep";
42
+ import {SwapStateInfo} from "../../../../types/SwapStateInfo";
35
43
 
36
44
  /**
37
45
  * State enum for legacy Lightning -> Smart chain swaps
@@ -600,70 +608,201 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
600
608
  }
601
609
 
602
610
  /**
603
- * @inheritDoc
604
- *
605
- * @param options
606
- * @param options.skipChecks Skip checks like making sure init signature is still valid and swap
607
- * wasn't commited yet (this is handled on swap creation, if you commit right after quoting, you
608
- * can use `skipChecks=true`)
609
- * @param options.secret A swap secret to use for the claim transaction, generally only needed if the swap
610
- * was recovered from on-chain data, or the pre-image was generated outside the SDK
611
+ * @internal
611
612
  */
612
- async txsExecute(options?: {
613
- skipChecks?: boolean,
613
+ protected async _getExecutionStatus(options?: {
614
614
  secret?: string
615
615
  }) {
616
- if(this._state===FromBTCLNSwapState.PR_CREATED) {
617
- if(!await this._verifyQuoteValid()) throw new Error("Quote already expired or close to expiry!");
618
- return [
619
- {
620
- name: "Payment" as const,
621
- description: "Initiates the swap by paying up the lightning network invoice",
622
- chain: "LIGHTNING" as const,
623
- txs: [
624
- {
625
- type: "BOLT11_PAYMENT_REQUEST" as const,
626
- address: this.getAddress(),
627
- hyperlink: this.getHyperlink()
628
- }
629
- ]
616
+ if(options?.secret!=null) this.setSecretPreimage(options.secret);
617
+ const state = this._state;
618
+
619
+ let lightningPaymentStatus: SwapExecutionStepPayment<"LIGHTNING">["status"] = "inactive";
620
+ let destinationSettlementStatus: SwapExecutionStepSettlement<T["ChainId"], "awaiting_manual">["status"] = "inactive";
621
+ let buildCurrentAction: (actionOptions?: {
622
+ skipChecks?: boolean
623
+ }) => Promise<
624
+ SwapExecutionActionSendToAddress<true> |
625
+ SwapExecutionActionSignSmartChainTx<T> |
626
+ undefined
627
+ > = async () => undefined;
628
+
629
+ switch(state) {
630
+ case FromBTCLNSwapState.PR_CREATED: {
631
+ const quoteValid = await this._verifyQuoteValid();
632
+ lightningPaymentStatus = quoteValid ? "awaiting" : "soft_expired";
633
+ if(quoteValid && this.pr!=null && this.pr.toLowerCase().startsWith("ln")) {
634
+ buildCurrentAction = this._buildLightningPaymentAction.bind(this);
635
+ }
636
+ break;
637
+ }
638
+ case FromBTCLNSwapState.QUOTE_SOFT_EXPIRED:
639
+ if(this.signatureData==null) {
640
+ lightningPaymentStatus = "soft_expired";
641
+ } else {
642
+ lightningPaymentStatus = "received";
643
+ destinationSettlementStatus = "soft_expired";
630
644
  }
631
- ];
645
+ break;
646
+ case FromBTCLNSwapState.PR_PAID:
647
+ case FromBTCLNSwapState.CLAIM_COMMITED:
648
+ lightningPaymentStatus = "received";
649
+ destinationSettlementStatus = "awaiting_manual";
650
+ if(
651
+ (state!==FromBTCLNSwapState.PR_PAID || await this._verifyQuoteValid()) &&
652
+ this.hasSecretPreimage()
653
+ ) {
654
+ buildCurrentAction = this._buildClaimSmartChainTxAction.bind(this);
655
+ }
656
+ break;
657
+ case FromBTCLNSwapState.CLAIM_CLAIMED:
658
+ lightningPaymentStatus = "confirmed";
659
+ destinationSettlementStatus = "settled";
660
+ break;
661
+ case FromBTCLNSwapState.EXPIRED:
662
+ case FromBTCLNSwapState.FAILED:
663
+ lightningPaymentStatus = "expired";
664
+ destinationSettlementStatus = "expired";
665
+ break;
666
+ case FromBTCLNSwapState.QUOTE_EXPIRED:
667
+ if(this.signatureData==null) {
668
+ lightningPaymentStatus = "expired";
669
+ } else {
670
+ lightningPaymentStatus = "expired";
671
+ destinationSettlementStatus = "expired";
672
+ }
673
+ break;
632
674
  }
633
675
 
634
- if(this._state===FromBTCLNSwapState.PR_PAID) {
635
- if(!await this._verifyQuoteValid()) throw new Error("Quote already expired or close to expiry!");
636
- const txsCommit = await this.txsCommit(options?.skipChecks);
637
- const txsClaim = await this._txsClaim(undefined, options?.secret);
638
- return [
676
+ return {
677
+ steps: [
639
678
  {
640
- name: "Commit" as const,
641
- description: `Creates the HTLC escrow on the ${this.chainIdentifier} side`,
642
- chain: this.chainIdentifier,
643
- txs: txsCommit
679
+ type: "Payment",
680
+ side: "source",
681
+ chain: "LIGHTNING",
682
+ title: "Lightning payment",
683
+ description: "Pay the Lightning network invoice to initiate the swap",
684
+ status: lightningPaymentStatus,
685
+ initTxId: this.getInputTxId(),
686
+ settleTxId: lightningPaymentStatus==="confirmed" ? this.getInputTxId() : undefined
644
687
  },
645
688
  {
646
- name: "Claim" as const,
647
- description: `Settles & claims the funds from the HTLC escrow on the ${this.chainIdentifier} side`,
689
+ type: "Settlement",
690
+ side: "destination",
648
691
  chain: this.chainIdentifier,
649
- txs: txsClaim
650
- },
651
- ];
692
+ title: "Destination settlement",
693
+ description: `Manually settle the swap on the ${this.chainIdentifier} side`,
694
+ status: destinationSettlementStatus,
695
+ initTxId: this._commitTxId,
696
+ settleTxId: this._claimTxId
697
+ }
698
+ ] as [
699
+ SwapExecutionStepPayment<"LIGHTNING">,
700
+ SwapExecutionStepSettlement<T["ChainId"], "awaiting_manual">
701
+ ],
702
+ buildCurrentAction,
703
+ state
704
+ };
705
+ }
706
+
707
+ /**
708
+ * @internal
709
+ */
710
+ private async _buildLightningPaymentAction(): Promise<SwapExecutionActionSendToAddress<true>> {
711
+ return {
712
+ type: "SendToAddress",
713
+ name: "Deposit on Lightning",
714
+ description: "Pay the lightning network invoice to initiate the swap",
715
+ chain: "LIGHTNING",
716
+ txs: [{
717
+ type: "BOLT11_PAYMENT_REQUEST",
718
+ address: this.getAddress(),
719
+ hyperlink: this.getHyperlink(),
720
+ amount: this.getInput()
721
+ }],
722
+ waitForTransactions: async (
723
+ maxWaitTimeSeconds?: number, pollIntervalSeconds?: number, abortSignal?: AbortSignal
724
+ ) => {
725
+ const abortController = extendAbortController(
726
+ abortSignal, maxWaitTimeSeconds, "Timed out waiting for lightning payment"
727
+ );
728
+
729
+ const success = await this.waitForPayment(
730
+ undefined,
731
+ pollIntervalSeconds,
732
+ abortController.signal
733
+ );
734
+ if(!success) throw new Error("Quote expired while waiting for Lightning payment");
735
+
736
+ return this.getInputTxId();
737
+ }
738
+ } as SwapExecutionActionSendToAddress<true>;
739
+ }
740
+
741
+ /**
742
+ * @inheritDoc
743
+ * @internal
744
+ */
745
+ async _submitExecutionTransactions(txs: (T["SignedTXType"] | string)[], abortSignal?: AbortSignal, requiredStates?: FromBTCLNSwapState[], idempotent?: boolean): Promise<string[]> {
746
+ const parsedTxs: T["SignedTXType"][] = [];
747
+ for(let tx of txs) {
748
+ parsedTxs.push(typeof(tx)==="string" ? await this.wrapper._chain.deserializeSignedTx(tx) : tx);
749
+ }
750
+
751
+ if(idempotent) {
752
+ // Handle idempotent calls
753
+ if(this.wrapper._chain.getTxId!=null) {
754
+ const txIds = await Promise.all(parsedTxs.map(tx => this.wrapper._chain.getTxId!(tx)));
755
+ const foundTxId = txIds.find(txId => this._commitTxId===txId || this._claimTxId===txId);
756
+ if(foundTxId!=null) return txIds;
757
+ }
758
+ }
759
+
760
+ if(requiredStates!=null && !requiredStates.includes(this._state)) throw new Error("Swap state has changed before transactions were submitted!");
761
+
762
+ if(this._state===FromBTCLNSwapState.PR_PAID || this._state===FromBTCLNSwapState.QUOTE_SOFT_EXPIRED) {
763
+ if(!await this._verifyQuoteValid()) throw new Error("Quote is already expired!");
764
+ const txIds = await this.wrapper._chain.sendSignedAndConfirm(parsedTxs, true, abortSignal, false);
765
+ await this.waitTillCommited(abortSignal);
766
+ await this.waitTillClaimed(undefined, abortSignal);
767
+ return txIds;
652
768
  }
653
769
 
654
770
  if(this._state===FromBTCLNSwapState.CLAIM_COMMITED) {
655
- const txsClaim = await this.txsClaim(undefined, options?.secret);
656
- return [
657
- {
658
- name: "Claim" as const,
659
- description: `Settles & claims the funds from the HTLC escrow on the ${this.chainIdentifier} side`,
660
- chain: this.chainIdentifier,
661
- txs: txsClaim
662
- },
663
- ];
771
+ const txIds = await this.wrapper._chain.sendSignedAndConfirm(parsedTxs, true, abortSignal, false);
772
+ await this.waitTillClaimed(undefined, abortSignal);
773
+ return txIds;
664
774
  }
665
775
 
666
- throw new Error("Invalid swap state to obtain execution txns, required PR_CREATED, PR_PAID or CLAIM_COMMITED");
776
+ throw new Error("Invalid swap state for transaction submission!");
777
+ }
778
+
779
+ /**
780
+ * @internal
781
+ */
782
+ private async _buildClaimSmartChainTxAction(actionOptions?: {
783
+ skipChecks?: boolean,
784
+ secret?: string
785
+ }): Promise<SwapExecutionActionSignSmartChainTx<T>> {
786
+ return {
787
+ type: "SignSmartChainTransaction",
788
+ name: "Settle manually",
789
+ description: "Create the HTLC escrow and settle the swap on the destination smart chain",
790
+ chain: this.chainIdentifier,
791
+ txs: await this.prepareTransactions(this.txsCommitAndClaim(actionOptions?.skipChecks, actionOptions?.secret)),
792
+ submitTransactions: async (txs: (T["SignedTXType"] | string)[], abortSignal?: AbortSignal, idempotent?: boolean) => {
793
+ return this._submitExecutionTransactions(
794
+ txs,
795
+ abortSignal,
796
+ [
797
+ FromBTCLNSwapState.PR_PAID,
798
+ FromBTCLNSwapState.QUOTE_SOFT_EXPIRED,
799
+ FromBTCLNSwapState.CLAIM_COMMITED
800
+ ],
801
+ idempotent
802
+ );
803
+ },
804
+ requiredSigner: this._getInitiator()
805
+ } as SwapExecutionActionSignSmartChainTx<T>;
667
806
  }
668
807
 
669
808
  /**
@@ -676,15 +815,53 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
676
815
  * @param options.secret A swap secret to use for the claim transaction, generally only needed if the swap
677
816
  * was recovered from on-chain data, or the pre-image was generated outside the SDK
678
817
  */
679
- async getCurrentActions(options?: {
818
+ async getExecutionAction(options?: {
680
819
  skipChecks?: boolean,
681
820
  secret?: string
682
- }): Promise<SwapExecutionAction<T>[]> {
683
- try {
684
- return await this.txsExecute(options);
685
- } catch (e) {
686
- return [];
687
- }
821
+ }): Promise<
822
+ SwapExecutionActionSendToAddress<true> |
823
+ SwapExecutionActionSignSmartChainTx<T> |
824
+ undefined
825
+ > {
826
+ const executionStatus = await this._getExecutionStatus(options);
827
+ return executionStatus.buildCurrentAction(options);
828
+ }
829
+
830
+ /**
831
+ * @inheritDoc
832
+ */
833
+ // TODO: Figure how we gonna trigger an LNURL-withdraw with the execution actions
834
+ async getExecutionStatus(options?: {
835
+ skipBuildingAction?: boolean,
836
+ skipChecks?: boolean,
837
+ secret?: string
838
+ }): Promise<{
839
+ steps: [
840
+ SwapExecutionStepPayment<"LIGHTNING">,
841
+ SwapExecutionStepSettlement<T["ChainId"], "awaiting_manual">
842
+ ],
843
+ currentAction:
844
+ SwapExecutionActionSendToAddress<true> |
845
+ SwapExecutionActionSignSmartChainTx<T> |
846
+ undefined,
847
+ stateInfo: SwapStateInfo<FromBTCLNSwapState>
848
+ }> {
849
+ const executionStatus = await this._getExecutionStatus(options);
850
+ return {
851
+ steps: executionStatus.steps,
852
+ currentAction: options?.skipBuildingAction ? undefined : await executionStatus.buildCurrentAction(options),
853
+ stateInfo: this._getStateInfo(executionStatus.state)
854
+ };
855
+ }
856
+
857
+ /**
858
+ * @inheritDoc
859
+ */
860
+ async getExecutionSteps(): Promise<[
861
+ SwapExecutionStepPayment<"LIGHTNING">,
862
+ SwapExecutionStepSettlement<T["ChainId"], "awaiting_manual">
863
+ ]> {
864
+ return (await this._getExecutionStatus()).steps;
688
865
  }
689
866
 
690
867
 
@@ -713,7 +890,7 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
713
890
  if(paymentHash==null)
714
891
  throw new Error("Failed to check LP payment received, payment hash not known (probably recovered swap?)");
715
892
 
716
- const resp = await IntermediaryAPI.getPaymentAuthorization(this.url, paymentHash.toString("hex"));
893
+ const resp = await this.wrapper._lpApi.getPaymentAuthorization(this.url, paymentHash.toString("hex"));
717
894
  switch(resp.code) {
718
895
  case PaymentAuthorizationResponseCodes.AUTH_DATA:
719
896
  const data = new (this.wrapper._swapDataDeserializer(this._contractVersion))(resp.data.data);
@@ -837,7 +1014,7 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
837
1014
 
838
1015
  let resp: PaymentAuthorizationResponse = {code: PaymentAuthorizationResponseCodes.PENDING, msg: ""};
839
1016
  while(!abortController.signal.aborted && resp.code===PaymentAuthorizationResponseCodes.PENDING) {
840
- resp = await IntermediaryAPI.getPaymentAuthorization(this.url, paymentHash.toString("hex"));
1017
+ resp = await this.wrapper._lpApi.getPaymentAuthorization(this.url, paymentHash.toString("hex"));
841
1018
  if(resp.code===PaymentAuthorizationResponseCodes.PENDING)
842
1019
  await timeoutPromise(checkIntervalSeconds*1000, abortController.signal);
843
1020
  }
@@ -919,9 +1096,12 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
919
1096
  ]);
920
1097
  abortController.abort();
921
1098
 
922
- if(result===0) this.logger.debug("waitTillCommited(): Resolved from state changed");
923
- if(result===true) this.logger.debug("waitTillCommited(): Resolved from watchdog - commited");
924
- if(result===false) {
1099
+ if(result===0) {
1100
+ this.logger.debug("waitTillCommited(): Resolved from state changed");
1101
+ } else if(result!=null) {
1102
+ this.logger.debug("waitTillCommited(): Resolved from watchdog - commited");
1103
+ }
1104
+ if(result===null) {
925
1105
  this.logger.debug("waitTillCommited(): Resolved from watchdog - signature expired");
926
1106
  if(
927
1107
  this._state===FromBTCLNSwapState.PR_PAID ||
@@ -936,6 +1116,8 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
936
1116
  this._state===FromBTCLNSwapState.PR_PAID ||
937
1117
  this._state===FromBTCLNSwapState.QUOTE_SOFT_EXPIRED
938
1118
  ) {
1119
+ if(typeof(result)==="object" && (result as any).getInitTxId!=null && this._commitTxId==null)
1120
+ this._commitTxId = await (result as any).getInitTxId();
939
1121
  await this._saveAndEmit(FromBTCLNSwapState.CLAIM_COMMITED);
940
1122
  }
941
1123
  }
@@ -1401,27 +1583,42 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
1401
1583
  async _forciblySetOnchainState(commitStatus: SwapCommitState): Promise<boolean> {
1402
1584
  switch(commitStatus.type) {
1403
1585
  case SwapCommitStateType.PAID:
1586
+ if(this._commitTxId==null && (commitStatus as any).getInitTxId!=null) this._commitTxId = await (commitStatus as any).getInitTxId();
1404
1587
  if(this._claimTxId==null) this._claimTxId = await commitStatus.getClaimTxId();
1405
1588
  if(this.secret==null || this.pr==null) this._setSwapSecret(await commitStatus.getClaimResult());
1406
1589
  this._state = FromBTCLNSwapState.CLAIM_CLAIMED;
1407
1590
  return true;
1408
1591
  case SwapCommitStateType.NOT_COMMITED:
1409
- if(this._refundTxId==null && commitStatus.getRefundTxId) this._refundTxId = await commitStatus.getRefundTxId();
1592
+ let changed: boolean = false;
1593
+ if(this._commitTxId==null && (commitStatus as any).getInitTxId!=null) {
1594
+ this._commitTxId = await (commitStatus as any).getInitTxId();
1595
+ changed = true;
1596
+ }
1597
+ if(this._refundTxId==null && commitStatus.getRefundTxId) {
1598
+ this._refundTxId = await commitStatus.getRefundTxId();
1599
+ changed = true;
1600
+ }
1410
1601
  if(this._refundTxId!=null) {
1411
1602
  this._state = FromBTCLNSwapState.FAILED;
1412
- return true;
1603
+ changed = true;
1413
1604
  }
1414
- break;
1605
+ return changed;
1415
1606
  case SwapCommitStateType.EXPIRED:
1607
+ if(this._commitTxId==null && (commitStatus as any).getInitTxId!=null) this._commitTxId = await (commitStatus as any).getInitTxId();
1416
1608
  if(this._refundTxId==null && commitStatus.getRefundTxId) this._refundTxId = await commitStatus.getRefundTxId();
1417
1609
  this._state = this._refundTxId==null ? FromBTCLNSwapState.QUOTE_EXPIRED : FromBTCLNSwapState.FAILED;
1418
1610
  return true;
1419
1611
  case SwapCommitStateType.COMMITED:
1612
+ let save: boolean = false;
1613
+ if(this._commitTxId==null && (commitStatus as any).getInitTxId!=null) {
1614
+ this._commitTxId = await (commitStatus as any).getInitTxId();
1615
+ save = true;
1616
+ }
1420
1617
  if(this._state!==FromBTCLNSwapState.CLAIM_COMMITED && this._state!==FromBTCLNSwapState.EXPIRED) {
1421
1618
  this._state = FromBTCLNSwapState.CLAIM_COMMITED;
1422
- return true;
1619
+ save = true;
1423
1620
  }
1424
- break;
1621
+ return save;
1425
1622
  }
1426
1623
  return false;
1427
1624
  }
@@ -117,6 +117,7 @@ export class FromBTCLNWrapper<
117
117
  * @param tokens
118
118
  * @param versionedContracts
119
119
  * @param lnApi
120
+ * @param lpApi
120
121
  * @param options
121
122
  * @param events Instance to use for emitting events
122
123
  */
@@ -134,11 +135,12 @@ export class FromBTCLNWrapper<
134
135
  }
135
136
  },
136
137
  lnApi: LightningNetworkApi,
138
+ lpApi: IntermediaryAPI,
137
139
  options?: AllOptional<FromBTCLNWrapperOptions>,
138
140
  events?: EventEmitter<{swapState: [ISwap]}>
139
141
  ) {
140
142
  super(
141
- chainIdentifier, unifiedStorage, unifiedChainEvents, chain, prices, tokens, versionedContracts, lnApi,
143
+ chainIdentifier, unifiedStorage, unifiedChainEvents, chain, prices, tokens, versionedContracts, lnApi, lpApi,
142
144
  {
143
145
  ...options,
144
146
  safetyFactor: options?.safetyFactor ?? 2,
@@ -310,7 +312,7 @@ export class FromBTCLNWrapper<
310
312
  const liquidityPromise: Promise<bigint | undefined> = this.preFetchIntermediaryLiquidity(amountData, lp, abortController, version);
311
313
 
312
314
  const {lnCapacityPromise, resp} = await tryWithRetries(async(retryCount: number) => {
313
- const {lnPublicKey, response} = IntermediaryAPI.initFromBTCLN(
315
+ const {lnPublicKey, response} = this._lpApi.initFromBTCLN(
314
316
  this.chainIdentifier, lp.url, nativeTokenAddress,
315
317
  {
316
318
  paymentHash,
@@ -320,7 +322,7 @@ export class FromBTCLNWrapper<
320
322
  description: _options.description,
321
323
  descriptionHash: _options.descriptionHash,
322
324
  exactOut: !amountData.exactIn,
323
- feeRate: throwIfUndefined(_preFetches.feeRatePromise[version]),
325
+ feeRate: throwIfUndefined(_preFetches.feeRatePromise[version], "Network fee rate pre-fetch failed!"),
324
326
  additionalParams
325
327
  },
326
328
  this._options.postRequestTimeout, abortController.signal, retryCount>0 ? false : undefined
@@ -351,7 +353,7 @@ export class FromBTCLNWrapper<
351
353
  lp.services[SwapType.FROM_BTCLN], false, amountIn, resp.total,
352
354
  amountData.token, {swapFeeBtc}, _preFetches.pricePrefetchPromise, _preFetches.usdPricePrefetchPromise, abortController.signal
353
355
  ),
354
- this.verifyIntermediaryLiquidity(resp.total, throwIfUndefined(liquidityPromise)),
356
+ this.verifyIntermediaryLiquidity(resp.total, throwIfUndefined(liquidityPromise, "LP liquidity pre-fetch failed!")),
355
357
  lnCapacityPromise!=null ? this.verifyLnNodeCapacity(lp, decodedPr, lnCapacityPromise, abortController.signal) : Promise.resolve()
356
358
  ]);
357
359