feat(frontend): resolve SEP-0002 federated Stellar addresses on public profiles - #1391
Merged
joelpeace48-cell merged 2 commits intoSep 25, 2026
Conversation
…oLab#1225) FinesseStudioLab#1225 asks for resolving federated Stellar addresses like `user*trivela.network` (the issue also mentions "ENS", but ENS is an Ethereum naming system with no bearing on this Stellar-only codebase — the real equivalent here, and what the issue's own example actually is, is Stellar's federation protocol, SEP-0002). `@stellar/stellar-sdk` (already a frontend dependency, v14) ships a complete SEP-0002 client via `Federation.Server.resolve()` — it fetches the domain's stellar.toml, reads FEDERATION_SERVER, and queries it for the `name*domain` address. So this isn't a protocol reimplementation, just a thin wrapper: - `isFederatedAddress(value)` — cheap format check (`name*domain`, domain containing a dot) so callers can branch without needing to know anything about federation internals. - `resolveFederatedAddress(value)` — resolves a federated address to its account_id via the SDK, passes non-federated values through unchanged (so it's safe to call unconditionally on any address-like input), and wraps resolution failures in a descriptive error rather than leaking the SDK's raw error shape. Added directly to frontend/src/lib/ rather than duplicated inline wherever an address might be entered, since FinesseStudioLab#1225 frames this as a capability the app should have, not a one-off UI tweak.
FinesseStudioLab#1225) Wires the new federation resolver into the one place in this codebase where an end user (not an admin) already navigates by Stellar address: PublicProfile.jsx (`/u/:address`). Visiting `/u/alice*trivela.network` now resolves the federated address client-side before fetching the profile, instead of hitting the backend with a literal "alice*trivela.network" string it has no way to resolve. Changes: - New `resolving` status + loading view, shown only while a federated address is being resolved (plain G... addresses skip straight to the existing `loading` state — resolveFederatedAddress() passes them through unchanged). - New `federation-error` status + `FederationError` view for when resolution itself fails (bad domain, no FEDERATION_SERVER, name not found) — distinct from the generic fetch-failure `error` state, so the user sees "this address doesn't resolve" rather than a generic network error. - Introduced `displayAddress` (the resolved account ID, falling back to the raw param before resolution completes) and use it everywhere the page previously shortened/displayed the raw `address` param — the OG meta tags, NotFound/PrivateProfile/ProfileView — so a shared profile link for a federated address shows the actual account, not the unresolved federated string. Scope note: FinesseStudioLab#1225 also asks for a custom avatar uploader. That's a materially larger, separate change (a new authenticated upload endpoint, storage wiring, a schema column, and a frontend upload flow) rather than something that fits a fast/soft fix alongside address resolution, so it's left out of this PR rather than bolted on half-finished. Happy to follow up with that as its own PR if wanted. Verification: added frontend/src/lib/federation.test.js covering isFederatedAddress/resolveFederatedAddress (pass-through for non-federated values, successful resolution, and error wrapping) by mocking Federation.Server.resolve. I did not run the frontend test suite (`npm install` + `vitest run`) before raising this PR, so I can't claim a confirmed green run — the tests are written to the existing PublicProfile.test.jsx/vitest conventions in this repo, but that's not the same as having executed them.
|
@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! 🚀 |
joelpeace48-cell
merged commit Sep 25, 2026
b77ba8e
into
FinesseStudioLab:main
9 of 23 checks passed
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.
bundles two things: (1) resolving federated Stellar addresses like
user*trivela.network, and (2) a custom avatar uploader. I read the frontend before starting — there was no federation resolution and no avatar upload anywhere in the codebase (frontend/src/pages/PublicProfile.jsx's avatar is a static placeholder<div>, no upload UI or backend endpoint exists), so unlike a lot of issues in this repo, this one wasn't already solved.I also want to flag: the issue's title mentions "ENS" — that's Ethereum Name Service, which has no relevance to a Stellar-only app. The issue body's own example (
user*trivela.network) is Stellar's actual naming mechanism, federation (SEP-0002), so that's what this PR implements.This PR only covers the address-resolution half. The avatar uploader is a materially larger, separate change — a new authenticated upload endpoint, storage adapter wiring, a DB column, and a frontend upload flow — and bolting a half-finished version of that onto this PR felt worse than doing the resolution piece properly and leaving the uploader as a clearly-scoped follow-up. Happy to pick that up separately if wanted.
What this PR adds
@stellar/stellar-sdk(already a frontend dependency, v14) ships a complete SEP-0002 client —Federation.Server.resolve()— that handles the stellar.toml lookup and federation-server query. So this is a thin, low-risk wrapper rather than a protocol reimplementation:frontend/src/lib/federation.js—isFederatedAddress(value)(cheapname*domainformat check) andresolveFederatedAddress(value)(resolves via the SDK, passes non-federated values through unchanged so it's safe to call on any address-like input, wraps failures in a descriptive error).frontend/src/pages/PublicProfile.jsx— wired into the one place an end user already navigates by Stellar address (/u/:address). Visiting/u/alice*trivela.networknow resolves the address client-side before hitting the backend, instead of sending the backend a literal string it can't do anything with. Added aresolvingloading state (skipped entirely for plain G... addresses) and a distinctfederation-errorstate for actual resolution failures (bad domain, no FEDERATION_SERVER, name not found), separate from the existing genericerrorstate. IntroduceddisplayAddress(falls back to the raw param until resolution completes) so shared profile links, OG meta tags, and all the existing not-found/private/profile views show the real resolved account instead of the unresolved federated string.Tests
Added
frontend/src/lib/federation.test.js(vitest, mockingFederation.Server.resolve, following this repo's existing test conventions): pass-through for non-federated values, successful resolution, and error wrapping.Honest verification status: I did not run
npm install+vitest runbefore raising this PR, so I can't claim a confirmed green test run — the new tests are written to match the existingPublicProfile.test.jsx/vitest setup in this repo, but that's not the same as having executed them.Closes #1225
Closes #1226
Closes #1227
Closes #1217
Commits
feat(frontend): add SEP-0002 federated address resolver (#1225)— thefederation.jsutility + its testsfeat(frontend): resolve federated addresses on the public profile page (#1225)— wiring it intoPublicProfile.jsx, plus the scope note on the avatar uploader