feat: add zeroDevWalletProvider - #665

Merged
CarsonRoscoe merged 14 commits into
coinbase:mainfrom
zerodevapp:zerodev-wallet-provider
Apr 18, 2025
Merged

feat: add zeroDevWalletProvider#665
CarsonRoscoe merged 14 commits into
coinbase:mainfrom
zerodevapp:zerodev-wallet-provider

Conversation

@jstinhw

@jstinhwjstinhw commented Apr 9, 2025

Copy link
Copy Markdown
Contributor

Description

This PR introduces a new ZeroDevWalletProvider and ZeroDevWalletActionProvider, which wraps existing EvmWalletProvider instances (e.g., privyEvmWalletProvider, cdpWalletProvider) to enable account abstraction via ZeroDev’s infrastructure. The result is a fully chain-abstracted smart account that can be used seamlessly across different EVM-compatible networks.

In addition to introducing the ZeroDevWalletProvider, this PR updates the hashMessage import from @coinbase/coinbase-sdk to viem. Previously, @coinbase/coinbase-sdk re-exported the same function from ethers.js, but this change consolidates our hashing logic under viem directly.

Key points:

  • Introduces ZeroDevWalletProvider, leveraging an existing signer (e.g., privyEvmWalletProvider) to create a ZeroDev smart contract wallet.
  • Introduces ZeroDevWalletActionProvider, providing the action to get chain abstracted balance (getCAB) from the smart account.
  • Supports chain abstraction, meaning that the user can send funds to the agent on any "source chain," and the agent can spend the funds on any "destination chain," even when the two chains are different. For example, the user can fund the agent on Base, and the agent can make transactions on Arbitrum.
  • Updates hashMessage usage to reference viem directly instead of relying on the ethers.js function from @coinbase/coinbase-sdk.

Tests

Chatbot: typescript/examples/langchain-zerodev-chatbot/chatbot.ts
Network: Base Mainnet
Setup: Transferred 0.5 USDC to the smart account wallet on Optimism
Prompt: transfer 0.1 USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913) to 0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F
-------------------
Transferred 100000 of 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 to 0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F.
Transaction hash for the transfer: 0x023920d2baff0f36755e7ceeae89cc938cbe099659d9a93596f3ec93013a8f55
-------------------
The transfer of 100,000 USDC has been successfully completed to the address **0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F**. Here is the transaction hash for your reference: **0x023920d2baff0f36755e7ceeae89cc938cbe099659d9a93596f3ec93013a8f55**
-------------------

Checklist

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

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

@cb-heimdall

cb-heimdall commented Apr 9, 2025

Copy link
Copy Markdown

✅ Heimdall Review Status

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

@cb-heimdall

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
From .codeflow.yml1
Additional review requirements
Show calculation
Max0
0
From CODEOWNERS0
Global minimum0
Max 1
1
1 if commit is unverified1
Sum2

@jstinhwjstinhw changed the title Zerodev wallet providerfeat: add zeroDev wallet providerApr 9, 2025
@jstinhwjstinhw changed the title feat: add zeroDev wallet providerfeat: add zeroDevWalletProviderApr 9, 2025
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation wallet provider New wallet provider example New example agent typescript labels Apr 10, 2025
* @param config - The configuration options for the ZeroDevWalletProvider.
* @returns A Promise that resolves to a new ZeroDevWalletProvider instance.
*/
public static async configureWithSigner(

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.

nit: Our convention is to call this configureWithWallet, please update this to such

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@CarsonRoscoeCarsonRoscoe 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.

There is a table int he section ## Action Providers in the file /typescript/agentkit/README.md. Please add a new table entry for Zero Dev.

Note: Entries are in alphabetical order

});

// Create a Viem account from the EVM wallet provider
const address = config.signer.getAddress() as `0x${string}`;

@CarsonRoscoeCarsonRoscoeApr 14, 2025

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.

nit: Please replace all 0x${string} with either Address or Hex (whichever is more appropriate) from Viem

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

done

/**
* The network of the wallet.
*/
network: Network;

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.

Your taking the entire network object, which requires that the calling user have the domain knowledge to set everything up. We prefer to minimize the caller's knowledge requirement, and handle defaults.

Please update this param into two optional params, networkId?: string and chainId?: string

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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


this.#signer = config.signer;
this.#projectId = config.projectId;
this.#network = config.network;

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 assign a #network as such:

const networkId = config.networkId || "base-sepolia";
const chainId = config.chainId || NETWORK_ID_TO_CHAIN_ID[networkId];
this.#network = {
protocolFamily: "evm",
networkId: networkId,
chainId: chainId,
};

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

