@toon-protocol/core 1.1.2 → 1.3.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/README.md +125 -6
- package/dist/{chunk-7AHDGE4H.js → chunk-5WT7ISKC.js} +7 -3
- package/dist/chunk-5WT7ISKC.js.map +1 -0
- package/dist/index.d.ts +1316 -176
- package/dist/index.js +1514 -155
- package/dist/index.js.map +1 -1
- package/dist/toon/index.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-7AHDGE4H.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# @toon-protocol/core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Peer discovery, bootstrap, settlement negotiation, and TOON event encoding for the TOON Protocol network.
|
|
4
|
+
|
|
5
|
+
> This is an internal package. Most users should start with [`@toon-protocol/client`](../client) or [`@toon-protocol/sdk`](../sdk).
|
|
4
6
|
|
|
5
7
|
## Install
|
|
6
8
|
|
|
@@ -8,18 +10,135 @@ Core library for Nostr-based ILP peer discovery, bootstrap, and settlement negot
|
|
|
8
10
|
npm install @toon-protocol/core
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
##
|
|
13
|
+
## Key Exports
|
|
14
|
+
|
|
15
|
+
### TOON Codec
|
|
16
|
+
|
|
17
|
+
Encode and decode Nostr events in the compact TOON binary format.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { encodeEventToToon, decodeEventFromToon, shallowParseToon } from '@toon-protocol/core';
|
|
21
|
+
|
|
22
|
+
// Encode a Nostr event to TOON binary format
|
|
23
|
+
const toonBytes = encodeEventToToon(nostrEvent);
|
|
24
|
+
|
|
25
|
+
// Decode back to a Nostr event
|
|
26
|
+
const event = decodeEventFromToon(toonBytes);
|
|
27
|
+
|
|
28
|
+
// Fast metadata extraction without full decode
|
|
29
|
+
const meta = shallowParseToon(toonBytes);
|
|
30
|
+
console.log(meta.kind, meta.pubkey);
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Peer Discovery
|
|
34
|
+
|
|
35
|
+
Discover ILP peers from Nostr relays, genesis nodes, or ArDrive registries.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { NostrPeerDiscovery, GenesisPeerLoader, parseIlpPeerInfo } from '@toon-protocol/core';
|
|
39
|
+
|
|
40
|
+
// Query Nostr relays for kind:10032 peer info events
|
|
41
|
+
const discovery = new NostrPeerDiscovery({ relayUrls: ['wss://relay.example.com'] });
|
|
42
|
+
const peers = await discovery.query();
|
|
43
|
+
|
|
44
|
+
// Or load peers from a genesis node
|
|
45
|
+
const loader = new GenesisPeerLoader('http://localhost:3100');
|
|
46
|
+
const genesisPeers = await loader.load();
|
|
47
|
+
|
|
48
|
+
// Parse a raw Nostr event into typed peer info
|
|
49
|
+
const peerInfo = parseIlpPeerInfo(event);
|
|
50
|
+
console.log(peerInfo.ilpAddress, peerInfo.btpEndpoint);
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Bootstrap Service
|
|
54
|
+
|
|
55
|
+
Orchestrates the full peer lifecycle: discovery, registration, settlement negotiation, and announcement.
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { BootstrapService } from '@toon-protocol/core';
|
|
59
|
+
|
|
60
|
+
const bootstrap = new BootstrapService(config);
|
|
61
|
+
|
|
62
|
+
bootstrap.addEventListener('phase', (e) => {
|
|
63
|
+
console.log('Phase:', e.phase); // 'discovering' → 'registering' → 'announcing' → 'ready'
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
await bootstrap.start();
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Compose API (Embedded Connector)
|
|
70
|
+
|
|
71
|
+
Wire a full TOON node with zero-latency embedded connector.
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { createToonNode } from '@toon-protocol/core';
|
|
75
|
+
|
|
76
|
+
const node = createToonNode({
|
|
77
|
+
connector,
|
|
78
|
+
secretKey,
|
|
79
|
+
basePricePerByte: 10n,
|
|
80
|
+
relayPort: 7100,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
node.on(1, async (ctx) => {
|
|
84
|
+
const event = ctx.decode();
|
|
85
|
+
return ctx.accept();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
await node.start();
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Event Builders
|
|
92
|
+
|
|
93
|
+
Build typed Nostr events for ILP peer info, service discovery, seed relay lists, and TEE attestation.
|
|
12
94
|
|
|
13
95
|
```ts
|
|
14
96
|
import {
|
|
15
|
-
NostrPeerDiscovery,
|
|
16
|
-
BootstrapService,
|
|
17
|
-
SocialPeerDiscovery,
|
|
18
|
-
parseIlpPeerInfo,
|
|
19
97
|
buildIlpPeerInfoEvent,
|
|
98
|
+
buildServiceDiscoveryEvent,
|
|
99
|
+
buildAttestationEvent,
|
|
100
|
+
buildJobRequestEvent,
|
|
20
101
|
} from '@toon-protocol/core';
|
|
21
102
|
```
|
|
22
103
|
|
|
104
|
+
### Chain Configuration
|
|
105
|
+
|
|
106
|
+
Resolve chain presets for settlement (Anvil, Arbitrum Sepolia, Arbitrum One).
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
import { resolveChainConfig, CHAIN_PRESETS } from '@toon-protocol/core';
|
|
110
|
+
|
|
111
|
+
const chain = resolveChainConfig('arbitrum-sepolia');
|
|
112
|
+
console.log(chain.chainId, chain.usdcAddress);
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Settlement Negotiation
|
|
116
|
+
|
|
117
|
+
Find a common settlement chain between two peers.
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
import { negotiateSettlementChain } from '@toon-protocol/core';
|
|
121
|
+
|
|
122
|
+
const chain = negotiateSettlementChain(peerInfo, localConfig);
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Full API
|
|
126
|
+
|
|
127
|
+
| Category | Exports |
|
|
128
|
+
|----------|---------|
|
|
129
|
+
| **Codec** | `encodeEventToToon`, `decodeEventFromToon`, `shallowParseToon`, `encodeEventToToonString` |
|
|
130
|
+
| **Discovery** | `NostrPeerDiscovery`, `GenesisPeerLoader`, `ArDrivePeerRegistry`, `SocialPeerDiscovery`, `SeedRelayDiscovery` |
|
|
131
|
+
| **Bootstrap** | `BootstrapService`, `createDiscoveryTracker` |
|
|
132
|
+
| **Compose** | `createToonNode`, `ToonNode`, `EmbeddableConnectorLike` |
|
|
133
|
+
| **Events** | `buildIlpPeerInfoEvent`, `buildServiceDiscoveryEvent`, `buildAttestationEvent`, `buildSeedRelayListEvent` |
|
|
134
|
+
| **DVM** | `buildJobRequestEvent`, `buildJobResultEvent`, `buildJobFeedbackEvent`, `parseJobRequest/Result/Feedback` |
|
|
135
|
+
| **Chain** | `resolveChainConfig`, `CHAIN_PRESETS`, `buildEip712Domain`, `validateChainId` |
|
|
136
|
+
| **Settlement** | `negotiateSettlementChain`, `resolveTokenForChain` |
|
|
137
|
+
| **TEE** | `AttestationVerifier`, `AttestationState`, `AttestationBootstrap`, `deriveFromKmsSeed` |
|
|
138
|
+
| **ILP Clients** | `createDirectIlpClient`, `createHttpIlpClient`, `createDirectConnectorAdmin`, `createHttpConnectorAdmin` |
|
|
139
|
+
| **Errors** | `ToonError`, `InvalidEventError`, `PeerDiscoveryError`, `ToonEncodeError`, `ToonDecodeError` |
|
|
140
|
+
| **Logging** | `createLogger`, `LogLevel` |
|
|
141
|
+
|
|
23
142
|
## License
|
|
24
143
|
|
|
25
144
|
MIT
|
|
@@ -75,7 +75,9 @@ function validateNostrEvent(obj) {
|
|
|
75
75
|
}
|
|
76
76
|
const event = obj;
|
|
77
77
|
if (!isValidHex(event["id"], 64)) {
|
|
78
|
-
throw new ToonDecodeError(
|
|
78
|
+
throw new ToonDecodeError(
|
|
79
|
+
"Invalid event id: must be a 64-character hex string"
|
|
80
|
+
);
|
|
79
81
|
}
|
|
80
82
|
if (!isValidHex(event["pubkey"], 64)) {
|
|
81
83
|
throw new ToonDecodeError(
|
|
@@ -99,7 +101,9 @@ function validateNostrEvent(obj) {
|
|
|
99
101
|
}
|
|
100
102
|
for (let j = 0; j < tag.length; j++) {
|
|
101
103
|
if (typeof tag[j] !== "string") {
|
|
102
|
-
throw new ToonDecodeError(
|
|
104
|
+
throw new ToonDecodeError(
|
|
105
|
+
`Invalid event tags[${i}][${j}]: must be a string`
|
|
106
|
+
);
|
|
103
107
|
}
|
|
104
108
|
}
|
|
105
109
|
}
|
|
@@ -186,4 +190,4 @@ export {
|
|
|
186
190
|
decodeEventFromToon,
|
|
187
191
|
shallowParseToon
|
|
188
192
|
};
|
|
189
|
-
//# sourceMappingURL=chunk-
|
|
193
|
+
//# sourceMappingURL=chunk-5WT7ISKC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/toon/encoder.ts","../src/errors.ts","../src/toon/decoder.ts","../src/toon/validate.ts","../src/toon/shallow-parse.ts"],"sourcesContent":["import { encode } from '@toon-format/toon';\nimport type { NostrEvent } from 'nostr-tools/pure';\nimport { ToonError } from '../errors.js';\n\n/**\n * Error thrown when TOON encoding fails.\n */\nexport class ToonEncodeError extends ToonError {\n constructor(message: string, cause?: Error) {\n super(message, 'TOON_ENCODE_ERROR', cause);\n this.name = 'ToonEncodeError';\n }\n}\n\n/**\n * Encode a NostrEvent to TOON format as a Uint8Array.\n *\n * Used for embedding Nostr events in ILP packets where compact encoding\n * reduces bytes and cost.\n *\n * @param event - The NostrEvent to encode\n * @returns Uint8Array containing the TOON-encoded event\n * @throws ToonEncodeError if encoding fails\n */\nexport function encodeEventToToon(event: NostrEvent): Uint8Array {\n try {\n const toonString = encode(event);\n return new TextEncoder().encode(toonString);\n } catch (error) {\n throw new ToonEncodeError(\n `Failed to encode event to TOON: ${error instanceof Error ? error.message : String(error)}`,\n error instanceof Error ? error : undefined\n );\n }\n}\n\n/**\n * Encode a NostrEvent to TOON format as a string.\n *\n * Used for embedding TOON-encoded events in outbound WebSocket messages\n * where the NIP-01 framing remains JSON but the event payload is TOON.\n *\n * @param event - The NostrEvent to encode\n * @returns TOON-encoded string representation of the event\n * @throws ToonEncodeError if encoding fails\n */\nexport function encodeEventToToonString(event: NostrEvent): string {\n try {\n return encode(event);\n } catch (error) {\n throw new ToonEncodeError(\n `Failed to encode event to TOON: ${error instanceof Error ? error.message : String(error)}`,\n error instanceof Error ? error : undefined\n );\n }\n}\n","/**\n * Custom error classes for @toon-protocol/core.\n */\n\n/**\n * Base error class for all toon errors.\n * Provides a consistent error interface with error codes and cause chaining.\n */\nexport class ToonError extends Error {\n public readonly code: string;\n\n constructor(message: string, code: string, cause?: Error) {\n super(message, { cause });\n this.name = 'ToonError';\n this.code = code;\n }\n}\n\n/**\n * Error thrown when parsing a Nostr event fails.\n * Used for malformed events, wrong kind, invalid JSON, or missing required fields.\n */\nexport class InvalidEventError extends ToonError {\n constructor(message: string, cause?: Error) {\n super(message, 'INVALID_EVENT', cause);\n this.name = 'InvalidEventError';\n }\n}\n\n/**\n * Error thrown when peer discovery fails.\n * Used for invalid pubkeys or relay failures.\n */\nexport class PeerDiscoveryError extends ToonError {\n constructor(message: string, cause?: Error) {\n super(message, 'PEER_DISCOVERY_FAILED', cause);\n this.name = 'PeerDiscoveryError';\n }\n}\n","import { decode } from '@toon-format/toon';\nimport type { NostrEvent } from 'nostr-tools/pure';\nimport { ToonError } from '../errors.js';\nimport { isValidHex } from './validate.js';\n\n/**\n * Error thrown when TOON decoding or validation fails.\n */\nexport class ToonDecodeError extends ToonError {\n constructor(message: string, cause?: Error) {\n super(message, 'TOON_DECODE_ERROR', cause);\n this.name = 'ToonDecodeError';\n }\n}\n\n/**\n * Validate that a decoded object is a valid NostrEvent.\n */\nfunction validateNostrEvent(obj: unknown): asserts obj is NostrEvent {\n if (typeof obj !== 'object' || obj === null) {\n throw new ToonDecodeError('Decoded value is not an object');\n }\n\n const event = obj as Record<string, unknown>;\n\n // Validate id (64-char hex)\n if (!isValidHex(event['id'], 64)) {\n throw new ToonDecodeError(\n 'Invalid event id: must be a 64-character hex string'\n );\n }\n\n // Validate pubkey (64-char hex)\n if (!isValidHex(event['pubkey'], 64)) {\n throw new ToonDecodeError(\n 'Invalid event pubkey: must be a 64-character hex string'\n );\n }\n\n // Validate kind (number)\n if (typeof event['kind'] !== 'number' || !Number.isInteger(event['kind'])) {\n throw new ToonDecodeError('Invalid event kind: must be an integer');\n }\n\n // Validate content (string)\n if (typeof event['content'] !== 'string') {\n throw new ToonDecodeError('Invalid event content: must be a string');\n }\n\n // Validate tags (array of string arrays)\n const tags = event['tags'];\n if (!Array.isArray(tags)) {\n throw new ToonDecodeError('Invalid event tags: must be an array');\n }\n for (let i = 0; i < tags.length; i++) {\n const tag = tags[i];\n if (!Array.isArray(tag)) {\n throw new ToonDecodeError(`Invalid event tags[${i}]: must be an array`);\n }\n for (let j = 0; j < tag.length; j++) {\n if (typeof tag[j] !== 'string') {\n throw new ToonDecodeError(\n `Invalid event tags[${i}][${j}]: must be a string`\n );\n }\n }\n }\n\n // Validate created_at (number)\n if (\n typeof event['created_at'] !== 'number' ||\n !Number.isInteger(event['created_at'])\n ) {\n throw new ToonDecodeError('Invalid event created_at: must be an integer');\n }\n\n // Validate sig (128-char hex)\n if (!isValidHex(event['sig'], 128)) {\n throw new ToonDecodeError(\n 'Invalid event sig: must be a 128-character hex string'\n );\n }\n}\n\n/**\n * Decode a TOON-encoded Uint8Array back to a NostrEvent.\n *\n * Used for extracting Nostr events from ILP packets.\n *\n * @param data - The TOON-encoded Uint8Array\n * @returns The decoded NostrEvent\n * @throws ToonDecodeError if decoding or validation fails\n */\nexport function decodeEventFromToon(data: Uint8Array): NostrEvent {\n try {\n const toonString = new TextDecoder().decode(data);\n const decoded = decode(toonString);\n validateNostrEvent(decoded);\n return decoded;\n } catch (error) {\n if (error instanceof ToonDecodeError) {\n throw error;\n }\n throw new ToonDecodeError(\n `Failed to decode TOON data: ${error instanceof Error ? error.message : String(error)}`,\n error instanceof Error ? error : undefined\n );\n }\n}\n","/**\n * Shared validation utilities for the TOON codec.\n */\n\n/**\n * Validate that a value is a valid hex string of expected length.\n *\n * @param value - The value to check\n * @param length - The expected string length (number of hex characters)\n * @returns True if value is a hex string of the expected length\n */\nexport function isValidHex(value: unknown, length: number): value is string {\n if (typeof value !== 'string') return false;\n if (value.length !== length) return false;\n return /^[0-9a-f]+$/i.test(value);\n}\n","import { decode } from '@toon-format/toon';\nimport { ToonDecodeError } from './decoder.js';\nimport { isValidHex } from './validate.js';\n\n/**\n * Routing metadata extracted from TOON-encoded bytes without full NostrEvent validation.\n *\n * The shallow parser extracts only the 4 routing fields needed for signature verification\n * and event routing, skipping expensive validation of content, tags, and created_at.\n */\nexport interface ToonRoutingMeta {\n kind: number;\n pubkey: string;\n id: string;\n sig: string;\n rawBytes: Uint8Array;\n}\n\n/**\n * Shallow-parse TOON-encoded bytes to extract routing metadata.\n *\n * This function decodes the TOON data and extracts only the 4 routing fields\n * (kind, pubkey, id, sig) without performing full NostrEvent validation.\n * It is cheaper than a full decode + validate cycle.\n *\n * The `rawBytes` field preserves the original input bytes for downstream\n * use (e.g., Schnorr signature verification against the serialized payload).\n *\n * @param data - The TOON-encoded Uint8Array\n * @returns Routing metadata with the original raw bytes\n * @throws ToonDecodeError if the data cannot be parsed or required routing fields are missing/invalid\n */\nexport function shallowParseToon(data: Uint8Array): ToonRoutingMeta {\n let decoded: unknown;\n try {\n const toonString = new TextDecoder().decode(data);\n decoded = decode(toonString);\n } catch (error) {\n throw new ToonDecodeError(\n `Failed to parse TOON data: ${error instanceof Error ? error.message : String(error)}`,\n error instanceof Error ? error : undefined\n );\n }\n\n if (typeof decoded !== 'object' || decoded === null) {\n throw new ToonDecodeError('Decoded TOON value is not an object');\n }\n\n const obj = decoded as Record<string, unknown>;\n\n // Validate kind (number, integer)\n if (typeof obj['kind'] !== 'number' || !Number.isInteger(obj['kind'])) {\n throw new ToonDecodeError(\n 'Missing or invalid routing field: kind must be an integer'\n );\n }\n\n // Validate pubkey (64-char hex)\n if (!isValidHex(obj['pubkey'], 64)) {\n throw new ToonDecodeError(\n 'Missing or invalid routing field: pubkey must be a 64-character hex string'\n );\n }\n\n // Validate id (64-char hex)\n if (!isValidHex(obj['id'], 64)) {\n throw new ToonDecodeError(\n 'Missing or invalid routing field: id must be a 64-character hex string'\n );\n }\n\n // Validate sig (128-char hex)\n if (!isValidHex(obj['sig'], 128)) {\n throw new ToonDecodeError(\n 'Missing or invalid routing field: sig must be a 128-character hex string'\n );\n }\n\n return {\n kind: obj['kind'] as number,\n pubkey: obj['pubkey'] as string,\n id: obj['id'] as string,\n sig: obj['sig'] as string,\n rawBytes: data,\n };\n}\n"],"mappings":"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","names":["decode","decode"]}
|