@liquidium/client 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -4
- package/dist/index.cjs +91 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +160 -69
- package/dist/index.d.ts +160 -69
- package/dist/index.js +90 -22
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<p align="center">
|
|
15
15
|
<a href="https://liquidium-inc.github.io/liquidium-sdk/"><b>SDK Docs</b></a> ·
|
|
16
16
|
<a href="https://github.com/Liquidium-Inc/liquidium-sdk/tree/main/examples/instant-loans-flow"><b>Instant Loan Example</b></a> ·
|
|
17
|
-
<a href="https://github.com/Liquidium-Inc/liquidium-sdk/tree/main/examples/
|
|
17
|
+
<a href="https://github.com/Liquidium-Inc/liquidium-sdk/tree/main/examples/sdk-method-query"><b>SDK Method Query Example</b></a> ·
|
|
18
18
|
<a href="#core-api"><b>Core API</b></a>
|
|
19
19
|
</p>
|
|
20
20
|
|
|
@@ -148,7 +148,7 @@ Instant-loan integrations use this sequence:
|
|
|
148
148
|
| Step | SDK call | What your app does |
|
|
149
149
|
| --- | --- | --- |
|
|
150
150
|
| Load market data | `client.market.listPools()` and `client.market.getAssetPrices()` | Show supported collateral and borrow assets |
|
|
151
|
-
| Validate amounts | `client.quote.calculateLtv(...)` | Block invalid LTV or frozen-pool input before creating a loan |
|
|
151
|
+
| Validate amounts | `client.quote.calculateLtv(...)` | Block too-small borrow amounts, invalid LTV, or frozen-pool input before creating a loan |
|
|
152
152
|
| Create loan | `client.instantLoans.create(...)` | Store `loan.ref` and show `loan.initialDeposit.amount` plus `loan.initialDeposit.target` |
|
|
153
153
|
| Track loan | `client.instantLoans.get({ ref })` and `client.activities.list({ shortRef: ref })` | Reload loan state, initial deposit quote, and repayment activity |
|
|
154
154
|
| Repay loan | Read `loan.repayment` | Ask the user to send `loan.repayment.amount` to `loan.repayment.target`; amount is `0n` when no repayment is due |
|
|
@@ -168,7 +168,7 @@ Creates an accountless instant loan and returns generated transfer targets.
|
|
|
168
168
|
| `collateralAsset` | Collateral asset symbol, for example `"BTC"` |
|
|
169
169
|
| `borrowAsset` | Borrow asset symbol, for example `"USDC"` |
|
|
170
170
|
| `collateralAmount` | Intended credited collateral amount in base units, before deposit/inflow fees |
|
|
171
|
-
| `borrowAmount` | Borrow amount in base units |
|
|
171
|
+
| `borrowAmount` | Borrow amount in base units. The SDK rejects values below the asset minimum. |
|
|
172
172
|
| `ltvMaxBps` | Maximum LTV in basis points, where `6_000n` is 60% |
|
|
173
173
|
| `depositWindowSeconds` | How long the user has to send collateral |
|
|
174
174
|
| `borrowDestination` | External address that receives borrowed funds |
|
|
@@ -200,6 +200,18 @@ Calculates implied LTV from selected pools, prices, borrow amount, and collatera
|
|
|
200
200
|
|
|
201
201
|
Use this before `client.instantLoans.create(...)` so your app can block invalid input and choose a safe `ltvMaxBps`.
|
|
202
202
|
|
|
203
|
+
### Borrow minimums
|
|
204
|
+
|
|
205
|
+
The SDK enforces product minimums before borrow creation:
|
|
206
|
+
|
|
207
|
+
| Asset | Minimum borrow amount |
|
|
208
|
+
| --- | --- |
|
|
209
|
+
| BTC | `5_100n` sats |
|
|
210
|
+
| USDC | `1_000_000n` base units |
|
|
211
|
+
| USDT | `1_000_000n` base units |
|
|
212
|
+
|
|
213
|
+
Use `getMinimumBorrowAmount(asset)` to display the same minimum that `client.quote.calculateLtv(...)`, `client.quote.getQuote(...)`, `client.instantLoans.create(...)`, and `client.lending.prepareBorrow(...)` enforce.
|
|
214
|
+
|
|
203
215
|
## Response Fields
|
|
204
216
|
|
|
205
217
|
Most instant-loan UIs show or store these fields:
|
|
@@ -255,7 +267,7 @@ Start browser integrations with the examples.
|
|
|
255
267
|
| Example | What it shows |
|
|
256
268
|
| --- | --- |
|
|
257
269
|
| [`examples/instant-loans-flow`](https://github.com/Liquidium-Inc/liquidium-sdk/tree/main/examples/instant-loans-flow) | Accountless instant loan UX with manual destination addresses, pool selection, LTV preview, loan creation, status reload, activity status, and address recovery |
|
|
258
|
-
| [`examples/
|
|
270
|
+
| [`examples/sdk-method-query`](https://github.com/Liquidium-Inc/liquidium-sdk/tree/main/examples/sdk-method-query) | Developer tool for calling SDK methods, including instant loan method templates |
|
|
259
271
|
|
|
260
272
|
Run the instant loan example:
|
|
261
273
|
|
package/dist/index.cjs
CHANGED
|
@@ -3107,6 +3107,39 @@ function assertSupportsIcrcAccountInflowTarget(asset) {
|
|
|
3107
3107
|
);
|
|
3108
3108
|
}
|
|
3109
3109
|
|
|
3110
|
+
// src/core/borrow-minimums.ts
|
|
3111
|
+
var MIN_BORROW_AMOUNTS_BY_ASSET = {
|
|
3112
|
+
BTC: 5100n,
|
|
3113
|
+
// 5,100 sats = 0.000051 BTC
|
|
3114
|
+
USDC: 1000000n,
|
|
3115
|
+
// 1 USDC
|
|
3116
|
+
USDT: 1000000n
|
|
3117
|
+
// 1 USDT
|
|
3118
|
+
};
|
|
3119
|
+
function getMinimumBorrowAmount(asset) {
|
|
3120
|
+
if (!isMinimumBorrowAsset(asset)) {
|
|
3121
|
+
return 0n;
|
|
3122
|
+
}
|
|
3123
|
+
return MIN_BORROW_AMOUNTS_BY_ASSET[asset];
|
|
3124
|
+
}
|
|
3125
|
+
function getBorrowAmountMinimumValidationError(params) {
|
|
3126
|
+
const minimumAmount = getMinimumBorrowAmount(params.asset);
|
|
3127
|
+
if (minimumAmount <= 0n || params.amount >= minimumAmount) {
|
|
3128
|
+
return null;
|
|
3129
|
+
}
|
|
3130
|
+
return {
|
|
3131
|
+
asset: params.asset,
|
|
3132
|
+
minimumAmount,
|
|
3133
|
+
message: formatMinimumBorrowAmountMessage(params.asset, minimumAmount)
|
|
3134
|
+
};
|
|
3135
|
+
}
|
|
3136
|
+
function formatMinimumBorrowAmountMessage(asset, minimumAmount) {
|
|
3137
|
+
return `Borrow amount must be at least ${minimumAmount} base units for ${asset}`;
|
|
3138
|
+
}
|
|
3139
|
+
function isMinimumBorrowAsset(asset) {
|
|
3140
|
+
return Object.hasOwn(MIN_BORROW_AMOUNTS_BY_ASSET, asset);
|
|
3141
|
+
}
|
|
3142
|
+
|
|
3110
3143
|
// src/modules/quote/types.ts
|
|
3111
3144
|
var QuoteValidationErrorCode = /* @__PURE__ */ ((QuoteValidationErrorCode2) => {
|
|
3112
3145
|
QuoteValidationErrorCode2["INVALID_LTV"] = "INVALID_LTV";
|
|
@@ -3129,7 +3162,6 @@ var BASIS_POINTS_DENOMINATOR = 10000n;
|
|
|
3129
3162
|
var BPS_PER_PERCENT = 100n;
|
|
3130
3163
|
var MIN_LTV_BPS = 0n;
|
|
3131
3164
|
var HIGH_LTV_WARNING_THRESHOLD_BPS = 8000n;
|
|
3132
|
-
var MIN_BORROW_AMOUNT_BASE_UNITS = 5000n;
|
|
3133
3165
|
var INTERNAL_USD_DECIMAL_PLACES = 8;
|
|
3134
3166
|
var PRICE_SCALE_DECIMAL_PLACES = 8;
|
|
3135
3167
|
var QuoteModule = class {
|
|
@@ -3187,11 +3219,12 @@ var QuoteModule = class {
|
|
|
3187
3219
|
message: `Price not available for collateral asset: ${collateralPool.asset}`
|
|
3188
3220
|
});
|
|
3189
3221
|
}
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3222
|
+
const borrowAmountError = createBorrowAmountValidationError({
|
|
3223
|
+
amount: request.borrowAmount,
|
|
3224
|
+
asset: borrowPool.asset
|
|
3225
|
+
});
|
|
3226
|
+
if (borrowAmountError) {
|
|
3227
|
+
validationErrors.push(borrowAmountError);
|
|
3195
3228
|
}
|
|
3196
3229
|
if (request.collateralAmount <= 0n) {
|
|
3197
3230
|
validationErrors.push({
|
|
@@ -3313,16 +3346,12 @@ var QuoteModule = class {
|
|
|
3313
3346
|
message: `Price not available for collateral asset: ${collateralAsset}`
|
|
3314
3347
|
});
|
|
3315
3348
|
}
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
validationErrors.push({
|
|
3323
|
-
code: "BORROW_AMOUNT_TOO_LOW" /* BORROW_AMOUNT_TOO_LOW */,
|
|
3324
|
-
message: `Borrow amount must be at least ${MIN_BORROW_AMOUNT_BASE_UNITS} base units`
|
|
3325
|
-
});
|
|
3349
|
+
const borrowAmountError = createBorrowAmountValidationError({
|
|
3350
|
+
amount: borrowAmount,
|
|
3351
|
+
asset: borrowAsset
|
|
3352
|
+
});
|
|
3353
|
+
if (borrowAmountError) {
|
|
3354
|
+
validationErrors.push(borrowAmountError);
|
|
3326
3355
|
}
|
|
3327
3356
|
if (targetLtvBps <= MIN_LTV_BPS) {
|
|
3328
3357
|
validationErrors.push({
|
|
@@ -3445,6 +3474,22 @@ function createQuoteResult(params) {
|
|
|
3445
3474
|
warnings: params.warnings
|
|
3446
3475
|
};
|
|
3447
3476
|
}
|
|
3477
|
+
function createBorrowAmountValidationError(params) {
|
|
3478
|
+
if (params.amount <= 0n) {
|
|
3479
|
+
return {
|
|
3480
|
+
code: "BORROW_AMOUNT_TOO_LOW" /* BORROW_AMOUNT_TOO_LOW */,
|
|
3481
|
+
message: "Borrow amount must be greater than 0"
|
|
3482
|
+
};
|
|
3483
|
+
}
|
|
3484
|
+
const minimumBorrowAmountError = getBorrowAmountMinimumValidationError(params);
|
|
3485
|
+
if (!minimumBorrowAmountError) {
|
|
3486
|
+
return null;
|
|
3487
|
+
}
|
|
3488
|
+
return {
|
|
3489
|
+
code: "BORROW_AMOUNT_TOO_LOW" /* BORROW_AMOUNT_TOO_LOW */,
|
|
3490
|
+
message: minimumBorrowAmountError.message
|
|
3491
|
+
};
|
|
3492
|
+
}
|
|
3448
3493
|
function computeUsdInternalFromBaseUnits(params) {
|
|
3449
3494
|
const { amountBaseUnits, priceScaled, assetDecimalPlaces } = params;
|
|
3450
3495
|
const scaleDiff = INTERNAL_USD_DECIMAL_PLACES - PRICE_SCALE_DECIMAL_PLACES;
|
|
@@ -3770,7 +3815,9 @@ var InstantLoansModule = class {
|
|
|
3770
3815
|
);
|
|
3771
3816
|
}
|
|
3772
3817
|
const apiClient = this.requireApi("Instant loan address lookup");
|
|
3773
|
-
const response = await apiClient.get(
|
|
3818
|
+
const response = await apiClient.get(
|
|
3819
|
+
buildInstantLoanAddressLookupPath({ address: trimmedAddress })
|
|
3820
|
+
);
|
|
3774
3821
|
return (response.candidates ?? response.loans ?? []).map(mapCandidateWire);
|
|
3775
3822
|
}
|
|
3776
3823
|
async mapLoanRecord(record, collateralAmount) {
|
|
@@ -3791,7 +3838,9 @@ var InstantLoansModule = class {
|
|
|
3791
3838
|
}
|
|
3792
3839
|
async getCollateralAmountHint(loanId) {
|
|
3793
3840
|
const apiClient = this.requireApi("Instant loan lookup");
|
|
3794
|
-
const response = await apiClient.get(
|
|
3841
|
+
const response = await apiClient.get(
|
|
3842
|
+
buildInstantLoanCollateralHintPath({ loanId })
|
|
3843
|
+
);
|
|
3795
3844
|
return parseBigintWire(response.collateralAmountHint, "collateral amount");
|
|
3796
3845
|
}
|
|
3797
3846
|
async mapLoanWire(loan) {
|
|
@@ -4715,9 +4764,28 @@ var LendingModule = class {
|
|
|
4715
4764
|
"Borrow requires a signer account"
|
|
4716
4765
|
);
|
|
4717
4766
|
}
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4767
|
+
if (request.amount <= 0n) {
|
|
4768
|
+
throw new LiquidiumError(
|
|
4769
|
+
LiquidiumErrorCode.VALIDATION_ERROR,
|
|
4770
|
+
"Borrow amount must be greater than 0"
|
|
4771
|
+
);
|
|
4772
|
+
}
|
|
4773
|
+
const selectedPool = await this.getPoolById(request.poolId);
|
|
4774
|
+
const selectedAsset = getVariantKey(selectedPool.asset);
|
|
4775
|
+
const minimumBorrowAmountError = getBorrowAmountMinimumValidationError({
|
|
4776
|
+
amount: request.amount,
|
|
4777
|
+
asset: selectedAsset
|
|
4778
|
+
});
|
|
4779
|
+
if (minimumBorrowAmountError) {
|
|
4780
|
+
throw new LiquidiumError(
|
|
4781
|
+
LiquidiumErrorCode.VALIDATION_ERROR,
|
|
4782
|
+
minimumBorrowAmountError.message
|
|
4783
|
+
);
|
|
4784
|
+
}
|
|
4785
|
+
const receiverAddress = normalizeExternalAddress({
|
|
4786
|
+
address: destinationAccount,
|
|
4787
|
+
asset: selectedAsset,
|
|
4788
|
+
chain: getVariantKey(selectedPool.chain)
|
|
4721
4789
|
});
|
|
4722
4790
|
const lendingActor = createLendingActor(this.canisterContext);
|
|
4723
4791
|
try {
|
|
@@ -5985,6 +6053,7 @@ exports.LendingModule = LendingModule;
|
|
|
5985
6053
|
exports.LiquidiumClient = LiquidiumClient;
|
|
5986
6054
|
exports.LiquidiumError = LiquidiumError;
|
|
5987
6055
|
exports.LiquidiumErrorCode = LiquidiumErrorCode;
|
|
6056
|
+
exports.MIN_BORROW_AMOUNTS_BY_ASSET = MIN_BORROW_AMOUNTS_BY_ASSET;
|
|
5988
6057
|
exports.MarketModule = MarketModule;
|
|
5989
6058
|
exports.OutflowType = OutflowType;
|
|
5990
6059
|
exports.PositionsModule = PositionsModule;
|
|
@@ -6002,6 +6071,7 @@ exports.UserHistoryStatus = UserHistoryStatus;
|
|
|
6002
6071
|
exports.WalletExecutionKind = WalletExecutionKind;
|
|
6003
6072
|
exports.createTransferErc20Transaction = createTransferErc20Transaction;
|
|
6004
6073
|
exports.executeWith = executeWith;
|
|
6074
|
+
exports.getMinimumBorrowAmount = getMinimumBorrowAmount;
|
|
6005
6075
|
exports.intFromPublicId = intFromPublicId;
|
|
6006
6076
|
exports.publicIdFromInt = publicIdFromInt;
|
|
6007
6077
|
//# sourceMappingURL=index.cjs.map
|