@t2000/sdk 0.6.0 → 0.6.2
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 +60 -27
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.js +60 -27
- package/dist/adapters/index.js.map +1 -1
- package/dist/index.cjs +42 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +42 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/adapters/index.js
CHANGED
|
@@ -3,6 +3,28 @@ import { bcs } from '@mysten/sui/bcs';
|
|
|
3
3
|
import { AggregatorClient, Env } from '@cetusprotocol/aggregator-sdk';
|
|
4
4
|
import { normalizeStructTag } from '@mysten/sui/utils';
|
|
5
5
|
|
|
6
|
+
// src/errors.ts
|
|
7
|
+
var T2000Error = class extends Error {
|
|
8
|
+
code;
|
|
9
|
+
data;
|
|
10
|
+
retryable;
|
|
11
|
+
constructor(code, message, data, retryable = false) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = "T2000Error";
|
|
14
|
+
this.code = code;
|
|
15
|
+
this.data = data;
|
|
16
|
+
this.retryable = retryable;
|
|
17
|
+
}
|
|
18
|
+
toJSON() {
|
|
19
|
+
return {
|
|
20
|
+
error: this.code,
|
|
21
|
+
message: this.message,
|
|
22
|
+
...this.data && { data: this.data },
|
|
23
|
+
retryable: this.retryable
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
6
28
|
// src/adapters/registry.ts
|
|
7
29
|
var ProtocolRegistry = class {
|
|
8
30
|
lending = /* @__PURE__ */ new Map();
|
|
@@ -25,7 +47,7 @@ var ProtocolRegistry = class {
|
|
|
25
47
|
}
|
|
26
48
|
}
|
|
27
49
|
if (candidates.length === 0) {
|
|
28
|
-
throw new
|
|
50
|
+
throw new T2000Error("ASSET_NOT_SUPPORTED", `No lending adapter supports saving ${asset}`);
|
|
29
51
|
}
|
|
30
52
|
candidates.sort((a, b) => b.rate.saveApy - a.rate.saveApy);
|
|
31
53
|
return candidates[0];
|
|
@@ -43,7 +65,7 @@ var ProtocolRegistry = class {
|
|
|
43
65
|
}
|
|
44
66
|
}
|
|
45
67
|
if (candidates.length === 0) {
|
|
46
|
-
throw new
|
|
68
|
+
throw new T2000Error("ASSET_NOT_SUPPORTED", `No lending adapter supports borrowing ${asset}`);
|
|
47
69
|
}
|
|
48
70
|
candidates.sort((a, b) => a.rate.borrowApy - b.rate.borrowApy);
|
|
49
71
|
return candidates[0];
|
|
@@ -60,7 +82,7 @@ var ProtocolRegistry = class {
|
|
|
60
82
|
}
|
|
61
83
|
}
|
|
62
84
|
if (candidates.length === 0) {
|
|
63
|
-
throw new
|
|
85
|
+
throw new T2000Error("ASSET_NOT_SUPPORTED", `No swap adapter supports ${from} \u2192 ${to}`);
|
|
64
86
|
}
|
|
65
87
|
candidates.sort((a, b) => b.quote.expectedOutput - a.quote.expectedOutput);
|
|
66
88
|
return candidates[0];
|
|
@@ -127,28 +149,6 @@ var T2000_TREASURY_ID = process.env.T2000_TREASURY_ID ?? "0x3bb501b8300125dca590
|
|
|
127
149
|
process.env.T2000_API_URL ?? "https://api.t2000.ai";
|
|
128
150
|
var CETUS_USDC_SUI_POOL = "0x51e883ba7c0b566a26cbc8a94cd33eb0abd418a77cc1e60ad22fd9b1f29cd2ab";
|
|
129
151
|
|
|
130
|
-
// src/errors.ts
|
|
131
|
-
var T2000Error = class extends Error {
|
|
132
|
-
code;
|
|
133
|
-
data;
|
|
134
|
-
retryable;
|
|
135
|
-
constructor(code, message, data, retryable = false) {
|
|
136
|
-
super(message);
|
|
137
|
-
this.name = "T2000Error";
|
|
138
|
-
this.code = code;
|
|
139
|
-
this.data = data;
|
|
140
|
-
this.retryable = retryable;
|
|
141
|
-
}
|
|
142
|
-
toJSON() {
|
|
143
|
-
return {
|
|
144
|
-
error: this.code,
|
|
145
|
-
message: this.message,
|
|
146
|
-
...this.data && { data: this.data },
|
|
147
|
-
retryable: this.retryable
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
|
|
152
152
|
// src/utils/format.ts
|
|
153
153
|
function usdcToRaw(amount) {
|
|
154
154
|
return BigInt(Math.round(amount * 10 ** USDC_DECIMALS));
|
|
@@ -250,6 +250,24 @@ async function getUsdcPool() {
|
|
|
250
250
|
if (!usdc) throw new T2000Error("PROTOCOL_UNAVAILABLE", "USDC pool not found on NAVI");
|
|
251
251
|
return usdc;
|
|
252
252
|
}
|
|
253
|
+
function addOracleUpdate(tx, config, pool) {
|
|
254
|
+
const feed = config.oracle.feeds?.find((f2) => f2.assetId === pool.id);
|
|
255
|
+
if (!feed) {
|
|
256
|
+
throw new T2000Error("PROTOCOL_UNAVAILABLE", `Oracle feed not found for asset ${pool.token?.symbol ?? pool.id}`);
|
|
257
|
+
}
|
|
258
|
+
tx.moveCall({
|
|
259
|
+
target: `${config.oracle.packageId}::oracle_pro::update_single_price_v2`,
|
|
260
|
+
arguments: [
|
|
261
|
+
tx.object(CLOCK),
|
|
262
|
+
tx.object(config.oracle.oracleConfig),
|
|
263
|
+
tx.object(config.oracle.priceOracle),
|
|
264
|
+
tx.object(config.oracle.supraOracleHolder),
|
|
265
|
+
tx.object(feed.pythPriceInfoObject),
|
|
266
|
+
tx.object(config.oracle.switchboardAggregator),
|
|
267
|
+
tx.pure.address(feed.feedId)
|
|
268
|
+
]
|
|
269
|
+
});
|
|
270
|
+
}
|
|
253
271
|
function rateToApy(rawRate) {
|
|
254
272
|
if (!rawRate || rawRate === "0") return 0;
|
|
255
273
|
return Number(BigInt(rawRate)) / 10 ** RATE_DECIMALS * 100;
|
|
@@ -272,7 +290,7 @@ function compoundBalance(rawBalance, currentIndex) {
|
|
|
272
290
|
if (!rawBalance || !currentIndex || currentIndex === "0") return 0;
|
|
273
291
|
const scale = BigInt("1" + "0".repeat(RATE_DECIMALS));
|
|
274
292
|
const half = scale / 2n;
|
|
275
|
-
const result = (rawBalance *
|
|
293
|
+
const result = (rawBalance * BigInt(currentIndex) + half) / scale;
|
|
276
294
|
return Number(result) / 10 ** NAVI_BALANCE_DECIMALS;
|
|
277
295
|
}
|
|
278
296
|
async function getUserState(client, address) {
|
|
@@ -315,6 +333,9 @@ function mergeCoins(tx, coins) {
|
|
|
315
333
|
return primary;
|
|
316
334
|
}
|
|
317
335
|
async function buildSaveTx(client, address, amount, options = {}) {
|
|
336
|
+
if (!amount || amount <= 0 || !Number.isFinite(amount)) {
|
|
337
|
+
throw new T2000Error("INVALID_AMOUNT", "Save amount must be a positive number");
|
|
338
|
+
}
|
|
318
339
|
const rawAmount = Number(usdcToRaw(amount));
|
|
319
340
|
const [config, pool] = await Promise.all([getConfig(), getUsdcPool()]);
|
|
320
341
|
const coins = await fetchCoins(client, address, USDC_TYPE);
|
|
@@ -355,6 +376,7 @@ async function buildWithdrawTx(client, address, amount) {
|
|
|
355
376
|
const rawAmount = Number(usdcToRaw(effectiveAmount));
|
|
356
377
|
const tx = new Transaction();
|
|
357
378
|
tx.setSender(address);
|
|
379
|
+
addOracleUpdate(tx, config, pool);
|
|
358
380
|
const [balance] = tx.moveCall({
|
|
359
381
|
target: `${config.package}::incentive_v3::withdraw_v2`,
|
|
360
382
|
arguments: [
|
|
@@ -379,10 +401,14 @@ async function buildWithdrawTx(client, address, amount) {
|
|
|
379
401
|
return { tx, effectiveAmount };
|
|
380
402
|
}
|
|
381
403
|
async function buildBorrowTx(client, address, amount, options = {}) {
|
|
404
|
+
if (!amount || amount <= 0 || !Number.isFinite(amount)) {
|
|
405
|
+
throw new T2000Error("INVALID_AMOUNT", "Borrow amount must be a positive number");
|
|
406
|
+
}
|
|
382
407
|
const rawAmount = Number(usdcToRaw(amount));
|
|
383
408
|
const [config, pool] = await Promise.all([getConfig(), getUsdcPool()]);
|
|
384
409
|
const tx = new Transaction();
|
|
385
410
|
tx.setSender(address);
|
|
411
|
+
addOracleUpdate(tx, config, pool);
|
|
386
412
|
const [balance] = tx.moveCall({
|
|
387
413
|
target: `${config.package}::incentive_v3::borrow_v2`,
|
|
388
414
|
arguments: [
|
|
@@ -403,16 +429,23 @@ async function buildBorrowTx(client, address, amount, options = {}) {
|
|
|
403
429
|
arguments: [balance],
|
|
404
430
|
typeArguments: [pool.suiCoinType]
|
|
405
431
|
});
|
|
432
|
+
if (options.collectFee) {
|
|
433
|
+
addCollectFeeToTx(tx, borrowedCoin, "borrow");
|
|
434
|
+
}
|
|
406
435
|
tx.transferObjects([borrowedCoin], address);
|
|
407
436
|
return tx;
|
|
408
437
|
}
|
|
409
438
|
async function buildRepayTx(client, address, amount) {
|
|
439
|
+
if (!amount || amount <= 0 || !Number.isFinite(amount)) {
|
|
440
|
+
throw new T2000Error("INVALID_AMOUNT", "Repay amount must be a positive number");
|
|
441
|
+
}
|
|
410
442
|
const rawAmount = Number(usdcToRaw(amount));
|
|
411
443
|
const [config, pool] = await Promise.all([getConfig(), getUsdcPool()]);
|
|
412
444
|
const coins = await fetchCoins(client, address, USDC_TYPE);
|
|
413
445
|
if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", "No USDC coins to repay with");
|
|
414
446
|
const tx = new Transaction();
|
|
415
447
|
tx.setSender(address);
|
|
448
|
+
addOracleUpdate(tx, config, pool);
|
|
416
449
|
const coinObj = mergeCoins(tx, coins);
|
|
417
450
|
tx.moveCall({
|
|
418
451
|
target: `${config.package}::incentive_v3::entry_repay`,
|
|
@@ -569,7 +602,7 @@ var NaviAdapter = class {
|
|
|
569
602
|
const rates = await getRates(this.client);
|
|
570
603
|
const key = asset.toUpperCase();
|
|
571
604
|
const r = rates[key];
|
|
572
|
-
if (!r) throw new
|
|
605
|
+
if (!r) throw new T2000Error("ASSET_NOT_SUPPORTED", `NAVI does not support ${asset}`);
|
|
573
606
|
return { asset, saveApy: r.saveApy, borrowApy: r.borrowApy };
|
|
574
607
|
}
|
|
575
608
|
async getPositions(address) {
|