Testing
SmartAgentKit provides a dedicated testing package with a MockSmartAgentKitClient that enforces policies in-memory. This lets you write fast, deterministic tests without needing a blockchain, bundler, or any network connectivity.
Install
npm install -D @smartagentkit/testingMockSmartAgentKitClient
import { MockSmartAgentKitClient } from "@smartagentkit/testing";
const client = new MockSmartAgentKitClient({
verbose: true, // Log all operations to console
initialBalance: parseEther("10"), // Start with 10 ETH
});The mock client implements the same interface as SmartAgentKitClient, making it a drop-in replacement for testing.
In-Memory Policy Enforcement
The mock client enforces all three policy types locally:
- Spending limits -- Tracks cumulative spending per token per window. Resets after the window expires.
- Allowlist -- Checks targets against the configured allow/block list before executing.
- Pause -- Blocks all executions when the wallet is paused.
const wallet = await client.createWallet({
owner: "0xYourAddress",
preset: "defi-trader",
});
// This works -- within the 1 ETH/day limit
await client.execute(wallet, {
target: "0xSomeAddress",
value: parseEther("0.5"),
});
// This fails -- cumulative 1.1 ETH exceeds the 1 ETH/day limit
await client.execute(wallet, {
target: "0xSomeAddress",
value: parseEther("0.6"),
});
// Throws SpendingLimitExceededErrorPresets
The mock client supports the same presets as the real SDK:
const wallet = await client.createWallet({
owner: "0x...",
preset: "defi-trader", // or treasury-agent, payment-agent, minimal
presetParams: { dailyEthLimit: parseEther("2") },
});See the Wallet Creation guide for the full preset table.
Mock-Specific Methods
The mock client exposes additional methods for test setup and assertions.
getLog()
Returns a chronological log of all operations performed:
const log = client.getLog();
// [
// { operation: "createWallet", timestamp: ..., params: {...}, result: {...} },
// { operation: "execute", timestamp: ..., params: {...}, result: {...} },
// ...
// ]setState()
Directly set wallet state for test scenarios:
client.setState(wallet.address, {
paused: true,
ethBalance: parseEther("5"),
});getWalletState()
Read the current wallet state:
const state = client.getWalletState(wallet.address);
console.log(state.paused); // true
console.log(state.ethBalance); // 5000000000000000000nUsing with Vitest
import { describe, it, expect } from "vitest";
import { MockSmartAgentKitClient } from "@smartagentkit/testing";
import { parseEther } from "viem";
describe("My Agent", () => {
it("respects spending limits", async () => {
const client = new MockSmartAgentKitClient();
const wallet = await client.createWallet({
owner: "0x1234567890abcdef1234567890abcdef12345678",
preset: "defi-trader",
});
// Should succeed
await client.execute(wallet, {
target: "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
value: parseEther("0.5"),
});
// Should fail -- exceeds 1 ETH/day limit
await expect(
client.execute(wallet, {
target: "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
value: parseEther("0.6"),
}),
).rejects.toThrow("Spending limit exceeded");
});
});Mock Flag Pattern
All SmartAgentKit examples support a --mock flag for running without network access:
import { SmartAgentKitClient } from "@smartagentkit/sdk";
import { MockSmartAgentKitClient } from "@smartagentkit/testing";
import { baseSepolia } from "viem/chains";
const isMock = process.argv.includes("--mock");
const client = isMock
? new MockSmartAgentKitClient({ verbose: true })
: new SmartAgentKitClient({
chain: baseSepolia,
rpcUrl: process.env.RPC_URL!,
bundlerUrl: process.env.BUNDLER_URL!,
});This pattern lets you develop and test your agent logic locally, then switch to the real client for testnet or mainnet execution.
Using with LangChain
The mock client works seamlessly with the LangChain integration:
import { createSmartAgentKitTools } from "@smartagentkit/langchain";
import { MockSmartAgentKitClient } from "@smartagentkit/testing";
const client = new MockSmartAgentKitClient();
const wallet = await client.createWallet({ owner: "0x...", preset: "minimal" });
const tools = createSmartAgentKitTools(client, wallet.address);
// Tools work the same -- mock client is a drop-in replacementThis is particularly useful for testing LangChain agent flows without incurring gas costs or waiting for transaction confirmations.