Skip to content

Add Robinhood Chain exchange rates - #123

Merged
j0ntz merged 1 commit into
masterfrom
jon/robinhood-chain
Aug 28, 2026
Merged

Add Robinhood Chain exchange rates#123
j0ntz merged 1 commit into
masterfrom
jon/robinhood-chain

Conversation

@j0ntz

@j0ntz j0ntz commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Technical Design Document

robinhood-chain.md

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Description

Asana task

Robinhood Chain assets have no exchange rate, so every fiat figure for them renders $0 in the app: wallet list, wallet scene, send confirm and swap quote. On the exchange scene the zero destination value also trips a "High Price Impact" warning, which reads to users as a broken or predatory quote on an otherwise correct swap.

The cause is that the v3 API keys on {pluginId, tokenId}, not on currency code. Robinhood Chain's native asset is ETH, but the robinhood pluginId was never registered, so no provider could resolve it. Reproduced against production before the change, on the hosts the app actually calls (RATES_SERVERS in edge-react-gui src/util/network.ts):

POST https://rates3.edge.app/v3/rates
{"crypto":[{"asset":{"pluginId":"robinhood","tokenId":null}},
           {"asset":{"pluginId":"ethereum","tokenId":null}}], ...}

{"asset":{"pluginId":"robinhood"}}                      <- no rate field
{"asset":{"pluginId":"ethereum"},"rate":1875.95}

rates1, rates2 and rates4 all behave identically.

What this registers

Map Value Effect
coingeckoMainnetCurrencyMapping ethereum native ETH prices off ETH
coingeckoPlatformIdMapping robinhood maps this chain's tokens
coinmarketcapMainnetCurrencyMapping 1027 ETH, same id arbitrum/base/optimism/zksync use
coinmarketcapPlatformIdMapping null CMC has no platform id for this chain yet
defaultTokenTypes evm contract addresses become tokenIds
defaultPlatformPriority 630 ranks last, so bridged assets resolve to their canonical chain
defaultCrossChainMapping 3 entries USDC, USDT and WBTC price off their Ethereum counterparts

CoinGecko lists this chain as platform robinhood (chain_identifier: 4663, native_coin_id: ethereum) with 534 coins on it, so its tokens map automatically. It carries no Robinhood Chain address for the canonical usd-coin, tether or wrapped-bitcoin coins, which is why those three need explicit cross-chain entries. WETH and USDG need none: CoinGecko does list those here, so the daily sweep maps them on its own.

Deploying this: one part is automatic, one part is not

templates in a DatabaseSetup are written only when the document does not yet exist, so on an existing deployment they are inert. That splits this change in two.

Automatic. The native ETH rate needs only the mainnet maps, and the daily tokenMapping engine rewrites <provider>:automated as {...existingDoc, ...uidMappingFromTheCodeConstant}, with the code constant spread last. Deploying this branch fixes the reported $0 bug on the next engine run with no manual step.

Needs a one-time write to the production rates_settings database. The token rates do not self-propagate, because the platform, token-type, priority and cross-chain docs are template-only and already exist. Their values are exactly the ones in this diff:

tokenTypes.robinhood            = "evm"
platformPriority.robinhood      = 630
coingecko:platforms.robinhood   = "robinhood"
crosschain.robinhood_6bac06600d220ac5ac281ad1f504d2cf0f90f6e6 = {"sourceChain":"robinhood","destChain":"ethereum","currencyCode":"WBTC","tokenId":"2260fac5e5542a773aa44fbcfedf7c193bc2c599"}
crosschain.robinhood_80e0e24718dbfcad49ecaa6f1e6c89a190586ca8 = {"sourceChain":"robinhood","destChain":"ethereum","currencyCode":"USDC","tokenId":"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"}
crosschain.robinhood_e246bc49b0598d7cd9f0ead48b885034f1254380 = {"sourceChain":"robinhood","destChain":"ethereum","currencyCode":"USDT","tokenId":"dac17f958d2ee523a2206206994597c13d831ec7"}

That asymmetry is worth fixing separately: the mainnet maps are read from the code constant every sweep, while the platform, token-type and priority docs are read only from CouchDB, so a newly added chain never reaches production on its own. Making the sweep merge the code defaults underneath the DB docs ({...codeDefault, ...dbDoc}) would remove this manual step for every future chain. Deliberately left out here because it changes shared merge semantics for every chain and provider, which does not belong in a PR that registers one chain.

