Skip to content

fix(transport): stop signing throwaway events during oversized size probing - #98

Merged
ContextVM-org merged 3 commits into
masterfrom
fix/oversized-size-probe-signer-round-trips
Sep 17, 2026
Merged

ContextVM-org merged 3 commits into
masterfrom
fix/oversized-size-probe-signer-round-trips

Conversation

@ContextVM-org

Copy link
Copy Markdown
Contributor

measurePublishedMcpMessageSize built and signed the real event via the configured signer just to measure its serialized byte length, discarding the signature. Every progress-token request paid an extra getPublicKey+signEvent round trip (invisible for local signers; an approval prompt for NIP-07/NIP-55, a billed operation for NIP-46), and the oversized chunk-size binary search multiplied that ~16x. The server response path had the same problem via outbound-response-router.

Sizing never needs a valid signature: pubkey/id/sig are fixed-length hex and NIP-44 v2 padding is deterministic given plaintext length, so a placeholder event serializes to a byte-identical length. Build it directly and drop the now-unused buildPublishedMcpEvent wrapper; the real send path (createSignedNostrEvent) is untouched, and the NIP-44 65 535-byte plaintext-cap throw handling in the binary search still works because encryptMessage still runs.

…robing

measurePublishedMcpMessageSize built and signed the real event via the
configured signer just to measure its serialized byte length, discarding
the signature. Every progress-token request paid an extra
getPublicKey+signEvent round trip (invisible for local signers; an
approval prompt for NIP-07/NIP-55, a billed operation for NIP-46), and
the oversized chunk-size binary search multiplied that ~16x. The server
response path had the same problem via outbound-response-router.

Sizing never needs a valid signature: pubkey/id/sig are fixed-length hex
and NIP-44 v2 padding is deterministic given plaintext length, so a
placeholder event serializes to a byte-identical length. Build it
directly and drop the now-unused buildPublishedMcpEvent wrapper; the
real send path (createSignedNostrEvent) is untouched, and the NIP-44
65 535-byte plaintext-cap throw handling in the binary search still
works because encryptMessage still runs.
…rams type

splitStringByByteSize encoded one character at a time (a TextEncoder
allocation per char), costing ~65ms per MB of oversized payload on both
client and server send paths. Encode once and split on byte boundaries,
backing off over UTF-8 continuation bytes; identical output and error
contract, ~60x faster.

Also hoist resolveSafeOversizedChunkSize's params object, previously
declared identically in the base transport, both outbound deps
interfaces, and tests, into one exported
ResolveSafeOversizedChunkSizeParams.
@ContextVM-org
ContextVM-org merged commit 6ad27b1 into master Sep 17, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant