@liquidium/client 0.1.2 → 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 +33 -17
- package/dist/index.cjs +351 -115
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +244 -109
- package/dist/index.d.ts +244 -109
- package/dist/index.js +351 -117
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -6,6 +6,7 @@ var agent = require('@icp-sdk/core/agent');
|
|
|
6
6
|
var principal = require('@icp-sdk/core/principal');
|
|
7
7
|
var ledgerIcrc = require('@dfinity/ledger-icrc');
|
|
8
8
|
var principal$1 = require('@dfinity/principal');
|
|
9
|
+
var bitcoinAddressValidation = require('bitcoin-address-validation');
|
|
9
10
|
|
|
10
11
|
// src/client.ts
|
|
11
12
|
|
|
@@ -59,7 +60,8 @@ function resolveCanisterIds(environment = DEFAULT_ENVIRONMENT, overrides) {
|
|
|
59
60
|
}
|
|
60
61
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
61
62
|
var CK_CANISTER_IDS = {
|
|
62
|
-
btcMinter: "mqygn-kiaaa-aaaar-qaadq-cai"
|
|
63
|
+
btcMinter: "mqygn-kiaaa-aaaar-qaadq-cai",
|
|
64
|
+
btcLedger: "mxzaz-hqaaa-aaaar-qaada-cai"};
|
|
63
65
|
|
|
64
66
|
// src/core/errors.ts
|
|
65
67
|
var LiquidiumErrorCode = {
|
|
@@ -1595,6 +1597,11 @@ function buildInstantLoanAddressLookupPath(request) {
|
|
|
1595
1597
|
const query = new URLSearchParams({ address: request.address });
|
|
1596
1598
|
return `${INSTANT_LOANS}/address?${query.toString()}`;
|
|
1597
1599
|
}
|
|
1600
|
+
function buildInstantLoanCollateralHintPath(request) {
|
|
1601
|
+
return `${INSTANT_LOANS}/${encodeURIComponent(
|
|
1602
|
+
request.loanId.toString()
|
|
1603
|
+
)}/collateral-hint`;
|
|
1604
|
+
}
|
|
1598
1605
|
var SdkApiPath = {
|
|
1599
1606
|
inflow: INFLOW,
|
|
1600
1607
|
instantLoans: INSTANT_LOANS
|
|
@@ -2217,6 +2224,24 @@ function mapHistoryStatusToApi(status) {
|
|
|
2217
2224
|
return status.toUpperCase();
|
|
2218
2225
|
}
|
|
2219
2226
|
|
|
2227
|
+
// src/core/utils/asset-decimals.ts
|
|
2228
|
+
var ASSET_NATIVE_DECIMALS = {
|
|
2229
|
+
BTC: 8n,
|
|
2230
|
+
USDC: 6n,
|
|
2231
|
+
USDT: 6n,
|
|
2232
|
+
SOL: 9n
|
|
2233
|
+
};
|
|
2234
|
+
function getAssetNativeDecimals(asset) {
|
|
2235
|
+
const decimals = ASSET_NATIVE_DECIMALS[asset];
|
|
2236
|
+
if (decimals === void 0) {
|
|
2237
|
+
throw new LiquidiumError(
|
|
2238
|
+
LiquidiumErrorCode.VALIDATION_ERROR,
|
|
2239
|
+
`Native decimals are not configured for asset: ${asset}`
|
|
2240
|
+
);
|
|
2241
|
+
}
|
|
2242
|
+
return decimals;
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2220
2245
|
// src/generated/canisters/ck-btc-minter/declaration.js
|
|
2221
2246
|
var idlFactory3 = ({ IDL }) => {
|
|
2222
2247
|
const Mode = IDL.Variant({
|
|
@@ -3082,6 +3107,39 @@ function assertSupportsIcrcAccountInflowTarget(asset) {
|
|
|
3082
3107
|
);
|
|
3083
3108
|
}
|
|
3084
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
|
+
|
|
3085
3143
|
// src/modules/quote/types.ts
|
|
3086
3144
|
var QuoteValidationErrorCode = /* @__PURE__ */ ((QuoteValidationErrorCode2) => {
|
|
3087
3145
|
QuoteValidationErrorCode2["INVALID_LTV"] = "INVALID_LTV";
|
|
@@ -3104,7 +3162,6 @@ var BASIS_POINTS_DENOMINATOR = 10000n;
|
|
|
3104
3162
|
var BPS_PER_PERCENT = 100n;
|
|
3105
3163
|
var MIN_LTV_BPS = 0n;
|
|
3106
3164
|
var HIGH_LTV_WARNING_THRESHOLD_BPS = 8000n;
|
|
3107
|
-
var MIN_BORROW_AMOUNT_BASE_UNITS = 5000n;
|
|
3108
3165
|
var INTERNAL_USD_DECIMAL_PLACES = 8;
|
|
3109
3166
|
var PRICE_SCALE_DECIMAL_PLACES = 8;
|
|
3110
3167
|
var QuoteModule = class {
|
|
@@ -3162,11 +3219,12 @@ var QuoteModule = class {
|
|
|
3162
3219
|
message: `Price not available for collateral asset: ${collateralPool.asset}`
|
|
3163
3220
|
});
|
|
3164
3221
|
}
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3222
|
+
const borrowAmountError = createBorrowAmountValidationError({
|
|
3223
|
+
amount: request.borrowAmount,
|
|
3224
|
+
asset: borrowPool.asset
|
|
3225
|
+
});
|
|
3226
|
+
if (borrowAmountError) {
|
|
3227
|
+
validationErrors.push(borrowAmountError);
|
|
3170
3228
|
}
|
|
3171
3229
|
if (request.collateralAmount <= 0n) {
|
|
3172
3230
|
validationErrors.push({
|
|
@@ -3288,16 +3346,12 @@ var QuoteModule = class {
|
|
|
3288
3346
|
message: `Price not available for collateral asset: ${collateralAsset}`
|
|
3289
3347
|
});
|
|
3290
3348
|
}
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
validationErrors.push({
|
|
3298
|
-
code: "BORROW_AMOUNT_TOO_LOW" /* BORROW_AMOUNT_TOO_LOW */,
|
|
3299
|
-
message: `Borrow amount must be at least ${MIN_BORROW_AMOUNT_BASE_UNITS} base units`
|
|
3300
|
-
});
|
|
3349
|
+
const borrowAmountError = createBorrowAmountValidationError({
|
|
3350
|
+
amount: borrowAmount,
|
|
3351
|
+
asset: borrowAsset
|
|
3352
|
+
});
|
|
3353
|
+
if (borrowAmountError) {
|
|
3354
|
+
validationErrors.push(borrowAmountError);
|
|
3301
3355
|
}
|
|
3302
3356
|
if (targetLtvBps <= MIN_LTV_BPS) {
|
|
3303
3357
|
validationErrors.push({
|
|
@@ -3420,6 +3474,22 @@ function createQuoteResult(params) {
|
|
|
3420
3474
|
warnings: params.warnings
|
|
3421
3475
|
};
|
|
3422
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
|
+
}
|
|
3423
3493
|
function computeUsdInternalFromBaseUnits(params) {
|
|
3424
3494
|
const { amountBaseUnits, priceScaled, assetDecimalPlaces } = params;
|
|
3425
3495
|
const scaleDiff = INTERNAL_USD_DECIMAL_PLACES - PRICE_SCALE_DECIMAL_PLACES;
|
|
@@ -3462,6 +3532,82 @@ function formatBpsAsPercent(bps) {
|
|
|
3462
3532
|
const padded = fractional.toString().padStart(2, "0").replace(/0+$/, "");
|
|
3463
3533
|
return `${whole}.${padded}`;
|
|
3464
3534
|
}
|
|
3535
|
+
var BTC_MAINNET_ADDRESS_ERROR = "Address must be a valid mainnet BTC address";
|
|
3536
|
+
var EVM_ADDRESS_ERROR = "Address must be a valid EVM address";
|
|
3537
|
+
var ADDRESS_CHAIN_MISMATCH_ERROR = "Address chain must match asset";
|
|
3538
|
+
function normalizeExternalAddress(params) {
|
|
3539
|
+
if (params.asset === Asset.BTC) {
|
|
3540
|
+
if (params.chain !== Chain.BTC) {
|
|
3541
|
+
throw new LiquidiumError(
|
|
3542
|
+
LiquidiumErrorCode.INVALID_ADDRESS,
|
|
3543
|
+
ADDRESS_CHAIN_MISMATCH_ERROR
|
|
3544
|
+
);
|
|
3545
|
+
}
|
|
3546
|
+
if (!bitcoinAddressValidation.validate(params.address, bitcoinAddressValidation.Network.mainnet)) {
|
|
3547
|
+
throw new LiquidiumError(
|
|
3548
|
+
LiquidiumErrorCode.INVALID_ADDRESS,
|
|
3549
|
+
BTC_MAINNET_ADDRESS_ERROR
|
|
3550
|
+
);
|
|
3551
|
+
}
|
|
3552
|
+
return params.address;
|
|
3553
|
+
}
|
|
3554
|
+
if (isEthStablecoin2(params.asset)) {
|
|
3555
|
+
if (params.chain !== Chain.ETH) {
|
|
3556
|
+
throw new LiquidiumError(
|
|
3557
|
+
LiquidiumErrorCode.INVALID_ADDRESS,
|
|
3558
|
+
ADDRESS_CHAIN_MISMATCH_ERROR
|
|
3559
|
+
);
|
|
3560
|
+
}
|
|
3561
|
+
if (!viem.isAddress(params.address)) {
|
|
3562
|
+
throw new LiquidiumError(
|
|
3563
|
+
LiquidiumErrorCode.INVALID_ADDRESS,
|
|
3564
|
+
EVM_ADDRESS_ERROR
|
|
3565
|
+
);
|
|
3566
|
+
}
|
|
3567
|
+
return viem.getAddress(params.address);
|
|
3568
|
+
}
|
|
3569
|
+
return params.address;
|
|
3570
|
+
}
|
|
3571
|
+
function normalizeAndValidateEvmAddress(address, errorMessage) {
|
|
3572
|
+
if (!viem.isAddress(address)) {
|
|
3573
|
+
throw new LiquidiumError(LiquidiumErrorCode.INVALID_ADDRESS, errorMessage);
|
|
3574
|
+
}
|
|
3575
|
+
return viem.getAddress(address);
|
|
3576
|
+
}
|
|
3577
|
+
function isEthStablecoin2(asset) {
|
|
3578
|
+
return asset === Asset.USDC || asset === Asset.USDT;
|
|
3579
|
+
}
|
|
3580
|
+
|
|
3581
|
+
// src/modules/instant-loans/_internal/address-validation.ts
|
|
3582
|
+
function validateInstantLoanBorrowDestination(address, asset) {
|
|
3583
|
+
return normalizeExternalAddress({
|
|
3584
|
+
address,
|
|
3585
|
+
asset,
|
|
3586
|
+
chain: getChainForInstantLoanAsset(asset)
|
|
3587
|
+
});
|
|
3588
|
+
}
|
|
3589
|
+
function validateInstantLoanRefundDestination(address, asset) {
|
|
3590
|
+
return normalizeExternalAddress({
|
|
3591
|
+
address,
|
|
3592
|
+
asset,
|
|
3593
|
+
chain: getChainForInstantLoanAsset(asset)
|
|
3594
|
+
});
|
|
3595
|
+
}
|
|
3596
|
+
function getChainForInstantLoanAsset(asset) {
|
|
3597
|
+
if (asset === Asset.BTC) return Chain.BTC;
|
|
3598
|
+
if (asset === Asset.USDC || asset === Asset.USDT) return Chain.ETH;
|
|
3599
|
+
return asset;
|
|
3600
|
+
}
|
|
3601
|
+
|
|
3602
|
+
// src/modules/instant-loans/types.ts
|
|
3603
|
+
var InstantLoanStatus = {
|
|
3604
|
+
awaitingDeposit: "awaiting_deposit",
|
|
3605
|
+
depositDetected: "deposit_detected",
|
|
3606
|
+
active: "active",
|
|
3607
|
+
settling: "settling",
|
|
3608
|
+
closed: "closed",
|
|
3609
|
+
expired: "expired"
|
|
3610
|
+
};
|
|
3465
3611
|
|
|
3466
3612
|
// src/modules/instant-loans/instant-loans.ts
|
|
3467
3613
|
var REPAYMENT_BUFFER_SECONDS = 86400n;
|
|
@@ -3482,7 +3628,7 @@ var InstantLoansModule = class {
|
|
|
3482
3628
|
positions;
|
|
3483
3629
|
/**
|
|
3484
3630
|
* Creates a profileless instant loan and returns canonical canister state plus
|
|
3485
|
-
* deposit
|
|
3631
|
+
* generated initial-deposit and repayment quote targets.
|
|
3486
3632
|
*
|
|
3487
3633
|
* Choose `collateralPoolId` and `borrowPoolId` from
|
|
3488
3634
|
* `client.market.listPools()`, convert UI amounts to base units with the
|
|
@@ -3495,10 +3641,22 @@ var InstantLoansModule = class {
|
|
|
3495
3641
|
* SDK maps it to the canister's internal `ltv_timer_s` field.
|
|
3496
3642
|
*
|
|
3497
3643
|
* @param request - Pool ids, assets, base-unit amounts, LTV limit, timeout, and destinations.
|
|
3498
|
-
* @returns Hydrated loan state plus generated deposit and repayment targets.
|
|
3644
|
+
* @returns Hydrated loan state plus generated initial-deposit and repayment quote targets.
|
|
3499
3645
|
*/
|
|
3500
3646
|
async create(request) {
|
|
3501
3647
|
validateCreateRequest(request);
|
|
3648
|
+
const borrowDestination = {
|
|
3649
|
+
External: validateInstantLoanBorrowDestination(
|
|
3650
|
+
addressFromAccountInput(request.borrowDestination),
|
|
3651
|
+
request.borrowAsset
|
|
3652
|
+
)
|
|
3653
|
+
};
|
|
3654
|
+
const refundDestination = {
|
|
3655
|
+
External: validateInstantLoanRefundDestination(
|
|
3656
|
+
addressFromAccountInput(request.refundDestination),
|
|
3657
|
+
request.collateralAsset
|
|
3658
|
+
)
|
|
3659
|
+
};
|
|
3502
3660
|
const apiClient = this.requireApi("Instant loan creation");
|
|
3503
3661
|
await this.validateInstantLoanLtvPolicy(request);
|
|
3504
3662
|
const response = await apiClient.post(SdkApiPath.instantLoans, {
|
|
@@ -3510,17 +3668,10 @@ var InstantLoansModule = class {
|
|
|
3510
3668
|
borrowAmount: request.borrowAmount.toString(),
|
|
3511
3669
|
ltvMaxBps: request.ltvMaxBps.toString(),
|
|
3512
3670
|
depositWindowSeconds: request.depositWindowSeconds.toString(),
|
|
3513
|
-
borrowDestination
|
|
3514
|
-
refundDestination
|
|
3671
|
+
borrowDestination,
|
|
3672
|
+
refundDestination
|
|
3515
3673
|
});
|
|
3516
|
-
|
|
3517
|
-
return {
|
|
3518
|
-
...loan,
|
|
3519
|
-
collateral: {
|
|
3520
|
-
...loan.collateral,
|
|
3521
|
-
amount: request.collateralAmount
|
|
3522
|
-
}
|
|
3523
|
-
};
|
|
3674
|
+
return await this.mapLoanWire(response.loan);
|
|
3524
3675
|
}
|
|
3525
3676
|
/**
|
|
3526
3677
|
* Resolves canonical canister state by loan id or short reference.
|
|
@@ -3529,7 +3680,7 @@ var InstantLoansModule = class {
|
|
|
3529
3680
|
* from the instant-loans canister.
|
|
3530
3681
|
*
|
|
3531
3682
|
* @param request - Canister loan id or short public reference.
|
|
3532
|
-
* @returns Hydrated loan state plus generated deposit and repayment targets.
|
|
3683
|
+
* @returns Hydrated loan state plus generated initial-deposit and repayment quote targets.
|
|
3533
3684
|
*/
|
|
3534
3685
|
async get(request) {
|
|
3535
3686
|
const loanId = "loanId" in request ? request.loanId : decodeRef(request.ref);
|
|
@@ -3540,7 +3691,8 @@ var InstantLoansModule = class {
|
|
|
3540
3691
|
if ("Err" in result) {
|
|
3541
3692
|
throw mapInstantLoansErrorToLiquidiumError(result.Err);
|
|
3542
3693
|
}
|
|
3543
|
-
|
|
3694
|
+
const collateralAmount = await this.getCollateralAmountHint(loanId);
|
|
3695
|
+
return await this.mapLoanRecord(result.Ok, collateralAmount);
|
|
3544
3696
|
} catch (error) {
|
|
3545
3697
|
if (error instanceof LiquidiumError) {
|
|
3546
3698
|
throw error;
|
|
@@ -3663,25 +3815,34 @@ var InstantLoansModule = class {
|
|
|
3663
3815
|
);
|
|
3664
3816
|
}
|
|
3665
3817
|
const apiClient = this.requireApi("Instant loan address lookup");
|
|
3666
|
-
const response = await apiClient.get(
|
|
3818
|
+
const response = await apiClient.get(
|
|
3819
|
+
buildInstantLoanAddressLookupPath({ address: trimmedAddress })
|
|
3820
|
+
);
|
|
3667
3821
|
return (response.candidates ?? response.loans ?? []).map(mapCandidateWire);
|
|
3668
3822
|
}
|
|
3669
|
-
async mapLoanRecord(record) {
|
|
3823
|
+
async mapLoanRecord(record, collateralAmount) {
|
|
3670
3824
|
return await this.hydrateLoan({
|
|
3671
3825
|
loanId: record.id,
|
|
3672
3826
|
profileId: record.lending_profile.toText(),
|
|
3673
3827
|
ltvMaxBps: record.ltv_max_bps,
|
|
3674
3828
|
depositWindowSeconds: record.ltv_timer_s,
|
|
3675
3829
|
collateralPoolId: record.lend_pool_id.toText(),
|
|
3830
|
+
collateralAmount,
|
|
3676
3831
|
borrowPoolId: record.borrow_pool_id.toText(),
|
|
3677
3832
|
collateralAsset: getVariantKey(record.lend_asset),
|
|
3678
3833
|
borrowAsset: getVariantKey(record.borrow_asset),
|
|
3679
3834
|
borrowAmount: record.borrow_amount,
|
|
3680
3835
|
borrowDestination: accountFromCanister(record.borrow_destination),
|
|
3681
|
-
refundDestination: accountFromCanister(record.refund_destination)
|
|
3682
|
-
started: record.started
|
|
3836
|
+
refundDestination: accountFromCanister(record.refund_destination)
|
|
3683
3837
|
});
|
|
3684
3838
|
}
|
|
3839
|
+
async getCollateralAmountHint(loanId) {
|
|
3840
|
+
const apiClient = this.requireApi("Instant loan lookup");
|
|
3841
|
+
const response = await apiClient.get(
|
|
3842
|
+
buildInstantLoanCollateralHintPath({ loanId })
|
|
3843
|
+
);
|
|
3844
|
+
return parseBigintWire(response.collateralAmountHint, "collateral amount");
|
|
3845
|
+
}
|
|
3685
3846
|
async mapLoanWire(loan) {
|
|
3686
3847
|
const loanId = parseBigintWire(loan.loanId, "loan ID");
|
|
3687
3848
|
return await this.hydrateLoan({
|
|
@@ -3693,6 +3854,10 @@ var InstantLoansModule = class {
|
|
|
3693
3854
|
"deposit window"
|
|
3694
3855
|
),
|
|
3695
3856
|
collateralPoolId: loan.collateral.poolId,
|
|
3857
|
+
collateralAmount: parseBigintWire(
|
|
3858
|
+
loan.collateral.amountHint,
|
|
3859
|
+
"collateral amount"
|
|
3860
|
+
),
|
|
3696
3861
|
borrowPoolId: loan.borrow.poolId,
|
|
3697
3862
|
collateralAsset: loan.collateral.asset,
|
|
3698
3863
|
borrowAsset: loan.borrow.asset,
|
|
@@ -3737,54 +3902,64 @@ var InstantLoansModule = class {
|
|
|
3737
3902
|
);
|
|
3738
3903
|
const repaymentInflowFee = totalDebtAmount > 0n ? await this.estimateRepaymentInflowFee(borrowAsset, repayTarget.chain) : { totalFee: 0n, estimateAvailable: false };
|
|
3739
3904
|
const repaymentAmount = totalDebtAmount + interestBufferAmount + repaymentInflowFee.totalFee;
|
|
3740
|
-
const
|
|
3741
|
-
const
|
|
3905
|
+
const currentCollateralAmount = collateralPosition?.deposited ?? 0n;
|
|
3906
|
+
const collateralAmount = input.collateralAmount;
|
|
3907
|
+
const collateralDecimals = collateralPosition?.depositedDecimals ?? getAssetNativeDecimals(collateralAsset);
|
|
3742
3908
|
const collateralInterestAmount = collateralPosition?.earnedInterest ?? 0n;
|
|
3743
3909
|
const borrowedAmount = borrowPosition?.borrowed ?? 0n;
|
|
3744
|
-
const borrowedDecimals = borrowPosition?.borrowedDecimals ??
|
|
3910
|
+
const borrowedDecimals = borrowPosition?.borrowedDecimals ?? getAssetNativeDecimals(borrowAsset);
|
|
3745
3911
|
const debtInterestAmount = borrowPosition?.debtInterest ?? 0n;
|
|
3746
3912
|
const status = deriveInstantLoanStatus({
|
|
3747
|
-
collateralAmount,
|
|
3748
|
-
started: input.started,
|
|
3913
|
+
collateralAmount: currentCollateralAmount,
|
|
3749
3914
|
totalDebtAmount
|
|
3750
3915
|
});
|
|
3916
|
+
const initialDeposit = await this.createInitialDepositQuote({
|
|
3917
|
+
collateralAmount,
|
|
3918
|
+
decimals: collateralDecimals,
|
|
3919
|
+
asset: collateralAsset,
|
|
3920
|
+
target: depositTarget
|
|
3921
|
+
});
|
|
3922
|
+
const repayment = {
|
|
3923
|
+
amount: repaymentAmount,
|
|
3924
|
+
decimals: borrowedDecimals,
|
|
3925
|
+
debtAmount: totalDebtAmount,
|
|
3926
|
+
interestBufferAmount,
|
|
3927
|
+
interestBufferSeconds: REPAYMENT_BUFFER_SECONDS,
|
|
3928
|
+
inflowFeeAmount: repaymentInflowFee.totalFee,
|
|
3929
|
+
inflowFeeEstimateAvailable: repaymentInflowFee.estimateAvailable,
|
|
3930
|
+
asset: borrowAsset,
|
|
3931
|
+
chain: repayTarget.chain,
|
|
3932
|
+
target: repayTarget
|
|
3933
|
+
};
|
|
3751
3934
|
return {
|
|
3752
3935
|
loanId: input.loanId,
|
|
3753
3936
|
ref: publicIdFromInt(input.loanId),
|
|
3754
3937
|
status,
|
|
3755
3938
|
profileId,
|
|
3756
|
-
|
|
3757
|
-
|
|
3939
|
+
terms: {
|
|
3940
|
+
ltvMaxBps: input.ltvMaxBps,
|
|
3941
|
+
depositWindowSeconds: input.depositWindowSeconds
|
|
3942
|
+
},
|
|
3758
3943
|
collateral: {
|
|
3759
3944
|
poolId: collateralPoolId,
|
|
3760
3945
|
asset: collateralAsset,
|
|
3761
3946
|
chain: depositTarget.chain,
|
|
3947
|
+
decimals: collateralDecimals,
|
|
3762
3948
|
amount: collateralAmount
|
|
3763
3949
|
},
|
|
3764
3950
|
borrow: {
|
|
3765
3951
|
poolId: borrowPoolId,
|
|
3766
3952
|
asset: borrowAsset,
|
|
3767
3953
|
chain: repayTarget.chain,
|
|
3954
|
+
decimals: borrowedDecimals,
|
|
3768
3955
|
amount: input.borrowAmount,
|
|
3769
3956
|
destination: input.borrowDestination
|
|
3770
3957
|
},
|
|
3771
3958
|
refundDestination: input.refundDestination,
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
repayment: {
|
|
3775
|
-
amount: repaymentAmount,
|
|
3776
|
-
decimals: borrowedDecimals,
|
|
3777
|
-
debtAmount: totalDebtAmount,
|
|
3778
|
-
interestBufferAmount,
|
|
3779
|
-
interestBufferSeconds: REPAYMENT_BUFFER_SECONDS,
|
|
3780
|
-
inflowFeeAmount: repaymentInflowFee.totalFee,
|
|
3781
|
-
inflowFeeEstimateAvailable: repaymentInflowFee.estimateAvailable,
|
|
3782
|
-
asset: borrowAsset,
|
|
3783
|
-
chain: repayTarget.chain,
|
|
3784
|
-
target: repayTarget
|
|
3785
|
-
},
|
|
3959
|
+
initialDeposit,
|
|
3960
|
+
repayment,
|
|
3786
3961
|
position: {
|
|
3787
|
-
collateralAmount,
|
|
3962
|
+
collateralAmount: currentCollateralAmount,
|
|
3788
3963
|
collateralDecimals,
|
|
3789
3964
|
collateralInterestAmount,
|
|
3790
3965
|
borrowedAmount,
|
|
@@ -3794,6 +3969,21 @@ var InstantLoansModule = class {
|
|
|
3794
3969
|
}
|
|
3795
3970
|
};
|
|
3796
3971
|
}
|
|
3972
|
+
async createInitialDepositQuote(input) {
|
|
3973
|
+
const inflowFee = await this.lending.estimateInflowFee({
|
|
3974
|
+
asset: input.asset,
|
|
3975
|
+
chain: input.target.chain
|
|
3976
|
+
});
|
|
3977
|
+
return {
|
|
3978
|
+
amount: input.collateralAmount + inflowFee.totalFee,
|
|
3979
|
+
decimals: input.decimals,
|
|
3980
|
+
collateralAmount: input.collateralAmount,
|
|
3981
|
+
inflowFeeAmount: inflowFee.totalFee,
|
|
3982
|
+
asset: input.asset,
|
|
3983
|
+
chain: input.target.chain,
|
|
3984
|
+
target: input.target
|
|
3985
|
+
};
|
|
3986
|
+
}
|
|
3797
3987
|
async estimateRepaymentInflowFee(asset, chain) {
|
|
3798
3988
|
try {
|
|
3799
3989
|
const fee = await this.lending.estimateInflowFee({
|
|
@@ -3880,15 +4070,12 @@ function calculateTotalDebtAmount(borrowPosition) {
|
|
|
3880
4070
|
}
|
|
3881
4071
|
function deriveInstantLoanStatus(input) {
|
|
3882
4072
|
if (input.totalDebtAmount > 0n) {
|
|
3883
|
-
return
|
|
4073
|
+
return InstantLoanStatus.active;
|
|
3884
4074
|
}
|
|
3885
4075
|
if (input.collateralAmount > 0n) {
|
|
3886
|
-
return
|
|
4076
|
+
return InstantLoanStatus.depositDetected;
|
|
3887
4077
|
}
|
|
3888
|
-
|
|
3889
|
-
return "closed";
|
|
3890
|
-
}
|
|
3891
|
-
return "awaiting_deposit";
|
|
4078
|
+
return InstantLoanStatus.awaitingDeposit;
|
|
3892
4079
|
}
|
|
3893
4080
|
function validateCreateRequest(request) {
|
|
3894
4081
|
if (request.collateralAmount <= 0n) {
|
|
@@ -3922,7 +4109,7 @@ function throwLtvCalculationError(error) {
|
|
|
3922
4109
|
error?.message ?? "Unable to calculate instant loan LTV"
|
|
3923
4110
|
);
|
|
3924
4111
|
}
|
|
3925
|
-
function
|
|
4112
|
+
function addressFromAccountInput(account) {
|
|
3926
4113
|
const address = typeof account === "string" ? account.trim() : account.address.trim();
|
|
3927
4114
|
if (!address) {
|
|
3928
4115
|
throw new LiquidiumError(
|
|
@@ -3930,7 +4117,7 @@ function accountWireFromInput(account) {
|
|
|
3930
4117
|
"Instant loan account address must be non-empty"
|
|
3931
4118
|
);
|
|
3932
4119
|
}
|
|
3933
|
-
return
|
|
4120
|
+
return address;
|
|
3934
4121
|
}
|
|
3935
4122
|
function accountFromCanister(account) {
|
|
3936
4123
|
if ("Native" in account) {
|
|
@@ -4096,19 +4283,20 @@ function mapCandidateWire(wire) {
|
|
|
4096
4283
|
wire.borrowAsset ?? wire.borrow_asset,
|
|
4097
4284
|
"borrow asset"
|
|
4098
4285
|
),
|
|
4099
|
-
|
|
4100
|
-
wire.
|
|
4101
|
-
"collateral amount
|
|
4286
|
+
collateralAmount: parseBigintWire(
|
|
4287
|
+
wire.collateralAmount,
|
|
4288
|
+
"collateral amount"
|
|
4102
4289
|
)
|
|
4103
4290
|
};
|
|
4104
4291
|
}
|
|
4105
4292
|
function parseBigintWire(value, label) {
|
|
4106
|
-
if (
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4293
|
+
if (!value || !/^\d+$/.test(value)) {
|
|
4294
|
+
throw new LiquidiumError(
|
|
4295
|
+
LiquidiumErrorCode.VALIDATION_ERROR,
|
|
4296
|
+
`Invalid instant loan ${label}`
|
|
4297
|
+
);
|
|
4298
|
+
}
|
|
4299
|
+
return BigInt(value);
|
|
4112
4300
|
}
|
|
4113
4301
|
function requiredString(value, label) {
|
|
4114
4302
|
if (value?.trim()) return value;
|
|
@@ -4179,15 +4367,6 @@ function formatBpsAsPercent2(value) {
|
|
|
4179
4367
|
const fractionalPart = (absoluteValue % 100n).toString().padStart(2, "0");
|
|
4180
4368
|
return `${sign}${wholePart.toString()}.${fractionalPart}%`;
|
|
4181
4369
|
}
|
|
4182
|
-
|
|
4183
|
-
// src/modules/instant-loans/types.ts
|
|
4184
|
-
var InstantLoanStatus = {
|
|
4185
|
-
awaitingDeposit: "awaiting_deposit",
|
|
4186
|
-
depositDetected: "deposit_detected",
|
|
4187
|
-
active: "active",
|
|
4188
|
-
settling: "settling",
|
|
4189
|
-
closed: "closed"
|
|
4190
|
-
};
|
|
4191
4370
|
function createApproveTransaction(params) {
|
|
4192
4371
|
return {
|
|
4193
4372
|
to: params.tokenAddress,
|
|
@@ -4264,6 +4443,16 @@ function encodeBytes32Hex(bytes) {
|
|
|
4264
4443
|
(byte) => byte.toString(16).padStart(2, "0")
|
|
4265
4444
|
).join("")}`;
|
|
4266
4445
|
}
|
|
4446
|
+
var idlFactory5 = ({ IDL }) => IDL.Service({
|
|
4447
|
+
icrc1_fee: IDL.Func([], [IDL.Nat], ["query"])
|
|
4448
|
+
});
|
|
4449
|
+
function createCkBtcLedgerActor(canisterContext) {
|
|
4450
|
+
const canisterId = CK_CANISTER_IDS.btcLedger;
|
|
4451
|
+
return agent.Actor.createActor(idlFactory5, {
|
|
4452
|
+
agent: canisterContext.agent,
|
|
4453
|
+
canisterId
|
|
4454
|
+
});
|
|
4455
|
+
}
|
|
4267
4456
|
|
|
4268
4457
|
// src/core/canisters/lending/messages.ts
|
|
4269
4458
|
function createBorrowAssetMessage(request, nonce) {
|
|
@@ -4346,6 +4535,28 @@ function assertValidRetryOptions(options) {
|
|
|
4346
4535
|
}
|
|
4347
4536
|
}
|
|
4348
4537
|
|
|
4538
|
+
// src/modules/lending/_internal/inflow-fee-rounding.ts
|
|
4539
|
+
var ETH_STABLECOIN_INFLOW_FEE_ROUND_UP_TO_NEAREST_10_CENTS = 100000n;
|
|
4540
|
+
var BTC_INFLOW_FEE_ROUND_UP_TO_NEAREST_SATS = 500n;
|
|
4541
|
+
function roundInflowFeeEstimate(request, totalFee) {
|
|
4542
|
+
if (totalFee <= 0n) {
|
|
4543
|
+
return 0n;
|
|
4544
|
+
}
|
|
4545
|
+
if (isEthStablecoin(request.asset, request.chain)) {
|
|
4546
|
+
return roundUpToNearest(
|
|
4547
|
+
totalFee,
|
|
4548
|
+
ETH_STABLECOIN_INFLOW_FEE_ROUND_UP_TO_NEAREST_10_CENTS
|
|
4549
|
+
);
|
|
4550
|
+
}
|
|
4551
|
+
if (request.asset === Asset.BTC && request.chain === Chain.BTC) {
|
|
4552
|
+
return roundUpToNearest(totalFee, BTC_INFLOW_FEE_ROUND_UP_TO_NEAREST_SATS);
|
|
4553
|
+
}
|
|
4554
|
+
return totalFee;
|
|
4555
|
+
}
|
|
4556
|
+
function roundUpToNearest(amount, roundingUnit) {
|
|
4557
|
+
return ceilDivBigint(amount, roundingUnit) * roundingUnit;
|
|
4558
|
+
}
|
|
4559
|
+
|
|
4349
4560
|
// src/modules/lending/mappers.ts
|
|
4350
4561
|
function mapCanisterOutflowDetails(outflow) {
|
|
4351
4562
|
const rawOutflowType = getVariantKey(outflow.outflow_type);
|
|
@@ -4434,6 +4645,10 @@ var LendingModule = class {
|
|
|
4434
4645
|
"Withdraw requires a signer account"
|
|
4435
4646
|
);
|
|
4436
4647
|
}
|
|
4648
|
+
const receiverAddress = await this.normalizeOutflowReceiverAddress({
|
|
4649
|
+
poolId: request.poolId,
|
|
4650
|
+
receiverAddress: destinationAccount
|
|
4651
|
+
});
|
|
4437
4652
|
const lendingActor = createLendingActor(this.canisterContext);
|
|
4438
4653
|
try {
|
|
4439
4654
|
const expiryTimestamp = computeExpiryTimestampFromNow();
|
|
@@ -4442,7 +4657,7 @@ var LendingModule = class {
|
|
|
4442
4657
|
profileId: request.profileId,
|
|
4443
4658
|
poolId: request.poolId,
|
|
4444
4659
|
amount: request.amount,
|
|
4445
|
-
receiverAddress
|
|
4660
|
+
receiverAddress,
|
|
4446
4661
|
signerWalletAddress: signerAccount,
|
|
4447
4662
|
expiryTimestamp
|
|
4448
4663
|
};
|
|
@@ -4456,7 +4671,7 @@ var LendingModule = class {
|
|
|
4456
4671
|
{
|
|
4457
4672
|
pool_id: request.poolId,
|
|
4458
4673
|
amount: request.amount.toString(),
|
|
4459
|
-
account: { type: "External", data:
|
|
4674
|
+
account: { type: "External", data: receiverAddress },
|
|
4460
4675
|
expiry_timestamp: expiryTimestamp
|
|
4461
4676
|
},
|
|
4462
4677
|
nonce
|
|
@@ -4549,6 +4764,29 @@ var LendingModule = class {
|
|
|
4549
4764
|
"Borrow requires a signer account"
|
|
4550
4765
|
);
|
|
4551
4766
|
}
|
|
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)
|
|
4789
|
+
});
|
|
4552
4790
|
const lendingActor = createLendingActor(this.canisterContext);
|
|
4553
4791
|
try {
|
|
4554
4792
|
const expiryTimestamp = computeExpiryTimestampFromNow();
|
|
@@ -4557,7 +4795,7 @@ var LendingModule = class {
|
|
|
4557
4795
|
profileId: request.profileId,
|
|
4558
4796
|
poolId: request.poolId,
|
|
4559
4797
|
amount: request.amount,
|
|
4560
|
-
receiverAddress
|
|
4798
|
+
receiverAddress,
|
|
4561
4799
|
signerWalletAddress: signerAccount,
|
|
4562
4800
|
expiryTimestamp
|
|
4563
4801
|
};
|
|
@@ -4571,7 +4809,7 @@ var LendingModule = class {
|
|
|
4571
4809
|
{
|
|
4572
4810
|
pool_id: request.poolId,
|
|
4573
4811
|
amount: request.amount.toString(),
|
|
4574
|
-
account: { type: "External", data:
|
|
4812
|
+
account: { type: "External", data: receiverAddress },
|
|
4575
4813
|
expiry_timestamp: expiryTimestamp
|
|
4576
4814
|
},
|
|
4577
4815
|
nonce
|
|
@@ -4820,10 +5058,10 @@ var LendingModule = class {
|
|
|
4820
5058
|
* Estimates the network/deposit fee for an inflow target.
|
|
4821
5059
|
*
|
|
4822
5060
|
* ETH stablecoin deposit-address estimates are served by the deposit-address
|
|
4823
|
-
* canister. BTC estimates
|
|
5061
|
+
* canister. BTC estimates include the ckBTC minter deposit fee and ledger fee.
|
|
4824
5062
|
*
|
|
4825
5063
|
* @param request - Asset and chain pair to estimate for.
|
|
4826
|
-
* @returns Total fee estimate in the asset's base units.
|
|
5064
|
+
* @returns Total fee estimate rounded up in the asset's base units.
|
|
4827
5065
|
*/
|
|
4828
5066
|
async estimateInflowFee(request) {
|
|
4829
5067
|
if (isEthStablecoin(request.asset, request.chain)) {
|
|
@@ -4833,16 +5071,28 @@ var LendingModule = class {
|
|
|
4833
5071
|
if ("Err" in result) {
|
|
4834
5072
|
throw mapDepositAccountErrorToLiquidiumError(result.Err);
|
|
4835
5073
|
}
|
|
4836
|
-
return {
|
|
5074
|
+
return {
|
|
5075
|
+
totalFee: roundInflowFeeEstimate(request, result.Ok)
|
|
5076
|
+
};
|
|
4837
5077
|
}
|
|
4838
5078
|
if (request.asset === Asset.BTC && request.chain === Chain.BTC) {
|
|
4839
|
-
|
|
5079
|
+
const estimate = await this.estimateBtcInflowFee();
|
|
5080
|
+
return {
|
|
5081
|
+
totalFee: roundInflowFeeEstimate(request, estimate.totalFee)
|
|
5082
|
+
};
|
|
4840
5083
|
}
|
|
4841
5084
|
throw new LiquidiumError(
|
|
4842
5085
|
LiquidiumErrorCode.VALIDATION_ERROR,
|
|
4843
5086
|
`Inflow fee estimates are not supported for ${request.asset} on ${request.chain}`
|
|
4844
5087
|
);
|
|
4845
5088
|
}
|
|
5089
|
+
async estimateBtcInflowFee() {
|
|
5090
|
+
const [minterFee, ledgerFee] = await Promise.all([
|
|
5091
|
+
createCkBtcMinterActor(this.canisterContext).get_deposit_fee(),
|
|
5092
|
+
createCkBtcLedgerActor(this.canisterContext).icrc1_fee()
|
|
5093
|
+
]);
|
|
5094
|
+
return { totalFee: minterFee + ledgerFee };
|
|
5095
|
+
}
|
|
4846
5096
|
async sendAndSubmitNativeSupplyInflow(params) {
|
|
4847
5097
|
const { request, instruction, defaultSubmitInflowRequest } = params;
|
|
4848
5098
|
if (instruction.target.type !== "nativeAddress") {
|
|
@@ -5135,6 +5385,14 @@ var LendingModule = class {
|
|
|
5135
5385
|
}
|
|
5136
5386
|
return selectedPool;
|
|
5137
5387
|
}
|
|
5388
|
+
async normalizeOutflowReceiverAddress(params) {
|
|
5389
|
+
const selectedPool = await this.getPoolById(params.poolId);
|
|
5390
|
+
return normalizeExternalAddress({
|
|
5391
|
+
address: params.receiverAddress,
|
|
5392
|
+
asset: getVariantKey(selectedPool.asset),
|
|
5393
|
+
chain: getVariantKey(selectedPool.chain)
|
|
5394
|
+
});
|
|
5395
|
+
}
|
|
5138
5396
|
async sendEthContractTransaction(walletAdapter, walletAddress, request, actionType) {
|
|
5139
5397
|
if (!walletAdapter.sendEthTransaction) {
|
|
5140
5398
|
throw new LiquidiumError(
|
|
@@ -5209,12 +5467,6 @@ function getApprovalStrategy(params) {
|
|
|
5209
5467
|
}
|
|
5210
5468
|
return EvmSupplyApprovalStrategy.resetThenApproveMax;
|
|
5211
5469
|
}
|
|
5212
|
-
function normalizeAndValidateEvmAddress(address, errorMessage) {
|
|
5213
|
-
if (!viem.isAddress(address)) {
|
|
5214
|
-
throw new LiquidiumError(LiquidiumErrorCode.INVALID_ADDRESS, errorMessage);
|
|
5215
|
-
}
|
|
5216
|
-
return viem.getAddress(address);
|
|
5217
|
-
}
|
|
5218
5470
|
function mapExpectedOutflowDetails(details, expectedOutflowType, operation) {
|
|
5219
5471
|
if (details.outflowType !== expectedOutflowType) {
|
|
5220
5472
|
throw new LiquidiumError(
|
|
@@ -5264,24 +5516,6 @@ function shouldSubmitInflow(params) {
|
|
|
5264
5516
|
return !isEthStablecoin(params.instruction.asset, params.instruction.chain);
|
|
5265
5517
|
}
|
|
5266
5518
|
|
|
5267
|
-
// src/core/utils/asset-decimals.ts
|
|
5268
|
-
var ASSET_NATIVE_DECIMALS = {
|
|
5269
|
-
BTC: 8n,
|
|
5270
|
-
USDC: 6n,
|
|
5271
|
-
USDT: 6n,
|
|
5272
|
-
SOL: 9n
|
|
5273
|
-
};
|
|
5274
|
-
function getAssetNativeDecimals(asset) {
|
|
5275
|
-
const decimals = ASSET_NATIVE_DECIMALS[asset];
|
|
5276
|
-
if (decimals === void 0) {
|
|
5277
|
-
throw new LiquidiumError(
|
|
5278
|
-
LiquidiumErrorCode.VALIDATION_ERROR,
|
|
5279
|
-
`Native decimals are not configured for asset: ${asset}`
|
|
5280
|
-
);
|
|
5281
|
-
}
|
|
5282
|
-
return decimals;
|
|
5283
|
-
}
|
|
5284
|
-
|
|
5285
5519
|
// src/modules/market/mappers.ts
|
|
5286
5520
|
var DECIMAL_BASE = 10;
|
|
5287
5521
|
var PAIR_SEPARATOR = "_";
|
|
@@ -5819,6 +6053,7 @@ exports.LendingModule = LendingModule;
|
|
|
5819
6053
|
exports.LiquidiumClient = LiquidiumClient;
|
|
5820
6054
|
exports.LiquidiumError = LiquidiumError;
|
|
5821
6055
|
exports.LiquidiumErrorCode = LiquidiumErrorCode;
|
|
6056
|
+
exports.MIN_BORROW_AMOUNTS_BY_ASSET = MIN_BORROW_AMOUNTS_BY_ASSET;
|
|
5822
6057
|
exports.MarketModule = MarketModule;
|
|
5823
6058
|
exports.OutflowType = OutflowType;
|
|
5824
6059
|
exports.PositionsModule = PositionsModule;
|
|
@@ -5836,6 +6071,7 @@ exports.UserHistoryStatus = UserHistoryStatus;
|
|
|
5836
6071
|
exports.WalletExecutionKind = WalletExecutionKind;
|
|
5837
6072
|
exports.createTransferErc20Transaction = createTransferErc20Transaction;
|
|
5838
6073
|
exports.executeWith = executeWith;
|
|
6074
|
+
exports.getMinimumBorrowAmount = getMinimumBorrowAmount;
|
|
5839
6075
|
exports.intFromPublicId = intFromPublicId;
|
|
5840
6076
|
exports.publicIdFromInt = publicIdFromInt;
|
|
5841
6077
|
//# sourceMappingURL=index.cjs.map
|