@atomiqlabs/chain-starknet 8.0.13 → 8.1.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.
@@ -30,8 +30,11 @@ export type StarknetOptions = {
30
30
  };
31
31
  chainId?: constants.StarknetChainId;
32
32
  swapContract?: string;
33
+ swapContractDeploymentHeight?: number;
33
34
  btcRelayContract?: string;
35
+ btcRelayContractDeploymentHeight?: number;
34
36
  spvVaultContract?: string;
37
+ spvVaultContractDeploymentHeight?: number;
35
38
  handlerContracts?: {
36
39
  refund?: {
37
40
  timelock?: string;
@@ -71,9 +71,9 @@ function initializeStarknet(options, bitcoinRpc, network) {
71
71
  const chainId = options.chainId ??
72
72
  (network === base_1.BitcoinNetwork.MAINNET ? starknet_1.constants.StarknetChainId.SN_MAIN : starknet_1.constants.StarknetChainId.SN_SEPOLIA);
73
73
  const chainInterface = new StarknetChainInterface_1.StarknetChainInterface(chainId, provider, wsChannel, Fees, options.starknetConfig);
74
- const btcRelay = new StarknetBtcRelay_1.StarknetBtcRelay(chainInterface, bitcoinRpc, network, options.btcRelayContract);
75
- const swapContract = new StarknetSwapContract_1.StarknetSwapContract(chainInterface, btcRelay, options.swapContract, options.handlerContracts);
76
- const spvVaultContract = new StarknetSpvVaultContract_1.StarknetSpvVaultContract(chainInterface, btcRelay, bitcoinRpc, options.spvVaultContract);
74
+ const btcRelay = new StarknetBtcRelay_1.StarknetBtcRelay(chainInterface, bitcoinRpc, network, options.btcRelayContract, options.btcRelayContractDeploymentHeight);
75
+ const swapContract = new StarknetSwapContract_1.StarknetSwapContract(chainInterface, btcRelay, options.swapContract, options.handlerContracts, options.swapContractDeploymentHeight);
76
+ const spvVaultContract = new StarknetSpvVaultContract_1.StarknetSpvVaultContract(chainInterface, btcRelay, bitcoinRpc, options.spvVaultContract, options.spvVaultContractDeploymentHeight);
77
77
  const chainEvents = new StarknetChainEventsBrowser_1.StarknetChainEventsBrowser(chainInterface, swapContract, spvVaultContract);
78
78
  return {
79
79
  chainId: "STARKNET",
@@ -47,7 +47,7 @@ export declare class StarknetBtcRelay<B extends BtcBlock> extends StarknetContra
47
47
  readonly maxHeadersPerTx: number;
48
48
  readonly maxForkHeadersPerTx: number;
49
49
  readonly maxShortForkHeadersPerTx: number;
50
- constructor(chainInterface: StarknetChainInterface, bitcoinRpc: BitcoinRpc<B>, bitcoinNetwork: BitcoinNetwork, contractAddress?: string | undefined);
50
+ constructor(chainInterface: StarknetChainInterface, bitcoinRpc: BitcoinRpc<B>, bitcoinNetwork: BitcoinNetwork, contractAddress?: string | undefined, contractDeploymentHeight?: number);
51
51
  /**
52
52
  * Computes subsequent commited headers as they will appear on the blockchain when transactions
53
53
  * are submitted & confirmed
@@ -29,6 +29,11 @@ const btcRelayAddreses = {
29
29
  [base_1.BitcoinNetwork.TESTNET]: "0x068601c79da2231d21e015ccfd59c243861156fa523a12c9f987ec28eb8dbc8c",
30
30
  [base_1.BitcoinNetwork.MAINNET]: "0x057b14a4231b82f1e525ff35a722d893ca3dd2bde0baa6cee97937c5be861dbc"
31
31
  };
32
+ const btcRelayDeploymentHeights = {
33
+ [base_1.BitcoinNetwork.TESTNET4]: 760719,
34
+ [base_1.BitcoinNetwork.TESTNET]: 633915,
35
+ [base_1.BitcoinNetwork.MAINNET]: 1278562
36
+ };
32
37
  function serializeCalldata(headers, storedHeader, span) {
33
38
  span.push((0, Utils_1.toHex)(headers.length));
34
39
  headers.forEach(header => {
@@ -91,10 +96,13 @@ class StarknetBtcRelay extends StarknetContractBase_1.StarknetContractBase {
91
96
  calldata: serializeCalldata(forkHeaders, storedHeader, [(0, Utils_1.toHex)(forkId)])
92
97
  }, (0, StarknetFees_1.starknetGasAdd)((0, StarknetFees_1.starknetGasMul)(GAS_PER_BLOCKHEADER, forkHeaders.length), (0, StarknetFees_1.starknetGasMul)(GAS_PER_BLOCKHEADER_FORK, totalForkHeaders)));
93
98
  }
94
- constructor(chainInterface, bitcoinRpc, bitcoinNetwork, contractAddress = btcRelayAddreses[bitcoinNetwork]) {
99
+ constructor(chainInterface, bitcoinRpc, bitcoinNetwork, contractAddress = btcRelayAddreses[bitcoinNetwork], contractDeploymentHeight) {
95
100
  if (contractAddress == null)
96
101
  throw new Error("No BtcRelay address specified!");
97
- super(chainInterface, contractAddress, BtcRelayAbi_1.BtcRelayAbi);
102
+ super(chainInterface, contractAddress, BtcRelayAbi_1.BtcRelayAbi, contractDeploymentHeight ??
103
+ (btcRelayAddreses[bitcoinNetwork] === contractAddress
104
+ ? btcRelayDeploymentHeights[bitcoinNetwork]
105
+ : undefined));
98
106
  this.maxHeadersPerTx = 40;
99
107
  this.maxForkHeadersPerTx = 30;
100
108
  this.maxShortForkHeadersPerTx = 40;
@@ -21,6 +21,12 @@ export type StarknetTxDeployAccount = StarknetTxBase & {
21
21
  export declare function isStarknetTxDeployAccount(obj: any): obj is StarknetTxDeployAccount;
22
22
  export type StarknetTx = StarknetTxInvoke | StarknetTxDeployAccount;
23
23
  export type SignedStarknetTx = StarknetTx;
24
+ export type StarknetTraceCall = {
25
+ calldata: string[];
26
+ contract_address: string;
27
+ entry_point_selector: string;
28
+ calls: StarknetTraceCall[];
29
+ };
24
30
  export declare class StarknetTransactions extends StarknetModule {
25
31
  private readonly latestConfirmedNonces;
26
32
  private readonly latestPendingNonces;
@@ -108,6 +114,7 @@ export declare class StarknetTransactions extends StarknetModule {
108
114
  * @param txId
109
115
  */
110
116
  getTxIdStatus(txId: string): Promise<"pending" | "success" | "not_found" | "reverted">;
117
+ traceTransaction(txId: string, blockHash?: string): Promise<StarknetTraceCall | null>;
111
118
  onBeforeTxReplace(callback: (oldTx: string, oldTxId: string, newTx: string, newTxId: string) => Promise<void>): void;
112
119
  offBeforeTxReplace(callback: (oldTx: string, oldTxId: string, newTx: string, newTxId: string) => Promise<void>): boolean;
113
120
  onBeforeTxSigned(callback: (tx: StarknetTx) => Promise<void>): void;
@@ -588,6 +588,27 @@ class StarknetTransactions extends StarknetModule_1.StarknetModule {
588
588
  return "reverted";
589
589
  return status;
590
590
  }
591
+ async traceTransaction(txId, blockHash) {
592
+ let trace;
593
+ try {
594
+ trace = await this.provider.getTransactionTrace(txId);
595
+ }
596
+ catch (e) {
597
+ this.logger.warn("getSwapDataGetter(): getter: starknet_traceTransaction not supported by the RPC: ", e);
598
+ if (blockHash == null)
599
+ throw e;
600
+ const blockTraces = await this.provider.getBlockTransactionsTraces(blockHash);
601
+ const foundTrace = blockTraces.find(val => (0, Utils_1.toHex)(val.transaction_hash) === (0, Utils_1.toHex)(txId));
602
+ if (foundTrace == null)
603
+ throw new Error(`Cannot find ${txId} in the block traces, block: ${blockHash}`);
604
+ trace = foundTrace.trace_root;
605
+ }
606
+ if (trace == null)
607
+ return null;
608
+ if (trace.execute_invocation.revert_reason != null)
609
+ return null;
610
+ return trace.execute_invocation;
611
+ }
591
612
  onBeforeTxReplace(callback) {
592
613
  this._cbksBeforeTxReplace.push(callback);
593
614
  }
@@ -9,5 +9,6 @@ export declare class StarknetContractBase<T extends Abi> {
9
9
  contract: TypedContractV2<T>;
10
10
  readonly Events: StarknetContractEvents<T>;
11
11
  readonly Chain: StarknetChainInterface;
12
- constructor(chainInterface: StarknetChainInterface, contractAddress: string, contractAbi: T);
12
+ readonly contractDeploymentHeight?: number;
13
+ constructor(chainInterface: StarknetChainInterface, contractAddress: string, contractAbi: T, contractDeploymentHeight?: number);
13
14
  }
@@ -7,7 +7,7 @@ const StarknetContractEvents_1 = require("./modules/StarknetContractEvents");
7
7
  * Base class providing program specific utilities
8
8
  */
9
9
  class StarknetContractBase {
10
- constructor(chainInterface, contractAddress, contractAbi) {
10
+ constructor(chainInterface, contractAddress, contractAbi, contractDeploymentHeight) {
11
11
  this.Chain = chainInterface;
12
12
  this.contract = new starknet_1.Contract({
13
13
  abi: contractAbi,
@@ -15,6 +15,7 @@ class StarknetContractBase {
15
15
  providerOrAccount: chainInterface.provider
16
16
  }).typedv2(contractAbi);
17
17
  this.Events = new StarknetContractEvents_1.StarknetContractEvents(chainInterface, this, contractAbi);
18
+ this.contractDeploymentHeight = contractDeploymentHeight;
18
19
  }
19
20
  }
20
21
  exports.StarknetContractBase = StarknetContractBase;
@@ -105,7 +105,7 @@ class StarknetContractEvents extends StarknetEvents_1.StarknetEvents {
105
105
  return result;
106
106
  }
107
107
  return null;
108
- }, startHeight, abortSignal);
108
+ }, Math.max(startHeight ?? 0, this.contract.contractDeploymentHeight ?? 0), abortSignal);
109
109
  }
110
110
  }
