Email OTP Authentication
Email OTP authentication allows you to log in and sign up users using an email address. Your users will receive six-digit code in their inbox which they can enter in your site to complete login.
For setting up an account config, see the Signer Quickstart.
Authenticate a user
import { import signersigner } from "./signer";
// send the email
// Promise resolves when the user is fully authenticated (OTP + optional MFA),
// even if final step completes in another tab/window
await import signersigner.anyauthenticate({
type: stringtype: "email",
emailMode: stringemailMode: "otp",
email: stringemail: "[email protected]",
});
// later once the user has entered the code from their email
// Promise resolves when the user is fully authenticated (OTP + optional MFA),
// even if final step completes in another tab/window
await import signersigner.anyauthenticate({
type: stringtype: "otp",
otpCode: stringotpCode: "123456",
});
import { class AlchemyWebSignerA SmartAccountSigner that can be used with any SmartContractAccount
AlchemyWebSigner } from "@account-kit/signer";
export const const signer: AlchemyWebSignersigner = new new AlchemyWebSigner(params: AlchemySignerParams): AlchemyWebSignerInitializes an instance with the provided Alchemy signer parameters after parsing them with a schema.
AlchemyWebSigner({
client: ({
connection: {
apiKey: string;
rpcUrl?: undefined;
jwt?: undefined;
} | {
jwt: string;
rpcUrl?: undefined;
apiKey?: undefined;
} | {
rpcUrl: string;
apiKey?: undefined;
jwt?: undefined;
} | {
rpcUrl: string;
jwt: string;
apiKey?: undefined;
};
... 4 more ...;
enablePopupOauth?: boolean | undefined;
} | AlchemySignerWebClient) & (AlchemySignerWebClient | ... 1 more ... | undefined)client: {
connection: {
apiKey: string;
}connection: {
apiKey: stringapiKey: "API_KEY",
},
iframeConfig: {
iframeContainerId: string;
}iframeConfig: {
iframeContainerId: stringiframeContainerId: "alchemy-signer-iframe-container",
},
},
});
Track Authentication Status
Use signer.on("statusChanged", callback)
and the AlchemySignerStatus
enum to respond to OTP/MFA prompts and completion:
import { import signersigner } from "./signer";
import { enum AlchemySignerStatusAlchemySignerStatus } from "@account-kit/signer";
import signersigner.anyon("statusChanged", (status: anystatus) => {
switch (status: anystatus) {
case enum AlchemySignerStatusAlchemySignerStatus.function (enum member) AlchemySignerStatus.AWAITING_EMAIL_AUTH = "AWAITING_EMAIL_AUTH"AWAITING_EMAIL_AUTH:
// show OTP input UI
break;
case enum AlchemySignerStatusAlchemySignerStatus.function (enum member) AlchemySignerStatus.AWAITING_MFA_AUTH = "AWAITING_MFA_AUTH"AWAITING_MFA_AUTH:
// show TOTP input UI
break;
case enum AlchemySignerStatusAlchemySignerStatus.function (enum member) AlchemySignerStatus.CONNECTED = "CONNECTED"CONNECTED:
// authentication complete
break;
}
});
import { class AlchemyWebSignerA SmartAccountSigner that can be used with any SmartContractAccount
AlchemyWebSigner } from "@account-kit/signer";
export const const signer: AlchemyWebSignersigner = new new AlchemyWebSigner(params: AlchemySignerParams): AlchemyWebSignerInitializes an instance with the provided Alchemy signer parameters after parsing them with a schema.
AlchemyWebSigner({
client: ({
connection: {
apiKey: string;
rpcUrl?: undefined;
jwt?: undefined;
} | {
jwt: string;
rpcUrl?: undefined;
apiKey?: undefined;
} | {
rpcUrl: string;
apiKey?: undefined;
jwt?: undefined;
} | {
rpcUrl: string;
jwt: string;
apiKey?: undefined;
};
... 4 more ...;
enablePopupOauth?: boolean | undefined;
} | AlchemySignerWebClient) & (AlchemySignerWebClient | ... 1 more ... | undefined)client: {
connection: {
apiKey: string;
}connection: {
apiKey: stringapiKey: "API_KEY",
},
iframeConfig: {
iframeContainerId: string;
}iframeConfig: {
iframeContainerId: stringiframeContainerId: "alchemy-signer-iframe-container",
},
},
});