Skip to content

Price & token sources: The Forge as a built-in token index - #898

Open
awizardxch wants to merge 5 commits into
xch-dev:mainfrom
awizardxch:feat/forge-token-source
Open

awizardxch wants to merge 5 commits into
xch-dev:mainfrom
awizardxch:feat/forge-token-source

Conversation

@awizardxch

@awizardxch awizardxch commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Depends on #897 (Price & token sources). Review that one first; this PR is the single commit on top of it.

Problem

Many CATs trade only in AMM pools, with no order book on Dexie. Dexie has no last_price for them, so Sage values them at $0. The liquidity tokens those pools mint aren't registered with Dexie, so Sage shows them as "Unknown CAT". After #897 a user can fix this by adding a token index by hand, but that requires knowing that an index exists and pasting its URL.

Change

The Forge (forge.awizard.dev, an AMM for Chia CATs) becomes a built-in source in the Price & Token Sources list, beside Dexie and CoinGecko:

Source Provides Default
Dexie CAT prices; names and icons (saved in the wallet) On, first
CoinGecko XCH/USD rate On, second
The Forge CAT prices from its AMM pools (with liquidity), names, tickers and icons for Forge-traded CATs and Forge LP tokens On, third

Because it comes after Dexie and CoinGecko, it only fills what they lack. A CAT that Dexie prices keeps Dexie's price, and the XCH/USD rate stays CoinGecko's. The Forge's names, tickers and icons are display-only suggestions for what a token lacks, under the same rules as any token index in #897. They never replace a value the wallet has and are never written to it. The user can turn The Forge off or move it like any other source.

It reads the same token index format (version 1) as a custom source, at a URL that depends on the network:

  • mainnet: https://forge.awizard.dev/token-index/v1/mainnet.json
  • testnet11: https://forge.awizard.dev/token-index/v1/testnet11.json

A source list saved before this source existed gains it in the same place, after Dexie and CoinGecko, switched on.

The diff is one source entry in src/lib/priceSources.ts (name, homepage, a URL per network) and its tests in src/lib/priceSources.test.ts. The Settings row, fetching, validation and priority all come from #897.

Why on by default

This adds a default host, which is a fair thing to question, so here is the reasoning:

  • Cost to the user: one GET per minute, on the price refresh Sage already runs. No key, no cookie, no wallet data and no query string: the URL is the same for every user. The response is about 11 KB (31 CATs today).
  • Cost to the host: the index is served from Vercel's edge with Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=86400, so wallets' polls are answered by the CDN (X-Vercel-Cache: HIT after the first call), not by the Forge's servers. CORS is *.
  • Failure is silent: if the host is down, slow or returns something invalid, the fetch fails on its own. Sage keeps the last good copy (or nothing) and shows what it shows today. Dexie and CoinGecko are never affected.
  • It only fills gaps: being third means it can't change a value Sage shows today. It only adds values where Sage currently shows $0 or "Unknown CAT".

If maintainers would rather not add a default host, it's a one-line change (enabledByDefault: false). The Forge would then still be listed, ready to switch on, without making a request until the user does. Happy to switch it.

How to test

  1. pnpm test:unit (src/lib/priceSources.test.ts), pnpm lint, pnpm tsc -b.
  2. Fresh profile: Settings → Network → Price & Token Sources lists Dexie, CoinGecko and The Forge, all on, in that order. The network tab shows one GET to forge.awizard.dev/token-index/v1/mainnet.json per refresh (testnet11.json on testnet), beside the Dexie and CoinGecko requests.
  3. Hold a CAT that trades on the Forge but has no Dexie price: it now has a USD value. Hold a CAT that Dexie prices: its price is unchanged.
  4. Hold a Forge LP token: it shows as "FLP - …" with the Forge icon instead of "Unknown CAT". Rename it: your name is shown.
  5. Turn The Forge off: its request stops, and those values and suggestions disappear.
  6. With a source list saved from Price & token sources: list, order and extend where Sage reads prices #897 (for example, a custom index added), update to this branch: The Forge appears after Dexie and CoinGecko and before the custom index.
  7. Block forge.awizard.dev (or go offline): Sage shows what it shows without the source, with only a console warning.

🤖 Generated with Claude Code

awizardxch and others added 2 commits October 17, 2026 01:10
A new Settings > Network > Price & Token Sources section lists the sources
Sage already uses, with what each provides and a switch: Dexie (CAT prices;
its names and icons are saved by the wallet's own sync) and CoinGecko (the
XCH/USD rate). The user can add custom token indexes (one https JSON document,
version 1, listing CATs with a name, ticker, https icon and price in XCH) and
reorder all sources with up/down buttons.

For each value, the first enabled source that has it wins and later sources
only fill gaps: a CAT's price in XCH, the XCH/USD rate, and a display-only
label for a CAT with no name. Index labels never replace a name the wallet
has (from the user, Dexie or chia_updateCat) and are never written to it.
Indexes are fetched on the existing 60-second price refresh, validated
(version, network, text bounds matching chia_updateCat, https icons, finite
positive prices), and a failed fetch keeps the last good copy.

Nothing is stored until the user changes the list, and the defaults (Dexie
then CoinGecko, both on, no custom sources) make exactly the requests Sage
made before. The single tokenIndexUrl key from an earlier build of this
branch is read once into the list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@awizardxch

awizardxch commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor Author

A note on the red checks: the two iOS jobs and Android fail at the signing step, because GitHub doesn't pass this repo's signing secrets to a PR from a fork. The iOS log shows APPLE_CERTIFICATE empty and xcodebuild: error: The flag -authenticationKeyID is required when specifying -authenticationKeyPath; the Android log writes an empty keyAlias, password and keystore.jks. Every job that builds or tests the code passes: Tests, Linux x64 and ARM, Windows x64 and ARM, macOS and Validate package.

…oken page

A token the wallet already named (for example through chia_updateCat) kept
"CAT" and no icon, because a suggestion was made only for a token with no
name. Each of name, ticker and icon is now suggested where the token has
none, and an existing value is still never replaced. The token page's card
also shows the suggested ticker and icon; its edit dialog keeps starting
from, and saving, the wallet's own record.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@awizardxch
awizardxch force-pushed the feat/forge-token-source branch from 80230e3 to 15ff63d Compare October 17, 2026 19:04
awizardxch and others added 2 commits October 17, 2026 12:05
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds The Forge (forge.awizard.dev) to the built-in sources, on by default
and placed after Dexie and CoinGecko, so it only fills what they lack: AMM
prices for CATs Dexie has no price for, and display-only names and icons for
Forge-traded CATs and Forge LP tokens that have no name. Its index is the
same token index format (version 1), one keyless, CDN-cached GET per refresh,
at token-index/v1/mainnet.json or testnet11.json by network. A list saved
before this source existed gains it in the same place, after Dexie and
CoinGecko.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@awizardxch
awizardxch force-pushed the feat/forge-token-source branch from 15ff63d to 59845ea Compare October 17, 2026 19:06

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant