Skip to content

Commit cfd12cf

Browse files
Merge pull request #73 from LIT-Protocol/wyatt/lit-relayer
Mint PKP through relayer using Google OAuth
2 parents 4c64b09 + 15d64c4 commit cfd12cf

22 files changed

+5774
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
VITE_GOOGLE_CLIENT_ID=
2+
VITE_GOOGLE_CLIENT_SECRET=
3+
VITE_LIT_RELAYER_API_KEY=
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module.exports = {
2+
root: true,
3+
env: { browser: true, es2020: true },
4+
extends: [
5+
"eslint:recommended",
6+
"plugin:@typescript-eslint/recommended",
7+
"plugin:react-hooks/recommended",
8+
],
9+
ignorePatterns: ["dist", ".eslintrc.cjs"],
10+
parser: "@typescript-eslint/parser",
11+
plugins: ["react-refresh"],
12+
rules: {
13+
"react-refresh/only-export-components": [
14+
"warn",
15+
{ allowConstantExport: true },
16+
],
17+
},
18+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
.env
15+
16+
# Editor directories and files
17+
.vscode/*
18+
!.vscode/extensions.json
19+
.idea
20+
.DS_Store
21+
*.suo
22+
*.ntvs*
23+
*.njsproj
24+
*.sln
25+
*.sw?
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Mint PKP Through Lit Relayer and Google OAuth
2+
3+
This code examples demonstrates how to mint a PKP through the Lit Relayer, using Google OAuth to authenticate the user.
4+
5+
## Prerequisites
6+
7+
- Google OAuth Client ID and Secret
8+
- You can get these by creating a new project in the [Google Developer Console](https://console.cloud.google.com/apis/credentials)
9+
- Lit Relayer API Key
10+
- You submit a request for one using [this form](https://docs.google.com/forms/d/e/1FAIpQLSeVraHsp1evK_9j-8LpUBiEJWFn4G5VKjOWBmHFjxFRJZJdrg/viewform)
11+
- This code example uses Node.js and Yarn
12+
13+
## Installation and Setup
14+
15+
1. Clone the repository
16+
2. `cd` into the code example directory: `cd lit-relayer/mintPKPThroughRelayer/browser`
17+
3. Install the dependencies: `yarn`
18+
4. Create and fill in the `.env` file: `cp .env.example .env`
19+
- `VITE_GOOGLE_CLIENT_ID`: **Required** This is the Google OAuth Client ID
20+
- `VITE_GOOGLE_CLIENT_SECRET`: **Required** This is the Google OAuth Client Secret
21+
- `VITE_LIT_RELAYER_API_KEY`: **Required** This is the Lit Relayer API Key
22+
5. Start the development server: `yarn dev`
23+
24+
## Executing the Example
25+
26+
1. Open the app in your browser: http://localhost:5173
27+
2. Open the JavaScript browser console
28+
3. Click the `Sign in with Google` button and connect your Google account
29+
4. Click the `Mint PKP` button to mint a PKP using the authenticated Google account
30+
31+
### Expected Output
32+
33+
After clicking the `Mint PKP` button, the code example will use the authenticated Google account to mint a PKP through the Lit Relayer.
34+
35+
After successful execution, you should see `✅ PKP successfully minted` in the JavaScript console and the PKP info on the web page:
36+
37+
![Successful execution](./public/pkpMintRelayerGoogleAccount.png)
38+
39+
## Specific Files to Reference
40+
41+
- [App.tsx](./src/App.tsx): Contains the frontend code and the code for authenticating the Google account
42+
- [lit.ts](./src/lit.ts): Contains the code for minting a PKP through the Lit Relayer
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Vite + React + TS</title>
8+
<style>
9+
body,
10+
html {
11+
margin: 0;
12+
height: 100%;
13+
display: flex;
14+
justify-content: center;
15+
align-items: center;
16+
}
17+
#root {
18+
width: 100%;
19+
text-align: center;
20+
}
21+
</style>
22+
</head>
23+
<body>
24+
<div id="root"></div>
25+
<script type="module" src="/src/main.tsx"></script>
26+
</body>
27+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "browser-template",
3+
"private": true,
4+
"version": "0.0.0",
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite",
8+
"build": "tsc -b && vite build",
9+
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
10+
"preview": "vite preview"
11+
},
12+
"dependencies": {
13+
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
14+
"@esbuild-plugins/node-modules-polyfill": "^0.2.2",
15+
"@lit-protocol/constants": "^6.11.0",
16+
"@lit-protocol/lit-auth-client": "^6.11.0",
17+
"@react-oauth/google": "^0.12.1",
18+
"@simplewebauthn/browser": "^10.0.0",
19+
"@vitejs/plugin-react-swc": "^3.7.0",
20+
"ethers": "v5",
21+
"react": "^18.3.1",
22+
"react-dom": "^18.3.1",
23+
"rollup-plugin-polyfill-node": "^0.13.0",
24+
"vite-plugin-node-polyfills": "^0.22.0"
25+
},
26+
"devDependencies": {
27+
"@types/react": "^18.3.3",
28+
"@types/react-dom": "^18.3.0",
29+
"@typescript-eslint/eslint-plugin": "^7.13.1",
30+
"@typescript-eslint/parser": "^7.13.1",
31+
"@vitejs/plugin-react": "^4.3.1",
32+
"eslint": "^8.57.0",
33+
"eslint-plugin-react-hooks": "^4.6.2",
34+
"eslint-plugin-react-refresh": "^0.4.7",
35+
"typescript": "^5.5.3",
36+
"vite": "^5.3.1"
37+
}
38+
}
Loading
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#root {
2+
max-width: 1280px;
3+
margin: 0 auto;
4+
padding: 2rem;
5+
text-align: center;
6+
}
7+
8+
.logo {
9+
height: 6em;
10+
padding: 1.5em;
11+
will-change: filter;
12+
transition: filter 300ms;
13+
}
14+
.logo:hover {
15+
filter: drop-shadow(0 0 2em #646cffaa);
16+
}
17+
.logo.react:hover {
18+
filter: drop-shadow(0 0 2em #61dafbaa);
19+
}
20+
21+
@keyframes logo-spin {
22+
from {
23+
transform: rotate(0deg);
24+
}
25+
to {
26+
transform: rotate(360deg);
27+
}
28+
}
29+
30+
@media (prefers-reduced-motion: no-preference) {
31+
a:nth-of-type(2) .logo {
32+
animation: logo-spin infinite 20s linear;
33+
}
34+
}
35+
36+
.card {
37+
padding: 2em;
38+
}
39+
40+
.read-the-docs {
41+
color: #888;
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { GoogleOAuthProvider, GoogleLogin } from "@react-oauth/google";
2+
import * as lit from "./lit";
3+
import { useState } from "react";
4+
5+
function App() {
6+
const [isAuthenticated, setIsAuthenticated] = useState(false);
7+
const [credentialResponse, setCredentialResponse] = useState<any>(null);
8+
const [pkpInfo, setPkpInfo] = useState<any>(null);
9+
10+
const handleGoogleSuccess = (response: any) => {
11+
console.log("Google login successful:", response);
12+
setIsAuthenticated(true);
13+
setCredentialResponse(response);
14+
};
15+
16+
const handleGoogleError = () => {
17+
console.log("Google login failed");
18+
setIsAuthenticated(false);
19+
setCredentialResponse(null);
20+
};
21+
22+
const handleMintPKP = async () => {
23+
if (!credentialResponse) {
24+
console.error("No credential response available");
25+
return;
26+
}
27+
try {
28+
const pkp = await lit.mintPkpUsingGoogleAndLitRelayer(credentialResponse);
29+
console.log("Minted PKP:", pkp);
30+
setPkpInfo(pkp);
31+
} catch (error) {
32+
console.error("Error minting PKP:", error);
33+
setPkpInfo(null);
34+
}
35+
};
36+
37+
return (
38+
<GoogleOAuthProvider clientId={import.meta.env.VITE_GOOGLE_CLIENT_ID}>
39+
<div className="card">
40+
<hr />
41+
<h3>Lit Relayer Google oAuth Example</h3>
42+
{!isAuthenticated ? (
43+
<GoogleLogin
44+
onSuccess={handleGoogleSuccess}
45+
onError={handleGoogleError}
46+
/>
47+
) : (
48+
<>
49+
<p>Authenticated successfully!</p>
50+
<button onClick={handleMintPKP}>Mint PKP</button>
51+
{pkpInfo && (
52+
<div>
53+
<h4>PKP Information:</h4>
54+
<p>Public Key: {pkpInfo.publicKey}</p>
55+
<p>ETH Address: {pkpInfo.ethAddress}</p>
56+
<p>Token ID: {pkpInfo.tokenId}</p>
57+
</div>
58+
)}
59+
</>
60+
)}
61+
<h5>Check the browser console!</h5>
62+
<hr />
63+
</div>
64+
</GoogleOAuthProvider>
65+
);
66+
}
67+
68+
export default App;
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
interface Window {
2+
ethereum?: any;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
:root {
2+
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3+
line-height: 1.5;
4+
font-weight: 400;
5+
6+
color-scheme: light dark;
7+
color: rgba(255, 255, 255, 0.87);
8+
background-color: #242424;
9+
10+
font-synthesis: none;
11+
text-rendering: optimizeLegibility;
12+
-webkit-font-smoothing: antialiased;
13+
-moz-osx-font-smoothing: grayscale;
14+
}
15+
16+
a {
17+
font-weight: 500;
18+
color: #646cff;
19+
text-decoration: inherit;
20+
}
21+
a:hover {
22+
color: #535bf2;
23+
}
24+
25+
body {
26+
margin: 0;
27+
display: flex;
28+
place-items: center;
29+
min-width: 320px;
30+
min-height: 100vh;
31+
}
32+
33+
h1 {
34+
font-size: 3.2em;
35+
line-height: 1.1;
36+
}
37+
38+
button {
39+
border-radius: 8px;
40+
border: 1px solid transparent;
41+
padding: 0.6em 1.2em;
42+
font-size: 1em;
43+
font-weight: 500;
44+
font-family: inherit;
45+
background-color: #1a1a1a;
46+
cursor: pointer;
47+
transition: border-color 0.25s;
48+
}
49+
button:hover {
50+
border-color: #646cff;
51+
}
52+
button:focus,
53+
button:focus-visible {
54+
outline: 4px auto -webkit-focus-ring-color;
55+
}
56+
57+
@media (prefers-color-scheme: light) {
58+
:root {
59+
color: #213547;
60+
background-color: #ffffff;
61+
}
62+
a:hover {
63+
color: #747bff;
64+
}
65+
button {
66+
background-color: #f9f9f9;
67+
}
68+
}

0 commit comments

Comments
 (0)