Skip to content

Fix black-and-white design-system violations and consolidate Stellar-address validation - #330

Merged
Jaydbrown merged 5 commits into
conduit-protocol:mainfrom
prodbycorne:fix/issues-310-311-312-327
Aug 26, 2026
Merged

Fix black-and-white design-system violations and consolidate Stellar-address validation#330
Jaydbrown merged 5 commits into
conduit-protocol:mainfrom
prodbycorne:fix/issues-310-311-312-327

Conversation

@prodbycorne

Copy link
Copy Markdown
Contributor

Summary

Closes #310
Closes #311
Closes #312
Closes #327

Test plan

  • npx tsc --noEmit clean
  • npx next build — compiles, lints, and generates all pages successfully
  • npx vitest run — 20 failed / 323 passed, identical to the pre-existing baseline on main (verified via git stash diff before/after; both pre-existing failures are an unrelated localStorage-in-jsdom setup issue); no new failures or regressions

…ss regexes into lib/stellar-address.ts

The same address-format check was reimplemented independently in
app/create/page.tsx, components/stream/BulkWithdrawButton.tsx,
lib/token-allowance-gateway.ts, and app/profile/page.tsx -- each a
regex checking only length and a loose character class, not the
version byte or CRC16 checksum. app/profile/page.tsx's copy accepted
a G-or-A-prefixed address; A is not a valid Stellar StrKey version
byte at all (valid are G, C, M, S, T) -- currently unreachable since
Freighter always returns a G-address, but exactly the kind of
copy-paste bug this consolidation exists to prevent from spreading
further.

Added lib/stellar-address.ts wrapping @stellar/stellar-sdk's StrKey
(per CONTRIBUTING.md's own reviewer checklist) with
isValidStellarPublicKey/isValidStellarContract/isValidStellarAddress,
and migrated all four call sites -- preserving each site's existing
accepted prefix set (G-only, C-only, or G-or-C) except profile's,
which is now correctly G-only. TokenSelector.tsx's copy is already
tracked separately in conduit-protocol#224 and left untouched.

Test fixtures in BulkWithdrawButton.test.tsx and
app/create/__tests__/page.test.tsx used placeholder addresses
(e.g. `G` + `'A'.repeat(55)`) that satisfied the old length-only regex
but fail StrKey's real checksum validation -- replaced with
genuinely valid generated addresses.
… the black-and-white design system

.badge-paused used bg-yellow-50/text-yellow-800 and .badge-cancelled
used bg-red-50/text-red-700 -- both explicitly prohibited hues per
CONTRIBUTING.md, and neither covered by the text-only green/red delta
exception. Badge is rendered on every StreamCard across /streams,
/dashboard, and the stream detail page, so status was effectively
signaled by yellow-vs-red-vs-gray color alone.

components/ui/README.md (the Badge component's own docs) already
specified the correct target -- border-gray-400/text-gray-400 for
paused, border-gray-200/text-gray-300/line-through for cancelled --
but the actual CSS never matched it. Brought the CSS in line with the
documented spec, with reasonable dark-mode gray equivalents.
…ls in app/transactions/page.tsx

STATUS_CLASS used bg-green-50/bg-red-50 for Success/Failed pills --
bg- classes aren't covered by CONTRIBUTING.md's text-only delta
exception at all. The demo-data and disconnected-wallet banners used
amber/blue, neither in the exception list. The duplicated (mobile +
desktop) amountColor logic used text-yellow-500 for withdrawals, also
outside the exception, and neither the green nor red branches carried
an aria-label.

Converted STATUS_CLASS to gray shades (the visible "Success"/
"Pending"/"Failed" text already carries the distinction; added
line-through to Failed as an extra non-color cue) and both banners to
gray. amountColor's yellow branch is now red-600 (a withdrawal is a
negative delta, which red-600 is meant for) and the cancelled branch
-- not really a directional delta -- is now black instead of red;
positive/negative branches now carry aria-label="increase"/"decrease".
…exception hue colors

Sweep across the remaining flagged spots:
- StreamCard.tsx / BatchStreamCreator.tsx: rate displays kept
  text-green-600 (a positive flow-rate reasonably fits the delta
  exception) but gained an aria-label; BatchStreamCreator's unrelated
  "Remove" button also lost its unflagged-but-equally-prohibited
  text-red-500 while this file was already being touched.
- BulkWithdrawButton.tsx: progress fill was bg-green-500 (bg- isn't
  in the exception at all) -> bg-black; excluded-streams notice was
  text-amber-600, not in the exception -> text-gray-500.
- Input.tsx: error-state border (border-red-400/etc.) and error text
  (text-red-600) both converted to black/gray -- neither is a delta,
  and the existing aria-invalid + role="alert" + visible error text
  already carry the signal without color.
- settings/page.tsx: "Settings saved" (text-green-600) gained
  aria-label="confirmation"; the reset button's border-red-300/
  text-red-600 (border- not in the exception) converted to gray/black.
- stream/[id]/page.tsx: "Stream is paused" text-amber-600, not in the
  exception, converted to gray (matching the surrounding text style).
@drips-wave

drips-wave Bot commented Aug 26, 2026

Copy link
Copy Markdown

@prodbycorne Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Jaydbrown

Copy link
Copy Markdown
Contributor

Thanks for the contribution here — squash-merging this now. Any follow-ups we'll track in a fresh issue. 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment