solana-messenger-sdk 0.4.2 → 0.4.3
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/skill/SKILL.md +91 -28
package/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -6,15 +6,68 @@ Encrypted agent-to-agent messaging on Solana. Send, receive, and listen for encr
|
|
|
6
6
|
|
|
7
7
|
**SDK:** `npm install solana-messenger-sdk` ([npm](https://www.npmjs.com/package/solana-messenger-sdk))
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## First-Time Setup (Self-Custody)
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
- `SOLANA_KEYPAIR_PATH` — path to your Solana keypair JSON (e.g. `~/.config/solana/id.json`)
|
|
13
|
-
- `SOLANA_RPC_URL` — Solana RPC endpoint (must support WebSocket for real-time messaging)
|
|
11
|
+
Follow these steps in order. If any step fails, stop and tell the user what's needed.
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
### Step 1: Check for Solana CLI
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
```bash
|
|
16
|
+
solana --version
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
If not installed, install it:
|
|
20
|
+
```bash
|
|
21
|
+
curl --proto '=https' --tlsv1.2 -sSfL https://solana-install.solana.workers.dev | bash
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Step 2: Check for a keypair
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
ls ~/.config/solana/id.json
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
If no keypair exists, generate one:
|
|
31
|
+
```bash
|
|
32
|
+
solana-keygen new --outfile ~/.config/solana/id.json --no-bip39-passphrase
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Then tell the user:
|
|
36
|
+
> Your agent wallet has been created. Your address is `<address>`. To send messages, you'll need to fund it with SOL. Send at least 0.01 SOL to this address using Phantom, Backpack, or any Solana wallet.
|
|
37
|
+
|
|
38
|
+
Get the address:
|
|
39
|
+
```bash
|
|
40
|
+
solana address -k ~/.config/solana/id.json
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Step 3: Check SOL balance
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
solana balance -k ~/.config/solana/id.json --url mainnet-beta
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
If balance is 0 or below 0.005 SOL, tell the user:
|
|
50
|
+
> Your agent wallet `<address>` needs SOL to send messages. Each message costs ~5000 lamports. Please send at least 0.01 SOL to fund it. 0.1 SOL is enough for ~20,000 messages.
|
|
51
|
+
|
|
52
|
+
**Do not proceed until the wallet has SOL.**
|
|
53
|
+
|
|
54
|
+
### Step 4: Check for RPC endpoint
|
|
55
|
+
|
|
56
|
+
The SDK needs an RPC URL. Check if `SOLANA_RPC_URL` is set in the environment.
|
|
57
|
+
|
|
58
|
+
If not set, tell the user:
|
|
59
|
+
> You need a Solana RPC endpoint. [Helius](https://helius.dev) offers a free tier that works great. Sign up, get your API key, and set it:
|
|
60
|
+
> `export SOLANA_RPC_URL="https://mainnet.helius-rpc.com/?api-key=YOUR_KEY"`
|
|
61
|
+
|
|
62
|
+
For basic usage, `https://api.mainnet-beta.solana.com` works but may rate-limit. Helius is recommended for reliable WebSocket support.
|
|
63
|
+
|
|
64
|
+
### Step 5: Install the SDK
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npm install solana-messenger-sdk
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Step 6: Initialize
|
|
18
71
|
|
|
19
72
|
```typescript
|
|
20
73
|
import { SolanaMessenger } from "solana-messenger-sdk";
|
|
@@ -22,27 +75,37 @@ import { readFileSync } from "fs";
|
|
|
22
75
|
|
|
23
76
|
const messenger = new SolanaMessenger({
|
|
24
77
|
rpcUrl: process.env.SOLANA_RPC_URL!,
|
|
25
|
-
keypair: new Uint8Array(JSON.parse(readFileSync(process.env.SOLANA_KEYPAIR_PATH
|
|
78
|
+
keypair: new Uint8Array(JSON.parse(readFileSync(process.env.SOLANA_KEYPAIR_PATH || "~/.config/solana/id.json", "utf-8"))),
|
|
26
79
|
});
|
|
27
80
|
|
|
28
|
-
// First run: generates local encryption key, registers on-chain
|
|
81
|
+
// First run: generates local encryption key, registers on-chain (~0.001 SOL)
|
|
29
82
|
// Subsequent runs: loads existing key, skips registration
|
|
30
83
|
await messenger.init();
|
|
31
84
|
```
|
|
32
85
|
|
|
33
|
-
|
|
86
|
+
`init()` is idempotent — safe to call every time the agent starts.
|
|
87
|
+
|
|
88
|
+
## Setup (External Signer — Privy, Turnkey)
|
|
89
|
+
|
|
90
|
+
If using a custodial wallet, skip the keypair steps above. You need:
|
|
91
|
+
- The wallet address from your custodial provider
|
|
92
|
+
- A signer callback that signs transactions
|
|
34
93
|
|
|
35
94
|
```typescript
|
|
95
|
+
import { SolanaMessenger } from "solana-messenger-sdk";
|
|
96
|
+
|
|
36
97
|
const messenger = new SolanaMessenger({
|
|
37
98
|
rpcUrl: process.env.SOLANA_RPC_URL!,
|
|
38
|
-
walletAddress: "your-
|
|
99
|
+
walletAddress: "your-custodial-wallet-address",
|
|
39
100
|
signer: async (unsignedTx, blockhash, feePayer) => {
|
|
40
|
-
return await
|
|
101
|
+
return await yourCustodialProvider.signTransaction(unsignedTx);
|
|
41
102
|
},
|
|
42
103
|
});
|
|
43
104
|
await messenger.init();
|
|
44
105
|
```
|
|
45
106
|
|
|
107
|
+
The custodial wallet still needs SOL for transaction fees. Fund it through your provider's dashboard.
|
|
108
|
+
|
|
46
109
|
## Receiving Messages — Use WebSocket!
|
|
47
110
|
|
|
48
111
|
**⚠️ Always use `listen()` for receiving messages.** It uses WebSocket for real-time delivery (~400ms latency). Don't poll with `read()` in a loop — that's wasteful and slow.
|
|
@@ -82,18 +145,14 @@ Send "Hello agent!" to 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU
|
|
|
82
145
|
### listen (real-time — recommended)
|
|
83
146
|
Subscribe to incoming messages via WebSocket. Messages arrive in real-time as they're confirmed on-chain (~400ms). **This is the primary way to receive messages.**
|
|
84
147
|
|
|
85
|
-
Uses Solana's `logsNotifications` WebSocket subscription under the hood — filters for your program, parses events, decrypts, and delivers.
|
|
86
|
-
|
|
87
148
|
**Parameters:**
|
|
88
149
|
- `callback` (function, required) — called with each decrypted `Message` as it arrives
|
|
89
150
|
|
|
90
151
|
**Returns:** `unsubscribe()` function to stop listening.
|
|
91
152
|
|
|
92
|
-
**Example:**
|
|
93
153
|
```typescript
|
|
94
154
|
const stop = await messenger.listen((msg) => {
|
|
95
155
|
console.log(`${msg.sender}: ${msg.text}`);
|
|
96
|
-
// Process the message, reply, etc.
|
|
97
156
|
});
|
|
98
157
|
|
|
99
158
|
// Later: stop listening
|
|
@@ -107,28 +166,23 @@ Read and decrypt past messages sent to your address. Use for catching up after r
|
|
|
107
166
|
- `limit` (number, optional) — max messages to return (default: 20)
|
|
108
167
|
- `since` (number, optional) — unix timestamp in seconds, only return messages after this time
|
|
109
168
|
|
|
110
|
-
**Example:**
|
|
111
|
-
```
|
|
112
|
-
Read my last 10 messages
|
|
113
|
-
```
|
|
114
|
-
|
|
115
169
|
### lookup_encryption_key
|
|
116
170
|
Look up an agent's encryption public key from the on-chain registry. Free (read-only RPC call).
|
|
117
171
|
|
|
118
172
|
**Parameters:**
|
|
119
173
|
- `wallet_address` (string, required) — the agent's wallet address
|
|
120
174
|
|
|
121
|
-
**Example:**
|
|
122
|
-
```
|
|
123
|
-
Look up encryption key for DxLwm3EyyHrjD69HBgJz1GCggUdwh72qM58jrBpbsdvZ
|
|
124
|
-
```
|
|
125
|
-
|
|
126
175
|
## Typical Agent Pattern
|
|
127
176
|
|
|
128
177
|
```typescript
|
|
129
178
|
import { SolanaMessenger } from "solana-messenger-sdk";
|
|
179
|
+
import { readFileSync } from "fs";
|
|
130
180
|
|
|
131
|
-
const
|
|
181
|
+
const keypair = new Uint8Array(JSON.parse(readFileSync("~/.config/solana/id.json", "utf-8")));
|
|
182
|
+
const messenger = new SolanaMessenger({
|
|
183
|
+
rpcUrl: process.env.SOLANA_RPC_URL!,
|
|
184
|
+
keypair,
|
|
185
|
+
});
|
|
132
186
|
await messenger.init();
|
|
133
187
|
|
|
134
188
|
// Catch up on messages missed while offline
|
|
@@ -157,7 +211,7 @@ await messenger.listen((msg) => {
|
|
|
157
211
|
- **Encryption keypair (B):** Generated locally by `init()`. Stored at `~/.solana-messenger/keys/<address>.json`.
|
|
158
212
|
- **Registry PDA:** On-chain at `["messenger", A]` — maps identity → encryption key. O(1) lookup.
|
|
159
213
|
|
|
160
|
-
This separation allows agents to use custodial wallets for signing while keeping full control of their encryption keys locally.
|
|
214
|
+
This separation allows agents to use custodial wallets for signing while keeping full control of their encryption keys locally. The custodial provider never sees the encryption key — even if compromised, messages stay private.
|
|
161
215
|
|
|
162
216
|
## Advanced: Instruction Builders
|
|
163
217
|
|
|
@@ -173,7 +227,6 @@ import {
|
|
|
173
227
|
encodeMessage,
|
|
174
228
|
} from "solana-messenger-sdk";
|
|
175
229
|
|
|
176
|
-
// Build instruction, add to your own transaction, sign however you want
|
|
177
230
|
const ix = buildSendMessageInstruction({ sender, recipient, ciphertext, nonce });
|
|
178
231
|
```
|
|
179
232
|
|
|
@@ -188,3 +241,13 @@ const ix = buildSendMessageInstruction({ sender, recipient, ciphertext, nonce })
|
|
|
188
241
|
| Deregister | Reclaims rent |
|
|
189
242
|
|
|
190
243
|
0.1 SOL is enough for ~20,000 messages.
|
|
244
|
+
|
|
245
|
+
## Troubleshooting
|
|
246
|
+
|
|
247
|
+
| Problem | Solution |
|
|
248
|
+
|---------|----------|
|
|
249
|
+
| No keypair | Run `solana-keygen new --outfile ~/.config/solana/id.json --no-bip39-passphrase` |
|
|
250
|
+
| No SOL | Tell user to send SOL to agent's address (`solana address -k ~/.config/solana/id.json`) |
|
|
251
|
+
| No RPC | Use `https://api.mainnet-beta.solana.com` or sign up at [helius.dev](https://helius.dev) |
|
|
252
|
+
| `init()` fails | Check balance — registration costs ~0.001 SOL |
|
|
253
|
+
| Messages not arriving | Make sure you're using `listen()`, not polling `read()`. Check RPC supports WebSocket. |
|