@t2000/sdk 0.19.20 → 0.19.22
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/README.md +0 -9
- package/dist/adapters/descriptors.cjs +68 -0
- package/dist/adapters/descriptors.cjs.map +1 -0
- package/dist/adapters/descriptors.d.cts +3 -0
- package/dist/adapters/descriptors.d.ts +3 -0
- package/dist/adapters/descriptors.js +63 -0
- package/dist/adapters/descriptors.js.map +1 -0
- package/dist/adapters/index.cjs +69 -64
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.d.cts +171 -3
- package/dist/adapters/index.d.ts +171 -3
- package/dist/adapters/index.js +67 -61
- package/dist/adapters/index.js.map +1 -1
- package/dist/browser.js +2 -15
- package/dist/browser.js.map +1 -1
- package/dist/{index-DAxuyiS2.d.cts → descriptors-B6qt_mwi.d.cts} +5 -225
- package/dist/{index-DAxuyiS2.d.ts → descriptors-B6qt_mwi.d.ts} +5 -225
- package/dist/index.cjs +86 -291
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -20
- package/dist/index.d.ts +18 -20
- package/dist/index.js +84 -281
- package/dist/index.js.map +1 -1
- package/package.json +11 -6
package/dist/index.js
CHANGED
|
@@ -9,7 +9,6 @@ import { access, mkdir, writeFile, readFile } from 'fs/promises';
|
|
|
9
9
|
import { join, dirname, resolve } from 'path';
|
|
10
10
|
import { homedir } from 'os';
|
|
11
11
|
import { getPools, getLendingPositions, getHealthFactor as getHealthFactor$1, depositCoinPTB, withdrawCoinPTB, borrowCoinPTB, repayCoinPTB, getUserAvailableLendingRewards, summaryLendingRewards, claimLendingRewardsPTB, updateOraclePriceBeforeUserOperationPTB } from '@naviprotocol/lending';
|
|
12
|
-
import { bcs } from '@mysten/sui/bcs';
|
|
13
12
|
import { AggregatorClient, Env } from '@cetusprotocol/aggregator-sdk';
|
|
14
13
|
import { SuilendClient, LENDING_MARKET_ID, LENDING_MARKET_TYPE } from '@suilend/sdk/client';
|
|
15
14
|
import { initializeSuilend, initializeObligations } from '@suilend/sdk/lib/initialize';
|
|
@@ -133,18 +132,6 @@ var PERPS_MARKETS = ["SUI-PERP"];
|
|
|
133
132
|
var DEFAULT_MAX_LEVERAGE = 5;
|
|
134
133
|
var DEFAULT_MAX_POSITION_SIZE = 1e3;
|
|
135
134
|
var GAS_RESERVE_MIN = 0.05;
|
|
136
|
-
var SENTINEL = {
|
|
137
|
-
PACKAGE: "0x88b83f36dafcd5f6dcdcf1d2cb5889b03f61264ab3cee9cae35db7aa940a21b7",
|
|
138
|
-
AGENT_REGISTRY: "0xc47564f5f14c12b31e0dfa1a3dc99a6380a1edf8929c28cb0eaa3359c8db36ac",
|
|
139
|
-
ENCLAVE: "0xfb1261aeb9583514cb1341a548a5ec12d1231bd96af22215f1792617a93e1213",
|
|
140
|
-
PROTOCOL_CONFIG: "0x2fa4fa4a1dd0498612304635ff9334e1b922e78af325000e9d9c0e88adea459f",
|
|
141
|
-
TEE_API: "https://app.suisentinel.xyz/api/consume-prompt",
|
|
142
|
-
SENTINELS_API: "https://api.suisentinel.xyz/agents/mainnet",
|
|
143
|
-
RANDOM: "0x8",
|
|
144
|
-
MIN_FEE_MIST: 100000000n,
|
|
145
|
-
// 0.1 SUI
|
|
146
|
-
MAX_PROMPT_TOKENS: 600
|
|
147
|
-
};
|
|
148
135
|
|
|
149
136
|
// src/errors.ts
|
|
150
137
|
var T2000Error = class extends Error {
|
|
@@ -557,7 +544,7 @@ async function queryBalance(client, address) {
|
|
|
557
544
|
var SUI_TYPE = "0x2::sui::SUI";
|
|
558
545
|
var KNOWN_TARGETS = [
|
|
559
546
|
[/::suilend|::obligation/, "lending"],
|
|
560
|
-
[/::navi|::
|
|
547
|
+
[/::navi|::incentive_v\d+|::oracle_pro/, "lending"],
|
|
561
548
|
[/::cetus|::pool/, "swap"],
|
|
562
549
|
[/::deepbook/, "swap"],
|
|
563
550
|
[/::transfer::public_transfer/, "send"]
|
|
@@ -711,6 +698,7 @@ function sdkOptions(client) {
|
|
|
711
698
|
return { env: "prod", client, cacheTime: 0, disableCache: true };
|
|
712
699
|
}
|
|
713
700
|
async function refreshOracle(tx, client, address, options) {
|
|
701
|
+
if (options?.skipOracle) return;
|
|
714
702
|
const origInfo = console.info;
|
|
715
703
|
const origWarn = console.warn;
|
|
716
704
|
console.info = (...args) => {
|
|
@@ -878,13 +866,14 @@ async function buildSaveTx(client, address, amount, options = {}) {
|
|
|
878
866
|
const assetInfo = resolveAssetInfo(asset);
|
|
879
867
|
const coins = await fetchCoins(client, address, assetInfo.type);
|
|
880
868
|
if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", `No ${assetInfo.displayName} coins found`);
|
|
869
|
+
const totalBalance = coins.reduce((sum, c) => sum + BigInt(c.balance), 0n);
|
|
881
870
|
const tx = new Transaction();
|
|
882
871
|
tx.setSender(address);
|
|
883
872
|
const coinObj = mergeCoins(tx, coins);
|
|
884
873
|
if (options.collectFee) {
|
|
885
874
|
addCollectFeeToTx(tx, coinObj, "save");
|
|
886
875
|
}
|
|
887
|
-
const rawAmount = Number(stableToRaw(amount, assetInfo.decimals));
|
|
876
|
+
const rawAmount = Math.min(Number(stableToRaw(amount, assetInfo.decimals)), Number(totalBalance));
|
|
888
877
|
try {
|
|
889
878
|
await depositCoinPTB(tx, assetInfo.type, coinObj, {
|
|
890
879
|
...sdkOptions(client),
|
|
@@ -925,6 +914,7 @@ async function buildWithdrawTx(client, address, amount, options = {}) {
|
|
|
925
914
|
}
|
|
926
915
|
async function addWithdrawToTx(tx, client, address, amount, options = {}) {
|
|
927
916
|
const asset = options.asset ?? "USDC";
|
|
917
|
+
const sponsored = options.sponsored ?? true;
|
|
928
918
|
const assetInfo = resolveAssetInfo(asset);
|
|
929
919
|
const posResult = await getPositions(client, address);
|
|
930
920
|
const supply = posResult.positions.find(
|
|
@@ -942,7 +932,7 @@ async function addWithdrawToTx(tx, client, address, amount, options = {}) {
|
|
|
942
932
|
});
|
|
943
933
|
return { coin, effectiveAmount: 0 };
|
|
944
934
|
}
|
|
945
|
-
await refreshOracle(tx, client, address);
|
|
935
|
+
await refreshOracle(tx, client, address, { skipPythUpdate: sponsored });
|
|
946
936
|
try {
|
|
947
937
|
const coin = await withdrawCoinPTB(tx, assetInfo.type, rawAmount, sdkOptions(client));
|
|
948
938
|
return { coin, effectiveAmount };
|
|
@@ -966,8 +956,9 @@ async function addSaveToTx(tx, _client, _address, coin, options = {}) {
|
|
|
966
956
|
}
|
|
967
957
|
async function addRepayToTx(tx, client, address, coin, options = {}) {
|
|
968
958
|
const asset = options.asset ?? "USDC";
|
|
959
|
+
const sponsored = options.sponsored ?? true;
|
|
969
960
|
const assetInfo = resolveAssetInfo(asset);
|
|
970
|
-
await refreshOracle(tx, client, address);
|
|
961
|
+
await refreshOracle(tx, client, address, { skipPythUpdate: sponsored });
|
|
971
962
|
try {
|
|
972
963
|
await repayCoinPTB(tx, assetInfo.type, coin, { env: "prod" });
|
|
973
964
|
} catch (err) {
|
|
@@ -1005,12 +996,16 @@ async function buildRepayTx(client, address, amount, options = {}) {
|
|
|
1005
996
|
const assetInfo = resolveAssetInfo(asset);
|
|
1006
997
|
const coins = await fetchCoins(client, address, assetInfo.type);
|
|
1007
998
|
if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", `No ${assetInfo.displayName} coins to repay with`);
|
|
999
|
+
const totalBalance = coins.reduce((sum, c) => sum + BigInt(c.balance), 0n);
|
|
1008
1000
|
const tx = new Transaction();
|
|
1009
1001
|
tx.setSender(address);
|
|
1010
1002
|
const coinObj = mergeCoins(tx, coins);
|
|
1011
|
-
const rawAmount = Number(stableToRaw(amount, assetInfo.decimals));
|
|
1003
|
+
const rawAmount = Math.min(Number(stableToRaw(amount, assetInfo.decimals)), Number(totalBalance));
|
|
1012
1004
|
const [repayCoin] = tx.splitCoins(coinObj, [rawAmount]);
|
|
1013
|
-
await refreshOracle(tx, client, address, {
|
|
1005
|
+
await refreshOracle(tx, client, address, {
|
|
1006
|
+
skipPythUpdate: options.sponsored,
|
|
1007
|
+
skipOracle: options.skipOracle
|
|
1008
|
+
});
|
|
1014
1009
|
try {
|
|
1015
1010
|
await repayCoinPTB(tx, assetInfo.type, repayCoin, {
|
|
1016
1011
|
...sdkOptions(client),
|
|
@@ -1124,206 +1119,6 @@ async function getFundStatus(client, address) {
|
|
|
1124
1119
|
projectedMonthly: earnings.dailyEarning * 30
|
|
1125
1120
|
};
|
|
1126
1121
|
}
|
|
1127
|
-
var descriptor = {
|
|
1128
|
-
id: "sentinel",
|
|
1129
|
-
name: "Sui Sentinel",
|
|
1130
|
-
packages: [SENTINEL.PACKAGE],
|
|
1131
|
-
actionMap: {
|
|
1132
|
-
"sentinel::request_attack": "sentinel_attack",
|
|
1133
|
-
"sentinel::consume_prompt": "sentinel_settle"
|
|
1134
|
-
}
|
|
1135
|
-
};
|
|
1136
|
-
function mapAgent(raw) {
|
|
1137
|
-
return {
|
|
1138
|
-
id: raw.agent_id,
|
|
1139
|
-
objectId: raw.agent_object_id,
|
|
1140
|
-
name: raw.agent_name,
|
|
1141
|
-
model: raw.model ?? "unknown",
|
|
1142
|
-
systemPrompt: raw.prompt,
|
|
1143
|
-
attackFee: BigInt(raw.cost_per_message),
|
|
1144
|
-
prizePool: BigInt(raw.total_balance),
|
|
1145
|
-
totalAttacks: raw.total_attacks,
|
|
1146
|
-
successfulBreaches: raw.successful_breaches ?? 0,
|
|
1147
|
-
state: raw.state
|
|
1148
|
-
};
|
|
1149
|
-
}
|
|
1150
|
-
async function listSentinels() {
|
|
1151
|
-
const res = await fetch(SENTINEL.SENTINELS_API);
|
|
1152
|
-
if (!res.ok) {
|
|
1153
|
-
throw new T2000Error("SENTINEL_API_ERROR", `Sentinel API returned ${res.status}`);
|
|
1154
|
-
}
|
|
1155
|
-
const data = await res.json();
|
|
1156
|
-
if (!Array.isArray(data.agents)) {
|
|
1157
|
-
throw new T2000Error("SENTINEL_API_ERROR", "Unexpected API response shape");
|
|
1158
|
-
}
|
|
1159
|
-
return data.agents.filter((a) => a.state === "active").map(mapAgent);
|
|
1160
|
-
}
|
|
1161
|
-
async function getSentinelInfo(client, sentinelObjectId) {
|
|
1162
|
-
const agents = await listSentinels();
|
|
1163
|
-
const match = agents.find((a) => a.objectId === sentinelObjectId || a.id === sentinelObjectId);
|
|
1164
|
-
if (match) return match;
|
|
1165
|
-
const obj = await client.getObject({
|
|
1166
|
-
id: sentinelObjectId,
|
|
1167
|
-
options: { showContent: true, showType: true }
|
|
1168
|
-
});
|
|
1169
|
-
if (!obj.data) {
|
|
1170
|
-
throw new T2000Error("SENTINEL_NOT_FOUND", `Sentinel ${sentinelObjectId} not found on-chain`);
|
|
1171
|
-
}
|
|
1172
|
-
const content = obj.data.content;
|
|
1173
|
-
if (!content || content.dataType !== "moveObject") {
|
|
1174
|
-
throw new T2000Error("SENTINEL_NOT_FOUND", `Object ${sentinelObjectId} is not a Move object`);
|
|
1175
|
-
}
|
|
1176
|
-
const fields = content.fields;
|
|
1177
|
-
return {
|
|
1178
|
-
id: fields.id?.id ?? sentinelObjectId,
|
|
1179
|
-
objectId: sentinelObjectId,
|
|
1180
|
-
name: fields.name ?? "Unknown",
|
|
1181
|
-
model: fields.model ?? "unknown",
|
|
1182
|
-
systemPrompt: fields.system_prompt ?? "",
|
|
1183
|
-
attackFee: BigInt(fields.cost_per_message ?? "0"),
|
|
1184
|
-
prizePool: BigInt(fields.balance ?? "0"),
|
|
1185
|
-
totalAttacks: Number(fields.total_attacks ?? "0"),
|
|
1186
|
-
successfulBreaches: Number(fields.successful_breaches ?? "0"),
|
|
1187
|
-
state: fields.state ?? "unknown"
|
|
1188
|
-
};
|
|
1189
|
-
}
|
|
1190
|
-
async function requestAttack(client, signer, sentinelObjectId, feeMist) {
|
|
1191
|
-
if (feeMist < SENTINEL.MIN_FEE_MIST) {
|
|
1192
|
-
throw new T2000Error("INVALID_AMOUNT", `Attack fee must be at least 0.1 SUI (${SENTINEL.MIN_FEE_MIST} MIST)`);
|
|
1193
|
-
}
|
|
1194
|
-
const address = signer.getAddress();
|
|
1195
|
-
const tx = new Transaction();
|
|
1196
|
-
tx.setSender(address);
|
|
1197
|
-
const [coin] = tx.splitCoins(tx.gas, [Number(feeMist)]);
|
|
1198
|
-
const [attack2] = tx.moveCall({
|
|
1199
|
-
target: `${SENTINEL.PACKAGE}::sentinel::request_attack`,
|
|
1200
|
-
arguments: [
|
|
1201
|
-
tx.object(SENTINEL.AGENT_REGISTRY),
|
|
1202
|
-
tx.object(sentinelObjectId),
|
|
1203
|
-
tx.object(SENTINEL.PROTOCOL_CONFIG),
|
|
1204
|
-
coin,
|
|
1205
|
-
tx.object(SENTINEL.RANDOM),
|
|
1206
|
-
tx.object(CLOCK_ID)
|
|
1207
|
-
]
|
|
1208
|
-
});
|
|
1209
|
-
tx.transferObjects([attack2], address);
|
|
1210
|
-
const built = await tx.build({ client });
|
|
1211
|
-
const { signature } = await signer.signTransaction(built);
|
|
1212
|
-
const result = await client.executeTransactionBlock({
|
|
1213
|
-
transactionBlock: built,
|
|
1214
|
-
signature,
|
|
1215
|
-
options: { showObjectChanges: true, showEffects: true }
|
|
1216
|
-
});
|
|
1217
|
-
await client.waitForTransaction({ digest: result.digest });
|
|
1218
|
-
const attackObj = result.objectChanges?.find(
|
|
1219
|
-
(c) => c.type === "created" && c.objectType?.includes("::sentinel::Attack")
|
|
1220
|
-
);
|
|
1221
|
-
const attackObjectId = attackObj && "objectId" in attackObj ? attackObj.objectId : void 0;
|
|
1222
|
-
if (!attackObjectId) {
|
|
1223
|
-
throw new T2000Error("SENTINEL_TX_FAILED", "Attack object was not created \u2014 transaction may have failed");
|
|
1224
|
-
}
|
|
1225
|
-
return { attackObjectId, digest: result.digest };
|
|
1226
|
-
}
|
|
1227
|
-
async function submitPrompt(agentId, attackObjectId, prompt) {
|
|
1228
|
-
const res = await fetch(SENTINEL.TEE_API, {
|
|
1229
|
-
method: "POST",
|
|
1230
|
-
headers: { "Content-Type": "application/json" },
|
|
1231
|
-
body: JSON.stringify({
|
|
1232
|
-
agent_id: agentId,
|
|
1233
|
-
attack_object_id: attackObjectId,
|
|
1234
|
-
message: prompt
|
|
1235
|
-
})
|
|
1236
|
-
});
|
|
1237
|
-
if (!res.ok) {
|
|
1238
|
-
const body = await res.text().catch(() => "");
|
|
1239
|
-
throw new T2000Error("SENTINEL_TEE_ERROR", `TEE returned ${res.status}: ${body.slice(0, 200)}`);
|
|
1240
|
-
}
|
|
1241
|
-
const raw = await res.json();
|
|
1242
|
-
const envelope = raw.response ?? raw;
|
|
1243
|
-
const data = envelope.data ?? envelope;
|
|
1244
|
-
const signature = raw.signature ?? data.signature;
|
|
1245
|
-
const timestampMs = envelope.timestamp_ms ?? data.timestamp_ms;
|
|
1246
|
-
if (typeof signature !== "string") {
|
|
1247
|
-
throw new T2000Error("SENTINEL_TEE_ERROR", "TEE response missing signature");
|
|
1248
|
-
}
|
|
1249
|
-
return {
|
|
1250
|
-
success: data.success ?? data.is_success,
|
|
1251
|
-
score: data.score,
|
|
1252
|
-
agentResponse: data.agent_response,
|
|
1253
|
-
juryResponse: data.jury_response,
|
|
1254
|
-
funResponse: data.fun_response ?? "",
|
|
1255
|
-
signature,
|
|
1256
|
-
timestampMs
|
|
1257
|
-
};
|
|
1258
|
-
}
|
|
1259
|
-
async function settleAttack(client, signer, sentinelObjectId, attackObjectId, prompt, verdict) {
|
|
1260
|
-
const sigBytes = Array.from(Buffer.from(verdict.signature.replace(/^0x/, ""), "hex"));
|
|
1261
|
-
const address = signer.getAddress();
|
|
1262
|
-
const tx = new Transaction();
|
|
1263
|
-
tx.setSender(address);
|
|
1264
|
-
tx.moveCall({
|
|
1265
|
-
target: `${SENTINEL.PACKAGE}::sentinel::consume_prompt`,
|
|
1266
|
-
arguments: [
|
|
1267
|
-
tx.object(SENTINEL.AGENT_REGISTRY),
|
|
1268
|
-
tx.object(SENTINEL.PROTOCOL_CONFIG),
|
|
1269
|
-
tx.object(sentinelObjectId),
|
|
1270
|
-
tx.pure.bool(verdict.success),
|
|
1271
|
-
tx.pure.string(verdict.agentResponse),
|
|
1272
|
-
tx.pure.string(verdict.juryResponse),
|
|
1273
|
-
tx.pure.string(verdict.funResponse),
|
|
1274
|
-
tx.pure.string(prompt),
|
|
1275
|
-
tx.pure.u8(verdict.score),
|
|
1276
|
-
tx.pure.u64(verdict.timestampMs),
|
|
1277
|
-
tx.pure(bcs.vector(bcs.u8()).serialize(sigBytes)),
|
|
1278
|
-
tx.object(SENTINEL.ENCLAVE),
|
|
1279
|
-
tx.object(attackObjectId),
|
|
1280
|
-
tx.object(CLOCK_ID)
|
|
1281
|
-
]
|
|
1282
|
-
});
|
|
1283
|
-
const built = await tx.build({ client });
|
|
1284
|
-
const { signature } = await signer.signTransaction(built);
|
|
1285
|
-
const result = await client.executeTransactionBlock({
|
|
1286
|
-
transactionBlock: built,
|
|
1287
|
-
signature,
|
|
1288
|
-
options: { showEffects: true }
|
|
1289
|
-
});
|
|
1290
|
-
await client.waitForTransaction({ digest: result.digest });
|
|
1291
|
-
const txSuccess = result.effects?.status?.status === "success";
|
|
1292
|
-
return { digest: result.digest, success: txSuccess };
|
|
1293
|
-
}
|
|
1294
|
-
async function attack(client, signer, sentinelId, prompt, feeMist) {
|
|
1295
|
-
const sentinel = await getSentinelInfo(client, sentinelId);
|
|
1296
|
-
const fee = feeMist ?? sentinel.attackFee;
|
|
1297
|
-
if (fee < SENTINEL.MIN_FEE_MIST) {
|
|
1298
|
-
throw new T2000Error("INVALID_AMOUNT", `Attack fee must be at least 0.1 SUI`);
|
|
1299
|
-
}
|
|
1300
|
-
const { attackObjectId, digest: requestTx } = await requestAttack(
|
|
1301
|
-
client,
|
|
1302
|
-
signer,
|
|
1303
|
-
sentinel.objectId,
|
|
1304
|
-
fee
|
|
1305
|
-
);
|
|
1306
|
-
const verdict = await submitPrompt(sentinel.id, attackObjectId, prompt);
|
|
1307
|
-
const { digest: settleTx } = await settleAttack(
|
|
1308
|
-
client,
|
|
1309
|
-
signer,
|
|
1310
|
-
sentinel.objectId,
|
|
1311
|
-
attackObjectId,
|
|
1312
|
-
prompt,
|
|
1313
|
-
verdict
|
|
1314
|
-
);
|
|
1315
|
-
const won = verdict.success && verdict.score >= 70;
|
|
1316
|
-
return {
|
|
1317
|
-
attackObjectId,
|
|
1318
|
-
sentinelId: sentinel.id,
|
|
1319
|
-
prompt,
|
|
1320
|
-
verdict,
|
|
1321
|
-
requestTx,
|
|
1322
|
-
settleTx,
|
|
1323
|
-
won,
|
|
1324
|
-
feePaid: Number(fee) / Number(MIST_PER_SUI)
|
|
1325
|
-
};
|
|
1326
|
-
}
|
|
1327
1122
|
|
|
1328
1123
|
// src/adapters/registry.ts
|
|
1329
1124
|
var ProtocolRegistry = class {
|
|
@@ -1470,8 +1265,9 @@ var ProtocolRegistry = class {
|
|
|
1470
1265
|
}
|
|
1471
1266
|
};
|
|
1472
1267
|
|
|
1473
|
-
// src/adapters/
|
|
1474
|
-
var
|
|
1268
|
+
// src/adapters/descriptors.ts
|
|
1269
|
+
var SUILEND_PACKAGE = "0xf95b06141ed4a174f239417323bde3f209b972f5930d8521ea38a52aff3a6ddf";
|
|
1270
|
+
var naviDescriptor = {
|
|
1475
1271
|
id: "navi",
|
|
1476
1272
|
name: "NAVI Protocol",
|
|
1477
1273
|
packages: [],
|
|
@@ -1487,6 +1283,42 @@ var descriptor2 = {
|
|
|
1487
1283
|
"incentive_v3::repay": "repay"
|
|
1488
1284
|
}
|
|
1489
1285
|
};
|
|
1286
|
+
var suilendDescriptor = {
|
|
1287
|
+
id: "suilend",
|
|
1288
|
+
name: "Suilend",
|
|
1289
|
+
packages: [SUILEND_PACKAGE],
|
|
1290
|
+
actionMap: {
|
|
1291
|
+
"lending_market::deposit_liquidity_and_mint_ctokens": "save",
|
|
1292
|
+
"lending_market::deposit_ctokens_into_obligation": "save",
|
|
1293
|
+
"lending_market::create_obligation": "save",
|
|
1294
|
+
"lending_market::withdraw_ctokens": "withdraw",
|
|
1295
|
+
"lending_market::redeem_ctokens_and_withdraw_liquidity": "withdraw",
|
|
1296
|
+
"lending_market::redeem_ctokens_and_withdraw_liquidity_request": "withdraw",
|
|
1297
|
+
"lending_market::fulfill_liquidity_request": "withdraw",
|
|
1298
|
+
"lending_market::unstake_sui_from_staker": "withdraw",
|
|
1299
|
+
"lending_market::borrow": "borrow",
|
|
1300
|
+
"lending_market::repay": "repay"
|
|
1301
|
+
}
|
|
1302
|
+
};
|
|
1303
|
+
var cetusDescriptor = {
|
|
1304
|
+
id: "cetus",
|
|
1305
|
+
name: "Cetus DEX",
|
|
1306
|
+
packages: [CETUS_PACKAGE],
|
|
1307
|
+
actionMap: {
|
|
1308
|
+
"router::swap": "swap",
|
|
1309
|
+
"router::swap_ab_bc": "swap",
|
|
1310
|
+
"router::swap_ab_cb": "swap",
|
|
1311
|
+
"router::swap_ba_bc": "swap",
|
|
1312
|
+
"router::swap_ba_cb": "swap"
|
|
1313
|
+
}
|
|
1314
|
+
};
|
|
1315
|
+
var allDescriptors = [
|
|
1316
|
+
naviDescriptor,
|
|
1317
|
+
suilendDescriptor,
|
|
1318
|
+
cetusDescriptor
|
|
1319
|
+
];
|
|
1320
|
+
|
|
1321
|
+
// src/adapters/navi.ts
|
|
1490
1322
|
var NaviAdapter = class {
|
|
1491
1323
|
id = "navi";
|
|
1492
1324
|
name = "NAVI Protocol";
|
|
@@ -1535,7 +1367,11 @@ var NaviAdapter = class {
|
|
|
1535
1367
|
}
|
|
1536
1368
|
async buildRepayTx(address, amount, asset, options) {
|
|
1537
1369
|
const normalized = normalizeAsset(asset);
|
|
1538
|
-
const tx = await buildRepayTx(this.client, address, amount, {
|
|
1370
|
+
const tx = await buildRepayTx(this.client, address, amount, {
|
|
1371
|
+
asset: normalized,
|
|
1372
|
+
sponsored: options?.sponsored,
|
|
1373
|
+
skipOracle: options?.skipOracle
|
|
1374
|
+
});
|
|
1539
1375
|
return { tx };
|
|
1540
1376
|
}
|
|
1541
1377
|
async maxWithdraw(address, _asset) {
|
|
@@ -1762,18 +1598,6 @@ function fallbackQuote(fromAsset, amount, poolPrice) {
|
|
|
1762
1598
|
}
|
|
1763
1599
|
|
|
1764
1600
|
// src/adapters/cetus.ts
|
|
1765
|
-
var descriptor3 = {
|
|
1766
|
-
id: "cetus",
|
|
1767
|
-
name: "Cetus DEX",
|
|
1768
|
-
packages: [CETUS_PACKAGE],
|
|
1769
|
-
actionMap: {
|
|
1770
|
-
"router::swap": "swap",
|
|
1771
|
-
"router::swap_ab_bc": "swap",
|
|
1772
|
-
"router::swap_ab_cb": "swap",
|
|
1773
|
-
"router::swap_ba_bc": "swap",
|
|
1774
|
-
"router::swap_ba_cb": "swap"
|
|
1775
|
-
}
|
|
1776
|
-
};
|
|
1777
1601
|
var CetusAdapter = class {
|
|
1778
1602
|
id = "cetus";
|
|
1779
1603
|
name = "Cetus";
|
|
@@ -1832,7 +1656,6 @@ var CetusAdapter = class {
|
|
|
1832
1656
|
});
|
|
1833
1657
|
}
|
|
1834
1658
|
};
|
|
1835
|
-
var SUILEND_PACKAGE = "0xf95b06141ed4a174f239417323bde3f209b972f5930d8521ea38a52aff3a6ddf";
|
|
1836
1659
|
var MIN_HEALTH_FACTOR2 = 1.5;
|
|
1837
1660
|
async function quietSuilend(fn) {
|
|
1838
1661
|
const origLog = console.log;
|
|
@@ -1849,23 +1672,6 @@ async function quietSuilend(fn) {
|
|
|
1849
1672
|
console.warn = origWarn;
|
|
1850
1673
|
});
|
|
1851
1674
|
}
|
|
1852
|
-
var descriptor4 = {
|
|
1853
|
-
id: "suilend",
|
|
1854
|
-
name: "Suilend",
|
|
1855
|
-
packages: [SUILEND_PACKAGE],
|
|
1856
|
-
actionMap: {
|
|
1857
|
-
"lending_market::deposit_liquidity_and_mint_ctokens": "save",
|
|
1858
|
-
"lending_market::deposit_ctokens_into_obligation": "save",
|
|
1859
|
-
"lending_market::create_obligation": "save",
|
|
1860
|
-
"lending_market::withdraw_ctokens": "withdraw",
|
|
1861
|
-
"lending_market::redeem_ctokens_and_withdraw_liquidity": "withdraw",
|
|
1862
|
-
"lending_market::redeem_ctokens_and_withdraw_liquidity_request": "withdraw",
|
|
1863
|
-
"lending_market::fulfill_liquidity_request": "withdraw",
|
|
1864
|
-
"lending_market::unstake_sui_from_staker": "withdraw",
|
|
1865
|
-
"lending_market::borrow": "borrow",
|
|
1866
|
-
"lending_market::repay": "repay"
|
|
1867
|
-
}
|
|
1868
|
-
};
|
|
1869
1675
|
var SuilendAdapter = class {
|
|
1870
1676
|
id = "suilend";
|
|
1871
1677
|
name = "Suilend";
|
|
@@ -2208,16 +2014,23 @@ var SuilendAdapter = class {
|
|
|
2208
2014
|
if (obligationOwnerCaps.length === 0 || obligations.length === 0) return [];
|
|
2209
2015
|
const ob = obligations[0];
|
|
2210
2016
|
const rewards = [];
|
|
2017
|
+
const WAD = 1e18;
|
|
2211
2018
|
for (const dep of ob.deposits) {
|
|
2212
|
-
|
|
2019
|
+
const urm = dep.userRewardManager;
|
|
2020
|
+
for (const rw of dep.reserve.depositsPoolRewardManager?.poolRewards ?? []) {
|
|
2213
2021
|
if (rw.endTimeMs <= Date.now()) continue;
|
|
2022
|
+
let claimableAmount = 0;
|
|
2023
|
+
const userReward = urm?.rewards?.[rw.rewardIndex];
|
|
2024
|
+
if (userReward?.earnedRewards) {
|
|
2025
|
+
claimableAmount = Number(BigInt(userReward.earnedRewards.value.toString())) / WAD / 10 ** rw.mintDecimals;
|
|
2026
|
+
}
|
|
2214
2027
|
const symbol = rw.symbol || rw.coinType.split("::").pop() || "UNKNOWN";
|
|
2215
2028
|
rewards.push({
|
|
2216
2029
|
protocol: "suilend",
|
|
2217
2030
|
asset: this.resolveSymbol(dep.coinType),
|
|
2218
2031
|
coinType: rw.coinType,
|
|
2219
2032
|
symbol,
|
|
2220
|
-
amount:
|
|
2033
|
+
amount: claimableAmount,
|
|
2221
2034
|
estimatedValueUsd: 0
|
|
2222
2035
|
});
|
|
2223
2036
|
}
|
|
@@ -2666,8 +2479,7 @@ async function resolveGas(client, signer, buildTx) {
|
|
|
2666
2479
|
// src/safeguards/types.ts
|
|
2667
2480
|
var OUTBOUND_OPS = /* @__PURE__ */ new Set([
|
|
2668
2481
|
"send",
|
|
2669
|
-
"pay"
|
|
2670
|
-
"sentinel"
|
|
2482
|
+
"pay"
|
|
2671
2483
|
]);
|
|
2672
2484
|
var DEFAULT_SAFEGUARD_CONFIG = {
|
|
2673
2485
|
locked: false,
|
|
@@ -2901,6 +2713,7 @@ var ContactManager = class {
|
|
|
2901
2713
|
}
|
|
2902
2714
|
}
|
|
2903
2715
|
};
|
|
2716
|
+
var UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
2904
2717
|
function emptyData() {
|
|
2905
2718
|
return { positions: {}, strategies: {}, realizedPnL: 0 };
|
|
2906
2719
|
}
|
|
@@ -3056,25 +2869,34 @@ var PortfolioManager = class {
|
|
|
3056
2869
|
}
|
|
3057
2870
|
// --- Strategy position tracking ---
|
|
3058
2871
|
recordStrategyBuy(strategyKey, trade) {
|
|
2872
|
+
if (UNSAFE_KEYS.has(strategyKey) || UNSAFE_KEYS.has(trade.asset)) {
|
|
2873
|
+
throw new T2000Error("ASSET_NOT_SUPPORTED", "Invalid strategy key or asset name");
|
|
2874
|
+
}
|
|
3059
2875
|
this.load();
|
|
3060
|
-
if (!this.data.strategies
|
|
3061
|
-
this.data.strategies[strategyKey] =
|
|
2876
|
+
if (!Object.hasOwn(this.data.strategies, strategyKey)) {
|
|
2877
|
+
this.data.strategies[strategyKey] = /* @__PURE__ */ Object.create(null);
|
|
3062
2878
|
}
|
|
3063
2879
|
const bucket = this.data.strategies[strategyKey];
|
|
3064
|
-
const pos = bucket[trade.asset]
|
|
2880
|
+
const pos = Object.hasOwn(bucket, trade.asset) ? bucket[trade.asset] : { totalAmount: 0, costBasis: 0, avgPrice: 0, trades: [] };
|
|
3065
2881
|
pos.totalAmount += trade.amount;
|
|
3066
2882
|
pos.costBasis += trade.usdValue;
|
|
3067
2883
|
pos.avgPrice = pos.costBasis / pos.totalAmount;
|
|
3068
2884
|
pos.trades.push(trade);
|
|
3069
|
-
bucket
|
|
2885
|
+
Object.defineProperty(bucket, trade.asset, { value: pos, writable: true, enumerable: true, configurable: true });
|
|
3070
2886
|
this.save();
|
|
3071
2887
|
}
|
|
3072
2888
|
recordStrategySell(strategyKey, trade) {
|
|
2889
|
+
if (UNSAFE_KEYS.has(strategyKey) || UNSAFE_KEYS.has(trade.asset)) {
|
|
2890
|
+
throw new T2000Error("ASSET_NOT_SUPPORTED", "Invalid strategy key or asset name");
|
|
2891
|
+
}
|
|
3073
2892
|
this.load();
|
|
3074
2893
|
const bucket = this.data.strategies[strategyKey];
|
|
3075
2894
|
if (!bucket) {
|
|
3076
2895
|
throw new T2000Error("STRATEGY_NOT_FOUND", `No positions for strategy '${strategyKey}'`);
|
|
3077
2896
|
}
|
|
2897
|
+
if (!Object.hasOwn(bucket, trade.asset)) {
|
|
2898
|
+
throw new T2000Error("INSUFFICIENT_INVESTMENT", `No ${trade.asset} position in strategy '${strategyKey}'`);
|
|
2899
|
+
}
|
|
3078
2900
|
const pos = bucket[trade.asset];
|
|
3079
2901
|
if (!pos || pos.totalAmount <= 0) {
|
|
3080
2902
|
throw new T2000Error("INSUFFICIENT_INVESTMENT", `No ${trade.asset} position in strategy '${strategyKey}'`);
|
|
@@ -3091,7 +2913,7 @@ var PortfolioManager = class {
|
|
|
3091
2913
|
pos.avgPrice = 0;
|
|
3092
2914
|
}
|
|
3093
2915
|
pos.trades.push(trade);
|
|
3094
|
-
bucket
|
|
2916
|
+
Object.defineProperty(bucket, trade.asset, { value: pos, writable: true, enumerable: true, configurable: true });
|
|
3095
2917
|
const hasPositions = Object.values(bucket).some((p) => p.totalAmount > 0);
|
|
3096
2918
|
if (!hasPositions) {
|
|
3097
2919
|
delete this.data.strategies[strategyKey];
|
|
@@ -5925,17 +5747,6 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
5925
5747
|
async fundStatus() {
|
|
5926
5748
|
return getFundStatus(this.client, this._address);
|
|
5927
5749
|
}
|
|
5928
|
-
// -- Sentinel --
|
|
5929
|
-
async sentinelList() {
|
|
5930
|
-
return listSentinels();
|
|
5931
|
-
}
|
|
5932
|
-
async sentinelInfo(id) {
|
|
5933
|
-
return getSentinelInfo(this.client, id);
|
|
5934
|
-
}
|
|
5935
|
-
async sentinelAttack(id, prompt, fee) {
|
|
5936
|
-
this.enforcer.check({ operation: "sentinel", amount: fee ? Number(fee) / 1e9 : 0.1 });
|
|
5937
|
-
return attack(this.client, this._signer, id, prompt, fee);
|
|
5938
|
-
}
|
|
5939
5750
|
// -- Helpers --
|
|
5940
5751
|
async getFreeBalance(asset) {
|
|
5941
5752
|
if (!(asset in INVESTMENT_ASSETS)) return Infinity;
|
|
@@ -6088,14 +5899,6 @@ function parseMoveAbort(errorStr) {
|
|
|
6088
5899
|
return { reason: errorStr };
|
|
6089
5900
|
}
|
|
6090
5901
|
|
|
6091
|
-
|
|
6092
|
-
var allDescriptors = [
|
|
6093
|
-
descriptor2,
|
|
6094
|
-
descriptor4,
|
|
6095
|
-
descriptor3,
|
|
6096
|
-
descriptor
|
|
6097
|
-
];
|
|
6098
|
-
|
|
6099
|
-
export { AutoInvestManager, BPS_DENOMINATOR, CLOCK_ID, CetusAdapter, ContactManager, DEFAULT_MAX_LEVERAGE, DEFAULT_MAX_POSITION_SIZE, DEFAULT_NETWORK, DEFAULT_SAFEGUARD_CONFIG, DEFAULT_STRATEGIES, GAS_RESERVE_MIN, INVESTMENT_ASSETS, KeypairSigner, MIST_PER_SUI, NaviAdapter, OUTBOUND_OPS, PERPS_MARKETS, PortfolioManager, ProtocolRegistry, SENTINEL, STABLE_ASSETS, SUI_DECIMALS, SUPPORTED_ASSETS, SafeguardEnforcer, SafeguardError, StrategyManager, SuilendAdapter, T2000, T2000Error, USDC_DECIMALS, ZkLoginSigner, addCollectFeeToTx, allDescriptors, calculateFee, descriptor3 as cetusDescriptor, executeAutoTopUp, executeWithGas, exportPrivateKey, formatAssetAmount, formatSui, formatUsd, generateKeypair, getAddress, getDecimals, getGasStatus, getPoolPrice, getRates, getSentinelInfo, keypairFromPrivateKey, listSentinels, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, descriptor2 as naviDescriptor, rawToStable, rawToUsdc, requestAttack, saveKey, attack as sentinelAttack, descriptor as sentinelDescriptor, settleAttack, shouldAutoTopUp, simulateTransaction, solveHashcash, stableToRaw, submitPrompt, suiToMist, descriptor4 as suilendDescriptor, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
|
|
5902
|
+
export { AutoInvestManager, BPS_DENOMINATOR, CLOCK_ID, CetusAdapter, ContactManager, DEFAULT_MAX_LEVERAGE, DEFAULT_MAX_POSITION_SIZE, DEFAULT_NETWORK, DEFAULT_SAFEGUARD_CONFIG, DEFAULT_STRATEGIES, GAS_RESERVE_MIN, INVESTMENT_ASSETS, KeypairSigner, MIST_PER_SUI, NaviAdapter, OUTBOUND_OPS, PERPS_MARKETS, PortfolioManager, ProtocolRegistry, STABLE_ASSETS, SUI_DECIMALS, SUPPORTED_ASSETS, SafeguardEnforcer, SafeguardError, StrategyManager, SuilendAdapter, T2000, T2000Error, USDC_DECIMALS, ZkLoginSigner, addCollectFeeToTx, allDescriptors, calculateFee, cetusDescriptor, executeAutoTopUp, executeWithGas, exportPrivateKey, formatAssetAmount, formatSui, formatUsd, generateKeypair, getAddress, getDecimals, getGasStatus, getPoolPrice, getRates, keypairFromPrivateKey, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, naviDescriptor, rawToStable, rawToUsdc, saveKey, shouldAutoTopUp, simulateTransaction, solveHashcash, stableToRaw, suiToMist, suilendDescriptor, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
|
|
6100
5903
|
//# sourceMappingURL=index.js.map
|
|
6101
5904
|
//# sourceMappingURL=index.js.map
|