@liquidium/client 0.3.0 → 0.3.2

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.js CHANGED
@@ -1,7 +1,9 @@
1
- import { encodeFunctionData, createPublicClient, http, isAddress, getAddress } from 'viem';
1
+ import { encodeFunctionData, createPublicClient, http, isAddress, getAddress, isHex, bytesToHex } from 'viem';
2
2
  import { mainnet } from 'viem/chains';
3
3
  import { Actor, HttpAgent } from '@icp-sdk/core/agent';
4
4
  import { Principal } from '@icp-sdk/core/principal';
5
+ import { base64, base64nopad } from '@scure/base';
6
+ import { idlLabelToId } from '@icp-sdk/core/candid';
5
7
  import { encodeIcrcAccount } from '@dfinity/ledger-icrc';
6
8
  import { Principal as Principal$1 } from '@dfinity/principal';
7
9
  import { validate, Network } from 'bitcoin-address-validation';
@@ -1063,17 +1065,68 @@ function executeWith(options) {
1063
1065
  }
1064
1066
  };
1065
1067
  }
1066
-
1067
- // src/core/utils/signature.ts
1068
+ var HEX_PREFIX = "0x";
1069
+ var HEX_BYTE_CHAR_LENGTH = 2;
1070
+ var BASE64_PADDING = "=";
1071
+ function normalizeWalletSignature(signature, chain) {
1072
+ switch (chain) {
1073
+ case Chain.BTC:
1074
+ return normalizeBtcSignature(signature);
1075
+ case Chain.ETH:
1076
+ return normalizeHexSignature(signature);
1077
+ }
1078
+ }
1068
1079
  function normalizeHexSignature(signature) {
1069
- if (!signature.startsWith("0x")) {
1080
+ if (!isPrefixedHex(signature)) {
1070
1081
  return signature;
1071
1082
  }
1072
- const signatureWithoutPrefix = signature.slice(2);
1073
- if (!/^[0-9a-fA-F]+$/.test(signatureWithoutPrefix)) {
1074
- return signature;
1083
+ return signature.slice(HEX_PREFIX.length);
1084
+ }
1085
+ function normalizeBtcSignature(signature) {
1086
+ const signatureWithoutPrefix = signature.startsWith(HEX_PREFIX) ? signature.slice(HEX_PREFIX.length) : signature;
1087
+ if (isHexBytes(signatureWithoutPrefix)) {
1088
+ return signatureWithoutPrefix;
1089
+ }
1090
+ if (signature.startsWith(HEX_PREFIX)) {
1091
+ throw invalidBtcSignatureFormatError();
1092
+ }
1093
+ return bytesToUnprefixedHex(decodeBase64Signature(signature));
1094
+ }
1095
+ function isHexBytes(signature) {
1096
+ return signature.length > 0 && signature.length % HEX_BYTE_CHAR_LENGTH === 0 && isHex(`${HEX_PREFIX}${signature}`);
1097
+ }
1098
+ function decodeBase64Signature(signature) {
1099
+ try {
1100
+ const bytes = decodeBase64Bytes(signature);
1101
+ if (bytes.length === 0) {
1102
+ throw invalidBtcSignatureFormatError();
1103
+ }
1104
+ return bytes;
1105
+ } catch (error) {
1106
+ if (error instanceof LiquidiumError) {
1107
+ throw error;
1108
+ }
1109
+ throw invalidBtcSignatureFormatError(error);
1075
1110
  }
1076
- return signatureWithoutPrefix;
1111
+ }
1112
+ function bytesToUnprefixedHex(bytes) {
1113
+ return normalizeHexSignature(bytesToHex(bytes));
1114
+ }
1115
+ function isPrefixedHex(signature) {
1116
+ return signature.length > HEX_PREFIX.length && isHex(signature);
1117
+ }
1118
+ function decodeBase64Bytes(signature) {
1119
+ if (signature.includes(BASE64_PADDING)) {
1120
+ return base64.decode(signature);
1121
+ }
1122
+ return base64nopad.decode(signature);
1123
+ }
1124
+ function invalidBtcSignatureFormatError(cause) {
1125
+ return new LiquidiumError(
1126
+ LiquidiumErrorCode.SIGNATURE_ERROR,
1127
+ "BTC signature must be hex or base64-encoded bytes",
1128
+ cause
1129
+ );
1077
1130
  }
1078
1131
 
1079
1132
  // src/modules/accounts/mappers.ts
@@ -1091,7 +1144,10 @@ function mapCreateAccountRequestToRegisterProfileRequest(request) {
1091
1144
  },
1092
1145
  signature_info: {
1093
1146
  Wallet: {
1094
- signature: normalizeHexSignature(request.signatureInfo.signature),
1147
+ signature: normalizeWalletSignature(
1148
+ request.signatureInfo.signature,
1149
+ request.signatureInfo.chain
1150
+ ),
1095
1151
  chain: mapAccountChainToLendingChainVariant(
1096
1152
  request.signatureInfo.chain
1097
1153
  ),
@@ -1305,17 +1361,35 @@ function mapCanisterWalletToWallet(canisterWallet) {
1305
1361
  );
1306
1362
  }
1307
1363
  }
1308
- var idlFactory2 = ({ IDL }) => {
1364
+ var KNOWN_ASSET_TAGS = ["BTC", "SOL", "USDC", "USDT"];
1365
+ var KNOWN_CHAIN_TAGS = ["BTC", "ETH", "SOL"];
1366
+ function extractVariantTag(variant, knownTags) {
1367
+ const [key] = Object.keys(variant);
1368
+ if (!key) {
1369
+ return null;
1370
+ }
1371
+ if (knownTags.includes(key)) {
1372
+ return key;
1373
+ }
1374
+ const hashMatch = /^_(\d+)_$/.exec(key);
1375
+ if (!hashMatch) {
1376
+ return null;
1377
+ }
1378
+ const hash = Number(hashMatch[1]);
1379
+ for (const tag of knownTags) {
1380
+ if (idlLabelToId(tag) === hash) {
1381
+ return tag;
1382
+ }
1383
+ }
1384
+ return null;
1385
+ }
1386
+
1387
+ // src/core/canisters/instant-loans/flexible-actor.ts
1388
+ var flexibleInstantLoansIdlFactory = ({ IDL }) => {
1309
1389
  const AccountType = IDL.Variant({
1310
1390
  Native: IDL.Principal,
1311
1391
  External: IDL.Text
1312
1392
  });
1313
- const Assets = IDL.Variant({
1314
- BTC: IDL.Null,
1315
- SOL: IDL.Null,
1316
- USDC: IDL.Null,
1317
- USDT: IDL.Null
1318
- });
1319
1393
  const SignatureVerificationError = IDL.Variant({
1320
1394
  InvalidEthSignature: IDL.Null,
1321
1395
  UnsupportedChain: IDL.Null,
@@ -1386,13 +1460,13 @@ var idlFactory2 = ({ IDL }) => {
1386
1460
  });
1387
1461
  const CreateLoanRequest = IDL.Record({
1388
1462
  borrow_destination: AccountType,
1389
- lend_asset: Assets,
1463
+ lend_asset: IDL.Unknown,
1390
1464
  borrow_amount: IDL.Nat,
1391
1465
  lend_pool_id: IDL.Principal,
1392
1466
  refund_destination: AccountType,
1393
1467
  ltv_max_bps: IDL.Nat64,
1394
1468
  borrow_pool_id: IDL.Principal,
1395
- borrow_asset: Assets,
1469
+ borrow_asset: IDL.Unknown,
1396
1470
  ltv_timer_s: IDL.Nat64
1397
1471
  });
1398
1472
  const CreateLoanResponse = IDL.Record({
@@ -1408,7 +1482,7 @@ var idlFactory2 = ({ IDL }) => {
1408
1482
  LoanCreated: IDL.Record({
1409
1483
  loan_id: IDL.Nat,
1410
1484
  borrow_destination: AccountType,
1411
- lend_asset: Assets,
1485
+ lend_asset: IDL.Unknown,
1412
1486
  borrow_amount: IDL.Nat,
1413
1487
  lend_pool_id: IDL.Principal,
1414
1488
  refund_destination: AccountType,
@@ -1416,7 +1490,7 @@ var idlFactory2 = ({ IDL }) => {
1416
1490
  ltv_timer_s: IDL.Nat64,
1417
1491
  lending_profile: IDL.Principal,
1418
1492
  borrow_pool_id: IDL.Principal,
1419
- borrow_asset: Assets
1493
+ borrow_asset: IDL.Unknown
1420
1494
  }),
1421
1495
  FullLendWithdrawalRequested: IDL.Record({
1422
1496
  loan_id: IDL.Nat,
@@ -1467,7 +1541,7 @@ var idlFactory2 = ({ IDL }) => {
1467
1541
  authorisation: AuthorisationType,
1468
1542
  borrow_destination: AccountType,
1469
1543
  started: IDL.Bool,
1470
- lend_asset: Assets,
1544
+ lend_asset: IDL.Unknown,
1471
1545
  created_at: IDL.Nat64,
1472
1546
  schema_version: IDL.Nat16,
1473
1547
  borrow_amount: IDL.Nat,
@@ -1478,7 +1552,7 @@ var idlFactory2 = ({ IDL }) => {
1478
1552
  lending_profile: IDL.Principal,
1479
1553
  expires_at: IDL.Opt(IDL.Nat64),
1480
1554
  borrow_pool_id: IDL.Principal,
1481
- borrow_asset: Assets,
1555
+ borrow_asset: IDL.Unknown,
1482
1556
  deposit_detected_ts: IDL.Opt(IDL.Nat64)
1483
1557
  });
1484
1558
  const LoanResult = IDL.Variant({ Ok: Loan, Err: InstantLoansError });
@@ -1506,7 +1580,7 @@ var idlFactory2 = ({ IDL }) => {
1506
1580
  list_warmed_profiles: IDL.Func([], [IDL.Vec(WarmedProfile)], ["query"])
1507
1581
  });
1508
1582
  };
1509
- function createInstantLoansActor(canisterContext) {
1583
+ function createFlexibleInstantLoansActor(canisterContext) {
1510
1584
  const canisterId = canisterContext.canisterIds.instantLoans;
1511
1585
  if (!canisterId) {
1512
1586
  throw new LiquidiumError(
@@ -1514,10 +1588,84 @@ function createInstantLoansActor(canisterContext) {
1514
1588
  "Instant loans canister ID is not configured"
1515
1589
  );
1516
1590
  }
1517
- return Actor.createActor(idlFactory2, {
1518
- agent: canisterContext.agent,
1519
- canisterId
1520
- });
1591
+ return Actor.createActor(
1592
+ flexibleInstantLoansIdlFactory,
1593
+ {
1594
+ agent: canisterContext.agent,
1595
+ canisterId
1596
+ }
1597
+ );
1598
+ }
1599
+ function decodeFlexibleInstantLoanRecord(record) {
1600
+ const lend_asset = extractVariantTag(record.lend_asset, KNOWN_ASSET_TAGS);
1601
+ const borrow_asset = extractVariantTag(record.borrow_asset, KNOWN_ASSET_TAGS);
1602
+ if (!lend_asset || !borrow_asset) {
1603
+ return null;
1604
+ }
1605
+ return {
1606
+ id: record.id,
1607
+ authorisation: record.authorisation,
1608
+ borrow_destination: record.borrow_destination,
1609
+ started: record.started,
1610
+ lend_asset,
1611
+ created_at: record.created_at,
1612
+ schema_version: record.schema_version,
1613
+ borrow_amount: record.borrow_amount,
1614
+ lend_pool_id: record.lend_pool_id,
1615
+ refund_destination: record.refund_destination,
1616
+ ltv_max_bps: record.ltv_max_bps,
1617
+ ltv_timer_s: record.ltv_timer_s,
1618
+ lending_profile: record.lending_profile,
1619
+ borrow_pool_id: record.borrow_pool_id,
1620
+ borrow_asset,
1621
+ expires_at: record.expires_at,
1622
+ deposit_detected_ts: record.deposit_detected_ts
1623
+ };
1624
+ }
1625
+ function decodeFlexibleHeadlessLoanEvent(event) {
1626
+ if ("LoanCreated" in event.event_type) {
1627
+ const decoded = decodeLoanCreatedEvent(event.event_type.LoanCreated);
1628
+ if (!decoded) {
1629
+ return null;
1630
+ }
1631
+ return {
1632
+ id: event.id,
1633
+ schema_version: event.schema_version,
1634
+ timestamp: event.timestamp,
1635
+ event_type: decoded
1636
+ };
1637
+ }
1638
+ return {
1639
+ id: event.id,
1640
+ schema_version: event.schema_version,
1641
+ timestamp: event.timestamp,
1642
+ event_type: event.event_type
1643
+ };
1644
+ }
1645
+ function decodeLoanCreatedEvent(payload) {
1646
+ const lend_asset = extractVariantTag(payload.lend_asset, KNOWN_ASSET_TAGS);
1647
+ const borrow_asset = extractVariantTag(
1648
+ payload.borrow_asset,
1649
+ KNOWN_ASSET_TAGS
1650
+ );
1651
+ if (!lend_asset || !borrow_asset) {
1652
+ return null;
1653
+ }
1654
+ return {
1655
+ LoanCreated: {
1656
+ loan_id: payload.loan_id,
1657
+ borrow_destination: payload.borrow_destination,
1658
+ lend_asset,
1659
+ borrow_amount: payload.borrow_amount,
1660
+ lend_pool_id: payload.lend_pool_id,
1661
+ refund_destination: payload.refund_destination,
1662
+ ltv_max_bps: payload.ltv_max_bps,
1663
+ ltv_timer_s: payload.ltv_timer_s,
1664
+ lending_profile: payload.lending_profile,
1665
+ borrow_pool_id: payload.borrow_pool_id,
1666
+ borrow_asset
1667
+ }
1668
+ };
1521
1669
  }
1522
1670
 
1523
1671
  // src/core/sdk-api-paths.ts
@@ -1807,7 +1955,7 @@ var ActivitiesModule = class {
1807
1955
  );
1808
1956
  }
1809
1957
  try {
1810
- const result = await createInstantLoansActor(
1958
+ const result = await createFlexibleInstantLoansActor(
1811
1959
  this.canisterContext
1812
1960
  ).get_loan(loanId);
1813
1961
  if ("Err" in result) {
@@ -2276,7 +2424,7 @@ function getAssetNativeDecimals(asset) {
2276
2424
  }
2277
2425
 
2278
2426
  // src/generated/canisters/ck-btc-minter/declaration.js
2279
- var idlFactory3 = ({ IDL }) => {
2427
+ var idlFactory2 = ({ IDL }) => {
2280
2428
  const Mode = IDL.Variant({
2281
2429
  "RestrictedTo": IDL.Vec(IDL.Principal),
2282
2430
  "DepositsRestrictedTo": IDL.Vec(IDL.Principal),
@@ -2656,14 +2804,14 @@ var idlFactory3 = ({ IDL }) => {
2656
2804
  // src/core/canisters/ckbtc/minter.ts
2657
2805
  function createCkBtcMinterActor(canisterContext) {
2658
2806
  const canisterId = CK_CANISTER_IDS.btcMinter;
2659
- return Actor.createActor(idlFactory3, {
2807
+ return Actor.createActor(idlFactory2, {
2660
2808
  agent: canisterContext.agent,
2661
2809
  canisterId
2662
2810
  });
2663
2811
  }
2664
2812
 
2665
2813
  // src/generated/canisters/deposit-accounts/deposit_accounts.did.js
2666
- var idlFactory4 = ({ IDL }) => {
2814
+ var idlFactory3 = ({ IDL }) => {
2667
2815
  const DepositAccountErrors = IDL.Variant({
2668
2816
  "Busy": IDL.Null,
2669
2817
  "NotFound": IDL.Null,
@@ -2883,7 +3031,7 @@ function createDepositAccountsActor(canisterContext) {
2883
3031
  "ETH deposit canister ID is not configured"
2884
3032
  );
2885
3033
  }
2886
- return Actor.createActor(idlFactory4, {
3034
+ return Actor.createActor(idlFactory3, {
2887
3035
  agent: canisterContext.agent,
2888
3036
  canisterId
2889
3037
  });
@@ -3769,7 +3917,7 @@ var InstantLoansModule = class {
3769
3917
  */
3770
3918
  async getConfig() {
3771
3919
  try {
3772
- const config = await createInstantLoansActor(
3920
+ const config = await createFlexibleInstantLoansActor(
3773
3921
  this.canisterContext
3774
3922
  ).get_config();
3775
3923
  return {
@@ -3787,10 +3935,11 @@ var InstantLoansModule = class {
3787
3935
  */
3788
3936
  async getEvent(eventId) {
3789
3937
  try {
3790
- const event = await createInstantLoansActor(
3938
+ const event = await createFlexibleInstantLoansActor(
3791
3939
  this.canisterContext
3792
3940
  ).get_event(eventId);
3793
- return event[0] ? mapInstantLoanEvent(event[0]) : null;
3941
+ const decoded = event[0] ? decodeFlexibleHeadlessLoanEvent(event[0]) : null;
3942
+ return decoded ? mapInstantLoanEvent(decoded) : null;
3794
3943
  } catch (error) {
3795
3944
  throw mapCanisterCallErrorToLiquidiumError("get_event", error);
3796
3945
  }
@@ -3803,10 +3952,10 @@ var InstantLoansModule = class {
3803
3952
  */
3804
3953
  async listEvents(request) {
3805
3954
  try {
3806
- const events = await createInstantLoansActor(
3955
+ const events = await createFlexibleInstantLoansActor(
3807
3956
  this.canisterContext
3808
3957
  ).list_events(request.start, request.limit);
3809
- return events.map(([, event]) => mapInstantLoanEvent(event));
3958
+ return events.map(([, event]) => decodeFlexibleHeadlessLoanEvent(event)).filter((event) => event !== null).map((event) => mapInstantLoanEvent(event));
3810
3959
  } catch (error) {
3811
3960
  throw mapCanisterCallErrorToLiquidiumError("list_events", error);
3812
3961
  }
@@ -3818,7 +3967,7 @@ var InstantLoansModule = class {
3818
3967
  */
3819
3968
  async listAccessList() {
3820
3969
  try {
3821
- const principals = await createInstantLoansActor(
3970
+ const principals = await createFlexibleInstantLoansActor(
3822
3971
  this.canisterContext
3823
3972
  ).list_access_list();
3824
3973
  return principals.map((principal) => principal.toText());
@@ -3833,7 +3982,7 @@ var InstantLoansModule = class {
3833
3982
  */
3834
3983
  async countWarmedProfiles() {
3835
3984
  try {
3836
- return await createInstantLoansActor(
3985
+ return await createFlexibleInstantLoansActor(
3837
3986
  this.canisterContext
3838
3987
  ).count_warmed_profiles();
3839
3988
  } catch (error) {
@@ -3850,7 +3999,7 @@ var InstantLoansModule = class {
3850
3999
  */
3851
4000
  async listWarmedProfiles() {
3852
4001
  try {
3853
- const profiles = await createInstantLoansActor(
4002
+ const profiles = await createFlexibleInstantLoansActor(
3854
4003
  this.canisterContext
3855
4004
  ).list_warmed_profiles();
3856
4005
  return profiles.map(mapWarmedProfile);
@@ -3867,13 +4016,20 @@ var InstantLoansModule = class {
3867
4016
  }
3868
4017
  async getLoanRecord(loanId) {
3869
4018
  try {
3870
- const result = await createInstantLoansActor(
4019
+ const result = await createFlexibleInstantLoansActor(
3871
4020
  this.canisterContext
3872
4021
  ).get_loan(loanId);
3873
4022
  if ("Err" in result) {
3874
4023
  throw mapInstantLoansErrorToLiquidiumError(result.Err);
3875
4024
  }
3876
- return result.Ok;
4025
+ const decoded = decodeFlexibleInstantLoanRecord(result.Ok);
4026
+ if (!decoded) {
4027
+ throw new LiquidiumError(
4028
+ LiquidiumErrorCode.POOL_NOT_FOUND,
4029
+ `Instant loan ${loanId.toString()} uses an unsupported asset`
4030
+ );
4031
+ }
4032
+ return decoded;
3877
4033
  } catch (error) {
3878
4034
  if (error instanceof LiquidiumError) {
3879
4035
  throw error;
@@ -3890,8 +4046,8 @@ var InstantLoansModule = class {
3890
4046
  collateralPoolId: record.lend_pool_id.toText(),
3891
4047
  collateralAmount,
3892
4048
  borrowPoolId: record.borrow_pool_id.toText(),
3893
- collateralAsset: getVariantKey(record.lend_asset),
3894
- borrowAsset: getVariantKey(record.borrow_asset),
4049
+ collateralAsset: record.lend_asset,
4050
+ borrowAsset: record.borrow_asset,
3895
4051
  borrowAmount: record.borrow_amount,
3896
4052
  borrowDestination: accountFromCanister(record.borrow_destination),
3897
4053
  refundDestination: accountFromCanister(record.refund_destination),
@@ -4196,7 +4352,7 @@ function mapInstantLoanEventType(eventType) {
4196
4352
  type: "LoanCreated",
4197
4353
  loanId: event.loan_id,
4198
4354
  borrowDestination: accountFromCanister(event.borrow_destination),
4199
- collateralAsset: assetFromCanister(event.lend_asset),
4355
+ collateralAsset: event.lend_asset,
4200
4356
  borrowAmount: event.borrow_amount,
4201
4357
  collateralPoolId: event.lend_pool_id.toText(),
4202
4358
  refundDestination: accountFromCanister(event.refund_destination),
@@ -4204,7 +4360,7 @@ function mapInstantLoanEventType(eventType) {
4204
4360
  depositWindowSeconds: event.ltv_timer_s,
4205
4361
  profileId: event.lending_profile.toText(),
4206
4362
  borrowPoolId: event.borrow_pool_id.toText(),
4207
- borrowAsset: assetFromCanister(event.borrow_asset)
4363
+ borrowAsset: event.borrow_asset
4208
4364
  };
4209
4365
  }
4210
4366
  if ("FullLendWithdrawalRequested" in eventType) {
@@ -4282,9 +4438,6 @@ function authorizationFromCanister(authorization) {
4282
4438
  address: authorization.EthSignature.address
4283
4439
  };
4284
4440
  }
4285
- function assetFromCanister(asset) {
4286
- return getVariantKey(asset);
4287
- }
4288
4441
  function legFromCanister(leg) {
4289
4442
  return getVariantKey(leg);
4290
4443
  }
@@ -4512,12 +4665,12 @@ function encodeBytes32Hex(bytes) {
4512
4665
  (byte) => byte.toString(16).padStart(2, "0")
4513
4666
  ).join("")}`;
4514
4667
  }
4515
- var idlFactory5 = ({ IDL }) => IDL.Service({
4668
+ var idlFactory4 = ({ IDL }) => IDL.Service({
4516
4669
  icrc1_fee: IDL.Func([], [IDL.Nat], ["query"])
4517
4670
  });
4518
4671
  function createCkBtcLedgerActor(canisterContext) {
4519
4672
  const canisterId = CK_CANISTER_IDS.btcLedger;
4520
- return Actor.createActor(idlFactory5, {
4673
+ return Actor.createActor(idlFactory4, {
4521
4674
  agent: canisterContext.agent,
4522
4675
  canisterId
4523
4676
  });
@@ -4770,7 +4923,10 @@ var LendingModule = class {
4770
4923
  },
4771
4924
  signature_info: {
4772
4925
  Wallet: {
4773
- signature: normalizeHexSignature(signatureInfo.signature),
4926
+ signature: normalizeWalletSignature(
4927
+ signatureInfo.signature,
4928
+ signatureInfo.chain
4929
+ ),
4774
4930
  chain: mapWalletChainToLendingChain(signatureInfo.chain),
4775
4931
  account: request.signerWalletAddress
4776
4932
  }
@@ -4908,7 +5064,10 @@ var LendingModule = class {
4908
5064
  },
4909
5065
  signature_info: {
4910
5066
  Wallet: {
4911
- signature: normalizeHexSignature(signatureInfo.signature),
5067
+ signature: normalizeWalletSignature(
5068
+ signatureInfo.signature,
5069
+ signatureInfo.chain
5070
+ ),
4912
5071
  chain: mapWalletChainToLendingChain(signatureInfo.chain),
4913
5072
  account: request.signerWalletAddress
4914
5073
  }
@@ -5584,21 +5743,203 @@ function shouldSubmitInflow(params) {
5584
5743
  }
5585
5744
  return !isEthStablecoin(params.instruction.asset, params.instruction.chain);
5586
5745
  }
5746
+ var flexibleLendingIdlFactory = ({ IDL }) => {
5747
+ const PoolRecord = IDL.Record({
5748
+ principal: IDL.Principal,
5749
+ asset: IDL.Unknown,
5750
+ chain: IDL.Unknown,
5751
+ total_supply_at_last_sync: IDL.Nat,
5752
+ total_debt_at_last_sync: IDL.Nat,
5753
+ supply_cap: IDL.Opt(IDL.Nat),
5754
+ borrow_cap: IDL.Opt(IDL.Nat),
5755
+ max_ltv: IDL.Nat64,
5756
+ liquidation_threshold: IDL.Nat64,
5757
+ liquidation_bonus: IDL.Nat64,
5758
+ protocol_liquidation_fee: IDL.Nat64,
5759
+ reserve_factor: IDL.Nat64,
5760
+ base_rate: IDL.Nat,
5761
+ optimal_utilization_rate: IDL.Nat,
5762
+ rate_slope_before: IDL.Nat,
5763
+ rate_slope_after: IDL.Nat,
5764
+ lending_index: IDL.Nat,
5765
+ borrow_index: IDL.Nat,
5766
+ same_asset_borrowing: IDL.Opt(IDL.Bool),
5767
+ frozen: IDL.Bool,
5768
+ last_updated: IDL.Opt(IDL.Nat64)
5769
+ });
5770
+ const BorrowingPowerRecord = IDL.Record({
5771
+ max_borrowable_usd: IDL.Nat,
5772
+ weighted_max_ltv: IDL.Nat
5773
+ });
5774
+ const PositionRecord = IDL.Record({
5775
+ asset: IDL.Unknown,
5776
+ total_debt_interest: IDL.Nat,
5777
+ borrow_index_snapshot: IDL.Nat,
5778
+ lending_index_snapshot: IDL.Nat,
5779
+ debt_scaled: IDL.Nat,
5780
+ total_earned_interest: IDL.Nat,
5781
+ deposit_scaled: IDL.Nat,
5782
+ pool_id: IDL.Principal,
5783
+ unpaid_debt_interest: IDL.Nat,
5784
+ last_update: IDL.Nat64,
5785
+ user_profile: IDL.Principal
5786
+ });
5787
+ const UserStatsRecord = IDL.Record({
5788
+ debt: IDL.Nat,
5789
+ collateral: IDL.Nat,
5790
+ acumulated_interest: IDL.Nat,
5791
+ borrowing_power: BorrowingPowerRecord,
5792
+ positions: IDL.Vec(PositionRecord),
5793
+ weighted_liquidation_threshold: IDL.Nat
5794
+ });
5795
+ const PositionViewRecord = IDL.Record({
5796
+ lending_index_now: IDL.Nat,
5797
+ interest_since_snapshot: IDL.Nat,
5798
+ asset: IDL.Unknown,
5799
+ total_debt_interest: IDL.Nat,
5800
+ borrow_index_snapshot: IDL.Nat,
5801
+ debt_native_now: IDL.Nat,
5802
+ borrow_index_now: IDL.Nat,
5803
+ lending_index_snapshot: IDL.Nat,
5804
+ debt_scaled: IDL.Nat,
5805
+ total_earned_interest: IDL.Nat,
5806
+ deposit_scaled: IDL.Nat,
5807
+ earned_since_snapshot: IDL.Nat,
5808
+ deposited_native_now: IDL.Nat,
5809
+ pool_id: IDL.Principal,
5810
+ last_update: IDL.Nat64,
5811
+ user_profile: IDL.Principal
5812
+ });
5813
+ return IDL.Service({
5814
+ list_pools: IDL.Func([], [IDL.Vec(PoolRecord)], ["query"]),
5815
+ get_pool_rate: IDL.Func(
5816
+ [IDL.Principal],
5817
+ [IDL.Opt(IDL.Tuple(IDL.Nat, IDL.Nat, IDL.Nat))],
5818
+ ["query"]
5819
+ ),
5820
+ get_health_factor: IDL.Func(
5821
+ [IDL.Principal],
5822
+ [IDL.Nat, UserStatsRecord],
5823
+ ["query"]
5824
+ ),
5825
+ get_profile_stats: IDL.Func([IDL.Principal], [UserStatsRecord], ["query"]),
5826
+ get_position: IDL.Func(
5827
+ [IDL.Principal, IDL.Principal],
5828
+ [IDL.Opt(PositionViewRecord)],
5829
+ ["query"]
5830
+ )
5831
+ });
5832
+ };
5833
+ function createFlexibleLendingActor(canisterContext) {
5834
+ const canisterId = canisterContext.canisterIds.lending;
5835
+ if (!canisterId) {
5836
+ throw new LiquidiumError(
5837
+ LiquidiumErrorCode.SERVICE_UNAVAILABLE,
5838
+ "Lending canister ID is not configured"
5839
+ );
5840
+ }
5841
+ return Actor.createActor(flexibleLendingIdlFactory, {
5842
+ agent: canisterContext.agent,
5843
+ canisterId
5844
+ });
5845
+ }
5846
+ function decodeFlexiblePool(pool) {
5847
+ const asset = extractVariantTag(pool.asset, KNOWN_ASSET_TAGS);
5848
+ const chain = extractVariantTag(pool.chain, KNOWN_CHAIN_TAGS);
5849
+ if (!asset || !chain) {
5850
+ return null;
5851
+ }
5852
+ return {
5853
+ principal: pool.principal,
5854
+ asset,
5855
+ chain,
5856
+ total_supply_at_last_sync: pool.total_supply_at_last_sync,
5857
+ total_debt_at_last_sync: pool.total_debt_at_last_sync,
5858
+ supply_cap: pool.supply_cap,
5859
+ borrow_cap: pool.borrow_cap,
5860
+ max_ltv: pool.max_ltv,
5861
+ liquidation_threshold: pool.liquidation_threshold,
5862
+ liquidation_bonus: pool.liquidation_bonus,
5863
+ protocol_liquidation_fee: pool.protocol_liquidation_fee,
5864
+ reserve_factor: pool.reserve_factor,
5865
+ base_rate: pool.base_rate,
5866
+ optimal_utilization_rate: pool.optimal_utilization_rate,
5867
+ rate_slope_before: pool.rate_slope_before,
5868
+ rate_slope_after: pool.rate_slope_after,
5869
+ lending_index: pool.lending_index,
5870
+ borrow_index: pool.borrow_index,
5871
+ same_asset_borrowing: pool.same_asset_borrowing,
5872
+ frozen: pool.frozen,
5873
+ last_updated: pool.last_updated
5874
+ };
5875
+ }
5876
+ function decodeFlexiblePosition(position) {
5877
+ const asset = extractVariantTag(position.asset, KNOWN_ASSET_TAGS);
5878
+ if (!asset) {
5879
+ return null;
5880
+ }
5881
+ return {
5882
+ asset,
5883
+ total_debt_interest: position.total_debt_interest,
5884
+ borrow_index_snapshot: position.borrow_index_snapshot,
5885
+ lending_index_snapshot: position.lending_index_snapshot,
5886
+ debt_scaled: position.debt_scaled,
5887
+ total_earned_interest: position.total_earned_interest,
5888
+ deposit_scaled: position.deposit_scaled,
5889
+ pool_id: position.pool_id,
5890
+ unpaid_debt_interest: position.unpaid_debt_interest,
5891
+ last_update: position.last_update,
5892
+ user_profile: position.user_profile
5893
+ };
5894
+ }
5895
+ function decodeFlexiblePositionView(view) {
5896
+ const asset = extractVariantTag(view.asset, KNOWN_ASSET_TAGS);
5897
+ if (!asset) {
5898
+ return null;
5899
+ }
5900
+ return {
5901
+ lending_index_now: view.lending_index_now,
5902
+ interest_since_snapshot: view.interest_since_snapshot,
5903
+ asset,
5904
+ total_debt_interest: view.total_debt_interest,
5905
+ borrow_index_snapshot: view.borrow_index_snapshot,
5906
+ debt_native_now: view.debt_native_now,
5907
+ borrow_index_now: view.borrow_index_now,
5908
+ lending_index_snapshot: view.lending_index_snapshot,
5909
+ debt_scaled: view.debt_scaled,
5910
+ total_earned_interest: view.total_earned_interest,
5911
+ deposit_scaled: view.deposit_scaled,
5912
+ earned_since_snapshot: view.earned_since_snapshot,
5913
+ deposited_native_now: view.deposited_native_now,
5914
+ pool_id: view.pool_id,
5915
+ last_update: view.last_update,
5916
+ user_profile: view.user_profile
5917
+ };
5918
+ }
5919
+ function decodeFlexibleUserStats(stats) {
5920
+ return {
5921
+ debt: stats.debt,
5922
+ collateral: stats.collateral,
5923
+ acumulated_interest: stats.acumulated_interest,
5924
+ borrowing_power: stats.borrowing_power,
5925
+ positions: stats.positions.map(decodeFlexiblePosition).filter((position) => position !== null),
5926
+ weighted_liquidation_threshold: stats.weighted_liquidation_threshold
5927
+ };
5928
+ }
5587
5929
 
5588
5930
  // src/modules/market/mappers.ts
5589
5931
  var DECIMAL_BASE = 10;
5590
5932
  var PAIR_SEPARATOR = "_";
5591
5933
  var USDT_SYMBOL = "USDT";
5592
- function mapLendingPoolRecordToPool(pool, rate) {
5593
- const asset = getVariantKey(pool.asset);
5934
+ function mapDecodedPoolToPool(pool, rate) {
5594
5935
  const totalSupply = pool.total_supply_at_last_sync;
5595
5936
  const totalDebt = pool.total_debt_at_last_sync;
5596
5937
  const availableLiquidity = totalSupply > totalDebt ? totalSupply - totalDebt : 0n;
5597
5938
  return {
5598
5939
  id: pool.principal.toString(),
5599
- asset,
5600
- chain: getVariantKey(pool.chain),
5601
- decimals: getAssetNativeDecimals(asset),
5940
+ asset: pool.asset,
5941
+ chain: pool.chain,
5942
+ decimals: getAssetNativeDecimals(pool.asset),
5602
5943
  frozen: pool.frozen,
5603
5944
  totalSupply,
5604
5945
  totalDebt,
@@ -5671,13 +6012,14 @@ var MarketModule = class {
5671
6012
  async listPools() {
5672
6013
  void this.apiClient;
5673
6014
  try {
5674
- const lendingActor = createLendingActor(this.canisterContext);
5675
- const lendingPools = await lendingActor.list_pools();
6015
+ const flexibleActor = createFlexibleLendingActor(this.canisterContext);
6016
+ const rawPools = await flexibleActor.list_pools();
6017
+ const decodedPools = rawPools.map(decodeFlexiblePool).filter((pool) => pool !== null);
5676
6018
  return await Promise.all(
5677
- lendingPools.map(async (pool) => {
5678
- const poolRate = await lendingActor.get_pool_rate(pool.principal);
6019
+ decodedPools.map(async (pool) => {
6020
+ const poolRate = await flexibleActor.get_pool_rate(pool.principal);
5679
6021
  const resolvedPoolRate = poolRate[0] ?? ZERO_POOL_RATE;
5680
- return mapLendingPoolRecordToPool(pool, resolvedPoolRate);
6022
+ return mapDecodedPoolToPool(pool, resolvedPoolRate);
5681
6023
  })
5682
6024
  );
5683
6025
  } catch (error) {
@@ -5782,12 +6124,11 @@ var MarketModule = class {
5782
6124
 
5783
6125
  // src/modules/positions/mappers.ts
5784
6126
  var USD_VALUE_SCALE_DECIMALS = 27n;
5785
- function mapPositionViewToPosition(view) {
5786
- const asset = getVariantKey(view.asset);
5787
- const nativeDecimals = getAssetNativeDecimals(asset);
6127
+ function mapDecodedPositionViewToPosition(view) {
6128
+ const nativeDecimals = getAssetNativeDecimals(view.asset);
5788
6129
  return {
5789
6130
  poolId: view.pool_id.toText(),
5790
- asset,
6131
+ asset: view.asset,
5791
6132
  deposited: view.deposited_native_now,
5792
6133
  depositedDecimals: nativeDecimals,
5793
6134
  borrowed: view.debt_native_now,
@@ -5804,15 +6145,18 @@ function mapBorrowingPowerRecordToBorrowingPower(record) {
5804
6145
  maxBorrowableUsdDecimals: USD_VALUE_SCALE_DECIMALS
5805
6146
  };
5806
6147
  }
5807
- function mapUserStatsRecordToUserStats(record) {
6148
+ function mapDecodedUserStatsToUserStats(stats) {
6149
+ return mapUserStatsLikeToUserStats(stats);
6150
+ }
6151
+ function mapUserStatsLikeToUserStats(stats) {
5808
6152
  return {
5809
- debt: record.debt,
6153
+ debt: stats.debt,
5810
6154
  debtDecimals: USD_VALUE_SCALE_DECIMALS,
5811
- collateral: record.collateral,
6155
+ collateral: stats.collateral,
5812
6156
  collateralDecimals: USD_VALUE_SCALE_DECIMALS,
5813
- weightedLiquidationThreshold: record.weighted_liquidation_threshold,
6157
+ weightedLiquidationThreshold: stats.weighted_liquidation_threshold,
5814
6158
  borrowingPower: mapBorrowingPowerRecordToBorrowingPower(
5815
- record.borrowing_power
6159
+ stats.borrowing_power
5816
6160
  )
5817
6161
  };
5818
6162
  }
@@ -5836,14 +6180,18 @@ var PositionsModule = class {
5836
6180
  */
5837
6181
  async getPosition(profileId, poolId) {
5838
6182
  try {
5839
- const result = await createLendingActor(
6183
+ const result = await createFlexibleLendingActor(
5840
6184
  this.canisterContext
5841
6185
  ).get_position(Principal.fromText(profileId), Principal.fromText(poolId));
5842
6186
  const view = result[0];
5843
6187
  if (!view) {
5844
6188
  return null;
5845
6189
  }
5846
- return mapPositionViewToPosition(view);
6190
+ const decodedView = decodeFlexiblePositionView(view);
6191
+ if (!decodedView) {
6192
+ return null;
6193
+ }
6194
+ return mapDecodedPositionViewToPosition(decodedView);
5847
6195
  } catch (error) {
5848
6196
  if (error instanceof LiquidiumError) {
5849
6197
  throw error;
@@ -5859,15 +6207,16 @@ var PositionsModule = class {
5859
6207
  */
5860
6208
  async listPositions(profileId) {
5861
6209
  try {
5862
- const actor = createLendingActor(this.canisterContext);
6210
+ const actor = createFlexibleLendingActor(this.canisterContext);
5863
6211
  const profilePrincipal = Principal.fromText(profileId);
5864
6212
  const stats = await actor.get_profile_stats(profilePrincipal);
6213
+ const decodedStats = decodeFlexibleUserStats(stats);
5865
6214
  const positionViews = await Promise.all(
5866
- stats.positions.map(
6215
+ decodedStats.positions.map(
5867
6216
  (position) => actor.get_position(profilePrincipal, position.pool_id)
5868
6217
  )
5869
6218
  );
5870
- return positionViews.map((result) => result[0]).filter((view) => view !== void 0).map(mapPositionViewToPosition);
6219
+ return positionViews.map((result) => result[0]).filter((view) => view !== void 0).map(decodeFlexiblePositionView).filter((view) => view !== null).map(mapDecodedPositionViewToPosition);
5871
6220
  } catch (error) {
5872
6221
  if (error instanceof LiquidiumError) {
5873
6222
  throw error;
@@ -5883,12 +6232,14 @@ var PositionsModule = class {
5883
6232
  */
5884
6233
  async getHealthFactor(profileId) {
5885
6234
  try {
5886
- const [healthFactor, userStatsRecord] = await createLendingActor(
6235
+ const [healthFactor, userStatsRecord] = await createFlexibleLendingActor(
5887
6236
  this.canisterContext
5888
6237
  ).get_health_factor(Principal.fromText(profileId));
5889
6238
  return {
5890
6239
  healthFactor,
5891
- userStats: mapUserStatsRecordToUserStats(userStatsRecord)
6240
+ userStats: mapDecodedUserStatsToUserStats(
6241
+ decodeFlexibleUserStats(userStatsRecord)
6242
+ )
5892
6243
  };
5893
6244
  } catch (error) {
5894
6245
  if (error instanceof LiquidiumError) {
@@ -5905,10 +6256,10 @@ var PositionsModule = class {
5905
6256
  */
5906
6257
  async getUserStats(profileId) {
5907
6258
  try {
5908
- const result = await createLendingActor(
6259
+ const result = await createFlexibleLendingActor(
5909
6260
  this.canisterContext
5910
6261
  ).get_profile_stats(Principal.fromText(profileId));
5911
- return mapUserStatsRecordToUserStats(result);
6262
+ return mapDecodedUserStatsToUserStats(decodeFlexibleUserStats(result));
5912
6263
  } catch (error) {
5913
6264
  if (error instanceof LiquidiumError) {
5914
6265
  throw error;