@suxinmin/plugin-casper 1.0.3 → 1.0.5

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/actions.js CHANGED
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getDeployStatusAction = exports.transferAction = exports.getBalanceAction = exports.generateWalletAction = void 0;
4
4
  const config_1 = require("./config");
5
+ const utils_1 = require("./utils");
5
6
  /**
6
7
  * 生成钱包 Action
7
8
  */
@@ -67,7 +68,7 @@ exports.getBalanceAction = {
67
68
  try {
68
69
  const client = (0, config_1.createCasperClient)(runtime);
69
70
  // 从消息中提取公钥或地址
70
- const publicKey = extractPublicKey(message.content.text || '');
71
+ const publicKey = (0, utils_1.extractPublicKey)(message.content.text || '');
71
72
  if (!publicKey) {
72
73
  callback({
73
74
  text: 'Please provide a Casper public key or address to check the balance.',
@@ -191,11 +192,12 @@ exports.getDeployStatusAction = {
191
192
  return;
192
193
  }
193
194
  const status = await client.getDeployStatus(deployHash);
195
+ const serializedStatus = (0, utils_1.toSerializable)(status);
194
196
  callback({
195
- text: `📊 Transaction Status:\nDeploy Hash: ${deployHash}\nStatus: ${JSON.stringify(status, null, 2)}`,
197
+ text: `📊 Transaction Status:\nDeploy Hash: ${deployHash}\nStatus: ${(0, utils_1.safeJsonStringify)(serializedStatus, 2)}`,
196
198
  content: {
197
199
  deployHash,
198
- status
200
+ status: serializedStatus
199
201
  }
200
202
  });
201
203
  }
@@ -219,19 +221,13 @@ exports.getDeployStatusAction = {
219
221
  ]
220
222
  ]
221
223
  };
222
- // Helper functions
223
- function extractPublicKey(text) {
224
- // Match Casper public key pattern (hex string starting with 02 or 03)
225
- const match = text.match(/0[2-3][0-9a-fA-F]{64}/);
226
- return match ? match[0] : null;
227
- }
228
224
  function extractDeployHash(text) {
229
225
  // Match deploy hash pattern (hex string)
230
226
  const match = text.match(/[0-9a-fA-F]{64}/);
231
227
  return match ? match[0] : null;
232
228
  }
233
229
  function parseTransferDetails(text) {
234
- const publicKey = extractPublicKey(text);
230
+ const publicKey = (0, utils_1.extractPublicKey)(text);
235
231
  // Match amount pattern (number followed by optional CSPR)
236
232
  const amountMatch = text.match(/(\d+(?:\.\d+)?)\s*(?:CSPR)?/i);
237
233
  const amount = amountMatch ? parseFloat(amountMatch[1]) : null;
package/dist/client.js CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CasperClient = void 0;
4
4
  const casper_js_sdk_1 = require("casper-js-sdk");
5
5
  const client_js_1 = require("@open-rpc/client-js");
6
+ const utils_1 = require("./utils");
6
7
  class AuthenticatedCasperRpcClient extends casper_js_sdk_1.CasperServiceByJsonRPC {
7
8
  constructor(url, headers) {
8
9
  super(url);
@@ -10,6 +11,16 @@ class AuthenticatedCasperRpcClient extends casper_js_sdk_1.CasperServiceByJsonRP
10
11
  this.client.requestManager.transports = [transport];
11
12
  }
12
13
  }
14
+ function extractBlockHeader(blockInfo) {
15
+ if (blockInfo?.block?.header) {
16
+ return blockInfo.block.header;
17
+ }
18
+ const version2Header = blockInfo?.block_with_signatures?.block?.Version2?.header;
19
+ if (version2Header) {
20
+ return version2Header;
21
+ }
22
+ return null;
23
+ }
13
24
  class CasperClient {
14
25
  constructor(config) {
15
26
  this.config = config;
@@ -62,14 +73,12 @@ class CasperClient {
62
73
  */
63
74
  async getBalance(publicKey) {
64
75
  try {
65
- // 移除公钥前缀 (02 or 03)
66
- const publicKeyHex = publicKey.startsWith('02') || publicKey.startsWith('03')
67
- ? publicKey.slice(2)
68
- : publicKey;
69
- const publicKeyBytes = Buffer.from(publicKeyHex, 'hex');
70
- const clPublicKey = casper_js_sdk_1.CLPublicKey.fromEd25519(publicKeyBytes);
76
+ const clPublicKey = (0, utils_1.parseCasperPublicKey)(publicKey);
71
77
  // 获取状态根哈希
72
78
  const stateRootHash = await this.getStateRootHash();
79
+ if (!stateRootHash) {
80
+ throw new Error('Failed to resolve Casper state root hash from latest block');
81
+ }
73
82
  // 获取账户余额 URef
74
83
  const balanceUref = await this.client.getAccountBalanceUrefByPublicKey(stateRootHash, clPublicKey);
75
84
  // 获取余额
@@ -91,11 +100,7 @@ class CasperClient {
91
100
  const publicKeyBytes = casper_js_sdk_1.Keys.Ed25519.privateToPublicKey(privateKeyBytes);
92
101
  const keyPair = casper_js_sdk_1.Keys.Ed25519.parseKeyPair(publicKeyBytes, privateKeyBytes);
93
102
  // 构建目标公钥
94
- const targetPublicKeyHex = toPublicKey.startsWith('02') || toPublicKey.startsWith('03')
95
- ? toPublicKey.slice(2)
96
- : toPublicKey;
97
- const targetPublicKeyBytes = Buffer.from(targetPublicKeyHex, 'hex');
98
- const targetCLPublicKey = casper_js_sdk_1.CLPublicKey.fromEd25519(targetPublicKeyBytes);
103
+ const targetCLPublicKey = (0, utils_1.parseCasperPublicKey)(toPublicKey);
99
104
  // 构建转账 session
100
105
  const session = casper_js_sdk_1.DeployUtil.ExecutableDeployItem.newTransfer(amount, targetCLPublicKey, null, 0);
101
106
  // 构建支付
@@ -180,10 +185,11 @@ class CasperClient {
180
185
  async getLatestBlock() {
181
186
  try {
182
187
  const blockInfo = await this.client.getLatestBlockInfo();
188
+ const header = extractBlockHeader(blockInfo);
183
189
  return {
184
- stateRootHash: blockInfo.block?.header.state_root_hash,
185
- timestamp: blockInfo.block?.header.timestamp,
186
- height: blockInfo.block?.header.height
190
+ stateRootHash: header?.state_root_hash,
191
+ timestamp: header?.timestamp,
192
+ height: header?.height,
187
193
  };
188
194
  }
189
195
  catch (error) {
@@ -196,7 +202,7 @@ class CasperClient {
196
202
  */
197
203
  async getStateRootHash() {
198
204
  const blockInfo = await this.client.getLatestBlockInfo();
199
- return blockInfo.block?.header.state_root_hash || '';
205
+ return extractBlockHeader(blockInfo)?.state_root_hash || '';
200
206
  }
201
207
  }
202
208
  exports.CasperClient = CasperClient;
package/dist/config.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { IAgentRuntime } from '@elizaos/core';
2
2
  import { CasperClient, CasperConfig } from './client';
3
- /** Public testnet RPC endpoint that does not require an API key. */
4
- export declare const DEFAULT_CASPER_NODE_URL = "https://rpc.testnet.cspr.cloud:443/rpc";
3
+ /** Official Casper Association public testnet RPC (no API key required). */
4
+ export declare const DEFAULT_CASPER_NODE_URL = "https://node.testnet.casper.network/rpc";
5
5
  export declare function getCasperConfigFromRuntime(runtime: IAgentRuntime): CasperConfig;
6
6
  export declare function createCasperClient(runtime: IAgentRuntime): CasperClient;
package/dist/config.js CHANGED
@@ -4,8 +4,8 @@ exports.DEFAULT_CASPER_NODE_URL = void 0;
4
4
  exports.getCasperConfigFromRuntime = getCasperConfigFromRuntime;
5
5
  exports.createCasperClient = createCasperClient;
6
6
  const client_1 = require("./client");
7
- /** Public testnet RPC endpoint that does not require an API key. */
8
- exports.DEFAULT_CASPER_NODE_URL = 'https://rpc.testnet.cspr.cloud:443/rpc';
7
+ /** Official Casper Association public testnet RPC (no API key required). */
8
+ exports.DEFAULT_CASPER_NODE_URL = 'https://node.testnet.casper.network/rpc';
9
9
  function getCasperConfigFromRuntime(runtime) {
10
10
  const nodeUrl = runtime.getSetting('CASPER_NODE_URL') || exports.DEFAULT_CASPER_NODE_URL;
11
11
  const apiKey = runtime.getSetting('CASPER_API_KEY');
@@ -0,0 +1,5 @@
1
+ import { CLPublicKey } from 'casper-js-sdk';
2
+ export declare function extractPublicKey(text: string): string | null;
3
+ export declare function parseCasperPublicKey(publicKey: string): CLPublicKey;
4
+ export declare function safeJsonStringify(value: unknown, space?: number): string;
5
+ export declare function toSerializable<T>(value: T): T;
package/dist/utils.js ADDED
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractPublicKey = extractPublicKey;
4
+ exports.parseCasperPublicKey = parseCasperPublicKey;
5
+ exports.safeJsonStringify = safeJsonStringify;
6
+ exports.toSerializable = toSerializable;
7
+ const casper_js_sdk_1 = require("casper-js-sdk");
8
+ /** Casper tagged public key: algorithm tag (01/02/03) + 32-byte hex. */
9
+ const TAGGED_PUBLIC_KEY_PATTERN = /0[1-3][0-9a-fA-F]{64}/;
10
+ function extractPublicKey(text) {
11
+ const match = text.match(TAGGED_PUBLIC_KEY_PATTERN);
12
+ return match ? match[0] : null;
13
+ }
14
+ function parseCasperPublicKey(publicKey) {
15
+ const trimmed = publicKey.trim();
16
+ if (trimmed.startsWith('account-hash-')) {
17
+ throw new Error('Account hash balance lookup is not supported yet. Please provide a public key (starts with 01, 02, or 03).');
18
+ }
19
+ return casper_js_sdk_1.CLPublicKey.fromHex(trimmed);
20
+ }
21
+ function safeJsonStringify(value, space) {
22
+ const seen = new WeakSet();
23
+ return JSON.stringify(value, (_key, currentValue) => {
24
+ if (typeof currentValue === 'bigint') {
25
+ return currentValue.toString();
26
+ }
27
+ if (typeof currentValue === 'object' && currentValue !== null) {
28
+ if (seen.has(currentValue)) {
29
+ return '[Circular]';
30
+ }
31
+ seen.add(currentValue);
32
+ }
33
+ return currentValue;
34
+ }, space);
35
+ }
36
+ function toSerializable(value) {
37
+ return JSON.parse(safeJsonStringify(value));
38
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suxinmin/plugin-casper",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Casper blockchain plugin for Eliza AI agent framework",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",