111
111
  exports.StarknetContractEvents = StarknetContractEvents;
@@ -2,8 +2,6 @@ import { ChainEvents, EventListener } from "@atomiqlabs/base";
2
2
  import { StarknetSwapData } from "../swaps/StarknetSwapData";
3
3
  import { StarknetSwapContract } from "../swaps/StarknetSwapContract";
4
4
  import { Provider, SubscriptionStarknetEventsEvent, WebSocketChannel } from "starknet";
5
- import { EscrowManagerAbiType } from "../swaps/EscrowManagerAbi";
6
- import { ExtractAbiFunctionNames } from "abi-wan-kanabi/dist/kanabi";
7
5
  import { StarknetSpvVaultContract } from "../spv_swap/StarknetSpvVaultContract";
8
6
  import { StarknetChainInterface } from "../chain/StarknetChainInterface";
9
7
  /**
@@ -35,8 +33,6 @@ export declare class StarknetChainEventsBrowser implements ChainEvents<StarknetS
35
33
  protected readonly logger: import("../../utils/Utils").LoggerType;
36
34
  protected escrowContractSubscription?: SubscriptionStarknetEventsEvent;
37
35
  protected spvVaultContractSubscription?: SubscriptionStarknetEventsEvent;
38
- protected initFunctionName: ExtractAbiFunctionNames<EscrowManagerAbiType>;
39
- protected initEntryPointSelector: bigint;
40
36
  protected stopped: boolean;
41
37
  protected pollIntervalSeconds: number;
42
38
  private timeout;
@@ -59,14 +55,6 @@ export declare class StarknetChainEventsBrowser implements ChainEvents<StarknetS
59
55
  * @private
60
56
  */
