Open-source project
unicity-sphere/sphere avatar
unicity-sphere/sphere

Unicity AgentSphere: a wallet, a relay and an iframe host in one React app

A Web3 wallet and agent platform for the Unicity network - crypto wallet, DMs, group chat, and marketplace.

9,724 stars54 forksTypeScriptLicense varies

At a glance

What is it?
Sphere is the TypeScript client for the Unicity network: a wallet built on @unicitylabs/sphere-sdk, a Nostr DM and NIP-29 group chat client, and a host that loads external dApps into tabs. It is a private Unicity Labs project, so the interesting question is not whether it is good but whether you can run it at all.
Who is it for?
Adopt Sphere if you are building an agent or dApp that needs to appear inside the Unicity wallet, because the Connect protocol and the unicity-connect deep link scheme are the integration surface and the README documents both. Do not adopt it as a wallet for a different chain, and do not plan around it if you need a permissively licensed codebase: the README closes with a private licence line.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What Sphere actually is, and who it is built for

Sphere is not a general wallet that happens to have chat. It is the Unicity network's client, and the README lists the network-level features first: state transitions for token transfers, balance tracking, incoming payment notifications and a nametag system for @username addressing. Everything else in the app, the DM tab, the group chat tab, the marketplace, exists inside that wallet context. The SDK line confirms the dependency direction: @unicitylabs/sphere-sdk is described in the README as handling all wallet operations across L3, Nostr and IPFS, and the src/sdk directory is a React adapter layer of 24 files sitting on top of it. If you are an application developer on Unicity, Sphere is the surface your users will already have installed. If you are looking for a wallet for an existing chain, the L3 state transition model and the nametag system have nothing to offer you, and the private licence makes the point moot.

The Connect protocol is the real integration surface

Sphere implements ConnectHost, the wallet side of the Sphere Connect protocol, and the README is explicit that external dApps connect to it rather than the other way round. There are two transports. In iframe mode the dApp is embedded inside Sphere and talks over PostMessageTransport. In popup mode the dApp opens Sphere as a popup window and the user approves the connection. Access is scope-based: the dApp requests specific permissions and the user approves or rejects them, and approved intents can trigger send, sign or DM flows inside the wallet UI. The named components are ConnectPage on the /connect route, ConnectProvider, and ConnectionApprovalModal. That last one matters more than it looks. Because the approval step lives in the wallet, a dApp cannot silently widen its own scope after the fact, and the user sees the request in the same interface that holds the keys. The permission model is only as granular as the scopes the host defines, and the README does not enumerate them, so you will need to read the ConnectProvider source to know what you can ask for.

How unicity-connect:// links move a dApp into a tab

The deep link scheme is the part of Sphere with the most moving pieces, and the README documents the data flow end to end. A dApp builds an ordinary https URL, replaces the scheme with unicity-connect://, and sends it as a DM message. The protocol format is unicity-connect://host/path?query=params. On the receiving side, Sphere's markdown parser detects the scheme in three shapes: bare plain text, a markdown link, and an anchor tag. Each becomes a DeepLinkButton dropdown with two choices. Open in Sphere registers a global handler through useDeepLinkNavigation inside DashboardLayout and navigates to /agents/custom?url=<httpsUrl>, which loads the target as an iframe agent. Open in browser resolves the scheme back to http or https and calls window.open. The resolution rule is stated plainly: unicity-connect:// becomes https://, except for localhost and 127.0.0.1, which become http://. Three files carry this: src/utils/deepLinkHandler.ts for the conversion and the global click handler registry, src/utils/markdown.tsx for the button and the detection, and src/hooks/useDeepLinkNavigation.ts for the Sphere-side navigation handler. Note the asymmetry. A link that arrives by any route other than the markdown parser will not get a button, so the delivery channel is part of the contract.

Agents are tabs, and that is the whole extension model

The agent system is deliberately thin. Agents are specialized interfaces loaded as tabs, and the README names three that are currently active: Messages for private conversations over Nostr, Group Chat for public channels via NIP-29, and Sphere Agents, which loads any external dApp by iframe from a custom URL. The README adds that further agent types can be registered in src/config/activities.ts, which means an in-tree agent is a config entry plus a component, while an out-of-tree one is a URL. That is a real constraint on what you can build. An iframe agent runs under the browser's iframe rules, so anything requiring direct access to wallet internals has to go through Connect instead of reaching into the host. Group chat is relay-based over NIP-29, with public and private groups, invite codes, WebSocket delivery, discovery, join and leave, and unread tracking, pointed at a dedicated Zooid relay at wss://sphere-relay.unicity.network. That relay address is hardcoded in the documentation, which tells you group chat depends on Unicity-operated infrastructure rather than on any relay the user chooses.

Running it locally: Node 20, a .env file and port 5173

