Skip to content

Conversation

@phdargen
Copy link
Contributor

@phdargen phdargen commented Aug 8, 2025

Description

Fixes various issues with the swap API implementation in CdpApiActionProvider

  • bumps cdp-sdk version
  • throws error for unsupported networks
  • changes unsupported assetId to tokenContract for input arguments
  • adds slippage config
  • changes fromAmount to human readable format
  • handles permit2 approval if needed
  • adds get swap quote action to check price before executing
  • checks if swap failed
  • retrieves correct account for cdpSmartWallet
  • throws error when owner account is not a CDP server wallet

Other changes:

Tests

Chatbot: typescript/examples/langchain-cdp-chatbot/chatbot.ts
Network: Base mainnet

Prompt: price quote for 1 eth to usdc (0x833589fcd6edb6e08f4c7c32d4f71b54bda02913)

-------------------
{"success":true,"fromAmount":"1","fromTokenName":"ETH","fromToken":"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee","toAmount":"3815.31087","minToAmount":"3777.11957","toTokenName":"USD Coin","toToken":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","slippageBps":100,"liquidityAvailable":true,"balanceEnough":false,"allowanceEnough":true,"priceOfBuyTokenInSellToken":"0.0002621018402099434","priceOfSellTokenInBuyToken":"3815.31087"}
-------------------
The price quote for swapping 1 ETH to USDC (0x833589fcd6edb6e08f4c7c32d4f71b54bda02913) is approximately **3815.31 USDC**. 

- Minimum amount you can receive: **3777.12 USDC**
- Price of 1 ETH in USDC: **3815.31 USDC**
- Price of 1 USDC in ETH: **0.0002621 ETH**
-------------------

Prompt: swap 0.00001 eth to  USDC (0x833589fcd6edb6e08f4c7c32d4f71b54bda02913) 

-------------------
{"success":true,"transactionHash":{"transactionHash":"0x96264f7ab5eac524ab658b61e78d31187cbce3e3442263cdef18d592b8130116"},"fromAmount":"0.00001","fromTokenName":"ETH","fromToken":"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee","toAmount":"0.038313","minToAmount":"0.037929","toTokenName":"USD Coin","toToken":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","slippageBps":100,"network":"base-mainnet"}
-------------------
The swap of **0.00001 ETH** to USDC (0x833589fcd6edb6e08f4c7c32d4f71b54bda02913) was successful!

- Amount received: **0.038313 USDC**
- Minimum amount you can receive: **0.037929 USDC**
- Transaction Hash: **[0x96264f7ab5eac524ab658b61e78d31187cbce3e3442263cdef18d592b8130116](https://explorer.base.org/tx/0x96264f7ab5eac524ab658b61e78d31187cbce3e3442263cdef18d592b8130116)**
-------------------

Prompt: swap 0.01 usdc to cbBTC 0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf 

-------------------
{"success":true,"approvalTxHash":"0x28cbe8be28a3d192ede5a870a4778363a5302e55aa60f0ac38eeeb4c09b7e89e","transactionHash":{"transactionHash":"0xccb181ce15d17d108e08be721d7c13bbcb35a959fd8508831c8fa779f3a9ac4a"},"fromAmount":"0.01","fromTokenName":"USD Coin","fromToken":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","toAmount":"0.00000009","minToAmount":"0.00000009","toTokenName":"Coinbase Wrapped BTC","toToken":"0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf","slippageBps":100,"network":"base-mainnet"}
-------------------
The swap of **0.01 USDC** to Coinbase Wrapped BTC (0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf) was successful!

- Amount received: **0.00000009 CBTC**
- Minimum amount you can receive: **0.00000009 CBTC**
- Transaction Hash: **[0xccb181ce15d17d108e08be721d7c13bbcb35a959fd8508831c8fa779f3a9ac4a](https://explorer.base.org/tx/0xccb181ce15d17d108e08be721d7c13bbcb35a959fd8508831c8fa779f3a9ac4a)**

Chatbot: typescript/examples/langchain-smart-wallet-chatbot/chatbot.ts
Network: Base mainnet
Setup: Funded with erc20 token, no ETH, paymaster enabled

Prompt: swap 1 token 0xD769d56f479E9E72a77bB1523e866A33098Feec5 to  usdc (0x833589fcd6edb6e08f4c7c32d4f71b54bda02913) 

-------------------
{"success":true,"approvalTxHash":"0x37a0fd65e87bbbdd88d7e7742b0f2fd51f7c8c73e6c1ff87e833fa4689a6000b","transactionHash":"0x694eb62df1f62f97b47d3d7f4397d9be9d50e7714c4afed49f9a51776cb479b1","fromAmount":"1","fromTokenName":"Base is for everyone","fromToken":"0xD769d56f479E9E72a77bB1523e866A33098Feec5","toAmount":"0.003855","minToAmount":"0.003816","toTokenName":"USD Coin","toToken":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","slippageBps":100,"network":"base-mainnet"}
-------------------
The swap has been successfully executed!

- **Swapped**: 1 Base is for everyone
- **Received**: Approximately 0.00386 USDC
- **Transaction Hash**: [0x694eb62df1f62f97b47d3d7f4397d9be9d50e7714c4afed49f9a51776cb479b1](https://etherscan.io/tx/0x694eb62df1f62f97b47d3d7f4397d9be9d50e7714c4afed49f9a51776cb479b1)

Checklist

A couple of things to include in your PR for completeness:

  • Added documentation to all relevant README.md files
  • Added a changelog entry

@phdargen phdargen requested a review from murrlincoln as a code owner August 8, 2025 14:42
@cb-heimdall
Copy link

cb-heimdall commented Aug 8, 2025

✅ Heimdall Review Status

Requirement Status More Info
Reviews 1/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1

@phdargen phdargen marked this pull request as draft August 8, 2025 14:42
@github-actions github-actions bot added documentation Improvements or additions to documentation action provider New action provider wallet provider New wallet provider typescript labels Aug 8, 2025
@github-actions github-actions bot removed the wallet provider New wallet provider label Aug 12, 2025
@phdargen
Copy link
Contributor Author

phdargen commented Aug 12, 2025

Hi @0xRAG, I rebased to account for your changes in #818.

I still can't get the swap API to work with smart accounts, it throws this error APIError: EVM account with given address not found.

Also tried to use createSwapQuote + sign permit2 + sendTransaction instead of the all-in-one pattern.
Same issue but could narrow it down to happen in the sign permit2 step:

const signature = await walletProvider.smartAccount.signTypedData({ network: cdpNetwork as any, domain: swapQuote.permit2.eip712.domain, types: swapQuote.permit2.eip712.types, primaryType: swapQuote.permit2.eip712.primaryType, message: swapQuote.permit2.eip712.message, })

Any ideas how solve this?

@0xRAG
Copy link
Contributor

0xRAG commented Aug 15, 2025

Hey @phdargen, I think this may happen when the smart wallet owner is not a CDP wallet, since walletProvider.smartAccount.signTypedData ends up calling the CDP API with the owner address.

Could you confirm by trying again with a new smart wallet whose owner is a CDP server wallet?

We may need to add a disclaimer that swap only works with smart accounts owned by a CDP wallet.

@github-actions github-actions bot added wallet provider New wallet provider example New example agent labels Aug 19, 2025
@phdargen phdargen force-pushed the swap-api-ts branch 3 times, most recently from 3dca4bb to f7332e9 Compare August 19, 2025 23:07
@phdargen phdargen marked this pull request as ready for review August 19, 2025 23:16
@phdargen
Copy link
Contributor Author

Hey @phdargen, I think this may happen when the smart wallet owner is not a CDP wallet, since walletProvider.smartAccount.signTypedData ends up calling the CDP API with the owner address.

Could you confirm by trying again with a new smart wallet whose owner is a CDP server wallet?

We may need to add a disclaimer that swap only works with smart accounts owned by a CDP wallet.

Hi @0xRAG, thanks that was indeed the problem!

I thus changed the chatbot and next template to create a CDP server wallet as owner by default and the swap action throws a descriptive error when its called with a LocalAccount as owner

? walletProvider.smartAccount
: await walletProvider.getClient().evm.getAccount({
address: walletProvider.getAddress() as Hex,
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Given we are getting and later using the account / smart account via .swap, I think this action is better suited to live in the cdpEvmWalletActionProvider / cdpSmartWalletActionProvider. The get_swap_price action is provider-agnostic so that one is fine to remain, although may be worth moving along with swap just to reduce potential confusion on why the actions are on different providers. LMK your thoughts, also cc @CarsonRoscoe

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah good point, this would avoid the messy conditional logic and type casts. Will refactor

Choose a reason for hiding this comment

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

Based on the codebase today, I am in agreement.

However, this is making me think about a refactor. There seems to be an association between wallet providers & action providers, and I think that's causing some confusion here.

Imagine a world where wallet provider files exported their own action providers, or used the CreateAction() decorator on their own functions, allowing them to declare tools that we can auto-register when a wallet provider is used. This would create a clear separation of concerns between what actions are needed for a specific wallet, and what actions are coming from a shared API like the CDP API. It also would reduce a friction point in the devx, which is knowing that, for example, using the CdpEvmWalletProvider means importing both WalletActionProvider and CdpEvmWalletActionProvider. It then allows CdpApiActionProvider to remain pure and focus only on features that any wallet using CDP can leverage such as get_swap_price and faucet.

@CarsonRoscoe CarsonRoscoe merged commit 406f994 into coinbase:main Aug 21, 2025
26 checks passed
@phdargen phdargen mentioned this pull request Sep 5, 2025
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action provider New action provider documentation Improvements or additions to documentation example New example agent typescript wallet provider New wallet provider

Development

Successfully merging this pull request may close these issues.

5 participants