@atomiqlabs/chain-solana 13.3.0 → 13.5.6

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 (54) hide show
  1. package/dist/index.d.ts +2 -2
  2. package/dist/index.js +2 -2
  3. package/dist/solana/SolanaChainType.d.ts +1 -1
  4. package/dist/solana/SolanaChains.d.ts +5 -2
  5. package/dist/solana/SolanaChains.js +25 -13
  6. package/dist/solana/SolanaInitializer.d.ts +30 -4
  7. package/dist/solana/SolanaInitializer.js +105 -15
  8. package/dist/solana/btcrelay/SolanaBtcRelay.d.ts +4 -2
  9. package/dist/solana/btcrelay/SolanaBtcRelay.js +7 -1
  10. package/dist/solana/chain/SolanaAction.d.ts +1 -1
  11. package/dist/solana/chain/SolanaAction.js +2 -2
  12. package/dist/solana/chain/SolanaChainInterface.d.ts +6 -1
  13. package/dist/solana/chain/SolanaChainInterface.js +30 -0
  14. package/dist/solana/events/SolanaChainEvents.d.ts +5 -1
  15. package/dist/solana/events/SolanaChainEvents.js +16 -6
  16. package/dist/solana/events/SolanaChainEventsBrowser.d.ts +39 -16
  17. package/dist/solana/events/SolanaChainEventsBrowser.js +96 -61
  18. package/dist/solana/swaps/SolanaSwapData.d.ts +50 -5
  19. package/dist/solana/swaps/SolanaSwapData.js +52 -8
  20. package/dist/solana/swaps/SolanaSwapModule.d.ts +4 -3
  21. package/dist/solana/swaps/SolanaSwapProgram.d.ts +12 -6
  22. package/dist/solana/swaps/SolanaSwapProgram.js +73 -47
  23. package/dist/solana/swaps/modules/SwapClaim.js +2 -0
  24. package/dist/solana/swaps/modules/SwapInit.d.ts +10 -5
  25. package/dist/solana/swaps/modules/SwapInit.js +222 -85
  26. package/dist/solana/swaps/modules/SwapRefund.d.ts +8 -2
  27. package/dist/solana/swaps/modules/SwapRefund.js +38 -22
  28. package/dist/solana/swaps/v1/programIdl.json +945 -0
  29. package/dist/solana/swaps/v1/programTypes.d.ts +943 -0
  30. package/dist/solana/swaps/v1/programTypes.js +945 -0
  31. package/dist/solana/swaps/v2/programIdl.json +952 -0
  32. package/dist/solana/swaps/v2/programTypes.d.ts +950 -0
  33. package/dist/solana/swaps/v2/programTypes.js +952 -0
  34. package/package.json +2 -2
  35. package/src/index.ts +2 -2
  36. package/src/solana/SolanaChainType.ts +2 -2
  37. package/src/solana/SolanaChains.ts +29 -14
  38. package/src/solana/SolanaInitializer.ts +147 -25
  39. package/src/solana/btcrelay/SolanaBtcRelay.ts +10 -2
  40. package/src/solana/chain/SolanaAction.ts +2 -2
  41. package/src/solana/chain/SolanaChainInterface.ts +35 -1
  42. package/src/solana/events/SolanaChainEvents.ts +22 -11
  43. package/src/solana/events/SolanaChainEventsBrowser.ts +110 -67
  44. package/src/solana/swaps/SolanaSwapData.ts +95 -11
  45. package/src/solana/swaps/SolanaSwapModule.ts +5 -3
  46. package/src/solana/swaps/SolanaSwapProgram.ts +87 -43
  47. package/src/solana/swaps/modules/SolanaLpVault.ts +2 -2
  48. package/src/solana/swaps/modules/SwapClaim.ts +3 -1
  49. package/src/solana/swaps/modules/SwapInit.ts +227 -99
  50. package/src/solana/swaps/modules/SwapRefund.ts +38 -20
  51. package/src/solana/swaps/v2/programIdl.json +952 -0
  52. package/src/solana/swaps/v2/programTypes.ts +1899 -0
  53. /package/src/solana/swaps/{programIdl.json → v1/programIdl.json} +0 -0
  54. /package/src/solana/swaps/{programTypes.ts → v1/programTypes.ts} +0 -0
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SolanaSwapData = exports.isSerializedData = void 0;
3
+ exports.SolanaSwapDataV2 = exports.SolanaSwapDataV1 = exports.SolanaSwapData = exports.isSerializedData = void 0;
4
4
  const web3_js_1 = require("@solana/web3.js");
5
5
  const BN = require("bn.js");
6
6
  const base_1 = require("@atomiqlabs/base");
