Skip to content

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 ​

bash
npm install -D @smartagentkit/testing

MockSmartAgentKitClient ​

typescript
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.
typescript
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 SpendingLimitExceededError

Presets ​

The mock client supports the same presets as the real SDK:

typescript
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:

typescript
const log = client.getLog();
// [
//   { operation: "createWallet", timestamp: ..., params: {...}, result: {...} },
//   { operation: "execute", timestamp: ..., params: {...}, result: {...} },
//   ...
// ]

setState() ​

Directly set wallet state for test scenarios:

typescript
client.setState(wallet.address, {
  paused: true,
  ethBalance: parseEther("5"),
});

getWalletState() ​

Read the current wallet state:

typescript
const state = client.getWalletState(wallet.address);
console.log(state.paused);     // true
console.log(state.ethBalance); // 5000000000000000000n

Using with Vitest ​

typescript
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:

typescript
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:

typescript
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 replacement

This is particularly useful for testing LangChain agent flows without incurring gas costs or waiting for transaction confirmations.

Released under the MIT License.