@liquidium/client 0.5.1 → 0.6.0-rc.0
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 +2 -2
- package/dist/index.cjs +291 -91
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +56 -23
- package/dist/index.d.ts +56 -23
- package/dist/index.js +290 -92
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -7,8 +7,8 @@ var principal = require('@icp-sdk/core/principal');
|
|
|
7
7
|
var base = require('@scure/base');
|
|
8
8
|
var candid = require('@icp-sdk/core/candid');
|
|
9
9
|
var icrc = require('@icp-sdk/canisters/ledger/icrc');
|
|
10
|
-
var icp = require('@icp-sdk/canisters/ledger/icp');
|
|
11
10
|
var bitcoinAddressValidation = require('bitcoin-address-validation');
|
|
11
|
+
var icp = require('@icp-sdk/canisters/ledger/icp');
|
|
12
12
|
|
|
13
13
|
// src/client.ts
|
|
14
14
|
|
|
@@ -88,6 +88,7 @@ var Environment = {
|
|
|
88
88
|
};
|
|
89
89
|
var Asset = {
|
|
90
90
|
BTC: "BTC",
|
|
91
|
+
ETH: "ETH",
|
|
91
92
|
ICP: "ICP",
|
|
92
93
|
USDC: "USDC",
|
|
93
94
|
USDT: "USDT"
|
|
@@ -102,9 +103,9 @@ function isAssetIdentifier(identifier) {
|
|
|
102
103
|
case Chain.BTC:
|
|
103
104
|
return identifier.asset === Asset.BTC;
|
|
104
105
|
case Chain.ETH:
|
|
105
|
-
return identifier.asset === Asset.USDC || identifier.asset === Asset.USDT;
|
|
106
|
+
return identifier.asset === Asset.ETH || identifier.asset === Asset.USDC || identifier.asset === Asset.USDT;
|
|
106
107
|
case Chain.ICP:
|
|
107
|
-
return identifier.asset === Asset.BTC || identifier.asset === Asset.ICP || identifier.asset === Asset.USDC || identifier.asset === Asset.USDT;
|
|
108
|
+
return identifier.asset === Asset.BTC || identifier.asset === Asset.ETH || identifier.asset === Asset.ICP || identifier.asset === Asset.USDC || identifier.asset === Asset.USDT;
|
|
108
109
|
default:
|
|
109
110
|
return false;
|
|
110
111
|
}
|
|
@@ -127,6 +128,7 @@ var MAINNET_CANISTER_IDS = {
|
|
|
127
128
|
lending: "hyk4r-jqaaa-aaaar-qb4ca-cai",
|
|
128
129
|
pools: {
|
|
129
130
|
btc: "hkmli-faaaa-aaaar-qb4ba-cai",
|
|
131
|
+
eth: "qcg7y-syaaa-aaaar-qb75q-cai",
|
|
130
132
|
usdt: "hnnn4-iyaaa-aaaar-qb4bq-cai",
|
|
131
133
|
usdc: "6sna2-oiaaa-aaaar-qb66q-cai",
|
|
132
134
|
icp: "r2pk3-4yaaa-aaaar-qb7zq-cai"
|
|
@@ -145,6 +147,7 @@ var SUPPORTED_CANISTER_ID_OVERRIDE_KEYS = /* @__PURE__ */ new Set([
|
|
|
145
147
|
]);
|
|
146
148
|
var SUPPORTED_POOL_CANISTER_ID_OVERRIDE_KEYS = /* @__PURE__ */ new Set([
|
|
147
149
|
"btc",
|
|
150
|
+
"eth",
|
|
148
151
|
"usdt",
|
|
149
152
|
"usdc",
|
|
150
153
|
"icp"
|
|
@@ -195,6 +198,8 @@ var CK_CANISTER_IDS = {
|
|
|
195
198
|
BTC: {
|
|
196
199
|
minter: "mqygn-kiaaa-aaaar-qaadq-cai",
|
|
197
200
|
ledger: "mxzaz-hqaaa-aaaar-qaada-cai"},
|
|
201
|
+
ETH: {
|
|
202
|
+
ledger: "ss2fx-dyaaa-aaaar-qacoq-cai"},
|
|
198
203
|
USDT: {
|
|
199
204
|
ledger: "cngnf-vqaaa-aaaar-qag4q-cai"},
|
|
200
205
|
USDC: {
|
|
@@ -433,6 +438,7 @@ var idlFactory = ({ IDL }) => {
|
|
|
433
438
|
});
|
|
434
439
|
const Assets = IDL.Variant({
|
|
435
440
|
"BTC": IDL.Null,
|
|
441
|
+
"ETH": IDL.Null,
|
|
436
442
|
"ICP": IDL.Null,
|
|
437
443
|
"SOL": IDL.Null,
|
|
438
444
|
"USDC": IDL.Null,
|
|
@@ -1016,6 +1022,16 @@ var ERC20_ABI = [
|
|
|
1016
1022
|
}
|
|
1017
1023
|
];
|
|
1018
1024
|
var CK_DEPOSIT_ABI = [
|
|
1025
|
+
{
|
|
1026
|
+
inputs: [
|
|
1027
|
+
{ internalType: "bytes32", name: "principal", type: "bytes32" },
|
|
1028
|
+
{ internalType: "bytes32", name: "subaccount", type: "bytes32" }
|
|
1029
|
+
],
|
|
1030
|
+
name: "depositEth",
|
|
1031
|
+
outputs: [],
|
|
1032
|
+
stateMutability: "payable",
|
|
1033
|
+
type: "function"
|
|
1034
|
+
},
|
|
1019
1035
|
{
|
|
1020
1036
|
inputs: [
|
|
1021
1037
|
{ internalType: "address", name: "erc20Address", type: "address" },
|
|
@@ -1399,7 +1415,7 @@ function mapCanisterWalletToWallet(canisterWallet) {
|
|
|
1399
1415
|
);
|
|
1400
1416
|
}
|
|
1401
1417
|
}
|
|
1402
|
-
var KNOWN_ASSET_TAGS = ["BTC", "ICP", "USDC", "USDT"];
|
|
1418
|
+
var KNOWN_ASSET_TAGS = ["BTC", "ETH", "ICP", "USDC", "USDT"];
|
|
1403
1419
|
var KNOWN_CHAIN_TAGS = ["BTC", "ETH", "ICP"];
|
|
1404
1420
|
function extractVariantTag(variant, knownTags) {
|
|
1405
1421
|
const [key] = Object.keys(variant);
|
|
@@ -2225,28 +2241,7 @@ function createTransferErc20Transaction(params) {
|
|
|
2225
2241
|
};
|
|
2226
2242
|
}
|
|
2227
2243
|
function createDepositErc20Transaction(params) {
|
|
2228
|
-
const
|
|
2229
|
-
owner: principal.Principal.fromText(params.poolId),
|
|
2230
|
-
subaccount: encodeInflowSubaccount({
|
|
2231
|
-
action: params.action,
|
|
2232
|
-
principal: principal.Principal.fromText(params.profileId)
|
|
2233
|
-
})
|
|
2234
|
-
});
|
|
2235
|
-
if (params.destinationAccount !== expectedDestinationAccount) {
|
|
2236
|
-
throw new LiquidiumError(
|
|
2237
|
-
LiquidiumErrorCode.VALIDATION_ERROR,
|
|
2238
|
-
"ETH supply destination account does not match the expected inflow account"
|
|
2239
|
-
);
|
|
2240
|
-
}
|
|
2241
|
-
const principalBytes32 = encodePrincipalToBytes32(
|
|
2242
|
-
principal.Principal.fromText(params.poolId)
|
|
2243
|
-
);
|
|
2244
|
-
const subaccountHex = encodeBytes32Hex(
|
|
2245
|
-
encodeInflowSubaccount({
|
|
2246
|
-
action: params.action,
|
|
2247
|
-
principal: principal.Principal.fromText(params.profileId)
|
|
2248
|
-
})
|
|
2249
|
-
);
|
|
2244
|
+
const { principalBytes32, subaccountHex } = createDepositAccountContext(params);
|
|
2250
2245
|
return {
|
|
2251
2246
|
to: params.depositContractAddress,
|
|
2252
2247
|
data: viem.encodeFunctionData({
|
|
@@ -2261,6 +2256,40 @@ function createDepositErc20Transaction(params) {
|
|
|
2261
2256
|
})
|
|
2262
2257
|
};
|
|
2263
2258
|
}
|
|
2259
|
+
function createDepositEthTransaction(params) {
|
|
2260
|
+
const { principalBytes32, subaccountHex } = createDepositAccountContext(params);
|
|
2261
|
+
return {
|
|
2262
|
+
to: params.depositContractAddress,
|
|
2263
|
+
data: viem.encodeFunctionData({
|
|
2264
|
+
abi: CK_DEPOSIT_ABI,
|
|
2265
|
+
functionName: "depositEth",
|
|
2266
|
+
args: [principalBytes32, subaccountHex]
|
|
2267
|
+
}),
|
|
2268
|
+
value: params.amount.toString()
|
|
2269
|
+
};
|
|
2270
|
+
}
|
|
2271
|
+
function createDepositAccountContext(params) {
|
|
2272
|
+
const inflowSubaccount = encodeInflowSubaccount({
|
|
2273
|
+
action: params.action,
|
|
2274
|
+
principal: principal.Principal.fromText(params.profileId)
|
|
2275
|
+
});
|
|
2276
|
+
const expectedDestinationAccount = icrc.encodeIcrcAccount({
|
|
2277
|
+
owner: principal.Principal.fromText(params.poolId),
|
|
2278
|
+
subaccount: inflowSubaccount
|
|
2279
|
+
});
|
|
2280
|
+
if (params.destinationAccount !== expectedDestinationAccount) {
|
|
2281
|
+
throw new LiquidiumError(
|
|
2282
|
+
LiquidiumErrorCode.VALIDATION_ERROR,
|
|
2283
|
+
"ETH supply destination account does not match the expected inflow account"
|
|
2284
|
+
);
|
|
2285
|
+
}
|
|
2286
|
+
return {
|
|
2287
|
+
principalBytes32: encodePrincipalToBytes32(
|
|
2288
|
+
principal.Principal.fromText(params.poolId)
|
|
2289
|
+
),
|
|
2290
|
+
subaccountHex: encodeBytes32Hex(inflowSubaccount)
|
|
2291
|
+
};
|
|
2292
|
+
}
|
|
2264
2293
|
function encodePrincipalToBytes32(principal) {
|
|
2265
2294
|
const principalBytes = principal.toUint8Array();
|
|
2266
2295
|
if (principalBytes.length > 29) {
|
|
@@ -2280,12 +2309,59 @@ function encodeBytes32Hex(bytes) {
|
|
|
2280
2309
|
(byte) => byte.toString(16).padStart(2, "0")
|
|
2281
2310
|
).join("")}`;
|
|
2282
2311
|
}
|
|
2312
|
+
var BTC_MAINNET_ADDRESS_ERROR = "Address must be a valid mainnet BTC address";
|
|
2313
|
+
var EVM_ADDRESS_ERROR = "Address must be a valid EVM address";
|
|
2314
|
+
var ADDRESS_CHAIN_MISMATCH_ERROR = "Address chain must match asset";
|
|
2315
|
+
function normalizeExternalAddress(params) {
|
|
2316
|
+
if (params.asset === Asset.BTC) {
|
|
2317
|
+
if (params.chain !== Chain.BTC) {
|
|
2318
|
+
throw new LiquidiumError(
|
|
2319
|
+
LiquidiumErrorCode.INVALID_ADDRESS,
|
|
2320
|
+
ADDRESS_CHAIN_MISMATCH_ERROR
|
|
2321
|
+
);
|
|
2322
|
+
}
|
|
2323
|
+
if (!bitcoinAddressValidation.validate(params.address, bitcoinAddressValidation.Network.mainnet)) {
|
|
2324
|
+
throw new LiquidiumError(
|
|
2325
|
+
LiquidiumErrorCode.INVALID_ADDRESS,
|
|
2326
|
+
BTC_MAINNET_ADDRESS_ERROR
|
|
2327
|
+
);
|
|
2328
|
+
}
|
|
2329
|
+
return params.address;
|
|
2330
|
+
}
|
|
2331
|
+
if (isEvmAsset(params.asset)) {
|
|
2332
|
+
if (params.chain !== Chain.ETH) {
|
|
2333
|
+
throw new LiquidiumError(
|
|
2334
|
+
LiquidiumErrorCode.INVALID_ADDRESS,
|
|
2335
|
+
ADDRESS_CHAIN_MISMATCH_ERROR
|
|
2336
|
+
);
|
|
2337
|
+
}
|
|
2338
|
+
if (!viem.isAddress(params.address)) {
|
|
2339
|
+
throw new LiquidiumError(
|
|
2340
|
+
LiquidiumErrorCode.INVALID_ADDRESS,
|
|
2341
|
+
EVM_ADDRESS_ERROR
|
|
2342
|
+
);
|
|
2343
|
+
}
|
|
2344
|
+
return viem.getAddress(params.address);
|
|
2345
|
+
}
|
|
2346
|
+
return params.address;
|
|
2347
|
+
}
|
|
2348
|
+
function normalizeAndValidateEvmAddress(address, errorMessage) {
|
|
2349
|
+
if (!viem.isAddress(address)) {
|
|
2350
|
+
throw new LiquidiumError(LiquidiumErrorCode.INVALID_ADDRESS, errorMessage);
|
|
2351
|
+
}
|
|
2352
|
+
return viem.getAddress(address);
|
|
2353
|
+
}
|
|
2354
|
+
function isEvmAsset(asset) {
|
|
2355
|
+
return asset === Asset.ETH || asset === Asset.USDC || asset === Asset.USDT;
|
|
2356
|
+
}
|
|
2283
2357
|
|
|
2284
2358
|
// src/core/borrow-minimums.ts
|
|
2285
2359
|
var MINIMUM_BTC_BORROW_AMOUNT_SATS = 5100n;
|
|
2360
|
+
var MINIMUM_ETH_BORROW_AMOUNT_WEI = 5000000000000000n;
|
|
2286
2361
|
var MINIMUM_STABLECOIN_BORROW_AMOUNT_BASE_UNITS = 1000000n;
|
|
2287
2362
|
var MIN_BORROW_AMOUNTS_BY_ASSET = {
|
|
2288
2363
|
[Asset.BTC]: MINIMUM_BTC_BORROW_AMOUNT_SATS,
|
|
2364
|
+
[Asset.ETH]: MINIMUM_ETH_BORROW_AMOUNT_WEI,
|
|
2289
2365
|
[Asset.USDC]: MINIMUM_STABLECOIN_BORROW_AMOUNT_BASE_UNITS,
|
|
2290
2366
|
[Asset.USDT]: MINIMUM_STABLECOIN_BORROW_AMOUNT_BASE_UNITS
|
|
2291
2367
|
};
|
|
@@ -3179,6 +3255,13 @@ function getPoolLedgerAssetRoute(params) {
|
|
|
3179
3255
|
chain: params.chain
|
|
3180
3256
|
};
|
|
3181
3257
|
}
|
|
3258
|
+
if (params.asset === Asset.ETH && (params.chain === Chain.ETH || params.chain === Chain.ICP)) {
|
|
3259
|
+
return {
|
|
3260
|
+
ledgerCanisterId: CK_CANISTER_IDS.ETH.ledger,
|
|
3261
|
+
asset: Asset.ETH,
|
|
3262
|
+
chain: params.chain
|
|
3263
|
+
};
|
|
3264
|
+
}
|
|
3182
3265
|
if (params.asset === Asset.USDT && (params.chain === Chain.ETH || params.chain === Chain.ICP)) {
|
|
3183
3266
|
return {
|
|
3184
3267
|
ledgerCanisterId: CK_CANISTER_IDS.USDT.ledger,
|
|
@@ -3253,9 +3336,11 @@ function createLiquidiumStatus(params) {
|
|
|
3253
3336
|
|
|
3254
3337
|
// src/core/withdraw-minimums.ts
|
|
3255
3338
|
var MINIMUM_BTC_WITHDRAW_AMOUNT_SATS = 5000n;
|
|
3339
|
+
var MINIMUM_ETH_WITHDRAW_AMOUNT_WEI = 5000000000000000n;
|
|
3256
3340
|
var MINIMUM_STABLECOIN_WITHDRAW_AMOUNT_BASE_UNITS = 1000000n;
|
|
3257
3341
|
var MIN_WITHDRAW_AMOUNTS_BY_ASSET = {
|
|
3258
3342
|
[Asset.BTC]: MINIMUM_BTC_WITHDRAW_AMOUNT_SATS,
|
|
3343
|
+
[Asset.ETH]: MINIMUM_ETH_WITHDRAW_AMOUNT_WEI,
|
|
3259
3344
|
[Asset.USDC]: MINIMUM_STABLECOIN_WITHDRAW_AMOUNT_BASE_UNITS,
|
|
3260
3345
|
[Asset.USDT]: MINIMUM_STABLECOIN_WITHDRAW_AMOUNT_BASE_UNITS
|
|
3261
3346
|
};
|
|
@@ -3392,7 +3477,7 @@ function resolveSupplyMechanism(params) {
|
|
|
3392
3477
|
if (params.mechanism !== SupplyPlanType.contractInteraction) {
|
|
3393
3478
|
return SupplyPlanType.transfer;
|
|
3394
3479
|
}
|
|
3395
|
-
if (params.identifier.chain === Chain.ETH && (params.identifier.asset === Asset.USDC || params.identifier.asset === Asset.USDT)) {
|
|
3480
|
+
if (params.identifier.chain === Chain.ETH && (params.identifier.asset === Asset.ETH || params.identifier.asset === Asset.USDC || params.identifier.asset === Asset.USDT)) {
|
|
3396
3481
|
return SupplyPlanType.contractInteraction;
|
|
3397
3482
|
}
|
|
3398
3483
|
throw new LiquidiumError(
|
|
@@ -3415,6 +3500,12 @@ function getEthStablecoinContractAddress(asset) {
|
|
|
3415
3500
|
`ETH stablecoin contract address is not configured for ${asset}`
|
|
3416
3501
|
);
|
|
3417
3502
|
}
|
|
3503
|
+
function getEthDepositTokenAddress(asset) {
|
|
3504
|
+
if (asset === Asset.ETH) {
|
|
3505
|
+
return [];
|
|
3506
|
+
}
|
|
3507
|
+
return [getEthStablecoinContractAddress(asset)];
|
|
3508
|
+
}
|
|
3418
3509
|
function mapDepositAccountErrorToLiquidiumError(error) {
|
|
3419
3510
|
if ("InvalidEvmAddress" in error) {
|
|
3420
3511
|
return new LiquidiumError(
|
|
@@ -3478,7 +3569,7 @@ function resolveSupplyAssetIdentifier(params) {
|
|
|
3478
3569
|
return { asset: Asset.BTC, chain: Chain.ICP };
|
|
3479
3570
|
}
|
|
3480
3571
|
}
|
|
3481
|
-
if ((params.asset === Asset.USDC || params.asset === Asset.USDT) && params.poolChain === Chain.ETH) {
|
|
3572
|
+
if ((params.asset === Asset.ETH || params.asset === Asset.USDC || params.asset === Asset.USDT) && params.poolChain === Chain.ETH) {
|
|
3482
3573
|
if (params.transferChain === Chain.ETH) {
|
|
3483
3574
|
return { asset: params.asset, chain: Chain.ETH };
|
|
3484
3575
|
}
|
|
@@ -3496,7 +3587,6 @@ function resolveSupplyAssetIdentifier(params) {
|
|
|
3496
3587
|
}
|
|
3497
3588
|
async function getChainAddressSupplyTarget(canisterContext, profileId, request) {
|
|
3498
3589
|
if (request.chain === Chain.ETH) {
|
|
3499
|
-
const tokenAddress = getEthStablecoinContractAddress(request.asset);
|
|
3500
3590
|
const subaccount2 = encodeInflowSubaccount({
|
|
3501
3591
|
action: request.action,
|
|
3502
3592
|
principal: principal.Principal.fromText(profileId)
|
|
@@ -3508,17 +3598,21 @@ async function getChainAddressSupplyTarget(canisterContext, profileId, request)
|
|
|
3508
3598
|
owner: principal.Principal.fromText(request.poolId),
|
|
3509
3599
|
subaccount: [subaccount2]
|
|
3510
3600
|
},
|
|
3511
|
-
|
|
3601
|
+
getEthDepositTokenAddress(request.asset)
|
|
3512
3602
|
);
|
|
3513
3603
|
if ("Err" in result) {
|
|
3514
3604
|
throw mapDepositAccountErrorToLiquidiumError(result.Err);
|
|
3515
3605
|
}
|
|
3606
|
+
const address2 = normalizeAndValidateEvmAddress(
|
|
3607
|
+
result.Ok,
|
|
3608
|
+
"Deposit address canister returned an invalid EVM address"
|
|
3609
|
+
);
|
|
3516
3610
|
return {
|
|
3517
3611
|
poolId: request.poolId,
|
|
3518
3612
|
asset: request.asset,
|
|
3519
3613
|
chain: request.chain,
|
|
3520
3614
|
action: request.action,
|
|
3521
|
-
address:
|
|
3615
|
+
address: address2
|
|
3522
3616
|
};
|
|
3523
3617
|
}
|
|
3524
3618
|
const configuredBtcPoolId = canisterContext.canisterIds.pools.btc;
|
|
@@ -3597,50 +3691,38 @@ function roundInflowFeeEstimate(request, totalFee) {
|
|
|
3597
3691
|
function roundUpToNearest(amount, roundingUnit) {
|
|
3598
3692
|
return ceilDivBigint(amount, roundingUnit) * roundingUnit;
|
|
3599
3693
|
}
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
var
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
}
|
|
3617
|
-
return params.address;
|
|
3618
|
-
}
|
|
3619
|
-
if (isEthStablecoin2(params.asset)) {
|
|
3620
|
-
if (params.chain !== Chain.ETH) {
|
|
3621
|
-
throw new LiquidiumError(
|
|
3622
|
-
LiquidiumErrorCode.INVALID_ADDRESS,
|
|
3623
|
-
ADDRESS_CHAIN_MISMATCH_ERROR
|
|
3624
|
-
);
|
|
3625
|
-
}
|
|
3626
|
-
if (!viem.isAddress(params.address)) {
|
|
3627
|
-
throw new LiquidiumError(
|
|
3628
|
-
LiquidiumErrorCode.INVALID_ADDRESS,
|
|
3629
|
-
EVM_ADDRESS_ERROR
|
|
3630
|
-
);
|
|
3631
|
-
}
|
|
3632
|
-
return viem.getAddress(params.address);
|
|
3694
|
+
|
|
3695
|
+
// src/core/deposit-minimums.ts
|
|
3696
|
+
var MINIMUM_BTC_DEPOSIT_AMOUNT_SATS = 5100n;
|
|
3697
|
+
var MINIMUM_ETH_DEPOSIT_AMOUNT_WEI = 5000000000000000n;
|
|
3698
|
+
var MINIMUM_ICP_DEPOSIT_AMOUNT_E8S = 10000n;
|
|
3699
|
+
var MINIMUM_STABLECOIN_DEPOSIT_AMOUNT_BASE_UNITS = 1000000n;
|
|
3700
|
+
var MIN_DEPOSIT_AMOUNTS_BY_ASSET = {
|
|
3701
|
+
[Asset.BTC]: MINIMUM_BTC_DEPOSIT_AMOUNT_SATS,
|
|
3702
|
+
[Asset.ETH]: MINIMUM_ETH_DEPOSIT_AMOUNT_WEI,
|
|
3703
|
+
[Asset.ICP]: MINIMUM_ICP_DEPOSIT_AMOUNT_E8S,
|
|
3704
|
+
[Asset.USDC]: MINIMUM_STABLECOIN_DEPOSIT_AMOUNT_BASE_UNITS,
|
|
3705
|
+
[Asset.USDT]: MINIMUM_STABLECOIN_DEPOSIT_AMOUNT_BASE_UNITS
|
|
3706
|
+
};
|
|
3707
|
+
function getMinimumDepositAmount(asset) {
|
|
3708
|
+
if (!isMinimumDepositAsset(asset)) {
|
|
3709
|
+
return 0n;
|
|
3633
3710
|
}
|
|
3634
|
-
return
|
|
3711
|
+
return MIN_DEPOSIT_AMOUNTS_BY_ASSET[asset];
|
|
3635
3712
|
}
|
|
3636
|
-
function
|
|
3637
|
-
|
|
3638
|
-
|
|
3713
|
+
function getDepositAmountMinimumValidationError(params) {
|
|
3714
|
+
const minimumAmount = getMinimumDepositAmount(params.asset);
|
|
3715
|
+
if (minimumAmount <= 0n || params.amount >= minimumAmount) {
|
|
3716
|
+
return null;
|
|
3639
3717
|
}
|
|
3640
|
-
return
|
|
3718
|
+
return {
|
|
3719
|
+
asset: params.asset,
|
|
3720
|
+
minimumAmount,
|
|
3721
|
+
message: `Deposit amount must be at least ${minimumAmount} base units for ${params.asset}`
|
|
3722
|
+
};
|
|
3641
3723
|
}
|
|
3642
|
-
function
|
|
3643
|
-
return
|
|
3724
|
+
function isMinimumDepositAsset(asset) {
|
|
3725
|
+
return Object.hasOwn(MIN_DEPOSIT_AMOUNTS_BY_ASSET, asset);
|
|
3644
3726
|
}
|
|
3645
3727
|
|
|
3646
3728
|
// src/core/utils/retry.ts
|
|
@@ -3707,7 +3789,13 @@ var SupplyFlowExecutor = class {
|
|
|
3707
3789
|
params;
|
|
3708
3790
|
async create(request) {
|
|
3709
3791
|
const requestedMechanism = request.mechanism ?? null;
|
|
3710
|
-
if (requestedMechanism
|
|
3792
|
+
if (requestedMechanism !== null && requestedMechanism !== SupplyPlanType.transfer && requestedMechanism !== SupplyPlanType.contractInteraction) {
|
|
3793
|
+
throw new LiquidiumError(
|
|
3794
|
+
LiquidiumErrorCode.VALIDATION_ERROR,
|
|
3795
|
+
`Unsupported supply mechanism: ${String(requestedMechanism)}`
|
|
3796
|
+
);
|
|
3797
|
+
}
|
|
3798
|
+
if (requestedMechanism !== SupplyPlanType.contractInteraction && request.walletAdapter === void 0 && (request.account !== void 0 || request.amount !== void 0)) {
|
|
3711
3799
|
throw new LiquidiumError(
|
|
3712
3800
|
LiquidiumErrorCode.VALIDATION_ERROR,
|
|
3713
3801
|
"Wallet-executed supply requires walletAdapter, account, and amount"
|
|
@@ -3717,6 +3805,13 @@ var SupplyFlowExecutor = class {
|
|
|
3717
3805
|
this.params.canisterContext,
|
|
3718
3806
|
request.poolId
|
|
3719
3807
|
);
|
|
3808
|
+
if (request.amount !== void 0) {
|
|
3809
|
+
validateDepositMinimum({
|
|
3810
|
+
action: request.action,
|
|
3811
|
+
amount: request.amount,
|
|
3812
|
+
asset: selectedPool.asset
|
|
3813
|
+
});
|
|
3814
|
+
}
|
|
3720
3815
|
const target = await resolveSupplyTargetForPool(
|
|
3721
3816
|
this.params.canisterContext,
|
|
3722
3817
|
{
|
|
@@ -3781,6 +3876,11 @@ var SupplyFlowExecutor = class {
|
|
|
3781
3876
|
this.params.canisterContext,
|
|
3782
3877
|
request.poolId
|
|
3783
3878
|
);
|
|
3879
|
+
validateDepositMinimum({
|
|
3880
|
+
action: request.action,
|
|
3881
|
+
amount: request.amount,
|
|
3882
|
+
asset: selectedPool.asset
|
|
3883
|
+
});
|
|
3784
3884
|
return await this.getEvmSupplyContextForPool({
|
|
3785
3885
|
request,
|
|
3786
3886
|
asset: selectedPool.asset,
|
|
@@ -3852,13 +3952,17 @@ var SupplyFlowExecutor = class {
|
|
|
3852
3952
|
"Wallet-executed supply requires a wallet adapter"
|
|
3853
3953
|
);
|
|
3854
3954
|
}
|
|
3855
|
-
const
|
|
3856
|
-
if (!
|
|
3955
|
+
const accountInput = request.account?.trim();
|
|
3956
|
+
if (!accountInput) {
|
|
3857
3957
|
throw new LiquidiumError(
|
|
3858
3958
|
LiquidiumErrorCode.VALIDATION_ERROR,
|
|
3859
3959
|
"Wallet-executed transfer supply requires an account"
|
|
3860
3960
|
);
|
|
3861
3961
|
}
|
|
3962
|
+
const senderAccount = target.chain === Chain.ETH ? normalizeAndValidateEvmAddress(
|
|
3963
|
+
accountInput,
|
|
3964
|
+
"Invalid EVM wallet address"
|
|
3965
|
+
) : accountInput;
|
|
3862
3966
|
if (!request.amount || request.amount <= 0n) {
|
|
3863
3967
|
throw new LiquidiumError(
|
|
3864
3968
|
LiquidiumErrorCode.VALIDATION_ERROR,
|
|
@@ -3874,14 +3978,14 @@ var SupplyFlowExecutor = class {
|
|
|
3874
3978
|
to: decodeIcrcAccountAddress(target.address).account,
|
|
3875
3979
|
amount: request.amount
|
|
3876
3980
|
},
|
|
3877
|
-
senderAccount
|
|
3981
|
+
senderAccount,
|
|
3878
3982
|
action: request.action
|
|
3879
3983
|
}) : await this.sendChainAddressSupplyTransaction({
|
|
3880
3984
|
walletAdapter: request.walletAdapter,
|
|
3881
3985
|
chain: target.chain,
|
|
3882
3986
|
toAddress: target.address,
|
|
3883
3987
|
amount: request.amount,
|
|
3884
|
-
senderAccount
|
|
3988
|
+
senderAccount,
|
|
3885
3989
|
asset: target.asset,
|
|
3886
3990
|
action: request.action
|
|
3887
3991
|
});
|
|
@@ -3913,10 +4017,10 @@ var SupplyFlowExecutor = class {
|
|
|
3913
4017
|
}
|
|
3914
4018
|
async executeContractSupply(params) {
|
|
3915
4019
|
const { request, target, defaultSubmitInflowRequest } = params;
|
|
3916
|
-
if (!isEthStablecoin(target.asset, target.chain)) {
|
|
4020
|
+
if (target.chain !== Chain.ETH || target.asset !== Asset.ETH && !isEthStablecoin(target.asset, target.chain)) {
|
|
3917
4021
|
throw new LiquidiumError(
|
|
3918
4022
|
LiquidiumErrorCode.VALIDATION_ERROR,
|
|
3919
|
-
"Contract-interaction supply is only supported for ETH stablecoin targets"
|
|
4023
|
+
"Contract-interaction supply is only supported for native ETH and ETH stablecoin targets"
|
|
3920
4024
|
);
|
|
3921
4025
|
}
|
|
3922
4026
|
const walletAddressInput = request.account?.trim();
|
|
@@ -3936,6 +4040,12 @@ var SupplyFlowExecutor = class {
|
|
|
3936
4040
|
"Contract-interaction supply requires a positive amount"
|
|
3937
4041
|
);
|
|
3938
4042
|
}
|
|
4043
|
+
if (request.amount > MAX_UINT256) {
|
|
4044
|
+
throw new LiquidiumError(
|
|
4045
|
+
LiquidiumErrorCode.VALIDATION_ERROR,
|
|
4046
|
+
"Contract-interaction supply amount exceeds uint256 maximum"
|
|
4047
|
+
);
|
|
4048
|
+
}
|
|
3939
4049
|
const walletAdapter = request.walletAdapter;
|
|
3940
4050
|
if (!walletAdapter?.sendEthTransaction) {
|
|
3941
4051
|
throw new LiquidiumError(
|
|
@@ -3944,6 +4054,26 @@ var SupplyFlowExecutor = class {
|
|
|
3944
4054
|
);
|
|
3945
4055
|
}
|
|
3946
4056
|
this.params.requireApi();
|
|
4057
|
+
if (target.asset === Asset.ETH) {
|
|
4058
|
+
const depositTxid2 = await this.sendEthContractTransaction(
|
|
4059
|
+
walletAdapter,
|
|
4060
|
+
walletAddress,
|
|
4061
|
+
createDepositEthTransaction({
|
|
4062
|
+
depositContractAddress: CK_ETH_DEPOSIT_CONTRACT_ADDRESS,
|
|
4063
|
+
amount: request.amount,
|
|
4064
|
+
poolId: request.poolId,
|
|
4065
|
+
profileId: request.profileId,
|
|
4066
|
+
destinationAccount: target.address,
|
|
4067
|
+
action: request.action
|
|
4068
|
+
}),
|
|
4069
|
+
`supply-${request.action}-deposit-eth`
|
|
4070
|
+
);
|
|
4071
|
+
await this.registerContractSupplyInflow(
|
|
4072
|
+
depositTxid2,
|
|
4073
|
+
defaultSubmitInflowRequest
|
|
4074
|
+
);
|
|
4075
|
+
return depositTxid2;
|
|
4076
|
+
}
|
|
3947
4077
|
this.requireEvmReadClient(
|
|
3948
4078
|
"Contract-interaction supply requires an EVM RPC URL or public client"
|
|
3949
4079
|
);
|
|
@@ -4017,11 +4147,17 @@ var SupplyFlowExecutor = class {
|
|
|
4017
4147
|
}),
|
|
4018
4148
|
`supply-${request.action}-deposit-erc20`
|
|
4019
4149
|
);
|
|
4150
|
+
await this.registerContractSupplyInflow(
|
|
4151
|
+
depositTxid,
|
|
4152
|
+
defaultSubmitInflowRequest
|
|
4153
|
+
);
|
|
4154
|
+
return depositTxid;
|
|
4155
|
+
}
|
|
4156
|
+
async registerContractSupplyInflow(txid, defaultSubmitInflowRequest) {
|
|
4020
4157
|
try {
|
|
4021
|
-
await this.submitInflowWithRetry(
|
|
4158
|
+
await this.submitInflowWithRetry(txid, defaultSubmitInflowRequest);
|
|
4022
4159
|
} catch {
|
|
4023
4160
|
}
|
|
4024
|
-
return depositTxid;
|
|
4025
4161
|
}
|
|
4026
4162
|
async sendChainAddressSupplyTransaction(params) {
|
|
4027
4163
|
switch (params.chain) {
|
|
@@ -4230,6 +4366,22 @@ function isContractInteractionSupplyRequest(request) {
|
|
|
4230
4366
|
function mapSupplyActionToStatusOperation(action) {
|
|
4231
4367
|
return action === SupplyAction.repayment ? "repayment" : "deposit";
|
|
4232
4368
|
}
|
|
4369
|
+
function validateDepositMinimum(params) {
|
|
4370
|
+
if (params.action !== SupplyAction.deposit) {
|
|
4371
|
+
return;
|
|
4372
|
+
}
|
|
4373
|
+
const minimumDepositAmountError = getDepositAmountMinimumValidationError({
|
|
4374
|
+
amount: params.amount,
|
|
4375
|
+
asset: params.asset
|
|
4376
|
+
});
|
|
4377
|
+
if (!minimumDepositAmountError) {
|
|
4378
|
+
return;
|
|
4379
|
+
}
|
|
4380
|
+
throw new LiquidiumError(
|
|
4381
|
+
LiquidiumErrorCode.VALIDATION_ERROR,
|
|
4382
|
+
minimumDepositAmountError.message
|
|
4383
|
+
);
|
|
4384
|
+
}
|
|
4233
4385
|
function shouldSubmitInflow(params) {
|
|
4234
4386
|
if (params.mechanism !== SupplyPlanType.transfer) {
|
|
4235
4387
|
return true;
|
|
@@ -4760,7 +4912,7 @@ var LendingModule = class {
|
|
|
4760
4912
|
return await this.createSupplyFlowExecutor().getEvmSupplyContext(request);
|
|
4761
4913
|
}
|
|
4762
4914
|
/**
|
|
4763
|
-
* Returns the read-only deposit address for an ETH
|
|
4915
|
+
* Returns the read-only deposit address for an ETH-chain inflow target.
|
|
4764
4916
|
*
|
|
4765
4917
|
* This is a query call that does not create or mutate state. Use it when you
|
|
4766
4918
|
* need the deposit address without hitting the authorization-gated update path.
|
|
@@ -4769,13 +4921,22 @@ var LendingModule = class {
|
|
|
4769
4921
|
* @returns The EVM deposit address for the derived account.
|
|
4770
4922
|
*/
|
|
4771
4923
|
async getDepositAddress(request) {
|
|
4772
|
-
if (!isEthStablecoin(request.asset, Chain.ETH)) {
|
|
4924
|
+
if (request.asset !== Asset.ETH && !isEthStablecoin(request.asset, Chain.ETH)) {
|
|
4925
|
+
throw new LiquidiumError(
|
|
4926
|
+
LiquidiumErrorCode.VALIDATION_ERROR,
|
|
4927
|
+
"getDepositAddress is only supported for ETH-chain assets"
|
|
4928
|
+
);
|
|
4929
|
+
}
|
|
4930
|
+
const selectedPool = await getPoolById(
|
|
4931
|
+
this.canisterContext,
|
|
4932
|
+
request.poolId
|
|
4933
|
+
);
|
|
4934
|
+
if (selectedPool.asset !== request.asset || selectedPool.chain !== Chain.ETH) {
|
|
4773
4935
|
throw new LiquidiumError(
|
|
4774
4936
|
LiquidiumErrorCode.VALIDATION_ERROR,
|
|
4775
|
-
|
|
4937
|
+
`Deposit address asset ${request.asset} does not match pool ${request.poolId}`
|
|
4776
4938
|
);
|
|
4777
4939
|
}
|
|
4778
|
-
const tokenAddress = getEthStablecoinContractAddress(request.asset);
|
|
4779
4940
|
const subaccount = encodeInflowSubaccount({
|
|
4780
4941
|
action: request.action,
|
|
4781
4942
|
principal: principal.Principal.fromText(request.profileId)
|
|
@@ -4787,17 +4948,20 @@ var LendingModule = class {
|
|
|
4787
4948
|
owner: principal.Principal.fromText(request.poolId),
|
|
4788
4949
|
subaccount: [subaccount]
|
|
4789
4950
|
},
|
|
4790
|
-
|
|
4951
|
+
getEthDepositTokenAddress(request.asset)
|
|
4791
4952
|
);
|
|
4792
4953
|
if ("Err" in result) {
|
|
4793
4954
|
throw mapDepositAccountErrorToLiquidiumError(result.Err);
|
|
4794
4955
|
}
|
|
4795
|
-
return
|
|
4956
|
+
return normalizeAndValidateEvmAddress(
|
|
4957
|
+
result.Ok,
|
|
4958
|
+
"Deposit address canister returned an invalid EVM address"
|
|
4959
|
+
);
|
|
4796
4960
|
}
|
|
4797
4961
|
/**
|
|
4798
4962
|
* Estimates the network/deposit fee for an inflow target.
|
|
4799
4963
|
*
|
|
4800
|
-
* ETH
|
|
4964
|
+
* ETH-chain deposit-address estimates are served by the deposit-address
|
|
4801
4965
|
* canister. BTC estimates include the ckBTC minter deposit fee and ledger fee.
|
|
4802
4966
|
* ICP-chain estimates return the corresponding ICRC ledger fee.
|
|
4803
4967
|
*
|
|
@@ -4811,10 +4975,10 @@ var LendingModule = class {
|
|
|
4811
4975
|
totalFee: roundInflowFeeEstimate(request, ledgerFee)
|
|
4812
4976
|
};
|
|
4813
4977
|
}
|
|
4814
|
-
if (isEthStablecoin(request.asset, request.chain)) {
|
|
4978
|
+
if (request.chain === Chain.ETH && (request.asset === Asset.ETH || isEthStablecoin(request.asset, request.chain))) {
|
|
4815
4979
|
const result = await createDepositAccountsActor(
|
|
4816
4980
|
this.canisterContext
|
|
4817
|
-
).estimate_deposit_fee(
|
|
4981
|
+
).estimate_deposit_fee(getEthDepositTokenAddress(request.asset));
|
|
4818
4982
|
if ("Err" in result) {
|
|
4819
4983
|
throw mapDepositAccountErrorToLiquidiumError(result.Err);
|
|
4820
4984
|
}
|
|
@@ -4988,6 +5152,7 @@ var RATE_DECIMALS = BigInt(RATE_SCALE.toString().length - 1);
|
|
|
4988
5152
|
// src/core/utils/asset-decimals.ts
|
|
4989
5153
|
var ASSET_NATIVE_DECIMALS = {
|
|
4990
5154
|
BTC: 8n,
|
|
5155
|
+
ETH: 18n,
|
|
4991
5156
|
ICP: 8n,
|
|
4992
5157
|
USDC: 6n,
|
|
4993
5158
|
USDT: 6n,
|
|
@@ -5077,6 +5242,7 @@ function formatPrice(price, decimals) {
|
|
|
5077
5242
|
var ZERO_POOL_RATE = [0n, 0n, 0n];
|
|
5078
5243
|
var BACKING_POOL_CHAIN_BY_ASSET = {
|
|
5079
5244
|
[Asset.BTC]: Chain.BTC,
|
|
5245
|
+
[Asset.ETH]: Chain.ETH,
|
|
5080
5246
|
[Asset.ICP]: Chain.ICP,
|
|
5081
5247
|
[Asset.USDC]: Chain.ETH,
|
|
5082
5248
|
[Asset.USDT]: Chain.ETH
|
|
@@ -5967,12 +6133,14 @@ var REPAYMENT_BUFFER_SECONDS = 86400n;
|
|
|
5967
6133
|
var RATE_SCALE2 = 10n ** 27n;
|
|
5968
6134
|
var SECONDS_PER_YEAR = 31536000n;
|
|
5969
6135
|
var MILLISECONDS_PER_SECOND3 = 1e3;
|
|
6136
|
+
var ETH_NATIVE_INFLOW_FEE_FALLBACK_WEI = 250000000000000n;
|
|
5970
6137
|
var ETH_STABLECOIN_INFLOW_FEE_FALLBACK = 1500000n;
|
|
5971
6138
|
var SIMPLE_LOAN_MIN_SLIPPAGE_BUFFER_BPS = 200n;
|
|
5972
6139
|
var SIMPLE_LOAN_FIND_QUERY_MAX_LENGTH = 256;
|
|
5973
6140
|
var SIMPLE_LOAN_WIRE_CONTEXT = "simple loan";
|
|
5974
6141
|
var SIMPLE_LOAN_ASSETS = [
|
|
5975
6142
|
Asset.BTC,
|
|
6143
|
+
Asset.ETH,
|
|
5976
6144
|
Asset.ICP,
|
|
5977
6145
|
Asset.USDC,
|
|
5978
6146
|
Asset.USDT
|
|
@@ -6403,7 +6571,7 @@ var SimpleLoansModule = class {
|
|
|
6403
6571
|
const target = input.targets[chain];
|
|
6404
6572
|
if (!target) continue;
|
|
6405
6573
|
assertTargetAsset(target, input.asset);
|
|
6406
|
-
const inflowFee = await this.
|
|
6574
|
+
const inflowFee = await this.estimateInitialDepositInflowFee(target);
|
|
6407
6575
|
targets[chain] = {
|
|
6408
6576
|
amount: input.collateralAmount + inflowFee.totalFee,
|
|
6409
6577
|
inflowFeeAmount: inflowFee.totalFee,
|
|
@@ -6419,6 +6587,24 @@ var SimpleLoansModule = class {
|
|
|
6419
6587
|
expiryTimestamp: input.expiryTimestamp
|
|
6420
6588
|
};
|
|
6421
6589
|
}
|
|
6590
|
+
async estimateInitialDepositInflowFee(target) {
|
|
6591
|
+
try {
|
|
6592
|
+
const fee = await this.lending.estimateInflowFee(target);
|
|
6593
|
+
if (shouldUseNativeEthInflowFeeFallback(target, fee.totalFee)) {
|
|
6594
|
+
return {
|
|
6595
|
+
totalFee: getRepaymentInflowFeeFallback(target.asset, target.chain)
|
|
6596
|
+
};
|
|
6597
|
+
}
|
|
6598
|
+
return fee;
|
|
6599
|
+
} catch (error) {
|
|
6600
|
+
if (target.asset !== Asset.ETH || target.chain !== Chain.ETH) {
|
|
6601
|
+
throw error;
|
|
6602
|
+
}
|
|
6603
|
+
return {
|
|
6604
|
+
totalFee: getRepaymentInflowFeeFallback(target.asset, target.chain)
|
|
6605
|
+
};
|
|
6606
|
+
}
|
|
6607
|
+
}
|
|
6422
6608
|
async resolveSimpleLoanInflowTargets(request) {
|
|
6423
6609
|
const selectedPool = await getPoolById(
|
|
6424
6610
|
this.canisterContext,
|
|
@@ -6469,6 +6655,12 @@ var SimpleLoansModule = class {
|
|
|
6469
6655
|
async estimateRepaymentInflowFee(target) {
|
|
6470
6656
|
try {
|
|
6471
6657
|
const fee = await this.lending.estimateInflowFee(target);
|
|
6658
|
+
if (shouldUseNativeEthInflowFeeFallback(target, fee.totalFee)) {
|
|
6659
|
+
return {
|
|
6660
|
+
totalFee: getRepaymentInflowFeeFallback(target.asset, target.chain),
|
|
6661
|
+
estimateAvailable: false
|
|
6662
|
+
};
|
|
6663
|
+
}
|
|
6472
6664
|
return { totalFee: fee.totalFee, estimateAvailable: true };
|
|
6473
6665
|
} catch {
|
|
6474
6666
|
return {
|
|
@@ -6544,11 +6736,17 @@ var SimpleLoansModule = class {
|
|
|
6544
6736
|
}
|
|
6545
6737
|
};
|
|
6546
6738
|
function getRepaymentInflowFeeFallback(asset, chain) {
|
|
6739
|
+
if (chain === Chain.ETH && asset === Asset.ETH) {
|
|
6740
|
+
return ETH_NATIVE_INFLOW_FEE_FALLBACK_WEI;
|
|
6741
|
+
}
|
|
6547
6742
|
if (chain === "ETH" && (asset === "USDT" || asset === "USDC")) {
|
|
6548
6743
|
return ETH_STABLECOIN_INFLOW_FEE_FALLBACK;
|
|
6549
6744
|
}
|
|
6550
6745
|
return 0n;
|
|
6551
6746
|
}
|
|
6747
|
+
function shouldUseNativeEthInflowFeeFallback(target, totalFee) {
|
|
6748
|
+
return totalFee <= 0n && target.asset === Asset.ETH && target.chain === Chain.ETH;
|
|
6749
|
+
}
|
|
6552
6750
|
function assertTargetAsset(target, expectedAsset) {
|
|
6553
6751
|
if (target.asset === expectedAsset) {
|
|
6554
6752
|
return;
|
|
@@ -6698,7 +6896,7 @@ function inferSimpleLoanDeliveryChain(destination, asset) {
|
|
|
6698
6896
|
if (asset === Asset.BTC) {
|
|
6699
6897
|
return Chain.BTC;
|
|
6700
6898
|
}
|
|
6701
|
-
if (asset === Asset.USDC || asset === Asset.USDT) {
|
|
6899
|
+
if (asset === Asset.ETH || asset === Asset.USDC || asset === Asset.USDT) {
|
|
6702
6900
|
return Chain.ETH;
|
|
6703
6901
|
}
|
|
6704
6902
|
return Chain.ICP;
|
|
@@ -7246,6 +7444,7 @@ exports.LiquidiumClient = LiquidiumClient;
|
|
|
7246
7444
|
exports.LiquidiumError = LiquidiumError;
|
|
7247
7445
|
exports.LiquidiumErrorCode = LiquidiumErrorCode;
|
|
7248
7446
|
exports.MIN_BORROW_AMOUNTS_BY_ASSET = MIN_BORROW_AMOUNTS_BY_ASSET;
|
|
7447
|
+
exports.MIN_DEPOSIT_AMOUNTS_BY_ASSET = MIN_DEPOSIT_AMOUNTS_BY_ASSET;
|
|
7249
7448
|
exports.MIN_WITHDRAW_AMOUNTS_BY_ASSET = MIN_WITHDRAW_AMOUNTS_BY_ASSET;
|
|
7250
7449
|
exports.MarketModule = MarketModule;
|
|
7251
7450
|
exports.OutflowType = OutflowType;
|
|
@@ -7266,6 +7465,7 @@ exports.WalletExecutionKind = WalletExecutionKind;
|
|
|
7266
7465
|
exports.createTransferErc20Transaction = createTransferErc20Transaction;
|
|
7267
7466
|
exports.executeWith = executeWith;
|
|
7268
7467
|
exports.getMinimumBorrowAmount = getMinimumBorrowAmount;
|
|
7468
|
+
exports.getMinimumDepositAmount = getMinimumDepositAmount;
|
|
7269
7469
|
exports.getMinimumWithdrawAmount = getMinimumWithdrawAmount;
|
|
7270
7470
|
exports.intFromPublicId = intFromPublicId;
|
|
7271
7471
|
exports.isAssetIdentifier = isAssetIdentifier;
|