*/
async sendTransaction(transaction: TransactionRequest): Promise<`0x${string}`> {
// Get the chain ID from the network
const chainId = parseInt(this.#network.chainId || "1");

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.

nit: since we now do the network assignment in a way that guarantees chainId, replace the || "1" fallback with a !

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

*
* @returns The underlying signer.
*/
// getSigner(): EvmWalletProvider {

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.

nit: remove

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@CarsonRoscoeCarsonRoscoe 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.

Your solution to creating a signer out of a EvmWalletProvider is very elegant. I would like to promote this logic to EvmWalletProvider as a helper function toSigner() which returns a Viem signer.

Then, update your action provider to take a viem signer. Callers will be expected to toSigner() their provider before passing it in.

};
cdpWalletProvider = evmWalletProvider =
await CdpWalletProvider.configureWithWallet(cdpConfig);
console.log(`CDP Wallet Address: ${evmWalletProvider.getAddress()}`);

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.

nit: Remove the multiple Wallet Address prints and marge it into one after this if/else

console.log(Evm Wallet Address: ${evmWalletProvider.getAddress()});

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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


// Configure ZeroDev Wallet Provider with CDP Wallet as signer
const zeroDevConfig = {
signer: evmWalletProvider,

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.

nit: After the toSigner refactor, pass in signer: evmWalletProvider.toSigner()

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@jstinhw

Copy link
Copy Markdown
ContributorAuthor

There is a table int he section ## Action Providers in the file /typescript/agentkit/README.md. Please add a new table entry for Zero Dev.

Note: Entries are in alphabetical order

added

@github-actionsgithub-actionsBot added the action provider New action provider label Apr 17, 2025
@jstinhw

Copy link
Copy Markdown
ContributorAuthor

Your solution to creating a signer out of a EvmWalletProvider is very elegant. I would like to promote this logic to EvmWalletProvider as a helper function toSigner() which returns a Viem signer.

added

Comment threadtypescript/agentkit/README.md
Comment threadtypescript/agentkit/src/wallet-providers/zeroDevWalletProvider.ts Outdated
jstinhwand others added 9 commits April 18, 2025 13:31
- Replace configureWithSigner with configureWithWallet
- Replace `0x${string}` type with Address, Hex or Hash
- networkId as config instead of network
- Update `network` params to `networkId`
- Use `!` when getting chainId in sendTransaction
- Remove unused `getSigner`
- Merge evm wallet address log in example
- added "toSigner" helper func to evmWalletProvider
- updated type of signer to Account in config of zeroDevWalletProvider
@jstinhw
jstinhwforce-pushed the zerodev-wallet-provider branch from e338e2a to f733210CompareApril 18, 2025 21:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action providerNew action providerbananadocumentationImprovements or additions to documentationexampleNew example agenttypescriptwallet providerNew wallet provider

Development

Successfully merging this pull request may close these issues.

5 participants

@jstinhw@cb-heimdall@CarsonRoscoe@murrlincoln@derekchiang
, '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: add zeroDevWalletProvider - #665

Merged
CarsonRoscoe merged 14 commits into
coinbase:mainfrom
zerodevapp:zerodev-wallet-provider
Apr 18, 2025
Merged

feat: add zeroDevWalletProvider#665
CarsonRoscoe merged 14 commits into
coinbase:mainfrom
zerodevapp:zerodev-wallet-provider

Conversation

@jstinhw

@jstinhwjstinhw commented Apr 9, 2025

Copy link
Copy Markdown
Contributor

Description

This PR introduces a new ZeroDevWalletProvider and ZeroDevWalletActionProvider, which wraps existing EvmWalletProvider instances (e.g., privyEvmWalletProvider, cdpWalletProvider) to enable account abstraction via ZeroDev’s infrastructure. The result is a fully chain-abstracted smart account that can be used seamlessly across different EVM-compatible networks.

In addition to introducing the ZeroDevWalletProvider, this PR updates the hashMessage import from @coinbase/coinbase-sdk to viem. Previously, @coinbase/coinbase-sdk re-exported the same function from ethers.js, but this change consolidates our hashing logic under viem directly.

Key points:

  • Introduces ZeroDevWalletProvider, leveraging an existing signer (e.g., privyEvmWalletProvider) to create a ZeroDev smart contract wallet.
  • Introduces ZeroDevWalletActionProvider, providing the action to get chain abstracted balance (getCAB) from the smart account.
  • Supports chain abstraction, meaning that the user can send funds to the agent on any "source chain," and the agent can spend the funds on any "destination chain," even when the two chains are different. For example, the user can fund the agent on Base, and the agent can make transactions on Arbitrum.
  • Updates hashMessage usage to reference viem directly instead of relying on the ethers.js function from @coinbase/coinbase-sdk.

Tests

Chatbot: typescript/examples/langchain-zerodev-chatbot/chatbot.ts
Network: Base Mainnet
Setup: Transferred 0.5 USDC to the smart account wallet on Optimism
Prompt: transfer 0.1 USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913) to 0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F
-------------------
Transferred 100000 of 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 to 0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F.
Transaction hash for the transfer: 0x023920d2baff0f36755e7ceeae89cc938cbe099659d9a93596f3ec93013a8f55
-------------------
The transfer of 100,000 USDC has been successfully completed to the address **0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F**. Here is the transaction hash for your reference: **0x023920d2baff0f36755e7ceeae89cc938cbe099659d9a93596f3ec93013a8f55**
-------------------

Checklist

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

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

@cb-heimdall

cb-heimdall commented Apr 9, 2025

Copy link
Copy Markdown

✅ Heimdall Review Status

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

@cb-heimdall

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
From .codeflow.yml1
Additional review requirements
Show calculation
Max0
0
From CODEOWNERS0
Global minimum0
Max 1
1
1 if commit is unverified1
Sum2

@jstinhwjstinhw changed the title Zerodev wallet providerfeat: add zeroDev wallet providerApr 9, 2025
@jstinhwjstinhw changed the title feat: add zeroDev wallet providerfeat: add zeroDevWalletProviderApr 9, 2025
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation wallet provider New wallet provider example New example agent typescript labels Apr 10, 2025
* @param config - The configuration options for the ZeroDevWalletProvider.
* @returns A Promise that resolves to a new ZeroDevWalletProvider instance.
*/
public static async configureWithSigner(

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.

nit: Our convention is to call this configureWithWallet, please update this to such

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@CarsonRoscoeCarsonRoscoe 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.

There is a table int he section ## Action Providers in the file /typescript/agentkit/README.md. Please add a new table entry for Zero Dev.

Note: Entries are in alphabetical order

});

// Create a Viem account from the EVM wallet provider
const address = config.signer.getAddress() as `0x${string}`;

@CarsonRoscoeCarsonRoscoeApr 14, 2025

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.

nit: Please replace all 0x${string} with either Address or Hex (whichever is more appropriate) from Viem

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

done

/**
* The network of the wallet.
*/
network: Network;

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.

Your taking the entire network object, which requires that the calling user have the domain knowledge to set everything up. We prefer to minimize the caller's knowledge requirement, and handle defaults.

Please update this param into two optional params, networkId?: string and chainId?: string

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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


this.#signer = config.signer;
this.#projectId = config.projectId;
this.#network = config.network;

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 assign a #network as such:

const networkId = config.networkId || "base-sepolia";
const chainId = config.chainId || NETWORK_ID_TO_CHAIN_ID[networkId];
this.#network = {
protocolFamily: "evm",
networkId: networkId,
chainId: chainId,
};

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

