feat: Aerodrome Action Provider - #672

Draft
Pranav2456 wants to merge 3 commits into
coinbase:mainfrom
Pranav2456:feat/aerodome-action-provider
Draft

feat: Aerodrome Action Provider#672
Pranav2456 wants to merge 3 commits into
coinbase:mainfrom
Pranav2456:feat/aerodome-action-provider

Conversation

@Pranav2456

@Pranav2456Pranav2456 commented Apr 13, 2025

Copy link
Copy Markdown

Aerodrome Action Provider for AgentKit

Overview

The Aerodrome Action Provider integrates Aerodrome Finance with AgentKit, enabling AI agents to interact with this Base-native DEX. Currently supports Base Mainnet for veAERO management, governance voting, and token swaps.

File Structure

agentkit/src/action-providers/aerodrome/
├── aerodromeActionProvider.ts # Main provider implementation
├── aerodromeActionProvider.test.ts # Test suite
├── constants.ts # Contract addresses & ABIs
├── schemas.ts # Zod validation schemas
├── utils.ts # Helper functions
└── index.ts # Public exports

Core Features

Create Lock Action

@CreateAction({name: "createLock",description: "Create a new veAERO lock by depositing AERO tokens",schema: CreateLockSchema,})

Creates veAERO governance NFTs by locking AERO tokens
Handles token approvals automatically
Enforces lock duration constraints (1 week to 4 years)
Verifies token balances before locking

Vote Action

@CreateAction({name: "vote",description: "Cast votes with veAERO NFT for liquidity pool emissions",schema: VoteSchema,})

Casts votes for gauge emissions using veAERO NFTs
Validates pool gauge existence
Enforces epoch-based voting rules
Provides detailed vote allocation feedback

Swap Action

@CreateAction({name: "swapExactTokensForTokens",description: "Swap tokens via Aerodrome pools",schema: SwapExactTokensSchema,})

Swaps exact input tokens for minimum output tokens
Supports both stable and volatile pools
Provides price quotes and slippage warnings
Handles approvals and deadline validation

Technical Details

Dependencies: viem for blockchain interactions, zod for schema validation
Error Handling: Comprehensive checks for balances, approvals, deadlines, and contract-specific errors
Helper Functions: Modular utility functions for token info, transaction formatting, and epoch calculations

Testing

Comprehensive Jest test suite with mocked wallet provider
Tests for success and error paths for all actions
Coverage for specific contract errors (NotApprovedOrOwner, INSUFFICIENT_OUTPUT_AMOUNT, etc.)
Network validation testing

Current Limitations

Base Mainnet support only
Direct swap routes only (no multi-hop routing)
Limited to core veAERO and trading operations

Future Enhancements

Additional veAERO management (increase amount/duration, withdraw)
Rewards claiming (fees, bribes)
Liquidity provision and staking
Multi-hop swap routing

@cb-heimdall

cb-heimdall commented Apr 13, 2025

Copy link
Copy Markdown

🟡 Heimdall Review Status

RequirementStatusMore Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot0
1 if user is external0
2 if repo is sensitive0
From .codeflow.yml1
Additional review requirements
Show calculation
Max0
0
From CODEOWNERS0
Global minimum0
Max 1
1
1 if commit is unverified0
Sum1

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation action provider New action provider typescript labels Apr 13, 2025
@Pranav2456Pranav2456 changed the title feat: Aerodome Action Providerfeat: Aerodrome Action ProviderApr 14, 2025
@Pranav2456
Pranav2456 marked this pull request as draft April 15, 2025 13:37
@phdargen

Copy link
Copy Markdown
Contributor

Hey @Pranav2456, would be great to get an aerodrome action provider in!

This is still marked as draft, are you still working on this or is it ready for review?
Let me know if I can help with something or provide some feedback

@Pranav2456

Copy link
Copy Markdown
Author

Hey @phdargen

Hope you are doing well! I had to stop working on this due to some issues, but I definitely want to continue working on it and would greatly appreciate your feedback, initial review, or expectations. Since Aerodrome is quite a vast protocol, it would be difficult to complete all the features quickly, so it would be great if you could provide some direction.

@phdargen

Copy link
Copy Markdown
Contributor

Ok great @Pranav2456, thanks for your reply!

Aerodrome is indeed a quite complex protocol, by no means your PR needs to be feature complete.
It would be perfectly fine to only concentrate on the governance/vote actions at first.

Especially the LP action might be fairly difficult to implement and could be done in a follow-up PR (by you or someone else).

I would put less priority on the swap related actions as we have CDP API and 0x actions that aggregate various trade routes. Your swap action looks good though, if its not too much trouble would be nice to add.

Concerning the governance/vote actions it would be great to have the full flow with increase lock, withdraw, claim but again its up to you how much you are willing to contribute.

I will provide some initial comments below

Hey @phdargen

Hope you are doing well! I had to stop working on this due to some issues, but I definitely want to continue working on it and would greatly appreciate your feedback, initial review, or expectations. Since Aerodrome is quite a vast protocol, it would be difficult to complete all the features quickly, so it would be great if you could provide some direction.

@phdargen

Copy link
Copy Markdown
Contributor

Note that we require signed commits. See here for instructions on setting up commit signing. Once setup, rebase against main to re-sign all commits

@phdargen

Copy link
Copy Markdown
Contributor

Please add entry in agentkit/README (https://github.com/coinbase/agentkit/blob/main/typescript/agentkit/README.md), should follow alphabetic order

@phdargen

phdargen commented Sep 16, 2025

Copy link
Copy Markdown
Contributor

When you think it is ready to be merged, please remove all console.logs in your code and mark the PR from 'draft' to 'ready for review'

Also add the result of some manual testing including prompts and responses to the PR description above

return `Error: Lock duration (${lockDurationSeconds}s) cannot exceed 4 years (${MAX_LOCK_DURATION}s)`;
}

const { decimals, symbol } = await getTokenInfo(wallet, AERO_ADDRESS as Hex);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you may reuse the getTokenDetails function from erc20 action/utils here to fetch this info + balances more efficiently with a multicall

},
] as const satisfies Abi;

