Skip to content
GitHubXDiscordRSS

EvmAccount

The EvmAccount resource allows you to create and manage EVM Externally Owned Accounts (EOAs) through the Coinbase Developer Platform.

import { EvmAccount } from "alchemy/coinbase";
const account = await EvmAccount("my-account", {
name: "my-wallet"
});
NameTypeRequiredDescription
namestringYesName for the account in CDP. Must contain only letters, numbers, and hyphens
privateKeySecret<PrivateKey>NoPrivate key to import an existing account. Must be encrypted using alchemy.secret()
adoptbooleanNoUse existing account with the same name if it exists. Default: false
faucetFaucetConfigNoTestnet tokens to request automatically on creation/update
apiKeyIdSecretNoCDP API key ID (overrides environment variable)
apiKeySecretSecretNoCDP API key secret (overrides environment variable)
walletSecretSecretNoCDP wallet secret (overrides environment variable)
NameTypeDescription
namestringThe account name in CDP
addressAddressThe EVM address
faucetFaucetConfigFaucet configuration (if provided)
import { EvmAccount } from "alchemy/coinbase";
const account = await EvmAccount("my-account", {
name: "my-wallet"
});
console.log("Account address:", account.address);

Accounts automatically request testnet tokens when created with faucet configuration:

import { EvmAccount } from "alchemy/coinbase";
const account = await EvmAccount("test-account", {
name: "test-wallet",
faucet: {
"base-sepolia": ["eth", "usdc"],
"ethereum-sepolia": ["eth"]
}
});
// Account automatically receives ETH and USDC on Base Sepolia, and ETH on Ethereum Sepolia

Import an account using an encrypted private key:

import { EvmAccount } from "alchemy/coinbase";
import alchemy from "alchemy";
const account = await EvmAccount("imported", {
name: "imported-wallet",
privateKey: alchemy.secret(process.env.PRIVATE_KEY)
});

Use an existing account instead of creating a new one:

import { EvmAccount } from "alchemy/coinbase";
const account = await EvmAccount("my-account", {
name: "existing-wallet",
adopt: true // Uses existing account if it exists
});

Account names can be updated:

import { EvmAccount } from "alchemy/coinbase";
// Initial creation
const account = await EvmAccount("my-account", {
name: "original-name"
});
// Later, update the name
const updated = await EvmAccount("my-account", {
name: "new-name"
});
console.log(updated.address === account.address); // true - same address

Adding new tokens to faucet configuration automatically requests them:

import { EvmAccount } from "alchemy/coinbase";
// Initial account with ETH on Base Sepolia
const account = await EvmAccount("my-account", {
name: "test-account",
faucet: {
"base-sepolia": ["eth"]
}
});
// Update to add USDC and Ethereum Sepolia
const updated = await EvmAccount("my-account", {
name: "test-account",
faucet: {
"base-sepolia": ["eth", "usdc"], // USDC will be automatically requested
"ethereum-sepolia": ["eth"] // ETH on new network will be requested
}
});
type FaucetNetwork = "base-sepolia" | "ethereum-sepolia";
type FaucetToken = "eth" | "usdc" | "eurc" | "cbbtc";
type FaucetConfig = Partial<Record<FaucetNetwork, FaucetToken[]>>;
type Address = `0x${string}`; // Ethereum address format
type PrivateKey = `0x${string}`; // Private key hex format
  • Name Validation: Account names must contain only letters, numbers, and hyphens
  • Auto-Funding: Faucet requests are non-blocking - failures don’t prevent account creation
  • Security: Private keys must be encrypted using alchemy.secret() for security
  • Idempotent: Importing the same private key multiple times returns the same account
  • Immutability: Accounts remain in CDP even after being removed from Alchemy state