> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrating from Privy

> Move an existing Privy embedded-wallet app over to Helius Wallet-as-a-Service

Migrating from Privy is a **code migration, not a wallet migration**. You swap Privy's provider and hook for Helius's — the mental model (embedded, non-custodial, social/passkey login) is the same. What does **not** carry over is your users' existing wallets: Privy wallets can't be imported into Turnkey, so every user gets a **new Helius embedded wallet the first time they sign in** to your app.

The other big change is the economics: Privy bills per monthly-active-wallet on top of your RPC, while Helius bills 200 credits per signature through the [credits](/billing/credits) you already have.

## What migrates — and what doesn't

* **Migrates (your integration):** the provider, hook, sign-in config, and RPC. This is the code swap in the [steps below](#migrate-your-integration) — usually a few hours of work.
* **Does not migrate (your users' wallets):** existing Privy wallets, keys, and balances. Turnkey can't import them, so each user creates a fresh Helius embedded wallet on first sign-in.

<Warning>
  **If you have 1,000 Privy users with funds:** after you migrate, each one signs
  in and gets a **new, empty** Helius embedded wallet at a different address.
  Their Privy balances stay in the old wallets. Moving funds is a separate,
  user-initiated step you orchestrate (see [Your users' wallets and
  funds](#your-users-wallets-and-funds)) — neither Helius nor Turnkey can move
  funds on a user's behalf.
</Warning>

## Privy Mappings to Helius WaaS

| Privy                                    | Helius WaaS                                                                              |
| ---------------------------------------- | ---------------------------------------------------------------------------------------- |
| `PrivyProvider` with `appId`             | `HeliusWalletProvider` with `{ apiKey }`                                                 |
| `usePrivy()` — `login`, `logout`, `user` | `useHeliusWallet()` — `login`, `logout`, `user`, `status`                                |
| `useSolanaWallets()` / embedded wallet   | `address`, `signTransaction`, `signAndSendTransaction`, `signMessage` from the same hook |
| Login methods set in the Privy dashboard | Sign-in methods set in Helius dashboard (**WaaS → Configuration**)                       |
| `exportWallet()`                         | `exportWallet()`                                                                         |
| Per-MAU billing + separate RPC provider  | One bill: 200 credits / signature via Helius credits, RPC included                       |

## Migrate your integration

These steps swap your code from Privy to Helius. None of them touch end-user wallets — that's covered [below](#your-users-wallets-and-funds).

<Steps>
  <Step title="Swap the provider">
    Replace `PrivyProvider` with `HeliusWalletProvider` and pass your Helius API key instead of your Privy `appId`. See [Setup](/waas/quickstart#setup).
  </Step>

  <Step title="Swap the hook">
    Replace `usePrivy()` / `useSolanaWallets()` calls with `useHeliusWallet()`. `login`, `logout`, `user`, and `exportWallet` map directly; signing moves onto the same hook (`signTransaction`, `signAndSendTransaction`, `signMessage`).
  </Step>

  <Step title="Move auth config to the dashboard">
    Configure your sign-in methods in the dashboard under **WaaS → Configuration** rather than in provider props — see [Configure sign-in methods](/waas/configuration#configure-sign-in-methods).
  </Step>

  <Step title="Point RPC at Helius">
    Sending already routes through Helius. Drop your standalone RPC provider config and use the `connection` / `rpcUrl` from the hook, or add the [route handler](/waas/quickstart#setup) for Sender-optimized landing.
  </Step>
</Steps>

## Your users' wallets and funds

On first sign-in after you ship the swap, each user gets a **brand-new embedded Helius wallet** — a different address from their Privy wallet, with a zero balance. Old Privy wallets and their funds are untouched.

If you need users to keep their existing balances, plan a **migration window**:

<Steps>
  <Step title="Surface the new address">
    Show each signed-in user their new Helius address (`address` from `useHeliusWallet()`).
  </Step>

  <Step title="Have users move their funds">
    Users transfer funds from their old Privy wallet to their new Helius address. This is a per-user, user-initiated action — neither Helius nor Turnkey can move funds on their behalf.
  </Step>

  <Step title="Retire the old integration">
    Once users are on their Helius wallets, remove the Privy SDK.
  </Step>
</Steps>

<Note>
  **Can't users just keep using their existing wallet instead?** Not as a
  replacement for the embedded wallet. External wallet is offered as a
  **sign-in method** — it authenticates a user into a Helius embedded wallet, it
  doesn't operate the external wallet's keys directly. Signing straight from an
  external wallet would bypass Helius entirely (no Turnkey signing, no metering),
  so it isn't a substitute for the embedded wallet your app runs on.
</Note>