61
57
  private isEventProcessed;
62
- /**
63
- *
64
- * @param call
65
- * @param escrowHash
66
- * @param claimHandler
67
- * @private
68
- */
69
- private findInitSwapData;
70
58
  /**
71
59
  * Returns async getter for fetching on-demand initialize event swap data
72
60
  *
@@ -2,30 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.StarknetChainEventsBrowser = void 0;
4
4
  const base_1 = require("@atomiqlabs/base");
5
- const StarknetSwapData_1 = require("../swaps/StarknetSwapData");
6
5
  const Utils_1 = require("../../utils/Utils");
7
6
  const starknet_1 = require("starknet");
8
7
  const sha2_1 = require("@noble/hashes/sha2");
9
8
  const buffer_1 = require("buffer");
10
9
  const PROCESSED_EVENTS_BACKLOG = 5000;
11
10
  const LOGS_SLIDING_WINDOW = 60;
12
- function parseInitFunctionCalldata(calldata, claimHandler) {
13
- const escrow = StarknetSwapData_1.StarknetSwapData.fromSerializedFeltArray(calldata, claimHandler);
14
- if (calldata.length < 1)
15
- throw new Error("Calldata invalid length");
16
- const signatureLen = Number((0, Utils_1.toBigInt)(calldata.shift()));
17
- if (calldata.length < signatureLen + 2)
18
- throw new Error("Calldata invalid length");
19
- const signature = calldata.splice(0, signatureLen);
20
- const timeout = (0, Utils_1.toBigInt)(calldata.shift());
21
- const extraDataLen = Number((0, Utils_1.toBigInt)(calldata.shift()));
22
- if (calldata.length < extraDataLen)
23
- throw new Error("Calldata invalid length");
24
- const extraData = calldata.splice(0, extraDataLen);
25
- if (calldata.length !== 0)
26
- throw new Error("Calldata not read fully!");
27
- return { escrow, signature, timeout, extraData };
28
- }
29
11
  /**
30
12
  * Starknet on-chain event handler for front-end systems without access to fs, uses WS or long-polling to subscribe, might lose
31
13
  * out on some events if the network is unreliable, front-end systems should take this into consideration and not
@@ -39,8 +21,6 @@ class StarknetChainEventsBrowser {
39
21
  this.processedEvents = new Set();
40
22
  this.listeners = [];
41
23
  this.logger = (0, Utils_1.getLogger)("StarknetChainEventsBrowser: ");
42
- this.initFunctionName = "initialize";
43
- this.initEntryPointSelector = BigInt(starknet_1.hash.starknetKeccak(this.initFunctionName));
44
24
  this.stopped = true;
45
25
  this.wsStarted = false;
46
26
  this.Chain = chainInterface;
@@ -82,32 +62,6 @@ class StarknetChainEventsBrowser {
82
62
  const eventFingerprint = typeof (eventOrFingerprint) === "string" ? eventOrFingerprint : this.getEventFingerprint(eventOrFingerprint);
83
63
  return this.processedEvents.has(eventFingerprint);
84
64
  }
85
- /**
86
- *
87
- * @param call
88
- * @param escrowHash
89
- * @param claimHandler
90
- * @private
91
- */
92
- findInitSwapData(call, escrowHash, claimHandler) {
93
- if (BigInt(call.contract_address) === BigInt(this.starknetSwapContract.contract.address) &&
94
- BigInt(call.entry_point_selector) === this.initEntryPointSelector) {
95
- //Found, check correct escrow hash
96
- const { escrow, extraData } = parseInitFunctionCalldata(call.calldata, claimHandler);
97
- if ("0x" + escrow.getEscrowHash() === (0, Utils_1.toHex)(escrowHash)) {
98
- if (extraData.length !== 0) {
99
- escrow.setExtraData((0, Utils_1.bytes31SpanToBuffer)(extraData, 42).toString("hex"));
100
- }
101
- return escrow;
102
- }
103
- }
104
- for (let _call of call.calls) {
105
- const found = this.findInitSwapData(_call, escrowHash, claimHandler);
106
- if (found != null)
107
- return found;
108
- }
109
- return null;
110
- }
111
65
  /**
112
66
  * Returns async getter for fetching on-demand initialize event swap data
113
67
  *
@@ -118,23 +72,10 @@ class StarknetChainEventsBrowser {
118
72
  */
