Core Quickstart

If you’re not using React, but still want a number of the abstractions that make the React package so easy to use, you can leverage the @account-kit/core package directly.

In this guide, we’ll walk you through how to use this package to send a user operation, while using the reactive utilities exported by this package.

Install packages

Prerequisites

  • minimum Typescript version of 5

Installation

To get started, you’ll need to install the required packages. We also install the infra package because it contains the necessary Chain definitions that makes it easier to setup your a Bundler client.

$yarn add @account-kit/core @account-kit/infra

Get your Environment Variables

  1. Create an app in the dashboard and copy the API Key.

  2. Create a configuration in the Smart Wallets dashboard to enable login methods.

  3. Create a policy in your gas manager dashboard to set rules for sponsorship.

If your setup allows, store both the policy and API key in a .env so you can use them in the following steps. Otherwise you can hold onto them for the next section where you will make use of them!

Create a config

Now, you’re ready to create a config. The config we create should be a static object that you can import anywhere into your application. It contains all of the state that the functions within this package use.

config.ts
1import { createConfig } from "@account-kit/core";
2import { alchemy, sepolia } from "@account-kit/infra";
3
4export const config = createConfig({
5 transport: alchemy({ apiKey: "YOUR_API_KEY" }),
6 chain: sepolia,
7 // optional if you want to sponsor gas
8 policyId: "YOUR_POLICY_ID",
9});

Authenticate the user

Before you can create a Smart Account instance for your users, you need to authenticate them with the user. Depending on what framework you’re using this will look different, but using email based auth as an example you would:

  1. collect the user’s email
  2. call the authenticate method on the signer
  3. handle the redirect from the user’s email and pass the bundle to the signer to complete login
1import { config } from "./config";
2import { getSigner } from "@account-kit/core";
3
4const signer = getSigner(config);
5
6if (!signer) {
7 // this can happen if your rendering this on the server
8 // the signer instance is only available on the client
9 throw new Error("Signer not found");
10}
11
12// authenticate the user with email
13await signer.authenticate({
14 type: "email",
15 email: "[email protected]",
16});
17
18// once the user has clicked on the email and been redirected back to your site
19const bundle = new URLSearchParams(window.location.search).get("bundle");
20if (!bundle) {
21 throw new Error("No bundle found in URL");
22}
23await signer.authenticate({ type: "email", bundle });

Send a user operation

Now that you have your config, you can send user operations by leveraging the underlying smart account client.

1import { watchSmartAccountClient } from "@account-kit/core";
2import { config } from "./config";
3
4let clientState;
5
6// The watch smart account client will handle all of the possible state changes
7// that can impact this client:
8// - Signer status
9// - Account instantiation
10// - Chain changes
11const clientSubscription = watchSmartAccountClient(
12 {
13 type: "LightAccount",
14 },
15 config,
16)((clientState_) => {
17 clientState = clientState_;
18});
19
20if (clientState == null || clientState.isLoadingClient) {
21 console.log("Loading...");
22}
23
24const client = clientState.client;
25
26await client.sendUserOperation({
27 uo: {
28 target: "0xtarget",
29 data: "0x",
30 value: 0n,
31 },
32});

The key thing here is the watchSmartAccountClient method which allows you to subscribe to the state of signer and underlying account to give you a stable instance of the Smart Account Client. How you store the clientState variable will depend largely on your framework, but the above example should give you a good starting point.

Next steps

Now that you have basic authentication and user operations working, you can explore additional features: