SessionKit docs
Scopes
What you can ask for, what the user sees, and what can never be granted.
A scope is one thing you're asking the user to share. You request them in
connect(); the wallet shows each one in plain language and the
user approves or declines. Nothing outside the granted set is ever sent.
The catalog
| Scope | You receive | The user sees |
|---|---|---|
identity | user.id, user.pubKey, user.proof | "Sign you in" |
profile:username | user.username | "See your username" |
profile:avatar | user.avatar, user.avatarMimeType | "See your profile picture" |
address:solana | user.solanaAddress | "See your Solana address" |
favorites:read | user.favoriteMarkets | "See your favorite markets" |
identity is added automatically — every session returns a
verifiable user, that's the point of signing in. The rest you ask for
explicitly.
What can never be granted
There is no trading scope, and there never will be. SessionKit sessions cannot place, modify, or cancel orders, cannot change leverage or margin, cannot sign transactions, and cannot move funds. The wallet enforces this by audience, not by who you are — so it holds even if your key leaks, even if your site is compromised.
This is deliberate and it protects you as much as the user: the worst case
of a breach on your side is the data the user explicitly agreed to share,
never their money. Requesting a scope outside the catalog throws
invalid_scope before anything is rendered.
Ask for less
Every extra scope is a reason to decline. Approval rates fall as the list grows, and unused data is a liability you have to store, secure, and delete.
- Just signing people in? Request nothing —
identityalone is a complete login. - Showing who they are? Add
profile:usernameandprofile:avatar. - Checking NFTs or token holdings? Add
address:solana.
Handling partial grants
A user can approve the login and decline an optional scope. Check
grantedScopes, and degrade rather than fail:
const session = await connect({
scopes: ["identity", "profile:username", "address:solana"],
mount, sign
});
if (session.grantedScopes.includes("address:solana")) {
await loadNfts(session.user.solanaAddress);
} else {
showConnectWalletLater(); // they're still logged in
} Adding chains
Further address scopes (address:ethereum, and so on) are added
additively — no version bump, no change on your side. Requesting a scope the
user's wallet version doesn't know simply comes back ungranted, so write
your code to tolerate that from day one.