Skip to main content
Rainbow Wallet supports multiple accounts per wallet, each with customizable profiles and automatic ENS integration.

Account Structure

Each account in Rainbow has:
  • Unique Address: Ethereum address derived from wallet
  • Account Label: Custom name for easy identification
  • Color: Visual identifier (color-coded)
  • Emoji Symbol: Quick visual reference
  • ENS Name: Automatically fetched if registered
  • Avatar: ENS avatar or custom image

Creating New Accounts

In Existing Wallet

Add accounts to any HD wallet:
1

Open Wallet Settings

Navigate to Settings > Wallets and select your wallet
2

Create Account

Tap “Create New Account” to generate the next account in the derivation path
3

Customize Account

Set account name, color, and emoji identifier
4

Account Ready

New account is immediately available for receiving and sending

Implementation

// From src/state/wallets/walletsStore.ts
createAccountInExistingWallet: async (data: {
  id: RainbowWallet['id'];
  name: RainbowWallet['name'];
  color: RainbowWallet['color'] | null;
}) => {
  const wallets = get().wallets;
  const wallet = wallets[data.id];
  
  if (!wallet) return;
  
  // Generate new account from seed
  const newAccount = await generateAccount({
    walletId: wallet.id,
    color: data.color,
    name: data.name,
  });
  
  // Update wallet with new account
  const updatedWallet = {
    ...wallet,
    addresses: [...wallet.addresses, newAccount],
  };
  
  await saveAllWallets({
    ...wallets,
    [data.id]: updatedWallet,
  });
  
  // Refresh wallet info to fetch ENS
  await get().refreshWalletInfo();
}

Account Profile Information

Rainbow automatically enriches account profiles:
interface AccountProfileInfo {
  accountAddress: Address;
  accountColor: number;        // Color index for UI
  accountENS?: string;         // ENS name if registered
  accountImage?: string | null; // ENS avatar or custom
  accountName?: string;        // Custom label
  accountSymbol?: string | false; // Emoji identifier
}

Fetching Account Info

// From src/state/wallets/walletsStore.ts
getAccountProfileInfo: (address?: Address) => {
  const targetAddress = address || get().accountAddress;
  const { wallets, walletNames } = get();
  
  // Find account in wallets
  let accountInfo = null;
  for (const wallet of Object.values(wallets)) {
    const account = wallet.addresses?.find(
      acc => acc.address.toLowerCase() === targetAddress.toLowerCase()
    );
    if (account) {
      accountInfo = account;
      break;
    }
  }
  
  return {
    accountAddress: targetAddress,
    accountColor: accountInfo?.color || addressHashedColorIndex(targetAddress),
    accountENS: walletNames[targetAddress],
    accountImage: accountInfo?.image,
    accountName: accountInfo?.label,
    accountSymbol: accountInfo?.emoji || addressHashedEmoji(targetAddress),
  };
}

Customizing Accounts

Update Account Details

Users can customize account appearance and metadata:
updateAccountInfo: ({
  address,
  walletId,
  color,
  emoji,
  image,
  label,
}: {
  address: Address;
  walletId: string;
} & Partial<RainbowAccount>) => {
  const wallets = get().wallets;
  const wallet = wallets[walletId];
  
  if (!wallet) return;
  
  // Find and update account
  const updatedAddresses = wallet.addresses.map(account => {
    if (account.address.toLowerCase() === address.toLowerCase()) {
      return {
        ...account,
        ...(color !== undefined && { color }),
        ...(emoji !== undefined && { emoji }),
        ...(image !== undefined && { image }),
        ...(label !== undefined && { label }),
      };
    }
    return account;
  });
  
  // Save updated wallet
  const updatedWallet = { ...wallet, addresses: updatedAddresses };
  saveAllWallets({ ...wallets, [walletId]: updatedWallet });
}

Available Customizations