export const ERC20_ABI = [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import from view instead

import {erc20Abi } from "viem";

"created veAERO lock",
`Locked ${args.aeroAmount} ${symbol} for ${durationText}.`,
txHash,
receipt,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can the veAERO tokenId be retrieved from the tx logs? This might be useful for follow-up actions like vote

Comment on lines +255 to +257
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn (e.g., '1.5'), amountOutMin (atomic units/wei), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

amountOutMin should also be in whole units, not in atomic units.

Problem here is that the user needs to know the fair price and then compute a sensible amountOutMin for this action. Better would be to replace amountOutMin arg with a slippage arg (default to 1%) which then internally computes the amountOutMin

Suggested change
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn (e.g., '1.5'), amountOutMin (atomic units/wei), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn in whole units (e.g., '1.5'), amountOutMin in whole units (e.g., '2.1'), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,

Comment on lines +63 to +65
deadline: positiveIntegerStringSchema.describe(
"Unix timestamp deadline (seconds since epoch) for the transaction to succeed. Must be in the future.",
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be good to set a reasonable default for the deadline, like 10mins for example

@Pranav2456
Pranav2456force-pushed the feat/aerodome-action-provider branch 5 times, most recently from 25718ab to c623b56CompareNovember 10, 2025 06:38
@Pranav2456
Pranav2456force-pushed the feat/aerodome-action-provider branch from c623b56 to c2ea1fbCompareNovember 24, 2025 05:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action providerNew action providerdocumentationImprovements or additions to documentationtypescript

Development

Successfully merging this pull request may close these issues.

4 participants

@Pranav2456@cb-heimdall@phdargen@Tanker187
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: Aerodrome Action Provider - #672

Draft
Pranav2456 wants to merge 3 commits into
coinbase:mainfrom
Pranav2456:feat/aerodome-action-provider
Draft

feat: Aerodrome Action Provider#672
Pranav2456 wants to merge 3 commits into
coinbase:mainfrom
Pranav2456:feat/aerodome-action-provider

Conversation

@Pranav2456

@Pranav2456Pranav2456 commented Apr 13, 2025

Copy link
Copy Markdown

Aerodrome Action Provider for AgentKit

Overview

The Aerodrome Action Provider integrates Aerodrome Finance with AgentKit, enabling AI agents to interact with this Base-native DEX. Currently supports Base Mainnet for veAERO management, governance voting, and token swaps.

File Structure

agentkit/src/action-providers/aerodrome/
├── aerodromeActionProvider.ts # Main provider implementation
├── aerodromeActionProvider.test.ts # Test suite
├── constants.ts # Contract addresses & ABIs
├── schemas.ts # Zod validation schemas
├── utils.ts # Helper functions
└── index.ts # Public exports

Core Features

Create Lock Action

@CreateAction({name: "createLock",description: "Create a new veAERO lock by depositing AERO tokens",schema: CreateLockSchema,})

Creates veAERO governance NFTs by locking AERO tokens
Handles token approvals automatically
Enforces lock duration constraints (1 week to 4 years)
Verifies token balances before locking

Vote Action

@CreateAction({name: "vote",description: "Cast votes with veAERO NFT for liquidity pool emissions",schema: VoteSchema,})

Casts votes for gauge emissions using veAERO NFTs
Validates pool gauge existence
Enforces epoch-based voting rules
Provides detailed vote allocation feedback

Swap Action

@CreateAction({name: "swapExactTokensForTokens",description: "Swap tokens via Aerodrome pools",schema: SwapExactTokensSchema,})

Swaps exact input tokens for minimum output tokens
Supports both stable and volatile pools
Provides price quotes and slippage warnings
Handles approvals and deadline validation

Technical Details

Dependencies: viem for blockchain interactions, zod for schema validation
Error Handling: Comprehensive checks for balances, approvals, deadlines, and contract-specific errors
Helper Functions: Modular utility functions for token info, transaction formatting, and epoch calculations

Testing

Comprehensive Jest test suite with mocked wallet provider
Tests for success and error paths for all actions
Coverage for specific contract errors (NotApprovedOrOwner, INSUFFICIENT_OUTPUT_AMOUNT, etc.)
Network validation testing

Current Limitations

Base Mainnet support only
Direct swap routes only (no multi-hop routing)
Limited to core veAERO and trading operations

Future Enhancements

Additional veAERO management (increase amount/duration, withdraw)
Rewards claiming (fees, bribes)
Liquidity provision and staking
Multi-hop swap routing

@cb-heimdall

cb-heimdall commented Apr 13, 2025

Copy link
Copy Markdown

🟡 Heimdall Review Status

RequirementStatusMore Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot0
1 if user is external0
2 if repo is sensitive0
From .codeflow.yml1
Additional review requirements
Show calculation
Max0
0
From CODEOWNERS0
Global minimum0
Max 1
1
1 if commit is unverified0
Sum1

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation action provider New action provider typescript labels Apr 13, 2025
@Pranav2456Pranav2456 changed the title feat: Aerodome Action Providerfeat: Aerodrome Action ProviderApr 14, 2025
@Pranav2456
Pranav2456 marked this pull request as draft April 15, 2025 13:37
@phdargen

Copy link
Copy Markdown
Contributor

Hey @Pranav2456, would be great to get an aerodrome action provider in!

This is still marked as draft, are you still working on this or is it ready for review?
Let me know if I can help with something or provide some feedback

@Pranav2456

Copy link
Copy Markdown
Author

Hey @phdargen

Hope you are doing well! I had to stop working on this due to some issues, but I definitely want to continue working on it and would greatly appreciate your feedback, initial review, or expectations. Since Aerodrome is quite a vast protocol, it would be difficult to complete all the features quickly, so it would be great if you could provide some direction.

@phdargen

Copy link
Copy Markdown
Contributor

Ok great @Pranav2456, thanks for your reply!

Aerodrome is indeed a quite complex protocol, by no means your PR needs to be feature complete.
It would be perfectly fine to only concentrate on the governance/vote actions at first.

Especially the LP action might be fairly difficult to implement and could be done in a follow-up PR (by you or someone else).

I would put less priority on the swap related actions as we have CDP API and 0x actions that aggregate various trade routes. Your swap action looks good though, if its not too much trouble would be nice to add.

Concerning the governance/vote actions it would be great to have the full flow with increase lock, withdraw, claim but again its up to you how much you are willing to contribute.

I will provide some initial comments below

Hey @phdargen

Hope you are doing well! I had to stop working on this due to some issues, but I definitely want to continue working on it and would greatly appreciate your feedback, initial review, or expectations. Since Aerodrome is quite a vast protocol, it would be difficult to complete all the features quickly, so it would be great if you could provide some direction.

@phdargen

Copy link
Copy Markdown
Contributor

Note that we require signed commits. See here for instructions on setting up commit signing. Once setup, rebase against main to re-sign all commits

@phdargen

Copy link
Copy Markdown
Contributor

Please add entry in agentkit/README (https://github.com/coinbase/agentkit/blob/main/typescript/agentkit/README.md), should follow alphabetic order

@phdargen

phdargen commented Sep 16, 2025

Copy link
Copy Markdown
Contributor

When you think it is ready to be merged, please remove all console.logs in your code and mark the PR from 'draft' to 'ready for review'

Also add the result of some manual testing including prompts and responses to the PR description above

return `Error: Lock duration (${lockDurationSeconds}s) cannot exceed 4 years (${MAX_LOCK_DURATION}s)`;
}

const { decimals, symbol } = await getTokenInfo(wallet, AERO_ADDRESS as Hex);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you may reuse the getTokenDetails function from erc20 action/utils here to fetch this info + balances more efficiently with a multicall

},
] as const satisfies Abi;

