From e223a50a4e9ce0cf10332ad845eab9b025c078c0 Mon Sep 17 00:00:00 2001 From: dajiaohuang Date: Wed, 2 Sep 2026 17:56:33 +0800 Subject: [PATCH 1/2] fix: support 'auth' header type and raw-byte signature encoding - Add 'auth' to accepted header types in decodeHeader - Support both ASCII-hex and raw-byte signature encodings in decodeCustodyTypeSignature Fixes framesjs/frames.js#551 --- .../frames.js/src/farcaster-v2/json-signature.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/frames.js/src/farcaster-v2/json-signature.ts b/packages/frames.js/src/farcaster-v2/json-signature.ts index 578fdd1d..5ff20af8 100644 --- a/packages/frames.js/src/farcaster-v2/json-signature.ts +++ b/packages/frames.js/src/farcaster-v2/json-signature.ts @@ -26,7 +26,7 @@ export class InvalidJFSSignatureError extends Error { export type JSONFarcasterSignatureHeader = { fid: number; - type: "custody" | "app_key"; + type: "custody" | "app_key" | "auth"; key: `0x${string}`; }; @@ -311,7 +311,7 @@ export function decodeHeader( if ( "type" in value && typeof value.type === "string" && - ["custody", "app_key"].includes(value.type) + ["custody", "app_key", "auth"].includes(value.type) ) { header.type = value.type as JSONFarcasterSignatureHeader["type"]; } else { @@ -380,13 +380,16 @@ export function decodeAppKeyTypeSignature(signature: string): `0x${string}` { export function decodeCustodyTypeSignature(signature: string): `0x${string}` { try { - const decoded = base64urlDecode(signature).toString("utf-8"); + const decoded = base64urlDecode(signature); + const asText = decoded.toString("utf-8").trim(); - if (!decoded.startsWith("0x")) { - throw new Error("Invalid signature, must contain hex text"); + // Check if it's a valid hex string (ASCII encoding) + if (/^0x[0-9a-fA-F]+$/.test(asText) && asText.length % 2 === 0) { + return asText as `0x${string}`; } - return decoded as `0x${string}`; + // Otherwise, treat as raw 65-byte signature encoded as base64url + return `0x${decoded.toString("hex")}` as `0x${string}`; } catch (e) { throw new InvalidJFSSignatureError(e); } From 4121a93d81dec1d9bdabd7f79b870165ba042a46 Mon Sep 17 00:00:00 2001 From: dajiaohuang Date: Fri, 4 Sep 2026 14:05:49 +0800 Subject: [PATCH 2/2] fix: verify auth signatures and preserve odd hex --- packages/frames.js/src/farcaster-v2/json-signature.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/frames.js/src/farcaster-v2/json-signature.ts b/packages/frames.js/src/farcaster-v2/json-signature.ts index 5ff20af8..9799af8f 100644 --- a/packages/frames.js/src/farcaster-v2/json-signature.ts +++ b/packages/frames.js/src/farcaster-v2/json-signature.ts @@ -240,6 +240,12 @@ export async function verify( return false; } + // Auth addresses are delegated signers, so they are not the custody + // address returned by the IdRegistry custodyOf lookup. + if (decodedHeader.type === "auth") { + return true; + } + const custodyAddressOfFid = await publicClient.readContract({ abi: parseAbi([ "function custodyOf(uint256) public view returns (address)", @@ -384,7 +390,7 @@ export function decodeCustodyTypeSignature(signature: string): `0x${string}` { const asText = decoded.toString("utf-8").trim(); // Check if it's a valid hex string (ASCII encoding) - if (/^0x[0-9a-fA-F]+$/.test(asText) && asText.length % 2 === 0) { + if (/^0x[0-9a-fA-F]+$/.test(asText)) { return asText as `0x${string}`; }