@atomiqlabs/sdk 8.3.6 → 8.4.4

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 (58) hide show
  1. package/dist/bitcoin/wallet/BitcoinWallet.d.ts +3 -2
  2. package/dist/bitcoin/wallet/BitcoinWallet.js +15 -1
  3. package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.d.ts +25 -3
  4. package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.js +51 -2
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.js +1 -0
  7. package/dist/intermediaries/apis/IntermediaryAPI.d.ts +2 -0
  8. package/dist/intermediaries/apis/IntermediaryAPI.js +2 -0
  9. package/dist/swapper/Swapper.d.ts +2 -1
  10. package/dist/swapper/Swapper.js +4 -3
  11. package/dist/swaps/ISwap.d.ts +34 -0
  12. package/dist/swaps/ISwap.js +10 -0
  13. package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +12 -0
  14. package/dist/swaps/escrow_swaps/IEscrowSwap.js +18 -0
  15. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +54 -4
  16. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +72 -8
  17. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +4 -1
  18. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +23 -4
  19. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +89 -3
  20. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +118 -5
  21. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +2 -0
  22. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +30 -4
  23. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +48 -3
  24. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +69 -4
  25. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +40 -2
  26. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +72 -2
  27. package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +51 -1
  28. package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +71 -3
  29. package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +28 -2
  30. package/dist/swaps/trusted/ln/LnForGasSwap.js +39 -1
  31. package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +28 -3
  32. package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +44 -1
  33. package/dist/types/SwapStateInfo.d.ts +5 -0
  34. package/dist/types/SwapStateInfo.js +2 -0
  35. package/dist/types/lnurl/LNURLPay.d.ts +0 -1
  36. package/dist/types/lnurl/LNURLPay.js +0 -1
  37. package/dist/types/lnurl/LNURLWithdraw.d.ts +0 -1
  38. package/dist/types/lnurl/LNURLWithdraw.js +0 -1
  39. package/package.json +3 -1
  40. package/src/bitcoin/wallet/BitcoinWallet.ts +21 -4
  41. package/src/bitcoin/wallet/SingleAddressBitcoinWallet.ts +60 -5
  42. package/src/index.ts +1 -0
  43. package/src/intermediaries/apis/IntermediaryAPI.ts +5 -1
  44. package/src/swapper/Swapper.ts +5 -2
  45. package/src/swaps/ISwap.ts +45 -0
  46. package/src/swaps/escrow_swaps/IEscrowSwap.ts +20 -0
  47. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +86 -11
  48. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +28 -3
  49. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +137 -9
  50. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +35 -4
  51. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +83 -6
  52. package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +77 -4
  53. package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +90 -4
  54. package/src/swaps/trusted/ln/LnForGasSwap.ts +51 -3
  55. package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +58 -3
  56. package/src/types/SwapStateInfo.ts +6 -0
  57. package/src/types/lnurl/LNURLPay.ts +0 -1
  58. package/src/types/lnurl/LNURLWithdraw.ts +0 -1
@@ -87,6 +87,20 @@ var SpvFromBTCSwapState;
87
87
  */
88
88
  SpvFromBTCSwapState[SpvFromBTCSwapState["CLAIMED"] = 6] = "CLAIMED";
89
89
  })(SpvFromBTCSwapState = exports.SpvFromBTCSwapState || (exports.SpvFromBTCSwapState = {}));
