> ## 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.

# Embedded Wallets Overview

> Offer non-custodial embedded wallets in your Android or iOS app with a modular SDK: a vendor-free core plus adapters for Turnkey, Portal, and Privy.

Use the Rain Client SDK to give your users a non-custodial embedded wallet and a Rain card from a single mobile integration.

The SDK is modular: a vendor-free core module handles the wallet, card, and collateral logic, and each wallet provider (Turnkey, Portal, or Privy) plugs in as a separate adapter module. You add only the adapter for the provider you use, so an unselected provider's vendor SDK never enters your app.

<Info>
  The Client SDK is separate from the [server-side Rain SDK](/sdks/overview), which wraps the Rain REST API for TypeScript, Go, and Python. The Client SDK runs on user devices and interacts with the blockchain directly.
</Info>

## What you can build

* **Create non-custodial wallets** for your users, where only the user can authorize transactions.
* [**Query balances and transaction history, and send tokens**](/sdks/embedded-wallets-balances-and-transactions).
* [**Withdraw from collateral**](/sdks/embedded-wallets-withdraw-collateral) with a single call.
* [**Back card spend**](/sdks/embedded-wallets-funding) with the user's collateral, funded on-chain.

Funds your users hold in the wallet don't back their card spend on their own: their card spend draws on their [Rain collateral](/sdks/embedded-wallets-funding).

## How custody works

A **non-custodial** wallet is one where only the user can authorize transactions. Neither Rain nor the wallet provider can move the user's funds on the user's behalf.

Your wallet provider secures the key material — for example, in a secure enclave (TEE) or as an encrypted key share on the user's device. No one can sign without the user's approval. Rain stores only wallet addresses. Rain can move a user's funds only within the limits set by the on-chain contract rules and the user's own signature.

Here's who holds what:

| Party               | Holds                                                                                 | Never holds                                         |
| ------------------- | ------------------------------------------------------------------------------------- | --------------------------------------------------- |
| **Your user**       | Sole authority to authorize transactions                                              | None — the user's own signature is never restricted |
| **Wallet provider** | The secured key material (in a secure enclave or as an encrypted on-device key share) | The ability to move funds without the user          |
| **Rain**            | Wallet addresses                                                                      | The ability to move a user's funds                  |

## Wallet providers

The SDK supports three wallet providers. Rain's managed Turnkey program is the recommended default: Rain provisions and configures [Turnkey](https://www.turnkey.com/) for you, so there's no separate wallet-provider contract to negotiate, and Turnkey secures keys in secure enclaves (TEE), authenticating users with passkeys or one-time passcodes. Contact [platform@rain.xyz](mailto:platform@rain.xyz) to enable it for your account.

Here's how they compare:

| Provider                           | Use when                                                  | How                                                                                 |
| ---------------------------------- | --------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| **Turnkey** (managed, recommended) | You want Rain to run wallet infrastructure end to end.    | The managed Turnkey adapter ships inside the core module: no extra dependency.      |
| **Portal**                         | You already integrate [Portal](https://www.portalhq.io/). | Add the Portal adapter module and pass your Portal session token.                   |
| **Privy**                          | You already integrate [Privy](https://www.privy.io/).     | Add the Privy adapter module and hand the SDK your authenticated `Privy` singleton. |

Each provider handles user authentication with its own SDK before Rain's SDK gets involved. See [Authentication](/sdks/embedded-wallets-authentication) for what each adapter needs from your app.

## Modules

The core module carries:

* The builder entry point (`RainSdk`) and `RainClient`
* The transaction builder and provider SPI
* Models, errors, and chain readers
* The built-in Rain API client
* The managed Turnkey adapter

Adapter modules depend on core; core depends on neither.

The module breakdown:

| Module         | iOS (SPM product)                | Android (Kotlin package)                      | Vendor dependency |
| -------------- | -------------------------------- | --------------------------------------------- | ----------------- |
| Core           | `rain-core-ios` (`RainCore`)     | `rain-core-android` (`com.rain.sdk`)          | Turnkey (bundled) |
| Portal adapter | `rain-portal-ios` (`RainPortal`) | `rain-portal-android` (`com.rain.sdk.portal`) | Portal            |
| Privy adapter  | `rain-privy-ios` (`RainPrivy`)   | `rain-privy-android` (`com.rain.sdk.privy`)   | Privy             |

## Requirements

Minimum platform and tooling versions:

| Platform | Minimum version                   | Package manager        |
| -------- | --------------------------------- | ---------------------- |
| Android  | SDK 28 (Android 9.0), Kotlin 1.8+ | Gradle (Maven Central) |
| iOS      | iOS 17+ / Swift 6.1+              | Swift Package Manager  |

## Installation

Add the core module plus the adapter(s) for the providers your app ships. A Turnkey-only integration needs just the core module.

<CodeGroup>
  ```swift Package.swift theme={null}
  dependencies: [
      // Turnkey apps: core alone is enough (managed Turnkey ships inside RainCore)
      .package(url: "https://github.com/SignifyHQ/rain-core-ios", from: "<version>"),
      // Portal apps: the adapter package (brings RainCore transitively)
      .package(url: "https://github.com/SignifyHQ/rain-portal-ios", from: "<version>"),
      // Privy apps: the adapter package (brings RainCore transitively)
      .package(url: "https://github.com/SignifyHQ/rain-privy-ios", from: "<version>"),
  ],
  targets: [
      .target(name: "YourApp", dependencies: [
          .product(name: "RainCore", package: "rain-core-ios"),      // Turnkey (and core APIs)
          .product(name: "RainPortal", package: "rain-portal-ios"),  // only if you use Portal
          .product(name: "RainPrivy", package: "rain-privy-ios"),    // only if you use Privy
      ])
  ]
  ```

  ```kotlin build.gradle.kts theme={null}
  dependencies {
      implementation("com.rain.sdk:rain-core-android:<version>")    // core + managed Turnkey
      implementation("com.rain.sdk:rain-portal-android:<version>")  // only if you use Portal
      implementation("com.rain.sdk:rain-privy-android:<version>")   // only if you use Privy
  }
  ```
</CodeGroup>

Rain provides the exact package coordinates and versions during onboarding. The modular artifacts publish with the first modular release.

<Note>
  On iOS, existing integrations can keep depending on [rain-sdk-ios](https://github.com/SignifyHQ/rain-sdk-ios): its `RainSDK` umbrella product re-exports `RainCore` + `RainPortal`, so `import RainSDK` keeps compiling. It exists for migration only and doesn't include `RainPrivy`.
</Note>

## Source code

Both SDKs are open source. Review the implementation yourself, or open an issue on GitHub:

<Columns cols={2}>
  <Card title="rain-sdk-ios" icon="github" href="https://github.com/SignifyHQ/rain-sdk-ios" horizontal />

  <Card title="rain-sdk-android" icon="github" href="https://github.com/SignifyHQ/rain-sdk-android" horizontal />
</Columns>

## What's next

<Columns cols={3}>
  <Card title="Common Flows" icon="route" href="/sdks/embedded-wallets-common-flows">
    See how a full integration fits together, end to end.
  </Card>

  <Card title="Authentication" icon="key" href="/sdks/embedded-wallets-authentication">
    Authenticate wallets with your provider and mint session tokens.
  </Card>

  <Card title="Set Up a Wallet" icon="wallet" href="/sdks/embedded-wallets-setup">
    Build the SDK and create a user's wallet.
  </Card>
</Columns>
