Skip to main content
The Mnemonic wallet provider enables automated testing of dApps by allowing direct entry of account mnemonics. While this removes the security features of traditional wallets that require explicit user interaction, it provides a way to automate end-to-end testing of your application.

Overview

Most supported wallets are designed for production use and require manual user interaction for security. The Mnemonic provider removes these security constraints, making it ideal for:
  • End-to-end (E2E) testing
  • CI/CD pipelines
  • Test automation
The Mnemonic wallet is strictly for testing and development. For security reasons:
  • It cannot be used on MainNet
  • Mnemonics are stored in plaintext if persistence is enabled
  • Accounts should never hold real assets

Configuration

Add the Mnemonic provider to your WalletManager configuration:
import { WalletManager, WalletId } from '@txnlab/use-wallet'

const manager = new WalletManager({
  wallets: [
    // Production wallets...
    WalletId.PERA,
    WalletId.DEFLY,
    
    // Test wallet
    {
      id: WalletId.MNEMONIC,
      options: {
        // Optional: persist mnemonic to localStorage
        persistToStorage: false
      }
    }
  ],
  defaultNetwork: 'testnet'
})

Session persistence

By default, the Mnemonic provider does not persist sessions to localStorage. This means:
  • The mnemonic must be re-entered after page reloads
  • The wallet disconnects when closing/reloading the page
  • Sessions cannot be resumed automatically
To match the behavior of production wallets in tests, enable persistence:
{
  id: WalletId.MNEMONIC,
  options: {
    persistToStorage: true
  }
}
When persistence is enabled:
  • Mnemonics are stored in plaintext in localStorage
  • Sessions persist until explicitly disconnected
  • Any stored mnemonics should be considered compromised

End-to-end testing

The Mnemonic provider enables automated E2E testing with frameworks like Playwright, Cypress, or Selenium. It enables automated wallet connections and transaction signing without requiring manual user interaction.
1

Set up your test framework

Install your preferred testing framework and configure it for your application.
2

Handle the mnemonic prompt

The Mnemonic wallet prompts for a 25-word passphrase. Configure your test to provide this automatically.
3

Mock node responses

Mock responses from the Algorand node to create reliable and predictable tests.
4

Write your test scenarios

Test wallet connections, transactions, account switching, and error handling.

Example test

Here’s a basic example using Playwright that demonstrates connecting to the wallet and verifying the connection:
import { test, expect } from '@playwright/test'

test('wallet connection flow', async ({ page }) => {
  // Navigate to app
  await page.goto('/')
  
  // Mock Algod responses
  await mockAlgodResponses(page)
  
  // Handle mnemonic prompt
  page.on('dialog', (dialog) => dialog.accept(
    // !! WARNING !!
    // THIS ACCOUNT IS COMPROMISED
    // Use for testing only!
    // !! WARNING !!
    'sugar bronze century excuse animal jacket what rail biology symbol want craft annual soul increase question army win execute slim girl chief exhaust abstract wink'
  ))
  
  // Verify Mnemonic wallet is available
  await expect(page.getByRole('heading', { name: 'Mnemonic' })).toBeVisible()
  
  // Connect to wallet
  await page
    .locator('.wallet-group', {
      has: page.locator('h4', { hasText: 'Mnemonic' })
    })
    .getByRole('button', { name: 'Connect' })
    .click()
    
  // Verify connection succeeded
  await expect(page.getByRole('heading', { name: 'Mnemonic [active]' })).toBeVisible()
  
  // Verify correct account is connected
  await expect(page.getByRole('combobox')).toHaveValue(
    '3F3FPW6ZQQYD6JDC7FKKQHNGVVUIBIZOUI5WPSJEHBRABZDRN6LOTBMFEY'
  )
})

Mocking node responses

To create reliable and predictable tests, it’s recommended to mock responses from the Algorand node. This prevents tests from failing due to network issues or rate limits, and allows testing specific scenarios:
async function mockAlgodResponses(page: Page) {
  // Mock transaction parameters
  await page.route('**/v2/transactions/params', (route) => {
    route.fulfill({
      status: 200,
      body: JSON.stringify({
        'last-round': 1000,
        'consensus-version': 'test-1.0',
        'min-fee': 1000,
        'genesis-hash': 'SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=',
        'genesis-id': 'testnet-v1.0'
      })
    })
  })

  // Mock transaction submission
  await page.route('**/v2/transactions', (route) => {
    route.fulfill({
      status: 200,
      body: JSON.stringify({ txId: 'TEST_TX_ID' })
    })
  })
}

Best practices

When using the Mnemonic provider for testing:

Test account security

Generate dedicated test accounts that will never be used in production. Consider these accounts compromised as their mnemonics are stored in test files.

Mock API responses

Mock responses from the Algorand node to:
  • Prevent overwhelming API providers with test requests
  • Create predictable test scenarios
  • Test error handling
  • Speed up test execution

Test organization

Structure tests to cover different wallet operations:
  • Connection/disconnection flows
  • Account switching
  • Transaction signing
  • Error handling
  • Network switching

CI/CD integration

The Mnemonic provider works well in CI/CD pipelines since it doesn’t require user interaction. Consider:
  • Storing test mnemonics securely (e.g., in CI environment variables)
  • Running tests against LocalNet (sandbox) or a private network
  • Including wallet tests in your automated test suite
For complete testing examples, including mocking strategies and common test scenarios, see the E2E test examples in the repository.

Build docs developers (and LLMs) love