Category
Hardcoded Third-Party Service URLs and Embedded Project Identifiers
Locations
Goldsky subgraph — embedded project ID, no env override:
core/src/subscriber/external/goldsky.ts — const POLYMARKET_TRADES_ENDPOINT = 'https://api.goldsky.com/api/public/project_cl6mb8i9h0003e201j6li0diw/subgraphs/orderbook-subgraph/prod/gn'
The Goldsky project ID (project_cl6mb8i9h0003e201j6li0diw) is embedded directly in the URL string. Migrating to a new Goldsky project, promoting a staging subgraph to production, or pointing to a forked subgraph requires a code change.
Router client — always targets production:
core/src/router/client.ts — const DEFAULT_BASE_URL = 'https://api.pmxt.dev'
No process.env.PMXT_API_URL check. Any consumer of PmxtApiClient in tests or a staging environment hits the live production API.
Opinion exchange — three URL constants, zero env support:
core/src/exchanges/opinion/config.ts:1 — export const DEFAULT_OPINION_API_URL = "https://openapi.opinion.trade/openapi" (no env var)
core/src/exchanges/opinion/config.ts:2 — export const OPINION_WS_URL = "wss://ws.opinion.trade" (no env var)
Both constants are used directly with no process.env.OPINION_API_URL || ... pattern.
Hardcoded GraphQL result limits within query strings:
core/src/subscriber/external/goldsky.ts — first: 5 in BUILD_POLYMARKET_TRADES_AS_MAKER_QUERY
core/src/subscriber/external/goldsky.ts — first: 20 in BUILD_POLYMARKET_TRADES_AS_TAKER_QUERY
These literal integers are embedded inside template-literal GraphQL query strings, making them invisible to grep for numeric literals and impossible to adjust without editing query text.
Inconsistencies
- Polymarket uses
process.env.POLYMARKET_CLOB_URL || 'https://clob.polymarket.com' and four other env-guarded URL constants; Kalshi uses an {env} server variable in its OpenAPI spec. Opinion uses neither pattern.
- The router client
PmxtApiClient is the one internal-service URL in the codebase with no env variable override, while every exchange already supports env-level URL overrides.
- The Goldsky maker query allows only
first: 5 results per poll while the taker query allows first: 20 — a 4× asymmetry. GoldSkySubscriber.pollMs defaults to 3 000 ms. A Polymarket market maker executing more than 5 fills inside a 3-second poll window will silently drop the excess fills from balance/trade activity calculations.
Risk
- Goldsky project ID: Goldsky subgraph migrations (version upgrades, chain re-indexing, project consolidation) require a code change and deploy rather than a config change.
- Router default URL: Integration tests and staging deployments inadvertently call
api.pmxt.dev production unless every caller manually overrides baseUrl — easy to miss and hard to detect.
- Opinion no env: Opinion cannot be pointed at a staging/sandbox environment without a code change.
- GraphQL
first limits: Silent data loss for high-frequency Polymarket market makers — no warning is emitted when the first: 5 cap is reached.
Suggested Fix
// core/src/subscriber/external/goldsky.ts
const GOLDSKY_POLYMARKET_PROJECT_URL = process.env.POLYMARKET_GOLDSKY_URL ||
'https://api.goldsky.com/api/public/project_cl6mb8i9h0003e201j6li0diw/subgraphs/orderbook-subgraph/prod/gn';
const GOLDSKY_MAKER_TRADES_LIMIT = 5; // lower than taker: market makers trade less frequently per poll
const GOLDSKY_TAKER_TRADES_LIMIT = 20;
// core/src/router/client.ts
const DEFAULT_BASE_URL = process.env.PMXT_API_URL || 'https://api.pmxt.dev';
// core/src/exchanges/opinion/config.ts
export const DEFAULT_OPINION_API_URL = process.env.OPINION_API_URL || "https://openapi.opinion.trade/openapi";
export const OPINION_WS_URL = process.env.OPINION_WS_URL || "wss://ws.opinion.trade";
Found by automated magic numbers audit
Category
Hardcoded Third-Party Service URLs and Embedded Project Identifiers
Locations
Goldsky subgraph — embedded project ID, no env override:
core/src/subscriber/external/goldsky.ts—const POLYMARKET_TRADES_ENDPOINT = 'https://api.goldsky.com/api/public/project_cl6mb8i9h0003e201j6li0diw/subgraphs/orderbook-subgraph/prod/gn'The Goldsky project ID (
project_cl6mb8i9h0003e201j6li0diw) is embedded directly in the URL string. Migrating to a new Goldsky project, promoting a staging subgraph to production, or pointing to a forked subgraph requires a code change.Router client — always targets production:
core/src/router/client.ts—const DEFAULT_BASE_URL = 'https://api.pmxt.dev'No
process.env.PMXT_API_URLcheck. Any consumer ofPmxtApiClientin tests or a staging environment hits the live production API.Opinion exchange — three URL constants, zero env support:
core/src/exchanges/opinion/config.ts:1—export const DEFAULT_OPINION_API_URL = "https://openapi.opinion.trade/openapi"(no env var)core/src/exchanges/opinion/config.ts:2—export const OPINION_WS_URL = "wss://ws.opinion.trade"(no env var)Both constants are used directly with no
process.env.OPINION_API_URL || ...pattern.Hardcoded GraphQL result limits within query strings:
core/src/subscriber/external/goldsky.ts—first: 5inBUILD_POLYMARKET_TRADES_AS_MAKER_QUERYcore/src/subscriber/external/goldsky.ts—first: 20inBUILD_POLYMARKET_TRADES_AS_TAKER_QUERYThese literal integers are embedded inside template-literal GraphQL query strings, making them invisible to grep for numeric literals and impossible to adjust without editing query text.
Inconsistencies
process.env.POLYMARKET_CLOB_URL || 'https://clob.polymarket.com'and four other env-guarded URL constants; Kalshi uses an{env}server variable in its OpenAPI spec. Opinion uses neither pattern.PmxtApiClientis the one internal-service URL in the codebase with no env variable override, while every exchange already supports env-level URL overrides.first: 5results per poll while the taker query allowsfirst: 20— a 4× asymmetry.GoldSkySubscriber.pollMsdefaults to 3 000 ms. A Polymarket market maker executing more than 5 fills inside a 3-second poll window will silently drop the excess fills from balance/trade activity calculations.Risk
api.pmxt.devproduction unless every caller manually overridesbaseUrl— easy to miss and hard to detect.firstlimits: Silent data loss for high-frequency Polymarket market makers — no warning is emitted when thefirst: 5cap is reached.Suggested Fix
Found by automated magic numbers audit