Overview

This guide shows you how to work with imported EVM wallets for common operations. Once you’ve imported a private key, you’ll need to retrieve key shares and perform various wallet operations.

Prerequisites

Step 1: Retrieve Your Wallet Information

After importing a wallet, you’ll need to get the external server key shares for signing operations:
import { authenticatedEvmClient } from './client';

const evmClient = await authenticatedEvmClient();

// Get external server key shares for your imported wallet
const keyShares = await evmClient.getExternalServerKeyShares({
  accountAddress: '0xYourImportedWalletAddress'
});

console.log('Key shares retrieved:', keyShares.length);

Step 2: Check Wallet Balance

Check the balance of your imported wallet:
import { http } from 'viem';
import { base } from 'viem/chains';

const publicClient = evmClient.createViemPublicClient({
  chain: base,
  rpcUrl: 'https://mainnet.base.org',
});

const balance = await publicClient.getBalance({
  address: '0xYourImportedWalletAddress' as `0x${string}`,
});

console.log('Balance:', balance.toString(), 'wei');
console.log('Balance in ETH:', Number(balance) / 1e18);

Step 3: Sign Transactions with Imported Wallet

Use your imported wallet to sign transactions:
import { parseEther } from 'viem/utils';

// Prepare transaction
const transactionRequest = {
  to: '0xRecipientAddress' as `0x${string}`,
  value: parseEther('0.1'),
};

const preparedTx = await publicClient.prepareTransactionRequest({
  ...transactionRequest,
  chain: base,
  account: '0xYourImportedWalletAddress' as `0x${string}`,
});

// Sign with imported wallet
const signedTx = await evmClient.signTransaction({
  senderAddress: '0xYourImportedWalletAddress' as `0x${string}`,
  externalServerKeyShares: keyShares,
  transaction: preparedTx,
  password: 'your-wallet-password', // if wallet is password-protected
});

console.log('Transaction signed with imported wallet');

Step 4: Sign Messages with Imported Wallet

Sign messages for authentication or data integrity:
const message = 'Hello from my imported wallet!';
const signature = await evmClient.signMessage({
  message,
  accountAddress: '0xYourImportedWalletAddress',
  externalServerKeyShares: keyShares,
  password: 'your-wallet-password', // if wallet is password-protected
});

console.log('Message signed:', signature);

Step 5: Verify Wallet Operations

Verify that your imported wallet can perform operations:
// Check if wallet requires password for operations
const requiresPassword = await evmClient.requiresPasswordForOperation({
  accountAddress: '0xYourImportedWalletAddress',
  walletOperation: 'SIGN_MESSAGE',
});

console.log('Requires password for signing:', requiresPassword);

// Verify password if needed
if (requiresPassword) {
  await evmClient.verifyPassword({
    accountAddress: '0xYourImportedWalletAddress',
    password: 'your-wallet-password',
    walletOperation: 'SIGN_MESSAGE'
  });
  console.log('Password verified successfully');
}

Complete Example: Send ETH from Imported Wallet

export const sendEthFromImportedWallet = async ({
  walletAddress,
  toAddress,
  amount,
  password,
}: {
  walletAddress: string;
  toAddress: string;
  amount: string; // Amount in ETH
  password?: string;
}) => {
  const evmClient = await authenticatedEvmClient();

  // Get key shares for imported wallet
  const keyShares = await evmClient.getExternalServerKeyShares({
    accountAddress: walletAddress
  });

  // Create public client
  const publicClient = evmClient.createViemPublicClient({
    chain: base,
    rpcUrl: 'https://mainnet.base.org',
  });

  // Check balance first
  const balance = await publicClient.getBalance({
    address: walletAddress as `0x${string}`,
  });

  const amountWei = parseEther(amount);
  if (balance < amountWei) {
    throw new Error('Insufficient balance');
  }

  // Prepare and sign transaction
  const preparedTx = await publicClient.prepareTransactionRequest({
    to: toAddress as `0x${string}`,
    value: amountWei,
    chain: base,
    account: walletAddress as `0x${string}`,
  });

  const signedTx = await evmClient.signTransaction({
    senderAddress: walletAddress as `0x${string}`,
    externalServerKeyShares: keyShares,
    transaction: preparedTx,
    password,
  });

  // Send transaction
  const walletClient = createWalletClient({
    chain: base,
    transport: http('https://mainnet.base.org'),
    account: walletAddress as `0x${string}`,
  });

  const txHash = await walletClient.sendRawTransaction({
    serializedTransaction: signedTx,
  });

  return txHash;
};

// Usage
const txHash = await sendEthFromImportedWallet({
  walletAddress: '0xYourImportedWalletAddress',
  toAddress: '0xRecipientAddress',
  amount: '0.1',
  password: 'your-wallet-password',
});

console.log('Transaction sent:', txHash);

Best Practices

  1. Key Share Management: Always retrieve fresh key shares before operations
  2. Balance Checking: Verify sufficient balance before sending transactions
  3. Password Handling: Check if password is required and handle accordingly
  4. Error Handling: Implement proper error handling for all wallet operations
  5. Security: Never expose key shares in client-side code

Next Steps