*/
async sendTransaction(transaction: TransactionRequest): Promise<`0x${string}`> {
// Get the chain ID from the network
const chainId = parseInt(this.#network.chainId || "1");

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.

nit: since we now do the network assignment in a way that guarantees chainId, replace the || "1" fallback with a !

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

*
* @returns The underlying signer.
*/
// getSigner(): EvmWalletProvider {

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.

nit: remove

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@CarsonRoscoeCarsonRoscoe 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.

Your solution to creating a signer out of a EvmWalletProvider is very elegant. I would like to promote this logic to EvmWalletProvider as a helper function toSigner() which returns a Viem signer.

Then, update your action provider to take a viem signer. Callers will be expected to toSigner() their provider before passing it in.

};
cdpWalletProvider = evmWalletProvider =
await CdpWalletProvider.configureWithWallet(cdpConfig);
console.log(`CDP Wallet Address: ${evmWalletProvider.getAddress()}`);

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.

nit: Remove the multiple Wallet Address prints and marge it into one after this if/else

console.log(Evm Wallet Address: ${evmWalletProvider.getAddress()});

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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


// Configure ZeroDev Wallet Provider with CDP Wallet as signer
const zeroDevConfig = {
signer: evmWalletProvider,

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.

nit: After the toSigner refactor, pass in signer: evmWalletProvider.toSigner()

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@jstinhw

Copy link
Copy Markdown
ContributorAuthor

There is a table int he section ## Action Providers in the file /typescript/agentkit/README.md. Please add a new table entry for Zero Dev.

Note: Entries are in alphabetical order

added

@github-actionsgithub-actionsBot added the action provider New action provider label Apr 17, 2025
@jstinhw

Copy link
Copy Markdown
ContributorAuthor

Your solution to creating a signer out of a EvmWalletProvider is very elegant. I would like to promote this logic to EvmWalletProvider as a helper function toSigner() which returns a Viem signer.

added

Comment threadtypescript/agentkit/README.md
Comment threadtypescript/agentkit/src/wallet-providers/zeroDevWalletProvider.ts Outdated
jstinhwand others added 9 commits April 18, 2025 13:31
- Replace configureWithSigner with configureWithWallet
- Replace `0x${string}` type with Address, Hex or Hash
- networkId as config instead of network
- Update `network` params to `networkId`
- Use `!` when getting chainId in sendTransaction
- Remove unused `getSigner`
- Merge evm wallet address log in example
- added "toSigner" helper func to evmWalletProvider
- updated type of signer to Account in config of zeroDevWalletProvider
@jstinhw
jstinhwforce-pushed the zerodev-wallet-provider branch from e338e2a to f733210CompareApril 18, 2025 21:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action providerNew action providerbananadocumentationImprovements or additions to documentationexampleNew example agenttypescriptwallet providerNew wallet provider

Development

Successfully merging this pull request may close these issues.

5 participants

@jstinhw@cb-heimdall@CarsonRoscoe@murrlincoln@derekchiang
, '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: add zeroDevWalletProvider - #665

Merged
CarsonRoscoe merged 14 commits into
coinbase:mainfrom
zerodevapp:zerodev-wallet-provider
Apr 18, 2025
Merged

feat: add zeroDevWalletProvider#665
CarsonRoscoe merged 14 commits into
coinbase:mainfrom
zerodevapp:zerodev-wallet-provider

Conversation

@jstinhw

@jstinhwjstinhw commented Apr 9, 2025

Copy link
Copy Markdown
Contributor

Description

This PR introduces a new ZeroDevWalletProvider and ZeroDevWalletActionProvider, which wraps existing EvmWalletProvider instances (e.g., privyEvmWalletProvider, cdpWalletProvider) to enable account abstraction via ZeroDev’s infrastructure. The result is a fully chain-abstracted smart account that can be used seamlessly across different EVM-compatible networks.

In addition to introducing the ZeroDevWalletProvider, this PR updates the hashMessage import from @coinbase/coinbase-sdk to viem. Previously, @coinbase/coinbase-sdk re-exported the same function from ethers.js, but this change consolidates our hashing logic under viem directly.

Key points:

  • Introduces ZeroDevWalletProvider, leveraging an existing signer (e.g., privyEvmWalletProvider) to create a ZeroDev smart contract wallet.
  • Introduces ZeroDevWalletActionProvider, providing the action to get chain abstracted balance (getCAB) from the smart account.
  • Supports chain abstraction, meaning that the user can send funds to the agent on any "source chain," and the agent can spend the funds on any "destination chain," even when the two chains are different. For example, the user can fund the agent on Base, and the agent can make transactions on Arbitrum.
  • Updates hashMessage usage to reference viem directly instead of relying on the ethers.js function from @coinbase/coinbase-sdk.

Tests

Chatbot: typescript/examples/langchain-zerodev-chatbot/chatbot.ts
Network: Base Mainnet
Setup: Transferred 0.5 USDC to the smart account wallet on Optimism
Prompt: transfer 0.1 USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913) to 0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F
-------------------
Transferred 100000 of 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 to 0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F.
Transaction hash for the transfer: 0x023920d2baff0f36755e7ceeae89cc938cbe099659d9a93596f3ec93013a8f55
-------------------
The transfer of 100,000 USDC has been successfully completed to the address **0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F**. Here is the transaction hash for your reference: **0x023920d2baff0f36755e7ceeae89cc938cbe099659d9a93596f3ec93013a8f55**
-------------------

Checklist

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

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

@cb-heimdall

cb-heimdall commented Apr 9, 2025

Copy link
Copy Markdown

✅ Heimdall Review Status

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

@cb-heimdall

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
From .codeflow.yml1
Additional review requirements
Show calculation
Max0
0
From CODEOWNERS0
Global minimum0
Max 1
1
1 if commit is unverified1
Sum2

@jstinhwjstinhw changed the title Zerodev wallet providerfeat: add zeroDev wallet providerApr 9, 2025
@jstinhwjstinhw changed the title feat: add zeroDev wallet providerfeat: add zeroDevWalletProviderApr 9, 2025
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation wallet provider New wallet provider example New example agent typescript labels Apr 10, 2025
* @param config - The configuration options for the ZeroDevWalletProvider.
* @returns A Promise that resolves to a new ZeroDevWalletProvider instance.
*/
public static async configureWithSigner(

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.

nit: Our convention is to call this configureWithWallet, please update this to such

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@CarsonRoscoeCarsonRoscoe 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.

There is a table int he section ## Action Providers in the file /typescript/agentkit/README.md. Please add a new table entry for Zero Dev.

Note: Entries are in alphabetical order

});

// Create a Viem account from the EVM wallet provider
const address = config.signer.getAddress() as `0x${string}`;

@CarsonRoscoeCarsonRoscoeApr 14, 2025

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.

nit: Please replace all 0x${string} with either Address or Hex (whichever is more appropriate) from Viem

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

done

/**
* The network of the wallet.
*/
network: Network;

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.

Your taking the entire network object, which requires that the calling user have the domain knowledge to set everything up. We prefer to minimize the caller's knowledge requirement, and handle defaults.

Please update this param into two optional params, networkId?: string and chainId?: string

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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


this.#signer = config.signer;
this.#projectId = config.projectId;
this.#network = config.network;

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 assign a #network as such:

const networkId = config.networkId || "base-sepolia";
const chainId = config.chainId || NETWORK_ID_TO_CHAIN_ID[networkId];
this.#network = {
protocolFamily: "evm",
networkId: networkId,
chainId: chainId,
};

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