Set a custom label for easy identification:
  • “Main Account”
  • “Trading”
  • “Cold Storage”
  • Any custom text

ENS Integration

Rainbow automatically fetches and displays ENS names:

Automatic ENS Resolution

1

Account Detection

When account is created or imported, Rainbow checks for ENS reverse record
2

Name Fetching

If ENS name exists, it’s fetched and cached:
const ensName = await fetchReverseRecordWithRetry(address);
3

Avatar Fetching

ENS avatar is retrieved if configured:
const avatar = await fetchENSAvatarWithRetry(ensName);
4

Profile Update

Account profile updated with ENS data:
  • Name displayed instead of address
  • Avatar shown in UI
  • Cached for performance

Refresh Wallet Info

Manually refresh ENS data for all accounts:
refreshWalletInfo: async (props?: { 
  addresses?: string[]; 
  useCachedENS?: boolean; 
}) => {
  const { addresses = [], useCachedENS = true } = props || {};
  const { wallets } = get();
  
  // Get all addresses to refresh
  const allAddresses = addresses.length > 0 
    ? addresses 
    : Object.values(wallets).flatMap(wallet => 
        wallet.addresses.map(acc => acc.address)
      );
  
  // Fetch ENS names
  const ensNames = await Promise.all(
    allAddresses.map(address => 
      fetchReverseRecordWithRetry(address, { useCachedENS })
    )
  );
  
  // Update wallet names
  const walletNames: WalletNames = {};
  allAddresses.forEach((address, i) => {
    if (ensNames[i]) {
      walletNames[address] = ensNames[i];
    }
  });
  
  set({ walletNames });
}
ENS names are cached to improve performance. Use refreshWalletInfo({ useCachedENS: false }) to force a fresh lookup from the blockchain.

Account Switching

Switch between accounts in the same wallet or different wallets:

Within Same Wallet

  • Tap account selector in navigation
  • Choose from accounts in current wallet
  • Assets and balances update instantly

Between Wallets

  • Open wallet selector
  • Choose different wallet
  • Select account within that wallet
  • Full app state switches to new context

Implementation Details

setAccountAddress: (address: Address) => {
  set({ accountAddress: address });
  
  // Trigger dependent stores to update
  useUserAssetsStore.getState().setAddress(address);
  useNftsStore.getState().setAddress(address);
}
Switching accounts changes the entire app context. Any pending transactions or unsaved state may be lost.

Account Security

Read-Only Detection

getIsReadOnlyWallet: () => {
  const { selected } = get();
  return selected?.type === WalletTypes.readOnly;
}
Read-only accounts:
  • Cannot sign transactions
  • Can view balances and history
  • Useful for monitoring addresses

Damaged Wallet Detection

getIsDamagedWallet: (walletId?: string) => {
  const { selected, wallets } = get();
  const targetWalletId = walletId || selected?.id;
  
  if (!targetWalletId) return false;
  
  const wallet = wallets[targetWalletId];
  return wallet?.damaged === true;
}
Damaged wallets are flagged when:
  • Keychain data is corrupted
  • Private keys are inaccessible
  • Backup restoration fails

Best Practices

Create separate accounts for different use cases:
  • Main Account: Daily transactions
  • Savings: Long-term holdings
  • DeFi: Protocol interactions
  • NFTs: Collectibles and art
  • Trading: Active trading
Clear account names help prevent errors:
  • Avoid generic names like “Account 1”
  • Include purpose: “ETH Savings”, “NFT Collection”
  • Use emoji for quick visual identification
Keep ENS data fresh:
  • Refresh wallet info monthly
  • Update after changing ENS settings
  • Verify ENS names before sending large amounts
Track activity across all accounts:
  • Check balances regularly
  • Review transaction history
  • Set up notifications for activity

Wallet Overview

Learn about wallet types and management

Backup & Restore

Back up accounts to cloud storage

Assets Management

View assets across all accounts

Build docs developers (and LLMs) love