Before you begin
Install the Rain SDK and configure a Base Sepolia RPC endpoint. All wallet operations in this quickstart run directly in your iOS application. You do not need a Rain API key.1
Create the provider
RainProvider is the Rain wallet: it owns login, wallet creation, and sessions. The wallet backend’s identity is embedded in the SDK, so the default configuration is the product. Create one provider per app and keep it for the app’s lifetime.RainWalletConfig:2
Log in: restore a session or start a login
On launch, wait for the SDK to restore a persisted session. A returning user skips the code entirely.
wallet.authState publishes .loading, .authenticated, or .unauthenticated on every change, and wallet.currentAuthState() is its snapshot, so a login screen can bind to it instead of polling.3
Send a one-time code
Send a login code to the user’s email address or phone number. The contact is the account’s identity: a first login with it signs the user up, and later logins with the same contact find the same account.Calling
sendLoginCode again for the same contact issues a new code and replaces the pending one, which is how you implement Resend code. A blank email or a phone number that isn’t a valid international number throws RainError.invalidConfig before anything leaves the device.4
Confirm the code and create the wallet
Pass the code the user typed. On a first login the SDK signs the user up and creates one wallet holding an Ethereum account and a Solana account, from a single seed, in the same request. On a returning login it finds the existing account.A wrong code keeps the pending challenge, so the user can retype it without requesting a new one. Codes expire after 5 minutes and lock after 3 wrong attempts.
The user is logged in and their wallet exists. A successful login also ends the user’s sessions on other devices; the signed-out device’s
onSessionExpired fires on its next call.5
Build the SDK and resolve the wallet
Register the provider with the chains you want to use and build the SDK. Then resolve the wallet-bound Resolving before a session is live throws
RainClient. Resolution suspends once, while the SDK materializes the wallet, and is cached afterwards.RainError.tokenExpired (RAIN_201). Send the EVM address (and the Solana address, if you use Solana) to your backend: creating the user’s Rain application requires it. See Wallet creation.6
Send a transaction
Fund the wallet with testnet USDC first (the Circle faucet supports Base Sepolia), then send some of it to another address you control. Amounts are Gas is sponsored by default, so the wallet doesn’t need ETH to send. Native sends use
Decimal in human units; the SDK resolves the token’s decimals and converts exactly.client.sendNative(chainId:to:amount:).You’ve logged in, created a wallet, and sent a token. Everything else on
RainClient follows the same shape: balances and history, receiving funds, and card funding.Log in with a passkey instead
Users can log in with an existing passkey or add a passkey to their account for future authentication. ConfigurepasskeyDomain during SDK setup. The anchor parameter specifies the window used to display the system passkey prompt.
signUpWithPasskey(anchor:) only when creating a new account. Returning users should use loginWithPasskey(anchor:) to access their existing wallet.
See Authentication options for additional configuration and recovery guidance.
Log out and clean up
Uselogout() to end the user’s session and close() to release SDK resources.
rain.close() permanently closes the SDK instance. Create a new RainSdk instance before the next login. Use rain.reset() instead if you only need to clear resolved clients while keeping the provider active.
Using an existing wallet provider
If your application already uses Portal, Privy, or your own Turnkey organization, register the corresponding provider adapter instead ofRainProvider. Authentication and session management remain with your existing provider. Subsequent wallet operations use the same RainClient interface.
What’s next
Features
What each platform and chain supports.
Testing
Testnets, test tokens, and the pre-go-live checklist.
Error reference
Every
RAIN_* code and how to handle it.