The Trinity Beast – EAM Admin Panel

Visual management of the Exchange Asset Map — toggle prewarm feeds, enable/disable assets, and sync to running containers without writing SQL

Region: us-east-2 (Ohio) Version: v1.0 May 31, 2026 Aurora: exchange_asset_map (221 rows)

1. What Is the EAM?

EAM stands for Exchange Asset Map. It is the Aurora table (exchange_asset_map) that is the single source of truth for every crypto asset The Trinity Beast tracks. Each row answers three questions about one asset on one exchange:

Column: enabled
Dropdown Visibility

Does this asset appear in the subscriber demo dropdown? Controls /asset-categories.

Column: prewarm
Live WebSocket Feed

Does this asset get a persistent WebSocket subscription at startup? false = REST fallback only.

Column: exchange_symbol
Exchange Ticker

What symbol does this exchange use? Coinbase: BTC-USD. OKX: BTC-USDT. Gate.io: BTC_USDT.

Column: category
Dropdown Group

Which category group the asset appears under in the demo dropdown. 7 categories: Major Currencies, DeFi, Layer 2, AI & Data, Gaming & NFTs, Meme Coins, Infrastructure.

Design rule: Each asset has exactly one exchange home. No asset appears on two exchanges simultaneously in the prewarm list. The asset-rebalance routine enforces this — when adding assets to an exchange, it automatically excludes assets already covered by any other exchange.

Current Scale

ExchangeEnabledPrewarmedTotal Rows
Coinbase262628
Crypto.com242424
Gate.io242427
Gemini252541
Kraken262633
OKX363643
Bybit (legacy, disabled)02425
Total161161221

2. Why It Matters

Before the EAM Admin Panel, managing the asset map required three separate manual steps every time an asset needed to be added, toggled, or rebalanced:

Before (Manual)After (EAM Admin Panel)
Write raw SQL against Aurora via /admin/sql — easy to make a typo, no visual confirmation Click a toggle switch — change is applied instantly with optimistic UI and toast confirmation
Run bash scripts/kcc.sh sync-eam from the terminal to push EAM rows into legacy application_parameters Click "Run Sync" in the Sync & Deploy panel — same operation, visual per-exchange results
Run bash scripts/kcc.sh force-deploy to push parameters to running containers Click "Force Deploy" (unlocked after sync) — containers pick up changes immediately
No visibility into current state — had to query Aurora to see what was enabled/prewarmed Full table view with per-exchange stats, search, filter by enabled/prewarm/disabled
Why sync is a separate step: The EAM table is the source of truth the LPO server reads at startup. But the legacy *_prewarm_assets parameters in application_parameters are what the running containers use for their in-memory prewarm lists. Sync bridges the two. Force-deploy then pushes the updated parameters into every container's live cache without a restart.

3. Panel Overview

The EAM Admin Panel is a standalone HTML page at /docs/eam-admin.html. It is admin-key authenticated — all API calls include the X-Admin-Key header. No login screen; access is controlled at the WAF and network level.

3.1 Main Asset Table

The default view shows all 221 EAM rows across all exchanges. The table is sortable by asset name or exchange, searchable by asset symbol or exchange ticker, and filterable by state.

https://api.cpmp-site.org/docs/eam-admin.html
EAM Admin Exchange Asset Map
⟳ Sync & Deploy + Add Asset
Exchanges
All Exchanges221 total
⬡ 161 pw
Coinbase26/28
⬡ 26
Crypto.com24/24
⬡ 24
Gate.io24/27
⬡ 24
Gemini25/41
⬡ 25
Kraken26/33
⬡ 26
OKX36/43
⬡ 36
221Total Assets
161Enabled
161Prewarmed
60Disabled
All Exchanges 221 assets All Enabled Prewarmed Disabled
Asset ↑Exchange SymbolCategoryExchangeEnabledPrewarm
AAVE
aaveusdDeFigemini
On
Live
ACE
ACE-USDTGaming & NFTsokx
On
Live
ADA
ADA-USDMajor Currenciescoinbase
On
Live
1INCH
1INCHUSDTDeFibybit
Off
Live

Figure 3.1 — Main asset table showing all exchanges. Sidebar shows per-exchange enabled/prewarmed counts. Stats bar updates as filters are applied.

3.2 Exchange Sidebar

Clicking any exchange tab filters the table to that exchange only. The sidebar shows two numbers per exchange: enabled/total and the prewarmed count in purple. The active tab is highlighted in amber.

