feat: resolve Soroban Domains (*.xlm) to addresses - #2949
salazarsebas wants to merge 10 commits into
Conversation
…afe-eval - Add npmScopes.jsr to .yarnrc.yml so Yarn resolves JSR packages via the npm-compatible registry (https://npm.jsr.io). - Add @creit-tech/sorobandomains-sdk@^1.0.4 (via npm:@jsr/creit-tech__sorobandomains-sdk) to extension/package.json dependencies. - Add 'wasm-unsafe-eval' to the extension's manifest CSP (extension_pages script-src) so the SDK's WASM-based KECCAK-256 hashing (via @std/crypto) can run. Security-relevant change: MV3's default CSP disallows WebAssembly. - Add @creit-tech/sorobandomains-sdk and @jsr to jest's esModules transform allowlist; the package and its @jsr/* dependencies (std__crypto, std__bytes, std__encoding, creit-tech__stellar-assets-sdk) ship as ESM and were failing with 'Unexpected token export' under Jest's default node_modules transform-ignore.
Resolves a Soroban Domain (e.g. "jhon.xlm") to the Stellar/contract address it points to, using Freighter's own configured Soroban RPC only - never falling back to the SDK's default third-party RPC. Contract or simulation error details are never surfaced to the caller; only a generic translated message, with the real cause reported to Sentry. Also switches tsconfig.json's moduleResolution from "node" to "bundler": @creit-tech/sorobandomains-sdk ships only a conditional "exports" map (no top-level "main"/"types"), which classic Node resolution can't follow, breaking both `tsc` and the webpack build (ForkTsCheckerWebpackPlugin) with TS2307 as soon as the package is imported from real source. Verified no regressions: extension, and @stellar/freighter-api project type-check clean before and after; the two @shared sub-projects have the same pre-existing, unrelated error counts (2 and 419) with or without the change.
Wires isSorobanDomain validation, the new getAddressFromInput(userInput, networkDetails) signature, and saveDomainAddress into SendTo/index.tsx: Formik validation now accepts *.xlm domains, the Suggestions/Recents handleContinue paths resolve and persist the domain string alongside the resolved address, and a stored domain renders untruncated in the Recents list. Also fixes a stale one-argument getAddressFromInput call site left over from the signature change.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Adds end-to-end Soroban Domain resolution to Freighter’s send flow.
Changes:
- Resolves
*.xlmdomains through Freighter’s Mainnet Soroban RPC. - Persists and displays domain names throughout transaction screens and recents.
- Adds SDK configuration, translations, and unit/component coverage.
Reviewed changes
Copilot reviewed 22 out of 25 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
.yarnrc.yml |
Configures the JSR registry. |
extension/package.json |
Adds the Soroban Domains SDK. |
extension/public/static/manifest/v3.json |
Enables WebAssembly in the extension CSP. |
extension/src/helpers/stellar.ts |
Detects Soroban Domain input. |
extension/src/helpers/__tests__/stellar.test.ts |
Tests domain detection. |
extension/src/popup/components/InternalTransaction/ReviewTransaction/index.tsx |
Displays domains during review. |
extension/src/popup/components/InternalTransaction/SubmitTransaction/hooks/useSubmitTxData.tsx |
Saves domains to recent recipients. |
extension/src/popup/components/send/AddressTile/index.tsx |
Displays resolved domains. |
extension/src/popup/components/send/AddressTile/__tests__/index.test.tsx |
Tests domain labels. |
extension/src/popup/components/send/SendAmount/index.tsx |
Passes domains to recipient tiles. |
extension/src/popup/components/send/SendTo/index.tsx |
Integrates domain input and selection. |
extension/src/popup/components/send/SendTo/__tests__/index.test.tsx |
Tests domain input behavior. |
extension/src/popup/components/send/SendTo/hooks/useSendToData.tsx |
Resolves domains and guards async requests. |
extension/src/popup/components/send/SendTo/hooks/__tests__/useSendToData.test.tsx |
Tests resolution and stale requests. |
extension/src/popup/components/sendCollectible/SelectedCollectible/index.tsx |
Displays collectible recipient domains. |
extension/src/popup/constants/sorobanDomains.ts |
Pins the registry contract. |
extension/src/popup/ducks/transactionSubmission.ts |
Stores resolved domain state. |
extension/src/popup/helpers/sorobanDomains.ts |
Implements SDK-backed resolution. |
extension/src/popup/helpers/__tests__/sorobanDomains.test.ts |
Tests the resolver. |
extension/src/popup/locales/__tests__/translationParity.test.ts |
Checks translation parity. |
extension/src/popup/locales/en/translation.json |
Adds English messages. |
extension/src/popup/locales/pt/translation.json |
Adds Portuguese messages. |
jest.config.js |
Transforms the new ESM dependencies. |
tsconfig.json |
Uses bundler module resolution. |
yarn.lock |
Locks SDK transitive dependencies. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| abortControllerRef.current?.abort(); | ||
| const controller = new AbortController(); | ||
| abortControllerRef.current = controller; |
| recipientName = "", | ||
| federationMemo, | ||
| federationMemoType, | ||
| domainAddress = "", |
| const addressFromInput = await getAddressFromInput( | ||
| address, | ||
| networkDetails, | ||
| ); |
|
@salazarsebas thanks for putting this together, this looks like a solid start for this feature but we have concerns about the level of adoption that Soroban Domains has seen and frankly wether it is the right underlying mechanism for this kind of feature in Freighter. At this time we're going to choose to not merge this change set. This doesn't mean that we won't support this feature in the future but for now I'd like to turn this into an issue where we can engage @earrietadev and other team members to better understand the health of the project and the long term involvement from the maintainer, as well as consider other options for human friendly identifiers(like an internal contact book). |
|
I've started the issue - #2950 |
|
there is also xlm.domains. we think .xlm should be taken to a top level domain. we are passionate about .xlm and think there is much work to be done before a wallet adopts .xlm. we are willing to work on .xlm as maintainers and would love to collaborate with others who are passionate about the true potential of .xlm |
@xlmdomains we would certainly consider all protocols available when planning this feature. If you'd like to join the conversation in #2950 we can continue to see where this feature fits into Freighter's future. |
|
Makes sense, thanks for the honest take @aristidesstaffieri. I built this on the same pattern Freighter already uses for Federation addresses specifically so it wouldn't be a one-off, but I get that the real question here is bigger than implementation, it's about which naming mechanism the wallet should actually commit to long term. I'd rather this land as the right feature than a fast one, so I'll follow up with more thoughts in #2950. Happy to help with whichever direction the team lands on. |
|
The frustrating part is that we had Soroban Domains for 2 years and did not get the process going for .xlm to become a Top Level Domain with SDF/SCF support, despite repeated requests from the community. What is even more frustrating is that the 2026 ICANN window closed August 12 2026. And there won't be another application window until 2028 to 2030, which means even if the SDF committed to taking .xlm to a TLD today that it would not be able to be live with .xlm until 2030-2032. NEAR and Unstoppable Domains managed to get in the 2026 cohort and wont even get live until 2028. Another missed opportunity for Stellar Community. Imagine what we could have done with .xlm as a TLD using x402 in 2028... |
Summary
Freighter currently only resolves Federation addresses to a friendly name;
Soroban Domains (
*.xlm) fall back to the rawG.../C...address, which iseasy to mistype and gets truncated in the UI. This adds Soroban Domain
resolution end-to-end, following the same pattern already established for
Federation addresses.
*.xlminput and resolves it via the official@creit-tech/sorobandomains-sdk, using Freighter's own configured SorobanRPC only (never the SDK's default third-party RPC)
SendTo,AddressTile, review, submit, and send-amount screens, matching existingFederation-address handling
translated message, with the real cause reported to Sentry
Relates to #1585 (closed in 2025 as a duplicate of an internal spike) —
opening this as a ready-to-review implementation in case that effort didn't
move forward. Happy to adjust scope against any existing internal design.
Demo
https://youtube.com/shorts/pSmJFXXbRH8
Test plan
yarn test:cipassing (new coverage:sorobanDomainshelper,resolveSorobanDomainmodule,AddressTile,SendTo,useSendToData)yarn build:extensiontype-checks and bundles cleannpx eslintclean on all touched files*.xlmdomain end-to-end (see demoabove)