Skip to content

Add Robinhood Chain swap support - #483

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

Add Robinhood Chain swap support#483
j0ntz merged 1 commit into
masterfrom
jon/robinhood-chain

Conversation

@j0ntz

@j0ntz j0ntz commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

Companion PRs for the same chain (this PR is independent of both and passes CI standalone):

Description

Maps the robinhood plugin id (Robinhood Chain, EVM chain 4663) onto each swap provider's own chain code, so quotes can route to and from the chain. No engine or plugin logic changes: lifi.ts, rango.ts and the central plugins all gate on a non-null MAINNET_CODE_TRANSCRIPTION lookup, so a chain the map does not know is invisible to the provider no matter what its API supports.

robinhood is added to src/util/edgeCurrencyPluginIds.ts via mapctl add-plugin; the six provider entries are authored in scripts/mappings/*Mappings.ts and the src/mappings/*.ts files are regenerated with npm run mapctl update-mappings.

Two of those generated files are hand-added here rather than regenerated. updateMappings in scripts/mapctl.ts iterates the synchronizer list, and changelly has a mapping file but no synchronizer while nexchange is hand-maintained with no source file at all, so the generator can never write either one. Both were missing exactly the robinhood key against every sibling, which docs/CHAIN_MAPPING_SYNCHRONIZERS.md says must be an explicit null so a later maintainer can tell a deliberate exclusion from a missed one. Making the sweep iterate the authored mapping files instead is left as follow-up work.

Provider Chain code Why
SideShift robinhood /v2/pair/btc-bitcoin/eth-robinhood and /v2/pair/eth-arbitrum/eth-robinhood both quote, in both directions
LI.FI out /v1/quote routes cross-chain into 4663. The key really is the string out, which is what /v1/chains returns for this chain
Rango ROBINHOOD Chain enabled with 495 tokens; quotes via Relay and GasZip
ChangeNow hood Native ETH, USDG, CASHCAT and tokenized equities. The native-ETH pair was inactive when first mapped and fills now
Swapuz ROBINHOOD Native ETH, USDG, CASHCAT, PONS, PIPEDOG. rate/ quotes 0.05 ETH into 0.04940 ETH on the chain, min 0.03402
LetsExchange ROBINHOOD CASHCAT and ARROW listed, no native ETH. info quotes 0.1 ETH into 1154.42 CASHCAT, min 0.06

Two providers are mapped without a fillable native-ETH pair at the time of mapping, on the same reasoning: the map is chain-level while fill availability is per-pair and dynamic. changenow.ts rebuilds chainCodeTickerMap hourly from exchange/currencies?active=true filtered to the chain codes the map knows, so an unmapped chain could never appear even once a pair activates. ChangeNow proved the point: the pair it was mapped ahead of fills today with no further change. LetsExchange is the same bet on tokens rather than gas, and costs a declined quote meanwhile, since checkWhitelistedMainnetCodes raises a plain SwapCurrencyError for a pair the provider cannot serve.

Every provider in the repo was probed against its own live discovery endpoint, not against documentation. ChangeHero, Exolix, Godex and n.exchange carry nothing on this chain and stay null. SwapKit's chain code appeared in an earlier sweep but is absent from its keyed provider list. Changelly and Xgram could not be probed: Changelly's API is request-signed, and the available Xgram key returns 401.

Two providers advertise the chain but are deliberately left unmapped: LetsExchange carries only CASHCAT and ARROW there (no native ETH, so it cannot deliver gas), and SwapKit's HOOD code turns up in the provider sweep with no tradeable asset behind it.

Testing

npm run test (56 passing), tsc, and verify-repo.sh all pass.

Exercised end to end on the iOS simulator with this branch served into the app, which is what the mapping is for. An exchange of 529.16 S from My Sonic to a Robinhood Chain wallet quoted 0.006243 ETH "Powered by LI.FI" and executed to the success scene; eth_getBalance for the receiving address then returned 6248511112300593 wei and the wallet rendered 0.006248511112300593 ETH.

That balance unblocked the send that the chain integration could not previously test: 0.001 ETH sent from the funded wallet is transaction 0x70e4950b5991c9419eff70ea2478c7ae55c5c58adcc3da237d5889394f8fdf62, success in block 35308086.

The route was pinned to LI.FI/Rango for the test by disabling competitors locally, because SideShift is geo-blocked from this host's egress; its mapping is verified against its live pair endpoint instead.

One unrelated gap this surfaced: Edge's rates server has no entry for robinhood, so ETH on the chain prices at $0 everywhere, and on the exchange scene that zero destination value trips the "High Price Impact" banner. Cosmetic, fixed where rates are configured rather than here.

Design doc: src/docs/robinhood-chain.md, section 7.

Asana: https://app.asana.com/0/1215088146871429/1217382370104887


Note

Low Risk
Additive mapping data verified against live provider APIs; mis-mapping would mainly affect quote availability rather than altering existing swap execution paths.

Overview
Adds robinhood as an Edge currency plugin id and wires Robinhood Chain (EVM 4663) into swap routing through chain-code mappings only—no quote or engine logic changes. Providers only see a chain when their src/mappings/*.ts entry is non-null.

Enabled on six partners with each provider’s own identifier: SideShift (robinhood), LI.FI (out), Rango (ROBINHOOD), ChangeNow (hood), Swapuz (ROBINHOOD), and LetsExchange (ROBINHOOD). Authoritative entries live in scripts/mappings/*Mappings.ts; most src/mappings/*.ts files are regenerated, with changelly and nexchange updated by hand to set robinhoodnull like the other unsupported providers.

Every other swap partner in the repo gets an explicit robinhoodnull mapping so the chain stays invisible where APIs do not support it. CHANGELOG records Robinhood Chain swaps via those six integrations.

Reviewed by Cursor Bugbot for commit 876a757. 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: swap into Robinhood Chain, then send

lifi quote into robinhood

lifi quote into robinhood

swap executed

swap executed

hood wallet funded

hood wallet funded

send composed

send composed

send success

send success

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

@j0ntz
j0ntz force-pushed the jon/robinhood-chain branch from 37d5a13 to de63cfe Compare August 13, 2026 10:21
@j0ntz
j0ntz marked this pull request as ready for review August 13, 2026 10:21
@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 force-pushed the jon/robinhood-chain branch 2 times, most recently from 05bee10 to 703f05f Compare August 28, 2026 08:16
Map the robinhood plugin id to each provider's chain code so quotes can
route to and from the chain. Every provider in the repo was probed against
its own live discovery endpoint; six carry the chain:

  SideShift    'robinhood'   native ETH and bridged WETH
  LI.FI        'out'         cross-chain into 4663
  Rango        'ROBINHOOD'   chain enabled, tokens indexed
  ChangeNow    'hood'        native ETH, USDG, CASHCAT, tokenized stocks
  Swapuz       'ROBINHOOD'   native ETH, USDG, CASHCAT, PONS, PIPEDOG
  LetsExchange 'ROBINHOOD'   CASHCAT and ARROW only, no native ETH

ChangeNow's native-ETH pair was inactive when the chain was first mapped
and now fills. LetsExchange is mapped despite carrying no native ETH: the
map is chain-level while fill availability is per-pair and dynamic, and
`chainCodeTickerMap` is built from the live API filtered to mapped chain
codes, so an unmapped chain can never surface its tokens at all.

Godex, Exolix, n.exchange and ChangeHero were probed and carry nothing on
this chain, so they stay null. Changelly and Xgram could not be probed.
@j0ntz
j0ntz force-pushed the jon/robinhood-chain branch from 703f05f to 876a757 Compare August 28, 2026 23:01
@j0ntz
j0ntz enabled auto-merge August 28, 2026 23:01
@j0ntz
j0ntz merged commit d5861b9 into master Aug 28, 2026
4 checks passed

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 876a757. Configure here.

'qtum',
'ravencoin',
'ripple',
'robinhood',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swapter omits robinhood mapping

Low Severity

Adding robinhood to the plugin-id list updated every generated map and the hand-maintained changelly and nexchange files, but src/mappings/swapter.ts still jumps from ripple to rsk. That full matrix is supposed to carry an explicit null for a checked-unsupported chain so a later maintainer can tell a deliberate skip from a missed one.

Fix in Cursor Fix in Web

Triggered by project rule: Bugbot Review Rules

Reviewed by Cursor Bugbot for commit 876a757. Configure here.

j0ntz added a commit that referenced this pull request Aug 28, 2026
Reverts the #483 merge (d5861b9) so 2.54.0 publishes the LI.FI slippage
change on its own. Robinhood re-lands by reverting this commit.

Also restores the 'added: Swapter swap provider' entry to the 2.53.0
section, which #483 had moved up into Unreleased even though 2.53.0 is
the version that shipped it.
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