export const ERC20_ABI = [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import from view instead

import {erc20Abi } from "viem";

"created veAERO lock",
`Locked ${args.aeroAmount} ${symbol} for ${durationText}.`,
txHash,
receipt,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can the veAERO tokenId be retrieved from the tx logs? This might be useful for follow-up actions like vote

Comment on lines +255 to +257
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn (e.g., '1.5'), amountOutMin (atomic units/wei), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

amountOutMin should also be in whole units, not in atomic units.

Problem here is that the user needs to know the fair price and then compute a sensible amountOutMin for this action. Better would be to replace amountOutMin arg with a slippage arg (default to 1%) which then internally computes the amountOutMin

Suggested change
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn (e.g., '1.5'), amountOutMin (atomic units/wei), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn in whole units (e.g., '1.5'), amountOutMin in whole units (e.g., '2.1'), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,

Comment on lines +63 to +65
deadline: positiveIntegerStringSchema.describe(
"Unix timestamp deadline (seconds since epoch) for the transaction to succeed. Must be in the future.",
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be good to set a reasonable default for the deadline, like 10mins for example

@Pranav2456
Pranav2456force-pushed the feat/aerodome-action-provider branch 5 times, most recently from 25718ab to c623b56CompareNovember 10, 2025 06:38
@Pranav2456
Pranav2456force-pushed the feat/aerodome-action-provider branch from c623b56 to c2ea1fbCompareNovember 24, 2025 05:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action providerNew action providerdocumentationImprovements or additions to documentationtypescript

Development

Successfully merging this pull request may close these issues.

4 participants

@Pranav2456@cb-heimdall@phdargen@Tanker187
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Aerodrome Action Provider - #672

Draft
Pranav2456 wants to merge 3 commits into
coinbase:mainfrom
Pranav2456:feat/aerodome-action-provider
Draft

feat: Aerodrome Action Provider#672
Pranav2456 wants to merge 3 commits into
coinbase:mainfrom
Pranav2456:feat/aerodome-action-provider

Conversation

@Pranav2456

@Pranav2456Pranav2456 commented Apr 13, 2025

Copy link
Copy Markdown

Aerodrome Action Provider for AgentKit

Overview

The Aerodrome Action Provider integrates Aerodrome Finance with AgentKit, enabling AI agents to interact with this Base-native DEX. Currently supports Base Mainnet for veAERO management, governance voting, and token swaps.

File Structure

agentkit/src/action-providers/aerodrome/
├── aerodromeActionProvider.ts # Main provider implementation
├── aerodromeActionProvider.test.ts # Test suite
├── constants.ts # Contract addresses & ABIs
├── schemas.ts # Zod validation schemas
├── utils.ts # Helper functions
└── index.ts # Public exports

Core Features

Create Lock Action

@CreateAction({name: "createLock",description: "Create a new veAERO lock by depositing AERO tokens",schema: CreateLockSchema,})

Creates veAERO governance NFTs by locking AERO tokens
Handles token approvals automatically
Enforces lock duration constraints (1 week to 4 years)
Verifies token balances before locking

Vote Action

@CreateAction({name: "vote",description: "Cast votes with veAERO NFT for liquidity pool emissions",schema: VoteSchema,})

Casts votes for gauge emissions using veAERO NFTs
Validates pool gauge existence
Enforces epoch-based voting rules
Provides detailed vote allocation feedback

Swap Action

@CreateAction({name: "swapExactTokensForTokens",description: "Swap tokens via Aerodrome pools",schema: SwapExactTokensSchema,})

Swaps exact input tokens for minimum output tokens
Supports both stable and volatile pools
Provides price quotes and slippage warnings
Handles approvals and deadline validation

Technical Details

Dependencies: viem for blockchain interactions, zod for schema validation
Error Handling: Comprehensive checks for balances, approvals, deadlines, and contract-specific errors
Helper Functions: Modular utility functions for token info, transaction formatting, and epoch calculations

Testing

Comprehensive Jest test suite with mocked wallet provider
Tests for success and error paths for all actions
Coverage for specific contract errors (NotApprovedOrOwner, INSUFFICIENT_OUTPUT_AMOUNT, etc.)
Network validation testing

Current Limitations

Base Mainnet support only
Direct swap routes only (no multi-hop routing)
Limited to core veAERO and trading operations

Future Enhancements

Additional veAERO management (increase amount/duration, withdraw)
Rewards claiming (fees, bribes)
Liquidity provision and staking
Multi-hop swap routing

@cb-heimdall

cb-heimdall commented Apr 13, 2025

Copy link
Copy Markdown

🟡 Heimdall Review Status

RequirementStatusMore Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot0
1 if user is external0
2 if repo is sensitive0
From .codeflow.yml1
Additional review requirements
Show calculation
Max0
0
From CODEOWNERS0
Global minimum0
Max 1
1
1 if commit is unverified0
Sum1

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation action provider New action provider typescript labels Apr 13, 2025
@Pranav2456Pranav2456 changed the title feat: Aerodome Action Providerfeat: Aerodrome Action ProviderApr 14, 2025
@Pranav2456
Pranav2456 marked this pull request as draft April 15, 2025 13:37
@phdargen

Copy link
Copy Markdown
Contributor

Hey @Pranav2456, would be great to get an aerodrome action provider in!

This is still marked as draft, are you still working on this or is it ready for review?
Let me know if I can help with something or provide some feedback

@Pranav2456

Copy link
Copy Markdown
Author

Hey @phdargen

Hope you are doing well! I had to stop working on this due to some issues, but I definitely want to continue working on it and would greatly appreciate your feedback, initial review, or expectations. Since Aerodrome is quite a vast protocol, it would be difficult to complete all the features quickly, so it would be great if you could provide some direction.

@phdargen

Copy link
Copy Markdown
Contributor

Ok great @Pranav2456, thanks for your reply!

Aerodrome is indeed a quite complex protocol, by no means your PR needs to be feature complete.
It would be perfectly fine to only concentrate on the governance/vote actions at first.

Especially the LP action might be fairly difficult to implement and could be done in a follow-up PR (by you or someone else).

I would put less priority on the swap related actions as we have CDP API and 0x actions that aggregate various trade routes. Your swap action looks good though, if its not too much trouble would be nice to add.

Concerning the governance/vote actions it would be great to have the full flow with increase lock, withdraw, claim but again its up to you how much you are willing to contribute.

I will provide some initial comments below

Hey @phdargen

Hope you are doing well! I had to stop working on this due to some issues, but I definitely want to continue working on it and would greatly appreciate your feedback, initial review, or expectations. Since Aerodrome is quite a vast protocol, it would be difficult to complete all the features quickly, so it would be great if you could provide some direction.

@phdargen

Copy link
Copy Markdown
Contributor

Note that we require signed commits. See here for instructions on setting up commit signing. Once setup, rebase against main to re-sign all commits

@phdargen

Copy link
Copy Markdown
Contributor

Please add entry in agentkit/README (https://github.com/coinbase/agentkit/blob/main/typescript/agentkit/README.md), should follow alphabetic order

@phdargen

phdargen commented Sep 16, 2025

Copy link
Copy Markdown
Contributor

When you think it is ready to be merged, please remove all console.logs in your code and mark the PR from 'draft' to 'ready for review'

Also add the result of some manual testing including prompts and responses to the PR description above

return `Error: Lock duration (${lockDurationSeconds}s) cannot exceed 4 years (${MAX_LOCK_DURATION}s)`;
}

const { decimals, symbol } = await getTokenInfo(wallet, AERO_ADDRESS as Hex);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you may reuse the getTokenDetails function from erc20 action/utils here to fetch this info + balances more efficiently with a multicall

},
] as const satisfies Abi;

