Skip to content

Commit 7a5aaa0

Browse files
committed
feat: generate TypeScript ABI files for improved type inference
1 parent 3b02e4d commit 7a5aaa0

5 files changed

Lines changed: 60 additions & 6 deletions

File tree

contracts/README.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ After installation, use the following paths:
2323
| Path | Description |
2424
|------|-------------|
2525
| `cosmos-evm-contracts/precompiles/` | Solidity sources (`.sol`) |
26-
| `cosmos-evm-contracts/abi/precompiles/` | ABI-only JSON (`.json`) |
26+
| `cosmos-evm-contracts/abi/precompiles/` | ABI as JSON (`.json`) or typed ESM (`.js` + `.d.ts`) |
2727

2828
Included precompiles: `bank`, `bech32`, `callbacks`, `common`, `distribution`, `erc20`, `gov`, `ics02`, `ics20`, `slashing`, `staking`, `werc20` (testdata and testutil excluded).
2929

@@ -38,6 +38,27 @@ import IBankAbi from "cosmos-evm-contracts/abi/precompiles/bank/IBank.json" asse
3838
const IBankAbi = require("cosmos-evm-contracts/abi/precompiles/bank/IBank.json");
3939
```
4040

41+
### Loading ABI with TypeScript / viem (typed)
42+
43+
Import the named ABI constant so that `functionName`, `args`, and return types are inferred:
44+
45+
```typescript
46+
import { createPublicClient, http } from "viem";
47+
import { IBank_ABI } from "cosmos-evm-contracts/abi/precompiles/bank/IBank";
48+
49+
const client = createPublicClient({ transport: http() });
50+
51+
// functionName and args are type-checked and autocompleted
52+
const balances = await client.readContract({
53+
address: "0x0000000000000000000000000000000000000804",
54+
abi: IBank_ABI,
55+
functionName: "balances",
56+
args: ["0x..."],
57+
});
58+
```
59+
60+
Use the same pattern for other precompiles, e.g. `DistributionI_ABI` from `abi/precompiles/distribution/DistributionI`, `StakingI_ABI` from `abi/precompiles/staking/StakingI`, etc.
61+
4162
### Using interfaces in Hardhat
4263

4364
Import by package path in your contract:

contracts/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
{
22
"name": "cosmos-evm-contracts",
33
"packageManager": "pnpm@9.15.0",
4-
"version": "0.0.1",
4+
"version": "0.0.6",
55
"description": "A collection of smart contracts used in the development of the Cosmos EVM blockchain.",
66
"devDependencies": {
77
"@openzeppelin/contracts": "^5.4.0",
8-
"hardhat": "^3.1.10"
8+
"hardhat": "^3.1.10",
9+
"typescript": "^5.0.0"
910
},
1011
"scripts": {
11-
"build:precompiles": "node scripts/build-precompiles.js",
12+
"build:precompiles": "node scripts/build-precompiles.js && pnpm exec tsc -p tsconfig.json",
1213
"compile": "hardhat compile",
1314
"prepublishOnly": "pnpm run build:precompiles"
1415
},

contracts/pnpm-lock.yaml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/scripts/build-precompiles.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/**
33
* Build precompile contracts (excluding testdata, testutil) in OpenZeppelin style:
44
* - dist/precompiles/ : .sol sources
5-
* - dist/abi/ : ABI-only JSON per contract
5+
* - dist/abi/ : ABI-only JSON + .ts (as const); tsc emits .js + .d.ts
66
*
77
* Run from contracts directory: pnpm run build:precompiles
88
*/
@@ -80,14 +80,22 @@ function buildPrecompiles() {
8080
if (!sourceName || !sourceName.startsWith("solidity/precompiles/")) continue;
8181

8282
const relFromSolidity = sourceName.replace(/^solidity\//, ""); // precompiles/bank/IBank.sol
83+
const contractName = relFromSolidity.replace(/\.sol$/, "").split("/").pop(); // e.g. IBank
8384
const solPath = join(SOLIDITY_SOURCE, relFromSolidity);
8485
const abiOutPath = join(DIST_ABI, relFromSolidity.replace(".sol", ".json"));
86+
const abiTsOutPath = join(DIST_ABI, relFromSolidity.replace(".sol", ".ts"));
8587
const solOutPath = join(DIST, relFromSolidity);
8688

8789
ensureDir(dirname(abiOutPath));
8890
ensureDir(dirname(solOutPath));
8991

90-
writeFileSync(abiOutPath, JSON.stringify(artifact.abi ?? [], null, 2), "utf8");
92+
const abi = artifact.abi ?? [];
93+
writeFileSync(abiOutPath, JSON.stringify(abi, null, 2), "utf8");
94+
writeFileSync(
95+
abiTsOutPath,
96+
`export const ${contractName}_ABI = ${JSON.stringify(abi, null, 2)} as const;\n`,
97+
"utf8"
98+
);
9199
if (existsSync(solPath)) {
92100
cpSync(solPath, solOutPath);
93101
copiedSol.add(relFromSolidity);

contracts/tsconfig.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2020",
4+
"module": "ESNext",
5+
"moduleResolution": "node",
6+
"declaration": true,
7+
"rootDir": "dist/abi",
8+
"outDir": "dist/abi",
9+
"skipLibCheck": true,
10+
"strict": true
11+
},
12+
"include": ["dist/abi/**/*.ts"],
13+
"exclude": []
14+
}

0 commit comments

Comments
 (0)