Create and restore a Simple Loan
Create a Simple Loan, show the deposit target, and restore the loan by reference.
Before you start
Complete the following preparation:
- Install
@liquidium/client. - Prepare an Ethereum address to receive the borrowed USDC.
- Prepare a Bitcoin address to receive a collateral refund.
- Confirm that your runtime provides
fetchandBigInt.
new LiquidiumClient() uses Liquidium mainnet defaults. This example creates
a real Simple Loan. Review every amount and destination before you send funds.
The example uses 50_000n satoshis (0.0005 BTC) as collateral and
9_000_000n base units (9 USDC) as the borrow amount. Replace
ETHEREUM_BORROW_ADDRESS with the Ethereum address that receives the USDC.
Replace BITCOIN_REFUND_ADDRESS with the Bitcoin address that receives a
collateral refund.
Before you create the loan, make sure that the borrow amount meets the SDK
minimum for the selected asset. If your UI shows the minimum, use
getMinimumBorrowAmount(borrowPool.asset).
Create and restore the loan:
import { Asset, Chain, LiquidiumClient, type Pool } from "@liquidium/client";
const client = new LiquidiumClient();
const [pools, prices] = await Promise.all([
client.market.listPools(),
client.market.getAssetPrices(),
]);
const collateralPool = requirePool(pools, Asset.BTC, Chain.BTC);
const borrowPool = requirePool(pools, Asset.USDC, Chain.ETH);
const collateralAmount = 50_000n;
const borrowAmount = 9_000_000n;
const ltv = client.quote.calculateLtv(
{
collateralPoolId: collateralPool.id,
borrowPoolId: borrowPool.id,
collateralAmount,
borrowAmount,
},
pools,
prices
);
if (ltv.validationErrors.length > 0) {
throw new Error(ltv.validationErrors.map((error) => error.message).join(" "));
}
const loan = await client.simpleLoans.create({
collateral: {
poolId: collateralPool.id,
asset: Asset.BTC,
amount: collateralAmount,
},
borrow: {
poolId: borrowPool.id,
asset: Asset.USDC,
amount: borrowAmount,
chain: Chain.ETH,
destination: "ETHEREUM_BORROW_ADDRESS",
},
refund: {
chain: Chain.BTC,
destination: "BITCOIN_REFUND_ADDRESS",
},
ltvMaxBps: ltv.maxAllowedLtvBps,
depositWindowSeconds: 3_600n,
});
const initialDeposit = loan.initialDeposit.targets[Chain.BTC];
if (!initialDeposit) {
throw new Error("Missing BTC initial-deposit target.");
}
console.log("Save this loan reference:", loan.ref);
console.log("Send collateral amount:", initialDeposit.amount.toString());
console.log("Send collateral to:", initialDeposit.target.address);
const restoredLoan = await client.simpleLoans.get({ ref: loan.ref });
const repayment = restoredLoan.repayment.targets[Chain.ETH];
console.log("Loan status:", restoredLoan.status);
if (repayment && repayment.amount > 0n) {
console.log("Repay amount:", repayment.amount.toString());
console.log("Repay target:", repayment.target.address);
} else {
console.log("No repayment due yet.");
}
function requirePool(
pools: Pool[],
asset: Pool["asset"],
chain: Pool["chain"]
): Pool {
const pool = pools.find(
(candidatePool) =>
candidatePool.asset === asset && candidatePool.chain === chain
);
if (!pool) {
throw new Error(`Missing ${chain}/${asset} pool.`);
}
if (pool.frozen) {
throw new Error(`${chain}/${asset} pool is frozen.`);
}
return pool;
}
Save loan.ref. Use it for refreshes, status pages, and support links.
If create(...) throws SimpleLoanCreatedError, recover the loan with the
error's loanId or ref. Do not call create(...) again. For recovery code,
see Handle SDK errors.