export const ERC20_ABI = [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import from view instead

import {erc20Abi } from "viem";

"created veAERO lock",
`Locked ${args.aeroAmount} ${symbol} for ${durationText}.`,
txHash,
receipt,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can the veAERO tokenId be retrieved from the tx logs? This might be useful for follow-up actions like vote

Comment on lines +255 to +257
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn (e.g., '1.5'), amountOutMin (atomic units/wei), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

amountOutMin should also be in whole units, not in atomic units.

Problem here is that the user needs to know the fair price and then compute a sensible amountOutMin for this action. Better would be to replace amountOutMin arg with a slippage arg (default to 1%) which then internally computes the amountOutMin

Suggested change
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn (e.g., '1.5'), amountOutMin (atomic units/wei), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn in whole units (e.g., '1.5'), amountOutMin in whole units (e.g., '2.1'), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,

Comment on lines +63 to +65
deadline: positiveIntegerStringSchema.describe(
"Unix timestamp deadline (seconds since epoch) for the transaction to succeed. Must be in the future.",
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be good to set a reasonable default for the deadline, like 10mins for example

@Pranav2456
Pranav2456force-pushed the feat/aerodome-action-provider branch 5 times, most recently from 25718ab to c623b56CompareNovember 10, 2025 06:38
@Pranav2456
Pranav2456force-pushed the feat/aerodome-action-provider branch from c623b56 to c2ea1fbCompareNovember 24, 2025 05:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action providerNew action providerdocumentationImprovements or additions to documentationtypescript

Development

Successfully merging this pull request may close these issues.

4 participants

@Pranav2456@cb-heimdall@phdargen@Tanker187
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Aerodrome Action Provider - #672

Draft
Pranav2456 wants to merge 3 commits into
coinbase:mainfrom
Pranav2456:feat/aerodome-action-provider
Draft

feat: Aerodrome Action Provider#672
Pranav2456 wants to merge 3 commits into
coinbase:mainfrom
Pranav2456:feat/aerodome-action-provider

Conversation

@Pranav2456

@Pranav2456Pranav2456 commented Apr 13, 2025

Copy link
Copy Markdown

Aerodrome Action Provider for AgentKit

Overview

The Aerodrome Action Provider integrates Aerodrome Finance with AgentKit, enabling AI agents to interact with this Base-native DEX. Currently supports Base Mainnet for veAERO management, governance voting, and token swaps.

File Structure

agentkit/src/action-providers/aerodrome/
├── aerodromeActionProvider.ts # Main provider implementation
├── aerodromeActionProvider.test.ts # Test suite
├── constants.ts # Contract addresses & ABIs
├── schemas.ts # Zod validation schemas
├── utils.ts # Helper functions
└── index.ts # Public exports

Core Features

Create Lock Action

@CreateAction({name: "createLock",description: "Create a new veAERO lock by depositing AERO tokens",schema: CreateLockSchema,})

Creates veAERO governance NFTs by locking AERO tokens
Handles token approvals automatically
Enforces lock duration constraints (1 week to 4 years)
Verifies token balances before locking

Vote Action

@CreateAction({name: "vote",description: "Cast votes with veAERO NFT for liquidity pool emissions",schema: VoteSchema,})

Casts votes for gauge emissions using veAERO NFTs
Validates pool gauge existence
Enforces epoch-based voting rules
Provides detailed vote allocation feedback

Swap Action

@CreateAction({name: "swapExactTokensForTokens",description: "Swap tokens via Aerodrome pools",schema: SwapExactTokensSchema,})

Swaps exact input tokens for minimum output tokens
Supports both stable and volatile pools
Provides price quotes and slippage warnings
Handles approvals and deadline validation

Technical Details

Dependencies: viem for blockchain interactions, zod for schema validation
Error Handling: Comprehensive checks for balances, approvals, deadlines, and contract-specific errors
Helper Functions: Modular utility functions for token info, transaction formatting, and epoch calculations

Testing

Comprehensive Jest test suite with mocked wallet provider
Tests for success and error paths for all actions
Coverage for specific contract errors (NotApprovedOrOwner, INSUFFICIENT_OUTPUT_AMOUNT, etc.)
Network validation testing

Current Limitations

Base Mainnet support only
Direct swap routes only (no multi-hop routing)
Limited to core veAERO and trading operations

Future Enhancements

Additional veAERO management (increase amount/duration, withdraw)
Rewards claiming (fees, bribes)
Liquidity provision and staking
Multi-hop swap routing

@cb-heimdall

cb-heimdall commented Apr 13, 2025

Copy link
Copy Markdown

🟡 Heimdall Review Status

RequirementStatusMore Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot0
1 if user is external0
2 if repo is sensitive0
From .codeflow.yml1
Additional review requirements
Show calculation
Max0
0
From CODEOWNERS0
Global minimum0
Max 1
1
1 if commit is unverified0
Sum1

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation action provider New action provider typescript labels Apr 13, 2025
@Pranav2456Pranav2456 changed the title feat: Aerodome Action Providerfeat: Aerodrome Action ProviderApr 14, 2025
@Pranav2456
Pranav2456 marked this pull request as draft April 15, 2025 13:37
@phdargen

Copy link
Copy Markdown
Contributor

Hey @Pranav2456, would be great to get an aerodrome action provider in!

This is still marked as draft, are you still working on this or is it ready for review?
Let me know if I can help with something or provide some feedback

@Pranav2456

Copy link
Copy Markdown
Author

Hey @phdargen

Hope you are doing well! I had to stop working on this due to some issues, but I definitely want to continue working on it and would greatly appreciate your feedback, initial review, or expectations. Since Aerodrome is quite a vast protocol, it would be difficult to complete all the features quickly, so it would be great if you could provide some direction.

@phdargen

Copy link
Copy Markdown
Contributor

Ok great @Pranav2456, thanks for your reply!

Aerodrome is indeed a quite complex protocol, by no means your PR needs to be feature complete.
It would be perfectly fine to only concentrate on the governance/vote actions at first.

Especially the LP action might be fairly difficult to implement and could be done in a follow-up PR (by you or someone else).

I would put less priority on the swap related actions as we have CDP API and 0x actions that aggregate various trade routes. Your swap action looks good though, if its not too much trouble would be nice to add.

Concerning the governance/vote actions it would be great to have the full flow with increase lock, withdraw, claim but again its up to you how much you are willing to contribute.

I will provide some initial comments below

Hey @phdargen

Hope you are doing well! I had to stop working on this due to some issues, but I definitely want to continue working on it and would greatly appreciate your feedback, initial review, or expectations. Since Aerodrome is quite a vast protocol, it would be difficult to complete all the features quickly, so it would be great if you could provide some direction.

@phdargen

Copy link
Copy Markdown
Contributor

Note that we require signed commits. See here for instructions on setting up commit signing. Once setup, rebase against main to re-sign all commits

@phdargen

Copy link
Copy Markdown
Contributor

Please add entry in agentkit/README (https://github.com/coinbase/agentkit/blob/main/typescript/agentkit/README.md), should follow alphabetic order

@phdargen

phdargen commented Sep 16, 2025

Copy link
Copy Markdown
Contributor

When you think it is ready to be merged, please remove all console.logs in your code and mark the PR from 'draft' to 'ready for review'

Also add the result of some manual testing including prompts and responses to the PR description above

return `Error: Lock duration (${lockDurationSeconds}s) cannot exceed 4 years (${MAX_LOCK_DURATION}s)`;
}

const { decimals, symbol } = await getTokenInfo(wallet, AERO_ADDRESS as Hex);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you may reuse the getTokenDetails function from erc20 action/utils here to fetch this info + balances more efficiently with a multicall

},
] as const satisfies Abi;

