Sphere wallet Connect protocol integration. Use when the developer wants to connect their dApp to a Sphere wallet, imports @unicitylabs/sphere-sdk/connect, asks about wallet integration, ConnectClient, autoConnect, PostMessageTransport, ExtensionTransport, or WebSocketTransport.
You are helping a developer integrate the Sphere wallet Connect protocol into their project. Follow these steps:
package.json for React (react), Vue (vue), Svelte (svelte), or Node.js (no browser framework)tsconfig.json (TypeScript) or plain JavaScriptbun.lockb (bun), pnpm-lock.yaml (pnpm), yarn.lock (yarn), or package-lock.json (npm)@unicitylabs/sphere-sdk is in dependenciesIf @unicitylabs/sphere-sdk is not installed, install it:
npm install @unicitylabs/sphere-sdknpm install @unicitylabs/sphere-sdk wsBased on the detected framework:
Generate one file + env:
src/hooks/useWalletConnect.ts (see react-template.md)VITE_WALLET_URL=https://sphere.unicity.network to .envNo separate detection file needed — autoConnect() handles transport detection internally.
Generate one file:
src/lib/sphere-client.ts (see nodejs-template.md)Generate two files:
src/sphere-detection.js (see detection.md)src/sphere-connect.js — use autoConnect() from SDK (see vanilla example below)Add to tsconfig.json compilerOptions.paths:
{
"paths": {
"@unicitylabs/sphere-sdk/connect": ["./node_modules/@unicitylabs/sphere-sdk/dist/connect/index.d.ts"],
"@unicitylabs/sphere-sdk/connect/browser": ["./node_modules/@unicitylabs/sphere-sdk/dist/impl/browser/connect/index.d.ts"]
}
}
After generating files, show a concise usage example:
import { useWalletConnect } from './hooks/useWalletConnect';
function App() {
const wallet = useWalletConnect();
if (wallet.isAutoConnecting) return <div>Connecting...</div>;
if (!wallet.isConnected) return <button onClick={wallet.connect}>Connect Wallet</button>;
return <div>Connected as {wallet.identity?.nametag}</div>;
}
// In your components:
const balance = await wallet.query('sphere_getBalance');
await wallet.intent('send', { recipient: '@alice', amount: '1000000', coinId: 'UCT' });
const unsub = wallet.on('transfer:incoming', (data) => console.log('Received:', data));
<button id="connect">Connect Wallet</button>
<script type="module">
import { autoConnect } from '@unicitylabs/sphere-sdk/connect/browser';
let wallet = null;
// Try silent auto-reconnect on page load
try {
wallet = await autoConnect({
dapp: { name: 'My App', url: location.origin },
walletUrl: 'https://sphere.unicity.network',
silent: true,
});
document.getElementById('connect').textContent = `Connected: ${wallet.connection.identity.nametag}`;
} catch {
// Not approved yet — wait for button click
}
document.getElementById('connect').onclick = async () => {
wallet = await autoConnect({
dapp: { name: 'My App', url: location.origin },
walletUrl: 'https://sphere.unicity.network',
});
console.log('Connected:', wallet.connection.identity);
};
</script>
The wallet pushes two events automatically after connection — no sphere_subscribe needed:
wallet:locked — wallet logged out, popup closed/refreshed, or session ended. Handling depends on the transport:
isWalletLocked = true and wait. The host is still alive; when the user unlocks, identity:changed fires and clears the flag.identity:changed — user switched address (or unlocked after lock). Must update displayed identity and clear locked state.Host-side note: When the wallet's
Sphereinstance is destroyed, the host must callnotifyWalletLocked()to push the event to connected dApps.
Additionally, wrap query()/intent() calls with error handling: if the transport is dead (popup crashed, network lost), auto-disconnect as a fallback. See react-template.md for implementation.
Popup connections are not persistent — if the user reloads the page, the connection is lost unless the session is saved. The React template saves connection.sessionId to sessionStorage after connect and passes resumeSessionId to autoConnect() on mount. This allows the popup session to resume after a page reload (as long as the popup is still open). On disconnect or connection failure, the saved session is cleared.
When using WebSocketTransport in Node.js, always guard against writes to a closing or closed socket. The nodejs-template.md patches ws.send automatically, or you can use a standalone guard:
const safeSend = (data: string) => {
if (ws.readyState === WebSocket.OPEN) ws.send(data);
};
This prevents "WebSocket is not open" errors during disconnect races.
autoConnect() from @unicitylabs/sphere-sdk/connect/browser handles everything automatically:
client for queries, intents, and eventsimport { autoConnect } from '@unicitylabs/sphere-sdk/connect/browser';
// One function — that's it
const result = await autoConnect({
dapp: { name: 'My App', url: location.origin },
walletUrl: 'https://sphere.unicity.network',
silent: true, // auto-reconnect without UI
});
result.client.query('sphere_getBalance');
result.client.intent('send', { recipient: '@alice', amount: '1000000', coinId: 'UCT' });
result.client.on('transfer:incoming', (data) => console.log(data));
await result.disconnect();
| Priority | Mode | When | Persistent? |
|---|---|---|---|
| P1 | Iframe | isInIframe() — dApp embedded in Sphere | Yes |
| P2 | Extension | hasExtension() — Chrome extension installed | Yes (best UX) |
| P3 | Popup | Fallback | No — popup must stay open |
Extension (P2) is the best mode for production — the background service worker is always running, so:
chrome.storage.localAlways try silent: true first to avoid flashing the Connect button:
try {
const result = await autoConnect({ dapp, walletUrl, silent: true });
// Reconnected — origin was already approved
} catch {
// Not approved — show Connect button
}
For extension mode, silent connect works even if the wallet popup is not open — the background service worker handles it.
await autoConnect({ dapp, walletUrl, forceTransport: 'extension' });
await autoConnect({ dapp, walletUrl, forceTransport: 'popup' });
// Recommended: autoConnect (handles everything)
import { autoConnect } from '@unicitylabs/sphere-sdk/connect/browser';
import type { AutoConnectResult, DetectedTransport } from '@unicitylabs/sphere-sdk/connect/browser';
// Detection utilities (also available standalone)
import { isInIframe, hasExtension, detectTransport } from '@unicitylabs/sphere-sdk/connect/browser';
// Low-level (only if you need manual control)
import { ConnectClient } from '@unicitylabs/sphere-sdk/connect';
import { PostMessageTransport, ExtensionTransport } from '@unicitylabs/sphere-sdk/connect/browser';
import type { ConnectTransport, PublicIdentity, RpcMethod, IntentAction, PermissionScope } from '@unicitylabs/sphere-sdk/connect';
// Node.js
import { WebSocketTransport } from '@unicitylabs/sphere-sdk/connect/nodejs';
ConnectHost code — that's only for wallet developersTo authenticate users to a backend server using wallet signatures (challenge-response → JWT), see backend-auth.md.
For complete RPC methods, intents, permissions, events, and error codes, see reference.md.