119
73
  getSwapDataGetter(event, claimHandler) {
120
74
  return async () => {
121
- let trace;
122
- try {
123
- trace = await this.provider.getTransactionTrace(event.txHash);
124
- }
125
- catch (e) {
126
- this.logger.warn("getSwapDataGetter(): getter: starknet_traceTransaction not supported by the RPC: ", e);
127
- const blockTraces = await this.provider.getBlockTransactionsTraces(event.blockHash);
128
- const foundTrace = blockTraces.find(val => (0, Utils_1.toHex)(val.transaction_hash) === (0, Utils_1.toHex)(event.txHash));
129
- if (foundTrace == null)
130
- throw new Error(`Cannot find ${event.txHash} in the block traces, block: ${event.blockHash}`);
131
- trace = foundTrace.trace_root;
132
- }
75
+ const trace = await this.Chain.Transactions.traceTransaction(event.txHash, event.blockHash);
133
76
  if (trace == null)
134
77
  return null;
135
- if (trace.execute_invocation.revert_reason != null)
136
- return null;
137
- return this.findInitSwapData(trace.execute_invocation, event.params.escrow_hash, claimHandler);
78
+ return this.starknetSwapContract.findInitSwapData(trace, event.params.escrow_hash, claimHandler);
138
79
  };
139
80
  }
