diff --git a/.changeset/remove-ibc-oracle-precompiles.md b/.changeset/remove-ibc-oracle-precompiles.md index 2da185e11..cb2782668 100644 --- a/.changeset/remove-ibc-oracle-precompiles.md +++ b/.changeset/remove-ibc-oracle-precompiles.md @@ -2,6 +2,8 @@ '@sei-js/precompiles': major --- -**Breaking:** remove the IBC and Oracle precompiles. `IBC_PRECOMPILE_ADDRESS`, `IBC_PRECOMPILE_ABI`, `ETHERS_IBC_PRECOMPILE_ABI`, `getIbcPrecompileEthersV6Contract`, `VIEM_IBC_PRECOMPILE_ABI`, `ORACLE_PRECOMPILE_ADDRESS`, `ORACLE_PRECOMPILE_ABI`, `ETHERS_ORACLE_PRECOMPILE_ABI`, `getOraclePrecompileEthersV6Contract`, and `VIEM_ORACLE_PRECOMPILE_ABI` are no longer exported. +**Breaking:** remove the unsupported IBC and Oracle precompile addresses, ABIs, and Ethers factories. Neither precompile is supported on Sei any more, so calls to them fail on-chain regardless of where the address and ABI come from. There is no drop-in replacement: re-declaring them locally will not restore working calls, and code still depending on them needs to move off these precompiles. + +Also remove the redundant Viem-specific ABI aliases. Import the raw `*_PRECOMPILE_ABI` constants instead; they work directly with Viem and preserve literal types for contract inference. The `viem` subpath re-exports these raw constants alongside the Sei chain definitions. diff --git a/.changeset/sync-v66-precompiles.md b/.changeset/sync-v66-precompiles.md new file mode 100644 index 000000000..5cdcd6faa --- /dev/null +++ b/.changeset/sync-v66-precompiles.md @@ -0,0 +1,7 @@ +--- +'@sei-js/precompiles': minor +--- + +Sync the exported precompile ABIs with Sei Chain v6.6.1. + +This adds the P256 precompile address, ABI, and Ethers factory. It also adds the missing staking queries and events, governance proposal methods, distribution events and validator commission withdrawal, JSON array extraction, and CW1155 pointer methods. diff --git a/biome.json b/biome.json index 0f6e3e01f..aa65ec242 100644 --- a/biome.json +++ b/biome.json @@ -15,6 +15,7 @@ "!**/bun.lock", "!packages/create-sei/templates", "!packages/create-sei/extensions", + "!packages/precompiles/src/__tests__/fixtures/v66", "!packages/registry/chain-registry", "!packages/registry/community-assetlist" ] diff --git a/packages/create-sei/extensions/precompiles/src/components/default/index.tsx b/packages/create-sei/extensions/precompiles/src/components/default/index.tsx index 852646090..d2e250a64 100644 --- a/packages/create-sei/extensions/precompiles/src/components/default/index.tsx +++ b/packages/create-sei/extensions/precompiles/src/components/default/index.tsx @@ -3,10 +3,9 @@ import { CodeHighlight } from '@mantine/code-highlight'; import { ActionIcon, Badge, Button, Card, Collapse, Container, Flex, Group, Paper, Stack, Text, ThemeIcon, Title } from '@mantine/core'; import { notifications } from '@mantine/notifications'; -import { BANK_PRECOMPILE_ADDRESS, VIEM_BANK_PRECOMPILE_ABI } from '@sei-js/precompiles'; +import { BANK_PRECOMPILE_ABI, BANK_PRECOMPILE_ADDRESS } from '@sei-js/precompiles'; import { IconBulb, IconChevronDown, IconChevronUp, IconCopy, IconDatabase } from '@tabler/icons-react'; import { useState } from 'react'; -import type { ReadContractParameters } from 'viem'; import { usePublicClient } from 'wagmi'; function Examples() { @@ -49,16 +48,14 @@ function Examples() { return undefined; } - const readContractParams: ReadContractParameters = { - abi: VIEM_BANK_PRECOMPILE_ABI, - address: BANK_PRECOMPILE_ADDRESS, - functionName: 'supply', - args: ['usei'] - }; - try { - const result = await publicClient.readContract(readContractParams); - setSupply((result as bigint).toString()); + const result = await publicClient.readContract({ + abi: BANK_PRECOMPILE_ABI, + address: BANK_PRECOMPILE_ADDRESS, + functionName: 'supply', + args: ['usei'] + }); + setSupply(result.toString()); } catch (error) { console.error('Error fetching supply:', error); notifications.show({ @@ -70,21 +67,19 @@ function Examples() { }; const codeExample = `// Sei Precompile Example - Bank Precompile -import { BANK_PRECOMPILE_ADDRESS, VIEM_BANK_PRECOMPILE_ABI } from '@sei-js/precompiles'; +import { BANK_PRECOMPILE_ABI, BANK_PRECOMPILE_ADDRESS } from '@sei-js/precompiles'; import { usePublicClient } from 'wagmi'; const publicClient = usePublicClient(); const getSeiSupply = async () => { - const readContractParams = { - abi: VIEM_BANK_PRECOMPILE_ABI, + const result = await publicClient?.readContract({ + abi: BANK_PRECOMPILE_ABI, address: BANK_PRECOMPILE_ADDRESS, functionName: 'supply', args: ['usei'], - }; - - const result = await publicClient?.readContract(readContractParams); - return (result as bigint).toString(); + }); + return result?.toString(); };`; return ( diff --git a/packages/create-sei/templates/next-template/src/components/default/examples.ts b/packages/create-sei/templates/next-template/src/components/default/examples.ts index b7eb8c73d..fbae6a2bb 100644 --- a/packages/create-sei/templates/next-template/src/components/default/examples.ts +++ b/packages/create-sei/templates/next-template/src/components/default/examples.ts @@ -26,22 +26,19 @@ const weiBalance = await publicClient.getBalance({ address }); const seiBalance = formatEther(weiBalance);`; export const precompileCodeExample = `// Import Sei precompiles -import { VIEM_BANK_PRECOMPILE_ABI, BANK_PRECOMPILE_ADDRESS } from '@sei-js/precompiles'; +import { BANK_PRECOMPILE_ABI, BANK_PRECOMPILE_ADDRESS } from '@sei-js/precompiles'; import { usePublicClient } from 'wagmi'; -import { type ReadContractParameters } from 'viem'; // Use the hook const publicClient = usePublicClient(); // Call precompile -const readContractParams: ReadContractParameters = { - abi: VIEM_BANK_PRECOMPILE_ABI, +const result = await publicClient.readContract({ + abi: BANK_PRECOMPILE_ABI, address: BANK_PRECOMPILE_ADDRESS, functionName: 'supply', args: ['usei'] -}; - -const result = await publicClient.readContract(readContractParams);`; +});`; export const transactionCodeExample = `// Import transaction hooks import { useSendTransaction, useWaitForTransactionReceipt } from 'wagmi'; diff --git a/packages/precompiles/README.md b/packages/precompiles/README.md index 36a87175c..e882c20ec 100644 --- a/packages/precompiles/README.md +++ b/packages/precompiles/README.md @@ -7,23 +7,59 @@ [![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?logo=typescript&logoColor=white)](https://www.typescriptlang.org/) [![Sei Network](https://img.shields.io/badge/Sei-Network-red)](https://sei.io) -**TypeScript utilities for interacting with Sei's precompile contracts** +TypeScript ABIs, addresses, and Ethers/Viem helpers for Sei precompiles. [GitHub](https://github.com/sei-protocol/sei-js) • [NPM](https://www.npmjs.com/package/@sei-js/precompiles) • [Telegram](https://t.me/+LPW_1djQwRQwMzlk) -## 🚀 Quick Start +## Install ```bash npm install @sei-js/precompiles ``` -Works seamlessly with your favorite Ethereum development tools: -- **Viem** - Type-safe contract interactions -- **Ethers.js** - Contract factories and utilities -- **Wagmi** - React hooks for precompile contracts -- **Hardhat/Foundry** - Testing and deployment +## Sei Chain compatibility + +The exported ABIs match [Sei Chain v6.6.1](https://github.com/sei-protocol/sei-chain/tree/v6.6.1/precompiles). The `legacy/v66` directory is a frozen historical snapshot for that release, not a moving view of the current chain surface. Chain and package versions are independent; adopting a later Sei Chain minor snapshot is treated as at least a minor release of `@sei-js/precompiles`. + +This package exports: + +- Bank at `0x0000000000000000000000000000000000001001` +- CosmWasm at `0x0000000000000000000000000000000000001002` +- JSON at `0x0000000000000000000000000000000000001003` +- Address association at `0x0000000000000000000000000000000000001004` +- Staking at `0x0000000000000000000000000000000000001005` +- Governance at `0x0000000000000000000000000000000000001006` +- Distribution at `0x0000000000000000000000000000000000001007` +- Pointer view at `0x000000000000000000000000000000000000100A` +- Pointer registration at `0x000000000000000000000000000000000000100B` +- Solo migration at `0x000000000000000000000000000000000000100C` +- P256 verification at `0x0000000000000000000000000000000000001011` + +Oracle and IBC are intentionally excluded: the [v6.6.1 Oracle implementation returns a retired error for every query](https://github.com/sei-protocol/sei-chain/blob/v6.6.1/precompiles/oracle/oracle.go#L85-L104), and [SIP-03 disabled IBC in both directions](https://docs.sei.io/learn/sip-03-migration#ibc-is-disabled). Calls to either cannot succeed on live Sei. Some ABI methods can also be disabled by chain governance. Check the [Sei precompile docs](https://docs.sei.io/evm/precompiles/example-usage) before using a deprecated module or method. + +## Usage + +Addresses and raw `as const` ABIs are available from the package root and the `precompiles` and `viem` entrypoints. They work directly with Viem and preserve full type inference. Ethers factories are available from the `ethers` entrypoint. + +```ts +import { STAKING_PRECOMPILE_ABI, STAKING_PRECOMPILE_ADDRESS } from '@sei-js/precompiles'; +import { getStakingPrecompileEthersV6Contract } from '@sei-js/precompiles/ethers'; +``` + +With a configured Viem public client, the v6.6 staking query methods can be called directly: + +```ts +const result = await publicClient.readContract({ + address: STAKING_PRECOMPILE_ADDRESS, + abi: STAKING_PRECOMPILE_ABI, + functionName: 'validators', + args: ['BOND_STATUS_BONDED', '0x'] +}); + +console.log(result.validators, result.nextKey); +``` ## Sei chain definitions diff --git a/packages/precompiles/src/__tests__/barrelParity.spec.ts b/packages/precompiles/src/__tests__/barrelParity.spec.ts index 3060fe5d3..bd5b310a2 100644 --- a/packages/precompiles/src/__tests__/barrelParity.spec.ts +++ b/packages/precompiles/src/__tests__/barrelParity.spec.ts @@ -2,7 +2,7 @@ import * as ethersBarrel from '../ethers'; import * as precompilesBarrel from '../precompiles'; import * as viemBarrel from '../viem'; -const precompileNamesFrom = (barrel: Record, prefix: '' | 'ETHERS_' | 'VIEM_'): string[] => { +const precompileNamesFrom = (barrel: Record, prefix: '' | 'ETHERS_'): string[] => { const pattern = new RegExp(`^${prefix}([A-Z0-9]+)_PRECOMPILE_ABI$`); return Object.keys(barrel) @@ -14,7 +14,7 @@ const precompileNamesFrom = (barrel: Record, prefix: '' | 'ETHE describe('Precompile barrel parity', () => { const precompileNames = precompileNamesFrom(precompilesBarrel, ''); const ethersNames = precompileNamesFrom(ethersBarrel, 'ETHERS_'); - const viemNames = precompileNamesFrom(viemBarrel, 'VIEM_'); + const viemNames = precompileNamesFrom(viemBarrel, ''); // Without this the three comparisons below would pass on three empty sets if the // ABI naming convention ever changes out from under the pattern above. diff --git a/packages/precompiles/src/__tests__/fixtures/v66/README.md b/packages/precompiles/src/__tests__/fixtures/v66/README.md new file mode 100644 index 000000000..4d72acc56 --- /dev/null +++ b/packages/precompiles/src/__tests__/fixtures/v66/README.md @@ -0,0 +1,5 @@ +# Sei Chain v6.6 ABI fixtures + +The JSON files in this directory are verbatim copies of `precompiles/*/legacy/v66/abi.json` from the [`v6.6.1`](https://github.com/sei-protocol/sei-chain/tree/v6.6.1/precompiles) tag of `sei-chain`. + +The parity test compares the package's TypeScript ABI constants with these independently vendored fixtures. IBC and Oracle are retained here to document the complete frozen snapshot, but they are intentionally not exported by `@sei-js/precompiles`. diff --git a/packages/precompiles/src/__tests__/fixtures/v66/addr.json b/packages/precompiles/src/__tests__/fixtures/v66/addr.json new file mode 100644 index 000000000..f0425eaf8 --- /dev/null +++ b/packages/precompiles/src/__tests__/fixtures/v66/addr.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"string","name":"v","type":"string"},{"internalType":"string","name":"r","type":"string"},{"internalType":"string","name":"s","type":"string"},{"internalType":"string","name":"customMessage","type":"string"}],"name":"associate","outputs":[{"internalType":"string","name":"seiAddr","type":"string"},{"internalType":"address","name":"evmAddr","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"pubKeyHex","type":"string"}],"name":"associatePubKey","outputs":[{"internalType":"string","name":"seiAddr","type":"string"},{"internalType":"address","name":"evmAddr","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getSeiAddr","outputs":[{"internalType":"string","name":"response","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"addr","type":"string"}],"name":"getEvmAddr","outputs":[{"internalType":"address","name":"response","type":"address"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/packages/precompiles/src/__tests__/fixtures/v66/bank.json b/packages/precompiles/src/__tests__/fixtures/v66/bank.json new file mode 100644 index 000000000..844ac4894 --- /dev/null +++ b/packages/precompiles/src/__tests__/fixtures/v66/bank.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address","name":"acc","type":"address"}],"name":"all_balances","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"denom","type":"string"}],"internalType":"struct IBank.Coin[]","name":"response","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"acc","type":"address"},{"internalType":"string","name":"denom","type":"string"}],"name":"balance","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"denom","type":"string"}],"name":"decimals","outputs":[{"internalType":"uint8","name":"response","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"denom","type":"string"}],"name":"name","outputs":[{"internalType":"string","name":"response","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fromAddress","type":"address"},{"internalType":"address","name":"toAddress","type":"address"},{"internalType":"string","name":"denom","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"send","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"toNativeAddress","type":"string"}],"name":"sendNative","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"denom","type":"string"}],"name":"supply","outputs":[{"internalType":"uint256","name":"response","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"denom","type":"string"}],"name":"symbol","outputs":[{"internalType":"string","name":"response","type":"string"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/packages/precompiles/src/__tests__/fixtures/v66/distribution.json b/packages/precompiles/src/__tests__/fixtures/v66/distribution.json new file mode 100644 index 000000000..cc5781977 --- /dev/null +++ b/packages/precompiles/src/__tests__/fixtures/v66/distribution.json @@ -0,0 +1 @@ +[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":false,"internalType":"string","name":"validator","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DelegationRewardsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":false,"internalType":"string[]","name":"validators","type":"string[]"},{"indexed":false,"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"MultipleDelegationRewardsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"validator","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ValidatorCommissionWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":false,"internalType":"address","name":"withdrawAddr","type":"address"}],"name":"WithdrawAddressSet","type":"event"},{"inputs":[{"internalType":"address","name":"delegatorAddress","type":"address"}],"name":"rewards","outputs":[{"components":[{"components":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"string","name":"denom","type":"string"}],"internalType":"struct IDistr.Coin[]","name":"coins","type":"tuple[]"},{"internalType":"string","name":"validator_address","type":"string"}],"internalType":"struct IDistr.Reward[]","name":"rewards","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"string","name":"denom","type":"string"}],"internalType":"struct IDistr.Coin[]","name":"total","type":"tuple[]"}],"internalType":"struct IDistr.Rewards","name":"rewards","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"withdrawAddr","type":"address"}],"name":"setWithdrawAddress","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"validator","type":"string"}],"name":"withdrawDelegationRewards","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string[]","name":"validators","type":"string[]"}],"name":"withdrawMultipleDelegationRewards","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawValidatorCommission","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/packages/precompiles/src/__tests__/fixtures/v66/gov.json b/packages/precompiles/src/__tests__/fixtures/v66/gov.json new file mode 100644 index 000000000..1c0a870cc --- /dev/null +++ b/packages/precompiles/src/__tests__/fixtures/v66/gov.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"string","name":"proposalJSON","type":"string"}],"name":"submitProposal","outputs":[{"internalType":"uint64","name":"proposalID","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint64","name":"proposalID","type":"uint64"}],"name":"deposit","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint64","name":"proposalID","type":"uint64"},{"internalType":"int32","name":"option","type":"int32"}],"name":"vote","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"proposalID","type":"uint64"},{"components":[{"internalType":"int32","name":"option","type":"int32"},{"internalType":"string","name":"weight","type":"string"}],"internalType":"struct WeightedVoteOption[]","name":"options","type":"tuple[]"}],"name":"voteWeighted","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] diff --git a/packages/precompiles/src/__tests__/fixtures/v66/ibc.json b/packages/precompiles/src/__tests__/fixtures/v66/ibc.json new file mode 100644 index 000000000..5c2809d2d --- /dev/null +++ b/packages/precompiles/src/__tests__/fixtures/v66/ibc.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"string","name":"toAddress","type":"string"},{"internalType":"string","name":"port","type":"string"},{"internalType":"string","name":"channel","type":"string"},{"internalType":"string","name":"denom","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint64","name":"revisionNumber","type":"uint64"},{"internalType":"uint64","name":"revisionHeight","type":"uint64"},{"internalType":"uint64","name":"timeoutTimestamp","type":"uint64"},{"internalType":"string","name":"memo","type":"string"}],"name":"transfer","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"toAddress","type":"string"},{"internalType":"string","name":"port","type":"string"},{"internalType":"string","name":"channel","type":"string"},{"internalType":"string","name":"denom","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"memo","type":"string"}],"name":"transferWithDefaultTimeout","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] diff --git a/packages/precompiles/src/__tests__/fixtures/v66/json.json b/packages/precompiles/src/__tests__/fixtures/v66/json.json new file mode 100644 index 000000000..48bd4c6f2 --- /dev/null +++ b/packages/precompiles/src/__tests__/fixtures/v66/json.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"bytes","name":"input","type":"bytes"},{"internalType":"string","name":"key","type":"string"}],"name":"extractAsBytes","outputs":[{"internalType":"bytes","name":"response","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"input","type":"bytes"},{"internalType":"string","name":"key","type":"string"}],"name":"extractAsBytesList","outputs":[{"internalType":"bytes[]","name":"response","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"input","type":"bytes"},{"internalType":"string","name":"key","type":"string"}],"name":"extractAsUint256","outputs":[{"internalType":"uint256","name":"response","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"input","type":"bytes"},{"internalType":"uint16","name":"arrayIndex","type":"uint16"}],"name":"extractAsBytesFromArray","outputs":[{"internalType":"bytes","name":"response","type":"bytes"}],"stateMutability":"view","type":"function"}] diff --git a/packages/precompiles/src/__tests__/fixtures/v66/oracle.json b/packages/precompiles/src/__tests__/fixtures/v66/oracle.json new file mode 100644 index 000000000..1bb91d96a --- /dev/null +++ b/packages/precompiles/src/__tests__/fixtures/v66/oracle.json @@ -0,0 +1 @@ +[{"inputs":[],"name":"getExchangeRates","outputs":[{"components":[{"internalType":"string","name":"denom","type":"string"},{"components":[{"internalType":"string","name":"exchangeRate","type":"string"},{"internalType":"string","name":"lastUpdate","type":"string"},{"internalType":"int64","name":"lastUpdateTimestamp","type":"int64"}],"internalType":"struct IOracle.OracleExchangeRate","name":"oracleExchangeRateVal","type":"tuple"}],"internalType":"struct IOracle.DenomOracleExchangeRatePair[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"lookback_seconds","type":"uint64"}],"name":"getOracleTwaps","outputs":[{"components":[{"internalType":"string","name":"denom","type":"string"},{"internalType":"string","name":"twap","type":"string"},{"internalType":"int64","name":"lookbackSeconds","type":"int64"}],"internalType":"struct IOracle.OracleTwap[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/packages/precompiles/src/__tests__/fixtures/v66/p256.json b/packages/precompiles/src/__tests__/fixtures/v66/p256.json new file mode 100644 index 000000000..b1f354141 --- /dev/null +++ b/packages/precompiles/src/__tests__/fixtures/v66/p256.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"verify","outputs":[{"internalType":"bytes","name":"response","type":"bytes"}],"stateMutability":"view","type":"function"}] diff --git a/packages/precompiles/src/__tests__/fixtures/v66/pointer.json b/packages/precompiles/src/__tests__/fixtures/v66/pointer.json new file mode 100644 index 000000000..6f96c1959 --- /dev/null +++ b/packages/precompiles/src/__tests__/fixtures/v66/pointer.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"string","name":"cwAddr","type":"string"}],"name":"addCW1155Pointer","outputs":[{"internalType":"address","name":"ret","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"cwAddr","type":"string"}],"name":"addCW20Pointer","outputs":[{"internalType":"address","name":"ret","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"cwAddr","type":"string"}],"name":"addCW721Pointer","outputs":[{"internalType":"address","name":"ret","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"token","type":"string"}],"name":"addNativePointer","outputs":[{"internalType":"address","name":"ret","type":"address"}],"stateMutability":"payable","type":"function"}] \ No newline at end of file diff --git a/packages/precompiles/src/__tests__/fixtures/v66/pointerview.json b/packages/precompiles/src/__tests__/fixtures/v66/pointerview.json new file mode 100644 index 000000000..c089390d1 --- /dev/null +++ b/packages/precompiles/src/__tests__/fixtures/v66/pointerview.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"string","name":"cwAddr","type":"string"}],"name":"getCW1155Pointer","outputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint16","name":"version","type":"uint16"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"cwAddr","type":"string"}],"name":"getCW20Pointer","outputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint16","name":"version","type":"uint16"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"cwAddr","type":"string"}],"name":"getCW721Pointer","outputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint16","name":"version","type":"uint16"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"token","type":"string"}],"name":"getNativePointer","outputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint16","name":"version","type":"uint16"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/packages/precompiles/src/__tests__/fixtures/v66/solo.json b/packages/precompiles/src/__tests__/fixtures/v66/solo.json new file mode 100644 index 000000000..37adc6f0e --- /dev/null +++ b/packages/precompiles/src/__tests__/fixtures/v66/solo.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"claim","outputs":[{"internalType":"bool","name":"response","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"claimSpecific","outputs":[{"internalType":"bool","name":"response","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/packages/precompiles/src/__tests__/fixtures/v66/staking.json b/packages/precompiles/src/__tests__/fixtures/v66/staking.json new file mode 100644 index 000000000..a6584f25c --- /dev/null +++ b/packages/precompiles/src/__tests__/fixtures/v66/staking.json @@ -0,0 +1 @@ +[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":false,"internalType":"string","name":"validator","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Delegate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":false,"internalType":"string","name":"validator","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DelegationRewardsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":false,"internalType":"string","name":"srcValidator","type":"string"},{"indexed":false,"internalType":"string","name":"dstValidator","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Redelegate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":false,"internalType":"string","name":"validator","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Undelegate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"creator","type":"address"},{"indexed":false,"internalType":"string","name":"validatorAddress","type":"string"},{"indexed":false,"internalType":"string","name":"moniker","type":"string"}],"name":"ValidatorCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"editor","type":"address"},{"indexed":false,"internalType":"string","name":"validatorAddress","type":"string"},{"indexed":false,"internalType":"string","name":"moniker","type":"string"}],"name":"ValidatorEdited","type":"event"},{"inputs":[{"internalType":"string","name":"pubKeyHex","type":"string"},{"internalType":"string","name":"moniker","type":"string"},{"internalType":"string","name":"commissionRate","type":"string"},{"internalType":"string","name":"commissionMaxRate","type":"string"},{"internalType":"string","name":"commissionMaxChangeRate","type":"string"},{"internalType":"uint256","name":"minSelfDelegation","type":"uint256"}],"name":"createValidator","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"valAddress","type":"string"}],"name":"delegate","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"delegator","type":"address"},{"internalType":"string","name":"valAddress","type":"string"}],"name":"delegation","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"denom","type":"string"}],"internalType":"struct IStaking.Balance","name":"balance","type":"tuple"},{"components":[{"internalType":"string","name":"delegator_address","type":"string"},{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"string","name":"validator_address","type":"string"}],"internalType":"struct IStaking.DelegationDetails","name":"delegation","type":"tuple"}],"internalType":"struct IStaking.Delegation","name":"delegation","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegator","type":"address"},{"internalType":"bytes","name":"nextKey","type":"bytes"}],"name":"delegatorDelegations","outputs":[{"components":[{"components":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"denom","type":"string"}],"internalType":"struct IStaking.Balance","name":"balance","type":"tuple"},{"components":[{"internalType":"string","name":"delegator_address","type":"string"},{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"string","name":"validator_address","type":"string"}],"internalType":"struct IStaking.DelegationDetails","name":"delegation","type":"tuple"}],"internalType":"struct IStaking.Delegation[]","name":"delegations","type":"tuple[]"},{"internalType":"bytes","name":"nextKey","type":"bytes"}],"internalType":"struct IStaking.DelegationsResponse","name":"response","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegator","type":"address"},{"internalType":"bytes","name":"nextKey","type":"bytes"}],"name":"delegatorUnbondingDelegations","outputs":[{"components":[{"components":[{"internalType":"string","name":"delegatorAddress","type":"string"},{"internalType":"string","name":"validatorAddress","type":"string"},{"components":[{"internalType":"int64","name":"creationHeight","type":"int64"},{"internalType":"int64","name":"completionTime","type":"int64"},{"internalType":"string","name":"initialBalance","type":"string"},{"internalType":"string","name":"balance","type":"string"}],"internalType":"struct IStaking.UnbondingDelegationEntry[]","name":"entries","type":"tuple[]"}],"internalType":"struct IStaking.UnbondingDelegation[]","name":"unbondingDelegations","type":"tuple[]"},{"internalType":"bytes","name":"nextKey","type":"bytes"}],"internalType":"struct IStaking.UnbondingDelegationsResponse","name":"response","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegator","type":"address"},{"internalType":"string","name":"validatorAddress","type":"string"}],"name":"delegatorValidator","outputs":[{"components":[{"internalType":"string","name":"operatorAddress","type":"string"},{"internalType":"bytes","name":"consensusPubkey","type":"bytes"},{"internalType":"bool","name":"jailed","type":"bool"},{"internalType":"int32","name":"status","type":"int32"},{"internalType":"string","name":"tokens","type":"string"},{"internalType":"string","name":"delegatorShares","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"int64","name":"unbondingHeight","type":"int64"},{"internalType":"int64","name":"unbondingTime","type":"int64"},{"internalType":"string","name":"commissionRate","type":"string"},{"internalType":"string","name":"commissionMaxRate","type":"string"},{"internalType":"string","name":"commissionMaxChangeRate","type":"string"},{"internalType":"int64","name":"commissionUpdateTime","type":"int64"},{"internalType":"string","name":"minSelfDelegation","type":"string"}],"internalType":"struct IStaking.Validator","name":"validator","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegator","type":"address"},{"internalType":"bytes","name":"nextKey","type":"bytes"}],"name":"delegatorValidators","outputs":[{"components":[{"components":[{"internalType":"string","name":"operatorAddress","type":"string"},{"internalType":"bytes","name":"consensusPubkey","type":"bytes"},{"internalType":"bool","name":"jailed","type":"bool"},{"internalType":"int32","name":"status","type":"int32"},{"internalType":"string","name":"tokens","type":"string"},{"internalType":"string","name":"delegatorShares","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"int64","name":"unbondingHeight","type":"int64"},{"internalType":"int64","name":"unbondingTime","type":"int64"},{"internalType":"string","name":"commissionRate","type":"string"},{"internalType":"string","name":"commissionMaxRate","type":"string"},{"internalType":"string","name":"commissionMaxChangeRate","type":"string"},{"internalType":"int64","name":"commissionUpdateTime","type":"int64"},{"internalType":"string","name":"minSelfDelegation","type":"string"}],"internalType":"struct IStaking.Validator[]","name":"validators","type":"tuple[]"},{"internalType":"bytes","name":"nextKey","type":"bytes"}],"internalType":"struct IStaking.ValidatorsResponse","name":"response","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"moniker","type":"string"},{"internalType":"string","name":"commissionRate","type":"string"},{"internalType":"uint256","name":"minSelfDelegation","type":"uint256"}],"name":"editValidator","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int64","name":"height","type":"int64"}],"name":"historicalInfo","outputs":[{"components":[{"internalType":"int64","name":"height","type":"int64"},{"components":[{"internalType":"string","name":"operatorAddress","type":"string"},{"internalType":"bytes","name":"consensusPubkey","type":"bytes"},{"internalType":"bool","name":"jailed","type":"bool"},{"internalType":"int32","name":"status","type":"int32"},{"internalType":"string","name":"tokens","type":"string"},{"internalType":"string","name":"delegatorShares","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"int64","name":"unbondingHeight","type":"int64"},{"internalType":"int64","name":"unbondingTime","type":"int64"},{"internalType":"string","name":"commissionRate","type":"string"},{"internalType":"string","name":"commissionMaxRate","type":"string"},{"internalType":"string","name":"commissionMaxChangeRate","type":"string"},{"internalType":"int64","name":"commissionUpdateTime","type":"int64"},{"internalType":"string","name":"minSelfDelegation","type":"string"}],"internalType":"struct IStaking.Validator[]","name":"validators","type":"tuple[]"}],"internalType":"struct IStaking.HistoricalInfo","name":"historicalInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"params","outputs":[{"components":[{"internalType":"uint64","name":"unbondingTime","type":"uint64"},{"internalType":"uint32","name":"maxValidators","type":"uint32"},{"internalType":"uint32","name":"maxEntries","type":"uint32"},{"internalType":"uint32","name":"historicalEntries","type":"uint32"},{"internalType":"string","name":"bondDenom","type":"string"},{"internalType":"string","name":"minCommissionRate","type":"string"},{"internalType":"string","name":"maxVotingPowerRatio","type":"string"},{"internalType":"string","name":"maxVotingPowerEnforcementThreshold","type":"string"}],"internalType":"struct IStaking.Params","name":"params","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pool","outputs":[{"components":[{"internalType":"string","name":"notBondedTokens","type":"string"},{"internalType":"string","name":"bondedTokens","type":"string"}],"internalType":"struct IStaking.Pool","name":"pool","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"srcAddress","type":"string"},{"internalType":"string","name":"dstAddress","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"redelegate","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"delegator","type":"string"},{"internalType":"string","name":"srcValidator","type":"string"},{"internalType":"string","name":"dstValidator","type":"string"},{"internalType":"bytes","name":"nextKey","type":"bytes"}],"name":"redelegations","outputs":[{"components":[{"components":[{"internalType":"string","name":"delegatorAddress","type":"string"},{"internalType":"string","name":"validatorSrcAddress","type":"string"},{"internalType":"string","name":"validatorDstAddress","type":"string"},{"components":[{"internalType":"int64","name":"creationHeight","type":"int64"},{"internalType":"int64","name":"completionTime","type":"int64"},{"internalType":"string","name":"initialBalance","type":"string"},{"internalType":"string","name":"sharesDst","type":"string"}],"internalType":"struct IStaking.RedelegationEntry[]","name":"entries","type":"tuple[]"}],"internalType":"struct IStaking.Redelegation[]","name":"redelegations","type":"tuple[]"},{"internalType":"bytes","name":"nextKey","type":"bytes"}],"internalType":"struct IStaking.RedelegationsResponse","name":"response","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegator","type":"address"},{"internalType":"string","name":"validatorAddress","type":"string"}],"name":"unbondingDelegation","outputs":[{"components":[{"internalType":"string","name":"delegatorAddress","type":"string"},{"internalType":"string","name":"validatorAddress","type":"string"},{"components":[{"internalType":"int64","name":"creationHeight","type":"int64"},{"internalType":"int64","name":"completionTime","type":"int64"},{"internalType":"string","name":"initialBalance","type":"string"},{"internalType":"string","name":"balance","type":"string"}],"internalType":"struct IStaking.UnbondingDelegationEntry[]","name":"entries","type":"tuple[]"}],"internalType":"struct IStaking.UnbondingDelegation","name":"unbondingDelegation","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"valAddress","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"undelegate","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"validatorAddress","type":"string"}],"name":"validator","outputs":[{"components":[{"internalType":"string","name":"operatorAddress","type":"string"},{"internalType":"bytes","name":"consensusPubkey","type":"bytes"},{"internalType":"bool","name":"jailed","type":"bool"},{"internalType":"int32","name":"status","type":"int32"},{"internalType":"string","name":"tokens","type":"string"},{"internalType":"string","name":"delegatorShares","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"int64","name":"unbondingHeight","type":"int64"},{"internalType":"int64","name":"unbondingTime","type":"int64"},{"internalType":"string","name":"commissionRate","type":"string"},{"internalType":"string","name":"commissionMaxRate","type":"string"},{"internalType":"string","name":"commissionMaxChangeRate","type":"string"},{"internalType":"int64","name":"commissionUpdateTime","type":"int64"},{"internalType":"string","name":"minSelfDelegation","type":"string"}],"internalType":"struct IStaking.Validator","name":"validator","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"validatorAddress","type":"string"},{"internalType":"bytes","name":"nextKey","type":"bytes"}],"name":"validatorDelegations","outputs":[{"components":[{"components":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"denom","type":"string"}],"internalType":"struct IStaking.Balance","name":"balance","type":"tuple"},{"components":[{"internalType":"string","name":"delegator_address","type":"string"},{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"string","name":"validator_address","type":"string"}],"internalType":"struct IStaking.DelegationDetails","name":"delegation","type":"tuple"}],"internalType":"struct IStaking.Delegation[]","name":"delegations","type":"tuple[]"},{"internalType":"bytes","name":"nextKey","type":"bytes"}],"internalType":"struct IStaking.DelegationsResponse","name":"response","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"validatorAddress","type":"string"},{"internalType":"bytes","name":"nextKey","type":"bytes"}],"name":"validatorUnbondingDelegations","outputs":[{"components":[{"components":[{"internalType":"string","name":"delegatorAddress","type":"string"},{"internalType":"string","name":"validatorAddress","type":"string"},{"components":[{"internalType":"int64","name":"creationHeight","type":"int64"},{"internalType":"int64","name":"completionTime","type":"int64"},{"internalType":"string","name":"initialBalance","type":"string"},{"internalType":"string","name":"balance","type":"string"}],"internalType":"struct IStaking.UnbondingDelegationEntry[]","name":"entries","type":"tuple[]"}],"internalType":"struct IStaking.UnbondingDelegation[]","name":"unbondingDelegations","type":"tuple[]"},{"internalType":"bytes","name":"nextKey","type":"bytes"}],"internalType":"struct IStaking.UnbondingDelegationsResponse","name":"response","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"status","type":"string"},{"internalType":"bytes","name":"nextKey","type":"bytes"}],"name":"validators","outputs":[{"components":[{"components":[{"internalType":"string","name":"operatorAddress","type":"string"},{"internalType":"bytes","name":"consensusPubkey","type":"bytes"},{"internalType":"bool","name":"jailed","type":"bool"},{"internalType":"int32","name":"status","type":"int32"},{"internalType":"string","name":"tokens","type":"string"},{"internalType":"string","name":"delegatorShares","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"int64","name":"unbondingHeight","type":"int64"},{"internalType":"int64","name":"unbondingTime","type":"int64"},{"internalType":"string","name":"commissionRate","type":"string"},{"internalType":"string","name":"commissionMaxRate","type":"string"},{"internalType":"string","name":"commissionMaxChangeRate","type":"string"},{"internalType":"int64","name":"commissionUpdateTime","type":"int64"},{"internalType":"string","name":"minSelfDelegation","type":"string"}],"internalType":"struct IStaking.Validator[]","name":"validators","type":"tuple[]"},{"internalType":"bytes","name":"nextKey","type":"bytes"}],"internalType":"struct IStaking.ValidatorsResponse","name":"response","type":"tuple"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/packages/precompiles/src/__tests__/fixtures/v66/wasmd.json b/packages/precompiles/src/__tests__/fixtures/v66/wasmd.json new file mode 100644 index 000000000..c5e5b1b3f --- /dev/null +++ b/packages/precompiles/src/__tests__/fixtures/v66/wasmd.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"string","name":"contractAddress","type":"string"},{"internalType":"bytes","name":"msg","type":"bytes"},{"internalType":"bytes","name":"coins","type":"bytes"}],"name":"execute","outputs":[{"internalType":"bytes","name":"response","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"contractAddress","type":"string"},{"internalType":"bytes","name":"msg","type":"bytes"},{"internalType":"bytes","name":"coins","type":"bytes"}],"internalType":"struct IWasmd.ExecuteMsg[]","name":"executeMsgs","type":"tuple[]"}],"name":"execute_batch","outputs":[{"internalType":"bytes[]","name":"responses","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint64","name":"codeID","type":"uint64"},{"internalType":"string","name":"admin","type":"string"},{"internalType":"bytes","name":"msg","type":"bytes"},{"internalType":"string","name":"label","type":"string"},{"internalType":"bytes","name":"coins","type":"bytes"}],"name":"instantiate","outputs":[{"internalType":"string","name":"contractAddr","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"contractAddress","type":"string"},{"internalType":"bytes","name":"req","type":"bytes"}],"name":"query","outputs":[{"internalType":"bytes","name":"response","type":"bytes"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/packages/precompiles/src/__tests__/v66AbiParity.spec.ts b/packages/precompiles/src/__tests__/v66AbiParity.spec.ts new file mode 100644 index 000000000..f6b030b91 --- /dev/null +++ b/packages/precompiles/src/__tests__/v66AbiParity.spec.ts @@ -0,0 +1,84 @@ +import { readdirSync, readFileSync } from 'node:fs'; +import { + ADDRESS_PRECOMPILE_ABI, + ADDRESS_PRECOMPILE_ADDRESS, + BANK_PRECOMPILE_ABI, + BANK_PRECOMPILE_ADDRESS, + DISTRIBUTION_PRECOMPILE_ABI, + DISTRIBUTION_PRECOMPILE_ADDRESS, + GOVERNANCE_PRECOMPILE_ABI, + GOVERNANCE_PRECOMPILE_ADDRESS, + JSON_PRECOMPILE_ABI, + JSON_PRECOMPILE_ADDRESS, + P256_PRECOMPILE_ABI, + P256_PRECOMPILE_ADDRESS, + POINTER_PRECOMPILE_ABI, + POINTER_PRECOMPILE_ADDRESS, + POINTERVIEW_PRECOMPILE_ABI, + POINTERVIEW_PRECOMPILE_ADDRESS, + SOLO_PRECOMPILE_ABI, + SOLO_PRECOMPILE_ADDRESS, + STAKING_PRECOMPILE_ABI, + STAKING_PRECOMPILE_ADDRESS, + WASM_PRECOMPILE_ABI, + WASM_PRECOMPILE_ADDRESS +} from '../precompiles'; + +const V66_FIXTURE_DIRECTORY = new URL('./fixtures/v66/', import.meta.url); +const INTENTIONALLY_UNEXPORTED_V66_ABIS = ['ibc.json', 'oracle.json'] as const; + +const loadAbiFixture = (fileName: string): readonly unknown[] => { + const fixture: unknown = JSON.parse(readFileSync(new URL(fileName, V66_FIXTURE_DIRECTORY), 'utf8')); + if (!Array.isArray(fixture)) { + throw new TypeError(`Expected ${fileName} to contain an ABI array`); + } + return fixture; +}; + +const canonicalizeValue = (value: unknown): unknown => { + if (Array.isArray(value)) { + return value.map(canonicalizeValue); + } + if (value !== null && typeof value === 'object') { + return Object.fromEntries( + Object.entries(value) + .sort(([left], [right]) => left.localeCompare(right)) + .map(([key, entry]) => [key, canonicalizeValue(entry)]) + ); + } + return value; +}; + +const canonicalizeAbi = (abi: readonly unknown[]): unknown[] => { + return abi.map(canonicalizeValue).sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right))); +}; + +const V66_PRECOMPILES = [ + ['Address', ADDRESS_PRECOMPILE_ADDRESS, '0x0000000000000000000000000000000000001004', ADDRESS_PRECOMPILE_ABI, 'addr.json'], + ['Bank', BANK_PRECOMPILE_ADDRESS, '0x0000000000000000000000000000000000001001', BANK_PRECOMPILE_ABI, 'bank.json'], + ['Distribution', DISTRIBUTION_PRECOMPILE_ADDRESS, '0x0000000000000000000000000000000000001007', DISTRIBUTION_PRECOMPILE_ABI, 'distribution.json'], + ['Governance', GOVERNANCE_PRECOMPILE_ADDRESS, '0x0000000000000000000000000000000000001006', GOVERNANCE_PRECOMPILE_ABI, 'gov.json'], + ['JSON', JSON_PRECOMPILE_ADDRESS, '0x0000000000000000000000000000000000001003', JSON_PRECOMPILE_ABI, 'json.json'], + ['P256', P256_PRECOMPILE_ADDRESS, '0x0000000000000000000000000000000000001011', P256_PRECOMPILE_ABI, 'p256.json'], + ['Pointer', POINTER_PRECOMPILE_ADDRESS, '0x000000000000000000000000000000000000100B', POINTER_PRECOMPILE_ABI, 'pointer.json'], + ['Pointerview', POINTERVIEW_PRECOMPILE_ADDRESS, '0x000000000000000000000000000000000000100A', POINTERVIEW_PRECOMPILE_ABI, 'pointerview.json'], + ['Solo', SOLO_PRECOMPILE_ADDRESS, '0x000000000000000000000000000000000000100C', SOLO_PRECOMPILE_ABI, 'solo.json'], + ['Staking', STAKING_PRECOMPILE_ADDRESS, '0x0000000000000000000000000000000000001005', STAKING_PRECOMPILE_ABI, 'staking.json'], + ['Wasm', WASM_PRECOMPILE_ADDRESS, '0x0000000000000000000000000000000000001002', WASM_PRECOMPILE_ABI, 'wasmd.json'] +] as const; + +describe('Sei Chain v6.6.1 precompile parity', () => { + it('accounts for every ABI in the frozen v6.6 snapshot', () => { + const fixtureFiles = readdirSync(V66_FIXTURE_DIRECTORY) + .filter((fileName) => fileName.endsWith('.json')) + .sort(); + const accountedForFiles = [...V66_PRECOMPILES.map(([, , , , fileName]) => fileName), ...INTENTIONALLY_UNEXPORTED_V66_ABIS].sort(); + + expect(fixtureFiles).toEqual(accountedForFiles); + }); + + it.each(V66_PRECOMPILES)('%s address and ABI match the vendored v6.6 snapshot', (_name, address, expectedAddress, abi, fixtureFile) => { + expect(address).toBe(expectedAddress); + expect(canonicalizeAbi(abi)).toEqual(canonicalizeAbi(loadAbiFixture(fixtureFile))); + }); +}); diff --git a/packages/precompiles/src/ethers/__tests__/ethersPrecompiles.spec.ts b/packages/precompiles/src/ethers/__tests__/ethersPrecompiles.spec.ts index aeaaf47b3..dac536881 100644 --- a/packages/precompiles/src/ethers/__tests__/ethersPrecompiles.spec.ts +++ b/packages/precompiles/src/ethers/__tests__/ethersPrecompiles.spec.ts @@ -10,6 +10,8 @@ import { GOVERNANCE_PRECOMPILE_ADDRESS, JSON_PRECOMPILE_ABI, JSON_PRECOMPILE_ADDRESS, + P256_PRECOMPILE_ABI, + P256_PRECOMPILE_ADDRESS, POINTER_PRECOMPILE_ABI, POINTER_PRECOMPILE_ADDRESS, POINTERVIEW_PRECOMPILE_ABI, @@ -27,6 +29,7 @@ import { ETHERS_DISTRIBUTION_PRECOMPILE_ABI, ETHERS_GOVERNANCE_PRECOMPILE_ABI, ETHERS_JSON_PRECOMPILE_ABI, + ETHERS_P256_PRECOMPILE_ABI, ETHERS_POINTER_PRECOMPILE_ABI, ETHERS_POINTERVIEW_PRECOMPILE_ABI, ETHERS_SOLO_PRECOMPILE_ABI, @@ -37,6 +40,7 @@ import { getDistributionPrecompileEthersV6Contract, getGovernancePrecompileEthersV6Contract, getJSONPrecompileEthersV6Contract, + getP256PrecompileEthersV6Contract, getPointerPrecompileEthersV6Contract, getPointerviewPrecompileEthersV6Contract, getSoloPrecompileEthersV6Contract, @@ -50,6 +54,7 @@ const FACTORIES: [string, string, InterfaceAbi, unknown, (runner: ContractRunner ['DISTRIBUTION', DISTRIBUTION_PRECOMPILE_ADDRESS, DISTRIBUTION_PRECOMPILE_ABI, ETHERS_DISTRIBUTION_PRECOMPILE_ABI, getDistributionPrecompileEthersV6Contract], ['GOVERNANCE', GOVERNANCE_PRECOMPILE_ADDRESS, GOVERNANCE_PRECOMPILE_ABI, ETHERS_GOVERNANCE_PRECOMPILE_ABI, getGovernancePrecompileEthersV6Contract], ['JSON', JSON_PRECOMPILE_ADDRESS, JSON_PRECOMPILE_ABI, ETHERS_JSON_PRECOMPILE_ABI, getJSONPrecompileEthersV6Contract], + ['P256', P256_PRECOMPILE_ADDRESS, P256_PRECOMPILE_ABI, ETHERS_P256_PRECOMPILE_ABI, getP256PrecompileEthersV6Contract], ['POINTER', POINTER_PRECOMPILE_ADDRESS, POINTER_PRECOMPILE_ABI, ETHERS_POINTER_PRECOMPILE_ABI, getPointerPrecompileEthersV6Contract], ['POINTERVIEW', POINTERVIEW_PRECOMPILE_ADDRESS, POINTERVIEW_PRECOMPILE_ABI, ETHERS_POINTERVIEW_PRECOMPILE_ABI, getPointerviewPrecompileEthersV6Contract], ['SOLO', SOLO_PRECOMPILE_ADDRESS, SOLO_PRECOMPILE_ABI, ETHERS_SOLO_PRECOMPILE_ABI, getSoloPrecompileEthersV6Contract], diff --git a/packages/precompiles/src/ethers/index.ts b/packages/precompiles/src/ethers/index.ts index 5cecb81c1..1599b8e4b 100644 --- a/packages/precompiles/src/ethers/index.ts +++ b/packages/precompiles/src/ethers/index.ts @@ -3,6 +3,7 @@ export * from './bankPrecompile'; export * from './distributionPrecompile'; export * from './governancePrecompile'; export * from './jsonPrecompile'; +export * from './p256Precompile'; export * from './pointerPrecompile'; export * from './pointerviewPrecompile'; export * from './soloPrecompile'; diff --git a/packages/precompiles/src/ethers/p256Precompile.ts b/packages/precompiles/src/ethers/p256Precompile.ts new file mode 100644 index 000000000..77f323d1e --- /dev/null +++ b/packages/precompiles/src/ethers/p256Precompile.ts @@ -0,0 +1,44 @@ +import { Contract, type ContractRunner, type InterfaceAbi } from 'ethers'; +import { P256_PRECOMPILE_ABI, P256_PRECOMPILE_ADDRESS } from '../precompiles'; + +/** + * The ABI for the P256 precompile contract, used to create an Ethers contract. + * @category ABI + */ +export const ETHERS_P256_PRECOMPILE_ABI = P256_PRECOMPILE_ABI as InterfaceAbi; + +/** + * Creates an Ethers v6 contract instance for the P256 signature verification precompile. + * + * Invalid signatures return no data on-chain, which makes Ethers reject the high-level + * call with `BAD_DATA`. The same error can mean that the precompile is unavailable, such + * as on a non-Sei network or after governance disables it. Verify availability independently + * before interpreting `BAD_DATA` as an invalid signature, and rethrow other errors. + * + * @example + * ```ts + * import { concat, isError, zeroPadValue } from 'ethers'; + * import { getP256PrecompileEthersV6Contract } from '@sei-js/precompiles/ethers'; + * + * const p256 = getP256PrecompileEthersV6Contract(provider); + * + * const verifyP256 = async (digest: string, r: string, s: string, publicKeyX: string, publicKeyY: string) => { + * const input = concat([digest, r, s, publicKeyX, publicKeyY].map((value) => zeroPadValue(value, 32))); + * + * try { + * return (await p256.verify(input)) === zeroPadValue('0x01', 32); + * } catch (error) { + * // This assumes the P256 precompile's availability was verified separately. + * if (isError(error, 'BAD_DATA')) return false; + * throw error; + * } + * }; + * ``` + * + * @param runner A [Provider](https://docs.ethers.org/v6/api/providers/) or ethers.Signer to use with the contract. + * @returns The contract instance for interacting with the P256 precompile. + * @category Contract Factory + */ +export const getP256PrecompileEthersV6Contract = (runner: ContractRunner) => { + return new Contract(P256_PRECOMPILE_ADDRESS, ETHERS_P256_PRECOMPILE_ABI, runner); +}; diff --git a/packages/precompiles/src/ethers/stakingPrecompile.ts b/packages/precompiles/src/ethers/stakingPrecompile.ts index 58884f4fc..e158132ba 100644 --- a/packages/precompiles/src/ethers/stakingPrecompile.ts +++ b/packages/precompiles/src/ethers/stakingPrecompile.ts @@ -23,7 +23,7 @@ export const ETHERS_STAKING_PRECOMPILE_ABI = STAKING_PRECOMPILE_ABI as Interface * * const contract = getStakingPrecompileEthersV6Contract(signer); * - * const response = await contract.delegate('0xVALIDATOR_ADDRESS', parseEther(1)); + * const response = await contract.delegate('seivaloper1...', { value: parseEther('1') }); * console.log('Delegate Response:', response); * ``` * diff --git a/packages/precompiles/src/index.ts b/packages/precompiles/src/index.ts index 46873f7bc..8159fd16d 100644 --- a/packages/precompiles/src/index.ts +++ b/packages/precompiles/src/index.ts @@ -1,3 +1,3 @@ export * from './ethers'; export * from './precompiles'; -export * from './viem'; +export * from './viem/chain'; diff --git a/packages/precompiles/src/precompiles/address.ts b/packages/precompiles/src/precompiles/address.ts index f2ef103e6..064d30a39 100644 --- a/packages/precompiles/src/precompiles/address.ts +++ b/packages/precompiles/src/precompiles/address.ts @@ -1,29 +1,18 @@ +import type { Abi } from 'viem'; + /** * The address of the Address precompile contract. - * This contract gets associated Sei and EVM addresses. * @category Address */ export const ADDRESS_PRECOMPILE_ADDRESS: `0x${string}` = '0x0000000000000000000000000000000000001004'; /** * The ABI for the Address precompile contract. + * Synced from the frozen Sei Chain v6.6.1 precompile snapshot. + * @see https://github.com/sei-protocol/sei-chain/blob/v6.6.1/precompiles/addr/legacy/v66/abi.json * @category ABI */ export const ADDRESS_PRECOMPILE_ABI = [ - { - inputs: [{ internalType: 'string', name: 'addr', type: 'string' }], - name: 'getEvmAddr', - outputs: [{ internalType: 'address', name: 'response', type: 'address' }], - stateMutability: 'view', - type: 'function' - }, - { - inputs: [{ internalType: 'address', name: 'addr', type: 'address' }], - name: 'getSeiAddr', - outputs: [{ internalType: 'string', name: 'response', type: 'string' }], - stateMutability: 'view', - type: 'function' - }, { inputs: [ { internalType: 'string', name: 'v', type: 'string' }, @@ -48,5 +37,19 @@ export const ADDRESS_PRECOMPILE_ABI = [ ], stateMutability: 'nonpayable', type: 'function' + }, + { + inputs: [{ internalType: 'address', name: 'addr', type: 'address' }], + name: 'getSeiAddr', + outputs: [{ internalType: 'string', name: 'response', type: 'string' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'string', name: 'addr', type: 'string' }], + name: 'getEvmAddr', + outputs: [{ internalType: 'address', name: 'response', type: 'address' }], + stateMutability: 'view', + type: 'function' } -] as const; +] as const satisfies Abi; diff --git a/packages/precompiles/src/precompiles/bank.ts b/packages/precompiles/src/precompiles/bank.ts index 6f293efcd..f068c21f8 100644 --- a/packages/precompiles/src/precompiles/bank.ts +++ b/packages/precompiles/src/precompiles/bank.ts @@ -1,3 +1,5 @@ +import type { Abi } from 'viem'; + /** * The address of the Bank precompile contract. * @category Address @@ -6,6 +8,8 @@ export const BANK_PRECOMPILE_ADDRESS: `0x${string}` = '0x00000000000000000000000 /** * The ABI for the Bank precompile contract. + * Synced from the frozen Sei Chain v6.6.1 precompile snapshot. + * @see https://github.com/sei-protocol/sei-chain/blob/v6.6.1/precompiles/bank/legacy/v66/abi.json * @category ABI */ export const BANK_PRECOMPILE_ABI = [ @@ -83,4 +87,4 @@ export const BANK_PRECOMPILE_ABI = [ stateMutability: 'view', type: 'function' } -] as const; +] as const satisfies Abi; diff --git a/packages/precompiles/src/precompiles/distribution.ts b/packages/precompiles/src/precompiles/distribution.ts index caf93ccde..d4a761175 100644 --- a/packages/precompiles/src/precompiles/distribution.ts +++ b/packages/precompiles/src/precompiles/distribution.ts @@ -1,3 +1,5 @@ +import type { Abi } from 'viem'; + /** * The address of the Distribution precompile contract. * @category Address @@ -6,29 +8,48 @@ export const DISTRIBUTION_PRECOMPILE_ADDRESS: `0x${string}` = '0x000000000000000 /** * The ABI for the Distribution precompile contract. + * Synced from the frozen Sei Chain v6.6.1 precompile snapshot. + * @see https://github.com/sei-protocol/sei-chain/blob/v6.6.1/precompiles/distribution/legacy/v66/abi.json * @category ABI */ export const DISTRIBUTION_PRECOMPILE_ABI = [ { - inputs: [{ internalType: 'address', name: 'withdrawAddr', type: 'address' }], - name: 'setWithdrawAddress', - outputs: [{ internalType: 'bool', name: 'success', type: 'bool' }], - stateMutability: 'nonpayable', - type: 'function' + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'delegator', type: 'address' }, + { indexed: false, internalType: 'string', name: 'validator', type: 'string' }, + { indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' } + ], + name: 'DelegationRewardsWithdrawn', + type: 'event' }, { - inputs: [{ internalType: 'string', name: 'validator', type: 'string' }], - name: 'withdrawDelegationRewards', - outputs: [{ internalType: 'bool', name: 'success', type: 'bool' }], - stateMutability: 'nonpayable', - type: 'function' + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'delegator', type: 'address' }, + { indexed: false, internalType: 'string[]', name: 'validators', type: 'string[]' }, + { indexed: false, internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' } + ], + name: 'MultipleDelegationRewardsWithdrawn', + type: 'event' }, { - inputs: [{ internalType: 'string[]', name: 'validators', type: 'string[]' }], - name: 'withdrawMultipleDelegationRewards', - outputs: [{ internalType: 'bool', name: 'success', type: 'bool' }], - stateMutability: 'nonpayable', - type: 'function' + anonymous: false, + inputs: [ + { indexed: true, internalType: 'string', name: 'validator', type: 'string' }, + { indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' } + ], + name: 'ValidatorCommissionWithdrawn', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'delegator', type: 'address' }, + { indexed: false, internalType: 'address', name: 'withdrawAddr', type: 'address' } + ], + name: 'WithdrawAddressSet', + type: 'event' }, { inputs: [{ internalType: 'address', name: 'delegatorAddress', type: 'address' }], @@ -44,13 +65,13 @@ export const DISTRIBUTION_PRECOMPILE_ABI = [ { internalType: 'uint256', name: 'decimals', type: 'uint256' }, { internalType: 'string', name: 'denom', type: 'string' } ], - internalType: 'struct Coin[]', + internalType: 'struct IDistr.Coin[]', name: 'coins', type: 'tuple[]' }, { internalType: 'string', name: 'validator_address', type: 'string' } ], - internalType: 'struct Reward[]', + internalType: 'struct IDistr.Reward[]', name: 'rewards', type: 'tuple[]' }, @@ -60,17 +81,45 @@ export const DISTRIBUTION_PRECOMPILE_ABI = [ { internalType: 'uint256', name: 'decimals', type: 'uint256' }, { internalType: 'string', name: 'denom', type: 'string' } ], - internalType: 'struct Coin[]', + internalType: 'struct IDistr.Coin[]', name: 'total', type: 'tuple[]' } ], - internalType: 'struct Rewards', + internalType: 'struct IDistr.Rewards', name: 'rewards', type: 'tuple' } ], stateMutability: 'view', type: 'function' + }, + { + inputs: [{ internalType: 'address', name: 'withdrawAddr', type: 'address' }], + name: 'setWithdrawAddress', + outputs: [{ internalType: 'bool', name: 'success', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [{ internalType: 'string', name: 'validator', type: 'string' }], + name: 'withdrawDelegationRewards', + outputs: [{ internalType: 'bool', name: 'success', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [{ internalType: 'string[]', name: 'validators', type: 'string[]' }], + name: 'withdrawMultipleDelegationRewards', + outputs: [{ internalType: 'bool', name: 'success', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'withdrawValidatorCommission', + outputs: [{ internalType: 'bool', name: 'success', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function' } -] as const; +] as const satisfies Abi; diff --git a/packages/precompiles/src/precompiles/governance.ts b/packages/precompiles/src/precompiles/governance.ts index 8a773da0e..1cf9f2bac 100644 --- a/packages/precompiles/src/precompiles/governance.ts +++ b/packages/precompiles/src/precompiles/governance.ts @@ -1,3 +1,5 @@ +import type { Abi } from 'viem'; + /** * The address of the Governance precompile contract. * @category Address @@ -6,9 +8,18 @@ export const GOVERNANCE_PRECOMPILE_ADDRESS: `0x${string}` = '0x00000000000000000 /** * The ABI for the Governance precompile contract. + * Synced from the frozen Sei Chain v6.6.1 precompile snapshot. + * @see https://github.com/sei-protocol/sei-chain/blob/v6.6.1/precompiles/gov/legacy/v66/abi.json * @category ABI */ export const GOVERNANCE_PRECOMPILE_ABI = [ + { + inputs: [{ internalType: 'string', name: 'proposalJSON', type: 'string' }], + name: 'submitProposal', + outputs: [{ internalType: 'uint64', name: 'proposalID', type: 'uint64' }], + stateMutability: 'payable', + type: 'function' + }, { inputs: [{ internalType: 'uint64', name: 'proposalID', type: 'uint64' }], name: 'deposit', @@ -25,5 +36,23 @@ export const GOVERNANCE_PRECOMPILE_ABI = [ outputs: [{ internalType: 'bool', name: 'success', type: 'bool' }], stateMutability: 'nonpayable', type: 'function' + }, + { + inputs: [ + { internalType: 'uint64', name: 'proposalID', type: 'uint64' }, + { + components: [ + { internalType: 'int32', name: 'option', type: 'int32' }, + { internalType: 'string', name: 'weight', type: 'string' } + ], + internalType: 'struct WeightedVoteOption[]', + name: 'options', + type: 'tuple[]' + } + ], + name: 'voteWeighted', + outputs: [{ internalType: 'bool', name: 'success', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function' } -] as const; +] as const satisfies Abi; diff --git a/packages/precompiles/src/precompiles/index.ts b/packages/precompiles/src/precompiles/index.ts index 516fa3f13..22c0f216c 100644 --- a/packages/precompiles/src/precompiles/index.ts +++ b/packages/precompiles/src/precompiles/index.ts @@ -3,6 +3,7 @@ export * from './bank'; export * from './distribution'; export * from './governance'; export * from './json'; +export * from './p256'; export * from './pointer'; export * from './pointerview'; export * from './solo'; diff --git a/packages/precompiles/src/precompiles/json.ts b/packages/precompiles/src/precompiles/json.ts index 5cff00257..83287e312 100644 --- a/packages/precompiles/src/precompiles/json.ts +++ b/packages/precompiles/src/precompiles/json.ts @@ -1,3 +1,5 @@ +import type { Abi } from 'viem'; + /** * The address of the JSON precompile contract. * @category Address @@ -6,6 +8,8 @@ export const JSON_PRECOMPILE_ADDRESS: `0x${string}` = '0x00000000000000000000000 /** * The ABI for the JSON precompile contract. + * Synced from the frozen Sei Chain v6.6.1 precompile snapshot. + * @see https://github.com/sei-protocol/sei-chain/blob/v6.6.1/precompiles/json/legacy/v66/abi.json * @category ABI */ export const JSON_PRECOMPILE_ABI = [ @@ -38,5 +42,15 @@ export const JSON_PRECOMPILE_ABI = [ outputs: [{ internalType: 'uint256', name: 'response', type: 'uint256' }], stateMutability: 'view', type: 'function' + }, + { + inputs: [ + { internalType: 'bytes', name: 'input', type: 'bytes' }, + { internalType: 'uint16', name: 'arrayIndex', type: 'uint16' } + ], + name: 'extractAsBytesFromArray', + outputs: [{ internalType: 'bytes', name: 'response', type: 'bytes' }], + stateMutability: 'view', + type: 'function' } -] as const; +] as const satisfies Abi; diff --git a/packages/precompiles/src/precompiles/p256.ts b/packages/precompiles/src/precompiles/p256.ts new file mode 100644 index 000000000..c5f5c6d6a --- /dev/null +++ b/packages/precompiles/src/precompiles/p256.ts @@ -0,0 +1,30 @@ +import type { Abi } from 'viem'; + +/** + * The address of the P256 precompile contract. + * @category Address + */ +export const P256_PRECOMPILE_ADDRESS: `0x${string}` = '0x0000000000000000000000000000000000001011'; + +/** + * The ABI for the P256 precompile contract. + * + * `verify` expects exactly 160 bytes containing five 32-byte values in this order: + * message digest, signature `r`, signature `s`, public-key `x`, and public-key `y`. + * A valid signature decodes to 32 bytes ending in `01`. An invalid signature returns + * no data, so high-level clients can throw while decoding instead of returning `false`. + * + * Synced from the frozen Sei Chain v6.6.1 precompile snapshot. + * @see https://github.com/sei-protocol/sei-chain/blob/v6.6.1/precompiles/p256/legacy/v66/abi.json + * @see https://docs.sei.io/evm/precompiles/p256-precompile + * @category ABI + */ +export const P256_PRECOMPILE_ABI = [ + { + inputs: [{ internalType: 'bytes', name: 'signature', type: 'bytes' }], + name: 'verify', + outputs: [{ internalType: 'bytes', name: 'response', type: 'bytes' }], + stateMutability: 'view', + type: 'function' + } +] as const satisfies Abi; diff --git a/packages/precompiles/src/precompiles/pointer.ts b/packages/precompiles/src/precompiles/pointer.ts index 293588a1d..5bf042bd7 100644 --- a/packages/precompiles/src/precompiles/pointer.ts +++ b/packages/precompiles/src/precompiles/pointer.ts @@ -1,3 +1,5 @@ +import type { Abi } from 'viem'; + /** * The address of the Pointer precompile contract. * @category Address @@ -6,9 +8,18 @@ export const POINTER_PRECOMPILE_ADDRESS: `0x${string}` = '0x00000000000000000000 /** * The ABI for the Pointer precompile contract. + * Synced from the frozen Sei Chain v6.6.1 precompile snapshot. + * @see https://github.com/sei-protocol/sei-chain/blob/v6.6.1/precompiles/pointer/legacy/v66/abi.json * @category ABI */ export const POINTER_PRECOMPILE_ABI = [ + { + inputs: [{ internalType: 'string', name: 'cwAddr', type: 'string' }], + name: 'addCW1155Pointer', + outputs: [{ internalType: 'address', name: 'ret', type: 'address' }], + stateMutability: 'payable', + type: 'function' + }, { inputs: [{ internalType: 'string', name: 'cwAddr', type: 'string' }], name: 'addCW20Pointer', @@ -30,4 +41,4 @@ export const POINTER_PRECOMPILE_ABI = [ stateMutability: 'payable', type: 'function' } -] as const; +] as const satisfies Abi; diff --git a/packages/precompiles/src/precompiles/pointerview.ts b/packages/precompiles/src/precompiles/pointerview.ts index 12f78493c..b41af09ad 100644 --- a/packages/precompiles/src/precompiles/pointerview.ts +++ b/packages/precompiles/src/precompiles/pointerview.ts @@ -1,3 +1,5 @@ +import type { Abi } from 'viem'; + /** * The address of the Pointerview precompile contract. * @category Address @@ -6,9 +8,22 @@ export const POINTERVIEW_PRECOMPILE_ADDRESS: `0x${string}` = '0x0000000000000000 /** * The ABI for the Pointerview precompile contract. + * Synced from the frozen Sei Chain v6.6.1 precompile snapshot. + * @see https://github.com/sei-protocol/sei-chain/blob/v6.6.1/precompiles/pointerview/legacy/v66/abi.json * @category ABI */ export const POINTERVIEW_PRECOMPILE_ABI = [ + { + inputs: [{ internalType: 'string', name: 'cwAddr', type: 'string' }], + name: 'getCW1155Pointer', + outputs: [ + { internalType: 'address', name: 'addr', type: 'address' }, + { internalType: 'uint16', name: 'version', type: 'uint16' }, + { internalType: 'bool', name: 'exists', type: 'bool' } + ], + stateMutability: 'view', + type: 'function' + }, { inputs: [{ internalType: 'string', name: 'cwAddr', type: 'string' }], name: 'getCW20Pointer', @@ -42,4 +57,4 @@ export const POINTERVIEW_PRECOMPILE_ABI = [ stateMutability: 'view', type: 'function' } -] as const; +] as const satisfies Abi; diff --git a/packages/precompiles/src/precompiles/solo.ts b/packages/precompiles/src/precompiles/solo.ts index 48613d268..932118d81 100644 --- a/packages/precompiles/src/precompiles/solo.ts +++ b/packages/precompiles/src/precompiles/solo.ts @@ -1,3 +1,5 @@ +import type { Abi } from 'viem'; + /** * The address of the Solo precompile contract. * @category Address @@ -6,6 +8,8 @@ export const SOLO_PRECOMPILE_ADDRESS: `0x${string}` = '0x00000000000000000000000 /** * The ABI for the Solo precompile contract. + * Synced from the frozen Sei Chain v6.6.1 precompile snapshot. + * @see https://github.com/sei-protocol/sei-chain/blob/v6.6.1/precompiles/solo/legacy/v66/abi.json * @category ABI */ export const SOLO_PRECOMPILE_ABI = [ @@ -23,4 +27,4 @@ export const SOLO_PRECOMPILE_ABI = [ stateMutability: 'nonpayable', type: 'function' } -] as const; +] as const satisfies Abi; diff --git a/packages/precompiles/src/precompiles/staking.ts b/packages/precompiles/src/precompiles/staking.ts index 75660bbe8..f5c49d0d7 100644 --- a/packages/precompiles/src/precompiles/staking.ts +++ b/packages/precompiles/src/precompiles/staking.ts @@ -1,3 +1,5 @@ +import type { Abi } from 'viem'; + /** * The address of the Staking precompile contract. * @category Address @@ -6,9 +8,86 @@ export const STAKING_PRECOMPILE_ADDRESS: `0x${string}` = '0x00000000000000000000 /** * The ABI for the Staking precompile contract. + * Synced from the frozen Sei Chain v6.6.1 precompile snapshot. + * @see https://github.com/sei-protocol/sei-chain/blob/v6.6.1/precompiles/staking/legacy/v66/abi.json * @category ABI */ export const STAKING_PRECOMPILE_ABI = [ + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'delegator', type: 'address' }, + { indexed: false, internalType: 'string', name: 'validator', type: 'string' }, + { indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' } + ], + name: 'Delegate', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'delegator', type: 'address' }, + { indexed: false, internalType: 'string', name: 'validator', type: 'string' }, + { indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' } + ], + name: 'DelegationRewardsWithdrawn', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'delegator', type: 'address' }, + { indexed: false, internalType: 'string', name: 'srcValidator', type: 'string' }, + { indexed: false, internalType: 'string', name: 'dstValidator', type: 'string' }, + { indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' } + ], + name: 'Redelegate', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'delegator', type: 'address' }, + { indexed: false, internalType: 'string', name: 'validator', type: 'string' }, + { indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' } + ], + name: 'Undelegate', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'creator', type: 'address' }, + { indexed: false, internalType: 'string', name: 'validatorAddress', type: 'string' }, + { indexed: false, internalType: 'string', name: 'moniker', type: 'string' } + ], + name: 'ValidatorCreated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'editor', type: 'address' }, + { indexed: false, internalType: 'string', name: 'validatorAddress', type: 'string' }, + { indexed: false, internalType: 'string', name: 'moniker', type: 'string' } + ], + name: 'ValidatorEdited', + type: 'event' + }, + { + inputs: [ + { internalType: 'string', name: 'pubKeyHex', type: 'string' }, + { internalType: 'string', name: 'moniker', type: 'string' }, + { internalType: 'string', name: 'commissionRate', type: 'string' }, + { internalType: 'string', name: 'commissionMaxRate', type: 'string' }, + { internalType: 'string', name: 'commissionMaxChangeRate', type: 'string' }, + { internalType: 'uint256', name: 'minSelfDelegation', type: 'uint256' } + ], + name: 'createValidator', + outputs: [{ internalType: 'bool', name: 'success', type: 'bool' }], + stateMutability: 'payable', + type: 'function' + }, { inputs: [{ internalType: 'string', name: 'valAddress', type: 'string' }], name: 'delegate', @@ -16,6 +95,289 @@ export const STAKING_PRECOMPILE_ABI = [ stateMutability: 'payable', type: 'function' }, + { + inputs: [ + { internalType: 'address', name: 'delegator', type: 'address' }, + { internalType: 'string', name: 'valAddress', type: 'string' } + ], + name: 'delegation', + outputs: [ + { + components: [ + { + components: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'string', name: 'denom', type: 'string' } + ], + internalType: 'struct IStaking.Balance', + name: 'balance', + type: 'tuple' + }, + { + components: [ + { internalType: 'string', name: 'delegator_address', type: 'string' }, + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'string', name: 'validator_address', type: 'string' } + ], + internalType: 'struct IStaking.DelegationDetails', + name: 'delegation', + type: 'tuple' + } + ], + internalType: 'struct IStaking.Delegation', + name: 'delegation', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'delegator', type: 'address' }, + { internalType: 'bytes', name: 'nextKey', type: 'bytes' } + ], + name: 'delegatorDelegations', + outputs: [ + { + components: [ + { + components: [ + { + components: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'string', name: 'denom', type: 'string' } + ], + internalType: 'struct IStaking.Balance', + name: 'balance', + type: 'tuple' + }, + { + components: [ + { internalType: 'string', name: 'delegator_address', type: 'string' }, + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'string', name: 'validator_address', type: 'string' } + ], + internalType: 'struct IStaking.DelegationDetails', + name: 'delegation', + type: 'tuple' + } + ], + internalType: 'struct IStaking.Delegation[]', + name: 'delegations', + type: 'tuple[]' + }, + { internalType: 'bytes', name: 'nextKey', type: 'bytes' } + ], + internalType: 'struct IStaking.DelegationsResponse', + name: 'response', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'delegator', type: 'address' }, + { internalType: 'bytes', name: 'nextKey', type: 'bytes' } + ], + name: 'delegatorUnbondingDelegations', + outputs: [ + { + components: [ + { + components: [ + { internalType: 'string', name: 'delegatorAddress', type: 'string' }, + { internalType: 'string', name: 'validatorAddress', type: 'string' }, + { + components: [ + { internalType: 'int64', name: 'creationHeight', type: 'int64' }, + { internalType: 'int64', name: 'completionTime', type: 'int64' }, + { internalType: 'string', name: 'initialBalance', type: 'string' }, + { internalType: 'string', name: 'balance', type: 'string' } + ], + internalType: 'struct IStaking.UnbondingDelegationEntry[]', + name: 'entries', + type: 'tuple[]' + } + ], + internalType: 'struct IStaking.UnbondingDelegation[]', + name: 'unbondingDelegations', + type: 'tuple[]' + }, + { internalType: 'bytes', name: 'nextKey', type: 'bytes' } + ], + internalType: 'struct IStaking.UnbondingDelegationsResponse', + name: 'response', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'delegator', type: 'address' }, + { internalType: 'string', name: 'validatorAddress', type: 'string' } + ], + name: 'delegatorValidator', + outputs: [ + { + components: [ + { internalType: 'string', name: 'operatorAddress', type: 'string' }, + { internalType: 'bytes', name: 'consensusPubkey', type: 'bytes' }, + { internalType: 'bool', name: 'jailed', type: 'bool' }, + { internalType: 'int32', name: 'status', type: 'int32' }, + { internalType: 'string', name: 'tokens', type: 'string' }, + { internalType: 'string', name: 'delegatorShares', type: 'string' }, + { internalType: 'string', name: 'description', type: 'string' }, + { internalType: 'int64', name: 'unbondingHeight', type: 'int64' }, + { internalType: 'int64', name: 'unbondingTime', type: 'int64' }, + { internalType: 'string', name: 'commissionRate', type: 'string' }, + { internalType: 'string', name: 'commissionMaxRate', type: 'string' }, + { internalType: 'string', name: 'commissionMaxChangeRate', type: 'string' }, + { internalType: 'int64', name: 'commissionUpdateTime', type: 'int64' }, + { internalType: 'string', name: 'minSelfDelegation', type: 'string' } + ], + internalType: 'struct IStaking.Validator', + name: 'validator', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'delegator', type: 'address' }, + { internalType: 'bytes', name: 'nextKey', type: 'bytes' } + ], + name: 'delegatorValidators', + outputs: [ + { + components: [ + { + components: [ + { internalType: 'string', name: 'operatorAddress', type: 'string' }, + { internalType: 'bytes', name: 'consensusPubkey', type: 'bytes' }, + { internalType: 'bool', name: 'jailed', type: 'bool' }, + { internalType: 'int32', name: 'status', type: 'int32' }, + { internalType: 'string', name: 'tokens', type: 'string' }, + { internalType: 'string', name: 'delegatorShares', type: 'string' }, + { internalType: 'string', name: 'description', type: 'string' }, + { internalType: 'int64', name: 'unbondingHeight', type: 'int64' }, + { internalType: 'int64', name: 'unbondingTime', type: 'int64' }, + { internalType: 'string', name: 'commissionRate', type: 'string' }, + { internalType: 'string', name: 'commissionMaxRate', type: 'string' }, + { internalType: 'string', name: 'commissionMaxChangeRate', type: 'string' }, + { internalType: 'int64', name: 'commissionUpdateTime', type: 'int64' }, + { internalType: 'string', name: 'minSelfDelegation', type: 'string' } + ], + internalType: 'struct IStaking.Validator[]', + name: 'validators', + type: 'tuple[]' + }, + { internalType: 'bytes', name: 'nextKey', type: 'bytes' } + ], + internalType: 'struct IStaking.ValidatorsResponse', + name: 'response', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'string', name: 'moniker', type: 'string' }, + { internalType: 'string', name: 'commissionRate', type: 'string' }, + { internalType: 'uint256', name: 'minSelfDelegation', type: 'uint256' } + ], + name: 'editValidator', + outputs: [{ internalType: 'bool', name: 'success', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [{ internalType: 'int64', name: 'height', type: 'int64' }], + name: 'historicalInfo', + outputs: [ + { + components: [ + { internalType: 'int64', name: 'height', type: 'int64' }, + { + components: [ + { internalType: 'string', name: 'operatorAddress', type: 'string' }, + { internalType: 'bytes', name: 'consensusPubkey', type: 'bytes' }, + { internalType: 'bool', name: 'jailed', type: 'bool' }, + { internalType: 'int32', name: 'status', type: 'int32' }, + { internalType: 'string', name: 'tokens', type: 'string' }, + { internalType: 'string', name: 'delegatorShares', type: 'string' }, + { internalType: 'string', name: 'description', type: 'string' }, + { internalType: 'int64', name: 'unbondingHeight', type: 'int64' }, + { internalType: 'int64', name: 'unbondingTime', type: 'int64' }, + { internalType: 'string', name: 'commissionRate', type: 'string' }, + { internalType: 'string', name: 'commissionMaxRate', type: 'string' }, + { internalType: 'string', name: 'commissionMaxChangeRate', type: 'string' }, + { internalType: 'int64', name: 'commissionUpdateTime', type: 'int64' }, + { internalType: 'string', name: 'minSelfDelegation', type: 'string' } + ], + internalType: 'struct IStaking.Validator[]', + name: 'validators', + type: 'tuple[]' + } + ], + internalType: 'struct IStaking.HistoricalInfo', + name: 'historicalInfo', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'params', + outputs: [ + { + components: [ + { internalType: 'uint64', name: 'unbondingTime', type: 'uint64' }, + { internalType: 'uint32', name: 'maxValidators', type: 'uint32' }, + { internalType: 'uint32', name: 'maxEntries', type: 'uint32' }, + { internalType: 'uint32', name: 'historicalEntries', type: 'uint32' }, + { internalType: 'string', name: 'bondDenom', type: 'string' }, + { internalType: 'string', name: 'minCommissionRate', type: 'string' }, + { internalType: 'string', name: 'maxVotingPowerRatio', type: 'string' }, + { internalType: 'string', name: 'maxVotingPowerEnforcementThreshold', type: 'string' } + ], + internalType: 'struct IStaking.Params', + name: 'params', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'pool', + outputs: [ + { + components: [ + { internalType: 'string', name: 'notBondedTokens', type: 'string' }, + { internalType: 'string', name: 'bondedTokens', type: 'string' } + ], + internalType: 'struct IStaking.Pool', + name: 'pool', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + }, { inputs: [ { internalType: 'string', name: 'srcAddress', type: 'string' }, @@ -27,6 +389,79 @@ export const STAKING_PRECOMPILE_ABI = [ stateMutability: 'nonpayable', type: 'function' }, + { + inputs: [ + { internalType: 'string', name: 'delegator', type: 'string' }, + { internalType: 'string', name: 'srcValidator', type: 'string' }, + { internalType: 'string', name: 'dstValidator', type: 'string' }, + { internalType: 'bytes', name: 'nextKey', type: 'bytes' } + ], + name: 'redelegations', + outputs: [ + { + components: [ + { + components: [ + { internalType: 'string', name: 'delegatorAddress', type: 'string' }, + { internalType: 'string', name: 'validatorSrcAddress', type: 'string' }, + { internalType: 'string', name: 'validatorDstAddress', type: 'string' }, + { + components: [ + { internalType: 'int64', name: 'creationHeight', type: 'int64' }, + { internalType: 'int64', name: 'completionTime', type: 'int64' }, + { internalType: 'string', name: 'initialBalance', type: 'string' }, + { internalType: 'string', name: 'sharesDst', type: 'string' } + ], + internalType: 'struct IStaking.RedelegationEntry[]', + name: 'entries', + type: 'tuple[]' + } + ], + internalType: 'struct IStaking.Redelegation[]', + name: 'redelegations', + type: 'tuple[]' + }, + { internalType: 'bytes', name: 'nextKey', type: 'bytes' } + ], + internalType: 'struct IStaking.RedelegationsResponse', + name: 'response', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'delegator', type: 'address' }, + { internalType: 'string', name: 'validatorAddress', type: 'string' } + ], + name: 'unbondingDelegation', + outputs: [ + { + components: [ + { internalType: 'string', name: 'delegatorAddress', type: 'string' }, + { internalType: 'string', name: 'validatorAddress', type: 'string' }, + { + components: [ + { internalType: 'int64', name: 'creationHeight', type: 'int64' }, + { internalType: 'int64', name: 'completionTime', type: 'int64' }, + { internalType: 'string', name: 'initialBalance', type: 'string' }, + { internalType: 'string', name: 'balance', type: 'string' } + ], + internalType: 'struct IStaking.UnbondingDelegationEntry[]', + name: 'entries', + type: 'tuple[]' + } + ], + internalType: 'struct IStaking.UnbondingDelegation', + name: 'unbondingDelegation', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + }, { inputs: [ { internalType: 'string', name: 'valAddress', type: 'string' }, @@ -37,42 +472,158 @@ export const STAKING_PRECOMPILE_ABI = [ stateMutability: 'nonpayable', type: 'function' }, + { + inputs: [{ internalType: 'string', name: 'validatorAddress', type: 'string' }], + name: 'validator', + outputs: [ + { + components: [ + { internalType: 'string', name: 'operatorAddress', type: 'string' }, + { internalType: 'bytes', name: 'consensusPubkey', type: 'bytes' }, + { internalType: 'bool', name: 'jailed', type: 'bool' }, + { internalType: 'int32', name: 'status', type: 'int32' }, + { internalType: 'string', name: 'tokens', type: 'string' }, + { internalType: 'string', name: 'delegatorShares', type: 'string' }, + { internalType: 'string', name: 'description', type: 'string' }, + { internalType: 'int64', name: 'unbondingHeight', type: 'int64' }, + { internalType: 'int64', name: 'unbondingTime', type: 'int64' }, + { internalType: 'string', name: 'commissionRate', type: 'string' }, + { internalType: 'string', name: 'commissionMaxRate', type: 'string' }, + { internalType: 'string', name: 'commissionMaxChangeRate', type: 'string' }, + { internalType: 'int64', name: 'commissionUpdateTime', type: 'int64' }, + { internalType: 'string', name: 'minSelfDelegation', type: 'string' } + ], + internalType: 'struct IStaking.Validator', + name: 'validator', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + }, { inputs: [ - { internalType: 'address', name: 'delegator', type: 'address' }, - { internalType: 'string', name: 'valAddress', type: 'string' } + { internalType: 'string', name: 'validatorAddress', type: 'string' }, + { internalType: 'bytes', name: 'nextKey', type: 'bytes' } ], - name: 'delegation', + name: 'validatorDelegations', outputs: [ { components: [ { components: [ - { internalType: 'uint256', name: 'amount', type: 'uint256' }, - { internalType: 'string', name: 'denom', type: 'string' } + { + components: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'string', name: 'denom', type: 'string' } + ], + internalType: 'struct IStaking.Balance', + name: 'balance', + type: 'tuple' + }, + { + components: [ + { internalType: 'string', name: 'delegator_address', type: 'string' }, + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'string', name: 'validator_address', type: 'string' } + ], + internalType: 'struct IStaking.DelegationDetails', + name: 'delegation', + type: 'tuple' + } ], - internalType: 'struct Balance', - name: 'balance', - type: 'tuple' + internalType: 'struct IStaking.Delegation[]', + name: 'delegations', + type: 'tuple[]' }, + { internalType: 'bytes', name: 'nextKey', type: 'bytes' } + ], + internalType: 'struct IStaking.DelegationsResponse', + name: 'response', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'string', name: 'validatorAddress', type: 'string' }, + { internalType: 'bytes', name: 'nextKey', type: 'bytes' } + ], + name: 'validatorUnbondingDelegations', + outputs: [ + { + components: [ { components: [ - { internalType: 'string', name: 'delegator_address', type: 'string' }, - { internalType: 'uint256', name: 'shares', type: 'uint256' }, - { internalType: 'uint256', name: 'decimals', type: 'uint256' }, - { internalType: 'string', name: 'validator_address', type: 'string' } + { internalType: 'string', name: 'delegatorAddress', type: 'string' }, + { internalType: 'string', name: 'validatorAddress', type: 'string' }, + { + components: [ + { internalType: 'int64', name: 'creationHeight', type: 'int64' }, + { internalType: 'int64', name: 'completionTime', type: 'int64' }, + { internalType: 'string', name: 'initialBalance', type: 'string' }, + { internalType: 'string', name: 'balance', type: 'string' } + ], + internalType: 'struct IStaking.UnbondingDelegationEntry[]', + name: 'entries', + type: 'tuple[]' + } ], - internalType: 'struct DelegationDetails', - name: 'delegation', - type: 'tuple' - } + internalType: 'struct IStaking.UnbondingDelegation[]', + name: 'unbondingDelegations', + type: 'tuple[]' + }, + { internalType: 'bytes', name: 'nextKey', type: 'bytes' } ], - internalType: 'struct Delegation', - name: 'delegation', + internalType: 'struct IStaking.UnbondingDelegationsResponse', + name: 'response', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'string', name: 'status', type: 'string' }, + { internalType: 'bytes', name: 'nextKey', type: 'bytes' } + ], + name: 'validators', + outputs: [ + { + components: [ + { + components: [ + { internalType: 'string', name: 'operatorAddress', type: 'string' }, + { internalType: 'bytes', name: 'consensusPubkey', type: 'bytes' }, + { internalType: 'bool', name: 'jailed', type: 'bool' }, + { internalType: 'int32', name: 'status', type: 'int32' }, + { internalType: 'string', name: 'tokens', type: 'string' }, + { internalType: 'string', name: 'delegatorShares', type: 'string' }, + { internalType: 'string', name: 'description', type: 'string' }, + { internalType: 'int64', name: 'unbondingHeight', type: 'int64' }, + { internalType: 'int64', name: 'unbondingTime', type: 'int64' }, + { internalType: 'string', name: 'commissionRate', type: 'string' }, + { internalType: 'string', name: 'commissionMaxRate', type: 'string' }, + { internalType: 'string', name: 'commissionMaxChangeRate', type: 'string' }, + { internalType: 'int64', name: 'commissionUpdateTime', type: 'int64' }, + { internalType: 'string', name: 'minSelfDelegation', type: 'string' } + ], + internalType: 'struct IStaking.Validator[]', + name: 'validators', + type: 'tuple[]' + }, + { internalType: 'bytes', name: 'nextKey', type: 'bytes' } + ], + internalType: 'struct IStaking.ValidatorsResponse', + name: 'response', type: 'tuple' } ], stateMutability: 'view', type: 'function' } -] as const; +] as const satisfies Abi; diff --git a/packages/precompiles/src/precompiles/wasm.ts b/packages/precompiles/src/precompiles/wasm.ts index c5ee4b37c..67729116b 100644 --- a/packages/precompiles/src/precompiles/wasm.ts +++ b/packages/precompiles/src/precompiles/wasm.ts @@ -1,3 +1,5 @@ +import type { Abi } from 'viem'; + /** * The address of the Wasm precompile contract. * @category Address @@ -6,6 +8,8 @@ export const WASM_PRECOMPILE_ADDRESS: `0x${string}` = '0x00000000000000000000000 /** * The ABI for the Wasm precompile contract. + * Synced from the frozen Sei Chain v6.6.1 precompile snapshot. + * @see https://github.com/sei-protocol/sei-chain/blob/v6.6.1/precompiles/wasmd/legacy/v66/abi.json * @category ABI */ export const WASM_PRECOMPILE_ABI = [ @@ -64,4 +68,4 @@ export const WASM_PRECOMPILE_ABI = [ stateMutability: 'view', type: 'function' } -] as const; +] as const satisfies Abi; diff --git a/packages/precompiles/src/viem/__tests__/viemPrecompiles.spec.ts b/packages/precompiles/src/viem/__tests__/viemPrecompiles.spec.ts index 12d7d0acb..37b89f0c2 100644 --- a/packages/precompiles/src/viem/__tests__/viemPrecompiles.spec.ts +++ b/packages/precompiles/src/viem/__tests__/viemPrecompiles.spec.ts @@ -5,64 +5,38 @@ import { DISTRIBUTION_PRECOMPILE_ABI, GOVERNANCE_PRECOMPILE_ABI, JSON_PRECOMPILE_ABI, + P256_PRECOMPILE_ABI, POINTER_PRECOMPILE_ABI, POINTERVIEW_PRECOMPILE_ABI, SOLO_PRECOMPILE_ABI, STAKING_PRECOMPILE_ABI, WASM_PRECOMPILE_ABI } from '../../precompiles'; +import * as viemEntryPoint from '../'; -import { - VIEM_ADDRESS_PRECOMPILE_ABI, - VIEM_BANK_PRECOMPILE_ABI, - VIEM_DISTRIBUTION_PRECOMPILE_ABI, - VIEM_GOVERNANCE_PRECOMPILE_ABI, - VIEM_JSON_PRECOMPILE_ABI, - VIEM_POINTER_PRECOMPILE_ABI, - VIEM_POINTERVIEW_PRECOMPILE_ABI, - VIEM_SOLO_PRECOMPILE_ABI, - VIEM_STAKING_PRECOMPILE_ABI, - VIEM_WASM_PRECOMPILE_ABI -} from '../'; - -const PRECOMPILE_VIEM_ABIS: [string, Abi][] = [ - ['ADDRESS', ADDRESS_PRECOMPILE_ABI as Abi], - ['BANK', BANK_PRECOMPILE_ABI as Abi], - ['DISTRIBUTION', DISTRIBUTION_PRECOMPILE_ABI as Abi], - ['GOVERNANCE', GOVERNANCE_PRECOMPILE_ABI as Abi], - ['JSON', JSON_PRECOMPILE_ABI as Abi], - ['POINTER', POINTER_PRECOMPILE_ABI as Abi], - ['POINTERVIEW', POINTERVIEW_PRECOMPILE_ABI as Abi], - ['SOLO', SOLO_PRECOMPILE_ABI as Abi], - ['STAKING', STAKING_PRECOMPILE_ABI as Abi], - ['WASM', WASM_PRECOMPILE_ABI as Abi] +const PRECOMPILE_ABIS: [string, Abi, Abi][] = [ + ['ADDRESS', ADDRESS_PRECOMPILE_ABI, viemEntryPoint.ADDRESS_PRECOMPILE_ABI], + ['BANK', BANK_PRECOMPILE_ABI, viemEntryPoint.BANK_PRECOMPILE_ABI], + ['DISTRIBUTION', DISTRIBUTION_PRECOMPILE_ABI, viemEntryPoint.DISTRIBUTION_PRECOMPILE_ABI], + ['GOVERNANCE', GOVERNANCE_PRECOMPILE_ABI, viemEntryPoint.GOVERNANCE_PRECOMPILE_ABI], + ['JSON', JSON_PRECOMPILE_ABI, viemEntryPoint.JSON_PRECOMPILE_ABI], + ['P256', P256_PRECOMPILE_ABI, viemEntryPoint.P256_PRECOMPILE_ABI], + ['POINTER', POINTER_PRECOMPILE_ABI, viemEntryPoint.POINTER_PRECOMPILE_ABI], + ['POINTERVIEW', POINTERVIEW_PRECOMPILE_ABI, viemEntryPoint.POINTERVIEW_PRECOMPILE_ABI], + ['SOLO', SOLO_PRECOMPILE_ABI, viemEntryPoint.SOLO_PRECOMPILE_ABI], + ['STAKING', STAKING_PRECOMPILE_ABI, viemEntryPoint.STAKING_PRECOMPILE_ABI], + ['WASM', WASM_PRECOMPILE_ABI, viemEntryPoint.WASM_PRECOMPILE_ABI] ]; describe('Viem precompile ABIs', () => { - it.each(PRECOMPILE_VIEM_ABIS)('%s ABI should be a valid Viem Abi array', (_name, abi) => { + it.each(PRECOMPILE_ABIS)('%s ABI should be a valid Viem Abi array', (_name, _rawAbi, abi) => { expect(Array.isArray(abi)).toBe(true); for (const entry of abi) { expect(entry).toHaveProperty('type'); } }); -}); - -const ABI_PAIRS: [string, Abi, Abi][] = [ - ['ADDRESS', ADDRESS_PRECOMPILE_ABI, VIEM_ADDRESS_PRECOMPILE_ABI], - ['BANK', BANK_PRECOMPILE_ABI, VIEM_BANK_PRECOMPILE_ABI], - ['DISTRIBUTION', DISTRIBUTION_PRECOMPILE_ABI, VIEM_DISTRIBUTION_PRECOMPILE_ABI], - ['GOVERNANCE', GOVERNANCE_PRECOMPILE_ABI, VIEM_GOVERNANCE_PRECOMPILE_ABI], - ['JSON', JSON_PRECOMPILE_ABI, VIEM_JSON_PRECOMPILE_ABI], - ['POINTER', POINTER_PRECOMPILE_ABI, VIEM_POINTER_PRECOMPILE_ABI], - ['POINTERVIEW', POINTERVIEW_PRECOMPILE_ABI, VIEM_POINTERVIEW_PRECOMPILE_ABI], - ['SOLO', SOLO_PRECOMPILE_ABI, VIEM_SOLO_PRECOMPILE_ABI], - ['STAKING', STAKING_PRECOMPILE_ABI, VIEM_STAKING_PRECOMPILE_ABI], - ['WASM', WASM_PRECOMPILE_ABI, VIEM_WASM_PRECOMPILE_ABI] -]; -describe('Viem precompile ABI exports', () => { - it.each(ABI_PAIRS)('%s VIEM ABI should exactly match the raw ABI', (_name, rawAbi, viemAbi) => { - expect(viemAbi).toBe(rawAbi); // referential equality - expect(viemAbi).toEqual(rawAbi); // deep equality (optional) + it.each(PRECOMPILE_ABIS)('%s ABI should preserve raw export identity', (_name, rawAbi, entryPointAbi) => { + expect(entryPointAbi).toBe(rawAbi); }); }); diff --git a/packages/precompiles/src/viem/addressPrecompile.ts b/packages/precompiles/src/viem/addressPrecompile.ts deleted file mode 100644 index 4ecc5e917..000000000 --- a/packages/precompiles/src/viem/addressPrecompile.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { Abi } from 'viem'; -import { ADDRESS_PRECOMPILE_ABI } from '../precompiles'; - -/** - * The Viem ABI for the Address precompile contract. - * @category ABI - */ -export const VIEM_ADDRESS_PRECOMPILE_ABI = ADDRESS_PRECOMPILE_ABI as Abi; diff --git a/packages/precompiles/src/viem/bankPrecompile.ts b/packages/precompiles/src/viem/bankPrecompile.ts deleted file mode 100644 index 6fcc78be1..000000000 --- a/packages/precompiles/src/viem/bankPrecompile.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { Abi } from 'viem'; -import { BANK_PRECOMPILE_ABI } from '../precompiles'; - -/** - * The Viem ABI for the Bank precompile contract. - * @category ABI - */ -export const VIEM_BANK_PRECOMPILE_ABI = BANK_PRECOMPILE_ABI as Abi; diff --git a/packages/precompiles/src/viem/distributionPrecompile.ts b/packages/precompiles/src/viem/distributionPrecompile.ts deleted file mode 100644 index a93467098..000000000 --- a/packages/precompiles/src/viem/distributionPrecompile.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { Abi } from 'viem'; -import { DISTRIBUTION_PRECOMPILE_ABI } from '../precompiles'; - -/** - * The Viem ABI for the Distribution precompile contract. - * @category ABI - */ -export const VIEM_DISTRIBUTION_PRECOMPILE_ABI = DISTRIBUTION_PRECOMPILE_ABI as Abi; diff --git a/packages/precompiles/src/viem/governancePrecompile.ts b/packages/precompiles/src/viem/governancePrecompile.ts deleted file mode 100644 index 17118ed37..000000000 --- a/packages/precompiles/src/viem/governancePrecompile.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { Abi } from 'viem'; -import { GOVERNANCE_PRECOMPILE_ABI } from '../precompiles'; - -/** - * The Viem ABI for the Governance precompile contract. - * @category ABI - */ -export const VIEM_GOVERNANCE_PRECOMPILE_ABI = GOVERNANCE_PRECOMPILE_ABI as Abi; diff --git a/packages/precompiles/src/viem/index.ts b/packages/precompiles/src/viem/index.ts index 6bd6cf615..0a68546cb 100644 --- a/packages/precompiles/src/viem/index.ts +++ b/packages/precompiles/src/viem/index.ts @@ -1,11 +1,2 @@ -export * from './addressPrecompile'; -export * from './bankPrecompile'; +export * from '../precompiles'; export * from './chain'; -export * from './distributionPrecompile'; -export * from './governancePrecompile'; -export * from './jsonPrecompile'; -export * from './pointerPrecompile'; -export * from './pointerviewPrecompile'; -export * from './soloPrecompile'; -export * from './stakingPrecompile'; -export * from './wasmPrecompile'; diff --git a/packages/precompiles/src/viem/jsonPrecompile.ts b/packages/precompiles/src/viem/jsonPrecompile.ts deleted file mode 100644 index f73f64a7a..000000000 --- a/packages/precompiles/src/viem/jsonPrecompile.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { Abi } from 'viem'; -import { JSON_PRECOMPILE_ABI } from '../precompiles'; - -/** - * The Viem ABI for the JSON precompile contract. - * @category ABI - */ -export const VIEM_JSON_PRECOMPILE_ABI = JSON_PRECOMPILE_ABI as Abi; diff --git a/packages/precompiles/src/viem/pointerPrecompile.ts b/packages/precompiles/src/viem/pointerPrecompile.ts deleted file mode 100644 index 56449200a..000000000 --- a/packages/precompiles/src/viem/pointerPrecompile.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { Abi } from 'viem'; -import { POINTER_PRECOMPILE_ABI } from '../precompiles'; - -/** - * The Viem ABI for the Pointer precompile contract. - * @category ABI - */ -export const VIEM_POINTER_PRECOMPILE_ABI = POINTER_PRECOMPILE_ABI as Abi; diff --git a/packages/precompiles/src/viem/pointerviewPrecompile.ts b/packages/precompiles/src/viem/pointerviewPrecompile.ts deleted file mode 100644 index f47e9736b..000000000 --- a/packages/precompiles/src/viem/pointerviewPrecompile.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { Abi } from 'viem'; -import { POINTERVIEW_PRECOMPILE_ABI } from '../precompiles'; - -/** - * The Viem ABI for the Ponterview precompile contract. - * @category ABI - */ -export const VIEM_POINTERVIEW_PRECOMPILE_ABI = POINTERVIEW_PRECOMPILE_ABI as Abi; diff --git a/packages/precompiles/src/viem/soloPrecompile.ts b/packages/precompiles/src/viem/soloPrecompile.ts deleted file mode 100644 index 5d8aafb9a..000000000 --- a/packages/precompiles/src/viem/soloPrecompile.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { Abi } from 'viem'; -import { SOLO_PRECOMPILE_ABI } from '../precompiles'; - -/** - * The Viem ABI for the Solo precompile contract. - * @category ABI - */ -export const VIEM_SOLO_PRECOMPILE_ABI = SOLO_PRECOMPILE_ABI as Abi; diff --git a/packages/precompiles/src/viem/stakingPrecompile.ts b/packages/precompiles/src/viem/stakingPrecompile.ts deleted file mode 100644 index 11d55343f..000000000 --- a/packages/precompiles/src/viem/stakingPrecompile.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { Abi } from 'viem'; -import { STAKING_PRECOMPILE_ABI } from '../precompiles'; - -/** - * The Viem ABI for the Staking precompile contract. - * @category ABI - */ -export const VIEM_STAKING_PRECOMPILE_ABI = STAKING_PRECOMPILE_ABI as Abi; diff --git a/packages/precompiles/src/viem/wasmPrecompile.ts b/packages/precompiles/src/viem/wasmPrecompile.ts deleted file mode 100644 index 94418af4c..000000000 --- a/packages/precompiles/src/viem/wasmPrecompile.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { Abi } from 'viem'; -import { WASM_PRECOMPILE_ABI } from '../precompiles'; - -/** - * The Viem ABI for the Wasm precompile contract. - * @category ABI - */ -export const VIEM_WASM_PRECOMPILE_ABI = WASM_PRECOMPILE_ABI as Abi; diff --git a/scripts/check-precompile-exports.ts b/scripts/check-precompile-exports.ts index 43ae10d1d..5e29751de 100644 --- a/scripts/check-precompile-exports.ts +++ b/scripts/check-precompile-exports.ts @@ -41,6 +41,9 @@ const precompilesModule = await import(join(pkgDir, 'dist/precompiles/index.js') if (typeof ethersModule.getBankPrecompileEthersV6Contract !== 'function') { missing.push('getBankPrecompileEthersV6Contract is not a function'); } +if (typeof ethersModule.getP256PrecompileEthersV6Contract !== 'function') { + missing.push('getP256PrecompileEthersV6Contract is not a function'); +} for (const [name, chainId] of [ ['sei', 1329], ['seiTestnet', 1328], @@ -56,15 +59,27 @@ for (const [name, chainId] of [ if (!precompilesModule.BANK_PRECOMPILE_ADDRESS) { missing.push('BANK_PRECOMPILE_ADDRESS missing'); } +if (!precompilesModule.P256_PRECOMPILE_ADDRESS) { + missing.push('P256_PRECOMPILE_ADDRESS missing'); +} if (rootModule.BANK_PRECOMPILE_ABI !== precompilesModule.BANK_PRECOMPILE_ABI) { missing.push('root and precompiles subpaths do not share ABI identity'); } -if (rootModule.VIEM_BANK_PRECOMPILE_ABI !== viemModule.VIEM_BANK_PRECOMPILE_ABI) { +if (rootModule.BANK_PRECOMPILE_ABI !== viemModule.BANK_PRECOMPILE_ABI) { missing.push('root and viem subpaths do not share ABI identity'); } +if (rootModule.P256_PRECOMPILE_ABI !== precompilesModule.P256_PRECOMPILE_ABI) { + missing.push('root and precompiles subpaths do not share P256 ABI identity'); +} +if (rootModule.P256_PRECOMPILE_ABI !== viemModule.P256_PRECOMPILE_ABI) { + missing.push('root and viem subpaths do not share P256 ABI identity'); +} if (rootModule.getBankPrecompileEthersV6Contract !== ethersModule.getBankPrecompileEthersV6Contract) { missing.push('root and ethers subpaths do not share factory identity'); } +if (rootModule.getP256PrecompileEthersV6Contract !== ethersModule.getP256PrecompileEthersV6Contract) { + missing.push('root and ethers subpaths do not share P256 factory identity'); +} if (missing.length > 0) { console.error('Precompile export check failed:\n', missing.map((m) => ` - ${m}`).join('\n'));