diff --git a/packages/common/src/logger.ts b/packages/common/src/logger.ts index 54055ed2..428f4b6d 100644 --- a/packages/common/src/logger.ts +++ b/packages/common/src/logger.ts @@ -17,7 +17,7 @@ const logger = winston.createLogger({ winston.format.timestamp(), winston.format.printf(({ timestamp, level, message, service }) => { const colorize = winston.format.colorize() - return `${timestamp} [${level}] ${colorize.colorize("service", `${service}`)}: ${message}` + return `${timestamp} [${level}] ${service ? colorize.colorize("service", `${service}`) : ''}: ${message}` }), ), transports: [new winston.transports.Console(), new winston.transports.File({ filename: "./logs/application.log" })], diff --git a/packages/evm/contracts/interfaces/IHashiProver.sol b/packages/evm/contracts/interfaces/IHashiProver.sol new file mode 100644 index 00000000..a77b7e71 --- /dev/null +++ b/packages/evm/contracts/interfaces/IHashiProver.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: LGPL-3.0-only +pragma solidity ^0.8.0; + +/** + * @title IHashiProver + */ +interface IHashiProver { + struct AccountAndStorageProof { + uint256 chainId; + uint256 blockNumber; + bytes blockHeader; + uint256 ancestralBlockNumber; + bytes[] ancestralBlockHeaders; + address account; + bytes accountProof; + bytes32 storageHash; + bytes32[] storageKeys; + bytes[] storageProof; + } + + error AncestralBlockHeadersLengthReached(); + error BlockHeaderNotFound(); + error ConflictingBlockHeader(uint256 blockNumber, bytes32 ancestralBlockHeaderHash, bytes32 blockHeaderHash); + error InvalidAccount(); + error InvalidBlockHeader(); + error InvalidBlockHeaderLength(); + error InvalidStorageHash(); + error InvalidStorageProofParams(); +} diff --git a/packages/evm/contracts/libraries/MerklePatriciaProofVerifier.sol b/packages/evm/contracts/libraries/MerklePatriciaProofVerifier.sol new file mode 100644 index 00000000..29641241 --- /dev/null +++ b/packages/evm/contracts/libraries/MerklePatriciaProofVerifier.sol @@ -0,0 +1,248 @@ +pragma solidity ^0.8.20; +/* solhint-disable */ + +import { RLPReader } from "solidity-rlp/contracts/RLPReader.sol"; + +// Copied from here: https://github.com/defi-wonderland/safe-liveness/blob/dev/solidity/libraries/MerklePatriciaProofVerifier.sol +library MerklePatriciaProofVerifier { + using RLPReader for RLPReader.RLPItem; + using RLPReader for bytes; + + /// @dev Validates a Merkle-Patricia-Trie proof. + /// If the proof proves the inclusion of some key-value pair in the + /// trie, the value is returned. Otherwise, i.e. if the proof proves + /// the exclusion of a key from the trie, an empty byte array is + /// returned. + /// @param rootHash is the Keccak-256 hash of the root node of the MPT. + /// @param path is the key of the node whose inclusion/exclusion we are + /// proving. + /// @param stack is the stack of MPT nodes (starting with the root) that + /// need to be traversed during verification. + /// @return value whose inclusion is proved or an empty byte array for + /// a proof of exclusion + function extractProofValue( + bytes32 rootHash, + bytes memory path, + RLPReader.RLPItem[] memory stack + ) internal pure returns (bytes memory value) { + bytes memory mptKey = _decodeNibbles(path, 0); + uint256 mptKeyOffset = 0; + + bytes32 nodeHashHash; + RLPReader.RLPItem[] memory node; + + RLPReader.RLPItem memory rlpValue; + + if (stack.length == 0) { + // Root hash of empty Merkle-Patricia-Trie + require(rootHash == 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421); + return new bytes(0); + } + + // Traverse stack of nodes starting at root. + for (uint256 i = 0; i < stack.length; i++) { + // We use the fact that an rlp encoded list consists of some + // encoding of its length plus the concatenation of its + // *rlp-encoded* items. + + // The root node is hashed with Keccak-256 ... + if (i == 0 && rootHash != stack[i].rlpBytesKeccak256()) { + revert(); + } + // ... whereas all other nodes are hashed with the MPT + // hash function. + if (i != 0 && nodeHashHash != _mptHashHash(stack[i])) { + revert(); + } + // We verified that stack[i] has the correct hash, so we + // may safely decode it. + node = stack[i].toList(); + + if (node.length == 2) { + // Extension or Leaf node + + bool isLeaf; + bytes memory nodeKey; + (isLeaf, nodeKey) = _merklePatriciaCompactDecode(node[0].toBytes()); + + uint256 prefixLength = _sharedPrefixLength(mptKeyOffset, mptKey, nodeKey); + mptKeyOffset += prefixLength; + + if (prefixLength < nodeKey.length) { + // Proof claims divergent extension or leaf. (Only + // relevant for proofs of exclusion.) + // An Extension/Leaf node is divergent iff it 'skips' over + // the point at which a Branch node should have been had the + // excluded key been included in the trie. + // Example: Imagine a proof of exclusion for path [1, 4], + // where the current node is a Leaf node with + // path [1, 3, 3, 7]. For [1, 4] to be included, there + // should have been a Branch node at [1] with a child + // at 3 and a child at 4. + + // Sanity check + if (i < stack.length - 1) { + // divergent node must come last in proof + revert(); + } + + return new bytes(0); + } + + if (isLeaf) { + // Sanity check + if (i < stack.length - 1) { + // leaf node must come last in proof + revert(); + } + + if (mptKeyOffset < mptKey.length) { + return new bytes(0); + } + + rlpValue = node[1]; + return rlpValue.toBytes(); + } else { + // extension + // Sanity check + if (i == stack.length - 1) { + // shouldn't be at last level + revert(); + } + + if (!node[1].isList()) { + // rlp(child) was at least 32 bytes. node[1] contains + // Keccak256(rlp(child)). + nodeHashHash = node[1].payloadKeccak256(); + } else { + // rlp(child) was less than 32 bytes. node[1] contains + // rlp(child). + nodeHashHash = node[1].rlpBytesKeccak256(); + } + } + } else if (node.length == 17) { + // Branch node + + if (mptKeyOffset != mptKey.length) { + // we haven't consumed the entire path, so we need to look at a child + uint8 nibble = uint8(mptKey[mptKeyOffset]); + mptKeyOffset += 1; + if (nibble >= 16) { + // each element of the path has to be a nibble + revert(); + } + + if (_isEmptyBytesequence(node[nibble])) { + // Sanity + if (i != stack.length - 1) { + // leaf node should be at last level + revert(); + } + + return new bytes(0); + } else if (!node[nibble].isList()) { + nodeHashHash = node[nibble].payloadKeccak256(); + } else { + nodeHashHash = node[nibble].rlpBytesKeccak256(); + } + } else { + // we have consumed the entire mptKey, so we need to look at what's contained in this node. + + // Sanity + if (i != stack.length - 1) { + // should be at last level + revert(); + } + + return node[16].toBytes(); + } + } + } + } + + /// @dev Computes the hash of the Merkle-Patricia-Trie hash of the RLP item. + /// Merkle-Patricia-Tries use a weird 'hash function' that outputs + /// *variable-length* hashes: If the item is shorter than 32 bytes, + /// the MPT hash is the item. Otherwise, the MPT hash is the + /// Keccak-256 hash of the item. + /// The easiest way to compare variable-length byte sequences is + /// to compare their Keccak-256 hashes. + /// @param item The RLP item to be hashed. + /// @return Keccak-256(MPT-hash(item)) + function _mptHashHash(RLPReader.RLPItem memory item) private pure returns (bytes32) { + if (item.len < 32) { + return item.rlpBytesKeccak256(); + } else { + return keccak256(abi.encodePacked(item.rlpBytesKeccak256())); + } + } + + function _isEmptyBytesequence(RLPReader.RLPItem memory item) private pure returns (bool) { + if (item.len != 1) { + return false; + } + uint8 b; + uint256 memPtr = item.memPtr; + assembly { + b := byte(0, mload(memPtr)) + } + return b == 0x80; /* empty byte string */ + } + + function _merklePatriciaCompactDecode( + bytes memory compact + ) private pure returns (bool isLeaf, bytes memory nibbles) { + require(compact.length > 0); + uint256 first_nibble = (uint8(compact[0]) >> 4) & 0xF; + uint256 skipNibbles; + if (first_nibble == 0) { + skipNibbles = 2; + isLeaf = false; + } else if (first_nibble == 1) { + skipNibbles = 1; + isLeaf = false; + } else if (first_nibble == 2) { + skipNibbles = 2; + isLeaf = true; + } else if (first_nibble == 3) { + skipNibbles = 1; + isLeaf = true; + } else { + // Not supposed to happen! + revert(); + } + return (isLeaf, _decodeNibbles(compact, skipNibbles)); + } + + function _decodeNibbles(bytes memory compact, uint256 skipNibbles) private pure returns (bytes memory nibbles) { + require(compact.length > 0); + + uint256 length = compact.length * 2; + require(skipNibbles <= length); + length -= skipNibbles; + + nibbles = new bytes(length); + uint256 nibblesLength = 0; + + for (uint256 i = skipNibbles; i < skipNibbles + length; i += 1) { + if (i % 2 == 0) { + nibbles[nibblesLength] = bytes1((uint8(compact[i / 2]) >> 4) & 0xF); + } else { + nibbles[nibblesLength] = bytes1((uint8(compact[i / 2]) >> 0) & 0xF); + } + nibblesLength += 1; + } + + assert(nibblesLength == nibbles.length); + } + + function _sharedPrefixLength(uint256 xsOffset, bytes memory xs, bytes memory ys) private pure returns (uint256) { + uint256 i; + for (i = 0; i + xsOffset < xs.length && i < ys.length; i++) { + if (xs[i + xsOffset] != ys[i]) { + return i; + } + } + return i; + } +} diff --git a/packages/evm/contracts/prover/HashiProver.sol b/packages/evm/contracts/prover/HashiProver.sol new file mode 100644 index 00000000..85a138ce --- /dev/null +++ b/packages/evm/contracts/prover/HashiProver.sol @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: LGPL-3.0-only +pragma solidity ^0.8.20; + +import { RLPReader } from "solidity-rlp/contracts/RLPReader.sol"; +import { MerklePatriciaProofVerifier } from "../libraries/MerklePatriciaProofVerifier.sol"; +import { IHashiProver } from "../interfaces/IHashiProver.sol"; +import { IShoyuBashi } from "../interfaces/IShoyuBashi.sol"; + +contract HashiProver is IHashiProver { + using RLPReader for RLPReader.RLPItem; + using RLPReader for bytes; + + address public immutable SHOYU_BASHI; + + constructor(address shoyuBashi) { + SHOYU_BASHI = shoyuBashi; + } + + function verifyForeignStorage(AccountAndStorageProof calldata proof) internal view returns (bytes[] memory) { + bytes memory blockHeader = _checkBlockHeaderAgainstHashi( + proof.chainId, + proof.blockNumber, + proof.blockHeader, + proof.ancestralBlockNumber, + proof.ancestralBlockHeaders + ); + RLPReader.RLPItem[] memory blockHeaderFields = blockHeader.toRlpItem().toList(); + bytes32 stateRoot = bytes32(blockHeaderFields[3].toUint()); + (, , bytes32 expectedStorageHash, ) = _verifyAccountProof(proof.account, stateRoot, proof.accountProof); + if (proof.storageHash != expectedStorageHash) revert InvalidStorageHash(); + return _verifyStorageProof(proof.storageHash, proof.storageKeys, proof.storageProof); + } + + function _checkBlockHeaderAgainstHashi( + uint256 chainId, + uint256 blockNumber, + bytes memory blockHeader, + uint256 ancestralBlockNumber, + bytes[] memory ancestralBlockHeaders + ) private view returns (bytes memory) { + bytes32 blockHeaderHash = keccak256(blockHeader); + bytes32 currentBlockHeaderHash = IShoyuBashi(SHOYU_BASHI).getThresholdHash(chainId, blockNumber); + if (currentBlockHeaderHash == blockHeaderHash && ancestralBlockHeaders.length == 0) return blockHeader; + + for (uint256 i = 0; i < ancestralBlockHeaders.length; i++) { + RLPReader.RLPItem memory ancestralBlockHeaderRLP = RLPReader.toRlpItem(ancestralBlockHeaders[i]); + RLPReader.RLPItem[] memory ancestralBlockHeaderContent = ancestralBlockHeaderRLP.toList(); + + bytes32 blockParentHash = bytes32(ancestralBlockHeaderContent[0].toUint()); + uint256 currentAncestralBlockNumber = uint256(ancestralBlockHeaderContent[8].toUint()); + + bytes32 ancestralBlockHeaderHash = keccak256(ancestralBlockHeaders[i]); + if (ancestralBlockHeaderHash != currentBlockHeaderHash) + revert ConflictingBlockHeader( + currentAncestralBlockNumber, + ancestralBlockHeaderHash, + currentBlockHeaderHash + ); + + if (ancestralBlockNumber == currentAncestralBlockNumber && i == ancestralBlockHeaders.length - 1) { + return ancestralBlockHeaders[i]; + } else if (i == ancestralBlockHeaders.length - 1) { + revert AncestralBlockHeadersLengthReached(); + } else { + currentBlockHeaderHash = blockParentHash; + } + } + + revert BlockHeaderNotFound(); + } + + function _verifyAccountProof( + address account, + bytes32 stateRoot, + bytes memory proof + ) private pure returns (uint256, uint256, bytes32, bytes32) { + bytes memory accountRlp = MerklePatriciaProofVerifier.extractProofValue( + stateRoot, + abi.encodePacked(keccak256(abi.encodePacked(account))), + proof.toRlpItem().toList() + ); + bytes32 accountStorageRoot = bytes32(accountRlp.toRlpItem().toList()[2].toUint()); + if (accountStorageRoot.length == 0) revert InvalidStorageHash(); + RLPReader.RLPItem[] memory accountFields = accountRlp.toRlpItem().toList(); + if (accountFields.length != 4) revert InvalidAccount(); + // [nonce, balance, storageHash, codeHash] + return ( + accountFields[0].toUint(), + accountFields[1].toUint(), + bytes32(accountFields[2].toUint()), + bytes32(accountFields[3].toUint()) + ); + } + + function _verifyStorageProof( + bytes32 storageHash, + bytes32[] memory storageKeys, + bytes[] memory proof + ) private pure returns (bytes[] memory) { + bytes[] memory results = new bytes[](proof.length); + if (storageKeys.length == 0 || proof.length == 0 || storageKeys.length != proof.length) + revert InvalidStorageProofParams(); + for (uint256 i = 0; i < proof.length; ) { + RLPReader.RLPItem memory item = RLPReader.toRlpItem( + MerklePatriciaProofVerifier.extractProofValue( + storageHash, + abi.encodePacked(keccak256(abi.encode(storageKeys[i]))), + proof[i].toRlpItem().toList() + ) + ); + results[i] = item.toBytes(); + unchecked { + ++i; + } + } + return results; + } +} diff --git a/packages/evm/contracts/test/HashiProverTest.sol b/packages/evm/contracts/test/HashiProverTest.sol new file mode 100644 index 00000000..8e4d0892 --- /dev/null +++ b/packages/evm/contracts/test/HashiProverTest.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: LGPL-3.0-only +pragma solidity ^0.8.20; + +import { HashiProver } from "../prover/HashiProver.sol"; + +contract HashiProverTest is HashiProver { + constructor(address shoyuBashi) HashiProver(shoyuBashi) {} + + function getValue(HashiProver.AccountAndStorageProof calldata proof) external view returns (bytes[] memory) { + return verifyForeignStorage(proof); + } +} diff --git a/packages/evm/test/05_HashiProver.spec.ts b/packages/evm/test/05_HashiProver.spec.ts new file mode 100644 index 00000000..ebf16b43 --- /dev/null +++ b/packages/evm/test/05_HashiProver.spec.ts @@ -0,0 +1,106 @@ +import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/dist/src/signer-with-address" +import { expect } from "chai" +import { Contract } from "ethers" +import { ethers } from "hardhat" + +const SOURCE_CHAIN_ID = 10 +const BLOCK_NUMBER = 126086803 +const BLOCK_HEADER_HASH = "0xf72ab984efa166b226dcb589bc445afeb8e666f789173a32de6d04108ac5cb8c" +const VALUE = "0xb56d157e7f5a" + +const PROOF = [ + 10, + 126086803, + "0xf90244a006f019ce5f815a48534f1894e0bf2bc479f3624eb3658a5b8b09683210371cffa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347944200000000000000000000000000000000000011a0db07d5c7f51b0fabc0ab6abffb98efcac1cb95f63dcae01ea8e73301558f1c94a05ab78472371830bfed304d360240d57e7bee41309297278fd0dcd5b198979a2ea0a9bcb4d6a8f248c15860a40a38c1d965a5c33173226d35eab3cfbb7112bd3532b9010040703482510e004000001884022000202001880a000450400806000144d2210045081100280910224008001040003110004402640012220006200001402020c1000084188008208a3010880940b82000149414030182049548200000208c0001190000281a5406000010100203040900e0311685481c0150002500124808000840000003088c028200010600104840049080d5c08aa14000111090084a2800001210002815123401000011028040260008840010a000000040810410880004804000002308064400c10028860002800840c480040582c3008020040820102901001028010094000110102801088001119000100401828100840080000021280680840783ee938401c9c38083574af28466fbb6df80a0bc24644d93f212885acc3a93836ba214b962f7508721517fde36b89841d126638800000000000000008301fa63a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a080c2a58ed1b8b5bd35567d8dba40773b50e4bbe0b5f0e68b2a8a0d79c6619dae", + 0, + [], + "0x0b2c639c533813f4aa9d7837caf62653d097ff85", + "0xf90df4f90211a0844646418cdc472243623a6adf853cf42930ed027c5f2eceff9a2a274f5e9cc3a0ec7c3704cc16a2ace8fce26d2ad0da2fce10b66df732616516228db1d366cb4ea0c2c588c16144825eb7ea05706f6446d2cbffad3da2174cce3ec3a1effe54c803a01b2297c51766932182e29aafdf7dc4b9bf3c5307f0a38ba23b36f8ecd21fc0e2a063d96d72aa3d8c16be960a74f174e75c4e2db021710a8e461502f5146e30faf5a0012f48dd4b043f6f92c33b2d8deda920eb9865100c29b254f08954f09ecdd2f6a094e26fe5bca0e87b4019c815890e10788a637436fda3896d5505298016270182a0baf314b410c021b42295a806f14ce14700e1699dcf7de35a194229cf94954d1da0a7febdeed6c7dde904228dd454626d9427e0a3383e11398d41ccad56ade292b4a0463943e8401fdd6b0352ae228250096cfa8ddc9dfda3d38d4c33e55e17369a14a0a8b2218d9bb0268f2ed74484331ba4ba428d17b65f4d1a06d7f4ebaf9c514d4aa0f9e9916aaabdbacbf2004783d7403a8891c73c9aa468c72ac7e8b09a0f89142da0ff7d643adb489b721f611c0b981d67dae2b63945a1c7ff908d077746d6c1957fa0176c742cd7ddd01391f0863b472f318e91d3227a3357c306cd86a18d30303641a01e767c4d2bed2343988ea284102b234302b0e1ada620d9b9a0d194077dc7f873a0619ddda96da06f24140ddaafb3d5644b6da53041b39aa7dd5dcc3468d9fa445480f90211a0ecb37076729047293de85c6c4a2b13bb62fa4a402c6b1451e9119bf495aca8a0a0433f3f07bc576292134817472d7166183bc4730e837f964e3011b52bbf9b081aa0e9b2b29d4341d3b168d9bb4f4fe000b876a8f55027cbb69c45160d495141f210a04d482eb4f317e703aab85ad2c6990c98145af5f7cc89a7ccd2161f87b791bc01a0e9357b5192820eea672e3194d2020b131f29abe5671c37601633c485358eb421a00a3f410ab91d016cb1716203d732962685a6fc9436862ab83d9fc5109346a041a096e1687da814500097774352c9f49064dac34fe0de9f1848190b5a56fbedcb17a07006adaa8c1b203eab5ee33ea19de791fc8c9cf5cb15ec90d1ef051c9e2ed78aa0468135eecd2271411b5c039c6dce226ee4b251d3e671fea0238347a522241313a045483167728fabead0fa82c604abcf05e0141b1e82d5e94a427b367839985ed4a04c53cd84dd5c5e90d3e4c6bf7583a2d71a5f440e78d2e550c618a9c326ebce64a0f120f7e462069e2b91d3ce0f1e9be2cef10b699399b76e188a710c74b8968432a05a912ef4d4b331e64a4f5ff4a6268ea3bd66c8b823fcb4c3bf7c6e200d302a1ca07aab0db239e967467ed9b3a155ef0a4e8d03d058d44e9e63c39312ad2a986fc8a0afe49319cf159e2916404743d4ef869043fdeb37c79b20fb355a98e8500491f1a04e7bfee55002c5d87331c6d9a9fb394acf87247fc3e26519224e3851bee4c19380f90211a03b31c916b970491c86305379f7e67c97f98166cbc06fade873c5c7d324a7fa81a0d5ff65d687d30b465e3abc81774a9628de5a67f6f318fbbe0641634af53f0d74a098663d761acb23f77146aa5dc3fd4b487a3fec8d25ab2d5408e38e75489dea43a0a26e34fe93e7455b178fde2f89c1c99cfef61cbcb24bdb7ad8041be83ee67846a008662a0a8da5e79b6f4c601197a57ae00377f2f04a0f5edd17e3aed4c4d3777da0c3113823fec10487cde37f5ee2f39a8c72bd0413a21ba763acb5ebf0d40a49b6a044163b2ab486e7f99d831323ece00eb977db78a6594acb26082c5de00943616fa0dcfad53d7bef9f07e520b4b62d7f71620b244d13d06bb964a619f5536e37fa08a09c630785cd49c1b3aa3457999a1047d980392a18bc1d04f7763416ae01489ed6a07a1d5d86308774a7c26ed21faaa58d45efbb2616961a4bbe10d3fc88d99d0bf5a00c58bf78f9f278a3e75d22b39fda0df112a1cb8e05d79c32e5f31b94d4e99f64a070ed09023a65c88badb25edf59f2cab9708edc992ef461534b0e47ce3982ae90a01b690934defb8655cddc75185dd1612c1165ecfdcc8e7a19fdc57cae0f0065e8a054523f7b5547848216144e68b0ccdb1f819bd54ac210c2e4dd5a380edcce33f0a07dd9da455fb24559012c4903166f73f9c5e661b8c88f0bf7de019d73d4c19c89a04478f70fe968b2da1516a8f6b67a6b28011923c34ebecda2f45355e442cbcbbe80f90211a0d5393c3c06c8d597f6f325789484f12da87d807df33096a0af3161e33c44b8b0a0f27d4b26d1822dc04180fe221b3e7cba86c9fc524791c951b6b71c242099ef3ba011d2b20160240582f75dc941e1785643f7652a43d1d62697808657b0a0b8e186a0e9acd52b94dd294c782ad25e727c17934726d62052deac6cd8ffab7cca3e4176a04dcd91b21b8c73a57023c649f7d27cb9443450ee8301f56d4693e667218fcb3ea0630078c69bd028cb16cfccc05feb9f960484ed470f7bc0d1acf25fea5a68de0ca09ee40510308e721235620dc519619981d81e8997c0e7ab5c91f32f1f9ddffdeca0176656e94e76511030173bc6a39fc6fc11078add4c391a6edceb34cc28b7c83fa01cc9e278e51e81a30d6b18410a7411287b95c03d9ec2fd23396f0ada6410d2a8a019a07cd977b76673046b61debf2ce6e54615f5e69e31e17eb0c4dfb316da1cc1a08b8a356d612925d089be937debbdcbe8a40a941bbd07d7fe168cdbe2bfdc2d7fa0ebad3b72886fc350a5aaa24d20d8a143754c92eabab4ee2cba59697e7771cd50a0c24cf965d70417de74ee02b9cfdde3138d434c2cbc0c21006c04cde27a2d9ab7a0f21f4798a55807d429caadba5da04b2d12fc43569e7bc6c4b965976f21643874a0ec71a00e5b53a2f6043ed744c66b7ae5bc6ea1c7d32066014723a7744ad0e446a08b985961a92fed93614049284d0f08665a7a9f1b5dfbb025682a9551f2660f5380f90211a05510ce326198dee0033e6a2b29957f77687221d6f4b9a082f34922f9f589b003a0a6f336170753299b1adc48077e111e425fdc539ff7160a9babf8afdf5b5bef3ea0ad027c813622b3582247847a8537992e0a3f6a50e10c268d0ac8eacd1fd750bba037babb03742053f969204568854a958947fc93bcb978ebc85c83e35c5dc6fdfda07d3c1a847911e962071639472987bf9f0d112c983b393190af796342557a3ac5a07e243717881703400c60ec2fcc05040759a9646b61adb02412c8b0619e3059bda08acbc6de4a6c92f92dde22536a30bbc7bad7d44394e29312ebc9adfcd84ca300a0c558588e6ae83a42eaf44d7215f853262ad725faef6b3c73830e0903a31fefd6a0921f30e12a3b363b2aed7283870304a503f3613d311bae004eb7a922f6fd50f1a013987bb8a564c1513dd7b42682bb7237f51b94ac28780f41ae45a772e13fa76fa0596b2015a656fd4864bf6789cb5d4e4c67cc05114ae3fd7caa8355bd16cb00a7a0dea6e67052bdc0d975f894dbe6b4d7b7474c7bf6f2d0bb9b5298073a5e95a43ca0f532a3b3466a65f1e6e948bd1a9ac5b36bdb0f824609c37046acefb55f76d0b7a0b92f68142fb15ceac6044f289b074c3333e4826a9f02f1469318f2273026339ea0a5f42aa4c2fd149ba3a73028c450d1d3c0c10536bc1421c6e632bd56d63d7565a0156d9f2ce56dfe6e92fe5779b15821b6bae03882935a167a0d3c10e03523f77480f90211a05d176d139f8def1c9dd83692adad161605fdec658eef8bc28afc4da848d97662a0e3d1f706ca6308d1f5e2d4cb6d641ba574b9ad852d6c878f9cec25ba7c8c8183a0f3647cf8efec130e89c09170b6a82a06cf2b9f4b15aff5d2e93d3c8cb5c294f8a071493e91397ece4c52482e3a20656b6780054a56986544555b07f5b053a4d722a0b60b270ab95f7787f4a40d6f68b667126fcb1272ddc0e9347205ebae3069b7d2a0b00e67c2e390212edde83ad1182fc5f373e9f47f11c8c69a04b87d75d0123b15a02f20f6d8f52b12c28ddba6fdca481dcb5a07363ff08758d83f041b2535666b18a03f573e0937a15fa5167802cb25220547e8b6c2194633ad2d2b4e15fa9b2cc8fda0a27b621d4212470161d3a1786d70b24ba6f0ba013677c11e995feebb3f7be72aa0894ac9ee877ef9fc4ea797c33f994996567a17777a57d22050260b18bb994946a09bf44993469f668dadae80170dfb81156b0decb5f7fbceb62980a2508d3f3702a013fc551024f4961a8e4adedb726962975a60ae0553a65f0dd7e266b0ec34f2dca087561bc3f849b47500f1f503a264466616a31a4e7adf3f2b2753b3f8c60444bda0421bcca422a9f02867ab2b0269bad562e8d35bf35bb332a48d3be29b513e4a78a09fe8fdfd9c06692e93cc2f1b277aadebf462a38a28abfaaba33f4d7e4212ed71a0407f10b8182d07c7f9789d469b68926931e184d7afdc20322387db7dd8dd950b80f9011180a0af3e6c1703878fa0f54ce9ef81044131303255beda112c1750bd46e46c17749780808080a0ee3ef4e754b7044fbaf982f80b8ab4ea00503fe3ec4c50fd7864e81ce1e6c4408080a075fb4f68ac224ec54d38eee3bd972654ca5ee1833530f0ebefd71a9f49cf09f1a05c099f09257a656d98101ccd60d3fbe861cb889f9699b8eed136268028021b70a0b90a5365f3205e9df1129eecaa73667c4d2c567f1ab45f63860c3671b46dc27780a0e38b7963499d1bbde43a95289356e98e19cdc1e21e10e097e1490f15e3662e0ba052b569b11cc62b342b35edfd24e3f8c4f9b3ec16930ac8986eefe14e609d073ba052fe3bf973b9ff06f119a91481e15215c3eccadc584ce8b6e7a05ea68c73054180f8669d3d676334b26bbb561def1bb646db346a0ea5f7c4f069e5ce4083818685b846f8440180a0b8f3308b625ddb7bce9e10a6a13d9988d1b865eb09df34844bf6b86b00904ae6a0aad43333d28e146557f1c682e8a4226743fb231fdd00a577512233bd9e920008", + "0xb8f3308b625ddb7bce9e10a6a13d9988d1b865eb09df34844bf6b86b00904ae6", + ["0x000000000000000000000000000000000000000000000000000000000000000b"], + [ + "0xf909acf90211a01922b5f82f07bee421217744ed6d4e95b98852241f24dffa2f5701b1ddb8e6dca03fec17456b28fe0aea41291618b766813d90061104d8731e6e937b0922cae1f6a0fb94b76b2f2c5d4b40890a18b9f0579966eb56274035a58010db113ccbab922fa085b2e52483d7a1448504098bd8b3a0fc68becfe6fcf5e8f7442d08d1c17d9446a0c8b2aa37759feac9aad765fca7545ab9d02015364261d3f35384154e77ef77e9a0bc48fb8581b0926eb1d707cb1668b5ecdf2b1759fb7ed8d440bf1163103bd810a046fe65e822efc9f1b49e43ed4eb7600e9658c306b70a95999aeb0112c9954f9ca03d66c408b9ced8ee40c6281f15e26bb7db314045d5f65322fc1d5e24544b9192a0b26bf58b679aaf2a0a5f5a7fc9507e856f31e01a7ea47d9c5719957e51d99f92a003555409bff0cbb217e5d9fbd7d9e3b46a451e2b3cc0f27b34a3b553634770f7a05f71f83b940082edb3f0afaedd000ae4789a8b459c0befecf0085308961a38f4a0110aca3b49ff8a7fc3d60295d0c18602e576427a02907986d3fcdec5c8406607a0b197a531e48bf6f203d6f8b4088117caaa55d2318177d00a849c9bb9c0be11b5a021c55c465168ceb84725b61988c7c174880c9bccb99510ebffcf715f01344022a0173421253267ac8dacdd78bb3a49e4e68ce44c987335e7e22e2067f5998ccc8ba0ddb9469be4af0c764ae2984533a34b6ac6ad4535a7bf773d1bdcaba414288d4e80f90211a0134f748fc5e8562c4037bb335c253e159c2d3c7a1dc48b1e006fee1ffcc63874a0dcad9ec65f0b0b3e3d265b468ceda4c2626bea957ba6dd0f25e91d8f43615dcba0b8fdad766b78548db43d60da964d1abdd784ae56bd9ad9dd5ce7911beadab941a01db88587d7758f452204d265122d451f416f29219de91d8f1fd98b4695ad56f8a06464403607b9759cf6cb0e1bdd58d3a231ece185267c59d0113836bbce312007a0a23247953c05226318750e90668afd8b8f4a308f1f3e5573f92c03cd4fa9cc99a0ec186ad6ea36e64969fac78982f9ddd2c78f01fb5f059afc8d9253cafb348272a00e259709d156973caac69a52dbde1569f0ea9fc58cc9333b6fff01bed4ced9c3a01f76d216b1d1f75ebdcece38a62dc6d85cf090cec0b17ea8fe4a2fbadf02e418a0a44e06aa48e8e2b81b82ac7a55d10e0e75fb0016475f40b4b2b199016fefef11a04e31f7d98493c4af332a55a088d75bd53a55d37feee0fb4ea4bb89bd6cf1189da01fe39db746e4eef3572d1863d2edf73ef178986a33929a353e30d5a5459cffb7a0c64a8a52d3dfb4c33e5eac53820c25604e4c8f34062e2f31a00ada4c4e8ac794a02b09776c323c5f8fc6b69732fc17e7ac78fb63c9a42243b5b65bb067b05af034a0c371630f7af67645f11a19b70a01e20284fd2c3afa8ad5e72fa939e775090b94a0a2680edf63d1735ee9ce81c2bb867aa6708db5be648b511b2997cf6a82b7b12a80f90211a046660614c4b352e38c7a40b3fbacf123b88d343407c60aa3df2fc14e5c57667ea0f326e8d140b8c178ef04d4af3f9435159ad3c3cc9029a24daced2a2e5a7edadba04beaf51b9e686b2e9a3cb11906ac2c2b975a1f2b21fae6345baa832716d08904a00d9c648844e04c5a20d669382e429a02691b92a9ed51346e9e6b4c3e11950c51a0116e5123177580be67dfd0beaa66ff0aaad0d390afa05246c44dc8de9736c21ea0c566c23ca1b65aec125de0d781343787ae3f1037793af3d12e976ebc26b25d82a0ecc286af188cbb0d2f91980a6547e9c21d31e436f362565998d38063cb8e4a43a0161332b061fd1ae44a9cc9a7ee560b1f416a75f723df1d4607487149f0a6ef98a0ce4de6144c942d8cb5180aad406ac42934f039bafe6a7b1fba6094b104e3ed01a088da9aca558d0c51ce0fb208ab108b143e0a5122bcd5bd85c35e09b39a67a7ada0b24c5e971bdcc7151c89d69c0046c899379fcb9fd479d2b8a05df7348f08e4bda0bdb15b37b990be1e658ede5ed0e556d73fca185489124cad494721bd0c9dc79da0279294696fab46dcb10b5069d1929b96500342e6609fc85b5c242ebfd6dee280a02b3df2dfda83841f27315d0dcd3025dce8ee53425de4ccea153dd8f9893b65d6a07b3b6cb9b2148a7086adc24501672da8b0fc348a1fa78051ebb603f337f68de8a025f98ef38ab7bbaf176f7284ff1548b7638d013f817fd84979061507c4cb3f8080f90211a0817f0522b611763caedae0abdbf8a7d1fc523cc759bc6dd400d8837d94587832a0ecd37fcea2b496aeb18f74786fc7aeda2ea78bfb55cf27a829b69c4d15e2525ca019a27a34379a6a5dcd5a1cb8fdc5b7351b40eeb3f4e7d09db2daaf688e7a11b8a02339835ad35c836c7c9b1fd17f8ef9aa377a9e458316252ac63efe702fd895bda08e96214ae9077f46f6d2a440af91126a5bf62732edd0dc513efadba4b956fe9ea026370016e564a879e26f01a077e73badcca1551a92a05571e86d07af2a049493a0fab6a8b576dbf710ba642f849c36ab54ed462ac0f8e3593ad6d25af4e6f23677a06ed7fc714f359a29a6bd13c1a804fc6a19938f46c377fc97e787706dc8da0e58a0c0d3305cf25baab40da08bb2c141d0984d60afc353c4d0e708fed92fb2239460a057cdd07f66b3a31f01079d3933ee6a4fd5280ba7abec7c9bc1404ccca5224d9aa0ab9e1abf9a0bfd89d1483448ec555a10d7956b434787ae6c55605ce4c3fbb3e5a0d9d5c4782ba8bceaf3887b440321190898df7ce785679dcc628516de02069a17a05565679c56603a5614f90447648485ba6f3e324df4845af69482209fcc620156a09e4205f6a5c8e633cb7e5048148675d7aef4030de17d81e6d8e5a3e5f5b77a8ba0b995d98c91905fa0e083455afe9d4219e4f040c6e3bdf948b139a8d12b192157a05ed2de5e483fa16f32c9d56979082e36c77c1102e12020136172dfed9c85d28880f90131a0d56f8e12a9254f3fab9b7c5cb9e917dbc2540b1fa8e14f22840257d30c47adbfa0bcf412e2dcc182720eb7a6d3b260488603cefcdc206815beeea0b4700adb9e46808080a0ba844e9671269f0a8ab47cd42fc59e9ff5077adfa3c400e243146fcb708f4e5da0d1e9012aff863e29b5c2b7111ed41b55669bc3bd70aafd9302247c9a71176550a03f9b33fa55d938ae9dd41dfed6b17fc52327d20a2503c8e5d85a2f401a0e6ea380a0d4947649b148740ce5687696c87bb07217543329c73f7bb8900f1140b1563f3ca0c41116acc085e1d1b88f0998eacf59cc10a4646e9ffc4428b221c00ec5b1f4cca08c6b7c02a459200f13e8b385d3dcb998ec8f9c03cc1b7c8b3a5e753d5a65364880a09dc8cbc03d181ee816de24c1baeaa398a7b98e5f33e730011505e8496e74fefd808080e79e37a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db98786b56d157e7f5a", + ], +] + +const PROOF_WITH_ANCESTRAL_BLOCKS = [ + 10, + 126086803, + "0xf90244a006f019ce5f815a48534f1894e0bf2bc479f3624eb3658a5b8b09683210371cffa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347944200000000000000000000000000000000000011a0db07d5c7f51b0fabc0ab6abffb98efcac1cb95f63dcae01ea8e73301558f1c94a05ab78472371830bfed304d360240d57e7bee41309297278fd0dcd5b198979a2ea0a9bcb4d6a8f248c15860a40a38c1d965a5c33173226d35eab3cfbb7112bd3532b9010040703482510e004000001884022000202001880a000450400806000144d2210045081100280910224008001040003110004402640012220006200001402020c1000084188008208a3010880940b82000149414030182049548200000208c0001190000281a5406000010100203040900e0311685481c0150002500124808000840000003088c028200010600104840049080d5c08aa14000111090084a2800001210002815123401000011028040260008840010a000000040810410880004804000002308064400c10028860002800840c480040582c3008020040820102901001028010094000110102801088001119000100401828100840080000021280680840783ee938401c9c38083574af28466fbb6df80a0bc24644d93f212885acc3a93836ba214b962f7508721517fde36b89841d126638800000000000000008301fa63a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a080c2a58ed1b8b5bd35567d8dba40773b50e4bbe0b5f0e68b2a8a0d79c6619dae", + 126086800, + [ + "0xf90244a006f019ce5f815a48534f1894e0bf2bc479f3624eb3658a5b8b09683210371cffa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347944200000000000000000000000000000000000011a0db07d5c7f51b0fabc0ab6abffb98efcac1cb95f63dcae01ea8e73301558f1c94a05ab78472371830bfed304d360240d57e7bee41309297278fd0dcd5b198979a2ea0a9bcb4d6a8f248c15860a40a38c1d965a5c33173226d35eab3cfbb7112bd3532b9010040703482510e004000001884022000202001880a000450400806000144d2210045081100280910224008001040003110004402640012220006200001402020c1000084188008208a3010880940b82000149414030182049548200000208c0001190000281a5406000010100203040900e0311685481c0150002500124808000840000003088c028200010600104840049080d5c08aa14000111090084a2800001210002815123401000011028040260008840010a000000040810410880004804000002308064400c10028860002800840c480040582c3008020040820102901001028010094000110102801088001119000100401828100840080000021280680840783ee938401c9c38083574af28466fbb6df80a0bc24644d93f212885acc3a93836ba214b962f7508721517fde36b89841d126638800000000000000008301fa63a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a080c2a58ed1b8b5bd35567d8dba40773b50e4bbe0b5f0e68b2a8a0d79c6619dae", + "0xf90244a0bdb13612402a6004f26314e340d25c864e27cbd26d90464c3a3191195698a038a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347944200000000000000000000000000000000000011a016cd64cf4911d99e5413d5740b90cade7def9698cdabf726e8d931bd5967f878a0c622bc1d9430ec4062302efe23cc8127742f8ca8978a7c3b27743124c4b7430ca093be9a83ad2bf4a046bab6c7a9bf877f261238a9b96058936458d61c2ee4587eb90100907030825b420001a40218a688204060400c00280164a0000844000344c42900250810046000040a80400090006023000150144000032208045046c0406642c12a140080000c308a2100a02952a5302110c45008014b201619000101280200039daa43088b44000010115000020008318003460a4008160000000012a80a55184024002300822500582132023801b0041122168080200268002400582a388019821040923023048002811120890846001a8428862081420980800010200028406000120220420008354800060262301028f12000808803168008001aa801201003100c8d20b3002209904049028801c20800010414809a00800088042013101080840783ee928401c9c38083771a9b8466fbb6dd80a0bc24644d93f212885acc3a93836ba214b962f7508721517fde36b89841d126638800000000000000008301f941a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a080c2a58ed1b8b5bd35567d8dba40773b50e4bbe0b5f0e68b2a8a0d79c6619dae", + "0xf90244a02abeb2f843b0c7e14af20d88b51580260281529864bac81386715d186b188feca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347944200000000000000000000000000000000000011a07f973efd45c15188ca5b64afe8f2a431fc49da885ce3473aca30f18230bd9567a0070547bf249b370121ae7bfcf64c421a91c25b4a694b1982b1f473138d69bb22a057b9a7532db0ead6850099e396471c6ab4b1c1970850d259abe2e1e8f4003d51b90100c401a002c0040080d10018404420012080006908000402002006880044e0011025081804301200210000a0100010380010c1021000122280a4010140406809c822c00088b0290808200008b948a10401148608004108100414000000902800011485010882042204128012a00110480100210002ea0900400b010110010910080800006508800151002142001a08002050001781a82110008000109a2a0885180200000658028e000001010409089600268470040042008020900052a85800806910100200020800130088060882000042c40010038002008100000840046040583cc00902840010209040a1000055011001342c408089400620a08000142c0080840783ee918401c9c3808371781a8466fbb6db80a0bc24644d93f212885acc3a93836ba214b962f7508721517fde36b89841d126638800000000000000008301f846a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a080c2a58ed1b8b5bd35567d8dba40773b50e4bbe0b5f0e68b2a8a0d79c6619dae", + "0xf90244a012dfd2e2be4bcdd6b79eac25fb75a3fc4d755aa463acfc7ff80f3bf4ec49353aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347944200000000000000000000000000000000000011a0e49a1cb205090a958479f62241d3c812164630f09859538b98f20929700832caa0fb422fe08fca21bf0de2f413bee27c3ff3436ea54e32587238ce182d6dc1fb19a0274c2dbc71d835379c18401e3268e7c4f009b670b9a0ddca04743b7b0b65a111b90100005030021000000300001880204000001200020c000020000840000042c009000d08100030000108004000000000210800100442000022082040004040600000000280008008308a4000002850000000008400a02008000000210000000000000000010006040000000011000000889080004000200a00808000001208480908002000010002300060000202010180200100500080000000020000000a1004018a00001001000080300108208000000000000000000000090080408300000040400001020004240028008006004200000805800002880300000000084800200000300009002000000800001000000100000a011010902a00800010040001000080840783ee908401c9c3808335bb028466fbb6d980a0bc24644d93f212885acc3a93836ba214b962f7508721517fde36b89841d126638800000000000000008301f8dea056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a080c2a58ed1b8b5bd35567d8dba40773b50e4bbe0b5f0e68b2a8a0d79c6619dae", + ], + "0x0b2c639c533813f4aa9d7837caf62653d097ff85", + "0xf90df4f90211a0ae94776f5c237b1e277aa2206301cfcfd3990fef08b60f1acbb7518bd2c353dda0a6dc453d3af2966ec75db38d8b592099cd823972058a68fdfa217788b8307544a04d85ebfc910e05b7de2b9a780dd871d984c36ab0f2c3f38eea8de6adfd1c444da0b5fea1bad6564cade5a31e978195248b2fd67bb195006827d1d61d0d72593f64a0460766bc32f1ce32df10f604758468b2998250732e91dcc43b3e8b185bda669ca0e21dcda48944f76f3d6508ab3d36035cdd82cf3d649f327e78532a62a40376b4a0dba8c95c72743ae2b7bad789e3038040f06f3afbca090b9da364ae39f0b15963a0bca1300f03dcef17a2f614fea6c34eb6a6f0c52f57e7fa15a75860541c671322a06ce72250e0d542a46b25347cada837c6316695108071861dd4b041f4bc56d0dea0f00addb60c5ee291719dfe5d93383380ce0c3a9cf54d27faa70fb3b30d424810a007fbe090c28df1099bc1768e0eefc350701227b351d4b0d434d81673b4867e0ca04e1032bc06c39c9d9ba823088d8ba3106c5018f4ef60765c72b1402c7a7cc5cea0a848e579a56b4c19e92b4a582288f1cf701ffcecfd439fb88c8f40173cabe43ea0d5839de991945ebd86629e32de1de57140de090842f3809bcf4a737bd75c13bea0287235eea51447d1b9b6686381830195568efc908c27092f561b2c65e4113ccda0d902b9642b74f04cf670d6d216c5f03d0d92f2e77c374e3e41c6c6265d8d429980f90211a0d61d720b302bc422f0ece0f3c0e5172f16e8409b6b8bdd15db021284389b28fba0433f3f07bc576292134817472d7166183bc4730e837f964e3011b52bbf9b081aa02906d2af47eb17db297cac9e29381427fee7ebb53d6a914e402535f68c4c7c21a09de01bfc2a3986ed7a00b997b4cb7b55b837a155baa3bfc171efdf1ac31487c7a0e9357b5192820eea672e3194d2020b131f29abe5671c37601633c485358eb421a00a3f410ab91d016cb1716203d732962685a6fc9436862ab83d9fc5109346a041a096e1687da814500097774352c9f49064dac34fe0de9f1848190b5a56fbedcb17a07006adaa8c1b203eab5ee33ea19de791fc8c9cf5cb15ec90d1ef051c9e2ed78aa0468135eecd2271411b5c039c6dce226ee4b251d3e671fea0238347a522241313a045483167728fabead0fa82c604abcf05e0141b1e82d5e94a427b367839985ed4a04c53cd84dd5c5e90d3e4c6bf7583a2d71a5f440e78d2e550c618a9c326ebce64a0f120f7e462069e2b91d3ce0f1e9be2cef10b699399b76e188a710c74b8968432a05a912ef4d4b331e64a4f5ff4a6268ea3bd66c8b823fcb4c3bf7c6e200d302a1ca07aab0db239e967467ed9b3a155ef0a4e8d03d058d44e9e63c39312ad2a986fc8a0afe49319cf159e2916404743d4ef869043fdeb37c79b20fb355a98e8500491f1a024f8f3ea7890564e7c9b344f5493de5f87cfc5e4512c2396a51040cb64d6aba280f90211a03b31c916b970491c86305379f7e67c97f98166cbc06fade873c5c7d324a7fa81a01b01b15dc4b7c66db50809b4236a98a2f05f156dc70a1e00ff7f009784a88173a098663d761acb23f77146aa5dc3fd4b487a3fec8d25ab2d5408e38e75489dea43a0a26e34fe93e7455b178fde2f89c1c99cfef61cbcb24bdb7ad8041be83ee67846a008662a0a8da5e79b6f4c601197a57ae00377f2f04a0f5edd17e3aed4c4d3777da0c3113823fec10487cde37f5ee2f39a8c72bd0413a21ba763acb5ebf0d40a49b6a044163b2ab486e7f99d831323ece00eb977db78a6594acb26082c5de00943616fa026fa7daf50745e3a6dfff87c28840cbb09ddac372d7759b796ea60b775f69f60a09c630785cd49c1b3aa3457999a1047d980392a18bc1d04f7763416ae01489ed6a07a1d5d86308774a7c26ed21faaa58d45efbb2616961a4bbe10d3fc88d99d0bf5a00c58bf78f9f278a3e75d22b39fda0df112a1cb8e05d79c32e5f31b94d4e99f64a070ed09023a65c88badb25edf59f2cab9708edc992ef461534b0e47ce3982ae90a01b690934defb8655cddc75185dd1612c1165ecfdcc8e7a19fdc57cae0f0065e8a054523f7b5547848216144e68b0ccdb1f819bd54ac210c2e4dd5a380edcce33f0a07dd9da455fb24559012c4903166f73f9c5e661b8c88f0bf7de019d73d4c19c89a04478f70fe968b2da1516a8f6b67a6b28011923c34ebecda2f45355e442cbcbbe80f90211a0d5393c3c06c8d597f6f325789484f12da87d807df33096a0af3161e33c44b8b0a0f27d4b26d1822dc04180fe221b3e7cba86c9fc524791c951b6b71c242099ef3ba011d2b20160240582f75dc941e1785643f7652a43d1d62697808657b0a0b8e186a0e9acd52b94dd294c782ad25e727c17934726d62052deac6cd8ffab7cca3e4176a04dcd91b21b8c73a57023c649f7d27cb9443450ee8301f56d4693e667218fcb3ea0630078c69bd028cb16cfccc05feb9f960484ed470f7bc0d1acf25fea5a68de0ca09ee40510308e721235620dc519619981d81e8997c0e7ab5c91f32f1f9ddffdeca0176656e94e76511030173bc6a39fc6fc11078add4c391a6edceb34cc28b7c83fa01cc9e278e51e81a30d6b18410a7411287b95c03d9ec2fd23396f0ada6410d2a8a04060e9e3881260d3fff6981fdabe0861f12fe992e1a2704ff948339ab1ac694ca08b8a356d612925d089be937debbdcbe8a40a941bbd07d7fe168cdbe2bfdc2d7fa0ebad3b72886fc350a5aaa24d20d8a143754c92eabab4ee2cba59697e7771cd50a0c24cf965d70417de74ee02b9cfdde3138d434c2cbc0c21006c04cde27a2d9ab7a0f21f4798a55807d429caadba5da04b2d12fc43569e7bc6c4b965976f21643874a0ec71a00e5b53a2f6043ed744c66b7ae5bc6ea1c7d32066014723a7744ad0e446a08b985961a92fed93614049284d0f08665a7a9f1b5dfbb025682a9551f2660f5380f90211a05510ce326198dee0033e6a2b29957f77687221d6f4b9a082f34922f9f589b003a0a6f336170753299b1adc48077e111e425fdc539ff7160a9babf8afdf5b5bef3ea0ad027c813622b3582247847a8537992e0a3f6a50e10c268d0ac8eacd1fd750bba037babb03742053f969204568854a958947fc93bcb978ebc85c83e35c5dc6fdfda07d3c1a847911e962071639472987bf9f0d112c983b393190af796342557a3ac5a07e243717881703400c60ec2fcc05040759a9646b61adb02412c8b0619e3059bda08acbc6de4a6c92f92dde22536a30bbc7bad7d44394e29312ebc9adfcd84ca300a0c558588e6ae83a42eaf44d7215f853262ad725faef6b3c73830e0903a31fefd6a0921f30e12a3b363b2aed7283870304a503f3613d311bae004eb7a922f6fd50f1a013987bb8a564c1513dd7b42682bb7237f51b94ac28780f41ae45a772e13fa76fa0596b2015a656fd4864bf6789cb5d4e4c67cc05114ae3fd7caa8355bd16cb00a7a0dea6e67052bdc0d975f894dbe6b4d7b7474c7bf6f2d0bb9b5298073a5e95a43ca0f532a3b3466a65f1e6e948bd1a9ac5b36bdb0f824609c37046acefb55f76d0b7a021462b95a644603890bea60588a71a17aac1e830fe290f6d9627f6a0ee173de7a0a5f42aa4c2fd149ba3a73028c450d1d3c0c10536bc1421c6e632bd56d63d7565a0156d9f2ce56dfe6e92fe5779b15821b6bae03882935a167a0d3c10e03523f77480f90211a05d176d139f8def1c9dd83692adad161605fdec658eef8bc28afc4da848d97662a0e3d1f706ca6308d1f5e2d4cb6d641ba574b9ad852d6c878f9cec25ba7c8c8183a0f3647cf8efec130e89c09170b6a82a06cf2b9f4b15aff5d2e93d3c8cb5c294f8a071493e91397ece4c52482e3a20656b6780054a56986544555b07f5b053a4d722a0b60b270ab95f7787f4a40d6f68b667126fcb1272ddc0e9347205ebae3069b7d2a0b00e67c2e390212edde83ad1182fc5f373e9f47f11c8c69a04b87d75d0123b15a02f20f6d8f52b12c28ddba6fdca481dcb5a07363ff08758d83f041b2535666b18a0def25dabbdbebbdfef848073b51725528ae2680f9dc8b2371b52d97e5bce5645a0a27b621d4212470161d3a1786d70b24ba6f0ba013677c11e995feebb3f7be72aa0894ac9ee877ef9fc4ea797c33f994996567a17777a57d22050260b18bb994946a09bf44993469f668dadae80170dfb81156b0decb5f7fbceb62980a2508d3f3702a013fc551024f4961a8e4adedb726962975a60ae0553a65f0dd7e266b0ec34f2dca087561bc3f849b47500f1f503a264466616a31a4e7adf3f2b2753b3f8c60444bda0421bcca422a9f02867ab2b0269bad562e8d35bf35bb332a48d3be29b513e4a78a09fe8fdfd9c06692e93cc2f1b277aadebf462a38a28abfaaba33f4d7e4212ed71a0407f10b8182d07c7f9789d469b68926931e184d7afdc20322387db7dd8dd950b80f9011180a0af3e6c1703878fa0f54ce9ef81044131303255beda112c1750bd46e46c17749780808080a0ee3ef4e754b7044fbaf982f80b8ab4ea00503fe3ec4c50fd7864e81ce1e6c4408080a075fb4f68ac224ec54d38eee3bd972654ca5ee1833530f0ebefd71a9f49cf09f1a05c099f09257a656d98101ccd60d3fbe861cb889f9699b8eed136268028021b70a0b90a5365f3205e9df1129eecaa73667c4d2c567f1ab45f63860c3671b46dc27780a0e38b7963499d1bbde43a95289356e98e19cdc1e21e10e097e1490f15e3662e0ba0ce536ccc69891fc11f58ebaa1a9f09bd1644af223c17493de3fa30e6e39f6845a052fe3bf973b9ff06f119a91481e15215c3eccadc584ce8b6e7a05ea68c73054180f8669d3d676334b26bbb561def1bb646db346a0ea5f7c4f069e5ce4083818685b846f8440180a011a7fd82551848c90631f70de7f85bbc1fb9cce3618351c58eef7d86c6e6535da0aad43333d28e146557f1c682e8a4226743fb231fdd00a577512233bd9e920008", + "0x11a7fd82551848c90631f70de7f85bbc1fb9cce3618351c58eef7d86c6e6535d", + ["0x000000000000000000000000000000000000000000000000000000000000000b"], + [ + "0xf909acf90211a024523ab4c6860ddc65f3ee25893718ba117b0b64fa1a344b7f05424044422180a0ed987ec06cf1e724fb46f50e02e985eb14aa3de446a026be814cd2c240ab7884a01f37fe3602f2e817c85a42347aeb852d144d5df315f7ea19e5b946ec41e7710ca007818b958a696e024231c8bbc1940ab6f624063ae6536e78d4e751ace5ba3654a08a2d4ae213e6cd7da762e2a310a4b416794015af976c0df934700d67dcb6bb7da09b8c976db3807d89073d4ece4a434f2fb407dd7babc3d60557d7a6413397cd12a018ee334d7d36b3ec14e7fbe17cb2cc8827327961e20474b07b2d755fb60472eba086fd6918693e8bfec3a0b0b8963d88cca3bb1ff3f40058dcf5e0b8e12ebda780a08a57aa735f5e901686d294bb6a9f0af015bfa37a14e47df442043c55b29478afa0c5fdbed2d6f87128f683e845163c29abebd0fccc8720261233cd1739d8999bb8a0c667f820b9056acb0650bbb3da4fb5c829bb9ea3d58d65ab8e87cfaf689eb274a0110aca3b49ff8a7fc3d60295d0c18602e576427a02907986d3fcdec5c8406607a0e0a2958a4e2e8eb16e37ad795e02d8ea636266b4ea3f4e064a4da9ef1ee8f47aa076561dfa2df8680a70d7f949548502001363378d71e9102b2dc5f6bb8b48b328a0173421253267ac8dacdd78bb3a49e4e68ce44c987335e7e22e2067f5998ccc8ba0ddb9469be4af0c764ae2984533a34b6ac6ad4535a7bf773d1bdcaba414288d4e80f90211a0134f748fc5e8562c4037bb335c253e159c2d3c7a1dc48b1e006fee1ffcc63874a0dcad9ec65f0b0b3e3d265b468ceda4c2626bea957ba6dd0f25e91d8f43615dcba0b8fdad766b78548db43d60da964d1abdd784ae56bd9ad9dd5ce7911beadab941a01db88587d7758f452204d265122d451f416f29219de91d8f1fd98b4695ad56f8a06464403607b9759cf6cb0e1bdd58d3a231ece185267c59d0113836bbce312007a0a23247953c05226318750e90668afd8b8f4a308f1f3e5573f92c03cd4fa9cc99a0ec186ad6ea36e64969fac78982f9ddd2c78f01fb5f059afc8d9253cafb348272a00e259709d156973caac69a52dbde1569f0ea9fc58cc9333b6fff01bed4ced9c3a01f76d216b1d1f75ebdcece38a62dc6d85cf090cec0b17ea8fe4a2fbadf02e418a0a44e06aa48e8e2b81b82ac7a55d10e0e75fb0016475f40b4b2b199016fefef11a04e31f7d98493c4af332a55a088d75bd53a55d37feee0fb4ea4bb89bd6cf1189da01fe39db746e4eef3572d1863d2edf73ef178986a33929a353e30d5a5459cffb7a0c64a8a52d3dfb4c33e5eac53820c25604e4c8f34062e2f31a00ada4c4e8ac794a0ffc8acff839a16fefe9f3018b315c00a5d49b051bf7be70f35c452103e78dd6fa0c371630f7af67645f11a19b70a01e20284fd2c3afa8ad5e72fa939e775090b94a026173df7a5906e6d3ff8ee4f6467dfb731e50961f6d65546a4e6cd3efeaa509a80f90211a046660614c4b352e38c7a40b3fbacf123b88d343407c60aa3df2fc14e5c57667ea0f326e8d140b8c178ef04d4af3f9435159ad3c3cc9029a24daced2a2e5a7edadba04beaf51b9e686b2e9a3cb11906ac2c2b975a1f2b21fae6345baa832716d08904a00d9c648844e04c5a20d669382e429a02691b92a9ed51346e9e6b4c3e11950c51a0116e5123177580be67dfd0beaa66ff0aaad0d390afa05246c44dc8de9736c21ea0c566c23ca1b65aec125de0d781343787ae3f1037793af3d12e976ebc26b25d82a0ecc286af188cbb0d2f91980a6547e9c21d31e436f362565998d38063cb8e4a43a0161332b061fd1ae44a9cc9a7ee560b1f416a75f723df1d4607487149f0a6ef98a0ce4de6144c942d8cb5180aad406ac42934f039bafe6a7b1fba6094b104e3ed01a088da9aca558d0c51ce0fb208ab108b143e0a5122bcd5bd85c35e09b39a67a7ada0b24c5e971bdcc7151c89d69c0046c899379fcb9fd479d2b8a05df7348f08e4bda0bdb15b37b990be1e658ede5ed0e556d73fca185489124cad494721bd0c9dc79da0279294696fab46dcb10b5069d1929b96500342e6609fc85b5c242ebfd6dee280a02b3df2dfda83841f27315d0dcd3025dce8ee53425de4ccea153dd8f9893b65d6a07b3b6cb9b2148a7086adc24501672da8b0fc348a1fa78051ebb603f337f68de8a025f98ef38ab7bbaf176f7284ff1548b7638d013f817fd84979061507c4cb3f8080f90211a0817f0522b611763caedae0abdbf8a7d1fc523cc759bc6dd400d8837d94587832a0ecd37fcea2b496aeb18f74786fc7aeda2ea78bfb55cf27a829b69c4d15e2525ca019a27a34379a6a5dcd5a1cb8fdc5b7351b40eeb3f4e7d09db2daaf688e7a11b8a02339835ad35c836c7c9b1fd17f8ef9aa377a9e458316252ac63efe702fd895bda08e96214ae9077f46f6d2a440af91126a5bf62732edd0dc513efadba4b956fe9ea026370016e564a879e26f01a077e73badcca1551a92a05571e86d07af2a049493a0fab6a8b576dbf710ba642f849c36ab54ed462ac0f8e3593ad6d25af4e6f23677a06ed7fc714f359a29a6bd13c1a804fc6a19938f46c377fc97e787706dc8da0e58a0c0d3305cf25baab40da08bb2c141d0984d60afc353c4d0e708fed92fb2239460a057cdd07f66b3a31f01079d3933ee6a4fd5280ba7abec7c9bc1404ccca5224d9aa0ab9e1abf9a0bfd89d1483448ec555a10d7956b434787ae6c55605ce4c3fbb3e5a0d9d5c4782ba8bceaf3887b440321190898df7ce785679dcc628516de02069a17a05565679c56603a5614f90447648485ba6f3e324df4845af69482209fcc620156a09e4205f6a5c8e633cb7e5048148675d7aef4030de17d81e6d8e5a3e5f5b77a8ba0b995d98c91905fa0e083455afe9d4219e4f040c6e3bdf948b139a8d12b192157a05ed2de5e483fa16f32c9d56979082e36c77c1102e12020136172dfed9c85d28880f90131a0d56f8e12a9254f3fab9b7c5cb9e917dbc2540b1fa8e14f22840257d30c47adbfa0bcf412e2dcc182720eb7a6d3b260488603cefcdc206815beeea0b4700adb9e46808080a0ba844e9671269f0a8ab47cd42fc59e9ff5077adfa3c400e243146fcb708f4e5da0d1e9012aff863e29b5c2b7111ed41b55669bc3bd70aafd9302247c9a71176550a03f9b33fa55d938ae9dd41dfed6b17fc52327d20a2503c8e5d85a2f401a0e6ea380a0d4947649b148740ce5687696c87bb07217543329c73f7bb8900f1140b1563f3ca0c41116acc085e1d1b88f0998eacf59cc10a4646e9ffc4428b221c00ec5b1f4cca08c6b7c02a459200f13e8b385d3dcb998ec8f9c03cc1b7c8b3a5e753d5a65364880a09dc8cbc03d181ee816de24c1baeaa398a7b98e5f33e730011505e8496e74fefd808080e79e37a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db98786b56d157e7f5a", + ], +] + +let hashi: Contract, adapter: Contract, hashiProverTest: Contract, shoyuBashi: Contract, owner: SignerWithAddress + +describe("HashiProver", () => { + beforeEach(async () => { + const Hashi = await ethers.getContractFactory("Hashi") + const MockAdapter = await ethers.getContractFactory("MockAdapter") + const HashiProverTest = await ethers.getContractFactory("HashiProverTest") + const ShoyuBashi = await ethers.getContractFactory("ShoyuBashi") + + const signers = await ethers.getSigners() + owner = signers[0] + + hashi = await Hashi.deploy() + adapter = await MockAdapter.deploy() + shoyuBashi = await ShoyuBashi.deploy(owner.address, hashi.address) + hashiProverTest = await HashiProverTest.deploy(shoyuBashi.address) + + await shoyuBashi.enableAdapters(SOURCE_CHAIN_ID, [adapter.address], 1) + }) + + it("should't be able to get the value if the block is not available", async () => { + await expect(hashiProverTest.getValue(PROOF)).to.be.revertedWithCustomError(shoyuBashi, "ThresholdNotMet") + }) + + it("should be able to get the value", async () => { + await adapter.setHashes(SOURCE_CHAIN_ID, [BLOCK_NUMBER], [BLOCK_HEADER_HASH]) + expect(await hashiProverTest.getValue(PROOF)).to.be.deep.eq(["0xb56d157e7f5a"]) + }) + + it("should be able to get the value using ancestral blocks", async () => { + await adapter.setHashes(SOURCE_CHAIN_ID, [BLOCK_NUMBER], [BLOCK_HEADER_HASH]) + expect(await hashiProverTest.getValue(PROOF_WITH_ANCESTRAL_BLOCKS)).to.be.deep.eq(["0xb56d157e7f5a"]) + }) + + it("should not be able to get the value using ancestral blocks because the length is reached without finding the block", async () => { + const wrongProof = [...PROOF_WITH_ANCESTRAL_BLOCKS] + wrongProof[4] = [ + "0xf90256a06f14ee388c6004c9f591c05cc94509906ebcc57e6ce9d7e65c52aa7da6f530e7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479495222290dd7278aa3ddd389cc1e1d165cc4bafe5a07604903f485d83bda3b1333e28dec61ff3191fef0423ffce44abe02033b323d3a09c6967c2262b8e5aaf07f422806fa22eed9bd05898a71ef3435eb27e258ed240a061cf3a1b00a7ea8e1b8e4a921dbd9af3c73e9ec8646e9884b7936b74e011e05ab901005d61447fd94d1ba8d69022f0b7891c8486f9ae204a03b3b61bbbc905e371ecd613dfbe02ad85113252082314a8e78d016af918d9afd27030b5b7e890842a2f8058103e8c1640a87cd82c733d21e13afc3ce5e133ddd7fd3180a816dc8bfeeaa516555f3bf2545536b6605c1ea8276edf7d076e9346d88e37e24372bec69daa45caa8fe68c4c5edccefefbf60abaa9abee6106cf1dd25dc4fff490c7bf4b1f47993d733a25880a8170f165ed3bb283d69644fb677d0fd763a07218f66249961719ff37e762cf33f76036277f9c2d9e3d5a2a0b6b70cbfbd548a717143e29e3ef4a0f9b17f9f37bc546d06e5d23e02b3c64e2e542f026cf1d4391ccdf19400dc6d8084013d48a48401c9c3808401476c588466edbad78f6265617665726275696c642e6f7267a00b4078ca7a27f9b2448fa3f32e04a269353f80273e6dc95153458475a84238b98800000000000000008502d39a9e8ea00a7c969c5cab15361767d22966b8c0e507572acd096d3bc87af306be3ceb52138080a077f861b303ce5dd4bd241707d60a82406df608caa18ec241e33b5d5a2de94bc2", + "0xf90257a034c4cec5ba48eef207f01dace9b74648f75423b99274d285eb51a28ea45a7746a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347941f9090aae28b8a3dceadf281b0f12828e676c326a017cb8d562b6da86b898d1579f2c0252ca4fc673ddbece39b0181fe6341dbfbb1a0ae9cf403fc193494aabb363f25427aa1adfe15793abe5765d28b0b1537e0900ba0b950d9ad9c7de4e5bd031c14c6d3afd38f1639e1db56590c6abafacae1e8be9bb9010055b5d41511013102900308208e003834d0c002308b480102a0a90901861621a7664ca1054060d40153aa1b99d74229a5c69380c489626d9027c9635a8d3ba580ed1ddc2810e5ef3f788ac929c12470b06160a08901404f2232ac9d42d9fa0785854040174adb01b6a3dd900ac9098e9d842ee6f52e148f0aba80cab721886001aa28bbd6804c7783a158856d63745f924614c4e1cd398c2a6525247746f4116aeb2021e09a52a018635202c32e2dce22379b9d05caf5986b252e4e0c401a11595d31264220a8210f01132022d6695481a4a02847113ce09583c7220200c6603891f33e680597a840000416a199101be82c29d000738c21d03c3b99150db214078084013d48a38401c9c38083b3f8218466edbacb917273796e632d6275696c6465722e78797aa034169fa758cb3cb5d38e8c22af9b88c525474253da05ca76b683f0c6ef922cee8800000000000000008502e776c769a01c91a492ffa0281242fdcb78078b290d5b055505d1872498d611f8cf295496818080a0686d3a40a3dd6df623831fd87b3c54877f9717001c997f9f9e1758c864df5634", + ] + await adapter.setHashes(SOURCE_CHAIN_ID, [BLOCK_NUMBER], [BLOCK_HEADER_HASH]) + expect(await hashiProverTest.getValue(PROOF_WITH_ANCESTRAL_BLOCKS)).to.be.revertedWithCustomError( + hashiProverTest, + "AncestralBlockHeadersLengthReached", + ) + }) + + it("should not be able to get the value using ancestral blocks because of a conflict", async () => { + const wrongProof = [...PROOF_WITH_ANCESTRAL_BLOCKS] + wrongProof[4] = [ + "0xf90256a06f14ee388c6004c9f591c05cc94509906ebcc57e6ce9d7e65c52aa7da6f530e7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479495222290dd7278aa3ddd389cc1e1d165cc4bafe5a07604903f485d83bda3b1333e28dec61ff3191fef0423ffce44abe02033b323d3a09c6967c2262b8e5aaf07f422806fa22eed9bd05898a71ef3435eb27e258ed240a061cf3a1b00a7ea8e1b8e4a921dbd9af3c73e9ec8646e9884b7936b74e011e05ab901005d61447fd94d1ba8d69022f0b7891c8486f9ae204a03b3b61bbbc905e371ecd613dfbe02ad85113252082314a8e78d016af918d9afd27030b5b7e890842a2f8058103e8c1640a87cd82c733d21e13afc3ce5e133ddd7fd3180a816dc8bfeeaa516555f3bf2545536b6605c1ea8276edf7d076e9346d88e37e24372bec69daa45caa8fe68c4c5edccefefbf60abaa9abee6106cf1dd25dc4fff490c7bf4b1f47993d733a25880a8170f165ed3bb283d69644fb677d0fd763a07218f66249961719ff37e762cf33f76036277f9c2d9e3d5a2a0b6b70cbfbd548a717143e29e3ef4a0f9b17f9f37bc546d06e5d23e02b3c64e2e542f026cf1d4391ccdf19400dc6d8084013d48a48401c9c3808401476c588466edbad78f6265617665726275696c642e6f7267a00b4078ca7a27f9b2448fa3f32e04a269353f80273e6dc95153458475a84238b98800000000000000008502d39a9e8ea00a7c969c5cab15361767d22966b8c0e507572acd096d3bc87af306be3ceb52138080a077f861b303ce5dd4bd241707d60a82406df608caa18ec241e33b5d5a2de94bc2", + "0xf90257a034c4cec5ba48eef207f01dace9b74648f75423b99274d285eb51a28ea45a7746a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347941f9090aae28b8a3dceadf281b0f12828e676c326a017cb8d562b6da86b898d1579f2c0252ca4fc673ddbece39b0181fe6341dbfbb1a0ae9cf403fc193494aabb363f25427aa1adfe15793abe5765d28b0b1537e0900ba0b950d9ad9c7de4e5bd031c14c6d3afd38f1639e1db56590c6abafacae1e8be9bb9010055b5d41511013102900308208e003834d0c002308b480102a0a90901861621a7664ca1054060d40153aa1b99d74229a5c69380c489626d9027c9635a8d3ba580ed1ddc2810e5ef3f788ac929c12470b06160a08901404f2232ac9d42d9fa0785854040174adb01b6a3dd900ac9098e9d842ee6f52e148f0aba80cab721886001aa28bbd6804c7783a158856d63745f924614c4e1cd398c2a6525247746f4116aeb2021e09a52a018635202c32e2dce22379b9d05caf5986b252e4e0c401a11595d31264220a8210f01132022d6695481a4a02847113ce09583c7220200c6603891f33e680597a840000416a199101be82c29d000738c21d03c3b99150db214078084013d48a38401c9c38083b3f8218466edbacb917273796e632d6275696c6465722e78797aa034169fa758cb3cb5d38e8c22af9b88c525474253da05ca76b683f0c6ef922cee8800000000000000008502e776c769a01c91a492ffa0281242fdcb78078b290d5b055505d1872498d611f8cf295496818080a0686d3a40a3dd6df623831fd87b3c54877f9717001c997f9f9e1758c864df5634", + "0xf9025ba03f60781072e20bd526b224ff426c9784c24a949e977ad855585fc76c897d509fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479495222290dd7278aa3ddd389cc1e1d165cc4bafe5a021c619739b6e81e67572203fb27f00c390e605a6fef0fe41c59f226853b082aba050885bd6330e2d1e68c236f561bcea587cfde066214e1fd0ca396d5574685a1da00f98eb31cf5b863de6be609e3389a276cdd0f5247ab142bba2210bcb5133d7d7b9010013f1cd759bd4d129b3bc004786899411332acb21690da0fe8cad091d3a35e08220c245663a4a52b01e4cda40d80f2fc1d2ad9988a862ee76672c504a032fc546d78187483ae99a39f89bd13ebde02ab494a3b071ed61dda0ac304eeaf83ac988d55bb445077b71e2a0c8c08d29496a11223b0387e5150c3620059c7c688dd1554a091f5492678d624c6d916063e43956c49dc589cd61013a60a345c7e1f65622bbbc4b9d5419e000ab03b6ef3ce98e82855d2f2748e6820988478101217e81ade1532542a5d11f555011218feb43548f47eb67c742392c7439c70e5be26174b5e5f32cfe83956d41a88413c522f2cfb0febf952d59b816e98a595fa1a18396e58084013d48a28401c9c38083d4d7678466edbabf8f6265617665726275696c642e6f7267a06f3f13b39fc3605558c21368794faf69b5edc4639f5f191fedbb9145f547fd7e8800000000000000008502ee08d0f0a0c3da7cb220020e2b5c78854d4e0822ed99dfeb75ff41a4066cd5c7b27e8943f88302000083040000a0f5decec30ba81918d464d9692fd3e0660f0f0247714899e77787b9b3e2fb2260", + ] + await adapter.setHashes(SOURCE_CHAIN_ID, [BLOCK_NUMBER], [BLOCK_HEADER_HASH]) + expect(await hashiProverTest.getValue(PROOF_WITH_ANCESTRAL_BLOCKS)).to.be.revertedWithCustomError( + hashiProverTest, + "ConflictingBlockHeader", + ) + }) +}) diff --git a/packages/rpc/.env.example b/packages/rpc/.env.example new file mode 100644 index 00000000..5c46bb15 --- /dev/null +++ b/packages/rpc/.env.example @@ -0,0 +1,2 @@ +PORT= +JSON_RPC_URL_1= \ No newline at end of file diff --git a/packages/rpc/.eslintignore b/packages/rpc/.eslintignore new file mode 100644 index 00000000..b68087da --- /dev/null +++ b/packages/rpc/.eslintignore @@ -0,0 +1,2 @@ +**/dist +**/node_modules \ No newline at end of file diff --git a/packages/rpc/.eslintrc.yml b/packages/rpc/.eslintrc.yml new file mode 100644 index 00000000..27672a35 --- /dev/null +++ b/packages/rpc/.eslintrc.yml @@ -0,0 +1,21 @@ +extends: + - "eslint:recommended" + - "plugin:@typescript-eslint/eslint-recommended" + - "plugin:@typescript-eslint/recommended" + - "prettier" +parser: "@typescript-eslint/parser" +parserOptions: + project: "tsconfig.json" +plugins: + - "@typescript-eslint" +root: true +rules: + "@typescript-eslint/no-floating-promises": + - error + - ignoreIIFE: true + ignoreVoid: true + "@typescript-eslint/no-inferrable-types": "off" + "@typescript-eslint/no-unused-vars": + - error + - argsIgnorePattern: "_" + varsIgnorePattern: "_" diff --git a/packages/rpc/.prettierignore b/packages/rpc/.prettierignore new file mode 100644 index 00000000..b68087da --- /dev/null +++ b/packages/rpc/.prettierignore @@ -0,0 +1,2 @@ +**/dist +**/node_modules \ No newline at end of file diff --git a/packages/rpc/.prettierrc.yml b/packages/rpc/.prettierrc.yml new file mode 100644 index 00000000..e9bada2e --- /dev/null +++ b/packages/rpc/.prettierrc.yml @@ -0,0 +1,7 @@ +bracketSpacing: true +printWidth: 120 +proseWrap: "always" +singleQuote: false +tabWidth: 2 +trailingComma: "all" +semi: false diff --git a/packages/rpc/nodemon.json b/packages/rpc/nodemon.json new file mode 100644 index 00000000..094036ef --- /dev/null +++ b/packages/rpc/nodemon.json @@ -0,0 +1,5 @@ +{ + "watch": ["src"], + "ext": "ts,json", + "exec": "ts-node ./src/index.ts" +} diff --git a/packages/rpc/package.json b/packages/rpc/package.json new file mode 100644 index 00000000..65404eda --- /dev/null +++ b/packages/rpc/package.json @@ -0,0 +1,40 @@ +{ + "name": "@gnosis/hashi-rpc", + "private": true, + "version": "0.1.0", + "scripts": { + "compile": "tsc", + "lint": "eslint --ignore-path ./.eslintignore --ext .js,.ts .", + "prettier:check": "prettier --check \"**/*.{js,json,md,sol,ts,yml}\"", + "prettier:write": "prettier --write \"**/*.{js,json,md,sol,ts,yml}\"", + "start": "node --loader ts-node/esm ./src/index.ts", + "start:prod": "node ./dist/index.js", + "start:dev": "nodemon" + }, + "dependencies": { + "@ethereumjs/block": "^5.3.0", + "@ethereumjs/common": "^4.4.0", + "@ethereumjs/rlp": "^5.0.2", + "@ethereumjs/util": "^9.0.3", + "@gnosis/hashi-common": "0.1.0", + "body-parser": "^1.20.2", + "dotenv": "^16.4.5", + "ethers": "^6.13.2", + "express": "^4.19.2", + "json-rpc-2.0": "^1.7.0", + "kzg-wasm": "^0.4.0" + }, + "devDependencies": { + "@tsconfig/node22": "^22.0.0", + "@types/express": "^4.17.21", + "@types/node": "^20.8.9", + "@typescript-eslint/eslint-plugin": "^6.7.5", + "@typescript-eslint/parser": "^6.7.5", + "eslint": "^8.51.0", + "eslint-config-prettier": "^9.0.0", + "nodemon": "^3.0.1", + "prettier": "^3.3.2", + "ts-node": "^10.9.1", + "typescript": "^5.2.2" + } +} diff --git a/packages/rpc/src/index.ts b/packages/rpc/src/index.ts new file mode 100644 index 00000000..be4da8b7 --- /dev/null +++ b/packages/rpc/src/index.ts @@ -0,0 +1,34 @@ +import "dotenv/config" +import express from "express" +import bodyParser from "body-parser" +import { JSONRPCServer, TypedJSONRPCServer } from "json-rpc-2.0" +import { logger } from "@gnosis/hashi-common" + +import logMiddleware from "./middlewares/log" +import getAccountAndStorageProof from "./methods/get-account-and-storage-proof" +import { Methods } from "./methods/types" + +const start = async () => { + const server: TypedJSONRPCServer = new JSONRPCServer() + server.addMethod("hashi_getAccountAndStorageProof", getAccountAndStorageProof) + server.applyMiddleware(logMiddleware) + + const app = express() + app.use(bodyParser.json()) + + app.post("/v1", (_req, _res) => { + const jsonRPCRequest = _req.body + server.receive(jsonRPCRequest).then((_jsonRPCResponse) => { + if (_jsonRPCResponse) { + _res.json(_jsonRPCResponse) + } else { + _res.sendStatus(204) + } + }) + }) + + app.listen(process.env.PORT) + logger.info(`Server listening on port ${process.env.PORT} ...`) +} + +start() diff --git a/packages/rpc/src/methods/get-account-and-storage-proof.ts b/packages/rpc/src/methods/get-account-and-storage-proof.ts new file mode 100644 index 00000000..c539fb8d --- /dev/null +++ b/packages/rpc/src/methods/get-account-and-storage-proof.ts @@ -0,0 +1,132 @@ +import "dotenv/config" +import { ethers } from "ethers" +import { logger } from "@gnosis/hashi-common" +import { BlockHeader, JsonRpcBlock } from "@ethereumjs/block" +import { Common, Hardfork } from "@ethereumjs/common" +import { RLP } from "@ethereumjs/rlp" +import { + bigIntToHex, + bytesToHex, + intToHex, +} from "@ethereumjs/util" + +import { GetAccountAndStorageProofParams, GetAccountAndStorageProofResponse } from "../types" + +export function blockHeaderFromRpc(_block: JsonRpcBlock) { + const { + parentHash, + sha3Uncles, + miner, + stateRoot, + transactionsRoot, + receiptsRoot, + logsBloom, + difficulty, + number, + gasLimit, + gasUsed, + timestamp, + extraData, + mixHash, + nonce, + baseFeePerGas, + withdrawalsRoot, + blobGasUsed, + excessBlobGas, + parentBeaconBlockRoot, + requestsRoot, + } = _block + + return { + parentHash, + uncleHash: sha3Uncles, + coinbase: miner, + stateRoot, + transactionsTrie: transactionsRoot, + receiptTrie: receiptsRoot, + logsBloom, + difficulty, + number, + gasLimit, + gasUsed, + timestamp, + extraData, + mixHash, + nonce, + baseFeePerGas, + withdrawalsRoot, + blobGasUsed, + excessBlobGas, + parentBeaconBlockRoot, + requestsRoot, + } +} + +const getAccountAndStorageProof = async ({ + address, + ancestralBlockNumber = 0, + blockNumber, + chainId, + storageKeys, +}: GetAccountAndStorageProofParams) => { + try { + const rpcUrl = process.env[`JSON_RPC_URL_${chainId}`] + if (!rpcUrl) throw new Error("Chain not supported") + + const common = Common.custom( + { + chainId, + }, + { + hardfork: Hardfork.Cancun, + eips: [1559, 4895, 4844, 4788], + }, + ) + + const provider = new ethers.JsonRpcProvider(rpcUrl) + + const [proof, block] = await Promise.all([ + provider.send("eth_getProof", [address, storageKeys, bigIntToHex(BigInt(ancestralBlockNumber || blockNumber))]), + provider.send("eth_getBlockByNumber", [intToHex(blockNumber), false]), + ]) + const blockHeader = BlockHeader.fromHeaderData(blockHeaderFromRpc(block), { common }) + + let ancestralBlockHeaders = [] as `0x${string}`[] + if (ancestralBlockNumber !== 0) { + if (ancestralBlockNumber >= blockNumber) throw new Error("Invalid ancestral block number") + + const blockNumbers = [...Array(blockNumber - ancestralBlockNumber + 1).keys()].map( + (num) => num + ancestralBlockNumber, + ) + ancestralBlockHeaders = ( + await Promise.all( + blockNumbers.map((_blockNumber) => provider.send("eth_getBlockByNumber", [intToHex(_blockNumber), false])), + ) + ) + .map((_block) => bytesToHex(BlockHeader.fromHeaderData(blockHeaderFromRpc(_block), { common }).serialize())) + .reverse() + } + + return { + proof: [ + chainId, + blockNumber, + bytesToHex(blockHeader.serialize()), + ancestralBlockNumber, + ancestralBlockHeaders, + address, + bytesToHex(RLP.encode(proof.accountProof.map((_sibling: string) => RLP.decode(_sibling)))), + proof.storageHash, + proof.storageProof.map(({ key }: any) => key), + proof.storageProof.map(({ proof: storageProof }: any) => + bytesToHex(RLP.encode(storageProof.map((_sibling: string) => RLP.decode(_sibling)))), + ), + ], + } as GetAccountAndStorageProofResponse + } catch (_err) { + logger.error(_err) + throw _err + } +} + +export default getAccountAndStorageProof diff --git a/packages/rpc/src/methods/types.ts b/packages/rpc/src/methods/types.ts new file mode 100644 index 00000000..20499eee --- /dev/null +++ b/packages/rpc/src/methods/types.ts @@ -0,0 +1,5 @@ +import { GetAccountAndStorageProofParams, GetAccountAndStorageProofResponse } from "../types" + +export type Methods = { + hashi_getAccountAndStorageProof(params: GetAccountAndStorageProofParams): GetAccountAndStorageProofResponse +} diff --git a/packages/rpc/src/middlewares/log.ts b/packages/rpc/src/middlewares/log.ts new file mode 100644 index 00000000..64decbde --- /dev/null +++ b/packages/rpc/src/middlewares/log.ts @@ -0,0 +1,12 @@ +import { JSONRPCRequest, JSONRPCResponse, JSONRPCServerMiddlewareNext } from "json-rpc-2.0" +import { logger } from "@gnosis/hashi-common" + +const logMiddleware = (_next: JSONRPCServerMiddlewareNext, _request: JSONRPCRequest, _params: any) => { + logger.info(`Received ${JSON.stringify(_request)}`) + return _next(_request, _params).then((_response: JSONRPCResponse | null) => { + logger.info(`Responding ${JSON.stringify(_response)}`) + return _response + }) +} + +export default logMiddleware diff --git a/packages/rpc/src/types/index.ts b/packages/rpc/src/types/index.ts new file mode 100644 index 00000000..ec1af0a6 --- /dev/null +++ b/packages/rpc/src/types/index.ts @@ -0,0 +1,24 @@ +export type AccountAndStorageProof = [ + number, + number, + `0x${string}`, + number, + `0x${string}`[], + `0x${string}`, + `0x${string}`, + `0x${string}`, + `0x${string}`[], + `0x${string}`, +] + +export type GetAccountAndStorageProofParams = { + address: `0x${string}` + ancestralBlockNumber?: number + blockNumber: number + chainId: number + storageKeys: `0x${string}`[] +} + +export type GetAccountAndStorageProofResponse = { + proof: AccountAndStorageProof +} diff --git a/packages/rpc/tsconfig.json b/packages/rpc/tsconfig.json new file mode 100644 index 00000000..e6d845c2 --- /dev/null +++ b/packages/rpc/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "@tsconfig/node22/tsconfig.json", + "compilerOptions": { + "outDir": "./dist" + } +} diff --git a/yarn.lock b/yarn.lock index d155c39b..3ea890c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,6 +7,11 @@ resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7" integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q== +"@adraffy/ens-normalize@1.10.1": + version "1.10.1" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" + integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== + "@axelar-network/axelar-gmp-sdk-solidity@5.6.4": version "5.6.4" resolved "https://registry.yarnpkg.com/@axelar-network/axelar-gmp-sdk-solidity/-/axelar-gmp-sdk-solidity-5.6.4.tgz#fe224ff039f86f1cbf72d9b53339a8354f531b65" @@ -356,6 +361,25 @@ bufio "^1.0.7" chai "^4.3.4" +"@ethereumjs/block@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/block/-/block-5.3.0.tgz#a22d615f825a3aa123189434263a6c1d43d4ac8f" + integrity sha512-cyphdEB/ywIERqWLRHdAS6muTkAcd6BibMOp6XmGbeWgvtIhe4ArxcMDI78MVstJzT/faihvRI4rKQKy+MpdKQ== + dependencies: + "@ethereumjs/common" "^4.4.0" + "@ethereumjs/rlp" "^5.0.2" + "@ethereumjs/trie" "^6.2.1" + "@ethereumjs/tx" "^5.4.0" + "@ethereumjs/util" "^9.1.0" + ethereum-cryptography "^2.2.1" + +"@ethereumjs/common@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-4.4.0.tgz#fba41612f527a815bf304e98653d6b5fc5d6d4de" + integrity sha512-Fy5hMqF6GsE6DpYTyqdDIJPJgUtDn4dL120zKw+Pswuo+iLyBsEYuSyzMw6NVzD2vDzcBG9fE4+qX4X2bPc97w== + dependencies: + "@ethereumjs/util" "^9.1.0" + "@ethereumjs/rlp@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41" @@ -366,6 +390,29 @@ resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-5.0.2.tgz#c89bd82f2f3bec248ab2d517ae25f5bbc4aac842" integrity sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA== +"@ethereumjs/trie@^6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/trie/-/trie-6.2.1.tgz#11d3e91ffd7d565f468a62c0e3d7952063991fa9" + integrity sha512-MguABMVi/dPtgagK+SuY57rpXFP+Ghr2x+pBDy+e3VmMqUY+WGzFu1QWjBb5/iJ7lINk4CI2Uwsih07Nu9sTSg== + dependencies: + "@ethereumjs/rlp" "^5.0.2" + "@ethereumjs/util" "^9.1.0" + "@types/readable-stream" "^2.3.13" + debug "^4.3.4" + ethereum-cryptography "^2.2.1" + lru-cache "10.1.0" + readable-stream "^3.6.0" + +"@ethereumjs/tx@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-5.4.0.tgz#6f47894cc3e2d4e63d87c62b41ed7e8180a1de58" + integrity sha512-SCHnK7m/AouZ7nyoR0MEXw1OO/tQojSbp88t8oxhwes5iZkZCtfFdUrJaiIb72qIpH2FVw6s1k1uP7LXuH7PsA== + dependencies: + "@ethereumjs/common" "^4.4.0" + "@ethereumjs/rlp" "^5.0.2" + "@ethereumjs/util" "^9.1.0" + ethereum-cryptography "^2.2.1" + "@ethereumjs/util@^8.1.0": version "8.1.0" resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-8.1.0.tgz#299df97fb6b034e0577ce9f94c7d9d1004409ed4" @@ -375,7 +422,7 @@ ethereum-cryptography "^2.0.0" micro-ftch "^0.3.1" -"@ethereumjs/util@^9.0.3": +"@ethereumjs/util@^9.0.3", "@ethereumjs/util@^9.1.0": version "9.1.0" resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-9.1.0.tgz#75e3898a3116d21c135fa9e29886565609129bce" integrity sha512-XBEKsYqLGXLah9PNJbgdkigthkG7TAGvlD/sH12beMXEyHDyigfcbdvHhmLyDWgDyOJn4QwiQUaF7yeuhnjdog== @@ -1567,6 +1614,11 @@ dependencies: undici-types "~6.19.2" +"@types/node@18.15.13": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== + "@types/node@20.5.1": version "20.5.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.1.tgz#178d58ee7e4834152b0e8b4d30cbfab578b9bb30" @@ -1984,6 +2036,11 @@ aes-js@3.0.0: resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== +aes-js@4.0.0-beta.5: + version "4.0.0-beta.5" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873" + integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -2043,13 +2100,6 @@ ansi-escapes@^4.3.0: dependencies: type-fest "^0.21.3" -ansi-escapes@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-7.0.0.tgz#00fc19f491bbb18e1d481b97868204f92109bfe7" - integrity sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw== - dependencies: - environment "^1.0.0" - ansi-regex@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" @@ -2060,11 +2110,6 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-regex@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" - integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA== - ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -2079,11 +2124,6 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ansi-styles@^6.0.0, ansi-styles@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - antlr4@^4.11.0: version "4.13.2" resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.13.2.tgz#0d084ad0e32620482a9c3a0e2470c02e72e4006d" @@ -2519,11 +2559,6 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@~5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" - integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== - "charenc@>= 0.0.1": version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" @@ -2585,13 +2620,6 @@ clean-stack@^2.0.0: resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== -cli-cursor@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-5.0.0.tgz#24a4831ecf5a6b01ddeb32fb71a4b2088b0dce38" - integrity sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw== - dependencies: - restore-cursor "^5.0.0" - cli-table3@^0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" @@ -2602,14 +2630,6 @@ cli-table3@^0.5.0: optionalDependencies: colors "^1.1.2" -cli-truncate@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-4.0.0.tgz#6cc28a2924fee9e25ce91e973db56c7066e6172a" - integrity sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA== - dependencies: - slice-ansi "^5.0.0" - string-width "^7.0.0" - cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -2668,11 +2688,6 @@ color@^3.1.3: color-convert "^1.9.3" color-string "^1.6.0" -colorette@^2.0.20: - version "2.0.20" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" - integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== - colors@1.4.0, colors@^1.1.2: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" @@ -2733,11 +2748,6 @@ commander@^2.20.3: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@~12.1.0: - version "12.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-12.1.0.tgz#01423b36f501259fdaac4d0e4d60c96c991585d3" - integrity sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA== - compare-func@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-2.0.0.tgz#fb65e75edbddfd2e568554e8b5b05fff7a51fcb3" @@ -2896,7 +2906,7 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4, debug@^4, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.3.5, debug@~4.3.6: +debug@4, debug@^4, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.3.5: version "4.3.7" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== @@ -3005,7 +3015,7 @@ dot-prop@^5.1.0: dependencies: is-obj "^2.0.0" -dotenv@^16.0.3, dotenv@^16.3.1: +dotenv@^16.0.3, dotenv@^16.3.1, dotenv@^16.4.5: version "16.4.5" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== @@ -3045,11 +3055,6 @@ elliptic@^6.5.2, elliptic@^6.5.4: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" -emoji-regex@^10.3.0: - version "10.4.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.4.0.tgz#03553afea80b3975749cfcb36f776ca268e413d4" - integrity sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw== - emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -3088,11 +3093,6 @@ env-paths@^2.2.0: resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== -environment@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/environment/-/environment-1.1.0.tgz#8e86c66b180f363c7ab311787e0259665f45a9f1" - integrity sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q== - error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" @@ -3424,6 +3424,19 @@ ethers@^5.7.0, ethers@^5.7.1, ethers@^5.7.2: "@ethersproject/web" "5.7.1" "@ethersproject/wordlists" "5.7.0" +ethers@^6.13.2: + version "6.13.2" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.2.tgz#4b67d4b49e69b59893931a032560999e5e4419fe" + integrity sha512-9VkriTTed+/27BGuY1s0hf441kqwHJ1wtN2edksEtiRvXx+soxRX3iSXTfFqq2+YwrOqbDoTHjIhQnjJRlzKmg== + dependencies: + "@adraffy/ens-normalize" "1.10.1" + "@noble/curves" "1.2.0" + "@noble/hashes" "1.3.2" + "@types/node" "18.15.13" + aes-js "4.0.0-beta.5" + tslib "2.4.0" + ws "8.17.1" + ethjs-unit@0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" @@ -3468,21 +3481,6 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -execa@~8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-8.0.1.tgz#51f6a5943b580f963c3ca9c6321796db8cc39b8c" - integrity sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^8.0.1" - human-signals "^5.0.0" - is-stream "^3.0.0" - merge-stream "^2.0.0" - npm-run-path "^5.1.0" - onetime "^6.0.0" - signal-exit "^4.1.0" - strip-final-newline "^3.0.0" - express@^4.19.2: version "4.21.0" resolved "https://registry.yarnpkg.com/express/-/express-4.21.0.tgz#d57cb706d49623d4ac27833f1cbc466b668eb915" @@ -3813,11 +3811,6 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-east-asian-width@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz#5e6ebd9baee6fb8b7b6bd505221065f0cd91f64e" - integrity sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA== - get-func-name@^2.0.1, get-func-name@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" @@ -3844,11 +3837,6 @@ get-stream@^6.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== -get-stream@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-8.0.1.tgz#def9dfd71742cd7754a7761ed43749a27d02eca2" - integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA== - ghost-testrpc@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz#c4de9557b1d1ae7b2d20bbe474a91378ca90ce92" @@ -4256,11 +4244,6 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -human-signals@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28" - integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== - humanize-ms@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" @@ -4273,11 +4256,6 @@ husky@^8.0.3: resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.3.tgz#4936d7212e46d1dea28fef29bb3a108872cd9184" integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg== -husky@^9.0.11: - version "9.1.6" - resolved "https://registry.yarnpkg.com/husky/-/husky-9.1.6.tgz#e23aa996b6203ab33534bdc82306b0cf2cb07d6c" - integrity sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A== - iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -4412,18 +4390,6 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-fullwidth-code-point@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" - integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== - -is-fullwidth-code-point@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz#9609efced7c2f97da7b60145ef481c787c7ba704" - integrity sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA== - dependencies: - get-east-asian-width "^1.0.0" - is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -4466,11 +4432,6 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== -is-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" - integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== - is-text-path@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" @@ -4691,6 +4652,11 @@ kuler@^2.0.0: resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== +kzg-wasm@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/kzg-wasm/-/kzg-wasm-0.4.0.tgz#362048470e25fb9683eefa9d2b076283ae653fa0" + integrity sha512-hKEwFbKrY1LZnAH5gY8+PlVWfkGnj2wd2tc83eIgzuC4NoshXqplW9OzGlBDqpAmXxwhiN8fgPG2+NcvUIBSwg== + level-supports@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" @@ -4729,44 +4695,11 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -lilconfig@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.2.tgz#e4a7c3cb549e3a606c8dcc32e5ae1005e62c05cb" - integrity sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow== - lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -lint-staged@^15.2.7: - version "15.2.10" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-15.2.10.tgz#92ac222f802ba911897dcf23671da5bb80643cd2" - integrity sha512-5dY5t743e1byO19P9I4b3x8HJwalIznL5E1FWYnU6OWw33KxNBSLAc6Cy7F2PsFEO8FKnLwjwm5hx7aMF0jzZg== - dependencies: - chalk "~5.3.0" - commander "~12.1.0" - debug "~4.3.6" - execa "~8.0.1" - lilconfig "~3.1.2" - listr2 "~8.2.4" - micromatch "~4.0.8" - pidtree "~0.6.0" - string-argv "~0.3.2" - yaml "~2.5.0" - -listr2@~8.2.4: - version "8.2.4" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-8.2.4.tgz#486b51cbdb41889108cb7e2c90eeb44519f5a77f" - integrity sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g== - dependencies: - cli-truncate "^4.0.0" - colorette "^2.0.20" - eventemitter3 "^5.0.1" - log-update "^6.1.0" - rfdc "^1.4.1" - wrap-ansi "^9.0.0" - locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -4862,17 +4795,6 @@ log-symbols@^4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -log-update@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-6.1.0.tgz#1a04ff38166f94647ae1af562f4bd6a15b1b7cd4" - integrity sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w== - dependencies: - ansi-escapes "^7.0.0" - cli-cursor "^5.0.0" - slice-ansi "^7.1.0" - strip-ansi "^7.1.0" - wrap-ansi "^9.0.0" - logform@^2.6.0, logform@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/logform/-/logform-2.6.1.tgz#71403a7d8cae04b2b734147963236205db9b3df0" @@ -4892,6 +4814,11 @@ loupe@^2.3.6: dependencies: get-func-name "^2.0.1" +lru-cache@10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484" + integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -5016,7 +4943,7 @@ micro-ftch@^0.3.1: resolved "https://registry.yarnpkg.com/micro-ftch/-/micro-ftch-0.3.1.tgz#6cb83388de4c1f279a034fb0cf96dfc050853c5f" integrity sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg== -micromatch@^4.0.2, micromatch@^4.0.4, micromatch@~4.0.8: +micromatch@^4.0.2, micromatch@^4.0.4: version "4.0.8" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== @@ -5046,16 +4973,6 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -mimic-fn@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" - integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== - -mimic-function@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/mimic-function/-/mimic-function-5.0.1.tgz#acbe2b3349f99b9deaca7fb70e48b83e94e67076" - integrity sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA== - min-indent@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" @@ -5301,13 +5218,6 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" -npm-run-path@^5.1.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.3.0.tgz#e23353d0ebb9317f174e93417e4a4d82d0249e9f" - integrity sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ== - dependencies: - path-key "^4.0.0" - number-to-bn@1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" @@ -5364,20 +5274,6 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -onetime@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" - integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== - dependencies: - mimic-fn "^4.0.0" - -onetime@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-7.0.0.tgz#9f16c92d8c9ef5120e3acd9dd9957cceecc1ab60" - integrity sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ== - dependencies: - mimic-function "^5.0.0" - open@^7.4.2: version "7.4.2" resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" @@ -5552,11 +5448,6 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-key@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" - integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== - path-parse@^1.0.6, path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" @@ -5598,11 +5489,6 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pidtree@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c" - integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== - pify@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" @@ -5874,24 +5760,11 @@ resolve@^1.1.6, resolve@^1.10.0, resolve@^1.8.1: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -restore-cursor@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-5.1.0.tgz#0766d95699efacb14150993f55baf0953ea1ebe7" - integrity sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA== - dependencies: - onetime "^7.0.0" - signal-exit "^4.1.0" - reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rfdc@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" - integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== - rimraf@^2.2.8, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" @@ -6142,11 +6015,6 @@ signal-exit@^3.0.3: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -signal-exit@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== - simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" @@ -6180,22 +6048,6 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" -slice-ansi@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a" - integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== - dependencies: - ansi-styles "^6.0.0" - is-fullwidth-code-point "^4.0.0" - -slice-ansi@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-7.1.0.tgz#cd6b4655e298a8d1bdeb04250a433094b347b9a9" - integrity sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg== - dependencies: - ansi-styles "^6.2.1" - is-fullwidth-code-point "^5.0.0" - solc@0.7.3: version "0.7.3" resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" @@ -6363,11 +6215,6 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== -string-argv@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" - integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== - string-format@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" @@ -6390,15 +6237,6 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^7.0.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-7.2.0.tgz#b5bb8e2165ce275d4d43476dd2700ad9091db6dc" - integrity sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ== - dependencies: - emoji-regex "^10.3.0" - get-east-asian-width "^1.0.0" - strip-ansi "^7.1.0" - string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -6427,23 +6265,11 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-final-newline@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" - integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== - strip-hex-prefix@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" @@ -6692,6 +6518,11 @@ ts-node@^10.8.1, ts-node@^10.9.1, ts-node@^10.9.2: v8-compile-cache-lib "^3.0.1" yn "3.1.1" +tslib@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + tslib@^1.8.1, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" @@ -6950,7 +6781,7 @@ viem@^1.16.5: isows "1.0.3" ws "8.13.0" -viem@^2.17.5, viem@^2.9.28: +viem@^2.9.28: version "2.21.14" resolved "https://registry.yarnpkg.com/viem/-/viem-2.21.14.tgz#2ce78d52d43dd97103102fcb0852b973a911f478" integrity sha512-uM6XmY9Q/kJRVSopJAGsakmtNDpk/EswqXUzwOp9DzhGuwgpWtw2MgwpfFdIyqBDFIw+TTypCIUTcwJSgEYSzA== @@ -7036,7 +6867,7 @@ winston-transport@^4.7.0: readable-stream "^3.6.2" triple-beam "^1.3.0" -winston@^3.11.0, winston@^3.13.1: +winston@^3.11.0: version "3.14.2" resolved "https://registry.yarnpkg.com/winston/-/winston-3.14.2.tgz#94ce5fd26d374f563c969d12f0cd9c641065adab" integrity sha512-CO8cdpBB2yqzEf8v895L+GNKYJiEq8eKlHU38af3snQBQ+sdAIUepjMSguOIJC7ICbzm0ZI+Af2If4vIJrtmOg== @@ -7085,15 +6916,6 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-9.0.0.tgz#1a3dc8b70d85eeb8398ddfb1e4a02cd186e58b3e" - integrity sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q== - dependencies: - ansi-styles "^6.2.1" - string-width "^7.0.0" - strip-ansi "^7.1.0" - wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -7139,7 +6961,7 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^2.2.2, yaml@~2.5.0: +yaml@^2.2.2: version "2.5.1" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.1.tgz#c9772aacf62cb7494a95b0c4f1fb065b563db130" integrity sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==