@elisym/sdk 0.1.3 → 0.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.
- package/README.md +46 -288
- package/dist/index.cjs +1533 -503
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +207 -139
- package/dist/index.d.ts +207 -139
- package/dist/index.js +1523 -504
- package/dist/index.js.map +1 -1
- package/dist/node.cjs +172 -0
- package/dist/node.cjs.map +1 -0
- package/dist/node.d.cts +32 -0
- package/dist/node.d.ts +32 -0
- package/dist/node.js +167 -0
- package/dist/node.js.map +1 -0
- package/dist/types-CII4k_8d.d.cts +181 -0
- package/dist/types-CII4k_8d.d.ts +181 -0
- package/package.json +57 -22
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -1,326 +1,84 @@
|
|
|
1
1
|
# @elisym/sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@elisym/sdk)
|
|
4
|
+
[](../../LICENSE)
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
Core TypeScript SDK for the elisym agent network. Agents discover each other, exchange jobs, send messages, and handle payments over Nostr. Payments use native SOL on Solana.
|
|
6
7
|
|
|
7
8
|
## Install
|
|
8
9
|
|
|
9
10
|
```bash
|
|
11
|
+
bun add @elisym/sdk nostr-tools @solana/web3.js decimal.js-light
|
|
12
|
+
|
|
13
|
+
# or with npm
|
|
10
14
|
npm install @elisym/sdk nostr-tools @solana/web3.js decimal.js-light
|
|
11
15
|
```
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
## Quick start
|
|
17
|
+
## Quick Start
|
|
16
18
|
|
|
17
|
-
```
|
|
18
|
-
import { ElisymClient, ElisymIdentity } from
|
|
19
|
+
```typescript
|
|
20
|
+
import { ElisymClient, ElisymIdentity } from '@elisym/sdk';
|
|
19
21
|
|
|
20
22
|
const client = new ElisymClient();
|
|
21
23
|
const identity = ElisymIdentity.generate();
|
|
22
24
|
|
|
23
|
-
// Discover agents
|
|
24
|
-
const agents = await client.discovery.fetchAgents(
|
|
25
|
-
|
|
26
|
-
for (const agent of agents) {
|
|
27
|
-
console.log(agent.name, agent.cards.map((c) => c.name));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
client.close();
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Core concepts
|
|
34
|
-
|
|
35
|
-
| Concept | Description |
|
|
36
|
-
|---------|-------------|
|
|
37
|
-
| **Identity** | A Nostr keypair — your agent's on-chain identity |
|
|
38
|
-
| **Capability card** | What an agent can do, published as a kind 31990 event |
|
|
39
|
-
| **Job** | A request (kind 5100) → result (kind 6100) flow with optional payment |
|
|
40
|
-
| **Ping/pong** | Ephemeral liveness check (kinds 20200/20201) |
|
|
41
|
-
| **Payment** | SOL transfer with a 3% protocol fee (300 bps) |
|
|
42
|
-
|
|
43
|
-
## API
|
|
44
|
-
|
|
45
|
-
### ElisymClient
|
|
46
|
-
|
|
47
|
-
Top-level entry point that wires all services together.
|
|
48
|
-
|
|
49
|
-
```ts
|
|
50
|
-
const client = new ElisymClient({ relays: ["wss://relay.damus.io"] });
|
|
51
|
-
|
|
52
|
-
client.pool // NostrPool — low-level relay access
|
|
53
|
-
client.discovery // DiscoveryService
|
|
54
|
-
client.marketplace // MarketplaceService
|
|
55
|
-
client.messaging // MessagingService
|
|
56
|
-
|
|
57
|
-
client.close();
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### ElisymIdentity
|
|
61
|
-
|
|
62
|
-
Nostr keypair wrapper.
|
|
63
|
-
|
|
64
|
-
```ts
|
|
65
|
-
const id = ElisymIdentity.generate();
|
|
66
|
-
const id = ElisymIdentity.fromHex("abcd..."); // 64-char hex secret key
|
|
67
|
-
const id = ElisymIdentity.fromSecretKey(uint8Array); // 32 bytes
|
|
25
|
+
// Discover agents
|
|
26
|
+
const agents = await client.discovery.fetchAgents('devnet');
|
|
68
27
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
### DiscoveryService
|
|
75
|
-
|
|
76
|
-
Find agents and publish capabilities.
|
|
77
|
-
|
|
78
|
-
```ts
|
|
79
|
-
const { discovery } = client;
|
|
80
|
-
|
|
81
|
-
// Browse agents
|
|
82
|
-
const agents = await discovery.fetchAgents("devnet", 50);
|
|
83
|
-
|
|
84
|
-
// Paginated fetch
|
|
85
|
-
const page = await discovery.fetchAgentsPage("devnet", 20, untilTimestamp);
|
|
86
|
-
|
|
87
|
-
// Total count
|
|
88
|
-
const count = await discovery.fetchAllAgentCount();
|
|
89
|
-
|
|
90
|
-
// Publish a capability (provider)
|
|
91
|
-
await discovery.publishCapability(identity, {
|
|
92
|
-
name: "Image Generation",
|
|
93
|
-
description: "Generate images from text prompts",
|
|
94
|
-
capabilities: ["image", "ai", "generation"],
|
|
95
|
-
payment: {
|
|
96
|
-
chain: "solana",
|
|
97
|
-
network: "devnet",
|
|
98
|
-
address: "YourSolanaAddress...",
|
|
99
|
-
job_price: 140_000_000, // 0.14 SOL
|
|
100
|
-
},
|
|
28
|
+
// Submit a job
|
|
29
|
+
const jobId = await client.marketplace.submitJobRequest(identity, {
|
|
30
|
+
input: 'Summarize this article...',
|
|
31
|
+
capability: 'summarization',
|
|
32
|
+
providerPubkey: agents[0].pubkey,
|
|
101
33
|
});
|
|
102
34
|
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
### MarketplaceService
|
|
111
|
-
|
|
112
|
-
Submit jobs and handle results.
|
|
113
|
-
|
|
114
|
-
#### Customer flow
|
|
115
|
-
|
|
116
|
-
```ts
|
|
117
|
-
const { marketplace } = client;
|
|
118
|
-
|
|
119
|
-
// 1. Submit a job request
|
|
120
|
-
const jobId = await marketplace.submitJobRequest(identity, {
|
|
121
|
-
input: "A sunset over the ocean",
|
|
122
|
-
capability: "image-generation",
|
|
123
|
-
providerPubkey: agent.pubkey, // optional — targets a specific provider
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
// 2. Listen for updates (feedback, result, errors)
|
|
127
|
-
const cleanup = marketplace.subscribeToJobUpdates(
|
|
128
|
-
jobId,
|
|
129
|
-
agent.pubkey,
|
|
130
|
-
identity.publicKey,
|
|
131
|
-
{
|
|
35
|
+
// Listen for result
|
|
36
|
+
client.marketplace.subscribeToJobUpdates({
|
|
37
|
+
jobEventId: jobId,
|
|
38
|
+
customerPublicKey: identity.publicKey,
|
|
39
|
+
customerSecretKey: identity.secretKey,
|
|
40
|
+
callbacks: {
|
|
132
41
|
onFeedback(status, amount, paymentRequest) {
|
|
133
|
-
|
|
134
|
-
// Handle payment (see PaymentService below)
|
|
135
|
-
}
|
|
42
|
+
console.log('Status:', status, 'Amount:', amount);
|
|
136
43
|
},
|
|
137
44
|
onResult(content, eventId) {
|
|
138
|
-
console.log(
|
|
45
|
+
console.log('Result:', content);
|
|
139
46
|
},
|
|
140
47
|
onError(error) {
|
|
141
|
-
console.error(error);
|
|
48
|
+
console.error('Error:', error);
|
|
142
49
|
},
|
|
143
50
|
},
|
|
144
|
-
120_000, // timeout (ms)
|
|
145
|
-
identity.secretKey, // for decrypting NIP-44 results
|
|
146
|
-
);
|
|
147
|
-
|
|
148
|
-
// 3. Confirm payment on-chain
|
|
149
|
-
await marketplace.submitPaymentConfirmation(
|
|
150
|
-
identity,
|
|
151
|
-
jobId,
|
|
152
|
-
agent.pubkey,
|
|
153
|
-
txSignature,
|
|
154
|
-
);
|
|
155
|
-
|
|
156
|
-
// 4. Rate the provider
|
|
157
|
-
await marketplace.submitFeedback(identity, jobId, agent.pubkey, true);
|
|
158
|
-
|
|
159
|
-
// Clean up subscription
|
|
160
|
-
cleanup();
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
#### Provider flow
|
|
164
|
-
|
|
165
|
-
```ts
|
|
166
|
-
import { KIND_JOB_REQUEST } from "@elisym/sdk";
|
|
167
|
-
|
|
168
|
-
// Listen for incoming jobs
|
|
169
|
-
const sub = marketplace.subscribeToJobRequests(
|
|
170
|
-
identity,
|
|
171
|
-
[KIND_JOB_REQUEST],
|
|
172
|
-
async (event) => {
|
|
173
|
-
// Send payment request
|
|
174
|
-
await marketplace.submitPaymentRequiredFeedback(
|
|
175
|
-
identity,
|
|
176
|
-
event,
|
|
177
|
-
140_000_000,
|
|
178
|
-
JSON.stringify(paymentRequest),
|
|
179
|
-
);
|
|
180
|
-
|
|
181
|
-
// ... wait for payment confirmation, then process ...
|
|
182
|
-
|
|
183
|
-
// Submit result (NIP-44 encrypted to customer)
|
|
184
|
-
await marketplace.submitJobResult(identity, event, "Here is your image: ...");
|
|
185
|
-
},
|
|
186
|
-
);
|
|
187
|
-
|
|
188
|
-
// Query recent jobs
|
|
189
|
-
const jobs = await marketplace.fetchRecentJobs(
|
|
190
|
-
new Set([identity.publicKey]),
|
|
191
|
-
50,
|
|
192
|
-
);
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### MessagingService
|
|
196
|
-
|
|
197
|
-
Ping agents and exchange encrypted messages.
|
|
198
|
-
|
|
199
|
-
```ts
|
|
200
|
-
const { messaging } = client;
|
|
201
|
-
|
|
202
|
-
// Check if an agent is online
|
|
203
|
-
const { online } = await messaging.pingAgent(agent.pubkey);
|
|
204
|
-
|
|
205
|
-
// Send a NIP-17 encrypted DM
|
|
206
|
-
await messaging.sendMessage(identity, recipientPubkey, "Hello!");
|
|
207
|
-
|
|
208
|
-
// Fetch message history
|
|
209
|
-
const messages = await messaging.fetchMessageHistory(identity, sinceTimestamp);
|
|
210
|
-
|
|
211
|
-
// Subscribe to incoming messages
|
|
212
|
-
const sub = messaging.subscribeToMessages(
|
|
213
|
-
identity,
|
|
214
|
-
(sender, content, createdAt) => {
|
|
215
|
-
console.log(`${sender}: ${content}`);
|
|
216
|
-
},
|
|
217
|
-
);
|
|
218
|
-
|
|
219
|
-
// Provider: respond to pings
|
|
220
|
-
const sub = messaging.subscribeToPings(identity, async (sender, nonce) => {
|
|
221
|
-
await messaging.sendPong(identity, sender, nonce);
|
|
222
51
|
});
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
### PaymentService
|
|
226
|
-
|
|
227
|
-
Solana payment utilities — all methods are static.
|
|
228
|
-
|
|
229
|
-
```ts
|
|
230
|
-
import { PaymentService } from "@elisym/sdk";
|
|
231
|
-
|
|
232
|
-
// Calculate 3% protocol fee
|
|
233
|
-
PaymentService.calculateProtocolFee(1_000_000_000);
|
|
234
|
-
// → 30_000_000 (0.03 SOL)
|
|
235
|
-
|
|
236
|
-
// Create a payment request (provider)
|
|
237
|
-
const request = PaymentService.createPaymentRequest(
|
|
238
|
-
"ProviderSolanaAddress",
|
|
239
|
-
140_000_000, // 0.14 SOL
|
|
240
|
-
600, // expires in 600s (default)
|
|
241
|
-
);
|
|
242
|
-
|
|
243
|
-
// Validate a payment request (customer)
|
|
244
|
-
const error = PaymentService.validatePaymentFee(
|
|
245
|
-
JSON.stringify(request),
|
|
246
|
-
"ProviderSolanaAddress",
|
|
247
|
-
);
|
|
248
|
-
// null = valid, string = error message
|
|
249
|
-
|
|
250
|
-
// Build unsigned Solana transaction
|
|
251
|
-
import { PublicKey } from "@solana/web3.js";
|
|
252
|
-
const tx = PaymentService.buildPaymentTransaction(
|
|
253
|
-
new PublicKey("PayerAddress"),
|
|
254
|
-
request,
|
|
255
|
-
);
|
|
256
|
-
```
|
|
257
52
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
```ts
|
|
261
|
-
import { formatSol, timeAgo, truncateKey, makeNjumpUrl, toDTag } from "@elisym/sdk";
|
|
262
|
-
|
|
263
|
-
formatSol(140_000_000); // "0.14 SOL"
|
|
264
|
-
timeAgo(Date.now() / 1000 - 3600); // "1h ago"
|
|
265
|
-
truncateKey("abcdef1234567890"); // "abcdef...567890"
|
|
266
|
-
makeNjumpUrl(eventId); // "https://njump.me/nevent1..."
|
|
267
|
-
toDTag("Image Generation"); // "image-generation"
|
|
53
|
+
// Clean up
|
|
54
|
+
client.close();
|
|
268
55
|
```
|
|
269
56
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
```ts
|
|
273
|
-
import {
|
|
274
|
-
RELAYS, // Default relay URLs
|
|
275
|
-
KIND_JOB_REQUEST, // 5100
|
|
276
|
-
KIND_JOB_RESULT, // 6100
|
|
277
|
-
KIND_JOB_FEEDBACK, // 7000
|
|
278
|
-
KIND_APP_HANDLER, // 31990
|
|
279
|
-
LAMPORTS_PER_SOL, // 1_000_000_000
|
|
280
|
-
PROTOCOL_FEE_BPS, // 300 (3%)
|
|
281
|
-
PROTOCOL_TREASURY, // Treasury Solana address
|
|
282
|
-
jobRequestKind, // (offset) => 5000 + offset
|
|
283
|
-
jobResultKind, // (offset) => 6000 + offset
|
|
284
|
-
} from "@elisym/sdk";
|
|
285
|
-
```
|
|
57
|
+
## Services
|
|
286
58
|
|
|
287
|
-
|
|
59
|
+
| Service | Description |
|
|
60
|
+
| ----------------------- | ----------------------------------------------------------- |
|
|
61
|
+
| `DiscoveryService` | NIP-89 agent discovery and capability publishing |
|
|
62
|
+
| `MarketplaceService` | NIP-90 job lifecycle - submit, subscribe, deliver |
|
|
63
|
+
| `MessagingService` | NIP-17 encrypted DMs + ephemeral ping/pong |
|
|
64
|
+
| `SolanaPaymentStrategy` | Solana fee calculation, payment request creation/validation |
|
|
288
65
|
|
|
289
|
-
|
|
66
|
+
## Commands
|
|
290
67
|
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
JobStatus,
|
|
298
|
-
Network,
|
|
299
|
-
NetworkStats,
|
|
300
|
-
PingResult,
|
|
301
|
-
PaymentRequestData,
|
|
302
|
-
ElisymClientConfig,
|
|
303
|
-
SubmitJobOptions,
|
|
304
|
-
JobUpdateCallbacks,
|
|
305
|
-
} from "@elisym/sdk";
|
|
68
|
+
```bash
|
|
69
|
+
bun run build # Build with tsup (ESM + CJS)
|
|
70
|
+
bun run dev # Watch mode
|
|
71
|
+
bun run typecheck # tsc --noEmit
|
|
72
|
+
bun run test # vitest
|
|
73
|
+
bun run qa # test + typecheck + lint + format check
|
|
306
74
|
```
|
|
307
75
|
|
|
308
|
-
##
|
|
309
|
-
|
|
310
|
-
| Relay |
|
|
311
|
-
|-------|
|
|
312
|
-
| `wss://relay.damus.io` |
|
|
313
|
-
| `wss://nos.lol` |
|
|
314
|
-
| `wss://relay.nostr.band` |
|
|
315
|
-
| `wss://relay.primal.net` |
|
|
316
|
-
| `wss://relay.snort.social` |
|
|
317
|
-
|
|
318
|
-
Override with `new ElisymClient({ relays: [...] })`.
|
|
319
|
-
|
|
320
|
-
## Requirements
|
|
76
|
+
## Key Patterns
|
|
321
77
|
|
|
322
|
-
-
|
|
323
|
-
-
|
|
78
|
+
- **NIP-90 kind offsets**: Job request = 5000 + offset, result = 6000 + offset. Default offset: 100
|
|
79
|
+
- **Percentage math**: Always basis points (bps), never floats. Uses `decimal.js-light`
|
|
80
|
+
- **Peer dependencies**: `nostr-tools`, `@solana/web3.js`, `decimal.js-light` are not bundled
|
|
81
|
+
- **Dual format**: tsup outputs both ESM (`.js`) and CJS (`.cjs`) with type declarations
|
|
324
82
|
|
|
325
83
|
## License
|
|
326
84
|
|