Re-adding signing capabilities and adding better UI

This commit is contained in:
Samuel Andert 2023-09-02 13:26:05 +02:00
parent 9b9ac7d89e
commit 61ba4d0e4f
11 changed files with 375 additions and 57 deletions

View File

@ -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",

View File

@ -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:

View File

@ -14,7 +14,7 @@
}
}
</script>
<body data-sveltekit-preload-data="hover">
<body data-theme="wintry" data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

54
src/lib/Signer.svelte Normal file
View File

@ -0,0 +1,54 @@
<script lang="ts">
import { signMessageWithPKP } from "$lib/services/signMessage";
import { walletState, messageToSign, messageSignature } from "$lib/stores.js";
let currentPKP;
let sessionSigs;
let message;
let signature;
walletState.subscribe((value) => {
currentPKP = value.pkps[0];
sessionSigs = value.sessionSigs;
});
messageToSign.subscribe((value) => {
message = value;
});
messageSignature.subscribe((value) => {
signature = value;
});
async function signMessage() {
const result = await signMessageWithPKP(sessionSigs, currentPKP, message);
if (result.error) {
console.error(result.error);
} else {
messageSignature.set(result.messageSignature);
}
}
function declineSign() {
messageSignature.set(null);
}
</script>
<div class="flex flex-col items-center justify-center h-full space-y-4">
<p class="text-lg break-words">{JSON.stringify(message)}</p>
{#if signature}
<p class="text-sm font-bold break-words">
Signature: {JSON.stringify(signature)}
</p>
{/if}
<div
class="absolute bottom-0 flex items-center justify-center w-full pb-4 space-x-4"
>
<button on:click={declineSign} class="btn variant-filled-error"
>Decline</button
>
<button on:click={signMessage} class="btn variant-filled-success"
>Sign</button
>
</div>
</div>

120
src/lib/SignerOLD.svelte Normal file
View File

@ -0,0 +1,120 @@
<!-- SignVerifyMessage.svelte -->
<script lang="ts">
import { ethers } from "ethers";
import { onMount } from "svelte";
import { signRequest, signedMessages } from "./stores.js";
let messageToSign = {};
let currentPKP;
let sessionSigs;
let status = "";
let litNodeClient;
let messageSignature;
onMount(async () => {
litNodeClient = new LitNodeClient({ litNetwork: "serrano" });
await litNodeClient.connect();
const sessionSigsLocalStorage = localStorage.getItem("google-session");
const currentPKPLocalStorage = localStorage.getItem("current-pkp");
if (sessionSigsLocalStorage && currentPKPLocalStorage) {
sessionSigs = JSON.parse(sessionSigsLocalStorage);
currentPKP = JSON.parse(currentPKPLocalStorage);
}
});
async function signMessageWithPKP() {
const userConfirmed = window.confirm(
"Do you want to sign the following message?\n\n" +
JSON.stringify(messageToSign, null, 2)
);
if (!userConfirmed) {
status = "User did not allow to sign the message.";
dispatch("status", status);
return;
}
try {
// Create a specific JSON object
const jsonString = JSON.stringify(messageToSign);
// Convert the JSON string to an array of character codes
const toSign = ethers.getBytes(ethers.hashMessage(jsonString));
const litActionCode = `
const go = async () => {
const sigShare = await LitActions.signEcdsa({ toSign, publicKey, sigName });
};
go();
`;
// Sign message
const results = await litNodeClient.executeJs({
code: litActionCode,
sessionSigs: sessionSigs,
jsParams: {
toSign: toSign,
publicKey: currentPKP.publicKey,
sigName: "sig1",
},
});
// Get signature
const result = results.signatures["sig1"];
messageSignature = ethers.Signature.from({
r: "0x" + result.r,
s: "0x" + result.s,
v: result.recid,
});
signedMessages.update((messages) => [
...messages,
{ json: messageToSign, signature: messageSignature },
]);
// verify();
} catch (err) {
console.error(err);
}
}
async function verify() {
const response = await fetch("/api/verify", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
messageToSign,
messageSignature,
currentPKP,
}),
});
if (!response.ok) {
alert("verify failed");
} else {
let json = await response.json();
alert(json.verified ? "Signature valid" : "! Signature NOT valid !");
}
}
signRequest.subscribe(({ json }) => {
if (messageToSign && Object.keys(json).length > 0) {
signRequest.set({ json: {} });
messageToSign = json;
signMessageWithPKP(json);
}
});
</script>
{#if status}
<div class="mt-4 text-center">
<p>Status: {status}</p>
</div>
{/if}
{#if messageSignature}
<div class="mt-4 text-center">
<p>Signature</p>
<pre>{JSON.stringify(messageSignature)}</pre>
</div>
<button on:click={verify}>Verify</button><br />
{/if}

View File

@ -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" });
}
</script>
{#if $state.matches("sessionAvailable") || $state.matches("creatingSession") || $state.matches("signIn")}
@ -43,7 +57,7 @@
<div class="w-1/3">
<button
on:click={startSignIn}
class="w-full py-2 text-white bg-blue-500 rounded hover:bg-blue-700 flex items-center justify-center"
class="flex items-center justify-center w-full py-2 text-white bg-blue-500 rounded hover:bg-blue-700"
>
<span class="mr-2"><Icon icon="flat-color-icons:google" /></span>
<span>Sign in with Google</span>
@ -51,9 +65,9 @@
</div>
{:else if $state.context.pkps}
<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"
class="fixed bottom-0 left-0 right-0 flex flex-col items-center p-3 space-y-4 bg-white bg-opacity-75 rounded-t-lg shadow-md"
>
<div class="w-full flex items-center justify-between space-x-4">
<div class="flex items-center justify-between w-full space-x-4">
<div class="flex items-center space-x-2">
<div>
<p class="text-sm">
@ -66,23 +80,23 @@
</p>
</div>
</div>
<button
on:click={clearSession}
class="py-1 px-2 text-white bg-red-500 rounded hover:bg-red-700"
<button on:click={signRequest} type="button" class="btn variant-filled"
>SignRequest</button
>
<button type="button" class="btn variant-filled" on:click={clearSession}
>Logout</button
>
Logout
</button>
</div>
</div>
{:else if $state.matches("sessionExpired")}
<div class="bg-white p-10">
<div class="p-10 bg-white">
<p>Error creating session. Please try again.</p>
<pre>{JSON.stringify($state.context.error, null, 2)}</pre>
</div>
{/if}
{:else}
<div class="bg-white p-10 rounded-full">
<div class="bg-white rounded-full p-5 animate-spin">
<div class="p-10 bg-white rounded-full">
<div class="p-5 bg-white rounded-full animate-spin">
<Icon icon="la:spinner" width="100" height="100" />
</div>
</div>

View File

@ -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 };
}
}

View File

@ -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
});

View File

@ -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 @@
}
</script>
<Drawer>
{#if $drawerStore.id === "signMessage"}
<Signer messageToSign={{ hello: "me" }} />
{:else}
<!-- (fallback contents) -->
{/if}</Drawer
>
<div
class="flex items-center justify-center h-screen bg-cover bg-center"
class="flex items-center justify-center h-screen bg-center bg-cover"
style="background-image: url('lake.jpeg');"
>
<QueryClientProvider client={data.queryClient}>

View File

@ -1,9 +0,0 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{html,js,svelte,ts}'],
theme: {
extend: {},
},
plugins: [],
}

30
tailwind.config.ts Normal file
View File

@ -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;