Token Registry
The token registry service (ghost-token-registry, port 3009) tracks deployed GhostERC20 tokens on the Specter chain and provides token metadata to the webapp. It serves as the canonical directory of all privacy-wrapped tokens available in the Ghost Protocol ecosystem.
Purpose
When a new GhostERC20 token is deployed via the GhostERC20Factory, the on-chain contract records the token's address, name, symbol, and decimals. However, the on-chain data does not include rich metadata such as token icons, display categories, or ordering preferences. The token registry supplements on-chain data with this additional metadata, providing a complete picture for the webapp's token selection UI.
Data Model
Each token entry in the registry contains:
| Field | Source | Description |
|---|---|---|
address | On-chain | The GhostERC20 contract address on Specter |
name | On-chain | Token name (e.g., "Ghost Wrapped USDC") |
symbol | On-chain | Token symbol (e.g., "gUSDC") |
decimals | On-chain | Token decimal places (typically 18) |
tokenId | Derived | The Poseidon2-derived token identifier used in commitments |
icon | Admin-uploaded | URL or base64-encoded token icon image |
category | Admin-managed | Classification (e.g., "stablecoin", "governance", "native") |
enabled | Admin-managed | Whether the token is visible in the webapp |
sortOrder | Admin-managed | Display ordering in the token list |
underlyingChain | Admin-managed | The source chain of the underlying asset (e.g., "Base", "Ethereum") |
API
GET /tokens
Returns the full list of registered tokens.
Response:
{
"tokens": [
{
"address": "0x...",
"name": "Ghost Wrapped USDC",
"symbol": "gUSDC",
"decimals": 18,
"tokenId": "0x...",
"icon": "https://relayer.specterchain.com/icons/gusdc.png",
"category": "stablecoin",
"enabled": true,
"sortOrder": 1,
"underlyingChain": "Base"
}
]
}
GET /tokens/:address
Returns metadata for a single token by its contract address.
Response:
{
"address": "0x...",
"name": "Ghost Wrapped USDC",
"symbol": "gUSDC",
"decimals": 18,
"tokenId": "0x...",
"icon": "https://relayer.specterchain.com/icons/gusdc.png",
"category": "stablecoin",
"enabled": true,
"sortOrder": 1,
"underlyingChain": "Base"
}
POST /tokens (admin)
Adds or updates a token entry. Requires admin authentication.
Request:
{
"address": "0x...",
"icon": "<base64-encoded image or URL>",
"category": "stablecoin",
"enabled": true,
"sortOrder": 1,
"underlyingChain": "Base"
}
The service fetches name, symbol, and decimals directly from the on-chain contract, so the admin only needs to provide supplementary metadata.
POST /tokens/:address/icon (admin)
Uploads a token icon image. Accepts multipart/form-data with a single image file.
Response:
{
"iconUrl": "https://relayer.specterchain.com/icons/gusdc.png"
}
Icons are stored on the local filesystem and served statically by Caddy.
GET /health
{
"status": "healthy",
"tokenCount": 12,
"uptime": 864000
}
Admin Authentication
Admin endpoints are protected by an API key passed in the Authorization header:
Authorization: Bearer <ADMIN_API_KEY>
The admin API key is stored as an environment variable. Only the Specter team uses admin endpoints — the webapp only calls the public GET endpoints.
Token ID Derivation
The tokenId field is the Poseidon2-derived identifier used within the Ghost Protocol's ZK circuits to identify which token a commitment is associated with. The derivation follows this pattern:
tokenId = Poseidon2(tokenAddress, chainId) mod BN254_FIELD
The token registry computes this value when a token is added and includes it in API responses so that clients do not need to perform the Poseidon computation themselves.
Data Persistence
Token metadata is persisted to a JSON file on disk. The file is read at startup and written after any admin modification. The registry does not use a database — the token count is small enough (typically under 50 tokens) that a flat file is sufficient.
Configuration
| Parameter | Default | Description |
|---|---|---|
PORT | 3009 | HTTP server port |
RPC_URL | — | Specter chain RPC for on-chain token data |
ADMIN_API_KEY | — | API key for admin endpoints |
ICONS_DIR | ./icons | Directory for uploaded token icons |
DATA_FILE | ./tokens.json | Path to the persistent token data file |