@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
@@ -226,6 +226,7 @@ export type FromBTCLNResponseType = RequestSchemaResult<typeof FromBTCLNResponse
226
226
 
227
227
  export type FromBTCLNInit = BaseFromBTCSwapInit & {
228
228
  paymentHash: Buffer,
229
+ description?: string,
229
230
  descriptionHash?: Buffer
230
231
  }
231
232
 
@@ -258,6 +259,7 @@ export type FromBTCLNAutoResponseType = RequestSchemaResult<typeof FromBTCLNAuto
258
259
  export type FromBTCLNAutoInit = Omit<BaseFromBTCSwapInit, "feeRate"> & {
259
260
  paymentHash: Buffer,
260
261
  gasToken: string,
262
+ description?: string,
261
263
  descriptionHash?: Buffer,
262
264
  gasAmount?: bigint,
263
265
  claimerBounty?: Promise<bigint>
@@ -597,6 +599,7 @@ export class IntermediaryAPI {
597
599
  amount: init.amount.toString(),
598
600
  address: init.claimer,
599
601
  token: init.token,
602
+ description: init.description ?? null,
600
603
  descriptionHash: init.descriptionHash==null ? null : init.descriptionHash.toString("hex"),
601
604
  exactOut: init.exactOut,
602
605
  feeRate: init.feeRate
@@ -658,6 +661,7 @@ export class IntermediaryAPI {
658
661
  amount: init.amount.toString(),
659
662
  address: init.claimer,
660
663
  token: init.token,
664
+ description: init.description ?? null,
661
665
  descriptionHash: init.descriptionHash==null ? null : init.descriptionHash.toString("hex"),
662
666
  exactOut: init.exactOut,
663
667
  gasToken: init.gasToken,
@@ -937,4 +941,4 @@ export class IntermediaryAPI {
937
941
  });
938
942
  }
939
943
 
940
- }
944
+ }
@@ -1185,6 +1185,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
1185
1185
  * @param amount Amount to send in satoshis (if `exactOut=false`) or receive in token based units (if `exactOut=true`)
1186
1186
  * @param exactOut Whether to use a exact out instead of exact in
1187
1187
  * @param additionalParams Additional parameters sent to the LP when creating the swap
1188
+ * @param options Additional options for the swap
1188
1189
  */
