Skip to main content

Listing Wrapped Keys for a PKP

This guide covers the listEncryptedKeyMetadata function from the Wrapped Keys SDK. For an overview of what a Wrapped Key is and what can be done with it, please go here.

The listEncryptedKeyMetadata function allows you to request the Wrapped Key metadata for all the Wrapped Keys associated with a PKP. Covered in detail further in this guide, the returned metadata does not include the ciphertext and dataToEncryptHash for any of the Wrapped Keys - to get this metadata you must use the getEncryptedKey method for each Wrapped Key.

Below we will walk through an implementation of listEncryptedKeyMetadata. The full code implementation can be found here.

Overview of How it Works

  1. The Wrapped Keys SDK will derive the PKP Ethereum address from the provided PKP Session Signatures
  2. The SDK will submit the Ethereum address to the Wrapped Keys backend service to fetch and return all the associated Wrapped Keys

Prerequisites

Before continuing with this guide, you should have an understanding of:

listEncryptedKeyMetadata's Interface

Source code

import { LIT_NETWORKS_KEYS } from '@lit-protocol/types';

/** Get a previously encrypted and persisted private key and its metadata.
* Note that this method does _not_ decrypt the private key; only the _encrypted_ key and its metadata will be returned to the caller.
*/
export async function getEncryptedKey(
params: {
pkpSessionSigs: SessionSigsMap;
litNodeClient: ILitNodeClient;
}
): Promise<{
publicKey: string;
pkpAddress: string;
keyType: string;
litNetwork: LIT_NETWORKS_KEYS;
memo: string;
id: string;
}[]>

Parameters

pkpSessionSigs

When a Wrapped Key is generated, it's encrypted with the following Access Control Conditions:

[
{
contractAddress: '',
standardContractType: '',
chain: CHAIN_ETHEREUM,
method: '',
parameters: [':userAddress'],
returnValueTest: {
comparator: '=',
value: pkpAddress,
},
},
];

where pkpAddress is the addressed derived from the pkpSessionSigs. This restricts the decryption of the Wrapped Key to only those whom can generate valid Authentication Signatures from the PKP which generated the Wrapped Key.

A valid pkpSessionSigs object can be obtained using the getPkpSessionSigs helper method available on an instance of LitNodeClient. We dive deeper into obtaining a pkpSessionSigs using getPkpSessionSigs in the Generating PKP Session Signatures section of this guide.

litNodeClient

This is an instance of the LitNodeClient that is connected to a Lit network.

Return Value

An array of StoredKeyMetadata object for each Wrapped Key associated with the PKP from pkpSessionSigs.

publicKey

This is the corresponding public key for the underlying private key for the Wrapped Key.

pkpAddress

This is the Ethereum address for the PKP that is associated with the Wrapped Key i.e. the PKP that created the Session Signatures when the Wrapped Key was imported/generated, and used for encrypting the private key. The address is derived from the provided pkpSessionSigs.

keyType

This is the algorithm used to generate the underlying private key for the Wrapped Key.

litNetwork

This is the Lit network that the LitNodeClient was connected to when the Wrapped Key was created.

memo

This is the additional identifier/descriptor string set for the Wrapped key when it was imported, generated, or stored.

This parameter is an arbitrary string that can be used as an additional identifier or descriptor of the encrypted private key.

id

This is a unique identifier (UUID v4) generated by Lit for the Wrapped Key.

Because a PKP can have multiple Wrapped Keys attached to it, this ID is used to identify which Wrapped Key to use when calling other Wrapped Key methods such as signMessageWithEncryptedKey and signTransactionWithEncryptedKey.

Example Implementation

Now that we know what the listEncryptedKeyMetadata function does, it's parameters, and it's return values, let's now dig into a complete implementation.

The full code implementation can be found here.

Installing the Required Dependencies

npm install \
@lit-protocol/auth-helpers \
@lit-protocol/constants \
@lit-protocol/lit-auth-client \
@lit-protocol/lit-node-client \
@lit-protocol/wrapped-keys \
ethers@v5

Instantiating an Ethers Signer

The ETHEREUM_PRIVATE_KEY environment variable is required. The corresponding Ethereum address needs to have ownership of the PKP we will be using to generate the pkpSessionSigs.

import * as ethers from 'ethers';
import { LIT_RPC } from "@lit-protocol/constants";

const ethersSigner = new ethers.Wallet(
process.env.ETHEREUM_PRIVATE_KEY,
new ethers.providers.JsonRpcProvider(LIT_RPC.CHRONICLE_YELLOWSTONE)
);

Instantiating a LitNodeClient

Here we are instantiating an instance of LitNodeClient and connecting it to the datil-dev Lit network.

import { LitNodeClient } from "@lit-protocol/lit-node-client";
import { LitNetwork } from "@lit-protocol/constants";

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

Generating PKP Session Signatures

The LIT_PKP_PUBLIC_KEY environment variable is required. This PKP should be owned by the corresponding Ethereum address for the ETHEREUM_PRIVATE_KEY environment variable.

The PKP's Ethereum address will be used for the Access Control Conditions used to encrypt the generated private key, and by default, will be the only entity able to authorize decryption of the private key.

note

The expiration used for the Auth Method must be 10 minutes or less to be valid.

note

The Auth Method used in this example implementation is signing a Sign in With Ethereum (EIP-4361) message using an Externally Owned Account (EOA), but any Auth Method can be used to authenticate with Lit to get PKP Session Signatures.

import { EthWalletProvider } from "@lit-protocol/lit-auth-client";
import {
LitAbility,
LitActionResource,
LitPKPResource,
} from "@lit-protocol/auth-helpers";

const pkpSessionSigs = await litNodeClient.getPkpSessionSigs({
pkpPublicKey: process.env.LIT_PKP_PUBLIC_KEY,
authMethods: [
await EthWalletProvider.authenticate({
signer: ethersSigner,
litNodeClient,
expiration: new Date(Date.now() + 1000 * 60 * 10).toISOString(), // 10 minutes
}),
],
resourceAbilityRequests: [
{
resource: new LitActionResource("*"),
ability: LitAbility.LitActionExecution,
},
],
expiration: new Date(Date.now() + 1000 * 60 * 10).toISOString(), // 10 minutes
});

Getting a list of Wrapped Key Metadata

Now that we hall all that we need, we can call listEncryptedKeyMetadata to list all the stored metadata for all the Wrapped Keys associated with the PKP derived from the pkpSessionSigs.

import { api } from "@lit-protocol/wrapped-keys";

const { listEncryptedKeyMetadata } = api;

const wrappedKeyMetadatas = await listEncryptedKeyMetadata({
pkpSessionSigs,
litNodeClient,
});

Summary

The full code implementation can be found here.

After executing the example implementation above, you will have exported the stored metadata for all the Wrapped Keys associated with the PKP derived from the provided pkpSessionSigs. Note that this metadata will not include the ciphertext and dataToEncryptHash properties that are needed to decrypt the underlying private keys for the Wrapped Keys. To get the encryption metadata, you must use the getEncryptedKey method.