export const ERC20_ABI = [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import from view instead

import {erc20Abi } from "viem";

"created veAERO lock",
`Locked ${args.aeroAmount} ${symbol} for ${durationText}.`,
txHash,
receipt,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can the veAERO tokenId be retrieved from the tx logs? This might be useful for follow-up actions like vote

Comment on lines +255 to +257
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn (e.g., '1.5'), amountOutMin (atomic units/wei), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

amountOutMin should also be in whole units, not in atomic units.

Problem here is that the user needs to know the fair price and then compute a sensible amountOutMin for this action. Better would be to replace amountOutMin arg with a slippage arg (default to 1%) which then internally computes the amountOutMin

Suggested change
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn (e.g., '1.5'), amountOutMin (atomic units/wei), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn in whole units (e.g., '1.5'), amountOutMin in whole units (e.g., '2.1'), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,

Comment on lines +63 to +65
deadline: positiveIntegerStringSchema.describe(
"Unix timestamp deadline (seconds since epoch) for the transaction to succeed. Must be in the future.",
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be good to set a reasonable default for the deadline, like 10mins for example

@Pranav2456
Pranav2456force-pushed the feat/aerodome-action-provider branch 5 times, most recently from 25718ab to c623b56CompareNovember 10, 2025 06:38
@Pranav2456
Pranav2456force-pushed the feat/aerodome-action-provider branch from c623b56 to c2ea1fbCompareNovember 24, 2025 05:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action providerNew action providerdocumentationImprovements or additions to documentationtypescript

Development

Successfully merging this pull request may close these issues.

4 participants

@Pranav2456@cb-heimdall@phdargen@Tanker187
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: Aerodrome Action Provider - #672

Draft
Pranav2456 wants to merge 3 commits into
coinbase:mainfrom
Pranav2456:feat/aerodome-action-provider
Draft

feat: Aerodrome Action Provider#672
Pranav2456 wants to merge 3 commits into
coinbase:mainfrom
Pranav2456:feat/aerodome-action-provider

Conversation

@Pranav2456

@Pranav2456Pranav2456 commented Apr 13, 2025

Copy link
Copy Markdown

Aerodrome Action Provider for AgentKit

Overview

The Aerodrome Action Provider integrates Aerodrome Finance with AgentKit, enabling AI agents to interact with this Base-native DEX. Currently supports Base Mainnet for veAERO management, governance voting, and token swaps.

File Structure

agentkit/src/action-providers/aerodrome/
├── aerodromeActionProvider.ts # Main provider implementation
├── aerodromeActionProvider.test.ts # Test suite
├── constants.ts # Contract addresses & ABIs
├── schemas.ts # Zod validation schemas
├── utils.ts # Helper functions
└── index.ts # Public exports

Core Features

Create Lock Action

@CreateAction({name: "createLock",description: "Create a new veAERO lock by depositing AERO tokens",schema: CreateLockSchema,})

Creates veAERO governance NFTs by locking AERO tokens
Handles token approvals automatically
Enforces lock duration constraints (1 week to 4 years)
Verifies token balances before locking

Vote Action

@CreateAction({name: "vote",description: "Cast votes with veAERO NFT for liquidity pool emissions",schema: VoteSchema,})

Casts votes for gauge emissions using veAERO NFTs
Validates pool gauge existence
Enforces epoch-based voting rules
Provides detailed vote allocation feedback

Swap Action

@CreateAction({name: "swapExactTokensForTokens",description: "Swap tokens via Aerodrome pools",schema: SwapExactTokensSchema,})

Swaps exact input tokens for minimum output tokens
Supports both stable and volatile pools
Provides price quotes and slippage warnings
Handles approvals and deadline validation

Technical Details

Dependencies: viem for blockchain interactions, zod for schema validation
Error Handling: Comprehensive checks for balances, approvals, deadlines, and contract-specific errors
Helper Functions: Modular utility functions for token info, transaction formatting, and epoch calculations

Testing

Comprehensive Jest test suite with mocked wallet provider
Tests for success and error paths for all actions
Coverage for specific contract errors (NotApprovedOrOwner, INSUFFICIENT_OUTPUT_AMOUNT, etc.)
Network validation testing

Current Limitations

Base Mainnet support only
Direct swap routes only (no multi-hop routing)
Limited to core veAERO and trading operations

Future Enhancements

Additional veAERO management (increase amount/duration, withdraw)
Rewards claiming (fees, bribes)
Liquidity provision and staking
Multi-hop swap routing

@cb-heimdall

cb-heimdall commented Apr 13, 2025

Copy link
Copy Markdown

🟡 Heimdall Review Status

RequirementStatusMore Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot0
1 if user is external0
2 if repo is sensitive0
From .codeflow.yml1
Additional review requirements
Show calculation
Max0
0
From CODEOWNERS0
Global minimum0
Max 1
1
1 if commit is unverified0
Sum1

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation action provider New action provider typescript labels Apr 13, 2025
@Pranav2456Pranav2456 changed the title feat: Aerodome Action Providerfeat: Aerodrome Action ProviderApr 14, 2025
@Pranav2456
Pranav2456 marked this pull request as draft April 15, 2025 13:37
@phdargen

Copy link
Copy Markdown
Contributor

Hey @Pranav2456, would be great to get an aerodrome action provider in!

This is still marked as draft, are you still working on this or is it ready for review?
Let me know if I can help with something or provide some feedback

@Pranav2456

Copy link
Copy Markdown
Author

Hey @phdargen

Hope you are doing well! I had to stop working on this due to some issues, but I definitely want to continue working on it and would greatly appreciate your feedback, initial review, or expectations. Since Aerodrome is quite a vast protocol, it would be difficult to complete all the features quickly, so it would be great if you could provide some direction.

@phdargen

Copy link
Copy Markdown
Contributor

Ok great @Pranav2456, thanks for your reply!

Aerodrome is indeed a quite complex protocol, by no means your PR needs to be feature complete.
It would be perfectly fine to only concentrate on the governance/vote actions at first.

Especially the LP action might be fairly difficult to implement and could be done in a follow-up PR (by you or someone else).

I would put less priority on the swap related actions as we have CDP API and 0x actions that aggregate various trade routes. Your swap action looks good though, if its not too much trouble would be nice to add.

Concerning the governance/vote actions it would be great to have the full flow with increase lock, withdraw, claim but again its up to you how much you are willing to contribute.

I will provide some initial comments below

Hey @phdargen

Hope you are doing well! I had to stop working on this due to some issues, but I definitely want to continue working on it and would greatly appreciate your feedback, initial review, or expectations. Since Aerodrome is quite a vast protocol, it would be difficult to complete all the features quickly, so it would be great if you could provide some direction.

@phdargen

Copy link
Copy Markdown
Contributor

Note that we require signed commits. See here for instructions on setting up commit signing. Once setup, rebase against main to re-sign all commits

@phdargen

Copy link
Copy Markdown
Contributor

Please add entry in agentkit/README (https://github.com/coinbase/agentkit/blob/main/typescript/agentkit/README.md), should follow alphabetic order

@phdargen

phdargen commented Sep 16, 2025

Copy link
Copy Markdown
Contributor

When you think it is ready to be merged, please remove all console.logs in your code and mark the PR from 'draft' to 'ready for review'

Also add the result of some manual testing including prompts and responses to the PR description above

return `Error: Lock duration (${lockDurationSeconds}s) cannot exceed 4 years (${MAX_LOCK_DURATION}s)`;
}

const { decimals, symbol } = await getTokenInfo(wallet, AERO_ADDRESS as Hex);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you may reuse the getTokenDetails function from erc20 action/utils here to fetch this info + balances more efficiently with a multicall

},
] as const satisfies Abi;

