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

# Recovery

> Recover an account using guardians

## Overview

Social Recovery allows users to set one or multiple accounts as *guardians*. Guardians can recover access to the account by approving a change to the validator configuration.

For example, if a user loses access to their key, guardians are able to rotate the signer to a new ECDSA key. Or if a smart account has a multisig configuration, guardians can be used to recover a signer of the multisig or change the threshold.

Guardians can only update the validator configuration, they are not permitted to make any other transactions.

<Warning>Set guardians carefully! They can change the ownership of a smart account without any approval from the previous owner. There is no timelock for the recovery transaction. Prefer setting multiple trusted guardians with a higher signature threshold.</Warning>

<Note>Making recovery transactions requires setting up [ERC-4337](../advanced/erc4337).</Note>

<Note>Account recovery may result in multiple account calls, each of them should be done separately (batching is not supported).</Note>

## Initialization

To install a social recovery module during account deployment:

```ts {6-8} theme={null}
const rhinestoneAccount = await rhinestone.createAccount({
  owners: {
    type: 'ecdsa',
    accounts: [oldAccount],
  },
  recovery: {
    guardians: [guardianAccount],
  },
})
```

To install the module separately (i.e., when the account is already deployed):

```ts {3-6} theme={null}
import { enable as enableRecovery } from '@rhinestone/sdk/actions/recovery'

const setUpTransaction = await rhinestoneAccount.sendUserOperation({
  chain,
  calls: enableRecovery([guardianAccount]),
})
await rhinestoneAccount.waitForExecution(setUpTransaction)
```

### Multiple Guardians

You can also set multiple guardians for a single account, and use a custom signature threshold:

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

## Usage

<Tabs>
  <Tab title="ECDSA Account">
    To recover access to the account:

    ```ts {7,16-19} theme={null}
    import { recoverEcdsaOwnership } from '@rhinestone/sdk/actions/recovery'

    const recoveryCalls = await recoverEcdsaOwnership(
      address,
      {
        type: 'ecdsa',
        accounts: [newOwnerAccount],
      },
      chain,
    )
    for (const call of recoveryCalls) {
      const transaction = await rhinestoneAccount.sendUserOperation({
        chain,
        calls: [call],
        tokenRequests: [],
        signers: {
          type: 'guardians',
          guardians: [guardianAccountA],
        },
      })
      await rhinestoneAccount.waitForExecution(transaction)
    }
    ```

    This will prompt a signature from the guardian account, and submit a transaction on its behalf to update the ownership.
  </Tab>

  <Tab title="Passkey Account">
    To recover access to the account:

    ```ts {7-10,15,24-27} theme={null}
    import { recoverPasskeyOwnership } from '@rhinestone/sdk/actions/recovery'

    const recoveryCalls = await recoverPasskeyOwnership(
      address,
      // List of existing owners: those will be removed
      [
        {
          pubKeyX: BigInt(slice(passkeyAccountA.publicKey, 0, 32)),
          pubKeyY: BigInt(slice(passkeyAccountA.publicKey, 32, 64)),
        },
      ],
      // New owners: those will be added
      {
        type: "passkey",
        accounts: [passkeyAccountB],
      },
      chain
    );
    for (const call of recoveryCalls) {
      const transaction = await account.sendUserOperation({
        chain,
        calls: [call],
        tokenRequests: [],
        signers: {
          type: "guardians",
          guardians: [guardianAccountA],
        },
      });
      await account.waitForExecution(transaction);
    }
    ```

    This will prompt a signature from the guardian account, and submit a transaction on its behalf to update the ownership.
  </Tab>
</Tabs>
