@t2000/sdk 0.18.3 → 0.18.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1129,11 +1129,19 @@ async function getRates(client) {
1129
1129
  }
1130
1130
  async function getPositions(client, addressOrKeypair) {
1131
1131
  const address = typeof addressOrKeypair === "string" ? addressOrKeypair : addressOrKeypair.getPublicKey().toSuiAddress();
1132
- const [states, pools] = await Promise.all([getUserState(client, address), getPools()]);
1132
+ const [states, cachedPools] = await Promise.all([getUserState(client, address), getPools()]);
1133
+ let pools = cachedPools;
1134
+ const unmatchedIds = states.filter((s) => !pools.find((p) => p.id === s.assetId)).map((s) => s.assetId);
1135
+ if (unmatchedIds.length > 0) {
1136
+ pools = await getPools(true);
1137
+ }
1133
1138
  const positions = [];
1134
1139
  for (const state of states) {
1135
1140
  const pool = pools.find((p) => p.id === state.assetId);
1136
- if (!pool) continue;
1141
+ if (!pool) {
1142
+ console.warn(`[NAVI] No pool found for assetId=${state.assetId} (supply=${state.supplyBalance}, borrow=${state.borrowBalance}) \u2014 funds may be invisible`);
1143
+ continue;
1144
+ }
1137
1145
  const symbol = resolvePoolSymbol(pool);
1138
1146
  const supplyBal = compoundBalance(state.supplyBalance, pool.currentSupplyIndex, pool);
1139
1147
  const borrowBal = compoundBalance(state.borrowBalance, pool.currentBorrowIndex, pool);
@@ -1672,15 +1680,20 @@ var ProtocolRegistry = class {
1672
1680
  }
1673
1681
  async allPositions(address) {
1674
1682
  const results = [];
1683
+ const errors = [];
1675
1684
  for (const adapter of this.lending.values()) {
1676
1685
  try {
1677
1686
  const positions = await adapter.getPositions(address);
1678
1687
  if (positions.supplies.length > 0 || positions.borrows.length > 0) {
1679
1688
  results.push({ protocol: adapter.name, protocolId: adapter.id, positions });
1680
1689
  }
1681
- } catch {
1690
+ } catch (err) {
1691
+ errors.push(`${adapter.name}: ${err instanceof Error ? err.message : String(err)}`);
1682
1692
  }
1683
1693
  }
1694
+ if (results.length === 0 && errors.length > 0) {
1695
+ throw new T2000Error("PROTOCOL_UNAVAILABLE", `Protocol queries failed (${errors.length}/${this.lending.size}): ${errors.join("; ")}`);
1696
+ }
1684
1697
  return results;
1685
1698
  }
1686
1699
  getLending(id) {
@@ -3866,6 +3879,9 @@ To access invested funds: t2000 invest sell ${params.amount} ${asset}`,
3866
3879
  if (sp.asset in INVESTMENT_ASSETS) investedAssets.add(sp.asset);
3867
3880
  }
3868
3881
  }
3882
+ for (const asset of Object.keys(INVESTMENT_ASSETS)) {
3883
+ if ((bal.assets[asset] ?? 0) > 0) investedAssets.add(asset);
3884
+ }
3869
3885
  for (const asset of investedAssets) {
3870
3886
  if (asset === "SUI" || asset in assetPrices) continue;
3871
3887
  try {
@@ -4067,11 +4083,14 @@ To access invested funds: t2000 invest sell ${params.amount} ${asset}`,
4067
4083
  return this.withdrawAllProtocols();
4068
4084
  }
4069
4085
  const allPositions = await this.registry.allPositions(this._address);
4086
+ const earningAssets = new Set(
4087
+ this.portfolio.getPositions().filter((p) => p.earning).map((p) => p.asset)
4088
+ );
4070
4089
  const supplies = [];
4071
4090
  for (const pos of allPositions) {
4072
4091
  if (params.protocol && pos.protocolId !== params.protocol) continue;
4073
4092
  for (const s of pos.positions.supplies) {
4074
- if (s.amount > 1e-3 && !(s.asset in INVESTMENT_ASSETS)) {
4093
+ if (s.amount > 1e-3 && !earningAssets.has(s.asset)) {
4075
4094
  supplies.push({ protocolId: pos.protocolId, asset: s.asset, amount: s.amount, apy: s.apy });
4076
4095
  }
4077
4096
  }
@@ -4155,7 +4174,7 @@ To access invested funds: t2000 invest sell ${params.amount} ${asset}`,
4155
4174
  const withdrawable = [];
4156
4175
  for (const pos of allPositions) {
4157
4176
  for (const supply of pos.positions.supplies) {
4158
- if (supply.amount > 0.01 && !earningAssets.has(supply.asset) && !(supply.asset in INVESTMENT_ASSETS)) {
4177
+ if (supply.amount > 0.01 && !earningAssets.has(supply.asset)) {
4159
4178
  withdrawable.push({ protocolId: pos.protocolId, asset: supply.asset, amount: supply.amount });
4160
4179
  }
4161
4180
  }
@@ -4182,7 +4201,8 @@ To access invested funds: t2000 invest sell ${params.amount} ${asset}`,
4182
4201
  if (entries.length === 0) {
4183
4202
  throw new T2000Error("NO_COLLATERAL", "No savings to withdraw across any protocol");
4184
4203
  }
4185
- const swapAdapter = this.registry.listSwap()[0];
4204
+ const hasNonUsdc = entries.some((e) => e.asset !== "USDC");
4205
+ const swapAdapter = hasNonUsdc ? this.registry.listSwap()[0] : void 0;
4186
4206
  const canPTB = entries.every((e) => e.adapter.addWithdrawToTx) && (!swapAdapter || swapAdapter.addSwapToTx);
4187
4207
  let totalUsdcReceived = 0;
4188
4208
  const gasResult = await executeWithGas(this.client, this.keypair, async () => {
@@ -4190,7 +4210,6 @@ To access invested funds: t2000 invest sell ${params.amount} ${asset}`,
4190
4210
  const tx = new Transaction();
4191
4211
  tx.setSender(this._address);
4192
4212
  const usdcCoins = [];
4193
- const nonUsdcCoins = [];
4194
4213
  for (const entry of entries) {
4195
4214
  const { coin, effectiveAmount } = await entry.adapter.addWithdrawToTx(
4196
4215
  tx,
@@ -4201,9 +4220,20 @@ To access invested funds: t2000 invest sell ${params.amount} ${asset}`,
4201
4220
  if (entry.asset === "USDC") {
4202
4221
  totalUsdcReceived += effectiveAmount;
4203
4222
  usdcCoins.push(coin);
4223
+ } else if (swapAdapter?.addSwapToTx) {
4224
+ const { outputCoin, estimatedOut, toDecimals } = await swapAdapter.addSwapToTx(
4225
+ tx,
4226
+ this._address,
4227
+ coin,
4228
+ entry.asset,
4229
+ "USDC",
4230
+ effectiveAmount
4231
+ );
4232
+ totalUsdcReceived += estimatedOut / 10 ** toDecimals;
4233
+ usdcCoins.push(outputCoin);
4204
4234
  } else {
4205
4235
  totalUsdcReceived += effectiveAmount;
4206
- nonUsdcCoins.push(coin);
4236
+ tx.transferObjects([coin], this._address);
4207
4237
  }
4208
4238
  }
4209
4239
  if (usdcCoins.length > 1) {
@@ -4212,9 +4242,6 @@ To access invested funds: t2000 invest sell ${params.amount} ${asset}`,
4212
4242
  if (usdcCoins.length > 0) {
4213
4243
  tx.transferObjects([usdcCoins[0]], this._address);
4214
4244
  }
4215
- for (const coin of nonUsdcCoins) {
4216
- tx.transferObjects([coin], this._address);
4217
- }
4218
4245
  return tx;
4219
4246
  }
4220
4247
  let lastTx;
@@ -4223,6 +4250,9 @@ To access invested funds: t2000 invest sell ${params.amount} ${asset}`,
4223
4250
  totalUsdcReceived += built.effectiveAmount;
4224
4251
  lastTx = built.tx;
4225
4252
  }
4253
+ if (hasNonUsdc && swapAdapter) {
4254
+ await this._convertWalletStablesToUsdc(await queryBalance(this.client, this._address));
4255
+ }
4226
4256
  return lastTx;
4227
4257
  });
4228
4258
  if (totalUsdcReceived <= 0) {