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

# Set up recovery

> Set up EVM guardian recovery or a Solana recovery authority.

EVM social recovery lets one or more guardian accounts rotate the smart account's owner-validator configuration. Guardians cannot send normal transactions, but they can replace owners without approval from the current owner.

<Warning>
  There is no recovery time delay. A guardian threshold can take ownership
  immediately. Prefer several independently controlled guardians and a threshold
  greater than one.
</Warning>

This SDK flow is separate from [managed wallet recovery](/wallets/recovery/set-up). Managed recovery verifies a user's email or OAuth identity and registers a new app-origin passkey. The Custom signer flow below installs accounts you control as on-chain guardians.

Follow the [Custom signer quickstart](/wallets/custom-signer/quickstart) first. For EVM guardian recovery, configure a production bundler as described in [ERC-4337](/wallets/custom-signer/configuration/erc-4337); it uses UserOperations, not Rhinestone intents. Solana recovery uses the [authority-management procedure below](#solana-enroll-a-recovery-key), without a bundler.

## EVM: install during account creation

Add recovery to the account configuration:

```ts theme={null}
const rhinestoneAccount = await rhinestone.createAccount({
  evm: {
    owners: {
      type: "ecdsa",
      accounts: [ownerAccount],
    },
    recovery: {
      guardians: [guardianAccountA, guardianAccountB, guardianAccountC],
      threshold: 2,
    },
  },
});
```

The threshold defaults to `1`. Recovery is installed with the account's other modules when the account is deployed on a chain.

## Install on an existing account

Install the recovery validator with an owner-signed UserOperation:

```ts theme={null}
import { enable as enableRecovery } from "@rhinestone/sdk/actions/recovery";

const result = await rhinestoneAccount.sendUserOperation({
  chain,
  calls: [
    enableRecovery([guardianAccountA, guardianAccountB, guardianAccountC], 2),
  ],
});
await rhinestoneAccount.waitForExecution(result);
```

Set up recovery on every chain where the account needs it. Module installation on one chain does not install it elsewhere.

## Nexus constraints

Nexus accounts must use Ownable V0 as both their configured owner validator and the recovery target:

```ts theme={null}
const ownableV0Address = "0x2483da3a338895199e5e538530213157e931bf06";

const rhinestoneAccount = await rhinestone.createAccount({
  evm: {
    account: { type: "nexus" },
    owners: {
      type: "ecdsa",
      accounts: [ownerAccount],
      module: ownableV0Address,
    },
    recovery: {
      guardians: [guardianAccount],
    },
  },
});
```

An existing Nexus account using the default owner validator must migrate while its current owner is still available. Adding `recovery` to the local SDK configuration does not migrate an already deployed account.

<Warning>
  Guardian recovery does not support EIP-7702 Nexus accounts. Recovery modules
  cannot revoke the EOA's authority over its delegated account.
</Warning>

## Solana: enroll a recovery key

Solana uses Swig authority roles, not the EVM guardian validator. This procedure enrolls one secp256k1 recovery key; it does not provide guardian thresholds, a delay, or Smart Session restrictions. The configured Solana owner is one viem secp256k1 account or WebAuthn account, not an Ed25519 signer. See [Solana support](/wallets/custom-signer/solana-support) for scope.

Before enrollment, save both `id` and `swig` from `createSolanaSwigId()`, configure that `swig` with the intended root owner, and call `deploy('solana', solanaDevnet, { swigId: id })`. Do not prefund a predictable, undeployed address. Deployment returning `true` can mean the Swig already existed; it does not confirm the configured owner's role. Verify the on-chain root key and permissions before funding. The root is permanent and cannot be removed.

This example continues a deployed managed Solana `solanaAccount` and a securely held viem local `recoverySigner`. For a remote signer, enroll its secp256k1 public key as hex instead; an EVM address is not a public key. Persist the recovery public key and Swig identity, never the private key in client storage.

```ts theme={null}
import { addEcdsaKey, solanaDevnet } from '@rhinestone/sdk/solana'

const enrollRecovery = {
  destination: {
    chain: solanaDevnet,
    authority: addEcdsaKey(recoverySigner.publicKey, {
      permission: 'manageAuthority',
    }),
  },
}

const prepared = await solanaAccount.prepareTransaction(enrollRecovery)
const signed = await solanaAccount.signTransaction(prepared)
await solanaAccount.waitForExecution(
  await solanaAccount.submitTransaction(signed),
)

const role = await solanaAccount.getAuthorityStatus(enrollRecovery)
if (role.status !== 'applied') {
  throw new Error('Recovery role is missing or has conflicting permissions')
}
```

`getAuthorityStatus` checks this specific authority change, not global account readiness. `conflict` is not success. Authority changes use the shared intent lifecycle and are always gas-sponsored, including role rent; they do not take `source` or `sponsored`.

<Warning>
  Both `manageAuthority` and `all` can grant `all` to another key and take over
  the wallet. Treat the recovery key as a root-level secret, even though
  `manageAuthority` cannot spend directly. Recovery cannot revoke a compromised
  permanent root; move assets to a new wallet if the root is compromised.
</Warning>

Continue with [Recover an account](/wallets/custom-signer/recovery/recover-an-account).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.