Parent PRD
#98
What to build
The first vertical slice of the fee display overhaul. Cuts end-to-end (pure function → hook → UI) but only covers the validator-dex path. HIP-3 markets will display whatever the validator branch produces and will remain temporarily incorrect until Slice 2 lands.
End-to-end behavior on validator markets (BTC, ETH, SOL, etc.):
- The current
Est. Fee and Builder Fee rows in the trade summary are replaced with a single Fee row showing the effective percentage and dollar amount. The label is underline-dotted to signal the tooltip affordance.
- Hovering (desktop) or tapping (mobile) the row opens a tooltip with: exchange fee (taker / maker), builder fee with a one-line hint ("Supports interface development"), and a total row.
- When the wallet is disconnected, the Fee row is hidden entirely.
- When
userFees has not yet resolved, the row renders a skeleton.
- A new pure function
computeEffectiveFee encapsulates fee math. In this slice only the validator branch is implemented (effective = userRate).
useFeeRates is rewritten to accept a UnifiedMarket and compose computeEffectiveFee with live API data (userFees). It returns null when disconnected or still loading.
- The hardcoded
ORDER_FEE_RATE_* constants are deleted from config/constants.ts.
getOrderMetrics is updated to accept { exchangeRate, builderBps } and return { exchangeFee, builderFee, totalFee } alongside the existing fields.
- Unit tests cover
computeEffectiveFee for: validator no-discount, validator with discount, spot validator, zero rate edge case, string-precision cases.
Reference the parent PRD's Implementation Decisions and Testing Decisions sections for details on module shape and test conventions.
Acceptance criteria
Blocked by
None — can start immediately.
User stories addressed
Reference by number from the parent PRD:
- User story 1
- User story 5
- User story 6
- User story 7
- User story 8
- User story 9
- User story 10
- User story 11
- User story 12
- User story 15
- User story 18
- User story 19
- User story 20
Parent PRD
#98
What to build
The first vertical slice of the fee display overhaul. Cuts end-to-end (pure function → hook → UI) but only covers the validator-dex path. HIP-3 markets will display whatever the validator branch produces and will remain temporarily incorrect until Slice 2 lands.
End-to-end behavior on validator markets (BTC, ETH, SOL, etc.):
Est. FeeandBuilder Feerows in the trade summary are replaced with a singleFeerow showing the effective percentage and dollar amount. The label is underline-dotted to signal the tooltip affordance.userFeeshas not yet resolved, the row renders a skeleton.computeEffectiveFeeencapsulates fee math. In this slice only the validator branch is implemented (effective = userRate).useFeeRatesis rewritten to accept aUnifiedMarketand composecomputeEffectiveFeewith live API data (userFees). It returnsnullwhen disconnected or still loading.ORDER_FEE_RATE_*constants are deleted fromconfig/constants.ts.getOrderMetricsis updated to accept{ exchangeRate, builderBps }and return{ exchangeFee, builderFee, totalFee }alongside the existing fields.computeEffectiveFeefor: validator no-discount, validator with discount, spot validator, zero rate edge case, string-precision cases.Reference the parent PRD's Implementation Decisions and Testing Decisions sections for details on module shape and test conventions.
Acceptance criteria
Feerow renders on validator markets showing the user's effective rate (% and $).userFeesis loading.computeEffectiveFeepure function exists with the shape described in the PRD; validator branch returnsuserRateunchanged.useFeeRates(market)returnsnullwhen disconnected or data is loading; returns the full rate shape otherwise.ORDER_FEE_RATE_*constants are removed fromconfig/constants.tswith no dangling imports.getOrderMetricssignature and return shape match the PRD.computeEffectiveFeecover all cases listed above; all tests pass.Blocked by
None — can start immediately.
User stories addressed
Reference by number from the parent PRD: