UNPKG

@unruggable/gateways

Version:

Trustless Ethereum Multichain CCIP-Read Gateway

105 lines (104 loc) 4.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StarknetRollup = void 0; const abi_1 = require("ethers/abi"); const chains_js_1 = require("../chains.cjs"); const rollup_js_1 = require("../rollup.cjs"); const StarknetProver_js_1 = require("./StarknetProver.cjs"); const contract_1 = require("ethers/contract"); const utils_js_1 = require("../utils.cjs"); const EthProver_js_1 = require("../eth/EthProver.cjs"); const rlp_js_1 = require("../rlp.cjs"); const utils_1 = require("ethers/utils"); const hash_1 = require("ethers/hash"); const CORE_ABI = new abi_1.Interface([ `function stateRoot() view returns (bytes32)`, `function stateBlockNumber() view returns (uint256)`, `function updateStateKzgDA(uint256[] programOutput, bytes[] kzgProofs)`, `event LogStateUpdate(uint256 globalRoot, int256 blockNumber, uint256 blockHash)`, ]); const SLOT_STATE_ROOT = BigInt((0, hash_1.id)('STARKNET_1.0_INIT_STARKNET_STATE_STRUCT')); class StarknetRollup extends rollup_js_1.AbstractRollup { // https://docs.starknet.io/tools/important-addresses/ static mainnetConfig = { chain1: chains_js_1.CHAINS.MAINNET, chain2: chains_js_1.CHAINS.STARKNET, Rollup: '0xc662c410C0ECf747543f5bA90660f6ABeBD9C8c4', }; static sepoliaConfig = { chain1: chains_js_1.CHAINS.SEPOLIA, chain2: chains_js_1.CHAINS.SCROLL_SEPOLIA, Rollup: '0xE2Bb56ee936fd6433DC0F6e7e3b8365C906AA057', }; Rollup; constructor(providers, config) { super(providers); this.Rollup = new contract_1.Contract(config.Rollup, CORE_ABI, this.provider1); } async findStateUpdate(l2BlockNumber) { loop: for (let block = await this.provider1.getBlockNumber(); block >= 0; block -= this.getLogsStepSize) { const events = await this.Rollup.queryFilter(this.Rollup.filters.LogStateUpdate(), Math.max(0, block - this.getLogsStepSize), block); for (let i = events.length - 1; i >= 0; i--) { const event = events[i]; const bn = BigInt((0, utils_1.dataSlice)(event.data, 32, 64)); if (bn === l2BlockNumber) return event; if (bn < l2BlockNumber) break loop; } } throw new Error(`not finalized: ${l2BlockNumber}`); } fetchLatestCommitIndex() { return this.Rollup.stateBlockNumber({ blockTag: this.latestBlockTag, }); } async _fetchParentCommitIndex(commit) { const tx = await this.provider1.getTransaction(commit.commitTx); if (!tx) throw new Error(`no commit: ${commit.commitTx}`); const desc = this.Rollup.interface.parseTransaction(tx); if (!desc || desc.name !== 'updateStateKzgDA') { throw new Error(`expected updateStateKzgDA: ${tx}`); } return desc.args.programOutput[2]; // prev blockNumber } async _fetchCommit(index) { const event = await this.findStateUpdate(index); // const [event] = await this.Rollup.queryFilter( // this.Rollup.filters.LogStateUpdate(null, index, null) // ); // if (!event) throw new Error(`not finalized`); const prover1 = new EthProver_js_1.EthProver(this.provider1, event.blockNumber); const [block, proof] = await Promise.all([ prover1.fetchBlock(), prover1.fetchProofs(await this.Rollup.getAddress(), [SLOT_STATE_ROOT]), ]); const prover = new StarknetProver_js_1.StarknetProver(this.provider2, Number(index)); return { index, prover, commitTx: event.transactionHash, rlpEncodedL1Block: (0, rlp_js_1.encodeRlpBlock)(block), accountProof: EthProver_js_1.EthProver.encodeProof(proof.accountProof), storageProof: EthProver_js_1.EthProver.encodeProof(proof.storageProof[0].proof), }; } encodeWitness(commit, proofSeq) { return utils_js_1.ABI_CODER.encode(['(uint256, bytes, bytes, bytes, bytes[], bytes)'], [ commit.index, commit.rlpEncodedL1Block, commit.accountProof, commit.storageProof, proofSeq.proofs, proofSeq.order, ]); } windowFromSec(_sec) { // finalization is not onchain // TODO: fix me return 69420; } } exports.StarknetRollup = StarknetRollup;