1189
1190
  async createFromBTCLNSwapViaLNURL<ChainIdentifier extends ChainIds<T>>(
1190
1191
  chainIdentifier: ChainIdentifier,
@@ -1193,7 +1194,8 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
1193
1194
  lnurl: string | LNURLWithdraw,
1194
1195
  amount: bigint,
1195
1196
  exactOut: boolean = false,
1196
- additionalParams: Record<string, any> | undefined = this.options.defaultAdditionalParameters
1197
+ additionalParams: Record<string, any> | undefined = this.options.defaultAdditionalParameters,
1198
+ options?: FromBTCLNOptions
1197
1199
  ): Promise<FromBTCLNSwap<T[ChainIdentifier]>> {
1198
1200
  if(this._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
1199
1201
  if(typeof(lnurl)==="string" && !this.Utils.isValidLNURL(lnurl)) throw new Error("Invalid LNURL-withdraw link");
@@ -1211,6 +1213,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
1211
1213
  typeof(lnurl)==="string" ? (lnurl.startsWith("lightning:") ? lnurl.substring(10): lnurl) : lnurl.params,
1212
1214
  amountData,
1213
1215
  candidates,
1216
+ options,
1214
1217
  additionalParams,
1215
1218
  abortSignal
1216
1219
  ),
@@ -1477,7 +1480,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
1477
1480
  if(typeof(src)!=="string" && !isLNURLWithdraw(src)) throw new Error("LNURL must be a string or LNURLWithdraw object!");
1478
1481
  return this.supportsSwapType(dstToken.chainId, SwapType.FROM_BTCLN_AUTO) ?
1479
1482
  this.createFromBTCLNSwapNewViaLNURL(dstToken.chainId, dst, dstToken.address, src, amount, !exactIn, undefined, options as any) :
1480
- this.createFromBTCLNSwapViaLNURL(dstToken.chainId, dst, dstToken.address, src, amount, !exactIn);
1483
+ this.createFromBTCLNSwapViaLNURL(dstToken.chainId, dst, dstToken.address, src, amount, !exactIn, undefined, options as any);
1481
1484
  } else {
1482
1485
  return this.supportsSwapType(dstToken.chainId, SwapType.FROM_BTCLN_AUTO) ?
1483
1486
  this.createFromBTCLNSwapNew(dstToken.chainId, dst, dstToken.address, amount, !exactIn, undefined, options as any):
@@ -12,6 +12,7 @@ import {isSCToken, Token} from "../types/Token";
12
12
  import {SwapExecutionAction} from "../types/SwapExecutionAction";
13
13
  import {LoggerType} from "../utils/Logger";
14
14
  import {isPriceInfoType, PriceInfoType} from "../types/PriceInfoType";
15
+ import {SwapStateInfo} from "../types/SwapStateInfo";
15
16
 
16
17
  /**
17
18
  * Initialization data for creating a swap
@@ -57,6 +58,17 @@ export abstract class ISwap<
57
58
  * Swap type
58
59
  */
59
60
  protected readonly abstract TYPE: SwapType;
61
+
62
+ /**
63
+ * Description for the states
64
+ * @internal
65
+ */
66
+ protected readonly abstract swapStateDescription: Record<S, string>;
67
+ /**
68
+ * Name of the states
69
+ * @internal
70
+ */
71
+ protected readonly abstract swapStateName: (state: number) => string;
60
72
  /**
61
73
  * Swap logger
62
74
  * @internal
@@ -237,6 +249,17 @@ export abstract class ISwap<
237
249
  */
238
250
  public abstract txsExecute(options?: any): Promise<SwapExecutionAction<T>[]>;
239
251
 
252
+ /**
253
+ * Executes the swap with the provided wallet, the exact arguments for this functions differ for various swap
254
+ * types. Check the `execute()` function signature in the respective swap class to see the required arguments.
255
+ *
256
+ * @param args Execution arguments, usually contains a source wallet object, callbacks and options, for exact
257
+ * syntax check the respective swap class.
258
+ *
259
+ * @returns Whether a swap was successfully executed or not, if it wasn't the user can refund or claim manually
260
+ */
261
+ public abstract execute(...args: any[]): Promise<boolean>;
262
+
240
263
  //////////////////////////////
241
264
  //// Pricing
242
265
 
@@ -448,6 +471,11 @@ export abstract class ISwap<
448
471
  */
449
472
  public abstract isFailed(): boolean;
450
473
 
474
+ /**
475
+ * Returns whether the swap is currently being processed
476
+ */
477
+ public abstract isInProgress(): boolean;
478
+
451
479
  /**
452
480
  * Whether a swap was initialized, a swap is considered initialized on first interaction with it, i.e.
453
481
  * calling commit() on a Smart chain -> Bitcoin swaps, calling waitForPayment() or similar on the other
@@ -486,6 +514,23 @@ export abstract class ISwap<
486
514
  return this._state;
487
515
  }
488
516
 
517
+ /**
518
+ * Returns the current state of the swap along with the human-readable description of the state
519
+ */
520
+ public getStateInfo(): SwapStateInfo<S> {
521
+ return {
522
+ state: this._state,
523
+ name: this.swapStateName(this._state),
524
+ description: this.swapStateDescription[this._state]
525
+ }
526
+ }
527
+
528
+ /**
529
+ * Returns a state-dependent set of actions for the user to execute, or empty array if there is currently
530
+ * no action required from the user to execute.
531
+ */
532
+ public abstract getCurrentActions(): Promise<SwapExecutionAction<T>[]>;
533
+
489
534
  //////////////////////////////
490
535
  //// Amounts & fees
491
536
 
@@ -131,6 +131,26 @@ export abstract class IEscrowSwap<
131
131
  return this.getIdentifierHashString();
132
132
  }
133
133
 
