@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.
- package/api/index.d.ts +1 -0
- package/api/index.js +3 -0
- package/dist/ApiList.d.ts +37 -0
- package/dist/ApiList.js +30 -0
- package/dist/api/ApiEndpoints.d.ts +393 -0
- package/dist/api/ApiEndpoints.js +2 -0
- package/dist/api/ApiParser.d.ts +10 -0
- package/dist/api/ApiParser.js +134 -0
- package/dist/api/ApiTypes.d.ts +157 -0
- package/dist/api/ApiTypes.js +75 -0
- package/dist/api/SerializedAction.d.ts +40 -0
- package/dist/api/SerializedAction.js +59 -0
- package/dist/api/SwapperApi.d.ts +50 -0
- package/dist/api/SwapperApi.js +431 -0
- package/dist/api/index.d.ts +5 -0
- package/dist/api/index.js +24 -0
- package/dist/bitcoin/coinselect2/accumulative.d.ts +1 -0
- package/dist/bitcoin/coinselect2/accumulative.js +1 -1
- package/dist/bitcoin/coinselect2/blackjack.d.ts +1 -0
- package/dist/bitcoin/coinselect2/blackjack.js +1 -1
- package/dist/bitcoin/coinselect2/index.d.ts +3 -2
- package/dist/bitcoin/coinselect2/index.js +2 -2
- package/dist/bitcoin/coinselect2/utils.d.ts +7 -2
- package/dist/bitcoin/coinselect2/utils.js +45 -10
- package/dist/bitcoin/wallet/BitcoinWallet.d.ts +8 -25
- package/dist/bitcoin/wallet/BitcoinWallet.js +31 -18
- package/dist/bitcoin/wallet/IBitcoinWallet.d.ts +40 -2
- package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.d.ts +7 -2
- package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.js +10 -4
- package/dist/events/UnifiedSwapEventListener.d.ts +4 -3
- package/dist/events/UnifiedSwapEventListener.js +8 -2
- package/dist/http/HttpUtils.d.ts +4 -2
- package/dist/http/HttpUtils.js +10 -4
- package/dist/http/paramcoders/client/StreamingFetchPromise.d.ts +2 -1
- package/dist/http/paramcoders/client/StreamingFetchPromise.js +3 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/intermediaries/IntermediaryDiscovery.d.ts +7 -2
- package/dist/intermediaries/IntermediaryDiscovery.js +4 -4
- package/dist/intermediaries/apis/IntermediaryAPI.d.ts +182 -15
- package/dist/intermediaries/apis/IntermediaryAPI.js +192 -31
- package/dist/intermediaries/auth/SignedKeyBasedAuth.d.ts +14 -0
- package/dist/intermediaries/auth/SignedKeyBasedAuth.js +68 -0
- package/dist/storage/IUnifiedStorage.d.ts +45 -3
- package/dist/storage/UnifiedSwapStorage.d.ts +8 -2
- package/dist/storage/UnifiedSwapStorage.js +46 -8
- package/dist/swapper/Swapper.d.ts +77 -4
- package/dist/swapper/Swapper.js +117 -25
- package/dist/swapper/SwapperUtils.d.ts +18 -2
- package/dist/swapper/SwapperUtils.js +39 -1
- package/dist/swaps/ISwap.d.ts +70 -9
- package/dist/swaps/ISwap.js +28 -6
- package/dist/swaps/ISwapWrapper.d.ts +11 -1
- package/dist/swaps/ISwapWrapper.js +23 -3
- package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +1 -1
- package/dist/swaps/escrow_swaps/IEscrowSwap.js +4 -2
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +2 -1
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +2 -2
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +3 -1
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +3 -2
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +47 -31
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +201 -67
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +3 -1
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +6 -6
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +82 -15
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +304 -98
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +3 -1
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +6 -6
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +75 -42
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +424 -87
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +3 -1
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +7 -7
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +54 -11
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +214 -41
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +2 -1
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +7 -8
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +3 -1
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +5 -5
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +85 -22
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +299 -56
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +41 -7
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +183 -58
- package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +53 -12
- package/dist/swaps/trusted/ln/LnForGasSwap.js +163 -49
- package/dist/swaps/trusted/ln/LnForGasWrapper.js +1 -2
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +14 -13
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +30 -47
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +3 -1
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +4 -4
- package/dist/types/SwapExecutionAction.d.ts +141 -34
- package/dist/types/SwapExecutionAction.js +104 -0
- package/dist/types/SwapExecutionStep.d.ts +144 -0
- package/dist/types/SwapExecutionStep.js +87 -0
- package/dist/types/TokenAmount.d.ts +6 -0
- package/dist/types/TokenAmount.js +26 -1
- package/dist/utils/BitcoinUtils.d.ts +4 -0
- package/dist/utils/BitcoinUtils.js +73 -1
- package/dist/utils/BitcoinWalletUtils.d.ts +2 -2
- package/dist/utils/Utils.d.ts +3 -1
- package/dist/utils/Utils.js +7 -1
- package/package.json +7 -4
- package/src/api/ApiEndpoints.ts +427 -0
- package/src/api/ApiParser.ts +138 -0
- package/src/api/ApiTypes.ts +229 -0
- package/src/api/SerializedAction.ts +97 -0
- package/src/api/SwapperApi.ts +545 -0
- package/src/api/index.ts +5 -0
- package/src/bitcoin/coinselect2/accumulative.ts +2 -1
- package/src/bitcoin/coinselect2/blackjack.ts +2 -1
- package/src/bitcoin/coinselect2/index.ts +5 -4
- package/src/bitcoin/coinselect2/utils.ts +55 -14
- package/src/bitcoin/wallet/BitcoinWallet.ts +69 -57
- package/src/bitcoin/wallet/IBitcoinWallet.ts +44 -3
- package/src/bitcoin/wallet/SingleAddressBitcoinWallet.ts +12 -4
- package/src/events/UnifiedSwapEventListener.ts +11 -3
- package/src/http/HttpUtils.ts +10 -4
- package/src/http/paramcoders/client/StreamingFetchPromise.ts +4 -2
- package/src/index.ts +1 -0
- package/src/intermediaries/IntermediaryDiscovery.ts +9 -2
- package/src/intermediaries/apis/IntermediaryAPI.ts +335 -35
- package/src/intermediaries/auth/SignedKeyBasedAuth.ts +69 -0
- package/src/storage/IUnifiedStorage.ts +45 -4
- package/src/storage/UnifiedSwapStorage.ts +42 -8
- package/src/swapper/Swapper.ts +165 -24
- package/src/swapper/SwapperUtils.ts +42 -2
- package/src/swaps/ISwap.ts +88 -16
- package/src/swaps/ISwapWrapper.ts +28 -3
- package/src/swaps/escrow_swaps/IEscrowSwap.ts +5 -3
- package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +3 -1
- package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +4 -1
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +264 -67
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +6 -4
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +390 -89
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +6 -4
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +548 -94
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +7 -5
- package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +276 -45
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +7 -6
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +5 -3
- package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +413 -64
- package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +239 -61
- package/src/swaps/trusted/ln/LnForGasSwap.ts +211 -47
- package/src/swaps/trusted/ln/LnForGasWrapper.ts +1 -2
- package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +32 -51
- package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +5 -3
- package/src/types/SwapExecutionAction.ts +266 -43
- package/src/types/SwapExecutionStep.ts +224 -0
- package/src/types/TokenAmount.ts +36 -2
- package/src/utils/BitcoinUtils.ts +73 -0
- package/src/utils/BitcoinWalletUtils.ts +2 -2
- package/src/utils/Utils.ts +10 -1
- package/src/intermediaries/apis/TrustedIntermediaryAPI.ts +0 -258
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {isISwapInit, ISwap, ISwapInit} from "../ISwap";
|
|
2
2
|
import {
|
|
3
|
+
BtcTx,
|
|
3
4
|
BtcTxWithBlockheight,
|
|
4
5
|
ChainType,
|
|
5
6
|
isAbstractSigner,
|
|
@@ -16,7 +17,7 @@ import {parsePsbtTransaction, toCoinselectAddressType, toOutputScript} from "../
|
|
|
16
17
|
import {getInputType, Transaction} from "@scure/btc-signer";
|
|
17
18
|
import {Buffer} from "buffer";
|
|
18
19
|
import {Fee} from "../../types/fees/Fee";
|
|
19
|
-
import {IBitcoinWallet, isIBitcoinWallet} from "../../bitcoin/wallet/IBitcoinWallet";
|
|
20
|
+
import {BitcoinWalletUtxo, IBitcoinWallet, isIBitcoinWallet} from "../../bitcoin/wallet/IBitcoinWallet";
|
|
20
21
|
import {IntermediaryAPI} from "../../intermediaries/apis/IntermediaryAPI";
|
|
21
22
|
import {IBTCWalletSwap} from "../IBTCWalletSwap";
|
|
22
23
|
import {ISwapWithGasDrop} from "../ISwapWithGasDrop";
|
|
@@ -38,7 +39,16 @@ import {
|
|
|
38
39
|
serializePriceInfoType
|
|
39
40
|
} from "../../types/PriceInfoType";
|
|
40
41
|
import {toBitcoinWallet} from "../../utils/BitcoinWalletUtils";
|
|
41
|
-
import {
|
|
42
|
+
import {
|
|
43
|
+
SwapExecutionAction,
|
|
44
|
+
SwapExecutionActionSignPSBT, SwapExecutionActionSignSmartChainTx,
|
|
45
|
+
SwapExecutionActionWait
|
|
46
|
+
} from "../../types/SwapExecutionAction";
|
|
47
|
+
import {
|
|
48
|
+
SwapExecutionStepPayment,
|
|
49
|
+
SwapExecutionStepSettlement
|
|
50
|
+
} from "../../types/SwapExecutionStep";
|
|
51
|
+
import {SwapStateInfo} from "../../types/SwapStateInfo";
|
|
42
52
|
|
|
43
53
|
/**
|
|
44
54
|
* State enum for SPV vault (UTXO-controlled vault) based swaps
|
|
@@ -499,7 +509,7 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
499
509
|
* @inheritDoc
|
|
500
510
|
*/
|
|
501
511
|
isFinished(): boolean {
|
|
502
|
-
return this.
|
|
512
|
+
return this.isSuccessful() || this.isFailed() || this.isQuoteExpired();
|
|
503
513
|
}
|
|
504
514
|
|
|
505
515
|
/**
|
|
@@ -822,13 +832,15 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
822
832
|
/**
|
|
823
833
|
* Returns the raw PSBT (not funded), the wallet should fund the PSBT (add its inputs) and importantly **set the nSequence field of the
|
|
824
834
|
* 2nd input** (input 1 - indexing from 0) to the value returned in `in1sequence`, sign the PSBT and then pass
|
|
825
|
-
* it back to the swap with {@link submitPsbt} function.
|
|
835
|
+
* it back to the swap with {@link submitPsbt} function. The transaction should use at least the returned `feeRate`
|
|
836
|
+
* sats/vB as the transaction fee.
|
|
826
837
|
*/
|
|
827
838
|
async getPsbt(): Promise<{
|
|
828
839
|
psbt: Transaction,
|
|
829
840
|
psbtHex: string,
|
|
830
841
|
psbtBase64: string,
|
|
831
|
-
in1sequence: number
|
|
842
|
+
in1sequence: number,
|
|
843
|
+
feeRate: number
|
|
832
844
|
}> {
|
|
833
845
|
const res = await this.getTransactionDetails();
|
|
834
846
|
const psbt = new Transaction({
|
|
@@ -862,7 +874,8 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
862
874
|
psbt,
|
|
863
875
|
psbtHex: serializedPsbt.toString("hex"),
|
|
864
876
|
psbtBase64: serializedPsbt.toString("base64"),
|
|
865
|
-
in1sequence: res.in1sequence
|
|
877
|
+
in1sequence: res.in1sequence,
|
|
878
|
+
feeRate: this.minimumBtcFeeRate
|
|
866
879
|
};
|
|
867
880
|
}
|
|
868
881
|
|
|
@@ -877,16 +890,23 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
877
890
|
* @param _bitcoinWallet Sender's bitcoin wallet
|
|
878
891
|
* @param feeRate Optional fee rate in sats/vB for the transaction
|
|
879
892
|
* @param additionalOutputs additional outputs to add to the PSBT - can be used to collect fees from users
|
|
893
|
+
* @param utxos Pre-fetched list of UTXOs to spend from
|
|
894
|
+
* @param spendFully Instructs the wallet to spend all the passed UTXOs in the transaction without creating any
|
|
895
|
+
* change output, if the `feeRate` is passed, it will also enforce that the feeRate in sats/vB for the resulting
|
|
896
|
+
* transaction is not more than 50% and 10 sats/vB larger (considering also the CPFP adjustments)
|
|
880
897
|
*/
|
|
881
898
|
async getFundedPsbt(
|
|
882
899
|
_bitcoinWallet: IBitcoinWallet | MinimalBitcoinWalletInterface,
|
|
883
900
|
feeRate?: number,
|
|
884
|
-
additionalOutputs?: ({amount: bigint, outputScript: Uint8Array} | {amount: bigint, address: string})[]
|
|
901
|
+
additionalOutputs?: ({amount: bigint, outputScript: Uint8Array} | {amount: bigint, address: string})[],
|
|
902
|
+
utxos?: BitcoinWalletUtxo[],
|
|
903
|
+
spendFully?: boolean
|
|
885
904
|
): Promise<{
|
|
886
905
|
psbt: Transaction,
|
|
887
906
|
psbtHex: string,
|
|
888
907
|
psbtBase64: string,
|
|
889
|
-
signInputs: number[]
|
|
908
|
+
signInputs: number[],
|
|
909
|
+
feeRate: number
|
|
890
910
|
}> {
|
|
891
911
|
const bitcoinWallet: IBitcoinWallet = toBitcoinWallet(_bitcoinWallet, this.wrapper._btcRpc, this.wrapper._options.bitcoinNetwork);
|
|
892
912
|
if(feeRate!=null) {
|
|
@@ -901,7 +921,7 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
901
921
|
script: (output as {outputScript: Uint8Array}).outputScript ?? toOutputScript(this.wrapper._options.bitcoinNetwork, (output as {address: string}).address)
|
|
902
922
|
});
|
|
903
923
|
});
|
|
904
|
-
psbt = await bitcoinWallet.fundPsbt(psbt, feeRate);
|
|
924
|
+
psbt = await bitcoinWallet.fundPsbt(psbt, feeRate, utxos, spendFully);
|
|
905
925
|
psbt.updateInput(1, {sequence: in1sequence});
|
|
906
926
|
//Sign every input except the first one
|
|
907
927
|
const signInputs: number[] = [];
|
|
@@ -913,7 +933,8 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
913
933
|
psbt,
|
|
914
934
|
psbtHex: serializedPsbt.toString("hex"),
|
|
915
935
|
psbtBase64: serializedPsbt.toString("base64"),
|
|
916
|
-
signInputs
|
|
936
|
+
signInputs,
|
|
937
|
+
feeRate
|
|
917
938
|
};
|
|
918
939
|
}
|
|
919
940
|
|
|
@@ -994,7 +1015,7 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
994
1015
|
await this._saveAndEmit(SpvFromBTCSwapState.SIGNED);
|
|
995
1016
|
|
|
996
1017
|
try {
|
|
997
|
-
await
|
|
1018
|
+
await this.wrapper._lpApi.initSpvFromBTC(
|
|
998
1019
|
this.chainIdentifier,
|
|
999
1020
|
this.url,
|
|
1000
1021
|
{
|
|
@@ -1024,8 +1045,13 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
1024
1045
|
/**
|
|
1025
1046
|
* @inheritDoc
|
|
1026
1047
|
*/
|
|
1027
|
-
async sendBitcoinTransaction(
|
|
1028
|
-
|
|
1048
|
+
async sendBitcoinTransaction(
|
|
1049
|
+
wallet: IBitcoinWallet | MinimalBitcoinWalletInterfaceWithSigner,
|
|
1050
|
+
feeRate?: number,
|
|
1051
|
+
utxos?: BitcoinWalletUtxo[],
|
|
1052
|
+
spendFully?: boolean
|
|
1053
|
+
): Promise<string> {
|
|
1054
|
+
const {psbt, psbtBase64, psbtHex, signInputs} = await this.getFundedPsbt(wallet, feeRate, undefined, utxos, spendFully);
|
|
1029
1055
|
let signedPsbt: Transaction | string;
|
|
1030
1056
|
if(isIBitcoinWallet(wallet)) {
|
|
1031
1057
|
signedPsbt = await wallet.signPsbt(psbt, signInputs);
|
|
@@ -1060,7 +1086,9 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
1060
1086
|
feeRate?: number,
|
|
1061
1087
|
abortSignal?: AbortSignal,
|
|
1062
1088
|
btcTxCheckIntervalSeconds?: number,
|
|
1063
|
-
maxWaitTillAutomaticSettlementSeconds?: number
|
|
1089
|
+
maxWaitTillAutomaticSettlementSeconds?: number,
|
|
1090
|
+
utxos?: BitcoinWalletUtxo[],
|
|
1091
|
+
spendFully?: boolean
|
|
1064
1092
|
}
|
|
1065
1093
|
): Promise<boolean> {
|
|
1066
1094
|
if(this._state===SpvFromBTCSwapState.CLOSED) throw new Error("Swap encountered a catastrophic failure!");
|
|
@@ -1070,7 +1098,7 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
1070
1098
|
if(this._state===SpvFromBTCSwapState.CLAIMED || this._state===SpvFromBTCSwapState.FRONTED) throw new Error("Swap already settled or fronted!");
|
|
1071
1099
|
|
|
1072
1100
|
if(this._state===SpvFromBTCSwapState.CREATED) {
|
|
1073
|
-
const txId = await this.sendBitcoinTransaction(wallet, options?.feeRate);
|
|
1101
|
+
const txId = await this.sendBitcoinTransaction(wallet, options?.feeRate, options?.utxos, options?.spendFully);
|
|
1074
1102
|
if(callbacks?.onSourceTransactionSent!=null) callbacks.onSourceTransactionSent(txId);
|
|
1075
1103
|
}
|
|
1076
1104
|
if(this._state===SpvFromBTCSwapState.POSTED || this._state===SpvFromBTCSwapState.BROADCASTED) {
|
|
@@ -1089,39 +1117,329 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
1089
1117
|
}
|
|
1090
1118
|
|
|
1091
1119
|
/**
|
|
1092
|
-
* @
|
|
1093
|
-
*
|
|
1094
|
-
* @param options.bitcoinFeeRate Optional fee rate to use for the created Bitcoin transaction
|
|
1095
|
-
* @param options.bitcoinWallet Optional bitcoin wallet address specification to return a funded PSBT,
|
|
1096
|
-
* if not provided a raw PSBT is returned instead which necessitates the implementor to manually add
|
|
1097
|
-
* inputs to the bitcoin transaction and **set the nSequence field of the 2nd input** (input 1 -
|
|
1098
|
-
* indexing from 0) to the value returned in `in1sequence`
|
|
1120
|
+
* @internal
|
|
1099
1121
|
*/
|
|
1100
|
-
async
|
|
1122
|
+
protected async _getExecutionStatus(options?: {
|
|
1101
1123
|
bitcoinFeeRate?: number,
|
|
1102
1124
|
bitcoinWallet?: MinimalBitcoinWalletInterface,
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1125
|
+
manualSettlementSmartChainSigner?: string | T["Signer"] | T["NativeSigner"],
|
|
1126
|
+
maxWaitTillAutomaticSettlementSeconds?: number
|
|
1127
|
+
}) {
|
|
1128
|
+
const state = this._state;
|
|
1129
|
+
const now = Date.now();
|
|
1130
|
+
|
|
1131
|
+
let confirmations: {
|
|
1132
|
+
current: number,
|
|
1133
|
+
target: number,
|
|
1134
|
+
etaSeconds: number
|
|
1135
|
+
} | undefined;
|
|
1136
|
+
|
|
1137
|
+
let bitcoinPaymentStatus: SwapExecutionStepPayment<"BITCOIN">["status"] = "inactive";
|
|
1138
|
+
let destinationSettlementStatus: SwapExecutionStepSettlement<T["ChainId"], "awaiting_automatic" | "awaiting_manual">["status"] = "inactive";
|
|
1139
|
+
let buildCurrentAction: (actionOptions?: {
|
|
1140
|
+
bitcoinFeeRate?: number,
|
|
1141
|
+
bitcoinWallet?: MinimalBitcoinWalletInterface,
|
|
1142
|
+
manualSettlementSmartChainSigner?: string | T["Signer"] | T["NativeSigner"],
|
|
1143
|
+
maxWaitTillAutomaticSettlementSeconds?: number
|
|
1144
|
+
}) => Promise<
|
|
1145
|
+
SwapExecutionActionSignPSBT |
|
|
1146
|
+
SwapExecutionActionWait<"BITCOIN_CONFS" | "SETTLEMENT"> |
|
|
1147
|
+
SwapExecutionActionSignSmartChainTx<T> |
|
|
1148
|
+
undefined
|
|
1149
|
+
> = async () => undefined;
|
|
1150
|
+
|
|
1151
|
+
switch(state) {
|
|
1152
|
+
case SpvFromBTCSwapState.QUOTE_EXPIRED:
|
|
1153
|
+
case SpvFromBTCSwapState.DECLINED:
|
|
1154
|
+
case SpvFromBTCSwapState.FAILED:
|
|
1155
|
+
bitcoinPaymentStatus = "expired";
|
|
1156
|
+
break;
|
|
1157
|
+
case SpvFromBTCSwapState.CREATED: {
|
|
1158
|
+
const quoteValid = await this._verifyQuoteValid();
|
|
1159
|
+
bitcoinPaymentStatus = quoteValid ? "awaiting" : "soft_expired";
|
|
1160
|
+
if(quoteValid) {
|
|
1161
|
+
buildCurrentAction = this._buildDepositPsbtAction.bind(this);
|
|
1162
|
+
}
|
|
1163
|
+
break;
|
|
1164
|
+
}
|
|
1165
|
+
case SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED:
|
|
1166
|
+
case SpvFromBTCSwapState.SIGNED:
|
|
1167
|
+
case SpvFromBTCSwapState.POSTED:
|
|
1168
|
+
case SpvFromBTCSwapState.BROADCASTED:
|
|
1169
|
+
case SpvFromBTCSwapState.FRONTED: {
|
|
1170
|
+
const bitcoinPayment = await this.getBitcoinPayment();
|
|
1171
|
+
let bitcoinConfirmationDelay = -1;
|
|
1172
|
+
let knownBitcoinPaymentStatus: "received" | "confirmed" | undefined;
|
|
1173
|
+
if(bitcoinPayment!=null) {
|
|
1174
|
+
if(bitcoinPayment.confirmations >= bitcoinPayment.targetConfirmations) {
|
|
1175
|
+
knownBitcoinPaymentStatus = "confirmed";
|
|
1176
|
+
} else {
|
|
1177
|
+
const result = await this.wrapper._btcRpc.getConfirmationDelay(
|
|
1178
|
+
bitcoinPayment.btcTx,
|
|
1179
|
+
bitcoinPayment.targetConfirmations
|
|
1180
|
+
);
|
|
1181
|
+
confirmations = {
|
|
1182
|
+
current: bitcoinPayment.confirmations,
|
|
1183
|
+
target: bitcoinPayment.targetConfirmations,
|
|
1184
|
+
etaSeconds: result ?? -1
|
|
1185
|
+
};
|
|
1186
|
+
knownBitcoinPaymentStatus = "received";
|
|
1187
|
+
bitcoinConfirmationDelay = result ?? -1;
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
if(state===SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED)
|
|
1191
|
+
bitcoinPaymentStatus = knownBitcoinPaymentStatus ?? "soft_expired";
|
|
1192
|
+
if(state===SpvFromBTCSwapState.POSTED || state===SpvFromBTCSwapState.SIGNED)
|
|
1193
|
+
bitcoinPaymentStatus = knownBitcoinPaymentStatus ?? "awaiting";
|
|
1194
|
+
if(state===SpvFromBTCSwapState.BROADCASTED)
|
|
1195
|
+
bitcoinPaymentStatus = knownBitcoinPaymentStatus ?? "received";
|
|
1196
|
+
destinationSettlementStatus = "inactive";
|
|
1197
|
+
|
|
1198
|
+
if(state===SpvFromBTCSwapState.FRONTED) {
|
|
1199
|
+
bitcoinPaymentStatus = knownBitcoinPaymentStatus ?? "received";
|
|
1200
|
+
destinationSettlementStatus = "settled";
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
if(
|
|
1204
|
+
state===SpvFromBTCSwapState.SIGNED ||
|
|
1205
|
+
state===SpvFromBTCSwapState.POSTED ||
|
|
1206
|
+
state===SpvFromBTCSwapState.BROADCASTED
|
|
1207
|
+
) {
|
|
1208
|
+
buildCurrentAction = this._buildWaitBitcoinConfirmationsAction.bind(this, bitcoinConfirmationDelay);
|
|
1209
|
+
}
|
|
1210
|
+
break;
|
|
1211
|
+
}
|
|
1212
|
+
case SpvFromBTCSwapState.BTC_TX_CONFIRMED:
|
|
1213
|
+
bitcoinPaymentStatus = "confirmed";
|
|
1214
|
+
if(
|
|
1215
|
+
this.btcTxConfirmedAt==null ||
|
|
1216
|
+
options?.maxWaitTillAutomaticSettlementSeconds===0 ||
|
|
1217
|
+
(now - this.btcTxConfirmedAt) > (options?.maxWaitTillAutomaticSettlementSeconds ?? 60)*1000
|
|
1218
|
+
) {
|
|
1219
|
+
destinationSettlementStatus = "awaiting_manual";
|
|
1220
|
+
buildCurrentAction = this._buildClaimSmartChainTxAction.bind(this);
|
|
1221
|
+
} else {
|
|
1222
|
+
destinationSettlementStatus = "awaiting_automatic";
|
|
1223
|
+
buildCurrentAction = this._buildWaitSettlementAction.bind(this, options?.maxWaitTillAutomaticSettlementSeconds);
|
|
1224
|
+
}
|
|
1225
|
+
break;
|
|
1226
|
+
case SpvFromBTCSwapState.CLAIMED:
|
|
1227
|
+
bitcoinPaymentStatus = "confirmed";
|
|
1228
|
+
destinationSettlementStatus = "settled";
|
|
1229
|
+
break;
|
|
1230
|
+
case SpvFromBTCSwapState.CLOSED:
|
|
1231
|
+
bitcoinPaymentStatus = "confirmed";
|
|
1232
|
+
destinationSettlementStatus = "expired";
|
|
1233
|
+
break;
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
if(bitcoinPaymentStatus==="confirmed") {
|
|
1237
|
+
confirmations = {
|
|
1238
|
+
current: this.getRequiredConfirmationsCount(),
|
|
1239
|
+
target: this.getRequiredConfirmationsCount(),
|
|
1240
|
+
etaSeconds: 0
|
|
1241
|
+
};
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
return {
|
|
1245
|
+
steps: [
|
|
1109
1246
|
{
|
|
1110
|
-
|
|
1111
|
-
|
|
1247
|
+
type: "Payment",
|
|
1248
|
+
side: "source",
|
|
1112
1249
|
chain: "BITCOIN",
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1250
|
+
title: "Bitcoin payment",
|
|
1251
|
+
description: "Sign and submit the Bitcoin swap PSBT, then wait for the bitcoin transaction to confirm",
|
|
1252
|
+
status: bitcoinPaymentStatus,
|
|
1253
|
+
confirmations,
|
|
1254
|
+
initTxId: this._data?.btcTx?.txid,
|
|
1255
|
+
settleTxId: bitcoinPaymentStatus==="confirmed" ? this._data?.btcTx?.txid : undefined
|
|
1256
|
+
},
|
|
1257
|
+
{
|
|
1258
|
+
type: "Settlement",
|
|
1259
|
+
side: "destination",
|
|
1260
|
+
chain: this.chainIdentifier,
|
|
1261
|
+
title: "Destination settlement",
|
|
1262
|
+
description: `Wait for automatic settlement on the ${this.chainIdentifier} side, or settle manually if it takes too long`,
|
|
1263
|
+
status: destinationSettlementStatus,
|
|
1264
|
+
initTxId: this._frontTxId ?? this._claimTxId,
|
|
1265
|
+
settleTxId: this._frontTxId ?? this._claimTxId
|
|
1266
|
+
}
|
|
1267
|
+
] as [
|
|
1268
|
+
SwapExecutionStepPayment<"BITCOIN">,
|
|
1269
|
+
SwapExecutionStepSettlement<T["ChainId"], "awaiting_automatic" | "awaiting_manual">
|
|
1270
|
+
],
|
|
1271
|
+
buildCurrentAction,
|
|
1272
|
+
state
|
|
1273
|
+
};
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
/**
|
|
1277
|
+
* @inheritDoc
|
|
1278
|
+
* @internal
|
|
1279
|
+
*/
|
|
1280
|
+
async _submitExecutionTransactions(txs: (T["SignedTXType"] | Transaction | string)[], abortSignal?: AbortSignal, requiredStates?: SpvFromBTCSwapState[], idempotent?: boolean): Promise<string[]> {
|
|
1281
|
+
if(txs.length===0) throw new Error("Need to submit at least 1 transaction in the array, submitted empty array of transactions!");
|
|
1282
|
+
|
|
1283
|
+
// Handle idempotent calls
|
|
1284
|
+
if(idempotent) {
|
|
1285
|
+
let idempotencyTriggered = false;
|
|
1286
|
+
const txIds: string[] = [];
|
|
1287
|
+
for(let tx of txs) {
|
|
1288
|
+
let parsedTx: T["SignedTXType"] | Transaction | undefined;
|
|
1289
|
+
if(typeof(tx)==="string") {
|
|
1290
|
+
try {
|
|
1291
|
+
parsedTx = await this.wrapper._chain.deserializeSignedTx(tx);
|
|
1292
|
+
} catch (e) {}
|
|
1293
|
+
try {
|
|
1294
|
+
parsedTx = parsePsbtTransaction(tx);
|
|
1295
|
+
} catch (e) {}
|
|
1296
|
+
} else {
|
|
1297
|
+
parsedTx = tx;
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
if(parsedTx==null) {
|
|
1301
|
+
this.logger.debug("_submitExecutionTransactions(): Failed to parse provided execution transaction: ", tx);
|
|
1302
|
+
continue;
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
if(parsedTx instanceof Transaction) {
|
|
1306
|
+
// Bitcoin tx
|
|
1307
|
+
const btcTx = await this.wrapper._btcRpc.parseTransaction(Buffer.from(parsedTx.toBytes(true)).toString("hex"));
|
|
1308
|
+
if(btcTx.txid===this._data?.getTxId()) {
|
|
1309
|
+
if(this._state!==SpvFromBTCSwapState.SIGNED && this._state!==SpvFromBTCSwapState.DECLINED)
|
|
1310
|
+
idempotencyTriggered = true;
|
|
1311
|
+
}
|
|
1312
|
+
txIds.push(btcTx.txid);
|
|
1313
|
+
} else {
|
|
1314
|
+
// SC tx
|
|
1315
|
+
if(this.wrapper._chain.getTxId!=null) {
|
|
1316
|
+
const txId = await this.wrapper._chain.getTxId(parsedTx);
|
|
1317
|
+
if(this._claimTxId===txId) idempotencyTriggered = true;
|
|
1318
|
+
txIds.push(txId);
|
|
1319
|
+
}
|
|
1118
1320
|
}
|
|
1119
|
-
|
|
1321
|
+
}
|
|
1322
|
+
if(idempotencyTriggered) return txIds;
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
if(requiredStates!=null && !requiredStates.includes(this._state)) throw new Error("Swap state has changed before transactions were submitted!");
|
|
1326
|
+
|
|
1327
|
+
if(this._state===SpvFromBTCSwapState.CREATED || this._state===SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED) {
|
|
1328
|
+
let psbt: string | Transaction;
|
|
1329
|
+
if(txs.length!==1) throw new Error("Need to submit exactly 1 signed PSBT!");
|
|
1330
|
+
if(typeof(txs[0])!=="string" && !(txs[0] instanceof Transaction))
|
|
1331
|
+
throw new Error("Must submit a valid PSBT as hex/base64 string or `@scure/btc-signer` Transaction object!");
|
|
1332
|
+
psbt = txs[0];
|
|
1333
|
+
return [await this.submitPsbt(psbt)];
|
|
1120
1334
|
}
|
|
1121
1335
|
|
|
1122
|
-
|
|
1336
|
+
if(this._state===SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
|
|
1337
|
+
const parsedTxs: T["SignedTXType"][] = [];
|
|
1338
|
+
for(let tx of txs) {
|
|
1339
|
+
parsedTxs.push(typeof(tx)==="string" ? await this.wrapper._chain.deserializeSignedTx(tx) : tx);
|
|
1340
|
+
}
|
|
1341
|
+
const txIds = await this.wrapper._chain.sendSignedAndConfirm(parsedTxs, true, abortSignal, false);
|
|
1342
|
+
await this.waitTillClaimed(undefined, abortSignal);
|
|
1343
|
+
return txIds;
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
throw new Error("Invalid swap state for transaction submission!");
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
/**
|
|
1350
|
+
* @internal
|
|
1351
|
+
*/
|
|
1352
|
+
private async _buildDepositPsbtAction(actionOptions?: {
|
|
1353
|
+
bitcoinFeeRate?: number,
|
|
1354
|
+
bitcoinWallet?: MinimalBitcoinWalletInterface
|
|
1355
|
+
}): Promise<SwapExecutionActionSignPSBT> {
|
|
1356
|
+
return {
|
|
1357
|
+
type: "SignPSBT",
|
|
1358
|
+
name: "Deposit on Bitcoin",
|
|
1359
|
+
description: "Send funds to the bitcoin swap address",
|
|
1360
|
+
chain: "BITCOIN",
|
|
1361
|
+
txs: [
|
|
1362
|
+
actionOptions?.bitcoinWallet==null
|
|
1363
|
+
? {...await this.getPsbt(), type: "RAW_PSBT"}
|
|
1364
|
+
: {...await this.getFundedPsbt(actionOptions.bitcoinWallet, actionOptions?.bitcoinFeeRate), type: "FUNDED_PSBT"}
|
|
1365
|
+
],
|
|
1366
|
+
submitPsbt: async (signedPsbt: string | Transaction | (string | Transaction)[], idempotent) => {
|
|
1367
|
+
return this._submitExecutionTransactions(
|
|
1368
|
+
Array.isArray(signedPsbt) ? signedPsbt : [signedPsbt],
|
|
1369
|
+
undefined,
|
|
1370
|
+
[SpvFromBTCSwapState.CREATED, SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED],
|
|
1371
|
+
idempotent
|
|
1372
|
+
);
|
|
1373
|
+
}
|
|
1374
|
+
} as SwapExecutionActionSignPSBT;
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
/**
|
|
1378
|
+
* @internal
|
|
1379
|
+
*/
|
|
1380
|
+
private async _buildWaitBitcoinConfirmationsAction(confirmationDelay: number): Promise<SwapExecutionActionWait<"BITCOIN_CONFS">> {
|
|
1381
|
+
return {
|
|
1382
|
+
type: "Wait",
|
|
1383
|
+
name: "Bitcoin confirmations",
|
|
1384
|
+
description: "Wait for bitcoin transaction to confirm",
|
|
1385
|
+
pollTimeSeconds: 10,
|
|
1386
|
+
expectedTimeSeconds: confirmationDelay===-1 ? -1 : Math.floor(confirmationDelay/1000),
|
|
1387
|
+
wait: async (
|
|
1388
|
+
maxWaitTimeSeconds?: number, pollIntervalSeconds?: number, abortSignal?: AbortSignal,
|
|
1389
|
+
btcConfirmationsCallback?: (txId?: string, confirmations?: number, targetConfirmations?: number, txEtaMs?: number) => void
|
|
1390
|
+
) => {
|
|
1391
|
+
const abortController = extendAbortController(
|
|
1392
|
+
abortSignal, maxWaitTimeSeconds, "Timed out waiting for bitcoin transaction"
|
|
1393
|
+
);
|
|
1394
|
+
await this.waitForBitcoinTransaction(btcConfirmationsCallback, pollIntervalSeconds, abortController.signal);
|
|
1395
|
+
}
|
|
1396
|
+
} as SwapExecutionActionWait<"BITCOIN_CONFS">;
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
/**
|
|
1400
|
+
* @internal
|
|
1401
|
+
*/
|
|
1402
|
+
private async _buildWaitSettlementAction(maxWaitTillAutomaticSettlementSeconds?: number): Promise<SwapExecutionActionWait<"SETTLEMENT">> {
|
|
1403
|
+
return {
|
|
1404
|
+
type: "Wait",
|
|
1405
|
+
name: "Automatic settlement",
|
|
1406
|
+
description: "Wait for bitcoin transaction to confirm",
|
|
1407
|
+
pollTimeSeconds: 5,
|
|
1408
|
+
expectedTimeSeconds: 10,
|
|
1409
|
+
wait: async (
|
|
1410
|
+
maxWaitTimeSeconds?: number, pollIntervalSeconds?: number, abortSignal?: AbortSignal
|
|
1411
|
+
) => {
|
|
1412
|
+
await this.waitTillClaimedOrFronted(maxWaitTimeSeconds ?? maxWaitTillAutomaticSettlementSeconds ?? 60, abortSignal, pollIntervalSeconds);
|
|
1413
|
+
}
|
|
1414
|
+
} as SwapExecutionActionWait<"SETTLEMENT">;
|
|
1123
1415
|
}
|
|
1124
1416
|
|
|
1417
|
+
/**
|
|
1418
|
+
* @internal
|
|
1419
|
+
*/
|
|
1420
|
+
private async _buildClaimSmartChainTxAction(actionOptions?: {
|
|
1421
|
+
manualSettlementSmartChainSigner?: string | T["Signer"] | T["NativeSigner"]
|
|
1422
|
+
}): Promise<SwapExecutionActionSignSmartChainTx<T>> {
|
|
1423
|
+
const signerAddress =
|
|
1424
|
+
await this.wrapper._getSignerAddress(actionOptions?.manualSettlementSmartChainSigner);
|
|
1425
|
+
|
|
1426
|
+
return {
|
|
1427
|
+
type: "SignSmartChainTransaction",
|
|
1428
|
+
name: "Settle manually",
|
|
1429
|
+
description: "Manually settle the swap on the destination smart chain",
|
|
1430
|
+
chain: this.chainIdentifier,
|
|
1431
|
+
txs: await this.prepareTransactions(this.txsClaim(actionOptions?.manualSettlementSmartChainSigner)),
|
|
1432
|
+
submitTransactions: async (txs: (T["SignedTXType"] | string)[], abortSignal?: AbortSignal, idempotent?: boolean) => {
|
|
1433
|
+
return this._submitExecutionTransactions(
|
|
1434
|
+
txs,
|
|
1435
|
+
abortSignal,
|
|
1436
|
+
[SpvFromBTCSwapState.BTC_TX_CONFIRMED],
|
|
1437
|
+
idempotent
|
|
1438
|
+
);
|
|
1439
|
+
},
|
|
1440
|
+
requiredSigner: signerAddress ?? this._getInitiator()
|
|
1441
|
+
} as SwapExecutionActionSignSmartChainTx<T>;
|
|
1442
|
+
}
|
|
1125
1443
|
|
|
1126
1444
|
/**
|
|
1127
1445
|
* @inheritDoc
|
|
@@ -1135,32 +1453,60 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
1135
1453
|
* @param options.maxWaitTillAutomaticSettlementSeconds Maximum time to wait for an automatic settlement after
|
|
1136
1454
|
* the bitcoin transaction is confirmed (defaults to 60 seconds)
|
|
1137
1455
|
*/
|
|
1138
|
-
async
|
|
1456
|
+
async getExecutionAction(options?: {
|
|
1139
1457
|
bitcoinFeeRate?: number,
|
|
1140
1458
|
bitcoinWallet?: MinimalBitcoinWalletInterface,
|
|
1141
1459
|
manualSettlementSmartChainSigner?: string | T["Signer"] | T["NativeSigner"],
|
|
1142
1460
|
maxWaitTillAutomaticSettlementSeconds?: number
|
|
1143
|
-
}): Promise<
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1461
|
+
}): Promise<
|
|
1462
|
+
SwapExecutionActionSignPSBT |
|
|
1463
|
+
SwapExecutionActionWait<"BITCOIN_CONFS" | "SETTLEMENT"> |
|
|
1464
|
+
SwapExecutionActionSignSmartChainTx<T> |
|
|
1465
|
+
undefined
|
|
1466
|
+
> {
|
|
1467
|
+
const executionStatus = await this._getExecutionStatus(options);
|
|
1468
|
+
return executionStatus.buildCurrentAction(options);
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
/**
|
|
1472
|
+
* @inheritDoc
|
|
1473
|
+
*/
|
|
1474
|
+
async getExecutionStatus(options?: {
|
|
1475
|
+
skipBuildingAction?: boolean,
|
|
1476
|
+
bitcoinFeeRate?: number,
|
|
1477
|
+
bitcoinWallet?: MinimalBitcoinWalletInterface,
|
|
1478
|
+
manualSettlementSmartChainSigner?: string | T["Signer"] | T["NativeSigner"],
|
|
1479
|
+
maxWaitTillAutomaticSettlementSeconds?: number
|
|
1480
|
+
}): Promise<{
|
|
1481
|
+
steps: [
|
|
1482
|
+
SwapExecutionStepPayment<"BITCOIN">,
|
|
1483
|
+
SwapExecutionStepSettlement<T["ChainId"], "awaiting_automatic" | "awaiting_manual">
|
|
1484
|
+
],
|
|
1485
|
+
currentAction:
|
|
1486
|
+
SwapExecutionActionSignPSBT |
|
|
1487
|
+
SwapExecutionActionWait<"BITCOIN_CONFS" | "SETTLEMENT"> |
|
|
1488
|
+
SwapExecutionActionSignSmartChainTx<T> |
|
|
1489
|
+
undefined,
|
|
1490
|
+
stateInfo: SwapStateInfo<SpvFromBTCSwapState>
|
|
1491
|
+
}> {
|
|
1492
|
+
const executionStatus = await this._getExecutionStatus(options);
|
|
1493
|
+
return {
|
|
1494
|
+
steps: executionStatus.steps,
|
|
1495
|
+
currentAction: options?.skipBuildingAction ? undefined : await executionStatus.buildCurrentAction(options),
|
|
1496
|
+
stateInfo: this._getStateInfo(executionStatus.state)
|
|
1497
|
+
};
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
/**
|
|
1501
|
+
* @inheritDoc
|
|
1502
|
+
*/
|
|
1503
|
+
async getExecutionSteps(options?: {
|
|
1504
|
+
maxWaitTillAutomaticSettlementSeconds?: number
|
|
1505
|
+
}): Promise<[
|
|
1506
|
+
SwapExecutionStepPayment<"BITCOIN">,
|
|
1507
|
+
SwapExecutionStepSettlement<T["ChainId"], "awaiting_automatic" | "awaiting_manual">
|
|
1508
|
+
]> {
|
|
1509
|
+
return (await this._getExecutionStatus(options)).steps;
|
|
1164
1510
|
}
|
|
1165
1511
|
|
|
1166
1512
|
|
|
@@ -1175,6 +1521,7 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
1175
1521
|
txId: string,
|
|
1176
1522
|
confirmations: number,
|
|
1177
1523
|
targetConfirmations: number,
|
|
1524
|
+
btcTx: BtcTx,
|
|
1178
1525
|
inputAddresses?: string[]
|
|
1179
1526
|
} | null> {
|
|
1180
1527
|
if(this._data?.btcTx?.txid==null) return null;
|
|
@@ -1186,6 +1533,7 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
1186
1533
|
txId: result.txid,
|
|
1187
1534
|
confirmations: result.confirmations ?? 0,
|
|
1188
1535
|
targetConfirmations: this.vaultRequiredConfirmations,
|
|
1536
|
+
btcTx: result,
|
|
1189
1537
|
inputAddresses: result.inputAddresses
|
|
1190
1538
|
}
|
|
1191
1539
|
}
|
|
@@ -1366,11 +1714,11 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
1366
1714
|
/**
|
|
1367
1715
|
* Periodically checks the chain to see whether the swap was finished (claimed or refunded)
|
|
1368
1716
|
*
|
|
1369
|
-
* @param abortSignal
|
|
1370
1717
|
* @param interval How often to check (in seconds), default to 5s
|
|
1718
|
+
* @param abortSignal
|
|
1371
1719
|
* @internal
|
|
1372
1720
|
*/
|
|
1373
|
-
protected async watchdogWaitTillResult(
|
|
1721
|
+
protected async watchdogWaitTillResult(interval: number = 5, abortSignal?: AbortSignal): Promise<
|
|
1374
1722
|
SpvWithdrawalClaimedState | SpvWithdrawalFrontedState | SpvWithdrawalClosedState
|
|
1375
1723
|
> {
|
|
1376
1724
|
if(this._data==null) throw new Error("Cannot await the result before the btc transaction is sent!");
|
|
@@ -1416,11 +1764,12 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
1416
1764
|
* @param maxWaitTimeSeconds Maximum time in seconds to wait for the swap to be settled (by default
|
|
1417
1765
|
* it waits indefinitely)
|
|
1418
1766
|
* @param abortSignal Abort signal
|
|
1767
|
+
* @param pollIntervalSeconds How often to poll via the watchdog
|
|
1419
1768
|
*
|
|
1420
1769
|
* @returns {boolean} whether the swap was claimed or fronted automatically or not, if the swap was not claimed
|
|
1421
1770
|
* the user can claim manually through the {@link claim} function
|
|
1422
1771
|
*/
|
|
1423
|
-
async waitTillClaimedOrFronted(maxWaitTimeSeconds?: number, abortSignal?: AbortSignal): Promise<boolean> {
|
|
1772
|
+
async waitTillClaimedOrFronted(maxWaitTimeSeconds?: number, abortSignal?: AbortSignal, pollIntervalSeconds?: number): Promise<boolean> {
|
|
1424
1773
|
if(this._state===SpvFromBTCSwapState.CLAIMED || this._state===SpvFromBTCSwapState.FRONTED) return Promise.resolve(true);
|
|
1425
1774
|
|
|
1426
1775
|
const abortController = extendAbortController(abortSignal);
|
|
@@ -1437,7 +1786,7 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
1437
1786
|
let res: number | SpvWithdrawalState;
|
|
1438
1787
|
try {
|
|
1439
1788
|
res = await Promise.race([
|
|
1440
|
-
this.watchdogWaitTillResult(abortController.signal),
|
|
1789
|
+
this.watchdogWaitTillResult(pollIntervalSeconds, abortController.signal),
|
|
1441
1790
|
this.waitTillState(SpvFromBTCSwapState.CLAIMED, "eq", abortController.signal).then(() => 0),
|
|
1442
1791
|
this.waitTillState(SpvFromBTCSwapState.FRONTED, "eq", abortController.signal).then(() => 1),
|
|
1443
1792
|
this.waitTillState(SpvFromBTCSwapState.FAILED, "eq", abortController.signal).then(() => 2),
|