@suxinmin/plugin-casper 1.0.0
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 +253 -0
- package/dist/actions.d.ts +17 -0
- package/dist/actions.js +243 -0
- package/dist/client.d.ts +50 -0
- package/dist/client.js +183 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +46 -0
- package/dist/providers.d.ts +13 -0
- package/dist/providers.js +76 -0
- package/package.json +48 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Eliza Community
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# @elizaos/plugin-casper
|
|
2
|
+
|
|
3
|
+
Casper blockchain plugin for Eliza AI agent framework. This plugin enables AI agents to interact with the Casper blockchain network, including wallet management, token transfers, smart contract deployment, and blockchain data queries.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ๐ฆ **Wallet Management**: Generate new wallets and restore existing ones
|
|
8
|
+
- ๐ฐ **Balance Queries**: Check CSPR token balances for any account
|
|
9
|
+
- ๐ธ **Token Transfers**: Send CSPR tokens between accounts
|
|
10
|
+
- ๐ **Transaction Status**: Monitor transaction status by deploy hash
|
|
11
|
+
- ๐ **Smart Contracts**: Deploy and call smart contracts (WASM)
|
|
12
|
+
- ๐ **Network Info**: Query latest block and network status
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @elizaos/plugin-casper
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Configuration
|
|
21
|
+
|
|
22
|
+
Add the following environment variables to your `.env` file:
|
|
23
|
+
|
|
24
|
+
```env
|
|
25
|
+
# Casper Node URL (testnet or mainnet)
|
|
26
|
+
CASPER_NODE_URL=https://node.testnet.cspr.cloud:443
|
|
27
|
+
|
|
28
|
+
# Optional: Default wallet configuration
|
|
29
|
+
CASPER_PUBLIC_KEY=your_public_key_here
|
|
30
|
+
CASPER_PRIVATE_KEY=your_private_key_here
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Network URLs
|
|
34
|
+
|
|
35
|
+
- **Testnet**: `https://node.testnet.cspr.cloud:443`
|
|
36
|
+
- **Mainnet**: `https://node.cspr.cloud:443`
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
### Basic Setup
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { casperPlugin } from '@elizaos/plugin-casper';
|
|
44
|
+
|
|
45
|
+
// Register the plugin with your Eliza agent
|
|
46
|
+
const agent = new Agent({
|
|
47
|
+
plugins: [casperPlugin],
|
|
48
|
+
// ... other configuration
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Available Actions
|
|
53
|
+
|
|
54
|
+
#### 1. Generate Wallet
|
|
55
|
+
|
|
56
|
+
Create a new Casper wallet with public/private key pair.
|
|
57
|
+
|
|
58
|
+
**Example:**
|
|
59
|
+
```
|
|
60
|
+
User: Create a new Casper wallet
|
|
61
|
+
Agent: I'll generate a new Casper wallet for you...
|
|
62
|
+
|
|
63
|
+
๐ Address: account-hash-xxx
|
|
64
|
+
๐ Public Key: 02a1b2c3d4e5f6...
|
|
65
|
+
๐ Private Key: xxxxx
|
|
66
|
+
|
|
67
|
+
โ ๏ธ IMPORTANT: Store your private key securely! Never share it with anyone.
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
#### 2. Check Balance
|
|
71
|
+
|
|
72
|
+
Query the CSPR balance of a Casper account.
|
|
73
|
+
|
|
74
|
+
**Example:**
|
|
75
|
+
```
|
|
76
|
+
User: Check balance for 02a1b2c3d4e5f6...
|
|
77
|
+
Agent: Let me check the balance...
|
|
78
|
+
|
|
79
|
+
๐ฐ Balance for 02a1b2c3d4e5f6...:
|
|
80
|
+
100.500000000 CSPR
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
#### 3. Transfer Tokens
|
|
84
|
+
|
|
85
|
+
Send CSPR tokens to another account.
|
|
86
|
+
|
|
87
|
+
**Example:**
|
|
88
|
+
```
|
|
89
|
+
User: Send 5 CSPR to 02a1b2c3d4e5f6...
|
|
90
|
+
Agent: I'll initiate the transfer...
|
|
91
|
+
|
|
92
|
+
โ
Transfer initiated!
|
|
93
|
+
|
|
94
|
+
Amount: 5 CSPR
|
|
95
|
+
To: 02a1b2c3d4e5f6...
|
|
96
|
+
Deploy Hash: abc123def456...
|
|
97
|
+
|
|
98
|
+
You can check the transaction status using the deploy hash.
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
#### 4. Check Transaction Status
|
|
102
|
+
|
|
103
|
+
Monitor the status of a transaction by its deploy hash.
|
|
104
|
+
|
|
105
|
+
**Example:**
|
|
106
|
+
```
|
|
107
|
+
User: Check status of deploy abc123def456...
|
|
108
|
+
Agent: Let me check the transaction status...
|
|
109
|
+
|
|
110
|
+
๐ Transaction Status:
|
|
111
|
+
Deploy Hash: abc123def456...
|
|
112
|
+
Status: { ... }
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Providers
|
|
116
|
+
|
|
117
|
+
The plugin includes several providers that automatically provide context:
|
|
118
|
+
|
|
119
|
+
- **casperNetworkProvider**: Shows current network status
|
|
120
|
+
- **casperWalletProvider**: Displays configured wallet information
|
|
121
|
+
- **casperGasProvider**: Provides gas fee guidance
|
|
122
|
+
|
|
123
|
+
## API Reference
|
|
124
|
+
|
|
125
|
+
### CasperClient
|
|
126
|
+
|
|
127
|
+
The core client class for interacting with the Casper blockchain.
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
import { CasperClient } from '@elizaos/plugin-casper';
|
|
131
|
+
|
|
132
|
+
const client = new CasperClient({
|
|
133
|
+
nodeUrl: 'https://node.testnet.cspr.cloud:443',
|
|
134
|
+
chainName: 'casper-net-1'
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
#### Methods
|
|
139
|
+
|
|
140
|
+
##### `generateWallet(): WalletInfo`
|
|
141
|
+
|
|
142
|
+
Generate a new wallet with key pair.
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
const wallet = client.generateWallet();
|
|
146
|
+
console.log(wallet.address); // Account address
|
|
147
|
+
console.log(wallet.publicKey); // Public key
|
|
148
|
+
console.log(wallet.privateKey); // Private key
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
##### `getBalance(publicKey: string): Promise<string>`
|
|
152
|
+
|
|
153
|
+
Get account balance in motes (1 CSPR = 1,000,000,000 motes).
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
const balance = await client.getBalance(publicKey);
|
|
157
|
+
const csprBalance = parseInt(balance) / 1000000000;
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
##### `transfer(fromPrivateKey, toPublicKey, amount, paymentAmount?): Promise<string>`
|
|
161
|
+
|
|
162
|
+
Transfer CSPR tokens. Amount should be in motes.
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
const deployHash = await client.transfer(
|
|
166
|
+
privateKey,
|
|
167
|
+
recipientPublicKey,
|
|
168
|
+
5 * 1000000000, // 5 CSPR in motes
|
|
169
|
+
2500000000 // Gas fee in motes
|
|
170
|
+
);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
##### `getDeployStatus(deployHash: string): Promise<any>`
|
|
174
|
+
|
|
175
|
+
Check transaction status.
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
const status = await client.getDeployStatus(deployHash);
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
##### `getLatestBlock(): Promise<any>`
|
|
182
|
+
|
|
183
|
+
Get latest block information.
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
const block = await client.getLatestBlock();
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Development
|
|
190
|
+
|
|
191
|
+
### Build
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
npm run build
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Watch Mode
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
npm run dev
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Clean
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
npm run clean
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Dependencies
|
|
210
|
+
|
|
211
|
+
- `casper-js-sdk`: Official Casper JavaScript SDK
|
|
212
|
+
- `@elizaos/core`: Eliza framework core
|
|
213
|
+
|
|
214
|
+
## Security Notes
|
|
215
|
+
|
|
216
|
+
โ ๏ธ **Important Security Considerations:**
|
|
217
|
+
|
|
218
|
+
1. **Never expose private keys** in client-side code or logs
|
|
219
|
+
2. Use environment variables for sensitive data
|
|
220
|
+
3. Consider using hardware wallets or secure key storage solutions
|
|
221
|
+
4. Always verify transaction details before signing
|
|
222
|
+
5. Test on testnet before using mainnet
|
|
223
|
+
|
|
224
|
+
## Gas Fees
|
|
225
|
+
|
|
226
|
+
Casper uses a fixed gas price model:
|
|
227
|
+
|
|
228
|
+
- Standard Transfer: ~2.5 CSPR
|
|
229
|
+
- Contract Deployment: ~10 CSPR
|
|
230
|
+
- Contract Call: ~2.5 CSPR
|
|
231
|
+
|
|
232
|
+
Gas fees are relatively stable compared to other networks.
|
|
233
|
+
|
|
234
|
+
## Contributing
|
|
235
|
+
|
|
236
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
MIT
|
|
241
|
+
|
|
242
|
+
## Support
|
|
243
|
+
|
|
244
|
+
For issues and questions:
|
|
245
|
+
- GitHub Issues: [Report a bug](https://github.com/elizaos/plugin-casper/issues)
|
|
246
|
+
- Documentation: [Eliza Docs](https://elizaos.github.io/eliza/)
|
|
247
|
+
- Casper Docs: [Casper Network](https://docs.casper.network/)
|
|
248
|
+
|
|
249
|
+
## Acknowledgments
|
|
250
|
+
|
|
251
|
+
- Built with โค๏ธ for the Eliza community
|
|
252
|
+
- Powered by [Casper Network](https://casper.network/)
|
|
253
|
+
- Uses [casper-js-sdk](https://github.com/casper-ecosystem/casper-js-sdk)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Action } from '@elizaos/core';
|
|
2
|
+
/**
|
|
3
|
+
* ็ๆ้ฑๅ
Action
|
|
4
|
+
*/
|
|
5
|
+
export declare const generateWalletAction: Action;
|
|
6
|
+
/**
|
|
7
|
+
* ๆฅ่ฏขไฝ้ข Action
|
|
8
|
+
*/
|
|
9
|
+
export declare const getBalanceAction: Action;
|
|
10
|
+
/**
|
|
11
|
+
* ่ฝฌ่ดฆ Action
|
|
12
|
+
*/
|
|
13
|
+
export declare const transferAction: Action;
|
|
14
|
+
/**
|
|
15
|
+
* ๆฅ่ฏขไบคๆ็ถๆ Action
|
|
16
|
+
*/
|
|
17
|
+
export declare const getDeployStatusAction: Action;
|
package/dist/actions.js
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDeployStatusAction = exports.transferAction = exports.getBalanceAction = exports.generateWalletAction = void 0;
|
|
4
|
+
const client_1 = require("./client");
|
|
5
|
+
/**
|
|
6
|
+
* ็ๆ้ฑๅ
Action
|
|
7
|
+
*/
|
|
8
|
+
exports.generateWalletAction = {
|
|
9
|
+
name: 'GENERATE_CASPER_WALLET',
|
|
10
|
+
similes: ['CREATE_CASPER_WALLET', 'NEW_CASPER_ACCOUNT'],
|
|
11
|
+
description: 'Generate a new Casper blockchain wallet with public/private key pair',
|
|
12
|
+
validate: async (_runtime, _message) => {
|
|
13
|
+
return true;
|
|
14
|
+
},
|
|
15
|
+
handler: async (runtime, _message, state, _options, callback) => {
|
|
16
|
+
try {
|
|
17
|
+
const nodeUrl = runtime.getSetting('CASPER_NODE_URL') || 'https://node.testnet.cspr.cloud:443';
|
|
18
|
+
const client = new client_1.CasperClient({ nodeUrl });
|
|
19
|
+
const wallet = client.generateWallet();
|
|
20
|
+
const response = `I've generated a new Casper wallet for you:
|
|
21
|
+
|
|
22
|
+
๐ Address: ${wallet.address}
|
|
23
|
+
๐ Public Key: ${wallet.publicKey}
|
|
24
|
+
๐ Private Key: ${wallet.privateKey}
|
|
25
|
+
|
|
26
|
+
โ ๏ธ IMPORTANT: Store your private key securely! Never share it with anyone.`;
|
|
27
|
+
callback({
|
|
28
|
+
text: response,
|
|
29
|
+
content: {
|
|
30
|
+
address: wallet.address,
|
|
31
|
+
publicKey: wallet.publicKey,
|
|
32
|
+
privateKey: wallet.privateKey
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
callback({
|
|
38
|
+
text: `Error generating wallet: ${error.message}`,
|
|
39
|
+
content: { error: error.message }
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
examples: [
|
|
44
|
+
[
|
|
45
|
+
{
|
|
46
|
+
name: '{{user1}}',
|
|
47
|
+
content: { text: 'Create a new Casper wallet' }
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: '{{agent}}',
|
|
51
|
+
content: { text: 'I\'ll generate a new Casper wallet for you...' }
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
]
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* ๆฅ่ฏขไฝ้ข Action
|
|
58
|
+
*/
|
|
59
|
+
exports.getBalanceAction = {
|
|
60
|
+
name: 'GET_CASPER_BALANCE',
|
|
61
|
+
similes: ['CHECK_CASPER_BALANCE', 'CASPER_BALANCE'],
|
|
62
|
+
description: 'Check the CSPR token balance of a Casper account',
|
|
63
|
+
validate: async (_runtime, message) => {
|
|
64
|
+
return (message.content.text?.includes('balance') ||
|
|
65
|
+
message.content.text?.includes('CSPR')) ?? false;
|
|
66
|
+
},
|
|
67
|
+
handler: async (runtime, message, _state, _options, callback) => {
|
|
68
|
+
try {
|
|
69
|
+
const nodeUrl = runtime.getSetting('CASPER_NODE_URL') || 'https://node.testnet.cspr.cloud:443';
|
|
70
|
+
const client = new client_1.CasperClient({ nodeUrl });
|
|
71
|
+
// ไปๆถๆฏไธญๆๅๅ
ฌ้ฅๆๅฐๅ
|
|
72
|
+
const publicKey = extractPublicKey(message.content.text || '');
|
|
73
|
+
if (!publicKey) {
|
|
74
|
+
callback({
|
|
75
|
+
text: 'Please provide a Casper public key or address to check the balance.',
|
|
76
|
+
content: { error: 'No public key provided' }
|
|
77
|
+
});
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const balance = await client.getBalance(publicKey);
|
|
81
|
+
const balanceInCSPR = parseInt(balance) / 1000000000; // Convert motes to CSPR
|
|
82
|
+
callback({
|
|
83
|
+
text: `๐ฐ Balance for ${publicKey}:\n${balanceInCSPR.toFixed(9)} CSPR`,
|
|
84
|
+
content: {
|
|
85
|
+
publicKey,
|
|
86
|
+
balance: balanceInCSPR
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
callback({
|
|
92
|
+
text: `Error checking balance: ${error.message}`,
|
|
93
|
+
content: { error: error.message }
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
examples: [
|
|
98
|
+
[
|
|
99
|
+
{
|
|
100
|
+
name: '{{user1}}',
|
|
101
|
+
content: { text: 'Check balance for 02a1b2c3d4e5f6...' }
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: '{{agent}}',
|
|
105
|
+
content: { text: 'Let me check the balance...' }
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
]
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* ่ฝฌ่ดฆ Action
|
|
112
|
+
*/
|
|
113
|
+
exports.transferAction = {
|
|
114
|
+
name: 'TRANSFER_CASPER_TOKENS',
|
|
115
|
+
similes: ['SEND_CASPER', 'SEND_CSPR', 'CASPER_TRANSFER'],
|
|
116
|
+
description: 'Transfer CSPR tokens to another Casper account',
|
|
117
|
+
validate: async (_runtime, message) => {
|
|
118
|
+
return (message.content.text?.includes('send') ||
|
|
119
|
+
message.content.text?.includes('transfer') ||
|
|
120
|
+
message.content.text?.includes('pay')) ?? false;
|
|
121
|
+
},
|
|
122
|
+
handler: async (runtime, message, _state, _options, callback) => {
|
|
123
|
+
try {
|
|
124
|
+
const nodeUrl = runtime.getSetting('CASPER_NODE_URL') || 'https://node.testnet.cspr.cloud:443';
|
|
125
|
+
const client = new client_1.CasperClient({ nodeUrl });
|
|
126
|
+
const privateKey = runtime.getSetting('CASPER_PRIVATE_KEY');
|
|
127
|
+
if (!privateKey) {
|
|
128
|
+
callback({
|
|
129
|
+
text: 'Private key not configured. Please set CASPER_PRIVATE_KEY in environment variables.',
|
|
130
|
+
content: { error: 'No private key configured' }
|
|
131
|
+
});
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
// ไปๆถๆฏไธญๆๅๆฅๆถๆนๅ้้ข
|
|
135
|
+
const { toPublicKey, amount } = parseTransferDetails(message.content.text || '');
|
|
136
|
+
if (!toPublicKey || !amount) {
|
|
137
|
+
callback({
|
|
138
|
+
text: 'Please specify recipient public key and amount. Example: "Send 10 CSPR to 02abc..."',
|
|
139
|
+
content: { error: 'Missing transfer details' }
|
|
140
|
+
});
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const deployHash = await client.transfer(privateKey, toPublicKey, amount * 1000000000);
|
|
144
|
+
callback({
|
|
145
|
+
text: `โ
Transfer initiated!\n\nAmount: ${amount} CSPR\nTo: ${toPublicKey}\nDeploy Hash: ${deployHash}\n\nYou can check the transaction status using the deploy hash.`,
|
|
146
|
+
content: {
|
|
147
|
+
deployHash,
|
|
148
|
+
amount,
|
|
149
|
+
recipient: toPublicKey
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
callback({
|
|
155
|
+
text: `Error transferring tokens: ${error.message}`,
|
|
156
|
+
content: { error: error.message }
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
examples: [
|
|
161
|
+
[
|
|
162
|
+
{
|
|
163
|
+
name: '{{user1}}',
|
|
164
|
+
content: { text: 'Send 5 CSPR to 02a1b2c3d4e5f6...' }
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
name: '{{agent}}',
|
|
168
|
+
content: { text: 'I\'ll initiate the transfer...' }
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
]
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* ๆฅ่ฏขไบคๆ็ถๆ Action
|
|
175
|
+
*/
|
|
176
|
+
exports.getDeployStatusAction = {
|
|
177
|
+
name: 'GET_DEPLOY_STATUS',
|
|
178
|
+
similes: ['CHECK_TRANSACTION', 'TX_STATUS'],
|
|
179
|
+
description: 'Check the status of a Casper transaction by deploy hash',
|
|
180
|
+
validate: async (_runtime, message) => {
|
|
181
|
+
return (message.content.text?.includes('transaction') ||
|
|
182
|
+
message.content.text?.includes('status') ||
|
|
183
|
+
message.content.text?.includes('deploy')) ?? false;
|
|
184
|
+
},
|
|
185
|
+
handler: async (runtime, message, _state, _options, callback) => {
|
|
186
|
+
try {
|
|
187
|
+
const nodeUrl = runtime.getSetting('CASPER_NODE_URL') || 'https://node.testnet.cspr.cloud:443';
|
|
188
|
+
const client = new client_1.CasperClient({ nodeUrl });
|
|
189
|
+
const deployHash = extractDeployHash(message.content.text || '');
|
|
190
|
+
if (!deployHash) {
|
|
191
|
+
callback({
|
|
192
|
+
text: 'Please provide a deploy hash to check the transaction status.',
|
|
193
|
+
content: { error: 'No deploy hash provided' }
|
|
194
|
+
});
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const status = await client.getDeployStatus(deployHash);
|
|
198
|
+
callback({
|
|
199
|
+
text: `๐ Transaction Status:\nDeploy Hash: ${deployHash}\nStatus: ${JSON.stringify(status, null, 2)}`,
|
|
200
|
+
content: {
|
|
201
|
+
deployHash,
|
|
202
|
+
status
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
callback({
|
|
208
|
+
text: `Error checking transaction status: ${error.message}`,
|
|
209
|
+
content: { error: error.message }
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
examples: [
|
|
214
|
+
[
|
|
215
|
+
{
|
|
216
|
+
name: '{{user1}}',
|
|
217
|
+
content: { text: 'Check status of deploy abc123...' }
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
name: '{{agent}}',
|
|
221
|
+
content: { text: 'Let me check the transaction status...' }
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
]
|
|
225
|
+
};
|
|
226
|
+
// Helper functions
|
|
227
|
+
function extractPublicKey(text) {
|
|
228
|
+
// Match Casper public key pattern (hex string starting with 02 or 03)
|
|
229
|
+
const match = text.match(/0[2-3][0-9a-fA-F]{64}/);
|
|
230
|
+
return match ? match[0] : null;
|
|
231
|
+
}
|
|
232
|
+
function extractDeployHash(text) {
|
|
233
|
+
// Match deploy hash pattern (hex string)
|
|
234
|
+
const match = text.match(/[0-9a-fA-F]{64}/);
|
|
235
|
+
return match ? match[0] : null;
|
|
236
|
+
}
|
|
237
|
+
function parseTransferDetails(text) {
|
|
238
|
+
const publicKey = extractPublicKey(text);
|
|
239
|
+
// Match amount pattern (number followed by optional CSPR)
|
|
240
|
+
const amountMatch = text.match(/(\d+(?:\.\d+)?)\s*(?:CSPR)?/i);
|
|
241
|
+
const amount = amountMatch ? parseFloat(amountMatch[1]) : null;
|
|
242
|
+
return { toPublicKey: publicKey, amount };
|
|
243
|
+
}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface CasperConfig {
|
|
2
|
+
nodeUrl: string;
|
|
3
|
+
chainName?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface WalletInfo {
|
|
6
|
+
publicKey: string;
|
|
7
|
+
privateKey?: string;
|
|
8
|
+
address: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class CasperClient {
|
|
11
|
+
private client;
|
|
12
|
+
private config;
|
|
13
|
+
constructor(config: CasperConfig);
|
|
14
|
+
/**
|
|
15
|
+
* ็ๆๆฐ็้ฑๅ
ๅฏ้ฅๅฏน
|
|
16
|
+
*/
|
|
17
|
+
generateWallet(): WalletInfo;
|
|
18
|
+
/**
|
|
19
|
+
* ไป็ง้ฅๆขๅค้ฑๅ
|
|
20
|
+
*/
|
|
21
|
+
restoreWallet(privateKeyHex: string): WalletInfo;
|
|
22
|
+
/**
|
|
23
|
+
* ๆฅ่ฏข่ดฆๆทไฝ้ข
|
|
24
|
+
*/
|
|
25
|
+
getBalance(publicKey: string): Promise<string>;
|
|
26
|
+
/**
|
|
27
|
+
* ๅ้ CSPR ไปฃๅธ่ฝฌ่ดฆ
|
|
28
|
+
*/
|
|
29
|
+
transfer(fromPrivateKey: string, toPublicKey: string, amount: number, paymentAmount?: number): Promise<string>;
|
|
30
|
+
/**
|
|
31
|
+
* ้จ็ฝฒๆบ่ฝๅ็บฆ
|
|
32
|
+
*/
|
|
33
|
+
deployContract(privateKey: string, wasmBytes: Uint8Array, entryPoint: string, args: Record<string, any>, paymentAmount?: number): Promise<string>;
|
|
34
|
+
/**
|
|
35
|
+
* ่ฐ็จๆบ่ฝๅ็บฆ
|
|
36
|
+
*/
|
|
37
|
+
callContract(privateKey: string, contractHash: string, entryPoint: string, args: Record<string, any>, paymentAmount?: number): Promise<string>;
|
|
38
|
+
/**
|
|
39
|
+
* ๆฅ่ฏขไบคๆ็ถๆ
|
|
40
|
+
*/
|
|
41
|
+
getDeployStatus(deployHash: string): Promise<any>;
|
|
42
|
+
/**
|
|
43
|
+
* ่ทๅๆๆฐๅบๅไฟกๆฏ
|
|
44
|
+
*/
|
|
45
|
+
getLatestBlock(): Promise<any>;
|
|
46
|
+
/**
|
|
47
|
+
* ่ทๅ็ถๆๆ นๅๅธ
|
|
48
|
+
*/
|
|
49
|
+
private getStateRootHash;
|
|
50
|
+
}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CasperClient = void 0;
|
|
4
|
+
const casper_js_sdk_1 = require("casper-js-sdk");
|
|
5
|
+
class CasperClient {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
this.config = config;
|
|
8
|
+
this.client = new casper_js_sdk_1.CasperServiceByJsonRPC(config.nodeUrl);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* ็ๆๆฐ็้ฑๅ
ๅฏ้ฅๅฏน
|
|
12
|
+
*/
|
|
13
|
+
generateWallet() {
|
|
14
|
+
const keyPair = casper_js_sdk_1.Keys.Ed25519.new();
|
|
15
|
+
const publicKeyHex = Buffer.from(keyPair.publicKey).toString('hex');
|
|
16
|
+
const privateKeyHex = Buffer.from(keyPair.privateKey).toString('hex');
|
|
17
|
+
const accountHash = Buffer.from(keyPair.accountHash()).toString('hex');
|
|
18
|
+
const address = `account-hash-${accountHash}`;
|
|
19
|
+
return {
|
|
20
|
+
publicKey: `02${publicKeyHex}`,
|
|
21
|
+
privateKey: privateKeyHex,
|
|
22
|
+
address
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* ไป็ง้ฅๆขๅค้ฑๅ
|
|
27
|
+
*/
|
|
28
|
+
restoreWallet(privateKeyHex) {
|
|
29
|
+
const privateKeyBytes = Buffer.from(privateKeyHex, 'hex');
|
|
30
|
+
const publicKeyBytes = casper_js_sdk_1.Keys.Ed25519.privateToPublicKey(privateKeyBytes);
|
|
31
|
+
const keyPair = casper_js_sdk_1.Keys.Ed25519.parseKeyPair(publicKeyBytes, privateKeyBytes);
|
|
32
|
+
const publicKey = `02${Buffer.from(keyPair.publicKey).toString('hex')}`;
|
|
33
|
+
const accountHash = Buffer.from(keyPair.accountHash()).toString('hex');
|
|
34
|
+
const address = `account-hash-${accountHash}`;
|
|
35
|
+
return {
|
|
36
|
+
publicKey,
|
|
37
|
+
privateKey: privateKeyHex,
|
|
38
|
+
address
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* ๆฅ่ฏข่ดฆๆทไฝ้ข
|
|
43
|
+
*/
|
|
44
|
+
async getBalance(publicKey) {
|
|
45
|
+
try {
|
|
46
|
+
// ็งป้คๅ
ฌ้ฅๅ็ผ (02 or 03)
|
|
47
|
+
const publicKeyHex = publicKey.startsWith('02') || publicKey.startsWith('03')
|
|
48
|
+
? publicKey.slice(2)
|
|
49
|
+
: publicKey;
|
|
50
|
+
const publicKeyBytes = Buffer.from(publicKeyHex, 'hex');
|
|
51
|
+
const clPublicKey = casper_js_sdk_1.CLPublicKey.fromEd25519(publicKeyBytes);
|
|
52
|
+
// ่ทๅ็ถๆๆ นๅๅธ
|
|
53
|
+
const stateRootHash = await this.getStateRootHash();
|
|
54
|
+
// ่ทๅ่ดฆๆทไฝ้ข URef
|
|
55
|
+
const balanceUref = await this.client.getAccountBalanceUrefByPublicKey(stateRootHash, clPublicKey);
|
|
56
|
+
// ่ทๅไฝ้ข
|
|
57
|
+
const balance = await this.client.getAccountBalance(stateRootHash, balanceUref);
|
|
58
|
+
return balance.toString();
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
console.error('Error getting balance:', error);
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* ๅ้ CSPR ไปฃๅธ่ฝฌ่ดฆ
|
|
67
|
+
*/
|
|
68
|
+
async transfer(fromPrivateKey, toPublicKey, amount, paymentAmount = 2500000000) {
|
|
69
|
+
try {
|
|
70
|
+
// ่งฃๆ็ง้ฅ
|
|
71
|
+
const privateKeyBytes = Buffer.from(fromPrivateKey, 'hex');
|
|
72
|
+
const publicKeyBytes = casper_js_sdk_1.Keys.Ed25519.privateToPublicKey(privateKeyBytes);
|
|
73
|
+
const keyPair = casper_js_sdk_1.Keys.Ed25519.parseKeyPair(publicKeyBytes, privateKeyBytes);
|
|
74
|
+
// ๆๅปบ็ฎๆ ๅ
ฌ้ฅ
|
|
75
|
+
const targetPublicKeyHex = toPublicKey.startsWith('02') || toPublicKey.startsWith('03')
|
|
76
|
+
? toPublicKey.slice(2)
|
|
77
|
+
: toPublicKey;
|
|
78
|
+
const targetPublicKeyBytes = Buffer.from(targetPublicKeyHex, 'hex');
|
|
79
|
+
const targetCLPublicKey = casper_js_sdk_1.CLPublicKey.fromEd25519(targetPublicKeyBytes);
|
|
80
|
+
// ๆๅปบ่ฝฌ่ดฆ session
|
|
81
|
+
const session = casper_js_sdk_1.DeployUtil.ExecutableDeployItem.newTransfer(amount, targetCLPublicKey, null, 0);
|
|
82
|
+
// ๆๅปบๆฏไป
|
|
83
|
+
const payment = casper_js_sdk_1.DeployUtil.standardPayment(paymentAmount);
|
|
84
|
+
// ๅๅปบ deploy ๅๆฐ
|
|
85
|
+
const deployParams = new casper_js_sdk_1.DeployUtil.DeployParams(keyPair.publicKey, this.config.chainName || 'casper-test', 1, 1800000);
|
|
86
|
+
// ๅๅปบ deploy
|
|
87
|
+
const deploy = casper_js_sdk_1.DeployUtil.makeDeploy(deployParams, session, payment);
|
|
88
|
+
// ็ญพๅๅนถๅ้
|
|
89
|
+
const signedDeploy = casper_js_sdk_1.DeployUtil.signDeploy(deploy, keyPair);
|
|
90
|
+
const result = await this.client.deploy(signedDeploy);
|
|
91
|
+
return result.deploy_hash;
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
console.error('Error transferring tokens:', error);
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* ้จ็ฝฒๆบ่ฝๅ็บฆ
|
|
100
|
+
*/
|
|
101
|
+
async deployContract(privateKey, wasmBytes, entryPoint, args, paymentAmount = 10000000000) {
|
|
102
|
+
try {
|
|
103
|
+
const privateKeyBytes = Buffer.from(privateKey, 'hex');
|
|
104
|
+
const publicKeyBytes = casper_js_sdk_1.Keys.Ed25519.privateToPublicKey(privateKeyBytes);
|
|
105
|
+
const keyPair = casper_js_sdk_1.Keys.Ed25519.parseKeyPair(publicKeyBytes, privateKeyBytes);
|
|
106
|
+
// ๆๅปบๅ็บฆๅๆฐ
|
|
107
|
+
const runtimeArgs = casper_js_sdk_1.RuntimeArgs.fromMap(args);
|
|
108
|
+
// ๅๅปบ session
|
|
109
|
+
const session = casper_js_sdk_1.DeployUtil.ExecutableDeployItem.newModuleBytes(wasmBytes, runtimeArgs);
|
|
110
|
+
const payment = casper_js_sdk_1.DeployUtil.standardPayment(paymentAmount);
|
|
111
|
+
const deployParams = new casper_js_sdk_1.DeployUtil.DeployParams(keyPair.publicKey, this.config.chainName || 'casper-test', 1, 1800000);
|
|
112
|
+
const deploy = casper_js_sdk_1.DeployUtil.makeDeploy(deployParams, session, payment);
|
|
113
|
+
const signedDeploy = casper_js_sdk_1.DeployUtil.signDeploy(deploy, keyPair);
|
|
114
|
+
const result = await this.client.deploy(signedDeploy);
|
|
115
|
+
return result.deploy_hash;
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
console.error('Error deploying contract:', error);
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* ่ฐ็จๆบ่ฝๅ็บฆ
|
|
124
|
+
*/
|
|
125
|
+
async callContract(privateKey, contractHash, entryPoint, args, paymentAmount = 2500000000) {
|
|
126
|
+
try {
|
|
127
|
+
const privateKeyBytes = Buffer.from(privateKey, 'hex');
|
|
128
|
+
const publicKeyBytes = casper_js_sdk_1.Keys.Ed25519.privateToPublicKey(privateKeyBytes);
|
|
129
|
+
const keyPair = casper_js_sdk_1.Keys.Ed25519.parseKeyPair(publicKeyBytes, privateKeyBytes);
|
|
130
|
+
const runtimeArgs = casper_js_sdk_1.RuntimeArgs.fromMap(args);
|
|
131
|
+
const contractHashBytes = Buffer.from(contractHash.replace('0x', ''), 'hex');
|
|
132
|
+
const session = casper_js_sdk_1.DeployUtil.ExecutableDeployItem.newStoredContractByHash(contractHashBytes, entryPoint, runtimeArgs);
|
|
133
|
+
const payment = casper_js_sdk_1.DeployUtil.standardPayment(paymentAmount);
|
|
134
|
+
const deployParams = new casper_js_sdk_1.DeployUtil.DeployParams(keyPair.publicKey, this.config.chainName || 'casper-test', 1, 1800000);
|
|
135
|
+
const deploy = casper_js_sdk_1.DeployUtil.makeDeploy(deployParams, session, payment);
|
|
136
|
+
const signedDeploy = casper_js_sdk_1.DeployUtil.signDeploy(deploy, keyPair);
|
|
137
|
+
const result = await this.client.deploy(signedDeploy);
|
|
138
|
+
return result.deploy_hash;
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
console.error('Error calling contract:', error);
|
|
142
|
+
throw error;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* ๆฅ่ฏขไบคๆ็ถๆ
|
|
147
|
+
*/
|
|
148
|
+
async getDeployStatus(deployHash) {
|
|
149
|
+
try {
|
|
150
|
+
const deployInfo = await this.client.getDeployInfo(deployHash);
|
|
151
|
+
return deployInfo;
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
console.error('Error getting deploy status:', error);
|
|
155
|
+
throw error;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* ่ทๅๆๆฐๅบๅไฟกๆฏ
|
|
160
|
+
*/
|
|
161
|
+
async getLatestBlock() {
|
|
162
|
+
try {
|
|
163
|
+
const blockInfo = await this.client.getLatestBlockInfo();
|
|
164
|
+
return {
|
|
165
|
+
stateRootHash: blockInfo.block?.header.state_root_hash,
|
|
166
|
+
timestamp: blockInfo.block?.header.timestamp,
|
|
167
|
+
height: blockInfo.block?.header.height
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
console.error('Error getting latest block:', error);
|
|
172
|
+
throw error;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* ่ทๅ็ถๆๆ นๅๅธ
|
|
177
|
+
*/
|
|
178
|
+
async getStateRootHash() {
|
|
179
|
+
const blockInfo = await this.client.getLatestBlockInfo();
|
|
180
|
+
return blockInfo.block?.header.state_root_hash || '';
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
exports.CasperClient = CasperClient;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Plugin } from '@elizaos/core';
|
|
2
|
+
/**
|
|
3
|
+
* Casper Blockchain Plugin for Eliza
|
|
4
|
+
*
|
|
5
|
+
* This plugin provides integration with the Casper blockchain network,
|
|
6
|
+
* enabling AI agents to interact with Casper accounts, perform transactions,
|
|
7
|
+
* and query blockchain data.
|
|
8
|
+
*/
|
|
9
|
+
export declare const casperPlugin: Plugin;
|
|
10
|
+
export default casperPlugin;
|
|
11
|
+
export * from './client';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.casperPlugin = void 0;
|
|
18
|
+
const actions_1 = require("./actions");
|
|
19
|
+
const providers_1 = require("./providers");
|
|
20
|
+
/**
|
|
21
|
+
* Casper Blockchain Plugin for Eliza
|
|
22
|
+
*
|
|
23
|
+
* This plugin provides integration with the Casper blockchain network,
|
|
24
|
+
* enabling AI agents to interact with Casper accounts, perform transactions,
|
|
25
|
+
* and query blockchain data.
|
|
26
|
+
*/
|
|
27
|
+
exports.casperPlugin = {
|
|
28
|
+
name: 'casper',
|
|
29
|
+
description: 'Casper blockchain integration plugin',
|
|
30
|
+
actions: [
|
|
31
|
+
actions_1.generateWalletAction,
|
|
32
|
+
actions_1.getBalanceAction,
|
|
33
|
+
actions_1.transferAction,
|
|
34
|
+
actions_1.getDeployStatusAction
|
|
35
|
+
],
|
|
36
|
+
providers: [
|
|
37
|
+
providers_1.casperNetworkProvider,
|
|
38
|
+
providers_1.casperWalletProvider,
|
|
39
|
+
providers_1.casperGasProvider
|
|
40
|
+
],
|
|
41
|
+
evaluators: [],
|
|
42
|
+
services: []
|
|
43
|
+
};
|
|
44
|
+
exports.default = exports.casperPlugin;
|
|
45
|
+
// Export types and classes for external use
|
|
46
|
+
__exportStar(require("./client"), exports);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Provider } from '@elizaos/core';
|
|
2
|
+
/**
|
|
3
|
+
* Casper ็ฝ็ปไฟกๆฏ Provider
|
|
4
|
+
*/
|
|
5
|
+
export declare const casperNetworkProvider: Provider;
|
|
6
|
+
/**
|
|
7
|
+
* Casper ้ฑๅ
ไฟกๆฏ Provider
|
|
8
|
+
*/
|
|
9
|
+
export declare const casperWalletProvider: Provider;
|
|
10
|
+
/**
|
|
11
|
+
* Casper Gas ่ดน็จ Provider
|
|
12
|
+
*/
|
|
13
|
+
export declare const casperGasProvider: Provider;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.casperGasProvider = exports.casperWalletProvider = exports.casperNetworkProvider = void 0;
|
|
4
|
+
const client_1 = require("./client");
|
|
5
|
+
/**
|
|
6
|
+
* Casper ็ฝ็ปไฟกๆฏ Provider
|
|
7
|
+
*/
|
|
8
|
+
exports.casperNetworkProvider = {
|
|
9
|
+
name: 'casperNetwork',
|
|
10
|
+
get: async (runtime, message, state) => {
|
|
11
|
+
try {
|
|
12
|
+
const nodeUrl = runtime.getSetting('CASPER_NODE_URL') || 'https://node.testnet.cspr.cloud:443';
|
|
13
|
+
const client = new client_1.CasperClient({ nodeUrl });
|
|
14
|
+
const latestBlock = await client.getLatestBlock();
|
|
15
|
+
return {
|
|
16
|
+
text: `๐ Casper Network Status:
|
|
17
|
+
Node URL: ${nodeUrl}
|
|
18
|
+
State Root Hash: ${latestBlock.stateRootHash}
|
|
19
|
+
Timestamp: ${latestBlock.timestamp}`
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
return {
|
|
24
|
+
text: `Error fetching network status: ${error.message}`
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Casper ้ฑๅ
ไฟกๆฏ Provider
|
|
31
|
+
*/
|
|
32
|
+
exports.casperWalletProvider = {
|
|
33
|
+
name: 'casperWallet',
|
|
34
|
+
get: async (runtime, message, state) => {
|
|
35
|
+
try {
|
|
36
|
+
const publicKey = runtime.getSetting('CASPER_PUBLIC_KEY');
|
|
37
|
+
if (!publicKey) {
|
|
38
|
+
return {
|
|
39
|
+
text: 'No Casper wallet configured. Set CASPER_PUBLIC_KEY to view wallet info.'
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const nodeUrl = runtime.getSetting('CASPER_NODE_URL') || 'https://node.testnet.cspr.cloud:443';
|
|
43
|
+
const client = new client_1.CasperClient({ nodeUrl });
|
|
44
|
+
const balance = await client.getBalance(publicKey);
|
|
45
|
+
const balanceInCSPR = parseInt(balance) / 1000000000;
|
|
46
|
+
return {
|
|
47
|
+
text: `๐ผ Your Casper Wallet:
|
|
48
|
+
Address: ${publicKey}
|
|
49
|
+
Balance: ${balanceInCSPR.toFixed(9)} CSPR`
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
return {
|
|
54
|
+
text: `Error fetching wallet info: ${error.message}`
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Casper Gas ่ดน็จ Provider
|
|
61
|
+
*/
|
|
62
|
+
exports.casperGasProvider = {
|
|
63
|
+
name: 'casperGas',
|
|
64
|
+
get: async (runtime, message, state) => {
|
|
65
|
+
// Casper uses fixed gas prices, but we can provide guidance
|
|
66
|
+
return {
|
|
67
|
+
text: `โฝ Casper Gas Fees Guide:
|
|
68
|
+
|
|
69
|
+
Standard Transfer: ~2.5 CSPR (2,500,000,000 motes)
|
|
70
|
+
Contract Deployment: ~10 CSPR (10,000,000,000 motes)
|
|
71
|
+
Contract Call: ~2.5 CSPR (2,500,000,000 motes)
|
|
72
|
+
|
|
73
|
+
Note: Gas fees are relatively stable on Casper network.`
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@suxinmin/plugin-casper",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Casper blockchain plugin for Eliza AI agent framework",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"dev": "tsc --watch",
|
|
10
|
+
"clean": "rimraf dist",
|
|
11
|
+
"prebuild": "npm run clean"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"eliza",
|
|
15
|
+
"plugin",
|
|
16
|
+
"casper",
|
|
17
|
+
"blockchain",
|
|
18
|
+
"web3",
|
|
19
|
+
"cryptocurrency"
|
|
20
|
+
],
|
|
21
|
+
"author": "casper Community",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"README.md",
|
|
26
|
+
"LICENSE"
|
|
27
|
+
],
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/xinminsu/plugin-casper.git"
|
|
31
|
+
},
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/xinminsu/plugin-casper/issues"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://github.com/xinminsu/plugin-casper#readme",
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@elizaos/core": "latest",
|
|
38
|
+
"casper-js-sdk": "^2.15.4"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/node": "^20.10.0",
|
|
42
|
+
"rimraf": "^6.1.3",
|
|
43
|
+
"typescript": "^5.3.3"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"@elizaos/core": "latest"
|
|
47
|
+
}
|
|
48
|
+
}
|