eam-admin.html — Gemini selected
EAM Admin Exchange Asset Map
⟳ Sync & Deploy+ Add Asset
Exchanges
All Exchanges221 total
⬡ 161 pw
Coinbase26/28
⬡ 26
Crypto.com24/24
⬡ 24
Gate.io24/27
⬡ 24
Gemini25/41
⬡ 25
Kraken26/33
⬡ 26
OKX36/43
⬡ 36
41Total Assets
25Enabled
25Prewarmed
16Disabled
Gemini 41 assets AllEnabledPrewarmedDisabled
Asset ↑Exchange SymbolCategoryExchangeEnabledPrewarm
AAVE
aaveusdDeFigemini
On
Live
AMP
ampusdInfrastructuregemini
On
Live
APE
apeusdGaming & NFTsgemini
Off
REST
AVAX
avaxusdMajor Currenciesgemini
Off
REST

Figure 3.2 — Gemini tab selected. Stats bar updates to show Gemini-only counts. Disabled rows (APE, AVAX) show Off/REST toggles — they exist in EAM but are not active.

3.3 Inline Toggle Switches

Each asset row has two independent toggle switches. Changes are applied immediately via POST /admin/exchange-assets/toggle — no save button required. The UI updates optimistically and reverts if the API call fails.

ToggleColorOn StateOff StateEffect
EnabledGreenOn — appears in /asset-categories dropdownOff — hidden from subscribersImmediate in Aurora. Dropdown refreshes within 5 min (CDN cache) or on force-deploy.
PrewarmPurpleLive — persistent WebSocket subscriptionREST — served via REST fallback on demandImmediate in Aurora. Takes effect on next container restart or force-deploy after sync.
Prewarm vs Enabled are independent. An asset can be enabled (visible in dropdown) but not prewarmed (served via REST fallback). This is the right setting for low-volume tokens where a persistent WebSocket subscription would be wasteful. An asset that is prewarmed but not enabled has a live feed but is hidden from subscribers — useful during testing before a public launch.

3.4 Add / Edit Asset Modal

The + Add Asset button opens a two-step picker. For a new asset, the panel first calls POST /admin/eam/discover to fetch the top 18 uncovered candidates for the current exchange, ranked by 24h volume. You see a grid of cards — each showing the asset name, exchange symbol, price, and 24h volume. Click to select one or more, choose a category, set Enabled and Prewarm, then click Add Selected.

If you need to enter an asset manually (e.g. a newly listed token not yet ranked), click Enter manually to switch to the form view. The edit flow (pencil icon on row hover) always opens the form view directly — Asset and Exchange are locked since they form the primary key.

eam-admin.html — Add Asset modal
Add Asset
Asset Symbol *
Exchange Symbol *
Exchange *
Category
Enabled (appears in dropdown)
Prewarm (live WebSocket feed)

Figure 3.4 — Add Asset modal (manual entry view). The default view shows the discovery picker with top 18 uncovered candidates. Click "Enter manually" to reach this form. Both Enabled and Prewarm default to checked.

3.5 Sync & Deploy Panel

The Sync & Deploy button (header or sidebar) reveals the sync panel. This is a two-step operation: Run Sync writes the current EAM state to application_parameters, then Force Deploy (unlocked after sync) pushes those parameters to all running containers immediately.

eam-admin.html — Sync panel after successful sync
Sync EAM → Legacy Parameters + Force Deploy

Writes all prewarm=true, enabled=true rows from EAM into application_parameters, then triggers a force-deploy so running containers pick up the changes immediately.

⟳ Run Sync ▶ Force Deploy Close
✅ Synced 161 assets across 6 exchanges coinbase_prewarm_assets (26) cryptocom_prewarm_assets (24) gateio_prewarm_assets (24) gemini_prewarm_assets (25) kraken_prewarm_assets (26) okx_prewarm_assets (36) prewarm_assets_list (161) Parameters updated. Call /admin/force-deploy-params to push to running containers. ✅ Force-deploy complete — BeastMain (312ms)

Figure 3.5 — Sync panel after a successful sync + force-deploy. Each exchange parameter is confirmed individually. Force Deploy is unlocked only after a successful sync.

3.6 Prewarm Audit Panel

Click Audit in the header or Prewarm Audit in the sidebar to open the audit panel. Click Run Audit to start the 4-layer check. The audit runs asynchronously on the server (~12–15 seconds) — the panel polls every 3 seconds and renders results automatically when ready.

