@liquidium/client 0.7.0 → 0.8.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 -0
- package/dist/index.cjs +112 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -6
- package/dist/index.d.ts +19 -6
- package/dist/index.js +112 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -62,6 +62,8 @@ Amounts use `bigint` values in each asset's smallest unit. Read pool decimals be
|
|
|
62
62
|
|
|
63
63
|
`Asset.ETH` supports native ETH on `Chain.ETH` and ckETH ICRC transfers on `Chain.ICP`. Both routes use 18 decimals, so amounts are expressed in wei (`0.005 ETH` is `5_000_000_000_000_000n`). For native ETH deposits and repayments, select `mechanism: "transfer"` to send ETH to a generated deposit address or `mechanism: "contractInteraction"` to send ETH through the payable deposit helper. Transfer is the default when `mechanism` is omitted. ckETH routes use the generated ICRC target.
|
|
64
64
|
|
|
65
|
+
Native ETH borrows and withdrawals do not support addresses with deployed contract bytecode, including smart contract wallets. The same restriction applies to Simple Loan borrow destinations and native ETH collateral refund destinations.
|
|
66
|
+
|
|
65
67
|
See the [quick start](https://liquidium-inc.github.io/liquidium-sdk/getting-started/quick-start/) for LTV validation, repayment, and recovery.
|
|
66
68
|
|
|
67
69
|
## Examples
|
package/dist/index.cjs
CHANGED
|
@@ -47,6 +47,7 @@ var LiquidiumErrorCode = {
|
|
|
47
47
|
WITHDRAW_TOO_LOW: "WITHDRAW_TOO_LOW",
|
|
48
48
|
REPAYMENT_EXCEEDS_DEBT: "REPAYMENT_EXCEEDS_DEBT",
|
|
49
49
|
INVALID_ADDRESS: "INVALID_ADDRESS",
|
|
50
|
+
CONTRACT_DESTINATION_UNSUPPORTED: "CONTRACT_DESTINATION_UNSUPPORTED",
|
|
50
51
|
DEPOSIT_ADDRESS_ERROR: "DEPOSIT_ADDRESS_ERROR",
|
|
51
52
|
// Transport
|
|
52
53
|
NETWORK_ERROR: "NETWORK_ERROR",
|
|
@@ -320,6 +321,12 @@ function appendErrorContext(message, context) {
|
|
|
320
321
|
return `${message} (${details.join(", ")})`;
|
|
321
322
|
}
|
|
322
323
|
function createCanisterContext(opts) {
|
|
324
|
+
if (opts.agent) {
|
|
325
|
+
return {
|
|
326
|
+
agent: opts.agent,
|
|
327
|
+
canisterIds: opts.canisterIds
|
|
328
|
+
};
|
|
329
|
+
}
|
|
323
330
|
const host = resolveHost(opts.icHost);
|
|
324
331
|
const agent$1 = agent.HttpAgent.createSync({
|
|
325
332
|
host,
|
|
@@ -1787,6 +1794,11 @@ var HISTORY_ACTIVITIES = `${SDK_API_V2_PATH}/history/activities`;
|
|
|
1787
1794
|
var HISTORY_USERS = `${SDK_API_V2_PATH}/history/users`;
|
|
1788
1795
|
var INFLOW = `${SDK_API_V2_PATH}/inflow`;
|
|
1789
1796
|
var SIMPLE_LOANS = `${SDK_API_V1_PATH}/instant-loans`;
|
|
1797
|
+
function buildEthereumAddressBytecodePath(request) {
|
|
1798
|
+
return `${SDK_API_V2_PATH}/ethereum/addresses/${encodeURIComponent(
|
|
1799
|
+
request.address
|
|
1800
|
+
)}/bytecode`;
|
|
1801
|
+
}
|
|
1790
1802
|
function buildHistoryUserTransactionsPath(profileId, query) {
|
|
1791
1803
|
const base = `${HISTORY_USERS}/${encodeURIComponent(profileId)}/transactions`;
|
|
1792
1804
|
const qs = query.toString();
|
|
@@ -3343,6 +3355,71 @@ function accountTypeToString(accountType) {
|
|
|
3343
3355
|
return `Principal:${accountType.data}`;
|
|
3344
3356
|
}
|
|
3345
3357
|
}
|
|
3358
|
+
var EMPTY_EVM_BYTECODE = "0x";
|
|
3359
|
+
var LAST_ETHEREUM_MAINNET_PRECOMPILE_ADDRESS = 0x11n;
|
|
3360
|
+
var CONTRACT_DESTINATION_UNSUPPORTED_MESSAGE = "Contract addresses are not supported for native ETH withdrawals or borrowing";
|
|
3361
|
+
var RESERVED_DESTINATION_MESSAGE = "Ethereum outflow destination must not be the zero address or a precompile";
|
|
3362
|
+
async function guardEthereumOutflowDestination({
|
|
3363
|
+
address,
|
|
3364
|
+
apiClient,
|
|
3365
|
+
asset,
|
|
3366
|
+
chain,
|
|
3367
|
+
evmReadClient
|
|
3368
|
+
}) {
|
|
3369
|
+
if (chain !== Chain.ETH) {
|
|
3370
|
+
return;
|
|
3371
|
+
}
|
|
3372
|
+
const normalizedAddress = viem.getAddress(address);
|
|
3373
|
+
if (BigInt(normalizedAddress) <= LAST_ETHEREUM_MAINNET_PRECOMPILE_ADDRESS) {
|
|
3374
|
+
throw new LiquidiumError(
|
|
3375
|
+
LiquidiumErrorCode.INVALID_ADDRESS,
|
|
3376
|
+
RESERVED_DESTINATION_MESSAGE
|
|
3377
|
+
);
|
|
3378
|
+
}
|
|
3379
|
+
if (asset !== Asset.ETH) {
|
|
3380
|
+
return;
|
|
3381
|
+
}
|
|
3382
|
+
if (evmReadClient?.chain?.id === chains.mainnet.id && evmReadClient.getCode) {
|
|
3383
|
+
let bytecode;
|
|
3384
|
+
try {
|
|
3385
|
+
bytecode = await evmReadClient.getCode({
|
|
3386
|
+
address: normalizedAddress
|
|
3387
|
+
});
|
|
3388
|
+
} catch {
|
|
3389
|
+
return;
|
|
3390
|
+
}
|
|
3391
|
+
if (bytecode === void 0 || bytecode === EMPTY_EVM_BYTECODE) {
|
|
3392
|
+
return;
|
|
3393
|
+
}
|
|
3394
|
+
if (typeof bytecode !== "string" || !/^0x(?:[0-9a-fA-F]{2})*$/.test(bytecode)) {
|
|
3395
|
+
return;
|
|
3396
|
+
}
|
|
3397
|
+
throw new LiquidiumError(
|
|
3398
|
+
LiquidiumErrorCode.CONTRACT_DESTINATION_UNSUPPORTED,
|
|
3399
|
+
CONTRACT_DESTINATION_UNSUPPORTED_MESSAGE
|
|
3400
|
+
);
|
|
3401
|
+
}
|
|
3402
|
+
if (!apiClient) {
|
|
3403
|
+
return;
|
|
3404
|
+
}
|
|
3405
|
+
let response;
|
|
3406
|
+
try {
|
|
3407
|
+
response = await apiClient.get(
|
|
3408
|
+
buildEthereumAddressBytecodePath({ address: normalizedAddress })
|
|
3409
|
+
);
|
|
3410
|
+
} catch {
|
|
3411
|
+
return;
|
|
3412
|
+
}
|
|
3413
|
+
if (!response || typeof response !== "object" || !("hasDeployedBytecode" in response) || typeof response.hasDeployedBytecode !== "boolean") {
|
|
3414
|
+
return;
|
|
3415
|
+
}
|
|
3416
|
+
if (response.hasDeployedBytecode) {
|
|
3417
|
+
throw new LiquidiumError(
|
|
3418
|
+
LiquidiumErrorCode.CONTRACT_DESTINATION_UNSUPPORTED,
|
|
3419
|
+
CONTRACT_DESTINATION_UNSUPPORTED_MESSAGE
|
|
3420
|
+
);
|
|
3421
|
+
}
|
|
3422
|
+
}
|
|
3346
3423
|
|
|
3347
3424
|
// src/core/pool-ledger-assets.ts
|
|
3348
3425
|
function getPoolLedgerAssetRoute(params) {
|
|
@@ -4725,6 +4802,13 @@ var LendingModule = class {
|
|
|
4725
4802
|
poolChain: selectedPool.chain,
|
|
4726
4803
|
destinationChain: request.chain
|
|
4727
4804
|
});
|
|
4805
|
+
await guardEthereumOutflowDestination({
|
|
4806
|
+
address: receiver.address,
|
|
4807
|
+
apiClient: this.apiClient,
|
|
4808
|
+
asset: selectedAsset,
|
|
4809
|
+
chain: request.chain,
|
|
4810
|
+
evmReadClient: this.evmReadClient
|
|
4811
|
+
});
|
|
4728
4812
|
const lendingActor = createLendingActor(this.canisterContext);
|
|
4729
4813
|
try {
|
|
4730
4814
|
const expiryTimestamp = computeExpiryTimestampFromNow();
|
|
@@ -4743,7 +4827,9 @@ var LendingModule = class {
|
|
|
4743
4827
|
};
|
|
4744
4828
|
const withdrawSubmissionData = {
|
|
4745
4829
|
...withdrawActionData,
|
|
4746
|
-
|
|
4830
|
+
asset: selectedAsset,
|
|
4831
|
+
receiverAccount: receiver.canisterAccount,
|
|
4832
|
+
receiverAddress: receiver.address
|
|
4747
4833
|
};
|
|
4748
4834
|
return {
|
|
4749
4835
|
kind: WalletActionKind.createWithdraw,
|
|
@@ -4775,6 +4861,13 @@ var LendingModule = class {
|
|
|
4775
4861
|
}
|
|
4776
4862
|
}
|
|
4777
4863
|
async submitWithdraw(request, signatureInfo) {
|
|
4864
|
+
await guardEthereumOutflowDestination({
|
|
4865
|
+
address: request.receiverAddress,
|
|
4866
|
+
apiClient: this.apiClient,
|
|
4867
|
+
asset: request.asset,
|
|
4868
|
+
chain: request.chain,
|
|
4869
|
+
evmReadClient: this.evmReadClient
|
|
4870
|
+
});
|
|
4778
4871
|
try {
|
|
4779
4872
|
const result = await createLendingActor(this.canisterContext).withdraw(
|
|
4780
4873
|
principal.Principal.fromText(request.profileId),
|
|
@@ -4879,6 +4972,13 @@ var LendingModule = class {
|
|
|
4879
4972
|
poolChain: selectedPool.chain,
|
|
4880
4973
|
destinationChain: request.chain
|
|
4881
4974
|
});
|
|
4975
|
+
await guardEthereumOutflowDestination({
|
|
4976
|
+
address: receiver.address,
|
|
4977
|
+
apiClient: this.apiClient,
|
|
4978
|
+
asset: selectedAsset,
|
|
4979
|
+
chain: request.chain,
|
|
4980
|
+
evmReadClient: this.evmReadClient
|
|
4981
|
+
});
|
|
4882
4982
|
await this.guardBorrowSameAssetPolicy({
|
|
4883
4983
|
profileId: request.profileId,
|
|
4884
4984
|
pool: selectedPool
|
|
@@ -4901,7 +5001,9 @@ var LendingModule = class {
|
|
|
4901
5001
|
};
|
|
4902
5002
|
const borrowSubmissionData = {
|
|
4903
5003
|
...borrowActionData,
|
|
4904
|
-
|
|
5004
|
+
asset: selectedAsset,
|
|
5005
|
+
receiverAccount: receiver.canisterAccount,
|
|
5006
|
+
receiverAddress: receiver.address
|
|
4905
5007
|
};
|
|
4906
5008
|
return {
|
|
4907
5009
|
kind: WalletActionKind.createBorrow,
|
|
@@ -4930,6 +5032,13 @@ var LendingModule = class {
|
|
|
4930
5032
|
}
|
|
4931
5033
|
}
|
|
4932
5034
|
async submitBorrow(request, signatureInfo) {
|
|
5035
|
+
await guardEthereumOutflowDestination({
|
|
5036
|
+
address: request.receiverAddress,
|
|
5037
|
+
apiClient: this.apiClient,
|
|
5038
|
+
asset: request.asset,
|
|
5039
|
+
chain: request.chain,
|
|
5040
|
+
evmReadClient: this.evmReadClient
|
|
5041
|
+
});
|
|
4933
5042
|
try {
|
|
4934
5043
|
const result = await createLendingActor(
|
|
4935
5044
|
this.canisterContext
|
|
@@ -7622,6 +7731,7 @@ var LiquidiumClient = class {
|
|
|
7622
7731
|
const canisterIds = resolveCanisterIds(environment, config.canisterIds);
|
|
7623
7732
|
const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
7624
7733
|
this.canisterContext = createCanisterContext({
|
|
7734
|
+
agent: config.agent,
|
|
7625
7735
|
icHost: config.icHost,
|
|
7626
7736
|
identity: config.identity,
|
|
7627
7737
|
canisterIds
|