Skip to content

feat: add across action provider (ts) - #566

Merged
CarsonRoscoe merged 6 commits into
coinbase:mainfrom
phdargen:across-ts
Mar 25, 2025
Merged

feat: add across action provider (ts)#566
CarsonRoscoe merged 6 commits into
coinbase:mainfrom
phdargen:across-ts

Conversation

@phdargen

@phdargen phdargen commented Mar 14, 2025

Copy link
Copy Markdown
Contributor

Description

Adds new action provider to perform cross-chain interactions via the Across protocol.
Across SDK is added as new dependency.

Implements:

  • bridge_token action to bridge from connected chain to another evm chain
    -> supports native ETH and ERC-20 transfers (as long as supported by Across)
  • check_deposit_status action to check fill status on destination chain (mainnets only)

Tests

  • Added unit tests
  • Tested prompts
Chatbot: typescript/examples/langchain-cdp-chatbot/chatbot.ts
Network: Sepolia
Setup: Fauceted with 1 USDC and ETH

Prompt: bridge to chain 84532, amount 0.001 ETH, receipienct 0xb7f17bF94DBa50077be037CDc279a868f82D86C2

-------------------
Successfully deposited tokens:
- From: Chain 11155111 (Sepolia)
- To: Chain 84532 (Base Sepolia)
- Token: ETH (0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14)
- Input Amount: 0.001 ETH
- Output Amount: 0.000990746891309023 ETH
- Recipient: 0xb7f17bF94DBa50077be037CDc279a868f82D86C2
- Transaction Hash for deposit: 0x0f2c064c36991d9af1f0d81d347d5e16f61b6ea1302f430c1a57b07bec743cea
- Deposit ID: 1002457
-------------------

Prompt: bridge to chain 84532, amount 0.1 usdc, receipienct 0xb7f17bF94DBa50077be037CDc279a868f82D86C2, max slippage 3%
The bridging transaction was successful! Here are the details:

- **From Chain:** 11155111 (Sepolia)
- **To Chain:** 84532 (Base Sepolia)
- **Token:** USDC
- **Input Amount:** 0.1 USDC
- **Output Amount:** 0.098182 USDC
- **Recipient:** 0xb7f17bF94DBa50077be037CDc279a868f82D86C2
- **Transaction Hash for Approval:** 0x33575547e8031d3223e63dbc2e82fbc307b1391bd9c6379c8a91952b47024e92
- **Transaction Hash for Deposit:** 0x797f7d27e820f1832f994b6a6218118803fbc500f18caa70179811b4be21b2aa

Prompt: check status of deposit 1349975 with originChainId 137
-------------------
{
  "status": "filled",
  "depositTxInfo": {
    "txHash": "0x784f3cf234ffc960d087c5c02b166d838f7a170b337a349a49b54be837fd8152",
    "chainId": 137,
    "chainName": "Polygon"
  },
  "fillTxInfo": {
    "txHash": "0x788835d45d1ad5bc339990b23d2e09756ca1b4c98a6246be3505fb1baaf573e6",
    "chainId": 8453,
    "chainName": "Base"
  },
  "depositRefundTxInfo": null
}
-------------------
The status of the deposit with ID **1349975** and originChainId **137** is **filled**. Here are the transaction details:

- **Deposit Transaction Hash (Polygon)**: `0x784f3cf234ffc960d087c5c02b166d838f7a170b337a349a49b54be837fd8152`
  
- **Fill Transaction Hash (Base)**: `0x788835d45d1ad5bc339990b23d2e09756ca1b4c98a6246be3505fb1baaf573e6`

No refund transaction is related to this deposit.
-------------------

Checklist

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

@phdargen
phdargen requested a review from murrlincoln as a code owner March 14, 2025 14:59
@cb-heimdall

cb-heimdall commented Mar 14, 2025

Copy link
Copy Markdown

✅ 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
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

@github-actions github-actions Bot added documentation Improvements or additions to documentation action provider New action provider example New example agent typescript labels Mar 14, 2025

@KanishkKhurana KanishkKhurana left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

left one comment around manual txn simulation and executing the deposit txn.

overall, really good job from an Across Protocol integration POV

}

