CtrlK
CommunityDocumentationLog inGet started
Tessl Logo

tessl/npm-ledgerhq--errors

Comprehensive error handling library for the Ledger ecosystem with unified error classes, serialization, and hardware wallet status codes

Overview
Eval results
Files

user-errors.mddocs/

User Interaction Errors

Error classes for user-initiated cancellations, refusals, interaction-related failures, and manager operations.

Capabilities

User Refusal Errors

Error classes for operations that were declined or refused by the user on the device or in the interface.

const UserRefusedDeviceNameChange: CustomErrorFunc;
const UserRefusedAddress: CustomErrorFunc;
const UserRefusedFirmwareUpdate: CustomErrorFunc;
const UserRefusedAllowManager: CustomErrorFunc;
const UserRefusedOnDevice: CustomErrorFunc;

Usage Examples:

import { 
  UserRefusedDeviceNameChange,
  UserRefusedAddress,
  UserRefusedFirmwareUpdate,
  UserRefusedAllowManager,
  UserRefusedOnDevice
} from "@ledgerhq/errors";

// User declined device name change
throw new UserRefusedDeviceNameChange("User declined to change device name");

// User refused to verify address on device
throw new UserRefusedAddress("User refused address verification on device", {
  requestedAddress: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"
});

// User declined firmware update
throw new UserRefusedFirmwareUpdate("User declined firmware update", {
  currentVersion: "2.0.0",
  availableVersion: "2.1.0"
});

// User refused to allow manager access
throw new UserRefusedAllowManager("User refused to allow manager access to device");

// General user refusal on device (typically for transaction signing)  
throw new UserRefusedOnDevice("User refused the operation on device", {
  operation: "transaction_signing",
  transactionId: "tx_abc123"
});

Transport User Cancellation Errors

Error classes for user-initiated cancellations during transport operations and device selection.

const TransportOpenUserCancelled: CustomErrorFunc;
const TransportWebUSBGestureRequired: CustomErrorFunc;

Usage Examples:

import { 
  TransportOpenUserCancelled,
  TransportWebUSBGestureRequired
} from "@ledgerhq/errors";

// User cancelled device selection or transport opening
throw new TransportOpenUserCancelled("User cancelled device selection", {
  availableDevices: ["Ledger Nano S", "Ledger Nano X"],
  selectionTimeout: "30 seconds"
});

// WebUSB requires user gesture to access device
throw new TransportWebUSBGestureRequired("WebUSB requires user gesture to access device", {
  suggestedAction: "Click a button to trigger user gesture",
  securityReason: "Browser security policy"
});

Manager Operation Errors

Error classes for Ledger Manager operations including app installation, uninstallation, dependencies.

const ManagerAppAlreadyInstalledError: CustomErrorFunc;
const ManagerAppRelyOnBTCError: CustomErrorFunc;
const ManagerAppDepInstallRequired: CustomErrorFunc;
const ManagerAppDepUninstallRequired: CustomErrorFunc;
const ManagerDeviceLockedError: CustomErrorFunc;
const ManagerFirmwareNotEnoughSpaceError: CustomErrorFunc;
const ManagerNotEnoughSpaceError: CustomErrorFunc;
const ManagerUninstallBTCDep: CustomErrorFunc;

Usage Examples:

import { 
  ManagerAppAlreadyInstalledError,
  ManagerAppRelyOnBTCError,
  ManagerAppDepInstallRequired,
  ManagerAppDepUninstallRequired,
  ManagerDeviceLockedError,
  ManagerFirmwareNotEnoughSpaceError,
  ManagerNotEnoughSpaceError,
  ManagerUninstallBTCDep
} from "@ledgerhq/errors";

// App already installed
throw new ManagerAppAlreadyInstalledError("Bitcoin app is already installed on device", {
  appName: "Bitcoin",
  installedVersion: "2.0.1"
});

// App depends on Bitcoin app
throw new ManagerAppRelyOnBTCError("This app requires Bitcoin app to be installed", {
  requestedApp: "Bitcoin Cash",
  dependency: "Bitcoin"
});

// App dependency installation required
throw new ManagerAppDepInstallRequired("Required dependency must be installed first", {
  requestedApp: "Ethereum",
  requiredDependency: "Bitcoin",
  action: "Install Bitcoin app first"
});

