@atomiqlabs/chain-starknet 8.0.13 → 8.1.10
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/index.d.ts +18 -18
- package/dist/index.js +42 -42
- package/dist/starknet/StarknetChainType.d.ts +19 -19
- package/dist/starknet/StarknetChainType.js +2 -2
- package/dist/starknet/StarknetInitializer.d.ts +66 -63
- package/dist/starknet/StarknetInitializer.js +101 -101
- package/dist/starknet/btcrelay/BtcRelayAbi.d.ts +250 -250
- package/dist/starknet/btcrelay/BtcRelayAbi.js +341 -341
- package/dist/starknet/btcrelay/StarknetBtcRelay.d.ts +196 -196
- package/dist/starknet/btcrelay/StarknetBtcRelay.js +419 -411
- package/dist/starknet/btcrelay/headers/StarknetBtcHeader.d.ts +70 -70
- package/dist/starknet/btcrelay/headers/StarknetBtcHeader.js +115 -115
- package/dist/starknet/btcrelay/headers/StarknetBtcStoredHeader.d.ts +91 -91
- package/dist/starknet/btcrelay/headers/StarknetBtcStoredHeader.js +155 -155
- package/dist/starknet/chain/StarknetAction.d.ts +19 -19
- package/dist/starknet/chain/StarknetAction.js +74 -74
- package/dist/starknet/chain/StarknetChainInterface.d.ts +142 -143
- package/dist/starknet/chain/StarknetChainInterface.js +198 -199
- package/dist/starknet/chain/StarknetModule.d.ts +8 -8
- package/dist/starknet/chain/StarknetModule.js +12 -12
- package/dist/starknet/chain/modules/ERC20Abi.d.ts +755 -755
- package/dist/starknet/chain/modules/ERC20Abi.js +1032 -1032
- package/dist/starknet/chain/modules/StarknetAccounts.d.ts +6 -6
- package/dist/starknet/chain/modules/StarknetAccounts.js +26 -26
- package/dist/starknet/chain/modules/StarknetAddresses.d.ts +10 -10
- package/dist/starknet/chain/modules/StarknetAddresses.js +27 -27
- package/dist/starknet/chain/modules/StarknetBlocks.d.ts +27 -27
- package/dist/starknet/chain/modules/StarknetBlocks.js +82 -82
- package/dist/starknet/chain/modules/StarknetEvents.d.ts +47 -47
- package/dist/starknet/chain/modules/StarknetEvents.js +90 -90
- package/dist/starknet/chain/modules/StarknetFees.d.ts +118 -104
- package/dist/starknet/chain/modules/StarknetFees.js +150 -146
- package/dist/starknet/chain/modules/StarknetSignatures.d.ts +29 -29
- package/dist/starknet/chain/modules/StarknetSignatures.js +72 -72
- package/dist/starknet/chain/modules/StarknetTokens.d.ts +66 -66
- package/dist/starknet/chain/modules/StarknetTokens.js +99 -99
- package/dist/starknet/chain/modules/StarknetTransactions.d.ts +122 -115
- package/dist/starknet/chain/modules/StarknetTransactions.js +633 -612
- package/dist/starknet/contract/StarknetContractBase.d.ts +14 -13
- package/dist/starknet/contract/StarknetContractBase.js +21 -20
- package/dist/starknet/contract/StarknetContractModule.d.ts +8 -8
- package/dist/starknet/contract/StarknetContractModule.js +11 -11
- package/dist/starknet/contract/modules/StarknetContractEvents.d.ts +56 -57
- package/dist/starknet/contract/modules/StarknetContractEvents.js +111 -111
- package/dist/starknet/events/StarknetChainEvents.d.ts +21 -21
- package/dist/starknet/events/StarknetChainEvents.js +61 -61
- package/dist/starknet/events/StarknetChainEventsBrowser.d.ts +178 -190
- package/dist/starknet/events/StarknetChainEventsBrowser.js +523 -582
- package/dist/starknet/provider/RpcProviderWithRetries.d.ts +49 -53
- package/dist/starknet/provider/RpcProviderWithRetries.js +94 -94
- package/dist/starknet/provider/WebSocketChannelWithRetries.d.ts +21 -21
- package/dist/starknet/provider/WebSocketChannelWithRetries.js +46 -46
- package/dist/starknet/spv_swap/SpvVaultContractAbi.d.ts +488 -488
- package/dist/starknet/spv_swap/SpvVaultContractAbi.js +656 -656
- package/dist/starknet/spv_swap/StarknetSpvVaultContract.d.ts +225 -219
- package/dist/starknet/spv_swap/StarknetSpvVaultContract.js +663 -621
- package/dist/starknet/spv_swap/StarknetSpvVaultData.d.ts +108 -108
- package/dist/starknet/spv_swap/StarknetSpvVaultData.js +190 -190
- package/dist/starknet/spv_swap/StarknetSpvWithdrawalData.d.ts +56 -56
- package/dist/starknet/spv_swap/StarknetSpvWithdrawalData.js +103 -103
- package/dist/starknet/swaps/EscrowManagerAbi.d.ts +431 -431
- package/dist/starknet/swaps/EscrowManagerAbi.js +583 -583
- package/dist/starknet/swaps/StarknetSwapContract.d.ts +309 -278
- package/dist/starknet/swaps/StarknetSwapContract.js +755 -579
- package/dist/starknet/swaps/StarknetSwapData.d.ts +234 -234
- package/dist/starknet/swaps/StarknetSwapData.js +474 -474
- package/dist/starknet/swaps/StarknetSwapModule.d.ts +10 -10
- package/dist/starknet/swaps/StarknetSwapModule.js +12 -12
- package/dist/starknet/swaps/handlers/IHandler.d.ts +13 -13
- package/dist/starknet/swaps/handlers/IHandler.js +2 -2
- package/dist/starknet/swaps/handlers/claim/ClaimHandlers.d.ts +13 -13
- package/dist/starknet/swaps/handlers/claim/ClaimHandlers.js +13 -13
- package/dist/starknet/swaps/handlers/claim/HashlockClaimHandler.d.ts +21 -21
- package/dist/starknet/swaps/handlers/claim/HashlockClaimHandler.js +44 -44
- package/dist/starknet/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.d.ts +24 -24
- package/dist/starknet/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.js +48 -48
- package/dist/starknet/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.d.ts +25 -25
- package/dist/starknet/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.js +40 -40
- package/dist/starknet/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.d.ts +20 -20
- package/dist/starknet/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.js +30 -30
- package/dist/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.d.ts +42 -45
- package/dist/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.js +50 -54
- package/dist/starknet/swaps/handlers/refund/TimelockRefundHandler.d.ts +17 -17
- package/dist/starknet/swaps/handlers/refund/TimelockRefundHandler.js +27 -27
- package/dist/starknet/swaps/modules/StarknetLpVault.d.ts +67 -67
- package/dist/starknet/swaps/modules/StarknetLpVault.js +122 -122
- package/dist/starknet/swaps/modules/StarknetSwapClaim.d.ts +52 -52
- package/dist/starknet/swaps/modules/StarknetSwapClaim.js +99 -99
- package/dist/starknet/swaps/modules/StarknetSwapInit.d.ts +94 -94
- package/dist/starknet/swaps/modules/StarknetSwapInit.js +239 -239
- package/dist/starknet/swaps/modules/StarknetSwapRefund.d.ts +60 -60
- package/dist/starknet/swaps/modules/StarknetSwapRefund.js +126 -126
- package/dist/starknet/wallet/StarknetBrowserSigner.d.ts +11 -11
- package/dist/starknet/wallet/StarknetBrowserSigner.js +17 -17
- package/dist/starknet/wallet/StarknetPersistentSigner.d.ts +76 -76
- package/dist/starknet/wallet/StarknetPersistentSigner.js +291 -291
- package/dist/starknet/wallet/StarknetSigner.d.ts +72 -72
- package/dist/starknet/wallet/StarknetSigner.js +114 -114
- package/dist/starknet/wallet/accounts/StarknetKeypairWallet.d.ts +18 -18
- package/dist/starknet/wallet/accounts/StarknetKeypairWallet.js +45 -45
- package/dist/utils/Utils.d.ts +77 -77
- package/dist/utils/Utils.js +304 -303
- package/package.json +2 -2
- package/src/starknet/StarknetInitializer.ts +6 -3
- package/src/starknet/btcrelay/StarknetBtcRelay.ts +19 -6
- package/src/starknet/btcrelay/headers/StarknetBtcHeader.ts +7 -7
- package/src/starknet/btcrelay/headers/StarknetBtcStoredHeader.ts +6 -6
- package/src/starknet/chain/StarknetAction.ts +1 -0
- package/src/starknet/chain/StarknetChainInterface.ts +0 -2
- package/src/starknet/chain/modules/StarknetFees.ts +15 -2
- package/src/starknet/chain/modules/StarknetTransactions.ts +24 -0
- package/src/starknet/contract/StarknetContractBase.ts +7 -4
- package/src/starknet/contract/StarknetContractModule.ts +1 -1
- package/src/starknet/contract/modules/StarknetContractEvents.ts +7 -7
- package/src/starknet/events/StarknetChainEventsBrowser.ts +2 -64
- package/src/starknet/provider/RpcProviderWithRetries.ts +1 -1
- package/src/starknet/spv_swap/StarknetSpvVaultContract.ts +84 -18
- package/src/starknet/swaps/StarknetSwapContract.ts +242 -6
- package/src/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.ts +0 -4
|
@@ -71,8 +71,11 @@ export type StarknetOptions = {
|
|
|
71
71
|
chainId?: constants.StarknetChainId,
|
|
72
72
|
|
|
73
73
|
swapContract?: string,
|
|
74
|
+
swapContractDeploymentHeight?: number,
|
|
74
75
|
btcRelayContract?: string,
|
|
76
|
+
btcRelayContractDeploymentHeight?: number,
|
|
75
77
|
spvVaultContract?: string,
|
|
78
|
+
spvVaultContractDeploymentHeight?: number,
|
|
76
79
|
handlerContracts?: {
|
|
77
80
|
refund?: {
|
|
78
81
|
timelock?: string
|
|
@@ -113,15 +116,15 @@ export function initializeStarknet(
|
|
|
113
116
|
const chainInterface = new StarknetChainInterface(chainId, provider, wsChannel, Fees, options.starknetConfig);
|
|
114
117
|
|
|
115
118
|
const btcRelay = new StarknetBtcRelay(
|
|
116
|
-
chainInterface, bitcoinRpc, network, options.btcRelayContract
|
|
119
|
+
chainInterface, bitcoinRpc, network, options.btcRelayContract, options.btcRelayContractDeploymentHeight
|
|
117
120
|
);
|
|
118
121
|
|
|
119
122
|
const swapContract = new StarknetSwapContract(
|
|
120
|
-
chainInterface, btcRelay, options.swapContract, options.handlerContracts
|
|
123
|
+
chainInterface, btcRelay, options.swapContract, options.handlerContracts, options.swapContractDeploymentHeight
|
|
121
124
|
);
|
|
122
125
|
|
|
123
126
|
const spvVaultContract = new StarknetSpvVaultContract(
|
|
124
|
-
chainInterface, btcRelay, bitcoinRpc, options.spvVaultContract
|
|
127
|
+
chainInterface, btcRelay, bitcoinRpc, options.spvVaultContract, options.spvVaultContractDeploymentHeight
|
|
125
128
|
)
|
|
126
129
|
|
|
127
130
|
const chainEvents = new StarknetChainEventsBrowser(chainInterface, swapContract, spvVaultContract);
|
|
@@ -11,7 +11,7 @@ import {StarknetBtcStoredHeader} from "./headers/StarknetBtcStoredHeader";
|
|
|
11
11
|
import {StarknetTx} from "../chain/modules/StarknetTransactions";
|
|
12
12
|
import {StarknetSigner} from "../wallet/StarknetSigner";
|
|
13
13
|
import {BtcRelayAbi} from "./BtcRelayAbi";
|
|
14
|
-
import {BigNumberish, hash} from "starknet";
|
|
14
|
+
import {BigNumberish, constants, hash} from "starknet";
|
|
15
15
|
import {StarknetFees, starknetGasAdd, starknetGasMul} from "../chain/modules/StarknetFees";
|
|
16
16
|
import {StarknetChainInterface} from "../chain/StarknetChainInterface";
|
|
17
17
|
import {StarknetAction} from "../chain/StarknetAction";
|
|
@@ -37,6 +37,12 @@ const btcRelayAddreses: {[network in BitcoinNetwork]?: string} = {
|
|
|
37
37
|
[BitcoinNetwork.MAINNET]: "0x057b14a4231b82f1e525ff35a722d893ca3dd2bde0baa6cee97937c5be861dbc"
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
+
const btcRelayDeploymentHeights: {[network in BitcoinNetwork]?: number} = {
|
|
41
|
+
[BitcoinNetwork.TESTNET4]: 760719,
|
|
42
|
+
[BitcoinNetwork.TESTNET]: 633915,
|
|
43
|
+
[BitcoinNetwork.MAINNET]: 1278562
|
|
44
|
+
};
|
|
45
|
+
|
|
40
46
|
function serializeCalldata(headers: StarknetBtcHeader[], storedHeader: StarknetBtcStoredHeader, span: BigNumberish[]) {
|
|
41
47
|
span.push(toHex(headers.length));
|
|
42
48
|
headers.forEach(header => {
|
|
@@ -131,9 +137,16 @@ export class StarknetBtcRelay<B extends BtcBlock>
|
|
|
131
137
|
bitcoinRpc: BitcoinRpc<B>,
|
|
132
138
|
bitcoinNetwork: BitcoinNetwork,
|
|
133
139
|
contractAddress: string | undefined = btcRelayAddreses[bitcoinNetwork],
|
|
140
|
+
contractDeploymentHeight?: number
|
|
134
141
|
) {
|
|
135
142
|
if(contractAddress==null) throw new Error("No BtcRelay address specified!");
|
|
136
|
-
super(
|
|
143
|
+
super(
|
|
144
|
+
chainInterface, contractAddress, BtcRelayAbi,
|
|
145
|
+
contractDeploymentHeight ??
|
|
146
|
+
(btcRelayAddreses[bitcoinNetwork]===contractAddress
|
|
147
|
+
? btcRelayDeploymentHeights[bitcoinNetwork]
|
|
148
|
+
: undefined)
|
|
149
|
+
);
|
|
137
150
|
this.bitcoinRpc = bitcoinRpc;
|
|
138
151
|
}
|
|
139
152
|
|
|
@@ -266,7 +279,7 @@ export class StarknetBtcRelay<B extends BtcBlock>
|
|
|
266
279
|
const [storedBlockHeader, commitHash] = result;
|
|
267
280
|
|
|
268
281
|
//Check if block is part of the main chain
|
|
269
|
-
const chainCommitment = await this.contract.get_commit_hash(storedBlockHeader.
|
|
282
|
+
const chainCommitment = await this.contract.get_commit_hash(storedBlockHeader.getBlockheight());
|
|
270
283
|
if(BigInt(chainCommitment)!==BigInt(commitHash)) return null;
|
|
271
284
|
|
|
272
285
|
logger.debug("retrieveLogAndBlockheight(): block found," +
|
|
@@ -285,11 +298,11 @@ export class StarknetBtcRelay<B extends BtcBlock>
|
|
|
285
298
|
const [storedBlockHeader, commitHash] = result;
|
|
286
299
|
|
|
287
300
|
//Check if block is part of the main chain
|
|
288
|
-
const chainCommitment = await this.contract.get_commit_hash(storedBlockHeader.
|
|
301
|
+
const chainCommitment = await this.contract.get_commit_hash(storedBlockHeader.getBlockheight());
|
|
289
302
|
if(BigInt(chainCommitment)!==BigInt(commitHash)) return null;
|
|
290
303
|
|
|
291
304
|
logger.debug("retrieveLogByCommitHash(): block found," +
|
|
292
|
-
" commit hash: "+commitmentHash+" blockhash: "+blockData.blockhash+" height: "+storedBlockHeader.
|
|
305
|
+
" commit hash: "+commitmentHash+" blockhash: "+blockData.blockhash+" height: "+storedBlockHeader.getBlockheight());
|
|
293
306
|
|
|
294
307
|
return storedBlockHeader;
|
|
295
308
|
}
|
|
@@ -312,7 +325,7 @@ export class StarknetBtcRelay<B extends BtcBlock>
|
|
|
312
325
|
|
|
313
326
|
const [isInBtcMainChain, btcRelayCommitHash] = await Promise.all([
|
|
314
327
|
this.bitcoinRpc.isInMainChain(blockHashHex).catch(() => false),
|
|
315
|
-
this.contract.get_commit_hash(storedHeader.
|
|
328
|
+
this.contract.get_commit_hash(storedHeader.getBlockheight())
|
|
316
329
|
]);
|
|
317
330
|
|
|
318
331
|
if(!isInBtcMainChain) return null;
|
|
@@ -21,13 +21,13 @@ export type StarknetBtcHeaderType = {
|
|
|
21
21
|
*/
|
|
22
22
|
export class StarknetBtcHeader implements BtcHeader {
|
|
23
23
|
|
|
24
|
-
reversed_version: number;
|
|
25
|
-
previous_blockhash: number[];
|
|
26
|
-
merkle_root: number[];
|
|
27
|
-
reversed_timestamp: number;
|
|
28
|
-
nbits: number;
|
|
29
|
-
nonce: number;
|
|
30
|
-
hash?: Buffer;
|
|
24
|
+
private readonly reversed_version: number;
|
|
25
|
+
private readonly previous_blockhash: number[];
|
|
26
|
+
private readonly merkle_root: number[];
|
|
27
|
+
private readonly reversed_timestamp: number;
|
|
28
|
+
private readonly nbits: number;
|
|
29
|
+
private readonly nonce: number;
|
|
30
|
+
private readonly hash?: Buffer;
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* Constructs the bitcoin blockheader from a struct as returned by the starknet.js lib
|
|
@@ -21,12 +21,12 @@ export type StarknetBtcStoredHeaderType = {
|
|
|
21
21
|
*/
|
|
22
22
|
export class StarknetBtcStoredHeader implements BtcStoredHeader<StarknetBtcHeader> {
|
|
23
23
|
|
|
24
|
-
blockheader: StarknetBtcHeader;
|
|
25
|
-
block_hash: number[];
|
|
26
|
-
chain_work: Uint256;
|
|
27
|
-
block_height: number;
|
|
28
|
-
last_diff_adjustment: number;
|
|
29
|
-
prev_block_timestamps: number[];
|
|
24
|
+
private readonly blockheader: StarknetBtcHeader;
|
|
25
|
+
private readonly block_hash: number[];
|
|
26
|
+
private readonly chain_work: Uint256;
|
|
27
|
+
private readonly block_height: number;
|
|
28
|
+
private readonly last_diff_adjustment: number;
|
|
29
|
+
private readonly prev_block_timestamps: number[];
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* Constructs the bitcoin stored blockheader from a struct as returned by the starknet.js lib
|
|
@@ -54,8 +54,6 @@ export class StarknetChainInterface implements ChainInterface<StarknetTx, Signed
|
|
|
54
54
|
public readonly Accounts: StarknetAccounts;
|
|
55
55
|
public readonly Blocks: StarknetBlocks;
|
|
56
56
|
|
|
57
|
-
protected readonly logger = getLogger("StarknetChainInterface: ");
|
|
58
|
-
|
|
59
57
|
public readonly config: StarknetConfig;
|
|
60
58
|
|
|
61
59
|
constructor(
|
|
@@ -1,15 +1,24 @@
|
|
|
1
|
-
import {getLogger, toBigInt
|
|
1
|
+
import {getLogger, toBigInt} from "../../../utils/Utils";
|
|
2
2
|
import {Provider} from "starknet";
|
|
3
|
-
import {StarknetTokens} from "./StarknetTokens";
|
|
4
3
|
|
|
5
4
|
const MAX_FEE_AGE = 5000;
|
|
6
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Representation of a starknet feerate including costs for different units of gas
|
|
8
|
+
*
|
|
9
|
+
* @category Chain Interface
|
|
10
|
+
*/
|
|
7
11
|
export type StarknetFeeRate = {
|
|
8
12
|
l1GasCost: bigint;
|
|
9
13
|
l2GasCost: bigint;
|
|
10
14
|
l1DataGasCost: bigint;
|
|
11
15
|
};
|
|
12
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Representation of the starknet transaction gas limits used to create resource bounds and estimate fees
|
|
19
|
+
*
|
|
20
|
+
* @category Chain Interface
|
|
21
|
+
*/
|
|
13
22
|
export type StarknetGas = {
|
|
14
23
|
l1Gas: number,
|
|
15
24
|
l2Gas: number,
|
|
@@ -21,6 +30,8 @@ export type StarknetGas = {
|
|
|
21
30
|
*
|
|
22
31
|
* @param gas
|
|
23
32
|
* @param scalar
|
|
33
|
+
*
|
|
34
|
+
* @category Chain Interface
|
|
24
35
|
*/
|
|
25
36
|
export function starknetGasMul(gas: StarknetGas, scalar: number): StarknetGas {
|
|
26
37
|
return {l1Gas: gas.l1Gas * scalar, l2Gas: gas.l2Gas * scalar, l1DataGas: gas.l1DataGas * scalar};
|
|
@@ -31,6 +42,8 @@ export function starknetGasMul(gas: StarknetGas, scalar: number): StarknetGas {
|
|
|
31
42
|
*
|
|
32
43
|
* @param a
|
|
33
44
|
* @param b
|
|
45
|
+
*
|
|
46
|
+
* @category Chain Interface
|
|
34
47
|
*/
|
|
35
48
|
export function starknetGasAdd(a: StarknetGas, b?: StarknetGas): StarknetGas {
|
|
36
49
|
if(b==null) return a;
|
|
@@ -65,6 +65,13 @@ export function isStarknetTxDeployAccount(obj: any): obj is StarknetTxDeployAcco
|
|
|
65
65
|
export type StarknetTx = StarknetTxInvoke | StarknetTxDeployAccount;
|
|
66
66
|
export type SignedStarknetTx = StarknetTx;
|
|
67
67
|
|
|
68
|
+
export type StarknetTraceCall = {
|
|
69
|
+
calldata: string[],
|
|
70
|
+
contract_address: string,
|
|
71
|
+
entry_point_selector: string,
|
|
72
|
+
calls: StarknetTraceCall[]
|
|
73
|
+
};
|
|
74
|
+
|
|
68
75
|
const MAX_UNCONFIRMED_TXS = 25;
|
|
69
76
|
|
|
70
77
|
export class StarknetTransactions extends StarknetModule {
|
|
@@ -657,6 +664,23 @@ export class StarknetTransactions extends StarknetModule {
|
|
|
657
664
|
return status;
|
|
658
665
|
}
|
|
659
666
|
|
|
667
|
+
async traceTransaction(txId: string, blockHash?: string): Promise<StarknetTraceCall | null> {
|
|
668
|
+
let trace: any;
|
|
669
|
+
try {
|
|
670
|
+
trace = await this.provider.getTransactionTrace(txId);
|
|
671
|
+
} catch (e) {
|
|
672
|
+
this.logger.warn("getSwapDataGetter(): getter: starknet_traceTransaction not supported by the RPC: ", e);
|
|
673
|
+
if(blockHash==null) throw e;
|
|
674
|
+
const blockTraces: any[] = await this.provider.getBlockTransactionsTraces(blockHash);
|
|
675
|
+
const foundTrace = blockTraces.find(val => toHex(val.transaction_hash)===toHex(txId));
|
|
676
|
+
if(foundTrace==null) throw new Error(`Cannot find ${txId} in the block traces, block: ${blockHash}`);
|
|
677
|
+
trace = foundTrace.trace_root;
|
|
678
|
+
}
|
|
679
|
+
if(trace==null) return null;
|
|
680
|
+
if(trace.execute_invocation.revert_reason!=null) return null;
|
|
681
|
+
return trace.execute_invocation;
|
|
682
|
+
}
|
|
683
|
+
|
|
660
684
|
onBeforeTxReplace(callback: (oldTx: string, oldTxId: string, newTx: string, newTxId: string) => Promise<void>): void {
|
|
661
685
|
this._cbksBeforeTxReplace.push(callback);
|
|
662
686
|
}
|
|
@@ -8,15 +8,17 @@ import {StarknetContractEvents} from "./modules/StarknetContractEvents";
|
|
|
8
8
|
*/
|
|
9
9
|
export class StarknetContractBase<T extends Abi> {
|
|
10
10
|
|
|
11
|
-
contract: TypedContractV2<T>;
|
|
11
|
+
readonly contract: TypedContractV2<T>;
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
readonly Events: StarknetContractEvents<T>;
|
|
14
|
+
readonly Chain: StarknetChainInterface;
|
|
15
|
+
readonly contractDeploymentHeight?: number;
|
|
15
16
|
|
|
16
17
|
constructor(
|
|
17
18
|
chainInterface: StarknetChainInterface,
|
|
18
19
|
contractAddress: string,
|
|
19
|
-
contractAbi: T
|
|
20
|
+
contractAbi: T,
|
|
21
|
+
contractDeploymentHeight?: number
|
|
20
22
|
) {
|
|
21
23
|
this.Chain = chainInterface;
|
|
22
24
|
this.contract = new Contract({
|
|
@@ -25,6 +27,7 @@ export class StarknetContractBase<T extends Abi> {
|
|
|
25
27
|
providerOrAccount: chainInterface.provider
|
|
26
28
|
}).typedv2(contractAbi);
|
|
27
29
|
this.Events = new StarknetContractEvents(chainInterface, this, contractAbi);
|
|
30
|
+
this.contractDeploymentHeight = contractDeploymentHeight;
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
}
|
|
@@ -6,7 +6,7 @@ import {StarknetModule} from "../chain/StarknetModule";
|
|
|
6
6
|
|
|
7
7
|
export class StarknetContractModule<TAbi extends Abi> extends StarknetModule {
|
|
8
8
|
|
|
9
|
-
readonly contract: StarknetContractBase<TAbi>;
|
|
9
|
+
protected readonly contract: StarknetContractBase<TAbi>;
|
|
10
10
|
|
|
11
11
|
constructor(chainInterface: StarknetChainInterface, contract: StarknetContractBase<TAbi>) {
|
|
12
12
|
super(chainInterface)
|
|
@@ -18,12 +18,12 @@ export type StarknetAbiEvent<TAbi extends Abi, TEventName extends ExtractAbiEven
|
|
|
18
18
|
|
|
19
19
|
export class StarknetContractEvents<TAbi extends Abi> extends StarknetEvents {
|
|
20
20
|
|
|
21
|
-
readonly contract: StarknetContractBase<TAbi>;
|
|
22
|
-
readonly abi: TAbi;
|
|
23
|
-
readonly knownEventNames: string[];
|
|
24
|
-
readonly abiEvents: AbiEvents;
|
|
25
|
-
readonly abiStructs: AbiStructs;
|
|
26
|
-
readonly abiEnums: AbiEnums;
|
|
21
|
+
private readonly contract: StarknetContractBase<TAbi>;
|
|
22
|
+
private readonly abi: TAbi;
|
|
23
|
+
private readonly knownEventNames: string[];
|
|
24
|
+
private readonly abiEvents: AbiEvents;
|
|
25
|
+
private readonly abiStructs: AbiStructs;
|
|
26
|
+
private readonly abiEnums: AbiEnums;
|
|
27
27
|
|
|
28
28
|
constructor(chainInterface: StarknetChainInterface, contract: StarknetContractBase<TAbi>, abi: TAbi) {
|
|
29
29
|
super(chainInterface);
|
|
@@ -148,7 +148,7 @@ export class StarknetContractEvents<TAbi extends Abi> extends StarknetEvents {
|
|
|
148
148
|
if(result!=null) return result;
|
|
149
149
|
}
|
|
150
150
|
return null;
|
|
151
|
-
}, startHeight, abortSignal);
|
|
151
|
+
}, Math.max(startHeight ?? 0, this.contract.contractDeploymentHeight ?? 0), abortSignal);
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
}
|
|
@@ -39,13 +39,6 @@ import {Buffer} from "buffer";
|
|
|
39
39
|
const PROCESSED_EVENTS_BACKLOG = 5000;
|
|
40
40
|
const LOGS_SLIDING_WINDOW = 60;
|
|
41
41
|
|
|
42
|
-
type StarknetTraceCall = {
|
|
43
|
-
calldata: string[],
|
|
44
|
-
contract_address: string,
|
|
45
|
-
entry_point_selector: string,
|
|
46
|
-
calls: StarknetTraceCall[]
|
|
47
|
-
};
|
|
48
|
-
|
|
49
42
|
/**
|
|
50
43
|
* Current state of the starknet event listener, contains the last processed
|
|
51
44
|
* block number and transaction hash of the last processed event
|
|
@@ -57,20 +50,6 @@ export type StarknetEventListenerState = {
|
|
|
57
50
|
lastTxHash?: string
|
|
58
51
|
};
|
|
59
52
|
|
|
60
|
-
function parseInitFunctionCalldata(calldata: BigNumberish[], claimHandler: IClaimHandler<any, any>): {escrow: StarknetSwapData, signature: BigNumberish[], timeout: bigint, extraData: BigNumberish[]} {
|
|
61
|
-
const escrow = StarknetSwapData.fromSerializedFeltArray(calldata, claimHandler);
|
|
62
|
-
if(calldata.length < 1) throw new Error("Calldata invalid length");
|
|
63
|
-
const signatureLen = Number(toBigInt(calldata.shift()!));
|
|
64
|
-
if(calldata.length < signatureLen + 2) throw new Error("Calldata invalid length");
|
|
65
|
-
const signature = calldata.splice(0, signatureLen);
|
|
66
|
-
const timeout = toBigInt(calldata.shift()!);
|
|
67
|
-
const extraDataLen = Number(toBigInt(calldata.shift()!));
|
|
68
|
-
if(calldata.length < extraDataLen) throw new Error("Calldata invalid length");
|
|
69
|
-
const extraData = calldata.splice(0, extraDataLen);
|
|
70
|
-
if(calldata.length!==0) throw new Error("Calldata not read fully!");
|
|
71
|
-
return {escrow, signature, timeout, extraData};
|
|
72
|
-
}
|
|
73
|
-
|
|
74
53
|
/**
|
|
75
54
|
* Starknet on-chain event handler for front-end systems without access to fs, uses WS or long-polling to subscribe, might lose
|
|
76
55
|
* out on some events if the network is unreliable, front-end systems should take this into consideration and not
|
|
@@ -96,9 +75,6 @@ export class StarknetChainEventsBrowser implements ChainEvents<StarknetSwapData,
|
|
|
96
75
|
protected escrowContractSubscription?: SubscriptionStarknetEventsEvent;
|
|
97
76
|
protected spvVaultContractSubscription?: SubscriptionStarknetEventsEvent;
|
|
98
77
|
|
|
99
|
-
protected initFunctionName: ExtractAbiFunctionNames<EscrowManagerAbiType> = "initialize";
|
|
100
|
-
protected initEntryPointSelector = BigInt(hash.starknetKeccak(this.initFunctionName));
|
|
101
|
-
|
|
102
78
|
protected stopped: boolean = true;
|
|
103
79
|
protected pollIntervalSeconds: number;
|
|
104
80
|
|
|
@@ -153,34 +129,6 @@ export class StarknetChainEventsBrowser implements ChainEvents<StarknetSwapData,
|
|
|
153
129
|
return this.processedEvents.has(eventFingerprint);
|
|
154
130
|
}
|
|
155
131
|
|
|
156
|
-
/**
|
|
157
|
-
*
|
|
158
|
-
* @param call
|
|
159
|
-
* @param escrowHash
|
|
160
|
-
* @param claimHandler
|
|
161
|
-
* @private
|
|
162
|
-
*/
|
|
163
|
-
private findInitSwapData(call: StarknetTraceCall, escrowHash: BigNumberish, claimHandler: IClaimHandler<any, any>): StarknetSwapData | null {
|
|
164
|
-
if(
|
|
165
|
-
BigInt(call.contract_address)===BigInt(this.starknetSwapContract.contract.address) &&
|
|
166
|
-
BigInt(call.entry_point_selector)===this.initEntryPointSelector
|
|
167
|
-
) {
|
|
168
|
-
//Found, check correct escrow hash
|
|
169
|
-
const {escrow, extraData} = parseInitFunctionCalldata(call.calldata, claimHandler);
|
|
170
|
-
if("0x"+escrow.getEscrowHash()===toHex(escrowHash)) {
|
|
171
|
-
if(extraData.length!==0) {
|
|
172
|
-
escrow.setExtraData(bytes31SpanToBuffer(extraData, 42).toString("hex"));
|
|
173
|
-
}
|
|
174
|
-
return escrow;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
for(let _call of call.calls) {
|
|
178
|
-
const found = this.findInitSwapData(_call, escrowHash, claimHandler);
|
|
179
|
-
if(found!=null) return found;
|
|
180
|
-
}
|
|
181
|
-
return null;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
132
|
/**
|
|
185
133
|
* Returns async getter for fetching on-demand initialize event swap data
|
|
186
134
|
*
|
|
@@ -194,19 +142,9 @@ export class StarknetChainEventsBrowser implements ChainEvents<StarknetSwapData,
|
|
|
194
142
|
claimHandler: IClaimHandler<any, any>
|
|
195
143
|
): () => Promise<StarknetSwapData | null> {
|
|
196
144
|
return async () => {
|
|
197
|
-
|
|
198
|
-
try {
|
|
199
|
-
trace = await this.provider.getTransactionTrace(event.txHash);
|
|
200
|
-
} catch (e) {
|
|
201
|
-
this.logger.warn("getSwapDataGetter(): getter: starknet_traceTransaction not supported by the RPC: ", e);
|
|
202
|
-
const blockTraces: any[] = await this.provider.getBlockTransactionsTraces(event.blockHash);
|
|
203
|
-
const foundTrace = blockTraces.find(val => toHex(val.transaction_hash)===toHex(event.txHash));
|
|
204
|
-
if(foundTrace==null) throw new Error(`Cannot find ${event.txHash} in the block traces, block: ${event.blockHash}`);
|
|
205
|
-
trace = foundTrace.trace_root;
|
|
206
|
-
}
|
|
145
|
+
const trace = await this.Chain.Transactions.traceTransaction(event.txHash, event.blockHash);
|
|
207
146
|
if(trace==null) return null;
|
|
208
|
-
|
|
209
|
-
return this.findInitSwapData(trace.execute_invocation as any, event.params.escrow_hash, claimHandler);
|
|
147
|
+
return this.starknetSwapContract.findInitSwapData(trace, event.params.escrow_hash, claimHandler);
|
|
210
148
|
}
|
|
211
149
|
}
|
|
212
150
|
|
|
@@ -10,7 +10,7 @@ import {tryWithRetries} from "../../utils/Utils";
|
|
|
10
10
|
*/
|
|
11
11
|
export class Rpc09ChannelWithRetries extends RPC09.RpcChannel {
|
|
12
12
|
|
|
13
|
-
readonly retryPolicy?: {
|
|
13
|
+
private readonly retryPolicy?: {
|
|
14
14
|
maxRetries?: number, delay?: number, exponential?: boolean
|
|
15
15
|
};
|
|
16
16
|
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
BtcTx,
|
|
4
4
|
RelaySynchronizer,
|
|
5
5
|
SpvVaultContract,
|
|
6
|
-
SpvVaultTokenData,
|
|
6
|
+
SpvVaultTokenData, SpvWithdrawalClaimedState, SpvWithdrawalClosedState, SpvWithdrawalFrontedState,
|
|
7
7
|
SpvWithdrawalState,
|
|
8
8
|
SpvWithdrawalStateType,
|
|
9
9
|
SpvWithdrawalTransactionData,
|
|
@@ -31,6 +31,11 @@ const spvVaultContractAddreses = {
|
|
|
31
31
|
[constants.StarknetChainId.SN_MAIN]: "0x01932042992647771f3d0aa6ee526e65359c891fe05a285faaf4d3ffa373e132"
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
+
const spvVaultContractDeploymentHeights = {
|
|
35
|
+
[constants.StarknetChainId.SN_SEPOLIA]: 1118191,
|
|
36
|
+
[constants.StarknetChainId.SN_MAIN]: 1617295
|
|
37
|
+
};
|
|
38
|
+
|
|
34
39
|
const STARK_PRIME_MOD: bigint = 2n**251n + 17n * 2n**192n + 1n;
|
|
35
40
|
|
|
36
41
|
function decodeUtxo(utxo: string): {txHash: bigint, vout: bigint} {
|
|
@@ -66,20 +71,27 @@ export class StarknetSpvVaultContract
|
|
|
66
71
|
|
|
67
72
|
readonly chainId = "STARKNET";
|
|
68
73
|
|
|
69
|
-
readonly btcRelay: StarknetBtcRelay<any>;
|
|
70
|
-
readonly bitcoinRpc: BitcoinRpc<any>;
|
|
71
74
|
readonly claimTimeout: number = 180;
|
|
72
75
|
readonly maxClaimsPerTx: number = 10;
|
|
73
76
|
|
|
74
|
-
readonly
|
|
77
|
+
private readonly btcRelay: StarknetBtcRelay<any>;
|
|
78
|
+
private readonly bitcoinRpc: BitcoinRpc<any>;
|
|
79
|
+
private readonly logger = getLogger("StarknetSpvVaultContract: ");
|
|
75
80
|
|
|
76
81
|
constructor(
|
|
77
82
|
chainInterface: StarknetChainInterface,
|
|
78
83
|
btcRelay: StarknetBtcRelay<any>,
|
|
79
84
|
bitcoinRpc: BitcoinRpc<any>,
|
|
80
|
-
contractAddress: string = spvVaultContractAddreses[chainInterface.starknetChainId]
|
|
85
|
+
contractAddress: string = spvVaultContractAddreses[chainInterface.starknetChainId],
|
|
86
|
+
contractDeploymentHeight?: number
|
|
81
87
|
) {
|
|
82
|
-
super(
|
|
88
|
+
super(
|
|
89
|
+
chainInterface, contractAddress, SpvVaultContractAbi,
|
|
90
|
+
contractDeploymentHeight ??
|
|
91
|
+
(spvVaultContractAddreses[chainInterface.starknetChainId]===contractAddress
|
|
92
|
+
? spvVaultContractDeploymentHeights[chainInterface.starknetChainId]
|
|
93
|
+
: undefined)
|
|
94
|
+
);
|
|
83
95
|
this.btcRelay = btcRelay;
|
|
84
96
|
this.bitcoinRpc = bitcoinRpc;
|
|
85
97
|
}
|
|
@@ -280,7 +292,7 @@ export class StarknetSpvVaultContract
|
|
|
280
292
|
const openedVaults = new Set<string>();
|
|
281
293
|
await this.Events.findInContractEventsForward(
|
|
282
294
|
["spv_swap_vault::events::Opened", "spv_swap_vault::events::Closed"],
|
|
283
|
-
owner==null ? null : [null, owner],
|
|
295
|
+
owner==null ? null : [null, null, owner],
|
|
284
296
|
(event) => {
|
|
285
297
|
const owner = toHex(event.params.owner);
|
|
286
298
|
const vaultId = toBigInt(event.params.vault_id);
|
|
@@ -293,12 +305,20 @@ export class StarknetSpvVaultContract
|
|
|
293
305
|
return Promise.resolve(null);
|
|
294
306
|
}
|
|
295
307
|
);
|
|
296
|
-
|
|
297
|
-
|
|
308
|
+
|
|
309
|
+
const fetchedVaultData = await this.getMultipleVaultData([...openedVaults.keys()].map(identifier => {
|
|
298
310
|
const [owner, vaultIdStr] = identifier.split(":");
|
|
299
|
-
|
|
300
|
-
|
|
311
|
+
return {owner, vaultId: BigInt(vaultIdStr)}
|
|
312
|
+
}));
|
|
313
|
+
|
|
314
|
+
const vaults: StarknetSpvVaultData[] = [];
|
|
315
|
+
for(let owner in fetchedVaultData) {
|
|
316
|
+
for(let vaultIdStr in fetchedVaultData[owner]) {
|
|
317
|
+
const vault = fetchedVaultData[owner][vaultIdStr];
|
|
318
|
+
if(vault!=null) vaults.push(vault);
|
|
319
|
+
}
|
|
301
320
|
}
|
|
321
|
+
|
|
302
322
|
return vaults;
|
|
303
323
|
}
|
|
304
324
|
|
|
@@ -338,34 +358,53 @@ export class StarknetSpvVaultContract
|
|
|
338
358
|
* @param event
|
|
339
359
|
* @private
|
|
340
360
|
*/
|
|
341
|
-
private parseWithdrawalEvent(
|
|
361
|
+
private parseWithdrawalEvent(
|
|
362
|
+
event: StarknetAbiEvent<typeof SpvVaultContractAbi, "spv_swap_vault::events::Fronted"> |
|
|
363
|
+
StarknetAbiEvent<typeof SpvVaultContractAbi, "spv_swap_vault::events::Claimed"> |
|
|
364
|
+
StarknetAbiEvent<typeof SpvVaultContractAbi, "spv_swap_vault::events::Closed">
|
|
365
|
+
): ((SpvWithdrawalFrontedState | SpvWithdrawalClaimedState | SpvWithdrawalClosedState) & {btcTxId: string}) | null {
|
|
342
366
|
switch(event.name) {
|
|
343
367
|
case "spv_swap_vault::events::Fronted":
|
|
344
368
|
return {
|
|
345
369
|
type: SpvWithdrawalStateType.FRONTED,
|
|
346
|
-
|
|
370
|
+
btcTxId: bigNumberishToBuffer(event.params.btc_tx_hash, 32).reverse().toString("hex"),
|
|
347
371
|
owner: toHex(event.params.owner),
|
|
348
372
|
vaultId: toBigInt(event.params.vault_id),
|
|
349
373
|
recipient: toHex(event.params.recipient),
|
|
350
|
-
fronter: toHex(event.params.
|
|
374
|
+
fronter: toHex(event.params.caller),
|
|
375
|
+
txId: event.txHash,
|
|
376
|
+
getTxBlock: async() => ({
|
|
377
|
+
blockHeight: event.blockNumber!,
|
|
378
|
+
blockTime: await this.Chain.Blocks.getBlockTime(event.blockNumber!)
|
|
379
|
+
})
|
|
351
380
|
};
|
|
352
381
|
case "spv_swap_vault::events::Claimed":
|
|
353
382
|
return {
|
|
354
383
|
type: SpvWithdrawalStateType.CLAIMED,
|
|
355
|
-
|
|
384
|
+
btcTxId: bigNumberishToBuffer(event.params.btc_tx_hash, 32).reverse().toString("hex"),
|
|
356
385
|
owner: toHex(event.params.owner),
|
|
357
386
|
vaultId: toBigInt(event.params.vault_id),
|
|
358
387
|
recipient: toHex(event.params.recipient),
|
|
359
388
|
claimer: toHex(event.params.caller),
|
|
360
|
-
fronter: toHex(event.params.fronting_address)
|
|
389
|
+
fronter: toHex(event.params.fronting_address),
|
|
390
|
+
txId: event.txHash,
|
|
391
|
+
getTxBlock: async() => ({
|
|
392
|
+
blockHeight: event.blockNumber!,
|
|
393
|
+
blockTime: await this.Chain.Blocks.getBlockTime(event.blockNumber!)
|
|
394
|
+
})
|
|
361
395
|
};
|
|
362
396
|
case "spv_swap_vault::events::Closed":
|
|
363
397
|
return {
|
|
364
398
|
type: SpvWithdrawalStateType.CLOSED,
|
|
365
|
-
|
|
399
|
+
btcTxId: bigNumberishToBuffer(event.params.btc_tx_hash, 32).reverse().toString("hex"),
|
|
366
400
|
owner: toHex(event.params.owner),
|
|
367
401
|
vaultId: toBigInt(event.params.vault_id),
|
|
368
|
-
error: bigNumberishToBuffer(event.params.error).toString()
|
|
402
|
+
error: bigNumberishToBuffer(event.params.error).toString(),
|
|
403
|
+
txId: event.txHash,
|
|
404
|
+
getTxBlock: async() => ({
|
|
405
|
+
blockHeight: event.blockNumber!,
|
|
406
|
+
blockTime: await this.Chain.Blocks.getBlockTime(event.blockNumber!)
|
|
407
|
+
})
|
|
369
408
|
};
|
|
370
409
|
default:
|
|
371
410
|
return null;
|
|
@@ -447,6 +486,33 @@ export class StarknetSpvVaultContract
|
|
|
447
486
|
return result;
|
|
448
487
|
}
|
|
449
488
|
|
|
489
|
+
async getHistoricalWithdrawalStates(recipient: string, startBlockheight?: number): Promise<{
|
|
490
|
+
withdrawals: { [btcTxId: string]: SpvWithdrawalClaimedState | SpvWithdrawalFrontedState };
|
|
491
|
+
latestBlockheight?: number
|
|
492
|
+
}> {
|
|
493
|
+
const {height: latestBlockheight} = await this.Chain.getFinalizedBlock();
|
|
494
|
+
const withdrawals: { [btcTxId: string]: SpvWithdrawalClaimedState | SpvWithdrawalFrontedState } = {};
|
|
495
|
+
|
|
496
|
+
const eventTypes: ["spv_swap_vault::events::Fronted", "spv_swap_vault::events::Claimed"] =
|
|
497
|
+
["spv_swap_vault::events::Fronted", "spv_swap_vault::events::Claimed"];
|
|
498
|
+
|
|
499
|
+
await this.Events.findInContractEventsForward(
|
|
500
|
+
eventTypes,
|
|
501
|
+
[null, null, null, null, recipient],
|
|
502
|
+
async (_event) => {
|
|
503
|
+
const eventResult = this.parseWithdrawalEvent(_event);
|
|
504
|
+
if(eventResult==null || eventResult.type===SpvWithdrawalStateType.CLOSED) return null;
|
|
505
|
+
withdrawals[eventResult.btcTxId] = eventResult;
|
|
506
|
+
},
|
|
507
|
+
startBlockheight
|
|
508
|
+
);
|
|
509
|
+
|
|
510
|
+
return {
|
|
511
|
+
withdrawals,
|
|
512
|
+
latestBlockheight
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
450
516
|
/**
|
|
451
517
|
* @inheritDoc
|
|
452
518
|
*/
|