90
+ const SpvFromBTCSwapStateDescription = {
91
+ [SpvFromBTCSwapState.CLOSED]: "Catastrophic failure has occurred when processing the swap on the smart chain side, this implies a bug in the smart contract code or the user and intermediary deliberately creating a bitcoin transaction with invalid format unparsable by the smart contract.",
92
+ [SpvFromBTCSwapState.FAILED]: "Some of the bitcoin swap transaction inputs were double-spent, this means the swap has failed and no BTC was sent",
93
+ [SpvFromBTCSwapState.DECLINED]: "The intermediary (LP) declined to co-sign the submitted PSBT, hence the swap failed",
94
+ [SpvFromBTCSwapState.QUOTE_EXPIRED]: "Swap has expired for good and there is no way how it can be executed anymore",
95
+ [SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED]: "A swap is almost expired, and it should be presented to the user as expired, though there is still a chance that it will be processed",
96
+ [SpvFromBTCSwapState.CREATED]: "Swap was created, get the bitcoin swap PSBT that should be signed by the user's wallet and then submit it back to the SDK.",
97
+ [SpvFromBTCSwapState.SIGNED]: "Swap bitcoin PSBT was submitted by the client to the SDK",
98
+ [SpvFromBTCSwapState.POSTED]: "Swap bitcoin PSBT sent to the intermediary (LP), waiting for the intermediary co-sign it and broadcast.",
99
+ [SpvFromBTCSwapState.BROADCASTED]: "Intermediary (LP) has co-signed and broadcasted the bitcoin transaction.",
100
+ [SpvFromBTCSwapState.FRONTED]: "Settlement on the destination smart chain was fronted and funds were already received by the user, even before the final settlement.",
101
+ [SpvFromBTCSwapState.BTC_TX_CONFIRMED]: "Bitcoin transaction confirmed with necessary amount of confirmations, wait for automatic settlement by the watchtower or settle manually.",
102
+ [SpvFromBTCSwapState.CLAIMED]: "Swap settled on the smart chain and funds received"
103
+ };
90
104
  function isSpvFromBTCSwapInit(obj) {
91
105
  return typeof obj === "object" &&
92
106
  typeof (obj.quoteId) === "string" &&
@@ -130,6 +144,14 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
130
144
  initOrObject.url += "/frombtc_spv";
131
145
  super(wrapper, initOrObject);
132
146
  this.TYPE = SwapType_1.SwapType.SPV_VAULT_FROM_BTC;
147
+ /**
148
+ * @internal
149
+ */
150
+ this.swapStateDescription = SpvFromBTCSwapStateDescription;
151
+ /**
152
+ * @internal
153
+ */
154
+ this.swapStateName = (state) => SpvFromBTCSwapState[state];
133
155
  if (isSpvFromBTCSwapInit(initOrObject)) {
134
156
  this._state = SpvFromBTCSwapState.CREATED;
135
157
  this.quoteId = initOrObject.quoteId;
@@ -190,6 +212,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
190
212
  this._claimTxId = initOrObject.claimTxId;
191
213
  this._frontTxId = initOrObject.frontTxId;
192
214
  this.gasPricingInfo = (0, PriceInfoType_1.deserializePriceInfoType)(initOrObject.gasPricingInfo);
215
+ this.btcTxConfirmedAt = initOrObject.btcTxConfirmedAt;
193
216
  if (initOrObject.data != null)
194
217
  this._data = new this.wrapper._spvWithdrawalDataDeserializer(initOrObject.data);
195
218
  }
@@ -323,6 +346,14 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
323
346
  isFailed() {
324
347
  return this._state === SpvFromBTCSwapState.FAILED || this._state === SpvFromBTCSwapState.DECLINED || this._state === SpvFromBTCSwapState.CLOSED;
325
348
  }
349
+ /**
350
+ * @inheritDoc
351
+ */
352
+ isInProgress() {
353
+ return this._state === SpvFromBTCSwapState.POSTED ||
354
+ this._state === SpvFromBTCSwapState.BROADCASTED ||
355
+ this._state === SpvFromBTCSwapState.BTC_TX_CONFIRMED;
356
+ }
326
357
  /**
327
358
  * @inheritDoc
328
359
  */
@@ -778,6 +809,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
778
809
  /**
779
810
  * @inheritDoc
780
811
  *
812
+ * @param options.bitcoinFeeRate Optional fee rate to use for the created Bitcoin transaction
781
813
  * @param options.bitcoinWallet Optional bitcoin wallet address specification to return a funded PSBT,
782
814
  * if not provided a raw PSBT is returned instead which necessitates the implementor to manually add
783
815
  * inputs to the bitcoin transaction and **set the nSequence field of the 2nd input** (input 1 -
@@ -795,13 +827,46 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
795
827
  txs: [
796
828
  options?.bitcoinWallet == null
797
829
  ? { ...await this.getPsbt(), type: "RAW_PSBT" }
798
- : { ...await this.getFundedPsbt(options.bitcoinWallet), type: "FUNDED_PSBT" }
830
+ : { ...await this.getFundedPsbt(options.bitcoinWallet, options?.bitcoinFeeRate), type: "FUNDED_PSBT" }
799
831
  ]
800
832
  }
801
833
  ];
802
834
  }
803
835
  throw new Error("Invalid swap state to obtain execution txns, required CREATED");
804
836
  }
837
+ /**
838
+ * @inheritDoc
839
+ *
840
+ * @param options.bitcoinFeeRate Optional fee rate to use for the created Bitcoin transaction
841
+ * @param options.bitcoinWallet Optional bitcoin wallet address specification to return a funded PSBT,
842
+ * if not provided a raw PSBT is returned instead which necessitates the implementor to manually add
843
+ * inputs to the bitcoin transaction and **set the nSequence field of the 2nd input** (input 1 -
844
+ * indexing from 0) to the value returned in `in1sequence`
845
+ * @param options.manualSettlementSmartChainSigner Optional smart chain signer to create a manual claim (settlement) transaction
846
+ * @param options.maxWaitTillAutomaticSettlementSeconds Maximum time to wait for an automatic settlement after
847
+ * the bitcoin transaction is confirmed (defaults to 60 seconds)
848
+ */
849
+ async getCurrentActions(options) {
850
+ if (this._state === SpvFromBTCSwapState.CREATED) {
851
+ try {
852
+ return await this.txsExecute(options);
853
+ }
854
+ catch (e) { }
855
+ }
856
+ if (this._state === SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
857
+ if (this.btcTxConfirmedAt == null ||
858
+ options?.maxWaitTillAutomaticSettlementSeconds === 0 ||
859
+ (Date.now() - this.btcTxConfirmedAt) > (options?.maxWaitTillAutomaticSettlementSeconds ?? 60) * 1000) {
860
+ return [{
861
+ name: "Claim",
862
+ description: "Manually settle (claim) the swap on the destination smart chain",
863
+ chain: this.chainIdentifier,
864
+ txs: await this.txsClaim(options?.manualSettlementSmartChainSigner)
865
+ }];
866
+ }
867
+ }
868
+ return [];
869
+ }
805
870
  //////////////////////////////
806
871
  //// Bitcoin tx listener
807
872
  /**
@@ -860,6 +925,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
860
925
  }
861
926
  if (this._state !== SpvFromBTCSwapState.FRONTED &&
862
927
  this._state !== SpvFromBTCSwapState.CLAIMED) {
928
+ this.btcTxConfirmedAt ??= Date.now();
863
929
  this._state = SpvFromBTCSwapState.BTC_TX_CONFIRMED;
864
930
  save = true;
865
931
  }
@@ -1078,7 +1144,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
1078
1144
  if (res.type === base_1.SpvWithdrawalStateType.CLAIMED) {
1079
1145
  if (this._state !== SpvFromBTCSwapState.CLAIMED) {
1080
1146
  this._claimTxId = res.txId;
1081
- await this._saveAndEmit(SpvFromBTCSwapState.FRONTED);
1147
+ await this._saveAndEmit(SpvFromBTCSwapState.CLAIMED);
1082
1148
  }
1083
1149
  }
1084
1150
  if (res.type === base_1.SpvWithdrawalStateType.CLOSED) {
@@ -1138,7 +1204,8 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
1138
1204
  senderAddress: this._senderAddress,
1139
1205
  claimTxId: this._claimTxId,
1140
1206
  frontTxId: this._frontTxId,
1141
- data: this._data?.serialize()
1207
+ data: this._data?.serialize(),
1208
+ btcTxConfirmedAt: this.btcTxConfirmedAt
1142
1209
  };
1143
1210
  }
1144
1211
  //////////////////////////////
@@ -1200,6 +1267,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
1200
1267
  if (this._state !== SpvFromBTCSwapState.BTC_TX_CONFIRMED &&
1201
1268
  this._state !== SpvFromBTCSwapState.FRONTED &&
1202
1269
  this._state !== SpvFromBTCSwapState.CLAIMED) {
1270
+ this.btcTxConfirmedAt ??= Date.now();
1203
1271
  this._state = SpvFromBTCSwapState.BTC_TX_CONFIRMED;
1204
1272
  needsSave = true;
1205
1273
  }
@@ -8,7 +8,7 @@ import { FeeType } from "../../../enums/FeeType";
8
8
  import { TokenAmount } from "../../../types/TokenAmount";
9
9
  import { BtcToken, SCToken } from "../../../types/Token";
10
10
  import { LoggerType } from "../../../utils/Logger";
11
- import { SwapExecutionActionLightning } from "../../../types/SwapExecutionAction";
11
+ import { SwapExecutionAction, SwapExecutionActionLightning } from "../../../types/SwapExecutionAction";
12
12
  /**
13
13
  * State enum for trusted Lightning gas swaps
14
14
  *
@@ -24,7 +24,7 @@ export declare enum LnForGasSwapState {
24
24
  */
25
25
  FAILED = -1,
26
26
  /**
27
- * Swap was created
27
+ * Swap was created, pay the provided lightning network invoice
28
28
  */
29
29
  PR_CREATED = 0,
30
30
  /**
@@ -51,6 +51,20 @@ export declare function isLnForGasSwapInit(obj: any): obj is LnForGasSwapInit;
51
51
  */
52
52
  export declare class LnForGasSwap<T extends ChainType = ChainType> extends ISwap<T, LnForGasSwapTypeDefinition<T>, LnForGasSwapState> implements IAddressSwap {
53
53
  protected readonly TYPE: SwapType.TRUSTED_FROM_BTCLN;
54
+ /**
55
+ * @internal
56
+ */
57
+ protected readonly swapStateDescription: {
58
+ [-2]: string;
59
+ [-1]: string;
60
+ 0: string;
61
+ 1: string;
62
+ 2: string;
63
+ };
64
+ /**
65
+ * @internal
66
+ */
67
+ protected readonly swapStateName: (state: number) => string;
54
68
  /**
55
69
  * @internal
56
70
  */
@@ -137,6 +151,10 @@ export declare class LnForGasSwap<T extends ChainType = ChainType> extends ISwap
137
151
  * @inheritDoc
138
152
  */
139
153
  isSuccessful(): boolean;
154
+ /**
155
+ * @inheritDoc
156
+ */
157
+ isInProgress(): boolean;
140
158
  /**
141
159
  * @inheritDoc
142
160
  * @internal
@@ -195,6 +213,14 @@ export declare class LnForGasSwap<T extends ChainType = ChainType> extends ISwap
195
213
  * @inheritDoc
196
214
  */
197
215
  txsExecute(): Promise<[SwapExecutionActionLightning]>;
216
+ /**
217
+ * @remark Not supported
218
+ */
219
+ execute(): Promise<boolean>;
220
+ /**
221
+ * @inheritDoc
222
+ */
223
+ getCurrentActions(): Promise<SwapExecutionAction<T>[]>;
198
224
  /**
199
225
  * Queries the intermediary (LP) node for the state of the swap
200
226
  *
@@ -28,7 +28,7 @@ var LnForGasSwapState;
28
28
  */
29
29
  LnForGasSwapState[LnForGasSwapState["FAILED"] = -1] = "FAILED";
30
30
  /**
31
- * Swap was created
31
+ * Swap was created, pay the provided lightning network invoice
32
32
  */
33
33
  LnForGasSwapState[LnForGasSwapState["PR_CREATED"] = 0] = "PR_CREATED";
34
34
  /**
@@ -40,6 +40,13 @@ var LnForGasSwapState;
40
40
  */
41
41
  LnForGasSwapState[LnForGasSwapState["FINISHED"] = 2] = "FINISHED";
42
42
  })(LnForGasSwapState = exports.LnForGasSwapState || (exports.LnForGasSwapState = {}));
