@kasufinance/kasu-sdk 1.0.4 → 2.2.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.
Files changed (84) hide show
  1. package/CLAUDE.md +410 -0
  2. package/README.md +179 -12
  3. package/dist/bundle.cjs.js +658 -90
  4. package/dist/bundle.esm.js +654 -92
  5. package/dist/facade/chain-configs.d.ts +11 -0
  6. package/dist/facade/chain-configs.js +84 -0
  7. package/dist/facade/chain-configs.js.map +1 -0
  8. package/dist/facade/deposits.d.ts +56 -0
  9. package/dist/facade/deposits.js +87 -0
  10. package/dist/facade/deposits.js.map +1 -0
  11. package/dist/facade/index.d.ts +6 -0
  12. package/dist/facade/index.js +9 -0
  13. package/dist/facade/index.js.map +1 -0
  14. package/dist/facade/kasu.d.ts +71 -0
  15. package/dist/facade/kasu.js +101 -0
  16. package/dist/facade/kasu.js.map +1 -0
  17. package/dist/facade/strategies.d.ts +37 -0
  18. package/dist/facade/strategies.js +112 -0
  19. package/dist/facade/strategies.js.map +1 -0
  20. package/dist/facade/types.d.ts +127 -0
  21. package/dist/facade/types.js +2 -0
  22. package/dist/facade/types.js.map +1 -0
  23. package/dist/facade/user-portfolio.d.ts +35 -0
  24. package/dist/facade/user-portfolio.js +53 -0
  25. package/dist/facade/user-portfolio.js.map +1 -0
  26. package/dist/index.d.ts +9 -17
  27. package/dist/index.js +9 -16
  28. package/dist/index.js.map +1 -1
  29. package/dist/kasu-sdk.d.ts +17 -0
  30. package/dist/kasu-sdk.js +17 -0
  31. package/dist/kasu-sdk.js.map +1 -0
  32. package/dist/sdk-config.d.ts +34 -4
  33. package/dist/sdk-config.js +9 -6
  34. package/dist/sdk-config.js.map +1 -1
  35. package/dist/services/DataService/data-service.d.ts +9 -2
  36. package/dist/services/DataService/data-service.js +91 -53
  37. package/dist/services/DataService/data-service.js.map +1 -1
  38. package/dist/services/DataService/queries.d.ts +0 -1
  39. package/dist/services/DataService/queries.js +0 -8
  40. package/dist/services/DataService/queries.js.map +1 -1
  41. package/dist/services/DataService/subgraph-types.d.ts +0 -6
  42. package/dist/services/DataService/types.d.ts +0 -1
  43. package/dist/services/Locking/locking.d.ts +9 -3
  44. package/dist/services/Locking/locking.js +114 -20
  45. package/dist/services/Locking/locking.js.map +1 -1
  46. package/dist/services/Locking/types.d.ts +1 -1
  47. package/dist/services/Portfolio/portfolio.d.ts +3 -2
  48. package/dist/services/Portfolio/portfolio.js +15 -7
  49. package/dist/services/Portfolio/portfolio.js.map +1 -1
  50. package/dist/services/Portfolio/types.d.ts +2 -2
  51. package/dist/services/UserLending/user-lending.d.ts +3 -1
  52. package/dist/services/UserLending/user-lending.js +9 -3
  53. package/dist/services/UserLending/user-lending.js.map +1 -1
  54. package/dist/tests/facade.test.d.ts +1 -0
  55. package/dist/tests/facade.test.js +196 -0
  56. package/dist/tests/facade.test.js.map +1 -0
  57. package/dist/tests/sample.test.js +19 -14
  58. package/dist/tests/sample.test.js.map +1 -1
  59. package/dist/utils/deployment-mode.d.ts +6 -0
  60. package/dist/utils/deployment-mode.js +8 -0
  61. package/dist/utils/deployment-mode.js.map +1 -0
  62. package/package.json +2 -2
  63. package/src/facade/chain-configs.ts +93 -0
  64. package/src/facade/deposits.ts +102 -0
  65. package/src/facade/index.ts +26 -0
  66. package/src/facade/kasu.ts +144 -0
  67. package/src/facade/strategies.ts +119 -0
  68. package/src/facade/types.ts +168 -0
  69. package/src/facade/user-portfolio.ts +73 -0
  70. package/src/index.ts +59 -25
  71. package/src/kasu-sdk.ts +27 -0
  72. package/src/sdk-config.ts +43 -15
  73. package/src/services/DataService/data-service.ts +106 -66
  74. package/src/services/DataService/queries.ts +0 -9
  75. package/src/services/DataService/subgraph-types.ts +0 -7
  76. package/src/services/DataService/types.ts +0 -1
  77. package/src/services/Locking/locking.ts +141 -25
  78. package/src/services/Locking/types.ts +1 -1
  79. package/src/services/Portfolio/portfolio.ts +21 -11
  80. package/src/services/Portfolio/types.ts +2 -2
  81. package/src/services/UserLending/user-lending.ts +13 -4
  82. package/src/tests/facade.test.ts +245 -0
  83. package/src/tests/sample.test.ts +7 -9
  84. package/src/utils/deployment-mode.ts +9 -0
@@ -1,5 +1,5 @@
1
1
  import { formatUnits, parseUnits, formatEther, defaultAbiCoder, parseEther } from 'ethers/lib/utils';
2
- import { utils as utils$2, Contract, ethers, BigNumber } from 'ethers';
2
+ import { utils as utils$2, Contract, BigNumber, ethers } from 'ethers';
3
3
 
4
4
  function _mergeNamespaces(n, m) {
5
5
  m.forEach(function (e) {
@@ -15614,14 +15614,6 @@ function filterArray(array, id_in) {
15614
15614
  }
15615
15615
  }
15616
15616
 
15617
- const getPlumeTvl = gql `
15618
- {
15619
- lendingPools {
15620
- id
15621
- balance
15622
- }
15623
- }
15624
- `;
15625
15617
  const getPoolOverviewQuery = (ids) => gql `
15626
15618
  query getAllPoolOverview($epochId: String!, $unusedPools: [String]!) {
15627
15619
  lendingPools(
@@ -15775,17 +15767,36 @@ const getLendingPoolWithdrawalAndDepositsQuery = gql `
15775
15767
  class DataService {
15776
15768
  constructor(_kasuConfig, signerOrProvider) {
15777
15769
  this._kasuConfig = _kasuConfig;
15778
- this._plumeTvl = new Map();
15779
15770
  this._externalTvlAbi = KasuPoolExternalTVLAbi__factory.connect(_kasuConfig.contracts.ExternalTVL, signerOrProvider);
15780
15771
  this._graph = new GraphQLClient(_kasuConfig.subgraphUrl);
15781
- this._plumeGraph = new GraphQLClient(_kasuConfig.plumeSubgraphUrl);
15782
- this._directus = le(_kasuConfig.directusUrl)
15783
- .with(ne())
15784
- .with(Zp());
15772
+ if (_kasuConfig.directusUrl) {
15773
+ this._directus = le(_kasuConfig.directusUrl)
15774
+ .with(ne())
15775
+ .with(Zp());
15776
+ }
15777
+ else {
15778
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
15779
+ this._directus = null;
15780
+ }
15785
15781
  }
15786
15782
  getUrlFromFile(fileName) {
15787
15783
  return `${this._kasuConfig.directusUrl}assets/${fileName}`;
15788
15784
  }
15785
+ /**
15786
+ * Maps a pool ID to its metadata source pool ID.
15787
+ * Used for chains (XDC, Plume) that share Directus metadata with Base pools.
15788
+ */
15789
+ getMetadataPoolId(poolId) {
15790
+ var _a;
15791
+ const normalizedId = poolId.toLowerCase();
15792
+ return (_a = this._kasuConfig.poolMetadataMapping[normalizedId]) !== null && _a !== void 0 ? _a : normalizedId;
15793
+ }
15794
+ /**
15795
+ * Maps an array of pool IDs to their metadata source pool IDs.
15796
+ */
15797
+ getMetadataPoolIds(poolIds) {
15798
+ return poolIds.map((id) => this.getMetadataPoolId(id));
15799
+ }
15789
15800
  calculatePoolCapacity(poolCapacities, poolCapacityPercentages, index, spillOver, lendingPoolSubgraph, lendingPoolConfig) {
15790
15801
  const desiredDrawAmount = lendingPoolConfig.desiredDrawAmount; // subgraph
15791
15802
  const desiredTrancheRatio = lendingPoolConfig.tranchesConfig[index].desiredRatio;
@@ -15832,7 +15843,7 @@ class DataService {
15832
15843
  ];
15833
15844
  })));
