AI Agent (daccAiAgent)
The daccAiAgent function creates an AI-powered agent that can chat and perform blockchain actions on behalf of the user. The AI can execute transactions, check balances, and interact with smart contracts via natural language.
Import
import { daccAiAgent } from 'dacc-js';Usage
import { daccAiAgent } from 'dacc-js';
import { optimismSepolia, baseSepolia } from 'viem/chains'; // used `viem` - npm i viem
import { parseAbi } from 'viem'; // Inline Abi helper
const ai = await daccAiAgent({
daccPublickey: 'daccPublickey_0x123_XxX..',
passwordSecretkey: 'my+Password#123..',
// privateKey: '0xabc123...', // Optional
llm: {
baseURL: 'https://openrouter.ai/api/v1',
apiKey: process.env.OPENROUTER_API_KEY!,
model: 'openai/gpt-oss-20b',
},
chains: [optimismSepolia, baseSepolia],
tokens: [
{
name: 'Token1', // Unique name for the action
symbol: 'TOK1',
decimals: 18, // Optional: defaults to 18
chain: optimismSepolia,
address: '0x123...',
},
{
name: 'Token2', // Unique name for the action
symbol: 'TOK2',
decimals: 6, // e.g., USDC uses 6 decimals
chain: baseSepolia,
address: '0x234...',
},
],
contracts: [ // Optional: Permission custom smart contract execution
{
name: 'mint-nft-erc1155', // Unique name for the action
description: 'Mint an NFT ERC1155', // Optional: description
mode: 'write', // write = transaction
chain: optimismSepolia,
contractAddress: '0xNFTContract...',
abi: parseAbi(["function mint(address account, uint256 id, uint256 amount, bytes memory data) public"]), // ABI of the contract
functionName: 'mint', // Function to call
args: [ // Empty '' = AI will ask for args
'', // to
0, // tokenId
'', // amount
'0x', // data = '0x'
],
},
{
name: 'balance-nft-erc1155', // Unique name for the action
description: 'Get NFT ERC1155 balance', // Optional: description
mode: 'read', // read = view
chain: optimismSepolia,
contractAddress: '0xNFTContract...',
abi: fileImportABI[], // ABI of the contract
functionName: 'balanceOf', // Function to call
args: [
'0xWalletAddress...', // Fixed placeholder in arguments
0, // tokenId
],
},
{
name: 'total-supply-nft-erc1155', // Unique name for the action
description: 'Get NFT ERC1155 total supply', // Optional: description
mode: 'read', // read = view
chain: optimismSepolia,
contractAddress: '0xNFTContract...',
abi: fileImportABI[], // ABI of the contract
functionName: 'totalSupply', // Function to call
args: [], // None arguments
},
],
// Optional: system prompt to guide the AI behavior
systemPrompt: `
- If there is an error, please indicate the command usage.
- For chain id 11155420, use the chain name OP Sepolia.
URL Explorer: https://testnet-explorer.optimism.io/
Address: https://testnet-explorer.optimism.io/address/
Tx: https://testnet-explorer.optimism.io/tx/
- For chain id 84532, use the chain name Base Sepolia.
URL Explorer: https://sepolia.basescan.org/
Address: https://sepolia.basescan.org/address/
Tx: https://sepolia.basescan.org/tx/
`,
});
// Chat with AI to perform transactions
const response = await ai.chat("Transfer 0.01 Token1 to 0xRecipient...");
console.log('AI response:', response.text);
// Stream chat for real-time responses
const streamResponse = await ai.streamChat("Call use mint-nft-erc1155 args 0xWalletAddress.. 1");
for await (const chunk of streamResponse.textStream) {
process.stdout.write(chunk);
}Arguments
| Parameter | Type | Description |
|---|---|---|
daccPublickey | string | Conditional: The encrypted wallet data from createDaccWallet. |
passwordSecretkey | string | The password for decrypting the wallet. |
privateKey | 0x${string} | Conditional: Direct private key (alternative to daccPublickey + password). |
llm | LlmConfig | LLM configuration with baseURL, apiKey, and model. |
chains | Chain[] | Array of supported chains (e.g., [optimismSepolia, baseSepolia]). |
tokens | TokenInfo[] | Array of tokens with name, symbol, decimals, chain, and address. |
contracts | ContractInfo[] | Optional: Array of custom smart contract actions with name, description, mode, chain, contractAddress, abi[], functionName, and args[]. |
systemPrompt | string | Optional: Custom system prompt (defaults to built-in prompt). |
Return Value
The response result is an object containing {chat, streamChat} methods.
| Method | Parameters | Return Type | Description |
|---|---|---|---|
chat | message: string | Promise<{text: string}> | Chat with AI to perform blockchain actions. |
streamChat | message: string | Promise<{textStream: AsyncIterable<string>}> | Stream chat with AI for real-time responses. |
Parameters
daccPublickey (conditional)
- Type:
string
The user's encrypted public key from createDaccWallet.
const ai = await daccAiAgent({
daccPublickey: 'daccPublickey_0x123_XxX..',
passwordSecretkey: 'my+Password#123..',
// privateKey: '0xabc123...', //
llm: {
baseURL: 'https://openrouter.ai/api/v1',
apiKey: process.env.OPENROUTER_API_KEY!,
model: 'openai/gpt-oss-20b',
},
chains: [optimismSepolia],
tokens: [{ name: 'Token1', symbol: 'TOK1', chain: optimismSepolia, address: '0x123...' }],
});passwordSecretkey
- Type:
string
The same password used when creating the wallet with createDaccWallet.
const ai = await daccAiAgent({
daccPublickey: 'daccPublickey_0x123_XxX..',
passwordSecretkey: 'my+Password#123..',
llm: {
baseURL: 'https://openrouter.ai/api/v1',
apiKey: process.env.OPENROUTER_API_KEY!,
model: 'openai/gpt-oss-20b',
},
chains: [optimismSepolia],
tokens: [{ name: 'Token1', symbol: 'TOK1', chain: optimismSepolia, address: '0x123...' }],
});privateKey (conditional)
- Type:
0x${string}
Direct private key for wallet access.
const ai = await daccAiAgent({
// daccPublickey: 'daccPublickey_0x123_XxX..', //
// passwordSecretkey: 'my+Password#123..', //
privateKey: '0xabc123...',
llm: {
baseURL: 'https://openrouter.ai/api/v1',
apiKey: process.env.OPENROUTER_API_KEY!,
model: 'openai/gpt-oss-20b',
},
chains: [optimismSepolia],
tokens: [{ name: 'Token1', symbol: 'TOK1', chain: optimismSepolia, address: '0x123...' }],
});llm
- Type:
{ baseURL: string; apiKey: string; model: string }
LLM (Large Language Model) configuration for the AI provider.
const ai = await daccAiAgent({
daccPublickey: 'daccPublickey_0x123_XxX..',
passwordSecretkey: 'my+Password#123..',
llm: {
baseURL: 'https://openrouter.ai/api/v1',
apiKey: process.env.OPENROUTER_API_KEY!,
model: 'openai/gpt-oss-20b',
},
chains: [optimismSepolia],
tokens: [{ name: 'Token1', symbol: 'TOK1', chain: optimismSepolia, address: '0x123...' }],
});chains
- Type:
Chain[]
Array of supported blockchain networks from viem/chains.
import { optimismSepolia, baseSepolia } from 'viem/chains';
const ai = await daccAiAgent({
daccPublickey: 'daccPublickey_0x123_XxX..',
passwordSecretkey: 'my+Password#123..',
llm: {
baseURL: 'https://openrouter.ai/api/v1',
apiKey: process.env.OPENROUTER_API_KEY!,
model: 'openai/gpt-oss-20b',
},
chains: [optimismSepolia, baseSepolia],
tokens: [
{ name: 'Token1', symbol: 'TOK1', chain: optimismSepolia, address: '0x123...' },
{ name: 'Token2', symbol: 'TOK2', chain: baseSepolia, address: '0x234...' },
],
});tokens
- Type:
TokenInfo[]
Array of token configurations with name, symbol, decimals, chain, and address.
const ai = await daccAiAgent({
daccPublickey: 'daccPublickey_0x123_XxX..',
passwordSecretkey: 'my+Password#123..',
llm: {
baseURL: 'https://openrouter.ai/api/v1',
apiKey: process.env.OPENROUTER_API_KEY!,
model: 'openai/gpt-oss-20b',
},
chains: [optimismSepolia, baseSepolia],
tokens: [
{ name: 'Token1', symbol: 'TOK1', decimals: 18, chain: optimismSepolia, address: '0x123...' },
{ name: 'Token2', symbol: 'TOK2', decimals: 6, chain: baseSepolia, address: '0x234...' },
],
});contracts (optional)
- Type:
ContractInfo[]
Array of custom smart contract configurations with name, description, mode, chain, contractAddress, abi[], functionName, and args[].
import { erc20Abi } from 'viem';
const ai = await daccAiAgent({
daccPublickey: 'daccPublickey_0x123_XxX..',
passwordSecretkey: 'my+Password#123..',
llm: {
baseURL: 'https://openrouter.ai/api/v1',
apiKey: process.env.OPENROUTER_API_KEY!,
model: 'openai/gpt-oss-20b',
},
chains: [optimismSepolia],
tokens: [{ name: 'Token1', symbol: 'TOK1', chain: optimismSepolia, address: '0x123...' }],
contracts: [
{
name: 'opNftMint',
description: 'Mint an OP NFT',
mode: 'write',
chain: optimismSepolia,
contractAddress: '0xNFTContract...',
abi: erc1155Abi,
functionName: 'mint',
args: ['', 0, 1, '0x'], // - Empty '' = AI will ask for args
},
{
name: 'opNftBalance',
description: 'Get OP NFT balance',
mode: 'read',
chain: optimismSepolia,
contractAddress: '0xNFTContract...',
abi: erc1155Abi,
functionName: 'balanceOf',
args: ['0xWalletAddress...', 0], // - Fixed arg
},
],
});systemPrompt (optional)
- Type:
string - Default: Built-in system prompt
Custom system prompt for the AI agent to guide its behavior.
const ai = await daccAiAgent({
daccPublickey: 'daccPublickey_0x123_XxX..',
passwordSecretkey: 'my+Password#123..',
llm: {
baseURL: 'https://openrouter.ai/api/v1',
apiKey: process.env.OPENROUTER_API_KEY!,
model: 'openai/gpt-oss-20b',
},
chains: [optimismSepolia],
tokens: [{ name: 'Token1', symbol: 'TOK1', chain: optimismSepolia, address: '0x123...' }],
systemPrompt:
`You are a helpful blockchain assistant.
- Always confirm transactions before executing.
- If the user asks for a transaction, ask for confirmation.
`,
});Examples
Chat with AI to send tokens
import { daccAiAgent } from 'dacc-js';
import { optimismSepolia } from 'viem/chains';
const ai = await daccAiAgent({
daccPublickey: 'daccPublickey_0x123_XxX..',
passwordSecretkey: 'my+Password#123..',
llm: {
baseURL: 'https://openrouter.ai/api/v1',
apiKey: process.env.OPENROUTER_API_KEY!,
model: 'openai/gpt-oss-20b',
},
chains: [optimismSepolia],
tokens: [
{ name: 'Token1', symbol: 'TOK1', chain: optimismSepolia, address: '0x123...' },
],
});
// Ask AI to transfer tokens
const response = await ai.chat('Transfer 0.01 TOK1 to 0xRecipientAddress...');
console.log('AI response:', response.text);Stream chat for balance inquiry
import { daccAiAgent } from 'dacc-js';
import { baseSepolia } from 'viem/chains';
const ai = await daccAiAgent({
daccPublickey: 'daccPublickey_0x123_XxX..',
passwordSecretkey: 'my+Password#123..',
llm: {
baseURL: 'https://openrouter.ai/api/v1',
apiKey: process.env.OPENROUTER_API_KEY!,
model: 'openai/gpt-oss-20b',
},
chains: [baseSepolia],
tokens: [
{ name: 'Token2', symbol: 'TOK2', chain: baseSepolia, address: '0x234...' },
],
});
// Stream chat for real-time balance inquiry
const streamResponse = await ai.streamChat("What's my balance of Token2?");
for await (const chunk of streamResponse.textStream) {
process.stdout.write(chunk);
}Use AI with direct private key
import { daccAiAgent } from 'dacc-js';
import { optimismSepolia } from 'viem/chains';
const ai = await daccAiAgent({
privateKey: '0xabc123...',
llm: {
baseURL: 'https://openrouter.ai/api/v1',
apiKey: process.env.OPENROUTER_API_KEY!,
model: 'openai/gpt-oss-20b',
},
chains: [optimismSepolia],
tokens: [
{ name: 'Token1', symbol: 'TOK1', chain: optimismSepolia, address: '0x123...' },
],
});
// Ask AI about available tokens
const tokensResponse = await ai.chat('What tokens do I have available?');
console.log('Available tokens:', tokensResponse.text);Send native coin (e.g., ETH)
import { daccAiAgent } from 'dacc-js';
import { optimismSepolia } from 'viem/chains';
const ai = await daccAiAgent({
daccPublickey: 'daccPublickey_0x123_XxX..',
passwordSecretkey: 'my+Password#123..',
llm: {
baseURL: 'https://openrouter.ai/api/v1',
apiKey: process.env.OPENROUTER_API_KEY!,
model: 'openai/gpt-oss-20b',
},
chains: [optimismSepolia],
tokens: [
{
name: 'eth', // For native coin
symbol: 'ETH',
chain: optimismSepolia,
address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', // address for native coin
// decimals: 18,
},
{
name: 'eth-base', // For native coin with different chain
symbol: 'ETH',
chain: baseSepolia,
address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', // address for native coin
// decimals: 18,
},
{ name: 'Token1', symbol: 'TOK1', chain: optimismSepolia, address: '0x123...' },
],
});
// Send native token (ETH) to an address
const nativeResponse = await ai.chat('Send 0.01 ETH to 0xRecipientAddress on optimismSepolia');
console.log('Native transfer:', nativeResponse.text);Advanced Ai agent setup
import { ai } from './hook'
const streamResponse = await ai.streamChat("Call use mint-nft-erc1155 args 0xWalletAddress.. 1");
for await (const chunk of streamResponse.textStream) {
process.stdout.write(chunk);
}