Rising Tide Developers
Authentication

User Identity

How end-users authenticate in Rising Tide Protocol - a hosted account with a wallet made for them, or BYOW (Bring Your Own Wallet).

End-users authenticate with the protocol to establish a Stacks identity. Two modes are supported.

Hosted account (Privy)

The user signs in with Google or X - @rising-tide/ui offers those two and nothing else, because an invite binds to one of them and an account that cannot claim its invite arrives empty. On first sign-in the protocol creates a Stacks-capable wallet for them through Privy, and every transaction they make is signed server-side with no wallet prompt.

  • No wallet download required
  • Best for users new to Stacks

BYOW (Bring Your Own Wallet)

BYOW lets users connect an existing Stacks wallet (Leather, Xverse, etc.). The user signs a challenge to prove ownership of their address, and signs each transaction in the wallet.

  • Works with any Stacks-compatible wallet
  • The app never holds the private key
  • Best for experienced Stacks users

AuthenticationChoice

The AuthenticationChoice component presents the hosted sign-in and, when it is offered, the wallet option. The wallet option is hidden by default. It shows when the build does not set NEXT_PUBLIC_ENABLE_BYOW="false" AND either the server flag App.byowEnabled is on for this app (it defaults off; an operator flips it in rt-admin) or the page was opened with ?byow=1. Pass enableWalletAuth to override that composed default in either direction.

import { AuthenticationChoice } from "@rising-tide/ui/auth";

function LoginPage() {
  return <AuthenticationChoice appName="My App" appIconSrc="/my-app-mark.png" />;
}
PropPurpose
appNameThe heading. Defaults to Rising Tide
appIconSrcThe icon, served from this app's own public/. Defaults to /rt-logo-square-t.png, which is a path convention - a client app serves its own mark here
audience"consumer" (default) shows the education block; "operator" drops it
enableWalletAuthExplicit override for the wallet option
inlineRender inline rather than as a dialog body
onConnectStartCalled when a wallet connection begins

There is no description prop; the dialog shows a heading and no paragraph. AuthenticationChoice has no success callback either - it hands off to the shared auth stack. Post-signup routing is configured once at the provider level (onSignupComplete / signupRedirect on RisingTideProviders). See Provider Setup.

User identity model

After authentication, the protocol has a User record with:

  • stxAddress - the primary identifier
  • privyUserId - if authenticated via a hosted account (null for BYOW)
  • displayName - always present; signup falls back to User <last four of the address> when the welcome form is skipped
  • createdAt - first seen timestamp

Roles are held in a separate table and resolved to a flat entitlements list on the client object - see Protocol User and RBAC.

Cross-subdomain sessions

On any *.risingtide.app host the provider sets the Privy cookie domain to .risingtide.app, so a user signed in on one subdomain is authenticated on the others without signing in again. Each app's own session token lives in its origin's local storage, so signing out on one subdomain does not sign the others out until their tokens expire.