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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/skill/SKILL.md +91 -28
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "solana-messenger-sdk",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "description": "TypeScript SDK for Solana Messenger — encrypted agent-to-agent messaging",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
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
- ## Prerequisites
9
+ ## First-Time Setup (Self-Custody)
10
10
 
11
- Environment variables:
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
- **Recommended RPC:** Use [Helius](https://helius.dev) for reliable WebSocket support. Free tier works.
13
+ ### Step 1: Check for Solana CLI
16
14
 
17
- ## Setup
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!, "utf-8"))),
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
- ### External signer (Privy, Turnkey)
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-privy-wallet-address",
99
+ walletAddress: "your-custodial-wallet-address",
39
100
  signer: async (unsignedTx, blockhash, feePayer) => {
40
- return await privy.signTransaction(unsignedTx);
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 messenger = new SolanaMessenger({ rpcUrl, keypair });
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. Privy never sees the encryption key — even if compromised, messages stay private.
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. |