Class BrowserWallet

    Wallet implementation for browser environments

    BrowserWallet supports two modes of operation:

    1. Extension Mode (Default):

    • Integrates with the Klever Browser Extension
    • Users sign transactions through the extension UI
    • Most secure for dApps - private keys never leave the extension
    • Supports account switching and network changes
    • Requires Klever Extension to be installed

    2. Private Key Mode:

    • Direct signing using a private key (like NodeWallet)
    • Useful for testing or non-extension wallets
    • Can also use PEM files with optional password protection
    • Less secure - private keys are in browser memory

    Security Considerations:

    • Extension mode is recommended for production dApps
    • Private key mode should only be used for testing or trusted environments
    • Never expose private keys in production code
    • Always validate transaction details before signing

    Event Handling:

    • Emits 'accountChanged' when user switches accounts in extension
    • Emits 'disconnect' when user switches to a different blockchain
    • Events are debounced to prevent rapid firing
    // Extension mode (recommended for dApps)
    import { BrowserWallet } from '@klever/connect-wallet'
    import { KleverProvider } from '@klever/connect-provider'

    const provider = new KleverProvider({ network: 'mainnet' })
    const wallet = new BrowserWallet(provider)

    try {
    await wallet.connect()
    console.log('Connected:', wallet.address)

    // Listen for account changes
    wallet.on('accountChanged', ({ address }) => {
    console.log('Account changed to:', address)
    })

    // Send a transaction (extension will prompt user)
    const result = await wallet.transfer({
    receiver: 'klv1...',
    amount: 1000000,
    })
    console.log('Transaction hash:', result.hash)
    } catch (error) {
    if (error.message.includes('Extension not found')) {
    console.log('Please install Klever Extension')
    }
    }
    // Private key mode (testing only)
    const wallet = new BrowserWallet(provider, {
    privateKey: '0x123...',
    })
    await wallet.connect() // No extension needed
    // PEM file mode with password
    const pemContent = '-----BEGIN PRIVATE KEY-----...'
    const wallet = new BrowserWallet(provider, {
    pemContent,
    pemPassword: 'my-secure-password',
    })
    await wallet.connect()
    Hierarchy
    Index

    Constructors

    • Create a new BrowserWallet instance

      Parameters

      • provider: IProvider

        Provider instance for blockchain communication

      • Optionalconfig: WalletConfig

        Optional wallet configuration

        • privateKey

          Private key for private key mode (hex string)

        • pemContent

          PEM file content for PEM mode

        • pemPassword

          Optional password for encrypted PEM files

      Returns BrowserWallet

      If used in non-browser environment

      // Extension mode (default)
      const wallet = new BrowserWallet(provider)

      // Private key mode
      const wallet = new BrowserWallet(provider, {
      privateKey: '0x123...',
      })

      // PEM mode
      const wallet = new BrowserWallet(provider, {
      pemContent: pemFileContent,
      pemPassword: 'optional-password',
      })

    Properties

    _address: string = ''
    _connected: boolean = false
    _events: Map<WalletEvent, Set<WalletEventHandler>> = ...
    _provider: IProvider
    _publicKey: string = ''

    Accessors

    Methods

    • Build an unsigned transaction

      Creates a transaction with the specified contracts and parameters. The transaction is built but not signed.

      Extension Mode:

      • Uses KleverWeb extension's transaction builder
      • Automatically fetches nonce and other parameters

      Private Key Mode:

      • Uses TransactionBuilder with provider
      • Fetches account data for proper transaction construction

      Parameters

      • contracts: ContractRequestData[]

        Array of contract requests to include in the transaction

      • OptionaltxData: string[]

        Optional transaction data (for smart contracts or metadata)

      • Optionaloptions: { kdaFee?: string; nonce?: number }

        Optional transaction options

        • OptionalkdaFee?: string

          Asset ID to pay fees with (defaults to KLV)

        • Optionalnonce?: number

          Manual nonce override (auto-fetched if not provided)

      Returns Promise<Transaction>

      Unsigned transaction ready to be signed

      If wallet is not connected

      If transaction building fails

      // Build a simple transfer
      const tx = await wallet.buildTransaction([
      {
      contractType: TXType.Transfer,
      receiver: 'klv1...',
      amount: '1000000',
      }
      ])

      // Sign and broadcast
      const signedTx = await wallet.signTransaction(tx)
      const hash = await wallet.broadcastTransaction(signedTx)
      // Build multi-contract transaction
      const tx = await wallet.buildTransaction([
      { contractType: TXType.Transfer, receiver: 'klv1...', amount: '1000000' },
      { contractType: TXType.Claim, claimType: 0 },
      ])
      // Build with custom nonce and KDA fee
      const tx = await wallet.buildTransaction(
      [{ contractType: TXType.Transfer, receiver: 'klv1...', amount: '1000000' }],
      undefined,
      { nonce: 42, kdaFee: 'KFI' }
      )
    • Build and sign a transfer transaction

      Convenience method that combines building and signing a transfer in one call.

      Extension Mode:

      • Uses KleverWeb extension
      • User confirms the transfer in extension UI

      Private Key Mode:

      • Uses TransactionBuilder + local signing
      • Signs immediately without confirmation

      Parameters

      • to: string

        Recipient address (bech32 format)

      • amount: string | number

        Amount to transfer in smallest units (KLV has 6 decimals)

      • Optionaltoken: string

        Optional token ID (defaults to 'KLV')

      Returns Promise<Transaction>

      Signed transaction ready to broadcast

      If wallet is not connected

      If user rejects in extension mode

      // Transfer 1 KLV (1000000 smallest units)
      const signedTx = await wallet.buildTransfer(
      'klv1...',
      1000000
      )
      const hash = await wallet.broadcastTransaction(signedTx)
      // Transfer custom token
      const signedTx = await wallet.buildTransfer(
      'klv1...',
      5000000,
      'KFI-ABC' // Custom token ID
      )
    • Connect to the wallet

      Extension Mode:

      • Checks for Klever Extension installation
      • Retrieves the current wallet address from extension
      • Sets up event listeners for account changes
      • Prompts user if no wallet is connected in extension

      Private Key Mode:

      • Derives address from the provided private key or PEM file
      • No user interaction required

      Returns Promise<void>

      In extension mode: If extension is not installed or no wallet is connected

      In private key mode: If key is invalid or PEM decryption fails

      connect - Emits when successfully connected with { address: string }

      // Extension mode - user must have extension installed
      const wallet = new BrowserWallet(provider)
      try {
      await wallet.connect()
      console.log('Connected to:', wallet.address)
      } catch (error) {
      console.error('Extension not found or no wallet connected')
      }
      // Private key mode - instant connection
      const wallet = new BrowserWallet(provider, { privateKey: '0x123...' })
      await wallet.connect() // No extension needed
    • Create a new account using the extension Extension mode only

      Returns Promise<{ address: string; privateKey: string }>

      PEM response with private key and address

    • Disconnect from the wallet

      Extension Mode:

      • Disconnects from KleverHub
      • Removes event listeners
      • Clears connection state

      Private Key Mode:

      • Clears connection state
      • Optionally removes private key from memory (clearPrivateKey=true)

      Parameters

      • clearPrivateKey: boolean = false

        In private key mode, whether to clear the private key from memory (default: false) - false: Keep key in memory for quick reconnection - true: Remove key from memory (recommended for security)

      Returns Promise<void>

      disconnect - Emits when disconnected

      // Extension mode
      await wallet.disconnect()

      // Private key mode - clear key for security
      await wallet.disconnect(true)
    • Encrypts the wallet's private key to a keystore format

      Only available in private key mode - extension mode wallets cannot be encrypted as the private key is stored in the browser extension.

      Creates an encrypted keystore (Web3 Secret Storage format) that can be saved and later decrypted using WalletFactory.fromEncryptedJson().

      Security Notes:

      • Use a strong password with mixed characters, numbers, and symbols
      • The scryptN parameter controls encryption strength vs speed
      • Higher scryptN = more secure but slower (default: 262144)
      • Never store the password with the keystore

      Parameters

      • password: string

        The password to encrypt the keystore

      • Optionaloptions: EncryptOptions

        Optional scrypt parameters for encryption strength

        • scryptN

          Work factor (default: 262144, min: 4096)

      Returns Promise<Keystore>

      A promise that resolves to the encrypted keystore object

      If wallet is not connected or in extension mode

      // Private key mode only
      const wallet = new BrowserWallet(provider, { privateKey: '0x123...' })
      await wallet.connect()

      // Encrypt with default parameters
      const keystore = await wallet.encrypt('my-secure-password')

      // Save to localStorage or download as file
      localStorage.setItem('wallet', JSON.stringify(keystore))
      // Encrypt with custom parameters (faster, for testing)
      const testKeystore = await wallet.encrypt('password', {
      scryptN: 4096 // Faster but less secure
      })
    • Get account information In extension mode: Uses KleverWeb extension In private key mode: Uses provider

      Parameters

      • Optionaladdress: string

        Optional address to query (defaults to current wallet address)

      Returns Promise<
          {
              address: string;
              allowance?: number;
              balance?: number;
              nonce?: number;
              permissions?: string[];
              rootHash?: string;
              txCount?: number;
          },
      >

      Account information

    • Register an event handler

      Parameters

      • event: WalletEvent

        Event name ('connect', 'disconnect', 'accountChanged')

      • handler: WalletEventHandler

        Event handler function

      Returns void

    • Parse PEM file data using the extension Extension mode only

      Parameters

      • pemData: string

        PEM file content

      Returns Promise<{ address: string; privateKey: string }>

      Private key and address from PEM

    • Send a generic transaction In extension mode: Uses KleverWeb extension for building and broadcasting In private key mode: Uses base implementation (local signing + provider broadcast)

      Parameters

      • contract: ContractRequestData

      Returns Promise<TransactionSubmitResult>

    • Sign a message with the wallet's private key

      SECURITY WARNING:

      • Only sign messages from trusted sources
      • Verify message content before signing
      • Extension mode will show a confirmation dialog to the user
      • Malicious messages could trick users into authorizing unintended actions

      Extension Mode:

      • Prompts user to confirm signing in extension UI
      • User can review message before approving
      • More secure as private key never leaves extension

      Private Key Mode:

      • Signs immediately without user confirmation
      • Use only in trusted environments

      Parameters

      • message: string | Uint8Array<ArrayBufferLike>

        Message to sign (string or bytes)

      Returns Promise<Signature>

      Signature object with .toHex() and .toBase64() methods

      If wallet is not connected

      If user rejects signing in extension mode

      // Extension mode - user will see confirmation dialog
      const message = "Sign in to My dApp"
      const signature = await wallet.signMessage(message)
      console.log('Signature:', signature.toHex())
      // Private key mode - immediate signing
      const signature = await wallet.signMessage("Hello, Klever!")
      const isValid = await wallet.verifyMessage("Hello, Klever!", signature)
    • Sign a transaction with the wallet's private key

      SECURITY WARNING:

      • Always verify transaction details before signing
      • Check recipient address, amount, and contract type
      • Extension mode shows transaction details to user for review
      • Signed transactions authorize blockchain state changes

      Extension Mode:

      • Displays transaction in extension UI for user approval
      • User can review all details before signing
      • Most secure - private key never exposed

      Private Key Mode:

      • Signs immediately without user confirmation
      • Validate transaction parameters before calling

      Parameters

      Returns Promise<Transaction>

      Signed transaction ready for broadcast

      If wallet is not connected

      If user rejects signing in extension mode

      // Build a transaction
      const unsignedTx = await wallet.buildTransaction([
      {
      contractType: TXType.Transfer,
      receiver: 'klv1...',
      amount: '1000000',
      }
      ])

      // Sign it (extension will prompt user)
      const signedTx = await wallet.signTransaction(unsignedTx)

      // Broadcast
      const hash = await wallet.broadcastTransaction(signedTx)
    • Validate a signature using the extension Extension mode only

      Parameters

      • message: string

        The original message that was signed

      • signature: string

        The signature to validate

      • address: string

        The address of the expected signer

      Returns Promise<{ isValid: boolean; signer?: string }>

      Validation result with signer information

    • Verify a message signature

      Parameters

      • message: string | Uint8Array<ArrayBufferLike>

        The message that was signed (string or bytes)

      • signature: string | Signature

        The signature to verify (Signature object, hex string, or base64 string)

      Returns Promise<boolean>

      true if signature is valid, false otherwise

      const message = "Hello, Klever!"
      const signature = await wallet.signMessage(message)

      // Verify with Signature object
      const isValid = await wallet.verifyMessage(message, signature)

      // Or verify with hex string
      const isValidHex = await wallet.verifyMessage(message, signature.toHex())

      // Or verify with base64 string
      const isValidBase64 = await wallet.verifyMessage(message, signature.toBase64())
      console.log('Signature valid:', isValid)