@atomiqlabs/chain-solana 13.2.4 → 13.4.1
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/solana/SolanaChains.d.ts +1 -0
- package/dist/solana/SolanaChains.js +4 -2
- package/dist/solana/chain/SolanaChainInterface.d.ts +2 -1
- package/dist/solana/chain/SolanaChainInterface.js +22 -0
- package/dist/solana/events/SolanaChainEventsBrowser.js +1 -1
- package/dist/solana/program/SolanaProgramBase.d.ts +17 -0
- package/dist/solana/program/SolanaProgramBase.js +9 -3
- package/dist/solana/swaps/SolanaSwapData.d.ts +13 -2
- package/dist/solana/swaps/SolanaSwapData.js +44 -2
- package/dist/solana/swaps/SolanaSwapProgram.d.ts +4 -0
- package/dist/solana/swaps/SolanaSwapProgram.js +29 -24
- package/package.json +2 -2
- package/src/solana/SolanaChains.ts +8 -3
- package/src/solana/chain/SolanaChainInterface.ts +26 -1
- package/src/solana/events/SolanaChainEventsBrowser.ts +1 -1
- package/src/solana/program/SolanaProgramBase.ts +29 -4
- package/src/solana/swaps/SolanaSwapData.ts +59 -3
- package/src/solana/swaps/SolanaSwapProgram.ts +11 -6
|
@@ -14,12 +14,14 @@ exports.SolanaChains = {
|
|
|
14
14
|
addresses: {
|
|
15
15
|
swapContract: "4hfUykhqmD7ZRvNh1HuzVKEY7ToENixtdUKZspNDCrEM",
|
|
16
16
|
btcRelayContract: "3KHSHFpEK6bsjg3bqcxQ9qssJYtRCMi2S9TYVe4q6CQc"
|
|
17
|
-
}
|
|
17
|
+
},
|
|
18
|
+
clusterName: "devnet"
|
|
18
19
|
},
|
|
19
20
|
[base_1.BitcoinNetwork.MAINNET]: {
|
|
20
21
|
addresses: {
|
|
21
22
|
swapContract: "4hfUykhqmD7ZRvNh1HuzVKEY7ToENixtdUKZspNDCrEM",
|
|
22
23
|
btcRelayContract: "3KHSHFpEK6bsjg3bqcxQ9qssJYtRCMi2S9TYVe4q6CQc"
|
|
23
|
-
}
|
|
24
|
+
},
|
|
25
|
+
clusterName: "mainnet-beta"
|
|
24
26
|
}
|
|
25
27
|
};
|
|
@@ -8,7 +8,7 @@ import { SolanaTokens } from "./modules/SolanaTokens";
|
|
|
8
8
|
import { SignedSolanaTx, SolanaTransactions, SolanaTx } from "./modules/SolanaTransactions";
|
|
9
9
|
import { SolanaSignatures } from "./modules/SolanaSignatures";
|
|
10
10
|
import { SolanaEvents } from "./modules/SolanaEvents";
|
|
11
|
-
import { ChainInterface, TransactionConfirmationOptions } from "@atomiqlabs/base";
|
|
11
|
+
import { BitcoinNetwork, ChainInterface, TransactionConfirmationOptions } from "@atomiqlabs/base";
|
|
12
12
|
import { SolanaSigner } from "../wallet/SolanaSigner";
|
|
13
13
|
import { Buffer } from "buffer";
|
|
14
14
|
import { Wallet } from "@coral-xyz/anchor/dist/cjs/provider";
|
|
@@ -212,4 +212,5 @@ export declare class SolanaChainInterface implements ChainInterface<SolanaTx, Si
|
|
|
212
212
|
* @inheritDoc
|
|
213
213
|
*/
|
|
214
214
|
wrapSigner(signer: Wallet): Promise<SolanaSigner>;
|
|
215
|
+
verifyNetwork(bitcoinNetwork: BitcoinNetwork): Promise<void>;
|
|
215
216
|
}
|
|
@@ -10,9 +10,16 @@ const SolanaTransactions_1 = require("./modules/SolanaTransactions");
|
|
|
10
10
|
const SolanaSignatures_1 = require("./modules/SolanaSignatures");
|
|
11
11
|
const SolanaEvents_1 = require("./modules/SolanaEvents");
|
|
12
12
|
const Utils_1 = require("../../utils/Utils");
|
|
13
|
+
const base_1 = require("@atomiqlabs/base");
|
|
13
14
|
const SolanaAddresses_1 = require("./modules/SolanaAddresses");
|
|
14
15
|
const SolanaSigner_1 = require("../wallet/SolanaSigner");
|
|
15
16
|
const SolanaKeypairWallet_1 = require("../wallet/SolanaKeypairWallet");
|
|
17
|
+
const SolanaChains_1 = require("../SolanaChains");
|
|
18
|
+
const CLUSTER_BY_GENESIS_HASH = {
|
|
19
|
+
"5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d": "mainnet-beta",
|
|
20
|
+
"EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG": "devnet",
|
|
21
|
+
"4uhcVJyU9pJkvQyS88uRDiswHXSCkY3zQawwpjk2NsNY": "testnet",
|
|
22
|
+
};
|
|
16
23
|
/**
|
|
17
24
|
* Main chain interface for interacting with Solana blockchain
|
|
18
25
|
* @category Chain Interface
|
|
@@ -234,5 +241,20 @@ class SolanaChainInterface {
|
|
|
234
241
|
wrapSigner(signer) {
|
|
235
242
|
return Promise.resolve(new SolanaSigner_1.SolanaSigner(signer));
|
|
236
243
|
}
|
|
244
|
+
async verifyNetwork(bitcoinNetwork) {
|
|
245
|
+
const genesisHash = await this._connection.getGenesisHash();
|
|
246
|
+
const result = CLUSTER_BY_GENESIS_HASH[genesisHash];
|
|
247
|
+
if (result == null) {
|
|
248
|
+
this.logger.warn(`verifyNetwork(): Unknown cluster detected, genesis hash: ${genesisHash}`);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
const deployment = SolanaChains_1.SolanaChains[bitcoinNetwork];
|
|
252
|
+
if (deployment == null) {
|
|
253
|
+
this.logger.warn(`verifyNetwork(): No Solana deployment is defined for ${base_1.BitcoinNetwork[bitcoinNetwork]}, the RPC check is skipped.`);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (deployment.clusterName !== result)
|
|
257
|
+
throw new Error(`Expected ${deployment.clusterName} Solana cluster for ${base_1.BitcoinNetwork[bitcoinNetwork]}, but got ${result}!`);
|
|
258
|
+
}
|
|
237
259
|
}
|
|
238
260
|
exports.SolanaChainInterface = SolanaChainInterface;
|
|
@@ -134,7 +134,7 @@ class SolanaChainEventsBrowser {
|
|
|
134
134
|
const initIx = eventObject.instructions.find(ix => ix != null && (ix.name === "offererInitializePayIn" || ix.name === "offererInitialize"));
|
|
135
135
|
if (initIx == null)
|
|
136
136
|
return null;
|
|
137
|
-
return SolanaSwapData_1.SolanaSwapData.fromInstruction(initIx, txoHash);
|
|
137
|
+
return SolanaSwapData_1.SolanaSwapData.fromInstruction(this.solanaSwapProgram.program.programId, initIx, txoHash);
|
|
138
138
|
};
|
|
139
139
|
}
|
|
140
140
|
/**
|
|
@@ -45,6 +45,23 @@ export declare class SolanaProgramBase<T extends Idl> {
|
|
|
45
45
|
* @internal
|
|
46
46
|
*/
|
|
47
47
|
protected pda<T extends Array<any>>(seed: string, func: (...args: T) => Buffer[]): (...args: T) => PublicKey;
|
|
48
|
+
/**
|
|
49
|
+
* Derives static PDA address from the seed
|
|
50
|
+
*
|
|
51
|
+
* @param seed
|
|
52
|
+
*
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
static _pda(seed: string): (programId: PublicKey) => PublicKey;
|
|
56
|
+
/**
|
|
57
|
+
* Returns a function for deriving a dynamic PDA address from seed + dynamic arguments
|
|
58
|
+
*
|
|
59
|
+
* @param seed
|
|
60
|
+
* @param func function translating the function argument to Buffer[]
|
|
61
|
+
*
|
|
62
|
+
* @internal
|
|
63
|
+
*/
|
|
64
|
+
static _pda<T extends Array<any>>(seed: string, func: (...args: T) => Buffer[]): (programId: PublicKey, ...args: T) => PublicKey;
|
|
48
65
|
/**
|
|
49
66
|
* Returns a function for deriving a dynamic deterministic keypair from dynamic arguments
|
|
50
67
|
*
|
|
@@ -23,11 +23,17 @@ class SolanaProgramBase {
|
|
|
23
23
|
}
|
|
24
24
|
pda(seed, func) {
|
|
25
25
|
if (func == null) {
|
|
26
|
-
return
|
|
26
|
+
return SolanaProgramBase._pda(seed)(this.program.programId);
|
|
27
27
|
}
|
|
28
|
-
return (
|
|
28
|
+
return SolanaProgramBase._pda(seed, func).bind(this, this.program.programId);
|
|
29
|
+
}
|
|
30
|
+
static _pda(seed, func) {
|
|
31
|
+
if (func == null) {
|
|
32
|
+
return (programId) => web3_js_1.PublicKey.findProgramAddressSync([buffer_1.Buffer.from(seed)], programId)[0];
|
|
33
|
+
}
|
|
34
|
+
return (programId, ...args) => {
|
|
29
35
|
const res = func(...args);
|
|
30
|
-
return web3_js_1.PublicKey.findProgramAddressSync([buffer_1.Buffer.from(seed)].concat(res),
|
|
36
|
+
return web3_js_1.PublicKey.findProgramAddressSync([buffer_1.Buffer.from(seed)].concat(res), programId)[0];
|
|
31
37
|
};
|
|
32
38
|
}
|
|
33
39
|
/**
|
|
@@ -7,6 +7,7 @@ import { Serialized } from "../../utils/Utils";
|
|
|
7
7
|
import { SingleInstructionWithAccounts } from "../program/modules/SolanaProgramEvents";
|
|
8
8
|
export type InitInstruction = SingleInstructionWithAccounts<SwapProgram["instructions"][2 | 3], SwapProgram>;
|
|
9
9
|
export type SolanaSwapDataCtorArgs = {
|
|
10
|
+
programId: PublicKey;
|
|
10
11
|
offerer: PublicKey;
|
|
11
12
|
claimer: PublicKey;
|
|
12
13
|
token: PublicKey;
|
|
@@ -34,6 +35,10 @@ export declare function isSerializedData(obj: any): obj is ({
|
|
|
34
35
|
* @category Swaps
|
|
35
36
|
*/
|
|
36
37
|
export declare class SolanaSwapData extends SwapData {
|
|
38
|
+
/**
|
|
39
|
+
* Program ID for which this swap data was created
|
|
40
|
+
*/
|
|
41
|
+
programId: PublicKey;
|
|
37
42
|
/**
|
|
38
43
|
* Offerer address funding the swap.
|
|
39
44
|
*/
|
|
@@ -235,17 +240,19 @@ export declare class SolanaSwapData extends SwapData {
|
|
|
235
240
|
/**
|
|
236
241
|
* Converts initialize instruction data into {@link SolanaSwapData}.
|
|
237
242
|
*
|
|
243
|
+
* @param programId
|
|
238
244
|
* @param initIx Decoded initialize instruction
|
|
239
245
|
* @param txoHash Parsed txo hash hint from initialize event
|
|
240
246
|
* @returns Converted and parsed swap data
|
|
241
247
|
*/
|
|
242
|
-
static fromInstruction(initIx: InitInstruction, txoHash: string): SolanaSwapData;
|
|
248
|
+
static fromInstruction(programId: PublicKey, initIx: InitInstruction, txoHash: string): SolanaSwapData;
|
|
243
249
|
/**
|
|
244
250
|
* Deserializes swap data from an on-chain escrow account state.
|
|
245
251
|
*
|
|
252
|
+
* @param programId
|
|
246
253
|
* @param account Escrow account state as returned by Anchor
|
|
247
254
|
*/
|
|
248
|
-
static fromEscrowState(account: IdlAccounts<SwapProgram>["escrowState"]): SolanaSwapData;
|
|
255
|
+
static fromEscrowState(programId: PublicKey, account: IdlAccounts<SwapProgram>["escrowState"]): SolanaSwapData;
|
|
249
256
|
/**
|
|
250
257
|
* Converts abstract swap type to Solana program kind discriminator.
|
|
251
258
|
*
|
|
@@ -274,4 +281,8 @@ export declare class SolanaSwapData extends SwapData {
|
|
|
274
281
|
* @inheritDoc
|
|
275
282
|
*/
|
|
276
283
|
isDepositToken(token: string): boolean;
|
|
284
|
+
/**
|
|
285
|
+
* @inheritDoc
|
|
286
|
+
*/
|
|
287
|
+
getEscrowStruct(): any;
|
|
277
288
|
}
|
|
@@ -9,6 +9,7 @@ const buffer_1 = require("buffer");
|
|
|
9
9
|
const spl_token_1 = require("@solana/spl-token");
|
|
10
10
|
const Utils_1 = require("../../utils/Utils");
|
|
11
11
|
const SolanaTokens_1 = require("../chain/modules/SolanaTokens");
|
|
12
|
+
const SolanaSwapProgram_1 = require("./SolanaSwapProgram");
|
|
12
13
|
const EXPIRY_BLOCKHEIGHT_THRESHOLD = new BN("1000000000");
|
|
13
14
|
function isSerializedData(obj) {
|
|
14
15
|
return obj.type === "sol";
|
|
@@ -23,6 +24,7 @@ class SolanaSwapData extends base_1.SwapData {
|
|
|
23
24
|
constructor(data) {
|
|
24
25
|
super();
|
|
25
26
|
if (!isSerializedData(data)) {
|
|
27
|
+
this.programId = data.programId;
|
|
26
28
|
this.offerer = data.offerer;
|
|
27
29
|
this.claimer = data.claimer;
|
|
28
30
|
this.token = data.token;
|
|
@@ -42,6 +44,7 @@ class SolanaSwapData extends base_1.SwapData {
|
|
|
42
44
|
this.txoHash = data.txoHash;
|
|
43
45
|
}
|
|
44
46
|
else {
|
|
47
|
+
this.programId = new web3_js_1.PublicKey(data.programId ?? "4hfUykhqmD7ZRvNh1HuzVKEY7ToENixtdUKZspNDCrEM");
|
|
45
48
|
this.offerer = new web3_js_1.PublicKey(data.offerer);
|
|
46
49
|
this.claimer = new web3_js_1.PublicKey(data.claimer);
|
|
47
50
|
this.token = new web3_js_1.PublicKey(data.token);
|
|
@@ -96,6 +99,7 @@ class SolanaSwapData extends base_1.SwapData {
|
|
|
96
99
|
serialize() {
|
|
97
100
|
return {
|
|
98
101
|
type: "sol",
|
|
102
|
+
programId: this.programId?.toBase58(),
|
|
99
103
|
offerer: this.offerer?.toBase58(),
|
|
100
104
|
claimer: this.claimer?.toBase58(),
|
|
101
105
|
token: this.token?.toBase58(),
|
|
@@ -318,11 +322,12 @@ class SolanaSwapData extends base_1.SwapData {
|
|
|
318
322
|
/**
|
|
319
323
|
* Converts initialize instruction data into {@link SolanaSwapData}.
|
|
320
324
|
*
|
|
325
|
+
* @param programId
|
|
321
326
|
* @param initIx Decoded initialize instruction
|
|
322
327
|
* @param txoHash Parsed txo hash hint from initialize event
|
|
323
328
|
* @returns Converted and parsed swap data
|
|
324
329
|
*/
|
|
325
|
-
static fromInstruction(initIx, txoHash) {
|
|
330
|
+
static fromInstruction(programId, initIx, txoHash) {
|
|
326
331
|
const paymentHash = buffer_1.Buffer.from(initIx.data.swapData.hash);
|
|
327
332
|
let securityDeposit = new BN(0);
|
|
328
333
|
let claimerBounty = new BN(0);
|
|
@@ -333,6 +338,7 @@ class SolanaSwapData extends base_1.SwapData {
|
|
|
333
338
|
claimerBounty = initIx.data.claimerBounty;
|
|
334
339
|
}
|
|
335
340
|
return new SolanaSwapData({
|
|
341
|
+
programId,
|
|
336
342
|
offerer: initIx.accounts.offerer,
|
|
337
343
|
claimer: initIx.accounts.claimer,
|
|
338
344
|
token: initIx.accounts.mint,
|
|
@@ -355,11 +361,13 @@ class SolanaSwapData extends base_1.SwapData {
|
|
|
355
361
|
/**
|
|
356
362
|
* Deserializes swap data from an on-chain escrow account state.
|
|
357
363
|
*
|
|
364
|
+
* @param programId
|
|
358
365
|
* @param account Escrow account state as returned by Anchor
|
|
359
366
|
*/
|
|
360
|
-
static fromEscrowState(account) {
|
|
367
|
+
static fromEscrowState(programId, account) {
|
|
361
368
|
const data = account.data;
|
|
362
369
|
return new SolanaSwapData({
|
|
370
|
+
programId,
|
|
363
371
|
offerer: account.offerer,
|
|
364
372
|
claimer: account.claimer,
|
|
365
373
|
token: account.mint,
|
|
@@ -444,6 +452,40 @@ class SolanaSwapData extends base_1.SwapData {
|
|
|
444
452
|
isDepositToken(token) {
|
|
445
453
|
return SolanaTokens_1.SolanaTokens.WSOL_ADDRESS.equals(new web3_js_1.PublicKey(token));
|
|
446
454
|
}
|
|
455
|
+
/**
|
|
456
|
+
* @inheritDoc
|
|
457
|
+
*/
|
|
458
|
+
getEscrowStruct() {
|
|
459
|
+
return {
|
|
460
|
+
accounts: {
|
|
461
|
+
offerer: this.offerer.toString(),
|
|
462
|
+
claimer: this.claimer.toString(),
|
|
463
|
+
claimerAta: this.claimerAta == null || this.claimerAta.equals(web3_js_1.PublicKey.default) ? null : this.claimerAta.toString(),
|
|
464
|
+
offererAta: this.offererAta == null || this.offererAta.equals(web3_js_1.PublicKey.default) ? null : this.offererAta.toString(),
|
|
465
|
+
claimerUserData: SolanaSwapProgram_1.SolanaSwapProgram._SwapUserVault(this.programId, this.claimer, this.token).toString(),
|
|
466
|
+
offererUserData: SolanaSwapProgram_1.SolanaSwapProgram._SwapUserVault(this.programId, this.offerer, this.token).toString(),
|
|
467
|
+
initializer: this.isPayIn() ? this.offerer.toString() : this.claimer.toString(),
|
|
468
|
+
escrowState: SolanaSwapProgram_1.SolanaSwapProgram._SwapEscrowState(this.programId, buffer_1.Buffer.from(this.paymentHash, "hex")).toString(),
|
|
469
|
+
mint: this.token.toString(),
|
|
470
|
+
vault: SolanaSwapProgram_1.SolanaSwapProgram._SwapVault(this.programId, this.token).toString(),
|
|
471
|
+
vaultAuthority: SolanaSwapProgram_1.SolanaSwapProgram._SwapVaultAuthority(this.programId).toString(),
|
|
472
|
+
systemProgram: web3_js_1.SystemProgram.programId.toString(),
|
|
473
|
+
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID.toString(),
|
|
474
|
+
ixSysvar: web3_js_1.SYSVAR_INSTRUCTIONS_PUBKEY.toString(),
|
|
475
|
+
},
|
|
476
|
+
data: {
|
|
477
|
+
kind: SwapTypeEnum_1.SwapTypeEnum.fromNumber(this.kind),
|
|
478
|
+
confirmations: this.confirmations,
|
|
479
|
+
nonce: this.nonce.toString(10),
|
|
480
|
+
hash: [...buffer_1.Buffer.from(this.paymentHash, "hex")],
|
|
481
|
+
payIn: this.payIn,
|
|
482
|
+
payOut: this.payOut,
|
|
483
|
+
amount: this.amount.toString(10),
|
|
484
|
+
expiry: this.expiry.toString(10),
|
|
485
|
+
sequence: this.sequence.toString(10)
|
|
486
|
+
}
|
|
487
|
+
};
|
|
488
|
+
}
|
|
447
489
|
}
|
|
448
490
|
exports.SolanaSwapData = SolanaSwapData;
|
|
449
491
|
base_1.SwapData.deserializers["sol"] = SolanaSwapData;
|
|
@@ -27,21 +27,25 @@ export declare class SolanaSwapProgram extends SolanaProgramBase<SwapProgram> im
|
|
|
27
27
|
* PDA of the swap vault authority.
|
|
28
28
|
* @internal
|
|
29
29
|
*/
|
|
30
|
+
static readonly _SwapVaultAuthority: (programId: PublicKey) => PublicKey;
|
|
30
31
|
readonly _SwapVaultAuthority: PublicKey;
|
|
31
32
|
/**
|
|
32
33
|
* PDA helper for global token vault accounts.
|
|
33
34
|
* @internal
|
|
34
35
|
*/
|
|
36
|
+
static readonly _SwapVault: (programId: PublicKey, tokenAddress: PublicKey) => PublicKey;
|
|
35
37
|
readonly _SwapVault: (tokenAddress: PublicKey) => PublicKey;
|
|
36
38
|
/**
|
|
37
39
|
* PDA helper for per-user token vault accounts.
|
|
38
40
|
* @internal
|
|
39
41
|
*/
|
|
42
|
+
static readonly _SwapUserVault: (programId: PublicKey, publicKey: PublicKey, tokenAddress: PublicKey) => PublicKey;
|
|
40
43
|
readonly _SwapUserVault: (publicKey: PublicKey, tokenAddress: PublicKey) => PublicKey;
|
|
41
44
|
/**
|
|
42
45
|
* PDA helper for escrow state accounts.
|
|
43
46
|
* @internal
|
|
44
47
|
*/
|
|
48
|
+
static readonly _SwapEscrowState: (programId: PublicKey, hash: Buffer) => PublicKey;
|
|
45
49
|
readonly _SwapEscrowState: (hash: Buffer) => PublicKey;
|
|
46
50
|
/**
|
|
47
51
|
* @inheritDoc
|
|
@@ -35,28 +35,10 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
|
|
|
35
35
|
* Rent-exempt amount (lamports) for escrow state accounts.
|
|
36
36
|
*/
|
|
37
37
|
this.ESCROW_STATE_RENT_EXEMPT = 2658720;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
* @internal
|
|
43
|
-
*/
|
|
44
|
-
this._SwapVaultAuthority = this.pda("authority");
|
|
45
|
-
/**
|
|
46
|
-
* PDA helper for global token vault accounts.
|
|
47
|
-
* @internal
|
|
48
|
-
*/
|
|
49
|
-
this._SwapVault = this.pda("vault", (tokenAddress) => [tokenAddress.toBuffer()]);
|
|
50
|
-
/**
|
|
51
|
-
* PDA helper for per-user token vault accounts.
|
|
52
|
-
* @internal
|
|
53
|
-
*/
|
|
54
|
-
this._SwapUserVault = this.pda("uservault", (publicKey, tokenAddress) => [publicKey.toBuffer(), tokenAddress.toBuffer()]);
|
|
55
|
-
/**
|
|
56
|
-
* PDA helper for escrow state accounts.
|
|
57
|
-
* @internal
|
|
58
|
-
*/
|
|
59
|
-
this._SwapEscrowState = this.pda("state", (hash) => [hash]);
|
|
38
|
+
this._SwapVaultAuthority = SolanaSwapProgram._SwapVaultAuthority(this.program.programId);
|
|
39
|
+
this._SwapVault = SolanaSwapProgram._SwapVault.bind(this, this.program.programId);
|
|
40
|
+
this._SwapUserVault = SolanaSwapProgram._SwapUserVault.bind(this, this.program.programId);
|
|
41
|
+
this._SwapEscrowState = SolanaSwapProgram._SwapEscrowState.bind(this, this.program.programId);
|
|
60
42
|
////////////////////////
|
|
61
43
|
//// Timeouts
|
|
62
44
|
/**
|
|
@@ -360,7 +342,7 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
|
|
|
360
342
|
const account = await this.program.account.escrowState.fetchNullable(this._SwapEscrowState(paymentHashBuffer));
|
|
361
343
|
if (account == null)
|
|
362
344
|
return null;
|
|
363
|
-
return SolanaSwapData_1.SolanaSwapData.fromEscrowState(account);
|
|
345
|
+
return SolanaSwapData_1.SolanaSwapData.fromEscrowState(this.program.programId, account);
|
|
364
346
|
}
|
|
365
347
|
/**
|
|
366
348
|
* @inheritDoc
|
|
@@ -395,7 +377,7 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
|
|
|
395
377
|
continue;
|
|
396
378
|
}
|
|
397
379
|
swapsOpened[escrowHash] = {
|
|
398
|
-
data: SolanaSwapData_1.SolanaSwapData.fromInstruction(initIx, txoHash),
|
|
380
|
+
data: SolanaSwapData_1.SolanaSwapData.fromInstruction(this.program.programId, initIx, txoHash),
|
|
399
381
|
getInitTxId: () => Promise.resolve(txSignature),
|
|
400
382
|
getTxBlock: () => Promise.resolve({
|
|
401
383
|
blockHeight: tx.slot,
|
|
@@ -468,6 +450,7 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
|
|
|
468
450
|
const claimerKey = new web3_js_1.PublicKey(claimer);
|
|
469
451
|
const { paymentHash, nonce, confirmations } = (0, Utils_1.fromClaimHash)(claimHash);
|
|
470
452
|
const swapData = new SolanaSwapData_1.SolanaSwapData({
|
|
453
|
+
programId: this.program.programId,
|
|
471
454
|
offerer: offererKey,
|
|
472
455
|
claimer: claimerKey,
|
|
473
456
|
token: tokenAddr,
|
|
@@ -736,3 +719,25 @@ class SolanaSwapProgram extends SolanaProgramBase_1.SolanaProgramBase {
|
|
|
736
719
|
}
|
|
737
720
|
}
|
|
738
721
|
exports.SolanaSwapProgram = SolanaSwapProgram;
|
|
722
|
+
////////////////////////
|
|
723
|
+
//// PDA accessors
|
|
724
|
+
/**
|
|
725
|
+
* PDA of the swap vault authority.
|
|
726
|
+
* @internal
|
|
727
|
+
*/
|
|
728
|
+
SolanaSwapProgram._SwapVaultAuthority = SolanaProgramBase_1.SolanaProgramBase._pda("authority");
|
|
729
|
+
/**
|
|
730
|
+
* PDA helper for global token vault accounts.
|
|
731
|
+
* @internal
|
|
732
|
+
*/
|
|
733
|
+
SolanaSwapProgram._SwapVault = SolanaProgramBase_1.SolanaProgramBase._pda("vault", (tokenAddress) => [tokenAddress.toBuffer()]);
|
|
734
|
+
/**
|
|
735
|
+
* PDA helper for per-user token vault accounts.
|
|
736
|
+
* @internal
|
|
737
|
+
*/
|
|
738
|
+
SolanaSwapProgram._SwapUserVault = SolanaProgramBase_1.SolanaProgramBase._pda("uservault", (publicKey, tokenAddress) => [publicKey.toBuffer(), tokenAddress.toBuffer()]);
|
|
739
|
+
/**
|
|
740
|
+
* PDA helper for escrow state accounts.
|
|
741
|
+
* @internal
|
|
742
|
+
*/
|
|
743
|
+
SolanaSwapProgram._SwapEscrowState = SolanaProgramBase_1.SolanaProgramBase._pda("state", (hash) => [hash]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atomiqlabs/chain-solana",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.4.1",
|
|
4
4
|
"description": "Solana specific base implementation",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types:": "./dist/index.d.ts",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"author": "adambor",
|
|
27
27
|
"license": "ISC",
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@atomiqlabs/base": "^13.
|
|
29
|
+
"@atomiqlabs/base": "^13.4.0",
|
|
30
30
|
"@coral-xyz/anchor": "0.29.0",
|
|
31
31
|
"@noble/hashes": "^1.7.1",
|
|
32
32
|
"@solana/spl-token": "0.4.14",
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import {BitcoinNetwork} from "@atomiqlabs/base";
|
|
2
2
|
|
|
3
|
-
export const SolanaChains: {[key in BitcoinNetwork]?: {
|
|
3
|
+
export const SolanaChains: {[key in BitcoinNetwork]?: {
|
|
4
|
+
addresses: {swapContract: string, btcRelayContract: string}
|
|
5
|
+
clusterName: "mainnet-beta" | "devnet" | "testnet"
|
|
6
|
+
}} = {
|
|
4
7
|
//TODO: Not deployed yet
|
|
5
8
|
// [BitcoinNetwork.TESTNET4]: {
|
|
6
9
|
// addresses: {
|
|
@@ -12,12 +15,14 @@ export const SolanaChains: {[key in BitcoinNetwork]?: {addresses: {swapContract:
|
|
|
12
15
|
addresses: {
|
|
13
16
|
swapContract: "4hfUykhqmD7ZRvNh1HuzVKEY7ToENixtdUKZspNDCrEM",
|
|
14
17
|
btcRelayContract: "3KHSHFpEK6bsjg3bqcxQ9qssJYtRCMi2S9TYVe4q6CQc"
|
|
15
|
-
}
|
|
18
|
+
},
|
|
19
|
+
clusterName: "devnet"
|
|
16
20
|
},
|
|
17
21
|
[BitcoinNetwork.MAINNET]: {
|
|
18
22
|
addresses: {
|
|
19
23
|
swapContract: "4hfUykhqmD7ZRvNh1HuzVKEY7ToENixtdUKZspNDCrEM",
|
|
20
24
|
btcRelayContract: "3KHSHFpEK6bsjg3bqcxQ9qssJYtRCMi2S9TYVe4q6CQc"
|
|
21
|
-
}
|
|
25
|
+
},
|
|
26
|
+
clusterName: "mainnet-beta"
|
|
22
27
|
}
|
|
23
28
|
} as const;
|
|
@@ -7,12 +7,19 @@ import {SignedSolanaTx, SolanaTransactions, SolanaTx} from "./modules/SolanaTran
|
|
|
7
7
|
import {SolanaSignatures} from "./modules/SolanaSignatures";
|
|
8
8
|
import {SolanaEvents} from "./modules/SolanaEvents";
|
|
9
9
|
import {getLogger} from "../../utils/Utils";
|
|
10
|
-
import {ChainInterface, TransactionConfirmationOptions} from "@atomiqlabs/base";
|
|
10
|
+
import {BitcoinNetwork, ChainInterface, TransactionConfirmationOptions} from "@atomiqlabs/base";
|
|
11
11
|
import {SolanaAddresses} from "./modules/SolanaAddresses";
|
|
12
12
|
import {SolanaSigner} from "../wallet/SolanaSigner";
|
|
13
13
|
import {Buffer} from "buffer";
|
|
14
14
|
import {SolanaKeypairWallet} from "../wallet/SolanaKeypairWallet";
|
|
15
15
|
import {Wallet} from "@coral-xyz/anchor/dist/cjs/provider";
|
|
16
|
+
import {SolanaChains} from "../SolanaChains";
|
|
17
|
+
|
|
18
|
+
const CLUSTER_BY_GENESIS_HASH: Record<string, "mainnet-beta" | "devnet" | "testnet"> = {
|
|
19
|
+
"5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d": "mainnet-beta",
|
|
20
|
+
"EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG": "devnet",
|
|
21
|
+
"4uhcVJyU9pJkvQyS88uRDiswHXSCkY3zQawwpjk2NsNY": "testnet",
|
|
22
|
+
};
|
|
16
23
|
|
|
17
24
|
/**
|
|
18
25
|
* Retry policy configuration for Solana RPC calls
|
|
@@ -359,4 +366,22 @@ export class SolanaChainInterface implements ChainInterface<
|
|
|
359
366
|
return Promise.resolve(new SolanaSigner(signer));
|
|
360
367
|
}
|
|
361
368
|
|
|
369
|
+
async verifyNetwork(bitcoinNetwork: BitcoinNetwork): Promise<void> {
|
|
370
|
+
const genesisHash = await this._connection.getGenesisHash();
|
|
371
|
+
const result = CLUSTER_BY_GENESIS_HASH[genesisHash];
|
|
372
|
+
if(result==null) {
|
|
373
|
+
this.logger.warn(`verifyNetwork(): Unknown cluster detected, genesis hash: ${genesisHash}`);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const deployment = SolanaChains[bitcoinNetwork];
|
|
378
|
+
if(deployment==null) {
|
|
379
|
+
this.logger.warn(`verifyNetwork(): No Solana deployment is defined for ${BitcoinNetwork[bitcoinNetwork]}, the RPC check is skipped.`);
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if(deployment.clusterName!==result)
|
|
384
|
+
throw new Error(`Expected ${deployment.clusterName} Solana cluster for ${BitcoinNetwork[bitcoinNetwork]}, but got ${result}!`);
|
|
385
|
+
}
|
|
386
|
+
|
|
362
387
|
}
|
|
@@ -193,7 +193,7 @@ export class SolanaChainEventsBrowser implements ChainEvents<SolanaSwapData, Sol
|
|
|
193
193
|
) as InitInstruction;
|
|
194
194
|
if(initIx == null) return null;
|
|
195
195
|
|
|
196
|
-
return SolanaSwapData.fromInstruction(initIx, txoHash);
|
|
196
|
+
return SolanaSwapData.fromInstruction(this.solanaSwapProgram.program.programId, initIx, txoHash);
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
|
|
@@ -64,19 +64,44 @@ export class SolanaProgramBase<T extends Idl> {
|
|
|
64
64
|
protected pda<T extends Array<any>>(seed: string, func: (...args: T) => Buffer[]): (...args: T) => PublicKey;
|
|
65
65
|
protected pda<T extends Array<any>>(seed: string, func?: (...args: T) => Buffer[]): PublicKey | ((...args: T) => PublicKey) {
|
|
66
66
|
if(func==null) {
|
|
67
|
-
return
|
|
67
|
+
return SolanaProgramBase._pda(seed)(this.program.programId);
|
|
68
|
+
}
|
|
69
|
+
return SolanaProgramBase._pda(seed, func).bind(this, this.program.programId);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Derives static PDA address from the seed
|
|
74
|
+
*
|
|
75
|
+
* @param seed
|
|
76
|
+
*
|
|
77
|
+
* @internal
|
|
78
|
+
*/
|
|
79
|
+
static _pda(seed: string): (programId: PublicKey) => PublicKey;
|
|
80
|
+
/**
|
|
81
|
+
* Returns a function for deriving a dynamic PDA address from seed + dynamic arguments
|
|
82
|
+
*
|
|
83
|
+
* @param seed
|
|
84
|
+
* @param func function translating the function argument to Buffer[]
|
|
85
|
+
*
|
|
86
|
+
* @internal
|
|
87
|
+
*/
|
|
88
|
+
static _pda<T extends Array<any>>(seed: string, func: (...args: T) => Buffer[]): (programId: PublicKey, ...args: T) => PublicKey;
|
|
89
|
+
static _pda<T extends Array<any>>(seed: string, func?: (...args: T) => Buffer[]): ((programId: PublicKey) => PublicKey) | ((programId: PublicKey, ...args: T) => PublicKey) {
|
|
90
|
+
if(func==null) {
|
|
91
|
+
return (programId: PublicKey) => PublicKey.findProgramAddressSync(
|
|
68
92
|
[Buffer.from(seed)],
|
|
69
|
-
|
|
93
|
+
programId
|
|
70
94
|
)[0];
|
|
71
95
|
}
|
|
72
|
-
return (...args: T) => {
|
|
96
|
+
return (programId: PublicKey, ...args: T) => {
|
|
73
97
|
const res = func(...args);
|
|
74
98
|
return PublicKey.findProgramAddressSync(
|
|
75
99
|
[Buffer.from(seed)].concat(res as Buffer<ArrayBuffer>[]),
|
|
76
|
-
|
|
100
|
+
programId
|
|
77
101
|
)[0]
|
|
78
102
|
}
|
|
79
103
|
}
|
|
104
|
+
|
|
80
105
|
/**
|
|
81
106
|
* Returns a function for deriving a dynamic deterministic keypair from dynamic arguments
|
|
82
107
|
*
|
|
@@ -1,20 +1,23 @@
|
|
|
1
|
-
import {PublicKey} from "@solana/web3.js";
|
|
1
|
+
import {PublicKey, SystemProgram, SYSVAR_INSTRUCTIONS_PUBKEY} from "@solana/web3.js";
|
|
2
2
|
import * as BN from "bn.js";
|
|
3
3
|
import {ChainSwapType, SwapData} from "@atomiqlabs/base";
|
|
4
4
|
import {SwapProgram} from "./programTypes";
|
|
5
5
|
import {IdlAccounts, IdlTypes} from "@coral-xyz/anchor";
|
|
6
6
|
import {SwapTypeEnum} from "./SwapTypeEnum";
|
|
7
7
|
import {Buffer} from "buffer";
|
|
8
|
-
import {getAssociatedTokenAddressSync} from "@solana/spl-token";
|
|
8
|
+
import {getAssociatedTokenAddressSync, TOKEN_PROGRAM_ID} from "@solana/spl-token";
|
|
9
9
|
import {Serialized, toBigInt, toClaimHash, toEscrowHash} from "../../utils/Utils";
|
|
10
10
|
import {SolanaTokens} from "../chain/modules/SolanaTokens";
|
|
11
11
|
import {SingleInstructionWithAccounts} from "../program/modules/SolanaProgramEvents";
|
|
12
|
+
import {SolanaSwapProgram} from "./SolanaSwapProgram";
|
|
12
13
|
|
|
13
14
|
export type InitInstruction = SingleInstructionWithAccounts<SwapProgram["instructions"][2 | 3], SwapProgram>;
|
|
14
15
|
|
|
15
16
|
const EXPIRY_BLOCKHEIGHT_THRESHOLD = new BN("1000000000");
|
|
16
17
|
|
|
17
18
|
export type SolanaSwapDataCtorArgs = {
|
|
19
|
+
programId: PublicKey,
|
|
20
|
+
|
|
18
21
|
offerer: PublicKey,
|
|
19
22
|
claimer: PublicKey,
|
|
20
23
|
token: PublicKey,
|
|
@@ -48,6 +51,10 @@ export function isSerializedData(obj: any): obj is ({type: "sol"} & Serialized<S
|
|
|
48
51
|
*/
|
|
49
52
|
export class SolanaSwapData extends SwapData {
|
|
50
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Program ID for which this swap data was created
|
|
56
|
+
*/
|
|
57
|
+
programId: PublicKey;
|
|
51
58
|
/**
|
|
52
59
|
* Offerer address funding the swap.
|
|
53
60
|
*/
|
|
@@ -135,6 +142,7 @@ export class SolanaSwapData extends SwapData {
|
|
|
135
142
|
constructor(data: ({type: "sol"} & Serialized<SolanaSwapData>) | SolanaSwapDataCtorArgs) {
|
|
136
143
|
super();
|
|
137
144
|
if(!isSerializedData(data)) {
|
|
145
|
+
this.programId = data.programId;
|
|
138
146
|
this.offerer = data.offerer;
|
|
139
147
|
this.claimer = data.claimer;
|
|
140
148
|
this.token = data.token;
|
|
@@ -153,6 +161,7 @@ export class SolanaSwapData extends SwapData {
|
|
|
153
161
|
this.claimerBounty = data.claimerBounty;
|
|
154
162
|
this.txoHash = data.txoHash;
|
|
155
163
|
} else {
|
|
164
|
+
this.programId = new PublicKey(data.programId ?? "4hfUykhqmD7ZRvNh1HuzVKEY7ToENixtdUKZspNDCrEM");
|
|
156
165
|
this.offerer = new PublicKey(data.offerer);
|
|
157
166
|
this.claimer = new PublicKey(data.claimer);
|
|
158
167
|
this.token = new PublicKey(data.token);
|
|
@@ -212,6 +221,7 @@ export class SolanaSwapData extends SwapData {
|
|
|
212
221
|
serialize(): {type: "sol"} & Serialized<SolanaSwapData> {
|
|
213
222
|
return {
|
|
214
223
|
type: "sol",
|
|
224
|
+
programId: this.programId?.toBase58(),
|
|
215
225
|
offerer: this.offerer?.toBase58(),
|
|
216
226
|
claimer: this.claimer?.toBase58(),
|
|
217
227
|
token: this.token?.toBase58(),
|
|
@@ -452,11 +462,13 @@ export class SolanaSwapData extends SwapData {
|
|
|
452
462
|
/**
|
|
453
463
|
* Converts initialize instruction data into {@link SolanaSwapData}.
|
|
454
464
|
*
|
|
465
|
+
* @param programId
|
|
455
466
|
* @param initIx Decoded initialize instruction
|
|
456
467
|
* @param txoHash Parsed txo hash hint from initialize event
|
|
457
468
|
* @returns Converted and parsed swap data
|
|
458
469
|
*/
|
|
459
470
|
static fromInstruction(
|
|
471
|
+
programId: PublicKey,
|
|
460
472
|
initIx: InitInstruction,
|
|
461
473
|
txoHash: string
|
|
462
474
|
): SolanaSwapData {
|
|
@@ -471,6 +483,7 @@ export class SolanaSwapData extends SwapData {
|
|
|
471
483
|
}
|
|
472
484
|
|
|
473
485
|
return new SolanaSwapData({
|
|
486
|
+
programId,
|
|
474
487
|
offerer: initIx.accounts.offerer,
|
|
475
488
|
claimer: initIx.accounts.claimer,
|
|
476
489
|
token: initIx.accounts.mint,
|
|
@@ -494,12 +507,17 @@ export class SolanaSwapData extends SwapData {
|
|
|
494
507
|
/**
|
|
495
508
|
* Deserializes swap data from an on-chain escrow account state.
|
|
496
509
|
*
|
|
510
|
+
* @param programId
|
|
497
511
|
* @param account Escrow account state as returned by Anchor
|
|
498
512
|
*/
|
|
499
|
-
static fromEscrowState(
|
|
513
|
+
static fromEscrowState(
|
|
514
|
+
programId: PublicKey,
|
|
515
|
+
account: IdlAccounts<SwapProgram>["escrowState"]
|
|
516
|
+
) {
|
|
500
517
|
const data: IdlTypes<SwapProgram>["SwapData"] = account.data;
|
|
501
518
|
|
|
502
519
|
return new SolanaSwapData({
|
|
520
|
+
programId,
|
|
503
521
|
offerer: account.offerer,
|
|
504
522
|
claimer: account.claimer,
|
|
505
523
|
token: account.mint,
|
|
@@ -590,6 +608,44 @@ export class SolanaSwapData extends SwapData {
|
|
|
590
608
|
return SolanaTokens.WSOL_ADDRESS.equals(new PublicKey(token));
|
|
591
609
|
}
|
|
592
610
|
|
|
611
|
+
/**
|
|
612
|
+
* @inheritDoc
|
|
613
|
+
*/
|
|
614
|
+
getEscrowStruct(): any {
|
|
615
|
+
return {
|
|
616
|
+
accounts: {
|
|
617
|
+
offerer: this.offerer.toString(),
|
|
618
|
+
claimer: this.claimer.toString(),
|
|
619
|
+
claimerAta: this.claimerAta==null || this.claimerAta.equals(PublicKey.default) ? null : this.claimerAta.toString(),
|
|
620
|
+
offererAta: this.offererAta==null || this.offererAta.equals(PublicKey.default) ? null : this.offererAta.toString(),
|
|
621
|
+
claimerUserData: SolanaSwapProgram._SwapUserVault(this.programId, this.claimer, this.token).toString(),
|
|
622
|
+
offererUserData: SolanaSwapProgram._SwapUserVault(this.programId, this.offerer, this.token).toString(),
|
|
623
|
+
|
|
624
|
+
initializer: this.isPayIn() ? this.offerer.toString() : this.claimer.toString(),
|
|
625
|
+
|
|
626
|
+
escrowState: SolanaSwapProgram._SwapEscrowState(this.programId, Buffer.from(this.paymentHash, "hex")).toString(),
|
|
627
|
+
mint: this.token.toString(),
|
|
628
|
+
vault: SolanaSwapProgram._SwapVault(this.programId, this.token).toString(),
|
|
629
|
+
vaultAuthority: SolanaSwapProgram._SwapVaultAuthority(this.programId).toString(),
|
|
630
|
+
|
|
631
|
+
systemProgram: SystemProgram.programId.toString(),
|
|
632
|
+
tokenProgram: TOKEN_PROGRAM_ID.toString(),
|
|
633
|
+
ixSysvar: SYSVAR_INSTRUCTIONS_PUBKEY.toString(),
|
|
634
|
+
},
|
|
635
|
+
data: {
|
|
636
|
+
kind: SwapTypeEnum.fromNumber(this.kind as 0 | 1 | 2 | 3),
|
|
637
|
+
confirmations: this.confirmations,
|
|
638
|
+
nonce: this.nonce.toString(10),
|
|
639
|
+
hash: [...Buffer.from(this.paymentHash, "hex")],
|
|
640
|
+
payIn: this.payIn,
|
|
641
|
+
payOut: this.payOut,
|
|
642
|
+
amount: this.amount.toString(10),
|
|
643
|
+
expiry: this.expiry.toString(10),
|
|
644
|
+
sequence: this.sequence.toString(10)
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
|
|
593
649
|
}
|
|
594
650
|
|
|
595
651
|
SwapData.deserializers["sol"] = SolanaSwapData;
|
|
@@ -74,24 +74,28 @@ export class SolanaSwapProgram
|
|
|
74
74
|
* PDA of the swap vault authority.
|
|
75
75
|
* @internal
|
|
76
76
|
*/
|
|
77
|
-
readonly _SwapVaultAuthority =
|
|
77
|
+
static readonly _SwapVaultAuthority = SolanaProgramBase._pda("authority");
|
|
78
|
+
readonly _SwapVaultAuthority = SolanaSwapProgram._SwapVaultAuthority(this.program.programId);
|
|
78
79
|
/**
|
|
79
80
|
* PDA helper for global token vault accounts.
|
|
80
81
|
* @internal
|
|
81
82
|
*/
|
|
82
|
-
readonly _SwapVault =
|
|
83
|
+
static readonly _SwapVault = SolanaProgramBase._pda("vault", (tokenAddress: PublicKey) => [tokenAddress.toBuffer()]);
|
|
84
|
+
readonly _SwapVault = SolanaSwapProgram._SwapVault.bind(this, this.program.programId);
|
|
83
85
|
/**
|
|
84
86
|
* PDA helper for per-user token vault accounts.
|
|
85
87
|
* @internal
|
|
86
88
|
*/
|
|
87
|
-
readonly _SwapUserVault =
|
|
89
|
+
static readonly _SwapUserVault = SolanaProgramBase._pda("uservault",
|
|
88
90
|
(publicKey: PublicKey, tokenAddress: PublicKey) => [publicKey.toBuffer(), tokenAddress.toBuffer()]
|
|
89
91
|
);
|
|
92
|
+
readonly _SwapUserVault = SolanaSwapProgram._SwapUserVault.bind(this, this.program.programId);
|
|
90
93
|
/**
|
|
91
94
|
* PDA helper for escrow state accounts.
|
|
92
95
|
* @internal
|
|
93
96
|
*/
|
|
94
|
-
readonly _SwapEscrowState =
|
|
97
|
+
static readonly _SwapEscrowState = SolanaProgramBase._pda("state", (hash: Buffer) => [hash]);
|
|
98
|
+
readonly _SwapEscrowState = SolanaSwapProgram._SwapEscrowState.bind(this, this.program.programId);
|
|
95
99
|
|
|
96
100
|
////////////////////////
|
|
97
101
|
//// Timeouts
|
|
@@ -461,7 +465,7 @@ export class SolanaSwapProgram
|
|
|
461
465
|
);
|
|
462
466
|
if(account==null) return null;
|
|
463
467
|
|
|
464
|
-
return SolanaSwapData.fromEscrowState(account);
|
|
468
|
+
return SolanaSwapData.fromEscrowState(this.program.programId, account);
|
|
465
469
|
}
|
|
466
470
|
|
|
467
471
|
/**
|
|
@@ -540,7 +544,7 @@ export class SolanaSwapProgram
|
|
|
540
544
|
}
|
|
541
545
|
|
|
542
546
|
swapsOpened[escrowHash] = {
|
|
543
|
-
data: SolanaSwapData.fromInstruction(initIx, txoHash),
|
|
547
|
+
data: SolanaSwapData.fromInstruction(this.program.programId, initIx, txoHash),
|
|
544
548
|
getInitTxId: () => Promise.resolve(txSignature),
|
|
545
549
|
getTxBlock: () => Promise.resolve({
|
|
546
550
|
blockHeight: tx.slot,
|
|
@@ -632,6 +636,7 @@ export class SolanaSwapProgram
|
|
|
632
636
|
const claimerKey = new PublicKey(claimer);
|
|
633
637
|
const {paymentHash, nonce, confirmations} = fromClaimHash(claimHash);
|
|
634
638
|
const swapData = new SolanaSwapData({
|
|
639
|
+
programId: this.program.programId,
|
|
635
640
|
offerer: offererKey,
|
|
636
641
|
claimer: claimerKey,
|
|
637
642
|
token: tokenAddr,
|