*/
async sendTransaction(transaction: TransactionRequest): Promise<`0x${string}`> {
// Get the chain ID from the network
const chainId = parseInt(this.#network.chainId || "1");

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.

nit: since we now do the network assignment in a way that guarantees chainId, replace the || "1" fallback with a !

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

*
* @returns The underlying signer.
*/
// getSigner(): EvmWalletProvider {

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.

nit: remove

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@CarsonRoscoeCarsonRoscoe 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.

Your solution to creating a signer out of a EvmWalletProvider is very elegant. I would like to promote this logic to EvmWalletProvider as a helper function toSigner() which returns a Viem signer.

Then, update your action provider to take a viem signer. Callers will be expected to toSigner() their provider before passing it in.

};
cdpWalletProvider = evmWalletProvider =
await CdpWalletProvider.configureWithWallet(cdpConfig);
console.log(`CDP Wallet Address: ${evmWalletProvider.getAddress()}`);

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.

nit: Remove the multiple Wallet Address prints and marge it into one after this if/else

console.log(Evm Wallet Address: ${evmWalletProvider.getAddress()});

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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


// Configure ZeroDev Wallet Provider with CDP Wallet as signer
const zeroDevConfig = {
signer: evmWalletProvider,

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.

nit: After the toSigner refactor, pass in signer: evmWalletProvider.toSigner()

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@jstinhw

Copy link
Copy Markdown
ContributorAuthor

There is a table int he section ## Action Providers in the file /typescript/agentkit/README.md. Please add a new table entry for Zero Dev.

Note: Entries are in alphabetical order

added

@github-actionsgithub-actionsBot added the action provider New action provider label Apr 17, 2025
@jstinhw

Copy link
Copy Markdown
ContributorAuthor

Your solution to creating a signer out of a EvmWalletProvider is very elegant. I would like to promote this logic to EvmWalletProvider as a helper function toSigner() which returns a Viem signer.

added

Comment threadtypescript/agentkit/README.md
Comment threadtypescript/agentkit/src/wallet-providers/zeroDevWalletProvider.ts Outdated
jstinhwand others added 9 commits April 18, 2025 13:31
- Replace configureWithSigner with configureWithWallet
- Replace `0x${string}` type with Address, Hex or Hash
- networkId as config instead of network
- Update `network` params to `networkId`
- Use `!` when getting chainId in sendTransaction
- Remove unused `getSigner`
- Merge evm wallet address log in example
- added "toSigner" helper func to evmWalletProvider
- updated type of signer to Account in config of zeroDevWalletProvider
@jstinhw
jstinhwforce-pushed the zerodev-wallet-provider branch from e338e2a to f733210CompareApril 18, 2025 21:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action providerNew action providerbananadocumentationImprovements or additions to documentationexampleNew example agenttypescriptwallet providerNew wallet provider

Development

Successfully merging this pull request may close these issues.

5 participants

@jstinhw@cb-heimdall@CarsonRoscoe@murrlincoln@derekchiang
, '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: add zeroDevWalletProvider - #665

Merged
CarsonRoscoe merged 14 commits into
coinbase:mainfrom
zerodevapp:zerodev-wallet-provider
Apr 18, 2025
Merged

feat: add zeroDevWalletProvider#665
CarsonRoscoe merged 14 commits into
coinbase:mainfrom
zerodevapp:zerodev-wallet-provider

Conversation

@jstinhw

@jstinhwjstinhw commented Apr 9, 2025

Copy link
Copy Markdown
Contributor

Description

This PR introduces a new ZeroDevWalletProvider and ZeroDevWalletActionProvider, which wraps existing EvmWalletProvider instances (e.g., privyEvmWalletProvider, cdpWalletProvider) to enable account abstraction via ZeroDev’s infrastructure. The result is a fully chain-abstracted smart account that can be used seamlessly across different EVM-compatible networks.

In addition to introducing the ZeroDevWalletProvider, this PR updates the hashMessage import from @coinbase/coinbase-sdk to viem. Previously, @coinbase/coinbase-sdk re-exported the same function from ethers.js, but this change consolidates our hashing logic under viem directly.

Key points:

  • Introduces ZeroDevWalletProvider, leveraging an existing signer (e.g., privyEvmWalletProvider) to create a ZeroDev smart contract wallet.
  • Introduces ZeroDevWalletActionProvider, providing the action to get chain abstracted balance (getCAB) from the smart account.
  • Supports chain abstraction, meaning that the user can send funds to the agent on any "source chain," and the agent can spend the funds on any "destination chain," even when the two chains are different. For example, the user can fund the agent on Base, and the agent can make transactions on Arbitrum.
  • Updates hashMessage usage to reference viem directly instead of relying on the ethers.js function from @coinbase/coinbase-sdk.

Tests

Chatbot: typescript/examples/langchain-zerodev-chatbot/chatbot.ts
Network: Base Mainnet
Setup: Transferred 0.5 USDC to the smart account wallet on Optimism
Prompt: transfer 0.1 USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913) to 0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F
-------------------
Transferred 100000 of 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 to 0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F.
Transaction hash for the transfer: 0x023920d2baff0f36755e7ceeae89cc938cbe099659d9a93596f3ec93013a8f55
-------------------
The transfer of 100,000 USDC has been successfully completed to the address **0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F**. Here is the transaction hash for your reference: **0x023920d2baff0f36755e7ceeae89cc938cbe099659d9a93596f3ec93013a8f55**
-------------------

Checklist

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

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

@cb-heimdall

cb-heimdall commented Apr 9, 2025

Copy link
Copy Markdown

✅ Heimdall Review Status

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

@cb-heimdall

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
From .codeflow.yml1
Additional review requirements
Show calculation
Max0
0
From CODEOWNERS0
Global minimum0
Max 1
1
1 if commit is unverified1
Sum2

@jstinhwjstinhw changed the title Zerodev wallet providerfeat: add zeroDev wallet providerApr 9, 2025
@jstinhwjstinhw changed the title feat: add zeroDev wallet providerfeat: add zeroDevWalletProviderApr 9, 2025
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation wallet provider New wallet provider example New example agent typescript labels Apr 10, 2025
* @param config - The configuration options for the ZeroDevWalletProvider.
* @returns A Promise that resolves to a new ZeroDevWalletProvider instance.
*/
public static async configureWithSigner(

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.

nit: Our convention is to call this configureWithWallet, please update this to such

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@CarsonRoscoeCarsonRoscoe 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.

There is a table int he section ## Action Providers in the file /typescript/agentkit/README.md. Please add a new table entry for Zero Dev.

Note: Entries are in alphabetical order

});

// Create a Viem account from the EVM wallet provider
const address = config.signer.getAddress() as `0x${string}`;

@CarsonRoscoeCarsonRoscoeApr 14, 2025

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.

nit: Please replace all 0x${string} with either Address or Hex (whichever is more appropriate) from Viem

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

done

/**
* The network of the wallet.
*/
network: Network;

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.

Your taking the entire network object, which requires that the calling user have the domain knowledge to set everything up. We prefer to minimize the caller's knowledge requirement, and handle defaults.

Please update this param into two optional params, networkId?: string and chainId?: string

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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


this.#signer = config.signer;
this.#projectId = config.projectId;
this.#network = config.network;

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 assign a #network as such:

const networkId = config.networkId || "base-sepolia";
const chainId = config.chainId || NETWORK_ID_TO_CHAIN_ID[networkId];
this.#network = {
protocolFamily: "evm",
networkId: networkId,
chainId: chainId,
};

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

