Fix/wallet oracle claim error handling - #1
Open
adetomiwa21 wants to merge 26 commits into
Open
Conversation
…ield-Protocol#266) - Remove unused usePool() hook from usePools.ts (Parashield-Protocol#249) - Remove unused constants: HORIZON_URL, USDC_ASSET_CODE, USDC_ISSUER, USDC_ISSUER_TESTNET, ORACLE_CONTRACT_ID (Parashield-Protocol#248) - Refactor utilizationColor() to extract color name logic, use in pools/page.tsx to eliminate duplication (Parashield-Protocol#247) - Remove unused formatDuration() function (Parashield-Protocol#246)
… comparison (Parashield-Protocol#267) - Parashield-Protocol#240: Normalize STELLAR_NETWORK env var (uppercase + trim) so 'testnet'/'mainnet'/'public' all resolve correctly instead of silently falling through to testnet infrastructure. - Parashield-Protocol#241: Add validateConfig() that checks POLICY/CLAIMS/ORACLE_CONTRACT_ID are non-empty and valid Stellar strkeys at app startup, so misconfiguration fails fast with a clear error instead of deep in the purchase/claim flow. - Parashield-Protocol#244: Call api.submitClaim() after invokeSubmitClaim() succeeds in useClaim.ts, mirroring the existing buy-policy backend sync pattern so submitted claims reach the backend for UI polling/history. - Parashield-Protocol#245: Remove unused oracleValueUnit() — its logic is already handled by formatOracleValue() in format.ts. Co-authored-by: Dev Jaja <jajak5242@gmail.com>
…ards, add hook tests (Parashield-Protocol#268) - Remove the unused useProduct(id) hook from useProducts.ts — no product detail page consumes it, matching the dead-code pattern already fixed elsewhere in the codebase. - Compute the footer copyright year once via new Date().getFullYear() in layout.tsx and reuse it in both the desktop and mobile footers instead of the hardcoded "© 2026" literal. - Wrap PolicyCard, ProductCard, and ClaimHistoryTable in React.memo so list/table components rendered inside .map() don't re-render on every background poll tick when their own props haven't changed. - Add vitest coverage for all 8 custom hooks (useClaim, useDebounce, useKeyboardShortcut, useOracle, usePolicies, usePools, useProducts, useWallet), with dedicated regression tests for the loading/error/ cancellation and stale-response-guard behavior previously fixed by hand in useClaim, usePolicies, and useOracle. Closes Parashield-Protocol#250, Parashield-Protocol#251, Parashield-Protocol#252, Parashield-Protocol#253
…d-Protocol#289) - Parashield-Protocol#261: Bump text-gray-500/text-gray-600 to text-gray-400 for WCAG AA contrast - Parashield-Protocol#260: Extract shared input/label className constants in modals - Parashield-Protocol#259: Remove unused WalletState type - Parashield-Protocol#258: Use Comparison type in comparisonSymbol function Closes Parashield-Protocol#261, closes Parashield-Protocol#260, closes Parashield-Protocol#259, closes Parashield-Protocol#258
* feat(seo): add robots.txt and sitemap for search engine crawling - Add robots.ts with crawl rules for public routes - Add sitemap.ts with all public marketing routes - Disallow dashboard, policies, claims, oracle routes (authenticated) Closes Parashield-Protocol#262 * feat(pwa): add web app manifest for installability - Add manifest.ts with app name, icons, theme colors - Reference manifest from layout.tsx metadata - Enables Add to Home Screen on mobile devices Closes Parashield-Protocol#263 * test(buy-policy-modal): add test coverage for BuyPolicyModal - Test crop-specific inputs (lat, lng, month, year) - Test flight-specific inputs (flight number, date) - Test defi fixed oracle key display - Test manual oracle key input for disaster/health - Test configure step rendering - Test modal title with product name Closes Parashield-Protocol#269 * test(deposit-modal): add test coverage for DepositModal - Test deposit form rendering with amount input - Test pool liquidity and APY information display - Test pool label for each category (crop, flight, defi, disaster, health) - Test estimated LP shares placeholder Closes Parashield-Protocol#270
… ProductCard components (Parashield-Protocol#291)
…, and OracleDataWidget components (Parashield-Protocol#292) Closes Parashield-Protocol#275, Closes Parashield-Protocol#276, Closes Parashield-Protocol#277, Closes Parashield-Protocol#278 Add comprehensive test coverage for four components that previously had no tests: - WalletButton: Tests disconnected state, connecting state, className prop, and button structure - ConnectWalletPrompt: Tests default/custom messages, wallet name display, button rendering, and lock icon - NavBar: Tests aria-current=page highlighting for active routes, exact / matching, all navigation links, mobile menu toggle, and layout - OracleDataWidget: Tests loading, error, and no-data states; correct unit rendering for rainfall (mm), temperature (°C), flight (min delay), and defi (exploit/no exploit); confidence labels (High/Medium/Low); and source display
…archBar, and ProgressBar components (Parashield-Protocol#293)
… and Modal components (Parashield-Protocol#309) - Added tests for CopyButton: clipboard API, fallback, error handling, timer - Added tests for ToastContext: show, dismiss, auto-dismiss, multiple toasts - Added tests for Toast component: rendering, dismiss, variants - Added tests for ErrorBoundary: error catching, fallback, reset - Added tests for Modal: open/close, keyboard handling, focus management - Updated vitest config with setup file and installed testing libraries
…ton (Parashield-Protocol#316) * test: add test coverage for LoadingSpinner component Covers role/aria-label, default and size-variant classes, custom className, and the FullPageSpinner wrapper. Closes Parashield-Protocol#296 * test: add test coverage for Logo component Covers both Logo and LogoWordmark variants: img alt text, default and custom size, custom className, and dark/light styling. Closes Parashield-Protocol#297 * test: add test coverage for NetworkBanner component Covers banner visibility for TESTNET vs PUBLIC networks, and the default-to-visible behavior when no network env var is set. Closes Parashield-Protocol#298 * test: add test coverage for Skeleton component Covers Skeleton, SkeletonCard, SkeletonTable, and SkeletonText, verifying the expected placeholder element counts for default and custom count/rows props. Closes Parashield-Protocol#299
…iverge from the kit (Parashield-Protocol#312) src/lib/stellar.ts initialises StellarWalletsKit with allowAllModules(), so the kit's actual supported-wallet list changes with SDK updates independent of this component. The static "Use Freighter, xBull, LOBSTR, or any Stellar-compatible wallet" copy could go stale in either direction (a supported wallet like Rabet/Hana missing from the list, or a delisted wallet still advertised). Replaced it with copy that accurately represents the kit's dynamic nature instead of an enumerated list, per the issue's first acceptance-criteria option. "Connect Wallet" behavior (calling connect()) is unchanged.
…n accessible name (Parashield-Protocol#313) The role="progressbar" element had aria-valuenow/min/max but nothing tying it to the adjacent label text, so a screen reader announced only "45%, progress bar" with no indication of what's being measured (e.g. a pool's "Utilization" card). Added aria-labelledby pointing at the label span when a label is provided, falling back to a generic aria-label="Progress" when it isn't. Co-authored-by: nonsobethel0-dev <nonsobethel0@gmail.com>
… and hide decorative icon (Parashield-Protocol#314) The input relied on its placeholder as the only accessible-name signal, which isn't reliable and disappears once text is entered. Added aria-label={placeholder} to the input, and aria-hidden="true" on the decorative search-icon span (it was already pointer-events-none but not hidden from assistive tech). Co-authored-by: nonsobethel0-dev <nonsobethel0@gmail.com>
… tech (Parashield-Protocol#315) The static aria-label="Copy {label}" always overrode the visible button text as the accessible name, so a screen reader announced the same thing before and after a successful copy even though sighted users saw the text flip to "✓ Copied". Dropped the static aria-label so the visible text (Copy / label / "✓ Copied") is the accessible name, and added an aria-live="polite" region that announces "Copied" on success without being visually duplicated (sr-only).
* test(hooks): add comprehensive tests for useDebounce hook Resolves Parashield-Protocol#307 * test(hooks): add comprehensive tests for useProducts hook Resolves Parashield-Protocol#306 * test(hooks): add comprehensive tests for usePools hook Resolves Parashield-Protocol#305 * test(hooks): add tests for usePolicy hook Resolves Parashield-Protocol#304
…sive test coverage for api.ts and contract.ts (Parashield-Protocol#325) Implements test suites for api.ts (issue Parashield-Protocol#319) and contract.ts (issue Parashield-Protocol#320): api.test.ts: - Tests unwrap() throws ApiError on success:false even with HTTP 200 (issue Parashield-Protocol#198) - Tests withRetry() behavior: retries 5xx errors with exponential backoff, throws immediately on 4xx - Tests auth interceptor adds Bearer token when session exists - Tests auth error handler called on 401 responses - Tests endpoint behavior for 404 handling in fetchClaim() and fetchOracleReading() contract.test.ts: - Tests buildBuyPolicyTx() encodes oracle key as {type: 'string'} not {type: 'symbol'} (issue Parashield-Protocol#194 regression) - Tests simulateContractCall() throws ContractError with sanitized message and raw diagnostic in .details - Tests transaction building, signing, and submission flows for buyPolicy and claim operations - Tests poll-for-confirmation timeout handling - Tests RPC singleton caching for connection pool efficiency (issue Parashield-Protocol#129) - Tests BuyPolicyResult returns signedXdr for backend verification (issue Parashield-Protocol#195)
…ld-Protocol#318) - Add eslint + eslint-config-next with a flat config so `yarn lint` runs deterministically instead of failing or prompting in CI (fixes Parashield-Protocol#235). Also resolves the pre-existing no-explicit-any violations that surfaced once linting actually ran. - Add a request-id guard to usePools/useProducts so an older, slower refetch response can no longer overwrite a newer one (fixes Parashield-Protocol#234). - Track the in-flight AbortController for usePolicies' refetch() and abort the previous call before starting a new one, so rapid "Refresh" clicks can't race (fixes Parashield-Protocol#233). - Correct signAuthMessage's doc comment: the signature is passed through unmodified, not hex-encoded as previously claimed (fixes Parashield-Protocol#232).
…eClaim, and useOracle (Parashield-Protocol#300–Parashield-Protocol#303) (Parashield-Protocol#326) * test: add test coverage for TransactionLink component (Parashield-Protocol#300) - Explorer URL uses testnet by default and switches to public when STELLAR_NETWORK is PUBLIC - rel=noopener noreferrer attribute is present - Default label truncates tx hash correctly when no label prop is given - Links open in a new tab - Custom className prop is applied * test: add test coverage for WalletAddressDisplay component (Parashield-Protocol#301) - Renders shortened address correctly using shortenAddress - Renders full address when full prop is true - Returns null when wallet is not connected - Includes CopyButton with full address for copy affordance - Custom className prop is applied * test: add test coverage for useClaim hook (Parashield-Protocol#302) - submit() transitions through submitting then polling then done on success - submit() transitions to error state when submission fails - Failed submission after reset() still surfaces its error (regression for reset bug) - reset() clears all state back to idle - Starts in idle state * test: add test coverage for useOracle hook (Parashield-Protocol#303) - Loading is true only on initial fetch, not on background polls - Switching key does not let a stale response overwrite current reading - Error state is set on fetch failure - Returns null reading when key is null
…flow Call disconnect() before setError(`Auth failed: ...`) in the auth-failure catch block. disconnect() ends with setError(null), so the previous ordering wiped the message immediately. This matches the network-mismatch branch. Closes Parashield-Protocol#221
… categories buildRainfallKey() capped coordinates at 4 decimals so generated keys stay within Soroban's 32-char limit, and validate() now enforces that limit for the crop and flight categories (previously only disaster/health were checked). Closes Parashield-Protocol#222
… parsing parseOracleKey() now isolates the flight date from the final ':' so a flight number containing a colon (e.g. "AB:12") no longer swallows the date. The flight-number input also strips colons at the source and caps its length. Closes Parashield-Protocol#223
…rashield-Protocol#220) submit() already resets cancelledRef.current = false at its top (landed in Parashield-Protocol#218), which is the fix for the reset() hang. This adds a regression test proving a second failed submit after reset() surfaces an error instead of leaving the UI stuck on 'Submitting claim…'. Closes Parashield-Protocol#220
…Protocol#324 Parashield-Protocol#322 Parashield-Protocol#321 Parashield-Protocol#308) (Parashield-Protocol#328) * feat(pwa): add apple-icon.tsx for iOS home screen (Parashield-Protocol#324) * feat(types): add WalletState discriminated union and wire into WalletContext (Parashield-Protocol#322) * test(stellar): add unit tests for stellar.ts helpers (Parashield-Protocol#321)
* ci: add yarn lint step to CI workflow (Parashield-Protocol#257) * refactor(constants): extract timing constants for CopyButton and useClaim (Parashield-Protocol#255, Parashield-Protocol#256) * test(lib): add Vitest unit test coverage for api.ts and contract.ts (Parashield-Protocol#254) * fix(ProgressBar): define labelId with useId hook --------- Co-authored-by: Mosas2000 <Stellar-privacy@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes four related error-handling / data-integrity bugs across the wallet and claims flow, one focused commit per issue.
Changes
Parashield-Protocol#221 — Preserve auth-failure error message
In
WalletContext.tsx, the auth-failure catch block now callsdisconnect()beforesetError("Auth failed: …"). Sincedisconnect()ends withsetError(null), the previous order wiped the message instantly. Now matches the network-mismatch branch.Parashield-Protocol#222 — Clamp rainfall key precision + validate length
buildRainfallKey()clamps coordinates to 4 decimals so keys can't exceed Soroban's 32-char limit, andvalidate()inBuyPolicyModal.tsxnow enforces that limit for thecropandflightcategories (previously onlydisaster/health).Parashield-Protocol#223 — Colon-containing flight numbers
parseOracleKey()now isolates the date from the last:, so a flight number likeAB:12no longer swallows the date. The flight-number input also strips colons on change and caps its length.Parashield-Protocol#220 — cancelledRef reset on retry
submit()already resetscancelledRef.current = falseat its top (landed in Parashield-Protocol#218), which is the fix for the reset() hang. This adds a regression test proving a second failed submit afterreset()surfaces an error instead of hanging on "Submitting claim…".Testing
Full test suite green — 10 files, 85 tests. New tests cover each fix (auth-message persistence, over-length rainfall keys, colon flight-number round-trip, retried submit failure).
Closes Parashield-Protocol#221
Closes Parashield-Protocol#222
Closes Parashield-Protocol#223
Closes Parashield-Protocol#220