@@ -25,6 +25,7 @@ class SolanaSwapData extends base_1.SwapData {
25
25
  super();
26
26
  if (!isSerializedData(data)) {
27
27
  this.programId = data.programId;
28
+ this.version = data.version;
28
29
  this.offerer = data.offerer;
29
30
  this.claimer = data.claimer;
30
31
  this.token = data.token;
@@ -42,9 +43,11 @@ class SolanaSwapData extends base_1.SwapData {
42
43
  this.securityDeposit = data.securityDeposit;
43
44
  this.claimerBounty = data.claimerBounty;
44
45
  this.txoHash = data.txoHash;
46
+ this.offererInitializer = data.offererInitializer;
45
47
  }
46
48
  else {
47
49
  this.programId = new web3_js_1.PublicKey(data.programId ?? "4hfUykhqmD7ZRvNh1HuzVKEY7ToENixtdUKZspNDCrEM");
50
+ this.version = data.version ?? "v1";
48
51
  this.offerer = new web3_js_1.PublicKey(data.offerer);
49
52
  this.claimer = new web3_js_1.PublicKey(data.claimer);
50
53
  this.token = new web3_js_1.PublicKey(data.token);
@@ -62,6 +65,7 @@ class SolanaSwapData extends base_1.SwapData {
62
65
  this.securityDeposit = new BN(data.securityDeposit);
63
66
  this.claimerBounty = new BN(data.claimerBounty);
64
67
  this.txoHash = data.txoHash;
68
+ this.offererInitializer = data.offererInitializer;
65
69
  }
66
70
  }
67
71
  /**
@@ -100,6 +104,7 @@ class SolanaSwapData extends base_1.SwapData {
100
104
  return {
101
105
  type: "sol",
102
106
  programId: this.programId?.toBase58(),
107
+ version: this.version,
103
108
  offerer: this.offerer?.toBase58(),
104
109
  claimer: this.claimer?.toBase58(),
105
110
  token: this.token?.toBase58(),
@@ -116,7 +121,8 @@ class SolanaSwapData extends base_1.SwapData {
116
121
  claimerAta: this.claimerAta?.toBase58(),
117
122
  securityDeposit: this.securityDeposit?.toString(10),
118
123
  claimerBounty: this.claimerBounty?.toString(10),
119
- txoHash: this.txoHash
124
+ txoHash: this.txoHash,
125
+ offererInitializer: this.offererInitializer
120
126
  };
121
127
  }
122
128
  /**
@@ -282,7 +288,8 @@ class SolanaSwapData extends base_1.SwapData {
282
288
  (this.claimerAta == null || account.claimerAta.equals(this.claimerAta)) &&
283
289
  account.mint.equals(this.token) &&
284
290
  this.claimerBounty.eq(account.claimerBounty) &&
285
- this.securityDeposit.eq(account.securityDeposit);
291
+ this.securityDeposit.eq(account.securityDeposit) &&
292
+ (this.offererInitializer == null || account.offererInitializer === this.offererInitializer);
286
293
  }
287
294
  /**
288
295
  * @inheritDoc
@@ -304,6 +311,14 @@ class SolanaSwapData extends base_1.SwapData {
304
311
  if (!this.offererAta.equals(other.offererAta))
305
312
  return false;
306
313
  }
314
+ if (this.offererInitializer == null && other.offererInitializer != null)
315
+ return false;
316
+ if (this.offererInitializer != null && other.offererInitializer == null)
317
+ return false;
318
+ if (this.offererInitializer != null && other.offererInitializer != null) {
319
+ if (this.offererInitializer !== other.offererInitializer)
320
+ return false;
321
+ }
307
322
  return other.kind === this.kind &&
308
323
  other.confirmations === this.confirmations &&
309
324
  this.nonce.eq(other.nonce) &&
@@ -323,11 +338,12 @@ class SolanaSwapData extends base_1.SwapData {
323
338
  * Converts initialize instruction data into {@link SolanaSwapData}.
324
339
  *
325
340
  * @param programId
341
+ * @param version
326
342
  * @param initIx Decoded initialize instruction
327
343
  * @param txoHash Parsed txo hash hint from initialize event
328
344
  * @returns Converted and parsed swap data
329
345
  */
330
- static fromInstruction(programId, initIx, txoHash) {
346
+ static fromInstruction(programId, version, initIx, txoHash) {
331
347
  const paymentHash = buffer_1.Buffer.from(initIx.data.swapData.hash);
332
348
  let securityDeposit = new BN(0);
333
349
  let claimerBounty = new BN(0);
@@ -337,8 +353,14 @@ class SolanaSwapData extends base_1.SwapData {
337
353
  securityDeposit = initIx.data.securityDeposit;
338
354
  claimerBounty = initIx.data.claimerBounty;
339
355
  }
356
+ if (version !== "v1" && initIx.name === "offererInitializePayIn") {
357
+ payIn = true;
358
+ securityDeposit = initIx.data.securityDeposit;
359
+ claimerBounty = initIx.data.claimerBounty;
360
+ }
340
361
  return new SolanaSwapData({
341
362
  programId,
363
+ version,
342
364
  offerer: initIx.accounts.offerer,
343
365
  claimer: initIx.accounts.claimer,
344
366
  token: initIx.accounts.mint,
@@ -355,19 +377,22 @@ class SolanaSwapData extends base_1.SwapData {
355
377
  claimerAta: initIx.data.swapData.payOut ? initIx.accounts.claimerAta : web3_js_1.PublicKey.default,
356
378
  securityDeposit,
357
379
  claimerBounty,
358
- txoHash
380
+ txoHash,
381
+ offererInitializer: initIx.accounts.initializer != null ? initIx.accounts.initializer.equals(initIx.accounts.offerer) : undefined
359
382
  });
360
383
  }
361
384
  /**
362
385
  * Deserializes swap data from an on-chain escrow account state.
363
386
  *
364
387
  * @param programId
388
+ * @param version
365
389
  * @param account Escrow account state as returned by Anchor
366
390
  */
367
- static fromEscrowState(programId, account) {
391
+ static fromEscrowState(programId, version, account) {
368
392
  const data = account.data;
369
393
  return new SolanaSwapData({
370
394
  programId,
395
+ version,
371
396
  offerer: account.offerer,
372
397
  claimer: account.claimer,
373
398
  token: account.mint,
@@ -383,7 +408,8 @@ class SolanaSwapData extends base_1.SwapData {
383
408
  offererAta: account.offererAta,
384
409
  claimerAta: account.claimerAta,
385
410
  securityDeposit: account.securityDeposit,
386
- claimerBounty: account.claimerBounty
411
+ claimerBounty: account.claimerBounty,
412
+ offererInitializer: account.offererInitializer ?? undefined
387
413
  });
388
414
  }
389
415
  /**
@@ -464,7 +490,9 @@ class SolanaSwapData extends base_1.SwapData {
464
490
  offererAta: this.offererAta == null || this.offererAta.equals(web3_js_1.PublicKey.default) ? null : this.offererAta.toString(),
465
491
  claimerUserData: SolanaSwapProgram_1.SolanaSwapProgram._SwapUserVault(this.programId, this.claimer, this.token).toString(),
466
492
  offererUserData: SolanaSwapProgram_1.SolanaSwapProgram._SwapUserVault(this.programId, this.offerer, this.token).toString(),
467
- initializer: this.isPayIn() ? this.offerer.toString() : this.claimer.toString(),
493
+ initializer: this.offererInitializer != null
494
+ ? (this.offererInitializer ? this.offerer.toString() : this.claimer.toString())
495
+ : (this.isPayIn() ? this.offerer.toString() : this.claimer.toString()),
468
496
  escrowState: SolanaSwapProgram_1.SolanaSwapProgram._SwapEscrowState(this.programId, buffer_1.Buffer.from(this.paymentHash, "hex")).toString(),
469
497
  mint: this.token.toString(),
470
498
  vault: SolanaSwapProgram_1.SolanaSwapProgram._SwapVault(this.programId, this.token).toString(),
@@ -488,4 +516,20 @@ class SolanaSwapData extends base_1.SwapData {
488
516
  }
489
517
  }
490
518
  exports.SolanaSwapData = SolanaSwapData;
519
+ class SolanaSwapDataV1 extends SolanaSwapData {
520
+ constructor(data) {
521
+ super(data);
522
+ if (this.version !== "v1")
523
+ throw new Error(`Invalid swap data version, expected v1, got ${this.version}`);
524
+ }
525
+ }
526
+ exports.SolanaSwapDataV1 = SolanaSwapDataV1;
527
+ class SolanaSwapDataV2 extends SolanaSwapData {
528
+ constructor(data) {
529
+ super(data);
530
+ if (this.version !== "v2")
531
+ throw new Error(`Invalid swap data version, expected v2, got ${this.version}`);
532
+ }
533
+ }
534
+ exports.SolanaSwapDataV2 = SolanaSwapDataV2;
491
535
  base_1.SwapData.deserializers["sol"] = SolanaSwapData;
@@ -1,10 +1,11 @@
1
1
  import { SolanaSwapProgram } from "./SolanaSwapProgram";
2
2
  import { Program } from "@coral-xyz/anchor";
3
- import { SwapProgram } from "./programTypes";
3
+ import { SwapProgram } from "./v1/programTypes";
4
4
  import { SolanaProgramModule } from "../program/SolanaProgramModule";
5
5
  import { SolanaChainInterface } from "../chain/SolanaChainInterface";
6
- export declare class SolanaSwapModule extends SolanaProgramModule<SwapProgram> {
6
+ import { SwapProgramV2 } from "./v2/programTypes";
7
+ export declare class SolanaSwapModule extends SolanaProgramModule<SwapProgram | SwapProgramV2> {
7
8
  protected readonly program: SolanaSwapProgram;
8
- protected readonly swapProgram: Program<SwapProgram>;
9
+ protected readonly swapProgram: Program<SwapProgram | SwapProgramV2>;
9
10
  constructor(chainInterface: SolanaChainInterface, program: SolanaSwapProgram);
10
11
  }
@@ -1,11 +1,12 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
3
  import { SolanaSwapData } from "./SolanaSwapData";
4
+ import { Program } from "@coral-xyz/anchor";
4
5
  import { PublicKey } from "@solana/web3.js";
5
6
  import { SolanaBtcRelay } from "../btcrelay/SolanaBtcRelay";
6
- import { IStorageManager, SwapContract, ChainSwapType, IntermediaryReputationType, TransactionConfirmationOptions, SignatureData, RelaySynchronizer, SwapCommitState, SwapCommitStateType } from "@atomiqlabs/base";
7
+ import { IStorageManager, SwapContract, ChainSwapType, IntermediaryReputationType, TransactionConfirmationOptions, SignatureData, RelaySynchronizer, SwapCommitState, SwapCommitStateType, BitcoinNetwork } from "@atomiqlabs/base";
7
8
  import { SolanaBtcStoredHeader } from "../btcrelay/headers/SolanaBtcStoredHeader";
8
- import { SwapProgram } from "./programTypes";
9
+ import { SwapProgram } from "./v1/programTypes";
9
10
  import { SolanaChainInterface } from "../chain/SolanaChainInterface";
10
11
  import { SolanaProgramBase } from "../program/SolanaProgramBase";
11
12
  import { SolanaTx } from "../chain/modules/SolanaTransactions";
@@ -13,16 +14,21 @@ import { SolanaPreFetchData, SolanaPreFetchVerification } from "./modules/SwapIn
13
14
  import { SolanaDataAccount, StoredDataAccount } from "./modules/SolanaDataAccount";
14
15
  import { Buffer } from "buffer";
15
16
  import { SolanaSigner } from "../wallet/SolanaSigner";
17
+ import { SwapProgramV2 } from "./v2/programTypes";
18
+ export declare function isSwapProgramV1(obj: any): obj is Program<SwapProgram>;
19
+ export declare function isSwapProgramV2(obj: any): obj is Program<SwapProgramV2>;
16
20
  /**
17
21
  * Solana swap (escrow manager) program representation handling PrTLC (on-chain) and HTLC (lightning) based swaps.
18
22
  *
19
23
  * @category Swaps
20
24
  */
21
- export declare class SolanaSwapProgram extends SolanaProgramBase<SwapProgram> implements SwapContract<SolanaSwapData, SolanaTx, SolanaPreFetchData, SolanaPreFetchVerification, SolanaSigner, "SOLANA"> {
25
+ export declare class SolanaSwapProgram<Version extends "v1" | "v2" = "v1" | "v2"> extends SolanaProgramBase<SwapProgram | SwapProgramV2> implements SwapContract<SolanaSwapData, SolanaTx, SolanaPreFetchData, SolanaPreFetchVerification, SolanaSigner, "SOLANA"> {
22
26
  /**
23
27
  * Rent-exempt amount (lamports) for escrow state accounts.
24
28
  */
25
- readonly ESCROW_STATE_RENT_EXEMPT = 2658720;
29
+ readonly ESCROW_STATE_RENT_EXEMPT: number;
30
+ readonly version: Version;
31
+ readonly supportsInitWithoutClaimer: Version extends "v1" ? false : true;
26
32
  /**
27
33
  * PDA of the swap vault authority.
28
34
  * @internal
@@ -97,7 +103,7 @@ export declare class SolanaSwapProgram extends SolanaProgramBase<SwapProgram> im
97
103
  * @internal
98
104
  */
99
105
  readonly _DataAccount: SolanaDataAccount;
100
- constructor(chainInterface: SolanaChainInterface, btcRelay: SolanaBtcRelay<any>, storage: IStorageManager<StoredDataAccount>, programAddress?: string);
106
+ constructor(chainInterface: SolanaChainInterface, btcRelay: SolanaBtcRelay<any>, storage: IStorageManager<StoredDataAccount>, programAddress?: string, bitcoinNetwork?: BitcoinNetwork, version?: Version);
101
107
  /**
102
108
  * @inheritDoc
103
109
  */
@@ -168,7 +174,7 @@ export declare class SolanaSwapProgram extends SolanaProgramBase<SwapProgram> im
168
174
  /**
169
175
  * @inheritDoc
170
176
  */
171
- isExpired(signer: string, data: SolanaSwapData): Promise<boolean>;
177
+ isExpired(signer: string, data: SolanaSwapData, refundSide?: boolean): Promise<boolean>;
172
178
  /**
173
179
  * @inheritDoc
174
180
  */
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SolanaSwapProgram = void 0;
3
+ exports.SolanaSwapProgram = exports.isSwapProgramV2 = exports.isSwapProgramV1 = void 0;
4
4
  const SolanaSwapData_1 = require("./SolanaSwapData");
5
5
  const web3_js_1 = require("@solana/web3.js");
6
6
  const sha2_1 = require("@noble/hashes/sha2");
7
- const programIdl = require("./programIdl.json");
7
+ const programIdlV1 = require("./v1/programIdl.json");
8
+ const programIdlV2 = require("./v2/programIdl.json");
8
9
  const base_1 = require("@atomiqlabs/base");
9
10
  const spl_token_1 = require("@solana/spl-token");
10
11
  const SolanaProgramBase_1 = require("../program/SolanaProgramBase");
@@ -17,6 +18,15 @@ const buffer_1 = require("buffer");
17
18
  const Utils_1 = require("../../utils/Utils");
18
19
  const SolanaTokens_1 = require("../chain/modules/SolanaTokens");
19
20
  const BN = require("bn.js");
21
+ const SolanaChains_1 = require("../SolanaChains");
22
+ function isSwapProgramV1(obj) {
23
+ return obj.idl.version === "0.1.0";
24
+ }
25
+ exports.isSwapProgramV1 = isSwapProgramV1;
26
+ function isSwapProgramV2(obj) {
27
+ return obj.idl.version === "0.2.0";
28
+ }
29
+ exports.isSwapProgramV2 = isSwapProgramV2;
20
30
  function toPublicKeyOrNull(str) {
21
31
  return str == null ? undefined : new web3_js_1.PublicKey(str);
22
32
  }
@@ -27,15 +37,13 @@ const MAX_PARALLEL_COMMIT_STATUS_CHECKS = 5;
27
37
  * @category Swaps
28
38
  */
29
39
  class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
30
- constructor(chainInterface, btcRelay, storage, programAddress) {
31
- super(chainInterface, programIdl, programAddress);
32
- ////////////////////////
33
- //// Constants
34
- /**
35
- * Rent-exempt amount (lamports) for escrow state accounts.
36
- */
37
- this.ESCROW_STATE_RENT_EXEMPT = 2658720;
38
- this._SwapVaultAuthority = SolanaSwapProgram._SwapVaultAuthority(this.program.programId);
40
+ constructor(chainInterface, btcRelay, storage, programAddress, bitcoinNetwork, version) {
41
+ version ?? (version = "v1");
42
+ if (bitcoinNetwork != null && programAddress == null) {
43
+ programAddress = SolanaChains_1.SolanaChains[bitcoinNetwork]?.addresses[version ?? "v1"]?.swapContract;
44
+ }
45
+ super(chainInterface, version === "v1" ? programIdlV1 : programIdlV2, programAddress);
46
+ this._SwapVaultAuthority = SolanaSwapProgram._SwapVaultAuthority(this.program.programId); // Only necessary for V1 program
39
47
  this._SwapVault = SolanaSwapProgram._SwapVault.bind(this, this.program.programId);
40
48
  this._SwapUserVault = SolanaSwapProgram._SwapUserVault.bind(this, this.program.programId);
41
49
  this._SwapEscrowState = SolanaSwapProgram._SwapEscrowState.bind(this, this.program.programId);
@@ -69,7 +77,10 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
69
77
  * Authorization grace period in seconds.
70
78
  * @internal
71
79
  */
72
- this._authGracePeriod = 5 * 60;
80
+ this._authGracePeriod = 30;
81
+ this.version = version;
82
+ this.ESCROW_STATE_RENT_EXEMPT = this.version === "v1" ? 2658720 : 2665680;
83
+ this.supportsInitWithoutClaimer = (this.version !== "v1");
73
84
  this.Init = new SwapInit_1.SwapInit(chainInterface, this);
74
85
  this.Refund = new SwapRefund_1.SwapRefund(chainInterface, this);
75
86
  this.Claim = new SwapClaim_1.SwapClaim(chainInterface, this, btcRelay);
@@ -118,7 +129,7 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
118
129
  * @inheritDoc
119
130
  */
120
131
  isValidInitAuthorization(signer, swapData, sig, feeRate, preFetchedData) {
121
- return this.Init.isSignatureValid(signer, swapData, sig.timeout, sig.prefix, sig.signature, feeRate, preFetchedData);
132
+ return this.Init.isSignatureValid(new web3_js_1.PublicKey(signer), swapData, sig.timeout, sig.prefix, sig.signature, feeRate, preFetchedData);
122
133
  }
123
134
  /**
124
135
  * @inheritDoc
@@ -181,22 +192,24 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
181
192
  /**
182
193
  * @inheritDoc
183
194
  */
184
- isExpired(signer, data) {
195
+ isExpired(signer, data, refundSide) {
185
196
  let currentTimestamp = new BN(Math.floor(Date.now() / 1000));
186
- if (data.isClaimer(signer))
197
+ if (data.isClaimer(signer) && !refundSide) {
187
198
  currentTimestamp = currentTimestamp.add(new BN(this.claimGracePeriod));
188
- if (data.isOfferer(signer))
199
+ }
200
+ else {
189
201
  currentTimestamp = currentTimestamp.sub(new BN(this.refundGracePeriod));
202
+ }
190
203
  return Promise.resolve(data.expiry.lt(currentTimestamp));
191
204
  }
192
205
  /**
193
206
  * @inheritDoc
194
207
  */
195
208
  async isRequestRefundable(signer, data) {
196
- //Swap can only be refunded by the offerer
197
- if (!data.isOfferer(signer))
209
+ //V1 Swap can only be refunded by the offerer
210
+ if (isSwapProgramV1(this.program) && !data.isOfferer(signer))
198
211
  return false;
199
- if (!(await this.isExpired(signer, data)))
212
+ if (!(await this.isExpired(signer, data, true)))
200
213
  return false;
201
214
  return await this.isCommited(data);
202
215
  }
@@ -235,11 +248,26 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
235
248
  this.program.account.escrowState.fetchNullable(escrowStateKey),
236
249
  this.isExpired(signer, data)
237
250
  ]);
251
+ const getInitTxId = (0, Utils_1.onceAsync)(async () => {
252
+ const txId = await this._Events.findInEvents(escrowStateKey, async (event, tx) => {
253
+ if (event.name === "InitializeEvent") {
254
+ const paymentHash = buffer_1.Buffer.from(event.data.hash).toString("hex");
255
+ if (paymentHash !== data.paymentHash)
256
+ return null;
257
+ if (!event.data.sequence.eq(data.sequence))
258
+ return null;
259
+ return tx.transaction.signatures[0];
260
+ }
261
+ });
262
+ if (txId == null)
263
+ throw new Error("Initialize event not found!");
264
+ return txId;
265
+ });
238
266
  if (escrowState != null) {
239
267
  if (data.correctPDA(escrowState)) {
240
268
  if (data.isOfferer(signer) && isExpired)
241
- return { type: base_1.SwapCommitStateType.REFUNDABLE };
242
- return { type: base_1.SwapCommitStateType.COMMITED };
269
+ return { type: base_1.SwapCommitStateType.REFUNDABLE, getInitTxId };
270
+ return { type: base_1.SwapCommitStateType.COMMITED, getInitTxId };
243
271
  }
244
272
  if (data.isOfferer(signer) && isExpired)
245
273
  return { type: base_1.SwapCommitStateType.EXPIRED };
@@ -255,6 +283,7 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
255
283
  return null;
256
284
  return {
257
285
  type: base_1.SwapCommitStateType.PAID,
286
+ getInitTxId,
258
287
  getClaimTxId: () => Promise.resolve(tx.transaction.signatures[0]),
259
288
  getClaimResult: () => Promise.resolve(buffer_1.Buffer.from(event.data.secret).toString("hex")),
260
289
  getTxBlock: () => Promise.resolve({
@@ -271,6 +300,7 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
271
300
  return null;
272
301
  return {
273
302
  type: isExpired ? base_1.SwapCommitStateType.EXPIRED : base_1.SwapCommitStateType.NOT_COMMITED,
303
+ getInitTxId,
274
304
  getRefundTxId: () => Promise.resolve(tx.transaction.signatures[0]),
275
305
  getTxBlock: () => Promise.resolve({
276
306
  blockHeight: tx.slot,
@@ -342,7 +372,7 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
342
372
  const account = await this.program.account.escrowState.fetchNullable(this._SwapEscrowState(paymentHashBuffer));
343
373
  if (account == null)
344
374
  return null;
345
- return SolanaSwapData_1.SolanaSwapData.fromEscrowState(this.program.programId, account);
375
+ return SolanaSwapData_1.SolanaSwapData.fromEscrowState(this.program.programId, this.version, account);
346
376
  }
347
377
  /**
348
378
  * @inheritDoc
@@ -377,7 +407,7 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
377
407
  continue;
378
408
  }
379
409
  swapsOpened[escrowHash] = {
380
- data: SolanaSwapData_1.SolanaSwapData.fromInstruction(this.program.programId, initIx, txoHash),
410
+ data: SolanaSwapData_1.SolanaSwapData.fromInstruction(this.program.programId, this.version, initIx, txoHash),
381
411
  getInitTxId: () => Promise.resolve(txSignature),
382
412
  getTxBlock: () => Promise.resolve({
383
413
  blockHeight: tx.slot,
@@ -392,6 +422,7 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
392
422
  init: foundSwapData,
393
423
  state: {
394
424
  type: base_1.SwapCommitStateType.PAID,
425
+ getInitTxId: foundSwapData?.getInitTxId,
395
426
  getClaimTxId: () => Promise.resolve(txSignature),
396
427
  getClaimResult: () => Promise.resolve(buffer_1.Buffer.from(event.data.secret).toString("hex")),
397
428
  getTxBlock: () => Promise.resolve({
@@ -409,6 +440,7 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
409
440
  init: foundSwapData,
410
441
  state: {
411
442
  type: isExpired ? base_1.SwapCommitStateType.EXPIRED : base_1.SwapCommitStateType.NOT_COMMITED,
443
+ getInitTxId: foundSwapData?.getInitTxId,
412
444
  getRefundTxId: () => Promise.resolve(txSignature),
413
445
  getTxBlock: () => Promise.resolve({
414
446
  blockHeight: tx.slot,
@@ -426,8 +458,8 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
426
458
  resultingSwaps[escrowHash] = {
427
459
  init: foundSwapData,
428
460
  state: foundSwapData.data.isOfferer(signer) && isExpired
429
- ? { type: base_1.SwapCommitStateType.REFUNDABLE }
430
- : { type: base_1.SwapCommitStateType.COMMITED }
461
+ ? { type: base_1.SwapCommitStateType.REFUNDABLE, getInitTxId: foundSwapData.getInitTxId }
462
+ : { type: base_1.SwapCommitStateType.COMMITED, getInitTxId: foundSwapData.getInitTxId }
431
463
  };
432
464
  }
433
465
  return {
@@ -451,6 +483,7 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
451
483
  const { paymentHash, nonce, confirmations } = (0, Utils_1.fromClaimHash)(claimHash);
452
484
  const swapData = new SolanaSwapData_1.SolanaSwapData({
453
485
  programId: this.program.programId,
486
+ version: this.version,
454
487
  offerer: offererKey,
455
488
  claimer: claimerKey,
456
489
  token: tokenAddr,
@@ -525,31 +558,23 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
525
558
  * @inheritDoc
526
559
  */
527
560
  txsRefund(signer, swapData, check, initAta, feeRate) {
528
- if (!swapData.isOfferer(signer))
529
- throw new Error("Only offerer can refund on Solana");
530
- return this.Refund.txsRefund(swapData, check, initAta, feeRate);
561
+ return this.Refund.txsRefund(new web3_js_1.PublicKey(signer), swapData, check, initAta, feeRate);
531
562
  }
532
563
  /**
533
564
  * @inheritDoc
534
565
  */
535
566
  txsRefundWithAuthorization(signer, swapData, sig, check, initAta, feeRate) {
536
- if (!swapData.isOfferer(signer))
537
- throw new Error("Only offerer can refund on Solana");
538
- return this.Refund.txsRefundWithAuthorization(swapData, sig.timeout, sig.prefix, sig.signature, check, initAta, feeRate);
567
+ return this.Refund.txsRefundWithAuthorization(new web3_js_1.PublicKey(signer), swapData, sig.timeout, sig.prefix, sig.signature, check, initAta, feeRate);
539
568
  }
540
569
  /**
541
570
  * @inheritDoc
542
571
  */
543
572
  txsInit(sender, swapData, sig, skipChecks, feeRate) {
544
573
  if (swapData.isPayIn()) {
545
- if (!swapData.isOfferer(sender))
546
- throw new Error("Only offerer can create payIn=true swap");
547
- return this.Init.txsInitPayIn(swapData, sig.timeout, sig.prefix, sig.signature, skipChecks, feeRate);
574
+ return this.Init.txsInitPayIn(new web3_js_1.PublicKey(sender), swapData, sig.timeout, sig.prefix, sig.signature, skipChecks, feeRate);
548
575
  }
549
576
  else {
550
- if (!swapData.isClaimer(sender))
551
- throw new Error("Only claimer can create payIn=false swap");
552
- return this.Init.txsInit(swapData, sig.timeout, sig.prefix, sig.signature, skipChecks, feeRate);
577
+ return this.Init.txsInit(new web3_js_1.PublicKey(sender), swapData, sig.timeout, sig.prefix, sig.signature, skipChecks, feeRate);
553
578
  }
554
579
  }
555
580
  /**
@@ -605,14 +630,6 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
605
630
  * @inheritDoc
606
631
  */
607
632
  async init(signer, swapData, signature, skipChecks, txOptions) {
608
- if (swapData.isPayIn()) {
609
- if (!signer.getPublicKey().equals(swapData.offerer))
610
- throw new Error("Invalid signer provided!");
611
- }
612
- else {
613
- if (!signer.getPublicKey().equals(swapData.claimer))
614
- throw new Error("Invalid signer provided!");
615
- }
616
633
  const result = await this.txsInit(signer.getAddress(), swapData, signature, skipChecks, txOptions?.feeRate);
617
634
  const signatures = await this._Chain.sendAndConfirm(signer, result, txOptions?.waitForConfirmation, txOptions?.abortSignal);
618
635
  return signatures[signatures.length - 1];
@@ -624,7 +641,16 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
624
641
  if (!signer.getPublicKey().equals(swapData.claimer))
625
642
  throw new Error("Invalid signer provided!");
626
643
  const txsCommit = await this.txsInit(signer.getAddress(), swapData, signature, skipChecks, txOptions?.feeRate);
627
- const txsClaim = await this.Claim.txsClaimWithSecret(signer.getPublicKey(), swapData, secret, true, false, txOptions?.feeRate, true);
644
+ let txsClaim;
645
+ if (isSwapProgramV1(this.program)) {
646
+ // In V1 the initialize instruction has to contain the ATA initialization, hence we can skip checking it in claim
647
+ txsClaim = await this.Claim.txsClaimWithSecret(signer.getPublicKey(), swapData, secret, true, false, txOptions?.feeRate, true);
648
+ }
649
+ else {
650
+ // In V2 the initialize instruction doesn't necessarily contain the ATA initialization, hence the claim instruction needs to
651
+ // check and initialize the ATA if needed
652
+ txsClaim = await this.Claim.txsClaimWithSecret(signer.getPublicKey(), swapData, secret, true, true, txOptions?.feeRate, false);
653
+ }
628
654
  const signatures = await this._Chain.sendAndConfirm(signer, txsCommit.concat(txsClaim), txOptions?.waitForConfirmation, txOptions?.abortSignal);
629
655
  return [signatures[txsCommit.length - 1], signatures[signatures.length - 1]];
630
656
  }
@@ -725,7 +751,7 @@ exports.SolanaSwapProgram = SolanaSwapProgram;
725
751
  * PDA of the swap vault authority.
726
752
  * @internal
727
753
  */
728
- SolanaSwapProgram._SwapVaultAuthority = SolanaProgramBase_1.SolanaProgramBase._pda("authority");
754
+ SolanaSwapProgram._SwapVaultAuthority = SolanaProgramBase_1.SolanaProgramBase._pda("authority"); // Only necessary for V1 program
729
755
  /**
730
756
  * PDA helper for global token vault accounts.
731
757
  * @internal
@@ -14,6 +14,8 @@ class SwapClaim extends SolanaSwapModule_1.SolanaSwapModule {
14
14
  const isDataKey = typeof (secretOrDataKey) !== "string";
15
15
  const accounts = {
16
16
  signer,
17
+ offerer: swapData.offerer,
18
+ claimer: swapData.claimer,
17
19
  initializer: swapData.isPayIn() ? swapData.offerer : swapData.claimer,
18
20
  escrowState: this.program._SwapEscrowState(Buffer.from(swapData.paymentHash, "hex")),
19
21
  ixSysvar: web3_js_1.SYSVAR_INSTRUCTIONS_PUBKEY,
@@ -28,6 +28,7 @@ export declare class SwapInit extends SolanaSwapModule {
28
28
  /**
29
29
  * bare Init action based on the data passed in swapData
30
30
  *
31
+ * @param sender
31
32
  * @param swapData
32
33
  * @param timeout
33
34
  * @private
@@ -36,6 +37,7 @@ export declare class SwapInit extends SolanaSwapModule {
36
37
  /**
37
38
  * InitPayIn action which includes SOL to WSOL wrapping if indicated by the fee rate
38
39
  *
40
+ * @param signer
39
41
  * @param swapData
40
42
  * @param timeout
41
43
  * @param feeRate
@@ -46,6 +48,7 @@ export declare class SwapInit extends SolanaSwapModule {
46
48
  * InitNotPayIn action with additional createAssociatedTokenAccountIdempotentInstruction instruction, such that
47
49
  * a recipient ATA is created if it doesn't exist
48
50
  *
51
+ * @param sender
49
52
  * @param swapData
50
53
  * @param timeout
51
54
  * @private
@@ -135,7 +138,7 @@ export declare class SwapInit extends SolanaSwapModule {
135
138
  * @param preFetchedData
136
139
  * @public
137
140
  */
138
- isSignatureValid(sender: string, swapData: SolanaSwapData, timeout: string, prefix: string, signature: string, feeRate?: string, preFetchedData?: SolanaPreFetchVerification): Promise<Buffer>;
141
+ isSignatureValid(sender: PublicKey, swapData: SolanaSwapData, timeout: string, prefix: string, signature: string | null, feeRate?: string, preFetchedData?: SolanaPreFetchVerification): Promise<Buffer>;
139
142
  /**
140
143
  * Gets expiry of the provided signature data, this is a minimum of slot expiry & swap signature expiry
141
144
  *
@@ -144,7 +147,7 @@ export declare class SwapInit extends SolanaSwapModule {
144
147
  * @param preFetchedData
145
148
  * @public
146
149
  */
147
- getSignatureExpiry(timeout: string, signature: string, preFetchedData?: SolanaPreFetchVerification): Promise<number>;
150
+ getSignatureExpiry(timeout: string, signature: string | null, preFetchedData?: SolanaPreFetchVerification): Promise<number>;
148
151
  /**
149
152
  * Checks whether signature is expired for good (uses "finalized" slot)
150
153
  *
@@ -152,12 +155,13 @@ export declare class SwapInit extends SolanaSwapModule {
152
155
  * @param timeout
153
156
  * @public
154
157
  */
155
- isSignatureExpired(signature: string, timeout: string): Promise<boolean>;
158
+ isSignatureExpired(signature: string | null, timeout: string): Promise<boolean>;
156
159
  /**
157
160
  * Creates init transaction (InitPayIn) with a valid signature from an LP, also adds a SOL to WSOL wrapping ix to
158
161
  * the init transaction (if indicated by the fee rate) or adds the wrapping in a separate transaction (if no
159
162
  * indication in the fee rate)
160
163
  *
164
+ * @param sender
161
165
  * @param swapData swap to initialize
162
166
  * @param timeout init signature timeout
163
167
  * @param prefix init signature prefix
@@ -165,10 +169,11 @@ export declare class SwapInit extends SolanaSwapModule {
165
169
  * @param skipChecks whether to skip signature validity checks
166
170
  * @param feeRate fee rate to use for the transaction
167
171
  */
168
- txsInitPayIn(swapData: SolanaSwapData, timeout: string, prefix: string, signature: string, skipChecks?: boolean, feeRate?: string): Promise<SolanaTx[]>;
172
+ txsInitPayIn(sender: PublicKey, swapData: SolanaSwapData, timeout: string, prefix: string, signature: string, skipChecks?: boolean, feeRate?: string): Promise<SolanaTx[]>;
169
173
  /**
170
174
  * Creates init transactions (InitNotPayIn) with a valid signature from an intermediary
171
175
  *
176
+ * @param sender
172
177
  * @param swapData swap to initialize
173
178
  * @param timeout init signature timeout
174
179
  * @param prefix init signature prefix
@@ -176,7 +181,7 @@ export declare class SwapInit extends SolanaSwapModule {
176
181
  * @param skipChecks whether to skip signature validity checks
177
182
  * @param feeRate fee rate to use for the transaction
178
183
  */
179
- txsInit(swapData: SolanaSwapData, timeout: string, prefix: string, signature: string, skipChecks?: boolean, feeRate?: string): Promise<SolanaTx[]>;
184
+ txsInit(sender: PublicKey, swapData: SolanaSwapData, timeout: string, prefix: string, signature: string, skipChecks?: boolean, feeRate?: string): Promise<SolanaTx[]>;
180
185
  /**
181
186
  * Returns the fee rate to be used for a specific init transaction, also adding indication whether the WSOL ATA
182
187
  * should be initialized in the init transaction and/or current balance in the WSOL ATA