*/
async sendTransaction(transaction: TransactionRequest): Promise<`0x${string}`> {
// Get the chain ID from the network
const chainId = parseInt(this.#network.chainId || "1");

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.

nit: since we now do the network assignment in a way that guarantees chainId, replace the || "1" fallback with a !

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

*
* @returns The underlying signer.
*/
// getSigner(): EvmWalletProvider {

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.

nit: remove

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@CarsonRoscoeCarsonRoscoe 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.

Your solution to creating a signer out of a EvmWalletProvider is very elegant. I would like to promote this logic to EvmWalletProvider as a helper function toSigner() which returns a Viem signer.

Then, update your action provider to take a viem signer. Callers will be expected to toSigner() their provider before passing it in.

};
cdpWalletProvider = evmWalletProvider =
await CdpWalletProvider.configureWithWallet(cdpConfig);
console.log(`CDP Wallet Address: ${evmWalletProvider.getAddress()}`);

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.

nit: Remove the multiple Wallet Address prints and marge it into one after this if/else

console.log(Evm Wallet Address: ${evmWalletProvider.getAddress()});

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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


// Configure ZeroDev Wallet Provider with CDP Wallet as signer
const zeroDevConfig = {
signer: evmWalletProvider,

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.

nit: After the toSigner refactor, pass in signer: evmWalletProvider.toSigner()

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@jstinhw

Copy link
Copy Markdown
ContributorAuthor

There is a table int he section ## Action Providers in the file /typescript/agentkit/README.md. Please add a new table entry for Zero Dev.

Note: Entries are in alphabetical order

added

@github-actionsgithub-actionsBot added the action provider New action provider label Apr 17, 2025
@jstinhw

Copy link
Copy Markdown
ContributorAuthor

Your solution to creating a signer out of a EvmWalletProvider is very elegant. I would like to promote this logic to EvmWalletProvider as a helper function toSigner() which returns a Viem signer.

added

Comment threadtypescript/agentkit/README.md
Comment threadtypescript/agentkit/src/wallet-providers/zeroDevWalletProvider.ts Outdated
jstinhwand others added 9 commits April 18, 2025 13:31
- Replace configureWithSigner with configureWithWallet
- Replace `0x${string}` type with Address, Hex or Hash
- networkId as config instead of network
- Update `network` params to `networkId`
- Use `!` when getting chainId in sendTransaction
- Remove unused `getSigner`
- Merge evm wallet address log in example
- added "toSigner" helper func to evmWalletProvider
- updated type of signer to Account in config of zeroDevWalletProvider
@jstinhw
jstinhwforce-pushed the zerodev-wallet-provider branch from e338e2a to f733210CompareApril 18, 2025 21:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action providerNew action providerbananadocumentationImprovements or additions to documentationexampleNew example agenttypescriptwallet providerNew wallet provider

Development

Successfully merging this pull request may close these issues.

5 participants

@jstinhw@cb-heimdall@CarsonRoscoe@murrlincoln@derekchiang
, '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: add zeroDevWalletProvider - #665

Merged
CarsonRoscoe merged 14 commits into
coinbase:mainfrom
zerodevapp:zerodev-wallet-provider
Apr 18, 2025
Merged

feat: add zeroDevWalletProvider#665
CarsonRoscoe merged 14 commits into
coinbase:mainfrom
zerodevapp:zerodev-wallet-provider

Conversation

@jstinhw

@jstinhwjstinhw commented Apr 9, 2025

Copy link
Copy Markdown
Contributor

Description

This PR introduces a new ZeroDevWalletProvider and ZeroDevWalletActionProvider, which wraps existing EvmWalletProvider instances (e.g., privyEvmWalletProvider, cdpWalletProvider) to enable account abstraction via ZeroDev’s infrastructure. The result is a fully chain-abstracted smart account that can be used seamlessly across different EVM-compatible networks.

In addition to introducing the ZeroDevWalletProvider, this PR updates the hashMessage import from @coinbase/coinbase-sdk to viem. Previously, @coinbase/coinbase-sdk re-exported the same function from ethers.js, but this change consolidates our hashing logic under viem directly.

Key points:

  • Introduces ZeroDevWalletProvider, leveraging an existing signer (e.g., privyEvmWalletProvider) to create a ZeroDev smart contract wallet.
  • Introduces ZeroDevWalletActionProvider, providing the action to get chain abstracted balance (getCAB) from the smart account.
  • Supports chain abstraction, meaning that the user can send funds to the agent on any "source chain," and the agent can spend the funds on any "destination chain," even when the two chains are different. For example, the user can fund the agent on Base, and the agent can make transactions on Arbitrum.
  • Updates hashMessage usage to reference viem directly instead of relying on the ethers.js function from @coinbase/coinbase-sdk.

Tests

Chatbot: typescript/examples/langchain-zerodev-chatbot/chatbot.ts
Network: Base Mainnet
Setup: Transferred 0.5 USDC to the smart account wallet on Optimism
Prompt: transfer 0.1 USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913) to 0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F
-------------------
Transferred 100000 of 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 to 0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F.
Transaction hash for the transfer: 0x023920d2baff0f36755e7ceeae89cc938cbe099659d9a93596f3ec93013a8f55
-------------------
The transfer of 100,000 USDC has been successfully completed to the address **0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F**. Here is the transaction hash for your reference: **0x023920d2baff0f36755e7ceeae89cc938cbe099659d9a93596f3ec93013a8f55**
-------------------

Checklist

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

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

@cb-heimdall

cb-heimdall commented Apr 9, 2025

Copy link
Copy Markdown

✅ Heimdall Review Status

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

@cb-heimdall

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
From .codeflow.yml1
Additional review requirements
Show calculation
Max0
0
From CODEOWNERS0
Global minimum0
Max 1
1
1 if commit is unverified1
Sum2

@jstinhwjstinhw changed the title Zerodev wallet providerfeat: add zeroDev wallet providerApr 9, 2025
@jstinhwjstinhw changed the title feat: add zeroDev wallet providerfeat: add zeroDevWalletProviderApr 9, 2025
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation wallet provider New wallet provider example New example agent typescript labels Apr 10, 2025
* @param config - The configuration options for the ZeroDevWalletProvider.
* @returns A Promise that resolves to a new ZeroDevWalletProvider instance.
*/
public static async configureWithSigner(

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.

nit: Our convention is to call this configureWithWallet, please update this to such

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@CarsonRoscoeCarsonRoscoe 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.

There is a table int he section ## Action Providers in the file /typescript/agentkit/README.md. Please add a new table entry for Zero Dev.

Note: Entries are in alphabetical order

});

// Create a Viem account from the EVM wallet provider
const address = config.signer.getAddress() as `0x${string}`;

@CarsonRoscoeCarsonRoscoeApr 14, 2025

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.

nit: Please replace all 0x${string} with either Address or Hex (whichever is more appropriate) from Viem

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

done

/**
* The network of the wallet.
*/
network: Network;

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.

Your taking the entire network object, which requires that the calling user have the domain knowledge to set everything up. We prefer to minimize the caller's knowledge requirement, and handle defaults.

Please update this param into two optional params, networkId?: string and chainId?: string

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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


this.#signer = config.signer;
this.#projectId = config.projectId;
this.#network = config.network;

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 assign a #network as such:

const networkId = config.networkId || "base-sepolia";
const chainId = config.chainId || NETWORK_ID_TO_CHAIN_ID[networkId];
this.#network = {
protocolFamily: "evm",
networkId: networkId,
chainId: chainId,
};

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