15834
15845
  for (const [id, tvl] of results) {
15835
- tvlMap.set(id, formatUnits(tvl, 6));
15846
+ tvlMap.set(id, formatUnits(tvl, this._kasuConfig.stableAssetDecimals));
15836
15847
  }
15837
15848
  }
15838
15849
  catch (error) {
@@ -15843,7 +15854,7 @@ class DataService {
15843
15854
  }
15844
15855
  getPoolOverview(epochId, id_in) {
15845
15856
  return __awaiter(this, void 0, void 0, function* () {
15846
- var _a, _b, _c;
15857
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
15847
15858
  const trancheNames = [
15848
15859
  ['Senior'],
15849
15860
  ['Junior', 'Senior'],
@@ -15853,29 +15864,39 @@ class DataService {
15853
15864
  unusedPools: this._kasuConfig.UNUSED_LENDING_POOL_IDS,
15854
15865
  epochId,
15855
15866
  });
15856
- if (!this._plumeTvl.size) {
15857
- const plumeResults = yield this._plumeGraph.request(getPlumeTvl);
15858
- for (const pool of plumeResults.lendingPools) {
15859
- this._plumeTvl.set(pool.id, pool.balance);
15860
- }
15861
- }
15862
15867
  if (!this._directusPoolOverview) {
15863
- this._directusPoolOverview = yield this._directus.request(bs('PoolOverview', {
15864
- filter: {
15865
- enabled: {
15866
- _eq: true,
15867
- },
15868
- },
15869
- }));
15868
+ if (this._kasuConfig.directusUrl) {
15869
+ try {
15870
+ this._directusPoolOverview = yield this._directus.request(bs('PoolOverview', {
15871
+ filter: {
15872
+ enabled: {
15873
+ _eq: true,
15874
+ },
15875
+ },
15876
+ }));
15877
+ }
15878
+ catch (error) {
15879
+ console.warn('Directus fetch failed, falling back to on-chain data only:', error);
15880
+ this._directusPoolOverview = [];
15881
+ }
15882
+ }
15883
+ else {
15884
+ this._directusPoolOverview = [];
15885
+ }
15870
15886
  }
15871
15887
  const offchainTvlMap = yield this.getOffChainTvl(poolOverviewResults.lendingPools.map(({ id }) => id));
15872
15888
  const retn = [];
15873
15889
  for (const lendingPoolSubgraph of poolOverviewResults.lendingPools) {
15874
- const lendingPoolDirectus = this._directusPoolOverview.find((r) => r.id.toLowerCase() == lendingPoolSubgraph.id);
15890
+ // Use metadata mapping if available (for XDC/Plume pools that share metadata with Base)
15891
+ const metadataPoolId = (_a = this._kasuConfig.poolMetadataMapping[lendingPoolSubgraph.id]) !== null && _a !== void 0 ? _a : lendingPoolSubgraph.id;
15892
+ const lendingPoolDirectus = this._directusPoolOverview.find((r) => r.id.toLowerCase() === metadataPoolId);
15875
15893
  const lendingPoolConfig = lendingPoolSubgraph.configuration;
15876
15894
  if (!lendingPoolDirectus) {
15877
- console.warn("Couldn't find directus pool for id: ", lendingPoolSubgraph.id);
15878
- continue;
15895
+ console.warn("Couldn't find directus pool for id: ", lendingPoolSubgraph.id, metadataPoolId !== lendingPoolSubgraph.id
15896
+ ? `(mapped from ${metadataPoolId})`
15897
+ : '');
15898
+ // When Directus is unavailable or pool has no CMS entry,
15899
+ // use a fallback so the pool is still returned with on-chain data.
15879
15900
  }
15880
15901
  const poolCapacities = this.calculatePoolCapacity([], [], 0, 0, lendingPoolSubgraph, lendingPoolConfig);
15881
15902
  const tranches = lendingPoolSubgraph.tranches
@@ -15942,49 +15963,50 @@ class DataService {
15942
15963
  : parseFloat(tranche.balance) / trancheBalanceSum;
15943
15964
  averageApy += parseFloat(trancheData.averageApy) * weight;
15944
15965
  }
15945
- const plumeTvl = lendingPoolDirectus.plumeStrategy &&
15946
- this._plumeTvl.has(lendingPoolDirectus.plumeStrategy)
15947
- ? (_a = this._plumeTvl.get(lendingPoolDirectus.plumeStrategy)) !== null && _a !== void 0 ? _a : '0'
15948
- : '0';
15949
15966
  const offChainTvl = (_b = offchainTvlMap.get(lendingPoolSubgraph.id)) !== null && _b !== void 0 ? _b : '0';
15950
15967
  const poolOverview = {
15951
15968
  id: lendingPoolSubgraph.id,
15952
- security: lendingPoolDirectus.security,
15953
- enabled: lendingPoolDirectus.enabled,
15954
- isOversubscribed: lendingPoolDirectus.oversubscribed,
15969
+ security: (_c = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.security) !== null && _c !== void 0 ? _c : [],
15970
+ enabled: (_d = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.enabled) !== null && _d !== void 0 ? _d : true,
15971
+ isOversubscribed: (_e = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.oversubscribed) !== null && _e !== void 0 ? _e : false,
15955
15972
  apy: averageApy,
15956
- description: lendingPoolDirectus.description,
15957
- liteDescription: lendingPoolDirectus.liteDescription,
15958
- thumbnailImageUrl: this.getUrlFromFile(lendingPoolDirectus.thumbnailImage),
15959
- bannerImageUrl: this.getUrlFromFile(lendingPoolDirectus.bannerImage),
15960
- strategyDeckUrl: this.getUrlFromFile(lendingPoolDirectus.strategyDeck),
15961
- assetClass: lendingPoolDirectus.assetClass,
15962
- industryExposure: lendingPoolDirectus.industryExposure,
15963
- poolApyStructure: lendingPoolDirectus.poolApyStructure,
15964
- apyExpiryDate: lendingPoolDirectus.apyExpiryDate,
15965
- poolInvestmentTerm: lendingPoolDirectus.poolInvestmentTerm,
15966
- loanStructure: lendingPoolDirectus.loanStructure,
15967
- poolName: (_c = lendingPoolDirectus.poolName) !== null && _c !== void 0 ? _c : lendingPoolSubgraph.name,
15968
- subheading: lendingPoolDirectus.subheading,
15973
+ description: (_f = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.description) !== null && _f !== void 0 ? _f : '',
15974
+ liteDescription: (_g = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.liteDescription) !== null && _g !== void 0 ? _g : '',
15975
+ thumbnailImageUrl: (lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.thumbnailImage)
15976
+ ? this.getUrlFromFile(lendingPoolDirectus.thumbnailImage)
15977
+ : '',
15978
+ bannerImageUrl: (lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.bannerImage)
15979
+ ? this.getUrlFromFile(lendingPoolDirectus.bannerImage)
15980
+ : '',
15981
+ strategyDeckUrl: (lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.strategyDeck)
15982
+ ? this.getUrlFromFile(lendingPoolDirectus.strategyDeck)
15983
+ : '',
15984
+ assetClass: (_h = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.assetClass) !== null && _h !== void 0 ? _h : '',
15985
+ industryExposure: (_j = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.industryExposure) !== null && _j !== void 0 ? _j : '',
15986
+ poolApyStructure: (_k = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.poolApyStructure) !== null && _k !== void 0 ? _k : 'Variable',
15987
+ apyExpiryDate: (_l = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.apyExpiryDate) !== null && _l !== void 0 ? _l : null,
15988
+ poolInvestmentTerm: (_m = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.poolInvestmentTerm) !== null && _m !== void 0 ? _m : '',
15989
+ loanStructure: (_o = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.loanStructure) !== null && _o !== void 0 ? _o : '',
15990
+ poolName: (_p = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.poolName) !== null && _p !== void 0 ? _p : lendingPoolSubgraph.name,
15991
+ subheading: lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.subheading,
15969
15992
  totalValueLocked: {
15970
15993
  total: (parseFloat(lendingPoolSubgraph.balance) +
15971
- parseFloat(plumeTvl) +
15972
15994
  parseFloat(offChainTvl)).toString(),
15973
15995
  offchain: offChainTvl,
15974
- plume: plumeTvl,
15975
15996
  },
15976
- loansUnderManagement: lendingPoolDirectus.loansUnderManagement,
15997
+ loansUnderManagement: (_q = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.loansUnderManagement) !== null && _q !== void 0 ? _q : '0',
15977
15998
  yieldEarned: lendingPoolSubgraph.totalUserInterestAmount,
15978
15999
  poolCapacity: poolCapacitySum.toString(),
15979
16000
  poolCapacityPercentage: poolCapacityPercentageSum.toString(),
15980
- activeLoans: lendingPoolDirectus.activeLoans,
15981
- loanFundsOriginated: lendingPoolDirectus.loanFundsOriginated,
16001
+ activeLoans: (_r = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.activeLoans) !== null && _r !== void 0 ? _r : '0',
16002
+ loanFundsOriginated: (_s = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.loanFundsOriginated) !== null && _s !== void 0 ? _s : '0',
15982
16003
  tranches: tranches,
15983
16004
  isActive: !lendingPoolSubgraph.isStopped,
15984
16005
  requestEpochsInAdvance: lendingPoolSubgraph.configuration
15985
16006
  .lendingPoolWithdrawalConfig.requestEpochsInAdvance,
15986
16007
  };
15987
- // show only enabled pools from cms
16008
+ // When Directus is available, show only enabled pools.
16009
+ // When Directus is unavailable, include all pools.
15988
16010
  if (poolOverview.enabled) {
15989
16011
  retn.push(poolOverview);
15990
16012
  }
@@ -16204,7 +16226,11 @@ class DataService {
16204
16226
  const lendingPoolsWithdrawalsAndDepositsSubgraph = yield this._graph.request(getLendingPoolWithdrawalAndDepositsQuery, { unusedPools: this._kasuConfig.UNUSED_LENDING_POOL_IDS });
16205
16227
  const retn = [];
16206
16228
  for (const data of poolRepaymentDirectus) {
16207
- const lendingPoolSubgraph = lendingPoolsWithdrawalsAndDepositsSubgraph.lendingPools.find((pool) => pool.id == data.poolIdFK);
16229
+ // Find subgraph pool that maps to this Directus pool
16230
+ // On non-Base chains, subgraph pool IDs are different from Directus poolIdFK
16231
+ // Use getMetadataPoolId to map subgraph pool ID -> Directus/Base pool ID
16232
+ const lendingPoolSubgraph = lendingPoolsWithdrawalsAndDepositsSubgraph.lendingPools.find((pool) => this.getMetadataPoolId(pool.id) ===
16233
+ data.poolIdFK.toLowerCase());
16208
16234
  if (lendingPoolSubgraph === undefined) {
16209
16235
  continue;
16210
16236
  }
@@ -16293,9 +16319,13 @@ class DataService {
16293
16319
  retn.totalYieldEarned += parseFloat(poolOverview.yieldEarned);
16294
16320
  }
16295
16321
  for (const poolOverview of poolOverviews) {
16296
- const riskManagement = riskManagements.find((rm) => rm.poolIdFK.toLowerCase() === poolOverview.id.toLowerCase());
16322
+ // Map to metadata pool ID for Directus lookup (XDC pools → Base pools)
16323
+ const metadataPoolId = this.getMetadataPoolId(poolOverview.id);
16324
+ const riskManagement = riskManagements.find((rm) => rm.poolIdFK.toLowerCase() === metadataPoolId.toLowerCase());
16297
16325
  if (!riskManagement) {
16298
- console.warn("Couldn't find risk management for id: ", poolOverview.id);
16326
+ console.warn("Couldn't find risk management for id: ", poolOverview.id, metadataPoolId !== poolOverview.id
16327
+ ? `(mapped to ${metadataPoolId})`
16328
+ : '');
16299
16329
  continue;
16300
16330
  }
16301
16331
  const weight = retn.totalLoanFundsOriginated === 0
@@ -16333,14 +16363,18 @@ class DataService {
16333
16363
  }
16334
16364
 
16335
16365
  class KSULocking {
16336
- /**
16337
- *
16338
- */
16339
16366
  constructor(_kasuConfig, signerOrProvider) {
16340
16367
  this._kasuConfig = _kasuConfig;
16341
16368
  this.apyBonuses = [0, 0.001, 0.002];
16369
+ this._isLiteDeployment = _kasuConfig.isLiteDeployment;
16342
16370
  this._contractAbi = IKSULockingAbi__factory.connect(_kasuConfig.contracts.IKSULocking, signerOrProvider);
16343
- this._kasuToken = IERC20MetadataAbi__factory.connect(_kasuConfig.contracts.KSUToken, signerOrProvider);
16371
+ // Only initialize KSU token contract if not a Lite deployment and address is provided
16372
+ if (!this._isLiteDeployment && _kasuConfig.contracts.KSUToken) {
16373
+ this._kasuToken = IERC20MetadataAbi__factory.connect(_kasuConfig.contracts.KSUToken, signerOrProvider);
16374
+ }
16375
+ else {
16376
+ this._kasuToken = null;
16377
+ }
16344
16378
  this._userManagerAbi = IUserManagerAbi__factory.connect(_kasuConfig.contracts.UserManager, signerOrProvider);
16345
16379
  this._systemVariablesAbi = ISystemVariablesAbi__factory.connect(_kasuConfig.contracts.SystemVariables, signerOrProvider);
16346
16380
  this._ksuPriceAbi = IKsuPriceAbi__factory.connect(_kasuConfig.contracts.KsuPrice, signerOrProvider);
@@ -16348,13 +16382,25 @@ class KSULocking {
16348
16382
  this._graph = new GraphQLClient(_kasuConfig.subgraphUrl);
16349
16383
  this._userLoyaltyRewardsAbi = IUserLoyaltyRewardsAbi__factory.connect(_kasuConfig.contracts.UserLoyaltyRewards, signerOrProvider);
16350
16384
  }
16385
+ /**
16386
+ * Check if this is a Lite deployment (no KSU token functionality)
16387
+ */
16388
+ get isLiteDeployment() {
16389
+ return this._isLiteDeployment;
16390
+ }
16351
16391
  lockKSUTokens(amount, lockPeriod) {
16352
16392
  return __awaiter(this, void 0, void 0, function* () {
16393
+ if (this._isLiteDeployment) {
16394
+ throw new Error('Locking is not available on Lite deployments');
16395
+ }
16353
16396
  return this._contractAbi.lock(amount, lockPeriod);
16354
16397
  });
16355
16398
  }
16356
16399
  lockKSUWithPermit(amount, lockPeriod, permit) {
16357
16400
  return __awaiter(this, void 0, void 0, function* () {
16401
+ if (this._isLiteDeployment) {
16402
+ throw new Error('Locking is not available on Lite deployments');
16403
+ }
16358
16404
  const amountBN = BigNumber.from(amount);
16359
16405
  const lockPeriodBN = BigNumber.from(lockPeriod);
16360
16406
  const ksuPermit = {
@@ -16369,16 +16415,29 @@ class KSULocking {
16369
16415
  }
16370
16416
  unlockKSU(amount, userLockId) {
16371
16417
  return __awaiter(this, void 0, void 0, function* () {
16418
+ if (this._isLiteDeployment) {
16419
+ throw new Error('Locking is not available on Lite deployments');
16420
+ }
16372
16421
  return this._contractAbi.unlock(amount, userLockId);
16373
16422
  });
16374
16423
  }
16375
16424
  claimFees() {
16376
16425
  return __awaiter(this, void 0, void 0, function* () {
16426
+ if (this._isLiteDeployment) {
16427
+ throw new Error('Fee claiming is not available on Lite deployments');
16428
+ }
16377
16429
  return yield this._contractAbi.claimFees();
16378
16430
  });
16379
16431
  }
16380
16432
  lockDetails(lockPeriod) {
16381
16433
  return __awaiter(this, void 0, void 0, function* () {
16434
+ if (this._isLiteDeployment) {
16435
+ return {
16436
+ rKsuMultiplier: 0,
16437
+ ksuBonusMultiplier: 0,
16438
+ isActive: false,
16439
+ };
16440
+ }
16382
16441
  const result = yield this._contractAbi.lockDetails(lockPeriod);
16383
16442
  return {
16384
16443
  rKsuMultiplier: result[0].toNumber(),
@@ -16389,12 +16448,15 @@ class KSULocking {
16389
16448
  }
16390
16449
  userTotalDeposits(userAddress) {
16391
16450
  return __awaiter(this, void 0, void 0, function* () {
16451
+ if (this._isLiteDeployment) {
16452
+ return BigNumber.from(0);
16453
+ }
16392
16454
  return yield this._contractAbi.userTotalDeposits(userAddress);
16393
16455
  });
16394
16456
  }
16395
16457
  calculateUserLockProjectedProtocolFeeRewards(epochId, KSULocked, lockPeriod) {
16396
16458
  return __awaiter(this, void 0, void 0, function* () {
16397
- if (KSULocked === 0) {
16459
+ if (this._isLiteDeployment || KSULocked === 0) {
16398
16460
  return 0;
16399
16461
  }
16400
16462
  const lockingSummarySubgraph = yield this._graph.request(lockingSummariesQuery);
@@ -16440,18 +16502,21 @@ class KSULocking {
16440
16502
  }
16441
16503
  getUserLocks(userAddress) {
16442
16504
  return __awaiter(this, void 0, void 0, function* () {
16505
+ if (this._isLiteDeployment) {
16506
+ return [];
16507
+ }
16443
16508
  const result = yield this._graph.request(userLocksQuery, {
16444
16509
  userAddress: userAddress.toLowerCase(),
16445
16510
  });
16446
16511
  const resultPromises = result.userLocks.map((userLock) => __awaiter(this, void 0, void 0, function* () {
16447
16512
  const [, id] = userLock.id.split('-');
16448
- const rKSUtoUSDCRatio = yield this.getRKSUvsUSDCRatio(userLock.rKSUAmount, userAddress);
16449
- const loyaltyStatus = this.getLoyaltyLevelAndApyBonusFromRatio(rKSUtoUSDCRatio);
16513
+ const rKSUtoStableRatio = yield this.getRKSUvsStableRatio(userLock.rKSUAmount, userAddress);
16514
+ const loyaltyStatus = this.getLoyaltyLevelAndApyBonusFromRatio(rKSUtoStableRatio);
16450
16515
  return {
16451
16516
  id: BigNumber.from(id),
16452
16517
  lockedAmount: userLock.ksuAmount,
16453
16518
  rKSUAmount: userLock.rKSUAmount,
16454
- rKSUtoUSDCRatio: rKSUtoUSDCRatio,
16519
+ rKSUtoStableRatio: rKSUtoStableRatio,
16455
16520
  apyBonus: loyaltyStatus.apyBonus,
16456
16521
  loyaltyLevel: loyaltyStatus.loyaltyLevel,
16457
16522
  startTime: parseFloat(userLock.startTimestamp),
@@ -16465,8 +16530,14 @@ class KSULocking {
16465
16530
  }
16466
16531
  getUserBonusData(userAddress) {
16467
16532
  return __awaiter(this, void 0, void 0, function* () {
16468
- // TODO this userLocks query is kinda bad -> change to userLocksDepositInfo as u never need user locks by themselves
16469
- // whole function takes between 500 - 800ms
16533
+ if (this._isLiteDeployment) {
16534
+ return {
16535
+ ksuBonusAndRewards: '0',
16536
+ ksuBonusAndRewardsLifetime: '0',
16537
+ protocolFeesEarned: '0',
16538
+ totalLockedAmount: '0',
16539
+ };
16540
+ }
16470
16541
  const DECIMALS = 18;
16471
16542
  // Normalized user address
16472
16543
  const normalizedAddress = userAddress.toLowerCase();
@@ -16498,30 +16569,48 @@ class KSULocking {
16498
16569
  };
16499
16570
  });
16500
16571
  }
16501
- getLoyaltyLevelAndApyBonusFromRatio(rKSUtoUSDCRatio) {
16502
- if (rKSUtoUSDCRatio < 0.01) {
16572
+ getLoyaltyLevelAndApyBonusFromRatio(rKSUtoStableRatio) {
16573
+ // On Lite deployments, always return level 0 with no bonus
16574
+ if (this._isLiteDeployment) {
16575
+ return { loyaltyLevel: 0, apyBonus: 0 };
16576
+ }
16577
+ if (rKSUtoStableRatio < 0.01) {
16503
16578
  return { loyaltyLevel: 0, apyBonus: this.apyBonuses[0] };
16504
16579
  }
16505
- else if (rKSUtoUSDCRatio < 0.05) {
16580
+ else if (rKSUtoStableRatio < 0.05) {
16506
16581
  return { loyaltyLevel: 1, apyBonus: this.apyBonuses[1] };
16507
16582
  }
16508
16583
  return { loyaltyLevel: 2, apyBonus: this.apyBonuses[2] };
16509
16584
  }
16510
- getRKSUvsUSDCRatio(rKSUAmount, userAddress) {
16585
+ getRKSUvsStableRatio(rKSUAmount, userAddress) {
16511
16586
  return __awaiter(this, void 0, void 0, function* () {
16587
+ if (this._isLiteDeployment) {
16588
+ return 0;
16589
+ }
16512
16590
  const [depositedAmount, pendingAmount] = yield this._userManagerAbi.userTotalPendingAndActiveDepositedAmountForCurrentEpoch(userAddress);
16513
16591
  const ksuPrice = yield this._systemVariablesAbi.ksuEpochTokenPrice();
16514
16592
  const rKSUAmountBignumber = ethers.utils.parseUnits(rKSUAmount, 18);
16515
- const totalUserUsdcAmount = depositedAmount.toNumber() + pendingAmount.toNumber();
16516
- const rKSUInUSDC = rKSUAmountBignumber
16593
+ const totalUserStableAmount = depositedAmount.toNumber() + pendingAmount.toNumber();
16594
+ // Convert rKSU value to stable asset units: rKSU * ksuPrice / 1e18 / 1e(18 - stableDecimals)
16595
+ const decimalDiff = 18 - this._kasuConfig.stableAssetDecimals;
16596
+ const rKSUInStable = rKSUAmountBignumber
16517
16597
  .mul(ksuPrice)
16518
16598
  .div(ethers.utils.parseUnits('1', 18))
16519
- .div(ethers.utils.parseUnits('1', 12));
16520
- return rKSUInUSDC.toNumber() / totalUserUsdcAmount;
16599
+ .div(ethers.utils.parseUnits('1', decimalDiff));
16600
+ return rKSUInStable.toNumber() / totalUserStableAmount;
16601
+ });
16602
+ }
16603
+ /** @deprecated Use `getRKSUvsStableRatio` instead. */
16604
+ getRKSUvsUSDCRatio(rKSUAmount, userAddress) {
16605
+ return __awaiter(this, void 0, void 0, function* () {
16606
+ return this.getRKSUvsStableRatio(rKSUAmount, userAddress);
16521
16607
  });
16522
16608
  }
16523
16609
  getClaimableRewards(userAddress) {
16524
16610
  return __awaiter(this, void 0, void 0, function* () {
16611
+ if (this._isLiteDeployment) {
16612
+ return BigNumber.from(0);
16613
+ }
16525
16614
  const result = yield this._contractAbi.rewards(userAddress);
16526
16615
  return result;
16527
16616
  });
@@ -16529,6 +16618,7 @@ class KSULocking {
16529
16618
  getKasuTokenPrice() {
16530
16619
  return __awaiter(this, void 0, void 0, function* () {
16531
16620
  const decimals = 18;
16621
+ // Price can still be queried on Lite deployments (set to 0 or configured value)
16532
16622
  return Promise.resolve({
16533
16623
  price: yield this._ksuPriceAbi.ksuTokenPrice(),
16534
16624
  decimals,
@@ -16547,6 +16637,9 @@ class KSULocking {
16547
16637
  getLifetimeRewards(userAddress, rewardDecimals, claimableRewards) {
16548
16638
  return __awaiter(this, void 0, void 0, function* () {
16549
16639
  var _a, _b;
16640
+ if (this._isLiteDeployment) {
16641
+ return BigNumber.from(0);
16642
+ }
16550
16643
  const result = yield this._graph.request(claimedFeesQuery, {
16551
16644
  userAddress: userAddress.toLowerCase(),
16552
16645
  });
@@ -16558,6 +16651,9 @@ class KSULocking {
16558
16651
  });
16559
16652
  }
16560
16653
  getLaunchBonusAmount(lockAmount, bonusMultiplier, bonusTokensLeft) {
16654
+ if (this._isLiteDeployment) {
16655
+ return BigNumber.from(0);
16656
+ }
16561
16657
  const bonusMultiplierBN = ethers.utils.parseUnits(bonusMultiplier.toFixed(2), 2);
16562
16658
  const projectedBonus = lockAmount.mul(bonusMultiplierBN).div(100);
16563
16659
  if (bonusTokensLeft.gt(projectedBonus)) {
@@ -16569,6 +16665,9 @@ class KSULocking {
16569
16665
  }
16570
16666
  getUserStakedKsu(userAddress) {
16571
16667
  return __awaiter(this, void 0, void 0, function* () {
16668
+ if (this._isLiteDeployment) {
16669
+ return '0';
16670
+ }
16572
16671
  const result = yield this._graph.request(userStakedKsuQuery, {
16573
16672
  userAddress: userAddress.toLowerCase(),
16574
16673
  });
@@ -16580,6 +16679,9 @@ class KSULocking {
16580
16679
  }
16581
16680
  getUserEarnedrKsu(userAddress) {
16582
16681
  return __awaiter(this, void 0, void 0, function* () {
16682
+ if (this._isLiteDeployment) {
16683
+ return '0';
16684
+ }
16583
16685
  const result = yield this._graph.request(userEarnedrKsuQuery, {
16584
16686
  userAddress: userAddress.toLowerCase(),
16585
16687
  });
@@ -16591,6 +16693,9 @@ class KSULocking {
16591
16693
  }
16592
16694
  getUserTotalBonusAmount(userAddress) {
16593
16695
  return __awaiter(this, void 0, void 0, function* () {
16696
+ if (this._isLiteDeployment) {
16697
+ return '0';
16698
+ }
16594
16699
  const result = yield this._graph.request(userTotalBonusAmountQuery, {
16595
16700
  userAddress: userAddress.toLowerCase(),
16596
16701
  });
@@ -16602,7 +16707,13 @@ class KSULocking {
16602
16707
  }
16603
16708
  getLockingRewards(userAddress) {
16604
16709
  return __awaiter(this, void 0, void 0, function* () {
16605
- const rewardDecimals = 6;
16710
+ if (this._isLiteDeployment) {
16711
+ return {
16712
+ claimableRewards: '0',
16713
+ lifeTimeRewards: '0',
16714
+ };
16715
+ }
16716
+ const rewardDecimals = this._kasuConfig.stableAssetDecimals;
16606
16717
  const claimableRewards = yield this.getClaimableRewards(userAddress);
16607
16718
  const lifeTimeRewards = yield this.getLifetimeRewards(userAddress, rewardDecimals, claimableRewards);
16608
16719
  return {
@@ -16618,12 +16729,18 @@ class KSULocking {
16618
16729
  }
16619
16730
  getAvailableKsuBonus() {
16620
16731
  return __awaiter(this, void 0, void 0, function* () {
16732
+ if (this._isLiteDeployment || !this._kasuToken) {
16733
+ return '0';
16734
+ }
16621
16735
  const amount = yield this._kasuToken.balanceOf(this._kasuBonusAddress);
16622
16736
  return formatEther(amount);
16623
16737
  });
16624
16738
  }
16625
16739
  getUserKsuBalance(userAddress) {
16626
16740
  return __awaiter(this, void 0, void 0, function* () {
16741
+ if (this._isLiteDeployment || !this._kasuToken) {
16742
+ return '0';
16743
+ }
16627
16744
  const balance = yield this._kasuToken.balanceOf(userAddress.toLowerCase());
16628
16745
  return formatEther(balance);
16629
16746
  });
@@ -16650,6 +16767,9 @@ class KSULocking {
16650
16767
  }
16651
16768
  getActiveLockPeriods() {
16652
16769
  return __awaiter(this, void 0, void 0, function* () {
16770
+ if (this._isLiteDeployment) {
16771
+ return [];
16772
+ }
16653
16773
  const data = yield this._graph.request(lockingPeriodsQuery);
16654
16774
  return data.lockPeriods;
16655
16775
  });
@@ -16657,9 +16777,21 @@ class KSULocking {
16657
16777
  getProjectedApy() {
16658
16778
  return '10.00';
16659
16779
  }
16660
- getProjectedUSDC() {
16780
+ getProjectedStableAmount() {
16661
16781
  return '20.00';
16662
16782
  }
16783
+ /** @deprecated Use `getProjectedStableAmount` instead. */
16784
+ getProjectedUSDC() {
16785
+ return this.getProjectedStableAmount();
16786
+ }
16787
+ }
16788
+
16789
+ /**
16790
+ * Check if the SDK is configured for a Lite deployment.
16791
+ * Lite deployments don't have KSU token, locking, or loyalty features.
16792
+ */
16793
+ function isLiteDeployment(config) {
16794
+ return config.isLiteDeployment;
16663
16795
  }
16664
16796
 
16665
16797
  const USER_REQUEST_EVENT_MAP = {
@@ -16954,13 +17086,19 @@ class UserLending {
16954
17086
  return yield this._lendingPoolManagerAbi.requestWithdrawal(lendingPool, tranche, amount);
16955
17087
  });
16956
17088
  }
16957
- requestWithdrawalInUSDC(lendingPool, tranche, usdcAmount) {
17089
+ requestWithdrawalInAsset(lendingPool, tranche, assetAmount) {
16958
17090
  return __awaiter(this, void 0, void 0, function* () {
16959
17091
  const trancheContract = ILendingPoolTrancheAbi__factory.connect(tranche, this._signerOrProvider);
16960
- const shareAmount = yield trancheContract.convertToShares(usdcAmount);
17092
+ const shareAmount = yield trancheContract.convertToShares(assetAmount);
16961
17093
  return yield this._lendingPoolManagerAbi.requestWithdrawal(lendingPool, tranche, shareAmount);
16962
17094
  });
16963
17095
  }
17096
+ /** @deprecated Use `requestWithdrawalInAsset` instead. */
17097
+ requestWithdrawalInUSDC(lendingPool, tranche, amount) {
17098
+ return __awaiter(this, void 0, void 0, function* () {
17099
+ return this.requestWithdrawalInAsset(lendingPool, tranche, amount);
17100
+ });
17101
+ }
16964
17102
  requestWithdrawalMax(lendingPool, tranche, user) {
16965
17103
  return __awaiter(this, void 0, void 0, function* () {
16966
17104
  const trancheContract = ILendingPoolTrancheAbi__factory.connect(tranche, this._signerOrProvider);
@@ -17242,7 +17380,7 @@ class UserLending {
17242
17380
  lendingPool.id.toLowerCase())) === null || _a === void 0 ? void 0 : _a.balance) !== null && _b !== void 0 ? _b : BigNumber.from(0);
17243
17381
  return {
17244
17382
  poolId: lendingPool.id,
17245
- yieldEarned: parseFloat(ethers.utils.formatUnits(balance, 6)) -
17383
+ yieldEarned: parseFloat(ethers.utils.formatUnits(balance, this._kasuConfig.stableAssetDecimals)) -
17246
17384
  parseFloat(totalAcceptedDeposits) -
17247
17385
  -parseFloat(totalAcceptedWithdrawnAmount),
17248
17386
  balance,
@@ -17514,7 +17652,10 @@ class Portfolio {
17514
17652
  this._systemVariablesAbi = ISystemVariablesAbi__factory.connect(_kasuConfig.contracts.SystemVariables, signerOrProvider);
17515
17653
  this._userLoyaltyRewardsAbi = IUserLoyaltyRewardsAbi__factory.connect(_kasuConfig.contracts.UserLoyaltyRewards, signerOrProvider);
17516
17654
  this._userLendingService = new UserLending(_kasuConfig, signerOrProvider);
17517
- this._kasuNftContract = IKasuNFTsAbi__factory.connect(_kasuConfig.contracts.KasuNFTs, signerOrProvider);
17655
+ this._isLiteDeployment = isLiteDeployment(_kasuConfig);
17656
+ this._kasuNftContract = _kasuConfig.contracts.KasuNFTs
17657
+ ? IKasuNFTsAbi__factory.connect(_kasuConfig.contracts.KasuNFTs, signerOrProvider)
17658
+ : null;
17518
17659
  this._graph = new GraphQLClient(_kasuConfig.subgraphUrl);
17519
17660
  }
17520
17661
  computeYieldMetrics(portfolioLendingPools) {
@@ -17560,8 +17701,8 @@ class Portfolio {
17560
17701
  return this.computeYieldMetrics(portfolioLendingPools);
17561
17702
  }
17562
17703
  /**
17563
- * Calculate the user's weekly protocol fee share (USDC) given tranche balances/configs,
17564
- * system variables and locking summary. All inputs are expected to be pre-fetched.
17704
+ * Calculate the user's weekly protocol fee share (in stable asset units) given tranche
17705
+ * balances/configs, system variables and locking summary. All inputs are expected to be pre-fetched.
17565
17706
  */
17566
17707
  calculateWeeklyProtocolFees(params) {
17567
17708
  var _a, _b;
@@ -17603,8 +17744,8 @@ class Portfolio {
17603
17744
  const totalUserDeposits = userDepositAmounts[0].add(userDepositAmounts[1]);
17604
17745
  if (totalUserDeposits.isZero())
17605
17746
  return 0;
17606
- const rKSUtoUSDCRatio = yield this._lockingService.getRKSUvsUSDCRatio(userRksuAmount, userAddress);
17607
- const { loyaltyLevel } = this._lockingService.getLoyaltyLevelAndApyBonusFromRatio(rKSUtoUSDCRatio);
17747
+ const rKSUtoStableRatio = yield this._lockingService.getRKSUvsStableRatio(userRksuAmount, userAddress);
17748
+ const { loyaltyLevel } = this._lockingService.getLoyaltyLevelAndApyBonusFromRatio(rKSUtoStableRatio);
17608
17749
  const loyaltyRewardRate = yield this._userLoyaltyRewardsAbi.loyaltyEpochRewardRates(loyaltyLevel);
17609
17750
  if (loyaltyRewardRate.isZero() || ksuEpochPrice.price.isZero()) {
17610
17751
  return 0;
@@ -17632,9 +17773,9 @@ class Portfolio {
17632
17773
  },
17633
17774
  protocolFees: {
17634
17775
  claimableBalance: {
17635
- usdcAmount: lockingRewards.claimableRewards,
17776
+ stableAmount: lockingRewards.claimableRewards,
17636
17777
  },
17637
- lifeTime: { usdcAmount: lockingRewards.lifeTimeRewards },
17778
+ lifeTime: { stableAmount: lockingRewards.lifeTimeRewards },
17638
17779
  },
17639
17780
  ksuLaunchBonus: { lifeTime: { ksuAmount: ksuLaunchBonus } },
17640
17781
  };
@@ -17642,6 +17783,10 @@ class Portfolio {
17642
17783
  }
17643
17784
  getUserNfts(userAddress) {
17644
17785
  return __awaiter(this, void 0, void 0, function* () {
17786
+ // NFTs are not available on Lite deployments
17787
+ if (this._isLiteDeployment || !this._kasuNftContract) {
17788
+ return [];
17789
+ }
17645
17790
  const usernfts = yield this._kasuNftContract.tokensOfOwner(userAddress);
17646
17791
  return usernfts.map((nft) => nft.toNumber());
17647
17792
  });
@@ -21742,4 +21887,421 @@ class KasuSdk {
21742
21887
  }
21743
21888
  }
21744
21889
 
21745
- export { KasuSdk };
21890
+ class SdkConfig {
21891
+ constructor(options) {
21892
+ var _a, _b, _c, _d;
21893
+ this.subgraphUrl = options.subgraphUrl;
21894
+ this.contracts = options.contracts;
21895
+ this.directusUrl = (_a = options.directusUrl) !== null && _a !== void 0 ? _a : '';
21896
+ this.UNUSED_LENDING_POOL_IDS = options.UNUSED_LENDING_POOL_IDS;
21897
+ this.isLiteDeployment = (_b = options.isLiteDeployment) !== null && _b !== void 0 ? _b : false;
21898
+ this.poolMetadataMapping = (_c = options.poolMetadataMapping) !== null && _c !== void 0 ? _c : {};
21899
+ this.stableAssetDecimals = (_d = options.stableAssetDecimals) !== null && _d !== void 0 ? _d : 6;
21900
+ }
21901
+ }
21902
+
21903
+ /**
21904
+ * Built-in chain configurations for Kasu-supported networks.
21905
+ *
21906
+ * Usage:
21907
+ * ```ts
21908
+ * import { CHAIN_CONFIGS } from '@kasufinance/kasu-sdk';
21909
+ * const base = CHAIN_CONFIGS.base;
21910
+ * ```
21911
+ */
21912
+ const CHAIN_CONFIGS = {
21913
+ base: {
21914
+ chainId: 8453,
21915
+ name: 'Base Mainnet',
21916
+ isLiteDeployment: false,
21917
+ contracts: {
21918
+ KSUToken: '0x5D9b878744dbe721a3f33A60a6b102E289CeADBA',
21919
+ IKSULocking: '0xB145C061684C701c2C018A3f322aa14F5A553CE1',
21920
+ IKSULockBonus: '0xEEDE30AcF16caFf49c1a48F75185C67Be2e20B40',
21921
+ LendingPoolManager: '0xE1Be322323a412579b4A09fB08ff4bfcA12096B5',
21922
+ UserManager: '0x5Dc8D315a80fd99AbEF0f327B9a52a3FBC3C93f3',
21923
+ KasuAllowList: '0x807A7e119EBf0282420b5Ca0e0056c0525cBf8BB',
21924
+ SystemVariables: '0x193Bb02A24F5562b58fEB86550e6f09Bb6c41f69',
21925
+ KsuPrice: '0x221a54CbbD5f490Bd8e77CF36acBA4B1304E5c1b',
21926
+ UserLoyaltyRewards: '0xB4784f69Bb1F1076F50907cB0a815908a719D635',
21927
+ ClearingCoordinator: '0x2cF12A6d91fa4bEB5a4C17589a03e78F88f57DE2',
21928
+ KasuNFTs: '0x4946fF5f1a6550524C425479022D50446AA2968E',
21929
+ ExternalTVL: '0x662379FEBb3e4F91400B5f7d4f7F7ce4699F3c9F',
21930
+ },
21931
+ subgraphUrl: 'https://api.goldsky.com/api/public/project_cmgzlpxm300765np2a19421om/subgraphs/kasu-base/v1.0.13/gn',
21932
+ directusUrl: 'https://kasu-finance.directus.app/',
21933
+ unusedPoolIds: [],
21934
+ poolMetadataMapping: undefined,
21935
+ },
21936
+ xdc: {
21937
+ chainId: 50,
21938
+ name: 'XDC Mainnet',
21939
+ isLiteDeployment: true,
21940
+ contracts: {
21941
+ // No KSUToken on Lite deployments
21942
+ IKSULocking: '0x7fF469f8c5fba92A9051B8D28794CBb891760e81',
21943
+ IKSULockBonus: '0x7cc1434EfA50301Fdd56B7c5c6fF7e30Dc20C55c',
21944
+ LendingPoolManager: '0xa46143db92aBe5bB1f61d13d8C1cCd50fc40Ca10',
21945
+ UserManager: '0x9b57dF89e59235f0481A5Fae942302c8831e1B81',
21946
+ KasuAllowList: '0x32c1Ff5FbBe6D28503ddc46E5001C0D13d6E9B2A',
21947
+ SystemVariables: '0x34d17c9DD1f31Fb34757DE923EC083601d0eDFFe',
21948
+ KsuPrice: '0x666b589933965bF8B378eD973f0404b6cae0eb52',
21949
+ UserLoyaltyRewards: '0xb95834C5610A178be9065Dd1EF78258D29879CDb',
21950
+ ClearingCoordinator: '0xAF0a66953Eba1c5353eB7425b398B213Bb2c6121',
21951
+ // No KasuNFTs on Lite deployments
21952
+ ExternalTVL: '0xCCB4156964377CF36441f3775A2A800dbeCB8094',
21953
+ },
21954
+ subgraphUrl: 'https://api.goldsky.com/api/public/project_cmgzlpxm300765np2a19421om/subgraphs/kasu-xdc/v1.0.0/gn',
21955
+ directusUrl: 'https://kasu-finance.directus.app/',
21956
+ unusedPoolIds: [],
21957
+ poolMetadataMapping: {
21958
+ '0x20f42fb45f91657acf9528b99a5a16d0229c7800': '0xc987350716fe4a7d674c3591c391d29eba26b8ce',
21959
+ '0x3b7cb493aa22f731db2ab424d918e7375e00f6a9': '0x03f93c8caa9a82e000d35673ba34a4c0e6e117a2',
21960
+ '0xeda50c91a8c4ca8a83652b8542c0b3bd00a71fad': '0xc347a9e4aec8c8d11a149d2907deb2bf23b81c6f',
21961
+ },
21962
+ },
21963
+ plume: {
21964
+ chainId: 98866,
21965
+ name: 'Plume Mainnet',
21966
+ isLiteDeployment: true,
21967
+ contracts: {
21968
+ // Placeholder — update when Plume contracts are deployed
21969
+ IKSULocking: '',
21970
+ IKSULockBonus: '',
21971
+ LendingPoolManager: '',
21972
+ UserManager: '',
21973
+ KasuAllowList: '',
21974
+ SystemVariables: '',
21975
+ KsuPrice: '',
21976
+ UserLoyaltyRewards: '',
21977
+ ClearingCoordinator: '',
21978
+ ExternalTVL: '',
21979
+ },
21980
+ subgraphUrl: 'https://api.goldsky.com/api/public/project_cmgzlpxm300765np2a19421om/subgraphs/kasu-plume/prod',
21981
+ directusUrl: 'https://kasu-finance.directus.app/',
21982
+ unusedPoolIds: [],
21983
+ poolMetadataMapping: undefined,
21984
+ },
21985
+ };
21986
+
21987
+ /**
21988
+ * High-level facade for deposit and withdrawal operations.
21989
+ *
21990
+ * Integrators use this to submit on-chain transactions without
21991
+ * worrying about internal encoding details.
21992
+ */
21993
+ class DepositsFacade {
21994
+ constructor(_userLending, _chainId) {
21995
+ this._userLending = _userLending;
21996
+ this._chainId = _chainId;
21997
+ }
21998
+ /**
21999
+ * Submit a deposit request.
22000
+ *
22001
+ * The integrator must first obtain a KYC signature via the Nexera flow
22002
+ * using the params from `buildKycParams()`.
22003
+ *
22004
+ * ```ts
22005
+ * const kycParams = kasu.deposits.buildKycParams('0xUser...');
22006
+ * // ... obtain kycSignature from your backend via Nexera ...
22007
+ * const tx = await kasu.deposits.deposit({
22008
+ * poolId: '0x...',
22009
+ * trancheId: '0x...',
22010
+ * amount: parseUnits('1000', 6), // 6 decimals for USDC/AUDD; use token's actual decimals
22011
+ * kycSignature: { blockExpiration, signature },
22012
+ * });
22013
+ * ```
22014
+ */
22015
+ deposit(params) {
22016
+ return __awaiter(this, void 0, void 0, function* () {
22017
+ var _a, _b, _c, _d;
22018
+ return yield this._userLending.requestDepositWithKyc(params.poolId, params.trancheId, params.amount, (_a = params.swapData) !== null && _a !== void 0 ? _a : '0x', (_b = params.fixedTermConfigId) !== null && _b !== void 0 ? _b : 0, (_c = params.depositData) !== null && _c !== void 0 ? _c : '0x', params.kycSignature, (_d = params.ethValue) !== null && _d !== void 0 ? _d : '0');
22019
+ });
22020
+ }
22021
+ /**
22022
+ * Submit a withdrawal request for a specific stable asset amount.
22023
+ */
22024
+ withdraw(params) {
22025
+ return __awaiter(this, void 0, void 0, function* () {
22026
+ return yield this._userLending.requestWithdrawalInAsset(params.poolId, params.trancheId, params.amount);
22027
+ });
22028
+ }
22029
+ /**
22030
+ * Withdraw the entire balance from a tranche.
22031
+ */
22032
+ withdrawMax(poolId, trancheId, userAddress) {
22033
+ return __awaiter(this, void 0, void 0, function* () {
22034
+ return yield this._userLending.requestWithdrawalMax(poolId, trancheId, userAddress);
22035
+ });
22036
+ }
22037
+ /**
22038
+ * Build KYC signature parameters for the Nexera verification flow.
22039
+ *
22040
+ * The integrator is responsible for sending these to their backend,
22041
+ * which obtains the signature from Nexera's signing service.
22042
+ */
22043
+ buildKycParams(userAddress) {
22044
+ return this._userLending.buildKycSignatureParams(userAddress, this._chainId);
22045
+ }
22046
+ /**
22047
+ * Check whether the pool is currently in a clearing period
22048
+ * (deposits/withdrawals are temporarily paused).
22049
+ */
22050
+ isClearingPending(poolId) {
22051
+ return __awaiter(this, void 0, void 0, function* () {
22052
+ return yield this._userLending.isClearingPending(poolId);
22053
+ });
22054
+ }
22055
+ /**
22056
+ * Get the current epoch number.
22057
+ */
22058
+ getCurrentEpoch() {
22059
+ return __awaiter(this, void 0, void 0, function* () {
22060
+ return yield this._userLending.getCurrentEpoch();
22061
+ });
22062
+ }
22063
+ }
22064
+
22065
+ /**
22066
+ * High-level facade for browsing Kasu lending strategies (pools).
22067
+ *
22068
+ * Handles epoch fetching internally so callers never need to know about epochs.
22069
+ */
22070
+ class StrategiesFacade {
22071
+ constructor(_dataService, _userLending) {
22072
+ this._dataService = _dataService;
22073
+ this._userLending = _userLending;
22074
+ }
22075
+ /**
22076
+ * Fetch all active lending strategies.
22077
+ *
22078
+ * ```ts
22079
+ * const strategies = await kasu.strategies.getAll();
22080
+ * ```
22081
+ */
22082
+ getAll(poolIds) {
22083
+ return __awaiter(this, void 0, void 0, function* () {
22084
+ const epochId = yield this._userLending.getCurrentEpoch();
22085
+ const pools = yield this._dataService.getPoolOverview(epochId, poolIds);
22086
+ return pools.map((pool) => this.mapPoolToStrategy(pool));
22087
+ });
22088
+ }
22089
+ /**
22090
+ * Fetch a single strategy by pool ID. Returns `null` if not found.
22091
+ */
22092
+ getById(poolId) {
22093
+ return __awaiter(this, void 0, void 0, function* () {
22094
+ var _a;
22095
+ const results = yield this.getAll([poolId]);
22096
+ return (_a = results[0]) !== null && _a !== void 0 ? _a : null;
22097
+ });
22098
+ }
22099
+ /**
22100
+ * Aggregate platform statistics (TVL, loans, yield, loss rate).
22101
+ */
22102
+ getPlatformStats() {
22103
+ return __awaiter(this, void 0, void 0, function* () {
22104
+ const epochId = yield this._userLending.getCurrentEpoch();
22105
+ const pools = yield this._dataService.getPoolOverview(epochId);
22106
+ return yield this._dataService.getLendingTotals(pools);
22107
+ });
22108
+ }
22109
+ /**
22110
+ * Calculate deposit limits for a specific tranche.
22111
+ *
22112
+ * @param tranche - A `StrategyTranche` from `getAll()` or `getById()`.
22113
+ * @returns min/max/capacity in ether-formatted USDC strings.
22114
+ */
22115
+ calculateDepositLimits(tranche) {
22116
+ const raw = tranche._raw;
22117
+ const min = parseFloat(raw.minimumDeposit) < 1
22118
+ ? '1'
22119
+ : raw.minimumDeposit;
22120
+ const max = parseFloat(raw.maximumDeposit) > parseFloat(raw.poolCapacity)
22121
+ ? raw.poolCapacity
22122
+ : raw.maximumDeposit;
22123
+ return {
22124
+ min,
22125
+ max,
22126
+ availableCapacity: raw.poolCapacity,
22127
+ };
22128
+ }
22129
+ // ------------------------------------------------------------------
22130
+ // Private helpers
22131
+ // ------------------------------------------------------------------
22132
+ mapPoolToStrategy(pool) {
22133
+ const tranches = pool.tranches.map((t) => ({
22134
+ id: t.id,
22135
+ name: t.name,
22136
+ apy: parseFloat(t.apy),
22137
+ minApy: parseFloat(t.minApy),
22138
+ maxApy: parseFloat(t.maxApy),
22139
+ minimumDeposit: t.minimumDeposit,
22140
+ maximumDeposit: t.maximumDeposit,
22141
+ availableCapacity: t.poolCapacity,
22142
+ fixedTermOptions: t.fixedTermConfig.map((ftd) => ({
22143
+ configId: ftd.configId,
22144
+ apy: parseFloat(ftd.apy),
22145
+ epochLockDuration: ftd.epochLockDuration,
22146
+ })),
22147
+ _raw: t,
22148
+ }));
22149
+ return {
22150
+ id: pool.id,
22151
+ name: pool.poolName,
22152
+ description: pool.description,
22153
+ isActive: pool.isActive,
22154
+ apy: pool.apy,
22155
+ tvl: pool.totalValueLocked,
22156
+ availableCapacity: pool.poolCapacity,
22157
+ capacityUtilisation: pool.poolCapacityPercentage,
22158
+ tranches,
22159
+ assetClass: pool.assetClass,
22160
+ apyStructure: pool.poolApyStructure,
22161
+ thumbnailUrl: pool.thumbnailImageUrl,
22162
+ bannerUrl: pool.bannerImageUrl,
22163
+ _raw: pool,
22164
+ };
22165
+ }
22166
+ }
22167
+
22168
+ /**
22169
+ * High-level facade for querying a user's portfolio, positions, and history.
22170
+ *
22171
+ * Orchestrates DataService, UserLending, and Portfolio services so the caller
22172
+ * only needs to provide a wallet address.
22173
+ */
22174
+ class PortfolioFacade {
22175
+ constructor(_dataService, _userLending, _portfolio) {
22176
+ this._dataService = _dataService;
22177
+ this._userLending = _userLending;
22178
+ this._portfolio = _portfolio;
22179
+ }
22180
+ /**
22181
+ * Fetch a user's complete portfolio: per-pool positions and aggregate summary.
22182
+ *
22183
+ * ```ts
22184
+ * const positions = await kasu.portfolio.getPositions('0xUser...');
22185
+ * console.log(positions.summary.current.totalLendingPoolInvestments);
22186
+ * ```
22187
+ *
22188
+ * @param userAddress - Wallet address.
22189
+ * @param provider - Optional separate provider for balance queries (useful when the
22190
+ * SDK was initialised with a Signer but you need a read-only provider).
22191
+ */
22192
+ getPositions(userAddress, provider) {
22193
+ return __awaiter(this, void 0, void 0, function* () {
22194
+ const currentEpoch = yield this._userLending.getCurrentEpoch();
22195
+ const poolOverviews = yield this._dataService.getPoolOverview(currentEpoch);
22196
+ const pools = yield this._portfolio.getPortfolioLendingData(userAddress, poolOverviews, currentEpoch, provider);
22197
+ const summary = yield this._portfolio.getPortfolioSummary(userAddress, pools, currentEpoch);
22198
+ return { pools, summary };
22199
+ });
22200
+ }
22201
+ /**
22202
+ * Fetch a user's full transaction history (deposits, withdrawals, cancellations).
22203
+ */
22204
+ getTransactionHistory(userAddress) {
22205
+ return __awaiter(this, void 0, void 0, function* () {
22206
+ const currentEpoch = yield this._userLending.getCurrentEpoch();
22207
+ return yield this._userLending.getUserRequests(userAddress, currentEpoch);
22208
+ });
22209
+ }
22210
+ }
22211
+
22212
+ /**
22213
+ * High-level entry point for external integrators.
22214
+ *
22215
+ * Provides three domain facades — `strategies`, `deposits`, `portfolio` — and
22216
+ * exposes the underlying `KasuSdk` services via `.services` for power-users.
22217
+ *
22218
+ * ```ts
22219
+ * import { Kasu } from '@kasufinance/kasu-sdk';
22220
+ *
22221
+ * const kasu = Kasu.create({ chain: 'base', signerOrProvider: provider });
22222
+ *
22223
+ * // Browse strategies
22224
+ * const strategies = await kasu.strategies.getAll();
22225
+ *
22226
+ * // Deposit
22227
+ * const tx = await kasu.deposits.deposit({ poolId, trancheId, amount, kycSignature });
22228
+ *
22229
+ * // User positions
22230
+ * const positions = await kasu.portfolio.getPositions(userAddress);
22231
+ * ```
22232
+ */
22233
+ class Kasu {
22234
+ constructor(sdk, chainConfig) {
22235
+ this._sdk = sdk;
22236
+ this._chainConfig = chainConfig;
22237
+ this.strategies = new StrategiesFacade(sdk.DataService, sdk.UserLending);
22238
+ this.deposits = new DepositsFacade(sdk.UserLending, chainConfig.chainId.toString());
22239
+ this.portfolio = new PortfolioFacade(sdk.DataService, sdk.UserLending, sdk.Portfolio);
22240
+ }
22241
+ /**
22242
+ * Create a Kasu instance with built-in chain config.
22243
+ *
22244
+ * ```ts
22245
+ * // Minimal setup — uses built-in Base mainnet config
22246
+ * const kasu = Kasu.create({ chain: 'base', signerOrProvider: provider });
22247
+ *
22248
+ * // Custom config override
22249
+ * const kasu = Kasu.create({
22250
+ * chain: 'base',
22251
+ * signerOrProvider: signer,
22252
+ * configOverrides: { UNUSED_LENDING_POOL_IDS: ['0x...'] },
22253
+ * });
22254
+ *
22255
+ * // Fully custom chain
22256
+ * const kasu = Kasu.create({
22257
+ * chain: { chainId: 123, name: 'MyChain', ... },
22258
+ * signerOrProvider: provider,
22259
+ * });
22260
+ * ```
22261
+ */
22262
+ static create(options) {
22263
+ var _a, _b, _c, _d, _e, _f, _g;
22264
+ const chainConfig = resolveChainConfig(options.chain);
22265
+ const overrides = (_a = options.configOverrides) !== null && _a !== void 0 ? _a : {};
22266
+ const sdkConfig = new SdkConfig({
22267
+ subgraphUrl: (_b = overrides.subgraphUrl) !== null && _b !== void 0 ? _b : chainConfig.subgraphUrl,
22268
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
22269
+ contracts: (_c = overrides.contracts) !== null && _c !== void 0 ? _c : chainConfig.contracts,
22270
+ directusUrl: (_d = overrides.directusUrl) !== null && _d !== void 0 ? _d : chainConfig.directusUrl,
22271
+ UNUSED_LENDING_POOL_IDS: (_e = overrides.UNUSED_LENDING_POOL_IDS) !== null && _e !== void 0 ? _e : chainConfig.unusedPoolIds,
22272
+ isLiteDeployment: (_f = overrides.isLiteDeployment) !== null && _f !== void 0 ? _f : chainConfig.isLiteDeployment,
22273
+ poolMetadataMapping: (_g = overrides.poolMetadataMapping) !== null && _g !== void 0 ? _g : chainConfig.poolMetadataMapping,
22274
+ });
22275
+ const sdk = new KasuSdk(sdkConfig, options.signerOrProvider);
22276
+ return new Kasu(sdk, chainConfig);
22277
+ }
22278
+ /**
22279
+ * Access the underlying `KasuSdk` services for advanced use cases.
22280
+ *
22281
+ * ```ts
22282
+ * const locks = await kasu.services.Locking.getUserLocks(address);
22283
+ * ```
22284
+ */
22285
+ get services() {
22286
+ return this._sdk;
22287
+ }
22288
+ /** The resolved chain configuration. */
22289
+ get chainConfig() {
22290
+ return this._chainConfig;
22291
+ }
22292
+ /** Whether this deployment has KSU token / locking features. */
22293
+ get isLiteDeployment() {
22294
+ return this._chainConfig.isLiteDeployment;
22295
+ }
22296
+ }
22297
+ // ---------------------------------------------------------------------------
22298
+ // Helpers
22299
+ // ---------------------------------------------------------------------------
22300
+ function resolveChainConfig(chain) {
22301
+ if (typeof chain === 'string') {
22302
+ return CHAIN_CONFIGS[chain];
22303
+ }
22304
+ return chain;
22305
+ }
22306
+
22307
+ export { CHAIN_CONFIGS, DepositsFacade, Kasu, KasuSdk, PortfolioFacade, SdkConfig, StrategiesFacade };