@t2000/sdk 0.16.2 → 0.16.6

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/index.d.cts CHANGED
@@ -582,6 +582,13 @@ interface AutoTopUpResult {
582
582
  suiReceived: number;
583
583
  }
584
584
  declare function shouldAutoTopUp(client: SuiJsonRpcClient, address: string): Promise<boolean>;
585
+ /**
586
+ * Self-fund a USDC→SUI swap to replenish gas.
587
+ *
588
+ * Uses the agent's remaining SUI to pay for the swap gas (~0.007 SUI).
589
+ * This avoids the chicken-and-egg problem of needing gas station sponsorship
590
+ * to get gas, and works even when the gas station is down.
591
+ */
585
592
  declare function executeAutoTopUp(client: SuiJsonRpcClient, keypair: Ed25519Keypair): Promise<AutoTopUpResult>;
586
593
 
587
594
  type GasRequestType = 'bootstrap' | 'auto-topup' | 'fallback';
package/dist/index.d.ts CHANGED
@@ -582,6 +582,13 @@ interface AutoTopUpResult {
582
582
  suiReceived: number;
583
583
  }
584
584
  declare function shouldAutoTopUp(client: SuiJsonRpcClient, address: string): Promise<boolean>;
585
+ /**
586
+ * Self-fund a USDC→SUI swap to replenish gas.
587
+ *
588
+ * Uses the agent's remaining SUI to pay for the swap gas (~0.007 SUI).
589
+ * This avoids the chicken-and-egg problem of needing gas station sponsorship
590
+ * to get gas, and works even when the gas station is down.
591
+ */
585
592
  declare function executeAutoTopUp(client: SuiJsonRpcClient, keypair: Ed25519Keypair): Promise<AutoTopUpResult>;
586
593
 
587
594
  type GasRequestType = 'bootstrap' | 'auto-topup' | 'fallback';
package/dist/index.js CHANGED
@@ -2386,13 +2386,62 @@ function solveHashcash(challenge) {
2386
2386
  }
2387
2387
  }
2388
2388
 
2389
+ // src/gas/autoTopUp.ts
2390
+ var AUTO_TOPUP_MIN_SUI_FOR_GAS = 5000000n;
2391
+ async function shouldAutoTopUp(client, address) {
2392
+ const [suiBalance, usdcBalance] = await Promise.all([
2393
+ client.getBalance({ owner: address, coinType: SUPPORTED_ASSETS.SUI.type }),
2394
+ client.getBalance({ owner: address, coinType: SUPPORTED_ASSETS.USDC.type })
2395
+ ]);
2396
+ const suiRaw = BigInt(suiBalance.totalBalance);
2397
+ const usdcRaw = BigInt(usdcBalance.totalBalance);
2398
+ return suiRaw < AUTO_TOPUP_THRESHOLD && suiRaw >= AUTO_TOPUP_MIN_SUI_FOR_GAS && usdcRaw >= AUTO_TOPUP_MIN_USDC;
2399
+ }
2400
+ async function executeAutoTopUp(client, keypair) {
2401
+ const address = keypair.getPublicKey().toSuiAddress();
2402
+ const topupAmountHuman = Number(AUTO_TOPUP_AMOUNT) / 1e6;
2403
+ const { tx } = await buildSwapTx({
2404
+ client,
2405
+ address,
2406
+ fromAsset: "USDC",
2407
+ toAsset: "SUI",
2408
+ amount: topupAmountHuman
2409
+ });
2410
+ const result = await client.signAndExecuteTransaction({
2411
+ signer: keypair,
2412
+ transaction: tx,
2413
+ options: { showEffects: true, showBalanceChanges: true }
2414
+ });
2415
+ await client.waitForTransaction({ digest: result.digest });
2416
+ let suiReceived = 0;
2417
+ if (result.balanceChanges) {
2418
+ for (const change of result.balanceChanges) {
2419
+ if (change.coinType === SUPPORTED_ASSETS.SUI.type && change.owner && typeof change.owner === "object" && "AddressOwner" in change.owner && change.owner.AddressOwner === address) {
2420
+ suiReceived += Number(change.amount) / Number(MIST_PER_SUI);
2421
+ }
2422
+ }
2423
+ }
2424
+ return {
2425
+ success: true,
2426
+ tx: result.digest,
2427
+ usdcSpent: topupAmountHuman,
2428
+ suiReceived: Math.abs(suiReceived)
2429
+ };
2430
+ }
2431
+
2389
2432
  // src/gas/gasStation.ts
