From c1357090118cd867da3a89a2b4dc9d03e6c1783b Mon Sep 17 00:00:00 2001 From: greatest0fallt1me <1nonlygem@gmail.com> Date: Tue, 30 Jun 2026 01:01:08 +0530 Subject: [PATCH] feat: Add a live cost-and-yield estimator panel to CreateCommitmentStepConfigure Adds CostYieldEstimator component that reactively computes projected yield range, worst-case penalty, and platform fee from protocol constants as the user adjusts amount, duration, and max-loss inputs (debounced 300ms). Includes tests and accessibility attributes (aria-live, aria-label). Co-Authored-By: Claude Sonnet 4.6 --- docs/COST_YIELD_ESTIMATOR.md | 62 +++++++ .../CreateCommitmentStepConfigure.tsx | 9 + .../create/CostYieldEstimator.test.tsx | 165 ++++++++++++++++++ src/components/create/CostYieldEstimator.tsx | 137 +++++++++++++++ 4 files changed, 373 insertions(+) create mode 100644 docs/COST_YIELD_ESTIMATOR.md create mode 100644 src/components/create/CostYieldEstimator.test.tsx create mode 100644 src/components/create/CostYieldEstimator.tsx diff --git a/docs/COST_YIELD_ESTIMATOR.md b/docs/COST_YIELD_ESTIMATOR.md new file mode 100644 index 00000000..920862ce --- /dev/null +++ b/docs/COST_YIELD_ESTIMATOR.md @@ -0,0 +1,62 @@ +# Cost and Yield Estimator + +Live estimator panel in `CreateCommitmentStepConfigure` that shows projected yield range and worst-case penalty as the user adjusts commitment parameters. + +## Overview + +The `CostYieldEstimator` component reacts to changes in `amount`, `durationDays`, `maxLossPercent`, and `asset`, debounces updates (300 ms), and displays three key figures: + +- **Projected Yield (est.)** — low-to-high range based on protocol APY heuristics and duration. +- **Worst-case Penalty (est.)** — maximum early-exit penalty derived from protocol constants. +- **Platform Fee (est.)** — platform fee percentage applied to the committed amount. + +All figures are labeled as estimates and sourced from `/api/protocol/constants` (see `src/utils/protocol.ts`) rather than hardcoded values. + +## Props / API + +```ts +interface CostYieldEstimatorProps { + amount: string | number // commitment amount + durationDays: number // commitment duration in days (1–365) + maxLossPercent: number // maximum acceptable loss percent (0–100) + asset: string // asset ticker shown in labels (e.g. "XLM", "USDC") +} +``` + +## Usage + +```tsx +import CostYieldEstimator from '@/components/create/CostYieldEstimator' + + +``` + +The component is already integrated into `CreateCommitmentStepConfigure.tsx` between the `AllocationConstraintsEditor` and the Advanced Risk Parameters section. + +## Accessibility + +- The section has `aria-label="Cost and yield estimator"` and `aria-live="polite"` so screen readers announce value changes without interrupting the user. +- All estimate rows use `
/
/
` semantics for term/value pairing. +- A placeholder paragraph is shown (and announced) when inputs are invalid or constants are loading. + +## Edge Cases + +| Scenario | Behaviour | +|---|---| +| `amount` is empty or zero | Placeholder shown | +| `durationDays < 1` | Placeholder shown | +| Protocol constants fetch fails | Placeholder shown; no error thrown | +| `penalties` array is empty | Falls back to `maxLossPercent` for worst-case | + +## Related + +- `src/components/create/CostYieldEstimator.tsx` — component implementation +- `src/components/create/CostYieldEstimator.test.tsx` — tests +- `src/utils/protocol.ts` — `fetchProtocolConstants` helper +- `src/app/api/protocol/constants/route.ts` — constants API endpoint +- `docs/ALLOCATION_CONSTRAINTS_EDITOR.md` — sibling panel diff --git a/src/components/CreateCommitmentStepConfigure.tsx b/src/components/CreateCommitmentStepConfigure.tsx index 203c2ca1..50758b10 100644 --- a/src/components/CreateCommitmentStepConfigure.tsx +++ b/src/components/CreateCommitmentStepConfigure.tsx @@ -3,6 +3,7 @@ import React, { useState, useRef, useEffect } from 'react' import WizardStepper from './WizardStepper' import AllocationConstraintsEditor from './create/AllocationConstraintsEditor' +import CostYieldEstimator from './create/CostYieldEstimator' import styles from './CreateCommitmentStepConfigure.module.css' import GlossaryTerm from './GlossaryTerm' @@ -349,6 +350,14 @@ export default function CreateCommitmentStepConfigure({ onChangeMaxLoss={onChangeMaxLoss} /> + {/* Live Cost and Yield Estimator */} + + {/* Advanced Risk Settings */}