temporary refactor of sign in stateflow
This commit is contained in:
parent
879f7aad3f
commit
24b83ec99e
@ -46,6 +46,7 @@
|
||||
"@wagmi/core": "^1.3.9",
|
||||
"@wundergraph/sdk": "^0.174.5",
|
||||
"@wundergraph/svelte-query": "^0.3.10",
|
||||
"@xstate/svelte": "^2.1.0",
|
||||
"axios": "^1.4.0",
|
||||
"cookie": "^0.5.0",
|
||||
"dotenv": "^16.3.1",
|
||||
@ -57,7 +58,8 @@
|
||||
"node-jose": "^2.2.0",
|
||||
"path": "^0.12.7",
|
||||
"svelte-kit-cookie-session": "^4.0.0",
|
||||
"url": "^0.11.1"
|
||||
"url": "^0.11.1",
|
||||
"xstate": "^4.38.2"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
26
pnpm-lock.yaml
generated
26
pnpm-lock.yaml
generated
@ -40,6 +40,9 @@ dependencies:
|
||||
'@wundergraph/svelte-query':
|
||||
specifier: ^0.3.10
|
||||
version: 0.3.10(@tanstack/svelte-query@4.29.1)(@wundergraph/sdk@0.174.5)(svelte@3.54.0)
|
||||
'@xstate/svelte':
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0(svelte@3.54.0)(xstate@4.38.2)
|
||||
axios:
|
||||
specifier: ^1.4.0
|
||||
version: 1.4.0
|
||||
@ -76,6 +79,9 @@ dependencies:
|
||||
url:
|
||||
specifier: ^0.11.1
|
||||
version: 0.11.1
|
||||
xstate:
|
||||
specifier: ^4.38.2
|
||||
version: 4.38.2
|
||||
|
||||
devDependencies:
|
||||
'@fontsource/fira-mono':
|
||||
@ -5390,6 +5396,22 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@xstate/svelte@2.1.0(svelte@3.54.0)(xstate@4.38.2):
|
||||
resolution: {integrity: sha512-cot553w2v4MdmDLkRBLhEjGO5LlnlPcpZ9RT7jFqpn+h0rpmjtkva6zjIZddPrxEOM6DVHDwzYbpDe+BErElQg==}
|
||||
peerDependencies:
|
||||
'@xstate/fsm': ^2.1.0
|
||||
svelte: ^3.24.1 || ^4
|
||||
xstate: ^4.38.1
|
||||
peerDependenciesMeta:
|
||||
'@xstate/fsm':
|
||||
optional: true
|
||||
xstate:
|
||||
optional: true
|
||||
dependencies:
|
||||
svelte: 3.54.0
|
||||
xstate: 4.38.2
|
||||
dev: false
|
||||
|
||||
/JSONStream@1.3.5:
|
||||
resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==}
|
||||
hasBin: true
|
||||
@ -12048,6 +12070,10 @@ packages:
|
||||
optional: true
|
||||
dev: false
|
||||
|
||||
/xstate@4.38.2:
|
||||
resolution: {integrity: sha512-Fba/DwEPDLneHT3tbJ9F3zafbQXszOlyCJyQqqdzmtlY/cwE2th462KK48yaANf98jHlP6lJvxfNtN0LFKXPQg==}
|
||||
dev: false
|
||||
|
||||
/xstream@11.14.0:
|
||||
resolution: {integrity: sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw==}
|
||||
dependencies:
|
||||
|
@ -6,6 +6,7 @@
|
||||
} from "@lit-protocol/lit-auth-client";
|
||||
import type { IRelayPKP } from "@lit-protocol/types";
|
||||
import Icon from "@iconify/svelte";
|
||||
import { mintPkp } from "./mintPkp";
|
||||
import { createLitSession } from "./createLitSession";
|
||||
import { connectProvider } from "./setupLit";
|
||||
|
||||
|
@ -53,7 +53,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if myPKP}
|
||||
<!-- {#if myPKP}
|
||||
<div
|
||||
class="fixed bottom-0 left-0 right-0 p-3 bg-white bg-opacity-75 rounded-t-lg shadow-md flex flex-col items-center space-y-4"
|
||||
>
|
||||
@ -82,4 +82,4 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/if} -->
|
@ -1,103 +0,0 @@
|
||||
<script>
|
||||
let litNodeClient;
|
||||
|
||||
litNodeClient.connect();
|
||||
|
||||
var authSig = JSON.parse(
|
||||
'{"sig":"0x18a173d68d2f78cc5c13da0dfe36eec2a293285bee6d42547b9577bf26cdc985660ed3dddc4e75d422366cac07e8a9fc77669b10373bef9c7b8e4280252dfddf1b","derivedVia":"web3.eth.personal.sign","signedMessage":"I am creating an account to use LITs at 2021-08-04T20:14:04.918Z","address":"0xdbd360f30097fb6d938dcc8b7b62854b36160b45"}'
|
||||
);
|
||||
|
||||
var randomPath = () =>
|
||||
"/" +
|
||||
Math.random().toString(36).substring(2, 15) +
|
||||
Math.random().toString(36).substring(2, 15);
|
||||
var testProvisoningAndSigning = async ({
|
||||
unifiedAccessControlConditions,
|
||||
testName,
|
||||
}) => {
|
||||
document.getElementById("status").innerText = `Testing ${testName}...`;
|
||||
document.getElementById(
|
||||
"humanized"
|
||||
).innerText = `Humanized: ${await litNodeClient.humanizeAccessControlConditions(
|
||||
{
|
||||
unifiedAccessControlConditions,
|
||||
}
|
||||
)}`;
|
||||
|
||||
var solAuthSig = await litNodeClient.checkAndSignAuthMessage({
|
||||
chain: "solana",
|
||||
});
|
||||
var ethAuthSig = await litNodeClient.checkAndSignAuthMessage({
|
||||
chain: "ethereum",
|
||||
});
|
||||
|
||||
let resourceId = {
|
||||
baseUrl: "my-dynamic-content-server.com",
|
||||
path: randomPath(),
|
||||
orgId: "",
|
||||
role: "",
|
||||
extraData: "",
|
||||
};
|
||||
|
||||
await litNodeClient.saveSigningCondition({
|
||||
unifiedAccessControlConditions,
|
||||
authSig: {
|
||||
solana: solAuthSig,
|
||||
ethereum: ethAuthSig,
|
||||
},
|
||||
resourceId,
|
||||
});
|
||||
|
||||
let jwt = await litNodeClient.getSignedToken({
|
||||
unifiedAccessControlConditions,
|
||||
authSig: {
|
||||
solana: solAuthSig,
|
||||
ethereum: ethAuthSig,
|
||||
},
|
||||
resourceId,
|
||||
});
|
||||
console.log("jwt", jwt);
|
||||
|
||||
// uncomment this to break the jwt, to test an invalid jwt
|
||||
// jwt = jwt.replace(/.$/, "3");
|
||||
|
||||
const { verified, header, payload } = litNodeClient.verifyJwt({ jwt });
|
||||
console.log("verified", verified);
|
||||
console.log("header", header);
|
||||
console.log("payload", payload);
|
||||
|
||||
if (jwt && verified) {
|
||||
document.getElementById("status").innerText = `${testName}: Success`;
|
||||
} else {
|
||||
document.getElementById("status").innerText = `${testName}: Failure`;
|
||||
}
|
||||
};
|
||||
|
||||
var IsPermittedAction = async () => {
|
||||
/*
|
||||
{ contract_address: "0x9e1DDB2499C6834204347F047Ace1ae18E830449", chain: "mumbai", standard_contract_type: "PubkeyRouterAndPermissions", method: "isPermittedAction", parameters: ["0xab9704fbd33d96c0475f6d2f1e6e7ff3497d4eceb10df78d0fcf012ab3b09300", "0x12203577a857f9d58507be2f4a87d969cc582dd00a1d0486281113e68208163cb5e8"], return_value_test: JsonReturnValueTest { comparator: "=", value: "true" } }
|
||||
*/
|
||||
var unifiedAccessControlConditions = [
|
||||
{
|
||||
conditionType: "evmBasic",
|
||||
contractAddress: "0x9e1DDB2499C6834204347F047Ace1ae18E830449",
|
||||
chain: "mumbai",
|
||||
standardContractType: "PubkeyRouterAndPermissions",
|
||||
method: "isPermittedAction",
|
||||
parameters: [
|
||||
"0xab9704fbd33d96c0475f6d2f1e6e7ff3497d4eceb10df78d0fcf012ab3b09300",
|
||||
"0x12203577a857f9d58507be2f4a87d969cc582dd00a1d0486281113e68208163cb5e8",
|
||||
],
|
||||
returnValueTest: { comparator: "=", value: "true" },
|
||||
},
|
||||
];
|
||||
await testProvisoningEncryptingAndDecrypting({
|
||||
unifiedAccessControlConditions,
|
||||
testName: "IsPermittedAction",
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<br />
|
||||
<button on:click={IsPermittedAction}>IsPermittedAction</button>
|
||||
<br />
|
58
src/lib/Wallet.svelte
Normal file
58
src/lib/Wallet.svelte
Normal file
@ -0,0 +1,58 @@
|
||||
<script>
|
||||
import { useMachine } from "@xstate/svelte";
|
||||
import walletMachine from "./machines/walletMachine";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
const { state, send } = useMachine(walletMachine);
|
||||
$: {
|
||||
if ($state.context.pkps && $state.context.sessionSigs) {
|
||||
localStorage.setItem(
|
||||
"me",
|
||||
JSON.stringify({
|
||||
pkps: $state.context.pkps,
|
||||
sessionSigs: $state.context.sessionSigs,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
onMount(() => {
|
||||
const me = JSON.parse(localStorage.getItem("me"));
|
||||
if (me && me.pkps && me.sessionSigs) {
|
||||
send({ type: "RELOAD", ...me });
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if $state.matches("creatingSession")}
|
||||
<div class="bg-white p-10">
|
||||
<p>Authenticated successfully. Selecting or minting PKP...</p>
|
||||
</div>
|
||||
{:else if $state.matches("sessionAvailable")}
|
||||
<div class="bg-white p-10">
|
||||
<p>Signed in successfully. Here is your PKP:</p>
|
||||
<pre>{JSON.stringify($state.context.pkps[0].ethAddress, null, 2)}</pre>
|
||||
<p>Session available. Here are your session signatures:</p>
|
||||
<div class="flex flex-col">
|
||||
{#each Object.keys($state.context.sessionSigs) as key}
|
||||
<div class="flex items-center p-2 bg-white rounded shadow mb-2">
|
||||
<div
|
||||
class="w-4 h-4 mr-2 rounded-full"
|
||||
class:bg-green-500={!$state.context.sessionSigs[key].expired}
|
||||
class:bg-red-500={$state.context.sessionSigs[key].expired}
|
||||
/>
|
||||
<div class="flex-grow">
|
||||
<p class="font-bold">{key}</p>
|
||||
<p class="text-sm text-gray-500">
|
||||
{$state.context.sessionSigs[key].sig}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{:else if $state.matches("sessionExpired")}
|
||||
<div class="bg-white p-10">
|
||||
<p>Error creating session. Please try again.</p>
|
||||
<pre>{JSON.stringify($state.context.error, null, 2)}</pre>
|
||||
</div>
|
||||
{/if}
|
99
src/lib/machines/walletMachine.ts
Normal file
99
src/lib/machines/walletMachine.ts
Normal file
@ -0,0 +1,99 @@
|
||||
// src/lib/machines/walletMachine.ts
|
||||
import { createMachine, assign } from 'xstate';
|
||||
import { signInWithGoogle } from '../services/signInWithGoogle';
|
||||
import { createSession } from '../services/createSession';
|
||||
|
||||
const walletMachine = createMachine({
|
||||
id: 'wallet',
|
||||
initial: 'signIn',
|
||||
context: {
|
||||
provider: null,
|
||||
providerName: null,
|
||||
authMethod: null,
|
||||
pkps: [],
|
||||
sessionSigs: null
|
||||
},
|
||||
states: {
|
||||
signIn: {
|
||||
on: {
|
||||
RELOAD: {
|
||||
target: 'sessionAvailable',
|
||||
actions: assign({
|
||||
pkps: (_, event) => event.pkps,
|
||||
sessionSigs: (_, event) => event.sessionSigs,
|
||||
}),
|
||||
},
|
||||
},
|
||||
invoke: {
|
||||
src: 'signInWithGoogle',
|
||||
onDone: {
|
||||
target: 'authenticated',
|
||||
actions: assign({
|
||||
providerName: (_, event) => event.data.providerName,
|
||||
provider: (_, event) => event.data.provider,
|
||||
authMethod: (_, event) => event.data.authMethod,
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
authenticated: {
|
||||
invoke: {
|
||||
src: async (context) => {
|
||||
const pkps = await context.provider.fetchPKPsThroughRelayer(context.authMethod);
|
||||
if (pkps.length === 0) {
|
||||
const newPKP = await context.provider.mintPKP(context.authMethod);
|
||||
pkps.push(newPKP);
|
||||
}
|
||||
return pkps;
|
||||
},
|
||||
onDone: {
|
||||
target: 'creatingSession',
|
||||
actions: assign({
|
||||
pkps: (_, event) => event.data,
|
||||
}),
|
||||
},
|
||||
onError: 'authenticated',
|
||||
},
|
||||
},
|
||||
creatingSession: {
|
||||
invoke: {
|
||||
src: async (context) => {
|
||||
const { pkps, sessionSigs } = await createSession(context.provider, context.authMethod, context.pkps);
|
||||
return { pkps, sessionSigs };
|
||||
},
|
||||
onDone: {
|
||||
target: 'sessionAvailable',
|
||||
actions: [
|
||||
assign({
|
||||
pkps: (_, event) => event.data.pkps,
|
||||
sessionSigs: (_, event) => event.data.sessionSigs,
|
||||
}),
|
||||
(context) => console.log('Context after creating session:', context), // Debug log
|
||||
],
|
||||
},
|
||||
onError: {
|
||||
target: 'sessionExpired',
|
||||
actions: assign({
|
||||
error: (_, event) => event.data,
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
sessionAvailable: {
|
||||
on: {
|
||||
EXPIRED: {
|
||||
target: 'sessionExpired',
|
||||
cond: (context) => context.sessionSigs === null
|
||||
}
|
||||
}
|
||||
},
|
||||
sessionExpired: {}
|
||||
},
|
||||
}, {
|
||||
services: {
|
||||
signInWithGoogle,
|
||||
createSession
|
||||
},
|
||||
});
|
||||
|
||||
export default walletMachine;
|
18
src/lib/mintPkp.ts
Normal file
18
src/lib/mintPkp.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import type { IRelayPKP } from '@lit-protocol/types';
|
||||
import type { IProvider } from '$lib/IProvider';
|
||||
|
||||
export async function mintPkp(provider: IProvider, authMethod: any): Promise<IRelayPKP> {
|
||||
|
||||
const txHash: string = await provider.mintPKPThroughRelayer(authMethod);
|
||||
const response = await provider.relay.pollRequestUntilTerminalState(txHash);
|
||||
if (response.status !== 'Succeeded') {
|
||||
throw new Error('Minting failed');
|
||||
}
|
||||
const newPKP: IRelayPKP = {
|
||||
tokenId: response.pkpTokenId,
|
||||
publicKey: response.pkpPublicKey,
|
||||
ethAddress: response.pkpEthAddress
|
||||
};
|
||||
|
||||
return newPKP;
|
||||
}
|
30
src/lib/services/createSession.ts
Normal file
30
src/lib/services/createSession.ts
Normal file
@ -0,0 +1,30 @@
|
||||
// src/lib/services/createSession.ts
|
||||
import { createLitSession } from '$lib/createLitSession';
|
||||
import type { IRelayPKP } from "@lit-protocol/types";
|
||||
|
||||
export const createSession = async (provider, authMethod, pkps: IRelayPKP[]) => {
|
||||
try {
|
||||
let currentPKP;
|
||||
if (pkps.length === 0) {
|
||||
currentPKP = await provider.mintPKP(authMethod);
|
||||
pkps = [...pkps, currentPKP];
|
||||
} else {
|
||||
currentPKP = pkps[0];
|
||||
}
|
||||
|
||||
console.log('Current PKP:', currentPKP); // Debug log
|
||||
|
||||
const sessionSigs = await createLitSession(
|
||||
provider,
|
||||
currentPKP.publicKey,
|
||||
authMethod
|
||||
);
|
||||
|
||||
console.log('Session Signatures:', sessionSigs); // Debug log
|
||||
|
||||
return { pkps, sessionSigs };
|
||||
} catch (error) {
|
||||
console.error('Error in createSession:', error); // Debug log
|
||||
throw new Error(`Failed to create session: ${error.message}`);
|
||||
}
|
||||
};
|
25
src/lib/services/signInWithGoogle.ts
Normal file
25
src/lib/services/signInWithGoogle.ts
Normal file
@ -0,0 +1,25 @@
|
||||
// src/lib/services/signInWithGoogle.ts
|
||||
import { connectProvider } from "$lib/setupLit";
|
||||
import { isSignInRedirect, getProviderFromUrl } from "@lit-protocol/lit-auth-client";
|
||||
|
||||
export const signInWithGoogle = async () => {
|
||||
if (typeof window !== 'undefined') {
|
||||
try {
|
||||
let provider = await connectProvider();
|
||||
if (isSignInRedirect("http://localhost:3000/")) {
|
||||
const providerName = getProviderFromUrl();
|
||||
if (providerName) {
|
||||
const authMethod = await provider.authenticate();
|
||||
return { authMethod, provider, providerName }; // Return the data
|
||||
}
|
||||
} else {
|
||||
await provider.signIn();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
throw err;
|
||||
}
|
||||
} else {
|
||||
throw new Error("Cannot sign in with Google in a non-browser environment.");
|
||||
}
|
||||
};
|
@ -7,10 +7,11 @@
|
||||
import { onMount } from "svelte";
|
||||
import { initChainProvider } from "$lib/setupChainProvider";
|
||||
import { googleSession } from "$lib/stores.js";
|
||||
import GoogleSigner from "$lib/GoogleSigner.svelte";
|
||||
import GooglePKP from "$lib/GooglePKP.svelte";
|
||||
import GoogleSession from "$lib/GoogleSession.svelte";
|
||||
import Wallet from "$lib/Wallet.svelte";
|
||||
|
||||
let activeSession = true;
|
||||
let activeSession = false;
|
||||
|
||||
export let data: LayoutData;
|
||||
|
||||
@ -34,9 +35,11 @@
|
||||
style="background-image: url('lake.jpeg');"
|
||||
>
|
||||
<QueryClientProvider client={data.queryClient}>
|
||||
<div class="text-lg bg-white">{activeSession}</div>
|
||||
<Wallet />
|
||||
<!-- <GoogleSession />
|
||||
<div class="text-lg bg-white">{activeSession}</div> -->
|
||||
<slot />
|
||||
{#if activeSession}active {:else} <GooglePKP /> {/if}
|
||||
<GoogleSigner />
|
||||
<!-- {#if activeSession}active {:else} expired {/if}
|
||||
<GooglePKP /> -->
|
||||
</QueryClientProvider>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user