export const ERC20_ABI = [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import from view instead

import {erc20Abi } from "viem";

"created veAERO lock",
`Locked ${args.aeroAmount} ${symbol} for ${durationText}.`,
txHash,
receipt,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can the veAERO tokenId be retrieved from the tx logs? This might be useful for follow-up actions like vote

Comment on lines +255 to +257
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn (e.g., '1.5'), amountOutMin (atomic units/wei), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

amountOutMin should also be in whole units, not in atomic units.

Problem here is that the user needs to know the fair price and then compute a sensible amountOutMin for this action. Better would be to replace amountOutMin arg with a slippage arg (default to 1%) which then internally computes the amountOutMin

Suggested change
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn (e.g., '1.5'), amountOutMin (atomic units/wei), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn in whole units (e.g., '1.5'), amountOutMin in whole units (e.g., '2.1'), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,

Comment on lines +63 to +65
deadline: positiveIntegerStringSchema.describe(
"Unix timestamp deadline (seconds since epoch) for the transaction to succeed. Must be in the future.",
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be good to set a reasonable default for the deadline, like 10mins for example

@Pranav2456
Pranav2456force-pushed the feat/aerodome-action-provider branch 5 times, most recently from 25718ab to c623b56CompareNovember 10, 2025 06:38
@Pranav2456
Pranav2456force-pushed the feat/aerodome-action-provider branch from c623b56 to c2ea1fbCompareNovember 24, 2025 05:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action providerNew action providerdocumentationImprovements or additions to documentationtypescript

Development

Successfully merging this pull request may close these issues.

4 participants

@Pranav2456@cb-heimdall@phdargen@Tanker187
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Aerodrome Action Provider - #672

Draft
Pranav2456 wants to merge 3 commits into
coinbase:mainfrom
Pranav2456:feat/aerodome-action-provider
Draft

feat: Aerodrome Action Provider#672
Pranav2456 wants to merge 3 commits into
coinbase:mainfrom
Pranav2456:feat/aerodome-action-provider

Conversation

@Pranav2456

@Pranav2456Pranav2456 commented Apr 13, 2025

Copy link
Copy Markdown

Aerodrome Action Provider for AgentKit

Overview

The Aerodrome Action Provider integrates Aerodrome Finance with AgentKit, enabling AI agents to interact with this Base-native DEX. Currently supports Base Mainnet for veAERO management, governance voting, and token swaps.

File Structure

agentkit/src/action-providers/aerodrome/
├── aerodromeActionProvider.ts # Main provider implementation
├── aerodromeActionProvider.test.ts # Test suite
├── constants.ts # Contract addresses & ABIs
├── schemas.ts # Zod validation schemas
├── utils.ts # Helper functions
└── index.ts # Public exports

Core Features

Create Lock Action

@CreateAction({name: "createLock",description: "Create a new veAERO lock by depositing AERO tokens",schema: CreateLockSchema,})

Creates veAERO governance NFTs by locking AERO tokens
Handles token approvals automatically
Enforces lock duration constraints (1 week to 4 years)
Verifies token balances before locking

Vote Action

@CreateAction({name: "vote",description: "Cast votes with veAERO NFT for liquidity pool emissions",schema: VoteSchema,})

Casts votes for gauge emissions using veAERO NFTs
Validates pool gauge existence
Enforces epoch-based voting rules
Provides detailed vote allocation feedback

Swap Action

@CreateAction({name: "swapExactTokensForTokens",description: "Swap tokens via Aerodrome pools",schema: SwapExactTokensSchema,})

Swaps exact input tokens for minimum output tokens
Supports both stable and volatile pools
Provides price quotes and slippage warnings
Handles approvals and deadline validation

Technical Details

Dependencies: viem for blockchain interactions, zod for schema validation
Error Handling: Comprehensive checks for balances, approvals, deadlines, and contract-specific errors
Helper Functions: Modular utility functions for token info, transaction formatting, and epoch calculations

Testing

Comprehensive Jest test suite with mocked wallet provider
Tests for success and error paths for all actions
Coverage for specific contract errors (NotApprovedOrOwner, INSUFFICIENT_OUTPUT_AMOUNT, etc.)
Network validation testing

Current Limitations

Base Mainnet support only
Direct swap routes only (no multi-hop routing)
Limited to core veAERO and trading operations

Future Enhancements

Additional veAERO management (increase amount/duration, withdraw)
Rewards claiming (fees, bribes)
Liquidity provision and staking
Multi-hop swap routing

@cb-heimdall

cb-heimdall commented Apr 13, 2025

Copy link
Copy Markdown

🟡 Heimdall Review Status

RequirementStatusMore Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot0
1 if user is external0
2 if repo is sensitive0
From .codeflow.yml1
Additional review requirements
Show calculation
Max0
0
From CODEOWNERS0
Global minimum0
Max 1
1
1 if commit is unverified0
Sum1

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation action provider New action provider typescript labels Apr 13, 2025
@Pranav2456Pranav2456 changed the title feat: Aerodome Action Providerfeat: Aerodrome Action ProviderApr 14, 2025
@Pranav2456
Pranav2456 marked this pull request as draft April 15, 2025 13:37
@phdargen

Copy link
Copy Markdown
Contributor

Hey @Pranav2456, would be great to get an aerodrome action provider in!

This is still marked as draft, are you still working on this or is it ready for review?
Let me know if I can help with something or provide some feedback

@Pranav2456

Copy link
Copy Markdown
Author

Hey @phdargen

Hope you are doing well! I had to stop working on this due to some issues, but I definitely want to continue working on it and would greatly appreciate your feedback, initial review, or expectations. Since Aerodrome is quite a vast protocol, it would be difficult to complete all the features quickly, so it would be great if you could provide some direction.

@phdargen

Copy link
Copy Markdown
Contributor

Ok great @Pranav2456, thanks for your reply!

Aerodrome is indeed a quite complex protocol, by no means your PR needs to be feature complete.
It would be perfectly fine to only concentrate on the governance/vote actions at first.

Especially the LP action might be fairly difficult to implement and could be done in a follow-up PR (by you or someone else).

I would put less priority on the swap related actions as we have CDP API and 0x actions that aggregate various trade routes. Your swap action looks good though, if its not too much trouble would be nice to add.

Concerning the governance/vote actions it would be great to have the full flow with increase lock, withdraw, claim but again its up to you how much you are willing to contribute.

I will provide some initial comments below

Hey @phdargen

Hope you are doing well! I had to stop working on this due to some issues, but I definitely want to continue working on it and would greatly appreciate your feedback, initial review, or expectations. Since Aerodrome is quite a vast protocol, it would be difficult to complete all the features quickly, so it would be great if you could provide some direction.

@phdargen

Copy link
Copy Markdown
Contributor

Note that we require signed commits. See here for instructions on setting up commit signing. Once setup, rebase against main to re-sign all commits

@phdargen

Copy link
Copy Markdown
Contributor

Please add entry in agentkit/README (https://github.com/coinbase/agentkit/blob/main/typescript/agentkit/README.md), should follow alphabetic order

@phdargen

phdargen commented Sep 16, 2025

Copy link
Copy Markdown
Contributor

When you think it is ready to be merged, please remove all console.logs in your code and mark the PR from 'draft' to 'ready for review'

Also add the result of some manual testing including prompts and responses to the PR description above

return `Error: Lock duration (${lockDurationSeconds}s) cannot exceed 4 years (${MAX_LOCK_DURATION}s)`;
}

const { decimals, symbol } = await getTokenInfo(wallet, AERO_ADDRESS as Hex);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you may reuse the getTokenDetails function from erc20 action/utils here to fetch this info + balances more efficiently with a multicall

},
] as const satisfies Abi;