134
+ /**
135
+ * Returns the smart chain transaction ID of the tx that initiated the escrow
136
+ */
137
+ getEscrowInitTxId(): string | undefined {
138
+ return this._commitTxId;
139
+ }
140
+
141
+ /**
142
+ * Returns the smart chain transaction ID of the tx that claimed (settled) the escrow
143
+ */
144
+ getEscrowClaimTxId(): string | undefined {
145
+ return this._claimTxId;
146
+ }
147
+
148
+ /**
149
+ * Returns the smart chain transaction ID of the tx that refunded the escrow
150
+ */
151
+ getEscrowRefundTxId(): string | undefined {
152
+ return this._refundTxId;
153
+ }
134
154
 
135
155
  //////////////////////////////
136
156
  //// Watchdogs
@@ -31,6 +31,7 @@ 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
35
 
35
36
  /**
36
37
  * State enum for legacy Lightning -> Smart chain swaps
@@ -80,6 +81,17 @@ export enum FromBTCLNSwapState {
80
81
  CLAIM_CLAIMED = 3
81
82
  }
82
83
 
84
+ const FromBTCLNSwapStateDescription = {
85
+ [FromBTCLNSwapState.FAILED]: "Swap has failed as the user didn't settle the HTLC on the destination before expiration",
86
+ [FromBTCLNSwapState.QUOTE_EXPIRED]: "Swap has expired for good and there is no way how it can be executed anymore",
87
+ [FromBTCLNSwapState.QUOTE_SOFT_EXPIRED]: "Swap is expired, though there is still a chance that it will be processed",
88
+ [FromBTCLNSwapState.EXPIRED]: "Swap HTLC on the destination chain has expired, it is not safe anymore to settle (claim) the swap on the destination smart chain.",
89
+ [FromBTCLNSwapState.PR_CREATED]: "Swap quote was created, pay the bolt11 lightning network invoice to initiate the swap, then use the wait till the lightning network payment is received by the intermediary (LP)",
90
+ [FromBTCLNSwapState.PR_PAID]: "Lightning network payment has been received by the intermediary (LP), the user can now settle the swap on the destination smart chain side.",
91
+ [FromBTCLNSwapState.CLAIM_COMMITED]: "Swap escrow HTLC has been created on the destination chain. Continue by claiming it.",
92
+ [FromBTCLNSwapState.CLAIM_CLAIMED]: "Swap successfully settled and funds received on the destination chain"
93
+ };
94
+
83
95
  export type FromBTCLNSwapInit<T extends SwapData> = IEscrowSelfInitSwapInit<T> & {
84
96
  pr?: string,
85
97
  secret?: string,
@@ -109,6 +121,14 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
109
121
  implements IAddressSwap, IClaimableSwap<T, FromBTCLNDefinition<T>, FromBTCLNSwapState> {
110
122
 
111
123
  protected readonly TYPE = SwapType.FROM_BTCLN;
124
+ /**
125
+ * @internal
126
+ */
127
+ protected readonly swapStateName = (state: number) => FromBTCLNSwapState[state];
128
+ /**
129
+ * @internal
130
+ */
131
+ protected readonly swapStateDescription = FromBTCLNSwapStateDescription;
112
132
  /**
113
133
  * @internal
114
134
  */
@@ -365,6 +385,16 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
365
385
  return this._state===FromBTCLNSwapState.FAILED || this._state===FromBTCLNSwapState.EXPIRED;
366
386
  }
367
387
 
388
+ /**
389
+ * @inheritDoc
390
+ */
391
+ isInProgress(): boolean {
392
+ return (this._state===FromBTCLNSwapState.PR_CREATED && this.initiated) ||
393
+ (this._state===FromBTCLNSwapState.QUOTE_SOFT_EXPIRED && this.initiated) ||
394
+ this._state===FromBTCLNSwapState.PR_PAID ||
395
+ this._state===FromBTCLNSwapState.CLAIM_COMMITED;
396
+ }
397
+
368
398
  /**
369
399
  * @inheritDoc
370
400
  */
@@ -468,6 +498,25 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
468
498
  return this.getSwapData().getClaimHash()===claimHash;
469
499
  }
470
500
 
