The Chain 138 RPC access product catalog (core-rpc / alltra-rpc /
thirdweb-rpc, each with VMID + HTTP/WS URL + tier + billing model + use
cases + management features) used to be a hardcoded 50-line Go literal
in api/rest/auth.go. The review flagged this as the biggest source of
'magic constants in source' in the backend: changing a partner URL, a
VMID, or a billing model required a Go recompile, and the internal
192.168.11.x CIDR endpoints were baked into the binary.
This PR moves the catalog to backend/config/rpc_products.yaml and adds
a lazy loader so every call site reads from the YAML on first use.
New files:
backend/config/rpc_products.yaml source of truth
backend/api/rest/rpc_products_config.go loader + fallback defaults
backend/api/rest/rpc_products_config_test.go unit tests
Loader path-resolution order (first hit wins):
1. $RPC_PRODUCTS_PATH (absolute or cwd-relative)
2. $EXPLORER_BACKEND_DIR/config/rpc_products.yaml
3. <cwd>/backend/config/rpc_products.yaml
4. <cwd>/config/rpc_products.yaml
5. compiled-in defaultRPCAccessProducts fallback (logs a WARNING)
Validation on load:
- every product must have a non-empty slug,
- every product must have a non-empty http_url,
- slugs must be unique across the catalog.
A malformed YAML causes a WARNING + fallback to defaults, never a
silent empty product list.
Call-site changes in auth.go:
- 'var rpcAccessProducts []accessProduct' (literal) -> func
rpcAccessProducts() []accessProduct (forwards to the lazy loader).
- Both existing consumers (/api/v1/access/products handler at line
~369 and findAccessProduct() at line ~627) now call the function.
Zero other behavioural changes; the JSON shape of the response is
byte-identical.
Tests added:
- TestLoadRPCAccessProductsFromRepoDefault: confirms the shipped
YAML loads, produces >=3 products, and contains the 3 expected
slugs with non-empty http_url.
- TestLoadRPCAccessProductsRejectsDuplicateSlug.
- TestLoadRPCAccessProductsRejectsMissingHTTPURL.
Verification:
go build ./... clean
go vet ./... clean
go test ./api/rest/ PASS (new + existing)
go mod tidy pulled yaml.v3 from indirect to direct
Advances completion criterion 7 (no magic constants): 'Chain 138
access products / VMIDs / provider URLs live in a YAML that operators
can change without a rebuild; internal CIDRs are no longer required
to be present in source.'