Skip to content

AI Agent (daccAiAgent)

A function to create an AI Agent for blockchain interactions

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

ParameterTypeDescription
daccPublickeystringConditional: The encrypted wallet data from createDaccWallet.
passwordSecretkeystringThe password for decrypting the wallet.
privateKey0x${string}Conditional: Direct private key (alternative to daccPublickey + password).
llmLlmConfigLLM configuration with baseURL, apiKey, and model.
chainsChain[]Array of supported chains (e.g., [optimismSepolia, baseSepolia]).
tokensTokenInfo[]Array of tokens with name, symbol, decimals, chain, and address.
contractsContractInfo[]Optional: Array of custom smart contract actions with name, description, mode, chain, contractAddress, abi[], functionName, and args[].
systemPromptstringOptional: Custom system prompt (defaults to built-in prompt).

Return Value

The response result is an object containing {chat, streamChat} methods.

MethodParametersReturn TypeDescription
chatmessage: stringPromise<{text: string}>Chat with AI to perform blockchain actions.
streamChatmessage: stringPromise<{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

app.ts
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);
}