import { generateText, tool } from 'ai';
import { openai } from '@ai-sdk/openai';
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 tools = {
submit_pact: tool({
description: 'Submit a pact and return the pact id.',
inputSchema: z.object({
wallet_id: z.string(),
intent: z.string(),
}),
execute: async ({ wallet_id, intent }) => {
const response = await pactsApi.submitPact({
wallet_id,
intent,
spec: {
completion_conditions: [{ type: 'time_elapsed', threshold: '86400' }],
},
});
return response.data.result;
},
}),
contract_call: tool({
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 ({ wallet_uuid, contract_addr, calldata, request_id }) => {
return await returnPolicyDenial(async () => {
const response = await txApi.contractCall(wallet_uuid, {
chain_id: 'BASE_ETH',
contract_addr,
calldata,
value: '0',
request_id,
});
return response.data.result;
});
},
}),
get_transaction_record_by_request_id: tool({
description: 'Look up a transaction record by request id.',
inputSchema: z.object({
wallet_uuid: z.string(),
request_id: z.string(),
}),
execute: async ({ wallet_uuid, request_id }) => {
const response = await recordsApi.getTransactionRecordByRequestId(wallet_uuid, request_id);
return response.data.result;
},
}),
};
const result = await generateText({
model: openai('gpt-4.1-mini'),
tools,
maxSteps: 6,
system:
'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.',
prompt:
'Submit a pact, execute a contract call with request_id swap-2026-001, adapt if denied, then look up the transaction record.',
});
console.log(result.text);