140
81
  /**
@@ -1,4 +1,4 @@
1
- import { BitcoinRpc, BtcTx, RelaySynchronizer, SpvVaultContract, SpvVaultTokenData, SpvWithdrawalState, SpvWithdrawalTransactionData, TransactionConfirmationOptions } from "@atomiqlabs/base";
1
+ import { BitcoinRpc, BtcTx, RelaySynchronizer, SpvVaultContract, SpvVaultTokenData, SpvWithdrawalClaimedState, SpvWithdrawalFrontedState, SpvWithdrawalState, SpvWithdrawalTransactionData, TransactionConfirmationOptions } from "@atomiqlabs/base";
2
2
  import { Buffer } from "buffer";
3
3
  import { StarknetTx } from "../chain/modules/StarknetTransactions";
4
4
  import { StarknetContractBase } from "../contract/StarknetContractBase";
@@ -23,7 +23,7 @@ export declare class StarknetSpvVaultContract extends StarknetContractBase<typeo
23
23
  readonly claimTimeout: number;
24
24
  readonly maxClaimsPerTx: number;
25
25
  readonly logger: import("../../utils/Utils").LoggerType;
26
- constructor(chainInterface: StarknetChainInterface, btcRelay: StarknetBtcRelay<any>, bitcoinRpc: BitcoinRpc<any>, contractAddress?: string);
26
+ constructor(chainInterface: StarknetChainInterface, btcRelay: StarknetBtcRelay<any>, bitcoinRpc: BitcoinRpc<any>, contractAddress?: string, contractDeploymentHeight?: number);
27
27
  /**
28
28
  * Returns a {@link StarknetAction} that opens up the spv vault with the passed data
29
29
  *
@@ -136,6 +136,12 @@ export declare class StarknetSpvVaultContract extends StarknetContractBase<typeo
136
136
  * @inheritDoc
137
137
  */
