@kasufinance/kasu-sdk 1.0.4 → 2.1.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 (77) hide show
  1. package/.claude/settings.local.json +15 -0
  2. package/CLAUDE.md +410 -0
  3. package/README.md +179 -12
  4. package/dist/bundle.cjs.js +616 -67
  5. package/dist/bundle.esm.js +612 -69
  6. package/dist/facade/chain-configs.d.ts +11 -0
  7. package/dist/facade/chain-configs.js +84 -0
  8. package/dist/facade/chain-configs.js.map +1 -0
  9. package/dist/facade/deposits.d.ts +56 -0
  10. package/dist/facade/deposits.js +87 -0
  11. package/dist/facade/deposits.js.map +1 -0
  12. package/dist/facade/index.d.ts +6 -0
  13. package/dist/facade/index.js +9 -0
  14. package/dist/facade/index.js.map +1 -0
  15. package/dist/facade/kasu.d.ts +71 -0
  16. package/dist/facade/kasu.js +101 -0
  17. package/dist/facade/kasu.js.map +1 -0
  18. package/dist/facade/strategies.d.ts +37 -0
  19. package/dist/facade/strategies.js +112 -0
  20. package/dist/facade/strategies.js.map +1 -0
  21. package/dist/facade/types.d.ts +127 -0
  22. package/dist/facade/types.js +2 -0
  23. package/dist/facade/types.js.map +1 -0
  24. package/dist/facade/user-portfolio.d.ts +35 -0
  25. package/dist/facade/user-portfolio.js +53 -0
  26. package/dist/facade/user-portfolio.js.map +1 -0
  27. package/dist/index.d.ts +9 -17
  28. package/dist/index.js +9 -16
  29. package/dist/index.js.map +1 -1
  30. package/dist/kasu-sdk.d.ts +17 -0
  31. package/dist/kasu-sdk.js +17 -0
  32. package/dist/kasu-sdk.js.map +1 -0
  33. package/dist/sdk-config.d.ts +28 -4
  34. package/dist/sdk-config.js +8 -6
  35. package/dist/sdk-config.js.map +1 -1
  36. package/dist/services/DataService/data-service.d.ts +9 -2
  37. package/dist/services/DataService/data-service.js +90 -52
  38. package/dist/services/DataService/data-service.js.map +1 -1
  39. package/dist/services/DataService/queries.d.ts +0 -1
  40. package/dist/services/DataService/queries.js +0 -8
  41. package/dist/services/DataService/queries.js.map +1 -1
  42. package/dist/services/DataService/subgraph-types.d.ts +0 -6
  43. package/dist/services/DataService/types.d.ts +0 -1
  44. package/dist/services/Locking/locking.d.ts +4 -2
  45. package/dist/services/Locking/locking.js +89 -7
  46. package/dist/services/Locking/locking.js.map +1 -1
  47. package/dist/services/Portfolio/portfolio.d.ts +1 -0
  48. package/dist/services/Portfolio/portfolio.js +9 -1
  49. package/dist/services/Portfolio/portfolio.js.map +1 -1
  50. package/dist/tests/facade.test.d.ts +1 -0
  51. package/dist/tests/facade.test.js +196 -0
  52. package/dist/tests/facade.test.js.map +1 -0
  53. package/dist/tests/sample.test.js +19 -14
  54. package/dist/tests/sample.test.js.map +1 -1
  55. package/dist/utils/deployment-mode.d.ts +6 -0
  56. package/dist/utils/deployment-mode.js +8 -0
  57. package/dist/utils/deployment-mode.js.map +1 -0
  58. package/package.json +2 -2
  59. package/src/facade/chain-configs.ts +93 -0
  60. package/src/facade/deposits.ts +102 -0
  61. package/src/facade/index.ts +26 -0
  62. package/src/facade/kasu.ts +144 -0
  63. package/src/facade/strategies.ts +119 -0
  64. package/src/facade/types.ts +168 -0
  65. package/src/facade/user-portfolio.ts +73 -0
  66. package/src/index.ts +59 -25
  67. package/src/kasu-sdk.ts +27 -0
  68. package/src/sdk-config.ts +36 -15
  69. package/src/services/DataService/data-service.ts +105 -65
  70. package/src/services/DataService/queries.ts +0 -9
  71. package/src/services/DataService/subgraph-types.ts +0 -7
  72. package/src/services/DataService/types.ts +0 -1
  73. package/src/services/Locking/locking.ts +113 -12
  74. package/src/services/Portfolio/portfolio.ts +15 -5
  75. package/src/tests/facade.test.ts +245 -0
  76. package/src/tests/sample.test.ts +7 -9
  77. package/src/utils/deployment-mode.ts +9 -0
@@ -15616,14 +15616,6 @@ function filterArray(array, id_in) {
15616
15616
  }
15617
15617
  }
15618
15618
 
