@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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +56 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x1scroll/agent-sdk",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Agent identity and on-chain memory protocol for X1 blockchain",
5
5
  "license": "BSL-1.1",
6
6
  "main": "src/index.js",
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.x1.xyz';
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
  }