@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.
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/solana/SolanaChainType.d.ts +1 -1
- package/dist/solana/SolanaChains.d.ts +5 -2
- package/dist/solana/SolanaChains.js +25 -13
- package/dist/solana/SolanaInitializer.d.ts +30 -4
- package/dist/solana/SolanaInitializer.js +105 -15
- package/dist/solana/btcrelay/SolanaBtcRelay.d.ts +4 -2
- package/dist/solana/btcrelay/SolanaBtcRelay.js +7 -1
- package/dist/solana/chain/SolanaAction.d.ts +1 -1
- package/dist/solana/chain/SolanaAction.js +2 -2
- package/dist/solana/chain/SolanaChainInterface.d.ts +6 -1
- package/dist/solana/chain/SolanaChainInterface.js +30 -0
- package/dist/solana/events/SolanaChainEvents.d.ts +5 -1
- package/dist/solana/events/SolanaChainEvents.js +16 -6
- package/dist/solana/events/SolanaChainEventsBrowser.d.ts +39 -16
- package/dist/solana/events/SolanaChainEventsBrowser.js +96 -61
- package/dist/solana/swaps/SolanaSwapData.d.ts +50 -5
- package/dist/solana/swaps/SolanaSwapData.js +52 -8
- package/dist/solana/swaps/SolanaSwapModule.d.ts +4 -3
- package/dist/solana/swaps/SolanaSwapProgram.d.ts +12 -6
- package/dist/solana/swaps/SolanaSwapProgram.js +73 -47
- package/dist/solana/swaps/modules/SwapClaim.js +2 -0
- package/dist/solana/swaps/modules/SwapInit.d.ts +10 -5
- package/dist/solana/swaps/modules/SwapInit.js +222 -85
- package/dist/solana/swaps/modules/SwapRefund.d.ts +8 -2
- package/dist/solana/swaps/modules/SwapRefund.js +38 -22
- package/dist/solana/swaps/v1/programIdl.json +945 -0
- package/dist/solana/swaps/v1/programTypes.d.ts +943 -0
- package/dist/solana/swaps/v1/programTypes.js +945 -0
- package/dist/solana/swaps/v2/programIdl.json +952 -0
- package/dist/solana/swaps/v2/programTypes.d.ts +950 -0
- package/dist/solana/swaps/v2/programTypes.js +952 -0
- package/package.json +2 -2
- package/src/index.ts +2 -2
- package/src/solana/SolanaChainType.ts +2 -2
- package/src/solana/SolanaChains.ts +29 -14
- package/src/solana/SolanaInitializer.ts +147 -25
- package/src/solana/btcrelay/SolanaBtcRelay.ts +10 -2
- package/src/solana/chain/SolanaAction.ts +2 -2
- package/src/solana/chain/SolanaChainInterface.ts +35 -1
- package/src/solana/events/SolanaChainEvents.ts +22 -11
- package/src/solana/events/SolanaChainEventsBrowser.ts +110 -67
- package/src/solana/swaps/SolanaSwapData.ts +95 -11
- package/src/solana/swaps/SolanaSwapModule.ts +5 -3
- package/src/solana/swaps/SolanaSwapProgram.ts +87 -43
- package/src/solana/swaps/modules/SolanaLpVault.ts +2 -2
- package/src/solana/swaps/modules/SwapClaim.ts +3 -1
- package/src/solana/swaps/modules/SwapInit.ts +227 -99
- package/src/solana/swaps/modules/SwapRefund.ts +38 -20
- package/src/solana/swaps/v2/programIdl.json +952 -0
- package/src/solana/swaps/v2/programTypes.ts +1899 -0
- /package/src/solana/swaps/{programIdl.json → v1/programIdl.json} +0 -0
- /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.
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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
|