> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Create EVM Wallet

> Learn how to create and manage EVM server wallets with Dynamic's Node SDK

## Overview

This guide walks you through creating EVM wallets using Dynamic's Node SDK. You'll learn how to set up different threshold signature schemes and understand the security implications of each choice.

## Prerequisites

Before you begin, make sure you have:

* [Set up your Dynamic project](/node/quickstart)
* [Created an authenticated client](/node/quickstart)
* [Enabled EVM chains in your dashboard](https://app.dynamic.xyz/dashboard/chains)

## Step 1: Choose Your Security Model

Dynamic supports two threshold signature schemes, each offering different security and availability trade-offs:

### TWO\_OF\_TWO (Recommended for most use cases)

* **Security**: Highest - requires both your server and Dynamic's infrastructure
* **Availability**: Lower - both parties must be online
* **Use case**: High-value transactions, maximum security

### TWO\_OF\_THREE

* **Security**: High - requires 2 out of 3 shares
* **Availability**: Medium - can tolerate one party being offline
* **Use case**: Balanced security and availability

## Step 2: Create Your First Wallet

Here's a complete example of creating an EVM wallet:

```typescript theme={"system"}
import { DynamicEvmWalletClient } from '@dynamic-labs-wallet/node-evm';
import { ThresholdSignatureScheme } from '@dynamic-labs-wallet/node';

// Create authenticated client
export const authenticatedEvmClient = async () => {
  const client = new DynamicEvmWalletClient({
    environmentId: process.env.DYNAMIC_ENVIRONMENT_ID!,
  });

  await client.authenticateApiToken(process.env.DYNAMIC_AUTH_TOKEN!);
  return client;
};

export const createEvmWallet = async ({
  thresholdSignatureScheme = ThresholdSignatureScheme.TWO_OF_TWO,
  password,
}: {
  thresholdSignatureScheme?: ThresholdSignatureScheme;
  password: string; // Required when backUpToDynamic is true
}) => {
  const evmClient = await authenticatedEvmClient();

  const { walletMetadata, externalServerKeyShares } = await evmClient.createWalletAccount({
    thresholdSignatureScheme,
    password,
    backUpToDynamic: true,
  });

  return { walletMetadata, externalServerKeyShares };
};

// Usage example
const { walletMetadata, externalServerKeyShares } = await createEvmWallet({
  thresholdSignatureScheme: ThresholdSignatureScheme.TWO_OF_TWO,
  password: 'your-secure-password',
});

console.log('Wallet created:', walletMetadata.accountAddress);
```

## Step 3: Handle Errors Gracefully

Always implement proper error handling for wallet creation:

```typescript theme={"system"}
try {
  const { walletMetadata } = await createEvmWallet({
    thresholdSignatureScheme: ThresholdSignatureScheme.TWO_OF_TWO,
    password: 'your-secure-password',
  });
  console.log('Wallet created successfully:', walletMetadata.accountAddress);
} catch (error) {
  if (error.message.includes('Password is required')) {
    console.error('Password is required when backing up to Dynamic');
  } else if (error.message.includes('invalid session')) {
    console.error('Invalid session ID - please re-authenticate');
  } else {
    console.error('Wallet creation failed:', error.message);
  }
}
```

## Step 4: Persist `walletMetadata` and `externalServerKeyShares`

`createWalletAccount()` returns two pieces of state — each belongs in a different storage tier:

```typescript theme={"system"}
const { walletMetadata, externalServerKeyShares } = await evmClient.createWalletAccount({
  thresholdSignatureScheme: ThresholdSignatureScheme.TWO_OF_TWO,
  password: 'your-secure-password',
  backUpToDynamic: true,
});

// walletMetadata — non-sensitive identity + backup-pointer info. Cache it.
await redis.set(
  `wallet:${walletMetadata.accountAddress}`,
  JSON.stringify(walletMetadata),
);

// externalServerKeyShares — sensitive MPC key material. Vault it.
await vault.write(
  `wallet:${walletMetadata.accountAddress}/shares`,
  externalServerKeyShares,
);
```

The SDK is stateless and you must pass `walletMetadata` to every subsequent sign / export / backup operation. See [`WalletMetadata`](/node/reference/types/wallet-metadata) and [Storage Best Practices](/node/wallets/server-wallets/storage-best-practices) for the full pattern.

## Best Practices

1. **Password Security**: Use strong, unique passwords for each wallet
2. **Session Management**: Implement proper session lifecycle management
3. **Error Handling**: Always handle potential errors during wallet creation
4. **Monitoring**: Log wallet creation events for audit purposes
5. **Backup Strategy**: Implement secure backup strategies for key shares

## Next Steps

Now that you've created a wallet, you can:

* [Sign transactions](/node/evm/sign-transactions)
* [Sign messages](/node/evm/sign-messages)
* [Import existing private keys](/node/evm/import-private-keys)
* [Use imported wallets](/node/evm/use-imported-wallets)
