Create and track Simple Loans
Use Simple Loans for a checkout-style borrow flow. The SDK creates a generated Liquidium profile, returns transfer targets, and lets your app restore the loan from a short reference.
Simple Loan flow
The following table shows the flow and your app's responsibility at each step:
| Step | SDK call | Your app does |
|---|---|---|
| Load market data | client.market.listPools() and client.market.getAssetPrices() | Show supported collateral and borrow assets |
| Validate amounts | client.quote.calculateLtv(...) | Block too-small borrow amounts, an invalid loan-to-value (LTV) ratio, or frozen-pool input before creation |
| Create loan | client.simpleLoans.create(...) | Store loan.ref and show the selected quote from loan.initialDeposit.targets[chain] |
| Track loan | client.simpleLoans.get({ ref }), client.simpleLoans.find(...), and client.activities.list({ shortRef: ref }) | Reload state and monitor deposits, borrows, and repayments |
| Repay loan | Read loan.repayment.targets[chain] | If the selected quote exists and its amount > 0n, ask the user to send it to quote.target.address |
Create a loan
Use the following fields in a client.simpleLoans.create(...) request:
| Field | Description |
|---|---|
collateral | Collateral poolId, asset, and intended credited amount in base units |
borrow | Borrow poolId, asset, amount, delivery chain, and destination |
refund | Refund chain and destination for returned collateral |
ltvMaxBps | Maximum LTV in basis points, where 6_000n is 60% |
depositWindowSeconds | How long the user has to send collateral |
borrow.destination and refund.destination can be strings or typed account objects such as { type: "ChainAddress", address: "bc1q..." }, { type: "IcPrincipal", address: "aaaaa-aa" }, or { type: "IcrcAccount", address: "aaaaa-aa" }. The SDK validates that each destination family matches its selected asset and chain before creation.
Native ETH Simple Loans do not support borrow destinations with deployed contract bytecode. The same restriction applies to the refund destination when the collateral is native ETH. You do not need an Ethereum client for these checks.
Collateral minimums
The SDK rejects Simple Loan collateral below the configured deposit minimum before creating the loan:
| Asset | Minimum collateral amount |
|---|---|
| BTC | 5_100n sats |
| ETH | 5_000_000_000_000_000n wei (0.005 ETH) |
| ICP | 10_000n e8s |
| USDC | 1_000_000n base units |
| USDT | 1_000_000n base units |
If your UI displays or pre-checks the same minimum, use getMinimumDepositAmount(asset).
Borrow minimums
The SDK enforces these minimum borrow amounts before creation:
| Asset | Minimum borrow amount |
|---|---|
| BTC | 5_100n sats |
| ETH | 5_000_000_000_000_000n wei (0.005 ETH) |
| USDC | 1_000_000n base units |
| USDT | 1_000_000n base units |
If your UI displays or pre-checks the same minimum, use getMinimumBorrowAmount(asset).
ETH transfer rails
ETH pools expose native ETH targets under targets[Chain.ETH] and ckETH ICRC targets under targets[Chain.ICP]. Both routes use 18 decimals and amounts in wei. Native ETH transfers send value directly to the generated Ethereum address. ckETH transfers use the returned ICRC account.
Native ETH quotes use a 0.00025 ETH inflow-fee fallback when the live estimate fails or is non-positive. Repayment quotes expose inflowFeeEstimateAvailable: false when this fallback is used.
Restore a loan
Use the user-facing reference for refreshes, status pages, and support links:
const loan = await client.simpleLoans.get({ ref: savedReference });
Use the numeric loan ID when your backend stores it:
const loan = await client.simpleLoans.get({ loanId });
Use find(...) when the user might paste a short reference, numeric loan ID string, address, or transaction ID:
const results = await client.simpleLoans.find(addressOrTxidOrRef);
When its argument is a string, find(...) queries the SDK API search index and returns lightweight matches without hydrating every loan. It supports short references, numeric canister loan ID strings, generated deposit or repayment addresses, borrow or refund destination addresses, and indexed transaction IDs. After the user selects a match, use get({ ref }) or get({ loanId }).
Response fields
Most UIs need these fields after create(...) or get(...):
| Field | Description |
|---|---|
loan.ref | Short reference to save and show the user |
loan.status | Shared LiquidiumStatus with operation, state, confirmations, and requiredConfirmations |
loan.terms.ltvMaxBps | Maximum LTV selected at creation |
loan.terms.depositWindowSeconds | Deposit timeout selected at creation |
loan.collateral.decimals | Decimal scale for collateral display |
loan.borrow.decimals | Decimal scale for borrow, debt, and repayment display |
loan.initialDeposit.collateralAmount | Intended credited collateral target used for LTV |
loan.initialDeposit.decimals | Decimal scale for initial deposit amounts |
loan.initialDeposit.targets[chain] | Fee-inclusive amount, inflow fee, and target for an available collateral transfer rail |
loan.repayment.debtAmount | Current debt before transfer fees |
loan.repayment.targets[chain] | Fee-inclusive repayment amount, fee metadata, and target for an available repayment rail |
Target maps are partial. A missing chain entry means that transfer rail is unavailable, not that no debt exists. Check loan.repayment.debtAmount > 0n or the selected quote's amount > 0n before prompting for repayment.
client.simpleLoans.find(...) returns lightweight indexed fields, including loanId, ref, profileId, createdAt, collateral, and borrow. To load the full loan fields for a selected match, use client.simpleLoans.get(...). If you need active or completed flow activity, use client.activities.list(...) separately.
Diagnostic data
Diagnostic warmed-profile queries support both authorization types. client.simpleLoans.listWarmedProfiles() returns authorization.type as "EthSignature" for legacy profiles or "IcpCaller" for native IC caller profiles. "EthSignature" is deprecated for profile creation but remains supported for compatibility. Event queries can also return deprecated "ProfileWarmed" events or native "IcpProfileWarmed" events.
For loan.status, activity status, confirmation fields, and top-up handling, see the status system.