Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add safe wallet provider (ts) #330

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

phdargen
Copy link
Contributor

@phdargen phdargen commented Feb 10, 2025

Why? What?

Every AI Agent deserves a Safe wallet!

Adds new safeActionProvider to handle interactions with Safe multi-signature wallets.
This implementation uses the Safe sdk that is added as new dependency.

What changed?

  • New Wallet Provider: safeWalletProvider

    • connects to an existing safe account
    • or automatically creates a new one with the provided private key as single signer
    • getBalance() returns balance of safe wallet, not private-key of agent
    • nativeTransfer() transfers eth from Safe wallet, may require approval of other signers
  • New Action Provider: safeWalletActionProvider with actions:

    • addSigner: Add a new signer to a Safe wallet
    • removeSigner: Remove an existing signer from a Safe wallet
    • changeThreshold: Modify the number of required signatures
    • approvePending: Approve a pending transaction
    • enableAllowanceModule: Activate the allowance module for a Safe
    • setAllowance: Configure spending allowances for specific addresses
  • New Action Provider: safeApiActionProvider with actions:

    • safeInfo: Retrieve detailed information about a Safe wallet
    • getAllowanceInfo: Get current allowance configurations
    • withdrawAllowance: Withdraw funds from an allowance
  • Adds new getPublicClient() method to EvmWalletProvider, so the publicClient can be passed to safeApiActionProvider

  • Adds new signHash() method to EvmWalletProvider that is needed for withdrawAllowance action

  • Adds new langchain-safe-chatbot example

  • Adds safeApiActionProvider to langchain-cdp-chatbot example

Network support

  • All evm chains

How has it been tested?

  • Unit tests
  • Agent tested, example prompts below (using gpt-4o-mini)

Running langchain-safe-chatbot without setting SAFE_ADDRESS:

Prompt: wallet info
-------------

Your wallet details are as follows:

- **Address:** 0xC099a0dE7533f9F0A20979616376c353F330ed44
- **Network:** 
  - **Protocol Family:** EVM
  - **Network ID:** ethereum-sepolia
  - **Chain ID:** 11155111
- **Native Balance:** 0 WEI

Prompt: safe info
-------------

Here is the information about your Safe:

- **Safe Address:** 0xC099a0dE7533f9F0A20979616376c353F330ed44
- **Chain:** Sepolia
- **Owners:** 1 owner - 0xCe8C96bBF12aa630f439a74A75f86E96c9F50B3B
- **Threshold:** 1
- **Nonce:** 0
- **Modules:** None
- **Balance:** 0 ETH
- **Pending Transactions:** 0
Prompt: enable allowance module
-------------------

The allowance module has been successfully enabled for your Safe wallet at address **0xC099a0dE7533f9F0A20979616376c353F330ed44**. 

- **Transaction Hash**: 0x3eb5159d9a84324a199614a23ba0abfb1f10d56ac35865b988fd99a7c13fc0a6
Prompt: add 0xb7f17bF94DBa50077be037CDc279a868f82D86C2 as signer with threshold 2
-------------------

The signer **0xb7f17bF94DBa50077be037CDc279a868f82D86C2** has been successfully added to your Safe wallet.  

- **New Threshold**: 2
- **Transaction Hash**: 0x3f1a4de3647c0ee9d7b6e271f8dde7b096ee84437a21e6dabae7531bbce695e0

Prompt: I sent some eth to the safe, withdraw it all to 0xb7f17bF94DBa50077be037CDc279a868f82D86C2
-------------------

The withdrawal transaction has been proposed to transfer **0.00001 ETH** to **0xb7f17bF94DBa50077be037CDc279a868f82D86C2**.

- **Transaction Hash**: 0xdf0fd67b648f7bac6b1684436dd44f812de8963f66f77423bd654cb2d2b78f83

As the threshold is 2, other owners will need to confirm this transaction before it can be executed.
Prompt: safe info
-------------------

Here is the updated information for your Safe multi-sig wallet:

