Skip to content

Commit 889cef7

Browse files
committed
feat: use eip712 typed structured data signing
1 parent d4eb2da commit 889cef7

File tree

3 files changed

+42
-18
lines changed

3 files changed

+42
-18
lines changed

web/netlify/functions/update-settings.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Handler } from "@netlify/functions";
2-
import { verifyMessage } from "viem";
2+
import { verifyTypedData } from "viem";
33
import { createClient } from "@supabase/supabase-js";
4-
import { arbitrumGoerli } from "viem/chains";
4+
import messages from "../../src/consts/eip712-messages";
55

66
const SUPABASE_KEY = process.env.SUPABASE_CLIENT_API_KEY;
77
const SUPABASE_URL = process.env.SUPABASE_URL;
@@ -12,17 +12,15 @@ export const handler: Handler = async (event) => {
1212
if (!event.body) {
1313
throw new Error("No body provided");
1414
}
15-
// TODO: sanitize the body
15+
// TODO: sanitize event.body
1616
const { email, telegram, nonce, address, signature } = JSON.parse(event.body);
1717
const lowerCaseAddress = address.toLowerCase() as `0x${string}`;
18-
const data = {
19-
address: lowerCaseAddress,
20-
message: `Email:${email},Nonce:${nonce}`,
21-
signature,
22-
};
2318
// Note: this does NOT work for smart contract wallets, but viem's publicClient.verifyMessage() fails to verify atm.
24-
// https://viem.sh/docs/utilities/verifyMessage.html
25-
const isValid = await verifyMessage(data);
19+
// https://viem.sh/docs/utilities/verifyTypedData.html
20+
const isValid = await verifyTypedData({
21+
...messages.contactDetails(address, nonce, telegram, email),
22+
signature,
23+
});
2624
if (!isValid) {
2725
// If the recovered address does not match the provided address, return an error
2826
throw new Error("Signature verification failed");

web/src/consts/eip712-messages.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export default {
2+
contactDetails: (address: `0x${string}`, nonce, telegram = "", email = "") =>
3+
({
4+
address: address.toLowerCase() as `0x${string}`,
5+
domain: {
6+
name: "Kleros v2",
7+
version: "1",
8+
chainId: 421_613,
9+
},
10+
types: {
11+
ContactDetails: [
12+
{ name: "email", type: "string" },
13+
{ name: "telegram", type: "string" },
14+
{ name: "nonce", type: "string" },
15+
],
16+
},
17+
primaryType: "ContactDetails",
18+
message: {
19+
email,
20+
telegram,
21+
nonce,
22+
},
23+
} as const),
24+
};

web/src/layout/Header/navbar/Menu/Settings/SendMeNotifications/FormNotifs/index.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { useWalletClient, useAccount } from "wagmi";
44
import { Button } from "@kleros/ui-components-library";
55
import { uploadSettingsToSupabase } from "utils/uploadSettingsToSupabase";
66
import FormContact from "./FormContact";
7+
import messages from "../../../../../../../consts/eip712-messages";
78

89
const FormContainer = styled.form`
910
position: relative;
@@ -36,14 +37,15 @@ const FormNotifs: React.FC = () => {
3637

3738
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
3839
e.preventDefault();
40+
if (!address) {
41+
throw new Error("Missing address");
42+
}
3943
const nonce = new Date().getTime().toString();
40-
const signature = await walletClient?.signMessage({
41-
account: address,
42-
message: `Email:${emailInput},Nonce:${nonce}`,
43-
});
44-
if (!address || !signature) {
45-
console.error("Missing address or signature");
46-
return;
44+
const signature = await walletClient?.signTypedData(
45+
messages.contactDetails(address, nonce, telegramInput, emailInput)
46+
);
47+
if (!signature) {
48+
throw new Error("Missing signature");
4749
}
4850
const data = {
4951
email: emailInput,
@@ -80,7 +82,7 @@ const FormNotifs: React.FC = () => {
8082
</FormContactContainer>
8183

8284
<ButtonContainer>
83-
<Button text="Save" disabled={!emailIsValid} />
85+
<Button text="Save" disabled={!emailIsValid && !telegramIsValid} />
8486
</ButtonContainer>
8587
</FormContainer>
8688
);

0 commit comments

Comments
 (0)