501
+ /**
502
+ * Sets the secret preimage for the swap, in case it is not known already
503
+ *
504
+ * @param secret Secret preimage that matches the expected payment hash
505
+ *
506
+ * @throws {Error} If an invalid secret preimage is provided
507
+ */
508
+ setSecretPreimage(secret: string) {
509
+ if(!this.isValidSecretPreimage(secret)) throw new Error("Invalid secret preimage provided, hash doesn't match!");
510
+ this.secret = secret;
511
+ }
512
+
513
+ /**
514
+ * Returns whether the secret preimage for this swap is known
515
+ */
516
+ hasSecretPreimage(): boolean {
517
+ return this.secret != null;
518
+ }
519
+
471
520
 
472
521
  //////////////////////////////
473
522
  //// Execution
@@ -482,7 +531,7 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
482
531
  * link, wallet is not required and the LN invoice can be paid externally as well (just pass null or undefined here)
483
532
  * @param callbacks Callbacks to track the progress of the swap
484
533
  * @param options Optional options for the swap like feeRate, AbortSignal, and timeouts/intervals
485
- * @param secret A swap secret to use for the claim transaction, generally only needed if the swap
534
+ * @param options.secret A swap secret to use for the claim transaction, generally only needed if the swap
486
535
  * was recovered from on-chain data, or the pre-image was generated outside the SDK
487
536
  */
488
537
  async execute(
@@ -496,11 +545,11 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
496
545
  },
497
546
  options?: {
498
547
  abortSignal?: AbortSignal,
548
+ secret?: string,
499
549
  lightningTxCheckIntervalSeconds?: number,
500
550
  delayBetweenCommitAndClaimSeconds?: number
501
- },
502
- secret?: string
503
- ): Promise<void> {
551
+ }
552
+ ): Promise<boolean> {
504
553
  if(this._state===FromBTCLNSwapState.FAILED) throw new Error("Swap failed!");
505
554
  if(this._state===FromBTCLNSwapState.EXPIRED) throw new Error("Swap HTLC expired!");
506
555
  if(this._state===FromBTCLNSwapState.QUOTE_EXPIRED || this._state===FromBTCLNSwapState.QUOTE_SOFT_EXPIRED) throw new Error("Swap quote expired!");
@@ -530,14 +579,14 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
530
579
 
531
580
  if(this._state===FromBTCLNSwapState.PR_PAID || this._state===FromBTCLNSwapState.CLAIM_COMMITED) {
532
581
  if(this.canCommitAndClaimInOneShot()) {
533
- await this.commitAndClaim(dstSigner, options?.abortSignal, undefined, callbacks?.onDestinationCommitSent, callbacks?.onDestinationClaimSent, secret);
582
+ await this.commitAndClaim(dstSigner, options?.abortSignal, undefined, callbacks?.onDestinationCommitSent, callbacks?.onDestinationClaimSent, options?.secret);
534
583
  } else {
535
584
  if(this._state===FromBTCLNSwapState.PR_PAID) {
536
585
  await this.commit(dstSigner, options?.abortSignal, undefined, callbacks?.onDestinationCommitSent);
537
586
  if(options?.delayBetweenCommitAndClaimSeconds!=null) await timeoutPromise(options.delayBetweenCommitAndClaimSeconds * 1000, options?.abortSignal);
538
587
  }
539
588
  if(this._state===FromBTCLNSwapState.CLAIM_COMMITED) {
540
- await this.claim(dstSigner, options?.abortSignal, callbacks?.onDestinationClaimSent, secret);
589
+ await this.claim(dstSigner, options?.abortSignal, callbacks?.onDestinationClaimSent, options?.secret);
541
590
  }
542
591
  }
543
592
  }
@@ -546,6 +595,8 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
546
595
  if(this._state===FromBTCLNSwapState.CLAIM_CLAIMED) {
547
596
  if(callbacks?.onSwapSettled!=null) callbacks.onSwapSettled(this.getOutputTxId()!);
548
597
  }
598
+
599
+ return true;
549
600
  }
550
601
 
551
602
  /**
@@ -555,10 +606,13 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
555
606
  * @param options.skipChecks Skip checks like making sure init signature is still valid and swap
556
607
  * wasn't commited yet (this is handled on swap creation, if you commit right after quoting, you
557
608
  * can use `skipChecks=true`)
558
- * @param secret A swap secret to use for the claim transaction, generally only needed if the swap
609
+ * @param options.secret A swap secret to use for the claim transaction, generally only needed if the swap
559
610
  * was recovered from on-chain data, or the pre-image was generated outside the SDK
560
611
  */
