Skip to content

Commit 37ff35f

Browse files
Merge pull request #68 from LIT-Protocol/wyatt/wrapped-keys-eip-712
Init EIP-712 message signing using Wrapped Keys example
2 parents a74e6f6 + 4cbf632 commit 37ff35f

File tree

10 files changed

+5145
-0
lines changed

10 files changed

+5145
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ETHEREUM_PRIVATE_KEY=
2+
CAPACITY_CREDIT_TOKEN_ID=
3+
LIT_NETWORK=
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"$schema": "https://json.schemastore.org/mocharc.json",
3+
"require": "tsx"
4+
}

wrapped-keys/eip-712/nodejs/README.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# EIP-712 Signatures using Wrapped Keys
2+
3+
This code example demonstrates how to sign an EIP-712 message using a Wrapped Key.
4+
5+
## Prerequisites
6+
7+
- An Ethereum private key
8+
- This private key will be used to:
9+
- Mint a Lit Capacity Credit if none was specific in the project's `.env` file
10+
- In order to pay for this, the corresponding Ethereum account must have Lit Test Tokens. If you do not have any, you can get some from [the faucet](https://chronicle-yellowstone-faucet.getlit.dev/)
11+
- Create a Lit Capacity Credit delegation Auth Sig
12+
- Mint a PKP
13+
- Generate PKP Session Signatures
14+
- This code example uses Node.js and Yarn please have these installed before running the example
15+
16+
## Installation and Setup
17+
18+
1. Clone the repository
19+
2. `cd` into the code example directory: `cd wrapped-keys/eip-712/nodejs`
20+
3. Install the dependencies: `yarn`
21+
4. Create and fill in the `.env` file: `cp .env.example .env`
22+
- `ETHEREUM_PRIVATE_KEY`: **Required** This is the Ethereum private key that will be used to mint a Lit Capacity Credit and create Lit Session Signatures
23+
- `CAPACITY_CREDIT_TOKEN_ID`: **Optional** This is the ID of the Lit Capacity Credit to use for the PKP delegation Auth Sig
24+
- `LIT_NETWORK`: **Optional** This is the Lit Network to use for the Lit Contracts and Lit Node Clients
25+
26+
## Executing the Example
27+
28+
1. Run `yarn test` to execute the test that runs the example code
29+
30+
### Expected Output
31+
32+
```
33+
Signing an EIP-712 message using a Wrapped Key
34+
🔄 Generating EIP-712 message...
35+
✅ Generated and serialized EIP-712 message: {"domain":{"name":"Ether Mail","version":"1","chainId":1,"verifyingContract":"0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"},"types":{"Person":[{"name":"name","type":"string"},{"name":"wallet","type":"address"}],"Mail":[{"name":"from","type":"Person"},{"name":"to","type":"Person"},{"name":"contents","type":"string"}]},"primaryType":"Mail","message":{"from":{"name":"Alice","wallet":"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"},"to":{"name":"Bob","wallet":"0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"},"contents":"Hello, Bob!"}}
36+
🔄 Connecting LitNodeClient to Lit network...
37+
✅ Connected LitNodeClient to Lit network
38+
🔄 Connecting LitContracts client to network...
39+
✅ Connected LitContracts client to network
40+
🔄 Minting Capacity Credits NFT...
41+
✅ Minted new Capacity Credit with ID: 25144
42+
🔄 Minting new PKP...
43+
✅ Minted new PKP with public key: 04cf95d05f3e237fef866f7daf169be4b773ced0cbcc2ce260b03b63026fc858ea182dabad3bdb37c49554527b92dbe53b260d3934dfde18e0fac8a03ccb10fe09 and ETH address: 0xC3bb43D840801959890A565bB58A0290fF0FE8Be
44+
🔄 Creating capacityDelegationAuthSig...
45+
✅ Created the capacityDelegationAuthSig
46+
🔄 Getting PKP Session Sigs...
47+
Storage key "lit-session-key" is missing. Not a problem. Contiune...
48+
Storage key "lit-wallet-sig" is missing. Not a problem. Continue...
49+
Unable to store walletSig in local storage. Not a problem. Continue...
50+
✅ Got PKP Session Sigs
51+
🔄 Generating wrapped key...
52+
✅ Generated wrapped key with id: 1133b4d5-2ffb-46c3-951d-0f0d7f4ccde2 and public key: 0x0402e173bf643ae623771b24cdda0ca01bec0409ca01d67f02090961c1394e81e1dd78c80fa3e116b0be032616d907f2775a4e9e1dc4cc08d19cbec0e51b1f83af
53+
🔄 Getting wrapped key metadata...
54+
✅ Got wrapped key metadata: {
55+
"ciphertext": "okHLOUDld4UJD+LaDz++3QVDngfm/mz9HNPDuOlnJHH/iiCPiDT2Adnn6odOuw2igW8g3cclh0PDwoZO97zdsEmCfQrs2UuUEzR844n/S01HmO7exNHAVRglrK9azstkShE+0/KcIWjG3I2x6BCX9OfvJcTDb/LX2okN5HxLDNZMNuNtdBK11GAkfqPoV28AoBpj/oYdnw4C",
56+
"dataToEncryptHash": "76f7ff2ae254f0771089216fe8413a768f189242fa1b406c3805edaf7c64dc13",
57+
"id": "1133b4d5-2ffb-46c3-951d-0f0d7f4ccde2",
58+
"keyType": "K256",
59+
"pkpAddress": "0xC3bb43D840801959890A565bB58A0290fF0FE8Be",
60+
"publicKey": "0x0402e173bf643ae623771b24cdda0ca01bec0409ca01d67f02090961c1394e81e1dd78c80fa3e116b0be032616d907f2775a4e9e1dc4cc08d19cbec0e51b1f83af",
61+
"litNetwork": "datil-test"
62+
}
63+
🔄 Signing EIP-712 message with Wrapped Key...
64+
✅ Signed EIP-712 message
65+
```
66+
67+
## Specific Files to Reference
68+
69+
- [index.ts](./src/index.ts): Contains the code for:
70+
- Minting a PKP
71+
- Generating PKP Session Signatures
72+
- Generating a Wrapped Key
73+
- Getting the Wrapped Key metadata
74+
- Making the request to execute the Lit Action that signs an EIP-712 message using the Wrapped Key
75+
- [utils.ts](./src/utils.ts): Contains utility functions for the example
76+
- [wrappedKeyLitAction.ts](./src/wrappedKeyLitAction.ts): Contains the Lit Action code that signs an EIP-712 message
77+
- [index.spec.ts](./test/index.spec.ts): Contains the example EIP-712 message and test the example
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "nodejs",
3+
"version": "1.0.0",
4+
"main": "index.js",
5+
"license": "MIT",
6+
"type": "module",
7+
"scripts": {
8+
"test": "npx @dotenvx/dotenvx run -- mocha test/**/*.spec.ts"
9+
},
10+
"dependencies": {
11+
"@dotenvx/dotenvx": "^0.44.1",
12+
"@lit-protocol/constants": "^6.9.0",
13+
"@lit-protocol/contracts-sdk": "^6.9.0",
14+
"@lit-protocol/lit-auth-client": "^6.9.0",
15+
"@lit-protocol/lit-node-client": "^6.9.0",
16+
"@lit-protocol/types": "^6.9.0",
17+
"@lit-protocol/wrapped-keys": "^6.9.0",
18+
"ethers": "v5"
19+
},
20+
"devDependencies": {
21+
"@types/chai": "^4.3.16",
22+
"@types/chai-json-schema": "^1.4.10",
23+
"@types/mocha": "^10.0.6",
24+
"chai": "^5.1.1",
25+
"chai-json-schema": "^1.5.1",
26+
"mocha": "^10.4.0",
27+
"tsc": "^2.0.4",
28+
"tsx": "^4.12.0",
29+
"typescript": "^5.4.5"
30+
}
31+
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import { LIT_RPC, LitNetwork } from "@lit-protocol/constants";
2+
import { LitNodeClient } from "@lit-protocol/lit-node-client";
3+
import { LitAbility } from "@lit-protocol/types";
4+
import { ethers } from "ethers";
5+
import { api } from "@lit-protocol/wrapped-keys";
6+
import { LitActionResource } from "@lit-protocol/auth-helpers";
7+
8+
import {
9+
generateWrappedKey,
10+
getCapacityCreditDelegationAuthSig,
11+
getCapacityCreditTokenId,
12+
getEnv,
13+
getLitContracts,
14+
getLitNodeClient,
15+
getPkpAccessControlCondition,
16+
getSessionSigsViaPkp,
17+
mintPkp,
18+
} from "./utils";
19+
import { litActionCode } from "./wrappedKeyLitAction";
20+
21+
const { getEncryptedKey } = api;
22+
23+
const ETHEREUM_PRIVATE_KEY = getEnv("ETHEREUM_PRIVATE_KEY");
24+
const CAPACITY_CREDIT_TOKEN_ID =
25+
process.env.CAPACITY_CREDIT_TOKEN_ID || undefined;
26+
const LIT_NETWORK =
27+
(process.env.LIT_NETWORK as LitNetwork) || LitNetwork.DatilTest;
28+
29+
export const runExample = async (serializedEip712Message: string) => {
30+
let litNodeClient: LitNodeClient;
31+
32+
try {
33+
const ethersSigner = new ethers.Wallet(
34+
ETHEREUM_PRIVATE_KEY,
35+
new ethers.providers.JsonRpcProvider(LIT_RPC.CHRONICLE_YELLOWSTONE)
36+
);
37+
38+
litNodeClient = await getLitNodeClient(LIT_NETWORK);
39+
const litContracts = await getLitContracts(ethersSigner, LIT_NETWORK);
40+
41+
let _capacityCreditTokenId = CAPACITY_CREDIT_TOKEN_ID;
42+
if (_capacityCreditTokenId === undefined) {
43+
const capacityTokenId = await getCapacityCreditTokenId(litContracts);
44+
_capacityCreditTokenId = capacityTokenId;
45+
} else {
46+
console.log(
47+
`ℹ️ Using provided capacity credit token with ID: ${_capacityCreditTokenId}`
48+
);
49+
}
50+
51+
const pkpInfo = await mintPkp(litContracts);
52+
53+
const capacityDelegationAuthSig = await getCapacityCreditDelegationAuthSig(
54+
litNodeClient,
55+
ethersSigner,
56+
pkpInfo.ethAddress,
57+
_capacityCreditTokenId,
58+
"5"
59+
);
60+
61+
const pkpSessionSigs = await getSessionSigsViaPkp(
62+
litNodeClient,
63+
pkpInfo.publicKey,
64+
ethersSigner,
65+
[capacityDelegationAuthSig],
66+
[
67+
{
68+
resource: new LitActionResource("*"),
69+
ability: LitAbility.LitActionExecution,
70+
},
71+
]
72+
);
73+
74+
const wrappedKeyInfo = await generateWrappedKey(
75+
pkpSessionSigs,
76+
litNodeClient,
77+
"evm",
78+
"This is a test memo"
79+
);
80+
81+
console.log("🔄 Getting wrapped key metadata...");
82+
const wrappedKeyMetadata = await getEncryptedKey({
83+
pkpSessionSigs,
84+
litNodeClient,
85+
id: wrappedKeyInfo.id,
86+
});
87+
console.log(
88+
`✅ Got wrapped key metadata: ${JSON.stringify(
89+
wrappedKeyMetadata,
90+
null,
91+
2
92+
)}`
93+
);
94+
95+
console.log("🔄 Signing EIP-712 message with Wrapped Key...");
96+
const response = await litNodeClient.executeJs({
97+
sessionSigs: pkpSessionSigs,
98+
code: litActionCode,
99+
jsParams: {
100+
accessControlConditions: [
101+
getPkpAccessControlCondition(wrappedKeyInfo.pkpAddress),
102+
],
103+
ciphertext: wrappedKeyMetadata.ciphertext,
104+
dataToEncryptHash: wrappedKeyMetadata.dataToEncryptHash,
105+
messageToSign: serializedEip712Message,
106+
useEip712Signing: true,
107+
},
108+
});
109+
console.log("✅ Signed EIP-712 message");
110+
111+
return {
112+
signedMessage: response.response as string,
113+
wrappedKeyEthAddress: ethers.utils.computeAddress(
114+
wrappedKeyMetadata.publicKey
115+
),
116+
};
117+
} catch (error) {
118+
console.error(error);
119+
} finally {
120+
litNodeClient!.disconnect();
121+
}
122+
};

0 commit comments

Comments
 (0)