{"_id":"@0xtan0/chain-utils-core","_rev":"2-b90d8c729c8df043f7749f81b3c32e02","name":"@0xtan0/chain-utils-core","dist-tags":{"latest":"0.1.1"},"versions":{"0.0.1":{"name":"@0xtan0/chain-utils-core","version":"0.0.1","author":{"name":"Wonderland"},"license":"MIT","_id":"@0xtan0/chain-utils-core@0.0.1","maintainers":[{"name":"0xtan0","email":"tano@wonderland.xyz"}],"dist":{"shasum":"2279152d56c329afb23bded9b59f11c97cccaa6c","tarball":"https://registry.npmjs.org/@0xtan0/chain-utils-core/-/chain-utils-core-0.0.1.tgz","fileCount":90,"integrity":"sha512-ESwFqNj68wizjPFbFR9oqSWsDITzkyEJWZ0ZNyUaiMQoEk0zg8+jQ+9pRP4F/8JtKhganAAqIL1O144N2582PA==","signatures":[{"sig":"MEQCICKTClQL821vTIGNMVb6edUon+aFUTgiMHYxyybKP+NmAiAdAoXRO8EqScCK+qIz6SNS3R9ObcpBZBPy7ZAe0oUUKA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":128142},"main":"./dist/src/index.js","type":"module","types":"./dist/src/index.d.ts","exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js","default":"./dist/src/index.js"}},"gitHead":"bdb7dc8fb7be021b8f629b1247639bce0bc0ec56","private":false,"scripts":{"lint":"eslint \"{src,test}/**/*.{js,ts,json}\"","test":"vitest run --config vitest.config.ts --passWithNoTests","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist/","format":"prettier --check \"{src,test}/**/*.{js,ts,json}\"","lint:fix":"pnpm lint --fix","test:cov":"vitest run --config vitest.config.ts --coverage","format:fix":"prettier --write \"{src,test}/**/*.{js,ts,json}\"","check-types":"tsc --noEmit -p ./tsconfig.json"},"_npmUser":{"name":"0xtan0","email":"tano@wonderland.xyz"},"_npmVersion":"10.8.2","description":"Low-level multichain client primitives for [viem](https://viem.sh/). It handles RPC connections, contract reads/writes, multicall batching, and the `prepare -> sign -> send` pipeline.","directories":{"src":"src"},"_nodeVersion":"20.18.1","dependencies":{"viem":"2.45.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/chain-utils-core_0.0.1_1771776102993_0.24321246394455032","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@0xtan0/chain-utils-core","version":"0.1.1","private":false,"description":"Low-level multichain client primitives for [viem](https://viem.sh/). It handles RPC connections, contract reads/writes, multicall batching, and the `prepare -> sign -> send` pipeline.","repository":{"type":"git","url":"git+https://github.com/0xtan0/chain-utils.git","directory":"packages/core"},"license":"MIT","author":{"name":"Wonderland"},"type":"module","exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js","default":"./dist/src/index.js"}},"main":"./dist/src/index.js","types":"./dist/src/index.d.ts","directories":{"src":"src"},"dependencies":{"viem":"2.45.1"},"scripts":{"build":"tsc -p tsconfig.build.json","check-types":"tsc --noEmit -p ./tsconfig.json","clean":"rm -rf dist/","format":"prettier --check \"{src,test}/**/*.{js,ts,json}\"","format:fix":"prettier --write \"{src,test}/**/*.{js,ts,json}\"","lint":"eslint \"{src,test}/**/*.{js,ts,json}\"","lint:fix":"pnpm lint --fix","test":"vitest run --config vitest.config.ts --passWithNoTests","test:cov":"vitest run --config vitest.config.ts --coverage"},"_id":"@0xtan0/chain-utils-core@0.1.1","bugs":{"url":"https://github.com/0xtan0/chain-utils/issues"},"homepage":"https://github.com/0xtan0/chain-utils#readme","_integrity":"sha512-oqZ7wG9sH/3EqyOZPzQ0RCgTMJqpP++nk3PXi8ri1Aa9pENL9hoQSwkN5s76Bl1/6Jp826FHWQ0p1NbaL6SIOg==","_resolved":"/tmp/2bfded54393f69859127a4109585747e/0xtan0-chain-utils-core-0.1.1.tgz","_from":"file:0xtan0-chain-utils-core-0.1.1.tgz","_nodeVersion":"22.22.0","_npmVersion":"11.10.1","dist":{"integrity":"sha512-oqZ7wG9sH/3EqyOZPzQ0RCgTMJqpP++nk3PXi8ri1Aa9pENL9hoQSwkN5s76Bl1/6Jp826FHWQ0p1NbaL6SIOg==","shasum":"5517bb448920e3dbc25e43e38c6e2133dbc60f67","tarball":"https://registry.npmjs.org/@0xtan0/chain-utils-core/-/chain-utils-core-0.1.1.tgz","fileCount":71,"unpackedSize":108024,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@0xtan0%2fchain-utils-core@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAVcqbBmxepVM7SRENxzlKjFk1USgg5aOfhnv+vuLjHFAiEAmK3AlgBpDXziin8JlvD32Bmw7zqMlyjuKG8I9Bffl4U="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ed443d04-0415-4fd8-af35-bd1a58cfe79c"}},"maintainers":[{"name":"0xtan0","email":"tano@wonderland.xyz"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/chain-utils-core_0.1.1_1771784860093_0.550686603507754"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-22T16:01:42.850Z","modified":"2026-02-22T18:27:40.504Z","0.0.1":"2026-02-22T16:01:43.128Z","0.1.1":"2026-02-22T18:27:40.237Z"},"author":{"name":"Wonderland"},"license":"MIT","description":"Low-level multichain client primitives for [viem](https://viem.sh/). It handles RPC connections, contract reads/writes, multicall batching, and the `prepare -> sign -> send` pipeline.","maintainers":[{"name":"0xtan0","email":"tano@wonderland.xyz"}],"readme":"# @0xtan0/chain-utils-core\n\nLow-level multichain client primitives for [viem](https://viem.sh/). It handles RPC connections, contract reads/writes, multicall batching, and the `prepare -> sign -> send` pipeline.\n\nThis package is the foundation for higher-level packages (like `@0xtan0/chain-utils-erc20`) and is designed for both application developers and autonomous agents.\n\n## Install\n\n```bash\npnpm add @0xtan0/chain-utils-core viem\n```\n\n## Highlights\n\n-   `createMultichainClient` keeps chain wiring in one typed object instead of scattered per-chain conditionals.\n-   `ContractClient.readBatch` is multicall-first by default on chains with Multicall3, then falls back to sequential reads if needed.\n-   A single write flow (`prepare`, `sign`, `send`, `waitForReceipt`) removes ad-hoc transaction plumbing.\n-   Chain IDs and ABI function signatures are enforced at compile time.\n\n## TypeScript Safety\n\n```ts\nimport { createContractClient, createMultichainClient } from \"@0xtan0/chain-utils-core\";\nimport { createPublicClient, http } from \"viem\";\nimport { arbitrum, mainnet, optimism } from \"viem/chains\";\n\nconst publicClient = createPublicClient({ chain: mainnet, transport: http() });\nconst contractAddress = \"0x0000000000000000000000000000000000000000\";\n\nconst multichain = createMultichainClient([\n    createPublicClient({ chain: mainnet, transport: http() }),\n    createPublicClient({ chain: optimism, transport: http() }),\n] as const);\n\n// @ts-expect-error Chain 42161 is not configured in this multichain client\nmultichain.getPublicClient(arbitrum.id);\n\nconst counterAbi = [\n    {\n        type: \"function\",\n        name: \"count\",\n        stateMutability: \"view\",\n        inputs: [],\n        outputs: [{ type: \"uint256\" }],\n    },\n    {\n        type: \"function\",\n        name: \"increment\",\n        stateMutability: \"nonpayable\",\n        inputs: [],\n        outputs: [],\n    },\n] as const;\n\nconst client = createContractClient({ abi: counterAbi, publicClient });\n\nawait client.read(contractAddress, \"count\"); // ok\n\n// @ts-expect-error count() takes no arguments\nawait client.read(contractAddress, \"count\", [1n]);\n```\n\n### Example\n\nManual reads usually mean repeated `readContract` calls and custom error handling:\n\n```ts\nconst [tokenABalance, tokenBBalance] = await Promise.all([\n    publicClient.readContract({\n        abi: erc20Abi,\n        address: tokenA,\n        functionName: \"balanceOf\",\n        args: [account],\n    }),\n    publicClient.readContract({\n        abi: erc20Abi,\n        address: tokenB,\n        functionName: \"balanceOf\",\n        args: [account],\n    }),\n]);\n```\n\nWith `core`, the same flow is one typed batch call:\n\n```ts\nconst client = createContractClient({\n    abi: erc20Abi,\n    publicClient,\n});\n\nconst batch = await client.readBatch([\n    { address: tokenA, functionName: \"balanceOf\", args: [account] },\n    { address: tokenB, functionName: \"balanceOf\", args: [account] },\n]);\n```\n\n## Usage\n\n### Multichain client\n\nA typed collection of `PublicClient`s keyed by chain ID. Chain IDs are captured at the type level, so invalid references are compile-time errors.\n\n```ts\nimport { createMultichainClient } from \"@0xtan0/chain-utils-core\";\nimport { createPublicClient, http } from \"viem\";\nimport { arbitrum, mainnet, optimism } from \"viem/chains\";\n\nconst multichain = createMultichainClient([\n    createPublicClient({ chain: mainnet, transport: http() }),\n    createPublicClient({ chain: optimism, transport: http() }),\n    createPublicClient({ chain: arbitrum, transport: http() }),\n]);\n\nmultichain.chainIds; // [1, 10, 42161]\nmultichain.getPublicClient(1); // PublicClient for mainnet\nmultichain.hasChain(137); // false\n```\n\nYou can also create from transport configs:\n\n```ts\nconst multichain = createMultichainClient([\n    { chain: mainnet, transport: http() },\n    { chain: optimism, transport: http() },\n]);\n```\n\nImmutably add chains after creation:\n\n```ts\nconst expanded = multichain.withChain(polygonClient);\n```\n\n### Contract client\n\nType-safe wrapper around viem's contract interactions. Supports reads, batched multicall, and the full write pipeline.\n\n```ts\nimport { createContractClient } from \"@0xtan0/chain-utils-core\";\n\nconst client = createContractClient({\n    abi: myAbi,\n    publicClient,\n    walletClient, // optional, required for writes\n});\n```\n\n**Read a single function:**\n\n```ts\nconst value = await client.read(contractAddress, \"balanceOf\", [account]);\n```\n\n**Batch reads via multicall:**\n\n```ts\nconst batch = await client.readBatch([\n    { address: tokenA, functionName: \"balanceOf\", args: [account] },\n    { address: tokenB, functionName: \"balanceOf\", args: [account] },\n]);\n// batch.results[0].status === \"success\" | \"failure\"\n```\n\n**One-shot write (simulate + sign + send + optional wait):**\n\n```ts\nconst receipt = await client.execute(address, \"transfer\", [to, amount], {\n    waitForReceipt: true,\n});\n```\n\n**Granular write pipeline:**\n\n```ts\nconst prepared = await client.prepare(address, \"transfer\", [to, amount]);\nconst signed = await client.sign(prepared);\nconst hash = await client.send(signed);\nconst receipt = await client.waitForReceipt(hash);\n```\n\n### Error decoding\n\nAttach a custom `ErrorDecoder` to translate raw revert data into typed errors.\n\n```ts\nconst client = createContractClient({\n    abi: myAbi,\n    publicClient,\n    errorDecoder: myDecoder,\n});\n```\n\nBuilt-in error classes: `ChainUtilsFault`, `UnsupportedChain`, `RpcFailure`, `ContractReverted`, `MulticallPartialFailure`, `MulticallBatchFailure`.\n\n## API Summary\n\n| Export                     | Description                                              |\n| -------------------------- | -------------------------------------------------------- |\n| `createMultichainClient`   | Build a typed multichain RPC collection                  |\n| `MultichainClient`         | Class backing the multichain collection                  |\n| `createContractClient`     | Build a type-safe contract client                        |\n| `ContractClient`           | Class with read, readBatch, prepare, sign, send, execute |\n| `createMultichainContract` | Contract client across multiple chains                   |\n| `CompositeErrorDecoder`    | Combine multiple error decoders                          |\n\n## License\n\nMIT\n","readmeFilename":"README.md","homepage":"https://github.com/0xtan0/chain-utils#readme","repository":{"type":"git","url":"git+https://github.com/0xtan0/chain-utils.git","directory":"packages/core"},"bugs":{"url":"https://github.com/0xtan0/chain-utils/issues"}}