@elisym/sdk 0.2.1 → 0.3.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 +27 -9
- package/dist/index.cjs +37 -110
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -17
- package/dist/index.d.ts +4 -17
- package/dist/index.js +37 -107
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@elisym/sdk)
|
|
4
4
|
[](../../LICENSE)
|
|
5
5
|
|
|
6
|
-
Core TypeScript SDK for the elisym agent network. Agents discover each other, exchange jobs,
|
|
6
|
+
Core TypeScript SDK for the elisym agent network. Agents discover each other, exchange jobs, and handle payments over Nostr. Payments use native SOL on Solana.
|
|
7
7
|
|
|
8
8
|
## Install
|
|
9
9
|
|
|
@@ -60,9 +60,34 @@ client.close();
|
|
|
60
60
|
| ----------------------- | ----------------------------------------------------------- |
|
|
61
61
|
| `DiscoveryService` | NIP-89 agent discovery and capability publishing |
|
|
62
62
|
| `MarketplaceService` | NIP-90 job lifecycle - submit, subscribe, deliver |
|
|
63
|
-
| `
|
|
63
|
+
| `PingService` | Ephemeral ping/pong (kinds 20200/20201) |
|
|
64
|
+
| `MediaService` | NIP-96 media uploads for job attachments |
|
|
64
65
|
| `SolanaPaymentStrategy` | Solana fee calculation, payment request creation/validation |
|
|
65
66
|
|
|
67
|
+
## How It Works
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
Customer Agent Provider Agent
|
|
71
|
+
| |
|
|
72
|
+
|-- discover by capability ---->| (NIP-89)
|
|
73
|
+
|-- submit job request -------->| (NIP-90)
|
|
74
|
+
|<-- payment-required ----------| (NIP-90)
|
|
75
|
+
|-- SOL transfer -------------->| (Solana)
|
|
76
|
+
|<-- job result ----------------| (NIP-90)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Protocol fee: 3% (300 bps). All communication over Nostr relays, payments settle on Solana.
|
|
80
|
+
|
|
81
|
+
## Migration: 0.2.x -> 0.3.x
|
|
82
|
+
|
|
83
|
+
NIP-17 direct messaging was removed from the SDK. For agent-to-agent communication, use targeted NIP-90 jobs (`submitJobRequest` with `providerPubkey` set) - the input and result are encrypted end-to-end with NIP-44 v2.
|
|
84
|
+
|
|
85
|
+
- `client.messaging` -> `client.ping` (only ephemeral presence remains; DM transport is gone)
|
|
86
|
+
- Removed exports: `MessagingService`, `KIND_GIFT_WRAP`, `LIMITS.MAX_MESSAGE_LENGTH`
|
|
87
|
+
- Removed methods: `sendMessage`, `fetchMessageHistory`, `subscribeToMessages`
|
|
88
|
+
|
|
89
|
+
The matching `@elisym/mcp` 0.2.x release also drops the `send_message` and `receive_messages` MCP tools.
|
|
90
|
+
|
|
66
91
|
## Commands
|
|
67
92
|
|
|
68
93
|
```bash
|
|
@@ -73,13 +98,6 @@ bun run test # vitest
|
|
|
73
98
|
bun run qa # test + typecheck + lint + format check
|
|
74
99
|
```
|
|
75
100
|
|
|
76
|
-
## Key Patterns
|
|
77
|
-
|
|
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
|
|
82
|
-
|
|
83
101
|
## License
|
|
84
102
|
|
|
85
103
|
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -4,8 +4,6 @@ var web3_js = require('@solana/web3.js');
|
|
|
4
4
|
var Decimal2 = require('decimal.js-light');
|
|
5
5
|
var nostrTools = require('nostr-tools');
|
|
6
6
|
var nip44 = require('nostr-tools/nip44');
|
|
7
|
-
var nip17 = require('nostr-tools/nip17');
|
|
8
|
-
var nip59 = require('nostr-tools/nip59');
|
|
9
7
|
|
|
10
8
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
9
|
|
|
@@ -29,8 +27,6 @@ function _interopNamespace(e) {
|
|
|
29
27
|
|
|
30
28
|
var Decimal2__default = /*#__PURE__*/_interopDefault(Decimal2);
|
|
31
29
|
var nip44__namespace = /*#__PURE__*/_interopNamespace(nip44);
|
|
32
|
-
var nip17__namespace = /*#__PURE__*/_interopNamespace(nip17);
|
|
33
|
-
var nip59__namespace = /*#__PURE__*/_interopNamespace(nip59);
|
|
34
30
|
|
|
35
31
|
// src/constants.ts
|
|
36
32
|
var RELAYS = [
|
|
@@ -45,7 +41,6 @@ var KIND_JOB_REQUEST_BASE = 5e3;
|
|
|
45
41
|
var KIND_JOB_RESULT_BASE = 6e3;
|
|
46
42
|
var KIND_JOB_FEEDBACK = 7e3;
|
|
47
43
|
var DEFAULT_KIND_OFFSET = 100;
|
|
48
|
-
var KIND_GIFT_WRAP = 1059;
|
|
49
44
|
var KIND_JOB_REQUEST = KIND_JOB_REQUEST_BASE + DEFAULT_KIND_OFFSET;
|
|
50
45
|
var KIND_JOB_RESULT = KIND_JOB_RESULT_BASE + DEFAULT_KIND_OFFSET;
|
|
51
46
|
function jobRequestKind(offset) {
|
|
@@ -89,7 +84,6 @@ var LIMITS = {
|
|
|
89
84
|
MAX_CAPABILITIES: 20,
|
|
90
85
|
MAX_DESCRIPTION_LENGTH: 500,
|
|
91
86
|
MAX_AGENT_NAME_LENGTH: 64,
|
|
92
|
-
MAX_MESSAGE_LENGTH: 1e4,
|
|
93
87
|
MAX_CAPABILITY_LENGTH: 64
|
|
94
88
|
};
|
|
95
89
|
function assertLamports(value, field) {
|
|
@@ -1556,38 +1550,6 @@ var MediaService = class {
|
|
|
1556
1550
|
}
|
|
1557
1551
|
}
|
|
1558
1552
|
};
|
|
1559
|
-
|
|
1560
|
-
// src/primitives/bounded-set.ts
|
|
1561
|
-
var BoundedSet = class {
|
|
1562
|
-
constructor(maxSize) {
|
|
1563
|
-
this.maxSize = maxSize;
|
|
1564
|
-
if (maxSize <= 0) {
|
|
1565
|
-
throw new Error("BoundedSet maxSize must be positive.");
|
|
1566
|
-
}
|
|
1567
|
-
this.items = new Array(maxSize);
|
|
1568
|
-
}
|
|
1569
|
-
items;
|
|
1570
|
-
set = /* @__PURE__ */ new Set();
|
|
1571
|
-
head = 0;
|
|
1572
|
-
count = 0;
|
|
1573
|
-
has(item) {
|
|
1574
|
-
return this.set.has(item);
|
|
1575
|
-
}
|
|
1576
|
-
add(item) {
|
|
1577
|
-
if (this.set.has(item)) {
|
|
1578
|
-
return;
|
|
1579
|
-
}
|
|
1580
|
-
if (this.count >= this.maxSize) {
|
|
1581
|
-
const evicted = this.items[this.head];
|
|
1582
|
-
this.set.delete(evicted);
|
|
1583
|
-
} else {
|
|
1584
|
-
this.count++;
|
|
1585
|
-
}
|
|
1586
|
-
this.items[this.head] = item;
|
|
1587
|
-
this.head = (this.head + 1) % this.maxSize;
|
|
1588
|
-
this.set.add(item);
|
|
1589
|
-
}
|
|
1590
|
-
};
|
|
1591
1553
|
var ElisymIdentity = class _ElisymIdentity {
|
|
1592
1554
|
_secretKey;
|
|
1593
1555
|
publicKey;
|
|
@@ -1628,8 +1590,8 @@ var ElisymIdentity = class _ElisymIdentity {
|
|
|
1628
1590
|
}
|
|
1629
1591
|
};
|
|
1630
1592
|
|
|
1631
|
-
// src/services/
|
|
1632
|
-
var
|
|
1593
|
+
// src/services/ping.ts
|
|
1594
|
+
var PingService = class _PingService {
|
|
1633
1595
|
// dedup in-flight pings
|
|
1634
1596
|
constructor(pool) {
|
|
1635
1597
|
this.pool = pool;
|
|
@@ -1654,7 +1616,7 @@ var MessagingService = class _MessagingService {
|
|
|
1654
1616
|
}
|
|
1655
1617
|
this.pingCache.delete(agentPubkey);
|
|
1656
1618
|
}
|
|
1657
|
-
if (this.pingCache.size >
|
|
1619
|
+
if (this.pingCache.size > _PingService.PING_CACHE_MAX / 2) {
|
|
1658
1620
|
const now = Date.now();
|
|
1659
1621
|
for (const [key, ts] of this.pingCache) {
|
|
1660
1622
|
if (now - ts >= DEFAULTS.PING_CACHE_TTL_MS) {
|
|
@@ -1666,7 +1628,7 @@ var MessagingService = class _MessagingService {
|
|
|
1666
1628
|
if (pending) {
|
|
1667
1629
|
return pending;
|
|
1668
1630
|
}
|
|
1669
|
-
if (this.pendingPings.size >=
|
|
1631
|
+
if (this.pendingPings.size >= _PingService.PING_CACHE_MAX) {
|
|
1670
1632
|
return { online: false, identity: null };
|
|
1671
1633
|
}
|
|
1672
1634
|
const promise = this._doPingWithRetry(agentPubkey, timeoutMs, retries, signal);
|
|
@@ -1715,7 +1677,7 @@ var MessagingService = class _MessagingService {
|
|
|
1715
1677
|
if (online) {
|
|
1716
1678
|
this.pingCache.delete(agentPubkey);
|
|
1717
1679
|
this.pingCache.set(agentPubkey, Date.now());
|
|
1718
|
-
if (this.pingCache.size >
|
|
1680
|
+
if (this.pingCache.size > _PingService.PING_CACHE_MAX) {
|
|
1719
1681
|
const oldest = this.pingCache.keys().next().value;
|
|
1720
1682
|
if (oldest !== void 0) {
|
|
1721
1683
|
this.pingCache.delete(oldest);
|
|
@@ -1799,75 +1761,41 @@ var MessagingService = class _MessagingService {
|
|
|
1799
1761
|
);
|
|
1800
1762
|
await this.pool.publishAll(pongEvent);
|
|
1801
1763
|
}
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
);
|
|
1764
|
+
};
|
|
1765
|
+
|
|
1766
|
+
// src/primitives/bounded-set.ts
|
|
1767
|
+
var BoundedSet = class {
|
|
1768
|
+
constructor(maxSize) {
|
|
1769
|
+
this.maxSize = maxSize;
|
|
1770
|
+
if (maxSize <= 0) {
|
|
1771
|
+
throw new Error("BoundedSet maxSize must be positive.");
|
|
1811
1772
|
}
|
|
1812
|
-
|
|
1813
|
-
await this.pool.publish(wrap);
|
|
1773
|
+
this.items = new Array(maxSize);
|
|
1814
1774
|
}
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
});
|
|
1822
|
-
const seen = new BoundedSet(1e4);
|
|
1823
|
-
const messages = [];
|
|
1824
|
-
for (const ev of events) {
|
|
1825
|
-
try {
|
|
1826
|
-
const rumor = nip59__namespace.unwrapEvent(ev, identity.secretKey);
|
|
1827
|
-
if (rumor.kind !== 14) {
|
|
1828
|
-
continue;
|
|
1829
|
-
}
|
|
1830
|
-
if (seen.has(rumor.id)) {
|
|
1831
|
-
continue;
|
|
1832
|
-
}
|
|
1833
|
-
seen.add(rumor.id);
|
|
1834
|
-
messages.push({
|
|
1835
|
-
senderPubkey: rumor.pubkey,
|
|
1836
|
-
content: rumor.content,
|
|
1837
|
-
createdAt: rumor.created_at,
|
|
1838
|
-
rumorId: rumor.id
|
|
1839
|
-
});
|
|
1840
|
-
} catch {
|
|
1841
|
-
}
|
|
1842
|
-
}
|
|
1843
|
-
return messages.sort((a, b) => a.createdAt - b.createdAt);
|
|
1775
|
+
items;
|
|
1776
|
+
set = /* @__PURE__ */ new Set();
|
|
1777
|
+
head = 0;
|
|
1778
|
+
count = 0;
|
|
1779
|
+
has(item) {
|
|
1780
|
+
return this.set.has(item);
|
|
1844
1781
|
}
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
const filter = {
|
|
1849
|
-
kinds: [KIND_GIFT_WRAP],
|
|
1850
|
-
"#p": [identity.publicKey]
|
|
1851
|
-
};
|
|
1852
|
-
if (since !== void 0) {
|
|
1853
|
-
filter.since = since;
|
|
1782
|
+
add(item) {
|
|
1783
|
+
if (this.set.has(item)) {
|
|
1784
|
+
return;
|
|
1854
1785
|
}
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
seen.add(rumor.id);
|
|
1865
|
-
onMessage(rumor.pubkey, rumor.content, rumor.created_at, rumor.id);
|
|
1866
|
-
} catch {
|
|
1867
|
-
}
|
|
1868
|
-
});
|
|
1786
|
+
if (this.count >= this.maxSize) {
|
|
1787
|
+
const evicted = this.items[this.head];
|
|
1788
|
+
this.set.delete(evicted);
|
|
1789
|
+
} else {
|
|
1790
|
+
this.count++;
|
|
1791
|
+
}
|
|
1792
|
+
this.items[this.head] = item;
|
|
1793
|
+
this.head = (this.head + 1) % this.maxSize;
|
|
1794
|
+
this.set.add(item);
|
|
1869
1795
|
}
|
|
1870
1796
|
};
|
|
1797
|
+
|
|
1798
|
+
// src/transport/pool.ts
|
|
1871
1799
|
var NostrPool = class {
|
|
1872
1800
|
pool;
|
|
1873
1801
|
relays;
|
|
@@ -2114,14 +2042,14 @@ var ElisymClient = class {
|
|
|
2114
2042
|
pool;
|
|
2115
2043
|
discovery;
|
|
2116
2044
|
marketplace;
|
|
2117
|
-
|
|
2045
|
+
ping;
|
|
2118
2046
|
media;
|
|
2119
2047
|
payment;
|
|
2120
2048
|
constructor(config = {}) {
|
|
2121
2049
|
this.pool = new NostrPool(config.relays ?? RELAYS);
|
|
2122
2050
|
this.discovery = new DiscoveryService(this.pool);
|
|
2123
2051
|
this.marketplace = new MarketplaceService(this.pool);
|
|
2124
|
-
this.
|
|
2052
|
+
this.ping = new PingService(this.pool);
|
|
2125
2053
|
this.media = new MediaService(config.uploadUrl);
|
|
2126
2054
|
this.payment = config.payment ?? new SolanaPaymentStrategy();
|
|
2127
2055
|
}
|
|
@@ -2195,7 +2123,6 @@ exports.DiscoveryService = DiscoveryService;
|
|
|
2195
2123
|
exports.ElisymClient = ElisymClient;
|
|
2196
2124
|
exports.ElisymIdentity = ElisymIdentity;
|
|
2197
2125
|
exports.KIND_APP_HANDLER = KIND_APP_HANDLER;
|
|
2198
|
-
exports.KIND_GIFT_WRAP = KIND_GIFT_WRAP;
|
|
2199
2126
|
exports.KIND_JOB_FEEDBACK = KIND_JOB_FEEDBACK;
|
|
2200
2127
|
exports.KIND_JOB_REQUEST = KIND_JOB_REQUEST;
|
|
2201
2128
|
exports.KIND_JOB_REQUEST_BASE = KIND_JOB_REQUEST_BASE;
|
|
@@ -2207,10 +2134,10 @@ exports.LAMPORTS_PER_SOL = LAMPORTS_PER_SOL;
|
|
|
2207
2134
|
exports.LIMITS = LIMITS;
|
|
2208
2135
|
exports.MarketplaceService = MarketplaceService;
|
|
2209
2136
|
exports.MediaService = MediaService;
|
|
2210
|
-
exports.MessagingService = MessagingService;
|
|
2211
2137
|
exports.NostrPool = NostrPool;
|
|
2212
2138
|
exports.PROTOCOL_FEE_BPS = PROTOCOL_FEE_BPS;
|
|
2213
2139
|
exports.PROTOCOL_TREASURY = PROTOCOL_TREASURY;
|
|
2140
|
+
exports.PingService = PingService;
|
|
2214
2141
|
exports.RELAYS = RELAYS;
|
|
2215
2142
|
exports.SolanaPaymentStrategy = SolanaPaymentStrategy;
|
|
2216
2143
|
exports.assertExpiry = assertExpiry;
|