From cdd357cb08a2fba6e4aa42199ed61acb485b5287 Mon Sep 17 00:00:00 2001 From: Jakob Notland Date: Tue, 21 Apr 2026 14:10:33 +0200 Subject: [PATCH] Accept change --- packages/core/src/relay-client.ts | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/core/src/relay-client.ts b/packages/core/src/relay-client.ts index f6f9067..dade7b6 100644 --- a/packages/core/src/relay-client.ts +++ b/packages/core/src/relay-client.ts @@ -26,12 +26,19 @@ import { ChunkAssembler } from "./chunk-assembler.js"; import { debug, error as logError, Scope } from "./log.js"; /// Messages larger than this (JSON chars) are split into chunks when the peer -/// supports chunking. Chosen conservatively: a 30 000-char message produces a -/// rumor JSON of ≈32 700 chars after NIP-59 double-encoding, well under the -/// ~40 960-char threshold at which the outer NIP-44 layer would fail. +/// supports chunking. The NIP-44 limit is 65 535 bytes of plaintext per call. +/// createWrap encrypts the seal JSON; that seal JSON contains the base64 of the +/// inner NIP-44 ciphertext. NIP-44 pads plaintext to the next power of two, so +/// the ciphertext size jumps sharply once the rumor JSON crosses 32 768 bytes: +/// rumor JSON ≤ 32 768 B → inner ciphertext ≈ 43 780 B (base64) → seal JSON +/// ≈ 44 130 B → safe. Rumor JSON > 32 768 B → inner ciphertext ≈ 87 472 B +/// → seal JSON ≈ 87 822 B → exceeds the 65 535-byte limit → NIP-44 throws. +/// A 30 000-char message produces a rumor JSON of ≈ 30 300 bytes, leaving a +/// comfortable 2 500-byte margin below the 32 768-byte cliff. const MAX_SAFE_MESSAGE_SIZE = 30_000; -/// Size of each chunk_data slice (chars). Kept below MAX_SAFE_MESSAGE_SIZE so +/// Size of each chunk_data slice (chars). A 28 000-char slice produces a chunk +/// JSON of ≈ 28 100 bytes, which sits safely below MAX_SAFE_MESSAGE_SIZE so /// chunk metadata overhead cannot push a fragment over the limit. const CHUNK_SIZE = 28_000; @@ -209,6 +216,7 @@ export class RelayClient extends EventEmitter { async disconnect(): Promise { this.lastProcessedTimestamp = Math.floor(Date.now() / 1000); this.messageQueue.setNotReady(); + this.peerSupportsChunking = false; if (this.readyTimeoutId) { clearTimeout(this.readyTimeoutId); @@ -235,9 +243,9 @@ export class RelayClient extends EventEmitter { /** * Notify the RelayClient that the connected peer supports chunked messages. - * Must be called after receiving a wallet_ready (or equivalent) that includes - * the "chunked_messages" extension. Resets to false on every new connection - * cycle implicitly — callers should set it again on each wallet_ready. + * Call this after receiving a wallet_ready that includes the "chunked_messages" + * extension. Automatically reset to false by disconnect() — call again on + * each wallet_ready so reconnects don't inherit stale state. */ setPeerSupportsChunking(supports: boolean): void { this.peerSupportsChunking = supports;