2390
- async function requestGasSponsorship(txJson, sender, type) {
2391
- const txBytes = Buffer.from(txJson).toString("base64");
2433
+ async function requestGasSponsorship(txJson, sender, type, txBcsBytes) {
2434
+ const payload = { sender, type };
2435
+ if (txBcsBytes) {
2436
+ payload.txBcsBytes = txBcsBytes;
2437
+ } else {
2438
+ payload.txJson = txJson;
2439
+ payload.txBytes = Buffer.from(txJson).toString("base64");
2440
+ }
2392
2441
  const res = await fetch(`${API_BASE_URL}/api/gas`, {
2393
2442
  method: "POST",
2394
2443
  headers: { "Content-Type": "application/json" },
2395
- body: JSON.stringify({ txJson, txBytes, sender, type })
2444
+ body: JSON.stringify(payload)
2396
2445
  });
2397
2446
  const data = await res.json();
2398
2447
  if (!res.ok) {
@@ -2442,53 +2491,6 @@ async function getGasStatus(address) {
2442
2491
  return await res.json();
2443
2492
  }
2444
2493
 
2445
- // src/gas/autoTopUp.ts
2446
- async function shouldAutoTopUp(client, address) {
2447
- const [suiBalance, usdcBalance] = await Promise.all([
2448
- client.getBalance({ owner: address, coinType: SUPPORTED_ASSETS.SUI.type }),
2449
- client.getBalance({ owner: address, coinType: SUPPORTED_ASSETS.USDC.type })
2450
- ]);
2451
- const suiRaw = BigInt(suiBalance.totalBalance);
2452
- const usdcRaw = BigInt(usdcBalance.totalBalance);
2453
- return suiRaw < AUTO_TOPUP_THRESHOLD && usdcRaw >= AUTO_TOPUP_MIN_USDC;
2454
- }
2455
- async function executeAutoTopUp(client, keypair) {
2456
- const address = keypair.getPublicKey().toSuiAddress();
2457
- const topupAmountHuman = Number(AUTO_TOPUP_AMOUNT) / 1e6;
2458
- const { tx } = await buildSwapTx({
2459
- client,
2460
- address,
2461
- fromAsset: "USDC",
2462
- toAsset: "SUI",
2463
- amount: topupAmountHuman
2464
- });
2465
- const txJson = tx.serialize();
2466
- const sponsoredResult = await requestGasSponsorship(txJson, address, "auto-topup");
2467
- const sponsoredTxBytes = Buffer.from(sponsoredResult.txBytes, "base64");
2468
- const { signature: agentSig } = await keypair.signTransaction(sponsoredTxBytes);
2469
- const result = await client.executeTransactionBlock({
2470
- transactionBlock: sponsoredResult.txBytes,
2471
- signature: [agentSig, sponsoredResult.sponsorSignature],
2472
- options: { showEffects: true, showBalanceChanges: true }
2473
- });
2474
- await client.waitForTransaction({ digest: result.digest });
2475
- let suiReceived = 0;
2476
- if (result.balanceChanges) {
2477
- for (const change of result.balanceChanges) {
2478
- if (change.coinType === SUPPORTED_ASSETS.SUI.type && change.owner && typeof change.owner === "object" && "AddressOwner" in change.owner && change.owner.AddressOwner === address) {
2479
- suiReceived += Number(change.amount) / Number(MIST_PER_SUI);
2480
- }
2481
- }
2482
- }
2483
- reportGasUsage(address, result.digest, 0, 0, "auto-topup");
2484
- return {
2485
- success: true,
2486
- tx: result.digest,
2487
- usdcSpent: topupAmountHuman,
2488
- suiReceived: Math.abs(suiReceived)
2489
- };
2490
- }
2491
-
2492
2494
  // src/gas/manager.ts
2493
2495
  function extractGasCost(effects) {
2494
2496
  if (!effects?.gasUsed) return 0;
@@ -2516,11 +2518,12 @@ async function trySelfFunded(client, keypair, tx) {
2516
2518
  gasCostSui: extractGasCost(result.effects)
2517
2519
  };
2518
2520
  }
2519
- async function tryAutoTopUpThenSelfFund(client, keypair, tx) {
2521
+ async function tryAutoTopUpThenSelfFund(client, keypair, buildTx) {
2520
2522
  const address = keypair.getPublicKey().toSuiAddress();
2521
2523
  const canTopUp = await shouldAutoTopUp(client, address);
2522
2524
  if (!canTopUp) return null;
2523
2525
  await executeAutoTopUp(client, keypair);
2526
+ const tx = await buildTx();
2524
2527
  tx.setSender(address);
2525
2528
  const result = await client.signAndExecuteTransaction({
2526
2529
  signer: keypair,
@@ -2538,8 +2541,15 @@ async function tryAutoTopUpThenSelfFund(client, keypair, tx) {
2538
2541
  async function trySponsored(client, keypair, tx) {
2539
2542
  const address = keypair.getPublicKey().toSuiAddress();
2540
2543
  tx.setSender(address);
2541
- const txJson = tx.serialize();
2542
- const sponsoredResult = await requestGasSponsorship(txJson, address);
2544
+ let txJson;
2545
+ let txBcsBase64;
2546
+ try {
2547
+ txJson = tx.serialize();
2548
+ } catch {
2549
+ const bcsBytes = await tx.build({ client });
2550
+ txBcsBase64 = Buffer.from(bcsBytes).toString("base64");
2551
+ }
2552
+ const sponsoredResult = await requestGasSponsorship(txJson ?? "", address, void 0, txBcsBase64);
2543
2553
  const sponsoredTxBytes = Buffer.from(sponsoredResult.txBytes, "base64");
2544
2554
  const { signature: agentSig } = await keypair.signTransaction(sponsoredTxBytes);
2545
2555
  const result = await client.executeTransactionBlock({
@@ -2575,8 +2585,7 @@ async function executeWithGas(client, keypair, buildTx, options) {
2575
2585
  errors.push(`self-funded: ${msg}`);
2576
2586
  }
2577
2587
  try {
2578
- const tx = await buildTx();
2579
- const result = await tryAutoTopUpThenSelfFund(client, keypair, tx);
2588
+ const result = await tryAutoTopUpThenSelfFund(client, keypair, buildTx);
2580
2589
  if (result) return result;
2581
2590
  errors.push("auto-topup: not eligible (low USDC or sufficient SUI)");
2582
2591
  } catch (err) {