// App dependency uninstallation required
throw new ManagerAppDepUninstallRequired("Dependent apps must be uninstalled first", {
  appToUninstall: "Bitcoin",
  dependentApps: ["Bitcoin Cash", "Litecoin"],
  action: "Uninstall dependent apps first"
});

// Device locked during manager operation
throw new ManagerDeviceLockedError("Device is locked - please unlock to continue", {
  operation: "app_installation",
  requiredAction: "Enter PIN on device"
});

// Insufficient space for firmware
throw new ManagerFirmwareNotEnoughSpaceError("Insufficient space for firmware update", {
  requiredSpace: "512 KB",
  availableSpace: "256 KB",
  suggestedAction: "Uninstall unused apps"
});

// Insufficient space for app installation
throw new ManagerNotEnoughSpaceError("Insufficient space for app installation", {
  appName: "Ethereum",
  requiredSpace: "150 KB",
  availableSpace: "80 KB",
  installedApps: ["Bitcoin", "XRP", "Litecoin"]
});

// Cannot uninstall Bitcoin due to dependencies
throw new ManagerUninstallBTCDep("Cannot uninstall Bitcoin - other apps depend on it", {
  dependentApps: ["Bitcoin Cash", "Litecoin", "Dogecoin"],
  action: "Uninstall dependent apps first"
});

User Experience Patterns

Handling User Refusals

Common patterns for gracefully handling user refusals:

import { 
  UserRefusedOnDevice,
  UserRefusedAddress,
  TransportOpenUserCancelled
} from "@ledgerhq/errors";

async function performUserInteraction(operation: () => Promise<any>) {
  try {
    return await operation();
  } catch (error) {
    if (error instanceof UserRefusedOnDevice) {
      // Show user-friendly message for transaction refusal
      console.log("Transaction was cancelled on your Ledger device");
      return { cancelled: true, reason: "user_refused" };
    }
    
    if (error instanceof UserRefusedAddress) {
      // Allow user to retry address verification
      console.log("Address verification was cancelled. You can retry if needed.");
      return { cancelled: true, reason: "address_verification_refused" };
    }
    
    if (error instanceof TransportOpenUserCancelled) {
      // User cancelled device selection
      console.log("Device selection was cancelled");
      return { cancelled: true, reason: "device_selection_cancelled" };
    }
    
    throw error; // Re-throw if not a user cancellation
  }
}

Manager Operation Flow

import { 
  ManagerAppAlreadyInstalledError,
  ManagerAppDepInstallRequired,
  ManagerNotEnoughSpaceError
} from "@ledgerhq/errors";

async function installApp(appName: string) {
  try {
    await performAppInstallation(appName);
    console.log(`${appName} app installed successfully`);
  } catch (error) {
    if (error instanceof ManagerAppAlreadyInstalledError) {
      console.log(`${appName} app is already installed`);
      return { success: true, alreadyInstalled: true };
    }
    
    if (error instanceof ManagerAppDepInstallRequired) {
      console.log(`Installing required dependency: ${error.requiredDependency}`);
      await installApp(error.requiredDependency);
      return installApp(appName); // Retry after dependency installation
    }
    
    if (error instanceof ManagerNotEnoughSpaceError) {
      console.log("Insufficient space. Consider uninstalling unused apps:");
      console.log(error.installedApps.join(", "));
      throw error;
    }
    
    throw error;
  }
}

WebUSB Gesture Handling

import { TransportWebUSBGestureRequired } from "@ledgerhq/errors";

async function connectWithGesture() {
  try {
    return await connectToDevice();
  } catch (error) {
    if (error instanceof TransportWebUSBGestureRequired) {
      // Show UI element that requires user click
      return new Promise((resolve, reject) => {
        const button = document.createElement('button');
        button.textContent = 'Connect to Ledger Device';
        button.onclick = async () => {
          try {
            const result = await connectToDevice();
            button.remove();
            resolve(result);
          } catch (err) {
            button.remove();
            reject(err);
          }
        };
        document.body.appendChild(button);
      });
    }
    throw error;
  }
}

Type Definitions

type CustomErrorFunc = (
  message?: string,
  fields?: { [key: string]: any }
) => void;
tessl i tessl/npm-ledgerhq--errors@5.50.0

docs

account-errors.md

device-errors.md

index.md

network-errors.md

transport-errors.md

user-errors.md

utilities.md

validation-errors.md

tile.json