Skip to main content

Handle errors

Validate input before you call a state-changing method. Catch SDK errors at the boundary where your app can show a user-facing message or retry.

Validate the LTV result

Check the loan-to-value (LTV) result before you create a loan:

const ltv = client.quote.calculateLtv(request, pools, prices);

if (ltv.validationErrors.length > 0) {
return {
ok: false,
message: ltv.validationErrors.map((error) => error.message).join(" "),
};
}

Handle SDK errors

Catch exported SDK errors before you handle unknown errors:

import {
LiquidiumError,
LiquidiumErrorCode,
SimpleLoanCreatedError,
} from "@liquidium/client";

try {
const loan = await client.simpleLoans.create(request);
return loan;
} catch (error) {
if (error instanceof SimpleLoanCreatedError) {
return client.simpleLoans.get({ loanId: error.loanId });
}

if (error instanceof LiquidiumError) {
if (error.code === LiquidiumErrorCode.REQUEST_TIMEOUT) {
// Show retry copy or use the app's retry path.
}

throw error;
}

throw error;
}

If your UI needs different messages for timeout, transport, validation, or protocol failures, use the exported LiquidiumErrorCode values.

SimpleLoanCreatedError means the remote loan was created but response hydration failed. Recover with the error's loanId or ref through client.simpleLoans.get(...). Do not call create(...) again because that can create a duplicate loan.

Wallet-executed deposit, borrow, and withdraw amounts below SDK minimums throw or return validation errors before state-changing calls. To show the minimum next to an amount input, use getMinimumDepositAmount(asset), getMinimumBorrowAmount(asset), or getMinimumWithdrawAmount(asset). Manual deposit-address flows do not accept an amount, so callers must apply the deposit minimum before broadcasting.

Decide when to retry

Use the error type and the operation type before you retry:

ConditionAction
Read-only request fails with NETWORK_ERROR, SERVICE_UNAVAILABLE, or REQUEST_TIMEOUTRetry with your app's bounded backoff policy
State-changing request times outReload the related loan, activity, position, or history before you decide whether to submit another request
Request fails with VALIDATION_ERROR or a protocol errorCorrect the input or wait for the protocol state to change before you retry
SimpleLoanCreatedError is thrownRecover with client.simpleLoans.get(...); do not create another loan

The SDK does not define an application retry interval. Do not automatically repeat a state-changing method because an error might have occurred after the remote operation succeeded.

Validate destinations

Lending outflow and Simple Loan destinations are validated against the selected asset and delivery chain:

Asset pathChainAccepted destination family
BTC L1"BTC"Bitcoin mainnet chain address
Native ETH"ETH"Ethereum address
ETH L1 USDC/USDT"ETH"Ethereum address
ICP native"ICP"IC principal, ICRC account, or ICP account identifier
ckBTC, ckETH, ckUSDC, ckUSDT"ICP"IC principal

Lending uses chain and receiver. Simple Loans use borrow.chain, borrow.destination, refund.chain, and refund.destination. Prefer typed destination objects when the account family matters.

For lending, native ETH borrow and withdrawal destinations use a best-effort deployed-bytecode check. The SDK rejects a destination only when the check succeeds and confirms deployed bytecode. This includes smart contract wallets.

The SDK throws LiquidiumError with code LiquidiumErrorCode.INVALID_ADDRESS for malformed or reserved Ethereum addresses. It uses LiquidiumErrorCode.CONTRACT_DESTINATION_UNSUPPORTED when the best-effort check confirms that a native ETH lending destination has deployed bytecode. The Simple Loans API reports deployed-contract destination rejections as SDK API errors. Asset, chain, or destination-family mismatches use LiquidiumErrorCode.VALIDATION_ERROR. Catch these errors at the form boundary before retrying the flow.

When chain.id identifies Ethereum mainnet, lending queries the configured Ethereum Virtual Machine (EVM) client's getCode method. If the configured EVM client does not provide both chain.id and getCode, the SDK queries the Liquidium SDK API. RPC failures, API failures, and malformed responses do not block the outflow.

The SDK also validates the sender account for wallet-executed native ETH and ERC-20 supply as an EVM address. Deposit-address queries validate that the requested asset matches the selected ETH pool and reject malformed addresses returned by the deposit canister.