@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.cjs CHANGED
@@ -1131,11 +1131,19 @@ async function getRates(client) {
1131
1131
  }
1132
1132
  async function getPositions(client, addressOrKeypair) {
1133
1133
  const address = typeof addressOrKeypair === "string" ? addressOrKeypair : addressOrKeypair.getPublicKey().toSuiAddress();
1134
- const [states, pools] = await Promise.all([getUserState(client, address), getPools()]);
1134
+ const [states, cachedPools] = await Promise.all([getUserState(client, address), getPools()]);
1135
+ let pools = cachedPools;
1136
+ const unmatchedIds = states.filter((s) => !pools.find((p) => p.id === s.assetId)).map((s) => s.assetId);
1137
+ if (unmatchedIds.length > 0) {
1138
+ pools = await getPools(true);
1139
+ }
1135
1140
  const positions = [];
1136
1141
  for (const state of states) {
1137
1142
  const pool = pools.find((p) => p.id === state.assetId);
1138
- if (!pool) continue;
1143
+ if (!pool) {
1144
+ console.warn(`[NAVI] No pool found for assetId=${state.assetId} (supply=${state.supplyBalance}, borrow=${state.borrowBalance}) \u2014 funds may be invisible`);
1145
+ continue;
1146
+ }
1139
1147
  const symbol = resolvePoolSymbol(pool);
1140
1148
  const supplyBal = compoundBalance(state.supplyBalance, pool.currentSupplyIndex, pool);
1141
1149
  const borrowBal = compoundBalance(state.borrowBalance, pool.currentBorrowIndex, pool);
@@ -1674,15 +1682,20 @@ var ProtocolRegistry = class {
1674
1682
  }
1675
1683
  async allPositions(address) {
1676
1684
  const results = [];
1685
+ const errors = [];
1677
1686
  for (const adapter of this.lending.values()) {
1678
1687
  try {
1679
1688
  const positions = await adapter.getPositions(address);
1680
1689
  if (positions.supplies.length > 0 || positions.borrows.length > 0) {
1681
1690
  results.push({ protocol: adapter.name, protocolId: adapter.id, positions });
1682
1691
  }
1683
- } catch {
1692
+ } catch (err) {
1693
+ errors.push(`${adapter.name}: ${err instanceof Error ? err.message : String(err)}`);
1684
1694
  }
1685
1695
  }
1696
+ if (results.length === 0 && errors.length > 0) {
1697
+ throw new T2000Error("PROTOCOL_UNAVAILABLE", `Protocol queries failed (${errors.length}/${this.lending.size}): ${errors.join("; ")}`);
1698
+ }
1686
1699
  return results;
1687
1700
  }
1688
1701
  getLending(id) {
@@ -3868,6 +3881,9 @@ To access invested funds: t2000 invest sell ${params.amount} ${asset}`,
3868
3881
  if (sp.asset in INVESTMENT_ASSETS) investedAssets.add(sp.asset);
3869
3882
  }
3870
3883
  }
3884
+ for (const asset of Object.keys(INVESTMENT_ASSETS)) {
3885
+ if ((bal.assets[asset] ?? 0) > 0) investedAssets.add(asset);
3886
+ }
3871
3887
  for (const asset of investedAssets) {
3872
3888
  if (asset === "SUI" || asset in assetPrices) continue;
3873
3889
  try {
@@ -4069,11 +4085,14 @@ To access invested funds: t2000 invest sell ${params.amount} ${asset}`,
4069
4085
  return this.withdrawAllProtocols();
4070
4086
  }
4071
4087
  const allPositions = await this.registry.allPositions(this._address);
4088
+ const earningAssets = new Set(
4089
+ this.portfolio.getPositions().filter((p) => p.earning).map((p) => p.asset)
4090
+ );
4072
4091
  const supplies = [];
4073
4092
  for (const pos of allPositions) {
4074
4093
  if (params.protocol && pos.protocolId !== params.protocol) continue;
4075
4094
  for (const s of pos.positions.supplies) {
4076
- if (s.amount > 1e-3 && !(s.asset in INVESTMENT_ASSETS)) {
4095
+ if (s.amount > 1e-3 && !earningAssets.has(s.asset)) {
4077
4096
  supplies.push({ protocolId: pos.protocolId, asset: s.asset, amount: s.amount, apy: s.apy });
4078
4097
  }
4079
4098
  }
@@ -4157,7 +4176,7 @@ To access invested funds: t2000 invest sell ${params.amount} ${asset}`,
4157
4176
  const withdrawable = [];
4158
4177
  for (const pos of allPositions) {
4159
4178
  for (const supply of pos.positions.supplies) {
4160
- if (supply.amount > 0.01 && !earningAssets.has(supply.asset) && !(supply.asset in INVESTMENT_ASSETS)) {
4179
+ if (supply.amount > 0.01 && !earningAssets.has(supply.asset)) {
4161
4180
  withdrawable.push({ protocolId: pos.protocolId, asset: supply.asset, amount: supply.amount });
4162
4181
  }
4163
4182
  }
@@ -4184,7 +4203,8 @@ To access invested funds: t2000 invest sell ${params.amount} ${asset}`,
4184
4203
  if (entries.length === 0) {
4185
4204
  throw new T2000Error("NO_COLLATERAL", "No savings to withdraw across any protocol");
4186
4205
  }
4187
- const swapAdapter = this.registry.listSwap()[0];
4206
+ const hasNonUsdc = entries.some((e) => e.asset !== "USDC");
4207
+ const swapAdapter = hasNonUsdc ? this.registry.listSwap()[0] : void 0;
4188
4208
  const canPTB = entries.every((e) => e.adapter.addWithdrawToTx) && (!swapAdapter || swapAdapter.addSwapToTx);
4189
4209
  let totalUsdcReceived = 0;
4190
4210
  const gasResult = await executeWithGas(this.client, this.keypair, async () => {
@@ -4192,7 +4212,6 @@ To access invested funds: t2000 invest sell ${params.amount} ${asset}`,
4192
4212
  const tx = new transactions.Transaction();
4193
4213
  tx.setSender(this._address);
4194
4214
  const usdcCoins = [];
4195
- const nonUsdcCoins = [];
4196
4215
  for (const entry of entries) {
4197
4216
  const { coin, effectiveAmount } = await entry.adapter.addWithdrawToTx(
4198
4217
  tx,
@@ -4203,9 +4222,20 @@ To access invested funds: t2000 invest sell ${params.amount} ${asset}`,
4203
4222
  if (entry.asset === "USDC") {
4204
4223
  totalUsdcReceived += effectiveAmount;
4205
4224
  usdcCoins.push(coin);
4225
+ } else if (swapAdapter?.addSwapToTx) {
4226
+ const { outputCoin, estimatedOut, toDecimals } = await swapAdapter.addSwapToTx(
4227
+ tx,
4228
+ this._address,
4229
+ coin,
4230
+ entry.asset,
4231
+ "USDC",
4232
+ effectiveAmount
4233
+ );
4234
+ totalUsdcReceived += estimatedOut / 10 ** toDecimals;
4235
+ usdcCoins.push(outputCoin);
4206
4236
  } else {
4207
4237
  totalUsdcReceived += effectiveAmount;
4208
- nonUsdcCoins.push(coin);
4238
+ tx.transferObjects([coin], this._address);
4209
4239
  }
4210
4240
  }
4211
4241
  if (usdcCoins.length > 1) {
@@ -4214,9 +4244,6 @@ To access invested funds: t2000 invest sell ${params.amount} ${asset}`,
4214
4244
  if (usdcCoins.length > 0) {
4215
4245
  tx.transferObjects([usdcCoins[0]], this._address);
4216
4246
  }
4217
- for (const coin of nonUsdcCoins) {
4218
- tx.transferObjects([coin], this._address);
4219
- }
4220
4247
  return tx;
4221
4248
  }
4222
4249
  let lastTx;
@@ -4225,6 +4252,9 @@ To access invested funds: t2000 invest sell ${params.amount} ${asset}`,
4225
4252
  totalUsdcReceived += built.effectiveAmount;
4226
4253
  lastTx = built.tx;
4227
4254
  }
4255
+ if (hasNonUsdc && swapAdapter) {
4256
+ await this._convertWalletStablesToUsdc(await queryBalance(this.client, this._address));
4257
+ }
4228
4258
  return lastTx;
4229
4259
  });
4230
4260
  if (totalUsdcReceived <= 0) {