Skip to main content

Add an Social Account as a Recovery Method using Magic

Magic is a popular hosted wallet provider for EOAs. It enable users to login using various authentication methods like Social Logins and Email OTP.

To leverage the full potential of Account Abstraction, you can combine Magic with AbstractionKit to enable email / social recovery experience, while using a Smart Account as the smart wallet to sponsor gas for users, batch transactions, and more.

Below are some relevant links that provide additional information and resources which you might find helpful as you go through this guide.

Installation

Install required dependencies

npm i abstractionkit && magic-sdk

Create a Magic account

Create an account and get the API key on Magic's Dashboard. You will need the PUBLISHABLE API KEY.

Configure .env file

Configure the values you created from Magic dashboard in an .env file

// magic
PUBLISHABLE_API_KEY=

// candide
BUNDLER_URL=
JSON_RPC_NODE_PROVIDER=
OWNER_PUBLIC_ADDRESS=
NEW_OWNER_PUBLIC_ADDRESS=

Setup Guardian

import { 
SafeAccountV0_3_0 as SafeAccount,
SocialRecoveryModule,
} from "abstractionkit";
import { Magic } from "magic-sdk";
import { BrowserProvider } from 'ethers';

const magic = new Magic(process.env.PUBLISHABLE_API_KEY);
const provider = new BrowserProvider(magic.rpcProvider);
const guardianSigner = await provider.getSigner();

const smartAccount = SafeAccount.initializeNewAccount([process.env.OWNER_PUBLIC_ADDRESS]);

const srm = new SocialRecoveryModule();
const enableModuleTx = srm.createEnableModuleMetaTransaction(
smartAccount.accountAddress
);
const addGuardianTx = srm.createAddGuardianWithThresholdMetaTransaction(
smartAccount.accountAddress,
guardianSigner.address, // Magic Guardian Address
1n //threshold
);

let userOperation = await smartAccount.createUserOperation(
[enableModuleTx, addGuardianTx],
process.env.JSON_RPC_NODE_PROVIDER,
process.env.BUNDLER_URL,
);
info

To use MagicSigner in your app's client, you must ensure the window object is defined. For example, use magic in webapps and not node scripts.

Initiate Recovery

import { SafeAccountV0_2_0 as SafeAccount } from "abstractionkit";

const initiateRecoveryMetaTx = createConfirmRecoveryMetaTransaction(
smartAccount.address,
[process.env.NEW_OWNER_PUBLIC_ADDRESS],
1, // new threshold
true, // whether to auto-start execution of recovery
);

// make sure to fund the guardian address on magic
// otherwise, you can make the guardian a smart account from the start
// so you are able to sponsor the gas!
const sendTx1 = guardianSigner.sendTransaction({
to: initiateRecoveryMetaTx.to,
data: initiateRecoveryMetaTx.data,
value: 0,
});

Finilize Recovery

Wait for recovery period to pass before finilizing

const finalizeRecoveryMetaTx = createFinalizeRecoveryMetaTransaction(smartAccount.accountAddress)

// Anyone can call the finilize function after the grace period is over
const sendTx2 = await guardianSigner.sendTransaction({
to: finalizeRecoveryMetaTx.to,
data: finalizeRecoveryMetaTx.data,
})