Skip to main content
Use this path when your runtime is TypeScript-first and built with Mastra. Run CLI Setup and TypeScript SDK first, then add the Mastra layer. CAW does not ship a dedicated Mastra adapter. The recommended pattern is to define Mastra tools that call @cobo/agentic-wallet, then expose only the subset your agent needs.

Why Mastra fits CAW

Mastra is a good fit when you want:
  • TypeScript-native agents and workflows
  • explicit tool definitions with structured schemas
  • clean separation between planning logic and deterministic execution
That maps well to CAW’s model of scoped authorization, execution, and audit.

Step 1: Install

npm install @cobo/agentic-wallet @mastra/core @ai-sdk/openai zod

Step 2: Configure environment

export AGENT_WALLET_API_URL=https://api.agenticwallet.cobo.com
export AGENT_WALLET_API_KEY=your-api-key
export OPENAI_API_KEY=your-openai-api-key

Step 3: Define CAW-backed Mastra tools

mastra_quickstart.ts
import { openai } from '@ai-sdk/openai';
import { Agent } from '@mastra/core/agent';
import { createTool } from '@mastra/core/tools';
import { z } from 'zod';
import {
  Configuration,
  PactsApi,
  TransactionRecordsApi,
  TransactionsApi,
} from '@cobo/agentic-wallet';

const config = new Configuration({
  apiKey: process.env.AGENT_WALLET_API_KEY!,
  basePath: process.env.AGENT_WALLET_API_URL!,
});

const pactsApi = new PactsApi(config);
const txApi = new TransactionsApi(config);
const recordsApi = new TransactionRecordsApi(config);

async function returnPolicyDenial<T>(work: () => Promise<T>) {
  try {
    return await work();
  } catch (error) {
    return (error as {
      response?: { data?: { error?: Record<string, unknown> } };
    }).response?.data?.error ?? { error: 'UNKNOWN_ERROR' };
  }
}

const submitPactTool = createTool({
  id: 'submit-pact',
  description: 'Submit a pact and return the pact id.',
  inputSchema: z.object({
    wallet_id: z.string(),
    intent: z.string(),
  }),
  execute: async ({ context }) => {
    const response = await pactsApi.submitPact({
      wallet_id: context.wallet_id,
      intent: context.intent,
      spec: {
        completion_conditions: [{ type: 'time_elapsed', threshold: '86400' }],
      },
    });
    return response.data.result;
  },
});

const contractCallTool = createTool({
  id: 'contract-call',
  description: 'Execute a policy-enforced contract call.',
  inputSchema: z.object({
    wallet_uuid: z.string(),
    contract_addr: z.string(),
    calldata: z.string(),
    request_id: z.string(),
  }),
  execute: async ({ context }) => {
    return await returnPolicyDenial(async () => {
      const response = await txApi.contractCall(context.wallet_uuid, {
        chain_id: 'BASE_ETH',
        contract_addr: context.contract_addr,
        calldata: context.calldata,
        value: '0',
        request_id: context.request_id,
      });
      return response.data.result;
    });
  },
});

const recordTool = createTool({
  id: 'get-transaction-record-by-request-id',
  description: 'Look up a transaction record by request id.',
  inputSchema: z.object({
    wallet_uuid: z.string(),
    request_id: z.string(),
  }),
  execute: async ({ context }) => {
    const response = await recordsApi.getTransactionRecordByRequestId(
      context.wallet_uuid,
      context.request_id,
    );
    return response.data.result;
  },
});

const agent = new Agent({
  name: 'cobo-operator',
  model: openai('gpt-4.1-mini'),
  instructions:
    'Before executing blockchain actions, submit a pact and wait until it is active. If a tool returns a policy denial, read the suggestion and retry with compliant params. After submission, track the result by request_id.',
  tools: { submitPactTool, contractCallTool, recordTool },
});
For Mastra agents, start with one of these subsets:
  • Execution agentsubmit_pact, one execution tool, one tracking tool
  • Observer agent — balances, transaction records, audit logs
  • Planner plus executor — keep CAW submission in the executor only
Add audit-log tools on the observer side once you want agents to explain operator history. That avoids giving every agent broad wallet authority.

Design guidance

  • keep planner and executor roles separate when possible
  • keep CAW execution in a narrow subset instead of a broad wallet surface
  • track outcomes with transaction records and audit logs
  • treat pact submission as part of the runtime contract, not optional setup