This repository generates asset and chain information for the Osmosis Zone frontend. It uses the Cosmos Chain Registry as the source of truth for asset metadata, then layers Osmosis-specific configurations on top:
- Reliable Endpoints - Curated RPC/REST endpoints with validation and health monitoring
- Transfer Methods - Custom transfer configurations for assets requiring special handling
- Verification Status - Asset verification flags based on listing criteria
- Categories - Asset categorization (DeFi, meme tokens, etc.) for frontend filtering
- Property Overrides - Osmosis-specific display properties when needed
The generated files power the Osmosis Zone interface, providing wallet integration, asset discovery, and chain connectivity information. Asset metadata (logos, descriptions, social links) comes from Chain Registry and is automatically updated during scheduled runs.
The Cosmos Chain Registry is the source of truth for all asset metadata. Assets registered in Chain Registry with IBC connections to Osmosis are automatically detected and added to osmosis.zone_assets.json during scheduled workflow runs (daily), making them visible on Osmosis Zone.
-
Submit PR to Chain Registry - Register your chain and asset at the Cosmos Chain Registry
- Include complete asset metadata (name, symbol, logo, description, etc.)
- Register IBC connection information between your chain and Osmosis (if applicable)
- Follow the Chain Registry contribution guide
-
Wait for Chain Registry PR to be merged - Once your PR is approved and merged into Chain Registry
-
Automatic Detection and Listing - Automated runs in this repo occur daily (15:00 UTC) and will:
- Pull latest Chain Registry data
- Automatically detect new assets with IBC connections to Osmosis
- Automatically add detected assets to
osmosis.zone_assets.json - Generate assetlists with your complete metadata from Chain Registry
- Make your asset visible on Osmosis frontend
- Can also be triggered manually by maintainers
-
Optional: Configure Additional Properties - Manually edit your entry in
osmosis.zone_assets.jsonif you need to:- Set asset categories (
"defi","meme", etc.) - Request verified status (
osmosis_verified: true- requires meeting verification criteria) - Configure custom transfer methods or property overrides
- Override display properties from Chain Registry
- Set asset categories (
Important: All asset metadata (images, descriptions, social links, etc.) comes from Chain Registry. To update asset information, submit PRs to Chain Registry, not this repository. Changes will be automatically picked up during the next automated run (daily).
This repository contains several types of files organized by chain:
These files serve as input for automated generation:
osmosis.zone_assets.json- Configuration for assets on Osmosis Zone. Auto-populated by workflow for detected assets; manually edit for categories, verification, and overrides.osmosis.zone_chains.json- Manual configuration for chains with custom RPC/REST endpoints, explorers, and chain-specific settings.osmosis.zone_config.json- General configuration and settings for the zone.
These files are automatically generated by GitHub Actions and should not be edited manually:
generated/frontend/assetlist.json- Asset list formatted for Osmosis Zone frontend consumptiongenerated/frontend/chainlist.json- Chain list formatted for Osmosis Zone frontend, including wallet integration metadatagenerated/chain-registry/assetlist.json- Asset list in Cosmos Chain Registry formatgenerated/external/- Integration files for external services (CoinGecko, Mintscan)generated/asset_detail/- Detailed metadata for individual assets including pricing, related assets, and counterparty informationstate/- Tracks asset state information such as listing status, warnings, and historical data
osmosis-1/ # Mainnet configuration
├── osmosis.zone_assets.json
├── osmosis.zone_chains.json
├── osmosis.zone_config.json
├── state/
└── generated/
├── frontend/
├── chain-registry/
├── external/
└── asset_detail/
osmo-test-5/ # Testnet configuration
└── (same structure as mainnet)
How Assets Are Added to osmosis.zone_assets.json:
-
Automatically by Workflow - Assets with IBC connections to Osmosis are automatically detected from Chain Registry and added to
osmosis.zone_assets.jsonduring scheduled runs (daily). -
Manually for Additional Configuration - You can manually add or edit entries in
osmosis.zone_assets.jsonto configure:- Asset categories (
"defi","meme", etc.) - Verification status (
osmosis_verified: trueorfalse) - Custom transfer methods
- Property overrides
- Asset categories (
Please see the asset listing requirements for information about verification and display requirements on Osmosis Zone.
Each asset object in osmosis.zone_assets.json must include these identifying details:
chain_name- Must match exactly thechain_namein the chain's chain.json file at the Chain Registry.base_denom- The minimal/indivisible (i.e., exponent: 0) denomination unit for the asset, corresponding to itsbaseat the Chain Registry.path- Required for all ICS20 assets (transferred to Osmosis from another chain via IBC). Comprised of the destination IBC port and channel for each IBC hop, followed by the base denom on the IBC-originating chain. Used as input into the SHA256 hash function.- Exception: Not required for assets deployed directly on Osmosis (e.g., factory tokens)
- Example:
"path": "transfer/channel-0/uatom"
-
osmosis_verified(boolean, default:false) - Controls whether the asset appears by default or requires "Show Unverified Assets" toggle.- Should always be set to
falseupon initial listing - After meeting requirements in LISTING.md, can be upgraded to
truevia PR - Frontend output:
verified: true/false
- Should always be set to
-
osmosis_unlisted(boolean, default:false) - Temporarily hides the asset from the Osmosis Zone app, even if verified.- Use for deprecating assets or temporary removal
- Frontend output:
preview: true/false
Four orthogonal states describe an asset's transfer health. Each has a distinct UX and is owned by a specific automated script (or the curator).
-
osmosis_unstable(boolean, default:false). Warning-only indicator. Does not gate the deposit or withdraw flow; surfaces an alert-circle icon on the asset cell and a localised banner on the asset info page.- Frontend output:
unstable: true - Common causes: IBC client unstable, source chain killed, sustained low liquidity/volume, manual flag set during an incident
- Companion field:
osmosis_unstable_reason(enum, see below) drives the localised banner. The existingtooltip_messagefield is reused for curator free-text.
- Frontend output:
-
osmosis_unstable_reason(enum:"ibc_client" | "source_chain_killed" | "market" | "manual"). Closed-set reason forosmosis_unstable. Each value maps to a localised string in the frontend.- Owners:
ibc_clientandsource_chain_killedare owned bycheck_ibc_clients.mjs.marketis owned bycheck_market_health.mjs.manualis the curator's escape hatch; automation never overwrites or clears it.
- Owners:
-
osmosis_disabled(boolean, default:false). Internal-deposit UX override. The native flow is skipped in favour of routing the user to an external provider (Skip, Squid, Composable, etc.). Not a kill switch; for that, use the halt flags below.- Frontend output:
disabled: true - Common reasons: an asset that is only safely transferable through a partner UI (Composable PICA, Wormhole BTC, alloyed asset originators).
- Frontend output:
-
osmosis_halt_deposits(boolean, default:false). Kill switch for the deposit direction. The asset-page Deposit button is greyed; the bridge flow renders a "deposits halted" screen with no external-provider fallback. Withdrawals remain available unlessosmosis_halt_withdrawalsis also set.- Frontend output:
haltDeposits: true - Companion field:
osmosis_deposit_halt_reasondrives the localised banner.
- Frontend output:
-
osmosis_deposit_halt_reason(enum:"bridge_down" | "extended_unstable_market" | "planned_shutdown" | "source_chain_killed" | "manual").- Owners:
bridge_downandsource_chain_killedare owned bycheck_ibc_clients.mjs.extended_unstable_marketis owned bycheck_extended_halts.mjs(which sets the flag and clears it on the 1-day recovery branch).check_market_health.mjsmay also clear anextended_unstable_markethalt as part of its market-recovery flow, but never sets it.planned_shutdownis owned bycheck_extended_halts.mjs.manualis curator-only.
- Owners:
-
osmosis_halt_withdrawals(boolean, default:false). Kill switch for the withdraw direction.- Frontend output:
haltWithdrawals: true - Companion field:
osmosis_withdrawal_halt_reason(enum:"bridge_down" | "source_chain_killed" | "manual").
- Frontend output:
-
planned_shutdown_date(string, ISO 8601 UTC, optional). Date when the asset is scheduled to be shut down. When the date is within 14 days,check_extended_halts.mjspre-emptively setsosmosis_halt_deposits=truewith reasonplanned_shutdown.
Tooltip override / curator lock. The existing tooltip_message field doubles as the override signal for automation. If any asset has a non-empty tooltip_message, no automated script will modify its halt or unstable flags (the curator has taken ownership). Use this when you want to set a halt manually with bespoke context, or when you want to prevent the automated lifecycle from clearing a flag during recovery.
Reason-vocabulary contract. Each automated script only modifies flags whose current reason value it owns (see "Owners" above). This means check_ibc_clients will never overwrite a manual halt or an extended_unstable_market halt that another script set. To release a manual override, clear tooltip_message and either set the reason back to one the relevant script owns, or remove the flag and let the script re-derive it on the next run.
transfer_methods(array) - Custom transfer configurations for assets requiring special handling.- Should be included whenever basic IBC transfer cannot carry out an interchain transfer
- Types:
external_interface(e.g., Squid Router, TFM, chain bridges),integrated_bridge,fiat_onramp - Provides alternative deposit/withdraw interfaces when native IBC is disabled or unavailable
- Example:
"transfer_methods": [ { "name": "Squid Router", "type": "external_interface", "deposit_url": "https://app.squidrouter.com/?chains=1,osmosis-1&tokens=...", "withdraw_url": "https://app.squidrouter.com/?chains=osmosis-1,1&tokens=..." } ]
-
canonical(object:{chain_name, base_denom}) - Defines assets that are Osmosis' canonical representation of an asset different than its source.- Example: Axelar's WETH is Osmosis' canonical representation of Ethereum's ETH
- Used when multiple bridge paths exist but one is preferred
-
origin(object:{chain_name, base_denom}) - Defines the original/source asset for derivative or wrapped assets.- Traces an asset back to its ultimate origin chain and denomination
- Used for liquid staking derivatives and multi-hop wrapped assets
-
is_alloyed(boolean, default:false) - Indicates the asset is an Alloyed Asset on Osmosis.- Alloyed Assets are transmuter pools that combine multiple variants of the same underlying asset into a single fungible token
- Example: allUSDT combines USDT from different bridges
- Frontend output:
isAlloyed: true/false
-
peg_mechanism(enum:"collateralized","algorithmic","hybrid") - The peg mechanism for synthetically created assets, most important for stablecoins.
-
categories(array of strings) - Categorizes assets for filtering and organization.- Standard categories:
"defi","meme","liquid_staking","stablecoin","built_on_osmosis","dweb","oracles" - Best practice: Manually define categories for better asset discovery
- Standard categories:
-
tooltip_message(string) - Custom on-hover tooltip message displayed for the asset.- Use for warnings, clarifications, or important notices to users
- Example: "This asset is NOT affiliated with the Bad Kids NFT collection."
-
listing_date_time_utc(string, ISO 8601 format) - UTC timestamp when asset was listed on Osmosis Zone.- Format:
"YYYY-MM-DDTHH:MM:SSZ" - Used for "New" badges, sorting, and tracking
- Frontend output:
listingDate: Date
- Format:
override_properties(object) - Properties that should not follow the Chain Registry and behave or appear differently on Osmosis Zone.- Available overrides:
symbol,name,logo_URIs,coingecko_id,use_asset_name,counterparty - Use when Chain Registry data doesn't match desired Osmosis display
- Available overrides:
For complete schema definitions, see zone_assets.schema.json.
{
"chain_name": "cosmoshub",
"base_denom": "uatom",
"path": "transfer/channel-0/uatom",
"osmosis_verified": true,
"categories": ["defi"],
"_comment": "Cosmos Hub $ATOM"
}Result: Verified asset with native IBC deposit/withdraw buttons enabled.
{
"chain_name": "newchain",
"base_denom": "unew",
"path": "transfer/channel-999/unew",
"osmosis_verified": false,
"_comment": "NewChain $NEW"
}Result: Visible only with "Show Unverified Assets" toggle, native IBC works.
{
"chain_name": "genesisl1",
"base_denom": "el1",
"path": "transfer/channel-253/el1",
"osmosis_verified": false,
"osmosis_unstable": true,
"osmosis_unstable_reason": "ibc_client",
"_comment": "GenesisL1 $L1"
}Result: Warning indicator (alert-circle icon) shown next to the asset symbol. Both deposit and withdraw flows still work; the frontend renders a localised banner explaining the cause. Typically auto-set by check_ibc_clients.mjs.
To enable native IBC fully: check_ibc_clients.mjs clears osmosis_unstable automatically once both IBC clients are Active again. To force-clear, remove the flag manually.
{
"chain_name": "ethereum",
"base_denom": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"path": "transfer/channel-208/uusdc",
"osmosis_verified": true,
"transfer_methods": [
{
"name": "Squid Router",
"type": "external_interface",
"deposit_url": "https://app.squidrouter.com/?chains=1,osmosis-1&tokens=...",
"withdraw_url": "https://app.squidrouter.com/?chains=osmosis-1,1&tokens=..."
}
],
"_comment": "USDC via Axelar"
}Result: Shows both native IBC and Squid Router options.
{
"chain_name": "composable",
"base_denom": "ppica",
"path": "transfer/channel-1279/ppica",
"osmosis_disabled": true,
"transfer_methods": [
{
"name": "Picasso App",
"type": "external_interface",
"depositUrl": "https://app.picasso.network/?from=PicassoKusama&to=OSMOSIS",
"withdrawUrl": "https://app.picasso.network/?from=OSMOSIS&to=PicassoKusama"
}
],
"_comment": "Picasso $PICA - use custom interface only"
}Result: Native flow is skipped; user is routed straight to the Picasso App. Both deposit and withdraw still work, just via the external provider.
{
"chain_name": "namada",
"base_denom": "unam",
"path": "transfer/channel-XXXX/unam",
"osmosis_verified": true,
"osmosis_halt_deposits": true,
"osmosis_deposit_halt_reason": "manual",
"tooltip_message": "Deposits paused pending Namada IBC v0.x release.",
"_comment": "Namada $NAM"
}Result: Deposit button greyed on every surface (asset page, portfolio, bridge). Bridge flow shows "Deposits halted" with the tooltip text. Withdrawals work normally. The manual reason + non-empty tooltip_message together lock the halt against any automation.
{
"chain_name": "examplehub",
"base_denom": "uex",
"path": "transfer/channel-XXXX/uex",
"osmosis_unstable": true,
"osmosis_unstable_reason": "manual",
"osmosis_halt_deposits": true,
"osmosis_deposit_halt_reason": "manual",
"osmosis_halt_withdrawals": true,
"osmosis_withdrawal_halt_reason": "manual",
"tooltip_message": "Exploit response, working with the team. Status: https://status.example.com",
"_comment": "Example $EX - halted"
}Result: All transfer flows blocked, banner explains the cause, automation leaves the asset alone until the curator clears the tooltip and reasons.
Question: My asset's deposit/withdraw buttons are greyed (or missing). Why?
Check the asset entry in order:
-
osmosis_halt_deposits: trueorosmosis_halt_withdrawals: true→ that direction is halted (kill switch).- Solution: clear the flag and its
*_halt_reason. Iftooltip_messageis set, clearing the reason isn't enough; also clear the tooltip, otherwise automation won't pick the asset back up. - Consider: was this auto-set by
check_ibc_clients/check_extended_halts? If so, the underlying cause needs to resolve first (bridge back up, market recovers) orcheck_market_healthclears it on the next passing run.
- Solution: clear the flag and its
-
osmosis_disabled: true→ native flow is skipped; the user is sent to an external provider. The button is not greyed in this case; it still opens the bridge flow, but the flow renders the external-provider list rather than a native quote.- Solution: remove the flag if a native path is now available.
-
osmosis_unstable: true→ warning indicator only. Buttons stay enabled. If they look greyed, check 1 first.
Question: Which flag should I use?
| Symptom | Flag(s) to set |
|---|---|
| Warn the user but allow transfers | osmosis_unstable + osmosis_unstable_reason |
| Force the user to a partner UI for this asset | osmosis_disabled |
| Block deposits, keep withdraws (e.g. broken inbound IBC, planned migration) | osmosis_halt_deposits + osmosis_deposit_halt_reason |
| Block withdraws, keep deposits (rare) | osmosis_halt_withdrawals + osmosis_withdrawal_halt_reason |
| Block both directions (incident response) | both halt flags + reasons |
Question: Will automation overwrite my manual changes?
No, as long as one of the following is true:
- The reason is set to
"manual", or tooltip_messageis non-empty.
Both serve as curator-lock signals. To hand the asset back to automation, clear the tooltip and either change the reason to one of the script-owned values or remove the flag entirely.
You typically don't need to manually add chains. The generated chainlist includes chains from two sources:
- Manually Configured Chains (~47 chains) - Chains in
osmosis.zone_chains.jsonwith custom endpoints and settings (takes precedence) - Auto-Detected Counterparty Chains (~133 chains) - Origin chains of assets listed in
osmosis.zone_assets.json, automatically detected and included from Chain Registry
The automated generation process merges these sources:
- Manual chains from
osmosis.zone_chains.jsonare used first (with your custom RPC/REST endpoints and overrides) - Auto-detected counterparty chains supplement the manual list
- Chain metadata is fetched from Chain Registry for both
- Wallet-compatible chain configuration is generated for all chains
You only need to manually configure a chain in osmosis.zone_chains.json if you want to:
- Provide custom/reliable RPC and REST endpoints
- Override default Chain Registry properties
- Add a chain before any of its assets are listed
- Configure chain-specific features or settings
To manually add or update a chain, add/modify a chain object in osmosis.zone_chains.json:
Required Fields (for manual configuration):
chain_name- Must match exactly thechain_namein the Chain Registryrpc- A reliable RPC endpoint URL for the chainrest- A reliable REST API endpoint URL for the chainexplorer_tx_url- URL template for transaction explorer (e.g.,https://www.mintscan.io/osmosis/txs/{txHash})
Optional Fields:
keplr_features- Array of feature flags for Keplr wallet (e.g.,["ibc-go", "cosmwasm"])override_properties- Override specific chain properties from Chain Registry:pretty_name- Display namestatus- Chain status (e.g., "live", "upcoming")network_type- Network type (e.g., "mainnet", "testnet")bech32_prefix- Address prefixfees- Custom fee configurationimages- Custom chain logoforce_rpc- Boolean flag to force using ONLY the zone-specified RPC endpoint (ignores Chain Registry endpoints)force_rest- Boolean flag to force using ONLY the zone-specified REST endpoint (ignores Chain Registry endpoints)
outage- Boolean flag to indicate if chain is experiencing an outage
Example Chain Object:
{
"chain_name": "cosmoshub",
"rpc": "https://rpc.cosmos.directory/cosmoshub",
"rest": "https://rest.cosmos.directory/cosmoshub",
"explorer_tx_url": "https://www.mintscan.io/cosmos/txs/{txHash}",
"keplr_features": ["ibc-go"],
"_comment": "Cosmos Hub"
}Example Chain Object with Endpoint Override:
{
"chain_name": "stride",
"rpc": "https://stride-rpc.polkachu.com/",
"rest": "https://stride-api.polkachu.com/",
"explorer_tx_url": "https://explorer.stride.zone/stride/tx/${txHash}",
"keplr_features": ["ibc-go"],
"override_properties": {
"force_rest": true
},
"_comment": "Force using only the specified REST endpoint, ignoring Chain Registry backups"
}When you specify rpc or rest endpoints in your chain configuration:
- Your zone-specified endpoint is placed first in the endpoint list
- Chain Registry endpoints are added as backups
- State-based optimization may reorder endpoints based on validation results (unless forced)
How State-Based Optimization Works:
- Validation results are tracked in
state/state.json - If a backup endpoint works better than the primary, it's automatically promoted to first position in the generated chainlist
- This enables intelligent failover without manual intervention
- Optimization happens during chainlist generation based on historical validation data
Forcing Override Endpoint Priority: To lock your specified endpoint in first position (preventing state-based reordering):
- Set
"force_rpc": trueinoverride_propertiesto lock your RPC endpoint in first position - Set
"force_rest": trueinoverride_propertiesto lock your REST endpoint in first position - Chain Registry endpoints are still included as backups, they just won't be promoted to first position.
This is useful when:
- You have a highly reliable endpoint that should always be tried first
- You want to prevent the validation algorithm from reordering your preferred endpoint
An example asset object in osmosis.zone_assets.json:
{
"base_denom": "uosmo",
"chain_name": "osmosis",
"osmosis_verified": true,
"_comment": "Osmosis $OSMO"
},
...
{
"base_denom": "ustk",
"chain_name": "steakchain",
"path": "transfer/channel-69/ustk",
"osmosis_verified": true,
"_comment": "Steak $STK"
},
{
"base_denom": "ufoocoin",
"chain_name": "fubarchain",
"path": "transfer/channel-420/ufoocoin",
"osmosis_verified": false,
"osmosis_unlisted": true,
"_comment": "Foocoin $FOO"
}
Apps, interfaces, and tools that consume data from this repository:
- Osmosis Zone app (app.osmosis.zone):
generated/frontend/assetlist.jsongenerated/frontend/chainlist.json
- Osmosis Labs' Sidecar Query Service (SQS):
generated/frontend/assetlist.json
- Numia Data Services:
generated/frontend/assetlist.jsongenerated/chain-registry/assetlist.json
External services that provide data TO this repository:
- Cosmos Chain Registry - Source of truth for all asset metadata, chain information, and IBC connections
- Numia Data Services API - Provides pool liquidity data and market depth measurements for asset verification checks (requirements #6 and #7)
This repository uses GitHub Actions workflows to automatically generate and validate files:
Scheduled Generation (Daily at 15:00 UTC):
The Generate All Files bundle workflow runs automatically and includes:
- Updates the chain-registry submodule to the latest version
- Adds chain stubs to
osmosis.zone_chains.jsonfor any newly detected chains- Creates minimal entries (chain_name + comment) for chains in
zone_assets.jsonnot yet inzone_chains.json - Makes it easy for maintainers to add custom RPC/REST endpoints later
- All fields default to Chain Registry values unless explicitly overridden
- Creates minimal entries (chain_name + comment) for chains in
- Runs the bridge-state check (
check_ibc_clients.mjs): unified detection that drives both the IBC and killed-chain branches of the lifecycle (see "Asset lifecycle automation" below). - Runs the market-health check (
check_market_health.mjs): independent unstable track driven by Numia liquidity/volume. - Runs the extended-halts check (
check_extended_halts.mjs): 60-day deposit halt and planned-shutdown halt. - Validates RPC/REST endpoints for all chains (full validation, batched 10 at a time)
- Tracks validation results in
state/state.jsonfor endpoint optimization - Reorders endpoints based on health (working backups promoted, failed endpoints deprioritized)
- Tracks validation results in
- Generates assetlist files in multiple formats
- Generates chainlist files with wallet integration metadata
- Updates asset state
- Generates comments for zone assets
- Runs localization for multi-language support
- Creates a pull request with all updates to the
update/assetlist_allbranch - Auto-merges the PR after validation passes (scheduled runs only)
Manual Workflows (Not included in bundle): Individual generation workflows can be triggered manually via GitHub Actions:
Generate Assetlist- Regenerate asset lists onlyGenerate Chainlist- Regenerate chain lists onlyGenerate CoinGecko- Update CoinGecko integration (standalone)Generate Mintscan- Update Mintscan integration (standalone)Localization- Update translations
Note on Pool Pricing: Pool-based pricing functionality (getPools.mjs) exists in the codebase but is currently disabled via the getPools = false flag in generate_assetlist.mjs. This code includes pool querying, asset pricing calculations, and routing logic. It was previously used to add pricing information to generated assetlists but is not currently active. The code remains available for future re-implementation if needed.
When an asset stops working, it moves through a single observable timeline anchored on state.lastDowntimeDate. Five automated scripts cooperate to drive that timeline, each with a well-defined scope and a non-overlapping set of "reason" enum values it owns.
| State | Frontend effect | Set by |
|---|---|---|
osmosis_unstable (warning only) |
Alert-circle icon + localised banner; both directions still work | check_ibc_clients, check_market_health, or curator |
osmosis_disabled (external-router) |
Native flow skipped; user is routed to an external provider | Curator only |
osmosis_halt_deposits (kill switch) |
Deposit button greyed everywhere; bridge flow blocked, no external fallback | check_ibc_clients, check_extended_halts, or curator |
osmosis_halt_withdrawals (kill switch) |
Withdraw button greyed everywhere; bridge flow blocked, no external fallback | check_ibc_clients or curator |
Each flag has a paired *_reason enum field. The frontend uses the reason to pick a localised banner string. The existing tooltip_message field is reused for curator free-text, and a non-empty tooltip_message locks the asset against all automation.
no flag
│
│ bridge_down detected
│ (IBC Expired/Frozen on either side, OR source chain status="killed")
▼
osmosis_unstable=true, halt_deposits=true, halt_withdrawals=true
reasons: ibc_client | source_chain_killed
state.lastDowntimeDate = <now>
│
├──── bridge_up detected (both clients Active AND chain status="live")
│ ▼
│ halt_deposits=false, halt_withdrawals=false
│ osmosis_unstable stays
│ state.lastRecoveryDate = <now>
│ │
│ │ 60 days since state.lastDowntimeDate AND market still failing
│ ▼
│ halt_deposits=true (reason: extended_unstable_market)
│ withdrawals stay open
│
│ 90 days since state.lastDowntimeDate (regardless of intervening recovery)
▼
PR opened proposing osmosis_verified=false
state.lastUnverifyProposedAt = <now> (30-day cooldown)
On merge: only osmosis_verified flips; unstable + state history kept as record.
A second, independent track exists for market-driven unstable. When a verified, non-disabled asset is post-grace (23+ days past listing) and fails the market check (liquidity < $1k && volume_24h < $100) for 7 consecutive daily runs, it is flagged with reason market. The same 60/90-day timeline applies. Recovery is single-day for the halt and 7-day for the full unstable clear; on full recovery, state history is wiped.
-
check_ibc_clients.mjs, the unified bridge-state check. Detects IBC client status and source chainstatus="killed". Owns reasonsibc_client,source_chain_killed(unstable) andbridge_down,source_chain_killed(halts). Implements the flap-vs-fresh-incident rule (within 30 days of recovery = continuation; beyond = fresh incident). Includes a "manual-flip safety net" that populatesstate.lastDowntimeDateif a curator manually setsosmosis_unstablewithout one. -
check_market_health.mjs, the market track. Owns reasonmarketfor unstable and is the only writer that fully recovers an asset from market-driven instability. Skipped for unverified, disabled, and preview assets, and for assets within the 23-day post-listing grace window. Alloyed assets are evaluated normally; constituents of an alloy inherit the alloy's volume and liquidity viamax(self, alloy)so they are not falsely flagged when their standalone Numia row reads zero but the alloy carries real activity. Constituent membership is determined from SQS pool composition (positive balance in the alloyed transmuter pool). -
check_extended_halts.mjs, the 60-day rule and planned-shutdown rule. Owns reasonsextended_unstable_marketandplanned_shutdownfor deposit halts. Pre-emptively halts deposits 14 days before aplanned_shutdown_date.
check_unverify_candidates.mjs (Mondays at 16:00 UTC, via propose_unverify.yml). Collects every verified asset that has been continuously unstable for 90+ days and hasn't had an unverify PR opened in the last 30 days. Flips osmosis_verified=false for each, writes a markdown PR body, stamps state.lastUnverifyProposedAt for cooldown, and the workflow opens or updates a PR on a fixed branch (auto-unverify/weekly-candidates). The PR requires human approval.
asset_status_report.mjs (read-only, workflow_dispatch-triggered). Produces a six-section markdown report covering unstable assets, halt status, disabled assets, verification-borderline assets, pending unverifies in cooldown, and detected invariant violations.
--dry-runflag. Every writer script accepts--dry-run, which emits a markdown report of intended mutations without writing any file. Always use this before enabling a fresh script in CI or after a chain-registry submodule bump that might flip many chains at once.- Mutation cap.
check_ibc_clients.mjsandcheck_extended_halts.mjswill not write changes touching more than 10 distinct source chains in a single run. If exceeded, the script exits with code 2 and demands a--forceflag. This catches mass-flips from upstream regressions.check_market_health.mjsis exempt: market-wide liquidity/volume swings legitimately move many chains at once, so it always applies its full diff. - Reason-vocabulary contract. Each reason enum value has exactly one owner script (or
manual= the curator). No two scripts ever race on the same flag. - Curator lock. Any non-empty
tooltip_messageon a halted or unstable asset is treated as curator-owned and never overwritten by automation. To release the lock, clear the tooltip.
For Manual Changes to Zone Configuration:
- Submit Changes: Create a PR with additions/updates to
osmosis.zone_assets.jsonorosmosis.zone_chains.json - Validation: Automated checks run to validate your changes
- Zone file validation
- Asset data validation
- Endpoint health checks (for chains)
- Review: Maintainers review the PR
- Merge: Once approved, changes are merged
- Auto-Generation: Generated files are automatically updated on the next scheduled run or manual trigger
For Automated Generation Runs:
- Scheduled Run: Workflow executes daily at 15:00 UTC
- Generation: Creates updated assetlist/chainlist files
- PR Creation: Automatically creates a PR to the
update/assetlist_allbranch with all generated changes - Validation: All validation checks must pass
- Auto-Merge: PR is automatically merged (scheduled runs only; manual triggers require manual merge)
Changes to generated files are automatically deployed to the Osmosis Zone frontend via Vercel:
Deployment Schedule:
- Scheduled: Every day at 15:30 UTC (30 minutes after generation workflow completes)
- Manual: Can be triggered manually via GitHub Actions workflow dispatch
- Fallback: Push to main (won't trigger with auto-merge due to GITHUB_TOKEN limitation)
Monitored Files:
osmosis-1/generated/frontend/assetlist.jsonandchainlist.json(mainnet)osmo-test-5/generated/frontend/assetlist.jsonandchainlist.json(testnet)
Deployment Flow:
- Generation workflow completes at 15:00 UTC (daily) and auto-merges to
main - 30 minutes later (15:30 UTC), deployment workflow runs on schedule
- Workflow checks if monitored files were modified in the last 2 hours
- If files unchanged: Deployment is skipped (no unnecessary Vercel builds)
- If files changed: Vercel webhooks are triggered (preview + production for mainnet, testnet separately)
- Vercel builds and deploys to environments
- Osmosis Zone app reflects updated data within ~30-45 minutes of generation
This completes the full pipeline: Chain Registry → Detection → Generation → PR → Merge → Scheduled Deployment → Frontend
Several validation workflows help maintain data quality:
- Validate Zone Assets - Checks asset configurations are valid and complete
- Validate Zone Chains - Verifies chain configurations and endpoint availability
- Validate Zone Data - Cross-validates data against Chain Registry
- Check Verification Criteria - Evaluates if assets meet verification requirements (check workflow logs for results)
Assets in this repository can have two verification states:
- Default state for newly added assets (
osmosis_verified: false) - Visible only when "Show Unverified Assets" toggle is enabled in Osmosis Zone
- Minimal requirements:
- Complete Chain Registry registration
- Valid zone asset configuration
- Basic asset metadata (name, symbol, logo)
Assets can be upgraded to verified status (osmosis_verified: true) after meeting comprehensive requirements. See LISTING.md for complete criteria.
Key Requirements Summary:
- Complete asset metadata including
descriptionandextended_description - Social links (website, Twitter)
- Square logo image < 250 KB
- Minimum liquidity on Osmosis (≥$1,000 in pools)
- Market depth requirements (2% depth of $50)
- Validation by Osmosis Zone maintainers
Automated Verification Checks:
The Check Verification Criteria workflow automatically evaluates assets against verification requirements. To view verification status:
- Go to the Actions tab
- Select the "Check Verification Criteria" workflow
- View the latest run logs for detailed assessment results
Upgrading to Verified:
- Ensure your asset meets all requirements in LISTING.md
- Check the verification workflow logs for your asset
- Submit a PR updating
osmosis_verifiedfromfalsetotrue - Maintainers will review against criteria before approval
Contributions are welcome! Please ensure:
- Changes follow the documented structure and requirements
- All required fields are present and valid
- References to Chain Registry data are accurate
- PRs include clear descriptions of changes
For questions or issues, please open a GitHub issue or reach out in the Osmosis Discord.