*/
async sendTransaction(transaction: TransactionRequest): Promise<`0x${string}`> {
// Get the chain ID from the network
const chainId = parseInt(this.#network.chainId || "1");

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.

nit: since we now do the network assignment in a way that guarantees chainId, replace the || "1" fallback with a !

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

*
* @returns The underlying signer.
*/
// getSigner(): EvmWalletProvider {

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.

nit: remove

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@CarsonRoscoeCarsonRoscoe 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.

Your solution to creating a signer out of a EvmWalletProvider is very elegant. I would like to promote this logic to EvmWalletProvider as a helper function toSigner() which returns a Viem signer.

Then, update your action provider to take a viem signer. Callers will be expected to toSigner() their provider before passing it in.

};
cdpWalletProvider = evmWalletProvider =
await CdpWalletProvider.configureWithWallet(cdpConfig);
console.log(`CDP Wallet Address: ${evmWalletProvider.getAddress()}`);

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.

nit: Remove the multiple Wallet Address prints and marge it into one after this if/else

console.log(Evm Wallet Address: ${evmWalletProvider.getAddress()});

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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


// Configure ZeroDev Wallet Provider with CDP Wallet as signer
const zeroDevConfig = {
signer: evmWalletProvider,

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.

nit: After the toSigner refactor, pass in signer: evmWalletProvider.toSigner()

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@jstinhw

Copy link
Copy Markdown
ContributorAuthor

There is a table int he section ## Action Providers in the file /typescript/agentkit/README.md. Please add a new table entry for Zero Dev.

Note: Entries are in alphabetical order

added

@github-actionsgithub-actionsBot added the action provider New action provider label Apr 17, 2025
@jstinhw

Copy link
Copy Markdown
ContributorAuthor

Your solution to creating a signer out of a EvmWalletProvider is very elegant. I would like to promote this logic to EvmWalletProvider as a helper function toSigner() which returns a Viem signer.

added

Comment threadtypescript/agentkit/README.md
Comment threadtypescript/agentkit/src/wallet-providers/zeroDevWalletProvider.ts Outdated
jstinhwand others added 9 commits April 18, 2025 13:31
- Replace configureWithSigner with configureWithWallet
- Replace `0x${string}` type with Address, Hex or Hash
- networkId as config instead of network
- Update `network` params to `networkId`
- Use `!` when getting chainId in sendTransaction
- Remove unused `getSigner`
- Merge evm wallet address log in example
- added "toSigner" helper func to evmWalletProvider
- updated type of signer to Account in config of zeroDevWalletProvider
@jstinhw
jstinhwforce-pushed the zerodev-wallet-provider branch from e338e2a to f733210CompareApril 18, 2025 21:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action providerNew action providerbananadocumentationImprovements or additions to documentationexampleNew example agenttypescriptwallet providerNew wallet provider

Development

Successfully merging this pull request may close these issues.

5 participants

@jstinhw@cb-heimdall@CarsonRoscoe@murrlincoln@derekchiang
, '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: add zeroDevWalletProvider - #665

Merged
CarsonRoscoe merged 14 commits into
coinbase:mainfrom
zerodevapp:zerodev-wallet-provider
Apr 18, 2025
Merged

feat: add zeroDevWalletProvider#665
CarsonRoscoe merged 14 commits into
coinbase:mainfrom
zerodevapp:zerodev-wallet-provider

Conversation

@jstinhw

@jstinhwjstinhw commented Apr 9, 2025

Copy link
Copy Markdown
Contributor

Description

This PR introduces a new ZeroDevWalletProvider and ZeroDevWalletActionProvider, which wraps existing EvmWalletProvider instances (e.g., privyEvmWalletProvider, cdpWalletProvider) to enable account abstraction via ZeroDev’s infrastructure. The result is a fully chain-abstracted smart account that can be used seamlessly across different EVM-compatible networks.

In addition to introducing the ZeroDevWalletProvider, this PR updates the hashMessage import from @coinbase/coinbase-sdk to viem. Previously, @coinbase/coinbase-sdk re-exported the same function from ethers.js, but this change consolidates our hashing logic under viem directly.

Key points:

  • Introduces ZeroDevWalletProvider, leveraging an existing signer (e.g., privyEvmWalletProvider) to create a ZeroDev smart contract wallet.
  • Introduces ZeroDevWalletActionProvider, providing the action to get chain abstracted balance (getCAB) from the smart account.
  • Supports chain abstraction, meaning that the user can send funds to the agent on any "source chain," and the agent can spend the funds on any "destination chain," even when the two chains are different. For example, the user can fund the agent on Base, and the agent can make transactions on Arbitrum.
  • Updates hashMessage usage to reference viem directly instead of relying on the ethers.js function from @coinbase/coinbase-sdk.

Tests

Chatbot: typescript/examples/langchain-zerodev-chatbot/chatbot.ts
Network: Base Mainnet
Setup: Transferred 0.5 USDC to the smart account wallet on Optimism
Prompt: transfer 0.1 USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913) to 0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F
-------------------
Transferred 100000 of 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 to 0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F.
Transaction hash for the transfer: 0x023920d2baff0f36755e7ceeae89cc938cbe099659d9a93596f3ec93013a8f55
-------------------
The transfer of 100,000 USDC has been successfully completed to the address **0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F**. Here is the transaction hash for your reference: **0x023920d2baff0f36755e7ceeae89cc938cbe099659d9a93596f3ec93013a8f55**
-------------------

Checklist

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

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

@cb-heimdall

cb-heimdall commented Apr 9, 2025

Copy link
Copy Markdown

✅ Heimdall Review Status

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

@cb-heimdall

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
From .codeflow.yml1
Additional review requirements
Show calculation
Max0
0
From CODEOWNERS0
Global minimum0
Max 1
1
1 if commit is unverified1
Sum2

@jstinhwjstinhw changed the title Zerodev wallet providerfeat: add zeroDev wallet providerApr 9, 2025
@jstinhwjstinhw changed the title feat: add zeroDev wallet providerfeat: add zeroDevWalletProviderApr 9, 2025
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation wallet provider New wallet provider example New example agent typescript labels Apr 10, 2025
* @param config - The configuration options for the ZeroDevWalletProvider.
* @returns A Promise that resolves to a new ZeroDevWalletProvider instance.
*/
public static async configureWithSigner(

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.

nit: Our convention is to call this configureWithWallet, please update this to such

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@CarsonRoscoeCarsonRoscoe 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.

There is a table int he section ## Action Providers in the file /typescript/agentkit/README.md. Please add a new table entry for Zero Dev.

Note: Entries are in alphabetical order

});

// Create a Viem account from the EVM wallet provider
const address = config.signer.getAddress() as `0x${string}`;

@CarsonRoscoeCarsonRoscoeApr 14, 2025

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.

nit: Please replace all 0x${string} with either Address or Hex (whichever is more appropriate) from Viem

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

done

/**
* The network of the wallet.
*/
network: Network;

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.

Your taking the entire network object, which requires that the calling user have the domain knowledge to set everything up. We prefer to minimize the caller's knowledge requirement, and handle defaults.

Please update this param into two optional params, networkId?: string and chainId?: string

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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


this.#signer = config.signer;
this.#projectId = config.projectId;
this.#network = config.network;

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 assign a #network as such:

const networkId = config.networkId || "base-sepolia";
const chainId = config.chainId || NETWORK_ID_TO_CHAIN_ID[networkId];
this.#network = {
protocolFamily: "evm",
networkId: networkId,
chainId: chainId,
};

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

