@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.
@@ -5,7 +5,7 @@ import {
5
5
  encodeEventToToon,
6
6
  encodeEventToToonString,
7
7
  shallowParseToon
8
- } from "../chunk-7AHDGE4H.js";
8
+ } from "../chunk-5WT7ISKC.js";
9
9
  export {
10
10
  ToonDecodeError,
11
11
  ToonEncodeError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toon-protocol/core",
3
- "version": "1.1.2",
3
+ "version": "1.3.0",
4
4
  "description": "Core library for Nostr-based ILP peer discovery and settlement",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -57,7 +57,7 @@
57
57
  "ws": "^8.18.0"
58
58
  },
59
59
  "peerDependencies": {
60
- "@toon-protocol/connector": ">=1.7.0"
60
+ "@toon-protocol/connector": ">=2.2.0"
61
61
  },
62
62
  "peerDependenciesMeta": {
63
63
  "@toon-protocol/connector": {
@@ -1 +0,0 @@
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('Invalid event id: must be a 64-character hex string');\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(`Invalid event tags[${i}][${j}]: must be a string`);\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"]}