- **Safe Address**: 0xC099a0dE7533f9F0A20979616376c353F330ed44
- **Chain**: Sepolia
- **Owners**: 2 owners 
  - 1. 0xb7f17bF94DBa50077be037CDc279a868f82D86C2
  - 2. 0xCe8C96bBF12aa630f439a74A75f86E96c9F50B3B
- **Threshold**: 2 (requires two signatures for execution)
- **Nonce**: 2
- **Modules**: 0xCFbFaC74C26F8647cBDb8c5caf80BB5b32E43134
- **Balance**: 0.00001 ETH
- **Pending Transactions**: 1
  - **Transaction** 0xdf0fd67b648f7bac6b1684436dd44f812de8963f66f77423bd654cb2d2b78f83 (1/2 confirmations, confirmed by: 0xCe8C96bBF12aa630f439a74A75f86E96c9F50B3B)

Prompt: I approved the tx and proposed a new one to change threshold to 1 with safe tx hash: 0xdbc8583147403145e9ea04f5725b3d998f945abe32ce6de5dc8b80cba0841c86. approve and execute it
-------------------

I successfully approved and executed the transaction:

- **Safe Transaction Hash**: 0xdbc8583147403145e9ea04f5725b3d998f945abe32ce6de5dc8b80cba0841c86
- **Execution Transaction Hash**: 0x4c6b40aceeb670f5e3230a34cc30da6fa26681a4f3446b55e3f5d5858226caed

The threshold has now been changed to 1.
Prompt: add 1 weth (0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9) allowance for 0xCe8C96bBF12aa630f439a74A75f86E96c9F50B3B
-------------------
The allowance of **1 WETH** (contract address: **0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9**) has been successfully set for the delegate **0xCe8C96bBF12aa630f439a74A75f86E96c9F50B3B** (one-time allowance).

- **Transaction Hash**: 0xd282d081f9cb2a437502eda1963818b0d45f1a5589b5ee0cacb734a5f436b1ff 