138
138
  getWithdrawalState(withdrawalTx: StarknetSpvWithdrawalData, scStartBlockheight?: number): Promise<SpvWithdrawalState>;
139
+ getHistoricalWithdrawalStates(recipient: string, startBlockheight?: number): Promise<{
140
+ withdrawals: {
141
+ [btcTxId: string]: SpvWithdrawalClaimedState | SpvWithdrawalFrontedState;
142
+ };
143
+ latestBlockheight?: number;
144
+ }>;
139
145
  /**
140
146
  * @inheritDoc
141
147
  */
@@ -17,6 +17,10 @@ const spvVaultContractAddreses = {
17
17
  [starknet_1.constants.StarknetChainId.SN_SEPOLIA]: "0x02d581ea838cd5ca46ba08660eddd064d50a0392f618e95310432147928d572e",
18
18
  [starknet_1.constants.StarknetChainId.SN_MAIN]: "0x01932042992647771f3d0aa6ee526e65359c891fe05a285faaf4d3ffa373e132"
19
19
  };
20
+ const spvVaultContractDeploymentHeights = {
21
+ [starknet_1.constants.StarknetChainId.SN_SEPOLIA]: 1118191,
22
+ [starknet_1.constants.StarknetChainId.SN_MAIN]: 1617295
23
+ };
20
24
  const STARK_PRIME_MOD = 2n ** 251n + 17n * 2n ** 192n + 1n;