export const ERC20_ABI = [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import from view instead

import {erc20Abi } from "viem";

"created veAERO lock",
`Locked ${args.aeroAmount} ${symbol} for ${durationText}.`,
txHash,
receipt,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can the veAERO tokenId be retrieved from the tx logs? This might be useful for follow-up actions like vote

Comment on lines +255 to +257
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn (e.g., '1.5'), amountOutMin (atomic units/wei), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

amountOutMin should also be in whole units, not in atomic units.

Problem here is that the user needs to know the fair price and then compute a sensible amountOutMin for this action. Better would be to replace amountOutMin arg with a slippage arg (default to 1%) which then internally computes the amountOutMin

Suggested change
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn (e.g., '1.5'), amountOutMin (atomic units/wei), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn in whole units (e.g., '1.5'), amountOutMin in whole units (e.g., '2.1'), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,

Comment on lines +63 to +65
deadline: positiveIntegerStringSchema.describe(
"Unix timestamp deadline (seconds since epoch) for the transaction to succeed. Must be in the future.",
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be good to set a reasonable default for the deadline, like 10mins for example

@Pranav2456
Pranav2456force-pushed the feat/aerodome-action-provider branch 5 times, most recently from 25718ab to c623b56CompareNovember 10, 2025 06:38
@Pranav2456
Pranav2456force-pushed the feat/aerodome-action-provider branch from c623b56 to c2ea1fbCompareNovember 24, 2025 05:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action providerNew action providerdocumentationImprovements or additions to documentationtypescript

Development

Successfully merging this pull request may close these issues.

4 participants

@Pranav2456@cb-heimdall@phdargen@Tanker187
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Aerodrome Action Provider - #672

Draft
Pranav2456 wants to merge 3 commits into
coinbase:mainfrom
Pranav2456:feat/aerodome-action-provider
Draft

feat: Aerodrome Action Provider#672
Pranav2456 wants to merge 3 commits into
coinbase:mainfrom
Pranav2456:feat/aerodome-action-provider

Conversation

@Pranav2456

@Pranav2456Pranav2456 commented Apr 13, 2025

Copy link
Copy Markdown

Aerodrome Action Provider for AgentKit

Overview

The Aerodrome Action Provider integrates Aerodrome Finance with AgentKit, enabling AI agents to interact with this Base-native DEX. Currently supports Base Mainnet for veAERO management, governance voting, and token swaps.

File Structure

agentkit/src/action-providers/aerodrome/
├── aerodromeActionProvider.ts # Main provider implementation
├── aerodromeActionProvider.test.ts # Test suite
├── constants.ts # Contract addresses & ABIs
├── schemas.ts # Zod validation schemas
├── utils.ts # Helper functions
└── index.ts # Public exports

Core Features

Create Lock Action

@CreateAction({name: "createLock",description: "Create a new veAERO lock by depositing AERO tokens",schema: CreateLockSchema,})

Creates veAERO governance NFTs by locking AERO tokens
Handles token approvals automatically
Enforces lock duration constraints (1 week to 4 years)
Verifies token balances before locking

Vote Action

@CreateAction({name: "vote",description: "Cast votes with veAERO NFT for liquidity pool emissions",schema: VoteSchema,})

Casts votes for gauge emissions using veAERO NFTs
Validates pool gauge existence
Enforces epoch-based voting rules
Provides detailed vote allocation feedback

Swap Action

@CreateAction({name: "swapExactTokensForTokens",description: "Swap tokens via Aerodrome pools",schema: SwapExactTokensSchema,})

Swaps exact input tokens for minimum output tokens
Supports both stable and volatile pools
Provides price quotes and slippage warnings
Handles approvals and deadline validation

Technical Details

Dependencies: viem for blockchain interactions, zod for schema validation
Error Handling: Comprehensive checks for balances, approvals, deadlines, and contract-specific errors
Helper Functions: Modular utility functions for token info, transaction formatting, and epoch calculations

Testing

Comprehensive Jest test suite with mocked wallet provider
Tests for success and error paths for all actions
Coverage for specific contract errors (NotApprovedOrOwner, INSUFFICIENT_OUTPUT_AMOUNT, etc.)
Network validation testing

Current Limitations

Base Mainnet support only
Direct swap routes only (no multi-hop routing)
Limited to core veAERO and trading operations

Future Enhancements

Additional veAERO management (increase amount/duration, withdraw)
Rewards claiming (fees, bribes)
Liquidity provision and staking
Multi-hop swap routing

@cb-heimdall

cb-heimdall commented Apr 13, 2025

Copy link
Copy Markdown

🟡 Heimdall Review Status

RequirementStatusMore Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot0
1 if user is external0
2 if repo is sensitive0
From .codeflow.yml1
Additional review requirements
Show calculation
Max0
0
From CODEOWNERS0
Global minimum0
Max 1
1
1 if commit is unverified0
Sum1

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation action provider New action provider typescript labels Apr 13, 2025
@Pranav2456Pranav2456 changed the title feat: Aerodome Action Providerfeat: Aerodrome Action ProviderApr 14, 2025
@Pranav2456
Pranav2456 marked this pull request as draft April 15, 2025 13:37
@phdargen

Copy link
Copy Markdown
Contributor

Hey @Pranav2456, would be great to get an aerodrome action provider in!

This is still marked as draft, are you still working on this or is it ready for review?
Let me know if I can help with something or provide some feedback

@Pranav2456

Copy link
Copy Markdown
Author

Hey @phdargen

Hope you are doing well! I had to stop working on this due to some issues, but I definitely want to continue working on it and would greatly appreciate your feedback, initial review, or expectations. Since Aerodrome is quite a vast protocol, it would be difficult to complete all the features quickly, so it would be great if you could provide some direction.

@phdargen

Copy link
Copy Markdown
Contributor

Ok great @Pranav2456, thanks for your reply!

Aerodrome is indeed a quite complex protocol, by no means your PR needs to be feature complete.
It would be perfectly fine to only concentrate on the governance/vote actions at first.

Especially the LP action might be fairly difficult to implement and could be done in a follow-up PR (by you or someone else).

I would put less priority on the swap related actions as we have CDP API and 0x actions that aggregate various trade routes. Your swap action looks good though, if its not too much trouble would be nice to add.

Concerning the governance/vote actions it would be great to have the full flow with increase lock, withdraw, claim but again its up to you how much you are willing to contribute.

I will provide some initial comments below

Hey @phdargen

Hope you are doing well! I had to stop working on this due to some issues, but I definitely want to continue working on it and would greatly appreciate your feedback, initial review, or expectations. Since Aerodrome is quite a vast protocol, it would be difficult to complete all the features quickly, so it would be great if you could provide some direction.

@phdargen

Copy link
Copy Markdown
Contributor

Note that we require signed commits. See here for instructions on setting up commit signing. Once setup, rebase against main to re-sign all commits

@phdargen

Copy link
Copy Markdown
Contributor

Please add entry in agentkit/README (https://github.com/coinbase/agentkit/blob/main/typescript/agentkit/README.md), should follow alphabetic order

@phdargen

phdargen commented Sep 16, 2025

Copy link
Copy Markdown
Contributor

When you think it is ready to be merged, please remove all console.logs in your code and mark the PR from 'draft' to 'ready for review'

Also add the result of some manual testing including prompts and responses to the PR description above

return `Error: Lock duration (${lockDurationSeconds}s) cannot exceed 4 years (${MAX_LOCK_DURATION}s)`;
}

const { decimals, symbol } = await getTokenInfo(wallet, AERO_ADDRESS as Hex);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you may reuse the getTokenDetails function from erc20 action/utils here to fetch this info + balances more efficiently with a multicall

},
] as const satisfies Abi;

