write.wallet.approve
Build unsigned approval transactions for ERC20 tokens or NFTs to authorize Arcadia Finance operations like deposits and liquidity management.
Instructions
Build an unsigned approval transaction. For ERC20 tokens: generates approve(spender, amount). For ERC721/ERC1155 NFTs (e.g. LP positions): generates setApprovalForAll(operator, true). Required before write.account.deposit or write.account.add_liquidity (when depositing from wallet). Tip: call read.wallet.allowances first to check if approval already exists — skip this if the current allowance is sufficient.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| token_address | Yes | Token contract address to approve | |
| spender_address | Yes | Address being approved — use the Arcadia account address for deposits | |
| asset_type | No | Token type: 'erc20' (default) for fungible tokens, 'erc721' or 'erc1155' for NFTs (LP positions) | erc20 |
| amount | No | ERC20 only: amount in raw units, or 'max_uint256' for unlimited. Ignored for NFTs. | max_uint256 |
| chain_id | No | Chain ID: 8453 (Base) or 130 (Unichain) |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| description | Yes | ||
| transaction | Yes | ||
| predicted_account_address | No |
Implementation Reference
- src/tools/write/wallet/approve.ts:12-104 (registration)The tool "write.wallet.approve" is registered and handled within this function.
export function registerApproveTool(server: McpServer, _chains: Record<ChainId, ChainConfig>) { server.registerTool( "write.wallet.approve", { annotations: { title: "Build Approve Transaction", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false, }, outputSchema: SimpleTransactionOutput, description: "Build an unsigned approval transaction. For ERC20 tokens: generates approve(spender, amount). For ERC721/ERC1155 NFTs (e.g. LP positions): generates setApprovalForAll(operator, true). Required before write.account.deposit or write.account.add_liquidity (when depositing from wallet). Tip: call read.wallet.allowances first to check if approval already exists — skip this if the current allowance is sufficient.", inputSchema: { token_address: z.string().describe("Token contract address to approve"), spender_address: z .string() .describe("Address being approved — use the Arcadia account address for deposits"), asset_type: z .enum(["erc20", "erc721", "erc1155"]) .default("erc20") .describe( "Token type: 'erc20' (default) for fungible tokens, 'erc721' or 'erc1155' for NFTs (LP positions)", ), amount: z .string() .default("max_uint256") .describe( "ERC20 only: amount in raw units, or 'max_uint256' for unlimited. Ignored for NFTs.", ), chain_id: z.number().default(8453).describe("Chain ID: 8453 (Base) or 130 (Unichain)"), }, }, async (params) => { try { const validToken = validateAddress(params.token_address, "token_address"); const validSpender = validateAddress(params.spender_address, "spender_address"); let data: `0x${string}`; let description: string; if (params.asset_type === "erc721" || params.asset_type === "erc1155") { data = encodeFunctionData({ abi: nftmanagerAbi, functionName: "setApprovalForAll", args: [validSpender, true], }); description = `Approve ${params.spender_address} to transfer all ${params.asset_type.toUpperCase()} tokens from ${params.token_address}`; } else { const amount = !params.amount || params.amount === "max_uint256" ? MAX_UINT256 : BigInt(params.amount); data = encodeFunctionData({ abi: erc20Abi, functionName: "approve", args: [validSpender, amount], }); description = `Approve ${params.spender_address} to spend ${params.token_address}`; } data = appendDataSuffix(data) as `0x${string}`; const result = { description, transaction: { to: validToken, data, value: "0", chainId: params.chain_id, }, }; return { content: [ { type: "text" as const, text: JSON.stringify(result, null, 2), }, ], structuredContent: result, }; } catch (err) { return { content: [ { type: "text" as const, text: `Error: ${err instanceof Error ? err.message : String(err)}`, }, ], isError: true, }; } }, ); } - src/tools/write/wallet/approve.ts:46-102 (handler)The tool handler implementation for "write.wallet.approve", which generates an approval transaction for ERC20, ERC721, or ERC1155 tokens.
async (params) => { try { const validToken = validateAddress(params.token_address, "token_address"); const validSpender = validateAddress(params.spender_address, "spender_address"); let data: `0x${string}`; let description: string; if (params.asset_type === "erc721" || params.asset_type === "erc1155") { data = encodeFunctionData({ abi: nftmanagerAbi, functionName: "setApprovalForAll", args: [validSpender, true], }); description = `Approve ${params.spender_address} to transfer all ${params.asset_type.toUpperCase()} tokens from ${params.token_address}`; } else { const amount = !params.amount || params.amount === "max_uint256" ? MAX_UINT256 : BigInt(params.amount); data = encodeFunctionData({ abi: erc20Abi, functionName: "approve", args: [validSpender, amount], }); description = `Approve ${params.spender_address} to spend ${params.token_address}`; } data = appendDataSuffix(data) as `0x${string}`; const result = { description, transaction: { to: validToken, data, value: "0", chainId: params.chain_id, }, }; return { content: [ { type: "text" as const, text: JSON.stringify(result, null, 2), }, ], structuredContent: result, }; } catch (err) { return { content: [ { type: "text" as const, text: `Error: ${err instanceof Error ? err.message : String(err)}`, }, ], isError: true, }; } },