@t2000/sdk 5.0.0 → 5.2.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 +293 -94
- 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 +293 -92
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +330 -205
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +100 -19
- package/dist/index.d.ts +100 -19
- package/dist/index.js +320 -204
- package/dist/index.js.map +1 -1
- package/dist/{types-CgZWnHhs.d.cts → simulate-BTIIpnXc.d.cts} +11 -39
- package/dist/{types-CgZWnHhs.d.ts → simulate-BTIIpnXc.d.ts} +11 -39
- package/package.json +3 -4
package/dist/browser.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { B as BalanceResponse, C as CLOCK_ID, a as COIN_REGISTRY, b as ClassifyBalanceChange, c as ClassifyResult, d as CoinMeta, D as DEFAULT_NETWORK, e as
|
|
1
|
+
export { B as BalanceResponse, C as CLOCK_ID, a as COIN_REGISTRY, b as ClassifyBalanceChange, c as ClassifyResult, d as CoinMeta, D as DEFAULT_NETWORK, e as DepositInfo, E as ETH_TYPE, f as ExtractedTransfer, G as GAS_RESERVE_MIN, I as IKA_TYPE, K as KNOWN_TARGETS, g as KeypairSigner, L as LABEL_PATTERNS, h as LOFI_TYPE, M as MANIFEST_TYPE, i as MIST_PER_SUI, N as NAVX_TYPE, O as OVERLAY_FEE_RATE, j as OverlayFeeConfig, P as PayOptions, k as PayResult, S as STABLE_ASSETS, l as SUI_DECIMALS, m as SUI_TYPE, n as SUPPORTED_ASSETS, o as SendResult, p as SimulationResult, q as StableAsset, r as SuiHolding, s as SuiRpcTxBlock, t as SupportedAsset, u as SwapRouteResult, T as T2000Error, v as T2000ErrorCode, w as T2000ErrorData, x as T2000_OVERLAY_FEE_WALLET, y as TOKEN_MAP, z as TransactionLeg, A as TransactionRecord, F as TransactionSigner, H as TxDirection, U as USDC_DECIMALS, J as USDC_TYPE, Q as USDE_TYPE, R as USDSUI_TYPE, V as USDT_TYPE, W as WAL_TYPE, X as WBTC_TYPE, Z as ZkLoginProof, Y as ZkLoginSigner, _ as buildSwapTx, $ as classifyAction, a0 as classifyLabel, a1 as classifyTransaction, a2 as executeTx, a3 as extractAllUserLegs, a4 as extractTransferDetails, a5 as extractTxCommands, a6 as extractTxSender, a7 as fallbackLabel, a8 as findSwapRoute, a9 as formatAssetAmount, aa as formatSui, ab as formatUsd, ac as getDecimals, ad as getDecimalsForCoinType, ae as mapMoveAbortCode, af as mapWalletError, ag as mistToSui, ah as parseSuiRpcTx, ai as payWithMpp, aj as rawToStable, ak as rawToUsdc, al as refineLendingLabel, am as resolveSymbol, an as resolveTokenType, ao as stableToRaw, ap as suiToMist, aq as truncateAddress, ar as usdcToRaw, as as validateAddress } from './simulate-BTIIpnXc.cjs';
|
|
2
2
|
import '@mysten/sui/keypairs/ed25519';
|
|
3
3
|
import '@mysten/sui/grpc';
|
|
4
4
|
import '@mysten/sui/client';
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { B as BalanceResponse, C as CLOCK_ID, a as COIN_REGISTRY, b as ClassifyBalanceChange, c as ClassifyResult, d as CoinMeta, D as DEFAULT_NETWORK, e as
|
|
1
|
+
export { B as BalanceResponse, C as CLOCK_ID, a as COIN_REGISTRY, b as ClassifyBalanceChange, c as ClassifyResult, d as CoinMeta, D as DEFAULT_NETWORK, e as DepositInfo, E as ETH_TYPE, f as ExtractedTransfer, G as GAS_RESERVE_MIN, I as IKA_TYPE, K as KNOWN_TARGETS, g as KeypairSigner, L as LABEL_PATTERNS, h as LOFI_TYPE, M as MANIFEST_TYPE, i as MIST_PER_SUI, N as NAVX_TYPE, O as OVERLAY_FEE_RATE, j as OverlayFeeConfig, P as PayOptions, k as PayResult, S as STABLE_ASSETS, l as SUI_DECIMALS, m as SUI_TYPE, n as SUPPORTED_ASSETS, o as SendResult, p as SimulationResult, q as StableAsset, r as SuiHolding, s as SuiRpcTxBlock, t as SupportedAsset, u as SwapRouteResult, T as T2000Error, v as T2000ErrorCode, w as T2000ErrorData, x as T2000_OVERLAY_FEE_WALLET, y as TOKEN_MAP, z as TransactionLeg, A as TransactionRecord, F as TransactionSigner, H as TxDirection, U as USDC_DECIMALS, J as USDC_TYPE, Q as USDE_TYPE, R as USDSUI_TYPE, V as USDT_TYPE, W as WAL_TYPE, X as WBTC_TYPE, Z as ZkLoginProof, Y as ZkLoginSigner, _ as buildSwapTx, $ as classifyAction, a0 as classifyLabel, a1 as classifyTransaction, a2 as executeTx, a3 as extractAllUserLegs, a4 as extractTransferDetails, a5 as extractTxCommands, a6 as extractTxSender, a7 as fallbackLabel, a8 as findSwapRoute, a9 as formatAssetAmount, aa as formatSui, ab as formatUsd, ac as getDecimals, ad as getDecimalsForCoinType, ae as mapMoveAbortCode, af as mapWalletError, ag as mistToSui, ah as parseSuiRpcTx, ai as payWithMpp, aj as rawToStable, ak as rawToUsdc, al as refineLendingLabel, am as resolveSymbol, an as resolveTokenType, ao as stableToRaw, ap as suiToMist, aq as truncateAddress, ar as usdcToRaw, as as validateAddress } from './simulate-BTIIpnXc.js';
|
|
2
2
|
import '@mysten/sui/keypairs/ed25519';
|
|
3
3
|
import '@mysten/sui/grpc';
|
|
4
4
|
import '@mysten/sui/client';
|
package/dist/browser.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { coinWithBalance } from '@mysten/sui/transactions';
|
|
2
|
+
import { fromBase64, normalizeSuiAddress, isValidSuiAddress } from '@mysten/sui/utils';
|
|
1
3
|
import '@mysten/sui/grpc';
|
|
2
4
|
import '@mysten/sui/graphql';
|
|
3
|
-
import { normalizeSuiAddress, isValidSuiAddress } from '@mysten/sui/utils';
|
|
4
5
|
import { AggregatorClient, Env } from '@cetusprotocol/aggregator-sdk';
|
|
5
6
|
import 'bn.js';
|
|
6
7
|
|
|
@@ -104,6 +105,34 @@ var init_errors = __esm({
|
|
|
104
105
|
});
|
|
105
106
|
|
|
106
107
|
// src/token-registry.ts
|
|
108
|
+
var token_registry_exports = {};
|
|
109
|
+
__export(token_registry_exports, {
|
|
110
|
+
COIN_REGISTRY: () => COIN_REGISTRY,
|
|
111
|
+
ETH_TYPE: () => ETH_TYPE,
|
|
112
|
+
IKA_TYPE: () => IKA_TYPE,
|
|
113
|
+
LOFI_TYPE: () => LOFI_TYPE,
|
|
114
|
+
MANIFEST_TYPE: () => MANIFEST_TYPE,
|
|
115
|
+
NAVX_TYPE: () => NAVX_TYPE,
|
|
116
|
+
SUI_TYPE: () => SUI_TYPE,
|
|
117
|
+
TOKEN_MAP: () => TOKEN_MAP,
|
|
118
|
+
USDC_TYPE: () => USDC_TYPE,
|
|
119
|
+
USDE_TYPE: () => USDE_TYPE,
|
|
120
|
+
USDSUI_TYPE: () => USDSUI_TYPE,
|
|
121
|
+
USDT_TYPE: () => USDT_TYPE,
|
|
122
|
+
WAL_TYPE: () => WAL_TYPE,
|
|
123
|
+
WBTC_TYPE: () => WBTC_TYPE,
|
|
124
|
+
getCoinMeta: () => getCoinMeta,
|
|
125
|
+
getDecimalsForCoinType: () => getDecimalsForCoinType,
|
|
126
|
+
isInRegistry: () => isInRegistry,
|
|
127
|
+
resolveSymbol: () => resolveSymbol,
|
|
128
|
+
resolveTokenType: () => resolveTokenType
|
|
129
|
+
});
|
|
130
|
+
function getCoinMeta(coinType) {
|
|
131
|
+
return BY_TYPE.get(coinType);
|
|
132
|
+
}
|
|
133
|
+
function isInRegistry(coinType) {
|
|
134
|
+
return BY_TYPE.has(coinType);
|
|
135
|
+
}
|
|
107
136
|
function getDecimalsForCoinType(coinType) {
|
|
108
137
|
const direct = BY_TYPE.get(coinType);
|
|
109
138
|
if (direct) return direct.decimals;
|
|
@@ -186,6 +215,136 @@ var init_token_registry = __esm({
|
|
|
186
215
|
}
|
|
187
216
|
});
|
|
188
217
|
|
|
218
|
+
// src/wallet/coinSelection.ts
|
|
219
|
+
var coinSelection_exports = {};
|
|
220
|
+
__export(coinSelection_exports, {
|
|
221
|
+
fetchAllCoins: () => fetchAllCoins,
|
|
222
|
+
selectAndSplitCoin: () => selectAndSplitCoin,
|
|
223
|
+
selectSuiCoin: () => selectSuiCoin
|
|
224
|
+
});
|
|
225
|
+
async function fetchAllCoins(client, owner, coinType) {
|
|
226
|
+
const [balance, ids] = await Promise.all([
|
|
227
|
+
client.core.getBalance({ owner, coinType }),
|
|
228
|
+
(async () => {
|
|
229
|
+
const out = [];
|
|
230
|
+
let cursor;
|
|
231
|
+
let hasNext = true;
|
|
232
|
+
while (hasNext) {
|
|
233
|
+
const page = await client.core.listCoins({ owner, coinType, cursor: cursor ?? void 0 });
|
|
234
|
+
for (const c of page.objects) out.push(c.objectId);
|
|
235
|
+
cursor = page.cursor;
|
|
236
|
+
hasNext = page.hasNextPage;
|
|
237
|
+
}
|
|
238
|
+
return out;
|
|
239
|
+
})()
|
|
240
|
+
]);
|
|
241
|
+
return { ids, totalBalance: BigInt(balance.balance.balance) };
|
|
242
|
+
}
|
|
243
|
+
async function selectAndSplitCoin(tx, client, owner, coinType, amount, options = {}) {
|
|
244
|
+
if (options.sponsoredContext) {
|
|
245
|
+
return selectCoinObjectsOnly(
|
|
246
|
+
tx,
|
|
247
|
+
client,
|
|
248
|
+
owner,
|
|
249
|
+
coinType,
|
|
250
|
+
amount,
|
|
251
|
+
options.allowSwapAll ?? true,
|
|
252
|
+
options.mergeCache
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
const balanceResp = await client.core.getBalance({ owner, coinType });
|
|
256
|
+
const totalBalance = BigInt(balanceResp.balance.balance);
|
|
257
|
+
if (totalBalance === 0n) {
|
|
258
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `No balance found for ${coinType}`);
|
|
259
|
+
}
|
|
260
|
+
const allowSwapAll = options.allowSwapAll ?? true;
|
|
261
|
+
if (amount !== "all" && amount > totalBalance && !allowSwapAll) {
|
|
262
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient balance for ${coinType}`, {
|
|
263
|
+
available: totalBalance.toString(),
|
|
264
|
+
required: amount.toString()
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
const requested = amount === "all" ? totalBalance : amount;
|
|
268
|
+
const swapAll = amount === "all" || requested >= totalBalance;
|
|
269
|
+
const effectiveAmount = swapAll ? totalBalance : requested;
|
|
270
|
+
const coin = coinWithBalance({ type: coinType, balance: effectiveAmount })(tx);
|
|
271
|
+
return { coin, effectiveAmount, swapAll };
|
|
272
|
+
}
|
|
273
|
+
async function selectCoinObjectsOnly(tx, client, owner, coinType, amount, allowSwapAll, mergeCache) {
|
|
274
|
+
const cached = mergeCache?.get(coinType);
|
|
275
|
+
if (cached) {
|
|
276
|
+
const requested2 = amount === "all" ? cached.remaining : amount;
|
|
277
|
+
if (cached.remaining === 0n || requested2 > cached.remaining) {
|
|
278
|
+
throw new T2000Error(
|
|
279
|
+
"ADDRESS_BALANCE_UNSPONSORABLE",
|
|
280
|
+
`Not enough ${coinType} in coin objects to cover all legs of this sponsored bundle. The remaining funds are in your address balance, which sponsored transactions can't access yet.`,
|
|
281
|
+
{ remaining: cached.remaining.toString(), requested: requested2.toString(), coinType }
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
const swapAll2 = amount === "all" || requested2 >= cached.remaining;
|
|
285
|
+
const effectiveAmount2 = swapAll2 ? cached.remaining : requested2;
|
|
286
|
+
const coin2 = swapAll2 ? cached.primary : tx.splitCoins(cached.primary, [effectiveAmount2])[0];
|
|
287
|
+
cached.remaining -= effectiveAmount2;
|
|
288
|
+
return { coin: coin2, effectiveAmount: effectiveAmount2, swapAll: swapAll2 };
|
|
289
|
+
}
|
|
290
|
+
const objects = [];
|
|
291
|
+
let coinObjectTotal = 0n;
|
|
292
|
+
let cursor;
|
|
293
|
+
let hasNext = true;
|
|
294
|
+
while (hasNext) {
|
|
295
|
+
const page = await client.core.listCoins({ owner, coinType, cursor: cursor ?? void 0 });
|
|
296
|
+
for (const c of page.objects) {
|
|
297
|
+
objects.push({ objectId: c.objectId, balance: BigInt(c.balance) });
|
|
298
|
+
coinObjectTotal += BigInt(c.balance);
|
|
299
|
+
}
|
|
300
|
+
cursor = page.cursor;
|
|
301
|
+
hasNext = page.hasNextPage;
|
|
302
|
+
}
|
|
303
|
+
const unsponsorable = () => new T2000Error(
|
|
304
|
+
"ADDRESS_BALANCE_UNSPONSORABLE",
|
|
305
|
+
`These funds are in your address balance, which sponsored transactions can't access yet. (Funds received via gasless transfers land there.) This will work once the gas sponsor adds address-balance support.`,
|
|
306
|
+
{ coinObjectTotal: coinObjectTotal.toString(), coinType }
|
|
307
|
+
);
|
|
308
|
+
if (coinObjectTotal === 0n) {
|
|
309
|
+
throw unsponsorable();
|
|
310
|
+
}
|
|
311
|
+
const requested = amount === "all" ? coinObjectTotal : amount;
|
|
312
|
+
if (requested > coinObjectTotal) {
|
|
313
|
+
if (allowSwapAll && amount === "all") ; else {
|
|
314
|
+
throw unsponsorable();
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
const swapAll = amount === "all" || requested >= coinObjectTotal;
|
|
318
|
+
const effectiveAmount = swapAll ? coinObjectTotal : requested;
|
|
319
|
+
const [first, ...rest] = objects;
|
|
320
|
+
const primary = tx.object(first.objectId);
|
|
321
|
+
if (rest.length > 0) {
|
|
322
|
+
tx.mergeCoins(
|
|
323
|
+
primary,
|
|
324
|
+
rest.map((o) => tx.object(o.objectId))
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
const coin = swapAll ? primary : tx.splitCoins(primary, [effectiveAmount])[0];
|
|
328
|
+
mergeCache?.set(coinType, {
|
|
329
|
+
primary,
|
|
330
|
+
remaining: coinObjectTotal - effectiveAmount
|
|
331
|
+
});
|
|
332
|
+
return { coin, effectiveAmount, swapAll };
|
|
333
|
+
}
|
|
334
|
+
async function selectSuiCoin(tx, client, owner, amountMist, sponsoredContext, mergeCache) {
|
|
335
|
+
if (sponsoredContext) {
|
|
336
|
+
const { SUI_TYPE: SUI_TYPE2 } = await Promise.resolve().then(() => (init_token_registry(), token_registry_exports));
|
|
337
|
+
return selectCoinObjectsOnly(tx, client, owner, SUI_TYPE2, amountMist, false, mergeCache);
|
|
338
|
+
}
|
|
339
|
+
const [coin] = tx.splitCoins(tx.gas, [amountMist]);
|
|
340
|
+
return { coin, effectiveAmount: amountMist, swapAll: false };
|
|
341
|
+
}
|
|
342
|
+
var init_coinSelection = __esm({
|
|
343
|
+
"src/wallet/coinSelection.ts"() {
|
|
344
|
+
init_errors();
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
|
|
189
348
|
// src/wallet/keypairSigner.ts
|
|
190
349
|
var KeypairSigner = class {
|
|
191
350
|
constructor(keypair) {
|
|
@@ -245,12 +404,8 @@ var ZkLoginSigner = class {
|
|
|
245
404
|
}
|
|
246
405
|
};
|
|
247
406
|
|
|
248
|
-
// src/
|
|
249
|
-
|
|
250
|
-
const raw = challenge?.request?.amount;
|
|
251
|
-
const n = typeof raw === "string" ? Number(raw) : typeof raw === "number" ? raw : Number.NaN;
|
|
252
|
-
return Number.isFinite(n) ? n : void 0;
|
|
253
|
-
}
|
|
407
|
+
// src/wallet/pay.ts
|
|
408
|
+
init_errors();
|
|
254
409
|
|
|
255
410
|
// src/wallet/executeTx.ts
|
|
256
411
|
async function executeTx(client, signer, buildTx, options = {}) {
|
|
@@ -278,45 +433,122 @@ async function executeTx(client, signer, buildTx, options = {}) {
|
|
|
278
433
|
// src/wallet/pay.ts
|
|
279
434
|
async function payWithMpp(args) {
|
|
280
435
|
const { signer, client, options } = args;
|
|
281
|
-
const { Mppx } = await import('mppx/client');
|
|
282
|
-
const { sui, USDC } = await import('@suimpp/mpp/client');
|
|
283
|
-
const { SuiGrpcClient: SuiGrpcClient2 } = await import('@mysten/sui/grpc');
|
|
284
|
-
const signerAddress = signer.getAddress();
|
|
285
|
-
let paymentDigest;
|
|
286
|
-
let gasCostSui = 0;
|
|
287
|
-
let chargedAmount;
|
|
288
|
-
const network = client.network === "testnet" ? "testnet" : "mainnet";
|
|
289
|
-
const grpcBaseUrl = network === "testnet" ? "https://fullnode.testnet.sui.io" : "https://fullnode.mainnet.sui.io";
|
|
290
|
-
const grpcClient = new SuiGrpcClient2({ baseUrl: grpcBaseUrl, network });
|
|
291
|
-
const mppx = Mppx.create({
|
|
292
|
-
polyfill: false,
|
|
293
|
-
onChallenge: async (challenge) => {
|
|
294
|
-
const parsed = parseChallengeAmount(challenge);
|
|
295
|
-
if (parsed !== void 0) chargedAmount = parsed;
|
|
296
|
-
return void 0;
|
|
297
|
-
},
|
|
298
|
-
methods: [sui({
|
|
299
|
-
client,
|
|
300
|
-
currency: USDC,
|
|
301
|
-
signer: {
|
|
302
|
-
toSuiAddress: () => signerAddress,
|
|
303
|
-
signPersonalMessage: (bytes) => signer.signPersonalMessage(bytes)
|
|
304
|
-
},
|
|
305
|
-
execute: async (tx) => {
|
|
306
|
-
const result = await executeTx(client, signer, () => tx, { buildClient: grpcClient });
|
|
307
|
-
paymentDigest = result.digest;
|
|
308
|
-
gasCostSui = result.gasCostSui;
|
|
309
|
-
return { digest: result.digest };
|
|
310
|
-
}
|
|
311
|
-
})]
|
|
312
|
-
});
|
|
313
436
|
const method = (options.method ?? "GET").toUpperCase();
|
|
314
437
|
const canHaveBody = method !== "GET" && method !== "HEAD";
|
|
315
|
-
const
|
|
438
|
+
const reqInit = {
|
|
316
439
|
method,
|
|
317
440
|
headers: options.headers,
|
|
318
441
|
body: canHaveBody ? options.body : void 0
|
|
442
|
+
};
|
|
443
|
+
const probe = await fetch(options.url, reqInit);
|
|
444
|
+
if (probe.status !== 402) {
|
|
445
|
+
return finalize(probe, { paid: false });
|
|
446
|
+
}
|
|
447
|
+
const requirements = await pickSuiExactRequirements(probe, client.network);
|
|
448
|
+
if (!requirements) {
|
|
449
|
+
throw new T2000Error(
|
|
450
|
+
"FACILITATOR_REJECTION",
|
|
451
|
+
`Endpoint returned 402 without an x402 'exact' / sui:${client.network} payment requirement. This SDK only speaks the x402 dialect.`
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
return payViaX402({ signer, client, options, reqInit, requirements });
|
|
455
|
+
}
|
|
456
|
+
async function pickSuiExactRequirements(response, network) {
|
|
457
|
+
try {
|
|
458
|
+
const body = await response.clone().json();
|
|
459
|
+
const want = `sui:${network === "testnet" ? "testnet" : "mainnet"}`;
|
|
460
|
+
return body.accepts?.find((a) => a.scheme === "exact" && a.network === want);
|
|
461
|
+
} catch {
|
|
462
|
+
return void 0;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
async function payViaX402(args) {
|
|
466
|
+
const { signer, client, options, reqInit, requirements } = args;
|
|
467
|
+
const { buildX402SignedPayment, X402_PAYMENT_HEADER, X402_PAYMENT_RESPONSE_HEADER } = await import('@suimpp/mpp/x402');
|
|
468
|
+
const amountRaw = BigInt(requirements.maxAmountRequired);
|
|
469
|
+
const migrationGasSui = await ensureAddressBalanceCovers({
|
|
470
|
+
signer,
|
|
471
|
+
client,
|
|
472
|
+
asset: requirements.asset,
|
|
473
|
+
amountRaw
|
|
319
474
|
});
|
|
475
|
+
const signerAdapter = {
|
|
476
|
+
toSuiAddress: () => signer.getAddress(),
|
|
477
|
+
signTransaction: (bytes) => signer.signTransaction(bytes)
|
|
478
|
+
};
|
|
479
|
+
const { header } = await buildX402SignedPayment({ requirements, signer: signerAdapter });
|
|
480
|
+
const res = await fetch(options.url, {
|
|
481
|
+
...reqInit,
|
|
482
|
+
headers: { ...options.headers ?? {}, [X402_PAYMENT_HEADER]: header }
|
|
483
|
+
});
|
|
484
|
+
const settleHeader = res.headers.get(X402_PAYMENT_RESPONSE_HEADER);
|
|
485
|
+
const paid = !!settleHeader;
|
|
486
|
+
let digest;
|
|
487
|
+
if (settleHeader) {
|
|
488
|
+
try {
|
|
489
|
+
digest = JSON.parse(new TextDecoder().decode(fromBase64(settleHeader))).transaction;
|
|
490
|
+
} catch {
|
|
491
|
+
digest = void 0;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
const result = await finalize(res, { paid });
|
|
495
|
+
if (!paid) return { ...result, dialect: "x402" };
|
|
496
|
+
return {
|
|
497
|
+
...result,
|
|
498
|
+
dialect: "x402",
|
|
499
|
+
cost: atomicToHuman(amountRaw, await assetDecimals(requirements.asset)),
|
|
500
|
+
gasCostSui: migrationGasSui,
|
|
501
|
+
receipt: digest ? { reference: digest, timestamp: (/* @__PURE__ */ new Date()).toISOString() } : result.receipt
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
async function ensureAddressBalanceCovers(args) {
|
|
505
|
+
const { signer, client, asset, amountRaw } = args;
|
|
506
|
+
const owner = signer.getAddress();
|
|
507
|
+
const balanceResp = await client.core.getBalance({ owner, coinType: asset });
|
|
508
|
+
const total = BigInt(balanceResp.balance.balance);
|
|
509
|
+
if (total < amountRaw) {
|
|
510
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${asset} to pay`, {
|
|
511
|
+
available: total.toString(),
|
|
512
|
+
required: amountRaw.toString()
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
let coinSum = 0n;
|
|
516
|
+
let cursor;
|
|
517
|
+
let hasNext = true;
|
|
518
|
+
while (hasNext) {
|
|
519
|
+
const page = await client.core.listCoins({ owner, coinType: asset, cursor: cursor ?? void 0 });
|
|
520
|
+
for (const c of page.objects) coinSum += BigInt(c.balance);
|
|
521
|
+
cursor = page.cursor;
|
|
522
|
+
hasNext = page.hasNextPage;
|
|
523
|
+
}
|
|
524
|
+
const addressBalance = total - coinSum;
|
|
525
|
+
if (addressBalance >= amountRaw) return 0;
|
|
526
|
+
const shortfall = amountRaw - addressBalance;
|
|
527
|
+
const { Transaction: Transaction2 } = await import('@mysten/sui/transactions');
|
|
528
|
+
const { selectAndSplitCoin: selectAndSplitCoin2 } = await Promise.resolve().then(() => (init_coinSelection(), coinSelection_exports));
|
|
529
|
+
const grpcClient = await makeGrpcBuildClient(client);
|
|
530
|
+
const migration = await executeTx(
|
|
531
|
+
client,
|
|
532
|
+
signer,
|
|
533
|
+
async () => {
|
|
534
|
+
const tx = new Transaction2();
|
|
535
|
+
const { coin } = await selectAndSplitCoin2(tx, client, owner, asset, shortfall, {
|
|
536
|
+
sponsoredContext: true,
|
|
537
|
+
// coin-objects-only — never the address balance
|
|
538
|
+
allowSwapAll: false
|
|
539
|
+
});
|
|
540
|
+
tx.moveCall({
|
|
541
|
+
target: "0x2::coin::send_funds",
|
|
542
|
+
typeArguments: [asset],
|
|
543
|
+
arguments: [coin, tx.pure.address(owner)]
|
|
544
|
+
});
|
|
545
|
+
return tx;
|
|
546
|
+
},
|
|
547
|
+
{ buildClient: grpcClient }
|
|
548
|
+
);
|
|
549
|
+
return migration.gasCostSui;
|
|
550
|
+
}
|
|
551
|
+
async function finalize(response, opts) {
|
|
320
552
|
const contentType = response.headers.get("content-type") ?? "";
|
|
321
553
|
let body;
|
|
322
554
|
try {
|
|
@@ -324,15 +556,25 @@ async function payWithMpp(args) {
|
|
|
324
556
|
} catch {
|
|
325
557
|
body = null;
|
|
326
558
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
559
|
+
return { status: response.status, body, paid: opts.paid };
|
|
560
|
+
}
|
|
561
|
+
async function makeGrpcBuildClient(client) {
|
|
562
|
+
const { SuiGrpcClient: SuiGrpcClient2 } = await import('@mysten/sui/grpc');
|
|
563
|
+
const network = client.network === "testnet" ? "testnet" : "mainnet";
|
|
564
|
+
const baseUrl = network === "testnet" ? "https://fullnode.testnet.sui.io" : "https://fullnode.mainnet.sui.io";
|
|
565
|
+
return new SuiGrpcClient2({ baseUrl, network });
|
|
566
|
+
}
|
|
567
|
+
function atomicToHuman(raw, decimals) {
|
|
568
|
+
return Number(raw) / 10 ** decimals;
|
|
569
|
+
}
|
|
570
|
+
async function assetDecimals(coinType) {
|
|
571
|
+
try {
|
|
572
|
+
const { getDecimalsForCoinType: getDecimalsForCoinType2 } = await Promise.resolve().then(() => (init_token_registry(), token_registry_exports));
|
|
573
|
+
const d = getDecimalsForCoinType2(coinType);
|
|
574
|
+
return typeof d === "number" ? d : 6;
|
|
575
|
+
} catch {
|
|
576
|
+
return 6;
|
|
577
|
+
}
|
|
336
578
|
}
|
|
337
579
|
|
|
338
580
|
// src/browser.ts
|
|
@@ -674,7 +916,7 @@ function toBase64(bytes) {
|
|
|
674
916
|
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
675
917
|
return btoa(binary);
|
|
676
918
|
}
|
|
677
|
-
function
|
|
919
|
+
function fromBase642(b64) {
|
|
678
920
|
const binary = atob(b64);
|
|
679
921
|
const bytes = new Uint8Array(binary.length);
|
|
680
922
|
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
@@ -750,50 +992,9 @@ async function buildSwapTx(params) {
|
|
|
750
992
|
return outputCoin;
|
|
751
993
|
}
|
|
752
994
|
|
|
753
|
-
// src/safeguards/errors.ts
|
|
754
|
-
init_errors();
|
|
755
|
-
var SafeguardError = class extends T2000Error {
|
|
756
|
-
rule;
|
|
757
|
-
details;
|
|
758
|
-
constructor(rule, details, message) {
|
|
759
|
-
const msg = message ?? buildMessage(rule, details);
|
|
760
|
-
super("SAFEGUARD_BLOCKED", msg, { rule, ...details });
|
|
761
|
-
this.name = "SafeguardError";
|
|
762
|
-
this.rule = rule;
|
|
763
|
-
this.details = details;
|
|
764
|
-
}
|
|
765
|
-
toJSON() {
|
|
766
|
-
return {
|
|
767
|
-
error: "SAFEGUARD_BLOCKED",
|
|
768
|
-
message: this.message,
|
|
769
|
-
retryable: this.retryable,
|
|
770
|
-
data: { rule: this.rule, ...this.details }
|
|
771
|
-
};
|
|
772
|
-
}
|
|
773
|
-
};
|
|
774
|
-
function buildMessage(rule, details) {
|
|
775
|
-
switch (rule) {
|
|
776
|
-
case "locked":
|
|
777
|
-
return "Agent is locked. All operations are frozen.";
|
|
778
|
-
case "maxPerTx":
|
|
779
|
-
return `Amount $${(details.attempted ?? 0).toFixed(2)} exceeds per-transaction limit ($${(details.limit ?? 0).toFixed(2)})`;
|
|
780
|
-
case "maxDailySend":
|
|
781
|
-
return `Daily send limit reached ($${(details.current ?? 0).toFixed(2)}/$${(details.limit ?? 0).toFixed(2)} used today)`;
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
// src/safeguards/types.ts
|
|
786
|
-
var DEFAULT_SAFEGUARD_CONFIG = {
|
|
787
|
-
locked: false,
|
|
788
|
-
maxPerTx: 0,
|
|
789
|
-
maxDailySend: 0,
|
|
790
|
-
dailyUsed: 0,
|
|
791
|
-
dailyResetDate: ""
|
|
792
|
-
};
|
|
793
|
-
|
|
794
995
|
// src/browser.ts
|
|
795
996
|
init_token_registry();
|
|
796
997
|
|
|
797
|
-
export { CLOCK_ID, COIN_REGISTRY, DEFAULT_NETWORK,
|
|
998
|
+
export { CLOCK_ID, COIN_REGISTRY, DEFAULT_NETWORK, ETH_TYPE, GAS_RESERVE_MIN, IKA_TYPE, KNOWN_TARGETS, KeypairSigner, LABEL_PATTERNS, LOFI_TYPE, MANIFEST_TYPE, MIST_PER_SUI, NAVX_TYPE, OVERLAY_FEE_RATE, STABLE_ASSETS, SUI_DECIMALS, SUI_TYPE, SUPPORTED_ASSETS, T2000Error, T2000_OVERLAY_FEE_WALLET, TOKEN_MAP, USDC_DECIMALS, USDC_TYPE, USDE_TYPE, USDSUI_TYPE, USDT_TYPE, WAL_TYPE, WBTC_TYPE, ZkLoginSigner, buildSwapTx, classifyAction, classifyLabel, classifyTransaction, executeTx, extractAllUserLegs, extractTransferDetails, extractTxCommands, extractTxSender, fallbackLabel, findSwapRoute, formatAssetAmount, formatSui, formatUsd, fromBase642 as fromBase64, getDecimals, getDecimalsForCoinType, mapMoveAbortCode, mapWalletError, mistToSui, parseSuiRpcTx, payWithMpp, rawToStable, rawToUsdc, refineLendingLabel, resolveSymbol, resolveTokenType, stableToRaw, suiToMist, toBase64, truncateAddress, usdcToRaw, validateAddress };
|
|
798
999
|
//# sourceMappingURL=browser.js.map
|
|
799
1000
|
//# sourceMappingURL=browser.js.map
|