Fix session sigs (#7)
* Decouple Google OAuth sign in with Mint PKP step * Use new signSessionKey SDK method * Handle authentication separately from storing conditions * Use auth-helpers package to generate session sigs correctly * Use react-app-rewired to use config override for fixing webpack bundle create-react-app default webpack config does not match against .cjs files, so we need to override the default config to bundle .cjs files from auth-helpers using CJS to import the .cjs file from recap-ts. * Implement encrypt / decrypt using session sigs * Use latest js-sdk, use npm instead of yarn yarn still installs tslib at 1.14.1, which breaks, whereas npm installs at 2.5.0
This commit is contained in:
parent
e2d7fe5ecc
commit
81a70959af
15
config-overrides.js
Normal file
15
config-overrides.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
module.exports = {
|
||||||
|
webpack: function(config, env) {
|
||||||
|
config.module.rules = config.module.rules.map(rule => {
|
||||||
|
if (rule.oneOf instanceof Array) {
|
||||||
|
rule.oneOf[rule.oneOf.length - 1].exclude = [
|
||||||
|
/\.(js|mjs|jsx|cjs|ts|tsx)$/,
|
||||||
|
/\.html$/,
|
||||||
|
/\.json$/,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return rule;
|
||||||
|
});
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
};
|
24153
package-lock.json
generated
24153
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
23
package.json
23
package.json
@ -5,12 +5,14 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.10.5",
|
"@emotion/react": "^11.10.5",
|
||||||
"@emotion/styled": "^11.10.5",
|
"@emotion/styled": "^11.10.5",
|
||||||
"@lit-protocol/access-control-conditions": "^2.1.122",
|
"@lit-protocol/access-control-conditions": "^2.2.0",
|
||||||
"@lit-protocol/bls-sdk": "^2.1.122",
|
"@lit-protocol/auth-helpers": "^2.2.0",
|
||||||
"@lit-protocol/constants": "^2.1.122",
|
"@lit-protocol/bls-sdk": "^2.2.0",
|
||||||
"@lit-protocol/crypto": "^2.1.122",
|
"@lit-protocol/constants": "^2.2.0",
|
||||||
"@lit-protocol/lit-node-client": "^2.1.122",
|
"@lit-protocol/crypto": "^2.2.0",
|
||||||
"@lit-protocol/lit-node-client-nodejs": "^2.1.122",
|
"@lit-protocol/lit-node-client": "^2.2.0",
|
||||||
|
"@lit-protocol/lit-node-client-nodejs": "^2.2.0",
|
||||||
|
"@lit-protocol/types": "^2.2.0",
|
||||||
"@mui/material": "^5.10.16",
|
"@mui/material": "^5.10.16",
|
||||||
"@react-oauth/google": "^0.4.0",
|
"@react-oauth/google": "^0.4.0",
|
||||||
"@simplewebauthn/browser": "^6.2.2",
|
"@simplewebauthn/browser": "^6.2.2",
|
||||||
@ -31,15 +33,16 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prettier": "^1.18.2",
|
"prettier": "^1.18.2",
|
||||||
|
"react-app-rewired": "^2.2.1",
|
||||||
"tslint": "^5.19.0",
|
"tslint": "^5.19.0",
|
||||||
"tslint-config-prettier": "^1.18.0",
|
"tslint-config-prettier": "^1.18.0",
|
||||||
"typescript": "3.6.2"
|
"typescript": "3.6.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-app-rewired start",
|
||||||
"build": "yarn fetchContracts && react-scripts build",
|
"build": "yarn fetchContracts && react-app-rewired build",
|
||||||
"test": "react-scripts test",
|
"test": "react-app-rewired test",
|
||||||
"eject": "react-scripts eject",
|
"eject": "react-app-rewired eject",
|
||||||
"fetchContracts": "node ./tools/getDeployedContracts.mjs"
|
"fetchContracts": "node ./tools/getDeployedContracts.mjs"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
|
451
src/App.tsx
451
src/App.tsx
@ -1,7 +1,9 @@
|
|||||||
import * as LitJsSdk_accessControlConditions from "@lit-protocol/access-control-conditions";
|
import * as LitJsSdk_accessControlConditions from "@lit-protocol/access-control-conditions";
|
||||||
import * as LitJsSdk_blsSdk from "@lit-protocol/bls-sdk";
|
import * as LitJsSdk_blsSdk from "@lit-protocol/bls-sdk";
|
||||||
|
import * as LitJsSdk_authHelpers from "@lit-protocol/auth-helpers";
|
||||||
|
import * as LitJsSdk_types from "@lit-protocol/types";
|
||||||
import * as LitJsSdk from "@lit-protocol/lit-node-client";
|
import * as LitJsSdk from "@lit-protocol/lit-node-client";
|
||||||
import { AccsDefaultParams, JsonAuthSig } from "@lit-protocol/types";
|
import { AccsDefaultParams, AuthSig, AuthCallback } from "@lit-protocol/types";
|
||||||
import { Button, ButtonGroup, TextField } from "@mui/material";
|
import { Button, ButtonGroup, TextField } from "@mui/material";
|
||||||
import { GoogleLogin } from "@react-oauth/google";
|
import { GoogleLogin } from "@react-oauth/google";
|
||||||
import {
|
import {
|
||||||
@ -10,6 +12,7 @@ import {
|
|||||||
} from "@simplewebauthn/browser";
|
} from "@simplewebauthn/browser";
|
||||||
import base64url from "base64url";
|
import base64url from "base64url";
|
||||||
import { ethers, utils } from "ethers";
|
import { ethers, utils } from "ethers";
|
||||||
|
import { computeAddress } from "ethers/lib/utils";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import "./App.css";
|
import "./App.css";
|
||||||
import { getDomainFromOrigin } from "./utils/string";
|
import { getDomainFromOrigin } from "./utils/string";
|
||||||
@ -36,16 +39,29 @@ function App() {
|
|||||||
const [registeredPkpPublicKey, setRegisteredPkpPublicKey] = useState<
|
const [registeredPkpPublicKey, setRegisteredPkpPublicKey] = useState<
|
||||||
string
|
string
|
||||||
>("");
|
>("");
|
||||||
|
const [
|
||||||
|
authenticatedPkpEthAddress,
|
||||||
|
setAuthenticatedPkpEthAddress,
|
||||||
|
] = useState<string>("");
|
||||||
const [authenticatedPkpPublicKey, setAuthenticatedPkpPublicKey] = useState<
|
const [authenticatedPkpPublicKey, setAuthenticatedPkpPublicKey] = useState<
|
||||||
string
|
string
|
||||||
>("");
|
>("");
|
||||||
const [status, setStatus] = useState("");
|
const [status, setStatus] = useState("");
|
||||||
const [selectedAuthMethod, setSelectedAuthMethod] = useState(6);
|
const [selectedAuthMethod, setSelectedAuthMethod] = useState(6);
|
||||||
const [webAuthnUsername, setWebAuthnUsername] = useState<string>("");
|
const [webAuthnUsername, setWebAuthnUsername] = useState<string>("");
|
||||||
const [authSig, setAuthSig] = useState<JsonAuthSig | null>(null);
|
const [authSig, setAuthSig] = useState<AuthSig | null>(null);
|
||||||
const [executeJsSignature, setExecuteJsSignature] = useState<string | null>(
|
const [executeJsSignature, setExecuteJsSignature] = useState<string | null>(
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
const [encryptedSymmetricKey, setEncryptedSymmetricKey] = useState<
|
||||||
|
Uint8Array
|
||||||
|
>(new Uint8Array());
|
||||||
|
const [encryptedString, setEncryptedString] = useState<Blob | null>(null);
|
||||||
|
|
||||||
|
console.log("STATE", {
|
||||||
|
authenticatedPkpPublicKey,
|
||||||
|
authenticatedPkpEthAddress,
|
||||||
|
});
|
||||||
|
|
||||||
const handleLoggedInToGoogle = async (
|
const handleLoggedInToGoogle = async (
|
||||||
credentialResponse: CredentialResponse
|
credentialResponse: CredentialResponse
|
||||||
@ -55,18 +71,6 @@ function App() {
|
|||||||
credentialResponse,
|
credentialResponse,
|
||||||
});
|
});
|
||||||
setGoogleCredentialResponse(credentialResponse);
|
setGoogleCredentialResponse(credentialResponse);
|
||||||
const requestId = await mintPkpUsingRelayerGoogleAuthVerificationEndpoint(
|
|
||||||
credentialResponse,
|
|
||||||
setStatus
|
|
||||||
);
|
|
||||||
await pollRequestUntilTerminalState(
|
|
||||||
requestId,
|
|
||||||
setStatus,
|
|
||||||
({ pkpEthAddress, pkpPublicKey }) => {
|
|
||||||
setRegisteredPkpEthAddress(pkpEthAddress);
|
|
||||||
setRegisteredPkpPublicKey(pkpPublicKey);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -98,10 +102,7 @@ function App() {
|
|||||||
<div style={{ height: 24 }} />
|
<div style={{ height: 24 }} />
|
||||||
{selectedAuthMethod === 6 && (
|
{selectedAuthMethod === 6 && (
|
||||||
<>
|
<>
|
||||||
<h3>
|
<h3>Step 1: Log in with Google.</h3>
|
||||||
Step 1: Log in with Google. Upon OAuth success, we will
|
|
||||||
mint a PKP on your behalf.
|
|
||||||
</h3>
|
|
||||||
<GoogleLogin
|
<GoogleLogin
|
||||||
onSuccess={handleLoggedInToGoogle}
|
onSuccess={handleLoggedInToGoogle}
|
||||||
onError={() => {
|
onError={() => {
|
||||||
@ -109,6 +110,27 @@ function App() {
|
|||||||
}}
|
}}
|
||||||
useOneTap
|
useOneTap
|
||||||
/>
|
/>
|
||||||
|
{googleCredentialResponse && (
|
||||||
|
<div>
|
||||||
|
<b>Google Credential Response: </b>
|
||||||
|
{JSON.stringify(googleCredentialResponse)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<h3>Step 2: Use Google Credential to Mint PKP.</h3>
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
handleMintPkpUsingGoogleAuth(
|
||||||
|
googleCredentialResponse,
|
||||||
|
setStatus,
|
||||||
|
({ pkpEthAddress, pkpPublicKey }) => {
|
||||||
|
setRegisteredPkpEthAddress(pkpEthAddress);
|
||||||
|
setRegisteredPkpPublicKey(pkpPublicKey);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Mint PKP
|
||||||
|
</button>
|
||||||
{registeredPkpEthAddress && (
|
{registeredPkpEthAddress && (
|
||||||
<div>
|
<div>
|
||||||
Registered PKP Eth Address:{" "}
|
Registered PKP Eth Address:{" "}
|
||||||
@ -116,30 +138,56 @@ function App() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<h3>
|
<h3>
|
||||||
<s>
|
Step 3: Generate auth sigs from Lit Nodes, then generate
|
||||||
Step 2: Use Lit Network to obtain a session sig and
|
session sigs for storing an encryption condition.
|
||||||
then store an encryption condition.
|
|
||||||
</s>
|
|
||||||
(Session Sigs do not work currently.)
|
|
||||||
</h3>
|
</h3>
|
||||||
<button
|
<Button
|
||||||
onClick={() =>
|
variant="contained"
|
||||||
handleStoreEncryptionCondition(
|
onClick={async () => {
|
||||||
|
const {
|
||||||
|
encryptedString,
|
||||||
|
encryptedSymmetricKey,
|
||||||
|
authenticatedPkpPublicKey,
|
||||||
|
} = await handleStoreEncryptionConditionNodes(
|
||||||
setStatus,
|
setStatus,
|
||||||
selectedAuthMethod,
|
googleCredentialResponse
|
||||||
googleCredentialResponse,
|
);
|
||||||
{
|
setEncryptedString(encryptedString);
|
||||||
signature: "dummy",
|
setEncryptedSymmetricKey(encryptedSymmetricKey);
|
||||||
signatureBase: "dummy",
|
setAuthenticatedPkpPublicKey(
|
||||||
credentialPublicKey: "dummy",
|
authenticatedPkpPublicKey
|
||||||
},
|
);
|
||||||
registeredPkpEthAddress,
|
setAuthenticatedPkpEthAddress(
|
||||||
registeredPkpPublicKey
|
publicKeyToAddress(authenticatedPkpPublicKey)
|
||||||
)
|
);
|
||||||
}
|
}}
|
||||||
>
|
>
|
||||||
Encrypt with Lit
|
Authenticate + Encrypt with Lit
|
||||||
</button>
|
</Button>
|
||||||
|
{authenticatedPkpEthAddress && (
|
||||||
|
<div>
|
||||||
|
Authenticated PKP Eth Address:{" "}
|
||||||
|
{authenticatedPkpEthAddress}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<h3>
|
||||||
|
Step 4: Retrieve the decrypted symmetric key from Lit
|
||||||
|
Nodes.
|
||||||
|
</h3>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
onClick={async () => {
|
||||||
|
await handleRetrieveSymmetricKeyNodes(
|
||||||
|
setStatus,
|
||||||
|
encryptedSymmetricKey,
|
||||||
|
encryptedString!,
|
||||||
|
googleCredentialResponse,
|
||||||
|
authenticatedPkpEthAddress
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Decrypt
|
||||||
|
</Button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{selectedAuthMethod === 3 && (
|
{selectedAuthMethod === 3 && (
|
||||||
@ -187,6 +235,9 @@ function App() {
|
|||||||
// After authenticating, we can store the pkpPublicKey for executing a
|
// After authenticating, we can store the pkpPublicKey for executing a
|
||||||
// Lit Action later.
|
// Lit Action later.
|
||||||
setAuthenticatedPkpPublicKey(pkpPublicKey);
|
setAuthenticatedPkpPublicKey(pkpPublicKey);
|
||||||
|
setAuthenticatedPkpEthAddress(
|
||||||
|
computeAddress(`0x${pkpPublicKey}`)
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Authenticate
|
Authenticate
|
||||||
@ -234,9 +285,37 @@ function App() {
|
|||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|
||||||
|
const handleMintPkpUsingGoogleAuth = async (
|
||||||
|
credentialResponse: CredentialResponse,
|
||||||
|
setStatusFn: (status: string) => void,
|
||||||
|
onSuccess: ({
|
||||||
|
pkpEthAddress,
|
||||||
|
pkpPublicKey,
|
||||||
|
}: {
|
||||||
|
pkpEthAddress: string;
|
||||||
|
pkpPublicKey: string;
|
||||||
|
}) => void
|
||||||
|
) => {
|
||||||
|
setStatusFn("Minting PKP...");
|
||||||
|
const requestId = await mintPkpUsingRelayerGoogleAuthVerificationEndpoint(
|
||||||
|
credentialResponse,
|
||||||
|
setStatusFn
|
||||||
|
);
|
||||||
|
return pollRequestUntilTerminalState(requestId, setStatusFn, onSuccess);
|
||||||
|
};
|
||||||
|
|
||||||
|
async function getLitNodeClient(): Promise<LitJsSdk.LitNodeClient> {
|
||||||
|
const litNodeClient = new LitJsSdk.LitNodeClient({
|
||||||
|
litNetwork: "serrano",
|
||||||
|
});
|
||||||
|
await litNodeClient.connect();
|
||||||
|
|
||||||
|
return litNodeClient;
|
||||||
|
}
|
||||||
|
|
||||||
async function handleExecuteJs(
|
async function handleExecuteJs(
|
||||||
setStatusFn: (status: string) => void,
|
setStatusFn: (status: string) => void,
|
||||||
authSig: JsonAuthSig,
|
authSig: AuthSig,
|
||||||
pkpPublicKey: string
|
pkpPublicKey: string
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
setStatusFn("Executing JS...");
|
setStatusFn("Executing JS...");
|
||||||
@ -251,10 +330,7 @@ const go = async () => {
|
|||||||
|
|
||||||
go();
|
go();
|
||||||
`;
|
`;
|
||||||
const litNodeClient = new LitJsSdk.LitNodeClient({
|
const litNodeClient = await getLitNodeClient();
|
||||||
litNetwork: "serrano",
|
|
||||||
});
|
|
||||||
await litNodeClient.connect();
|
|
||||||
|
|
||||||
const results = await litNodeClient.executeJs({
|
const results = await litNodeClient.executeJs({
|
||||||
code: litActionCode,
|
code: litActionCode,
|
||||||
@ -366,90 +442,158 @@ async function pollRequestUntilTerminalState(
|
|||||||
setStatusFn(`Hmm this is taking longer than expected...`);
|
setStatusFn(`Hmm this is taking longer than expected...`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleStoreEncryptionCondition(
|
async function handleStoreEncryptionConditionNodes(
|
||||||
setStatusFn: (status: string) => void,
|
setStatusFn: (status: string) => void,
|
||||||
selectedAuthMethod: number,
|
googleCredentialResponse: any
|
||||||
googleCredentialResponse: any,
|
): Promise<{
|
||||||
webAuthnVerificationMaterial: {
|
encryptedSymmetricKey: Uint8Array;
|
||||||
signature: string;
|
encryptedString: Blob;
|
||||||
signatureBase: string;
|
authenticatedPkpPublicKey: string;
|
||||||
credentialPublicKey: string;
|
}> {
|
||||||
},
|
setStatusFn("Storing encryption condition with the network...");
|
||||||
pkpEthAddress: string,
|
|
||||||
pkpPublicKey: string
|
|
||||||
) {
|
|
||||||
setStatusFn("Storing encryption condition...");
|
|
||||||
var unifiedAccessControlConditions: AccsDefaultParams[] = [
|
|
||||||
{
|
|
||||||
conditionType: "evmBasic",
|
|
||||||
contractAddress: "",
|
|
||||||
standardContractType: "",
|
|
||||||
chain: "mumbai",
|
|
||||||
method: "",
|
|
||||||
parameters: [":userAddress"],
|
|
||||||
returnValueTest: {
|
|
||||||
comparator: "=",
|
|
||||||
value: pkpEthAddress,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// this will be fired if auth is needed. we can use this to prompt the user to sign in
|
|
||||||
const authNeededCallback = async ({
|
|
||||||
chain,
|
|
||||||
resources,
|
|
||||||
expiration,
|
|
||||||
uri,
|
|
||||||
litNodeClient,
|
|
||||||
}: any) => {
|
|
||||||
console.log("authNeededCallback fired");
|
|
||||||
const authMethods =
|
|
||||||
selectedAuthMethod === 6
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
authMethodType: 6,
|
|
||||||
accessToken: googleCredentialResponse.credential,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: [
|
|
||||||
{
|
|
||||||
authMethodType: 3,
|
|
||||||
accessToken: JSON.stringify(
|
|
||||||
webAuthnVerificationMaterial
|
|
||||||
),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const sessionSig = await litNodeClient.signSessionKey({
|
|
||||||
sessionKey: uri,
|
|
||||||
authMethods,
|
|
||||||
pkpPublicKey,
|
|
||||||
expiration,
|
|
||||||
resources,
|
|
||||||
chain,
|
|
||||||
});
|
|
||||||
console.log("got session sig from node and PKP: ", sessionSig);
|
|
||||||
return sessionSig;
|
|
||||||
};
|
|
||||||
|
|
||||||
// get the user a session with it
|
// get the user a session with it
|
||||||
const litNodeClient = new LitJsSdk.LitNodeClient({
|
const litNodeClient = await getLitNodeClient();
|
||||||
litNetwork: "serrano",
|
|
||||||
});
|
|
||||||
await litNodeClient.connect();
|
|
||||||
|
|
||||||
|
const { encryptedString, symmetricKey } = await LitJsSdk.encryptString(
|
||||||
|
"this is a secret message"
|
||||||
|
);
|
||||||
|
|
||||||
|
// key parameter - encrypt symmetric key then hash it
|
||||||
|
const encryptedSymmetricKey = LitJsSdk_blsSdk.wasmBlsSdkHelpers.encrypt(
|
||||||
|
LitJsSdk.uint8arrayFromString(litNodeClient.subnetPubKey, "base16"),
|
||||||
|
symmetricKey
|
||||||
|
);
|
||||||
|
|
||||||
|
// get the session sigs
|
||||||
|
const { sessionSigs, authenticatedPkpPublicKey } = await getSessionSigs(
|
||||||
|
litNodeClient,
|
||||||
|
encryptedSymmetricKey,
|
||||||
|
litNodeClient.generateAuthMethodForGoogleJWT(
|
||||||
|
googleCredentialResponse.credential
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const pkpEthAddress = publicKeyToAddress(authenticatedPkpPublicKey);
|
||||||
|
|
||||||
|
const unifiedAccessControlConditions = getUnifiedAccessControlConditions(
|
||||||
|
pkpEthAddress
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
"unifiedAccessControlConditions: ",
|
||||||
|
unifiedAccessControlConditions
|
||||||
|
);
|
||||||
|
|
||||||
|
// store the decryption conditions
|
||||||
|
await litNodeClient.saveEncryptionKey({
|
||||||
|
unifiedAccessControlConditions,
|
||||||
|
symmetricKey,
|
||||||
|
encryptedSymmetricKey,
|
||||||
|
sessionSigs, // Not actually needed for storing encryption condition.
|
||||||
|
chain: "ethereum",
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("encryptedSymmetricKey: ", encryptedSymmetricKey);
|
||||||
|
|
||||||
|
return {
|
||||||
|
encryptedSymmetricKey,
|
||||||
|
encryptedString,
|
||||||
|
authenticatedPkpPublicKey,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getSessionSigs(
|
||||||
|
litNodeClient: LitJsSdk.LitNodeClient,
|
||||||
|
encryptedSymmetricKey: Uint8Array,
|
||||||
|
authMethod: LitJsSdk_types.AuthMethod
|
||||||
|
): Promise<{
|
||||||
|
sessionSigs: LitJsSdk_types.SessionSigsMap;
|
||||||
|
authenticatedPkpPublicKey: string;
|
||||||
|
}> {
|
||||||
|
let authenticatedPkpPublicKey: string;
|
||||||
|
|
||||||
|
// this will be fired if auth is needed. we can use this to prompt the user to sign in
|
||||||
|
const authNeededCallback: AuthCallback = async ({
|
||||||
|
resources,
|
||||||
|
expiration,
|
||||||
|
statement,
|
||||||
|
}) => {
|
||||||
|
console.log("authNeededCallback fired");
|
||||||
|
|
||||||
|
// Generate authMethod.
|
||||||
|
const authMethods = [authMethod];
|
||||||
|
|
||||||
|
// Get AuthSig
|
||||||
|
const { authSig, pkpPublicKey } = await litNodeClient.signSessionKey({
|
||||||
|
authMethods,
|
||||||
|
statement,
|
||||||
|
expiration:
|
||||||
|
expiration ||
|
||||||
|
new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(), // 24 hours
|
||||||
|
resources: resources || [],
|
||||||
|
});
|
||||||
|
console.log("got session sig from node and PKP: ", {
|
||||||
|
authSig,
|
||||||
|
pkpPublicKey,
|
||||||
|
});
|
||||||
|
|
||||||
|
authenticatedPkpPublicKey = pkpPublicKey;
|
||||||
|
|
||||||
|
return authSig;
|
||||||
|
};
|
||||||
|
|
||||||
|
const hashedEncryptedSymmetricKeyStr = await hashBytes({
|
||||||
|
bytes: new Uint8Array(encryptedSymmetricKey),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Construct the LitResource
|
||||||
|
const litResource = new LitJsSdk_authHelpers.LitAccessControlConditionResource(
|
||||||
|
hashedEncryptedSymmetricKeyStr
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get the session sigs
|
||||||
const sessionSigs = await litNodeClient.getSessionSigs({
|
const sessionSigs = await litNodeClient.getSessionSigs({
|
||||||
expiration: new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(), // 24 hours
|
expiration: new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(), // 24 hours
|
||||||
chain: "ethereum",
|
chain: "ethereum",
|
||||||
resources: [`litEncryptionCondition://*`],
|
resourceAbilityRequests: [
|
||||||
|
{
|
||||||
|
resource: litResource,
|
||||||
|
ability:
|
||||||
|
LitJsSdk_authHelpers.LitAbility
|
||||||
|
.AccessControlConditionDecryption,
|
||||||
|
},
|
||||||
|
],
|
||||||
switchChain: false,
|
switchChain: false,
|
||||||
authNeededCallback,
|
authNeededCallback,
|
||||||
});
|
});
|
||||||
console.log("sessionSigs before saving encryption key: ", sessionSigs);
|
console.log("sessionSigs: ", sessionSigs);
|
||||||
|
console.log("authenticatedPkpPublicKey: ", authenticatedPkpPublicKey!);
|
||||||
|
|
||||||
|
return {
|
||||||
|
sessionSigs,
|
||||||
|
authenticatedPkpPublicKey: authenticatedPkpPublicKey!,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: use when system migrates to reading from chain for access control conditions
|
||||||
|
async function handleStoreEncryptionConditionRelay(
|
||||||
|
setStatusFn: (status: string) => void,
|
||||||
|
pkpEthAddress: string
|
||||||
|
) {
|
||||||
|
setStatusFn("Storing encryption condition...");
|
||||||
|
|
||||||
|
// get the user a session with it
|
||||||
|
const litNodeClient = await getLitNodeClient();
|
||||||
|
|
||||||
const { encryptedZip, symmetricKey } = await LitJsSdk.zipAndEncryptString(
|
const { encryptedZip, symmetricKey } = await LitJsSdk.zipAndEncryptString(
|
||||||
"this is a secret message"
|
"this is a secret message"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// get the ACCs
|
||||||
|
const unifiedAccessControlConditions = getUnifiedAccessControlConditions(
|
||||||
|
pkpEthAddress
|
||||||
|
);
|
||||||
|
|
||||||
// value parameter - hash unified conditions
|
// value parameter - hash unified conditions
|
||||||
const hashedAccessControlConditions = await LitJsSdk_accessControlConditions.hashUnifiedAccessControlConditions(
|
const hashedAccessControlConditions = await LitJsSdk_accessControlConditions.hashUnifiedAccessControlConditions(
|
||||||
unifiedAccessControlConditions
|
unifiedAccessControlConditions
|
||||||
@ -486,7 +630,6 @@ async function handleStoreEncryptionCondition(
|
|||||||
hashedEncryptedSymmetricKeyStr,
|
hashedEncryptedSymmetricKeyStr,
|
||||||
hashedAccessControlConditionsStr,
|
hashedAccessControlConditionsStr,
|
||||||
securityHashStr,
|
securityHashStr,
|
||||||
sessionSig: sessionSigs["https://serrano.litgateway.com:7370"],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// call centralized conditions relayer to write encryption conditions to chain.
|
// call centralized conditions relayer to write encryption conditions to chain.
|
||||||
@ -503,8 +646,6 @@ async function handleStoreEncryptionCondition(
|
|||||||
chainId: "1",
|
chainId: "1",
|
||||||
permanent: false,
|
permanent: false,
|
||||||
capabilityProtocolPrefix: "litEncryptionCondition",
|
capabilityProtocolPrefix: "litEncryptionCondition",
|
||||||
// just choose any one session signature that is generated.
|
|
||||||
sessionSig: sessionSigs["https://serrano.litgateway.com:7370"],
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -519,6 +660,51 @@ async function handleStoreEncryptionCondition(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleRetrieveSymmetricKeyNodes(
|
||||||
|
setStatusFn: (status: string) => void,
|
||||||
|
encryptedSymmetricKey: Uint8Array,
|
||||||
|
encryptedString: Blob,
|
||||||
|
googleCredentialResponse: any,
|
||||||
|
pkpEthAddress: string
|
||||||
|
) {
|
||||||
|
setStatusFn("Retrieving symmetric key...");
|
||||||
|
const litNodeClient = await getLitNodeClient();
|
||||||
|
|
||||||
|
// get the session sigs
|
||||||
|
const { sessionSigs } = await getSessionSigs(
|
||||||
|
litNodeClient,
|
||||||
|
encryptedSymmetricKey,
|
||||||
|
litNodeClient.generateAuthMethodForGoogleJWT(
|
||||||
|
googleCredentialResponse.credential
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// get the ACC
|
||||||
|
const unifiedAccessControlConditions = getUnifiedAccessControlConditions(
|
||||||
|
pkpEthAddress
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
"unifiedAccessControlConditions: ",
|
||||||
|
unifiedAccessControlConditions
|
||||||
|
);
|
||||||
|
|
||||||
|
const retrievedSymmKey = await litNodeClient.getEncryptionKey({
|
||||||
|
unifiedAccessControlConditions,
|
||||||
|
toDecrypt: LitJsSdk.uint8arrayToString(encryptedSymmetricKey, "base16"),
|
||||||
|
sessionSigs,
|
||||||
|
});
|
||||||
|
|
||||||
|
const decryptedString = await LitJsSdk.decryptString(
|
||||||
|
encryptedString,
|
||||||
|
retrievedSymmKey
|
||||||
|
);
|
||||||
|
console.log("decrypted string", decryptedString);
|
||||||
|
}
|
||||||
|
|
||||||
|
function publicKeyToAddress(publicKey: string) {
|
||||||
|
return utils.computeAddress(`0x${publicKey}`);
|
||||||
|
}
|
||||||
|
|
||||||
async function hashBytes({ bytes }: { bytes: Uint8Array }): Promise<string> {
|
async function hashBytes({ bytes }: { bytes: Uint8Array }): Promise<string> {
|
||||||
const hashOfBytes = await crypto.subtle.digest("SHA-256", bytes);
|
const hashOfBytes = await crypto.subtle.digest("SHA-256", bytes);
|
||||||
const hashOfBytesStr = LitJsSdk.uint8arrayToString(
|
const hashOfBytesStr = LitJsSdk.uint8arrayToString(
|
||||||
@ -577,10 +763,7 @@ async function hashBytes({ bytes }: { bytes: Uint8Array }): Promise<string> {
|
|||||||
// };
|
// };
|
||||||
|
|
||||||
// // get the user a session with it
|
// // get the user a session with it
|
||||||
// const litNodeClient = new LitJsSdk.LitNodeClient({
|
// const litNodeClient = await getLitNodeClient();
|
||||||
// litNetwork: "serrano",
|
|
||||||
// });
|
|
||||||
// await litNodeClient.connect();
|
|
||||||
|
|
||||||
// const sessionSigs = await litNodeClient.getSessionSigs({
|
// const sessionSigs = await litNodeClient.getSessionSigs({
|
||||||
// expiration: new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(), // 24 hours
|
// expiration: new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(), // 24 hours
|
||||||
@ -704,7 +887,7 @@ const rpcUrl = process.env.REACT_APP_RPC_URL || "http://localhost:8545";
|
|||||||
async function handleWebAuthnAuthenticate(
|
async function handleWebAuthnAuthenticate(
|
||||||
setStatusFn: (status: string) => void
|
setStatusFn: (status: string) => void
|
||||||
): Promise<{
|
): Promise<{
|
||||||
authSig: JsonAuthSig;
|
authSig: AuthSig;
|
||||||
pkpPublicKey: string;
|
pkpPublicKey: string;
|
||||||
}> {
|
}> {
|
||||||
// Fetch latest blockHash
|
// Fetch latest blockHash
|
||||||
@ -750,10 +933,7 @@ async function handleWebAuthnAuthenticate(
|
|||||||
|
|
||||||
// Call all nodes POST /web/auth/webauthn to generate authSig.
|
// Call all nodes POST /web/auth/webauthn to generate authSig.
|
||||||
setStatusFn("Verifying WebAuthn authentication against Lit Network...");
|
setStatusFn("Verifying WebAuthn authentication against Lit Network...");
|
||||||
const litNodeClient = new LitJsSdk.LitNodeClient({
|
const litNodeClient = await getLitNodeClient();
|
||||||
litNetwork: "serrano",
|
|
||||||
});
|
|
||||||
await litNodeClient.connect();
|
|
||||||
|
|
||||||
// Generate authMethod.
|
// Generate authMethod.
|
||||||
const authMethod = litNodeClient.generateAuthMethodForWebAuthn(
|
const authMethod = litNodeClient.generateAuthMethodForWebAuthn(
|
||||||
@ -769,3 +949,24 @@ async function handleWebAuthnAuthenticate(
|
|||||||
|
|
||||||
return { authSig, pkpPublicKey };
|
return { authSig, pkpPublicKey };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getUnifiedAccessControlConditions(
|
||||||
|
pkpEthAddress?: string
|
||||||
|
): AccsDefaultParams[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
conditionType: "evmBasic",
|
||||||
|
contractAddress: "",
|
||||||
|
standardContractType: "",
|
||||||
|
chain: "mumbai",
|
||||||
|
method: "",
|
||||||
|
parameters: [":userAddress"],
|
||||||
|
returnValueTest: {
|
||||||
|
comparator: "=",
|
||||||
|
value:
|
||||||
|
pkpEthAddress ||
|
||||||
|
"0x3c3CA2BFFfffE532aed2923A34D6c1F9307F8076",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user