export const ERC20_ABI = [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import from view instead

import {erc20Abi } from "viem";

"created veAERO lock",
`Locked ${args.aeroAmount} ${symbol} for ${durationText}.`,
txHash,
receipt,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can the veAERO tokenId be retrieved from the tx logs? This might be useful for follow-up actions like vote

Comment on lines +255 to +257
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn (e.g., '1.5'), amountOutMin (atomic units/wei), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

amountOutMin should also be in whole units, not in atomic units.

Problem here is that the user needs to know the fair price and then compute a sensible amountOutMin for this action. Better would be to replace amountOutMin arg with a slippage arg (default to 1%) which then internally computes the amountOutMin

Suggested change
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn (e.g., '1.5'), amountOutMin (atomic units/wei), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn in whole units (e.g., '1.5'), amountOutMin in whole units (e.g., '2.1'), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,

Comment on lines +63 to +65
deadline: positiveIntegerStringSchema.describe(
"Unix timestamp deadline (seconds since epoch) for the transaction to succeed. Must be in the future.",
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be good to set a reasonable default for the deadline, like 10mins for example

@Pranav2456
Pranav2456force-pushed the feat/aerodome-action-provider branch 5 times, most recently from 25718ab to c623b56CompareNovember 10, 2025 06:38
@Pranav2456
Pranav2456force-pushed the feat/aerodome-action-provider branch from c623b56 to c2ea1fbCompareNovember 24, 2025 05:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action providerNew action providerdocumentationImprovements or additions to documentationtypescript

Development

Successfully merging this pull request may close these issues.

4 participants

@Pranav2456@cb-heimdall@phdargen@Tanker187
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: Aerodrome Action Provider - #672

Draft
Pranav2456 wants to merge 3 commits into
coinbase:mainfrom
Pranav2456:feat/aerodome-action-provider
Draft

feat: Aerodrome Action Provider#672
Pranav2456 wants to merge 3 commits into
coinbase:mainfrom
Pranav2456:feat/aerodome-action-provider

Conversation

@Pranav2456

@Pranav2456Pranav2456 commented Apr 13, 2025

Copy link
Copy Markdown

Aerodrome Action Provider for AgentKit

Overview

The Aerodrome Action Provider integrates Aerodrome Finance with AgentKit, enabling AI agents to interact with this Base-native DEX. Currently supports Base Mainnet for veAERO management, governance voting, and token swaps.

File Structure

agentkit/src/action-providers/aerodrome/
├── aerodromeActionProvider.ts # Main provider implementation
├── aerodromeActionProvider.test.ts # Test suite
├── constants.ts # Contract addresses & ABIs
├── schemas.ts # Zod validation schemas
├── utils.ts # Helper functions
└── index.ts # Public exports

Core Features

Create Lock Action

@CreateAction({name: "createLock",description: "Create a new veAERO lock by depositing AERO tokens",schema: CreateLockSchema,})

Creates veAERO governance NFTs by locking AERO tokens
Handles token approvals automatically
Enforces lock duration constraints (1 week to 4 years)
Verifies token balances before locking

Vote Action

@CreateAction({name: "vote",description: "Cast votes with veAERO NFT for liquidity pool emissions",schema: VoteSchema,})

Casts votes for gauge emissions using veAERO NFTs
Validates pool gauge existence
Enforces epoch-based voting rules
Provides detailed vote allocation feedback

Swap Action

@CreateAction({name: "swapExactTokensForTokens",description: "Swap tokens via Aerodrome pools",schema: SwapExactTokensSchema,})

Swaps exact input tokens for minimum output tokens
Supports both stable and volatile pools
Provides price quotes and slippage warnings
Handles approvals and deadline validation

Technical Details

Dependencies: viem for blockchain interactions, zod for schema validation
Error Handling: Comprehensive checks for balances, approvals, deadlines, and contract-specific errors
Helper Functions: Modular utility functions for token info, transaction formatting, and epoch calculations

Testing

Comprehensive Jest test suite with mocked wallet provider
Tests for success and error paths for all actions
Coverage for specific contract errors (NotApprovedOrOwner, INSUFFICIENT_OUTPUT_AMOUNT, etc.)
Network validation testing

Current Limitations

Base Mainnet support only
Direct swap routes only (no multi-hop routing)
Limited to core veAERO and trading operations

Future Enhancements

Additional veAERO management (increase amount/duration, withdraw)
Rewards claiming (fees, bribes)
Liquidity provision and staking
Multi-hop swap routing

@cb-heimdall

cb-heimdall commented Apr 13, 2025

Copy link
Copy Markdown

🟡 Heimdall Review Status

RequirementStatusMore Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot0
1 if user is external0
2 if repo is sensitive0
From .codeflow.yml1
Additional review requirements
Show calculation
Max0
0
From CODEOWNERS0
Global minimum0
Max 1
1
1 if commit is unverified0
Sum1

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation action provider New action provider typescript labels Apr 13, 2025
@Pranav2456Pranav2456 changed the title feat: Aerodome Action Providerfeat: Aerodrome Action ProviderApr 14, 2025
@Pranav2456
Pranav2456 marked this pull request as draft April 15, 2025 13:37
@phdargen

Copy link
Copy Markdown
Contributor

Hey @Pranav2456, would be great to get an aerodrome action provider in!

This is still marked as draft, are you still working on this or is it ready for review?
Let me know if I can help with something or provide some feedback

@Pranav2456

Copy link
Copy Markdown
Author

Hey @phdargen

Hope you are doing well! I had to stop working on this due to some issues, but I definitely want to continue working on it and would greatly appreciate your feedback, initial review, or expectations. Since Aerodrome is quite a vast protocol, it would be difficult to complete all the features quickly, so it would be great if you could provide some direction.

@phdargen

Copy link
Copy Markdown
Contributor

Ok great @Pranav2456, thanks for your reply!

Aerodrome is indeed a quite complex protocol, by no means your PR needs to be feature complete.
It would be perfectly fine to only concentrate on the governance/vote actions at first.

Especially the LP action might be fairly difficult to implement and could be done in a follow-up PR (by you or someone else).

I would put less priority on the swap related actions as we have CDP API and 0x actions that aggregate various trade routes. Your swap action looks good though, if its not too much trouble would be nice to add.

Concerning the governance/vote actions it would be great to have the full flow with increase lock, withdraw, claim but again its up to you how much you are willing to contribute.

I will provide some initial comments below

Hey @phdargen

Hope you are doing well! I had to stop working on this due to some issues, but I definitely want to continue working on it and would greatly appreciate your feedback, initial review, or expectations. Since Aerodrome is quite a vast protocol, it would be difficult to complete all the features quickly, so it would be great if you could provide some direction.

@phdargen

Copy link
Copy Markdown
Contributor

Note that we require signed commits. See here for instructions on setting up commit signing. Once setup, rebase against main to re-sign all commits

@phdargen

Copy link
Copy Markdown
Contributor

Please add entry in agentkit/README (https://github.com/coinbase/agentkit/blob/main/typescript/agentkit/README.md), should follow alphabetic order

@phdargen

phdargen commented Sep 16, 2025

Copy link
Copy Markdown
Contributor

When you think it is ready to be merged, please remove all console.logs in your code and mark the PR from 'draft' to 'ready for review'

Also add the result of some manual testing including prompts and responses to the PR description above

return `Error: Lock duration (${lockDurationSeconds}s) cannot exceed 4 years (${MAX_LOCK_DURATION}s)`;
}

const { decimals, symbol } = await getTokenInfo(wallet, AERO_ADDRESS as Hex);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you may reuse the getTokenDetails function from erc20 action/utils here to fetch this info + balances more efficiently with a multicall

},
] as const satisfies Abi;

export const ERC20_ABI = [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import from view instead

import {erc20Abi } from "viem";

"created veAERO lock",
`Locked ${args.aeroAmount} ${symbol} for ${durationText}.`,
txHash,
receipt,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can the veAERO tokenId be retrieved from the tx logs? This might be useful for follow-up actions like vote

Comment on lines +255 to +257
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn (e.g., '1.5'), amountOutMin (atomic units/wei), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

amountOutMin should also be in whole units, not in atomic units.

Problem here is that the user needs to know the fair price and then compute a sensible amountOutMin for this action. Better would be to replace amountOutMin arg with a slippage arg (default to 1%) which then internally computes the amountOutMin

Suggested change
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn (e.g., '1.5'), amountOutMin (atomic units/wei), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,
name: "swapExactTokensForTokens",
description: `Swap an exact amount of an input token for a minimum amount of an output token on Aerodrome (Base Mainnet). Requires: tokenInAddress, tokenOutAddress, amountIn in whole units (e.g., '1.5'), amountOutMin in whole units (e.g., '2.1'), to (recipient address), deadline (Unix timestamp), and optionally useStablePool (boolean, default false for volatile). Note: Assumes a direct route exists.`,
schema: SwapExactTokensSchema,

Comment on lines +63 to +65
deadline: positiveIntegerStringSchema.describe(
"Unix timestamp deadline (seconds since epoch) for the transaction to succeed. Must be in the future.",
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be good to set a reasonable default for the deadline, like 10mins for example

@Pranav2456
Pranav2456force-pushed the feat/aerodome-action-provider branch 5 times, most recently from 25718ab to c623b56CompareNovember 10, 2025 06:38
@Pranav2456
Pranav2456force-pushed the feat/aerodome-action-provider branch from c623b56 to c2ea1fbCompareNovember 24, 2025 05:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action providerNew action providerdocumentationImprovements or additions to documentationtypescript

Development

Successfully merging this pull request may close these issues.

4 participants

@Pranav2456@cb-heimdall@phdargen@Tanker187