15619
- const getPlumeTvl = gql `
15620
- {
15621
- lendingPools {
15622
- id
15623
- balance
15624
- }
15625
- }
15626
- `;
15627
15619
  const getPoolOverviewQuery = (ids) => gql `
15628
15620
  query getAllPoolOverview($epochId: String!, $unusedPools: [String]!) {
15629
15621
  lendingPools(
@@ -15777,17 +15769,36 @@ const getLendingPoolWithdrawalAndDepositsQuery = gql `
15777
15769
  class DataService {
15778
15770
  constructor(_kasuConfig, signerOrProvider) {
15779
15771
  this._kasuConfig = _kasuConfig;
15780
- this._plumeTvl = new Map();
15781
15772
  this._externalTvlAbi = KasuPoolExternalTVLAbi__factory.connect(_kasuConfig.contracts.ExternalTVL, signerOrProvider);
15782
15773
  this._graph = new GraphQLClient(_kasuConfig.subgraphUrl);
15783
- this._plumeGraph = new GraphQLClient(_kasuConfig.plumeSubgraphUrl);
15784
- this._directus = le(_kasuConfig.directusUrl)
15785
- .with(ne())
15786
- .with(Zp());
15774
+ if (_kasuConfig.directusUrl) {
15775
+ this._directus = le(_kasuConfig.directusUrl)
15776
+ .with(ne())
15777
+ .with(Zp());
15778
+ }
15779
+ else {
15780
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
15781
+ this._directus = null;
15782
+ }
15787
15783
  }
15788
15784
  getUrlFromFile(fileName) {
15789
15785
  return `${this._kasuConfig.directusUrl}assets/${fileName}`;
15790
15786
  }
15787
+ /**
15788
+ * Maps a pool ID to its metadata source pool ID.
15789
+ * Used for chains (XDC, Plume) that share Directus metadata with Base pools.
15790
+ */
15791
+ getMetadataPoolId(poolId) {
15792
+ var _a;
15793
+ const normalizedId = poolId.toLowerCase();
15794
+ return (_a = this._kasuConfig.poolMetadataMapping[normalizedId]) !== null && _a !== void 0 ? _a : normalizedId;
15795
+ }
15796
+ /**
15797
+ * Maps an array of pool IDs to their metadata source pool IDs.
15798
+ */
15799
+ getMetadataPoolIds(poolIds) {
15800
+ return poolIds.map((id) => this.getMetadataPoolId(id));
15801
+ }
15791
15802
  calculatePoolCapacity(poolCapacities, poolCapacityPercentages, index, spillOver, lendingPoolSubgraph, lendingPoolConfig) {
15792
15803
  const desiredDrawAmount = lendingPoolConfig.desiredDrawAmount; // subgraph
15793
15804
  const desiredTrancheRatio = lendingPoolConfig.tranchesConfig[index].desiredRatio;
@@ -15845,7 +15856,7 @@ class DataService {
15845
15856
  }
15846
15857
  getPoolOverview(epochId, id_in) {
15847
15858
  return __awaiter(this, void 0, void 0, function* () {
15848
- var _a, _b, _c;
15859
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
15849
15860
  const trancheNames = [
15850
15861
  ['Senior'],
15851
15862
  ['Junior', 'Senior'],
@@ -15855,29 +15866,39 @@ class DataService {
15855
15866
  unusedPools: this._kasuConfig.UNUSED_LENDING_POOL_IDS,
15856
15867
  epochId,
15857
15868
  });
15858
- if (!this._plumeTvl.size) {
15859
- const plumeResults = yield this._plumeGraph.request(getPlumeTvl);
15860
- for (const pool of plumeResults.lendingPools) {
15861
- this._plumeTvl.set(pool.id, pool.balance);
15862
- }
15863
- }
15864
15869
  if (!this._directusPoolOverview) {
15865
- this._directusPoolOverview = yield this._directus.request(bs('PoolOverview', {
15866
- filter: {
15867
- enabled: {
15868
- _eq: true,
15869
- },
15870
- },
15871
- }));
15870
+ if (this._kasuConfig.directusUrl) {
15871
+ try {
15872
+ this._directusPoolOverview = yield this._directus.request(bs('PoolOverview', {
15873
+ filter: {
15874
+ enabled: {
15875
+ _eq: true,
15876
+ },
15877
+ },
15878
+ }));
15879
+ }
15880
+ catch (error) {
15881
+ console.warn('Directus fetch failed, falling back to on-chain data only:', error);
15882
+ this._directusPoolOverview = [];
15883
+ }
15884
+ }
15885
+ else {
15886
+ this._directusPoolOverview = [];
15887
+ }
15872
15888
  }
15873
15889
  const offchainTvlMap = yield this.getOffChainTvl(poolOverviewResults.lendingPools.map(({ id }) => id));
15874
15890
  const retn = [];
15875
15891
  for (const lendingPoolSubgraph of poolOverviewResults.lendingPools) {
15876
- const lendingPoolDirectus = this._directusPoolOverview.find((r) => r.id.toLowerCase() == lendingPoolSubgraph.id);
15892
+ // Use metadata mapping if available (for XDC/Plume pools that share metadata with Base)
15893
+ const metadataPoolId = (_a = this._kasuConfig.poolMetadataMapping[lendingPoolSubgraph.id]) !== null && _a !== void 0 ? _a : lendingPoolSubgraph.id;
15894
+ const lendingPoolDirectus = this._directusPoolOverview.find((r) => r.id.toLowerCase() === metadataPoolId);
15877
15895
  const lendingPoolConfig = lendingPoolSubgraph.configuration;
15878
15896
  if (!lendingPoolDirectus) {
15879
- console.warn("Couldn't find directus pool for id: ", lendingPoolSubgraph.id);
15880
- continue;
15897
+ console.warn("Couldn't find directus pool for id: ", lendingPoolSubgraph.id, metadataPoolId !== lendingPoolSubgraph.id
15898
+ ? `(mapped from ${metadataPoolId})`
15899
+ : '');
15900
+ // When Directus is unavailable or pool has no CMS entry,
15901
+ // use a fallback so the pool is still returned with on-chain data.
15881
15902
  }
15882
15903
  const poolCapacities = this.calculatePoolCapacity([], [], 0, 0, lendingPoolSubgraph, lendingPoolConfig);
15883
15904
  const tranches = lendingPoolSubgraph.tranches
@@ -15944,49 +15965,50 @@ class DataService {
15944
15965
  : parseFloat(tranche.balance) / trancheBalanceSum;
15945
15966
  averageApy += parseFloat(trancheData.averageApy) * weight;
15946
15967
  }
15947
- const plumeTvl = lendingPoolDirectus.plumeStrategy &&
15948
- this._plumeTvl.has(lendingPoolDirectus.plumeStrategy)
15949
- ? (_a = this._plumeTvl.get(lendingPoolDirectus.plumeStrategy)) !== null && _a !== void 0 ? _a : '0'
15950
- : '0';
15951
15968
  const offChainTvl = (_b = offchainTvlMap.get(lendingPoolSubgraph.id)) !== null && _b !== void 0 ? _b : '0';
15952
15969
  const poolOverview = {
15953
15970
  id: lendingPoolSubgraph.id,
15954
- security: lendingPoolDirectus.security,
15955
- enabled: lendingPoolDirectus.enabled,
15956
- isOversubscribed: lendingPoolDirectus.oversubscribed,
15971
+ security: (_c = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.security) !== null && _c !== void 0 ? _c : [],
15972
+ enabled: (_d = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.enabled) !== null && _d !== void 0 ? _d : true,
15973
+ isOversubscribed: (_e = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.oversubscribed) !== null && _e !== void 0 ? _e : false,
15957
15974
  apy: averageApy,
15958
- description: lendingPoolDirectus.description,
15959
- liteDescription: lendingPoolDirectus.liteDescription,
15960
- thumbnailImageUrl: this.getUrlFromFile(lendingPoolDirectus.thumbnailImage),
15961
- bannerImageUrl: this.getUrlFromFile(lendingPoolDirectus.bannerImage),
15962
- strategyDeckUrl: this.getUrlFromFile(lendingPoolDirectus.strategyDeck),
15963
- assetClass: lendingPoolDirectus.assetClass,
15964
- industryExposure: lendingPoolDirectus.industryExposure,
15965
- poolApyStructure: lendingPoolDirectus.poolApyStructure,
15966
- apyExpiryDate: lendingPoolDirectus.apyExpiryDate,
15967
- poolInvestmentTerm: lendingPoolDirectus.poolInvestmentTerm,
15968
- loanStructure: lendingPoolDirectus.loanStructure,
15969
- poolName: (_c = lendingPoolDirectus.poolName) !== null && _c !== void 0 ? _c : lendingPoolSubgraph.name,
15970
- subheading: lendingPoolDirectus.subheading,
15975
+ description: (_f = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.description) !== null && _f !== void 0 ? _f : '',
15976
+ liteDescription: (_g = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.liteDescription) !== null && _g !== void 0 ? _g : '',
15977
+ thumbnailImageUrl: (lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.thumbnailImage)
15978
+ ? this.getUrlFromFile(lendingPoolDirectus.thumbnailImage)
15979
+ : '',
15980
+ bannerImageUrl: (lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.bannerImage)
15981
+ ? this.getUrlFromFile(lendingPoolDirectus.bannerImage)
15982
+ : '',
15983
+ strategyDeckUrl: (lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.strategyDeck)
15984
+ ? this.getUrlFromFile(lendingPoolDirectus.strategyDeck)
15985
+ : '',
15986
+ assetClass: (_h = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.assetClass) !== null && _h !== void 0 ? _h : '',
15987
+ industryExposure: (_j = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.industryExposure) !== null && _j !== void 0 ? _j : '',
15988
+ poolApyStructure: (_k = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.poolApyStructure) !== null && _k !== void 0 ? _k : 'Variable',
15989
+ apyExpiryDate: (_l = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.apyExpiryDate) !== null && _l !== void 0 ? _l : null,
15990
+ poolInvestmentTerm: (_m = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.poolInvestmentTerm) !== null && _m !== void 0 ? _m : '',
15991
+ loanStructure: (_o = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.loanStructure) !== null && _o !== void 0 ? _o : '',
15992
+ poolName: (_p = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.poolName) !== null && _p !== void 0 ? _p : lendingPoolSubgraph.name,
15993
+ subheading: lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.subheading,
15971
15994
  totalValueLocked: {
15972
15995
  total: (parseFloat(lendingPoolSubgraph.balance) +
15973
- parseFloat(plumeTvl) +
15974
15996
  parseFloat(offChainTvl)).toString(),
15975
15997
  offchain: offChainTvl,
15976
- plume: plumeTvl,
15977
15998
  },
15978
- loansUnderManagement: lendingPoolDirectus.loansUnderManagement,
15999
+ loansUnderManagement: (_q = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.loansUnderManagement) !== null && _q !== void 0 ? _q : '0',
15979
16000
  yieldEarned: lendingPoolSubgraph.totalUserInterestAmount,
15980
16001
  poolCapacity: poolCapacitySum.toString(),
15981
16002
  poolCapacityPercentage: poolCapacityPercentageSum.toString(),
15982
- activeLoans: lendingPoolDirectus.activeLoans,
15983
- loanFundsOriginated: lendingPoolDirectus.loanFundsOriginated,
16003
+ activeLoans: (_r = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.activeLoans) !== null && _r !== void 0 ? _r : '0',
16004
+ loanFundsOriginated: (_s = lendingPoolDirectus === null || lendingPoolDirectus === void 0 ? void 0 : lendingPoolDirectus.loanFundsOriginated) !== null && _s !== void 0 ? _s : '0',
15984
16005
  tranches: tranches,
15985
16006
  isActive: !lendingPoolSubgraph.isStopped,
15986
16007
  requestEpochsInAdvance: lendingPoolSubgraph.configuration
15987
16008
  .lendingPoolWithdrawalConfig.requestEpochsInAdvance,
15988
16009
  };
15989
- // show only enabled pools from cms
16010
+ // When Directus is available, show only enabled pools.
16011
+ // When Directus is unavailable, include all pools.
15990
16012
  if (poolOverview.enabled) {
15991
16013
  retn.push(poolOverview);
15992
16014
  }
@@ -16206,7 +16228,11 @@ class DataService {
16206
16228
  const lendingPoolsWithdrawalsAndDepositsSubgraph = yield this._graph.request(getLendingPoolWithdrawalAndDepositsQuery, { unusedPools: this._kasuConfig.UNUSED_LENDING_POOL_IDS });
16207
16229
  const retn = [];
16208
16230
  for (const data of poolRepaymentDirectus) {
16209
- const lendingPoolSubgraph = lendingPoolsWithdrawalsAndDepositsSubgraph.lendingPools.find((pool) => pool.id == data.poolIdFK);
16231
+ // Find subgraph pool that maps to this Directus pool
16232
+ // On non-Base chains, subgraph pool IDs are different from Directus poolIdFK
16233
+ // Use getMetadataPoolId to map subgraph pool ID -> Directus/Base pool ID
16234
+ const lendingPoolSubgraph = lendingPoolsWithdrawalsAndDepositsSubgraph.lendingPools.find((pool) => this.getMetadataPoolId(pool.id) ===
16235
+ data.poolIdFK.toLowerCase());
16210
16236
  if (lendingPoolSubgraph === undefined) {
16211
16237
  continue;
16212
16238
  }
@@ -16295,9 +16321,13 @@ class DataService {
16295
16321
  retn.totalYieldEarned += parseFloat(poolOverview.yieldEarned);
16296
16322
  }
16297
16323
  for (const poolOverview of poolOverviews) {
16298
- const riskManagement = riskManagements.find((rm) => rm.poolIdFK.toLowerCase() === poolOverview.id.toLowerCase());
16324
+ // Map to metadata pool ID for Directus lookup (XDC pools → Base pools)
16325
+ const metadataPoolId = this.getMetadataPoolId(poolOverview.id);
16326
+ const riskManagement = riskManagements.find((rm) => rm.poolIdFK.toLowerCase() === metadataPoolId.toLowerCase());
16299
16327
  if (!riskManagement) {
16300
- console.warn("Couldn't find risk management for id: ", poolOverview.id);
16328
+ console.warn("Couldn't find risk management for id: ", poolOverview.id, metadataPoolId !== poolOverview.id
16329
+ ? `(mapped to ${metadataPoolId})`
16330
+ : '');
16301
16331
  continue;
16302
16332
  }
16303
16333
  const weight = retn.totalLoanFundsOriginated === 0
@@ -16335,14 +16365,18 @@ class DataService {
16335
16365
  }
16336
16366
 
16337
16367
  class KSULocking {
16338
- /**
16339
- *
16340
- */
16341
16368
  constructor(_kasuConfig, signerOrProvider) {
16342
16369
  this._kasuConfig = _kasuConfig;
16343
16370
  this.apyBonuses = [0, 0.001, 0.002];
16371
+ this._isLiteDeployment = _kasuConfig.isLiteDeployment;
16344
16372
  this._contractAbi = IKSULockingAbi__factory.connect(_kasuConfig.contracts.IKSULocking, signerOrProvider);
16345
- this._kasuToken = IERC20MetadataAbi__factory.connect(_kasuConfig.contracts.KSUToken, signerOrProvider);
16373
+ // Only initialize KSU token contract if not a Lite deployment and address is provided
16374
+ if (!this._isLiteDeployment && _kasuConfig.contracts.KSUToken) {
16375
+ this._kasuToken = IERC20MetadataAbi__factory.connect(_kasuConfig.contracts.KSUToken, signerOrProvider);
16376
+ }
16377
+ else {
16378
+ this._kasuToken = null;
16379
+ }
16346
16380
  this._userManagerAbi = IUserManagerAbi__factory.connect(_kasuConfig.contracts.UserManager, signerOrProvider);
16347
16381
  this._systemVariablesAbi = ISystemVariablesAbi__factory.connect(_kasuConfig.contracts.SystemVariables, signerOrProvider);
16348
16382
  this._ksuPriceAbi = IKsuPriceAbi__factory.connect(_kasuConfig.contracts.KsuPrice, signerOrProvider);
@@ -16350,13 +16384,25 @@ class KSULocking {
16350
16384
  this._graph = new GraphQLClient(_kasuConfig.subgraphUrl);
16351
16385
  this._userLoyaltyRewardsAbi = IUserLoyaltyRewardsAbi__factory.connect(_kasuConfig.contracts.UserLoyaltyRewards, signerOrProvider);
16352
16386
  }
16387
+ /**
16388
+ * Check if this is a Lite deployment (no KSU token functionality)
16389
+ */
16390
+ get isLiteDeployment() {
16391
+ return this._isLiteDeployment;
16392
+ }
16353
16393
  lockKSUTokens(amount, lockPeriod) {
16354
16394
  return __awaiter(this, void 0, void 0, function* () {
16395
+ if (this._isLiteDeployment) {
16396
+ throw new Error('Locking is not available on Lite deployments');
16397
+ }
16355
16398
  return this._contractAbi.lock(amount, lockPeriod);
16356
16399
  });
16357
16400
  }
16358
16401
  lockKSUWithPermit(amount, lockPeriod, permit) {
16359
16402
  return __awaiter(this, void 0, void 0, function* () {
16403
+ if (this._isLiteDeployment) {
16404
+ throw new Error('Locking is not available on Lite deployments');
16405
+ }
16360
16406
  const amountBN = ethers.BigNumber.from(amount);
16361
16407
  const lockPeriodBN = ethers.BigNumber.from(lockPeriod);
16362
16408
  const ksuPermit = {
@@ -16371,16 +16417,29 @@ class KSULocking {
16371
16417
  }
16372
16418
  unlockKSU(amount, userLockId) {
16373
16419
  return __awaiter(this, void 0, void 0, function* () {
16420
+ if (this._isLiteDeployment) {
16421
+ throw new Error('Locking is not available on Lite deployments');
16422
+ }
16374
16423
  return this._contractAbi.unlock(amount, userLockId);
16375
16424
  });
16376
16425
  }
16377
16426
  claimFees() {
16378
16427
  return __awaiter(this, void 0, void 0, function* () {
16428
+ if (this._isLiteDeployment) {
16429
+ throw new Error('Fee claiming is not available on Lite deployments');
16430
+ }
16379
16431
  return yield this._contractAbi.claimFees();
16380
16432
  });
16381
16433
  }
16382
16434
  lockDetails(lockPeriod) {
16383
16435
  return __awaiter(this, void 0, void 0, function* () {
16436
+ if (this._isLiteDeployment) {
16437
+ return {
16438
+ rKsuMultiplier: 0,
16439
+ ksuBonusMultiplier: 0,
16440
+ isActive: false,
16441
+ };
16442
+ }
16384
16443
  const result = yield this._contractAbi.lockDetails(lockPeriod);
16385
16444
  return {
16386
16445
  rKsuMultiplier: result[0].toNumber(),
@@ -16391,12 +16450,15 @@ class KSULocking {
16391
16450
  }
16392
16451
  userTotalDeposits(userAddress) {
16393
16452
  return __awaiter(this, void 0, void 0, function* () {
16453
+ if (this._isLiteDeployment) {
16454
+ return ethers.BigNumber.from(0);
16455
+ }
16394
16456
  return yield this._contractAbi.userTotalDeposits(userAddress);
16395
16457
  });
16396
16458
  }
16397
16459
  calculateUserLockProjectedProtocolFeeRewards(epochId, KSULocked, lockPeriod) {
16398
16460
  return __awaiter(this, void 0, void 0, function* () {
16399
- if (KSULocked === 0) {
16461
+ if (this._isLiteDeployment || KSULocked === 0) {
16400
16462
  return 0;
16401
16463
  }
16402
16464
  const lockingSummarySubgraph = yield this._graph.request(lockingSummariesQuery);
@@ -16442,6 +16504,9 @@ class KSULocking {
16442
16504
  }
16443
16505
  getUserLocks(userAddress) {
16444
16506
  return __awaiter(this, void 0, void 0, function* () {
16507
+ if (this._isLiteDeployment) {
16508
+ return [];
16509
+ }
16445
16510
  const result = yield this._graph.request(userLocksQuery, {
16446
16511
  userAddress: userAddress.toLowerCase(),
16447
16512
  });
@@ -16467,8 +16532,14 @@ class KSULocking {
16467
16532
  }
16468
16533
  getUserBonusData(userAddress) {
16469
16534
  return __awaiter(this, void 0, void 0, function* () {
16470
- // TODO this userLocks query is kinda bad -> change to userLocksDepositInfo as u never need user locks by themselves
16471
- // whole function takes between 500 - 800ms
16535
+ if (this._isLiteDeployment) {
16536
+ return {
16537
+ ksuBonusAndRewards: '0',
16538
+ ksuBonusAndRewardsLifetime: '0',
16539
+ protocolFeesEarned: '0',
16540
+ totalLockedAmount: '0',
16541
+ };
16542
+ }
16472
16543
  const DECIMALS = 18;
16473
16544
  // Normalized user address
16474
16545
  const normalizedAddress = userAddress.toLowerCase();
@@ -16501,6 +16572,10 @@ class KSULocking {
16501
16572
  });
16502
16573
  }
16503
16574
  getLoyaltyLevelAndApyBonusFromRatio(rKSUtoUSDCRatio) {
16575
+ // On Lite deployments, always return level 0 with no bonus
16576
+ if (this._isLiteDeployment) {
16577
+ return { loyaltyLevel: 0, apyBonus: 0 };
16578
+ }
16504
16579
  if (rKSUtoUSDCRatio < 0.01) {
16505
16580
  return { loyaltyLevel: 0, apyBonus: this.apyBonuses[0] };
16506
16581
  }
@@ -16511,6 +16586,9 @@ class KSULocking {
16511
16586
  }
16512
16587
  getRKSUvsUSDCRatio(rKSUAmount, userAddress) {
16513
16588
  return __awaiter(this, void 0, void 0, function* () {
16589
+ if (this._isLiteDeployment) {
16590
+ return 0;
16591
+ }
16514
16592
  const [depositedAmount, pendingAmount] = yield this._userManagerAbi.userTotalPendingAndActiveDepositedAmountForCurrentEpoch(userAddress);
16515
16593
  const ksuPrice = yield this._systemVariablesAbi.ksuEpochTokenPrice();
16516
16594
  const rKSUAmountBignumber = ethers.ethers.utils.parseUnits(rKSUAmount, 18);
@@ -16524,6 +16602,9 @@ class KSULocking {
16524
16602
  }
16525
16603
  getClaimableRewards(userAddress) {
16526
16604
  return __awaiter(this, void 0, void 0, function* () {
16605
+ if (this._isLiteDeployment) {
16606
+ return ethers.BigNumber.from(0);
16607
+ }
16527
16608
  const result = yield this._contractAbi.rewards(userAddress);
16528
16609
  return result;
16529
16610
  });
@@ -16531,6 +16612,7 @@ class KSULocking {
16531
16612
  getKasuTokenPrice() {
16532
16613
  return __awaiter(this, void 0, void 0, function* () {
16533
16614
  const decimals = 18;
16615
+ // Price can still be queried on Lite deployments (set to 0 or configured value)
16534
16616
  return Promise.resolve({
16535
16617
  price: yield this._ksuPriceAbi.ksuTokenPrice(),
16536
16618
  decimals,
@@ -16549,6 +16631,9 @@ class KSULocking {
16549
16631
  getLifetimeRewards(userAddress, rewardDecimals, claimableRewards) {
16550
16632
  return __awaiter(this, void 0, void 0, function* () {
16551
16633
  var _a, _b;
16634
+ if (this._isLiteDeployment) {
16635
+ return ethers.BigNumber.from(0);
16636
+ }
16552
16637
  const result = yield this._graph.request(claimedFeesQuery, {
16553
16638
  userAddress: userAddress.toLowerCase(),
16554
16639
  });
@@ -16560,6 +16645,9 @@ class KSULocking {
16560
16645
  });
16561
16646
  }
16562
16647
  getLaunchBonusAmount(lockAmount, bonusMultiplier, bonusTokensLeft) {
16648
+ if (this._isLiteDeployment) {
16649
+ return ethers.BigNumber.from(0);
16650
+ }
16563
16651
  const bonusMultiplierBN = ethers.ethers.utils.parseUnits(bonusMultiplier.toFixed(2), 2);
16564
16652
  const projectedBonus = lockAmount.mul(bonusMultiplierBN).div(100);
16565
16653
  if (bonusTokensLeft.gt(projectedBonus)) {
@@ -16571,6 +16659,9 @@ class KSULocking {
16571
16659
  }
16572
16660
  getUserStakedKsu(userAddress) {
16573
16661
  return __awaiter(this, void 0, void 0, function* () {
16662
+ if (this._isLiteDeployment) {
16663
+ return '0';
16664
+ }
16574
16665
  const result = yield this._graph.request(userStakedKsuQuery, {
16575
16666
  userAddress: userAddress.toLowerCase(),
16576
16667
  });
@@ -16582,6 +16673,9 @@ class KSULocking {
16582
16673
  }
16583
16674
  getUserEarnedrKsu(userAddress) {
16584
16675
  return __awaiter(this, void 0, void 0, function* () {
16676
+ if (this._isLiteDeployment) {
16677
+ return '0';
16678
+ }
16585
16679
  const result = yield this._graph.request(userEarnedrKsuQuery, {
16586
16680
  userAddress: userAddress.toLowerCase(),
16587
16681
  });
@@ -16593,6 +16687,9 @@ class KSULocking {
16593
16687
  }
16594
16688
  getUserTotalBonusAmount(userAddress) {
16595
16689
  return __awaiter(this, void 0, void 0, function* () {
16690
+ if (this._isLiteDeployment) {
16691
+ return '0';
16692
+ }
16596
16693
  const result = yield this._graph.request(userTotalBonusAmountQuery, {
16597
16694
  userAddress: userAddress.toLowerCase(),
16598
16695
  });
@@ -16604,6 +16701,12 @@ class KSULocking {
16604
16701
  }
16605
16702
  getLockingRewards(userAddress) {
16606
16703
  return __awaiter(this, void 0, void 0, function* () {
16704
+ if (this._isLiteDeployment) {
16705
+ return {
16706
+ claimableRewards: '0',
16707
+ lifeTimeRewards: '0',
16708
+ };
16709
+ }
16607
16710
  const rewardDecimals = 6;
16608
16711
  const claimableRewards = yield this.getClaimableRewards(userAddress);
16609
16712
  const lifeTimeRewards = yield this.getLifetimeRewards(userAddress, rewardDecimals, claimableRewards);
@@ -16620,12 +16723,18 @@ class KSULocking {
16620
16723
  }
16621
16724
  getAvailableKsuBonus() {
16622
16725
  return __awaiter(this, void 0, void 0, function* () {
16726
+ if (this._isLiteDeployment || !this._kasuToken) {
16727
+ return '0';
16728
+ }
16623
16729
  const amount = yield this._kasuToken.balanceOf(this._kasuBonusAddress);
16624
16730
  return utils$2.formatEther(amount);
16625
16731
  });
16626
16732
  }
16627
16733
  getUserKsuBalance(userAddress) {
16628
16734
  return __awaiter(this, void 0, void 0, function* () {
16735
+ if (this._isLiteDeployment || !this._kasuToken) {
16736
+ return '0';
16737
+ }
16629
16738
  const balance = yield this._kasuToken.balanceOf(userAddress.toLowerCase());
16630
16739
  return utils$2.formatEther(balance);
16631
16740
  });
@@ -16652,6 +16761,9 @@ class KSULocking {
16652
16761
  }
16653
16762
  getActiveLockPeriods() {
16654
16763
  return __awaiter(this, void 0, void 0, function* () {
16764
+ if (this._isLiteDeployment) {
16765
+ return [];
16766
+ }
16655
16767
  const data = yield this._graph.request(lockingPeriodsQuery);
16656
16768
  return data.lockPeriods;
16657
16769
  });
@@ -16664,6 +16776,14 @@ class KSULocking {
16664
16776
  }
16665
16777
  }
16666
16778
 
16779
+ /**
16780
+ * Check if the SDK is configured for a Lite deployment.
16781
+ * Lite deployments don't have KSU token, locking, or loyalty features.
16782
+ */
16783
+ function isLiteDeployment(config) {
16784
+ return config.isLiteDeployment;
16785
+ }
16786
+
16667
16787
  const USER_REQUEST_EVENT_MAP = {
16668
16788
  DepositAccepted: 'Accepted',
16669
16789
  DepositCancelled: 'Cancelled',
@@ -17516,7 +17636,10 @@ class Portfolio {
17516
17636
  this._systemVariablesAbi = ISystemVariablesAbi__factory.connect(_kasuConfig.contracts.SystemVariables, signerOrProvider);
17517
17637
  this._userLoyaltyRewardsAbi = IUserLoyaltyRewardsAbi__factory.connect(_kasuConfig.contracts.UserLoyaltyRewards, signerOrProvider);
17518
17638
  this._userLendingService = new UserLending(_kasuConfig, signerOrProvider);
17519
- this._kasuNftContract = IKasuNFTsAbi__factory.connect(_kasuConfig.contracts.KasuNFTs, signerOrProvider);
17639
+ this._isLiteDeployment = isLiteDeployment(_kasuConfig);
17640
+ this._kasuNftContract = _kasuConfig.contracts.KasuNFTs
17641
+ ? IKasuNFTsAbi__factory.connect(_kasuConfig.contracts.KasuNFTs, signerOrProvider)
17642
+ : null;
17520
17643
  this._graph = new GraphQLClient(_kasuConfig.subgraphUrl);
17521
17644
  }
17522
17645
  computeYieldMetrics(portfolioLendingPools) {
@@ -17644,6 +17767,10 @@ class Portfolio {
17644
17767
  }
17645
17768
  getUserNfts(userAddress) {
17646
17769
  return __awaiter(this, void 0, void 0, function* () {
17770
+ // NFTs are not available on Lite deployments
17771
+ if (this._isLiteDeployment || !this._kasuNftContract) {
17772
+ return [];
17773
+ }
17647
17774
  const usernfts = yield this._kasuNftContract.tokensOfOwner(userAddress);
17648
17775
  return usernfts.map((nft) => nft.toNumber());
17649
17776
  });
@@ -21744,4 +21871,426 @@ class KasuSdk {
21744
21871
  }
21745
21872
  }
21746
21873
 
21874
+ class SdkConfig {
21875
+ constructor(options) {
21876
+ var _a, _b, _c;
21877
+ this.subgraphUrl = options.subgraphUrl;
21878
+ this.contracts = options.contracts;
21879
+ this.directusUrl = (_a = options.directusUrl) !== null && _a !== void 0 ? _a : '';
21880
+ this.UNUSED_LENDING_POOL_IDS = options.UNUSED_LENDING_POOL_IDS;
21881
+ this.isLiteDeployment = (_b = options.isLiteDeployment) !== null && _b !== void 0 ? _b : false;
21882
+ this.poolMetadataMapping = (_c = options.poolMetadataMapping) !== null && _c !== void 0 ? _c : {};
21883
+ }
21884
+ }
21885
+
21886
+ /**
21887
+ * Built-in chain configurations for Kasu-supported networks.
21888
+ *
21889
+ * Usage:
21890
+ * ```ts
21891
+ * import { CHAIN_CONFIGS } from '@kasufinance/kasu-sdk';
21892
+ * const base = CHAIN_CONFIGS.base;
21893
+ * ```
21894
+ */
21895
+ const CHAIN_CONFIGS = {
21896
+ base: {
21897
+ chainId: 8453,
21898
+ name: 'Base Mainnet',
21899
+ isLiteDeployment: false,
21900
+ contracts: {
21901
+ KSUToken: '0x5D9b878744dbe721a3f33A60a6b102E289CeADBA',
21902
+ IKSULocking: '0xB145C061684C701c2C018A3f322aa14F5A553CE1',
21903
+ IKSULockBonus: '0xEEDE30AcF16caFf49c1a48F75185C67Be2e20B40',
21904
+ LendingPoolManager: '0xE1Be322323a412579b4A09fB08ff4bfcA12096B5',
21905
+ UserManager: '0x5Dc8D315a80fd99AbEF0f327B9a52a3FBC3C93f3',
21906
+ KasuAllowList: '0x807A7e119EBf0282420b5Ca0e0056c0525cBf8BB',
21907
+ SystemVariables: '0x193Bb02A24F5562b58fEB86550e6f09Bb6c41f69',
21908
+ KsuPrice: '0x221a54CbbD5f490Bd8e77CF36acBA4B1304E5c1b',
21909
+ UserLoyaltyRewards: '0xB4784f69Bb1F1076F50907cB0a815908a719D635',
21910
+ ClearingCoordinator: '0x2cF12A6d91fa4bEB5a4C17589a03e78F88f57DE2',
21911
+ KasuNFTs: '0x4946fF5f1a6550524C425479022D50446AA2968E',
21912
+ ExternalTVL: '0x662379FEBb3e4F91400B5f7d4f7F7ce4699F3c9F',
21913
+ },
21914
+ subgraphUrl: 'https://api.goldsky.com/api/public/project_cmgzlpxm300765np2a19421om/subgraphs/kasu-base/v1.0.13/gn',
21915
+ directusUrl: 'https://kasu-finance.directus.app/',
21916
+ unusedPoolIds: [],
21917
+ poolMetadataMapping: undefined,
21918
+ },
21919
+ xdc: {
21920
+ chainId: 50,
21921
+ name: 'XDC Mainnet',
21922
+ isLiteDeployment: true,
21923
+ contracts: {
21924
+ // No KSUToken on Lite deployments
21925
+ IKSULocking: '0x7fF469f8c5fba92A9051B8D28794CBb891760e81',
21926
+ IKSULockBonus: '0x7cc1434EfA50301Fdd56B7c5c6fF7e30Dc20C55c',
21927
+ LendingPoolManager: '0xa46143db92aBe5bB1f61d13d8C1cCd50fc40Ca10',
21928
+ UserManager: '0x9b57dF89e59235f0481A5Fae942302c8831e1B81',
21929
+ KasuAllowList: '0x32c1Ff5FbBe6D28503ddc46E5001C0D13d6E9B2A',
21930
+ SystemVariables: '0x34d17c9DD1f31Fb34757DE923EC083601d0eDFFe',
21931
+ KsuPrice: '0x666b589933965bF8B378eD973f0404b6cae0eb52',
21932
+ UserLoyaltyRewards: '0xb95834C5610A178be9065Dd1EF78258D29879CDb',
21933
+ ClearingCoordinator: '0xAF0a66953Eba1c5353eB7425b398B213Bb2c6121',
21934
+ // No KasuNFTs on Lite deployments
21935
+ ExternalTVL: '0xCCB4156964377CF36441f3775A2A800dbeCB8094',
21936
+ },
21937
+ subgraphUrl: 'https://api.goldsky.com/api/public/project_cmgzlpxm300765np2a19421om/subgraphs/kasu-xdc/v1.0.0/gn',
21938
+ directusUrl: 'https://kasu-finance.directus.app/',
21939
+ unusedPoolIds: [],
21940
+ poolMetadataMapping: {
21941
+ '0x20f42fb45f91657acf9528b99a5a16d0229c7800': '0xc987350716fe4a7d674c3591c391d29eba26b8ce',
21942
+ '0x3b7cb493aa22f731db2ab424d918e7375e00f6a9': '0x03f93c8caa9a82e000d35673ba34a4c0e6e117a2',
21943
+ '0xeda50c91a8c4ca8a83652b8542c0b3bd00a71fad': '0xc347a9e4aec8c8d11a149d2907deb2bf23b81c6f',
21944
+ },
21945
+ },
21946
+ plume: {
21947
+ chainId: 98866,
21948
+ name: 'Plume Mainnet',
21949
+ isLiteDeployment: true,
21950
+ contracts: {
21951
+ // Placeholder — update when Plume contracts are deployed
21952
+ IKSULocking: '',
21953
+ IKSULockBonus: '',
21954
+ LendingPoolManager: '',
21955
+ UserManager: '',
21956
+ KasuAllowList: '',
21957
+ SystemVariables: '',
21958
+ KsuPrice: '',
21959
+ UserLoyaltyRewards: '',
21960
+ ClearingCoordinator: '',
21961
+ ExternalTVL: '',
21962
+ },
21963
+ subgraphUrl: 'https://api.goldsky.com/api/public/project_cmgzlpxm300765np2a19421om/subgraphs/kasu-plume/prod',
21964
+ directusUrl: 'https://kasu-finance.directus.app/',
21965
+ unusedPoolIds: [],
21966
+ poolMetadataMapping: undefined,
21967
+ },
21968
+ };
21969
+
21970
+ /**
21971
+ * High-level facade for deposit and withdrawal operations.
21972
+ *
21973
+ * Integrators use this to submit on-chain transactions without
21974
+ * worrying about internal encoding details.
21975
+ */
21976
+ class DepositsFacade {
21977
+ constructor(_userLending, _chainId) {
21978
+ this._userLending = _userLending;
21979
+ this._chainId = _chainId;
21980
+ }
21981
+ /**
21982
+ * Submit a deposit request.
21983
+ *
21984
+ * The integrator must first obtain a KYC signature via the Nexera flow
21985
+ * using the params from `buildKycParams()`.
21986
+ *
21987
+ * ```ts
21988
+ * const kycParams = kasu.deposits.buildKycParams('0xUser...');
21989
+ * // ... obtain kycSignature from your backend via Nexera ...
21990
+ * const tx = await kasu.deposits.deposit({
21991
+ * poolId: '0x...',
21992
+ * trancheId: '0x...',
21993
+ * amount: parseUnits('1000', 6),
21994
+ * kycSignature: { blockExpiration, signature },
21995
+ * });
21996
+ * ```
21997
+ */
21998
+ deposit(params) {
21999
+ return __awaiter(this, void 0, void 0, function* () {
22000
+ var _a, _b, _c, _d;
22001
+ 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');
22002
+ });
22003
+ }
22004
+ /**
22005
+ * Submit a withdrawal request for a specific USDC amount.
22006
+ */
22007
+ withdraw(params) {
22008
+ return __awaiter(this, void 0, void 0, function* () {
22009
+ return yield this._userLending.requestWithdrawalInUSDC(params.poolId, params.trancheId, params.amount);
22010
+ });
22011
+ }
22012
+ /**
22013
+ * Withdraw the entire balance from a tranche.
22014
+ */
22015
+ withdrawMax(poolId, trancheId, userAddress) {
22016
+ return __awaiter(this, void 0, void 0, function* () {
22017
+ return yield this._userLending.requestWithdrawalMax(poolId, trancheId, userAddress);
22018
+ });
22019
+ }
22020
+ /**
22021
+ * Build KYC signature parameters for the Nexera verification flow.
22022
+ *
22023
+ * The integrator is responsible for sending these to their backend,
22024
+ * which obtains the signature from Nexera's signing service.
22025
+ */
22026
+ buildKycParams(userAddress) {
22027
+ return this._userLending.buildKycSignatureParams(userAddress, this._chainId);
22028
+ }
22029
+ /**
22030
+ * Check whether the pool is currently in a clearing period
22031
+ * (deposits/withdrawals are temporarily paused).
22032
+ */
22033
+ isClearingPending(poolId) {
22034
+ return __awaiter(this, void 0, void 0, function* () {
22035
+ return yield this._userLending.isClearingPending(poolId);
22036
+ });
22037
+ }
22038
+ /**
22039
+ * Get the current epoch number.
22040
+ */
22041
+ getCurrentEpoch() {
22042
+ return __awaiter(this, void 0, void 0, function* () {
22043
+ return yield this._userLending.getCurrentEpoch();
22044
+ });
22045
+ }
22046
+ }
22047
+
22048
+ /**
22049
+ * High-level facade for browsing Kasu lending strategies (pools).
22050
+ *
22051
+ * Handles epoch fetching internally so callers never need to know about epochs.
22052
+ */
22053
+ class StrategiesFacade {
22054
+ constructor(_dataService, _userLending) {
22055
+ this._dataService = _dataService;
22056
+ this._userLending = _userLending;
22057
+ }
22058
+ /**
22059
+ * Fetch all active lending strategies.
22060
+ *
22061
+ * ```ts
22062
+ * const strategies = await kasu.strategies.getAll();
22063
+ * ```
22064
+ */
22065
+ getAll(poolIds) {
22066
+ return __awaiter(this, void 0, void 0, function* () {
22067
+ const epochId = yield this._userLending.getCurrentEpoch();
22068
+ const pools = yield this._dataService.getPoolOverview(epochId, poolIds);
22069
+ return pools.map((pool) => this.mapPoolToStrategy(pool));
22070
+ });
22071
+ }
22072
+ /**
22073
+ * Fetch a single strategy by pool ID. Returns `null` if not found.
22074
+ */
22075
+ getById(poolId) {
22076
+ return __awaiter(this, void 0, void 0, function* () {
22077
+ var _a;
22078
+ const results = yield this.getAll([poolId]);
22079
+ return (_a = results[0]) !== null && _a !== void 0 ? _a : null;
22080
+ });
22081
+ }
22082
+ /**
22083
+ * Aggregate platform statistics (TVL, loans, yield, loss rate).
22084
+ */
22085
+ getPlatformStats() {
22086
+ return __awaiter(this, void 0, void 0, function* () {
22087
+ const epochId = yield this._userLending.getCurrentEpoch();
22088
+ const pools = yield this._dataService.getPoolOverview(epochId);
22089
+ return yield this._dataService.getLendingTotals(pools);
22090
+ });
22091
+ }
22092
+ /**
22093
+ * Calculate deposit limits for a specific tranche.
22094
+ *
22095
+ * @param tranche - A `StrategyTranche` from `getAll()` or `getById()`.
22096
+ * @returns min/max/capacity in ether-formatted USDC strings.
22097
+ */
22098
+ calculateDepositLimits(tranche) {
22099
+ const raw = tranche._raw;
22100
+ const min = parseFloat(raw.minimumDeposit) < 1
22101
+ ? '1'
22102
+ : raw.minimumDeposit;
22103
+ const max = parseFloat(raw.maximumDeposit) > parseFloat(raw.poolCapacity)
22104
+ ? raw.poolCapacity
22105
+ : raw.maximumDeposit;
22106
+ return {
22107
+ min,
22108
+ max,
22109
+ availableCapacity: raw.poolCapacity,
22110
+ };
22111
+ }
22112
+ // ------------------------------------------------------------------
22113
+ // Private helpers
22114
+ // ------------------------------------------------------------------
22115
+ mapPoolToStrategy(pool) {
22116
+ const tranches = pool.tranches.map((t) => ({
22117
+ id: t.id,
22118
+ name: t.name,
22119
+ apy: parseFloat(t.apy),
22120
+ minApy: parseFloat(t.minApy),
22121
+ maxApy: parseFloat(t.maxApy),
22122
+ minimumDeposit: t.minimumDeposit,
22123
+ maximumDeposit: t.maximumDeposit,
22124
+ availableCapacity: t.poolCapacity,
22125
+ fixedTermOptions: t.fixedTermConfig.map((ftd) => ({
22126
+ configId: ftd.configId,
22127
+ apy: parseFloat(ftd.apy),
22128
+ epochLockDuration: ftd.epochLockDuration,
22129
+ })),
22130
+ _raw: t,
22131
+ }));
22132
+ return {
22133
+ id: pool.id,
22134
+ name: pool.poolName,
22135
+ description: pool.description,
22136
+ isActive: pool.isActive,
22137
+ apy: pool.apy,
22138
+ tvl: pool.totalValueLocked,
22139
+ availableCapacity: pool.poolCapacity,
22140
+ capacityUtilisation: pool.poolCapacityPercentage,
22141
+ tranches,
22142
+ assetClass: pool.assetClass,
22143
+ apyStructure: pool.poolApyStructure,
22144
+ thumbnailUrl: pool.thumbnailImageUrl,
22145
+ bannerUrl: pool.bannerImageUrl,
22146
+ _raw: pool,
22147
+ };
22148
+ }
22149
+ }
22150
+
22151
+ /**
22152
+ * High-level facade for querying a user's portfolio, positions, and history.
22153
+ *
22154
+ * Orchestrates DataService, UserLending, and Portfolio services so the caller
22155
+ * only needs to provide a wallet address.
22156
+ */
22157
+ class PortfolioFacade {
22158
+ constructor(_dataService, _userLending, _portfolio) {
22159
+ this._dataService = _dataService;
22160
+ this._userLending = _userLending;
22161
+ this._portfolio = _portfolio;
22162
+ }
22163
+ /**
22164
+ * Fetch a user's complete portfolio: per-pool positions and aggregate summary.
22165
+ *
22166
+ * ```ts
22167
+ * const positions = await kasu.portfolio.getPositions('0xUser...');
22168
+ * console.log(positions.summary.current.totalLendingPoolInvestments);
22169
+ * ```
22170
+ *
22171
+ * @param userAddress - Wallet address.
22172
+ * @param provider - Optional separate provider for balance queries (useful when the
22173
+ * SDK was initialised with a Signer but you need a read-only provider).
22174
+ */
22175
+ getPositions(userAddress, provider) {
22176
+ return __awaiter(this, void 0, void 0, function* () {
22177
+ const currentEpoch = yield this._userLending.getCurrentEpoch();
22178
+ const poolOverviews = yield this._dataService.getPoolOverview(currentEpoch);
22179
+ const pools = yield this._portfolio.getPortfolioLendingData(userAddress, poolOverviews, currentEpoch, provider);
22180
+ const summary = yield this._portfolio.getPortfolioSummary(userAddress, pools, currentEpoch);
22181
+ return { pools, summary };
22182
+ });
22183
+ }
22184
+ /**
22185
+ * Fetch a user's full transaction history (deposits, withdrawals, cancellations).
22186
+ */
22187
+ getTransactionHistory(userAddress) {
22188
+ return __awaiter(this, void 0, void 0, function* () {
22189
+ const currentEpoch = yield this._userLending.getCurrentEpoch();
22190
+ return yield this._userLending.getUserRequests(userAddress, currentEpoch);
22191
+ });
22192
+ }
22193
+ }
22194
+
22195
+ /**
22196
+ * High-level entry point for external integrators.
22197
+ *
22198
+ * Provides three domain facades — `strategies`, `deposits`, `portfolio` — and
22199
+ * exposes the underlying `KasuSdk` services via `.services` for power-users.
22200
+ *
22201
+ * ```ts
22202
+ * import { Kasu } from '@kasufinance/kasu-sdk';
22203
+ *
22204
+ * const kasu = Kasu.create({ chain: 'base', signerOrProvider: provider });
22205
+ *
22206
+ * // Browse strategies
22207
+ * const strategies = await kasu.strategies.getAll();
22208
+ *
22209
+ * // Deposit
22210
+ * const tx = await kasu.deposits.deposit({ poolId, trancheId, amount, kycSignature });
22211
+ *
22212
+ * // User positions
22213
+ * const positions = await kasu.portfolio.getPositions(userAddress);
22214
+ * ```
22215
+ */
22216
+ class Kasu {
22217
+ constructor(sdk, chainConfig) {
22218
+ this._sdk = sdk;
22219
+ this._chainConfig = chainConfig;
22220
+ this.strategies = new StrategiesFacade(sdk.DataService, sdk.UserLending);
22221
+ this.deposits = new DepositsFacade(sdk.UserLending, chainConfig.chainId.toString());
22222
+ this.portfolio = new PortfolioFacade(sdk.DataService, sdk.UserLending, sdk.Portfolio);
22223
+ }
22224
+ /**
22225
+ * Create a Kasu instance with built-in chain config.
22226
+ *
22227
+ * ```ts
22228
+ * // Minimal setup — uses built-in Base mainnet config
22229
+ * const kasu = Kasu.create({ chain: 'base', signerOrProvider: provider });
22230
+ *
22231
+ * // Custom config override
22232
+ * const kasu = Kasu.create({
22233
+ * chain: 'base',
22234
+ * signerOrProvider: signer,
22235
+ * configOverrides: { UNUSED_LENDING_POOL_IDS: ['0x...'] },
22236
+ * });
22237
+ *
22238
+ * // Fully custom chain
22239
+ * const kasu = Kasu.create({
22240
+ * chain: { chainId: 123, name: 'MyChain', ... },
22241
+ * signerOrProvider: provider,
22242
+ * });
22243
+ * ```
22244
+ */
22245
+ static create(options) {
22246
+ var _a, _b, _c, _d, _e, _f, _g;
22247
+ const chainConfig = resolveChainConfig(options.chain);
22248
+ const overrides = (_a = options.configOverrides) !== null && _a !== void 0 ? _a : {};
22249
+ const sdkConfig = new SdkConfig({
22250
+ subgraphUrl: (_b = overrides.subgraphUrl) !== null && _b !== void 0 ? _b : chainConfig.subgraphUrl,
22251
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
22252
+ contracts: (_c = overrides.contracts) !== null && _c !== void 0 ? _c : chainConfig.contracts,
22253
+ directusUrl: (_d = overrides.directusUrl) !== null && _d !== void 0 ? _d : chainConfig.directusUrl,
22254
+ UNUSED_LENDING_POOL_IDS: (_e = overrides.UNUSED_LENDING_POOL_IDS) !== null && _e !== void 0 ? _e : chainConfig.unusedPoolIds,
22255
+ isLiteDeployment: (_f = overrides.isLiteDeployment) !== null && _f !== void 0 ? _f : chainConfig.isLiteDeployment,
22256
+ poolMetadataMapping: (_g = overrides.poolMetadataMapping) !== null && _g !== void 0 ? _g : chainConfig.poolMetadataMapping,
22257
+ });
22258
+ const sdk = new KasuSdk(sdkConfig, options.signerOrProvider);
22259
+ return new Kasu(sdk, chainConfig);
22260
+ }
22261
+ /**
22262
+ * Access the underlying `KasuSdk` services for advanced use cases.
22263
+ *
22264
+ * ```ts
22265
+ * const locks = await kasu.services.Locking.getUserLocks(address);
22266
+ * ```
22267
+ */
22268
+ get services() {
22269
+ return this._sdk;
22270
+ }
22271
+ /** The resolved chain configuration. */
22272
+ get chainConfig() {
22273
+ return this._chainConfig;
22274
+ }
22275
+ /** Whether this deployment has KSU token / locking features. */
22276
+ get isLiteDeployment() {
22277
+ return this._chainConfig.isLiteDeployment;
22278
+ }
22279
+ }
22280
+ // ---------------------------------------------------------------------------
22281
+ // Helpers
22282
+ // ---------------------------------------------------------------------------
22283
+ function resolveChainConfig(chain) {
22284
+ if (typeof chain === 'string') {
22285
+ return CHAIN_CONFIGS[chain];
22286
+ }
22287
+ return chain;
22288
+ }
22289
+
22290
+ exports.CHAIN_CONFIGS = CHAIN_CONFIGS;
22291
+ exports.DepositsFacade = DepositsFacade;
22292
+ exports.Kasu = Kasu;
21747
22293
  exports.KasuSdk = KasuSdk;
22294
+ exports.PortfolioFacade = PortfolioFacade;
22295
+ exports.SdkConfig = SdkConfig;
22296
+ exports.StrategiesFacade = StrategiesFacade;