Conversation
Hide the Sense page Add zoom limit for the 3D Earth map fixed UI issues Improve layout for the cascade page. - wallet connected
Remove drag & drop for the Supernodes chart on mobile Fix the bug on the Cascade page where the UI disappears after loading finishes and then reappears.
Add a warning icon when APIs return errors
Cascade - Update download button colour Cascade - View Public files Cascade - UI not adjusting properly
Cascade - Update download button colour Cascade - View Public files Cascade - UI not adjusting properly
Added more space to the left menu. update tracking add UI for Stats
add tracking for cascade download update UI for tracking page
Leap was sunset by its vendor and Cosmostation shuts down 2026-09-01; neither belongs in onboarding anymore. Add a MetaMask card gated on IS_EVM_NETWORK, since mainnet has no EVM RPC endpoint or chain ID and genuinely cannot support it yet.
fetchAccountInfo and fetchEvmAccountInfo wrapped their four sources in a bare Promise.all, so one rejection emptied every slice: a rewards 500 also zeroed the displayed balance, delegations and unbonding, where develop lost only the rewards section. Both now settle each source independently through a shared helper, keeping AccountInfoData's shape and the per-endpoint console.error trace. A failed EVM balance query yields no balance rather than a confident zero, and the evmBalanceToMicroLume conversion is unchanged. Six tests cover one-endpoint-fails per slice for both functions. Also correct the ConnectedStaking.availableBalance comment (it is the total bank balance, not the spendable amount) and split the onSlice test so the progressive-render claim is actually asserted against the aggregate promise instead of only checking that callbacks ran. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…zero Round 1 made the four account slices degrade independently, which stopped one failing endpoint from blanking all four — but it also removed the only signal the Wallet screen had: nothing rejects, so account.error stayed null and a failed balances query rendered as "Available: 0 LUME", the number that bounds the Send and Delegate inputs. fetchAccountInfo and fetchEvmAccountInfo now record the slices whose source failed in an additive optional AccountInfoData.unavailable, and the wallet page composes describeAccountInfoGaps() into the error string WalletScreen already renders under the balance total, so no packages/ui change is needed and partial data still renders. A list of slice names rather than a boolean lets the notice name the missing figure. The account page keeps its current behaviour: an endpoint failure has always rendered as zero there, so this is not a regression, and no number on that read-only page bounds a user action. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The SDK constructor throws when it cannot find an API key, and Next.js imports every API route module during its "collect page data" build phase. Constructing at module scope therefore failed `next build` on any machine without Snag credentials, including CI and the hub-docker image build, whose Dockerfile deliberately passes no build secrets. Exporting SNAG_API_KEY in the shell did not help either: turbo.json's build task declares a strict env allowlist (NEXT_PUBLIC_* plus NEXT_OUTPUT) with no passThroughEnv, so turbo stripped it before Next ran. Only a file-based apps/web/.env.local worked, which a container build has no way to supply. Construction now happens on first use behind a Proxy, so the 31 route modules keep importing the default export unchanged. Methods are bound to the genuine instance because the SDK keeps private state in WeakMaps keyed on the object the constructor saw (_APIClient_baseURLOverridden, read by buildURL through __classPrivateFieldGet) and brands instances in a WeakSet — calling such a method with a Proxy as `this` throws a private-member TypeError. Only a successful construction is cached, so a misconfigured deployment keeps raising the SDK's own missing-credential error per request rather than caching a broken client or degrading into a silent no-op. Verified: `make testnet-build` succeeds with SNAG_API_KEY absent from both the environment and .env.local; 187/187 tests across 22 files; tsc --noEmit clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…rrors in place
- resequence balance and transaction queries so a slower previous wallet
cannot overwrite the active wallet's data after switching accounts
- validate the transaction hash MetaMask returns before reporting success
- show MetaMask errors inside the wallet modal and account menu instead of
a header alert, and report global API failures as toasts
- require a complete profile (name, RPC, chain id) before advertising EVM
support so a partial private override cannot enable MetaMask flows
- normalize SNSCOPE_URL (no trailing slash) and unify every call site to
`${SNSCOPE_URL}/v1/...` so the path-proxied devnet deployment and
slash-less overrides both resolve correctly
- memoize getClient/getOfflineSigner and cover connect, profile
verification failure, disconnect revocation fallback and EIP-6963
discovery with tests; add hook tests for send, transactions and wallet
connect
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…upernode map Wallet-connect tracking: normalize bad optional fields in hubUserSchema instead of rejecting the whole request, decide isNewHub from the insert itself so concurrent processes cannot double-award referral bonuses, track every reported address per session (no retry loops on permanent 4xx, no double counts on account switches). Wallet state: connect/disconnect now supersede in-flight passive syncs in the EVM provider, the header explains wallet errors that cleared the address, and the global API error toast surfaces empty and overlapping error messages instead of swallowing them. Supernode map: geolocate unknown nodes through a bounded worker pool with O(1) cache matching, restore the checked-in location seed as a cold-start fallback, and let hostname-addressed nodes use the browser ipwho.is fallback again. Consolidation: shared useLatestRequest stale guard, openConnectView entry point (fixes the dead Cascade upload connect prompt on EVM), shared ipwho mapper and micro-LUME sum helper, PORTAL_URL keyed by network profile with an env override. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The wallet-switch guard was derived from persisted modal UI state (isModalOpen + preferredWalletName), which failed in both directions: a reload mid-switch rehydrated the flags and latched the suppression for the whole session, while a connect started from the auto-preselected option never armed it at all — so the synchronizer tore the fresh Keplr session down mid-approval on one path and never cleaned stale state on the other. The guard now reads connectingWalletName from a new walletFlow slice that is deliberately kept out of the redux-persist whitelist. The wallet chooser sets it at the start of every connect attempt (however the wallet was selected) and clears it in finally, after the selection dispatches, so the window is bounded to the attempt and there is no render where the guard is down but the old wallet is still selected. The persisted-storage Keplr scrub pauses together with the in-memory teardown. Also: post-connect verification moved into a shared, tested getKeplrConnectionIssue predicate and now requires a fresh getAccount read from the extension (the store may hold a rehydrated account from a previous session), rolls a failed connect back with disconnect(), and maps the NotExist startup race to a recoverable message. setModalOpen no longer clobbers a stored wallet target when re-opened without one, the staking page routes Switch wallet through openConnectView (fixing the dead non-EVM path), wallet-option clicks are local again instead of dispatching app-wide, the synchronizer uses narrow selectors, and the Switch-wallet menu item is present on the menu's first paint. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…harts, @babel/core Applies the version bumps from Dependabot PRs #83, #86, #87, #88, #89 and #90 directly on this branch (their lockfiles were generated against main and do not apply here). next is the important one: 15.5.21 fixes four high- and five moderate-severity advisories (SSRF in rewrites and Server Actions, middleware bypass, cache confusion, DoS). eslint-config-next moves in lockstep with next. The caret ranges resolve slightly above Dependabot's targets (axios 1.19.0, postcss 8.5.26, @babel/core 7.29.7). Verified on the bumped tree: 305 web tests pass, tsc clean, next lint clean, and a full production build succeeds (which also compiles packages/ui with echarts 6.1.0). The echarts-for-react peer-range warning predates this change (it never declared 6.x support). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The supernodes table guarded the hardware cell with the same CPUCores check repeated three times (flagged by code review on PR #92), so a report with cores but no memory/storage metrics would crash the render on MemoryTotalGb.toFixed(). Each of the three rendered metrics now guards itself, and the cell falls back to an em dash unless all three are present. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR promotes the entire develop line (332 commits) into main, adding a large set of platform features to the Next.js web app: EVM network support with a MetaMask wallet flow, the supernode/Cascade explorer surfaces, a loyalty-quest and referral platform backed by TypeORM/SQLite entities and server routes, admin tooling, plus dependency-security bumps (next 15.5.21, axios, postcss, echarts 6.1, @babel/core) and hardening work with new unit tests.
Changes:
- EVM + wallet support (MetaMask/Keplr selection, network profiles, EVM balance/transfer helpers, Bech32 + ETH address handling) and wallet-connect tracking hardening (session markers, lenient referral validation).
- Explorer/dashboard/loyalty features: blocks/account/supernodes pages, governance vote countdown, Cascade geolocation server route,
/loyaltyquest pages with reCAPTCHA, referral pages, and admin user/tracking screens plus TypeORM entities/migrations. - Infrastructure/quality: turbo build env forwarding, PostCSS source-map stripping, redux slices (error/admin/walletFlow), many new utils with vitest coverage, and dependency/security upgrades.
Reviewed changes
Copilot reviewed 195 out of 428 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/web/src/hooks/useSnagStake.ts | Stake verification hook; early-return leaves loading flag stuck (flagged). |
| apps/web/src/app/api/supernode/validators.ts | Supernode Zod schema; message typo + inaccurate "hex characters" wording (flagged). |
| apps/web/src/app/referral/page.tsx | Referral page; malformed referral link when no address (flagged). |
| apps/web/src/hooks/admin/useRetentionRate.ts | Retention hook; side-effect calls placed mid-import block (flagged). |
| apps/web/src/hooks/useSnag.ts | Snag connect hook; accumulating click listener without cleanup (flagged). |
| apps/web/src/schemas/cascadeUploadSchema.ts | Upload schema; awkward "taskId ID is required" message (flagged). |
| apps/web/src/middleware-bk.ts | Dead backup middleware committed alongside active one (flagged). |
| turbo.json / package.json / tsconfig.json | Build env allowlist, node engine range, decorator/ES2020 compiler options. |
| apps/web/src/redux/*.slice.ts, store/index.ts | New error/admin/walletFlow slices and SSR-safe persistence storage. |
| apps/web/src/entities/, migrations/ | TypeORM entities and admin-user seed migration for loyalty/tracking. |
| apps/web/src/utils/*.ts (+ tests) | New EVM/search/governance/countdown/ipwho/env helpers with unit tests. |
| apps/web/src/app/loyalty | referral |
| apps/web/src/app/api/** | New Next route handlers for snag/loyalty/admin/supernode data. |
| packages/ui/** | Screen additions, dependency swaps (drop numeral/jvectormap/svg, add echarts 6.1). |
| Others | globals.css font, postcss plugin, .gitignore, README, dependency bumps. |
Suppressed comments (1)
apps/web/src/app/api/supernode/validators.ts:29
- Typo in this validation message: "IP addres" should be "IP address".
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Summary
Brings the full
developline tomain(332 commits): EVM network support with MetaMask, the supernode and loyalty/referral platforms, explorer features, and the hardening and dependency work on top.EVM support & wallets
Explorer & dashboard
Supernodes & Cascade
Loyalty quests & referrals
Infrastructure & quality
Test plan
vitest),tsc --noEmitclean,next lintclean on touched files🤖 Generated with Claude Code