LayerWhat It ChecksHow
Layer 1Every prewarm asset's exchange_symbol returns a live price from that exchange's public APIBulk ticker fetch (Gemini, OKX, Gate.io, Crypto.com) + per-asset calls (Coinbase, Kraken)
Layer 2Each exchange's *_prewarm_assets parameter matches EAMAurora SQL diff — EAM vs application_parameters
Layer 3Master prewarm_assets_list matches the combined EAM prewarm setAurora SQL diff
Layer 410 random prewarm assets return 200 from the live LPO /price endpointEnd-to-end smoke test via demo API key
Dead asset remediation is built in. If Layer 1 finds a dead asset, a Disable button appears inline next to it. Clicking it sets enabled=false and prewarm=false immediately, then re-runs the audit automatically. Follow up with Sync & Deploy to push the change to running containers.
Drift remediation is one click. If Layers 2 or 3 detect drift between EAM and the legacy parameters, a Fix: Run Sync button appears inline. Clicking it opens the Sync & Deploy panel pre-positioned to resolve the drift.

The last audit result is cached in Valkey (eam:audit:latest, 24h TTL). If you open the panel and a recent result exists, it renders immediately without re-running the audit.

3.7 Asset Discovery Picker

When you click + Add Asset with an exchange tab selected, the panel calls POST /admin/eam/discover and shows a spinner while the server fetches the live catalog, filters out everything already in our collection across all exchanges, and ranks the remainder by 24h volume. Results appear as a card grid — click to select, click again to deselect. Multi-select is supported.

Card FieldSource
Asset name (e.g. AI)Canonical uppercase base asset
Exchange symbol (e.g. AI-USDT)Exact format for that exchange — used as-is when saving to EAM
PriceLive from the exchange's ticker API at discovery time
24h volumeUSD-denominated 24h volume — primary sort key
No regex, no pattern matching. The exclusion logic uses direct map lookups only — covered assets are checked by exact lowercase string equality against the full EAM collection. Stablecoins and fiat are excluded via an exact set of known strings (usdc, usdt, dai, eur, etc.). The exchange catalog filtering uses exact field comparisons (quote == "USDT", state == "live"). Deterministic, precise, no false positives.

Discovery results are cached in Valkey for 10 minutes per exchange (eam:discover:{exchange}). Opening the picker a second time for the same exchange within that window is instant — no re-fetch.

