[TypeScript] `ViemWalletProvider` rejects a wallet client from a newer viem than the exactly pinned one (TS2345, `tokens` missing on `Client`)
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
- Domain
- tooling
Research direction
Start with typescript/agentkit/package.json and inspect the viem dependency and peer dependency settings. Reproduce the failure with the provided typecheck.ts and newer viem version, then verify that the dependency setup allows the project client to typecheck without a cast and that the pinned-version control case still passes.
Written by the indexing model from the issue text.
Description
Language Affected
- Python
- TypeScript
Describe the bug
@coinbase/agentkit depends on viem with an exact version ("viem": "2.38.3" in 0.10.4). A project that uses a newer viem (2.57.2 here) gets two copies of viem: its own at the top level, and AgentKit's pinned one under node_modules/@coinbase/agentkit/node_modules/viem. Viem's Client types are not structurally compatible across these two copies, so a wallet client created in the project does not typecheck as the argument of new ViemWalletProvider(...). Passing a viem wallet client is the constructor's only argument, so a TypeScript project on a newer viem hits this, and the options are to pin the project's viem to AgentKit's exact version or to cast.
Reproduction (no network needed, this is type-level only)
npm init -y
npm i @coinbase/[email protected] [email protected] typescript@5
tsconfig.json:
{ "compilerOptions": { "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext", "strict": true, "noEmit": true, "skipLibCheck": true }, "include": ["typecheck.ts"] }
typecheck.ts:
import { ViemWalletProvider } from "@coinbase/agentkit";
import { createWalletClient, http } from "viem";
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
import { foundry } from "viem/chains";
const walletProvider = new ViemWalletProvider(
createWalletClient({
account: privateKeyToAccount(generatePrivateKey()),
chain: foundry,
transport: http(),
}),
);
npx tsc --noEmit -p . fails (tsc 5.9.3). First line and last line of the error (full output below):
typecheck.ts(7,3): error TS2345: Argument of type '{ account: { address: `0x${string}`; nonceManager?: NonceManager | undefined; sign: ...
...
Property 'tokens' is missing in type 'Client' but required in type 'Client_Base<Transport, Chain | undefined, Account | undefined, undefined, Tokens | undefined>'.
The chain of "incompatible" properties goes account -> nonceManager -> consume -> client and ends in Client of AgentKit's viem (node_modules/@coinbase/agentkit/node_modules/viem/_types/clients/createClient) lacking the tokens member that the project's viem 2.57.2 has.
Full tsc output
typecheck.ts(7,3): error TS2345: Argument of type '{ account: { address: `0x${string}`; nonceManager?: NonceManager | undefined; sign: (parameters: { hash: `0x${string}`; }) => Promise<`0x${string}`>; signAuthorization: (parameters: AuthorizationRequest) => Promise<...>; ... 5 more ...; type: "local"; }; ... 43 more ...; extend: <const client extends { ...; } & Exac...' is not assignable to parameter of type '{ account: Account | undefined; batch?: { multicall?: boolean | { batchSize?: number | undefined; deployless?: boolean | undefined; wait?: number | undefined; } | undefined; } | undefined; ... 38 more ...; extend: <const client extends { ...; } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>...'.
Types of property 'account' are incompatible.
Type '{ address: `0x${string}`; nonceManager?: NonceManager | undefined; sign: (parameters: { hash: `0x${string}`; }) => Promise<`0x${string}`>; signAuthorization: (parameters: AuthorizationRequest) => Promise<...>; ... 5 more ...; type: "local"; }' is not assignable to type 'Account | undefined'.
Type '{ address: `0x${string}`; nonceManager?: NonceManager | undefined; sign: (parameters: { hash: `0x${string}`; }) => Promise<`0x${string}`>; signAuthorization: (parameters: AuthorizationRequest) => Promise<...>; ... 5 more ...; type: "local"; }' is not assignable to type '{ address: `0x${string}`; nonceManager?: NonceManager | undefined; sign?: ((parameters: { hash: `0x${string}`; }) => Promise<`0x${string}`>) | undefined; signAuthorization?: ((parameters: AuthorizationRequest) => Promise<...>) | undefined; ... 19 more ...; isDeployed?: undefined; }'.
Types of property 'nonceManager' are incompatible.
Type 'import("<project>/node_modules/viem/_types/utils/nonceManager", { with: { "resolution-mode": "import" } }).NonceManager | undefined' is not assignable to type 'import("<project>/node_modules/@coinbase/agentkit/node_modules/viem/_types/utils/nonceManager").NonceManager | undefined'.
Type 'import("<project>/node_modules/viem/_types/utils/nonceManager", { with: { "resolution-mode": "import" } }).NonceManager' is not assignable to type 'import("<project>/node_modules/@coinbase/agentkit/node_modules/viem/_types/utils/nonceManager").NonceManager'.
Types of property 'consume' are incompatible.
Type '(parameters: FunctionParameters & { client: import("<project>/node_modules/viem/_types/clients/createClient", { with: { "resolution-mode": "import" } }).Client; }) => Promise<...>' is not assignable to type '(parameters: FunctionParameters & { client: import("<project>/node_modules/@coinbase/agentkit/node_modules/viem/_types/clients/createClient").Client; }) => Promise<...>'.
Types of parameters 'parameters' and 'parameters' are incompatible.
Type 'FunctionParameters & { client: import("<project>/node_modules/@coinbase/agentkit/node_modules/viem/_types/clients/createClient").Client; }' is not assignable to type 'FunctionParameters & { client: import("<project>/node_modules/viem/_types/clients/createClient", { with: { "resolution-mode": "import" } }).Client; }'.
Type 'FunctionParameters & { client: Client; }' is not assignable to type '{ client: Client; }'.
Types of property 'client' are incompatible.
Type 'import("<project>/node_modules/@coinbase/agentkit/node_modules/viem/_types/clients/createClient").Client' is not assignable to type 'import("<project>/node_modules/viem/_types/clients/createClient", { with: { "resolution-mode": "import" } }).Client'.
Property 'tokens' is missing in type 'Client' but required in type 'Client_Base<Transport, Chain | undefined, Account | undefined, undefined, Tokens | undefined>'.
Control: with npm i [email protected] (the version AgentKit pins) the two copies dedupe and the same file typechecks with exit code 0.
npm ls for the failing install shows the two copies: [email protected] at the top level and [email protected] nested under @coinbase/agentkit.
Expected: a viem client created from a compatible newer viem is accepted by ViemWalletProvider without casting.
Pin on current main (read from the source, not run): typescript/agentkit/package.json on main (2e6dbaf, version 0.11.0, not yet published to npm) still pins viem exactly, now to 2.47.4 (line 75 under dependencies), and has no peerDependencies. The latest npm release is 0.10.4 (2.38.3). I did not test 2.47.4 against 2.57.2.
Possible fix: treat viem as a peer dependency with a range (for example "peerDependencies": { "viem": "^2.38.3" }, possibly with peerDependenciesMeta if some users do not use the viem wallet providers), so a project and AgentKit share one copy. At minimum, a caret range for the regular dependency lets package managers dedupe within the 2.x line. The ViemWalletProvider constructor type could also be loosened, but a shared copy is the more robust fix. I did not check whether other viem-typed public signatures (for example getPublicClient()) are affected the same way.
I am happy to open a PR for the peer dependency change if that direction is acceptable.
Versions
$ node --version
v24.21.0
$ npm list @coinbase/agentkit viem typescript
├── @coinbase/[email protected]
├── [email protected]
└── [email protected]
Related, not duplicates: #332 (install only the dependencies of enabled providers) and #272 (expose viem client actions from ViemWalletProvider) touch the same area; I found no open or closed issue or PR about the viem version pin.
- Dominant language
- TypeScript
- Stars
- 1.3k
- Forks
- 857
- PR merge metrics
- No merged PRs in 30d
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from coinbase/agentkit
-
ERC20 transfer reports "Transferred" when the transaction reverts (receipt status ignored)Possibly taken @AgenticFinanceGraph claimed this 3 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
coinbase/agentkit#1558 · 1 comment ·
Maintainers usually reply within 1 day
-
coinbase-agentkit 0.7.x fails on fresh install: imports solana.rpc.api, which solana>=0.37 removedPossibly taken @JulienKervarrec claimed this 21 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 15/100
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 15/100
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 45/100
Maintainers usually reply within 1 day
All issues in coinbase/agentkit
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
homarr-labs/homarr#7191 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
AvaProtocol/ava-sdk-js#276 ·
Maintainers usually reply within 1 day
-
useFragment does not require `variables` when the fragment's variables type has required fieldsOpen
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
apollographql/apollo-client#13493 ·
Maintainers usually reply within 1 day