Skip to content

Commit aff7c5f

Browse files
committed
Init auth a session guide
1 parent 161acd1 commit aff7c5f

File tree

11 files changed

+4744
-2
lines changed

11 files changed

+4744
-2
lines changed

hacker-guides/_getting-started/README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33

44
The Lit SDK is a set of libraries that enable various functionalities of the Lit Protocol. Each package is available on npm, and can be installed with your preferred JavaScript package manager.
55

6-
- [Documentation](#documentation)
6+
<!-- omit in toc -->
7+
## Table of Contents
8+
9+
- [Lit Documentation](#lit-documentation)
710
- [Core Terminology](#core-terminology)
811
- [Lit Node Client](#lit-node-client)
912
- [Lit Network](#lit-network)
@@ -20,7 +23,7 @@ The Lit SDK is a set of libraries that enable various functionalities of the Lit
2023
- [Next Steps](#next-steps)
2124

2225

23-
## Documentation
26+
## Lit Documentation
2427

2528
- [Lit Documentation](https://developer.litprotocol.com)
2629
- This is the main source of information for the Lit Protocol. It contains guides, reference documentation, and other resources for developers.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ETHEREUM_PRIVATE_KEY=
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+
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
<!-- omit in toc -->
2+
# Authenticating a Session with Lit
3+
4+
In order to use your [Lit Resources and their corresponding abilities](../README.md#lit-resources-and-abilities), you need to authenticate yourself with the Lit Network. After your identity has been authenticated, the Lit nodes can then verify whether you have the necessary permissions to access a given Lit Resource and its associated abilities when you make requests to the Lit Network (such as decrypting data, signing transactions with a PKP, or executing a Lit Action).
5+
6+
As covered [here](../README.md#session-signatures) in the Getting Started `README`, Sessions are the means by which you authenticate with the Lit Network to interact with Lit Resources securely without repeatedly signing transactions with your wallet. This guide will walk you through the process of authenticating a session, which involves:
7+
8+
1. Generating a Session Key Pair
9+
2. Creating an Authentication Signature to authorize your Session Key to use Lit Resources you have access to
10+
3. Requesting the Lit network to generate Session Signatures for your Session, authorizing it to perform actions with the specified Lit Resources
11+
12+
<!-- omit in toc -->
13+
## Table of Contents
14+
15+
- [Prerequisites](#prerequisites)
16+
- [Running the Code Example](#running-the-code-example)
17+
- [Requirements](#requirements)
18+
- [Steps](#steps)
19+
- [Expected Output](#expected-output)
20+
- [Understanding the Code](#understanding-the-code)
21+
- [Creating an Ethers Signer](#creating-an-ethers-signer)
22+
- [Requesting Session Signatures](#requesting-session-signatures)
23+
24+
25+
## Prerequisites
26+
27+
- Understanding of Lit core terminology and concepts covered [here](../README.md#core-terminology)
28+
- Understanding of the [Connecting to the Lit Network](../connecting-to-lit/README.md) guide
29+
30+
## Running the Code Example
31+
32+
### Requirements
33+
34+
- [Node.js](https://nodejs.org/en)
35+
- [Yarn](https://yarnpkg.com/getting-started)
36+
- `@lit-protocol/constants`
37+
- `@lit-protocol/lit-node-client`
38+
- `@lit-protocol/auth-helpers`
39+
40+
### Steps
41+
42+
1. `yarn` to install the dependencies
43+
2. `yarn test` to run the code example
44+
45+
### Expected Output
46+
47+
After running the code example, you should see output in your terminal indicating that a connection to the Lit Network was successfully established, and that session signatures were successfully generated for the requested session:
48+
49+
```bash
50+
[Lit-JS-SDK v6.11.0] [2024-11-15T05:58:06.815Z] [DEBUG] [core] signatures: {
51+
'https://15.235.83.220:7470': {
52+
sig: 'cadda38603f3cc62b83f043ede4fd758a9aee7363aa8c0b510658aa43d0e955942e63629029117f89973999956c4d2c20f666cc7af124661ebaeb1d4cf7bc00f',
53+
derivedVia: 'litSessionSignViaNacl',
54+
signedMessage: `{"sessionKey":"963d6551d36a8b5be53d8959d45141764dbfd3c00649f56bc00433ef09db75f5","resourceAbilityRequests":[{"resource":{"resource":"*","resourcePrefix":"lit-accesscontrolcondition"},"ability":"access-control-condition-decryption"}],"capabilities":[{"sig":"0x3a18598d9dbcb4c3f588d3948803f34397790f6b3ea1620913e353a002fb5526032aad72400635419346ca91a9bcfcd36cbdfc5b0f5080ecc48ded6ccfe6da7b1b","derivedVia":"web3.eth.personal.sign","signedMessage":"localhost wants you to sign in with your Ethereum account:\\n0xA89543a7145C68E52a4D584f1ceb123605131211\\n\\nThis is a test statement. You can put anything you want here. I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Decryption' for 'lit-accesscontrolcondition://*'.\\n\\nURI: lit:session:963d6551d36a8b5be53d8959d45141764dbfd3c00649f56bc00433ef09db75f5\\nVersion: 1\\nChain ID: 1\\nNonce: 0x23f22526f00d01dc505e291881a44a8c74664f76cdaa2662b8af1ae54c9b4725\\nIssued At: 2024-11-15T05:58:06.757Z\\nExpiration Time: 2024-11-15T06:08:06.728Z\\nResources:\\n- urn:recap:eyJhdHQiOnsibGl0LWFjY2Vzc2NvbnRyb2xjb25kaXRpb246Ly8qIjp7IlRocmVzaG9sZC9EZWNyeXB0aW9uIjpbe31dfX0sInByZiI6W119","address":"0xA89543a7145C68E52a4D584f1ceb123605131211"}],"issuedAt":"2024-11-15T05:58:06.778Z","expiration":"2024-11-15T06:08:06.728Z","nodeAddress":"https://15.235.83.220:7470"}`,
55+
address: '963d6551d36a8b5be53d8959d45141764dbfd3c00649f56bc00433ef09db75f5',
56+
algo: 'ed25519'
57+
},
58+
'https://15.235.83.220:7472': {
59+
sig: 'fccb3a82b02f1f3c9ba66fc8b3a61b0404875baf95449c76727529970105b3d96a2de9869a6cefd7c510ee8ecc55d7345e2b469f30ae59511579c703d2ab3a0c',
60+
derivedVia: 'litSessionSignViaNacl',
61+
signedMessage: `{"sessionKey":"963d6551d36a8b5be53d8959d45141764dbfd3c00649f56bc00433ef09db75f5","resourceAbilityRequests":[{"resource":{"resource":"*","resourcePrefix":"lit-accesscontrolcondition"},"ability":"access-control-condition-decryption"}],"capabilities":[{"sig":"0x3a18598d9dbcb4c3f588d3948803f34397790f6b3ea1620913e353a002fb5526032aad72400635419346ca91a9bcfcd36cbdfc5b0f5080ecc48ded6ccfe6da7b1b","derivedVia":"web3.eth.personal.sign","signedMessage":"localhost wants you to sign in with your Ethereum account:\\n0xA89543a7145C68E52a4D584f1ceb123605131211\\n\\nThis is a test statement. You can put anything you want here. I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Decryption' for 'lit-accesscontrolcondition://*'.\\n\\nURI: lit:session:963d6551d36a8b5be53d8959d45141764dbfd3c00649f56bc00433ef09db75f5\\nVersion: 1\\nChain ID: 1\\nNonce: 0x23f22526f00d01dc505e291881a44a8c74664f76cdaa2662b8af1ae54c9b4725\\nIssued At: 2024-11-15T05:58:06.757Z\\nExpiration Time: 2024-11-15T06:08:06.728Z\\nResources:\\n- urn:recap:eyJhdHQiOnsibGl0LWFjY2Vzc2NvbnRyb2xjb25kaXRpb246Ly8qIjp7IlRocmVzaG9sZC9EZWNyeXB0aW9uIjpbe31dfX0sInByZiI6W119","address":"0xA89543a7145C68E52a4D584f1ceb123605131211"}],"issuedAt":"2024-11-15T05:58:06.778Z","expiration":"2024-11-15T06:08:06.728Z","nodeAddress":"https://15.235.83.220:7472"}`,
62+
address: '963d6551d36a8b5be53d8959d45141764dbfd3c00649f56bc00433ef09db75f5',
63+
algo: 'ed25519'
64+
},
65+
'https://15.235.83.220:7471': {
66+
sig: 'b1e0d8fd8d09c3392b540126418ee9a8d8dbbabdd4d0c368832d612b1f51dadcd5f02bf5ca19dbd0251a3986ad5ddb514fc1f7e1753f8a6a979adf45fbbbd901',
67+
derivedVia: 'litSessionSignViaNacl',
68+
signedMessage: `{"sessionKey":"963d6551d36a8b5be53d8959d45141764dbfd3c00649f56bc00433ef09db75f5","resourceAbilityRequests":[{"resource":{"resource":"*","resourcePrefix":"lit-accesscontrolcondition"},"ability":"access-control-condition-decryption"}],"capabilities":[{"sig":"0x3a18598d9dbcb4c3f588d3948803f34397790f6b3ea1620913e353a002fb5526032aad72400635419346ca91a9bcfcd36cbdfc5b0f5080ecc48ded6ccfe6da7b1b","derivedVia":"web3.eth.personal.sign","signedMessage":"localhost wants you to sign in with your Ethereum account:\\n0xA89543a7145C68E52a4D584f1ceb123605131211\\n\\nThis is a test statement. You can put anything you want here. I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Decryption' for 'lit-accesscontrolcondition://*'.\\n\\nURI: lit:session:963d6551d36a8b5be53d8959d45141764dbfd3c00649f56bc00433ef09db75f5\\nVersion: 1\\nChain ID: 1\\nNonce: 0x23f22526f00d01dc505e291881a44a8c74664f76cdaa2662b8af1ae54c9b4725\\nIssued At: 2024-11-15T05:58:06.757Z\\nExpiration Time: 2024-11-15T06:08:06.728Z\\nResources:\\n- urn:recap:eyJhdHQiOnsibGl0LWFjY2Vzc2NvbnRyb2xjb25kaXRpb246Ly8qIjp7IlRocmVzaG9sZC9EZWNyeXB0aW9uIjpbe31dfX0sInByZiI6W119","address":"0xA89543a7145C68E52a4D584f1ceb123605131211"}],"issuedAt":"2024-11-15T05:58:06.778Z","expiration":"2024-11-15T06:08:06.728Z","nodeAddress":"https://15.235.83.220:7471"}`,
69+
address: '963d6551d36a8b5be53d8959d45141764dbfd3c00649f56bc00433ef09db75f5',
70+
algo: 'ed25519'
71+
}
72+
}
73+
[Lit-JS-SDK v6.11.0] [2024-11-15T05:58:06.816Z] [DEBUG] [core] The request time is at: 2024-11-15T05:58:06.816Z
74+
* Outer expiration:
75+
* Issued at: 2024-11-15T05:58:06.778Z
76+
* Expiration: 2024-11-15T06:08:06.728Z
77+
* Duration: 9 minutes, 59.950 seconds
78+
* Status: ✅ Not expired (valid for 9 minutes, 59.912 seconds)
79+
* Capabilities:
80+
* Capability 1 (web3.eth.personal.sign):
81+
* Issued at: 2024-11-15T05:58:06.757Z
82+
* Expiration: 2024-11-15T06:08:06.728Z
83+
* Duration: 9 minutes, 59.971 seconds
84+
* Status: ✅ Not expired (valid for 9 minutes, 59.912 seconds)
85+
* Attenuation:
86+
* lit-accesscontrolcondition://*
87+
* Threshold/Decryption
88+
```
89+
90+
## Understanding the Code
91+
92+
The following code from [./src/index.ts](./src/index.ts) does the following:
93+
94+
### Creating an Ethers Signer
95+
96+
```typescript
97+
const ethersSigner = new ethers.Wallet(
98+
ETHEREUM_PRIVATE_KEY,
99+
new ethers.providers.JsonRpcProvider(LIT_RPC.CHRONICLE_YELLOWSTONE)
100+
);
101+
```
102+
103+
The wallet that corresponds to `ETHEREUM_PRIVATE_KEY` would be your dev wallet that has permission to decrypt some data, sign with a PKP that it controls, or would be paying for the execution of a Lit Action (payment is not required for the Lit DatilDev network, so you don't need to worry about it for the hackathon).
104+
105+
As we'll cover further below, the `ethersSigner` is used to generate an Authentication Signature which is a [ERC-5573](https://eips.ethereum.org/EIPS/eip-5573) message that specifies what Lit Resources and corresponding abilities the Session will be authorized to use.
106+
107+
### Requesting Session Signatures
108+
109+
After connecting an instance of `LitNodeClient` to the Lit Network, the code calls the `getSessionSigs` method to request the Lit network to generate session signatures for the session.
110+
111+
This method takes in an object with the following properties:
112+
113+
- **chain**: Corresponds to the signature schema and message format you're requesting the session to be authenticated with. This should almost always be `ethereum`.
114+
- **expiration**: The date and time at which the session will no longer be valid.
115+
- It's recommended that you set this value to be as soon as possible, to minimize the amount of time that the session is valid for in case it gets compromised.
116+
- **resourceAbilityRequests**: An array of objects that specify the Lit Resources and abilities you're requesting the session to be authorized to use.
117+
- **authNeededCallback**: A function that you implement that generates an Authentication Signature for the session.
118+
119+
As a result of executing `getSessionSigs`, the Lit SDK will generate the ephemeral session key pair, execute the `authNeededCallback` function to generate an Authentication Signature, and submit the request to the Lit Network to generate session signatures.
120+
121+
Upon receiving the request, each Lit node in the network will independently authenticate the Authentication Signature, deriving the corresponding Ethereum address, and use that address to check if it has the authority to delegate the specified Lit Resources and abilities to the session.
122+
123+
If a node determines that the Authentication Signature is valid and authorized to delegate the `resourceAbilityRequests` to the session, it will generate a Session Signature indicating that the session is authenticated and authorized to use the specified Lit Resources and abilities.
124+
125+
After a threshold of nodes have generated Session Signatures, the Lit Network will send the Session Signatures back to your client. You will then use these Session Signatures to interact with the Lit Network, as we'll cover in other code examples in this guide.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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/auth-helpers": "^6.11.0",
13+
"@lit-protocol/constants": "^6.11.0",
14+
"@lit-protocol/lit-node-client": "^6.11.0",
15+
"ethers": "v5"
16+
},
17+
"devDependencies": {
18+
"@types/chai": "^4.3.16",
19+
"@types/chai-json-schema": "^1.4.10",
20+
"@types/mocha": "^10.0.6",
21+
"chai": "^5.1.1",
22+
"chai-json-schema": "^1.5.1",
23+
"mocha": "^10.4.0",
24+
"tsc": "^2.0.4",
25+
"tsx": "^4.12.0",
26+
"typescript": "^5.4.5"
27+
}
28+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { LitNodeClient } from "@lit-protocol/lit-node-client";
2+
import { LIT_RPC, LitNetwork } from "@lit-protocol/constants";
3+
import {
4+
createSiweMessage,
5+
generateAuthSig,
6+
LitAbility,
7+
LitAccessControlConditionResource,
8+
} from "@lit-protocol/auth-helpers";
9+
import { ethers } from "ethers";
10+
11+
import { getEnv } from "./utils";
12+
13+
const ETHEREUM_PRIVATE_KEY = getEnv("ETHEREUM_PRIVATE_KEY");
14+
15+
export const runExample = async () => {
16+
let litNodeClient: LitNodeClient;
17+
18+
try {
19+
const ethersSigner = new ethers.Wallet(
20+
ETHEREUM_PRIVATE_KEY,
21+
new ethers.providers.JsonRpcProvider(LIT_RPC.CHRONICLE_YELLOWSTONE)
22+
);
23+
24+
litNodeClient = new LitNodeClient({
25+
litNetwork: LitNetwork.DatilDev,
26+
debug: true,
27+
});
28+
await litNodeClient.connect();
29+
30+
const sessionSignatures = await litNodeClient.getSessionSigs({
31+
chain: "ethereum",
32+
expiration: new Date(Date.now() + 1000 * 60 * 10).toISOString(), // 10 minutes
33+
resourceAbilityRequests: [
34+
{
35+
resource: new LitAccessControlConditionResource("*"),
36+
ability: LitAbility.AccessControlConditionDecryption,
37+
},
38+
],
39+
authNeededCallback: async ({
40+
uri,
41+
expiration,
42+
resourceAbilityRequests,
43+
}) => {
44+
const toSign = await createSiweMessage({
45+
uri,
46+
expiration,
47+
resources: resourceAbilityRequests,
48+
walletAddress: await ethersSigner.getAddress(),
49+
nonce: await litNodeClient.getLatestBlockhash(),
50+
litNodeClient,
51+
});
52+
53+
return await generateAuthSig({
54+
signer: ethersSigner,
55+
toSign,
56+
});
57+
},
58+
});
59+
60+
return sessionSignatures;
61+
} catch (error) {
62+
console.error(error);
63+
} finally {
64+
litNodeClient!.disconnect();
65+
}
66+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export const getEnv = (name: string): string => {
2+
const env = process.env[name];
3+
if (env === undefined || env === "")
4+
throw new Error(
5+
`${name} ENV is not defined, please define it in the .env file`
6+
);
7+
return env;
8+
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { expect, use } from "chai";
2+
import chaiJsonSchema from "chai-json-schema";
3+
4+
import { runExample } from "../src";
5+
6+
use(chaiJsonSchema);
7+
8+
describe("getSessionSigsViaAuthSig", () => {
9+
const sessionSigResponseSchema = {
10+
type: "object",
11+
patternProperties: {
12+
"^https://\\d+\\.\\d+\\.\\d+\\.\\d+:\\d+$": {
13+
type: "object",
14+
properties: {
15+
sig: { type: "string" },
16+
derivedVia: { type: "string" },
17+
signedMessage: { type: "string" },
18+
address: { type: "string" },
19+
algo: { type: "string" },
20+
},
21+
required: ["sig", "derivedVia", "signedMessage", "address", "algo"],
22+
},
23+
},
24+
additionalProperties: false,
25+
};
26+
27+
it("Attempting to get session signatures...", async () => {
28+
const sessionSignatures = await runExample();
29+
expect(sessionSignatures).to.be.jsonSchema(sessionSigResponseSchema);
30+
}).timeout(120_000);
31+
});

0 commit comments

Comments
 (0)