@atomiqlabs/chain-solana 12.0.0 → 12.0.7
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/chain/modules/SolanaEvents.d.ts +45 -2
- package/dist/solana/chain/modules/SolanaEvents.js +167 -2
- package/dist/solana/events/SolanaChainEventsBrowser.d.ts +1 -11
- package/dist/solana/events/SolanaChainEventsBrowser.js +1 -23
- package/dist/solana/program/modules/SolanaProgramEvents.d.ts +3 -9
- package/dist/solana/program/modules/SolanaProgramEvents.js +38 -27
- package/dist/solana/swaps/SolanaSwapData.d.ts +13 -1
- package/dist/solana/swaps/SolanaSwapData.js +25 -0
- package/dist/solana/swaps/SolanaSwapProgram.d.ts +16 -0
- package/dist/solana/swaps/SolanaSwapProgram.js +96 -15
- package/package.json +2 -2
- package/src/solana/chain/modules/SolanaEvents.ts +199 -5
- package/src/solana/events/SolanaChainEventsBrowser.ts +4 -51
- package/src/solana/program/modules/SolanaProgramEvents.ts +44 -29
- package/src/solana/swaps/SolanaSwapData.ts +52 -1
- package/src/solana/swaps/SolanaSwapProgram.ts +146 -16
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { SolanaModule } from "../SolanaModule";
|
|
2
|
-
import { ConfirmedSignatureInfo, PublicKey } from "@solana/web3.js";
|
|
2
|
+
import { ConfirmedSignatureInfo, ParsedTransactionWithMeta, PublicKey } from "@solana/web3.js";
|
|
3
3
|
export declare class SolanaEvents extends SolanaModule {
|
|
4
4
|
readonly LOG_FETCH_LIMIT = 500;
|
|
5
|
+
private usingHeliusTFA;
|
|
5
6
|
/**
|
|
6
7
|
* Gets the signatures for a given topicKey public key, if lastProcessedSignature is specified, it fetches only
|
|
7
8
|
* the signatures before this signature
|
|
@@ -12,6 +13,43 @@ export declare class SolanaEvents extends SolanaModule {
|
|
|
12
13
|
* @private
|
|
13
14
|
*/
|
|
14
15
|
private getSignatures;
|
|
16
|
+
/**
|
|
17
|
+
* Implements Helius getTransactionsForAddress RPC API
|
|
18
|
+
*
|
|
19
|
+
* @param account
|
|
20
|
+
* @param options
|
|
21
|
+
* @param commitment
|
|
22
|
+
*/
|
|
23
|
+
getTransactionsForAddress(account: PublicKey, options?: {
|
|
24
|
+
paginationToken?: string;
|
|
25
|
+
filters?: {
|
|
26
|
+
slot?: {
|
|
27
|
+
gte?: number;
|
|
28
|
+
lte?: number;
|
|
29
|
+
gt?: number;
|
|
30
|
+
lt?: number;
|
|
31
|
+
};
|
|
32
|
+
blockTime?: {
|
|
33
|
+
gte?: number;
|
|
34
|
+
lte?: number;
|
|
35
|
+
gt?: number;
|
|
36
|
+
lt?: number;
|
|
37
|
+
eq?: number;
|
|
38
|
+
};
|
|
39
|
+
signature?: {
|
|
40
|
+
gte?: number;
|
|
41
|
+
lte?: number;
|
|
42
|
+
gt?: number;
|
|
43
|
+
lt?: number;
|
|
44
|
+
eq?: number;
|
|
45
|
+
};
|
|
46
|
+
status?: "succeeded" | "failed" | "any";
|
|
47
|
+
};
|
|
48
|
+
}, commitment?: "finalized" | "confirmed" | "processed"): Promise<{
|
|
49
|
+
data: ParsedTransactionWithMeta[];
|
|
50
|
+
paginationToken?: string;
|
|
51
|
+
}>;
|
|
52
|
+
private _findInTxsTFA;
|
|
15
53
|
/**
|
|
16
54
|
* Runs a search backwards in time, processing transaction signatures for a specific topic public key
|
|
17
55
|
*
|
|
@@ -20,6 +58,11 @@ export declare class SolanaEvents extends SolanaModule {
|
|
|
20
58
|
* was found, or null if the search should continue
|
|
21
59
|
* @param abortSignal
|
|
22
60
|
* @param logFetchLimit
|
|
61
|
+
* @param startBlockheight
|
|
23
62
|
*/
|
|
24
|
-
|
|
63
|
+
private _findInSignatures;
|
|
64
|
+
findInSignatures<T>(topicKey: PublicKey, processor: (data: {
|
|
65
|
+
signatures?: ConfirmedSignatureInfo[];
|
|
66
|
+
txs?: ParsedTransactionWithMeta[];
|
|
67
|
+
}) => Promise<T>, abortSignal?: AbortSignal, logFetchLimit?: number, startBlockheight?: number): Promise<T>;
|
|
25
68
|
}
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SolanaEvents = void 0;
|
|
4
4
|
const SolanaModule_1 = require("../SolanaModule");
|
|
5
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
5
6
|
class SolanaEvents extends SolanaModule_1.SolanaModule {
|
|
6
7
|
constructor() {
|
|
7
8
|
super(...arguments);
|
|
8
9
|
this.LOG_FETCH_LIMIT = 500;
|
|
10
|
+
this.usingHeliusTFA = "auto";
|
|
9
11
|
}
|
|
10
12
|
/**
|
|
11
13
|
* Gets the signatures for a given topicKey public key, if lastProcessedSignature is specified, it fetches only
|
|
@@ -29,6 +31,147 @@ class SolanaEvents extends SolanaModule_1.SolanaModule {
|
|
|
29
31
|
}, "confirmed");
|
|
30
32
|
}
|
|
31
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Implements Helius getTransactionsForAddress RPC API
|
|
36
|
+
*
|
|
37
|
+
* @param account
|
|
38
|
+
* @param options
|
|
39
|
+
* @param commitment
|
|
40
|
+
*/
|
|
41
|
+
async getTransactionsForAddress(account, options, commitment) {
|
|
42
|
+
//Try to use getPriorityFeeEstimate api of Helius
|
|
43
|
+
const response = await this.connection._rpcRequest("getTransactionsForAddress", [
|
|
44
|
+
account.toString(),
|
|
45
|
+
{
|
|
46
|
+
...options,
|
|
47
|
+
transactionDetails: "full",
|
|
48
|
+
sortOrder: "desc",
|
|
49
|
+
limit: 100,
|
|
50
|
+
commitment: commitment ?? "confirmed",
|
|
51
|
+
encoding: "jsonParsed",
|
|
52
|
+
maxSupportedTransactionVersion: 0
|
|
53
|
+
}
|
|
54
|
+
]).catch(e => {
|
|
55
|
+
//Catching not supported errors
|
|
56
|
+
if (e.message != null && (e.message.includes("-32601") || e.message.includes("-32600") || e.message.includes("-32403"))) {
|
|
57
|
+
return {
|
|
58
|
+
error: {
|
|
59
|
+
code: -32601,
|
|
60
|
+
message: e.message
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
throw e;
|
|
65
|
+
});
|
|
66
|
+
if (response.error != null) {
|
|
67
|
+
//Catching not supported errors
|
|
68
|
+
if (response.error.code !== -32601 && response.error.code !== -32600 && response.error.code !== -32403)
|
|
69
|
+
throw new Error(response.error.message);
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
data: response.result.data.map(val => {
|
|
74
|
+
return {
|
|
75
|
+
...val,
|
|
76
|
+
meta: val.meta == null ? undefined : {
|
|
77
|
+
//ParsedTransactionMeta
|
|
78
|
+
...val.meta,
|
|
79
|
+
innerInstructions: val.meta.innerInstructions == null ? undefined : val.meta.innerInstructions.map(innerIx => ({
|
|
80
|
+
//ParsedInnerInstruction
|
|
81
|
+
...innerIx,
|
|
82
|
+
instructions: innerIx.instructions.map(ix => {
|
|
83
|
+
if (ix.program != null && ix.programId != null) {
|
|
84
|
+
return {
|
|
85
|
+
//ParsedInstruction
|
|
86
|
+
...ix,
|
|
87
|
+
programId: new web3_js_1.PublicKey(ix.programId)
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
return {
|
|
92
|
+
//PartiallyDecodedInstruction
|
|
93
|
+
data: ix.data,
|
|
94
|
+
programId: new web3_js_1.PublicKey(ix.programId),
|
|
95
|
+
accounts: ix.accounts.map(pubkey => new web3_js_1.PublicKey(pubkey))
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
})),
|
|
100
|
+
loadedAddresses: val.meta.loadedAddresses == null ? undefined : {
|
|
101
|
+
writable: val.meta.loadedAddresses.writable.map(pubkey => new web3_js_1.PublicKey(pubkey)),
|
|
102
|
+
readonly: val.meta.loadedAddresses.readonly.map(pubkey => new web3_js_1.PublicKey(pubkey)),
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
transaction: {
|
|
106
|
+
//ParsedTransaction
|
|
107
|
+
...val.transaction,
|
|
108
|
+
message: {
|
|
109
|
+
//ParsedMessage
|
|
110
|
+
...val.transaction.message,
|
|
111
|
+
accountKeys: val.transaction.message.accountKeys.map(accountKey => ({
|
|
112
|
+
//ParsedMessageAccount
|
|
113
|
+
...accountKey,
|
|
114
|
+
pubkey: new web3_js_1.PublicKey(accountKey.pubkey)
|
|
115
|
+
})),
|
|
116
|
+
instructions: val.transaction.message.instructions.map(ix => {
|
|
117
|
+
if (ix.program != null && ix.programId != null) {
|
|
118
|
+
return {
|
|
119
|
+
//ParsedInstruction
|
|
120
|
+
...ix,
|
|
121
|
+
programId: new web3_js_1.PublicKey(ix.programId)
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
return {
|
|
126
|
+
//PartiallyDecodedInstruction
|
|
127
|
+
data: ix.data,
|
|
128
|
+
programId: new web3_js_1.PublicKey(ix.programId),
|
|
129
|
+
accounts: ix.accounts.map(pubkey => new web3_js_1.PublicKey(pubkey))
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}),
|
|
133
|
+
addressTableLookups: val.transaction.message.addressTableLookups == null ? undefined : val.transaction.message.addressTableLookups.map(addressTableLookup => ({
|
|
134
|
+
//ParsedAddressTableLookup
|
|
135
|
+
...addressTableLookup,
|
|
136
|
+
accountKey: new web3_js_1.PublicKey(addressTableLookup.accountKey)
|
|
137
|
+
}))
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}),
|
|
142
|
+
paginationToken: response.result.paginationToken
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
async _findInTxsTFA(topicKey, processor, abortSignal, startBlockheight) {
|
|
146
|
+
let paginationToken;
|
|
147
|
+
let txs = null;
|
|
148
|
+
while (txs == null || txs.length > 0) {
|
|
149
|
+
let filters = startBlockheight != null ? {
|
|
150
|
+
slot: { gte: startBlockheight }
|
|
151
|
+
} : {};
|
|
152
|
+
const tfaResult = await this.getTransactionsForAddress(topicKey, {
|
|
153
|
+
paginationToken,
|
|
154
|
+
filters: {
|
|
155
|
+
...filters,
|
|
156
|
+
status: "succeeded"
|
|
157
|
+
}
|
|
158
|
+
}, "confirmed");
|
|
159
|
+
if (tfaResult == null) {
|
|
160
|
+
//Not supported
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
txs = tfaResult.data;
|
|
164
|
+
paginationToken = tfaResult.paginationToken;
|
|
165
|
+
if (abortSignal != null)
|
|
166
|
+
abortSignal.throwIfAborted();
|
|
167
|
+
const result = await processor({ txs });
|
|
168
|
+
if (result != null)
|
|
169
|
+
return result;
|
|
170
|
+
if (paginationToken == null)
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
32
175
|
/**
|
|
33
176
|
* Runs a search backwards in time, processing transaction signatures for a specific topic public key
|
|
34
177
|
*
|
|
@@ -37,16 +180,24 @@ class SolanaEvents extends SolanaModule_1.SolanaModule {
|
|
|
37
180
|
* was found, or null if the search should continue
|
|
38
181
|
* @param abortSignal
|
|
39
182
|
* @param logFetchLimit
|
|
183
|
+
* @param startBlockheight
|
|
40
184
|
*/
|
|
41
|
-
async
|
|
185
|
+
async _findInSignatures(topicKey, processor, abortSignal, logFetchLimit, startBlockheight) {
|
|
42
186
|
if (logFetchLimit == null || logFetchLimit > this.LOG_FETCH_LIMIT)
|
|
43
187
|
logFetchLimit = this.LOG_FETCH_LIMIT;
|
|
44
188
|
let signatures = null;
|
|
45
189
|
while (signatures == null || signatures.length > 0) {
|
|
46
190
|
signatures = await this.getSignatures(topicKey, logFetchLimit, signatures != null ? signatures[signatures.length - 1].signature : null);
|
|
191
|
+
if (startBlockheight != null) {
|
|
192
|
+
const endIndex = signatures.findIndex(val => val.slot < startBlockheight);
|
|
193
|
+
if (endIndex === 0)
|
|
194
|
+
return null;
|
|
195
|
+
if (endIndex !== -1)
|
|
196
|
+
signatures = signatures.slice(0, endIndex - 1);
|
|
197
|
+
}
|
|
47
198
|
if (abortSignal != null)
|
|
48
199
|
abortSignal.throwIfAborted();
|
|
49
|
-
const result = await processor(signatures);
|
|
200
|
+
const result = await processor({ signatures });
|
|
50
201
|
if (result != null)
|
|
51
202
|
return result;
|
|
52
203
|
if (signatures.length < logFetchLimit)
|
|
@@ -54,5 +205,19 @@ class SolanaEvents extends SolanaModule_1.SolanaModule {
|
|
|
54
205
|
}
|
|
55
206
|
return null;
|
|
56
207
|
}
|
|
208
|
+
async findInSignatures(topicKey, processor, abortSignal, logFetchLimit, startBlockheight) {
|
|
209
|
+
if (this.usingHeliusTFA !== "no") {
|
|
210
|
+
//Attempt to use Helius's gTFA
|
|
211
|
+
const result = await this._findInTxsTFA(topicKey, processor, abortSignal, startBlockheight);
|
|
212
|
+
if (result !== undefined)
|
|
213
|
+
return result;
|
|
214
|
+
//Not supported
|
|
215
|
+
if (this.usingHeliusTFA === "yes")
|
|
216
|
+
throw new Error("Helius gTFA is not supported with current provider!");
|
|
217
|
+
//If set to auto, we can manually set to "no"
|
|
218
|
+
this.usingHeliusTFA = "no";
|
|
219
|
+
}
|
|
220
|
+
return await this._findInSignatures(topicKey, processor, abortSignal, logFetchLimit, startBlockheight);
|
|
221
|
+
}
|
|
57
222
|
}
|
|
58
223
|
exports.SolanaEvents = SolanaEvents;
|
|
@@ -3,7 +3,7 @@ import { SolanaSwapData } from "../swaps/SolanaSwapData";
|
|
|
3
3
|
import { IdlEvents } from "@coral-xyz/anchor";
|
|
4
4
|
import { SolanaSwapProgram } from "../swaps/SolanaSwapProgram";
|
|
5
5
|
import { Connection } from "@solana/web3.js";
|
|
6
|
-
import { InstructionWithAccounts, ProgramEvent
|
|
6
|
+
import { InstructionWithAccounts, ProgramEvent } from "../program/modules/SolanaProgramEvents";
|
|
7
7
|
import { SwapProgram } from "../swaps/programTypes";
|
|
8
8
|
export type EventObject = {
|
|
9
9
|
events: ProgramEvent<SwapProgram>[];
|
|
@@ -11,7 +11,6 @@ export type EventObject = {
|
|
|
11
11
|
blockTime: number;
|
|
12
12
|
signature: string;
|
|
13
13
|
};
|
|
14
|
-
export type InitInstruction = SingleInstructionWithAccounts<SwapProgram["instructions"][2 | 3], SwapProgram>;
|
|
15
14
|
/**
|
|
16
15
|
* Solana on-chain event handler for front-end systems without access to fs, uses pure WS to subscribe, might lose
|
|
17
16
|
* out on some events if the network is unreliable, front-end systems should take this into consideration and not
|
|
@@ -36,15 +35,6 @@ export declare class SolanaChainEventsBrowser implements ChainEvents<SolanaSwapD
|
|
|
36
35
|
* @returns {Promise<InstructionWithAccounts<SwapProgram>[]>} array of parsed instructions
|
|
37
36
|
*/
|
|
38
37
|
private getTransactionInstructions;
|
|
39
|
-
/**
|
|
40
|
-
* Converts initialize instruction data into {SolanaSwapData}
|
|
41
|
-
*
|
|
42
|
-
* @param initIx
|
|
43
|
-
* @param txoHash
|
|
44
|
-
* @private
|
|
45
|
-
* @returns {SolanaSwapData} converted and parsed swap data
|
|
46
|
-
*/
|
|
47
|
-
private instructionToSwapData;
|
|
48
38
|
/**
|
|
49
39
|
* Returns async getter for fetching on-demand initialize event swap data
|
|
50
40
|
*
|
|
@@ -4,8 +4,6 @@ exports.SolanaChainEventsBrowser = void 0;
|
|
|
4
4
|
const base_1 = require("@atomiqlabs/base");
|
|
5
5
|
const SolanaSwapData_1 = require("../swaps/SolanaSwapData");
|
|
6
6
|
const Utils_1 = require("../../utils/Utils");
|
|
7
|
-
const web3_js_1 = require("@solana/web3.js");
|
|
8
|
-
const BN = require("bn.js");
|
|
9
7
|
const SwapTypeEnum_1 = require("../swaps/SwapTypeEnum");
|
|
10
8
|
const buffer_1 = require("buffer");
|
|
11
9
|
/**
|
|
@@ -43,26 +41,6 @@ class SolanaChainEventsBrowser {
|
|
|
43
41
|
return null;
|
|
44
42
|
return this.solanaSwapProgram.Events.decodeInstructions(transaction.transaction.message);
|
|
45
43
|
}
|
|
46
|
-
/**
|
|
47
|
-
* Converts initialize instruction data into {SolanaSwapData}
|
|
48
|
-
*
|
|
49
|
-
* @param initIx
|
|
50
|
-
* @param txoHash
|
|
51
|
-
* @private
|
|
52
|
-
* @returns {SolanaSwapData} converted and parsed swap data
|
|
53
|
-
*/
|
|
54
|
-
instructionToSwapData(initIx, txoHash) {
|
|
55
|
-
const paymentHash = buffer_1.Buffer.from(initIx.data.swapData.hash);
|
|
56
|
-
let securityDeposit = new BN(0);
|
|
57
|
-
let claimerBounty = new BN(0);
|
|
58
|
-
let payIn = true;
|
|
59
|
-
if (initIx.name === "offererInitialize") {
|
|
60
|
-
payIn = false;
|
|
61
|
-
securityDeposit = initIx.data.securityDeposit;
|
|
62
|
-
claimerBounty = initIx.data.claimerBounty;
|
|
63
|
-
}
|
|
64
|
-
return new SolanaSwapData_1.SolanaSwapData(initIx.accounts.offerer, initIx.accounts.claimer, initIx.accounts.mint, initIx.data.swapData.amount, paymentHash.toString("hex"), initIx.data.swapData.sequence, initIx.data.swapData.expiry, initIx.data.swapData.nonce, initIx.data.swapData.confirmations, initIx.data.swapData.payOut, SwapTypeEnum_1.SwapTypeEnum.toNumber(initIx.data.swapData.kind), payIn, initIx.name === "offererInitializePayIn" ? initIx.accounts.offererAta : web3_js_1.PublicKey.default, initIx.data.swapData.payOut ? initIx.accounts.claimerAta : web3_js_1.PublicKey.default, securityDeposit, claimerBounty, txoHash);
|
|
65
|
-
}
|
|
66
44
|
/**
|
|
67
45
|
* Returns async getter for fetching on-demand initialize event swap data
|
|
68
46
|
*
|
|
@@ -80,7 +58,7 @@ class SolanaChainEventsBrowser {
|
|
|
80
58
|
const initIx = eventObject.instructions.find(ix => ix != null && (ix.name === "offererInitializePayIn" || ix.name === "offererInitialize"));
|
|
81
59
|
if (initIx == null)
|
|
82
60
|
return null;
|
|
83
|
-
return
|
|
61
|
+
return SolanaSwapData_1.SolanaSwapData.fromInstruction(initIx, txoHash);
|
|
84
62
|
};
|
|
85
63
|
}
|
|
86
64
|
parseInitializeEvent(data, eventObject) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SolanaEvents } from "../../chain/modules/SolanaEvents";
|
|
2
2
|
import { DecodeType, Event, Idl, IdlTypes } from "@coral-xyz/anchor";
|
|
3
3
|
import { IdlField, IdlInstruction } from "@coral-xyz/anchor/dist/cjs/idl";
|
|
4
|
-
import {
|
|
4
|
+
import { ParsedMessage, ParsedTransactionWithMeta, PublicKey } from "@solana/web3.js";
|
|
5
5
|
import { SolanaProgramBase } from "../SolanaProgramBase";
|
|
6
6
|
import { SolanaChainInterface } from "../../chain/SolanaChainInterface";
|
|
7
7
|
type DecodedFieldOrNull<D, Defined> = D extends IdlField ? DecodeType<D["type"], Defined> : unknown;
|
|
@@ -25,13 +25,6 @@ export declare class SolanaProgramEvents<IDL extends Idl> extends SolanaEvents {
|
|
|
25
25
|
private readonly program;
|
|
26
26
|
private readonly nameMappedInstructions;
|
|
27
27
|
constructor(chain: SolanaChainInterface, program: SolanaProgramBase<IDL>);
|
|
28
|
-
/**
|
|
29
|
-
* Gets events from specific transaction as specified by signature, events are ordered from newest to oldest
|
|
30
|
-
*
|
|
31
|
-
* @param signature
|
|
32
|
-
* @private
|
|
33
|
-
*/
|
|
34
|
-
private getEvents;
|
|
35
28
|
/**
|
|
36
29
|
* Runs a search backwards in time, processing the events for a specific topic public key
|
|
37
30
|
*
|
|
@@ -40,8 +33,9 @@ export declare class SolanaProgramEvents<IDL extends Idl> extends SolanaEvents {
|
|
|
40
33
|
* if the search should continue
|
|
41
34
|
* @param abortSignal
|
|
42
35
|
* @param logBatchSize how many signatures should be fetched in one getSignaturesForAddress call
|
|
36
|
+
* @param startBlockheight
|
|
43
37
|
*/
|
|
44
|
-
findInEvents<T>(topicKey: PublicKey, processor: (event: ProgramEvent<IDL>,
|
|
38
|
+
findInEvents<T>(topicKey: PublicKey, processor: (event: ProgramEvent<IDL>, tx: ParsedTransactionWithMeta) => Promise<T>, abortSignal?: AbortSignal, logBatchSize?: number, startBlockheight?: number): Promise<T>;
|
|
45
39
|
/**
|
|
46
40
|
* Decodes the instructions for this program from the transaction, leaves null in the returned instructions array
|
|
47
41
|
* for every instruction that doesn't correspond to this program (as those are impossible to parse)
|
|
@@ -14,23 +14,6 @@ class SolanaProgramEvents extends SolanaEvents_1.SolanaEvents {
|
|
|
14
14
|
this.nameMappedInstructions[ix.name] = ix;
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
/**
|
|
18
|
-
* Gets events from specific transaction as specified by signature, events are ordered from newest to oldest
|
|
19
|
-
*
|
|
20
|
-
* @param signature
|
|
21
|
-
* @private
|
|
22
|
-
*/
|
|
23
|
-
async getEvents(signature) {
|
|
24
|
-
const tx = await this.connection.getTransaction(signature, {
|
|
25
|
-
commitment: "confirmed",
|
|
26
|
-
maxSupportedTransactionVersion: 0
|
|
27
|
-
});
|
|
28
|
-
if (tx.meta.err)
|
|
29
|
-
return [];
|
|
30
|
-
const events = this.parseLogs(tx.meta.logMessages);
|
|
31
|
-
events.reverse();
|
|
32
|
-
return events;
|
|
33
|
-
}
|
|
34
17
|
/**
|
|
35
18
|
* Runs a search backwards in time, processing the events for a specific topic public key
|
|
36
19
|
*
|
|
@@ -39,19 +22,47 @@ class SolanaProgramEvents extends SolanaEvents_1.SolanaEvents {
|
|
|
39
22
|
* if the search should continue
|
|
40
23
|
* @param abortSignal
|
|
41
24
|
* @param logBatchSize how many signatures should be fetched in one getSignaturesForAddress call
|
|
25
|
+
* @param startBlockheight
|
|
42
26
|
*/
|
|
43
|
-
findInEvents(topicKey, processor, abortSignal, logBatchSize) {
|
|
44
|
-
return this.findInSignatures(topicKey, async (
|
|
45
|
-
|
|
46
|
-
for (let
|
|
47
|
-
if (
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
27
|
+
findInEvents(topicKey, processor, abortSignal, logBatchSize, startBlockheight) {
|
|
28
|
+
return this.findInSignatures(topicKey, async (data) => {
|
|
29
|
+
if (data.signatures) {
|
|
30
|
+
for (let info of data.signatures) {
|
|
31
|
+
if (info.err == null)
|
|
32
|
+
continue;
|
|
33
|
+
const tx = await this.connection.getParsedTransaction(info.signature, {
|
|
34
|
+
commitment: "confirmed",
|
|
35
|
+
maxSupportedTransactionVersion: 0
|
|
36
|
+
});
|
|
37
|
+
if (tx.meta.err)
|
|
38
|
+
continue;
|
|
39
|
+
const events = this.parseLogs(tx.meta.logMessages);
|
|
40
|
+
events.reverse();
|
|
41
|
+
for (let event of events) {
|
|
42
|
+
if (abortSignal != null)
|
|
43
|
+
abortSignal.throwIfAborted();
|
|
44
|
+
const result = await processor(event, tx);
|
|
45
|
+
if (result != null)
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
for (let tx of data.txs) {
|
|
52
|
+
if (tx.meta.err)
|
|
53
|
+
continue;
|
|
54
|
+
const events = this.parseLogs(tx.meta.logMessages);
|
|
55
|
+
events.reverse();
|
|
56
|
+
for (let event of events) {
|
|
57
|
+
if (abortSignal != null)
|
|
58
|
+
abortSignal.throwIfAborted();
|
|
59
|
+
const result = await processor(event, tx);
|
|
60
|
+
if (result != null)
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
52
63
|
}
|
|
53
64
|
}
|
|
54
|
-
}, abortSignal, logBatchSize);
|
|
65
|
+
}, abortSignal, logBatchSize, startBlockheight);
|
|
55
66
|
}
|
|
56
67
|
/**
|
|
57
68
|
* Decodes the instructions for this program from the transaction, leaves null in the returned instructions array
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { PublicKey } from "@solana/web3.js";
|
|
2
2
|
import * as BN from "bn.js";
|
|
3
|
-
import {
|
|
3
|
+
import { ChainSwapType, SwapData } from "@atomiqlabs/base";
|
|
4
4
|
import { SwapProgram } from "./programTypes";
|
|
5
5
|
import { IdlAccounts, IdlTypes } from "@coral-xyz/anchor";
|
|
6
|
+
import { SingleInstructionWithAccounts } from "../program/modules/SolanaProgramEvents";
|
|
7
|
+
export type InitInstruction = SingleInstructionWithAccounts<SwapProgram["instructions"][2 | 3], SwapProgram>;
|
|
6
8
|
export declare class SolanaSwapData extends SwapData {
|
|
7
9
|
offerer: PublicKey;
|
|
8
10
|
claimer: PublicKey;
|
|
@@ -41,6 +43,7 @@ export declare class SolanaSwapData extends SwapData {
|
|
|
41
43
|
getEscrowHash(): string;
|
|
42
44
|
getSequence(): bigint;
|
|
43
45
|
getTxoHashHint(): string;
|
|
46
|
+
getHTLCHashHint(): string;
|
|
44
47
|
getExtraData(): string;
|
|
45
48
|
setExtraData(txoHash: string): void;
|
|
46
49
|
getSecurityDeposit(): bigint;
|
|
@@ -49,6 +52,15 @@ export declare class SolanaSwapData extends SwapData {
|
|
|
49
52
|
toSwapDataStruct(): IdlTypes<SwapProgram>["SwapData"];
|
|
50
53
|
correctPDA(account: IdlAccounts<SwapProgram>["escrowState"]): boolean;
|
|
51
54
|
equals(other: SolanaSwapData): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Converts initialize instruction data into {SolanaSwapData}
|
|
57
|
+
*
|
|
58
|
+
* @param initIx
|
|
59
|
+
* @param txoHash
|
|
60
|
+
* @private
|
|
61
|
+
* @returns {SolanaSwapData} converted and parsed swap data
|
|
62
|
+
*/
|
|
63
|
+
static fromInstruction(initIx: InitInstruction, txoHash: string): SolanaSwapData;
|
|
52
64
|
static fromEscrowState(account: IdlAccounts<SwapProgram>["escrowState"]): SolanaSwapData;
|
|
53
65
|
static typeToKind(type: ChainSwapType): number;
|
|
54
66
|
static kindToType(value: number): ChainSwapType;
|
|
@@ -135,6 +135,11 @@ class SolanaSwapData extends base_1.SwapData {
|
|
|
135
135
|
return null; //Txo hash opt-out flag
|
|
136
136
|
return this.txoHash;
|
|
137
137
|
}
|
|
138
|
+
getHTLCHashHint() {
|
|
139
|
+
if (this.getType() === base_1.ChainSwapType.HTLC)
|
|
140
|
+
return this.paymentHash;
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
138
143
|
getExtraData() {
|
|
139
144
|
return this.txoHash;
|
|
140
145
|
}
|
|
@@ -213,6 +218,26 @@ class SolanaSwapData extends base_1.SwapData {
|
|
|
213
218
|
other.claimerBounty.eq(this.claimerBounty) &&
|
|
214
219
|
other.token.equals(this.token);
|
|
215
220
|
}
|
|
221
|
+
/**
|
|
222
|
+
* Converts initialize instruction data into {SolanaSwapData}
|
|
223
|
+
*
|
|
224
|
+
* @param initIx
|
|
225
|
+
* @param txoHash
|
|
226
|
+
* @private
|
|
227
|
+
* @returns {SolanaSwapData} converted and parsed swap data
|
|
228
|
+
*/
|
|
229
|
+
static fromInstruction(initIx, txoHash) {
|
|
230
|
+
const paymentHash = buffer_1.Buffer.from(initIx.data.swapData.hash);
|
|
231
|
+
let securityDeposit = new BN(0);
|
|
232
|
+
let claimerBounty = new BN(0);
|
|
233
|
+
let payIn = true;
|
|
234
|
+
if (initIx.name === "offererInitialize") {
|
|
235
|
+
payIn = false;
|
|
236
|
+
securityDeposit = initIx.data.securityDeposit;
|
|
237
|
+
claimerBounty = initIx.data.claimerBounty;
|
|
238
|
+
}
|
|
239
|
+
return new SolanaSwapData(initIx.accounts.offerer, initIx.accounts.claimer, initIx.accounts.mint, initIx.data.swapData.amount, paymentHash.toString("hex"), initIx.data.swapData.sequence, initIx.data.swapData.expiry, initIx.data.swapData.nonce, initIx.data.swapData.confirmations, initIx.data.swapData.payOut, SwapTypeEnum_1.SwapTypeEnum.toNumber(initIx.data.swapData.kind), payIn, initIx.name === "offererInitializePayIn" ? initIx.accounts.offererAta : web3_js_1.PublicKey.default, initIx.data.swapData.payOut ? initIx.accounts.claimerAta : web3_js_1.PublicKey.default, securityDeposit, claimerBounty, txoHash);
|
|
240
|
+
}
|
|
216
241
|
static fromEscrowState(account) {
|
|
217
242
|
const data = account.data;
|
|
218
243
|
return new SolanaSwapData(account.offerer, account.claimer, account.mint, data.amount, buffer_1.Buffer.from(data.hash).toString("hex"), data.sequence, data.expiry, data.nonce, data.confirmations, data.payOut, SwapTypeEnum_1.SwapTypeEnum.toNumber(data.kind), data.payIn, account.offererAta, account.claimerAta, account.securityDeposit, account.claimerBounty, null);
|
|
@@ -137,6 +137,22 @@ export declare class SolanaSwapProgram extends SolanaProgramBase<SwapProgram> im
|
|
|
137
137
|
* @param claimHashHex
|
|
138
138
|
*/
|
|
139
139
|
getCommitedData(claimHashHex: string): Promise<SolanaSwapData>;
|
|
140
|
+
getHistoricalSwaps(signer: string, startBlockheight?: number): Promise<{
|
|
141
|
+
swaps: {
|
|
142
|
+
[escrowHash: string]: {
|
|
143
|
+
init?: {
|
|
144
|
+
data: SolanaSwapData;
|
|
145
|
+
getInitTxId: () => Promise<string>;
|
|
146
|
+
getTxBlock: () => Promise<{
|
|
147
|
+
blockTime: number;
|
|
148
|
+
blockHeight: number;
|
|
149
|
+
}>;
|
|
150
|
+
};
|
|
151
|
+
state: SwapCommitState;
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
latestBlockheight: number;
|
|
155
|
+
}>;
|
|
140
156
|
createSwapData(type: ChainSwapType, offerer: string, claimer: string, token: string, amount: bigint, claimHash: string, sequence: bigint, expiry: bigint, payIn: boolean, payOut: boolean, securityDeposit: bigint, claimerBounty: bigint, depositToken?: string): Promise<SolanaSwapData>;
|
|
141
157
|
getBalance(signer: string, tokenAddress: string, inContract: boolean): Promise<bigint>;
|
|
142
158
|
getIntermediaryData(address: string, token: string): Promise<{
|