> ## Documentation Index
> Fetch the complete documentation index at: https://rain-sandbox-trial.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Testing

> Test your Rain embedded wallet integration using public blockchain testnets and Rain's sandbox environment before moving to production.

Wallet authentication, creation, and transactions use the same SDK workflows in testing and production. Rain's sandbox issuing environment lets you test the integration with card issuing and collateral management.

## Testing environments

During beta, embedded wallets connect to Rain's **sandbox** wallet infrastructure. There is no environment setting in the SDK. Rain will coordinate the transition to production with you before launch. Blockchain networks are configured separately using chain IDs and RPC endpoints. Your application can connect to both mainnet and testnet networks within the same SDK instance.

| Component | Sandbox | Production |
| - | - | - |
| Wallet infrastructure | Rain sandbox | Rain production |
| Rain issuing API | `https://api-dev.rain.xyz` | `https://api.rain.xyz` |
| Blockchain networks | Configured testnets, including Base Sepolia, Arbitrum Sepolia, and Solana Devnet | Configured mainnet networks |

<Warning>
  **Important:** Authentication uses real email addresses and phone numbers in both environments. Use contact information you control when testing. Wallet accounts created in the sandbox are separate from production accounts and do not transfer automatically.
</Warning>

## Set up a test wallet

<Steps>
  <Step title="Register testnet endpoints">
    Build the SDK with the testnets you'll use. Base Sepolia is the best first choice: the Rain wallet can send there with sponsored gas, Rain's sandbox supports collateral contracts on it, and Circle runs a USDC faucet for it.

    ```swift theme={null}
    let rain = try RainSdk.builder()
        .rpcEndpoints([
            RainChain.baseSepolia: "https://sepolia.base.org",
            RainChain.solanaDevnet: "https://api.devnet.solana.com",
        ])
        .register(RainProvider())
        .build()
    ```
  </Step>

  <Step title="Log in and create the wallet">
    Run the one-time-code flow from the [quickstart](/sdks/embedded-wallets/quickstart/ios) with a test email address. The first login creates the wallet; read its addresses with `getWalletAddress`.
  </Step>

  <Step title="Fund the wallet with test tokens">
    | Asset | Where to get it |
    | - | - |
    | Testnet USDC (Base Sepolia, Arbitrum Sepolia, Solana devnet) | [Circle faucet](https://faucet.circle.com/) |
    | Base Sepolia ETH (only needed with gas sponsorship off) | [Base faucets](https://docs.base.org/base-chain/tools/network-faucets) |
    | Devnet SOL (needed for token-account rent) | [Solana faucet](https://faucet.solana.com/) or `solana airdrop 1 <address> --url devnet` |
    | rUSD, Rain's sandbox collateral token | Mint from the block explorer, see [Mint test tokens for collateral](/docs/sandbox-mint-test-tokens-for-collateral) |

    The sandbox rUSD contracts aren't in the SDK's built-in token registry. On EVM chains the SDK reads their decimals on-chain, so sends work without extra setup; register them with `registerTokens` if you want a symbol and name in balance reads.
  </Step>

  <Step title="Send and verify">
    Send a token to a second address, then check the result on the block explorer (`https://sepolia.basescan.org/tx/<hash>`). Confirm the same transaction appears in `getTransactions` for the chain.
  </Step>
</Steps>

## What you can test

Rain's sandbox supports testing the following wallet and card workflows.

* **Authentication:** Test account creation and login using email and SMS codes, invalid code handling (`RAIN_203`), code resends, session restoration across app launches, logout, and login on a second device that ends the first device's session. Passkeys on iOS require a device or simulator signed into iCloud Keychain and an associated domain configured at `https://<your-domain>/.well-known/apple-app-site-association`; on Android they require a device or emulator with a passkey provider (Google Password Manager signed into a Google account) and an `assetlinks.json` at your domain that lists the fingerprint of the certificate signing your test build.

* **Wallet operations:** Retrieve EVM and Solana addresses, check balances, view transaction history, and test sponsored transactions on Base Sepolia and Solana devnet. Verify that sending on unsupported networks, such as Avalanche Fuji, returns `RAIN_104`. Test key export in all three supported formats.

* **Card funding and settlement:** Test the full workflow against the sandbox issuing API. Create a user application with the wallet address, complete sandbox KYC, and receive the `contract.created` webhook. Send rUSD to the collateral contract's `depositAddress`, verify that spending power updates, create a card, and simulate [card authorizations](https://docs.rain.xyz/docs/simulating-transactions/card-authorizations) and [settlement](https://docs.rain.xyz/docs/simulating-transactions/settlement). You can also simulate deposits using [collateral funding](https://docs.rain.xyz/docs/simulating-transactions/collateral-funding) instead of submitting an onchain transfer.

* **Collateral withdrawals:** Request an admin signature from the sandbox API and execute `withdrawCollateral`. Verify the resulting transaction using a blockchain explorer.

## What you cannot test in the sandbox

Some production behaviors are unavailable or require additional configuration.

* **Production network fees:** Testnet transactions do not reproduce actual mainnet transaction costs or production billing for gas sponsorship. See [Gas sponsorship](/docs/embedded-wallets/gas-sponsorship).
* **Production accounts:** Sandbox wallets and authentication sessions are separate from production accounts.
* **Wallet webhooks:** Wallet events, including wallet creation, backup enrollment, and key export, are not available during beta. Use the SDK and Rain API to retrieve the information you need. See [**Transaction webhooks and history**](/docs/embedded-wallets/transaction-webhooks).
* **Real time funding:** This feature can only be tested if Rain has enabled it for your sandbox program.

## Before going live

Complete the following verification steps before launching your integration.

<AccordionGroup>
  <Accordion title="Authentication and sessions">
    * [ ] **Session expiration:** Handle `onSessionExpired` by returning users to the login screen on the main thread.
    * [ ] **Invalid login codes:** Handle `RAIN_203` without leaving the code entry screen, and provide an option to resend the code.
    * [ ] **Passkey login:** Ensure returning users can sign in with an existing passkey without accidentally creating a new account.
    * [ ] **Backup authentication:** Prompt users who sign up with a passkey to add a verified email address or phone number. See [Backup and recovery](/docs/embedded-wallets/backup-and-recovery).
    * [ ] **Passkey configuration:** Verify that your production passkey domain and association files are configured correctly: the Apple App Site Association (AASA) file and associated domain entitlement on iOS, and an `assetlinks.json` listing your release and Play App Signing certificate fingerprints on Android. You cannot change the domain after launch without affecting existing passkeys.
    * [ ] **Session restoration:** Call `awaitSessionRestore` before determining whether to display the login screen.
  </Accordion>

  <Accordion title="Wallet and transactions">
    * [ ] **Production RPC endpoints:** Configure mainnet RPC endpoints using a node provider with an appropriate service level agreement rather than public endpoints.
    * [ ] **Blockchain support:** Verify that every network used for card funding supports outbound transactions. Otherwise, disable sending for unsupported networks. See [Blockchain support](/sdks/embedded-wallets/features#blockchain-support).
    * [ ] **Transaction errors:** Handle `RAIN_402`, `RAIN_403`, `RAIN_405`, and `RAIN_302` as distinct outcomes. See [Error reference](/sdks/embedded-wallets/error-reference).
    * [ ] **Solana account creation:** Verify that Solana transfers account for the SOL required to create a recipient's token account, which gas sponsorship does not cover.
    * [ ] **Gas sponsorship:** If sponsorship is disabled, display estimated network fees and handle `RAIN_402` when the wallet lacks sufficient native tokens.
  </Accordion>

  <Accordion title="Card funding">
    * [ ] **Wallet registration:** Include the user's EVM wallet address, and Solana address where applicable, on their Rain application before submitting it for KYC.
    * [ ] **Backend security:** Retrieve collateral contracts and admin withdrawal signatures through your backend using your Rain API key. Never expose the API key in your application.
    * [ ] **Collateral deposits:** Display the contract's `depositAddress`, or `proxyAddress` when no deposit address is returned. Never direct collateral deposits to the user's wallet address.
    * [ ] **Program configuration:** Confirm whether your program is [Rain-managed or partner-managed](/docs/embedded-wallets/flow-of-funds). The SDK's collateral withdrawal methods apply to Rain managed programs.
  </Accordion>

  <Accordion title="Keys and recovery">
    * [ ] **Secure key export:** Require biometric or device passcode authentication before key export. Protect the display against screenshots and ensure exported secrets are never logged, stored, or transmitted to your backend. See [Key export](/docs/embedded-wallets/key-export).
    * [ ] **Account recovery:** Ensure your support procedures cover users who lose their devices, including login through an existing email address or phone number and guidance for users who previously exported recovery credentials.
  </Accordion>

  <Accordion title="Release engineering">
    * [ ] **iOS dependencies:** Link `rain-wallet-ios` and install a provider adapter only if your integration requires one.
    * [ ] **Android dependencies:** Keep all Rain modules on the same version, configure R8 to retain the SDK's consumer rules, and use `minSdk` 28 or higher.
    * [ ] **Sensitive data protection:** Confirm that crash reporting and analytics tools exclude exported keys, recovery phrases, authentication codes, and sensitive error details that may contain wallet addresses.
    * [ ] **Production activation:** Confirm with Rain that your program has been migrated to the production wallet infrastructure before launching.
  </Accordion>
</AccordionGroup>

## What's next

<Columns cols={2}>
  <Card title="Error reference" icon="circle-exclamation" href="/sdks/embedded-wallets/error-reference">
    Every code, what triggers it, and what to do.
  </Card>

  <Card title="Card funding and settlement" icon="credit-card" href="/docs/embedded-wallets/card-funding-and-settlement">
    The end-to-end Rain-managed flow you'll test against the sandbox.
  </Card>
</Columns>
