Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions typescript/.changeset/poor-lines-sniff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@coinbase/agentkit-model-context-protocol": minor
"@coinbase/agentkit-vercel-ai-sdk": minor
"@coinbase/agentkit-langchain": minor
"create-onchain-agent": minor
"@coinbase/agentkit": minor
---

Upgraded to zod v4, langchain v1 and vercel ai sdk v6
8 changes: 4 additions & 4 deletions typescript/agentkit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,12 @@ _Prerequisites_:
- Set `OPENAI_API_KEY` environment variable.

```bash
npm install @langchain @langchain/langgraph @langchain/openai
npm install langchain @langchain/langgraph @langchain/openai
```

```typescript
import { getLangChainTools } from "@coinbase/agentkit-langchain";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { createAgent } from "langchain";
import { ChatOpenAI } from "@langchain/openai";

const tools = await getLangChainTools(agentKit);
Expand All @@ -156,8 +156,8 @@ const llm = new ChatOpenAI({
model: "gpt-4o-mini",
});

const agent = createReactAgent({
llm,
const agent = createAgent({
model: llm,
tools,
});
```
Expand Down
12 changes: 6 additions & 6 deletions typescript/agentkit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"@across-protocol/app-sdk": "^0.2.0",
"@alloralabs/allora-sdk": "^0.1.0",
"@base-org/account": "^2.2.0",
"@coinbase/cdp-sdk": "^1.38.0",
"@coinbase/cdp-sdk": "^1.45.0",
"@dtelecom/x402-client": "^0.1.3",
"@ensofinance/sdk": "^2.0.6",
"@jup-ag/api": "^6.0.39",
Expand All @@ -52,9 +52,9 @@
"@solana/spl-token": "^0.4.12",
"@solana/web3.js": "^1.98.1",
"@vaultsfyi/sdk": "^2.1.9",
"@x402/evm": "^2.4.0",
"@x402/fetch": "^2.4.0",
"@x402/svm": "^2.4.0",
"@x402/evm": "^2.7.0",
"@x402/fetch": "^2.7.0",
"@x402/svm": "^2.7.0",
"@zerodev/ecdsa-validator": "^5.4.5",
"@zerodev/intent": "^0.0.24",
"@zerodev/sdk": "^5.4.28",
Expand All @@ -71,8 +71,8 @@
"reflect-metadata": "^0.2.2",
"sushi": "6.2.1",
"twitter-api-v2": "^1.18.2",
"viem": "2.38.3",
"zod": "^3.23.8"
"viem": "2.47.4",
"zod": "^4.3.6"
},
"devDependencies": {
"@types/jest": "^29.5.14",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export class AcrossActionProvider extends ActionProvider<EvmWalletProvider> {
throw new Error(`No input tokens available on chain ${originChain.id}`);
}
const tokenInfo = inputTokens.find(
token => token.symbol.toUpperCase() === args.inputTokenSymbol.toUpperCase(),
token => token.symbol.toUpperCase() === (args.inputTokenSymbol ?? "ETH").toUpperCase(),
);
if (!tokenInfo) {
throw new Error(
Expand All @@ -141,7 +141,7 @@ export class AcrossActionProvider extends ActionProvider<EvmWalletProvider> {
const inputAmount = parseUnits(args.amount, decimals);

// Check balance
const isNative = args.inputTokenSymbol.toUpperCase() === "ETH";
const isNative = (args.inputTokenSymbol ?? "ETH").toUpperCase() === "ETH";
if (isNative) {
// Check native ETH balance
const ethBalance = await walletProvider.getBalance();
Expand Down Expand Up @@ -212,7 +212,7 @@ export class AcrossActionProvider extends ActionProvider<EvmWalletProvider> {
((Number(formattedInfo.inputAmount) - Number(formattedInfo.outputAmount)) /
Number(formattedInfo.inputAmount)) *
100;
if (actualSlippagePercentage > args.maxSplippage) {
if (actualSlippagePercentage > (args.maxSplippage ?? 1.5)) {
throw new Error(
`Output amount has high slippage of ${actualSlippagePercentage.toFixed(2)}%, which exceeds the maximum allowed slippage of ${args.maxSplippage}%. ` +
`Input: ${formattedInfo.inputAmount} ${args.inputTokenSymbol}, Output: ${formattedInfo.outputAmount} ${args.inputTokenSymbol}`,
Expand Down
15 changes: 7 additions & 8 deletions typescript/agentkit/src/action-providers/across/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@ export const BridgeTokenSchema = z
inputTokenSymbol: z
.string()
.describe("The symbol of the token to bridge (e.g., 'ETH', 'WETH', 'USDC')")
.default("ETH"),
.nullable()
.transform(val => val ?? "ETH"),
amount: z
.string()
.describe("The amount of tokens to bridge in whole units (e.g. 1.5 WETH, 10 USDC)"),
recipient: z
.string()
.optional()
.nullable()
.describe("The recipient address on the destination chain (defaults to sender)"),
maxSplippage: z
.number()
.optional()
.describe("The maximum slippage percentage (e.g. 10 for 10%)")
.default(1.5),
.nullable()
.transform(val => val ?? 1.5)
.describe("The maximum slippage percentage (e.g. 10 for 10%)"),
})
.strip()
.describe("Instructions for bridging tokens across chains using Across Protocol");

/**
Expand All @@ -35,11 +35,10 @@ export const CheckDepositStatusSchema = z
.object({
originChainId: z
.string()
.optional()
.nullable()
.describe("The chain ID of the origin chain (defaults to the current chain)"),
depositId: z
.string()
.describe("The ID of the deposit to check (returned by the bridge deposit transaction)"),
})
.strip()
.describe("Instructions for checking the status of a deposit on Across Protocol");
3 changes: 0 additions & 3 deletions typescript/agentkit/src/action-providers/allora/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { z } from "zod";
*/
export const GetAllTopicsSchema = z
.object({})
.strip()
.describe("Instructions for getting all topics from Allora Network");

/**
Expand All @@ -15,7 +14,6 @@ export const GetInferenceByTopicIdSchema = z
.object({
topicId: z.number().describe("The ID of the topic to get inference data for"),
})
.strip()
.describe("Instructions for getting inference data from Allora Network by topic ID");

/**
Expand All @@ -26,5 +24,4 @@ export const GetPriceInferenceSchema = z
asset: z.string().describe("The token to get price inference for (e.g., 'BTC', 'ETH')"),
timeframe: z.string().describe("The timeframe for the prediction (e.g., '8h', '24h')"),
})
.strip()
.describe("Instructions for getting price inference for a token/timeframe pair");
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ describe("UseBaseAccountSpendPermissionSchema", () => {
const validInput = {
baseAccount: MOCK_BASE_ACCOUNT,
amount: MOCK_AMOUNT_USD,
tokenAddress: null,
permissionIndex: null,
};

const result = UseBaseAccountSpendPermissionSchema.safeParse(validInput);
Expand Down Expand Up @@ -155,6 +157,7 @@ describe("RevokeBaseAccountSpendPermissionSchema", () => {
it("should successfully parse valid input without permission index", () => {
const validInput = {
baseAccount: MOCK_BASE_ACCOUNT,
permissionIndex: null,
};

const result = RevokeBaseAccountSpendPermissionSchema.safeParse(validInput);
Expand Down Expand Up @@ -273,6 +276,8 @@ describe("BaseAccountActionProvider", () => {
const args = {
baseAccount: MOCK_BASE_ACCOUNT,
amount: MOCK_AMOUNT_USD,
tokenAddress: null,
permissionIndex: null,
};

const response = await actionProvider.spendFromBaseAccountPermission(mockWallet, args);
Expand All @@ -299,6 +304,8 @@ describe("BaseAccountActionProvider", () => {
const args = {
baseAccount: MOCK_BASE_ACCOUNT,
amount: 10.5, // 10.5 USDC
tokenAddress: null,
permissionIndex: null,
};

const response = await actionProvider.spendFromBaseAccountPermission(mockWallet, args);
Expand Down Expand Up @@ -330,6 +337,8 @@ describe("BaseAccountActionProvider", () => {
const args = {
baseAccount: MOCK_BASE_ACCOUNT,
amount: 10.5, // Trying to spend 10.5 USDC but only 1 available
tokenAddress: null,
permissionIndex: null,
};

const response = await actionProvider.spendFromBaseAccountPermission(mockWallet, args);
Expand All @@ -348,6 +357,7 @@ describe("BaseAccountActionProvider", () => {

const args = {
baseAccount: MOCK_BASE_ACCOUNT,
permissionIndex: null,
};

const response = await actionProvider.revokeBaseAccountSpendPermission(mockWallet, args);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export const ListBaseAccountSpendPermissionsSchema = z
.regex(/^0x[a-fA-F0-9]{40}$/, "Invalid Ethereum address format")
.describe("The Base Account address to query if it has granted spend permissions"),
})
.strip()
.describe("Instructions for listing spend permissions for a Base Account");

/**
Expand All @@ -25,27 +24,26 @@ export const UseBaseAccountSpendPermissionSchema = z
amount: z
.number()
.positive()
.optional()
.nullable()
.describe(
"The amount to spend in whole units of the token (e.g. 4.6 for 4.6 tokens). If not provided, will withdraw the full remaining allowance",
),
tokenAddress: z
.string()
.regex(/^0x[a-fA-F0-9]{40}$/, "Invalid Ethereum address format")
.optional()
.nullable()
.describe(
"The token contract address. If not provided, will use the first available permission token",
),
permissionIndex: z
.number()
.int()
.positive()
.optional()
.nullable()
.describe(
"The index of the permission to use (1-based). If not provided, the first permission will be used",
),
})
.strip()
.describe("Instructions for using a Base Account spend permission");

/**
Expand All @@ -61,10 +59,9 @@ export const RevokeBaseAccountSpendPermissionSchema = z
.number()
.int()
.positive()
.optional()
.nullable()
.describe(
"The index of the permission to revoke (1-based). If not provided, the first permission will be revoked",
),
})
.strip()
.describe("Instructions for revoking a Base Account spend permission");
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import { z } from "zod";
export const RegisterBasenameSchema = z
.object({
basename: z.string().describe("The Basename to assign to the agent"),
amount: z.string().default("0.002").describe("The amount of ETH to pay for registration"),
amount: z
.string()
.nullable()
.transform(val => val ?? "0.002")
.describe("The amount of ETH to pay for registration"),
})
.strip()
.describe("Instructions for registering a Basename");
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ describe("CDP API Action Provider", () => {
expect(result.success).toBe(true);
});

it("should allow missing assetId", () => {
const validInput = {};
it("should allow null assetId", () => {
const validInput = { assetId: null };
const result = RequestFaucetFundsV2Schema.safeParse(validInput);
expect(result.success).toBe(true);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ describe("CDP EVM Wallet Action Provider", () => {
describe("listSpendPermissions", () => {
const mockArgs = {
smartAccountAddress: "0xabcd1234567890123456789012345678901234567890",
network: null,
};

beforeEach(() => {
Expand Down Expand Up @@ -110,7 +111,10 @@ describe("CDP EVM Wallet Action Provider", () => {
});

it("should validate input schema", () => {
const validInput = { smartAccountAddress: "0xabcd1234567890123456789012345678901234567890" };
const validInput = {
smartAccountAddress: "0xabcd1234567890123456789012345678901234567890",
network: null,
};
const invalidInput = { wrongField: "0xabcd1234567890123456789012345678901234567890" };

expect(() => ListSpendPermissionsSchema.parse(validInput)).not.toThrow();
Expand All @@ -122,6 +126,7 @@ describe("CDP EVM Wallet Action Provider", () => {
const mockArgs = {
smartAccountAddress: "0xabcd1234567890123456789012345678901234567890",
value: "2500",
network: null,
};

beforeEach(() => {
Expand Down Expand Up @@ -285,6 +290,7 @@ describe("CDP EVM Wallet Action Provider", () => {
const validInput = {
smartAccountAddress: "0xabcd1234567890123456789012345678901234567890",
value: "1000",
network: null,
};
const invalidInput = {
smartAccountAddress: "not-an-address",
Expand Down Expand Up @@ -597,6 +603,7 @@ describe("CDP EVM Wallet Action Provider", () => {
fromToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
toToken: "0xA0b86991c6218b36c1d19D4a2e9EB0cE3606eB48",
fromAmount: "0.1",
slippageBps: null,
};
const result = SwapSchema.safeParse(validInput);
expect(result.success).toBe(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ describe("CDP Smart Wallet Action Provider", () => {
describe("listSpendPermissions", () => {
const mockArgs = {
smartAccountAddress: "0xabcd1234567890123456789012345678901234567890",
network: null,
};

beforeEach(() => {
Expand Down Expand Up @@ -105,7 +106,10 @@ describe("CDP Smart Wallet Action Provider", () => {
});

it("should validate input schema", () => {
const validInput = { smartAccountAddress: "0xabcd1234567890123456789012345678901234567890" };
const validInput = {
smartAccountAddress: "0xabcd1234567890123456789012345678901234567890",
network: null,
};
const invalidInput = { invalidField: "invalid" };

expect(() => ListSpendPermissionsSchema.parse(validInput)).not.toThrow();
Expand All @@ -117,6 +121,7 @@ describe("CDP Smart Wallet Action Provider", () => {
const mockArgs = {
smartAccountAddress: "0xabcd1234567890123456789012345678901234567890",
value: "1000",
network: null,
};

beforeEach(() => {
Expand Down Expand Up @@ -243,6 +248,7 @@ describe("CDP Smart Wallet Action Provider", () => {
const validInput = {
smartAccountAddress: "0xabcd1234567890123456789012345678901234567890",
value: "1000",
network: null,
};
const invalidInput = {
wrongField: "0xabcd1234567890123456789012345678901234567890",
Expand Down
Loading
Loading