diff --git a/package.json b/package.json index 116b9c1..28c561b 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,8 @@ "devDependencies": { "@fontsource/fira-mono": "^4.5.10", "@neoconfetti/svelte": "^1.0.0", + "@skeletonlabs/skeleton": "^2.0.0", + "@skeletonlabs/tw-plugin": "^0.1.0", "@sveltejs/adapter-auto": "^2.0.0", "@sveltejs/adapter-static": "^2.0.3", "@sveltejs/kit": "^1.5.0", @@ -23,6 +25,7 @@ "@types/cookie": "^0.5.1", "@types/js-cookie": "^3.0.3", "@types/jsonwebtoken": "^9.0.2", + "@types/node": "^20.5.8", "autoprefixer": "^10.4.15", "concurrently": "^7.6.0", "postcss": "^8.4.29", @@ -35,6 +38,7 @@ "wait-on": "^7.0.1" }, "dependencies": { + "@floating-ui/dom": "^1.5.1", "@graphql-tools/graphql-file-loader": "^8.0.0", "@graphql-tools/load": "^8.0.0", "@iconify/icons-ion": "^1.2.10", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 016907e..4605519 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,6 +1,9 @@ lockfileVersion: '6.0' dependencies: + '@floating-ui/dom': + specifier: ^1.5.1 + version: 1.5.1 '@graphql-tools/graphql-file-loader': specifier: ^8.0.0 version: 8.0.0(graphql@16.8.0) @@ -93,6 +96,12 @@ devDependencies: '@neoconfetti/svelte': specifier: ^1.0.0 version: 1.0.0 + '@skeletonlabs/skeleton': + specifier: ^2.0.0 + version: 2.0.0(svelte@3.54.0) + '@skeletonlabs/tw-plugin': + specifier: ^0.1.0 + version: 0.1.0(tailwindcss@3.3.3) '@sveltejs/adapter-auto': specifier: ^2.0.0 version: 2.0.0(@sveltejs/kit@1.5.0) @@ -114,6 +123,9 @@ devDependencies: '@types/jsonwebtoken': specifier: ^9.0.2 version: 9.0.2 + '@types/node': + specifier: ^20.5.8 + version: 20.5.8 autoprefixer: specifier: ^10.4.15 version: 10.4.15(postcss@8.4.29) @@ -140,7 +152,7 @@ devDependencies: version: 5.0.2 vite: specifier: ^4.2.0 - version: 4.2.0(@types/node@16.18.46) + version: 4.2.0(@types/node@20.5.8) wait-on: specifier: ^7.0.1 version: 7.0.1 @@ -2302,6 +2314,23 @@ packages: fastify-plugin: 4.5.1 dev: false + /@floating-ui/core@1.4.1: + resolution: {integrity: sha512-jk3WqquEJRlcyu7997NtR5PibI+y5bi+LS3hPmguVClypenMsCY3CBa3LAQnozRCtCrYWSEtAdiskpamuJRFOQ==} + dependencies: + '@floating-ui/utils': 0.1.1 + dev: false + + /@floating-ui/dom@1.5.1: + resolution: {integrity: sha512-KwvVcPSXg6mQygvA1TjbN/gh///36kKtllIF8SUm0qpFj8+rvYrpvlYdL1JoA71SHpDqgSSdGOSoQ0Mp3uY5aw==} + dependencies: + '@floating-ui/core': 1.4.1 + '@floating-ui/utils': 0.1.1 + dev: false + + /@floating-ui/utils@0.1.1: + resolution: {integrity: sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==} + dev: false + /@fontsource/fira-mono@4.5.10: resolution: {integrity: sha512-bxUnRP8xptGRo8YXeY073DSpfK74XpSb0ZyRNpHV9WvLnJ7TwPOjZll8hTMin7zLC6iOp59pDZ8EQDj1gzgAQQ==} dev: true @@ -2693,7 +2722,7 @@ packages: dependencies: '@jest/fake-timers': 29.6.4 '@jest/types': 29.6.3 - '@types/node': 20.5.6 + '@types/node': 20.5.8 jest-mock: 29.6.3 dev: false @@ -2703,7 +2732,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.5.6 + '@types/node': 20.5.8 jest-message-util: 29.6.3 jest-mock: 29.6.3 jest-util: 29.6.3 @@ -2722,7 +2751,7 @@ packages: dependencies: '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 20.5.6 + '@types/node': 20.5.8 '@types/yargs': 15.0.15 chalk: 4.1.2 dev: false @@ -2733,7 +2762,7 @@ packages: dependencies: '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 20.5.6 + '@types/node': 20.5.8 '@types/yargs': 16.0.5 chalk: 4.1.2 dev: false @@ -2745,7 +2774,7 @@ packages: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 20.5.6 + '@types/node': 20.5.8 '@types/yargs': 17.0.24 chalk: 4.1.2 dev: false @@ -4323,6 +4352,23 @@ packages: '@sinonjs/commons': 3.0.0 dev: false + /@skeletonlabs/skeleton@2.0.0(svelte@3.54.0): + resolution: {integrity: sha512-8SaDK3kEUU57cSb/5a984EbINgnOPzShlkwPkduAhqc71SEqhRvx+RlLEpe1174NAYi00oi//LguIAYuVrSfBA==} + peerDependencies: + svelte: ^3.56.0 || ^4.0.0 + dependencies: + esm-env: 1.0.0 + svelte: 3.54.0 + dev: true + + /@skeletonlabs/tw-plugin@0.1.0(tailwindcss@3.3.3): + resolution: {integrity: sha512-ufnm4FS+s/khuho4yJ/uqfW91u2YXnH3E5N541MtX9XjmoimQzYIcxWyTIuX9AM/brIPP6M6l0et3nRx17CRoQ==} + peerDependencies: + tailwindcss: '>=3.0.0' + dependencies: + tailwindcss: 3.3.3 + dev: true + /@solana/buffer-layout@4.0.1: resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} engines: {node: '>=5.10'} @@ -4525,7 +4571,7 @@ packages: svelte: 3.54.0 tiny-glob: 0.2.9 undici: 5.18.0 - vite: 4.2.0(@types/node@16.18.46) + vite: 4.2.0(@types/node@20.5.8) transitivePeerDependencies: - supports-color dev: true @@ -4541,7 +4587,7 @@ packages: '@sveltejs/vite-plugin-svelte': 2.4.5(svelte@3.54.0)(vite@4.2.0) debug: 4.3.4 svelte: 3.54.0 - vite: 4.2.0(@types/node@16.18.46) + vite: 4.2.0(@types/node@20.5.8) transitivePeerDependencies: - supports-color dev: true @@ -4560,7 +4606,7 @@ packages: magic-string: 0.30.3 svelte: 3.54.0 svelte-hmr: 0.15.3(svelte@3.54.0) - vite: 4.2.0(@types/node@16.18.46) + vite: 4.2.0(@types/node@20.5.8) vitefu: 0.2.4(vite@4.2.0) transitivePeerDependencies: - supports-color @@ -4716,7 +4762,7 @@ packages: resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} dependencies: '@types/connect': 3.4.35 - '@types/node': 20.5.6 + '@types/node': 20.5.8 dev: false /@types/common-tags@1.8.1: @@ -4726,7 +4772,7 @@ packages: /@types/connect@3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 20.5.6 + '@types/node': 20.5.8 dev: false /@types/cookie@0.5.1: @@ -4736,7 +4782,7 @@ packages: /@types/cross-spawn@6.0.2: resolution: {integrity: sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==} dependencies: - '@types/node': 20.5.6 + '@types/node': 20.5.8 dev: false /@types/debug@4.1.7: @@ -4748,7 +4794,7 @@ packages: /@types/express-serve-static-core@4.17.36: resolution: {integrity: sha512-zbivROJ0ZqLAtMzgzIUC4oNqDG9iF0lSsAqpOD9kbs5xcIM3dTiyuHvBc7R8MtWBp3AAWGaovJa+wzWPjLYW7Q==} dependencies: - '@types/node': 20.5.6 + '@types/node': 20.5.8 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 '@types/send': 0.17.1 @@ -4767,7 +4813,7 @@ packages: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 20.5.6 + '@types/node': 20.5.8 dev: false /@types/http-errors@2.0.1: @@ -4805,7 +4851,7 @@ packages: /@types/jsonwebtoken@9.0.2: resolution: {integrity: sha512-drE6uz7QBKq1fYqqoFKTDRdFCPHd5TCub75BM+D+cMx7NU9hUz7SESLfC2fSCXVFMO5Yj8sOWHuGqPgjc+fz0Q==} dependencies: - '@types/node': 20.5.6 + '@types/node': 20.5.8 /@types/lodash@4.14.197: resolution: {integrity: sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g==} @@ -4845,13 +4891,14 @@ packages: /@types/node@16.18.46: resolution: {integrity: sha512-Mnq3O9Xz52exs3mlxMcQuA7/9VFe/dXcrgAyfjLkABIqxXKOgBRjyazTxUbjsxDa4BP7hhPliyjVTP9RDP14xg==} + dev: false /@types/node@18.15.13: resolution: {integrity: sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==} dev: false - /@types/node@20.5.6: - resolution: {integrity: sha512-Gi5wRGPbbyOTX+4Y2iULQ27oUPrefaB0PxGQJnfyWN3kvEDGM3mIB5M/gQLmitZf7A9FmLeaqxD3L1CXpm3VKQ==} + /@types/node@20.5.8: + resolution: {integrity: sha512-eajsR9aeljqNhK028VG0Wuw+OaY5LLxYmxeoXynIoE6jannr9/Ucd1LL0hSSoafk5LTYG+FfqsyGt81Q6Zkybw==} /@types/prettier@2.7.3: resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} @@ -4873,7 +4920,7 @@ packages: resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==} dependencies: '@types/mime': 1.3.2 - '@types/node': 20.5.6 + '@types/node': 20.5.8 dev: false /@types/serve-static@1.15.2: @@ -4881,7 +4928,7 @@ packages: dependencies: '@types/http-errors': 2.0.1 '@types/mime': 3.0.1 - '@types/node': 20.5.6 + '@types/node': 20.5.8 dev: false /@types/stack-utils@2.0.1: @@ -4895,13 +4942,13 @@ packages: /@types/ws@7.4.7: resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} dependencies: - '@types/node': 20.5.6 + '@types/node': 20.5.8 dev: false /@types/ws@8.5.5: resolution: {integrity: sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==} dependencies: - '@types/node': 20.5.6 + '@types/node': 20.5.8 dev: false /@types/yargs-parser@21.0.0: @@ -8263,7 +8310,7 @@ packages: '@jest/environment': 29.6.4 '@jest/fake-timers': 29.6.4 '@jest/types': 29.6.3 - '@types/node': 20.5.6 + '@types/node': 20.5.8 jest-mock: 29.6.3 jest-util: 29.6.3 dev: false @@ -8293,7 +8340,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.5.6 + '@types/node': 20.5.8 jest-util: 29.6.3 dev: false @@ -8307,7 +8354,7 @@ packages: engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@jest/types': 27.5.1 - '@types/node': 20.5.6 + '@types/node': 20.5.8 chalk: 4.1.2 ci-info: 3.8.0 graceful-fs: 4.2.11 @@ -8319,7 +8366,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.5.6 + '@types/node': 20.5.8 chalk: 4.1.2 ci-info: 3.8.0 graceful-fs: 4.2.11 @@ -8342,7 +8389,7 @@ packages: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 20.5.6 + '@types/node': 20.5.8 merge-stream: 2.0.0 supports-color: 8.1.1 dev: false @@ -10195,7 +10242,7 @@ packages: '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 '@types/long': 4.0.2 - '@types/node': 20.5.6 + '@types/node': 20.5.8 long: 4.0.0 dev: false @@ -10214,7 +10261,7 @@ packages: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 20.5.6 + '@types/node': 20.5.8 long: 5.2.3 dev: false @@ -11981,7 +12028,7 @@ packages: - zod dev: false - /vite@4.2.0(@types/node@16.18.46): + /vite@4.2.0(@types/node@20.5.8): resolution: {integrity: sha512-AbDTyzzwuKoRtMIRLGNxhLRuv1FpRgdIw+1y6AQG73Q5+vtecmvzKo/yk8X/vrHDpETRTx01ABijqUHIzBXi0g==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -12006,7 +12053,7 @@ packages: terser: optional: true dependencies: - '@types/node': 16.18.46 + '@types/node': 20.5.8 esbuild: 0.17.19 postcss: 8.4.29 resolve: 1.22.4 @@ -12023,7 +12070,7 @@ packages: vite: optional: true dependencies: - vite: 4.2.0(@types/node@16.18.46) + vite: 4.2.0(@types/node@20.5.8) dev: true /vlq@1.0.1: diff --git a/src/app.html b/src/app.html index e6a191a..cbb77c8 100644 --- a/src/app.html +++ b/src/app.html @@ -14,7 +14,7 @@ } } - +
%sveltekit.body%
diff --git a/src/lib/Signer.svelte b/src/lib/Signer.svelte new file mode 100644 index 0000000..dee12a9 --- /dev/null +++ b/src/lib/Signer.svelte @@ -0,0 +1,54 @@ + + +
+

{JSON.stringify(message)}

+ {#if signature} +

+ Signature: {JSON.stringify(signature)} +

+ {/if} +
+ + +
+
diff --git a/src/lib/SignerOLD.svelte b/src/lib/SignerOLD.svelte new file mode 100644 index 0000000..2bd6e07 --- /dev/null +++ b/src/lib/SignerOLD.svelte @@ -0,0 +1,120 @@ + + + +{#if status} +
+

Status: {status}

+
+{/if} +{#if messageSignature} +
+

Signature

+
{JSON.stringify(messageSignature)}
+
+
+{/if} diff --git a/src/lib/Wallet.svelte b/src/lib/Wallet.svelte index b3980d0..c44c994 100644 --- a/src/lib/Wallet.svelte +++ b/src/lib/Wallet.svelte @@ -3,13 +3,20 @@ import walletMachine from "./machines/walletMachine"; import { onMount } from "svelte"; import Icon from "@iconify/svelte"; + import { walletState } from "./stores"; + import { messageToSign } from "./stores"; import { signInWithGoogle, startSignIn as startSignInService, } from "./services/signInWithGoogle"; + import Signer from "./Signer.svelte"; + import { getDrawerStore } from "@skeletonlabs/skeleton"; const { state, send } = useMachine(walletMachine); + const drawerStore = getDrawerStore(); + + $: walletState.set($state.context); $: { if ($state.context.pkps && $state.context.sessionSigs) { @@ -33,9 +40,16 @@ startSignInService.set(true); await signInWithGoogle(); } + function clearSession() { send("LOGOUT"); } + + function signRequest() { + const settings = { position: "bottom", id: "signMessage" }; + drawerStore.open(settings); + messageToSign.set({ hello: "test" }); + } {#if $state.matches("sessionAvailable") || $state.matches("creatingSession") || $state.matches("signIn")} @@ -43,7 +57,7 @@
{:else if $state.context.pkps}
-
+

@@ -66,23 +80,23 @@

- + - Logout -
{:else if $state.matches("sessionExpired")} -
+

Error creating session. Please try again.

{JSON.stringify($state.context.error, null, 2)}
{/if} {:else} -
-
+
+
diff --git a/src/lib/services/signMessage.ts b/src/lib/services/signMessage.ts new file mode 100644 index 0000000..458af3a --- /dev/null +++ b/src/lib/services/signMessage.ts @@ -0,0 +1,41 @@ +// $lib/services/signMessage.ts +import { ethers } from "ethers"; + +export async function signMessageWithPKP(sessionSigs, currentPKP, messageToSign) { + try { + const jsonString = JSON.stringify(messageToSign); + const toSign = ethers.getBytes(ethers.hashMessage(jsonString)); + + const litActionCode = ` + const go = async () => { + const sigShare = await LitActions.signEcdsa({ toSign, publicKey, sigName }); + }; + go(); + `; + + const litNodeClient = new LitNodeClient({ litNetwork: "serrano" }); + await litNodeClient.connect(); + + const results = await litNodeClient.executeJs({ + code: litActionCode, + sessionSigs: sessionSigs, + jsParams: { + toSign: toSign, + publicKey: currentPKP.publicKey, + sigName: "sig1", + }, + }); + + const result = results.signatures["sig1"]; + const messageSignature = ethers.Signature.from({ + r: "0x" + result.r, + s: "0x" + result.s, + v: result.recid, + }); + + return { messageSignature }; + } catch (err) { + console.error(err); + return { error: err }; + } +} \ No newline at end of file diff --git a/src/lib/stores.js b/src/lib/stores.js index f0a4496..66558fb 100644 --- a/src/lib/stores.js +++ b/src/lib/stores.js @@ -1,11 +1,13 @@ import { writable } from 'svelte/store'; -export const signRequest = writable({json: {}}); - -export const signedMessages = writable([]) - export const redirectStore = writable(false); +export const walletState = writable(null); + +export const messageToSign = writable(null); + +export const messageSignature = writable(null); + export const googleSession = writable({ activeSession: false }); \ No newline at end of file diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 3edeb5e..94e3228 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -8,6 +8,13 @@ import { initChainProvider } from "$lib/setupChainProvider"; import { googleSession } from "$lib/stores.js"; import Wallet from "$lib/Wallet.svelte"; + import { Drawer, initializeStores } from "@skeletonlabs/skeleton"; + import { getDrawerStore } from "@skeletonlabs/skeleton"; + import Signer from "$lib/Signer.svelte"; + + initializeStores(); + + const drawerStore = getDrawerStore(); let activeSession = false; @@ -28,8 +35,16 @@ } + + {#if $drawerStore.id === "signMessage"} + + {:else} + + {/if} +
diff --git a/tailwind.config.js b/tailwind.config.js deleted file mode 100644 index 13207cc..0000000 --- a/tailwind.config.js +++ /dev/null @@ -1,9 +0,0 @@ -/** @type {import('tailwindcss').Config} */ -export default { - content: ['./src/**/*.{html,js,svelte,ts}'], - theme: { - extend: {}, - }, - plugins: [], -} - diff --git a/tailwind.config.ts b/tailwind.config.ts new file mode 100644 index 0000000..fe7f8e8 --- /dev/null +++ b/tailwind.config.ts @@ -0,0 +1,30 @@ + +import { join } from 'path'; +import type { Config } from 'tailwindcss'; + +// 1. Import the Skeleton plugin +import { skeleton } from '@skeletonlabs/tw-plugin'; + +const config = { + // 2. Opt for dark mode to be handled via the class method + darkMode: 'class', + content: [ + './src/**/*.{html,js,svelte,ts}', + // 3. Append the path to the Skeleton package + join(require.resolve( + '@skeletonlabs/skeleton'), + '../**/*.{html,js,svelte,ts}' + ) + ], + theme: { + extend: {}, + }, + plugins: [ + // 4. Append the Skeleton plugin (after other plugins) + skeleton({ + themes: { preset: ["wintry"] } + }) + ] +} satisfies Config; + +export default config;