Running langchain-cdp-chatbot (could be different agent with other private-key, doesn't need to be owner of safe):

Prompt: wallet info
-------------------
Your wallet details are as follows:

- **Provider:** cdp_wallet_provider
- **Address:** 0xCe8C96bBF12aa630f439a74A75f86E96c9F50B3B
- **Network:**
  - **Protocol Family:** EVM
  - **Network ID:** ethereum-sepolia
  - **Chain ID:** 11155111
- **Native Balance:** 0.24262 ETH
Prompt: get info for safe 0xC099a0dE7533f9F0A20979616376c353F330ed44
-------------------
Here's the information for the Safe at address **0xC099a0dE7533f9F0A20979616376c353F330ed44**:

- **Chain:** Sepolia
- **Owners:** 
  - 0xb7f17bF94DBa50077be037CDc279a868f82D86C2
  - 0xCe8C96bBF12aa630f439a74A75f86E96c9F50B3B
- **Threshold:** 1
- **Nonce:** 5
- **Modules:** 0xCFbFaC74C26F8647cBDb8c5caf80BB5b32E43134
- **Balance:** 0 ETH
- **Pending Transactions:** 0
Prompt: get allowance info for this safe and delegate 0xCe8C96bBF12aa630f439a74A75f86E96c9F50B3B
-------------------
Here is the allowance information for the delegate **0xCe8C96bBF12aa630f439a74A75f86E96c9F50B3B** from the Safe at address **0xC099a0dE7533f9F0A20979616376c353F330ed44**:

- **Token:** WETH (0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9)
  - **Current Safe Balance:** 0.00001 WETH
  - **Allowance:** 1 available of 1 total (0 spent)

Prompt: withdraw full safe balance from allowance
-------------------
The full Safe balance of **0.00001 WETH** has been successfully withdrawn from the Safe **0xC099a0dE7533f9F0A20979616376c353F330ed44** to the delegate **0xCe8C96bBF12aa630f439a74A75f86E96c9F50B3B**.

- **Transaction Hash:** [0xf039503ffb1d213fb373f62cbb7867d99bd71127c8cab6a3e7cc9f2dc53d99c9](https://sepolia.etherscan.io/tx/0xf039503ffb1d213fb373f62cbb7867d99bd71127c8cab6a3e7cc9f2dc53d99c9)

@cb-heimdall
Copy link

cb-heimdall commented Feb 10, 2025

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/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

@phdargen phdargen marked this pull request as draft February 10, 2025 06:28
@John-peterson-coinbase
Copy link
Contributor

@phdargen Thanks for the contribution!

A few initial comments:

  • The Safe smart account wallet likely should be a WalletProvider implementation so that you can easily use any of the existing actions with this new wallet type
  • If you would like actions on top of the wallet provider, you can add a SafeWalletActionProvider implementation similar to how CdpWalletActionProvider allows for CdpWalletProvider specific actions

Let me know if you have any questions or comments

@0xRAG 0xRAG added action provider New action provider changes requested PR / Issue has changes requested banana typescript labels Feb 10, 2025
@phdargen
Copy link
Contributor Author

Thanks for the feedback @John-peterson-coinbase. That’s a good suggestion, I will look into it in the coming days. Only problem I see is that one couldn’t use cdp and safe actions at the same time but I guess thats not too bad in this case.

Before getting started, it would be good to clarify some design choices.
Lets say there is a safewalletprovider that is initialised with the private key of the agent and then creates a new safe account with the agent as signer (or connects to exciting safe). Then should the getAddress(), getBalance(), … return the address/balance of the safe rather than the agent wallet? Similar all tx should be done with the safe account, not the agent wallet, whose sole purpose would be to act as signer.

@phdargen
Copy link
Contributor Author

Hi @John-peterson-coinbase, I got a minimal example working for the new setup:

  • safeWalletProvider connects to an existing safe account or automatically creates a new one with the provided private key as single signer.

  • Get_wallet_info returns the address and balance of the safe, native_transfer sends eth from the safe (or propose tx).

  • Additional signers can be added with a safeWalletActionProvider.

  • safeApiActionProvider implements read-only actions such as the info of a safe account. The safeApiActionProvider actions can also be used with other EvmWalletProviders.

  • Added new langchain-safe-chatbot example

Please let me know if you agree with this implementation, then I'll go ahead and add the remaining actions and clean up by removing the old safeActionProvider

@phdargen
Copy link
Contributor Author

BTW, I submitted a related project at the safe agentathon (https://devfolio.co/projects/safegpt-d4c5) with a live demo here: https://safe-gpt.vercel.app/

@github-actions github-actions bot added documentation Improvements or additions to documentation wallet provider New wallet provider example New example agent needs triage labels Feb 24, 2025
@phdargen phdargen force-pushed the safe-ts branch 4 times, most recently from 82504f2 to c009f79 Compare February 26, 2025 17:38
@0xRAG 0xRAG removed the needs triage label Mar 3, 2025
@phdargen
Copy link
Contributor Author

phdargen commented Mar 4, 2025

This is in principle ready for review, however the actions in safeApiActionProvider rely on the safe api that is currently still down, see safe-global/safe-core-sdk#1155.

@phdargen
Copy link
Contributor Author

phdargen commented Mar 8, 2025

This is in principle ready for review, however the actions in safeApiActionProvider rely on the safe api that is currently still down, see safe-global/safe-core-sdk#1155.

The safe api is back and this is ready for review.
Changed the initial commit description to reflect changes.

error => {
throw new Error("Error initializing Safe wallet: " + error);
},
);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@John-peterson-coinbase @0xRAG @CarsonRoscoe any clue why the test-agentkit-typescript (20) units tests are failing? There seems to be a network timeout probably related to the fact that I do not call trackInitialization() immediately but wait until the Safe wallet is created (that requires an onchain tx). Running the test locally is successful and test-agentkit-typescript (18) seems to be fine too

@phdargen phdargen marked this pull request as ready for review March 8, 2025 12:44
@phdargen phdargen requested a review from murrlincoln as a code owner March 8, 2025 12:44
@phdargen phdargen changed the title feat: add safe smart account action (ts) feat: add safe wallet provider (ts) Mar 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
action provider New action provider banana changes requested PR / Issue has changes requested 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.

4 participants