From 24b83ec99ef07e7e1edfb8ae78619e4a1da0bbda Mon Sep 17 00:00:00 2001 From: Samuel Andert Date: Fri, 1 Sep 2023 14:11:27 +0200 Subject: [PATCH] temporary refactor of sign in stateflow --- package.json | 4 +- pnpm-lock.yaml | 26 +++++ src/lib/GoogleAuth.svelte | 1 + ...ogleSigner.svelte => GoogleSession.svelte} | 4 +- src/lib/Test.svelte | 103 ------------------ src/lib/Wallet.svelte | 58 ++++++++++ src/lib/machines/walletMachine.ts | 99 +++++++++++++++++ src/lib/mintPkp.ts | 18 +++ src/lib/services/createSession.ts | 30 +++++ src/lib/services/signInWithGoogle.ts | 25 +++++ src/routes/+layout.svelte | 13 ++- 11 files changed, 270 insertions(+), 111 deletions(-) rename src/lib/{GoogleSigner.svelte => GoogleSession.svelte} (98%) delete mode 100644 src/lib/Test.svelte create mode 100644 src/lib/Wallet.svelte create mode 100644 src/lib/machines/walletMachine.ts create mode 100644 src/lib/mintPkp.ts create mode 100644 src/lib/services/createSession.ts create mode 100644 src/lib/services/signInWithGoogle.ts diff --git a/package.json b/package.json index 954f2a8..1981415 100644 --- a/package.json +++ b/package.json @@ -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" } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1ff130d..b1f0537 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -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: diff --git a/src/lib/GoogleAuth.svelte b/src/lib/GoogleAuth.svelte index 0881b21..f96a165 100644 --- a/src/lib/GoogleAuth.svelte +++ b/src/lib/GoogleAuth.svelte @@ -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"; diff --git a/src/lib/GoogleSigner.svelte b/src/lib/GoogleSession.svelte similarity index 98% rename from src/lib/GoogleSigner.svelte rename to src/lib/GoogleSession.svelte index 02d319a..2dc95c6 100644 --- a/src/lib/GoogleSigner.svelte +++ b/src/lib/GoogleSession.svelte @@ -53,7 +53,7 @@ } -{#if myPKP} + diff --git a/src/lib/Test.svelte b/src/lib/Test.svelte deleted file mode 100644 index 8412b0f..0000000 --- a/src/lib/Test.svelte +++ /dev/null @@ -1,103 +0,0 @@ - - -
- -
diff --git a/src/lib/Wallet.svelte b/src/lib/Wallet.svelte new file mode 100644 index 0000000..4e6bf61 --- /dev/null +++ b/src/lib/Wallet.svelte @@ -0,0 +1,58 @@ + + +{#if $state.matches("creatingSession")} +
+

Authenticated successfully. Selecting or minting PKP...

+
+{:else if $state.matches("sessionAvailable")} +
+

Signed in successfully. Here is your PKP:

+
{JSON.stringify($state.context.pkps[0].ethAddress, null, 2)}
+

Session available. Here are your session signatures:

+
+ {#each Object.keys($state.context.sessionSigs) as key} +
+
+
+

{key}

+

+ {$state.context.sessionSigs[key].sig} +

+
+
+ {/each} +
+
+{:else if $state.matches("sessionExpired")} +
+

Error creating session. Please try again.

+
{JSON.stringify($state.context.error, null, 2)}
+
+{/if} diff --git a/src/lib/machines/walletMachine.ts b/src/lib/machines/walletMachine.ts new file mode 100644 index 0000000..b2e1775 --- /dev/null +++ b/src/lib/machines/walletMachine.ts @@ -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; diff --git a/src/lib/mintPkp.ts b/src/lib/mintPkp.ts new file mode 100644 index 0000000..9dced95 --- /dev/null +++ b/src/lib/mintPkp.ts @@ -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 { + + 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; +} diff --git a/src/lib/services/createSession.ts b/src/lib/services/createSession.ts new file mode 100644 index 0000000..4271d52 --- /dev/null +++ b/src/lib/services/createSession.ts @@ -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}`); + } +}; \ No newline at end of file diff --git a/src/lib/services/signInWithGoogle.ts b/src/lib/services/signInWithGoogle.ts new file mode 100644 index 0000000..9fa7c61 --- /dev/null +++ b/src/lib/services/signInWithGoogle.ts @@ -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."); + } +}; \ No newline at end of file diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index d1c5403..f36b2cf 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -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');" > -
{activeSession}
+ + - {#if activeSession}active {:else} {/if} - +