Skip to content

Commit ea74c97

Browse files
committed
First commit
1 parent c565351 commit ea74c97

26 files changed

+1285
-1674
lines changed

conditional-signing/browser/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ In this directory, `conditional-signing/browser`, run `yarn` to install the proj
1212

1313
If you already have a Lit PKP that you'd like to use, you can copy the contents of the provided `.env.example` to a `.env` file to specify it. If you don't have a PKP, or wish to use a new one for this example, then you can skip this step and one will be created for you when you run this example.
1414

15-
**NOTE** In order for a new Lit PKP to minted for you, you **must** have `testLPX` tokens. You can receive some `testLPX` using the faucet available [here](https://faucet.litprotocol.com/).
15+
**NOTE** In order for a new Lit PKP to minted for you, you **must** have `tstLPX` tokens. You can receive some `tstLPX` using the faucet available [here](https://faucet.litprotocol.com/).
1616

1717
```
1818
cp .env.example .env
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
VITE_CAPACITY_CREDIT_TOKEN_ID=
+35-18
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,47 @@
1-
# Encryption and Decryption React Example
1+
# String Encryption/Decryption Using the Lit SDK in the Browser
22

3-
This is a simple example, that currently contains hardcoded values as `const`s in [encryptString.ts](./src/encryptString.ts) and [decryptString.ts](./src/decryptString.ts), that demonstrates encrypting and decrypting a string within the Browser using React.
3+
This code example demonstrates how the Lit SDK can be used to encrypt and decrypt data within a browser.
44

5-
## Running the Example
5+
## Running this Example
66

7-
### Installed the dependencies
7+
### Install the Dependencies
88

9-
After downloading this repository, you will need to install the necessary dependencies"
9+
In this directory, `encryption-decryption/browser`, run `yarn` to install the project dependencies.
1010

11-
```bash
12-
yarn
13-
```
11+
### Specifying Your Lit Capacity Credit's Token ID
12+
13+
If you already have a Lit Capacity Credit that you'd like to use, you can copy the contents of the provided `.env.example` to a `.env` file to specify it. If you don't have a Capacity Credit, or wish to use a new one for this example, then you can skip this step and one will be minted for you when you run this example.
14+
15+
**NOTE** In order for a new Lit Capacity Credit to be minted, you **must** have `tstLPX` tokens. You can receive some `tstLPX` using the faucet available [here](https://faucet.litprotocol.com/).
1416

15-
### Run the Web App
17+
```
18+
cp .env.example .env
19+
```
1620

17-
This example uses Vite to bundle and serve the web app at `http://localhost:5173/`:
21+
Your `.env` file should look like:
1822

19-
```bash
20-
yarn dev
2123
```
24+
VITE_LIT_CAPACITY_CREDIT_TOKEN_ID=yourCapacityCreditTokenId
25+
```
26+
27+
### Starting the Example
28+
29+
In this directory, `encryption-decryption/browser`, run `yarn dev` to bundle all of this code and serve the HTML file at: [http://localhost:5173](http://localhost:5173).
30+
31+
Before you click the buttons, open up the JavaScript console in your browser so you can see the output of this example.
32+
33+
After typing in the text you want to encrypt, clicking the `Encrypt String` button will:
34+
35+
1. You will be prompted by your wallet (i.e. MetaMask) to connect an account to the site
36+
2. After connecting an account, the console should display a successful connection to the Lit network and the encrypted `ciphertext` and `dataToEncryptHash` that will later be used to decrypt the string.
37+
38+
After encrypting the string, clicking the `Decrypt String` button will:
2239

23-
### Console Output
40+
1. Connect you to the Lit network and LitContracts client
41+
2. If you did not provide a Capacity Credit token ID, you will be prompted by your wallet to mint a new one
42+
3. You will then be prompted by your wallet to sign a message. This message will create a `capacityDelegationAuthSig`, which is used to pay for decrypting data ([and other functionality](https://developer.litprotocol.com/paying-for-lit/capacity-credits)) on the Lit
43+
4. You will then be prompted by your wallet to sign another one final message. This message is the SIWE message that will derive your address from to use for the conditional check of whether or not you are permitted to decrypt the data
2444

25-
The web app will present you two buttons:
45+
The full example should look something like:
2646

27-
1. `Encrypt String`
28-
- Will encrypt a hardcoded string using the Lit SDK
29-
2. `Decrypt String`
30-
- Will decrypt a hardcoded string using the Lit SDK and Habanero network
47+
***video***

encryption-decryption/browser/package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
"dependencies": {
1313
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
1414
"@esbuild-plugins/node-modules-polyfill": "^0.2.2",
15-
"@lit-protocol/auth-helpers": "^6.2.2",
16-
"@lit-protocol/contracts-sdk": "^6.2.2",
17-
"@lit-protocol/lit-node-client": "^6.2.2",
18-
"@lit-protocol/types": "^6.2.2",
15+
"@lit-protocol/auth-helpers": "^6.4.10",
16+
"@lit-protocol/contracts-sdk": "^6.4.10",
17+
"@lit-protocol/lit-node-client": "^6.4.10",
18+
"@lit-protocol/types": "^6.4.10",
1919
"@simplewebauthn/browser": "^10.0.0",
2020
"@vitejs/plugin-react-swc": "^3.7.0",
2121
"ethers": "v5",

encryption-decryption/browser/src/App.tsx

+39-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,42 @@
1-
import { encryptString } from "./encryptString";
1+
import { useState } from "react";
2+
import { encryptToString } from "./encryptString";
23
import { decryptString } from "./decryptString";
34

45
function App() {
6+
const [encryptedResult, setEncryptedResult] = useState<{
7+
ciphertext: string;
8+
dataToEncryptHash: string;
9+
}>();
10+
const [toEncrypt, setToEncrypt] = useState("");
11+
12+
const handleInputChange = (e: any) => {
13+
setToEncrypt(e.target.value);
14+
};
15+
16+
const handleEncrypt = async () => {
17+
try {
18+
const result = await encryptToString(toEncrypt);
19+
setEncryptedResult(result);
20+
} catch (error) {
21+
console.error("Encryption failed:", error);
22+
}
23+
};
24+
525
return (
626
<>
727
<div className="card">
828
<hr />
929
<h3>Encrypt a String</h3>
10-
<button onClick={async () => await encryptString()}>
30+
<label htmlFor="input">Enter a string to encrypt:</label>
31+
<br></br>
32+
<input
33+
type="text"
34+
id="input"
35+
value={toEncrypt}
36+
onChange={handleInputChange}
37+
></input>
38+
<br></br>
39+
<button onClick={async () => await handleEncrypt()}>
1140
Encrypt String
1241
</button>
1342
<h5> Check the browser console! </h5>
@@ -17,7 +46,14 @@ function App() {
1746
<div className="card">
1847
<hr />
1948
<h3>Decrypt a String</h3>
20-
<button onClick={async () => await decryptString()}>
49+
<button
50+
onClick={async () =>
51+
await decryptString(
52+
encryptedResult!.ciphertext,
53+
encryptedResult!.dataToEncryptHash
54+
)
55+
}
56+
>
2157
Decrypt String
2258
</button>
2359
<h5> Check the browser console! </h5>

encryption-decryption/browser/src/decryptString.ts

+53-46
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { AccessControlConditions } from "@lit-protocol/types";
21
import { LitNodeClient, decryptToString } from "@lit-protocol/lit-node-client";
32
import { LitNetwork } from "@lit-protocol/constants";
3+
import { LitContracts } from "@lit-protocol/contracts-sdk";
44
import { ethers } from "ethers";
55
import {
66
LitAbility,
@@ -9,74 +9,82 @@ import {
99
generateAuthSig,
1010
} from "@lit-protocol/auth-helpers";
1111

12-
import { DEFAULT_AUTHORIZED_ETH_ADDRESS } from "./encryptString";
13-
import { mintCapacityCredit } from "./utils";
14-
15-
const DEFAULT_ACCESS_CONTROL_CONDITIONS = [
16-
{
17-
contractAddress: "",
18-
standardContractType: "",
19-
chain: "ethereum",
20-
method: "",
21-
parameters: [":userAddress"],
22-
returnValueTest: {
23-
comparator: "=",
24-
value: DEFAULT_AUTHORIZED_ETH_ADDRESS,
25-
},
26-
},
27-
];
28-
const DEFAULT_CAPACITY_CREDIT_TOKEN_ID = "";
12+
const LIT_CAPACITY_CREDIT_TOKEN_ID = import.meta.env.VITE_CAPACITY_CREDIT_TOKEN_ID;
13+
const LIT_NETWORK = LitNetwork.DatilTest;
2914

3015
export const decryptString = async (
31-
ciphertext: string = "rGAjRrv1xJgMclM4etouk7z0tU+a1J4BrFsA7c3jkn1Pyw34y2OjRKSqozBKqal4mkUk9m4oHeG6FLQrRmgUDuIiebHYtWV0vD6c14FsJ9Ui1gb7ToVowepOoR7FkOcDrG/44f6nU3o4HEyh3VOYE/4m9gM=",
32-
dataToEncryptHash: string = "bc0b1d383f84b1b32d29f904597559d1d111f242403dfa4d025c51d186bcd784",
33-
accessControlConditions: AccessControlConditions = DEFAULT_ACCESS_CONTROL_CONDITIONS,
34-
capacityCreditTokenId: string | undefined = DEFAULT_CAPACITY_CREDIT_TOKEN_ID
16+
ciphertext: string,
17+
dataToEncryptHash: string,
3518
) => {
3619
let litNodeClient: LitNodeClient;
3720

3821
try {
39-
console.log("🔄 Connecting to wallet...");
40-
if (typeof window.ethereum === "undefined") {
41-
throw new Error("❌ Browser wallet extension not installed");
42-
}
43-
44-
await window.ethereum.request({ method: "eth_requestAccounts" });
45-
4622
const ethersProvider = new ethers.providers.Web3Provider(window.ethereum);
4723
const ethersSigner = ethersProvider.getSigner();
48-
const connectedAddress = await ethersSigner.getAddress();
49-
console.log(`✅ Connected to wallet: ${connectedAddress}`);
24+
const address = await ethersSigner.getAddress();
25+
console.log(`✅ Connected to wallet: ${address}`);
5026

5127
console.log("🔄 Connecting to Lit network...");
5228
litNodeClient = new LitNodeClient({
53-
litNetwork: LitNetwork.DatilTest,
29+
litNetwork: LIT_NETWORK,
5430
debug: false,
5531
});
5632
await litNodeClient.connect();
5733
console.log("✅ Connected to Lit network");
5834

59-
let _capacityCreditTokenId: string | undefined = capacityCreditTokenId;
60-
if (capacityCreditTokenId === undefined || capacityCreditTokenId === "") {
61-
_capacityCreditTokenId = await mintCapacityCredit(ethersSigner);
35+
console.log("🔄 Connecting LitContracts client to the network...");
36+
const litContracts = new LitContracts({
37+
signer: ethersSigner,
38+
network: LIT_NETWORK,
39+
});
40+
await litContracts.connect();
41+
console.log("✅ Connected LitContracts client to the network");
6242

63-
if (_capacityCreditTokenId === undefined)
64-
throw new Error("❌ Failed to mint new Capacity Credit");
43+
let capacityTokenId = LIT_CAPACITY_CREDIT_TOKEN_ID;
44+
if (capacityTokenId === "" || capacityTokenId === undefined) {
45+
console.log("🔄 No Capacity Credit provided, minting a new one...");
46+
capacityTokenId = (
47+
await litContracts.mintCapacityCreditsNFT({
48+
requestsPerKilosecond: 10,
49+
daysUntilUTCMidnightExpiration: 1,
50+
})
51+
).capacityTokenIdStr;
52+
console.log(`✅ Minted new Capacity Credit with ID: ${capacityTokenId}`);
53+
} else {
54+
console.log(
55+
`ℹ️ Using provided Capacity Credit with ID: ${LIT_CAPACITY_CREDIT_TOKEN_ID}`
56+
);
6557
}
6658

67-
console.log("🔄 Getting Capacity Credit delegation auth sig...");
59+
console.log("🔄 Creating capacityDelegationAuthSig...");
6860
const { capacityDelegationAuthSig } =
6961
await litNodeClient.createCapacityDelegationAuthSig({
70-
uses: "1",
7162
dAppOwnerWallet: ethersSigner,
72-
capacityTokenId: _capacityCreditTokenId,
63+
capacityTokenId,
64+
delegateeAddresses: [await ethersSigner.getAddress()],
65+
uses: "1",
7366
});
74-
console.log("✅ Got Capacity Credit delegation auth sig");
67+
console.log("✅ Capacity Delegation Auth Sig created");
68+
69+
const accessControlConditions = [
70+
{
71+
contractAddress: "",
72+
standardContractType: "",
73+
chain: "ethereum",
74+
method: "",
75+
parameters: [":userAddress"],
76+
returnValueTest: {
77+
comparator: "=",
78+
value: address,
79+
},
80+
},
81+
];
7582

7683
console.log("🔄 Getting EOA Session Sigs...");
7784
const sessionSigs = await litNodeClient.getSessionSigs({
7885
chain: "ethereum",
79-
expiration: new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(), // 24 hours
86+
expiration: new Date(Date.now() + 1000 * 60 * 15).toISOString(), // 15 minutes
87+
capabilityAuthSigs: [capacityDelegationAuthSig],
8088
resourceAbilityRequests: [
8189
{
8290
resource: new LitAccessControlConditionResource(
@@ -97,7 +105,7 @@ export const decryptString = async (
97105
uri: uri!,
98106
expiration: expiration!,
99107
resources: resourceAbilityRequests!,
100-
walletAddress: connectedAddress,
108+
walletAddress: address,
101109
nonce: await litNodeClient.getLatestBlockhash(),
102110
litNodeClient,
103111
});
@@ -107,7 +115,6 @@ export const decryptString = async (
107115
toSign,
108116
});
109117
},
110-
capabilityAuthSigs: [capacityDelegationAuthSig],
111118
});
112119
console.log("✅ Got EOA Session Sigs");
113120

@@ -123,8 +130,8 @@ export const decryptString = async (
123130
litNodeClient
124131
);
125132
console.log(`✅ Decrypted string: ${decryptionResult}`);
126-
} catch (error) {
127-
console.error(error);
133+
} catch (error: any) {
134+
console.error(error.message);
128135
} finally {
129136
litNodeClient!.disconnect();
130137
}

encryption-decryption/browser/src/encryptString.ts

+31-25
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,52 @@
1-
import { LitNodeClient } from "@lit-protocol/lit-node-client";
1+
import { LitNodeClient, encryptString } from "@lit-protocol/lit-node-client";
22
import { LitNetwork } from "@lit-protocol/constants";
3+
import * as ethers from "ethers";
34

4-
export const DEFAULT_AUTHORIZED_ETH_ADDRESS =
5-
"0xA89543a7145C68E52a4D584f1ceb123605131211";
5+
const LIT_NETWORK = LitNetwork.DatilTest;
66

7-
export const encryptString = async (
8-
toEncrypt: string = "The answer to the universe is 42.",
9-
authorizedEthAddress: string = DEFAULT_AUTHORIZED_ETH_ADDRESS
10-
) => {
7+
export const encryptToString = async (toEncrypt: string) => {
118
let litNodeClient: LitNodeClient;
129

1310
try {
11+
const provider = new ethers.providers.Web3Provider(window.ethereum);
12+
await provider.send("eth_requestAccounts", []);
13+
const ethersSigner = provider.getSigner();
14+
const address = await ethersSigner.getAddress();
15+
console.log("Connected account:", await ethersSigner.getAddress());
16+
1417
console.log("🔄 Connecting to Lit network...");
1518
litNodeClient = new LitNodeClient({
16-
litNetwork: LitNetwork.DatilTest,
19+
litNetwork: LIT_NETWORK,
1720
debug: false,
1821
});
1922
await litNodeClient.connect();
2023
console.log("✅ Connected to Lit network");
2124

2225
console.log("🔄 Encoding and encrypting string...");
23-
const encoder = new TextEncoder();
24-
const { ciphertext, dataToEncryptHash } = await litNodeClient.encrypt({
25-
accessControlConditions: [
26-
{
27-
contractAddress: "",
28-
standardContractType: "",
29-
chain: "ethereum",
30-
method: "",
31-
parameters: [":userAddress"],
32-
returnValueTest: {
33-
comparator: "=",
34-
value: authorizedEthAddress,
35-
},
26+
const accessControlConditions = [
27+
{
28+
contractAddress: "",
29+
standardContractType: "",
30+
chain: "ethereum",
31+
method: "",
32+
parameters: [":userAddress"],
33+
returnValueTest: {
34+
comparator: "=",
35+
value: address,
3636
},
37-
],
38-
dataToEncrypt: encoder.encode(toEncrypt),
39-
});
37+
},
38+
];
39+
40+
const { ciphertext, dataToEncryptHash } = await encryptString(
41+
{
42+
accessControlConditions,
43+
dataToEncrypt: toEncrypt,
44+
},
45+
litNodeClient
46+
);
4047
console.log("✅ Encrypted string");
4148

4249
console.log({ ciphertext, dataToEncryptHash });
43-
4450
return { ciphertext, dataToEncryptHash };
4551
} catch (error) {
4652
console.error(error);

0 commit comments

Comments
 (0)