diff --git a/apps/indexer/src/normalize.ts b/apps/indexer/src/normalize.ts index edae87a..22d24e1 100644 --- a/apps/indexer/src/normalize.ts +++ b/apps/indexer/src/normalize.ts @@ -32,11 +32,77 @@ export type NormalizedOutput = { rawTarget: OutputTarget; }; +function sanitizeJsonString(payload: string): string { + let result = ""; + let inString = false; + + for (let index = 0; index < payload.length; index += 1) { + const char = payload[index]; + + if (!inString) { + if (char === "\"") { + inString = true; + } + result += char; + continue; + } + + if (char === "\\") { + const next = payload[index + 1]; + + if (next === undefined) { + result += "\\\\"; + continue; + } + + if (next === "\"" || next === "\\" || next === "/" || next === "b" || next === "f" || next === "n" || next === "r" || next === "t") { + result += "\\"; + result += next; + index += 1; + continue; + } + + if (next === "u") { + const hex = payload.slice(index + 2, index + 6); + if (/^[0-9a-fA-F]{4}$/.test(hex)) { + result += "\\u"; + result += hex; + index += 5; + continue; + } + } + + result += "\\\\"; + continue; + } + + if (char === "\"") { + result += char; + inString = false; + continue; + } + + const code = char.charCodeAt(0); + if (code <= 0x1f) { + result += `\\u${code.toString(16).padStart(4, "0")}`; + continue; + } + + result += char; + } + + return result; +} + export function parseRpcJson(value: string | undefined): T | null { if (!value) { return null; } - return JSON.parse(value) as T; + try { + return JSON.parse(value) as T; + } catch { + return JSON.parse(sanitizeJsonString(value)) as T; + } } export function normalizeOutputs(outputs: Array<{ amount?: string | number; target?: OutputTarget }> | undefined): NormalizedOutput[] {