@t2000/sdk 5.5.0 → 5.6.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/browser.cjs +164 -4
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +158 -7
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +134 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -87
- package/dist/index.d.ts +38 -87
- package/dist/index.js +128 -61
- package/dist/index.js.map +1 -1
- package/dist/{simulate-KETPmlDo.d.cts → send-D2nKpwJN.d.cts} +162 -21
- package/dist/{simulate-KETPmlDo.d.ts → send-D2nKpwJN.d.ts} +162 -21
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizeStructTag, isValidSuiAddress, normalizeSuiAddress, fromBase64 } from '@mysten/sui/utils';
|
|
1
2
|
import { coinWithBalance, Transaction } from '@mysten/sui/transactions';
|
|
2
3
|
import { AggregatorClient, Env } from '@cetusprotocol/aggregator-sdk';
|
|
3
4
|
import BN from 'bn.js';
|
|
@@ -5,7 +6,6 @@ import { EventEmitter } from 'eventemitter3';
|
|
|
5
6
|
import { createPaymentTransactionUri } from '@mysten/payment-kit';
|
|
6
7
|
import { SuiGrpcClient } from '@mysten/sui/grpc';
|
|
7
8
|
import { SuiGraphQLClient } from '@mysten/sui/graphql';
|
|
8
|
-
import { normalizeStructTag, normalizeSuiAddress, isValidSuiAddress, fromBase64 } from '@mysten/sui/utils';
|
|
9
9
|
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
|
|
10
10
|
import { decodeSuiPrivateKey } from '@mysten/sui/cryptography';
|
|
11
11
|
import { access, mkdir, writeFile, readFile } from 'fs/promises';
|
|
@@ -112,6 +112,37 @@ var init_errors = __esm({
|
|
|
112
112
|
};
|
|
113
113
|
}
|
|
114
114
|
});
|
|
115
|
+
function preflightFail(code, error) {
|
|
116
|
+
return { valid: false, code, error };
|
|
117
|
+
}
|
|
118
|
+
function checkPositiveAmount(amount, label = "Amount", max = PREFLIGHT_MAX_AMOUNT) {
|
|
119
|
+
if (typeof amount !== "number" || !Number.isFinite(amount)) {
|
|
120
|
+
return preflightFail("INVALID_AMOUNT", `${label} must be a finite number`);
|
|
121
|
+
}
|
|
122
|
+
if (amount <= 0) {
|
|
123
|
+
return preflightFail("INVALID_AMOUNT", `${label} must be greater than zero`);
|
|
124
|
+
}
|
|
125
|
+
if (amount > max) {
|
|
126
|
+
return preflightFail("INVALID_AMOUNT", `${label} ${amount} exceeds the sane maximum (${max})`);
|
|
127
|
+
}
|
|
128
|
+
return PREFLIGHT_OK;
|
|
129
|
+
}
|
|
130
|
+
function checkSuiAddress(address, label = "recipient") {
|
|
131
|
+
try {
|
|
132
|
+
if (typeof address === "string" && address.trim() !== "" && isValidSuiAddress(normalizeSuiAddress(address))) {
|
|
133
|
+
return PREFLIGHT_OK;
|
|
134
|
+
}
|
|
135
|
+
} catch {
|
|
136
|
+
}
|
|
137
|
+
return preflightFail("INVALID_ADDRESS", `Invalid ${label} address: ${address}`);
|
|
138
|
+
}
|
|
139
|
+
var PREFLIGHT_MAX_AMOUNT, PREFLIGHT_OK;
|
|
140
|
+
var init_preflight = __esm({
|
|
141
|
+
"src/preflight.ts"() {
|
|
142
|
+
PREFLIGHT_MAX_AMOUNT = 1e6;
|
|
143
|
+
PREFLIGHT_OK = { valid: true };
|
|
144
|
+
}
|
|
145
|
+
});
|
|
115
146
|
|
|
116
147
|
// src/token-registry.ts
|
|
117
148
|
var token_registry_exports = {};
|
|
@@ -376,10 +407,28 @@ __export(cetus_swap_exports, {
|
|
|
376
407
|
findSwapRoute: () => findSwapRoute,
|
|
377
408
|
isCetusRouteFresh: () => isCetusRouteFresh,
|
|
378
409
|
isPrecomputedRouteCompatibleWithProviders: () => isPrecomputedRouteCompatibleWithProviders,
|
|
410
|
+
preflightSwap: () => preflightSwap,
|
|
379
411
|
resolveTokenType: () => resolveTokenType,
|
|
380
412
|
serializeCetusRoute: () => serializeCetusRoute,
|
|
381
413
|
verifyCetusRouteCoinMatch: () => verifyCetusRouteCoinMatch
|
|
382
414
|
});
|
|
415
|
+
function preflightSwap(input) {
|
|
416
|
+
if (typeof input.from !== "string" || input.from.trim() === "") {
|
|
417
|
+
return preflightFail("INVALID_ASSET", "A `from` token is required to swap");
|
|
418
|
+
}
|
|
419
|
+
if (typeof input.to !== "string" || input.to.trim() === "") {
|
|
420
|
+
return preflightFail("INVALID_ASSET", "A `to` token is required to swap");
|
|
421
|
+
}
|
|
422
|
+
const amountCheck = checkPositiveAmount(input.amount, "Amount", Number.POSITIVE_INFINITY);
|
|
423
|
+
if (!amountCheck.valid) return amountCheck;
|
|
424
|
+
const resolvedFrom = resolveTokenType(input.from);
|
|
425
|
+
const resolvedTo = resolveTokenType(input.to);
|
|
426
|
+
const sameToken = input.from.trim() === input.to.trim() || resolvedFrom !== null && resolvedFrom === resolvedTo;
|
|
427
|
+
if (sameToken) {
|
|
428
|
+
return preflightFail("INVALID_ASSET", `Cannot swap ${input.from} to itself`);
|
|
429
|
+
}
|
|
430
|
+
return PREFLIGHT_OK;
|
|
431
|
+
}
|
|
383
432
|
function serializeCetusRoute(route, context) {
|
|
384
433
|
return {
|
|
385
434
|
routerData: serializeRouterDataV3(route.routerData),
|
|
@@ -631,6 +680,7 @@ var OVERLAY_FEE_RATE, clientCache;
|
|
|
631
680
|
var init_cetus_swap = __esm({
|
|
632
681
|
"src/protocols/cetus-swap.ts"() {
|
|
633
682
|
init_token_registry();
|
|
683
|
+
init_preflight();
|
|
634
684
|
init_token_registry();
|
|
635
685
|
OVERLAY_FEE_RATE = 1e-3;
|
|
636
686
|
clientCache = /* @__PURE__ */ new Map();
|
|
@@ -1004,8 +1054,33 @@ async function executeTx(client, signer, buildTx, options = {}) {
|
|
|
1004
1054
|
|
|
1005
1055
|
// src/wallet/pay.ts
|
|
1006
1056
|
init_errors();
|
|
1057
|
+
init_preflight();
|
|
1058
|
+
function preflightPay(input) {
|
|
1059
|
+
if (typeof input.url !== "string" || input.url.trim() === "") {
|
|
1060
|
+
return preflightFail("FACILITATOR_REJECTION", "A target URL is required to pay");
|
|
1061
|
+
}
|
|
1062
|
+
let parsed;
|
|
1063
|
+
try {
|
|
1064
|
+
parsed = new URL(input.url);
|
|
1065
|
+
} catch {
|
|
1066
|
+
return preflightFail("FACILITATOR_REJECTION", `Invalid URL: ${input.url}`);
|
|
1067
|
+
}
|
|
1068
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
1069
|
+
return preflightFail(
|
|
1070
|
+
"FACILITATOR_REJECTION",
|
|
1071
|
+
`URL must be http(s): got ${parsed.protocol}//`
|
|
1072
|
+
);
|
|
1073
|
+
}
|
|
1074
|
+
if (input.maxPrice !== void 0) {
|
|
1075
|
+
const priceCheck = checkPositiveAmount(input.maxPrice, "maxPrice");
|
|
1076
|
+
if (!priceCheck.valid) return priceCheck;
|
|
1077
|
+
}
|
|
1078
|
+
return PREFLIGHT_OK;
|
|
1079
|
+
}
|
|
1007
1080
|
async function payWithMpp(args) {
|
|
1008
1081
|
const { signer, client, options } = args;
|
|
1082
|
+
const pf = preflightPay({ url: options.url, maxPrice: options.maxPrice });
|
|
1083
|
+
if (!pf.valid) throw new T2000Error(pf.code, pf.error);
|
|
1009
1084
|
const method = (options.method ?? "GET").toUpperCase();
|
|
1010
1085
|
const canHaveBody = method !== "GET" && method !== "HEAD";
|
|
1011
1086
|
const reqInit = {
|
|
@@ -1240,6 +1315,25 @@ function normalizeAsset(input) {
|
|
|
1240
1315
|
}
|
|
1241
1316
|
|
|
1242
1317
|
// src/wallet/send.ts
|
|
1318
|
+
init_preflight();
|
|
1319
|
+
function preflightSend(input) {
|
|
1320
|
+
try {
|
|
1321
|
+
assertAllowedAsset("send", input.asset);
|
|
1322
|
+
} catch (e) {
|
|
1323
|
+
return preflightFail("INVALID_ASSET", e.message);
|
|
1324
|
+
}
|
|
1325
|
+
const amountCheck = checkPositiveAmount(input.amount);
|
|
1326
|
+
if (!amountCheck.valid) return amountCheck;
|
|
1327
|
+
if ((input.asset === "USDC" || input.asset === "USDsui") && input.amount < GASLESS_MIN_STABLE_AMOUNT) {
|
|
1328
|
+
return preflightFail(
|
|
1329
|
+
"INVALID_AMOUNT",
|
|
1330
|
+
`Minimum gasless transfer is ${GASLESS_MIN_STABLE_AMOUNT} ${input.asset}. Got ${input.amount}.`
|
|
1331
|
+
);
|
|
1332
|
+
}
|
|
1333
|
+
const addressCheck = checkSuiAddress(input.to);
|
|
1334
|
+
if (!addressCheck.valid) return addressCheck;
|
|
1335
|
+
return PREFLIGHT_OK;
|
|
1336
|
+
}
|
|
1243
1337
|
async function buildSendTx({
|
|
1244
1338
|
client,
|
|
1245
1339
|
address,
|
|
@@ -1247,17 +1341,11 @@ async function buildSendTx({
|
|
|
1247
1341
|
amount,
|
|
1248
1342
|
asset
|
|
1249
1343
|
}) {
|
|
1250
|
-
|
|
1344
|
+
const pf = preflightSend({ to, amount, asset });
|
|
1345
|
+
if (!pf.valid) throw new T2000Error(pf.code, pf.error);
|
|
1251
1346
|
const recipient = validateAddress(to);
|
|
1252
1347
|
const assetInfo = SUPPORTED_ASSETS[asset];
|
|
1253
1348
|
if (!assetInfo) throw new T2000Error("ASSET_NOT_SUPPORTED", `Asset ${asset} is not supported`);
|
|
1254
|
-
if (amount <= 0) throw new T2000Error("INVALID_AMOUNT", "Amount must be greater than zero");
|
|
1255
|
-
if ((asset === "USDC" || asset === "USDsui") && amount < GASLESS_MIN_STABLE_AMOUNT) {
|
|
1256
|
-
throw new T2000Error(
|
|
1257
|
-
"INVALID_AMOUNT",
|
|
1258
|
-
`Minimum gasless transfer is ${GASLESS_MIN_STABLE_AMOUNT} ${asset}. Got ${amount}.`
|
|
1259
|
-
);
|
|
1260
|
-
}
|
|
1261
1349
|
const rawAmount = displayToRaw(amount, assetInfo.decimals);
|
|
1262
1350
|
const tx = new Transaction();
|
|
1263
1351
|
tx.setSender(address);
|
|
@@ -1552,7 +1640,7 @@ var TX_NODE_FRAGMENT = `
|
|
|
1552
1640
|
}
|
|
1553
1641
|
`;
|
|
1554
1642
|
var HISTORY_QUERY = `query History($address: SuiAddress!, $last: Int!) {
|
|
1555
|
-
transactions(last: $last, filter: {
|
|
1643
|
+
transactions(last: $last, filter: { affectedAddress: $address }) {
|
|
1556
1644
|
nodes {${TX_NODE_FRAGMENT}}
|
|
1557
1645
|
}
|
|
1558
1646
|
}`;
|
|
@@ -1679,7 +1767,12 @@ function extractCommands(txBlock) {
|
|
|
1679
1767
|
init_token_registry();
|
|
1680
1768
|
|
|
1681
1769
|
// src/utils/suins.ts
|
|
1682
|
-
var
|
|
1770
|
+
var RESOLVE_NAME_QUERY = `query ResolveSuins($name: String!) {
|
|
1771
|
+
address(name: $name) { address }
|
|
1772
|
+
}`;
|
|
1773
|
+
var REVERSE_NAME_QUERY = `query ReverseSuins($address: SuiAddress!) {
|
|
1774
|
+
address(address: $address) { defaultNameRecord { domain } }
|
|
1775
|
+
}`;
|
|
1683
1776
|
var SUI_ADDRESS_REGEX = /^0x[a-fA-F0-9]{1,64}$/i;
|
|
1684
1777
|
var SUI_ADDRESS_STRICT_REGEX = /^0x[a-fA-F0-9]{64}$/i;
|
|
1685
1778
|
var SUINS_NAME_REGEX = /^[a-z0-9-]+(\.[a-z0-9-]+)*\.sui$/;
|
|
@@ -1717,76 +1810,45 @@ async function resolveSuinsViaRpc(rawName, ctx = {}) {
|
|
|
1717
1810
|
if (!SUINS_NAME_REGEX.test(name)) {
|
|
1718
1811
|
throw new InvalidAddressError(rawName);
|
|
1719
1812
|
}
|
|
1720
|
-
const
|
|
1813
|
+
const gql = getSuiGraphQLClient();
|
|
1721
1814
|
let res;
|
|
1722
1815
|
try {
|
|
1723
|
-
res = await
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
jsonrpc: "2.0",
|
|
1728
|
-
id: 1,
|
|
1729
|
-
method: "suix_resolveNameServiceAddress",
|
|
1730
|
-
params: [name]
|
|
1731
|
-
}),
|
|
1732
|
-
signal: ctx.signal ?? AbortSignal.timeout(8e3)
|
|
1816
|
+
res = await gql.query({
|
|
1817
|
+
query: RESOLVE_NAME_QUERY,
|
|
1818
|
+
variables: { name },
|
|
1819
|
+
signal: ctx.signal
|
|
1733
1820
|
});
|
|
1734
1821
|
} catch (err) {
|
|
1735
1822
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1736
1823
|
throw new SuinsRpcError(name, msg);
|
|
1737
1824
|
}
|
|
1738
|
-
if (
|
|
1739
|
-
throw new SuinsRpcError(name,
|
|
1740
|
-
}
|
|
1741
|
-
let body;
|
|
1742
|
-
try {
|
|
1743
|
-
body = await res.json();
|
|
1744
|
-
} catch (err) {
|
|
1745
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1746
|
-
throw new SuinsRpcError(name, `JSON parse failed: ${msg}`);
|
|
1747
|
-
}
|
|
1748
|
-
if (body.error) {
|
|
1749
|
-
throw new SuinsRpcError(name, body.error.message);
|
|
1825
|
+
if (res.errors?.length) {
|
|
1826
|
+
throw new SuinsRpcError(name, res.errors.map((e) => e.message ?? "unknown error").join("; "));
|
|
1750
1827
|
}
|
|
1751
|
-
return
|
|
1828
|
+
return res.data?.address?.address ?? null;
|
|
1752
1829
|
}
|
|
1753
1830
|
async function resolveAddressToSuinsViaRpc(rawAddress, ctx = {}) {
|
|
1754
1831
|
const address = rawAddress.trim().toLowerCase();
|
|
1755
1832
|
if (!SUI_ADDRESS_REGEX.test(address)) {
|
|
1756
1833
|
throw new InvalidAddressError(rawAddress);
|
|
1757
1834
|
}
|
|
1758
|
-
const
|
|
1835
|
+
const gql = getSuiGraphQLClient();
|
|
1759
1836
|
let res;
|
|
1760
1837
|
try {
|
|
1761
|
-
res = await
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
jsonrpc: "2.0",
|
|
1766
|
-
id: 1,
|
|
1767
|
-
method: "suix_resolveNameServiceNames",
|
|
1768
|
-
params: [address]
|
|
1769
|
-
}),
|
|
1770
|
-
signal: ctx.signal ?? AbortSignal.timeout(8e3)
|
|
1838
|
+
res = await gql.query({
|
|
1839
|
+
query: REVERSE_NAME_QUERY,
|
|
1840
|
+
variables: { address },
|
|
1841
|
+
signal: ctx.signal
|
|
1771
1842
|
});
|
|
1772
1843
|
} catch (err) {
|
|
1773
1844
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1774
1845
|
throw new SuinsRpcError(address, msg);
|
|
1775
1846
|
}
|
|
1776
|
-
if (
|
|
1777
|
-
throw new SuinsRpcError(address,
|
|
1778
|
-
}
|
|
1779
|
-
let body;
|
|
1780
|
-
try {
|
|
1781
|
-
body = await res.json();
|
|
1782
|
-
} catch (err) {
|
|
1783
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1784
|
-
throw new SuinsRpcError(address, `JSON parse failed: ${msg}`);
|
|
1785
|
-
}
|
|
1786
|
-
if (body.error) {
|
|
1787
|
-
throw new SuinsRpcError(address, body.error.message);
|
|
1847
|
+
if (res.errors?.length) {
|
|
1848
|
+
throw new SuinsRpcError(address, res.errors.map((e) => e.message ?? "unknown error").join("; "));
|
|
1788
1849
|
}
|
|
1789
|
-
|
|
1850
|
+
const domain = res.data?.address?.defaultNameRecord?.domain;
|
|
1851
|
+
return domain ? [domain] : [];
|
|
1790
1852
|
}
|
|
1791
1853
|
async function normalizeAddressInput(value, ctx = {}) {
|
|
1792
1854
|
const trimmed = value.trim();
|
|
@@ -2079,7 +2141,9 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2079
2141
|
amountUsd: approxUsdValue(params.from, params.amount) ?? 0,
|
|
2080
2142
|
force: params.force
|
|
2081
2143
|
});
|
|
2082
|
-
const { findSwapRoute: findSwapRoute2, buildSwapTx: buildSwapTx2, resolveTokenType: resolveTokenType2 } = await Promise.resolve().then(() => (init_cetus_swap(), cetus_swap_exports));
|
|
2144
|
+
const { findSwapRoute: findSwapRoute2, buildSwapTx: buildSwapTx2, resolveTokenType: resolveTokenType2, preflightSwap: preflightSwap2 } = await Promise.resolve().then(() => (init_cetus_swap(), cetus_swap_exports));
|
|
2145
|
+
const pf = preflightSwap2({ from: params.from, to: params.to, amount: params.amount });
|
|
2146
|
+
if (!pf.valid) throw new T2000Error(pf.code, pf.error);
|
|
2083
2147
|
const fromType = resolveTokenType2(params.from);
|
|
2084
2148
|
const toType = resolveTokenType2(params.to);
|
|
2085
2149
|
if (!fromType) throw new T2000Error("ASSET_NOT_SUPPORTED", `Unknown token: ${params.from}. Provide the full coin type.`);
|
|
@@ -2809,6 +2873,9 @@ function displayHandle(label) {
|
|
|
2809
2873
|
return `${label}@${parentDisplay}`;
|
|
2810
2874
|
}
|
|
2811
2875
|
|
|
2812
|
-
|
|
2876
|
+
// src/index.ts
|
|
2877
|
+
init_preflight();
|
|
2878
|
+
|
|
2879
|
+
export { AUDRIC_PARENT_NAME, AUDRIC_PARENT_NFT_ID, CETUS_USDC_SUI_POOL, CLOCK_ID, COIN_REGISTRY, DEFAULT_GRPC_URL, DEFAULT_NETWORK, ETH_TYPE, GASLESS_MIN_STABLE_AMOUNT, GASLESS_STABLE_TYPES, GAS_RESERVE_MIN, IKA_TYPE, InvalidAddressError, KNOWN_TARGETS, KeypairSigner, LABEL_PATTERNS, LOFI_TYPE, LimitEnforcer, LimitExceededError, MANIFEST_TYPE, MIST_PER_SUI, NAVX_TYPE, OPERATION_ASSETS, OVERLAY_FEE_RATE, PREFLIGHT_MAX_AMOUNT, PREFLIGHT_OK, SENDABLE_ASSETS, SPONSORED_PYTH_DEPENDENT_PROVIDERS, STABLE_ASSETS, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, SUI_DECIMALS, SUI_TYPE, SUPPORTED_ASSETS, SuinsNotRegisteredError, SuinsRpcError, T2000, T2000Error, T2000_OVERLAY_FEE_WALLET, TOKEN_MAP, USDC_DECIMALS, USDC_TYPE, USDE_TYPE, USDSUI_TYPE, USDT_TYPE, WAL_TYPE, WBTC_TYPE, WRITE_APPENDER_REGISTRY, ZkLoginSigner, addSendToTx, addSwapToTx, approxUsdValue, assertAllowedAsset, assertLimitConfig, buildAddLeafTx, buildRevokeLeafTx, buildSendTx, buildSwapTx, checkPositiveAmount, checkSuiAddress, classifyAction, classifyLabel, classifyTransaction, clearLimits, composeTx, dailySpentToday, deriveAllowedAddressesFromPtb, deserializeCetusRoute, displayHandle, executeTx, exportPrivateKey, extractAllUserLegs, extractTransferDetails, extractTxCommands, extractTxSender, fallbackLabel, fetchAllCoins, findSwapRoute, formatAssetAmount, formatSui, formatUsd, fullHandle, generateKeypair, getAddress, getCoinMeta, getDecimals, getDecimalsForCoinType, getLimits, getSponsoredSwapProviders, getSuiClient, getSuiGrpcClient, getSwapQuote, hasLimits, isAllowedAsset, isCetusRouteFresh, isInRegistry, keypairFromPrivateKey, loadKey, looksLikeSuiNs, mapMoveAbortCode, mapWalletError, mistToSui, normalizeAddressInput, normalizeAsset, normalizeCoinType, parseSuiRpcTx, payWithMpp, preflightFail, preflightPay, preflightSend, preflightSwap, queryBalance, queryHistory, queryTransaction, rawToStable, rawToUsdc, readLimitsFile, recordDailySpend, refineLendingLabel, resolveAddressToSuinsViaRpc, resolveSuinsViaRpc, resolveSymbol, resolveTokenType, saveBech32, saveKey, selectAndSplitCoin, selectSuiCoin, serializeCetusRoute, setLimits, simulateTransaction, stableToRaw, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, validateLabel, verifyCetusRouteCoinMatch, walletExists, writeLimitsFile };
|
|
2813
2880
|
//# sourceMappingURL=index.js.map
|
|
2814
2881
|
//# sourceMappingURL=index.js.map
|