---
# System prepended metadata

title: Lit Protocol <> ZeroDev

---

# Lit Protocol <> ZeroDev

## Introduction

[ZeroDev](https://docs.zerodev.app/) is an embedded AA wallet, currently powering many AA wallets deployed on EVM chains. ZeroDev is known for its large AA feature set, including not just gas sponsoring, but also session keys, recovery, multisig, [and more](https://docs.zerodev.app/use-wallets/overview).

## Getting Started

Follow [this tutorial](https://docs.zerodev.app/getting-started) to get started with ZeroDev. You will need to create a Project ID to pass to the `@zerodev/sdk` as seen below.

Note: Make sure your project is set up with the intended network. The example below is using Polygon Mumbai. ZeroDev project IDs have a 1 to 1 mapping to networks.

## Create the pkpWallet

```typescript
import { LitAbility, LitActionResource } from "@lit-protocol/auth-helpers";
import { LitNodeClient } from "@lit-protocol/lit-node-client";
import { PKPEthersWallet } from "@lit-protocol/pkp-ethers";
import { AuthCallbackParams } from "@lit-protocol/types";

const POLYGON_MUMBAI_RPC_URL = "<YOUR RPC URL HERE>";
const PKP_PUBLIC_KEY = "<YOUR PKP PUBLIC KEY>";

const litNodeClient = new LitNodeClient({
  litNetwork: "cayenne",
  debug: false,
});
await litNodeClient.connect();

const resourceAbilities = [
  {
    resource: new LitActionResource("*"),
    ability: LitAbility.PKPSigning,
  },
];

/**
 * For provisioning keys and setting up authentication methods see documentation below
 * https://developer.litprotocol.com/v2/pkp/minting
 */
const authNeededCallback = async (params: AuthCallbackParams) => {
  const response = await litNodeClient.signSessionKey({
    sessionKey: params.sessionKeyPair,
    statement: params.statement,
    authMethods: [],
    pkpPublicKey: PKP_PUBLIC_KEY,
    expiration: params.expiration,
    resources: params.resources,
    chainId: 1,
  });
  return response.authSig;
};

const sessionSigs = await litNodeClient
  .getSessionSigs({
    chain: "ethereum",
    expiration: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7).toISOString(),
    resourceAbilityRequests: resourceAbilities,
    authNeededCallback,
  })
  .catch((err) => {
    console.log("error while attempting to access session signatures: ", err);
    throw err;
  });

const pkpWallet = new PKPEthersWallet({
  pkpPubKey: PKP_PUBLIC_KEY,
  rpc: POLYGON_MUMBAI_RPC_URL,
  controllerSessionSigs: sessionSigs,
});
```

## Connect the pkpWallet to a ZeroDev ECDSAProvider and send a UserOp
```typescript
import { ECDSAProvider, convertEthersSignerToAccountSigner } from "@zerodev/sdk"

const ZERODEV_PROJECT_ID = "<YOUR ZERODEV PROJECT ID>";

// Create a ZeroDev provider
const ecdsaProvider = await ECDSAProvider.init({
    // ZeroDev projectId
    projectId: ZERODEV_PROJECT_ID,
    // Pass the pkpWallet that we created in the previous section
    owner: convertEthersSignerToAccountSigner(pkpWallet)
})

// 3. send a UserOperation
const { hash } = await ecdsaProvider.sendUserOperation({
    target: "0xTargetAddress",
    data: "0xcallData",
    value: 0n, // value: bigint or undefined
});

// Wait for the UserOp to complete
await ecdsaProvider.waitForUserOperationTransaction(hash)
```