Keep wallet addresses private across the portal#905
Conversation
Public surfaces no longer expose full wallet account addresses for other participants. Every public API response now carries the truncated display form (0x1234...abcd), enforced in the backend serializers rather than the UI, so the addresses are not retrievable from the API either. Profiles are now linked and looked up by user id (old address links keep resolving), copy buttons and explorer links for other users' account addresses are removed, and address search only matches a pasted complete address, never partial input, so hidden addresses cannot be reconstructed through search. Owners still see and copy their own full address, and stewards/admins keep full addresses for review work. Validator node wallet addresses and on-chain operator addresses remain full: they are public chain data used by explorer links and Grafana dashboards. Anonymous leaderboard reads get a scrape-bounding throttle. ## Claude Implementation Notes - backend/users/utils.py: New truncate_address / is_full_address / user_lookup_kwargs helpers (single source of truth for address privacy). - backend/users/serializers.py: LightUserSerializer, PublicUserListSerializer (adds id), UserSerializer (full only for owner/staff), referred_by_info truncated; public profile keeps id (the only linkable identifier now). - backend/users/views.py: search matches address only on exact full address (anti-oracle), search response truncated; retrieve/by_address/user_highlights accept id or address. - backend/leaderboard/views.py: search_fields drops user__address; referrals/community search gated to exact full address; user_address params accept id; trending/community payloads truncated + user_id added; anonymous-only public_leaderboard throttle. - backend/contributions/serializers.py: ContributionHighlightSerializer truncated + user_id added; FeaturedContentSerializer truncated. - backend/contributions/views.py: ContributionViewSet search_fields drops user__address; user_address filter accepts id. Steward filterset intentionally unchanged (steward-gated). - backend/validators/serializers.py + views.py: operator_user.address truncated everywhere; Grafana roster account truncated, synthetic missing-row node key is now user-<id>; by-user-address accepts id; /validators/ fallback rows truncated + id. - backend/poaps/views.py, backend/builders/views.py, backend/ethereum_auth/views.py, backend/projects/serializers.py, backend/api/overview_metrics.py: same redaction/dual-key treatment. - backend/tally/settings.py: public_leaderboard throttle rate. - backend/users/tests/test_address_privacy.py: new coverage for truncation, search anti-oracle, dual-key lookup; existing tests updated to the truncated contract (test_email_security, test_stats, grafana roster tests). - frontend/src/lib/address.js: shared truncateAddress / isFullAddress / participantPath helpers. - frontend/src (routes + components): all /participant/ links use user id with address fallback; ProfileHeader copy own-profile only; WaitlistParticipants explorer link removed; Profile balance RPC guarded to full addresses (owner); POAP/wallet/stats sub-fetches keyed by id; RankingsWidget own-row highlight compares ids; AllContributions highlight filter uses resolved participant id or truncated compare. - backend/CLAUDE.md, frontend/CLAUDE.md: address privacy rules documented.
A follow-up audit of every address comparison, API lookup, and profile link found five flows still keyed on other users' full addresses, which the API no longer returns. POAP recovery on your own profile now recognizes ownership by account id, ecosystem validator cards and submission cards link to profiles by id, the profile rank pill resolves community rank by id so it also works for visitors, and the project page editor loads participant contributions by id. ## Claude Implementation Notes - frontend/src/components/poaps/ProfilePoaps.svelte: canRecover compares the userId prop (now a user id) against userStore.user.id, keeping the address compare as fallback for address-keyed callers. - frontend/src/routes/EcosystemPartners.svelte: validator card href uses user.id with address fallback (payload addresses are truncated). - frontend/src/components/shared/CTABanner.svelte: community rank fetch sends participant.id as user_address (backend accepts id or full address); the banner renders on visitor-viewed profiles too. - frontend/src/routes/ProjectPageEditor.svelte: loadParticipantContributions keys the contributions filter on getParticipantId with address fallback; participant matching and saving were already id-first. - frontend/src/components/SubmissionCard.svelte: View Profile link uses user_details.id with address fallback. - frontend/src/tests/ProjectPageEditor.test.js: expects user_address to carry the user id per the new contract.
|
Warning Review limit reached
Next review available in: 5 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (60)
✨ 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 |
Locks the review fixes with regression tests: the public steward
directory and working group detail must serve truncated addresses with
user ids for profile links, and the referral breakdown must not expose
referred users' complete wallet addresses.
## Claude Implementation Notes
- backend/users/tests/test_address_privacy.py: three new tests covering GET /api/v1/stewards/ (anonymous, no 42-hex addresses, user_id + truncated address present), GET /api/v1/stewards/working-groups/{id}/ (participant truncated + id), and get_referral_breakdown() (referred users truncated + id). The fixes themselves shipped in d5d8886.
3a82fe1 to
4b294b9
Compare
Conflict resolutions: keep both changelog entries; combine imports in validators/serializers.py (dev's ValidatorOperatorWallet + truncate_address); in ProjectPageEditor keep the id-first participant lookup key and take dev's page_size of 50.
Two tests that cannot run in local workspaces (pre-existing seed collisions) surfaced on CI still asserting full addresses in public payloads: the community contributors endpoint and the referral breakdown. Both now expect the truncated form. ## Claude Implementation Notes - backend/community_xp/tests/test_mee6_sync.py: community-contributors user_address expectations wrapped in truncate_address. - backend/leaderboard/tests/test_referral_points.py: test_lists_all_referred_users expects truncated addresses in the breakdown set.
Changelog conflict: kept both the wallet privacy entry and dev's three new mobile/MetaMask entries.
Changelog conflict: kept both the wallet privacy entry and dev's mobile dropdown entry.
Summary
Validation
git diff --check origin/dev...HEADnpm test -- --run src/tests/referrals.test.js src/tests/userStore.test.jsNotes
npm run checkis currently blocked by existing project-wide Svelte/type diagnostics: 2201 errors and 183 warnings across 168 files.python3 manage.py test users.tests.test_address_privacycould not start in this environment because Django is not installed.