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