azeth_whitelist_protocol
Manage smart account protocol whitelists to enable automated DeFi interactions through executor modules. Add or remove contract addresses to control which protocols can operate on your behalf.
Instructions
Add or remove a protocol (contract address) from your smart account's guardian whitelist.
Use this when: You need to interact with a new DeFi protocol or contract through executor modules (like PaymentAgreementModule). Protocols must be whitelisted for automated operations to succeed.
The "protocol" field must be a valid Ethereum address of the contract to whitelist.
Returns: Confirmation of the whitelist update with transaction hash.
Note: This requires a UserOperation (gas). Only the account owner can modify whitelists. Whitelisting a protocol allows executor modules to interact with it on your behalf. Whitelist additions require guardian co-signature for security.
Example: { "protocol": "0x71D52798e3D0f5766f6f0AFEd6710EB5D1FF4DF9", "allowed": true }
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| chain | No | Target chain. Defaults to AZETH_CHAIN env var or "baseSepolia". Accepts "base", "baseSepolia", "ethereumSepolia", "ethereum" (and aliases like "base-sepolia", "eth-sepolia", "sepolia", "eth", "mainnet"). | |
| protocol | Yes | Protocol/contract address to whitelist or delist (0x...). | |
| allowed | Yes | true to whitelist, false to remove from whitelist. | |
| smartAccount | No | Smart account address, name, or "#N". Defaults to first smart account. |
Implementation Reference
- src/tools/guardian.ts:232-292 (handler)The handler implementation for the azeth_whitelist_protocol tool. It validates the address, resolves the smart account, calls client.setProtocolWhitelist, and handles potential errors including guardian co-signature requirements.
async (args) => { if (!validateAddress(args.protocol)) { return error('INVALID_INPUT', `Invalid protocol address: "${args.protocol}".`, 'Must be 0x-prefixed followed by 40 hex characters.'); } let client; try { client = await createClient(args.chain); let account: `0x${string}`; if (args.smartAccount) { try { account = (await resolveSmartAccount(args.smartAccount, client))!; } catch (resolveErr) { return handleError(resolveErr); } } else { account = await client.resolveSmartAccount(); } const txHash = await client.setProtocolWhitelist( args.protocol as `0x${string}`, args.allowed, account, ); const action = args.allowed ? 'whitelisted' : 'removed from whitelist'; // Resolve protocol name for known Azeth contracts const chain = resolveChain(args.chain); const contracts = AZETH_CONTRACTS[chain]; const protocolLower = args.protocol.toLowerCase(); let protocolName = args.protocol.slice(0, 6) + '...' + args.protocol.slice(-4); if (protocolLower === contracts.paymentAgreementModule.toLowerCase()) protocolName = 'PaymentAgreementModule'; else if (protocolLower === contracts.reputationModule.toLowerCase()) protocolName = 'ReputationModule'; else if (protocolLower === contracts.trustRegistryModule.toLowerCase()) protocolName = 'TrustRegistryModule'; else if (protocolLower === contracts.guardianModule.toLowerCase()) protocolName = 'GuardianModule'; else if (protocolLower === contracts.factory.toLowerCase()) protocolName = 'AzethFactory'; return success( { protocol: args.protocol, protocolName, allowed: args.allowed, message: `${protocolName} (${args.protocol}) ${action} on account ${account}.`, }, { txHash }, ); } catch (err) { // Detect AA24 signature validation failure — common for guardian-gated operations if (err instanceof Error && /AA24/.test(err.message)) { return guardianRequiredError( 'Protocol whitelisting requires guardian co-signature (guardrail-loosening change).', { operation: 'whitelist_protocol' }, ); } return handleError(err); } finally { try { await client?.destroy(); } catch (e) { process.stderr.write(`[azeth-mcp] destroy error: ${e instanceof Error ? e.message : String(e)}\n`); } } }, ); - src/tools/guardian.ts:205-231 (registration)Registration of the azeth_whitelist_protocol tool, including its schema and description.
server.registerTool( 'azeth_whitelist_protocol', { description: [ 'Add or remove a protocol (contract address) from your smart account\'s guardian whitelist.', '', 'Use this when: You need to interact with a new DeFi protocol or contract through', 'executor modules (like PaymentAgreementModule). Protocols must be whitelisted for', 'automated operations to succeed.', '', 'The "protocol" field must be a valid Ethereum address of the contract to whitelist.', '', 'Returns: Confirmation of the whitelist update with transaction hash.', '', 'Note: This requires a UserOperation (gas). Only the account owner can modify whitelists.', 'Whitelisting a protocol allows executor modules to interact with it on your behalf.', 'Whitelist additions require guardian co-signature for security.', '', 'Example: { "protocol": "0x71D52798e3D0f5766f6f0AFEd6710EB5D1FF4DF9", "allowed": true }', ].join('\n'), inputSchema: z.object({ chain: z.string().optional().describe('Target chain. Defaults to AZETH_CHAIN env var or "baseSepolia". Accepts "base", "baseSepolia", "ethereumSepolia", "ethereum" (and aliases like "base-sepolia", "eth-sepolia", "sepolia", "eth", "mainnet").'), protocol: z.string().describe('Protocol/contract address to whitelist or delist (0x...).'), allowed: z.boolean().describe('true to whitelist, false to remove from whitelist.'), smartAccount: z.string().optional().describe('Smart account address, name, or "#N". Defaults to first smart account.'), }), },