@atomiqlabs/chain-starknet 4.0.0-dev.36 → 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.
@@ -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
- export type StarknetBlockTag = "pre_confirmed" | "latest";
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 blockTimePromise = this.provider.getBlockWithTxHashes(blockTag).then(result => result.timestamp);
19
+ const blockPromise = this.provider.getBlockWithTxHashes(blockTag);
20
20
  const timestamp = Date.now();
21
21
  this.blockCache[blockTagStr] = {
22
- blockTime: blockTimePromise,
22
+ block: blockPromise,
23
23
  timestamp
24
24
  };
25
- blockTimePromise.catch(e => {
26
- if (this.blockCache[blockTagStr] != null && this.blockCache[blockTagStr].blockTime === blockTimePromise)
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
- blockTime: blockTimePromise,
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
- getBlockTime(blockTag) {
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.blockTime;
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,
@@ -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(btcTxIds: string[]): Promise<{
56
+ getWithdrawalStates(withdrawalTxs: {
57
+ withdrawal: StarknetSpvWithdrawalData;
58
+ scStartHeight?: number;
59
+ }[]): Promise<{
57
60
  [btcTxId: string]: SpvWithdrawalState;
58
61
  }>;
59
- getWithdrawalState(btcTxId: string): Promise<SpvWithdrawalState>;
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(btcTxIds) {
220
+ async getWithdrawalStates(withdrawalTxs) {
221
221
  const result = {};
222
- btcTxIds.forEach(txId => {
223
- result[txId] = {
222
+ withdrawalTxs.forEach(withdrawalTx => {
223
+ result[withdrawalTx.withdrawal.getTxId()] = {
224
224
  type: base_1.SpvWithdrawalStateType.NOT_FOUND
225
225
  };
226
226
  });
227
- for (let i = 0; i < btcTxIds.length; i += this.Chain.config.maxGetLogKeys) {
228
- const checkBtcTxIds = btcTxIds.slice(i, i + this.Chain.config.maxGetLogKeys);
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
- checkBtcTxIds.forEach(btcTxId => {
232
- const txHash = buffer_1.Buffer.from(btcTxId, "hex").reverse();
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(["spv_swap_vault::events::Fronted", "spv_swap_vault::events::Claimed", "spv_swap_vault::events::Closed"], [
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(btcTxId) {
254
- const txHash = buffer_1.Buffer.from(btcTxId, "hex").reverse();
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
- await this.Events.findInContractEventsForward(["spv_swap_vault::events::Fronted", "spv_swap_vault::events::Claimed", "spv_swap_vault::events::Closed"], [
260
- (0, Utils_1.toHex)(txHashU256.low),
261
- (0, Utils_1.toHex)(txHashU256.high)
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.36",
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.18",
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
- blockTime: Promise<number>,
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
- blockTime: Promise<number>,
25
+ block: Promise<BlockWithTxHashes>,
25
26
  timestamp: number
26
27
  } {
27
28
  const blockTagStr = blockTag.toString(10);
28
29
 
29
- const blockTimePromise = this.provider.getBlockWithTxHashes(blockTag).then(result => result.timestamp);
30
+ const blockPromise = this.provider.getBlockWithTxHashes(blockTag);
30
31
  const timestamp = Date.now();
31
32
  this.blockCache[blockTagStr] = {
32
- blockTime: blockTimePromise,
33
+ block: blockPromise,
33
34
  timestamp
34
35
  };
35
- blockTimePromise.catch(e => {
36
- if(this.blockCache[blockTagStr]!=null && this.blockCache[blockTagStr].blockTime===blockTimePromise) delete 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
- blockTime: blockTimePromise,
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 getBlockTime(blockTag: StarknetBlockTag | number): Promise<number> {
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.blockTime;
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,
@@ -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, SwapCommitState,
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(btcTxIds: string[]): Promise<{[btcTxId: string]: SpvWithdrawalState}> {
300
+ async getWithdrawalStates(withdrawalTxs: {withdrawal: StarknetSpvWithdrawalData, scStartHeight?: number}[]): Promise<{[btcTxId: string]: SpvWithdrawalState}> {
301
301
  const result: {[btcTxId: string]: SpvWithdrawalState} = {};
302
- btcTxIds.forEach(txId => {
303
- result[txId] = {
302
+ withdrawalTxs.forEach(withdrawalTx => {
303
+ result[withdrawalTx.withdrawal.getTxId()] = {
304
304
  type: SpvWithdrawalStateType.NOT_FOUND
305
305
  };
306
306
  });
307
307
 
308
- for(let i=0;i<btcTxIds.length;i+=this.Chain.config.maxGetLogKeys) {
309
- const checkBtcTxIds = btcTxIds.slice(i, i+this.Chain.config.maxGetLogKeys);
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
- checkBtcTxIds.forEach(btcTxId => {
313
- const txHash = Buffer.from(btcTxId, "hex").reverse();
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
- ["spv_swap_vault::events::Fronted", "spv_swap_vault::events::Claimed", "spv_swap_vault::events::Closed"],
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(btcTxId: string): Promise<SpvWithdrawalState> {
340
- const txHash = Buffer.from(btcTxId, "hex").reverse();
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
- ["spv_swap_vault::events::Fronted", "spv_swap_vault::events::Claimed", "spv_swap_vault::events::Closed"],
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
  }