@t2000/sdk 0.17.16 → 0.17.18

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.
@@ -352,6 +352,7 @@ interface AutoInvestRunResult {
352
352
  }
353
353
  interface PendingReward$1 {
354
354
  protocol: string;
355
+ asset: string;
355
356
  coinType: string;
356
357
  symbol: string;
357
358
  amount: number;
@@ -362,6 +363,7 @@ interface ClaimRewardsResult {
362
363
  tx: string;
363
364
  rewards: PendingReward$1[];
364
365
  totalValueUsd: number;
366
+ usdcReceived: number;
365
367
  gasCost: number;
366
368
  gasMethod: GasMethod;
367
369
  }
@@ -506,6 +508,7 @@ interface LendingAdapter {
506
508
  }
507
509
  interface PendingReward {
508
510
  protocol: string;
511
+ asset: string;
509
512
  coinType: string;
510
513
  symbol: string;
511
514
  amount: number;
@@ -352,6 +352,7 @@ interface AutoInvestRunResult {
352
352
  }
353
353
  interface PendingReward$1 {
354
354
  protocol: string;
355
+ asset: string;
355
356
  coinType: string;
356
357
  symbol: string;
357
358
  amount: number;
@@ -362,6 +363,7 @@ interface ClaimRewardsResult {
362
363
  tx: string;
363
364
  rewards: PendingReward$1[];
364
365
  totalValueUsd: number;
366
+ usdcReceived: number;
365
367
  gasCost: number;
366
368
  gasMethod: GasMethod;
367
369
  }
@@ -506,6 +508,7 @@ interface LendingAdapter {
506
508
  }
507
509
  interface PendingReward {
508
510
  protocol: string;
511
+ asset: string;
509
512
  coinType: string;
510
513
  symbol: string;
511
514
  amount: number;
package/dist/index.cjs CHANGED
@@ -1246,15 +1246,13 @@ function stripPrefix(coinType) {
1246
1246
  return coinType.replace(/^0x0*/, "");
1247
1247
  }
1248
1248
  async function getPendingRewards(client, address) {
1249
- const [pools, states, rules] = await Promise.all([
1249
+ const [pools, states] = await Promise.all([
1250
1250
  getPools(),
1251
- getUserState(client, address),
1252
- getIncentiveRules(client)
1251
+ getUserState(client, address)
1253
1252
  ]);
1254
1253
  const rewards = [];
1255
1254
  const deposited = states.filter((s) => s.supplyBalance > 0n);
1256
1255
  if (deposited.length === 0) return rewards;
1257
- const rewardTotals = /* @__PURE__ */ new Map();
1258
1256
  for (const state of deposited) {
1259
1257
  const pool = pools.find((p) => p.id === state.assetId);
1260
1258
  if (!pool) continue;
@@ -1263,20 +1261,14 @@ async function getPendingRewards(client, address) {
1263
1261
  const rewardCoins = pool.supplyIncentiveApyInfo?.rewardCoin;
1264
1262
  if (!Array.isArray(rewardCoins) || rewardCoins.length === 0) continue;
1265
1263
  const rewardType = rewardCoins[0];
1266
- const supplyBal = compoundBalance(state.supplyBalance, pool.currentSupplyIndex, pool);
1267
- const price = pool.token?.price ?? 0;
1268
- const depositUsd = supplyBal * price;
1269
- const annualRewardUsd = depositUsd * (boostedApr / 100);
1270
- const estimatedUsd = annualRewardUsd / 365;
1271
- rewardTotals.set(rewardType, (rewardTotals.get(rewardType) ?? 0) + estimatedUsd);
1272
- }
1273
- for (const [coinType, dailyUsd] of rewardTotals) {
1264
+ const assetSymbol = resolvePoolSymbol(pool);
1274
1265
  rewards.push({
1275
1266
  protocol: "navi",
1276
- coinType,
1277
- symbol: REWARD_SYMBOLS[coinType] ?? coinType.split("::").pop() ?? "UNKNOWN",
1267
+ asset: assetSymbol,
1268
+ coinType: rewardType,
1269
+ symbol: REWARD_SYMBOLS[rewardType] ?? rewardType.split("::").pop() ?? "UNKNOWN",
1278
1270
  amount: 0,
1279
- estimatedValueUsd: dailyUsd
1271
+ estimatedValueUsd: 0
1280
1272
  });
1281
1273
  }
1282
1274
  return rewards;
@@ -1337,6 +1329,7 @@ async function addClaimRewardsToTx(tx, client, address) {
1337
1329
  tx.transferObjects([coin], address);
1338
1330
  claimed.push({
1339
1331
  protocol: "navi",
1332
+ asset: assets.join(", "),
1340
1333
  coinType: rewardType,
1341
1334
  symbol: REWARD_SYMBOLS[rewardType] ?? "UNKNOWN",
1342
1335
  amount: 0,
@@ -1906,6 +1899,45 @@ async function addSwapToTx(params) {
1906
1899
  toDecimals: toInfo.decimals
1907
1900
  };
1908
1901
  }
1902
+ async function buildRawSwapTx(params) {
1903
+ const { client, address, fromCoinType, toCoinType, amount, toDecimals, maxSlippageBps = 500 } = params;
1904
+ const aggClient = createAggregatorClient(client, address);
1905
+ const _origLog = console.log;
1906
+ console.log = () => {
1907
+ };
1908
+ let result;
1909
+ try {
1910
+ result = await aggClient.findRouters({
1911
+ from: fromCoinType,
1912
+ target: toCoinType,
1913
+ amount,
1914
+ byAmountIn: true
1915
+ });
1916
+ } finally {
1917
+ console.log = _origLog;
1918
+ }
1919
+ if (!result || result.insufficientLiquidity) {
1920
+ throw new T2000Error("ASSET_NOT_SUPPORTED", `No swap route for reward token \u2192 USDC`);
1921
+ }
1922
+ const tx = new transactions.Transaction();
1923
+ const slippage = maxSlippageBps / 1e4;
1924
+ console.log = () => {
1925
+ };
1926
+ try {
1927
+ await aggClient.fastRouterSwap({
1928
+ router: result,
1929
+ txb: tx,
1930
+ slippage
1931
+ });
1932
+ } finally {
1933
+ console.log = _origLog;
1934
+ }
1935
+ return {
1936
+ tx,
1937
+ estimatedOut: Number(result.amountOut.toString()),
1938
+ toDecimals
1939
+ };
1940
+ }
1909
1941
  async function getPoolPrice(client) {
1910
1942
  try {
1911
1943
  const pool = await client.getObject({
@@ -2697,45 +2729,24 @@ var SuilendAdapter = class {
2697
2729
  this.fetchObligation(caps[0].obligationId)
2698
2730
  ]);
2699
2731
  const rewards = [];
2700
- const rewardEstimates = /* @__PURE__ */ new Map();
2701
2732
  for (const dep of obligation.deposits) {
2702
2733
  const reserve = reserves[dep.reserveIdx];
2703
2734
  if (!reserve) continue;
2704
- const ratio = cTokenRatio(reserve);
2705
- const amount = dep.ctokenAmount * ratio / 10 ** reserve.mintDecimals;
2706
- const price = reserve.price;
2707
- const depositUsd = amount * price;
2708
2735
  for (const rw of reserve.depositPoolRewards) {
2709
2736
  if (!this.isClaimableReward(rw.coinType)) continue;
2710
- const rewardReserve = reserves.find((r) => {
2711
- try {
2712
- return utils.normalizeStructTag(r.coinType) === utils.normalizeStructTag(rw.coinType);
2713
- } catch {
2714
- return false;
2715
- }
2716
- });
2717
- const rewardPrice = rewardReserve?.price ?? 0;
2718
- const rewardDecimals = rewardReserve?.mintDecimals ?? 9;
2719
2737
  const durationMs = rw.endTimeMs - rw.startTimeMs;
2720
2738
  if (durationMs <= 0) continue;
2721
- const annualTokens = rw.totalRewards / 10 ** rewardDecimals * (MS_PER_YEAR / durationMs);
2722
- const totalDepositValue = reserve.depositTotalShares / 10 ** reserve.mintDecimals * price;
2723
- if (totalDepositValue <= 0) continue;
2724
- const userShare = depositUsd / totalDepositValue;
2725
- const dailyRewardUsd = annualTokens * rewardPrice / 365 * userShare;
2726
- rewardEstimates.set(rw.coinType, (rewardEstimates.get(rw.coinType) ?? 0) + dailyRewardUsd);
2739
+ const assetSymbol = this.resolveSymbol(reserve.coinType);
2740
+ rewards.push({
2741
+ protocol: "suilend",
2742
+ asset: assetSymbol,
2743
+ coinType: rw.coinType,
2744
+ symbol: rw.coinType.includes("spring_sui") ? "sSUI" : rw.coinType.includes("deep::") ? "DEEP" : rw.coinType.split("::").pop() ?? "UNKNOWN",
2745
+ amount: 0,
2746
+ estimatedValueUsd: 0
2747
+ });
2727
2748
  }
2728
2749
  }
2729
- for (const [coinType, dailyUsd] of rewardEstimates) {
2730
- const symbol = coinType.includes("spring_sui") ? "SPRING_SUI" : coinType.includes("deep::") ? "DEEP" : coinType.split("::").pop() ?? "UNKNOWN";
2731
- rewards.push({
2732
- protocol: "suilend",
2733
- coinType,
2734
- symbol,
2735
- amount: 0,
2736
- estimatedValueUsd: dailyUsd
2737
- });
2738
- }
2739
2750
  return rewards;
2740
2751
  }
2741
2752
  async addClaimRewardsToTx(tx, address) {
@@ -2778,6 +2789,7 @@ var SuilendAdapter = class {
2778
2789
  const symbol = coinType.includes("spring_sui") ? "SPRING_SUI" : coinType.includes("deep::") ? "DEEP" : coinType.split("::").pop() ?? "UNKNOWN";
2779
2790
  claimed.push({
2780
2791
  protocol: "suilend",
2792
+ asset: "",
2781
2793
  coinType,
2782
2794
  symbol,
2783
2795
  amount: 0,
@@ -3681,6 +3693,11 @@ var AutoInvestManager = class {
3681
3693
  }
3682
3694
  };
3683
3695
  var LOW_LIQUIDITY_ASSETS = /* @__PURE__ */ new Set(["GOLD"]);
3696
+ var REWARD_TOKEN_DECIMALS = {
3697
+ "0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55::cert::CERT": 9,
3698
+ "0xdeeb7a4662eec9f2f3def03fb937a663dddaa2e215b8078a284d026b7946c270::deep::DEEP": 6,
3699
+ "0x83556891f4a0f233ce7b05cfe7f957d4020492a34f5405b2cb9377d060bef4bf::spring_sui::SPRING_SUI": 9
3700
+ };
3684
3701
  function defaultSlippage(asset) {
3685
3702
  return LOW_LIQUIDITY_ASSETS.has(asset) ? 0.05 : 0.03;
3686
3703
  }
@@ -4882,7 +4899,7 @@ To sell investment: t2000 invest sell ${params.amount} ${fromAsset}`,
4882
4899
  this.enforcer.assertNotLocked();
4883
4900
  const adapters = this.registry.listLending().filter((a) => a.addClaimRewardsToTx);
4884
4901
  if (adapters.length === 0) {
4885
- return { success: true, tx: "", rewards: [], totalValueUsd: 0, gasCost: 0, gasMethod: "none" };
4902
+ return { success: true, tx: "", rewards: [], totalValueUsd: 0, usdcReceived: 0, gasCost: 0, gasMethod: "none" };
4886
4903
  }
4887
4904
  const tx = new transactions.Transaction();
4888
4905
  tx.setSender(this._address);
@@ -4895,18 +4912,52 @@ To sell investment: t2000 invest sell ${params.amount} ${fromAsset}`,
4895
4912
  }
4896
4913
  }
4897
4914
  if (allRewards.length === 0) {
4898
- return { success: true, tx: "", rewards: [], totalValueUsd: 0, gasCost: 0, gasMethod: "none" };
4915
+ return { success: true, tx: "", rewards: [], totalValueUsd: 0, usdcReceived: 0, gasCost: 0, gasMethod: "none" };
4899
4916
  }
4900
- const gasResult = await executeWithGas(this.client, this.keypair, async () => tx);
4917
+ const claimResult = await executeWithGas(this.client, this.keypair, async () => tx);
4918
+ await this.client.waitForTransaction({ digest: claimResult.digest });
4919
+ const usdcReceived = await this.swapRewardTokensToUsdc(allRewards);
4901
4920
  return {
4902
4921
  success: true,
4903
- tx: gasResult.digest,
4922
+ tx: claimResult.digest,
4904
4923
  rewards: allRewards,
4905
- totalValueUsd: allRewards.reduce((s, r) => s + r.estimatedValueUsd, 0),
4906
- gasCost: gasResult.gasCostSui,
4907
- gasMethod: gasResult.gasMethod
4924
+ totalValueUsd: usdcReceived,
4925
+ usdcReceived,
4926
+ gasCost: claimResult.gasCostSui,
4927
+ gasMethod: claimResult.gasMethod
4908
4928
  };
4909
4929
  }
4930
+ async swapRewardTokensToUsdc(rewards) {
4931
+ const uniqueTokens = [...new Set(rewards.map((r) => r.coinType))];
4932
+ const usdcType = SUPPORTED_ASSETS.USDC.type;
4933
+ const usdcDecimals = SUPPORTED_ASSETS.USDC.decimals;
4934
+ let totalUsdc = 0;
4935
+ for (const coinType of uniqueTokens) {
4936
+ try {
4937
+ const balResult = await this.client.getBalance({
4938
+ owner: this._address,
4939
+ coinType
4940
+ });
4941
+ const rawBalance = BigInt(balResult.totalBalance);
4942
+ if (rawBalance <= 0n) continue;
4943
+ const decimals = REWARD_TOKEN_DECIMALS[coinType] ?? 9;
4944
+ const swapResult = await buildRawSwapTx({
4945
+ client: this.client,
4946
+ address: this._address,
4947
+ fromCoinType: coinType,
4948
+ fromDecimals: decimals,
4949
+ toCoinType: usdcType,
4950
+ toDecimals: usdcDecimals,
4951
+ amount: rawBalance
4952
+ });
4953
+ const gasResult = await executeWithGas(this.client, this.keypair, async () => swapResult.tx);
4954
+ await this.client.waitForTransaction({ digest: gasResult.digest });
4955
+ totalUsdc += swapResult.estimatedOut / 10 ** usdcDecimals;
4956
+ } catch {
4957
+ }
4958
+ }
4959
+ return totalUsdc;
4960
+ }
4910
4961
  // -- Strategies --
4911
4962
  async investStrategy(params) {
4912
4963
  this.enforcer.assertNotLocked();