The setup is conventional for a Vite project. Node.js 20 or later is required. Then npm install, cp .env.example .env to create the environment file, and npm run dev, which the README says serves at http://localhost:5173. The other scripts are npm run build for a TypeScript compile plus Vite production build, npm run preview, npm run lint for ESLint, npm run test for Vitest in watch mode and npm run test:run for a single pass. Docker is a one-liner, docker compose up, and the README states it runs on port 3010, which is a different port from the dev server and worth remembering when you switch between the two. The documented environment variables are few: VITE_WELCOME_AGENT_NAMETAG for the nametag of the welcome DM agent, VITE_WELCOME_DELAY_MS for the delay before that message in milliseconds, SSL_CERT_PATH for optional dev server HTTPS, HMR_HOST for a remote HMR host, and BASE_PATH for the deployment base path. There is no variable in the README for the relay endpoint or for any RPC URL, so those are either hardcoded or live somewhere the documentation does not cover. The stack is React 19 with TypeScript on Vite 7, TanStack Query v5 for server state, Tailwind CSS 4, Framer Motion, React Router DOM v7, and Vitest with jsdom for tests, which live under tests/unit.

Where Sphere is the wrong choice

The licence is the first blocker. The README ends with a single line, private project, Unicity Labs, and the repository metadata does not state a licence at all. That is not a permissive open source project with a missing file, it is a project that describes itself as private. Treat the code as readable rather than reusable until Unicity Labs says otherwise, and do not plan a fork, a redistribution or a hosted derivative on the strength of the repository being visible. The second limitation is coupling. Wallet operations are delegated to @unicitylabs/sphere-sdk, and the README does not say whether that package is published, under what terms, or whether it is required for a build to succeed. If it is not publicly available, npm install will fail and nothing else in this article applies to you. The third is deployment surface. Group chat depends on a named Zooid relay, deep links resolve to https except on localhost, and BASE_PATH exists because the app is expected to be hosted under a path prefix. None of that is wrong, but it means Sphere is not a self-contained artifact you can drop anywhere. A fourth point the README leaves open is seed phrase management, which is listed as a feature with no description of how the phrase is stored or protected. For a wallet, that is the one section I would want documented before trusting it with value.

How this compares to a plain Nostr client

The closest familiar alternative is a general-purpose Nostr client that adds a wallet through a NIP-47 style connection. The difference in approach is where the trust boundary sits. A general client treats the wallet as an external signer the user points at, so the client never holds keys and the integration is a protocol between two independently run programs. Sphere inverts that: it is the wallet, and dApps are the guests. Connect's iframe and popup modes, the scope approval modal, and the unicity-connect scheme all exist to let someone else's code run inside a host that already has the keys. That buys a tighter user experience, since a DM can contain a button that opens a working agent in one click, and it buys a narrower ecosystem, because a dApp must be written to the Connect host's scopes rather than to a neutral standard. NIP-29 group chat is the one piece that is genuinely portable, since it is a public Nostr specification, though the README's single relay address means the portability is theoretical until another relay is configured. Sphere is also not a browser extension, so it cannot intercept a page the user visits; the deep link has to arrive through a channel Sphere itself renders.

Maintenance cost and what to verify before you commit

The repository was last pushed in September 2026 and has no retrieved releases, so there is no versioned artifact to pin against and no changelog to read. Upgrades arrive as commits on main. The src/sdk adapter layer is 24 files of React hooks over the SDK, which is where a breaking change in @unicitylabs/sphere-sdk will land first, and the README's own structure listing, useSphere, useWalletStatus, useIdentity, useNametag, useSphereEvents, useIpfsSync, useTokens, useBalance, useTransfer and the rest, is the checklist to grep when that happens. Because the licence is private, there is also no community fork to fall back on if Unicity Labs stops pushing. Verify three things before writing integration code. First, that @unicitylabs/sphere-sdk installs and builds from a clean clone. Second, that the scope names ConnectProvider accepts match what your dApp intends to request, since the README does not list them. Third, that your deep link renders as a button in all three parser paths, plain text, markdown link and anchor tag, because a link that renders as plain text is a link nobody clicks.

Editorial conclusion

Adopt Sphere if you are building an agent or dApp that needs to appear inside the Unicity wallet, because the Connect protocol and the unicity-connect deep link scheme are the integration surface and the README documents both. Do not adopt it as a wallet for a different chain, and do not plan around it if you need a permissively licensed codebase: the README closes with a private licence line. Before writing any integration code, read src/utils/deepLinkHandler.ts and src/utils/markdown.tsx to confirm the accepted link formats, run npm run dev and check /connect, and ask Unicity Labs directly for the actual licence terms, since the repository metadata does not state one.

Official sources

  1. Issues
  2. Project website
  3. README
  4. unicity-sphere/sphere on GitHub
Community notes

Community notes