@toon-protocol/core 1.1.2 → 1.2.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.
@@ -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("Invalid event id: must be a 64-character hex string");
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(`Invalid event tags[${i}][${j}]: must be a string`);
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-7AHDGE4H.js.map
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"]}
package/dist/index.d.ts CHANGED
@@ -1526,21 +1526,15 @@ interface ConnectorNodeLike {
1526
1526
  }
1527
1527
  /**
1528
1528
  * Configuration options for the direct runtime client.
1529
+ *
1530
+ * @deprecated toonDecoder is no longer used for condition computation.
1531
+ * Execution condition is computed directly from raw data bytes:
1532
+ * condition = SHA-256(SHA-256(raw_data_bytes))
1529
1533
  */
1530
1534
  interface DirectRuntimeClientConfig {
1531
1535
  /**
1532
- * Optional callback for extracting the Nostr event ID from TOON-encoded data.
1533
- *
1534
- * When provided, the client computes
1535
- * `executionCondition = SHA256(SHA256(event.id))` and passes it to
1536
- * `sendPacket()`.
1537
- *
1538
- * When omitted, no executionCondition is set (connector uses its default).
1539
- *
1540
- * Note: this is intentionally a narrower type than
1541
- * `BootstrapServiceConfig.toonDecoder` (which returns a full `NostrEvent`).
1542
- * Only the `id` field is needed for condition computation, so the interface
1543
- * is minimal.
1536
+ * @deprecated No longer used. Execution condition is computed from raw data
1537
+ * bytes to match the connector's PaymentHandlerAdapter.
1544
1538
  */
1545
1539
  toonDecoder?: (bytes: Uint8Array) => {
1546
1540
  id: string;
@@ -2350,6 +2344,8 @@ interface ChainPreset {
2350
2344
  usdcAddress: string;
2351
2345
  /** TokenNetwork contract address for USDC on this chain. */
2352
2346
  tokenNetworkAddress: string;
2347
+ /** TokenNetworkRegistry contract address on this chain. */
2348
+ registryAddress: string;
2353
2349
  }
2354
2350
  /**
2355
2351
  * Built-in chain presets for supported deployment environments.
@@ -2369,6 +2365,7 @@ declare const CHAIN_PRESETS: Record<ChainName, ChainPreset>;
2369
2365
  * 3. Looks up the chain name in `CHAIN_PRESETS`
2370
2366
  * 4. `TOON_RPC_URL` env var overrides the preset's `rpcUrl`
2371
2367
  * 5. `TOON_TOKEN_NETWORK` env var overrides the preset's `tokenNetworkAddress`
2368
+ * 6. `TOON_REGISTRY_ADDRESS` env var overrides the preset's `registryAddress`
2372
2369
  *
2373
2370
  * Returns a defensive copy -- callers can mutate the result without
2374
2371
  * affecting the shared preset objects.
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  encodeEventToToon,
9
9
  encodeEventToToonString,
10
10
  shallowParseToon
11
- } from "./chunk-7AHDGE4H.js";
11
+ } from "./chunk-5WT7ISKC.js";
12
12
 
13
13
  // src/constants.ts
14
14
  var ILP_PEER_INFO_KIND = 10032;
@@ -710,6 +710,7 @@ function parseJobResult(event) {
710
710
  if (!amountTag) return null;
711
711
  const amount = amountTag[1];
712
712
  if (amount === void 0 || amount === "") return null;
713
+ if (!/^\d+$/.test(amount)) return null;
713
714
  return {
714
715
  kind: event.kind,
715
716
  requestEventId,
@@ -1868,11 +1869,20 @@ var BootstrapService = class {
1868
1869
  const toonBytes = this.toonEncoder(ilpInfoEvent);
1869
1870
  const base64Toon = Buffer.from(toonBytes).toString("base64");
1870
1871
  const amount = String(BigInt(toonBytes.length) * this.basePricePerByte);
1871
- const ilpResult = await this.ilpClient.sendIlpPacket({
1872
- destination: result.peerInfo.ilpAddress,
1873
- amount,
1874
- data: base64Toon
1875
- });
1872
+ let ilpResult;
1873
+ if (this.claimSigner && result.channelId && this.ilpClient.sendIlpPacketWithClaim) {
1874
+ const claim = await this.claimSigner(result.channelId, BigInt(amount));
1875
+ ilpResult = await this.ilpClient.sendIlpPacketWithClaim(
1876
+ { destination: result.peerInfo.ilpAddress, amount, data: base64Toon },
1877
+ claim
1878
+ );
1879
+ } else {
1880
+ ilpResult = await this.ilpClient.sendIlpPacket({
1881
+ destination: result.peerInfo.ilpAddress,
1882
+ amount,
1883
+ data: base64Toon
1884
+ });
1885
+ }
1876
1886
  if (ilpResult.accepted) {
1877
1887
  console.log(
1878
1888
  `[Bootstrap] Announced to ${result.registeredPeerId} via ILP (fulfillment: ${ilpResult.fulfillment}, eventId: ${ilpInfoEvent.id})`
@@ -2435,9 +2445,8 @@ function createDirectIlpClient(connector, config) {
2435
2445
  const amount = BigInt(params.amount);
2436
2446
  const data = Uint8Array.from(Buffer.from(params.data, "base64"));
2437
2447
  let executionCondition;
2438
- if (config?.toonDecoder && data.length > 0) {
2439
- const decoded = config.toonDecoder(data);
2440
- const fulfillment = createHash("sha256").update(decoded.id).digest();
2448
+ if (data.length > 0) {
2449
+ const fulfillment = createHash("sha256").update(data).digest();
2441
2450
  executionCondition = createHash("sha256").update(fulfillment).digest();
2442
2451
  }
2443
2452
  const result = await connector.sendPacket({
@@ -3017,21 +3026,24 @@ var CHAIN_PRESETS = {
3017
3026
  chainId: 31337,
3018
3027
  rpcUrl: "http://localhost:8545",
3019
3028
  usdcAddress: MOCK_USDC_ADDRESS,
3020
- tokenNetworkAddress: "0xCafac3dD18aC6c6e92c921884f9E4176737C052c"
3029
+ tokenNetworkAddress: "0xCafac3dD18aC6c6e92c921884f9E4176737C052c",
3030
+ registryAddress: "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512"
3021
3031
  },
3022
3032
  "arbitrum-sepolia": {
3023
3033
  name: "arbitrum-sepolia",
3024
3034
  chainId: 421614,
3025
3035
  rpcUrl: "https://sepolia-rollup.arbitrum.io/rpc",
3026
3036
  usdcAddress: "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d",
3027
- tokenNetworkAddress: ""
3037
+ tokenNetworkAddress: "0x91d62b1F7C5d1129A64EE3915c480DBF288B1cBa",
3038
+ registryAddress: ""
3028
3039
  },
3029
3040
  "arbitrum-one": {
3030
3041
  name: "arbitrum-one",
3031
3042
  chainId: 42161,
3032
3043
  rpcUrl: "https://arb1.arbitrum.io/rpc",
3033
3044
  usdcAddress: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
3034
- tokenNetworkAddress: ""
3045
+ tokenNetworkAddress: "",
3046
+ registryAddress: ""
3035
3047
  }
3036
3048
  };
3037
3049
  function resolveChainConfig(chain) {
@@ -3053,6 +3065,10 @@ function resolveChainConfig(chain) {
3053
3065
  if (envTokenNetwork) {
3054
3066
  resolved.tokenNetworkAddress = envTokenNetwork;
3055
3067
  }
3068
+ const envRegistryAddress = process.env["TOON_REGISTRY_ADDRESS"];
3069
+ if (envRegistryAddress) {
3070
+ resolved.registryAddress = envRegistryAddress;
3071
+ }
3056
3072
  return resolved;
3057
3073
  }
3058
3074
  function buildEip712Domain(config) {