@liquidium/client 0.7.0 → 0.7.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/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",
@@ -1787,6 +1788,11 @@ var HISTORY_ACTIVITIES = `${SDK_API_V2_PATH}/history/activities`;
1787
1788
  var HISTORY_USERS = `${SDK_API_V2_PATH}/history/users`;
1788
1789
  var INFLOW = `${SDK_API_V2_PATH}/inflow`;
1789
1790
  var SIMPLE_LOANS = `${SDK_API_V1_PATH}/instant-loans`;
1791
+ function buildEthereumAddressBytecodePath(request) {
1792
+ return `${SDK_API_V2_PATH}/ethereum/addresses/${encodeURIComponent(
1793
+ request.address
1794
+ )}/bytecode`;
1795
+ }
1790
1796
  function buildHistoryUserTransactionsPath(profileId, query) {
1791
1797
  const base = `${HISTORY_USERS}/${encodeURIComponent(profileId)}/transactions`;
1792
1798
  const qs = query.toString();
@@ -3343,6 +3349,71 @@ function accountTypeToString(accountType) {
3343
3349
  return `Principal:${accountType.data}`;
3344
3350
  }
3345
3351
  }
3352
+ var EMPTY_EVM_BYTECODE = "0x";
3353
+ var LAST_ETHEREUM_MAINNET_PRECOMPILE_ADDRESS = 0x11n;
3354
+ var CONTRACT_DESTINATION_UNSUPPORTED_MESSAGE = "Contract addresses are not supported for native ETH withdrawals or borrowing";
3355
+ var RESERVED_DESTINATION_MESSAGE = "Ethereum outflow destination must not be the zero address or a precompile";
3356
+ async function guardEthereumOutflowDestination({
3357
+ address,
3358
+ apiClient,
3359
+ asset,
3360
+ chain,
3361
+ evmReadClient
3362
+ }) {
3363
+ if (chain !== Chain.ETH) {
3364
+ return;
3365
+ }
3366
+ const normalizedAddress = viem.getAddress(address);
3367
+ if (BigInt(normalizedAddress) <= LAST_ETHEREUM_MAINNET_PRECOMPILE_ADDRESS) {
3368
+ throw new LiquidiumError(
3369
+ LiquidiumErrorCode.INVALID_ADDRESS,
3370
+ RESERVED_DESTINATION_MESSAGE
3371
+ );
3372
+ }
3373
+ if (asset !== Asset.ETH) {
3374
+ return;
3375
+ }
3376
+ if (evmReadClient?.chain?.id === chains.mainnet.id && evmReadClient.getCode) {
3377
+ let bytecode;
3378
+ try {
3379
+ bytecode = await evmReadClient.getCode({
3380
+ address: normalizedAddress
3381
+ });
3382
+ } catch {
3383
+ return;
3384
+ }
3385
+ if (bytecode === void 0 || bytecode === EMPTY_EVM_BYTECODE) {
3386
+ return;
3387
+ }
3388
+ if (typeof bytecode !== "string" || !/^0x(?:[0-9a-fA-F]{2})*$/.test(bytecode)) {
3389
+ return;
3390
+ }
3391
+ throw new LiquidiumError(
3392
+ LiquidiumErrorCode.CONTRACT_DESTINATION_UNSUPPORTED,
3393
+ CONTRACT_DESTINATION_UNSUPPORTED_MESSAGE
3394
+ );
3395
+ }
3396
+ if (!apiClient) {
3397
+ return;
3398
+ }
3399
+ let response;
3400
+ try {
3401
+ response = await apiClient.get(
3402
+ buildEthereumAddressBytecodePath({ address: normalizedAddress })
3403
+ );
3404
+ } catch {
3405
+ return;
3406
+ }
3407
+ if (!response || typeof response !== "object" || !("hasDeployedBytecode" in response) || typeof response.hasDeployedBytecode !== "boolean") {
3408
+ return;
3409
+ }
3410
+ if (response.hasDeployedBytecode) {
3411
+ throw new LiquidiumError(
3412
+ LiquidiumErrorCode.CONTRACT_DESTINATION_UNSUPPORTED,
3413
+ CONTRACT_DESTINATION_UNSUPPORTED_MESSAGE
3414
+ );
3415
+ }
3416
+ }
3346
3417
 
