Comprehensive error handling system for Ledger hardware wallet applications and libraries
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Error classes for account management and balance validation including insufficient funds, account state issues, and transaction validation errors.
interface Account {
balance: number;
delegatedBalance: number;
subAccounts: Account[];
deviceId?: string;
}Errors related to account requirements and validation.
const AccountNameRequiredError: CustomErrorFunc;
const AccountNotSupported: CustomErrorFunc;
const NoAddressesFound: CustomErrorFunc;
const WrongDeviceForAccount: CustomErrorFunc;Usage Examples:
import {
AccountNameRequiredError,
AccountNotSupported,
NoAddressesFound,
WrongDeviceForAccount
} from "@ledgerhq/errors";
// Validate account name requirement
function createAccount(name?: string) {
if (!name || name.trim() === "") {
throw new AccountNameRequiredError("Account name is required");
}
}
// Handle unsupported account types
function validateAccountType(accountType: string) {
const supportedTypes = ["bitcoin", "ethereum", "litecoin"];
if (!supportedTypes.includes(accountType)) {
throw new AccountNotSupported(`Account type '${accountType}' is not supported`);
}
}
// Handle missing addresses
if (addresses.length === 0) {
throw new NoAddressesFound("No addresses found for this account");
}
// Validate device-account pairing
if (account.deviceId !== connectedDevice.id) {
throw new WrongDeviceForAccount("This account belongs to a different device");
}Errors related to insufficient balances and spending limitations.
const NotEnoughBalance: CustomErrorFunc;
const NotEnoughBalanceToDelegate: CustomErrorFunc;
const NotEnoughBalanceInParentAccount: CustomErrorFunc;
const NotEnoughSpendableBalance: CustomErrorFunc;
const NotEnoughBalanceBecauseDestinationNotCreated: CustomErrorFunc;Usage Examples:
import {
NotEnoughBalance,
NotEnoughBalanceToDelegate,
NotEnoughBalanceInParentAccount,
NotEnoughSpendableBalance,
NotEnoughBalanceBecauseDestinationNotCreated
} from "@ledgerhq/errors";
// Validate sufficient balance for transaction
function validateTransactionAmount(balance: number, amount: number, fee: number) {
if (balance < amount + fee) {
throw new NotEnoughBalance(
`Insufficient balance: ${balance} < ${amount + fee} (amount + fee)`
);
}
}
// Validate delegation balance
function validateDelegation(balance: number, delegationAmount: number, minimumRequired: number) {
if (balance < minimumRequired) {
throw new NotEnoughBalanceToDelegate(
`Minimum balance of ${minimumRequired} required for delegation`
);
}
}
// Validate parent account for sub-accounts
function validateSubAccountOperation(parentBalance: number, requiredAmount: number) {
if (parentBalance < requiredAmount) {
throw new NotEnoughBalanceInParentAccount(
"Parent account has insufficient balance for this operation"
);
}
}
// Validate spendable balance (excluding locked/pending funds)
function validateSpendableAmount(totalBalance: number, lockedAmount: number, spendAmount: number) {
const spendableBalance = totalBalance - lockedAmount;
if (spendableBalance < spendAmount) {
throw new NotEnoughSpendableBalance(
`Only ${spendableBalance} available to spend (${lockedAmount} locked)`
);
}
}
// Handle destination account creation requirement
function validateDestinationAccount(destinationExists: boolean, amount: number, minimumCreation: number) {
if (!destinationExists && amount < minimumCreation) {
throw new NotEnoughBalanceBecauseDestinationNotCreated(
`Minimum ${minimumCreation} required to create destination account`
);
}
}Errors specific to delegation and staking operations.
const RecommendSubAccountsToEmpty: CustomErrorFunc;
const RecommendUndelegation: CustomErrorFunc;Usage Examples:
import {
RecommendSubAccountsToEmpty,
RecommendUndelegation
} from "@ledgerhq/errors";
// Recommend emptying sub-accounts before main operation
function checkSubAccounts(subAccounts: Account[]) {
const hasBalance = subAccounts.some(account => account.balance > 0);
if (hasBalance) {
throw new RecommendSubAccountsToEmpty(
"Please empty sub-accounts before performing this operation"
);
}
}
// Recommend undelegation before account operations
function checkDelegatedBalance(delegatedAmount: number) {
if (delegatedAmount > 0) {
throw new RecommendUndelegation(
"Please undelegate your funds before closing the account"
);
}
}
// Example usage in account management
function closeAccount(account: Account) {
// Check for delegated funds
if (account.delegatedBalance > 0) {
throw new RecommendUndelegation(
`Account has ${account.delegatedBalance} delegated. Undelegate first.`
);
}
// Check sub-accounts
checkSubAccounts(account.subAccounts);
// Proceed with account closure
performAccountClosure(account);
}Errors specific to Tezos originated accounts and their limitations.
const UnavailableTezosOriginatedAccountReceive: CustomErrorFunc;
const UnavailableTezosOriginatedAccountSend: CustomErrorFunc;Usage Examples:
import {
UnavailableTezosOriginatedAccountReceive,
UnavailableTezosOriginatedAccountSend
} from "@ledgerhq/errors";
// Handle Tezos originated account receive limitations
function validateTezosReceive(account: TezosAccount) {
if (account.type === "originated" && !account.canReceive) {
throw new UnavailableTezosOriginatedAccountReceive(
"This Tezos originated account cannot receive funds"
);
}
}
// Handle Tezos originated account send limitations
function validateTezosSend(account: TezosAccount) {
if (account.type === "originated" && !account.canSend) {
throw new UnavailableTezosOriginatedAccountSend(
"This Tezos originated account cannot send funds"
);
}
}
// Example usage in transaction validation
function validateTezosTransaction(fromAccount: TezosAccount, toAccount: TezosAccount) {
validateTezosSend(fromAccount);
validateTezosReceive(toAccount);
console.log("Tezos transaction validation passed");
}