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}
-
+