@t2000/sdk 1.23.1 → 1.24.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.
package/dist/index.cjs CHANGED
@@ -7444,6 +7444,183 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
7444
7444
  // src/index.ts
7445
7445
  init_errors();
7446
7446
  init_coinSelection();
7447
+ init_errors();
7448
+ init_token_registry();
7449
+ init_cetus_swap();
7450
+ async function addHarvestToTx(tx, client, address, options = {}) {
7451
+ const slippage = options.slippage ?? 0.01;
7452
+ const minRewardUsd = options.minRewardUsd ?? 0.01;
7453
+ const priceCache = options.priceCache;
7454
+ let rawRewards;
7455
+ try {
7456
+ rawRewards = await vt(address, {
7457
+ env: "prod",
7458
+ client,
7459
+ markets: ["main"]
7460
+ });
7461
+ } catch (err) {
7462
+ const msg = err instanceof Error ? err.message : String(err);
7463
+ throw new exports.T2000Error(
7464
+ "PROTOCOL_UNAVAILABLE",
7465
+ `NAVI rewards lookup failed: ${msg}`,
7466
+ { source: "navi-harvest-read" },
7467
+ true
7468
+ );
7469
+ }
7470
+ const claimable = (rawRewards ?? []).filter((r) => Number(r.userClaimableReward) > 0);
7471
+ if (claimable.length === 0) {
7472
+ throw new exports.T2000Error(
7473
+ "INVALID_AMOUNT",
7474
+ "No pending rewards to harvest.",
7475
+ { source: "navi-harvest" }
7476
+ );
7477
+ }
7478
+ const aggregated = aggregateClaimableRewards(claimable);
7479
+ let claimed;
7480
+ try {
7481
+ const claimResult = await Ct(tx, claimable, {
7482
+ env: "prod",
7483
+ // 'skip' = NAVI doesn't auto-transfer; coin handles stay in the PTB
7484
+ // for downstream consumption. Verified against NAVI lending source
7485
+ // (index.esm.js@1828–1911) — when type !== 'transfer' && type !==
7486
+ // 'depositNAVI', the `else` branch pushes `{ coin, identifier, ... }`
7487
+ // to the return without consuming the handle.
7488
+ customCoinReceive: { type: "skip" }
7489
+ });
7490
+ const grouped = /* @__PURE__ */ new Map();
7491
+ for (const c of claimResult) {
7492
+ const ct2 = c.identifier.suiCoinType ?? "";
7493
+ if (!ct2) continue;
7494
+ const list = grouped.get(ct2) ?? [];
7495
+ list.push(c.coin);
7496
+ grouped.set(ct2, list);
7497
+ }
7498
+ claimed = [];
7499
+ for (const [coinType, handles] of grouped.entries()) {
7500
+ if (handles.length === 1) {
7501
+ claimed.push({ coin: handles[0], coinType });
7502
+ } else {
7503
+ const [dest, ...rest] = handles;
7504
+ tx.mergeCoins(dest, rest);
7505
+ claimed.push({ coin: dest, coinType });
7506
+ }
7507
+ }
7508
+ } catch (err) {
7509
+ const msg = err instanceof Error ? err.message : String(err);
7510
+ throw new exports.T2000Error(
7511
+ "PROTOCOL_UNAVAILABLE",
7512
+ `NAVI claim PTB build failed: ${msg}`,
7513
+ { source: "navi-harvest-claim-ptb" },
7514
+ true
7515
+ );
7516
+ }
7517
+ const usdcHandles = [];
7518
+ const swaps = [];
7519
+ const skipped = [];
7520
+ let expectedUsdcDeposited = 0;
7521
+ for (const { coin, coinType } of claimed) {
7522
+ const aggRow = aggregated.find((r) => r.coinType === coinType);
7523
+ if (!aggRow) {
7524
+ continue;
7525
+ }
7526
+ if (coinType === exports.USDC_TYPE) {
7527
+ usdcHandles.push(coin);
7528
+ expectedUsdcDeposited += aggRow.amount;
7529
+ continue;
7530
+ }
7531
+ const meta = getCoinMeta(coinType);
7532
+ const isTradeable = meta && (meta.tier === 1 || meta.tier === 2);
7533
+ if (!isTradeable) {
7534
+ tx.transferObjects([coin], address);
7535
+ skipped.push({
7536
+ symbol: aggRow.symbol,
7537
+ coinType,
7538
+ amount: aggRow.amount,
7539
+ reason: "untradeable"
7540
+ });
7541
+ continue;
7542
+ }
7543
+ if (priceCache && minRewardUsd > 0) {
7544
+ const px = priceCache.get(aggRow.symbol.toUpperCase());
7545
+ if (px && px > 0 && aggRow.amount * px < minRewardUsd) {
7546
+ tx.transferObjects([coin], address);
7547
+ skipped.push({
7548
+ symbol: aggRow.symbol,
7549
+ coinType,
7550
+ amount: aggRow.amount,
7551
+ reason: "dust"
7552
+ });
7553
+ continue;
7554
+ }
7555
+ }
7556
+ try {
7557
+ const swapResult = await addSwapToTx(tx, client, address, {
7558
+ from: aggRow.symbol,
7559
+ to: "USDC",
7560
+ amount: aggRow.amount,
7561
+ slippage,
7562
+ inputCoin: coin,
7563
+ providers: options.providers
7564
+ });
7565
+ usdcHandles.push(swapResult.coin);
7566
+ expectedUsdcDeposited += swapResult.expectedAmountOut;
7567
+ swaps.push({
7568
+ fromSymbol: aggRow.symbol,
7569
+ fromCoinType: coinType,
7570
+ toSymbol: "USDC",
7571
+ inputAmount: swapResult.effectiveAmountIn,
7572
+ expectedOutputUsdc: swapResult.expectedAmountOut
7573
+ });
7574
+ } catch (err) {
7575
+ const code = err instanceof exports.T2000Error ? err.code : "UNKNOWN";
7576
+ if (code !== "SWAP_NO_ROUTE" && code !== "SWAP_FAILED") {
7577
+ throw err;
7578
+ }
7579
+ tx.transferObjects([coin], address);
7580
+ skipped.push({
7581
+ symbol: aggRow.symbol,
7582
+ coinType,
7583
+ amount: aggRow.amount,
7584
+ reason: "no-route"
7585
+ });
7586
+ }
7587
+ }
7588
+ if (usdcHandles.length > 0) {
7589
+ let depositCoin;
7590
+ if (usdcHandles.length === 1) {
7591
+ depositCoin = usdcHandles[0];
7592
+ } else {
7593
+ const [primary, ...rest] = usdcHandles;
7594
+ tx.mergeCoins(primary, rest);
7595
+ depositCoin = primary;
7596
+ }
7597
+ try {
7598
+ await addSaveToTx(tx, client, address, depositCoin, { asset: "USDC" });
7599
+ } catch (err) {
7600
+ const msg = err instanceof Error ? err.message : String(err);
7601
+ throw new exports.T2000Error(
7602
+ "PROTOCOL_UNAVAILABLE",
7603
+ `NAVI deposit failed during harvest: ${msg}`,
7604
+ { source: "navi-harvest-deposit" },
7605
+ true
7606
+ );
7607
+ }
7608
+ }
7609
+ return {
7610
+ claimed: aggregated,
7611
+ swaps,
7612
+ skipped,
7613
+ expectedUsdcDeposited
7614
+ };
7615
+ }
7616
+ async function buildHarvestRewardsTx(client, address, options = {}) {
7617
+ const tx = new transactions.Transaction();
7618
+ tx.setSender(address);
7619
+ const plan = await addHarvestToTx(tx, client, address, options);
7620
+ return { tx, plan };
7621
+ }
7622
+
7623
+ // src/composeTx.ts
7447
7624
  init_cetus_swap();
