Feature/multi peg frontend#96
Conversation
…ils and UI settings
…r dynamic labeling and improved maintainability
WalkthroughReplaced many hardcoded UI strings with values sourced from a new centralized Changes
Sequence Diagram(s)sequenceDiagram
participant UI as Frontend Components
participant CFG as protocolConfig
participant SW as ReactorSwap
participant RH as Reactor Helpers (fusion/fission/transmutation)
participant STORE as Wallet/Server Storage
rect `#DFF3E3`
UI->>CFG: read labels, tickers, hero/seo text
CFG-->>UI: provide dynamic strings
end
rect `#F6F6FF`
UI->>SW: user swap input (neutron/proton amounts)
SW->>RH: calculate & validate (neutron/proton)
RH-->>SW: ReceiptDetails { outputAmount: {neutron,proton}, ... }
SW->>STORE: captureWalletState (maps neutron→gau, proton→gauc for storage)
STORE-->>SW: ack
SW-->>UI: render receipts and messages (neutron/proton)
end
(Note: colors highlight config-read phase and swap calculation flow.) Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
src/lib/config/protocol.ts (1)
59-76: Consider using template literals for full configurability.The mechanics action descriptions contain hardcoded token symbols (
$GAU,$GAUC,$ERG) instead of using the dynamic config values. This limits the reusability goal of the config when switching to different protocol deployments.If you want full flexibility, consider refactoring to use template literals or a function that interpolates token tickers from the config. However, this adds complexity and may not be necessary if these descriptions are protocol-specific rather than deployment-specific.
src/lib/components/layout/SEO.tsx (1)
21-21: Consider making the site name check configurable.The
siteTitlelogic hardcodes "Gluon" in the check. For full protocol flexibility, this could be extracted to the config (e.g.,protocolConfig.seo.siteName).This is a minor concern and can be addressed if/when supporting multiple protocol brands becomes necessary.
src/lib/components/blocks/home/Features.tsx (1)
189-195: Consider removing hardcoded index logic from line break rendering.The conditional double breaks
idx === 1 || idx === 3tightly couple the UI layout to the specific structure of the current config array. If the config changes (e.g., lines reordered, items added/removed), this logic won't adapt correctly.Consider one of these alternatives:
Option 1: Add an optional spacing indicator to the config itself:
// In protocol.ts overviewBody: [ { text: "Get exposure to Gold with GAU.", spacing: "single" }, { text: "GAU is the stablecoin pegged to 1g of Gold.", spacing: "double" }, // ... ]Option 2: Remove the conditional logic and rely on consistent spacing:
-{protocolConfig.ui.mechanics.overviewBody.map((line, idx) => ( - <span key={idx}> +{protocolConfig.ui.mechanics.overviewBody.map((line) => ( + <span key={line}> {line} <br /> - {idx === 1 || idx === 3 ? <br /> : null} </span> ))}Option 3: Use CSS classes for spacing instead of hardcoded breaks.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
src/lib/components/blocks/dashboard/GluonStats.tsx(4 hunks)src/lib/components/blocks/dashboard/MyStats.tsx(2 hunks)src/lib/components/blocks/home/Features.tsx(3 hunks)src/lib/components/blocks/home/Hero.tsx(2 hunks)src/lib/components/layout/BottomNavbar.tsx(2 hunks)src/lib/components/layout/SEO.tsx(2 hunks)src/lib/components/layout/TopNavbar.tsx(2 hunks)src/lib/components/ui/hero-text.tsx(1 hunks)src/lib/config/protocol.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (8)
src/lib/components/layout/BottomNavbar.tsx (1)
src/lib/config/protocol.ts (1)
protocolConfig(1-79)
src/lib/components/ui/hero-text.tsx (1)
src/lib/config/protocol.ts (1)
protocolConfig(1-79)
src/lib/components/blocks/home/Features.tsx (1)
src/lib/config/protocol.ts (1)
protocolConfig(1-79)
src/lib/components/blocks/dashboard/MyStats.tsx (1)
src/lib/config/protocol.ts (1)
protocolConfig(1-79)
src/lib/components/layout/SEO.tsx (1)
src/lib/config/protocol.ts (1)
protocolConfig(1-79)
src/lib/components/layout/TopNavbar.tsx (1)
src/lib/config/protocol.ts (1)
protocolConfig(1-79)
src/lib/components/blocks/dashboard/GluonStats.tsx (1)
src/lib/config/protocol.ts (1)
protocolConfig(1-79)
src/lib/components/blocks/home/Hero.tsx (1)
src/lib/config/protocol.ts (1)
protocolConfig(1-79)
🔇 Additional comments (11)
src/lib/components/layout/TopNavbar.tsx (1)
12-12: LGTM!The navbar title is now properly driven by the centralized config, enabling easy customization for different protocol deployments.
Also applies to: 58-58
src/lib/components/layout/SEO.tsx (1)
14-20: LGTM!SEO defaults are now properly centralized, making it easy to customize metadata for different protocol deployments.
src/lib/components/blocks/home/Hero.tsx (1)
5-5: LGTM!Hero text is now driven by the centralized config, enabling easy customization of the main landing page messaging.
Also applies to: 25-27
src/lib/components/layout/BottomNavbar.tsx (1)
8-8: LGTM!The Telegram link is now dynamically constructed from the config, allowing easy customization for different protocol deployments.
Also applies to: 24-24
src/lib/components/ui/hero-text.tsx (1)
7-10: Dynamic hero text integration looks good.The implementation correctly uses
protocolConfig.peg.adjectivein the rotating titles. Note that there's a potential casing inconsistency with this value flagged inprotocol.tsline 4.The empty dependency array is appropriate since
protocolConfigis a constant withas constassertion.src/lib/components/blocks/dashboard/MyStats.tsx (1)
15-15: LGTM!The token display labels are now dynamically driven by the config, using the neutron/proton abstraction correctly. This enables easy customization for different protocol deployments while maintaining the current Gold/GAU/GAUC semantics.
Also applies to: 201-203, 208-210
src/lib/components/blocks/dashboard/GluonStats.tsx (1)
15-15: LGTM!The stats dashboard is now fully driven by the centralized config across all metrics, labels, and token references. This comprehensive refactoring properly abstracts Gold/GAU/GAUC specifics while preserving current deployment semantics.
Also applies to: 295-320, 335-346, 351-357, 421-421
src/lib/components/blocks/home/Features.tsx (4)
11-11: LGTM: Config import.The import of
protocolConfigcorrectly enables data-driven content throughout this component.
181-181: LGTM: Dynamic overview title.Successfully replaced hardcoded title with config-driven value.
200-237: LGTM: Actions successfully migrated to config-driven approach.All four action items (Fission, Fusion, Transmute To/From Gold) now properly source their titles and descriptions from
protocolConfig.ui.mechanics.actions, maintaining functionality while achieving the PR's goal of eliminating hardcoded strings.
245-251: LGTM: TokenFlow titles now config-driven.All TokenFlow components correctly use titles from
protocolConfig.ui.mechanics.actions, successfully replacing hardcoded strings with dynamic values. The token identifiers ("ERG","GAU","GAUC") remain hardcoded as technical constants, which is appropriate for this protocol-specific logic.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
src/lib/components/layout/SEO.tsx (1)
14-18: UsingprotocolConfig.seofor default props keeps SEO metadata consistentWiring the destructured defaults to
protocolConfig.seois correct and keepstitle,description,keywords,image, andurlin sync with the centralized config. This should make future peg deployments easier to rebrand without touching this component.If you ever need protocol-specific per-route titles, consider exposing small helpers (e.g.,
buildPageTitle(pageTitle)in the config layer) so theGluonsuffix rule is shared rather than hardcoded here.src/lib/components/blocks/dashboard/GluonStats.tsx (1)
385-387: Activity and supply labels now config‑driven; consider extending to remaining GAU/GAUC stringsThe 14d volume captions and supply labels now use
protocolConfig.tokens.*.tickerandprotocolConfig.ui.labels.*SupplyLabel, which aligns well with the multi‑peg goal and current neutron/proton abstractions.Optionally, to fully decouple copy from GAU/GAUC, you might later move the remaining hard‑coded GAU/GAUC mentions in tooltips (e.g., ratio and leverage descriptions) into
protocolConfig.uias well.Also applies to: 393-395, 401-402, 407-408
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/lib/components/blocks/dashboard/GluonStats.tsx(4 hunks)src/lib/components/layout/SEO.tsx(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/lib/components/blocks/dashboard/GluonStats.tsx (2)
src/lib/config/protocol.ts (1)
protocolConfig(1-79)src/lib/utils/erg-converter.ts (2)
nanoErgsToErgs(133-135)convertFromDecimals(30-33)
src/lib/components/layout/SEO.tsx (1)
src/lib/config/protocol.ts (1)
protocolConfig(1-79)
🔇 Additional comments (3)
src/lib/components/layout/SEO.tsx (1)
2-2: Centralizing SEO defaults viaprotocolConfigimport is aligned with the new config modelImporting
protocolConfighere cleanly makes SEO a consumer of the shared config, which helps avoid drift between SEO metadata and the rest of the UI copy. No issues spotted.src/lib/components/blocks/dashboard/GluonStats.tsx (2)
15-15: protocolConfig import wiring looks correctImport path and usage of
protocolConfigin this component are consistent with the new centralized config; no issues here.
318-325: Neutron/Proton price tiles correctly wired to protocolConfigBoth token tiles now pull tickers and subtitles from
protocolConfig, while still binding tostats.gauPrice/stats.gaucPrice. This keeps semantics for the current GAU/GAUC deployment while making labels config‑driven.Looks good as‑is.
Also applies to: 327-334
…ization for consistency
…onsistency across components
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (7)
src/lib/functions/reactor/handleTransmutation.ts (1)
33-42: Inconsistent indentation in early return block.The return statement body (lines 34-41) is not properly indented relative to the
ifblock. While this doesn't affect functionality, it reduces readability.if (numValue <= 0) { - return { - error: "Amount must be greater than zero.", - resetValues: { - neutronAmount: "0", - protonAmount: "0", - toAmount: "0", - }, - }; + return { + error: "Amount must be greater than zero.", + resetValues: { + neutronAmount: "0", + protonAmount: "0", + toAmount: "0", + }, + }; }src/lib/components/blocks/dashboard/GluonStats.tsx (1)
346-352: Tooltip text still contains hardcoded "GAU"/"GAUC" references.While card titles and labels use
protocolConfig, the tooltip explanations at lines 346, 352, and 505 still reference hardcoded "GAU"/"GAUC". For full config-driven consistency, consider usingprotocolConfig.tokens.neutron.tickerandprotocolConfig.tokens.proton.tickerin these tooltips as well.- <div className="text-sm text-muted-foreground">{renderTooltip("GAU Reserve Allocation", "Percentage of the reserve that is currently backing GAUs. The price of GAU is this reserve portion divided by the GAU supply.")}</div> + <div className="text-sm text-muted-foreground">{renderTooltip(`${protocolConfig.tokens.neutron.ticker} Reserve Allocation`, `Percentage of the reserve that is currently backing ${protocolConfig.tokens.neutron.ticker}s. The price of ${protocolConfig.tokens.neutron.ticker} is this reserve portion divided by the ${protocolConfig.tokens.neutron.ticker} supply.`)}</div>src/lib/components/blockchain/swap/ReactorSwap.tsx (2)
1147-1149: Hardcoded ticker strings in GAU/GAUC card badges.While line 1471 uses
protocolConfig.tokens.neutron.tickerandprotocolConfig.tokens.proton.ticker, the badge text inrenderGauGaucCardstill hardcodes "GAU" and "GAUC". For consistency with the config-driven approach, consider using protocolConfig here as well.<motion.div className="flex items-center gap-1.5 rounded-md bg-yellow-800/60 px-3 py-1.5 text-sm font-bold text-white dark:bg-yellow-900/60" whileHover={{ scale: 1.05 }} transition={{ duration: 0.1 }} > - GAU + {protocolConfig.tokens.neutron.ticker} </motion.div>Also applies to: 1182-1184
1584-1585: Hardcoded ticker strings in receipt "You Will Receive" section.These lines hardcode "GAU" and "GAUC" while line 1471 uses
protocolConfigfor the same purpose. For consistency:- <div>{formatTokenAmount(formatValue(receiptDetails.outputAmount.neutron))} GAU</div> - <div>{formatTokenAmount(formatValue(receiptDetails.outputAmount.proton))} GAUC</div> + <div>{formatTokenAmount(formatValue(receiptDetails.outputAmount.neutron))} {protocolConfig.tokens.neutron.ticker}</div> + <div>{formatTokenAmount(formatValue(receiptDetails.outputAmount.proton))} {protocolConfig.tokens.proton.ticker}</div>src/lib/functions/reactor/handleFusion.ts (3)
15-53: Minor clean‑up: avoid double‑wrapping bigint values fromconvertToDecimals
convertToDecimalsalready returns abigint, so wrapping its result inBigInt(...)is redundant:const neutronAmount = convertToDecimals(neutronBalance); const protonAmount = convertToDecimals(protonBalance);This keeps the types clearer without changing behavior, since all math here is already in
bigint.
56-117: Fusion amount calculation aligns with updated neutron/proton types; consider precision andinputAmountsemanticsThe neutron/proton rename is correctly propagated here:
calculateFusionAmountsnow:
- Calls
calculateMaxErgOutputwith neutron/proton balances.- Maps
neutrons/protonsfrom the SDK torequiredNeutron/requiredProtonviaconvertFromDecimals.- Returns
neutronAmount/protonAmountand fillsresetValues.neutronAmount/resetValues.protonAmountin line with the updatedSwapResult/SwapErrorandReceiptDetailsshapes fromtypes.ts.Two small points to double‑check:
Precision in
ReceiptDetails:
You currently do:inputAmount: parseFloat(requiredNeutron), outputAmount: { neutron: parseFloat(requiredNeutron), proton: parseFloat(requiredProton), erg: parseFloat(value), },Since
convertFromDecimalsreturns aBigNumber, converting to string and thenparseFloatconstrains you to JS number precision. If downstream UI/logic ever needs exact token amounts (especially for large values or many decimals), consider keeping these asBigNumberinstances instead of floats.
inputAmountmeaning:
inputAmountis now derived fromrequiredNeutronwhile the user‑specified field here isvalue(ERG). Make sure this matches howReceiptDetails.inputAmountis interpreted in the UI and other swap flows (e.g., that components don’t assume it always equals the user‑entered amount).If both are intentional and the consumers expect numbers, this implementation is fine as‑is.
175-189: Align GAU/GAUC‑style local names with neutron/proton terminology for clarityIn
handleFusionSwap, the verification/logging block still uses GAU‑style names:const requiredGau = convertFromDecimals(BigInt(neutrons)).toString(); const requiredGauc = convertFromDecimals(BigInt(protons)).toString(); tokensToBeConsumed: { rawNeutrons: neutrons.toString(), rawProtons: protons.toString(), displayGau: requiredGau, displayGauc: requiredGauc, }For consistency with the rest of this refactor, consider renaming these to neutron/proton equivalents (e.g.,
requiredNeutron,requiredProton,displayNeutron,displayProton). This keeps logs and local variables aligned with the new public types and should make future multi‑peg maintenance easier.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
src/lib/components/blockchain/swap/ReactorSwap.tsx(22 hunks)src/lib/components/blocks/dashboard/GluonStats.tsx(5 hunks)src/lib/components/blocks/home/Features.tsx(4 hunks)src/lib/config/protocol.ts(1 hunks)src/lib/functions/reactor/handleFission.ts(4 hunks)src/lib/functions/reactor/handleFusion.ts(6 hunks)src/lib/functions/reactor/handleTransmutation.ts(4 hunks)src/lib/functions/reactor/types.ts(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- src/lib/config/protocol.ts
- src/lib/components/blocks/home/Features.tsx
🧰 Additional context used
🧬 Code graph analysis (4)
src/lib/functions/reactor/handleFission.ts (1)
src/lib/utils/erg-converter.ts (2)
formatMicroNumber(89-114)convertFromDecimals(30-33)
src/lib/functions/reactor/handleFusion.ts (2)
src/lib/utils/erg-converter.ts (2)
convertToDecimals(40-47)convertFromDecimals(30-33)src/lib/functions/reactor/types.ts (3)
SwapResult(48-54)SwapError(56-63)ReceiptDetails(20-35)
src/lib/components/blockchain/swap/ReactorSwap.tsx (5)
src/lib/utils/transaction-listener.ts (2)
WalletState(19-25)ExpectedChanges(28-33)src/lib/constants/token.ts (1)
TOKEN_ADDRESS(1-5)src/lib/utils/erg-converter.ts (1)
convertToDecimals(40-47)src/lib/functions/reactor/handleFusion.ts (1)
calculateFusionAmounts(58-117)src/lib/config/protocol.ts (1)
protocolConfig(1-51)
src/lib/components/blocks/dashboard/GluonStats.tsx (3)
src/lib/config/protocol.ts (1)
protocolConfig(1-51)src/lib/components/ui/skeleton.tsx (1)
Skeleton(7-7)src/lib/utils/erg-converter.ts (2)
nanoErgsToErgs(133-135)convertFromDecimals(30-33)
🔇 Additional comments (10)
src/lib/functions/reactor/types.ts (1)
22-25: Type renaming from gau/gauc to neutron/proton is consistent and well-structured.The interface updates properly abstract the token roles (neutron = stable, proton = volatile) while preserving the protocol-level identifiers (
TokenSymbol,SwapAction) that still reference GAU/GAUC. This layered approach correctly separates the abstract role concept from the concrete deployment tokens.Also applies to: 48-54, 56-62
src/lib/functions/reactor/handleTransmutation.ts (1)
103-132: Transmutation output mapping is correctly preserved with new nomenclature.The logic correctly maps:
fromTokenSymbol === "GAUC"→ outputs toneutron(GAU)fromTokenSymbol === "GAU"→ outputs toproton(GAUC)This maintains the existing behavior while adopting the new abstract naming.
src/lib/components/blocks/dashboard/GluonStats.tsx (2)
306-331: Config-driven stat cards are well-implemented.The integration of
protocolConfigfor dynamic titles, subtitles, and token tickers properly abstracts the deployment-specific values. This enables future multi-peg deployments without code changes.
460-471: Past review issues addressed: BigNumber coercion and label disambiguation.The code now correctly uses
Number(stats.reserveRatio)for arithmetic and the label "Reserve-Implied {ticker} Leverage" clearly distinguishes this from the "GAUC Leverage" card below, addressing the duplicate semantics concern from the previous review.src/lib/functions/reactor/handleFission.ts (2)
36-44: Helpful inline documentation clarifying token roles.The comment at line 36 clearly documents the mapping: "neutrons are the stable token (GAU), protons are the leveraged token (GAUC)". This aids maintainability when working with the abstraction layer.
50-72: Fission calculation return values correctly updated to new nomenclature.The
ReceiptDetails.outputAmountandSwapResultfields properly useneutron/protonnaming, consistent with the updated types intypes.ts.src/lib/components/blockchain/swap/ReactorSwap.tsx (3)
112-113: State variables appropriately renamed to neutron/proton.The state naming aligns with the abstract token roles while the underlying logic remains unchanged.
150-163: Well-documented bridge between internal naming and external interface.The comments at lines 150 and 166 clearly explain that
WalletStateandExpectedChangesstill usegau/gauckeys for backward compatibility withtransaction-listener.ts. The mapping logic correctly translates between the internalneutron/protonnaming and the external interface.Also applies to: 166-205
1197-1254: Swap validation logic correctly updated with neutron/proton naming.The
isSwapDisabledfunction properly uses the renamed variables (neutronRequired,protonRequired,neutronBalance,protonBalance,neutronInput,protonInput) while maintaining the correct validation logic for each swap type.src/lib/functions/reactor/handleFusion.ts (1)
6-12: FusionParams neutron/proton balances look consistent with downstream usageThe rename to
neutronBalance/protonBalanceis wired correctly intocalculateFusionAmountsandcalculateMaxErgOutputvia destructuring and parameter passing; no functional issues here from what’s visible in this file. Just ensure any external call sites constructingFusionParamshave been updated to provide the new properties.
| labels: { | ||
| navbarTitle: "GLUON GOLD", | ||
| telegramHandle: "GluonGold", | ||
| assetPriceTitle: "1 kg of Gold", |
There was a problem hiding this comment.
This line and line 44 seem to be using a text from an old version. See https://gluon.gold to see the text that we are using now.
| {isLoading ? <Skeleton className="mx-auto h-8 w-16" /> : hasError ? "—" : convertFromDecimals(protocolMetrics.circulatingSupply.neutrons).toFixed(2)} | ||
| </div> | ||
| <div className="text-sm text-muted-foreground">GAU Supply</div> | ||
| <div className="text-sm text-muted-foreground">{protocolConfig.ui.labels.neutronSupplyLabel}</div> |
There was a problem hiding this comment.
Here we could use the neutron ticker from config and then " Supply". Then we wouldn't need to define neutronSupplyLabel.
| {isLoading ? <Skeleton className="mx-auto h-8 w-16" /> : hasError ? "—" : convertFromDecimals(protocolMetrics.circulatingSupply.protons).toFixed(2)} | ||
| </div> | ||
| <div className="text-sm text-muted-foreground">GAUC Supply</div> | ||
| <div className="text-sm text-muted-foreground">{protocolConfig.ui.labels.protonSupplyLabel}</div> |
There was a problem hiding this comment.
Here too, for protons.
| > | ||
| <div className="mb-1 text-4xl font-bold text-foreground">{hasError ? "—" : stats.priceCrashCushion ? Math.round(+stats.priceCrashCushion) : "—" }%</div> | ||
| <div className="text-sm font-medium text-muted-foreground">{renderTooltip("Price Crash Cushion", "Maximum drop in the price of ERG w.r.t. Gold that can be tolerated for GAU to remain pegged to Gold. When 0%, GAU depegs to prevent bank runs and maintain non-zero GAUC price.")}</div> | ||
| <div className="text-4xl font-bold text-foreground mb-1"> |
There was a problem hiding this comment.
It seems that, in this code block, some recent changes that iIhad committed are being erased.
Are you sure that you are working on the latest version of the main branch? Remember to always pull and synchronize your branch.
| icon: Maximize2, | ||
| title: "Fission", | ||
| description: "Splits $ERG tokens into $GAU stable tokeons and $GAUC volatile tokeons", | ||
| description: "Split ERG into the stable and leveraged tokens of the Gluon protocol.", |
There was a problem hiding this comment.
Can we use the ticker symbols from config?
| assetPriceSubtitle: "Oracle Gold Price", | ||
| neutronSubtitle: "Gold Pegged Token", | ||
| protonSubtitle: "Leveraged Yield Token", | ||
| neutronSupplyLabel: "GAU Supply", |
There was a problem hiding this comment.
See my other comment. Lines 47 adn 48 can be removed.
protocolConfig.Summary by CodeRabbit
Refactor
New
✏️ Tip: You can customize this high-level summary in your review settings.