Add HoudiniSwap swap plugin#469
Open
j0ntz wants to merge 1 commit into
Open
Conversation
- Privacy-routed CEX swaps via Houdini's v2 partner API: forward quotes take private (multi-exchange) routes only; reverse quotes price by the receive amount (amountType=receive, fixed-rate), which Houdini's private routing does not serve today, so they fall back to standard fixed-rate routes that still settle through Houdini. - Swap-to-address destinations: synthetic destination wallets skip the typed-address lookup and may carry destination memos, forwarded as destinationTag on order creation (memo chains XRP/XLM/ATOM/HBAR/TON/ RUNE are mapped; IBC-family chains stay unmapped until Houdini's metadata firms up). - Falls through to the next-best route when a fixed-rate route's static deposit address is held by another live order (409). - Max quotes via getMaxSwappable; zcash destinations use transparent addresses; requests ride Edge's CORS proxy (the partner API rejects browser-origin calls). - Mocha acceptance suite with disk-cached fixtures replays offline and stays inside the partner API budget.
Contributor
Author
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


CHANGELOG
Does this branch warrant an entry to the CHANGELOG?
Dependencies
none (compiles against published edge-core-js; the synthetic-destination interplay is runtime-only and guarded)
Description
Asana task
HoudiniSwap swap plugin: privacy-routed CEX swaps via Houdini's v2 partner API (
initOptions: { apiKey, apiSecret }, auth headerapiKey:apiSecret, requests forced through Edge's CORS proxy because the partner API rejects browser-origin calls from the core WebView).Behavior:
quoteFor: 'to') map toGET /quotes?amountType=receive&fixed=true. The API only prices exact-out on fixed-rate quotes, and its private routing does not serve exact-out today (verified live: exact-out returns standard routes only, across pairs). So reverse quotes fall back to standard fixed-rate routes, which still settle through Houdini (the recipient never sees the sender's address) but use a single exchange leg. Private routes remain preferred whenever the API offers them. Alternates considered: rejecting reverse quotes entirely (breaks the flip-input guarantee semantics the product spec requires), or emulating exact-out by inverting a forward quote (loses the receive-side guarantee).synthetic://) skips the typed-address lookup (addressTypeMap) since it holds exactly one pasted, caller-validated address, and may expose destination memos via agetMemosmethod (detected at runtime through a local guarded type, so this package keeps compiling against published edge-core-js). The memo is forwarded asdestinationTagon order creation. Memo chains XRP/XLM/ATOM/HBAR/TON/RUNE are mapped; IBC-family chains (coreum/osmosis/axelar) stay unmapped because Houdini reports nomemoNeededflag and a permissive^.*$address validation for them.STATIC_DEPOSIT_IN_USE, hit live during testing); order creation falls through to the next-best in-range route.min/max) are from-side, reverse limits (minOut/maxOut) receive-side; a reverse quote must also clear the route's from-side bounds with its own pricedamountIn(the API enforces this at order creation, verified live). API-level errors with a human-readablemessage(e.g. "Amount is too low, minimum is 25 USD") surface as that message instead of raw JSON.getMaxSwappable; zcash destinations use transparent addresses (ChangeNow'saddressTypeMapprecedent).Testing: mocha acceptance suite (
test/houdini.test.ts) runs in the normalnpm test(unlike the earlier out-of-suite harness) with disk-cached fixtures that replay offline within the partner API budget: forward BTC→ETH and ETH→USDC private swaps, a reverse BTC→ETH swap priced by the receive amount, and a synthetic memo-chain destination (ETH→XRP) asserting the entered destination tag reaches the create-exchange body. All fixtures recorded against the live API.tsc, eslint, and the full suite pass. In-app: live quotes through this plugin were exercised on the iOS sim via the Stealth Send UI (quote retrieval verified; order execution hit the shared dev key's free-tier 10-exchanges/day cap, with the tag-bearing order creation covered by the live-recorded fixture test).Note
Medium Risk
New third-party swap path that resolves quotes, converts API float amounts to native units, and submits payout/refund addresses and memos; mistakes could mis-route funds, though behavior is covered by cached acceptance tests and mirrors other central plugins.
Overview
Adds a new HoudiniSwap central swap provider wired into the plugin registry (
houdini), backed by Houdini’s v2 partner API withapiKey/apiSecretand always-on CORS proxy so calls work from the core WebView.The plugin quotes and creates exchanges end-to-end: it resolves Houdini token IDs per chain, prefers private routes on forward swaps, and supports reverse pricing (
quoteFor: 'to') viaamountType=receivewith fixed-rate routes when private exact-out isn’t available. It maps Edge assets throughsrc/mappings/houdini.ts, handles min/max (including reverseminOut/maxOutand pricedamountIn), retries order creation on 409STATIC_DEPOSIT_IN_USE, and builds deposit spends with optional deposit memos.Swap-to-address synthetic destinations (
synthetic://) skip typed address lookup and forward the first destination memo asdestinationTagon order creation (e.g. XRP). Zcash uses transparent payout addresses.Coverage is added via
test/houdini.test.tswith disk-cachedtest/houdiniFixtures/(forward BTC→ETH, ETH→USDC, reverse BTC→ETH, ETH→XRP with destination tag), plusHOUDINI_INITin test config and a CHANGELOG unreleased entry.Reviewed by Cursor Bugbot for commit a17062d. Bugbot is set up for automated code reviews on this repo. Configure here.