Add BTC Direct fiat buy provider#6037
Conversation
Integrate BTC Direct as a fiat on-ramp using their Unified Checkout REST API: partner-authenticate, fetch prices, then mint a single-use checkout URL that opens in a webview for payment-method selection. Supports EUR buys for EU/EEA regions across credit card, iDEAL, and SEPA.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 5b3e2f7. Configure here.
| }, | ||
| title: lstrings.fiat_plugin_buy_complete_title, | ||
| message | ||
| }) |
There was a problem hiding this comment.
Cancel treated as successful buy
High Severity
The checkout returnUrl always includes transactionStatus=success, and the deeplink handler never inspects redirect outcome before calling trackConversion('Buy_Success') and the purchase-complete modal. BTC Direct redirects to the same returnUrl after cancel as well as success, so cancelled checkouts can be recorded and shown as completed buys.
Reviewed by Cursor Bugbot for commit 5b3e2f7. Configure here.
| XLM: { pluginId: 'stellar', currencyCode: 'XLM' }, | ||
| TRX: { pluginId: 'tron', currencyCode: 'TRX' }, | ||
| AVAX: { pluginId: 'avalanche', currencyCode: 'AVAX' }, | ||
| POL: { pluginId: 'polygon', currencyCode: 'POL' }, |
There was a problem hiding this comment.
Polygon native asset mapping wrong
Medium Severity
The POL entry maps to Edge polygon with currencyCode: 'POL', but Polygon’s native currency in Edge is MATIC. getTokenId only treats the wallet’s native code as native, so getEdgeAsset drops POL-EUR pairs and Polygon never appears in supported buy assets despite being in the BTC Direct price map.
Reviewed by Cursor Bugbot for commit 5b3e2f7. Configure here.


Description
Integrate BTC Direct as a fiat on-ramp (buy) provider, following the existing
FiatProviderFactorypattern (modeled onrevolutProvider).BTC Direct exposes a v2 "Unified Checkout" REST API. The flow:
POST /api/v1/authenticate) for a 1-hour JWT.GET /api/v2/prices) to build the supported-asset list and estimate quotes.checkoutUrl(POST /api/v2/buy/checkout) and open it in a webview where the user selects a payment method and pays.Scope:
src/plugins/gui/util/fetchBtcDirect.ts(authenticate + token caching, prices, checkout, with cleaners).src/plugins/gui/providers/btcdirectProvider.tsregistered inamountQuotePlugin.ts.btcdirectcredentials wired intoPLUGIN_API_KEYS(envConfig.ts):{ username, password, sandbox? }.Not in scope (follow-ups):
/api/v1/authenticatewith ER038), not partner credentials, so the live checkout could not be exercised yet.btcdirecttofiatPluginPriorityin edge-info-server once partner credentials are in place (a deliberate go-live step, like revolut).btcdirect.pngpartner icon upload to the content server.Asana: https://app.asana.com/0/1215088146871429/1215776835822919
CHANGELOG
Does this branch warrant an entry to the CHANGELOG?
Dependencies
none
Requirements
If you have made any visual changes to the GUI. Make sure you have:
No user-visible change in this build: the provider is only instantiated when
PLUGIN_API_KEYS.btcdirectis configured, which it is not yet (no partner credentials). Verified statically withtsc --noEmit, eslint, and the jest suite (398 tests pass). The live payment-method webview cannot be exercised until partner credentials are provisioned.Note
Medium Risk
New third-party payment checkout and credential handling in the buy flow; limited blast radius until keys and info-server priority enable it for users.
Overview
Adds BTC Direct as a fiat buy provider using their Unified Checkout REST API (partner JWT auth, cached prices, hosted
checkoutUrlin a webview withreturn.edge.appdeeplink conversion tracking).New pieces:
fetchBtcDirect.ts(authenticate,/api/v2/prices,/api/v2/buy/checkout),btcdirectProvider.tsimplementingFiatProviderFactory, optionalPLUGIN_API_KEYS.btcdirectinenvConfig.ts, and registration inamountQuotePlugin.ts. EUR-only buys for EU/EEA with credit card, iDEAL, and SEPA; quotes are fiat-amount estimates from live buy prices; native chain assets only (no ERC-20 tokens until contract mapping exists).Provider only loads when API keys are configured; go-live also needs
btcdirecton info-serverfiatPluginPriorityand the partner icon asset (called out in the PR description).Reviewed by Cursor Bugbot for commit 5b3e2f7. Bugbot is set up for automated code reviews on this repo. Configure here.