@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/LICENSE +21 -0
- package/README.md +39 -2
- package/dist/index.cjs +64 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +64 -55
- package/dist/index.js.map +1 -1
- package/package.json +12 -12
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
|
|
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(
|
|
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,
|
|
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
|
-
|
|
2542
|
-
|
|
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
|
|
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) {
|