7448
7625
  init_volo();
7449
7626
  init_coinSelection();
@@ -7643,6 +7820,29 @@ var WRITE_APPENDER_REGISTRY = {
7643
7820
  const rewards = await addClaimRewardsToTx(tx, ctx.client, ctx.sender);
7644
7821
  return { preview: { toolName: "claim_rewards", rewards } };
7645
7822
  },
7823
+ // [Track B / 2026-05-08] Macro appender — assembles claim → swap(s) →
7824
+ // save inline. The audric host wires `getSponsoredSwapProviders()` into
7825
+ // `options.providers` automatically when `ctx.sponsoredContext === true`
7826
+ // (parity with `swap_execute` below). Slippage + dust-floor pulled from
7827
+ // the input; price cache is forwarded from the host so the dust filter
7828
+ // can compare claimed amounts to USD.
7829
+ harvest_rewards: async (tx, input, ctx) => {
7830
+ const providers = ctx.sponsoredContext ? await getSponsoredSwapProviders() : void 0;
7831
+ const plan = await addHarvestToTx(tx, ctx.client, ctx.sender, {
7832
+ slippage: input.slippage,
7833
+ minRewardUsd: input.minRewardUsd,
7834
+ providers
7835
+ });
7836
+ return {
7837
+ preview: {
7838
+ toolName: "harvest_rewards",
7839
+ claimed: plan.claimed,
7840
+ swaps: plan.swaps,
7841
+ skipped: plan.skipped,
7842
+ expectedUsdcDeposited: plan.expectedUsdcDeposited
7843
+ }
7844
+ };
7845
+ },
7646
7846
  volo_stake: async (tx, input, ctx) => {
7647
7847
  if (input.amountSui <= 0) {
7648
7848
  throw new exports.T2000Error("INVALID_AMOUNT", "Stake amount must be greater than zero");
@@ -8101,6 +8301,7 @@ exports.allDescriptors = allDescriptors;
8101
8301
  exports.assertAllowedAsset = assertAllowedAsset;
8102
8302
  exports.buildAddLeafTx = buildAddLeafTx;
8103
8303
  exports.buildClaimRewardsTx = buildClaimRewardsTx;
8304
+ exports.buildHarvestRewardsTx = buildHarvestRewardsTx;
8104
8305
  exports.buildRevokeLeafTx = buildRevokeLeafTx;
8105
8306
  exports.buildSendTx = buildSendTx;
8106
8307
  exports.buildStakeVSuiTx = buildStakeVSuiTx;