*/
async sendTransaction(transaction: TransactionRequest): Promise<`0x${string}`> {
// Get the chain ID from the network
const chainId = parseInt(this.#network.chainId || "1");

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.

nit: since we now do the network assignment in a way that guarantees chainId, replace the || "1" fallback with a !

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

*
* @returns The underlying signer.
*/
// getSigner(): EvmWalletProvider {

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.

nit: remove

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@CarsonRoscoeCarsonRoscoe 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.

Your solution to creating a signer out of a EvmWalletProvider is very elegant. I would like to promote this logic to EvmWalletProvider as a helper function toSigner() which returns a Viem signer.

Then, update your action provider to take a viem signer. Callers will be expected to toSigner() their provider before passing it in.

};
cdpWalletProvider = evmWalletProvider =
await CdpWalletProvider.configureWithWallet(cdpConfig);
console.log(`CDP Wallet Address: ${evmWalletProvider.getAddress()}`);

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.

nit: Remove the multiple Wallet Address prints and marge it into one after this if/else

console.log(Evm Wallet Address: ${evmWalletProvider.getAddress()});

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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


// Configure ZeroDev Wallet Provider with CDP Wallet as signer
const zeroDevConfig = {
signer: evmWalletProvider,

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.

nit: After the toSigner refactor, pass in signer: evmWalletProvider.toSigner()

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@jstinhw

Copy link
Copy Markdown
ContributorAuthor

There is a table int he section ## Action Providers in the file /typescript/agentkit/README.md. Please add a new table entry for Zero Dev.

Note: Entries are in alphabetical order

added

@github-actionsgithub-actionsBot added the action provider New action provider label Apr 17, 2025
@jstinhw

Copy link
Copy Markdown
ContributorAuthor

Your solution to creating a signer out of a EvmWalletProvider is very elegant. I would like to promote this logic to EvmWalletProvider as a helper function toSigner() which returns a Viem signer.

added

Comment threadtypescript/agentkit/README.md
Comment threadtypescript/agentkit/src/wallet-providers/zeroDevWalletProvider.ts Outdated
jstinhwand others added 9 commits April 18, 2025 13:31
- Replace configureWithSigner with configureWithWallet
- Replace `0x${string}` type with Address, Hex or Hash
- networkId as config instead of network
- Update `network` params to `networkId`
- Use `!` when getting chainId in sendTransaction
- Remove unused `getSigner`
- Merge evm wallet address log in example
- added "toSigner" helper func to evmWalletProvider
- updated type of signer to Account in config of zeroDevWalletProvider
@jstinhw
jstinhwforce-pushed the zerodev-wallet-provider branch from e338e2a to f733210CompareApril 18, 2025 21:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action providerNew action providerbananadocumentationImprovements or additions to documentationexampleNew example agenttypescriptwallet providerNew wallet provider

Development

Successfully merging this pull request may close these issues.

5 participants

@jstinhw@cb-heimdall@CarsonRoscoe@murrlincoln@derekchiang
, '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: add zeroDevWalletProvider - #665

Merged
CarsonRoscoe merged 14 commits into
coinbase:mainfrom
zerodevapp:zerodev-wallet-provider
Apr 18, 2025
Merged

feat: add zeroDevWalletProvider#665
CarsonRoscoe merged 14 commits into
coinbase:mainfrom
zerodevapp:zerodev-wallet-provider

Conversation

@jstinhw

@jstinhwjstinhw commented Apr 9, 2025

Copy link
Copy Markdown
Contributor

Description

This PR introduces a new ZeroDevWalletProvider and ZeroDevWalletActionProvider, which wraps existing EvmWalletProvider instances (e.g., privyEvmWalletProvider, cdpWalletProvider) to enable account abstraction via ZeroDev’s infrastructure. The result is a fully chain-abstracted smart account that can be used seamlessly across different EVM-compatible networks.

In addition to introducing the ZeroDevWalletProvider, this PR updates the hashMessage import from @coinbase/coinbase-sdk to viem. Previously, @coinbase/coinbase-sdk re-exported the same function from ethers.js, but this change consolidates our hashing logic under viem directly.

Key points:

  • Introduces ZeroDevWalletProvider, leveraging an existing signer (e.g., privyEvmWalletProvider) to create a ZeroDev smart contract wallet.
  • Introduces ZeroDevWalletActionProvider, providing the action to get chain abstracted balance (getCAB) from the smart account.
  • Supports chain abstraction, meaning that the user can send funds to the agent on any "source chain," and the agent can spend the funds on any "destination chain," even when the two chains are different. For example, the user can fund the agent on Base, and the agent can make transactions on Arbitrum.
  • Updates hashMessage usage to reference viem directly instead of relying on the ethers.js function from @coinbase/coinbase-sdk.

Tests

Chatbot: typescript/examples/langchain-zerodev-chatbot/chatbot.ts
Network: Base Mainnet
Setup: Transferred 0.5 USDC to the smart account wallet on Optimism
Prompt: transfer 0.1 USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913) to 0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F
-------------------
Transferred 100000 of 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 to 0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F.
Transaction hash for the transfer: 0x023920d2baff0f36755e7ceeae89cc938cbe099659d9a93596f3ec93013a8f55
-------------------
The transfer of 100,000 USDC has been successfully completed to the address **0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F**. Here is the transaction hash for your reference: **0x023920d2baff0f36755e7ceeae89cc938cbe099659d9a93596f3ec93013a8f55**
-------------------

Checklist

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

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

@cb-heimdall

cb-heimdall commented Apr 9, 2025

Copy link
Copy Markdown

✅ Heimdall Review Status

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

@cb-heimdall

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
From .codeflow.yml1
Additional review requirements
Show calculation
Max0
0
From CODEOWNERS0
Global minimum0
Max 1
1
1 if commit is unverified1
Sum2

@jstinhwjstinhw changed the title Zerodev wallet providerfeat: add zeroDev wallet providerApr 9, 2025
@jstinhwjstinhw changed the title feat: add zeroDev wallet providerfeat: add zeroDevWalletProviderApr 9, 2025
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation wallet provider New wallet provider example New example agent typescript labels Apr 10, 2025
* @param config - The configuration options for the ZeroDevWalletProvider.
* @returns A Promise that resolves to a new ZeroDevWalletProvider instance.
*/
public static async configureWithSigner(

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.

nit: Our convention is to call this configureWithWallet, please update this to such

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@CarsonRoscoeCarsonRoscoe 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.

There is a table int he section ## Action Providers in the file /typescript/agentkit/README.md. Please add a new table entry for Zero Dev.

Note: Entries are in alphabetical order

});

// Create a Viem account from the EVM wallet provider
const address = config.signer.getAddress() as `0x${string}`;

@CarsonRoscoeCarsonRoscoeApr 14, 2025

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.

nit: Please replace all 0x${string} with either Address or Hex (whichever is more appropriate) from Viem

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

done

/**
* The network of the wallet.
*/
network: Network;

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.

Your taking the entire network object, which requires that the calling user have the domain knowledge to set everything up. We prefer to minimize the caller's knowledge requirement, and handle defaults.

Please update this param into two optional params, networkId?: string and chainId?: string

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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


this.#signer = config.signer;
this.#projectId = config.projectId;
this.#network = config.network;

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 assign a #network as such:

const networkId = config.networkId || "base-sepolia";
const chainId = config.chainId || NETWORK_ID_TO_CHAIN_ID[networkId];
this.#network = {
protocolFamily: "evm",
networkId: networkId,
chainId: chainId,
};

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

