@atomiqlabs/chain-starknet 4.0.0-dev.35 → 4.0.0-dev.37
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/starknet/chain/StarknetChainInterface.d.ts +4 -0
- package/dist/starknet/chain/StarknetChainInterface.js +7 -0
- package/dist/starknet/chain/modules/StarknetBlocks.d.ts +8 -1
- package/dist/starknet/chain/modules/StarknetBlocks.js +16 -7
- package/dist/starknet/chain/modules/StarknetEvents.d.ts +2 -1
- package/dist/starknet/chain/modules/StarknetEvents.js +3 -1
- package/dist/starknet/chain/modules/StarknetTransactions.d.ts +2 -2
- package/dist/starknet/chain/modules/StarknetTransactions.js +21 -13
- package/dist/starknet/contract/modules/StarknetContractEvents.d.ts +2 -1
- package/dist/starknet/contract/modules/StarknetContractEvents.js +3 -2
- package/dist/starknet/spv_swap/StarknetSpvVaultContract.d.ts +5 -2
- package/dist/starknet/spv_swap/StarknetSpvVaultContract.js +25 -19
- package/package.json +2 -2
- package/src/starknet/chain/StarknetChainInterface.ts +8 -0
- package/src/starknet/chain/modules/StarknetBlocks.ts +21 -10
- package/src/starknet/chain/modules/StarknetEvents.ts +3 -0
- package/src/starknet/chain/modules/StarknetTransactions.ts +24 -16
- package/src/starknet/contract/modules/StarknetContractEvents.ts +3 -1
- package/src/starknet/spv_swap/StarknetSpvVaultContract.ts +32 -22
|
@@ -50,6 +50,10 @@ export declare class StarknetChainInterface implements ChainInterface<StarknetTx
|
|
|
50
50
|
deserializeTx(txData: string): Promise<StarknetTx>;
|
|
51
51
|
getTxIdStatus(txId: string): Promise<"not_found" | "pending" | "success" | "reverted">;
|
|
52
52
|
getTxStatus(tx: string): Promise<"not_found" | "pending" | "success" | "reverted">;
|
|
53
|
+
getFinalizedBlock(): Promise<{
|
|
54
|
+
height: number;
|
|
55
|
+
blockHash: string;
|
|
56
|
+
}>;
|
|
53
57
|
txsTransfer(signer: string, token: string, amount: bigint, dstAddress: string, feeRate?: string): Promise<StarknetTx[]>;
|
|
54
58
|
transfer(signer: StarknetSigner, token: string, amount: bigint, dstAddress: string, txOptions?: TransactionConfirmationOptions): Promise<string>;
|
|
55
59
|
wrapSigner(signer: Account): Promise<StarknetSigner>;
|
|
@@ -89,6 +89,13 @@ class StarknetChainInterface {
|
|
|
89
89
|
getTxStatus(tx) {
|
|
90
90
|
return this.Transactions.getTxStatus(tx);
|
|
91
91
|
}
|
|
92
|
+
async getFinalizedBlock() {
|
|
93
|
+
const block = await this.Blocks.getBlock("l1_accepted");
|
|
94
|
+
return {
|
|
95
|
+
height: block.block_number,
|
|
96
|
+
blockHash: block.block_hash
|
|
97
|
+
};
|
|
98
|
+
}
|
|
92
99
|
txsTransfer(signer, token, amount, dstAddress, feeRate) {
|
|
93
100
|
return this.Tokens.txsTransfer(signer, token, amount, dstAddress, feeRate);
|
|
94
101
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { StarknetModule } from "../StarknetModule";
|
|
2
|
-
|
|
2
|
+
import { BlockWithTxHashes } from "starknet";
|
|
3
|
+
export type StarknetBlockTag = "pre_confirmed" | "latest" | "l1_accepted";
|
|
3
4
|
export declare class StarknetBlocks extends StarknetModule {
|
|
4
5
|
private BLOCK_CACHE_TIME;
|
|
5
6
|
private blockCache;
|
|
@@ -11,6 +12,12 @@ export declare class StarknetBlocks extends StarknetModule {
|
|
|
11
12
|
*/
|
|
12
13
|
private fetchAndSaveBlockTime;
|
|
13
14
|
private cleanupBlocks;
|
|
15
|
+
/**
|
|
16
|
+
* Gets the block for a given blocktag, with caching
|
|
17
|
+
*
|
|
18
|
+
* @param blockTag
|
|
19
|
+
*/
|
|
20
|
+
getBlock(blockTag: StarknetBlockTag | number): Promise<BlockWithTxHashes>;
|
|
14
21
|
/**
|
|
15
22
|
* Gets the block for a given blocktag, with caching
|
|
16
23
|
*
|
|
@@ -16,19 +16,19 @@ class StarknetBlocks extends StarknetModule_1.StarknetModule {
|
|
|
16
16
|
*/
|
|
17
17
|
fetchAndSaveBlockTime(blockTag) {
|
|
18
18
|
const blockTagStr = blockTag.toString(10);
|
|
19
|
-
const
|
|
19
|
+
const blockPromise = this.provider.getBlockWithTxHashes(blockTag);
|
|
20
20
|
const timestamp = Date.now();
|
|
21
21
|
this.blockCache[blockTagStr] = {
|
|
22
|
-
|
|
22
|
+
block: blockPromise,
|
|
23
23
|
timestamp
|
|
24
24
|
};
|
|
25
|
-
|
|
26
|
-
if (this.blockCache[blockTagStr] != null && this.blockCache[blockTagStr].
|
|
25
|
+
blockPromise.catch(e => {
|
|
26
|
+
if (this.blockCache[blockTagStr] != null && this.blockCache[blockTagStr].block === blockPromise)
|
|
27
27
|
delete this.blockCache[blockTagStr];
|
|
28
28
|
throw e;
|
|
29
29
|
});
|
|
30
30
|
return {
|
|
31
|
-
|
|
31
|
+
block: blockPromise,
|
|
32
32
|
timestamp
|
|
33
33
|
};
|
|
34
34
|
}
|
|
@@ -52,13 +52,22 @@ class StarknetBlocks extends StarknetModule_1.StarknetModule {
|
|
|
52
52
|
*
|
|
53
53
|
* @param blockTag
|
|
54
54
|
*/
|
|
55
|
-
|
|
55
|
+
getBlock(blockTag) {
|
|
56
56
|
this.cleanupBlocks();
|
|
57
57
|
let cachedBlockData = this.blockCache[blockTag.toString(10)];
|
|
58
58
|
if (cachedBlockData == null || Date.now() - cachedBlockData.timestamp > this.BLOCK_CACHE_TIME) {
|
|
59
59
|
cachedBlockData = this.fetchAndSaveBlockTime(blockTag);
|
|
60
60
|
}
|
|
61
|
-
return cachedBlockData.
|
|
61
|
+
return cachedBlockData.block;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Gets the block for a given blocktag, with caching
|
|
65
|
+
*
|
|
66
|
+
* @param blockTag
|
|
67
|
+
*/
|
|
68
|
+
async getBlockTime(blockTag) {
|
|
69
|
+
const block = await this.getBlock(blockTag);
|
|
70
|
+
return block.timestamp;
|
|
62
71
|
}
|
|
63
72
|
}
|
|
64
73
|
exports.StarknetBlocks = StarknetBlocks;
|
|
@@ -37,8 +37,9 @@ export declare class StarknetEvents extends StarknetModule {
|
|
|
37
37
|
* @param keys
|
|
38
38
|
* @param processor called for every batch of returned signatures, should return a value if the correct signature
|
|
39
39
|
* was found, or null if the search should continue
|
|
40
|
+
* @param startHeight
|
|
40
41
|
* @param abortSignal
|
|
41
42
|
* @param logFetchLimit
|
|
42
43
|
*/
|
|
43
|
-
findInEventsForward<T>(contract: string, keys: string[][], processor: (signatures: StarknetEvent[]) => Promise<T>, abortSignal?: AbortSignal, logFetchLimit?: number): Promise<T>;
|
|
44
|
+
findInEventsForward<T>(contract: string, keys: string[][], processor: (signatures: StarknetEvent[]) => Promise<T>, startHeight?: number, abortSignal?: AbortSignal, logFetchLimit?: number): Promise<T>;
|
|
44
45
|
}
|
|
@@ -61,16 +61,18 @@ class StarknetEvents extends StarknetModule_1.StarknetModule {
|
|
|
61
61
|
* @param keys
|
|
62
62
|
* @param processor called for every batch of returned signatures, should return a value if the correct signature
|
|
63
63
|
* was found, or null if the search should continue
|
|
64
|
+
* @param startHeight
|
|
64
65
|
* @param abortSignal
|
|
65
66
|
* @param logFetchLimit
|
|
66
67
|
*/
|
|
67
|
-
async findInEventsForward(contract, keys, processor, abortSignal, logFetchLimit) {
|
|
68
|
+
async findInEventsForward(contract, keys, processor, startHeight, abortSignal, logFetchLimit) {
|
|
68
69
|
if (logFetchLimit == null || logFetchLimit > this.EVENTS_LIMIT)
|
|
69
70
|
logFetchLimit = this.EVENTS_LIMIT;
|
|
70
71
|
let eventsResult = null;
|
|
71
72
|
while (eventsResult == null || eventsResult?.continuation_token != null) {
|
|
72
73
|
eventsResult = await this.root.provider.getEvents({
|
|
73
74
|
address: contract,
|
|
75
|
+
from_block: startHeight == null ? undefined : { block_number: startHeight },
|
|
74
76
|
to_block: "latest",
|
|
75
77
|
keys,
|
|
76
78
|
chunk_size: logFetchLimit ?? this.EVENTS_LIMIT,
|
|
@@ -65,7 +65,7 @@ export declare class StarknetTransactions extends StarknetModule {
|
|
|
65
65
|
* of a batch of starknet transactions
|
|
66
66
|
*
|
|
67
67
|
* @param signer
|
|
68
|
-
* @param
|
|
68
|
+
* @param _txs transactions to send
|
|
69
69
|
* @param waitForConfirmation whether to wait for transaction confirmations (this also makes sure the transactions
|
|
70
70
|
* are re-sent at regular intervals)
|
|
71
71
|
* @param abortSignal abort signal to abort waiting for transaction confirmations
|
|
@@ -73,7 +73,7 @@ export declare class StarknetTransactions extends StarknetModule {
|
|
|
73
73
|
* are executed in order)
|
|
74
74
|
* @param onBeforePublish a callback called before every transaction is published
|
|
75
75
|
*/
|
|
76
|
-
sendAndConfirm(signer: StarknetSigner,
|
|
76
|
+
sendAndConfirm(signer: StarknetSigner, _txs: StarknetTx[], waitForConfirmation?: boolean, abortSignal?: AbortSignal, parallel?: boolean, onBeforePublish?: (txId: string, rawTx: string) => Promise<void>): Promise<string[]>;
|
|
77
77
|
/**
|
|
78
78
|
* Serializes the starknet transaction, saves the transaction, signers & last valid blockheight
|
|
79
79
|
*
|
|
@@ -144,8 +144,11 @@ class StarknetTransactions extends StarknetModule_1.StarknetModule {
|
|
|
144
144
|
//Add deploy account tx
|
|
145
145
|
if (nonce === 0n) {
|
|
146
146
|
const deployPayload = await signer.getDeployPayload();
|
|
147
|
-
if (deployPayload != null)
|
|
148
|
-
|
|
147
|
+
if (deployPayload != null) {
|
|
148
|
+
const tx = await this.root.Accounts.getAccountDeployTransaction(deployPayload);
|
|
149
|
+
tx.addedInPrepare = true;
|
|
150
|
+
txs.unshift(tx);
|
|
151
|
+
}
|
|
149
152
|
}
|
|
150
153
|
if (!signer.isManagingNoncesInternally) {
|
|
151
154
|
if (nonce === 0n) {
|
|
@@ -160,7 +163,7 @@ class StarknetTransactions extends StarknetModule_1.StarknetModule {
|
|
|
160
163
|
nonce = BigInt(await this.root.provider.getNonceForAddress(signer.getAddress())); //Fetch the nonce
|
|
161
164
|
if (tx.details.nonce == null)
|
|
162
165
|
tx.details.nonce = nonce;
|
|
163
|
-
this.logger.debug("
|
|
166
|
+
this.logger.debug("prepareTransactions(): transaction prepared (" + (i + 1) + "/" + txs.length + "), nonce: " + tx.details.nonce);
|
|
164
167
|
nonce += BigInt(1);
|
|
165
168
|
}
|
|
166
169
|
}
|
|
@@ -192,7 +195,7 @@ class StarknetTransactions extends StarknetModule_1.StarknetModule {
|
|
|
192
195
|
* of a batch of starknet transactions
|
|
193
196
|
*
|
|
194
197
|
* @param signer
|
|
195
|
-
* @param
|
|
198
|
+
* @param _txs transactions to send
|
|
196
199
|
* @param waitForConfirmation whether to wait for transaction confirmations (this also makes sure the transactions
|
|
197
200
|
* are re-sent at regular intervals)
|
|
198
201
|
* @param abortSignal abort signal to abort waiting for transaction confirmations
|
|
@@ -200,7 +203,8 @@ class StarknetTransactions extends StarknetModule_1.StarknetModule {
|
|
|
200
203
|
* are executed in order)
|
|
201
204
|
* @param onBeforePublish a callback called before every transaction is published
|
|
202
205
|
*/
|
|
203
|
-
async sendAndConfirm(signer,
|
|
206
|
+
async sendAndConfirm(signer, _txs, waitForConfirmation, abortSignal, parallel, onBeforePublish) {
|
|
207
|
+
const txs = _txs;
|
|
204
208
|
await this.prepareTransactions(signer, txs);
|
|
205
209
|
const signedTxs = [];
|
|
206
210
|
//Don't separate the signing process from the sending when using browser-based wallet
|
|
@@ -208,6 +212,7 @@ class StarknetTransactions extends StarknetModule_1.StarknetModule {
|
|
|
208
212
|
for (let i = 0; i < txs.length; i++) {
|
|
209
213
|
const tx = txs[i];
|
|
210
214
|
const signedTx = await signer.signTransaction(tx);
|
|
215
|
+
signedTx.addedInPrepare = tx.addedInPrepare;
|
|
211
216
|
signedTxs.push(signedTx);
|
|
212
217
|
this.logger.debug("sendAndConfirm(): transaction signed (" + (i + 1) + "/" + txs.length + "): " + signedTx.txId);
|
|
213
218
|
const nextAccountNonce = BigInt(signedTx.details.nonce) + 1n;
|
|
@@ -224,13 +229,13 @@ class StarknetTransactions extends StarknetModule_1.StarknetModule {
|
|
|
224
229
|
for (let i = 0; i < txs.length; i++) {
|
|
225
230
|
let tx;
|
|
226
231
|
if (signer.signTransaction == null) {
|
|
227
|
-
const txId = await signer.sendTransaction(txs[i], onBeforePublish);
|
|
232
|
+
const txId = await signer.sendTransaction(txs[i], txs[i].addedInPrepare ? undefined : onBeforePublish);
|
|
228
233
|
tx = txs[i];
|
|
229
234
|
tx.txId = txId;
|
|
230
235
|
}
|
|
231
236
|
else {
|
|
232
237
|
const signedTx = signedTxs[i];
|
|
233
|
-
await this.sendSignedTransaction(signedTx, onBeforePublish);
|
|
238
|
+
await this.sendSignedTransaction(signedTx, signedTx.addedInPrepare ? undefined : onBeforePublish);
|
|
234
239
|
tx = signedTx;
|
|
235
240
|
}
|
|
236
241
|
if (tx.details.nonce != null) {
|
|
@@ -240,9 +245,11 @@ class StarknetTransactions extends StarknetModule_1.StarknetModule {
|
|
|
240
245
|
this.latestPendingNonces[(0, Utils_1.toHex)(tx.details.walletAddress)] = nextAccountNonce;
|
|
241
246
|
}
|
|
242
247
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
248
|
+
if (!tx.addedInPrepare) {
|
|
249
|
+
promises.push(this.confirmTransaction(tx, abortSignal));
|
|
250
|
+
if (!waitForConfirmation)
|
|
251
|
+
txIds.push(tx.txId);
|
|
252
|
+
}
|
|
246
253
|
this.logger.debug("sendAndConfirm(): transaction sent (" + (i + 1) + "/" + txs.length + "): " + tx.txId);
|
|
247
254
|
if (promises.length >= MAX_UNCONFIRMED_TXS) {
|
|
248
255
|
if (waitForConfirmation)
|
|
@@ -258,13 +265,13 @@ class StarknetTransactions extends StarknetModule_1.StarknetModule {
|
|
|
258
265
|
for (let i = 0; i < txs.length; i++) {
|
|
259
266
|
let tx;
|
|
260
267
|
if (signer.signTransaction == null) {
|
|
261
|
-
const txId = await signer.sendTransaction(txs[i], onBeforePublish);
|
|
268
|
+
const txId = await signer.sendTransaction(txs[i], txs[i].addedInPrepare ? undefined : onBeforePublish);
|
|
262
269
|
tx = txs[i];
|
|
263
270
|
tx.txId = txId;
|
|
264
271
|
}
|
|
265
272
|
else {
|
|
266
273
|
const signedTx = signedTxs[i];
|
|
267
|
-
await this.sendSignedTransaction(signedTx, onBeforePublish);
|
|
274
|
+
await this.sendSignedTransaction(signedTx, signedTx.addedInPrepare ? undefined : onBeforePublish);
|
|
268
275
|
tx = signedTx;
|
|
269
276
|
}
|
|
270
277
|
if (tx.details.nonce != null) {
|
|
@@ -280,7 +287,8 @@ class StarknetTransactions extends StarknetModule_1.StarknetModule {
|
|
|
280
287
|
let txHash = tx.txId;
|
|
281
288
|
if (i < txs.length - 1 || waitForConfirmation)
|
|
282
289
|
txHash = await confirmPromise;
|
|
283
|
-
|
|
290
|
+
if (!tx.addedInPrepare)
|
|
291
|
+
txIds.push(txHash);
|
|
284
292
|
}
|
|
285
293
|
}
|
|
286
294
|
this.logger.info("sendAndConfirm(): sent transactions, count: " + txs.length +
|
|
@@ -45,7 +45,8 @@ export declare class StarknetContractEvents<TAbi extends Abi> extends StarknetEv
|
|
|
45
45
|
* @param keys
|
|
46
46
|
* @param processor called for every event, should return a value if the correct event was found, or null
|
|
47
47
|
* if the search should continue
|
|
48
|
+
* @param startHeight
|
|
48
49
|
* @param abortSignal
|
|
49
50
|
*/
|
|
50
|
-
findInContractEventsForward<T, TEvent extends ExtractAbiEventNames<TAbi>>(events: TEvent[], keys: (string | string[])[], processor: (event: StarknetAbiEvent<TAbi, TEvent>) => Promise<T>, abortSignal?: AbortSignal): Promise<T>;
|
|
51
|
+
findInContractEventsForward<T, TEvent extends ExtractAbiEventNames<TAbi>>(events: TEvent[], keys: (string | string[])[], processor: (event: StarknetAbiEvent<TAbi, TEvent>) => Promise<T>, startHeight?: number, abortSignal?: AbortSignal): Promise<T>;
|
|
51
52
|
}
|
|
@@ -81,9 +81,10 @@ class StarknetContractEvents extends StarknetEvents_1.StarknetEvents {
|
|
|
81
81
|
* @param keys
|
|
82
82
|
* @param processor called for every event, should return a value if the correct event was found, or null
|
|
83
83
|
* if the search should continue
|
|
84
|
+
* @param startHeight
|
|
84
85
|
* @param abortSignal
|
|
85
86
|
*/
|
|
86
|
-
async findInContractEventsForward(events, keys, processor, abortSignal) {
|
|
87
|
+
async findInContractEventsForward(events, keys, processor, startHeight, abortSignal) {
|
|
87
88
|
return this.findInEventsForward(this.contract.contract.address, this.toFilter(events, keys), async (events) => {
|
|
88
89
|
const parsedEvents = this.toStarknetAbiEvents(events);
|
|
89
90
|
for (let event of parsedEvents) {
|
|
@@ -91,7 +92,7 @@ class StarknetContractEvents extends StarknetEvents_1.StarknetEvents {
|
|
|
91
92
|
if (result != null)
|
|
92
93
|
return result;
|
|
93
94
|
}
|
|
94
|
-
}, abortSignal);
|
|
95
|
+
}, startHeight, abortSignal);
|
|
95
96
|
}
|
|
96
97
|
}
|
|
97
98
|
exports.StarknetContractEvents = StarknetContractEvents;
|
|
@@ -53,10 +53,13 @@ export declare class StarknetSpvVaultContract extends StarknetContractBase<typeo
|
|
|
53
53
|
[btcTxId: string]: string | null;
|
|
54
54
|
}>;
|
|
55
55
|
private parseWithdrawalEvent;
|
|
56
|
-
getWithdrawalStates(
|
|
56
|
+
getWithdrawalStates(withdrawalTxs: {
|
|
57
|
+
withdrawal: StarknetSpvWithdrawalData;
|
|
58
|
+
scStartHeight?: number;
|
|
59
|
+
}[]): Promise<{
|
|
57
60
|
[btcTxId: string]: SpvWithdrawalState;
|
|
58
61
|
}>;
|
|
59
|
-
getWithdrawalState(
|
|
62
|
+
getWithdrawalState(withdrawalTx: StarknetSpvWithdrawalData, scStartBlockheight?: number): Promise<SpvWithdrawalState>;
|
|
60
63
|
getWithdrawalData(btcTx: BtcTx): Promise<StarknetSpvWithdrawalData>;
|
|
61
64
|
fromOpReturnData(data: Buffer): {
|
|
62
65
|
recipient: string;
|
|
@@ -217,27 +217,34 @@ class StarknetSpvVaultContract extends StarknetContractBase_1.StarknetContractBa
|
|
|
217
217
|
return null;
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
|
-
async getWithdrawalStates(
|
|
220
|
+
async getWithdrawalStates(withdrawalTxs) {
|
|
221
221
|
const result = {};
|
|
222
|
-
|
|
223
|
-
result[
|
|
222
|
+
withdrawalTxs.forEach(withdrawalTx => {
|
|
223
|
+
result[withdrawalTx.withdrawal.getTxId()] = {
|
|
224
224
|
type: base_1.SpvWithdrawalStateType.NOT_FOUND
|
|
225
225
|
};
|
|
226
226
|
});
|
|
227
|
-
|
|
228
|
-
|
|
227
|
+
const events = ["spv_swap_vault::events::Fronted", "spv_swap_vault::events::Claimed", "spv_swap_vault::events::Closed"];
|
|
228
|
+
for (let i = 0; i < withdrawalTxs.length; i += this.Chain.config.maxGetLogKeys) {
|
|
229
|
+
const checkWithdrawalTxs = withdrawalTxs.slice(i, i + this.Chain.config.maxGetLogKeys);
|
|
229
230
|
const lows = [];
|
|
230
231
|
const highs = [];
|
|
231
|
-
|
|
232
|
-
|
|
232
|
+
let startHeight = undefined;
|
|
233
|
+
checkWithdrawalTxs.forEach(withdrawalTx => {
|
|
234
|
+
const txHash = buffer_1.Buffer.from(withdrawalTx.withdrawal.getTxId(), "hex").reverse();
|
|
233
235
|
const txHashU256 = starknet_1.cairo.uint256("0x" + txHash.toString("hex"));
|
|
234
236
|
lows.push((0, Utils_1.toHex)(txHashU256.low));
|
|
235
237
|
highs.push((0, Utils_1.toHex)(txHashU256.high));
|
|
238
|
+
if (startHeight !== null) {
|
|
239
|
+
if (withdrawalTx.scStartHeight == null) {
|
|
240
|
+
startHeight = null;
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
startHeight = Math.min(startHeight ?? Infinity, withdrawalTx.scStartHeight);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
236
246
|
});
|
|
237
|
-
await this.Events.findInContractEventsForward(
|
|
238
|
-
lows,
|
|
239
|
-
highs
|
|
240
|
-
], async (event) => {
|
|
247
|
+
await this.Events.findInContractEventsForward(events, [lows, highs], async (event) => {
|
|
241
248
|
const txId = (0, Utils_1.bigNumberishToBuffer)(event.params.btc_tx_hash, 32).reverse().toString("hex");
|
|
242
249
|
if (result[txId] == null) {
|
|
243
250
|
this.logger.warn(`getWithdrawalStates(): findInContractEvents-callback: loaded event for ${txId}, but transaction not found in input params!`);
|
|
@@ -246,24 +253,23 @@ class StarknetSpvVaultContract extends StarknetContractBase_1.StarknetContractBa
|
|
|
246
253
|
const eventResult = this.parseWithdrawalEvent(event);
|
|
247
254
|
if (eventResult != null)
|
|
248
255
|
result[txId] = eventResult;
|
|
249
|
-
});
|
|
256
|
+
}, startHeight);
|
|
250
257
|
}
|
|
251
258
|
return result;
|
|
252
259
|
}
|
|
253
|
-
async getWithdrawalState(
|
|
254
|
-
const txHash = buffer_1.Buffer.from(
|
|
260
|
+
async getWithdrawalState(withdrawalTx, scStartBlockheight) {
|
|
261
|
+
const txHash = buffer_1.Buffer.from(withdrawalTx.getTxId(), "hex").reverse();
|
|
255
262
|
const txHashU256 = starknet_1.cairo.uint256("0x" + txHash.toString("hex"));
|
|
256
263
|
let result = {
|
|
257
264
|
type: base_1.SpvWithdrawalStateType.NOT_FOUND
|
|
258
265
|
};
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
], async (event) => {
|
|
266
|
+
const events = ["spv_swap_vault::events::Fronted", "spv_swap_vault::events::Claimed", "spv_swap_vault::events::Closed"];
|
|
267
|
+
const keys = [(0, Utils_1.toHex)(txHashU256.low), (0, Utils_1.toHex)(txHashU256.high)];
|
|
268
|
+
await this.Events.findInContractEventsForward(events, keys, async (event) => {
|
|
263
269
|
const eventResult = this.parseWithdrawalEvent(event);
|
|
264
270
|
if (eventResult != null)
|
|
265
271
|
result = eventResult;
|
|
266
|
-
});
|
|
272
|
+
}, scStartBlockheight);
|
|
267
273
|
return result;
|
|
268
274
|
}
|
|
269
275
|
getWithdrawalData(btcTx) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atomiqlabs/chain-starknet",
|
|
3
|
-
"version": "4.0.0-dev.
|
|
3
|
+
"version": "4.0.0-dev.37",
|
|
4
4
|
"description": "Starknet specific base implementation",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"url": "git+https://github.com/atomiqlabs/atomiq-chain-starknet.git"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@atomiqlabs/base": "^10.0.0-dev.
|
|
31
|
+
"@atomiqlabs/base": "^10.0.0-dev.20",
|
|
32
32
|
"@noble/hashes": "^1.7.1",
|
|
33
33
|
"@scure/btc-signer": "^1.6.0",
|
|
34
34
|
"abi-wan-kanabi": "2.2.4",
|
|
@@ -151,6 +151,14 @@ export class StarknetChainInterface implements ChainInterface<StarknetTx, Starkn
|
|
|
151
151
|
return this.Transactions.getTxStatus(tx);
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
async getFinalizedBlock(): Promise<{ height: number; blockHash: string }> {
|
|
155
|
+
const block = await this.Blocks.getBlock("l1_accepted");
|
|
156
|
+
return {
|
|
157
|
+
height: block.block_number as number,
|
|
158
|
+
blockHash: block.block_hash as string
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
154
162
|
txsTransfer(signer: string, token: string, amount: bigint, dstAddress: string, feeRate?: string): Promise<StarknetTx[]> {
|
|
155
163
|
return this.Tokens.txsTransfer(signer, token, amount, dstAddress, feeRate);
|
|
156
164
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {StarknetModule} from "../StarknetModule";
|
|
2
|
+
import {BlockWithTxHashes} from "starknet";
|
|
2
3
|
|
|
3
4
|
// https://github.com/starkware-libs/starknet-specs/blob/c2e93098b9c2ca0423b7f4d15b201f52f22d8c36/api/starknet_api_openrpc.json#L1234
|
|
4
|
-
export type StarknetBlockTag = "pre_confirmed" | "latest";
|
|
5
|
+
export type StarknetBlockTag = "pre_confirmed" | "latest" | "l1_accepted";
|
|
5
6
|
|
|
6
7
|
export class StarknetBlocks extends StarknetModule {
|
|
7
8
|
|
|
@@ -9,7 +10,7 @@ export class StarknetBlocks extends StarknetModule {
|
|
|
9
10
|
|
|
10
11
|
private blockCache: {
|
|
11
12
|
[key: string]: {
|
|
12
|
-
|
|
13
|
+
block: Promise<BlockWithTxHashes>,
|
|
13
14
|
timestamp: number
|
|
14
15
|
}
|
|
15
16
|
} = {};
|
|
@@ -21,23 +22,23 @@ export class StarknetBlocks extends StarknetModule {
|
|
|
21
22
|
* @param blockTag
|
|
22
23
|
*/
|
|
23
24
|
private fetchAndSaveBlockTime(blockTag: StarknetBlockTag | number): {
|
|
24
|
-
|
|
25
|
+
block: Promise<BlockWithTxHashes>,
|
|
25
26
|
timestamp: number
|
|
26
27
|
} {
|
|
27
28
|
const blockTagStr = blockTag.toString(10);
|
|
28
29
|
|
|
29
|
-
const
|
|
30
|
+
const blockPromise = this.provider.getBlockWithTxHashes(blockTag);
|
|
30
31
|
const timestamp = Date.now();
|
|
31
32
|
this.blockCache[blockTagStr] = {
|
|
32
|
-
|
|
33
|
+
block: blockPromise,
|
|
33
34
|
timestamp
|
|
34
35
|
};
|
|
35
|
-
|
|
36
|
-
if(this.blockCache[blockTagStr]!=null && this.blockCache[blockTagStr].
|
|
36
|
+
blockPromise.catch(e => {
|
|
37
|
+
if(this.blockCache[blockTagStr]!=null && this.blockCache[blockTagStr].block===blockPromise) delete this.blockCache[blockTagStr];
|
|
37
38
|
throw e;
|
|
38
39
|
})
|
|
39
40
|
return {
|
|
40
|
-
|
|
41
|
+
block: blockPromise,
|
|
41
42
|
timestamp
|
|
42
43
|
};
|
|
43
44
|
}
|
|
@@ -62,7 +63,7 @@ export class StarknetBlocks extends StarknetModule {
|
|
|
62
63
|
*
|
|
63
64
|
* @param blockTag
|
|
64
65
|
*/
|
|
65
|
-
public
|
|
66
|
+
public getBlock(blockTag: StarknetBlockTag | number): Promise<BlockWithTxHashes> {
|
|
66
67
|
this.cleanupBlocks();
|
|
67
68
|
let cachedBlockData = this.blockCache[blockTag.toString(10)];
|
|
68
69
|
|
|
@@ -70,7 +71,17 @@ export class StarknetBlocks extends StarknetModule {
|
|
|
70
71
|
cachedBlockData = this.fetchAndSaveBlockTime(blockTag);
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
return cachedBlockData.
|
|
74
|
+
return cachedBlockData.block;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Gets the block for a given blocktag, with caching
|
|
79
|
+
*
|
|
80
|
+
* @param blockTag
|
|
81
|
+
*/
|
|
82
|
+
public async getBlockTime(blockTag: StarknetBlockTag | number): Promise<number> {
|
|
83
|
+
const block = await this.getBlock(blockTag);
|
|
84
|
+
return block.timestamp;
|
|
74
85
|
}
|
|
75
86
|
|
|
76
87
|
}
|
|
@@ -76,12 +76,14 @@ export class StarknetEvents extends StarknetModule {
|
|
|
76
76
|
* @param keys
|
|
77
77
|
* @param processor called for every batch of returned signatures, should return a value if the correct signature
|
|
78
78
|
* was found, or null if the search should continue
|
|
79
|
+
* @param startHeight
|
|
79
80
|
* @param abortSignal
|
|
80
81
|
* @param logFetchLimit
|
|
81
82
|
*/
|
|
82
83
|
public async findInEventsForward<T>(
|
|
83
84
|
contract: string, keys: string[][],
|
|
84
85
|
processor: (signatures: StarknetEvent[]) => Promise<T>,
|
|
86
|
+
startHeight?: number,
|
|
85
87
|
abortSignal?: AbortSignal,
|
|
86
88
|
logFetchLimit?: number
|
|
87
89
|
): Promise<T> {
|
|
@@ -90,6 +92,7 @@ export class StarknetEvents extends StarknetModule {
|
|
|
90
92
|
while(eventsResult==null || eventsResult?.continuation_token!=null) {
|
|
91
93
|
eventsResult = await this.root.provider.getEvents({
|
|
92
94
|
address: contract,
|
|
95
|
+
from_block: startHeight==null ? undefined : {block_number: startHeight},
|
|
93
96
|
to_block: "latest",
|
|
94
97
|
keys,
|
|
95
98
|
chunk_size: logFetchLimit ?? this.EVENTS_LIMIT,
|
|
@@ -167,7 +167,7 @@ export class StarknetTransactions extends StarknetModule {
|
|
|
167
167
|
* @param txs
|
|
168
168
|
* @private
|
|
169
169
|
*/
|
|
170
|
-
private async prepareTransactions(signer: StarknetSigner, txs: StarknetTx[]): Promise<void> {
|
|
170
|
+
private async prepareTransactions(signer: StarknetSigner, txs: (StarknetTx & {addedInPrepare?: boolean})[]): Promise<void> {
|
|
171
171
|
let nonce: bigint = await this.getNonce(signer.getAddress());
|
|
172
172
|
const latestPendingNonce = this.latestPendingNonces[toHex(signer.getAddress())];
|
|
173
173
|
if(latestPendingNonce!=null && latestPendingNonce > nonce) {
|
|
@@ -178,7 +178,11 @@ export class StarknetTransactions extends StarknetModule {
|
|
|
178
178
|
//Add deploy account tx
|
|
179
179
|
if(nonce===0n) {
|
|
180
180
|
const deployPayload = await signer.getDeployPayload();
|
|
181
|
-
if(deployPayload!=null)
|
|
181
|
+
if(deployPayload!=null) {
|
|
182
|
+
const tx: (StarknetTx & {addedInPrepare?: boolean}) = await this.root.Accounts.getAccountDeployTransaction(deployPayload);
|
|
183
|
+
tx.addedInPrepare = true;
|
|
184
|
+
txs.unshift(tx);
|
|
185
|
+
}
|
|
182
186
|
}
|
|
183
187
|
|
|
184
188
|
if(!signer.isManagingNoncesInternally) {
|
|
@@ -193,7 +197,7 @@ export class StarknetTransactions extends StarknetModule {
|
|
|
193
197
|
if(nonce==null) nonce = BigInt(await this.root.provider.getNonceForAddress(signer.getAddress())); //Fetch the nonce
|
|
194
198
|
if(tx.details.nonce==null) tx.details.nonce = nonce;
|
|
195
199
|
|
|
196
|
-
this.logger.debug("
|
|
200
|
+
this.logger.debug("prepareTransactions(): transaction prepared ("+(i+1)+"/"+txs.length+"), nonce: "+tx.details.nonce);
|
|
197
201
|
|
|
198
202
|
nonce += BigInt(1);
|
|
199
203
|
}
|
|
@@ -231,7 +235,7 @@ export class StarknetTransactions extends StarknetModule {
|
|
|
231
235
|
* of a batch of starknet transactions
|
|
232
236
|
*
|
|
233
237
|
* @param signer
|
|
234
|
-
* @param
|
|
238
|
+
* @param _txs transactions to send
|
|
235
239
|
* @param waitForConfirmation whether to wait for transaction confirmations (this also makes sure the transactions
|
|
236
240
|
* are re-sent at regular intervals)
|
|
237
241
|
* @param abortSignal abort signal to abort waiting for transaction confirmations
|
|
@@ -239,14 +243,16 @@ export class StarknetTransactions extends StarknetModule {
|
|
|
239
243
|
* are executed in order)
|
|
240
244
|
* @param onBeforePublish a callback called before every transaction is published
|
|
241
245
|
*/
|
|
242
|
-
public async sendAndConfirm(signer: StarknetSigner,
|
|
246
|
+
public async sendAndConfirm(signer: StarknetSigner, _txs: StarknetTx[], waitForConfirmation?: boolean, abortSignal?: AbortSignal, parallel?: boolean, onBeforePublish?: (txId: string, rawTx: string) => Promise<void>): Promise<string[]> {
|
|
247
|
+
const txs: (StarknetTx & {addedInPrepare?: boolean})[] = _txs;
|
|
243
248
|
await this.prepareTransactions(signer, txs);
|
|
244
|
-
const signedTxs: StarknetTx[] = [];
|
|
249
|
+
const signedTxs: (StarknetTx & {addedInPrepare?: boolean})[] = [];
|
|
245
250
|
|
|
246
251
|
//Don't separate the signing process from the sending when using browser-based wallet
|
|
247
252
|
if(signer.signTransaction!=null) for(let i=0;i<txs.length;i++) {
|
|
248
253
|
const tx = txs[i];
|
|
249
|
-
const signedTx = await signer.signTransaction(tx);
|
|
254
|
+
const signedTx: (StarknetTx & {addedInPrepare?: boolean}) = await signer.signTransaction(tx);
|
|
255
|
+
signedTx.addedInPrepare = tx.addedInPrepare;
|
|
250
256
|
signedTxs.push(signedTx);
|
|
251
257
|
this.logger.debug("sendAndConfirm(): transaction signed ("+(i+1)+"/"+txs.length+"): "+signedTx.txId);
|
|
252
258
|
|
|
@@ -264,14 +270,14 @@ export class StarknetTransactions extends StarknetModule {
|
|
|
264
270
|
if(parallel) {
|
|
265
271
|
let promises: Promise<string>[] = [];
|
|
266
272
|
for(let i=0;i<txs.length;i++) {
|
|
267
|
-
let tx: StarknetTx;
|
|
273
|
+
let tx: (StarknetTx & {addedInPrepare?: boolean});
|
|
268
274
|
if(signer.signTransaction==null) {
|
|
269
|
-
const txId = await signer.sendTransaction(txs[i], onBeforePublish);
|
|
275
|
+
const txId = await signer.sendTransaction(txs[i], txs[i].addedInPrepare ? undefined : onBeforePublish);
|
|
270
276
|
tx = txs[i];
|
|
271
277
|
tx.txId = txId;
|
|
272
278
|
} else {
|
|
273
279
|
const signedTx = signedTxs[i];
|
|
274
|
-
await this.sendSignedTransaction(signedTx, onBeforePublish);
|
|
280
|
+
await this.sendSignedTransaction(signedTx, signedTx.addedInPrepare ? undefined : onBeforePublish);
|
|
275
281
|
tx = signedTx;
|
|
276
282
|
}
|
|
277
283
|
|
|
@@ -283,8 +289,10 @@ export class StarknetTransactions extends StarknetModule {
|
|
|
283
289
|
}
|
|
284
290
|
}
|
|
285
291
|
|
|
286
|
-
|
|
287
|
-
|
|
292
|
+
if(!tx.addedInPrepare) {
|
|
293
|
+
promises.push(this.confirmTransaction(tx, abortSignal));
|
|
294
|
+
if(!waitForConfirmation) txIds.push(tx.txId);
|
|
295
|
+
}
|
|
288
296
|
this.logger.debug("sendAndConfirm(): transaction sent ("+(i+1)+"/"+txs.length+"): "+tx.txId);
|
|
289
297
|
if(promises.length >= MAX_UNCONFIRMED_TXS) {
|
|
290
298
|
if(waitForConfirmation) txIds.push(...await Promise.all(promises));
|
|
@@ -296,14 +304,14 @@ export class StarknetTransactions extends StarknetModule {
|
|
|
296
304
|
}
|
|
297
305
|
} else {
|
|
298
306
|
for(let i=0;i<txs.length;i++) {
|
|
299
|
-
let tx: StarknetTx;
|
|
307
|
+
let tx: (StarknetTx & {addedInPrepare?: boolean});
|
|
300
308
|
if(signer.signTransaction==null) {
|
|
301
|
-
const txId = await signer.sendTransaction(txs[i], onBeforePublish);
|
|
309
|
+
const txId = await signer.sendTransaction(txs[i], txs[i].addedInPrepare ? undefined : onBeforePublish);
|
|
302
310
|
tx = txs[i];
|
|
303
311
|
tx.txId = txId;
|
|
304
312
|
} else {
|
|
305
313
|
const signedTx = signedTxs[i];
|
|
306
|
-
await this.sendSignedTransaction(signedTx, onBeforePublish);
|
|
314
|
+
await this.sendSignedTransaction(signedTx, signedTx.addedInPrepare ? undefined : onBeforePublish);
|
|
307
315
|
tx = signedTx;
|
|
308
316
|
}
|
|
309
317
|
|
|
@@ -320,7 +328,7 @@ export class StarknetTransactions extends StarknetModule {
|
|
|
320
328
|
//Don't await the last promise when !waitForConfirmation
|
|
321
329
|
let txHash = tx.txId;
|
|
322
330
|
if(i<txs.length-1 || waitForConfirmation) txHash = await confirmPromise;
|
|
323
|
-
txIds.push(txHash);
|
|
331
|
+
if(!tx.addedInPrepare) txIds.push(txHash);
|
|
324
332
|
}
|
|
325
333
|
}
|
|
326
334
|
|
|
@@ -113,12 +113,14 @@ export class StarknetContractEvents<TAbi extends Abi> extends StarknetEvents {
|
|
|
113
113
|
* @param keys
|
|
114
114
|
* @param processor called for every event, should return a value if the correct event was found, or null
|
|
115
115
|
* if the search should continue
|
|
116
|
+
* @param startHeight
|
|
116
117
|
* @param abortSignal
|
|
117
118
|
*/
|
|
118
119
|
public async findInContractEventsForward<T, TEvent extends ExtractAbiEventNames<TAbi>>(
|
|
119
120
|
events: TEvent[],
|
|
120
121
|
keys: (string | string[])[],
|
|
121
122
|
processor: (event: StarknetAbiEvent<TAbi, TEvent>) => Promise<T>,
|
|
123
|
+
startHeight?: number,
|
|
122
124
|
abortSignal?: AbortSignal
|
|
123
125
|
) {
|
|
124
126
|
return this.findInEventsForward<T>(this.contract.contract.address, this.toFilter(events, keys), async (events: StarknetEvent[]) => {
|
|
@@ -127,7 +129,7 @@ export class StarknetContractEvents<TAbi extends Abi> extends StarknetEvents {
|
|
|
127
129
|
const result: T = await processor(event);
|
|
128
130
|
if(result!=null) return result;
|
|
129
131
|
}
|
|
130
|
-
}, abortSignal);
|
|
132
|
+
}, startHeight, abortSignal);
|
|
131
133
|
}
|
|
132
134
|
|
|
133
135
|
}
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
SpvVaultTokenData,
|
|
7
7
|
SpvWithdrawalState,
|
|
8
8
|
SpvWithdrawalStateType,
|
|
9
|
-
SpvWithdrawalTransactionData,
|
|
9
|
+
SpvWithdrawalTransactionData,
|
|
10
10
|
TransactionConfirmationOptions
|
|
11
11
|
} from "@atomiqlabs/base";
|
|
12
12
|
import {Buffer} from "buffer";
|
|
@@ -297,30 +297,38 @@ export class StarknetSpvVaultContract
|
|
|
297
297
|
}
|
|
298
298
|
}
|
|
299
299
|
|
|
300
|
-
async getWithdrawalStates(
|
|
300
|
+
async getWithdrawalStates(withdrawalTxs: {withdrawal: StarknetSpvWithdrawalData, scStartHeight?: number}[]): Promise<{[btcTxId: string]: SpvWithdrawalState}> {
|
|
301
301
|
const result: {[btcTxId: string]: SpvWithdrawalState} = {};
|
|
302
|
-
|
|
303
|
-
result[
|
|
302
|
+
withdrawalTxs.forEach(withdrawalTx => {
|
|
303
|
+
result[withdrawalTx.withdrawal.getTxId()] = {
|
|
304
304
|
type: SpvWithdrawalStateType.NOT_FOUND
|
|
305
305
|
};
|
|
306
306
|
});
|
|
307
307
|
|
|
308
|
-
|
|
309
|
-
|
|
308
|
+
const events: ["spv_swap_vault::events::Fronted", "spv_swap_vault::events::Claimed", "spv_swap_vault::events::Closed"] =
|
|
309
|
+
["spv_swap_vault::events::Fronted", "spv_swap_vault::events::Claimed", "spv_swap_vault::events::Closed"];
|
|
310
|
+
|
|
311
|
+
for(let i=0;i<withdrawalTxs.length;i+=this.Chain.config.maxGetLogKeys) {
|
|
312
|
+
const checkWithdrawalTxs = withdrawalTxs.slice(i, i+this.Chain.config.maxGetLogKeys);
|
|
310
313
|
const lows: string[] = [];
|
|
311
314
|
const highs: string[] = [];
|
|
312
|
-
|
|
313
|
-
|
|
315
|
+
let startHeight: number = undefined;
|
|
316
|
+
checkWithdrawalTxs.forEach(withdrawalTx => {
|
|
317
|
+
const txHash = Buffer.from(withdrawalTx.withdrawal.getTxId(), "hex").reverse();
|
|
314
318
|
const txHashU256 = cairo.uint256("0x"+txHash.toString("hex"));
|
|
315
319
|
lows.push(toHex(txHashU256.low));
|
|
316
320
|
highs.push(toHex(txHashU256.high));
|
|
321
|
+
if(startHeight!==null) {
|
|
322
|
+
if(withdrawalTx.scStartHeight==null) {
|
|
323
|
+
startHeight = null;
|
|
324
|
+
} else {
|
|
325
|
+
startHeight = Math.min(startHeight ?? Infinity, withdrawalTx.scStartHeight);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
317
328
|
});
|
|
329
|
+
|
|
318
330
|
await this.Events.findInContractEventsForward(
|
|
319
|
-
|
|
320
|
-
[
|
|
321
|
-
lows,
|
|
322
|
-
highs
|
|
323
|
-
],
|
|
331
|
+
events,[lows, highs],
|
|
324
332
|
async (event) => {
|
|
325
333
|
const txId = bigNumberishToBuffer(event.params.btc_tx_hash, 32).reverse().toString("hex");
|
|
326
334
|
if(result[txId]==null) {
|
|
@@ -329,29 +337,31 @@ export class StarknetSpvVaultContract
|
|
|
329
337
|
}
|
|
330
338
|
const eventResult = this.parseWithdrawalEvent(event);
|
|
331
339
|
if(eventResult!=null) result[txId] = eventResult;
|
|
332
|
-
}
|
|
340
|
+
},
|
|
341
|
+
startHeight
|
|
333
342
|
);
|
|
334
343
|
}
|
|
335
344
|
|
|
336
345
|
return result;
|
|
337
346
|
}
|
|
338
347
|
|
|
339
|
-
async getWithdrawalState(
|
|
340
|
-
const txHash = Buffer.from(
|
|
348
|
+
async getWithdrawalState(withdrawalTx: StarknetSpvWithdrawalData, scStartBlockheight?: number): Promise<SpvWithdrawalState> {
|
|
349
|
+
const txHash = Buffer.from(withdrawalTx.getTxId(), "hex").reverse();
|
|
341
350
|
const txHashU256 = cairo.uint256("0x"+txHash.toString("hex"));
|
|
342
351
|
let result: SpvWithdrawalState = {
|
|
343
352
|
type: SpvWithdrawalStateType.NOT_FOUND
|
|
344
353
|
};
|
|
354
|
+
const events: ["spv_swap_vault::events::Fronted", "spv_swap_vault::events::Claimed", "spv_swap_vault::events::Closed"] =
|
|
355
|
+
["spv_swap_vault::events::Fronted", "spv_swap_vault::events::Claimed", "spv_swap_vault::events::Closed"];
|
|
356
|
+
const keys = [toHex(txHashU256.low), toHex(txHashU256.high)];
|
|
357
|
+
|
|
345
358
|
await this.Events.findInContractEventsForward(
|
|
346
|
-
|
|
347
|
-
[
|
|
348
|
-
toHex(txHashU256.low),
|
|
349
|
-
toHex(txHashU256.high)
|
|
350
|
-
],
|
|
359
|
+
events, keys,
|
|
351
360
|
async (event) => {
|
|
352
361
|
const eventResult = this.parseWithdrawalEvent(event);
|
|
353
362
|
if(eventResult!=null) result = eventResult;
|
|
354
|
-
}
|
|
363
|
+
},
|
|
364
|
+
scStartBlockheight
|
|
355
365
|
);
|
|
356
366
|
return result;
|
|
357
367
|
}
|