diff --git a/src/middleware/validateSlab.ts b/src/middleware/validateSlab.ts index cd748f8..c72dc0e 100644 --- a/src/middleware/validateSlab.ts +++ b/src/middleware/validateSlab.ts @@ -1,6 +1,8 @@ import { PublicKey } from "@solana/web3.js"; import type { Context, Next } from "hono"; -import { sanitizeSlabAddress } from "@percolator/shared"; +import { sanitizeSlabAddress, createLogger } from "@percolator/shared"; + +const logger = createLogger("api:validateSlab"); /** * Known-bad slab addresses that cause backend 500 errors (empty vault / phantom OI). @@ -45,7 +47,16 @@ const ENV_BLOCKED_SLABS: ReadonlySet = new Set( (process.env.BLOCKED_MARKET_ADDRESSES ?? "") .split(",") .map((s) => s.trim()) - .filter(Boolean), + .filter(Boolean) + .filter((entry) => { + try { + new PublicKey(entry); + return true; + } catch { + logger.warn("Invalid BLOCKED_MARKET_ADDRESSES entry dropped (not a valid base58 pubkey)", { entry }); + return false; + } + }), ); /** diff --git a/tests/middleware/validateSlab.test.ts b/tests/middleware/validateSlab.test.ts index e9dc008..307db52 100644 --- a/tests/middleware/validateSlab.test.ts +++ b/tests/middleware/validateSlab.test.ts @@ -3,6 +3,9 @@ import { Hono } from "hono"; vi.mock("@percolator/shared", () => ({ sanitizeSlabAddress: vi.fn((addr: string) => addr), + createLogger: vi.fn(() => ({ + info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn(), + })), config: { supabaseUrl: "http://test", supabaseKey: "test", rpcUrl: "http://test" }, })); @@ -105,6 +108,29 @@ describe("validateSlab middleware", () => { expect(data).toEqual({ error: "Invalid slab address" }); }); + describe("BLOCKED_MARKET_ADDRESSES env validation", () => { + it("should drop invalid base58 entries and keep valid ones", async () => { + // Set env before re-importing the module + const validPubkey = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"; + process.env.BLOCKED_MARKET_ADDRESSES = `${validPubkey},not-a-valid-key,truncated`; + + vi.resetModules(); + + // Re-import after env change + const { isBlockedSlab } = await import("../../src/middleware/validateSlab.js"); + + // Valid pubkey should be blocked + expect(isBlockedSlab(validPubkey)).toBe(true); + // Invalid entries should have been dropped, not blocking anything + expect(isBlockedSlab("not-a-valid-key")).toBe(false); + expect(isBlockedSlab("truncated")).toBe(false); + + // Clean up + delete process.env.BLOCKED_MARKET_ADDRESSES; + vi.resetModules(); + }); + }); + describe("blocklist (GH#1357 / Sentry 2026-03-17)", () => { // These addresses are phantom-OI / empty-vault slabs that cause backend // 500s when queried. They are hardcoded so the API returns 404 even when called