21
25
  function decodeUtxo(utxo) {
22
26
  const [txId, vout] = utxo.split(":");
@@ -31,8 +35,11 @@ function decodeUtxo(utxo) {
31
35
  * @category Swaps
32
36
  */
33
37
  class StarknetSpvVaultContract extends StarknetContractBase_1.StarknetContractBase {
34
- constructor(chainInterface, btcRelay, bitcoinRpc, contractAddress = spvVaultContractAddreses[chainInterface.starknetChainId]) {
35
- super(chainInterface, contractAddress, SpvVaultContractAbi_1.SpvVaultContractAbi);
38
+ constructor(chainInterface, btcRelay, bitcoinRpc, contractAddress = spvVaultContractAddreses[chainInterface.starknetChainId], contractDeploymentHeight) {
39
+ super(chainInterface, contractAddress, SpvVaultContractAbi_1.SpvVaultContractAbi, contractDeploymentHeight ??
40
+ (spvVaultContractAddreses[chainInterface.starknetChainId] === contractAddress
41
+ ? spvVaultContractDeploymentHeights[chainInterface.starknetChainId]
42
+ : undefined));
36
43
  this.chainId = "STARKNET";
37
44
  this.claimTimeout = 180;
38
45
  this.maxClaimsPerTx = 10;
@@ -265,29 +272,44 @@ class StarknetSpvVaultContract extends StarknetContractBase_1.StarknetContractBa
265
272
  case "spv_swap_vault::events::Fronted":
266
273
  return {
267
274
  type: base_1.SpvWithdrawalStateType.FRONTED,
268
- txId: event.txHash,
275
+ btcTxId: (0, Utils_1.bigNumberishToBuffer)(event.params.btc_tx_hash, 32).reverse().toString("hex"),
269
276
  owner: (0, Utils_1.toHex)(event.params.owner),
270
277
  vaultId: (0, Utils_1.toBigInt)(event.params.vault_id),
271
278
  recipient: (0, Utils_1.toHex)(event.params.recipient),
272
- fronter: (0, Utils_1.toHex)(event.params.fronting_address)
279
+ fronter: (0, Utils_1.toHex)(event.params.caller),
280
+ txId: event.txHash,
281
+ getTxBlock: async () => ({
282
+ blockHeight: event.blockNumber,
283
+ blockTime: await this.Chain.Blocks.getBlockTime(event.blockNumber)
284
+ })
273
285
  };
274
286
  case "spv_swap_vault::events::Claimed":
275
287
  return {
276
288
  type: base_1.SpvWithdrawalStateType.CLAIMED,
277
- txId: event.txHash,
289
+ btcTxId: (0, Utils_1.bigNumberishToBuffer)(event.params.btc_tx_hash, 32).reverse().toString("hex"),
278
290
  owner: (0, Utils_1.toHex)(event.params.owner),
279
291
  vaultId: (0, Utils_1.toBigInt)(event.params.vault_id),
280
292
  recipient: (0, Utils_1.toHex)(event.params.recipient),
281
293
  claimer: (0, Utils_1.toHex)(event.params.caller),
282
- fronter: (0, Utils_1.toHex)(event.params.fronting_address)
294
+ fronter: (0, Utils_1.toHex)(event.params.fronting_address),
295
+ txId: event.txHash,
296
+ getTxBlock: async () => ({
297
+ blockHeight: event.blockNumber,
298
+ blockTime: await this.Chain.Blocks.getBlockTime(event.blockNumber)
299
+ })
283
300
  };
284
301
  case "spv_swap_vault::events::Closed":
285
302
  return {
286
303
  type: base_1.SpvWithdrawalStateType.CLOSED,
287
- txId: event.txHash,
304
+ btcTxId: (0, Utils_1.bigNumberishToBuffer)(event.params.btc_tx_hash, 32).reverse().toString("hex"),
288
305
  owner: (0, Utils_1.toHex)(event.params.owner),
289
306
  vaultId: (0, Utils_1.toBigInt)(event.params.vault_id),
290
- error: (0, Utils_1.bigNumberishToBuffer)(event.params.error).toString()
307
+ error: (0, Utils_1.bigNumberishToBuffer)(event.params.error).toString(),
308
+ txId: event.txHash,
309
+ getTxBlock: async () => ({
310
+ blockHeight: event.blockNumber,
311
+ blockTime: await this.Chain.Blocks.getBlockTime(event.blockNumber)
312
+ })
291
313
  };
292
314
  default:
293
315
  return null;
@@ -354,6 +376,21 @@ class StarknetSpvVaultContract extends StarknetContractBase_1.StarknetContractBa
354
376
  }, scStartBlockheight);
355
377
  return result;
356
378
  }
379
+ async getHistoricalWithdrawalStates(recipient, startBlockheight) {
380
+ const { height: latestBlockheight } = await this.Chain.getFinalizedBlock();
381
+ const withdrawals = {};
382
+ const eventTypes = ["spv_swap_vault::events::Fronted", "spv_swap_vault::events::Claimed"];
383
+ await this.Events.findInContractEventsForward(eventTypes, [null, null, null, null, recipient], async (_event) => {
384
+ const eventResult = this.parseWithdrawalEvent(_event);
385
+ if (eventResult == null || eventResult.type === base_1.SpvWithdrawalStateType.CLOSED)
386
+ return null;
387
+ withdrawals[eventResult.btcTxId] = eventResult;
388
+ }, startBlockheight);
389
+ return {
390
+ withdrawals,
391
+ latestBlockheight
392
+ };
393
+ }
357
394
  /**
358
395
  * @inheritDoc
359
396
  */
@@ -1,9 +1,10 @@
1
1
  import { ChainSwapType, IntermediaryReputationType, RelaySynchronizer, SignatureData, SwapCommitState, SwapContract, TransactionConfirmationOptions } from "@atomiqlabs/base";
2
2
  import { Buffer } from "buffer";
3
- import { EscrowManagerAbi } from "./EscrowManagerAbi";
3
+ import { EscrowManagerAbi, EscrowManagerAbiType } from "./EscrowManagerAbi";
4
4
  import { StarknetContractBase } from "../contract/StarknetContractBase";
5
- import { StarknetTx } from "../chain/modules/StarknetTransactions";
5
+ import { StarknetTraceCall, StarknetTx } from "../chain/modules/StarknetTransactions";
6
6
  import { StarknetSigner } from "../wallet/StarknetSigner";
7
+ import { BigNumberish } from "starknet";
7
8
  import { StarknetChainInterface } from "../chain/StarknetChainInterface";
8
9
  import { StarknetBtcRelay } from "../btcrelay/StarknetBtcRelay";
9
10
  import { StarknetSwapData } from "./StarknetSwapData";
@@ -14,6 +15,7 @@ import { IClaimHandler } from "./handlers/claim/ClaimHandlers";
14
15
  import { StarknetSwapClaim } from "./modules/StarknetSwapClaim";
15
16
  import { IHandler } from "./handlers/IHandler";
16
17
  import { StarknetBtcStoredHeader } from "../btcrelay/headers/StarknetBtcStoredHeader";
18
+ import { ExtractAbiFunctionNames } from "abi-wan-kanabi/dist/kanabi";
17
19
  /**
18
20
  * Starknet swap contract (escrow manager) contract representation handling PrTLC (on-chain) and HTLC (lightning)
19
21
  * based swaps
@@ -59,6 +61,8 @@ export declare class StarknetSwapContract extends StarknetContractBase<typeof Es
59
61
  };
60
62
  readonly timelockRefundHandler: IHandler<any, any>;
61
63
  readonly btcRelay: StarknetBtcRelay<any>;
64
+ protected readonly initFunctionName: ExtractAbiFunctionNames<EscrowManagerAbiType>;
65
+ protected readonly initEntryPointSelector: bigint;
62
66
  /**
63
67
  * Constructs the swap contract (escrow manager)
64
68
  *
@@ -66,6 +70,7 @@ export declare class StarknetSwapContract extends StarknetContractBase<typeof Es
66
70
  * @param btcRelay Btc relay light client contract
67
71
  * @param contractAddress Optional underlying contract address (default is used otherwise)
68
72
  * @param _handlerAddresses Optional handler addresses (defaults are used otherwise)
73
+ * @param contractDeploymentHeight The height at which this contract was deployed (default is used otherwise)
69
74
  */
70
75
  constructor(chainInterface: StarknetChainInterface, btcRelay: StarknetBtcRelay<any>, contractAddress?: string, _handlerAddresses?: {
71
76
  refund?: {
@@ -74,7 +79,7 @@ export declare class StarknetSwapContract extends StarknetContractBase<typeof Es
74
79
  claim?: {
75
80
  [type in ChainSwapType]?: string;
76
81
  };
77
- });
82
+ }, contractDeploymentHeight?: number);
78
83
  /**
79
84
  * @inheritDoc
80
85
  */
@@ -160,10 +165,37 @@ export declare class StarknetSwapContract extends StarknetContractBase<typeof Es
160
165
  }[]): Promise<{
161
166
  [p: string]: SwapCommitState;
162
167
  }>;
