Summary
When running the relayer SDK inside Next.js (undici fetch), Response.bytes() returns an ArrayBuffer, not a Uint8Array. The SDK assumes bytes() returns Uint8Array and passes it directly into TFHE safe_deserialize, causing:
Invalid public key (deserialization failed) wrapped as Impossible to fetch public key: wrong relayer url.
This is a non‑standard API behavior (bytes() isn’t standardized), so the SDK should normalize the return type.
Where
src/utils/bytes.ts → fetchBytes()
src/relayer/network.ts (direct calls to response.bytes())
Current logic (bytes.ts):
const bytes: Uint8Array =
typeof response.bytes === 'function'
? await response.bytes()
: new Uint8Array(await response.arrayBuffer());
If bytes() returns ArrayBuffer, this breaks.
Repro (Next.js)
- Next.js 16.1.1 (Webpack), Node 24.x
- Call
createInstance({...SepoliaConfig, relayerUrl}) on the server
- The SDK fetches
/v1/keyurl, then publicKeyUrl and crsUrl.
- In undici,
response.bytes() returns ArrayBuffer → TFHE deserialization throws.
Suggested fix
Normalize bytes() to Uint8Array, or fallback to arrayBuffer:
function normalizeBytes(value: unknown): Uint8Array {
if (value instanceof Uint8Array) return value;
if (value instanceof ArrayBuffer) return new Uint8Array(value);
if (ArrayBuffer.isView(value)) {
return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
}
throw new Error(`Unsupported bytes type: ${Object.prototype.toString.call(value)}`);
}
const bytes =
typeof response.bytes === 'function'
? normalizeBytes(await response.bytes())
: new Uint8Array(await response.arrayBuffer());
Why this matters
This issue causes false "wrong relayer url" errors even when the relayer URL is correct. We verified the fetched public key & CRS bytes deserialize correctly when coerced to Uint8Array.
Happy to provide a repro repo if helpful.
Summary
When running the relayer SDK inside Next.js (undici fetch),
Response.bytes()returns an ArrayBuffer, not a Uint8Array. The SDK assumesbytes()returns Uint8Array and passes it directly into TFHEsafe_deserialize, causing:Invalid public key (deserialization failed)wrapped asImpossible to fetch public key: wrong relayer url.This is a non‑standard API behavior (bytes() isn’t standardized), so the SDK should normalize the return type.
Where
src/utils/bytes.ts→fetchBytes()src/relayer/network.ts(direct calls toresponse.bytes())Current logic (bytes.ts):
If bytes() returns ArrayBuffer, this breaks.
Repro (Next.js)
createInstance({...SepoliaConfig, relayerUrl})on the server/v1/keyurl, thenpublicKeyUrlandcrsUrl.response.bytes()returns ArrayBuffer → TFHE deserialization throws.Suggested fix
Normalize bytes() to Uint8Array, or fallback to arrayBuffer:
Why this matters
This issue causes false "wrong relayer url" errors even when the relayer URL is correct. We verified the fetched public key & CRS bytes deserialize correctly when coerced to Uint8Array.
Happy to provide a repro repo if helpful.