Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/middleware/validateSlab.ts
Original file line number Diff line number Diff line change
@@ -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).
Expand Down Expand Up @@ -45,7 +47,16 @@ const ENV_BLOCKED_SLABS: ReadonlySet<string> = 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;
}
}),
);

/**
Expand Down
26 changes: 26 additions & 0 deletions tests/middleware/validateSlab.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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" },
}));

Expand Down Expand Up @@ -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
Expand Down