The Replace flow (from the audit panel's dead asset rows) uses the same picker, pre-loaded for the dead asset's exchange. When you confirm the replacement, the dead asset is automatically disabled and the new asset is added in a single operation.

4. Standard Workflow

The most common operations and the exact steps to perform them in the panel.

Run a prewarm audit

  1. Click Audit in the header (or Prewarm Audit in the sidebar).
  2. Click Run Audit. The panel shows a spinner while the audit runs (~12–15s).
  3. Results render automatically: per-exchange Layer 1 bars, drift status for Layers 2 & 3, smoke test chips for Layer 4.
  4. If dead assets are found, click Disable next to each one, then run Sync & Deploy.
  5. If drift is detected, click Fix: Run Sync to open the Sync & Deploy panel.

Toggle a single asset on or off

  1. Find the asset (use the search box or select the exchange tab).
  2. Click the Enabled toggle. The change is applied immediately — no sync needed for dropdown visibility.
  3. If you also changed Prewarm, run Sync & Deploy to push the updated prewarm list to running containers.

Add a new asset

  1. Select the target exchange tab in the sidebar.
  2. Click + Add Asset. The panel fetches the top 18 uncovered candidates from that exchange (~10–30s, shows a spinner).
  3. Click one or more asset cards to select them. Each card shows the asset name, exchange symbol, price, and 24h volume.
  4. Choose a category, confirm Enabled and Prewarm are checked, click Add N Assets.
  5. Click Sync & DeployRun SyncForce Deploy to activate the WebSocket subscriptions on running containers.
  6. If the asset you want isn't in the picker (newly listed, very low volume), click Enter manually to type the asset and exchange symbol directly.

Replace a dead/delisted asset

  1. Run the Prewarm Audit. Dead assets appear with Disable and Replace buttons.
  2. Click Replace next to the dead asset. The picker opens pre-loaded for that exchange.
  3. Select the replacement asset(s) and click Add Selected. The dead asset is automatically disabled and the new asset is added in one step.
  4. Run Sync & Deploy to push the change to running containers.

Rebalance an exchange (add multiple assets)

For bulk additions, use the asset-rebalance KCC command which handles discovery, deduplication, and volume ranking automatically. The panel is best for individual asset management and state inspection.

bash scripts/kcc.sh asset-rebalance gemini 5           # preview top 5 candidates
bash scripts/kcc.sh asset-rebalance gemini 5 --apply   # commit + sync + deploy

After the rebalance command completes, refresh the EAM Admin Panel to see the new rows.

Disable a delisted asset

  1. Find the asset in the table.
  2. Toggle Enabled off and Prewarm off.
  3. Run Sync & Deploy to remove it from the prewarm list on running containers.
  4. Optionally delete the row entirely using the trash icon (row hover).
Keyboard shortcuts: ⌘K (or Ctrl+K) focuses the search box. Esc closes the modal.

5. API Endpoints

All endpoints require the X-Admin-Key header. All responses use the standard UME envelope.

MethodPathPurpose
GET/admin/exchange-assetsList all EAM rows. Optional ?exchange=coinbase filter. Returns id, asset, exchange_name, exchange_symbol, enabled, prewarm, category.
POST/admin/exchange-assets/saveUpsert one or more asset rows. Body: {"exchange_name":"gemini","assets":[{"asset":"MON","exchange_symbol":"monusd","enabled":true,"prewarm":true,"category":"Meme Coins"}]}
POST/admin/exchange-assets/toggleFlip enabled and/or prewarm on a single row. Body: {"exchange_name":"okx","asset":"BANANA","prewarm":false}. Only the fields provided are updated.
DELETE/admin/exchange-assetsDelete a row. ?exchange=gemini&asset=APE deletes one asset. ?exchange=gemini deletes all assets for that exchange.
POST/admin/eam/syncSync EAM → application_parameters. Reads all enabled=true, prewarm=true rows, writes per-exchange CSV params and the master prewarm_assets_list. Returns per-key results.
GET/admin/force-deploy-paramsPush updated application_parameters to all running containers immediately. Used after sync to activate changes without a restart.
GET/admin/eam/auditStart a 4-layer prewarm audit in the background. Returns 202 immediately. The audit runs async (~12–15s) and stores results in Valkey (eam:audit:latest, 24h TTL). If an audit is already running, returns {"status":"already_running"}.
GET/admin/eam/audit?poll=1Poll for audit results. Returns {"ready":false,"running":true} while in progress, or {"ready":true,"result":{...}} when complete. The panel polls every 3 seconds automatically.
POST/admin/eam/discoverStart async discovery of uncovered assets for an exchange, ranked by 24h volume. Body: {"exchange":"okx","limit":18}. Returns 202 immediately. Filters against the full EAM collection across all exchanges. Results cached in Valkey 10 min per exchange (eam:discover:{exchange}).
GET/admin/eam/discover?exchange=okx&poll=1Poll for discovery results. Returns {"ready":false} while running, or {"ready":true,"result":{"candidates":[...],"uncovered":N,"scored":N}} when complete. Each candidate includes asset, exchange_symbol, price, and volume_24h.

6. Data Model

exchange_asset_map

ColumnTypeDescription
idSERIAL PRIMARY KEYAuto-increment row ID
exchange_nameTEXT NOT NULLExchange identifier: coinbase, gemini, kraken, gateio, cryptocom, okx
assetTEXT NOT NULLCanonical asset symbol: BTC, ETH, etc. Unique per exchange.
exchange_symbolTEXT NOT NULLThe ticker this exchange uses for the asset. Format varies by exchange.
enabledBOOLEAN NOT NULL DEFAULT trueWhether the asset appears in /asset-categories (the subscriber demo dropdown).
prewarmBOOLEAN NOT NULL DEFAULT falseWhether the asset gets a persistent WebSocket subscription at container startup.
categoryTEXT NOT NULL DEFAULT 'Infrastructure'Dropdown group. Must match a row in asset_categories.
Unique constraint: (exchange_name, asset) — one row per asset per exchange. The save endpoint uses ON CONFLICT DO UPDATE so upserts are safe to retry.

Downstream: application_parameters

After a sync, the following keys are written to application_parameters:

KeyValue
coinbase_prewarm_assetsComma-separated list of prewarmed assets on Coinbase
gemini_prewarm_assetsComma-separated list of prewarmed assets on Gemini
kraken_prewarm_assets…and so on for each exchange
prewarm_assets_listMaster combined list — all unique prewarmed assets across all exchanges

7. Access & Security

The EAM Admin Panel is an admin-only tool. It is not linked from any public page.

ControlDetail
AuthenticationAll API calls include X-Admin-Key header. The key is embedded in the page source — the page itself is the credential. Do not share the URL with non-admins.
WAF Rate Limit/admin/* paths are rate-limited to 100 requests per 5 minutes at the ALB WAF.
LockdownIf the admin key is compromised, run bash scripts/kcc.sh lockdown-admin $(curl -s ifconfig.me) immediately to restrict /admin/* to your IP only, then rotate the key.
URLhttps://api.cpmp-site.org/docs/eam-admin.html