168
+ /**
169
+ * @inheritDoc
170
+ */
171
+ getHistoricalSwaps(signer: string, startBlockheight?: number): Promise<{
172
+ swaps: {
173
+ [escrowHash: string]: {
174
+ init?: {
175
+ data: StarknetSwapData;
176
+ getInitTxId: () => Promise<string>;
177
+ getTxBlock: () => Promise<{
178
+ blockTime: number;
179
+ blockHeight: number;
180
+ }>;
181
+ };
182
+ state: SwapCommitState;
183
+ };
184
+ };
185
+ latestBlockheight?: number;
186
+ }>;
163
187
  /**
164
188
  * @inheritDoc
165
189
  */
166
190
  createSwapData(type: ChainSwapType, offerer: string, claimer: string, token: string, amount: bigint, claimData: string, sequence: bigint, expiry: bigint, payIn: boolean, payOut: boolean, securityDeposit: bigint, claimerBounty: bigint, depositToken?: string): Promise<StarknetSwapData>;
191
+ /**
192
+ *
193
+ * @param call
194
+ * @param escrowHash
195
+ * @param claimHandler
196
+ * @private
197
+ */
198
+ findInitSwapData(call: StarknetTraceCall, escrowHash: BigNumberish, claimHandler: IClaimHandler<any, any>): StarknetSwapData | null;
167
199
  /**
168
200
  *
169
201
  * @param address