Wallet Login
Wallet login lets users authenticate with their Solana wallet instead of an email and password. The mechanism is a Sign-in-with-Solana challenge-response: the server issues a nonce, the wallet signs it, and the server verifies the signature cryptographically. No personal information changes hands at any point.
Currently supported wallets: Phantom, Backpack, Solflare.
Enable wallet login
Section titled “Enable wallet login”- Go to the Tribe dashboard
- Open your site’s Settings → Auth → Privacy-Preserving Auth
- Toggle on Wallet Login
Check if a wallet is available
Section titled “Check if a wallet is available”Not every user will have a Solana wallet installed, so check before showing a wallet login button:
import { Tribe } from "@tribecloud/sdk";
const available = tribe.isWalletAvailable();// Returns true if Phantom, Backpack, or Solflare is detectedSign in with wallet
Section titled “Sign in with wallet”const { user } = await tribe.loginWithWallet();// user.walletAddress — the wallet's public key// user.pseudonymousId — stable hashed identifier// user.authMethod — "wallet"Behind this single call, the SDK orchestrates the full sequence:
- Requests a nonce from the Tribe server
- Prompts the user to sign a message in their wallet popup
- Sends the signature back to the server for cryptographic verification
- Stores the resulting session token
Show per-wallet buttons
Section titled “Show per-wallet buttons”If you want to display a distinct button for each installed wallet rather than a generic one, detectWallets() returns what the browser has available:
const wallets = tribe.detectWallets();// [{ id: "phantom", name: "Phantom" }, { id: "backpack", name: "Backpack" }]function WalletLoginButtons() { const [wallets] = useState(() => tribe.detectWallets()); const [loading, setLoading] = useState(false);
if (wallets.length === 0) return null;
const handleClick = async () => { setLoading(true); try { const { user } = await tribe.loginWithWallet(); console.log("Logged in:", user.walletAddress); } catch (err) { console.error("Wallet login failed:", err); } finally { setLoading(false); } };
return ( <> {wallets.map((wallet) => ( <button key={wallet.id} onClick={handleClick} disabled={loading}> {loading ? "Signing..." : `Sign in with ${wallet.name}`} </button> ))} </> );}<div id="wallet-buttons"></div>
<script src="https://api.tribe.utopian.build/sdk.js?site=YOUR_SITE_ID" defer></script><script defer> window.addEventListener("DOMContentLoaded", () => { const wallets = Tribe.detectWallets(); const container = document.getElementById("wallet-buttons");
wallets.forEach((wallet) => { const btn = document.createElement("button"); btn.textContent = `Sign in with ${wallet.name}`; btn.addEventListener("click", async () => { try { const { user } = await Tribe.loginWithWallet(); console.log("Logged in:", user.walletAddress); } catch (err) { console.error("Wallet login failed:", err); } }); container.appendChild(btn); }); });</script>Privacy
Section titled “Privacy”Wallet login is fully pseudonymous. The wallet address itself is stored (it’s needed for payment flows and already public on the blockchain), but no email or other personal information is collected.
After signing in with a wallet, the session contains:
user.email→nulluser.walletAddress→ the wallet’s public keyuser.pseudonymousId→ stable hashed identifier