The Axicov Blockchain Toolset provides your agents with powerful capabilities to interact with blockchain networks, deploy tokens, and manage digital assets. Built on top of thirdweb and web3, these tools allow your agents to perform common blockchain operations without requiring deep blockchain expertise.
Available Tools
Token Deployer (tokenDeployer)
Deploy custom ERC-20 tokens to the Sonic blockchain with configurable name, symbol, and initial supply. The tool includes built-in validation and confirmation flows to ensure accurate token deployment.
// Example usage
const response = await agent.messageAgent("Deploy a token named Axicov Finance with symbol AXF and supply of 1,000,000");
Token Balance Fetcher (tokenBalanceFetcher)
Check the balance of any ERC-20 token by providing the token's contract address. This tool allows your agent to retrieve token balances for the user's connected wallet.
// Example usage
const response = await agent.messageAgent("What's your balance of the token at 0x1234...5678?");
Retrieve the native Sonic (S) token balance of the user's connected wallet. This tool is automatically invoked when users ask about their wallet balance.
// Example usage
const response = await agent.messageAgent("What's your wallet balance?");
Key Features
User-Friendly Interaction: The tools handle the technical details, allowing users to interact using natural language
Built-in Safety Checks: Confirmation steps and validation to prevent accidental deployments
Automated Guidance: Tools prompt for any missing information needed to complete operations
Network Compatibility: Designed to work with Sonic blockchain
Use Cases
Creating custom tokens for projects or communities
Managing token portfolios
Checking balances across different tokens
Building blockchain-aware conversational experiences
These blockchain tools transform your Axicov agents into capable blockchain assistants, bridging the gap between natural language interaction and complex blockchain operations.
Paste this code at schema/blockchainRegistrySchema.ts
import { Tools } from "axicov-sdk";
import { z } from "zod";
export const blockchainRegistrySchema: Tools = {
deployTokenSchema: {
name: "tokenDeployer",
description: `
Deploys an ERC-20 token on the sonic blockchain based on tokenName, tokenSymbol and tokenSupply
**IMPORTANT INSTRUCTIONS**:
- Don't invent the token symbol, token name, initial supply of the token. These must be provided by the user itself
- Before deployment of the token, always make a confirmation from the user that the token details are correct
**EXAMPLES**
------------
User: Deploy a token
You: Please provide the token symbol, token name and initial supply of the token
User: Deploy a token named Silion
You: Provide the token supply, and the token symbol
User: Deploy a token named Silion with symbol SIL
You: Provide the token supply
User: 7000
You: I'll deploy a token named Silion with symbol SIL and initial supply of 7000. Should I proceed?
User: Yes
You: <Deploy the token>
------------
`,
schema: z.object({
tokenName: z.string().describe("The name of the token"),
tokenSymbol: z.string().describe("The symbol of the token"),
tokenSupply: z.number().describe("The initial total supply of the token"),
}),
requiresApproval: true,
},
getBalanceOfTokenSchema: {
name: "tokenBalanceFetcher",
description:
"Gets the balance of an ERC-20 token by taking the address of that token as input",
schema: z.object({
tokenAddress: z.string().describe("The address of the token"),
}),
},
getNativeTokenBalance: {
name: "nativeSonicBalanceFetcher",
description: `Gets the native Sonic balance of the user's address.
**IMPORTANT NOTES**:
- This tool is used by default when the user asks the agent to tell the user's wallet balance
- The symbol of the native token is 'S' not 'ETH'
`,
schema: undefined,
},
};
Copy the Tool Code
Copy this code to /tools/blockchainToolRegistry.ts
import {
Chain,
createThirdwebClient,
defineChain,
ThirdwebClient,
} from "thirdweb";
import { Account } from "thirdweb/dist/types/wallets/interfaces/wallet";
import { privateKeyToAccount } from "thirdweb/wallets";
import Web3 from "web3";
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
import { tool } from "@langchain/core/tools";
import { blockchainRegistrySchema as blockchainToolsSchema } from "../schema/blockchainRegistrySchema";
import chalk from "chalk";
import { toolType, Agent } from "axicov-sdk";
export class BlockchainClass {
public web3: Web3;
public client: ThirdwebClient;
public account: Account;
public chain: Chain;
private clientId?: string;
public sdk;
public agent: Agent | undefined;
constructor({
network,
thirdwebAPIKey,
clientId,
agent,
}: {
network: "testnet" | "mainnet";
agent: Agent;
thirdwebAPIKey?: string;
clientId?: string;
}) {
this.agent = agent;
if (!this.agent) {
throw new Error("Agent needs to be present");
}
if (!thirdwebAPIKey && !process.env.THIRDWEB_SECRET) {
throw new Error("Thirdweb secret needed");
}
if (!this.agent.params?.privateKey) {
throw new Error("Private key is required");
}
if (process.env.THIRDWEB_CLIENT_ID || clientId) {
this.clientId = (process.env.THIRDWEB_CLIENT_ID || clientId) as string;
}
if (network === "mainnet") {
const cId = 146;
this.web3 = new Web3(
`https://${cId}.rpc.thirdweb.com/${
process.env.THIRDWEB_SECRET! || thirdwebAPIKey
}`
);
this.chain = defineChain(cId);
} else {
const cId = 57054;
this.web3 = new Web3(
`https://${cId}.rpc.thirdweb.com/${
process.env.THIRDWEB_SECRET! || thirdwebAPIKey
}`
);
this.chain = defineChain(cId);
}
this.sdk = ThirdwebSDK.fromPrivateKey(
this.agent.params.privateKey as string,
this.chain.rpc,
{
clientId: this.clientId,
secretKey: (process.env.THIRDWEB_SECRET || thirdwebAPIKey) as string,
}
);
this.client = createThirdwebClient({
secretKey: (process.env.THIRDWEB_SECRET || thirdwebAPIKey) as string,
});
this.account = privateKeyToAccount({
client: this.client,
privateKey: this.agent.params.privateKey as string,
});
console.log(
"Agent wallet address:",
chalk.blueBright(this.account.address)
);
}
async initialize() {
// POST" Save something to the agent params
if (!this.agent) {
throw new Error("Agent instance is required");
}
if (!this.agent?.params.publicKey) {
this.agent.params["publicKey"] = this.account.address;
}
this.agent.runtimeParams = {
...this.agent.runtimeParams,
client: this.client,
};
return this.agent?.params;
}
async deployToken(
tokenName: string,
tokenSymbol: string,
tokenSupply: number
) {
try {
console.log(chalk.green(tokenName, tokenSymbol, tokenSupply));
console.log(chalk.bgGray("Deploying token"));
const deployedAddress = await this.sdk.deployer.deployToken({
name: tokenName,
symbol: tokenSymbol,
defaultAdmin: this.account.address,
});
console.log(
chalk.bgGray(
`Deployed at address ${deployedAddress}, Minting tokens to wallet`
)
);
const tokenContract = await this.sdk.getContract(
deployedAddress,
"token"
);
const mintTxn = await tokenContract.mintTo(
this.account.address,
tokenSupply
);
console.log(chalk.bgGray(`Minted tokens: ${mintTxn.receipt.blockHash}`));
return { token: deployedAddress, mintTxnHash: mintTxn.receipt.blockHash };
} catch (err: any) {
throw new Error(`Error Occurred: ${err}`);
}
}
async getBalanceOfToken(tokenAddress: string) {
try {
const tokenContract = await this.sdk.getContract(tokenAddress, "token");
return tokenContract.balanceOf(this.account.address);
} catch (err: any) {
console.log(chalk.red(err[0]));
throw new Error(`Error Occurred: ${err}`);
}
}
async getNativeTokenBalance() {
try {
console.log(chalk.bgGray("Fetching native token balance"));
return this.sdk.getBalance(this.account.address);
} catch (err: any) {
throw new Error(`Error Occurred: ${err}`);
}
}
}
export const blockchainToolsRegistry = async (agent: Agent) => {
const blockchainInstance = new BlockchainClass({
network: (process.env.NETWORK || "testnet") as "testnet" | "mainnet",
agent,
});
return blockchainInstance.initialize().then(() => {
const blockchainTools: {
[key: string]: toolType;
} = {
deployToken: tool(async (input) => {
return await blockchainInstance.deployToken(
input.tokenName,
input.tokenSymbol,
input.tokenSupply
);
}, blockchainToolsSchema.deployTokenSchema),
getBalanceOfToken: tool(async (input) => {
return await blockchainInstance.getBalanceOfToken(input.tokenAddress);
}, blockchainToolsSchema.getBalanceOfTokenSchema),
getNativeTokenBalance: tool(async () => {
return await blockchainInstance.getNativeTokenBalance();
}, blockchainToolsSchema.getNativeTokenBalance),
};
return {
tools: Object.values(blockchainTools),
schema: blockchainToolsSchema,
};
});
};
Register this tool to your coreRegistry or allRegistry
For now let's register it at coreRegistry
import { Agent } from "axicov-sdk";
import { blockchainToolsRegistry } from "./tools/blockchainToolRegistry";
import Web3 from "web3";
const web3 = new Web3();
const runAgent = async () => {
try {
const agent = new Agent({
threadId: "hello-123",
params: {
// other params
privateKey: web3.eth.accounts.create().privateKey, // 1. generate a private key
},
});
await agent.initialize({
// other params
coreRegistry: [
// others
blockchainToolsRegistry // 2. Use it in the registry
],
});
const res = await agent.messageAgent(
"What is your wallet balance?"
);
console.log(res);
return res;
} catch (err) {
console.log(err);
}
};
runAgent();