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

    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)
    • 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

      • payload: string

        Signature payload to validate

      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)