43
+ const LnForGasSwapStateDescription = {
44
+ [LnForGasSwapState.EXPIRED]: "The swap quote expired without user sending in the lightning network payment",
45
+ [LnForGasSwapState.FAILED]: "The swap has failed after the intermediary already received a lightning network payment on the source",
46
+ [LnForGasSwapState.PR_CREATED]: "Swap was created, pay the provided lightning network invoice",
47
+ [LnForGasSwapState.PR_PAID]: "User paid the lightning network invoice on the source",
48
+ [LnForGasSwapState.FINISHED]: "The swap is finished after the intermediary sent funds on the destination chain"
49
+ };
43
50
  function isLnForGasSwapInit(obj) {
44
51
  return typeof (obj.pr) === "string" &&
45
52
  typeof (obj.outputAmount) === "bigint" &&
@@ -60,6 +67,14 @@ class LnForGasSwap extends ISwap_1.ISwap {
60
67
  initOrObj.url += "/lnforgas";
61
68
  super(wrapper, initOrObj);
62
69
  this.TYPE = SwapType_1.SwapType.TRUSTED_FROM_BTCLN;
70
+ /**
71
+ * @internal
72
+ */
73
+ this.swapStateDescription = LnForGasSwapStateDescription;
74
+ /**
75
+ * @internal
76
+ */
77
+ this.swapStateName = (state) => LnForGasSwapState[state];
63
78
  /**
64
79
  * @internal
65
80
  */
@@ -203,6 +218,12 @@ class LnForGasSwap extends ISwap_1.ISwap {
203
218
  isSuccessful() {
204
219
  return this._state === LnForGasSwapState.FINISHED;
205
220
  }
221
+ /**
222
+ * @inheritDoc
223
+ */
224
+ isInProgress() {
225
+ return (this._state === LnForGasSwapState.PR_CREATED && this.initiated) || this._state === LnForGasSwapState.PR_PAID;
226
+ }
206
227
  /**
207
228
  * @inheritDoc
208
229
  * @internal
@@ -332,6 +353,23 @@ class LnForGasSwap extends ISwap_1.ISwap {
332
353
  }
333
354
  throw new Error("Invalid swap state to obtain execution txns, required PR_CREATED");
334
355
  }
356
+ /**
357
+ * @remark Not supported
358
+ */
359
+ async execute() {
360
+ throw new Error("Not supported");
361
+ }
362
+ /**
363
+ * @inheritDoc
364
+ */
365
+ async getCurrentActions() {
366
+ try {
367
+ return await this.txsExecute();
368
+ }
369
+ catch (e) {
370
+ return [];
371
+ }
372
+ }
335
373
  /**
336
374
  * Queries the intermediary (LP) node for the state of the swap
337
375
  *
@@ -12,7 +12,7 @@ import { FeeType } from "../../../enums/FeeType";
12
12
  import { TokenAmount } from "../../../types/TokenAmount";
13
13
  import { BtcToken, SCToken } from "../../../types/Token";
14
14
  import { LoggerType } from "../../../utils/Logger";
15
- import { SwapExecutionActionBitcoin } from "../../../types/SwapExecutionAction";
15
+ import { SwapExecutionAction, SwapExecutionActionBitcoin } from "../../../types/SwapExecutionAction";
16
16
  /**
17
17
  * State enum for trusted on-chain gas swaps
18
18
  *
@@ -32,7 +32,7 @@ export declare enum OnchainForGasSwapState {
32
32
  */
33
33
  REFUNDED = -1,
34
34
  /**
35
- * Swap was created
35
+ * Swap was created, send the BTC to the swap address
36
36
  */
37
37
  PR_CREATED = 0,
38
38
  /**
@@ -61,8 +61,16 @@ export declare function isOnchainForGasSwapInit(obj: any): obj is OnchainForGasS
61
61
  *
62
62
  * @category Swaps/Trusted Gas Swaps
63
63
  */
64
- export declare class OnchainForGasSwap<T extends ChainType = ChainType> extends ISwap<T, OnchainForGasSwapTypeDefinition<T>> implements IAddressSwap, IBTCWalletSwap {
64
+ export declare class OnchainForGasSwap<T extends ChainType = ChainType> extends ISwap<T, OnchainForGasSwapTypeDefinition<T>, OnchainForGasSwapState> implements IAddressSwap, IBTCWalletSwap {
65
65
  protected readonly TYPE: SwapType.TRUSTED_FROM_BTC;
66
+ /**
67
+ * @internal
68
+ */
69
+ protected readonly swapStateDescription: Record<OnchainForGasSwapState, string>;
70
+ /**
71
+ * @internal
72
+ */
73
+ protected readonly swapStateName: (state: number) => string;
66
74
  /**
67
75
  * @internal
68
76
  */
@@ -163,6 +171,10 @@ export declare class OnchainForGasSwap<T extends ChainType = ChainType> extends
163
171
  * @inheritDoc
164
172
  */
165
173
  isSuccessful(): boolean;
174
+ /**
175
+ * @inheritDoc
176
+ */
177
+ isInProgress(): boolean;
166
178
  /**
167
179
  * @inheritDoc
168
180
  * @internal
@@ -259,6 +271,19 @@ export declare class OnchainForGasSwap<T extends ChainType = ChainType> extends
259
271
  }): Promise<[
260
272
  SwapExecutionActionBitcoin<"ADDRESS" | "FUNDED_PSBT">
261
273
  ]>;
274
+ /**
275
+ * @remark Not supported
276
+ */
277
+ execute(): Promise<boolean>;
278
+ /**
279
+ * @inheritDoc
280
+ *
281
+ * @param options.bitcoinWallet Optional bitcoin wallet address specification to return a funded PSBT,
282
+ * if not provided an address is returned instead.
283
+ */
284
+ getCurrentActions(options?: {
285
+ bitcoinWallet?: MinimalBitcoinWalletInterface;
286
+ }): Promise<SwapExecutionAction<T>[]>;
262
287
  /**
263
288
  * Queries the intermediary (LP) node for the state of the swap
264
289
  *
@@ -37,7 +37,7 @@ var OnchainForGasSwapState;
37
37
  */
38
38
  OnchainForGasSwapState[OnchainForGasSwapState["REFUNDED"] = -1] = "REFUNDED";
39
39
  /**
40
- * Swap was created
40
+ * Swap was created, send the BTC to the swap address
41
41
  */
42
42
  OnchainForGasSwapState[OnchainForGasSwapState["PR_CREATED"] = 0] = "PR_CREATED";
43
43
  /**
@@ -49,6 +49,14 @@ var OnchainForGasSwapState;
49
49
  */
50
50
  OnchainForGasSwapState[OnchainForGasSwapState["REFUNDABLE"] = 2] = "REFUNDABLE";
51
51
  })(OnchainForGasSwapState = exports.OnchainForGasSwapState || (exports.OnchainForGasSwapState = {}));
52
+ const OnchainForGasSwapStateDescription = {
53
+ [OnchainForGasSwapState.EXPIRED]: "The swap quote expired without user sending in the BTC",
54
+ [OnchainForGasSwapState.FAILED]: "The swap has failed after the intermediary already received the BTC on the source chain",
55
+ [OnchainForGasSwapState.REFUNDED]: "Swap was refunded and BTC returned to the user's refund address",
56
+ [OnchainForGasSwapState.PR_CREATED]: "Swap was created, send the BTC to the swap address",
57
+ [OnchainForGasSwapState.FINISHED]: "The swap is finished after the intermediary sent funds on the destination chain",
58
+ [OnchainForGasSwapState.REFUNDABLE]: "Swap is refundable because the intermediary cannot honor the swap request on the destination chain",
59
+ };
52
60
  function isOnchainForGasSwapInit(obj) {
53
61
  return typeof (obj.paymentHash) === "string" &&
54
62
  typeof (obj.sequence) === "bigint" &&
@@ -73,6 +81,14 @@ class OnchainForGasSwap extends ISwap_1.ISwap {
73
81
  initOrObj.url += "/frombtc_trusted";
74
82
  super(wrapper, initOrObj);
75
83
  this.TYPE = SwapType_1.SwapType.TRUSTED_FROM_BTC;
84
+ /**
85
+ * @internal
86
+ */
87
+ this.swapStateDescription = OnchainForGasSwapStateDescription;
88
+ /**
89
+ * @internal
90
+ */
91
+ this.swapStateName = (state) => OnchainForGasSwapState[state];
76
92
  this.wrapper = wrapper;
77
93
  if (isOnchainForGasSwapInit(initOrObj)) {
78
94
  this.paymentHash = initOrObj.paymentHash;
@@ -209,6 +225,13 @@ class OnchainForGasSwap extends ISwap_1.ISwap {
209
225
  isSuccessful() {
210
226
  return this._state === OnchainForGasSwapState.FINISHED;
211
227
  }
228
+ /**
229
+ * @inheritDoc
230
+ */
231
+ isInProgress() {
232
+ return (this._state === OnchainForGasSwapState.PR_CREATED && this.txId != null) ||
233
+ (this._state === OnchainForGasSwapState.REFUNDABLE && this.refundAddress != null);
234
+ }
212
235
  /**
213
236
  * @inheritDoc
214
237
  * @internal
@@ -437,6 +460,26 @@ class OnchainForGasSwap extends ISwap_1.ISwap {
437
460
  }
438
461
  throw new Error("Invalid swap state to obtain execution txns, required PR_CREATED or CLAIM_COMMITED");
439
462
  }
463
+ /**
464
+ * @remark Not supported
465
+ */
466
+ async execute() {
467
+ throw new Error("Not supported");
468
+ }
469
+ /**
470
+ * @inheritDoc
471
+ *
472
+ * @param options.bitcoinWallet Optional bitcoin wallet address specification to return a funded PSBT,
473
+ * if not provided an address is returned instead.
474
+ */
475
+ async getCurrentActions(options) {
476
+ try {
477
+ return await this.txsExecute(options);
478
+ }
479
+ catch (e) {
480
+ return [];
481
+ }
482
+ }
440
483
  //////////////////////////////
441
484
  //// Payment
442
485
  /**
@@ -0,0 +1,5 @@
1
+ export type SwapStateInfo<S extends number> = {
2
+ state: S;
3
+ name: string;
4
+ description: string;
5
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -47,7 +47,6 @@ export declare function isLNURLPayParams(obj: any): obj is LNURLPayParams;
47
47
  * Type guard for {@link LNURLPay}
48
48
  *
49
49
  * @category Lightning
50
- * @internal
51
50
  */
52
51
  export declare function isLNURLPay(value: any): value is LNURLPay;
53
52
  /**
@@ -15,7 +15,6 @@ exports.isLNURLPayParams = isLNURLPayParams;
15
15
  * Type guard for {@link LNURLPay}
16
16
  *
17
17
  * @category Lightning
18
- * @internal
19
18
  */
20
19
  function isLNURLPay(value) {
21
20
  return (typeof value === "object" &&
@@ -37,7 +37,6 @@ export type LNURLWithdraw = {
37
37
  * Type guard for {@link LNURLWithdraw}
38
38
  *
39
39
  * @category Lightning
40
- * @internal
41
40
  */
42
41
  export declare function isLNURLWithdraw(value: any): value is LNURLWithdraw;
43
42
  /**
@@ -5,7 +5,6 @@ exports.isLNURLWithdrawParams = exports.isLNURLWithdraw = void 0;
5
5
  * Type guard for {@link LNURLWithdraw}
6
6
  *
7
7
  * @category Lightning
8
- * @internal
9
8
  */
10
9
  function isLNURLWithdraw(value) {
11
10
  return (typeof value === "object" &&
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atomiqlabs/sdk",
3
- "version": "8.3.6",
3
+ "version": "8.4.4",
4
4
  "description": "atomiq labs SDK for cross-chain swaps between smart chains and bitcoin",
5
5
  "main": "./dist/index.js",
6
6
  "types:": "./dist/index.d.ts",
@@ -30,6 +30,8 @@
30
30
  "@noble/ciphers": "^1.2.1",
31
31
  "@noble/hashes": "^1.7.1",
32
32
  "@scure/base": "^1.2.4",
33
+ "@scure/bip32": "^2.0.1",
34
+ "@scure/bip39": "^2.0.1",
33
35
  "@scure/btc-signer": "1.7.0",
34
36
  "buffer": "6.0.3",
35
37
  "events": "3.3.0"
@@ -1,5 +1,5 @@
1
1
  import {coinSelect, maxSendable, CoinselectAddressTypes, CoinselectTxInput} from "../coinselect2";
2
- import {BTC_NETWORK} from "@scure/btc-signer/utils"
2
+ import {BTC_NETWORK, NETWORK, TEST_NETWORK} from "@scure/btc-signer/utils"
3
3
  import {p2wpkh, OutScript, Transaction, p2tr, Address} from "@scure/btc-signer";
4
4
  import {IBitcoinWallet} from "./IBitcoinWallet";
5
5
  import {Buffer} from "buffer";
@@ -7,7 +7,7 @@ import {randomBytes} from "../../utils/Utils";
7
7
  import {toCoinselectAddressType, toOutputScript} from "../../utils/BitcoinUtils";
8
8
  import {TransactionInputUpdate} from "@scure/btc-signer/psbt";
9
9
  import {getLogger} from "../../utils/Logger";
10
- import {BitcoinRpcWithAddressIndex} from "@atomiqlabs/base";
10
+ import {BitcoinNetwork, BitcoinRpcWithAddressIndex} from "@atomiqlabs/base";
11
11
 
12
12
  /**
13
13
  * UTXO data structure for Bitcoin wallets
@@ -50,6 +50,16 @@ export function identifyAddressType(address: string, network: BTC_NETWORK): Coin
50
50
  }
51
51
  }
52
52
 
53
+ const btcNetworkMapping = {
54
+ [BitcoinNetwork.MAINNET]: NETWORK,
55
+ [BitcoinNetwork.TESTNET]: TEST_NETWORK,
56
+ [BitcoinNetwork.TESTNET4]: TEST_NETWORK,
57
+ [BitcoinNetwork.REGTEST]: {
58
+ ...TEST_NETWORK,
59
+ bech32: "bcrt"
60
+ }
61
+ }
62
+
53
63
  const logger = getLogger("BitcoinWallet: ");
54
64
 
55
65
  /**
@@ -65,9 +75,13 @@ export abstract class BitcoinWallet implements IBitcoinWallet {
65
75
  protected feeMultiplier: number;
66
76
  protected feeOverride?: number;
67
77
 
68
- constructor(mempoolApi: BitcoinRpcWithAddressIndex<any>, network: BTC_NETWORK, feeMultiplier: number = 1.25, feeOverride?: number) {
78
+ constructor(
79
+ mempoolApi: BitcoinRpcWithAddressIndex<any>,
80
+ network: BitcoinNetwork | BTC_NETWORK,
81
+ feeMultiplier: number = 1.25, feeOverride?: number
82
+ ) {
69
83
  this.rpc = mempoolApi;
70
- this.network = network;
84
+ this.network = typeof(network)==="object" ? network : BitcoinWallet.bitcoinNetworkToObject(network);
71
85
  this.feeMultiplier = feeMultiplier;
72
86
  this.feeOverride = feeOverride;
73
87
  }
@@ -407,5 +421,8 @@ export abstract class BitcoinWallet implements IBitcoinWallet {
407
421
  totalFee: number
408
422
  }>;
409
423
 
424
+ static bitcoinNetworkToObject(network: BitcoinNetwork): BTC_NETWORK {
425
+ return btcNetworkMapping[network];
426
+ }
410
427
 
411
428
  }
@@ -1,9 +1,13 @@
1
1
  import {CoinselectAddressTypes} from "../coinselect2";
2
- import {BTC_NETWORK, pubECDSA, randomPrivateKeyBytes} from "@scure/btc-signer/utils"
2
+ import {BTC_NETWORK, NETWORK, pubECDSA, randomPrivateKeyBytes, TEST_NETWORK} from "@scure/btc-signer/utils"
3
3
  import {getAddress, Transaction, WIF} from "@scure/btc-signer";
4
4
  import {Buffer} from "buffer";
5
5
  import {identifyAddressType, BitcoinWallet} from "./BitcoinWallet";
6
- import {BitcoinRpcWithAddressIndex} from "@atomiqlabs/base";
6
+ import {BitcoinNetwork, BitcoinRpcWithAddressIndex} from "@atomiqlabs/base";
7
+ import {HDKey} from "@scure/bip32";
8
+ import {entropyToMnemonic, generateMnemonic, mnemonicToSeed} from "@scure/bip39";
9
+ import {wordlist} from "@scure/bip39/wordlists/english.js";
10
+ import {sha256} from "@noble/hashes/sha2";
7
11
 
8
12
  /**
9
13
  * Bitcoin wallet implementation deriving a single address from a WIF encoded private key
@@ -19,11 +23,14 @@ export class SingleAddressBitcoinWallet extends BitcoinWallet {
19
23
 
20
24
  constructor(
21
25
  mempoolApi: BitcoinRpcWithAddressIndex<any>,
22
- network: BTC_NETWORK,
26
+ _network: BitcoinNetwork | BTC_NETWORK,
23
27
  addressDataOrWIF: string | {address: string, publicKey: string},
24
28
  feeMultiplier: number = 1.25,
25
29
  feeOverride?: number
26
30
  ) {
31
+ const network = typeof(_network)==="object"
32
+ ? _network
33
+ : BitcoinWallet.bitcoinNetworkToObject(_network);
27
34
  super(mempoolApi, network, feeMultiplier, feeOverride);
28
35
  if(typeof(addressDataOrWIF)==="string") {
29
36
  try {
@@ -144,8 +151,56 @@ export class SingleAddressBitcoinWallet extends BitcoinWallet {
144
151
  *
145
152
  * @returns A WIF encoded bitcoin private key
146
153
  */
147
- static generateRandomPrivateKey(network?: BTC_NETWORK): string {
148
- return WIF(network).encode(randomPrivateKeyBytes());
154
+ static generateRandomPrivateKey(network?: BitcoinNetwork | BTC_NETWORK): string {
155
+ const networkObject = network==null || typeof(network)==="object"
156
+ ? network
157
+ : BitcoinWallet.bitcoinNetworkToObject(network);
158
+ return WIF(networkObject).encode(randomPrivateKeyBytes());
159
+ }
160
+
161
+ /**
162
+ * Generates a 12-word long mnemonic from any entropy source with 128-bits or more, the entropy is first hashed
163
+ * using sha256, and the first 16 bytes of the hash are used to generate the mnemonic
164
+ *
165
+ * @param entropy Entropy to use for generating the mnemonic
166
+ */
167
+ static mnemonicFromEntropy(entropy: Buffer): string {
168
+ if(entropy.length<16) throw new Error("Requires at least 128-bit entropy (16 bytes)");
169
+ const entropyHash = Buffer.from(sha256(entropy)).subarray(0, 16);
170
+ return entropyToMnemonic(entropyHash, wordlist);
171
+ }
172
+
173
+ /**
174
+ * Generates a random 12-word long mnemonic
175
+ */
176
+ static generateRandomMnemonic(): string {
177
+ return generateMnemonic(wordlist, 128)
178
+ }
179
+
180
+ /**
181
+ * Generates a WIF private key from mnemonic phrase
182
+ *
183
+ * @param mnemonic Mnemonic to generate the WIF key from
184
+ * @param network Optional bitcoin network to generate the WIF for
185
+ * @param derivationPath Optional custom derivation path to use for deriving the wallet
186
+ */
187
+ static async mnemonicToPrivateKey(
188
+ mnemonic: string,
189
+ network?: BitcoinNetwork | BTC_NETWORK,
190
+ derivationPath?: string
191
+ ): Promise<string> {
192
+ const networkObject = network==null || typeof(network)==="object"
193
+ ? network
194
+ : BitcoinWallet.bitcoinNetworkToObject(network);
195
+
196
+ derivationPath = networkObject==null || networkObject.bech32===NETWORK.bech32
197
+ ? "m/84'/0'/0'/0/0" //Mainnet
198
+ : "m/84'/1'/0'/0/0"; //Testnet
199
+ const seed = await mnemonicToSeed(mnemonic);
200
+ const hdKey = HDKey.fromMasterSeed(seed);
201
+ const privateKey = hdKey.derive(derivationPath).privateKey;
202
+ if(privateKey==null) throw new Error("Cannot derive private key from the mnemonic!");
203
+ return WIF(networkObject).encode(privateKey);
149
204
  }
150
205
 
151
206
  }
package/src/index.ts CHANGED
@@ -127,6 +127,7 @@ export * from "./types/wallets/MinimalBitcoinWalletInterface";
127
127
  export * from "./types/wallets/MinimalLightningNetworkWalletInterface";
128
128
  export * from "./types/wallets/LightningInvoiceCreateService";
129
129
 
130
+ export * from "./types/SwapStateInfo";
130
131
  export * from "./types/AmountData";
131
132
  export * from "./types/CustomPriceFunction";
132
133
  export * from "./types/SwapExecutionAction";