561
- async txsExecute(options?: { skipChecks?: boolean }, secret?: string) {
612
+ async txsExecute(options?: {
613
+ skipChecks?: boolean,
614
+ secret?: string
615
+ }) {
562
616
  if(this._state===FromBTCLNSwapState.PR_CREATED) {
563
617
  if(!await this._verifyQuoteValid()) throw new Error("Quote already expired or close to expiry!");
564
618
  return [
@@ -580,7 +634,7 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
580
634
  if(this._state===FromBTCLNSwapState.PR_PAID) {
581
635
  if(!await this._verifyQuoteValid()) throw new Error("Quote already expired or close to expiry!");
582
636
  const txsCommit = await this.txsCommit(options?.skipChecks);
583
- const txsClaim = await this._txsClaim(undefined, secret);
637
+ const txsClaim = await this._txsClaim(undefined, options?.secret);
584
638
  return [
585
639
  {
586
640
  name: "Commit" as const,
@@ -598,7 +652,7 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
598
652
  }
599
653
 
600
654
  if(this._state===FromBTCLNSwapState.CLAIM_COMMITED) {
601
- const txsClaim = await this.txsClaim(undefined, secret);
655
+ const txsClaim = await this.txsClaim(undefined, options?.secret);
602
656
  return [
603
657
  {
604
658
  name: "Claim" as const,
@@ -612,6 +666,27 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
612
666
  throw new Error("Invalid swap state to obtain execution txns, required PR_CREATED, PR_PAID or CLAIM_COMMITED");
613
667
  }
614
668
 
669
+ /**
670
+ * @inheritDoc
671
+ *
672
+ * @param options
673
+ * @param options.skipChecks Skip checks like making sure init signature is still valid and swap
674
+ * wasn't commited yet (this is handled on swap creation, if you commit right after quoting, you
675
+ * can use `skipChecks=true`)
676
+ * @param options.secret A swap secret to use for the claim transaction, generally only needed if the swap
677
+ * was recovered from on-chain data, or the pre-image was generated outside the SDK
678
+ */
679
+ async getCurrentActions(options?: {
680
+ skipChecks?: boolean,
681
+ secret?: string
682
+ }): Promise<SwapExecutionAction<T>[]> {
683
+ try {
684
+ return await this.txsExecute(options);
685
+ } catch (e) {
686
+ return [];
687
+ }
688
+ }
689
+
615
690
 
616
691
  //////////////////////////////
617
692
  //// Payment
@@ -1387,4 +1462,4 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
1387
1462
  }
1388
1463
  }
1389
1464
 
1390
- }
1465
+ }
@@ -33,6 +33,8 @@ import {AllOptional} from "../../../../utils/TypeUtils";
33
33
  import {sha256} from "@noble/hashes/sha2";
34
34
 
35
35
  export type FromBTCLNOptions = {
36
+ paymentHash?: Buffer,
37
+ description?: string,
36
38
  descriptionHash?: Buffer,
37
39
  unsafeSkipLnNodeCheck?: boolean
38
40
  };
@@ -186,6 +188,9 @@ export class FromBTCLNWrapper<
186
188
  if(options.descriptionHash!=null && decodedPr.tagsObject.purpose_commit_hash!==options.descriptionHash.toString("hex"))
187
189
  throw new IntermediaryError("Invalid pr returned - description hash");
188
190
 
191
+ if(options.description!=null && decodedPr.tagsObject.description!==options.description)
192
+ throw new IntermediaryError("Invalid pr returned - description");
193
+
189
194
  if(
190
195
  decodedPr.tagsObject.payment_hash==null ||
191
196
  !Buffer.from(decodedPr.tagsObject.payment_hash, "hex").equals(paymentHash)
@@ -231,13 +236,27 @@ export class FromBTCLNWrapper<
231
236
  quote: Promise<FromBTCLNSwap<T>>,
232
237
  intermediary: Intermediary
233
238
  }[] {
239
+ if(!this.isInitialized) throw new Error("Not initialized, call init() first!");
240
+
234
241
  if(options==null) options = {};
235
242
  options.unsafeSkipLnNodeCheck ??= this._options.unsafeSkipLnNodeCheck;
236
243
 
244
+ if(options.paymentHash!=null && options.paymentHash.length!==32)
245
+ throw new UserError("Invalid payment hash length, must be exactly 32 bytes!");
246
+
237
247
  if(options.descriptionHash!=null && options.descriptionHash.length!==32)
238
248
  throw new UserError("Invalid description hash length");
239
249
 
240
- const {secret, paymentHash} = this.getSecretAndHash();
250
+ if(options.description!=null && Buffer.byteLength(options.description, "utf8") > 500)
251
+ throw new UserError("Invalid description length");
252
+
253
+ let secret: Buffer | undefined;
254
+ let paymentHash: Buffer;
255
+ if(options?.paymentHash!=null) {
256
+ paymentHash = options.paymentHash;
257
+ } else {
258
+ ({secret, paymentHash} = this.getSecretAndHash());
259
+ }
241
260
  const claimHash = this._contract.getHashForHtlc(paymentHash);
242
261
 
243
262
  const nativeTokenAddress = this._chain.getNativeCurrencyAddress();
@@ -267,6 +286,7 @@ export class FromBTCLNWrapper<
267
286
  amount: amountData.amount,
268
287
  claimer: recipient,
269
288
  token: amountData.token.toString(),
289
+ description: options?.description,
270
290
  descriptionHash: options?.descriptionHash,
271
291
  exactOut: !amountData.exactIn,
272
292
  feeRate: throwIfUndefined(_preFetches.feeRatePromise),
@@ -311,7 +331,7 @@ export class FromBTCLNWrapper<
311
331
  resp.securityDeposit, 0n, nativeTokenAddress
312
332
  ),
313
333
  pr: resp.pr,
314
- secret: secret.toString("hex"),
334
+ secret: secret?.toString("hex"),
315
335
  exactIn: amountData.exactIn ?? true
316
336
  } as FromBTCLNSwapInit<T["Data"]>);
317
337
  await quote._save();
@@ -336,6 +356,7 @@ export class FromBTCLNWrapper<
336
356
  * @param lnurl LNURL-withdraw link to pull the funds from
337
357
  * @param amountData Amount, token and exact input/output data for to swap
338
358
  * @param lps An array of intermediaries (LPs) to get the quotes from
359
+ * @param options Optional additional quote options
339
360
  * @param additionalParams Optional additional parameters sent to the LP when creating the swap
340
361
  * @param abortSignal Abort signal
341
362
  */
@@ -344,6 +365,7 @@ export class FromBTCLNWrapper<
344
365
  lnurl: string | LNURLWithdrawParamsWithUrl,
345
366
  amountData: AmountData,
346
367
  lps: Intermediary[],
368
+ options?: FromBTCLNOptions,
347
369
  additionalParams?: Record<string, any>,
348
370
  abortSignal?: AbortSignal
349
371
  ): Promise<{
@@ -352,6 +374,9 @@ export class FromBTCLNWrapper<
352
374
  }[]> {
353
375
  if(!this.isInitialized) throw new Error("Not initialized, call init() first!");
354
376
 
377
+ if(options?.paymentHash!=null && options.paymentHash.length!==32)
378
+ throw new UserError("Invalid payment hash length, must be exactly 32 bytes!");
379
+
355
380
  const abortController = extendAbortController(abortSignal);
356
381
  const preFetches = {
357
382
  pricePrefetchPromise: this.preFetchPrice(amountData, abortController.signal),
@@ -383,7 +408,7 @@ export class FromBTCLNWrapper<
383
408
  if((amount * 105n / 100n) > max) throw new UserError("Amount more than LNURL-withdraw maximum");
384
409
  }
385
410
 
386
- return this.create(recipient, amountData, lps, undefined, additionalParams, abortSignal, preFetches).map(data => {
411
+ return this.create(recipient, amountData, lps, options, additionalParams, abortSignal, preFetches).map(data => {
387
412
  return {
388
413
  quote: data.quote.then(quote => {
389
414
  quote._setLNURLData(