*/
async sendTransaction(transaction: TransactionRequest): Promise<`0x${string}`> {
// Get the chain ID from the network
const chainId = parseInt(this.#network.chainId || "1");

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.

nit: since we now do the network assignment in a way that guarantees chainId, replace the || "1" fallback with a !

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

*
* @returns The underlying signer.
*/
// getSigner(): EvmWalletProvider {

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.

nit: remove

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@CarsonRoscoeCarsonRoscoe 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.

Your solution to creating a signer out of a EvmWalletProvider is very elegant. I would like to promote this logic to EvmWalletProvider as a helper function toSigner() which returns a Viem signer.

Then, update your action provider to take a viem signer. Callers will be expected to toSigner() their provider before passing it in.

};
cdpWalletProvider = evmWalletProvider =
await CdpWalletProvider.configureWithWallet(cdpConfig);
console.log(`CDP Wallet Address: ${evmWalletProvider.getAddress()}`);

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.

nit: Remove the multiple Wallet Address prints and marge it into one after this if/else

console.log(Evm Wallet Address: ${evmWalletProvider.getAddress()});

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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


// Configure ZeroDev Wallet Provider with CDP Wallet as signer
const zeroDevConfig = {
signer: evmWalletProvider,

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.

nit: After the toSigner refactor, pass in signer: evmWalletProvider.toSigner()

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@jstinhw

Copy link
Copy Markdown
ContributorAuthor

There is a table int he section ## Action Providers in the file /typescript/agentkit/README.md. Please add a new table entry for Zero Dev.

Note: Entries are in alphabetical order

added

@github-actionsgithub-actionsBot added the action provider New action provider label Apr 17, 2025
@jstinhw

Copy link
Copy Markdown
ContributorAuthor

Your solution to creating a signer out of a EvmWalletProvider is very elegant. I would like to promote this logic to EvmWalletProvider as a helper function toSigner() which returns a Viem signer.

added

Comment threadtypescript/agentkit/README.md
Comment threadtypescript/agentkit/src/wallet-providers/zeroDevWalletProvider.ts Outdated
jstinhwand others added 9 commits April 18, 2025 13:31
- Replace configureWithSigner with configureWithWallet
- Replace `0x${string}` type with Address, Hex or Hash
- networkId as config instead of network
- Update `network` params to `networkId`
- Use `!` when getting chainId in sendTransaction
- Remove unused `getSigner`
- Merge evm wallet address log in example
- added "toSigner" helper func to evmWalletProvider
- updated type of signer to Account in config of zeroDevWalletProvider
@jstinhw
jstinhwforce-pushed the zerodev-wallet-provider branch from e338e2a to f733210CompareApril 18, 2025 21:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action providerNew action providerbananadocumentationImprovements or additions to documentationexampleNew example agenttypescriptwallet providerNew wallet provider

Development

Successfully merging this pull request may close these issues.

5 participants

@jstinhw@cb-heimdall@CarsonRoscoe@murrlincoln@derekchiang
, '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: add zeroDevWalletProvider - #665

Merged
CarsonRoscoe merged 14 commits into
coinbase:mainfrom
zerodevapp:zerodev-wallet-provider
Apr 18, 2025
Merged

feat: add zeroDevWalletProvider#665
CarsonRoscoe merged 14 commits into
coinbase:mainfrom
zerodevapp:zerodev-wallet-provider

Conversation

@jstinhw

@jstinhwjstinhw commented Apr 9, 2025

Copy link
Copy Markdown
Contributor

Description

This PR introduces a new ZeroDevWalletProvider and ZeroDevWalletActionProvider, which wraps existing EvmWalletProvider instances (e.g., privyEvmWalletProvider, cdpWalletProvider) to enable account abstraction via ZeroDev’s infrastructure. The result is a fully chain-abstracted smart account that can be used seamlessly across different EVM-compatible networks.

In addition to introducing the ZeroDevWalletProvider, this PR updates the hashMessage import from @coinbase/coinbase-sdk to viem. Previously, @coinbase/coinbase-sdk re-exported the same function from ethers.js, but this change consolidates our hashing logic under viem directly.

Key points:

  • Introduces ZeroDevWalletProvider, leveraging an existing signer (e.g., privyEvmWalletProvider) to create a ZeroDev smart contract wallet.
  • Introduces ZeroDevWalletActionProvider, providing the action to get chain abstracted balance (getCAB) from the smart account.
  • Supports chain abstraction, meaning that the user can send funds to the agent on any "source chain," and the agent can spend the funds on any "destination chain," even when the two chains are different. For example, the user can fund the agent on Base, and the agent can make transactions on Arbitrum.
  • Updates hashMessage usage to reference viem directly instead of relying on the ethers.js function from @coinbase/coinbase-sdk.

Tests

Chatbot: typescript/examples/langchain-zerodev-chatbot/chatbot.ts
Network: Base Mainnet
Setup: Transferred 0.5 USDC to the smart account wallet on Optimism
Prompt: transfer 0.1 USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913) to 0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F
-------------------
Transferred 100000 of 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 to 0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F.
Transaction hash for the transfer: 0x023920d2baff0f36755e7ceeae89cc938cbe099659d9a93596f3ec93013a8f55
-------------------
The transfer of 100,000 USDC has been successfully completed to the address **0xcABF44ea73E3CC30A46a85854236b4b3AC22d45F**. Here is the transaction hash for your reference: **0x023920d2baff0f36755e7ceeae89cc938cbe099659d9a93596f3ec93013a8f55**
-------------------

Checklist

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

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

@cb-heimdall

cb-heimdall commented Apr 9, 2025

Copy link
Copy Markdown

✅ Heimdall Review Status

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

@cb-heimdall

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
From .codeflow.yml1
Additional review requirements
Show calculation
Max0
0
From CODEOWNERS0
Global minimum0
Max 1
1
1 if commit is unverified1
Sum2

@jstinhwjstinhw changed the title Zerodev wallet providerfeat: add zeroDev wallet providerApr 9, 2025
@jstinhwjstinhw changed the title feat: add zeroDev wallet providerfeat: add zeroDevWalletProviderApr 9, 2025
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation wallet provider New wallet provider example New example agent typescript labels Apr 10, 2025
* @param config - The configuration options for the ZeroDevWalletProvider.
* @returns A Promise that resolves to a new ZeroDevWalletProvider instance.
*/
public static async configureWithSigner(

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.

nit: Our convention is to call this configureWithWallet, please update this to such

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@CarsonRoscoeCarsonRoscoe 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.

There is a table int he section ## Action Providers in the file /typescript/agentkit/README.md. Please add a new table entry for Zero Dev.

Note: Entries are in alphabetical order

});

// Create a Viem account from the EVM wallet provider
const address = config.signer.getAddress() as `0x${string}`;

@CarsonRoscoeCarsonRoscoeApr 14, 2025

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.

nit: Please replace all 0x${string} with either Address or Hex (whichever is more appropriate) from Viem

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

done

/**
* The network of the wallet.
*/
network: Network;

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.

Your taking the entire network object, which requires that the calling user have the domain knowledge to set everything up. We prefer to minimize the caller's knowledge requirement, and handle defaults.

Please update this param into two optional params, networkId?: string and chainId?: string

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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


this.#signer = config.signer;
this.#projectId = config.projectId;
this.#network = config.network;

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 assign a #network as such:

const networkId = config.networkId || "base-sepolia";
const chainId = config.chainId || NETWORK_ID_TO_CHAIN_ID[networkId];
this.#network = {
protocolFamily: "evm",
networkId: networkId,
chainId: chainId,
};

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

*/
async sendTransaction(transaction: TransactionRequest): Promise<`0x${string}`> {
// Get the chain ID from the network
const chainId = parseInt(this.#network.chainId || "1");

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.

nit: since we now do the network assignment in a way that guarantees chainId, replace the || "1" fallback with a !

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

*
* @returns The underlying signer.
*/
// getSigner(): EvmWalletProvider {

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.

nit: remove

@jstinhwjstinhwApr 14, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@CarsonRoscoeCarsonRoscoe 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.

Your solution to creating a signer out of a EvmWalletProvider is very elegant. I would like to promote this logic to EvmWalletProvider as a helper function toSigner() which returns a Viem signer.

Then, update your action provider to take a viem signer. Callers will be expected to toSigner() their provider before passing it in.

};
cdpWalletProvider = evmWalletProvider =
await CdpWalletProvider.configureWithWallet(cdpConfig);
console.log(`CDP Wallet Address: ${evmWalletProvider.getAddress()}`);

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.

nit: Remove the multiple Wallet Address prints and marge it into one after this if/else

console.log(Evm Wallet Address: ${evmWalletProvider.getAddress()});

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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


// Configure ZeroDev Wallet Provider with CDP Wallet as signer
const zeroDevConfig = {
signer: evmWalletProvider,

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.

nit: After the toSigner refactor, pass in signer: evmWalletProvider.toSigner()

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@jstinhw

Copy link
Copy Markdown
ContributorAuthor

There is a table int he section ## Action Providers in the file /typescript/agentkit/README.md. Please add a new table entry for Zero Dev.

Note: Entries are in alphabetical order

added

@github-actionsgithub-actionsBot added the action provider New action provider label Apr 17, 2025
@jstinhw

Copy link
Copy Markdown
ContributorAuthor

Your solution to creating a signer out of a EvmWalletProvider is very elegant. I would like to promote this logic to EvmWalletProvider as a helper function toSigner() which returns a Viem signer.

added

Comment threadtypescript/agentkit/README.md
Comment threadtypescript/agentkit/src/wallet-providers/zeroDevWalletProvider.ts Outdated
jstinhwand others added 9 commits April 18, 2025 13:31
- Replace configureWithSigner with configureWithWallet
- Replace `0x${string}` type with Address, Hex or Hash
- networkId as config instead of network
- Update `network` params to `networkId`
- Use `!` when getting chainId in sendTransaction
- Remove unused `getSigner`
- Merge evm wallet address log in example
- added "toSigner" helper func to evmWalletProvider
- updated type of signer to Account in config of zeroDevWalletProvider
@jstinhw
jstinhwforce-pushed the zerodev-wallet-provider branch from e338e2a to f733210CompareApril 18, 2025 21:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action providerNew action providerbananadocumentationImprovements or additions to documentationexampleNew example agenttypescriptwallet providerNew wallet provider

Development

Successfully merging this pull request may close these issues.

5 participants

@jstinhw@cb-heimdall@CarsonRoscoe@murrlincoln@derekchiang