3347
3418
  // src/core/pool-ledger-assets.ts
3348
3419
  function getPoolLedgerAssetRoute(params) {
@@ -4725,6 +4796,13 @@ var LendingModule = class {
4725
4796
  poolChain: selectedPool.chain,
4726
4797
  destinationChain: request.chain
4727
4798
  });
4799
+ await guardEthereumOutflowDestination({
4800
+ address: receiver.address,
4801
+ apiClient: this.apiClient,
4802
+ asset: selectedAsset,
4803
+ chain: request.chain,
4804
+ evmReadClient: this.evmReadClient
4805
+ });
4728
4806
  const lendingActor = createLendingActor(this.canisterContext);
4729
4807
  try {
4730
4808
  const expiryTimestamp = computeExpiryTimestampFromNow();
@@ -4743,7 +4821,9 @@ var LendingModule = class {
4743
4821
  };
4744
4822
  const withdrawSubmissionData = {
4745
4823
  ...withdrawActionData,
4746
- receiverAccount: receiver.canisterAccount
4824
+ asset: selectedAsset,
4825
+ receiverAccount: receiver.canisterAccount,
4826
+ receiverAddress: receiver.address
4747
4827
  };
4748
4828
  return {
4749
4829
  kind: WalletActionKind.createWithdraw,
@@ -4775,6 +4855,13 @@ var LendingModule = class {
4775
4855
  }
4776
4856
  }
4777
4857
  async submitWithdraw(request, signatureInfo) {
4858
+ await guardEthereumOutflowDestination({
4859
+ address: request.receiverAddress,
4860
+ apiClient: this.apiClient,
4861
+ asset: request.asset,
4862
+ chain: request.chain,
4863
+ evmReadClient: this.evmReadClient
4864
+ });
4778
4865
  try {
4779
4866
  const result = await createLendingActor(this.canisterContext).withdraw(
4780
4867
  principal.Principal.fromText(request.profileId),
@@ -4879,6 +4966,13 @@ var LendingModule = class {
4879
4966
  poolChain: selectedPool.chain,
4880
4967
  destinationChain: request.chain
4881
4968
  });
4969
+ await guardEthereumOutflowDestination({
4970
+ address: receiver.address,
4971
+ apiClient: this.apiClient,
4972
+ asset: selectedAsset,
4973
+ chain: request.chain,
4974
+ evmReadClient: this.evmReadClient
4975
+ });
4882
4976
  await this.guardBorrowSameAssetPolicy({
4883
4977
  profileId: request.profileId,
4884
4978
  pool: selectedPool
@@ -4901,7 +4995,9 @@ var LendingModule = class {
4901
4995
  };
4902
4996
  const borrowSubmissionData = {
4903
4997
  ...borrowActionData,
4904
- receiverAccount: receiver.canisterAccount
4998
+ asset: selectedAsset,
4999
+ receiverAccount: receiver.canisterAccount,
5000
+ receiverAddress: receiver.address
4905
5001
  };
4906
5002
  return {
4907
5003
  kind: WalletActionKind.createBorrow,
@@ -4930,6 +5026,13 @@ var LendingModule = class {
4930
5026
  }
4931
5027
  }
4932
5028
  async submitBorrow(request, signatureInfo) {
5029
+ await guardEthereumOutflowDestination({
5030
+ address: request.receiverAddress,
5031
+ apiClient: this.apiClient,
5032
+ asset: request.asset,
5033
+ chain: request.chain,
5034
+ evmReadClient: this.evmReadClient
5035
+ });
4933
5036
  try {
4934
5037
  const result = await createLendingActor(
4935
5038
  this.canisterContext