feat: Implement FiatStrategy submit flow with order polling and relay execution#8347
feat: Implement FiatStrategy submit flow with order polling and relay execution#8347
FiatStrategy submit flow with order polling and relay execution#8347Conversation
| /** Order identifier - `orderCode` specifically used as RampsService:getOrder parameter in normalized format (/providers/{provider}/orders/{id}). */ | ||
| orderCode?: string; |
There was a problem hiding this comment.
Originally we talked Ramps team to add metadata into fiat orders and also filtering mechanism.
Due to limitation of timeframe this may not be option to deliver besides headless ramp, hence we are adding orderCode (meaning order id) into TransactionFiatPayment
There was a problem hiding this comment.
Minor, orderId or rampsId to be more generic?
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
| .filter((singleRequest) => { | ||
| const hasTargetMinimum = singleRequest.targetAmountMinimum !== '0'; | ||
| const isPostQuote = Boolean(singleRequest.isPostQuote); | ||
| const isExactInputRequest = | ||
| Boolean(singleRequest.isMaxAmount) && | ||
| new BigNumber(singleRequest.sourceTokenAmount).gt(0); | ||
|
|
||
| return hasTargetMinimum || isPostQuote || isExactInputRequest; | ||
| }) |
There was a problem hiding this comment.
The fiat re-quote request could get dropped by this filter if targetAmountMinimum happened to be '0' - it's not a post-quote, so the second condition wouldn't save it. The isExactInputRequest check distinguishes real exact-input requests (positive source amount + max amount flag) from empty gas fee token requests (zero source amount), ensuring the fiat re-quote passes through.
FiatStrategy submit flow with order polling and relay execution
|
|
||
| const log = createModuleLogger(projectLogger, 'fiat-submit'); | ||
|
|
||
| const ORDER_POLL_INTERVAL_MS = 1000; |
There was a problem hiding this comment.
Minor, I added feature flags for this on Relay, could extend for fiat in future.
| throw new Error('Missing wallet address for fiat submission'); | ||
| } | ||
|
|
||
| const state = messenger.call('TransactionPayController:getState'); |
There was a problem hiding this comment.
Minor, should this be in the request to make it more "pure"?
|
|
||
| while (true) { | ||
| const order = await messenger.call( | ||
| 'RampsController:getOrder', |
There was a problem hiding this comment.
To clarify, does this trigger a network request in the RampsController?
Would it be more efficient if they owned the polling and we listened to a messenger event like RampsController:quoteStatusChange or RampsController:stateChange if it's updated in state?
| const expectedChainId = expectedAssetId.split('/')[0]; | ||
| const orderChainId = orderCrypto?.chainId?.toLowerCase(); | ||
|
|
||
| if (orderAssetId && orderAssetId !== expectedAssetId) { |
There was a problem hiding this comment.
Oh we already have an order ID? Is this generated by the provider or Ramps?
| transactionId, | ||
| }); | ||
|
|
||
| const relayQuotes = await getRelayQuotes({ |
There was a problem hiding this comment.
Do we need to validate the final quote to check the fees are within our original slippage compared to what we showed the user?
Or is that a separate PR?
| /** Order identifier - `orderCode` specifically used as RampsService:getOrder parameter in normalized format (/providers/{provider}/orders/{id}). */ | ||
| orderCode?: string; |
There was a problem hiding this comment.
Minor, orderId or rampsId to be more generic?

Explanation
Implements
FiatStrategysubmit flow with order polling and relay execution.submitFiatQuotesto poll the on-ramp order viaRampsController:getOrderuntil completion, then re-quote and submit the relay leg with the settled crypto amountorderCodefield toTransactionFiatPaymentandRampsControllerGetOrderActiontoAllowedActionsto enable order polling from the fiat strategyReferences
Checklist
Note
Medium Risk
Touches quote submission logic that controls on-ramp order handling and subsequent Relay execution, so mistakes could block fiat-funded flows or submit with incorrect amounts. The change is well-guarded with validation, timeouts, and broad unit test coverage, lowering regression risk.
Overview
Implements the
FiatStrategysubmit flow:submitFiatQuotesnow reads a storedorderCode, pollsRampsController:getOrderuntil the order completes (or fails/times out), validates the completed order’s asset/chain and amount, then re-quotes Relay with the settled exact-input amount and submits viasubmitRelayQuotes.Updates Relay quote request filtering to also keep exact-input max-amount requests (non-zero
sourceTokenAmount) so the fiat re-quote path isn’t dropped, extends controller types/state to includeTransactionFiatPayment.orderCodeand permitRampsController:getOrder, and adds comprehensive unit tests covering success and fail-closed error cases.Written by Cursor Bugbot for commit d149b0f. This will update automatically on new commits. Configure here.