@x1scroll/agent-sdk 1.2.0 → 1.2.1
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/package.json +1 -1
- package/src/index.js +56 -1
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -52,7 +52,7 @@ const PROGRAM_ID = new PublicKey('ECgaMEwH4KLSz3awDo1vz84mSrx5n6h1ZCrbmunB5UxB')
|
|
|
52
52
|
*/
|
|
53
53
|
const TREASURY = new PublicKey('GmvrL1ymC9ENuQCUqymC9robGa9t9L59AbFiwhDDd4Ld');
|
|
54
54
|
|
|
55
|
-
const DEFAULT_RPC_URL = 'https://rpc
|
|
55
|
+
const DEFAULT_RPC_URL = 'https://x1scroll.io/rpc';
|
|
56
56
|
|
|
57
57
|
// ── Anchor instruction discriminators (sha256("global:<name>")[0..8]) ─────────
|
|
58
58
|
// Pre-computed from the IDL. These are fixed for the deployed program version.
|
|
@@ -355,6 +355,54 @@ class AgentClient {
|
|
|
355
355
|
this._registryCacheExpiry = 0;
|
|
356
356
|
}
|
|
357
357
|
|
|
358
|
+
/**
|
|
359
|
+
* Check RPC connectivity. Throws AgentSDKError with fallback suggestion if unreachable.
|
|
360
|
+
* @returns {Promise<{ ok: boolean, slot: number, rpcUrl: string }>}
|
|
361
|
+
*/
|
|
362
|
+
async healthCheck() {
|
|
363
|
+
const conn = this._getConnection();
|
|
364
|
+
try {
|
|
365
|
+
const slot = await Promise.race([
|
|
366
|
+
conn.getSlot(),
|
|
367
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), 8000)),
|
|
368
|
+
]);
|
|
369
|
+
return { ok: true, slot, rpcUrl: this.rpcUrl };
|
|
370
|
+
} catch (err) {
|
|
371
|
+
throw new AgentSDKError(
|
|
372
|
+
`RPC endpoint unreachable: ${this.rpcUrl}. ` +
|
|
373
|
+
`Try the public fallback: https://x1scroll.io/rpc\n` +
|
|
374
|
+
`Original error: ${err.message}`,
|
|
375
|
+
'RPC_UNREACHABLE',
|
|
376
|
+
err
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Check that a keypair has sufficient XNT balance for an operation.
|
|
383
|
+
* Throws AgentSDKError with current balance and required amount if insufficient.
|
|
384
|
+
* @param {Keypair} keypair
|
|
385
|
+
* @param {number} requiredLamports
|
|
386
|
+
* @param {string} [operationName]
|
|
387
|
+
*/
|
|
388
|
+
async _assertSufficientBalance(keypair, requiredLamports, operationName = 'operation') {
|
|
389
|
+
const conn = this._getConnection();
|
|
390
|
+
const balance = await conn.getBalance(keypair.publicKey);
|
|
391
|
+
// Add 5000 lamports buffer for network tx fee
|
|
392
|
+
const totalRequired = requiredLamports + 5000;
|
|
393
|
+
if (balance < totalRequired) {
|
|
394
|
+
const balanceXNT = (balance / 1e9).toFixed(6);
|
|
395
|
+
const requiredXNT = (totalRequired / 1e9).toFixed(6);
|
|
396
|
+
throw new AgentSDKError(
|
|
397
|
+
`Insufficient balance for ${operationName}. ` +
|
|
398
|
+
`Have: ${balanceXNT} XNT, Need: ${requiredXNT} XNT. ` +
|
|
399
|
+
`Fund wallet: ${keypair.publicKey.toBase58()}`,
|
|
400
|
+
'INSUFFICIENT_BALANCE'
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
return balance;
|
|
404
|
+
}
|
|
405
|
+
|
|
358
406
|
// ── Internal ────────────────────────────────────────────────────────────────
|
|
359
407
|
|
|
360
408
|
/** @returns {Connection} */
|
|
@@ -518,6 +566,10 @@ class AgentClient {
|
|
|
518
566
|
|
|
519
567
|
const humanKeypair = this.keypair;
|
|
520
568
|
const agentPubkey = agentKeypair.publicKey;
|
|
569
|
+
|
|
570
|
+
// ── Pre-flight balance check (0.05 XNT registration fee) ──
|
|
571
|
+
await this._assertSufficientBalance(humanKeypair, 50_000_000, 'register_agent (0.05 XNT)');
|
|
572
|
+
|
|
521
573
|
const { pda: agentRecordPDA } = AgentClient.deriveAgentRecord(agentPubkey);
|
|
522
574
|
|
|
523
575
|
// Borsh-encode instruction data: discriminator + name + metadata_uri
|
|
@@ -945,6 +997,9 @@ class AgentClient {
|
|
|
945
997
|
validateString(branchLabel, 'branchLabel', 64);
|
|
946
998
|
validateString(cid, 'cid', 64);
|
|
947
999
|
|
|
1000
|
+
// ── Pre-flight balance check (0.001 XNT decision write fee) ──
|
|
1001
|
+
await this._assertSufficientBalance(agentKeypair, 1_000_000, 'decision_write (0.001 XNT)');
|
|
1002
|
+
|
|
948
1003
|
if (typeof outcome !== 'number' || ![0, 1, 2].includes(outcome)) {
|
|
949
1004
|
throw new AgentSDKError('outcome must be 0 (pending), 1 (executed), or 2 (rejected)', 'INVALID_INPUT');
|
|
950
1005
|
}
|