Testing

Verified against a local instance of this server (local CouchDB and Redis, real provider code path, no code modified for the test).

  1. Reproduced production. Seeded the databases, then stripped robinhood out of all eight documents so the local DB matched an existing deployment. The patched server still returned no rate, confirming the DB document wins over the code default at runtime and that a deploy alone is not sufficient.
  2. Confirmed the automatic half. Ran the tokenMapping engine once, as its daily loop does. coingecko:automated gained robinhood: {id: "ethereum"}, while coingecko:platforms, tokenTypes and platformPriority stayed empty, exactly as the template semantics predict. The native rate then resolved at 1878.73, matching ethereum at 1878.73 to the cent.
  3. Confirmed the cross-chain remap in isolation. Seeded sentinel rates in constantrates on the Ethereum token keys only (USDC 111.111, USDT 222.222, WBTC 333.333) and queried the Robinhood Chain token ids. Each returned its sentinel, which is reachable only through the remap. An unmapped Robinhood Chain address returned no rate, confirming this is not a blanket fallthrough.
  4. Confirmed real pricing for every shipped asset. With the documents applied and the sentinels removed, all six assets from the robinhood currency plugin priced off live market data:
robinhood ETH native  1877.38     (ethereum: 1877.38)
robinhood USDC        0.999518
robinhood USDT        0.999076
robinhood USDG        0.999788
robinhood WBTC        63149
robinhood WETH        1876.8

yarn prepare and yarn test (56 passing) both pass, and verify-repo.sh --base origin/master passed.


Note

Medium Risk
Changes core rate-resolution mappings for a new chain; production token pricing depends on correct CouchDB docs plus cross-chain remaps, but scope is limited to configuration defaults with no auth or payment logic.

Overview
Registers Robinhood Chain (robinhood) so v3 rates resolve for native ETH and EVM tokens instead of returning no rate and showing $0 fiat in the app.

Provider maps: CoinGecko treats native ETH like Ethereum (ethereum / platform robinhood); CoinMarketCap uses ETH id 1027 with no platform id yet.

Edge rates defaults: robinhood is classified as EVM, given platform priority 630 (last) so bridged assets prefer canonical-chain pricing, and three cross-chain entries remap Robinhood USDC, USDT, and WBTC to their Ethereum token ids where CoinGecko has no on-chain addresses.

Deploy note: Native ETH can pick up from code on the next automated mainnet sweep; token type, platform priority, platform doc, and cross-chain rows may still need a one-time update in production rates_settings because existing CouchDB templates do not overwrite those documents.

CHANGELOG entry added under Unreleased.

Reviewed by Cursor Bugbot for commit c65ac1c. Bugbot is set up for automated code reviews on this repo. Configure here.

@j0ntz

j0ntz commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

📸 Test evidence: Robinhood Chain wallets priced in-app against a local instance of this branch

robinhood wallets priced

robinhood wallets priced

Captured by the agent's in-app test run (build-and-test).

Register the robinhood pluginId across the v3 provider maps so its assets
resolve a rate. The v3 API keys on {pluginId, tokenId}, so an ETH-native
chain still priced at zero until the pluginId itself was registered.

Native ETH prices off ethereum on both CoinGecko and CoinMarketCap.
CoinGecko lists this chain as platform 'robinhood' (chain_identifier 4663),
which maps its tokens, but it carries no address for the canonical USDC,
USDT and WBTC coins, so those three bridge to their Ethereum counterparts
through the cross-chain map. WETH and USDG need no entry: CoinGecko does
list those here, so the daily sweep maps them on its own.

CoinMarketCap has no platform id for this chain yet, so token lookups
there stay null and fall through to CoinGecko.
@j0ntz
j0ntz marked this pull request as ready for review August 13, 2026 18:23
@j0ntz
j0ntz force-pushed the jon/robinhood-chain branch from 25a2243 to c65ac1c Compare August 13, 2026 18:23
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@j0ntz
j0ntz merged commit 428499a into master Aug 28, 2026
3 checks passed
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.

2 participants