@atomiqlabs/chain-starknet 1.0.0-beta.0
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/LICENSE +201 -0
- package/dist/get_serialized_block.d.ts +1 -0
- package/dist/get_serialized_block.js +28 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +50 -0
- package/dist/starknet/StarknetChainType.d.ts +9 -0
- package/dist/starknet/StarknetChainType.js +2 -0
- package/dist/starknet/StarknetInitializer.d.ts +18 -0
- package/dist/starknet/StarknetInitializer.js +49 -0
- package/dist/starknet/base/StarknetAction.d.ts +27 -0
- package/dist/starknet/base/StarknetAction.js +73 -0
- package/dist/starknet/base/StarknetBase.d.ts +34 -0
- package/dist/starknet/base/StarknetBase.js +29 -0
- package/dist/starknet/base/StarknetModule.d.ts +14 -0
- package/dist/starknet/base/StarknetModule.js +13 -0
- package/dist/starknet/base/modules/ERC20Abi.d.ts +755 -0
- package/dist/starknet/base/modules/ERC20Abi.js +1032 -0
- package/dist/starknet/base/modules/StarknetAccounts.d.ts +6 -0
- package/dist/starknet/base/modules/StarknetAccounts.js +24 -0
- package/dist/starknet/base/modules/StarknetAddresses.d.ts +9 -0
- package/dist/starknet/base/modules/StarknetAddresses.js +26 -0
- package/dist/starknet/base/modules/StarknetBlocks.d.ts +19 -0
- package/dist/starknet/base/modules/StarknetBlocks.js +49 -0
- package/dist/starknet/base/modules/StarknetEvents.d.ts +44 -0
- package/dist/starknet/base/modules/StarknetEvents.js +88 -0
- package/dist/starknet/base/modules/StarknetFees.d.ts +55 -0
- package/dist/starknet/base/modules/StarknetFees.js +102 -0
- package/dist/starknet/base/modules/StarknetSignatures.d.ts +30 -0
- package/dist/starknet/base/modules/StarknetSignatures.js +71 -0
- package/dist/starknet/base/modules/StarknetTokens.d.ts +67 -0
- package/dist/starknet/base/modules/StarknetTokens.js +97 -0
- package/dist/starknet/base/modules/StarknetTransactions.d.ts +87 -0
- package/dist/starknet/base/modules/StarknetTransactions.js +226 -0
- package/dist/starknet/btcrelay/BtcRelayAbi.d.ts +250 -0
- package/dist/starknet/btcrelay/BtcRelayAbi.js +341 -0
- package/dist/starknet/btcrelay/StarknetBtcRelay.d.ts +166 -0
- package/dist/starknet/btcrelay/StarknetBtcRelay.js +323 -0
- package/dist/starknet/btcrelay/headers/StarknetBtcHeader.d.ts +32 -0
- package/dist/starknet/btcrelay/headers/StarknetBtcHeader.js +74 -0
- package/dist/starknet/btcrelay/headers/StarknetBtcStoredHeader.d.ts +52 -0
- package/dist/starknet/btcrelay/headers/StarknetBtcStoredHeader.js +113 -0
- package/dist/starknet/contract/StarknetContractBase.d.ts +13 -0
- package/dist/starknet/contract/StarknetContractBase.js +18 -0
- package/dist/starknet/contract/modules/StarknetContractEvents.d.ts +40 -0
- package/dist/starknet/contract/modules/StarknetContractEvents.js +77 -0
- package/dist/starknet/events/StarknetChainEvents.d.ts +19 -0
- package/dist/starknet/events/StarknetChainEvents.js +51 -0
- package/dist/starknet/events/StarknetChainEventsBrowser.d.ts +73 -0
- package/dist/starknet/events/StarknetChainEventsBrowser.js +210 -0
- package/dist/starknet/swaps/EscrowManagerAbi.d.ts +445 -0
- package/dist/starknet/swaps/EscrowManagerAbi.js +601 -0
- package/dist/starknet/swaps/StarknetSwapContract.d.ts +215 -0
- package/dist/starknet/swaps/StarknetSwapContract.js +452 -0
- package/dist/starknet/swaps/StarknetSwapData.d.ts +74 -0
- package/dist/starknet/swaps/StarknetSwapData.js +316 -0
- package/dist/starknet/swaps/StarknetSwapModule.d.ts +9 -0
- package/dist/starknet/swaps/StarknetSwapModule.js +12 -0
- package/dist/starknet/swaps/handlers/IHandler.d.ts +13 -0
- package/dist/starknet/swaps/handlers/IHandler.js +2 -0
- package/dist/starknet/swaps/handlers/claim/ClaimHandlers.d.ts +13 -0
- package/dist/starknet/swaps/handlers/claim/ClaimHandlers.js +13 -0
- package/dist/starknet/swaps/handlers/claim/HashlockClaimHandler.d.ts +22 -0
- package/dist/starknet/swaps/handlers/claim/HashlockClaimHandler.js +44 -0
- package/dist/starknet/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.d.ts +25 -0
- package/dist/starknet/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.js +48 -0
- package/dist/starknet/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.d.ts +26 -0
- package/dist/starknet/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.js +40 -0
- package/dist/starknet/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.d.ts +20 -0
- package/dist/starknet/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.js +29 -0
- package/dist/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.d.ts +64 -0
- package/dist/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.js +86 -0
- package/dist/starknet/swaps/handlers/refund/TimelockRefundHandler.d.ts +17 -0
- package/dist/starknet/swaps/handlers/refund/TimelockRefundHandler.js +27 -0
- package/dist/starknet/swaps/modules/StarknetLpVault.d.ts +69 -0
- package/dist/starknet/swaps/modules/StarknetLpVault.js +122 -0
- package/dist/starknet/swaps/modules/StarknetSwapClaim.d.ts +53 -0
- package/dist/starknet/swaps/modules/StarknetSwapClaim.js +100 -0
- package/dist/starknet/swaps/modules/StarknetSwapInit.d.ts +84 -0
- package/dist/starknet/swaps/modules/StarknetSwapInit.js +164 -0
- package/dist/starknet/swaps/modules/StarknetSwapRefund.d.ts +64 -0
- package/dist/starknet/swaps/modules/StarknetSwapRefund.js +131 -0
- package/dist/starknet/swaps/modules/SwapClaim.d.ts +54 -0
- package/dist/starknet/swaps/modules/SwapClaim.js +115 -0
- package/dist/starknet/swaps/modules/SwapInit.d.ts +79 -0
- package/dist/starknet/swaps/modules/SwapInit.js +174 -0
- package/dist/starknet/swaps/modules/SwapRefund.d.ts +63 -0
- package/dist/starknet/swaps/modules/SwapRefund.js +149 -0
- package/dist/starknet/wallet/StarknetKeypairWallet.d.ts +6 -0
- package/dist/starknet/wallet/StarknetKeypairWallet.js +26 -0
- package/dist/starknet/wallet/StarknetSigner.d.ts +12 -0
- package/dist/starknet/wallet/StarknetSigner.js +46 -0
- package/dist/utils/Utils.d.ts +38 -0
- package/dist/utils/Utils.js +255 -0
- package/package.json +39 -0
- package/src/index.ts +41 -0
- package/src/starknet/StarknetChainType.ts +20 -0
- package/src/starknet/StarknetInitializer.ts +75 -0
- package/src/starknet/base/StarknetAction.ts +90 -0
- package/src/starknet/base/StarknetBase.ts +56 -0
- package/src/starknet/base/StarknetModule.ts +20 -0
- package/src/starknet/base/modules/ERC20Abi.ts +1029 -0
- package/src/starknet/base/modules/StarknetAccounts.ts +26 -0
- package/src/starknet/base/modules/StarknetAddresses.ts +23 -0
- package/src/starknet/base/modules/StarknetBlocks.ts +59 -0
- package/src/starknet/base/modules/StarknetEvents.ts +105 -0
- package/src/starknet/base/modules/StarknetFees.ts +136 -0
- package/src/starknet/base/modules/StarknetSignatures.ts +91 -0
- package/src/starknet/base/modules/StarknetTokens.ts +116 -0
- package/src/starknet/base/modules/StarknetTransactions.ts +254 -0
- package/src/starknet/btcrelay/BtcRelayAbi.ts +338 -0
- package/src/starknet/btcrelay/StarknetBtcRelay.ts +415 -0
- package/src/starknet/btcrelay/headers/StarknetBtcHeader.ts +101 -0
- package/src/starknet/btcrelay/headers/StarknetBtcStoredHeader.ts +142 -0
- package/src/starknet/contract/StarknetContractBase.ts +29 -0
- package/src/starknet/contract/modules/StarknetContractEvents.ts +108 -0
- package/src/starknet/events/StarknetChainEvents.ts +63 -0
- package/src/starknet/events/StarknetChainEventsBrowser.ts +289 -0
- package/src/starknet/swaps/EscrowManagerAbi.ts +600 -0
- package/src/starknet/swaps/StarknetSwapContract.ts +694 -0
- package/src/starknet/swaps/StarknetSwapData.ts +441 -0
- package/src/starknet/swaps/StarknetSwapModule.ts +17 -0
- package/src/starknet/swaps/handlers/IHandler.ts +20 -0
- package/src/starknet/swaps/handlers/claim/ClaimHandlers.ts +23 -0
- package/src/starknet/swaps/handlers/claim/HashlockClaimHandler.ts +54 -0
- package/src/starknet/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.ts +73 -0
- package/src/starknet/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.ts +67 -0
- package/src/starknet/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.ts +49 -0
- package/src/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.ts +151 -0
- package/src/starknet/swaps/handlers/refund/TimelockRefundHandler.ts +39 -0
- package/src/starknet/swaps/modules/StarknetLpVault.ts +148 -0
- package/src/starknet/swaps/modules/StarknetSwapClaim.ts +142 -0
- package/src/starknet/swaps/modules/StarknetSwapInit.ts +226 -0
- package/src/starknet/swaps/modules/StarknetSwapRefund.ts +202 -0
- package/src/starknet/wallet/StarknetKeypairWallet.ts +34 -0
- package/src/starknet/wallet/StarknetSigner.ts +55 -0
- package/src/utils/Utils.ts +247 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StarknetBtcRelay = void 0;
|
|
4
|
+
const buffer_1 = require("buffer");
|
|
5
|
+
const StarknetBtcHeader_1 = require("./headers/StarknetBtcHeader");
|
|
6
|
+
const base_1 = require("@atomiqlabs/base");
|
|
7
|
+
const Utils_1 = require("../../utils/Utils");
|
|
8
|
+
const StarknetContractBase_1 = require("../contract/StarknetContractBase");
|
|
9
|
+
const StarknetBtcStoredHeader_1 = require("./headers/StarknetBtcStoredHeader");
|
|
10
|
+
const BtcRelayAbi_1 = require("./BtcRelayAbi");
|
|
11
|
+
const starknet_1 = require("starknet");
|
|
12
|
+
const StarknetFees_1 = require("../base/modules/StarknetFees");
|
|
13
|
+
const StarknetAction_1 = require("../base/StarknetAction");
|
|
14
|
+
function serializeBlockHeader(e) {
|
|
15
|
+
return new StarknetBtcHeader_1.StarknetBtcHeader({
|
|
16
|
+
reversed_version: (0, Utils_1.u32ReverseEndianness)(e.getVersion()),
|
|
17
|
+
previous_blockhash: (0, Utils_1.bufferToU32Array)(buffer_1.Buffer.from(e.getPrevBlockhash(), "hex").reverse()),
|
|
18
|
+
merkle_root: (0, Utils_1.bufferToU32Array)(buffer_1.Buffer.from(e.getMerkleRoot(), "hex").reverse()),
|
|
19
|
+
reversed_timestamp: (0, Utils_1.u32ReverseEndianness)(e.getTimestamp()),
|
|
20
|
+
nbits: (0, Utils_1.u32ReverseEndianness)(e.getNbits()),
|
|
21
|
+
nonce: (0, Utils_1.u32ReverseEndianness)(e.getNonce()),
|
|
22
|
+
hash: buffer_1.Buffer.from(e.getHash(), "hex").reverse()
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
const GAS_PER_BLOCKHEADER = 750;
|
|
26
|
+
const GAS_PER_BLOCKHEADER_FORK = 750;
|
|
27
|
+
const btcRelayAddreses = {
|
|
28
|
+
[starknet_1.constants.StarknetChainId.SN_SEPOLIA]: "0x032afcea912ba13f6a1878fe38af23eaec3e6b4c7db31a3571550d3cf80d3e31",
|
|
29
|
+
[starknet_1.constants.StarknetChainId.SN_MAIN]: "0x05cc69b09e8c53520f9e328f6eca72cf02fe46ce290b757d42414e2238001603"
|
|
30
|
+
};
|
|
31
|
+
function serializeCalldata(headers, storedHeader, span) {
|
|
32
|
+
span.push((0, Utils_1.toHex)(headers.length));
|
|
33
|
+
headers.forEach(header => {
|
|
34
|
+
span.push(...header.serialize());
|
|
35
|
+
});
|
|
36
|
+
span.push(...storedHeader.serialize());
|
|
37
|
+
return span;
|
|
38
|
+
}
|
|
39
|
+
class StarknetBtcRelay extends StarknetContractBase_1.StarknetContractBase {
|
|
40
|
+
SaveMainHeaders(signer, mainHeaders, storedHeader) {
|
|
41
|
+
return new StarknetAction_1.StarknetAction(signer, this, {
|
|
42
|
+
contractAddress: this.contract.address,
|
|
43
|
+
entrypoint: "submit_main_blockheaders",
|
|
44
|
+
calldata: serializeCalldata(mainHeaders, storedHeader, [])
|
|
45
|
+
}, { l1: GAS_PER_BLOCKHEADER * mainHeaders.length, l2: 0 });
|
|
46
|
+
}
|
|
47
|
+
SaveShortForkHeaders(signer, forkHeaders, storedHeader) {
|
|
48
|
+
return new StarknetAction_1.StarknetAction(signer, this, {
|
|
49
|
+
contractAddress: this.contract.address,
|
|
50
|
+
entrypoint: "submit_short_fork_blockheaders",
|
|
51
|
+
calldata: serializeCalldata(forkHeaders, storedHeader, [])
|
|
52
|
+
}, { l1: GAS_PER_BLOCKHEADER * forkHeaders.length, l2: 0 });
|
|
53
|
+
}
|
|
54
|
+
SaveLongForkHeaders(signer, forkId, forkHeaders, storedHeader, totalForkHeaders = 100) {
|
|
55
|
+
return new StarknetAction_1.StarknetAction(signer, this, {
|
|
56
|
+
contractAddress: this.contract.address,
|
|
57
|
+
entrypoint: "submit_fork_blockheaders",
|
|
58
|
+
calldata: serializeCalldata(forkHeaders, storedHeader, [(0, Utils_1.toHex)(forkId)])
|
|
59
|
+
}, { l1: (GAS_PER_BLOCKHEADER * forkHeaders.length) + (GAS_PER_BLOCKHEADER_FORK * totalForkHeaders), l2: 0 });
|
|
60
|
+
}
|
|
61
|
+
constructor(chainId, provider, bitcoinRpc, contractAddress = btcRelayAddreses[chainId], retryPolicy, solanaFeeEstimator = new StarknetFees_1.StarknetFees(provider)) {
|
|
62
|
+
super(chainId, provider, contractAddress, BtcRelayAbi_1.BtcRelayAbi, retryPolicy, solanaFeeEstimator);
|
|
63
|
+
this.maxHeadersPerTx = 100;
|
|
64
|
+
this.maxForkHeadersPerTx = 100;
|
|
65
|
+
this.maxShortForkHeadersPerTx = 100;
|
|
66
|
+
this.bitcoinRpc = bitcoinRpc;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Computes subsequent commited headers as they will appear on the blockchain when transactions
|
|
70
|
+
* are submitted & confirmed
|
|
71
|
+
*
|
|
72
|
+
* @param initialStoredHeader
|
|
73
|
+
* @param syncedHeaders
|
|
74
|
+
* @private
|
|
75
|
+
*/
|
|
76
|
+
computeCommitedHeaders(initialStoredHeader, syncedHeaders) {
|
|
77
|
+
const computedCommitedHeaders = [initialStoredHeader];
|
|
78
|
+
for (let blockHeader of syncedHeaders) {
|
|
79
|
+
computedCommitedHeaders.push(computedCommitedHeaders[computedCommitedHeaders.length - 1].computeNext(blockHeader));
|
|
80
|
+
}
|
|
81
|
+
return computedCommitedHeaders;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* A common logic for submitting blockheaders in a transaction
|
|
85
|
+
*
|
|
86
|
+
* @param signer
|
|
87
|
+
* @param headers headers to sync to the btc relay
|
|
88
|
+
* @param storedHeader current latest stored block header for a given fork
|
|
89
|
+
* @param tipWork work of the current tip in a given fork
|
|
90
|
+
* @param forkId forkId to submit to, forkId=0 means main chain, forkId=-1 means short fork
|
|
91
|
+
* @param feeRate feeRate for the transaction
|
|
92
|
+
* @private
|
|
93
|
+
*/
|
|
94
|
+
async _saveHeaders(signer, headers, storedHeader, tipWork, forkId, feeRate) {
|
|
95
|
+
const blockHeaderObj = headers.map(serializeBlockHeader);
|
|
96
|
+
let starknetAction;
|
|
97
|
+
switch (forkId) {
|
|
98
|
+
case -1:
|
|
99
|
+
starknetAction = this.SaveShortForkHeaders(signer, blockHeaderObj, storedHeader);
|
|
100
|
+
break;
|
|
101
|
+
case 0:
|
|
102
|
+
starknetAction = this.SaveMainHeaders(signer, blockHeaderObj, storedHeader);
|
|
103
|
+
break;
|
|
104
|
+
default:
|
|
105
|
+
starknetAction = this.SaveLongForkHeaders(signer, forkId, blockHeaderObj, storedHeader);
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
const tx = await starknetAction.tx(feeRate);
|
|
109
|
+
const computedCommitedHeaders = this.computeCommitedHeaders(storedHeader, blockHeaderObj);
|
|
110
|
+
const lastStoredHeader = computedCommitedHeaders[computedCommitedHeaders.length - 1];
|
|
111
|
+
if (forkId !== 0 && base_1.StatePredictorUtils.gtBuffer(lastStoredHeader.getBlockHash(), tipWork)) {
|
|
112
|
+
//Fork's work is higher than main chain's work, this fork will become a main chain
|
|
113
|
+
forkId = 0;
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
forkId: forkId,
|
|
117
|
+
lastStoredHeader,
|
|
118
|
+
tx,
|
|
119
|
+
computedCommitedHeaders
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
getBlock(commitHash, blockHash) {
|
|
123
|
+
const keys = [commitHash == null ? null : (0, Utils_1.toHex)(commitHash)];
|
|
124
|
+
if (blockHash != null) {
|
|
125
|
+
const starknetBlockHash = starknet_1.hash.computePoseidonHashOnElements((0, Utils_1.bufferToU32Array)(buffer_1.Buffer.from([...blockHash]).reverse()));
|
|
126
|
+
keys.push(starknetBlockHash);
|
|
127
|
+
}
|
|
128
|
+
return this.Events.findInContractEvents(["btc_relay::events::StoreHeader", "btc_relay::events::StoreForkHeader"], keys, (event) => {
|
|
129
|
+
return Promise.resolve([StarknetBtcStoredHeader_1.StarknetBtcStoredHeader.fromSerializedFeltArray(event.data), BigInt(event.params.commit_hash)]);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
async getBlockHeight() {
|
|
133
|
+
return Number(await this.contract.get_blockheight());
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Returns data about current main chain tip stored in the btc relay
|
|
137
|
+
*/
|
|
138
|
+
async getTipData() {
|
|
139
|
+
const commitHash = await this.contract.get_tip_commit_hash();
|
|
140
|
+
if (commitHash == null || BigInt(commitHash) === BigInt(0))
|
|
141
|
+
return null;
|
|
142
|
+
const result = await this.getBlock(commitHash);
|
|
143
|
+
if (result == null)
|
|
144
|
+
return null;
|
|
145
|
+
const [storedBlockHeader] = result;
|
|
146
|
+
return {
|
|
147
|
+
blockheight: storedBlockHeader.getBlockheight(),
|
|
148
|
+
commitHash: (0, Utils_1.bigNumberishToBuffer)(commitHash, 32).toString("hex"),
|
|
149
|
+
blockhash: storedBlockHeader.getBlockHash().toString("hex"),
|
|
150
|
+
chainWork: storedBlockHeader.getChainWork()
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Retrieves blockheader with a specific blockhash, returns null if requiredBlockheight is provided and
|
|
155
|
+
* btc relay contract is not synced up to the desired blockheight
|
|
156
|
+
*
|
|
157
|
+
* @param blockData
|
|
158
|
+
* @param requiredBlockheight
|
|
159
|
+
*/
|
|
160
|
+
async retrieveLogAndBlockheight(blockData, requiredBlockheight) {
|
|
161
|
+
//TODO: we can fetch the blockheight and events in parallel
|
|
162
|
+
const blockHeight = await this.getBlockHeight();
|
|
163
|
+
if (requiredBlockheight != null && blockHeight < requiredBlockheight) {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
const result = await this.getBlock(null, buffer_1.Buffer.from(blockData.blockhash, "hex"));
|
|
167
|
+
if (result == null)
|
|
168
|
+
return null;
|
|
169
|
+
const [storedBlockHeader, commitHash] = result;
|
|
170
|
+
//Check if block is part of the main chain
|
|
171
|
+
const chainCommitment = await this.contract.get_commit_hash(storedBlockHeader.block_height);
|
|
172
|
+
if (BigInt(chainCommitment) !== BigInt(commitHash))
|
|
173
|
+
return null;
|
|
174
|
+
this.logger.debug("retrieveLogAndBlockheight(): block found," +
|
|
175
|
+
" commit hash: " + (0, Utils_1.toHex)(commitHash) + " blockhash: " + blockData.blockhash + " current btc relay height: " + blockHeight);
|
|
176
|
+
return { header: storedBlockHeader, height: blockHeight };
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Retrieves blockheader data by blockheader's commit hash,
|
|
180
|
+
*
|
|
181
|
+
* @param commitmentHashStr
|
|
182
|
+
* @param blockData
|
|
183
|
+
*/
|
|
184
|
+
async retrieveLogByCommitHash(commitmentHashStr, blockData) {
|
|
185
|
+
const result = await this.getBlock(commitmentHashStr, buffer_1.Buffer.from(blockData.blockhash, "hex"));
|
|
186
|
+
if (result == null)
|
|
187
|
+
return null;
|
|
188
|
+
const [storedBlockHeader, commitHash] = result;
|
|
189
|
+
//Check if block is part of the main chain
|
|
190
|
+
const chainCommitment = await this.contract.get_commit_hash(storedBlockHeader.block_height);
|
|
191
|
+
if (BigInt(chainCommitment) !== BigInt(commitHash))
|
|
192
|
+
return null;
|
|
193
|
+
this.logger.debug("retrieveLogByCommitHash(): block found," +
|
|
194
|
+
" commit hash: " + commitmentHashStr + " blockhash: " + blockData.blockhash + " height: " + storedBlockHeader.block_height);
|
|
195
|
+
return storedBlockHeader;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Retrieves latest known stored blockheader & blockheader from bitcoin RPC that is in the main chain
|
|
199
|
+
*/
|
|
200
|
+
async retrieveLatestKnownBlockLog() {
|
|
201
|
+
const data = await this.Events.findInContractEvents(["btc_relay::events::StoreHeader", "btc_relay::events::StoreForkHeader"], null, async (event) => {
|
|
202
|
+
const storedHeader = StarknetBtcStoredHeader_1.StarknetBtcStoredHeader.fromSerializedFeltArray(event.data);
|
|
203
|
+
const blockHashHex = storedHeader.getBlockHash().toString("hex");
|
|
204
|
+
const commitHash = event.params.commit_hash;
|
|
205
|
+
const [isInBtcMainChain, btcRelayCommitHash] = await Promise.all([
|
|
206
|
+
this.bitcoinRpc.isInMainChain(blockHashHex).catch(() => false),
|
|
207
|
+
this.contract.get_commit_hash(storedHeader.block_height)
|
|
208
|
+
]);
|
|
209
|
+
if (!isInBtcMainChain)
|
|
210
|
+
return null;
|
|
211
|
+
if (BigInt(commitHash) !== BigInt(btcRelayCommitHash))
|
|
212
|
+
return null;
|
|
213
|
+
return {
|
|
214
|
+
resultStoredHeader: storedHeader,
|
|
215
|
+
resultBitcoinHeader: await this.bitcoinRpc.getBlockHeader(blockHashHex),
|
|
216
|
+
commitHash: commitHash
|
|
217
|
+
};
|
|
218
|
+
});
|
|
219
|
+
if (data != null)
|
|
220
|
+
this.logger.debug("retrieveLatestKnownBlockLog(): block found," +
|
|
221
|
+
" commit hash: " + (0, Utils_1.toHex)(data.commitHash) + " blockhash: " + data.resultBitcoinHeader.getHash() +
|
|
222
|
+
" height: " + data.resultStoredHeader.getBlockheight());
|
|
223
|
+
return data;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Saves blockheaders as a bitcoin main chain to the btc relay
|
|
227
|
+
*
|
|
228
|
+
* @param signer
|
|
229
|
+
* @param mainHeaders
|
|
230
|
+
* @param storedHeader
|
|
231
|
+
* @param feeRate
|
|
232
|
+
*/
|
|
233
|
+
saveMainHeaders(signer, mainHeaders, storedHeader, feeRate) {
|
|
234
|
+
this.logger.debug("saveMainHeaders(): submitting main blockheaders, count: " + mainHeaders.length);
|
|
235
|
+
return this._saveHeaders(signer, mainHeaders, storedHeader, null, 0, feeRate);
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Creates a new long fork and submits the headers to it
|
|
239
|
+
*
|
|
240
|
+
* @param signer
|
|
241
|
+
* @param forkHeaders
|
|
242
|
+
* @param storedHeader
|
|
243
|
+
* @param tipWork
|
|
244
|
+
* @param feeRate
|
|
245
|
+
*/
|
|
246
|
+
async saveNewForkHeaders(signer, forkHeaders, storedHeader, tipWork, feeRate) {
|
|
247
|
+
let forkId = Math.floor(Math.random() * 0xFFFFFFFFFFFF);
|
|
248
|
+
this.logger.debug("saveNewForkHeaders(): submitting new fork & blockheaders," +
|
|
249
|
+
" count: " + forkHeaders.length + " forkId: 0x" + forkId.toString(16));
|
|
250
|
+
return await this._saveHeaders(signer, forkHeaders, storedHeader, tipWork, forkId, feeRate);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Continues submitting blockheaders to a given fork
|
|
254
|
+
*
|
|
255
|
+
* @param signer
|
|
256
|
+
* @param forkHeaders
|
|
257
|
+
* @param storedHeader
|
|
258
|
+
* @param forkId
|
|
259
|
+
* @param tipWork
|
|
260
|
+
* @param feeRate
|
|
261
|
+
*/
|
|
262
|
+
saveForkHeaders(signer, forkHeaders, storedHeader, forkId, tipWork, feeRate) {
|
|
263
|
+
this.logger.debug("saveForkHeaders(): submitting blockheaders to existing fork," +
|
|
264
|
+
" count: " + forkHeaders.length + " forkId: 0x" + forkId.toString(16));
|
|
265
|
+
return this._saveHeaders(signer, forkHeaders, storedHeader, tipWork, forkId, feeRate);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Submits short fork with given blockheaders
|
|
269
|
+
*
|
|
270
|
+
* @param signer
|
|
271
|
+
* @param forkHeaders
|
|
272
|
+
* @param storedHeader
|
|
273
|
+
* @param tipWork
|
|
274
|
+
* @param feeRate
|
|
275
|
+
*/
|
|
276
|
+
saveShortForkHeaders(signer, forkHeaders, storedHeader, tipWork, feeRate) {
|
|
277
|
+
this.logger.debug("saveShortForkHeaders(): submitting short fork blockheaders," +
|
|
278
|
+
" count: " + forkHeaders.length);
|
|
279
|
+
return this._saveHeaders(signer, forkHeaders, storedHeader, tipWork, -1, feeRate);
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Estimate required synchronization fee (worst case) to synchronize btc relay to the required blockheight
|
|
283
|
+
*
|
|
284
|
+
* @param requiredBlockheight
|
|
285
|
+
* @param feeRate
|
|
286
|
+
*/
|
|
287
|
+
async estimateSynchronizeFee(requiredBlockheight, feeRate) {
|
|
288
|
+
const tipData = await this.getTipData();
|
|
289
|
+
const currBlockheight = tipData.blockheight;
|
|
290
|
+
const blockheightDelta = requiredBlockheight - currBlockheight;
|
|
291
|
+
if (blockheightDelta <= 0)
|
|
292
|
+
return 0n;
|
|
293
|
+
const synchronizationFee = BigInt(blockheightDelta) * await this.getFeePerBlock(feeRate);
|
|
294
|
+
this.logger.debug("estimateSynchronizeFee(): required blockheight: " + requiredBlockheight +
|
|
295
|
+
" blockheight delta: " + blockheightDelta + " fee: " + synchronizationFee.toString(10));
|
|
296
|
+
return synchronizationFee;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Returns fee required (in SOL) to synchronize a single block to btc relay
|
|
300
|
+
*
|
|
301
|
+
* @param feeRate
|
|
302
|
+
*/
|
|
303
|
+
async getFeePerBlock(feeRate) {
|
|
304
|
+
feeRate ?? (feeRate = await this.Fees.getFeeRate());
|
|
305
|
+
return StarknetFees_1.StarknetFees.getGasFee(GAS_PER_BLOCKHEADER, feeRate);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Gets fee rate required for submitting blockheaders to the main chain
|
|
309
|
+
*/
|
|
310
|
+
getMainFeeRate(signer) {
|
|
311
|
+
return this.Fees.getFeeRate();
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Gets fee rate required for submitting blockheaders to the specific fork
|
|
315
|
+
*/
|
|
316
|
+
getForkFeeRate(signer, forkId) {
|
|
317
|
+
return this.Fees.getFeeRate();
|
|
318
|
+
}
|
|
319
|
+
saveInitialHeader(signer, header, epochStart, pastBlocksTimestamps, feeRate) {
|
|
320
|
+
throw new Error("Not supported, starknet contract is initialized with constructor!");
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
exports.StarknetBtcRelay = StarknetBtcRelay;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { BtcHeader } from "@atomiqlabs/base";
|
|
3
|
+
import { Buffer } from "buffer";
|
|
4
|
+
import { BigNumberish } from "starknet";
|
|
5
|
+
export type StarknetBtcHeaderType = {
|
|
6
|
+
reversed_version: BigNumberish;
|
|
7
|
+
previous_blockhash: BigNumberish[];
|
|
8
|
+
merkle_root: BigNumberish[];
|
|
9
|
+
reversed_timestamp: BigNumberish;
|
|
10
|
+
nbits: BigNumberish;
|
|
11
|
+
nonce: BigNumberish;
|
|
12
|
+
hash?: Buffer;
|
|
13
|
+
};
|
|
14
|
+
export declare class StarknetBtcHeader implements BtcHeader {
|
|
15
|
+
reversed_version: number;
|
|
16
|
+
previous_blockhash: number[];
|
|
17
|
+
merkle_root: number[];
|
|
18
|
+
reversed_timestamp: number;
|
|
19
|
+
nbits: number;
|
|
20
|
+
nonce: number;
|
|
21
|
+
hash?: Buffer;
|
|
22
|
+
constructor(obj: StarknetBtcHeaderType);
|
|
23
|
+
getMerkleRoot(): Buffer;
|
|
24
|
+
getNbits(): number;
|
|
25
|
+
getNonce(): number;
|
|
26
|
+
getReversedPrevBlockhash(): Buffer;
|
|
27
|
+
getTimestamp(): number;
|
|
28
|
+
getVersion(): number;
|
|
29
|
+
getHash(): Buffer;
|
|
30
|
+
serialize(): BigNumberish[];
|
|
31
|
+
static fromSerializedFeltArray(span: BigNumberish[]): StarknetBtcHeader;
|
|
32
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StarknetBtcHeader = void 0;
|
|
4
|
+
const buffer_1 = require("buffer");
|
|
5
|
+
const Utils_1 = require("../../../utils/Utils");
|
|
6
|
+
const createHash = require("create-hash");
|
|
7
|
+
class StarknetBtcHeader {
|
|
8
|
+
constructor(obj) {
|
|
9
|
+
this.reversed_version = Number(obj.reversed_version);
|
|
10
|
+
this.previous_blockhash = obj.previous_blockhash.map(val => Number(val));
|
|
11
|
+
this.merkle_root = obj.merkle_root.map(val => Number(val));
|
|
12
|
+
this.reversed_timestamp = Number(obj.reversed_timestamp);
|
|
13
|
+
this.nbits = Number(obj.nbits);
|
|
14
|
+
this.nonce = Number(obj.nonce);
|
|
15
|
+
this.hash = obj.hash;
|
|
16
|
+
}
|
|
17
|
+
getMerkleRoot() {
|
|
18
|
+
return (0, Utils_1.u32ArrayToBuffer)(this.merkle_root);
|
|
19
|
+
}
|
|
20
|
+
getNbits() {
|
|
21
|
+
return (0, Utils_1.u32ReverseEndianness)(this.nbits);
|
|
22
|
+
}
|
|
23
|
+
getNonce() {
|
|
24
|
+
return (0, Utils_1.u32ReverseEndianness)(this.nonce);
|
|
25
|
+
}
|
|
26
|
+
getReversedPrevBlockhash() {
|
|
27
|
+
return (0, Utils_1.u32ArrayToBuffer)(this.previous_blockhash);
|
|
28
|
+
}
|
|
29
|
+
getTimestamp() {
|
|
30
|
+
return (0, Utils_1.u32ReverseEndianness)(this.reversed_timestamp);
|
|
31
|
+
}
|
|
32
|
+
getVersion() {
|
|
33
|
+
return (0, Utils_1.u32ReverseEndianness)(this.reversed_version);
|
|
34
|
+
}
|
|
35
|
+
getHash() {
|
|
36
|
+
if (this.hash != null)
|
|
37
|
+
return this.hash;
|
|
38
|
+
const buffer = buffer_1.Buffer.alloc(80);
|
|
39
|
+
buffer.writeUInt32BE(this.reversed_version);
|
|
40
|
+
(0, Utils_1.u32ArrayToBuffer)(this.previous_blockhash).copy(buffer, 4);
|
|
41
|
+
(0, Utils_1.u32ArrayToBuffer)(this.merkle_root).copy(buffer, 36);
|
|
42
|
+
buffer.writeUInt32BE(this.reversed_timestamp, 68);
|
|
43
|
+
buffer.writeUInt32BE(this.nbits, 72);
|
|
44
|
+
buffer.writeUInt32BE(this.nonce, 76);
|
|
45
|
+
return createHash("sha256").update(createHash("sha256").update(buffer).digest()).digest();
|
|
46
|
+
}
|
|
47
|
+
serialize() {
|
|
48
|
+
return [
|
|
49
|
+
this.reversed_version,
|
|
50
|
+
...this.previous_blockhash,
|
|
51
|
+
...this.merkle_root,
|
|
52
|
+
this.reversed_timestamp,
|
|
53
|
+
this.nbits,
|
|
54
|
+
this.nonce
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
static fromSerializedFeltArray(span) {
|
|
58
|
+
const reversed_version = (0, Utils_1.toHex)(span.shift());
|
|
59
|
+
const previous_blockhash = span.splice(0, 8).map(Utils_1.toHex);
|
|
60
|
+
const merkle_root = span.splice(0, 8).map(Utils_1.toHex);
|
|
61
|
+
const reversed_timestamp = (0, Utils_1.toHex)(span.shift());
|
|
62
|
+
const nbits = (0, Utils_1.toHex)(span.shift());
|
|
63
|
+
const nonce = (0, Utils_1.toHex)(span.shift());
|
|
64
|
+
return new StarknetBtcHeader({
|
|
65
|
+
reversed_version,
|
|
66
|
+
previous_blockhash,
|
|
67
|
+
merkle_root,
|
|
68
|
+
reversed_timestamp,
|
|
69
|
+
nbits,
|
|
70
|
+
nonce
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
exports.StarknetBtcHeader = StarknetBtcHeader;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { BtcStoredHeader } from "@atomiqlabs/base";
|
|
3
|
+
import { StarknetBtcHeader, StarknetBtcHeaderType } from "./StarknetBtcHeader";
|
|
4
|
+
import { Buffer } from "buffer";
|
|
5
|
+
import { BigNumberish, Uint256 } from "starknet";
|
|
6
|
+
export type StarknetBtcStoredHeaderType = {
|
|
7
|
+
blockheader: StarknetBtcHeader | StarknetBtcHeaderType;
|
|
8
|
+
block_hash: BigNumberish[];
|
|
9
|
+
chain_work: BigNumberish | Uint256;
|
|
10
|
+
block_height: BigNumberish;
|
|
11
|
+
last_diff_adjustment: BigNumberish;
|
|
12
|
+
prev_block_timestamps: BigNumberish[];
|
|
13
|
+
};
|
|
14
|
+
export declare class StarknetBtcStoredHeader implements BtcStoredHeader<StarknetBtcHeader> {
|
|
15
|
+
blockheader: StarknetBtcHeader;
|
|
16
|
+
block_hash: number[];
|
|
17
|
+
chain_work: Uint256;
|
|
18
|
+
block_height: number;
|
|
19
|
+
last_diff_adjustment: number;
|
|
20
|
+
prev_block_timestamps: number[];
|
|
21
|
+
constructor(obj: StarknetBtcStoredHeaderType);
|
|
22
|
+
getBlockheight(): number;
|
|
23
|
+
getChainWork(): Buffer;
|
|
24
|
+
getHeader(): StarknetBtcHeader;
|
|
25
|
+
getLastDiffAdjustment(): number;
|
|
26
|
+
getPrevBlockTimestamps(): number[];
|
|
27
|
+
getBlockHash(): Buffer;
|
|
28
|
+
/**
|
|
29
|
+
* Computes prevBlockTimestamps for a next block, shifting the old block timestamps to the left & appending
|
|
30
|
+
* this block's timestamp to the end
|
|
31
|
+
*
|
|
32
|
+
* @private
|
|
33
|
+
*/
|
|
34
|
+
private computeNextBlockTimestamps;
|
|
35
|
+
/**
|
|
36
|
+
* Computes total chain work after a new header with "nbits" is added to the chain
|
|
37
|
+
*
|
|
38
|
+
* @param nbits
|
|
39
|
+
* @private
|
|
40
|
+
*/
|
|
41
|
+
private computeNextChainWork;
|
|
42
|
+
/**
|
|
43
|
+
* Computes lastDiffAdjustment, this changes only once every DIFF_ADJUSTMENT_PERIOD blocks
|
|
44
|
+
*
|
|
45
|
+
* @param headerTimestamp
|
|
46
|
+
* @private
|
|
47
|
+
*/
|
|
48
|
+
private computeNextLastDiffAdjustment;
|
|
49
|
+
computeNext(header: StarknetBtcHeader): StarknetBtcStoredHeader;
|
|
50
|
+
serialize(): BigNumberish[];
|
|
51
|
+
static fromSerializedFeltArray(span: BigNumberish[]): StarknetBtcStoredHeader;
|
|
52
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StarknetBtcStoredHeader = void 0;
|
|
4
|
+
const base_1 = require("@atomiqlabs/base");
|
|
5
|
+
const StarknetBtcHeader_1 = require("./StarknetBtcHeader");
|
|
6
|
+
const buffer_1 = require("buffer");
|
|
7
|
+
const starknet_1 = require("starknet");
|
|
8
|
+
const Utils_1 = require("../../../utils/Utils");
|
|
9
|
+
class StarknetBtcStoredHeader {
|
|
10
|
+
constructor(obj) {
|
|
11
|
+
this.blockheader = obj.blockheader instanceof StarknetBtcHeader_1.StarknetBtcHeader ? obj.blockheader : new StarknetBtcHeader_1.StarknetBtcHeader(obj.blockheader);
|
|
12
|
+
this.block_hash = obj.block_hash.map(val => Number(val));
|
|
13
|
+
this.chain_work = (0, Utils_1.isUint256)(obj.chain_work) ? obj.chain_work : starknet_1.cairo.uint256(obj.chain_work);
|
|
14
|
+
this.block_height = Number(obj.block_height);
|
|
15
|
+
this.last_diff_adjustment = Number(obj.last_diff_adjustment);
|
|
16
|
+
this.prev_block_timestamps = obj.prev_block_timestamps.map(val => Number(val));
|
|
17
|
+
}
|
|
18
|
+
getBlockheight() {
|
|
19
|
+
return this.block_height;
|
|
20
|
+
}
|
|
21
|
+
getChainWork() {
|
|
22
|
+
return (0, Utils_1.bigNumberishToBuffer)(this.chain_work, 32);
|
|
23
|
+
}
|
|
24
|
+
getHeader() {
|
|
25
|
+
return this.blockheader;
|
|
26
|
+
}
|
|
27
|
+
getLastDiffAdjustment() {
|
|
28
|
+
return this.last_diff_adjustment;
|
|
29
|
+
}
|
|
30
|
+
getPrevBlockTimestamps() {
|
|
31
|
+
return this.prev_block_timestamps;
|
|
32
|
+
}
|
|
33
|
+
getBlockHash() {
|
|
34
|
+
return (0, Utils_1.u32ArrayToBuffer)(this.block_hash).reverse();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Computes prevBlockTimestamps for a next block, shifting the old block timestamps to the left & appending
|
|
38
|
+
* this block's timestamp to the end
|
|
39
|
+
*
|
|
40
|
+
* @private
|
|
41
|
+
*/
|
|
42
|
+
computeNextBlockTimestamps() {
|
|
43
|
+
const prevBlockTimestamps = [...this.prev_block_timestamps];
|
|
44
|
+
for (let i = 1; i < 10; i++) {
|
|
45
|
+
prevBlockTimestamps[i - 1] = prevBlockTimestamps[i];
|
|
46
|
+
}
|
|
47
|
+
prevBlockTimestamps[9] = this.blockheader.getTimestamp();
|
|
48
|
+
return prevBlockTimestamps;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Computes total chain work after a new header with "nbits" is added to the chain
|
|
52
|
+
*
|
|
53
|
+
* @param nbits
|
|
54
|
+
* @private
|
|
55
|
+
*/
|
|
56
|
+
computeNextChainWork(nbits) {
|
|
57
|
+
const chainWork = [...this.getChainWork()];
|
|
58
|
+
base_1.StatePredictorUtils.addInPlace(chainWork, [...base_1.StatePredictorUtils.getChainwork(nbits)]);
|
|
59
|
+
return buffer_1.Buffer.from(chainWork);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Computes lastDiffAdjustment, this changes only once every DIFF_ADJUSTMENT_PERIOD blocks
|
|
63
|
+
*
|
|
64
|
+
* @param headerTimestamp
|
|
65
|
+
* @private
|
|
66
|
+
*/
|
|
67
|
+
computeNextLastDiffAdjustment(headerTimestamp) {
|
|
68
|
+
const blockheight = this.block_height + 1;
|
|
69
|
+
let lastDiffAdjustment = this.last_diff_adjustment;
|
|
70
|
+
if (blockheight % base_1.StatePredictorUtils.DIFF_ADJUSTMENT_PERIOD === 0) {
|
|
71
|
+
lastDiffAdjustment = headerTimestamp;
|
|
72
|
+
}
|
|
73
|
+
return lastDiffAdjustment;
|
|
74
|
+
}
|
|
75
|
+
computeNext(header) {
|
|
76
|
+
return new StarknetBtcStoredHeader({
|
|
77
|
+
chain_work: "0x" + this.computeNextChainWork(header.getNbits()).toString("hex"),
|
|
78
|
+
prev_block_timestamps: this.computeNextBlockTimestamps(),
|
|
79
|
+
block_height: this.block_height + 1,
|
|
80
|
+
last_diff_adjustment: this.computeNextLastDiffAdjustment(header.getTimestamp()),
|
|
81
|
+
block_hash: (0, Utils_1.bufferToU32Array)(header.getHash()),
|
|
82
|
+
blockheader: header
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
serialize() {
|
|
86
|
+
return [
|
|
87
|
+
...this.blockheader.serialize(),
|
|
88
|
+
...this.block_hash,
|
|
89
|
+
this.chain_work.low,
|
|
90
|
+
this.chain_work.high,
|
|
91
|
+
this.block_height,
|
|
92
|
+
this.last_diff_adjustment,
|
|
93
|
+
...this.prev_block_timestamps
|
|
94
|
+
];
|
|
95
|
+
}
|
|
96
|
+
static fromSerializedFeltArray(span) {
|
|
97
|
+
const blockheader = StarknetBtcHeader_1.StarknetBtcHeader.fromSerializedFeltArray(span);
|
|
98
|
+
const block_hash = span.splice(0, 8).map(Utils_1.toHex);
|
|
99
|
+
const chain_work = { low: span.shift(), high: span.shift() };
|
|
100
|
+
const block_height = (0, Utils_1.toHex)(span.shift());
|
|
101
|
+
const last_diff_adjustment = (0, Utils_1.toHex)(span.shift());
|
|
102
|
+
const prev_block_timestamps = span.splice(0, 10).map(Utils_1.toHex);
|
|
103
|
+
return new StarknetBtcStoredHeader({
|
|
104
|
+
blockheader,
|
|
105
|
+
block_hash,
|
|
106
|
+
chain_work,
|
|
107
|
+
block_height,
|
|
108
|
+
last_diff_adjustment,
|
|
109
|
+
prev_block_timestamps
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exports.StarknetBtcStoredHeader = StarknetBtcStoredHeader;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { StarknetBase, StarknetRetryPolicy } from "../base/StarknetBase";
|
|
2
|
+
import { constants, Provider, TypedContractV2 } from "starknet";
|
|
3
|
+
import { StarknetFees } from "../base/modules/StarknetFees";
|
|
4
|
+
import { Abi } from "abi-wan-kanabi";
|
|
5
|
+
import { StarknetContractEvents } from "./modules/StarknetContractEvents";
|
|
6
|
+
/**
|
|
7
|
+
* Base class providing program specific utilities
|
|
8
|
+
*/
|
|
9
|
+
export declare class StarknetContractBase<T extends Abi> extends StarknetBase {
|
|
10
|
+
contract: TypedContractV2<T>;
|
|
11
|
+
readonly Events: StarknetContractEvents<T>;
|
|
12
|
+
constructor(chainId: constants.StarknetChainId, provider: Provider, contractAddress: string, contractAbi: T, retryPolicy?: StarknetRetryPolicy, solanaFeeEstimator?: StarknetFees);
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StarknetContractBase = void 0;
|
|
4
|
+
const StarknetBase_1 = require("../base/StarknetBase");
|
|
5
|
+
const starknet_1 = require("starknet");
|
|
6
|
+
const StarknetFees_1 = require("../base/modules/StarknetFees");
|
|
7
|
+
const StarknetContractEvents_1 = require("./modules/StarknetContractEvents");
|
|
8
|
+
/**
|
|
9
|
+
* Base class providing program specific utilities
|
|
10
|
+
*/
|
|
11
|
+
class StarknetContractBase extends StarknetBase_1.StarknetBase {
|
|
12
|
+
constructor(chainId, provider, contractAddress, contractAbi, retryPolicy, solanaFeeEstimator = new StarknetFees_1.StarknetFees(provider)) {
|
|
13
|
+
super(chainId, provider, retryPolicy, solanaFeeEstimator);
|
|
14
|
+
this.contract = new starknet_1.Contract(contractAbi, contractAddress, provider).typedv2(contractAbi);
|
|
15
|
+
this.Events = new StarknetContractEvents_1.StarknetContractEvents(this, contractAbi);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.StarknetContractBase = StarknetContractBase;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Abi } from "abi-wan-kanabi";
|
|
2
|
+
import { EventToPrimitiveType, ExtractAbiEventNames } from "abi-wan-kanabi/dist/kanabi";
|
|
3
|
+
import { StarknetEvents } from "../../base/modules/StarknetEvents";
|
|
4
|
+
import { StarknetContractBase } from "../StarknetContractBase";
|
|
5
|
+
export type StarknetAbiEvent<TAbi extends Abi, TEventName extends ExtractAbiEventNames<TAbi>> = {
|
|
6
|
+
name: TEventName;
|
|
7
|
+
params: EventToPrimitiveType<TAbi, TEventName>;
|
|
8
|
+
txHash: string;
|
|
9
|
+
blockHash: string;
|
|
10
|
+
blockNumber: number;
|
|
11
|
+
keys: string[];
|
|
12
|
+
data: string[];
|
|
13
|
+
};
|
|
14
|
+
export declare class StarknetContractEvents<TAbi extends Abi> extends StarknetEvents {
|
|
15
|
+
readonly root: StarknetContractBase<TAbi>;
|
|
16
|
+
readonly abi: TAbi;
|
|
17
|
+
constructor(root: StarknetContractBase<TAbi>, abi: TAbi);
|
|
18
|
+
private toStarknetAbiEvents;
|
|
19
|
+
private toFilter;
|
|
20
|
+
/**
|
|
21
|
+
* Returns the events occuring in a range of starknet block as identified by the contract and keys,
|
|
22
|
+
* returns pending events if no startHeight & endHeight is passed
|
|
23
|
+
*
|
|
24
|
+
* @param events
|
|
25
|
+
* @param keys
|
|
26
|
+
* @param startBlockHeight
|
|
27
|
+
* @param endBlockHeight
|
|
28
|
+
*/
|
|
29
|
+
getContractBlockEvents<T extends ExtractAbiEventNames<TAbi>>(events: T[], keys: string[], startBlockHeight?: number, endBlockHeight?: number): Promise<StarknetAbiEvent<TAbi, T>[]>;
|
|
30
|
+
/**
|
|
31
|
+
* Runs a search forawrds in time, processing the events for a specific topic public key
|
|
32
|
+
*
|
|
33
|
+
* @param events
|
|
34
|
+
* @param keys
|
|
35
|
+
* @param processor called for every event, should return a value if the correct event was found, or null
|
|
36
|
+
* if the search should continue
|
|
37
|
+
* @param abortSignal
|
|
38
|
+
*/
|
|
39
|
+
findInContractEvents<T, TEvent extends ExtractAbiEventNames<TAbi>>(events: TEvent[], keys: string[], processor: (event: StarknetAbiEvent<TAbi, TEvent>) => Promise<T>, abortSignal?: AbortSignal): Promise<T>;
|
|
40
|
+
}
|