@t2000/sdk 1.23.0 → 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/adapters/index.cjs +45 -48
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.js +45 -48
- package/dist/adapters/index.js.map +1 -1
- package/dist/index.cjs +208 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +191 -4
- package/dist/index.d.ts +191 -4
- package/dist/index.js +206 -49
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5101,35 +5101,6 @@ async function vt(e, n) {
|
|
|
5101
5101
|
);
|
|
5102
5102
|
return await De(e, t, n);
|
|
5103
5103
|
}
|
|
5104
|
-
function wt(e) {
|
|
5105
|
-
const n = /* @__PURE__ */ new Map();
|
|
5106
|
-
e.forEach((r) => {
|
|
5107
|
-
const t = r.assetId, a = r.option, s = `${t}-${a}-${r.rewardCoinType}-${r.market}`;
|
|
5108
|
-
n.has(s) ? n.get(s).total += r.userClaimableReward : n.set(s, {
|
|
5109
|
-
assetId: t,
|
|
5110
|
-
rewardType: a,
|
|
5111
|
-
coinType: r.rewardCoinType,
|
|
5112
|
-
total: Number(r.userClaimableReward),
|
|
5113
|
-
market: r.market
|
|
5114
|
-
});
|
|
5115
|
-
});
|
|
5116
|
-
const o = /* @__PURE__ */ new Map();
|
|
5117
|
-
for (const { assetId: r, rewardType: t, coinType: a, total: s, market: i } of n.values()) {
|
|
5118
|
-
const c = `${r}-${t}-${i}`;
|
|
5119
|
-
o.has(c) || o.set(c, { assetId: r, rewardType: t, market: i, rewards: /* @__PURE__ */ new Map() });
|
|
5120
|
-
const u = o.get(c);
|
|
5121
|
-
u.rewards.set(a, (u.rewards.get(a) || 0) + s);
|
|
5122
|
-
}
|
|
5123
|
-
return Array.from(o.values()).map((r) => ({
|
|
5124
|
-
assetId: r.assetId,
|
|
5125
|
-
rewardType: r.rewardType,
|
|
5126
|
-
market: r.market,
|
|
5127
|
-
rewards: Array.from(r.rewards.entries()).map(([t, a]) => ({
|
|
5128
|
-
coinType: t,
|
|
5129
|
-
available: a.toFixed(6)
|
|
5130
|
-
}))
|
|
5131
|
-
}));
|
|
5132
|
-
}
|
|
5133
5104
|
async function Ct(e, n, o) {
|
|
5134
5105
|
const r = await R({
|
|
5135
5106
|
...o,
|
|
@@ -5307,6 +5278,7 @@ async function Ct(e, n, o) {
|
|
|
5307
5278
|
|
|
5308
5279
|
// src/protocols/navi.ts
|
|
5309
5280
|
init_errors();
|
|
5281
|
+
init_token_registry();
|
|
5310
5282
|
var MIN_HEALTH_FACTOR = 1.5;
|
|
5311
5283
|
function sdkOptions(client) {
|
|
5312
5284
|
return { env: "prod", client, cacheTime: 0, disableCache: true };
|
|
@@ -5681,24 +5653,8 @@ async function getPendingRewards(client, address) {
|
|
|
5681
5653
|
);
|
|
5682
5654
|
}
|
|
5683
5655
|
if (!rewards || rewards.length === 0) return [];
|
|
5684
|
-
const
|
|
5685
|
-
|
|
5686
|
-
for (const s of summary) {
|
|
5687
|
-
for (const rw of s.rewards) {
|
|
5688
|
-
const available = Number(rw.available);
|
|
5689
|
-
if (available <= 0) continue;
|
|
5690
|
-
const symbol = rw.coinType.split("::").pop() ?? "UNKNOWN";
|
|
5691
|
-
result.push({
|
|
5692
|
-
protocol: "navi",
|
|
5693
|
-
asset: String(s.assetId),
|
|
5694
|
-
coinType: rw.coinType,
|
|
5695
|
-
symbol,
|
|
5696
|
-
amount: available,
|
|
5697
|
-
estimatedValueUsd: 0
|
|
5698
|
-
});
|
|
5699
|
-
}
|
|
5700
|
-
}
|
|
5701
|
-
return result;
|
|
5656
|
+
const claimable = rewards.filter((r) => Number(r.userClaimableReward) > 0);
|
|
5657
|
+
return aggregateClaimableRewards(claimable);
|
|
5702
5658
|
}
|
|
5703
5659
|
async function addClaimRewardsToTx(tx, client, address) {
|
|
5704
5660
|
let rewards;
|
|
@@ -5748,7 +5704,8 @@ function aggregateClaimableRewards(claimable) {
|
|
|
5748
5704
|
for (const c of claimable) {
|
|
5749
5705
|
const coinType = c.rewardCoinType;
|
|
5750
5706
|
if (!coinType) continue;
|
|
5751
|
-
const
|
|
5707
|
+
const meta = getCoinMeta(coinType);
|
|
5708
|
+
const symbol = meta?.symbol ?? coinType.split("::").pop() ?? "REWARD";
|
|
5752
5709
|
const amount = Number(c.userClaimableReward);
|
|
5753
5710
|
if (!Number.isFinite(amount) || amount <= 0) continue;
|
|
5754
5711
|
const existing = aggregated.get(coinType);
|
|
@@ -7487,6 +7444,183 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
7487
7444
|
// src/index.ts
|
|
7488
7445
|
init_errors();
|
|
7489
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
|
|
7490
7624
|
init_cetus_swap();
|
|
7491
7625
|
init_volo();
|
|
7492
7626
|
init_coinSelection();
|
|
@@ -7686,6 +7820,29 @@ var WRITE_APPENDER_REGISTRY = {
|
|
|
7686
7820
|
const rewards = await addClaimRewardsToTx(tx, ctx.client, ctx.sender);
|
|
7687
7821
|
return { preview: { toolName: "claim_rewards", rewards } };
|
|
7688
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
|
+
},
|
|
7689
7846
|
volo_stake: async (tx, input, ctx) => {
|
|
7690
7847
|
if (input.amountSui <= 0) {
|
|
7691
7848
|
throw new exports.T2000Error("INVALID_AMOUNT", "Stake amount must be greater than zero");
|
|
@@ -8133,15 +8290,18 @@ exports.T2000_OVERLAY_FEE_WALLET = T2000_OVERLAY_FEE_WALLET;
|
|
|
8133
8290
|
exports.USDC_DECIMALS = USDC_DECIMALS;
|
|
8134
8291
|
exports.WRITE_APPENDER_REGISTRY = WRITE_APPENDER_REGISTRY;
|
|
8135
8292
|
exports.ZkLoginSigner = ZkLoginSigner;
|
|
8293
|
+
exports.addClaimRewardsToTx = addClaimRewardsToTx;
|
|
8136
8294
|
exports.addFeeTransfer = addFeeTransfer;
|
|
8137
8295
|
exports.addSendToTx = addSendToTx;
|
|
8138
8296
|
exports.addStakeVSuiToTx = addStakeVSuiToTx;
|
|
8139
8297
|
exports.addSwapToTx = addSwapToTx;
|
|
8140
8298
|
exports.addUnstakeVSuiToTx = addUnstakeVSuiToTx;
|
|
8299
|
+
exports.aggregateClaimableRewards = aggregateClaimableRewards;
|
|
8141
8300
|
exports.allDescriptors = allDescriptors;
|
|
8142
8301
|
exports.assertAllowedAsset = assertAllowedAsset;
|
|
8143
8302
|
exports.buildAddLeafTx = buildAddLeafTx;
|
|
8144
8303
|
exports.buildClaimRewardsTx = buildClaimRewardsTx;
|
|
8304
|
+
exports.buildHarvestRewardsTx = buildHarvestRewardsTx;
|
|
8145
8305
|
exports.buildRevokeLeafTx = buildRevokeLeafTx;
|
|
8146
8306
|
exports.buildSendTx = buildSendTx;
|
|
8147
8307
|
exports.buildStakeVSuiTx = buildStakeVSuiTx;
|