// Simulate the deposit transaction
const { request } = await acrossClient.simulateDepositTx({

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Diving deep into the logic behind this, are we simulating txn and executing the deposit fn manually because there's no way to trigger a wallet extension ?
I ask because we have the executeQuote function which will be able to wrap complexities around txn simulation and executing the deposit txn.

overall this is a stellar job. thank you for putting in the effort here!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hi @KanishkKhurana , thank you for the feedback!

I initially used executeQuote which would indeed simplify the process. This works fine until progress.step === "deposit" is succesful but then throws errors in the progress.step === "fill" step. I suspect this is because no RPC was available for the destination chain.

Now thinking about it again, it might work when we just add the destination chain to the viem client. It would certainly be nice to also return the fill txHash. A bit busy atm but will give it a try in the next days and get back to you

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

So executeQuote would work if provided with an additional publicClient for the destinationChain.

However, I think it is best to stick to the current manual tx implementation to avoid some edge cases where the fill transaction is delayed significantly. The agent would then be stuck and not return any response for an extended period of time.

In my last commit, I added the depositID to the 'bridge_token' tool output
and implemented a 'check_deposit_status' tool to check the status for a given depositID

Comment thread typescript/agentkit/src/action-providers/across/acrossActionProvider.ts Outdated
Comment thread typescript/agentkit/src/action-providers/across/acrossActionProvider.ts Outdated
Comment thread typescript/agentkit/src/action-providers/across/acrossActionProvider.ts Outdated

@CarsonRoscoe CarsonRoscoe left a comment

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.

Please add a entry into typescript/agentkit/README.md's ## Action Providers section, so this action is discoverable via readmes

Note: entries are in alphabetical order

Comment thread typescript/agentkit/src/action-providers/across/utils.ts Outdated
Comment thread typescript/examples/langchain-cdp-chatbot/chatbot.ts Outdated
@github-actions github-actions Bot removed the example New example agent label Mar 25, 2025
@phdargen

phdargen commented Mar 25, 2025

Copy link
Copy Markdown
Contributor Author

Please add a entry into typescript/agentkit/README.md's ## Action Providers section, so this action is discoverable via readmes

Note: entries are in alphabetical order

Added entry to README

@phdargen

Copy link
Copy Markdown
Contributor Author

Hi @CarsonRoscoe, thanks for the feedback, I implemented the changes.

I have one question about the wallets created by CdpWalletProvider and saved in wallet_data.txt when using the chatbot.ts example script. Is there an easy way to use this wallet on a different chain? It seems editing the networkId in wallet_data.txt and reimporting has no effect. You can export the private key of the cdpWallet but then importing only supports mnemonicPhrase.

If the chain cannot be easily switched, do we need a warning for wallets created with CdpWalletProvider or do not default the recipient address to sender?

@CarsonRoscoe CarsonRoscoe left a comment

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.

re: Wallet question

Yes, the current version of the CDP server wallet exports to 1 wallet per chain. The same API keys work on all the networks, however it will generate a different address/private key per network.

We understand the current wallet persistence approach is lacking. We're exploring other approaches, for example in the python side, if you run pipx run create-onchain-agent --beginnner to generate a chatbot, you can see here that we handle the wallets on a per-network basis now.

We will be refactoring all the examples shortly to use a similar approach in order to make sure that its a different wallet generated per network.

The temporary solution to the question regarding networks is to rename your file when you change networks. i.e. rename towallet_data_base_sepolia.txt when you switch networks and generate a new wallet, and then rename back when you go back. After the refactor, this process will happen automatically for you.

@phdargen

Copy link
Copy Markdown
Contributor Author

re: Wallet question

Yes, the current version of the CDP server wallet exports to 1 wallet per chain. The same API keys work on all the networks, however it will generate a different address/private key per network.

We understand the current wallet persistence approach is lacking. We're exploring other approaches, for example in the python side, if you run pipx run create-onchain-agent --beginnner to generate a chatbot, you can see here that we handle the wallets on a per-network basis now.

We will be refactoring all the examples shortly to use a similar approach in order to make sure that its a different wallet generated per network.

The temporary solution to the question regarding networks is to rename your file when you change networks. i.e. rename towallet_data_base_sepolia.txt when you switch networks and generate a new wallet, and then rename back when you go back. After the refactor, this process will happen automatically for you.

OK I see, thanks for the info. Imo it would be better to have the same address on all chains.

My concern in relation to this cross-chain action is that a user sends eg ETH from Base to Ethereum with destinationAdress = senderAdress. But then after switching to Ethereum a new wallet is created and the funds deposited at destinationAdress are not accessible (within AgentKit).

But even if that happens, I suppose its possible to export the private key and then import it in MM or another wallet, so the funds would at least not be lost.

@CarsonRoscoe

Copy link
Copy Markdown
Contributor

OK I see, thanks for the info. Imo it would be better to have the same address on all chains.

My concern in relation to this cross-chain action is that a user sends eg ETH from Base to Ethereum with destinationAdress = senderAdress. But then after switching to Ethereum a new wallet is created and the funds deposited at destinationAdress are not accessible (within AgentKit).

But even if that happens, I suppose its possible to export the private key and then import it in MM or another wallet, so the funds would at least not be lost.

Agreed. Fyi, multi-network wallet API support is coming soon, but in the meantime, you are right that funds are safe and can be accessed through exporting the private key. You can also swap out the CdpWalletProvider for a ViemWalletProvider in the meantime to ensure your account is the same on each network.

Comment thread typescript/.changeset/neat-emus-exist.md Outdated
@phdargen

Copy link
Copy Markdown
Contributor Author

OK I see, thanks for the info. Imo it would be better to have the same address on all chains.
My concern in relation to this cross-chain action is that a user sends eg ETH from Base to Ethereum with destinationAdress = senderAdress. But then after switching to Ethereum a new wallet is created and the funds deposited at destinationAdress are not accessible (within AgentKit).
But even if that happens, I suppose its possible to export the private key and then import it in MM or another wallet, so the funds would at least not be lost.

Agreed. Fyi, multi-network wallet API support is coming soon, but in the meantime, you are right that funds are safe and can be accessed through exporting the private key. You can also swap out the CdpWalletProvider for a ViemWalletProvider in the meantime to ensure your account is the same on each network.

Added warning about this and recommendation to use ViemWalletProvider to across readme

@CarsonRoscoe CarsonRoscoe left a comment

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.

LGTM!

Nicely done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action provider New action provider apple documentation Improvements or additions to documentation typescript

Development

Successfully merging this pull request may close these issues.

5 participants