# Recover via Email / SMS

Recover your Safe account using [Candide Guardian](https://docs.candide.dev/wallet/recovery/auth-api.md) when you've lost access to your owner keys. This guide covers the complete recovery process using email and SMS verification.

> If you haven't set up Candide Guardian yet, see the [Add Candide Guardian](https://docs.candide.dev/wallet/plugins/add-candide-guardian.md) guide first.

## What You'll Need[​](#what-youll-need "Direct link to What You'll Need")

Before starting recovery, ensure you have:

* **Access to registered recovery methods** (email or SMS)
* **Safe account address** to recover
* **New private key** to replace the lost key
* **Recovery service access** (Candide Guardian enabled)

## Recovery Overview[​](#recovery-overview "Direct link to Recovery Overview")

The recovery process consists of five key steps:

1. **Generate New Owner Key** - Create a replacement for the lost key
2. **Request Guardian Signature** - Initiate recovery through the Guardian service
3. **Verify All Channels** - Confirm identity through ALL registered methods
4. **Execute Recovery** - Submit the recovery transaction
5. **Finalize Recovery** - Complete ownership transfer after the grace period

## Quickstart[​](#quickstart "Direct link to Quickstart")

> You can also [fork the complete code](https://github.com/candidelabs/safe-recovery-service-sdk/blob/main/examples/03-recovery-flow/index.ts) and follow along.

### Installation[​](#installation "Direct link to Installation")

* npm
* yarn

```
npm i abstractionkit safe-recovery-service-sdk viem
```

```
yarn add abstractionkit safe-recovery-service-sdk viem
```

### Configure Environment[​](#configure-environment "Direct link to Configure Environment")

* .env

```
# Network Configuration
CHAIN_ID=11155111
BUNDLER_URL=https://api.candide.dev/public/v3/11155111
NODE_URL=https://ethereum-sepolia-rpc.publicnode.com

# Recovery Service URL
# Get access here: https://app.formbricks.com/s/brdzlw0t897cz3mxl3ausfb5
RECOVERY_SERVICE_URL= 
```

## Step 1: Initialize Recovery Service[​](#step-1-initialize-recovery-service "Direct link to Step 1: Initialize Recovery Service")

```
import { RecoveryByCustodialGuardian } from "safe-recovery-service-sdk";
import { privateKeyToAccount, generatePrivateKey } from 'viem/accounts';

const chainId = BigInt(process.env.CHAIN_ID as string);
const serviceUrl = process.env.RECOVERY_SERVICE_URL as string;

// Initialize recovery service
const custodialGuardianService = new RecoveryByCustodialGuardian(serviceUrl, chainId);

// Generate new owner key to replace the lost one
const newOwnerPrivateKey = generatePrivateKey();
const newOwner = privateKeyToAccount(newOwnerPrivateKey);
```

## Step 2: Request Guardian Signature Challenge[​](#step-2-request-guardian-signature-challenge "Direct link to Step 2: Request Guardian Signature Challenge")

Request a recovery signature from Candide Guardian:

```
// Request Candide Guardian signature for recovery
const signatureRequest = await custodialGuardianService.requestCustodialGuardianSignatureChallenge(
    safeAccountAddress,
    [newOwner.address], // New owner array
    1 // New threshold
);
```

## Step 3: Verify All Recovery Channels[​](#step-3-verify-all-recovery-channels "Direct link to Step 3: Verify All Recovery Channels")

You must verify **ALL** registered channels to complete recovery. Submit the OTP codes received:

* Email Verification
* SMS Verification
* Verify All Channels

```
// Find the email authentication challenge
const emailAuth = signatureRequest.auths.find(auth => auth.channel === 'email');

// Enter OTP from email
const emailOtp = "123456"; // Replace with actual OTP

const verificationResult = await custodialGuardianService.submitCustodialGuardianSignatureChallenge(
    signatureRequest.requestId,
    emailAuth.challengeId,
    emailOtp
);
```

```
// Find the SMS authentication challenge
const smsAuth = signatureRequest.auths.find(auth => auth.channel === 'sms');

// Enter OTP from SMS
const smsOtp = "654321"; // Replace with actual OTP

const verificationResult = await custodialGuardianService.submitCustodialGuardianSignatureChallenge(
    signatureRequest.requestId,
    smsAuth.challengeId,
    smsOtp
);
```

```
// Verify ALL registered channels (required for recovery)
let verificationResult;

for (const auth of signatureRequest.auths) {
    // Enter OTP for current channel
    const recoveryOtpCode = "123456"; // Replace with actual OTP from respective channel
    
    verificationResult = await custodialGuardianService.submitCustodialGuardianSignatureChallenge(
        signatureRequest.requestId,
        auth.challengeId,
        recoveryOtpCode
    );
}
```

## Step 4: Execute Recovery Transaction[​](#step-4-execute-recovery-transaction "Direct link to Step 4: Execute Recovery Transaction")

After verifying all channels, execute the recovery with the obtained guardian signature:

```
// Execute recovery using the service
const recoveryRequest = await custodialGuardianService.createAndExecuteRecoveryRequest(
    safeAccountAddress,
    [newOwner.address], // New owner array
    1, // New threshold
    verificationResult.custodianGuardianAddress as string,
    verificationResult.custodianGuardianSignature as string
);
```

## Step 5: Finalize Recovery After Grace Period[​](#step-5-finalize-recovery-after-grace-period "Direct link to Step 5: Finalize Recovery After Grace Period")

Wait for the grace period to expire, then finalize the recovery:

```
import { SocialRecoveryModuleGracePeriodSelector } from "abstractionkit";
import { RecoveryByGuardian } from "safe-recovery-service-sdk";

// Wait for grace period (3 minutes)
await new Promise(resolve => setTimeout(resolve, 3 * 60 * 1000));

// Initialize recovery service for finalization
const recoveryService = new RecoveryByGuardian(
    serviceUrl,
    chainId,
    SocialRecoveryModuleGracePeriodSelector.After3Minutes
);

// Finalize the recovery
const finalizationResult = await recoveryService.finalizeRecoveryRequest(recoveryRequest.id);
```

## Complete Working Example[​](#complete-working-example "Direct link to Complete Working Example")

Full Recovery Flow Example

examples/03-recovery-flow/index.ts

```
loading...
```

[See full example on GitHub](https://github.com/candidelabs/safe-recovery-service-sdk/blob/main/examples/03-recovery-flow/index.ts)

## What's Next[​](#whats-next "Direct link to What's Next")

* [Recovery Alerts Guide](https://docs.candide.dev/wallet/plugins/recovery-alerts-guide.md): set up email and SMS notifications so account owners are alerted if a recovery is ever initiated
