From 9d44945ff2d96fc4de5e0348a48608d91e2ec924 Mon Sep 17 00:00:00 2001 From: Andrew Min Date: Thu, 11 Sep 2025 21:38:40 -0400 Subject: [PATCH] use viem signature verification --- .../src/app/dashboard/page.tsx | 4 ++-- examples/react-components/src/app/utils.ts | 22 ++++++++++++------- .../src/components/demo/DemoPanel.tsx | 2 +- examples/react-wallet-kit/src/utils.ts | 13 ++++++----- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/examples/react-components/src/app/dashboard/page.tsx b/examples/react-components/src/app/dashboard/page.tsx index 7a8977760..9252818ce 100644 --- a/examples/react-components/src/app/dashboard/page.tsx +++ b/examples/react-components/src/app/dashboard/page.tsx @@ -451,12 +451,12 @@ export default function Dashboard() { } }; - const handleVerify = () => { + const handleVerify = async () => { if (!signature) return; const addressType = selectedAccount?.startsWith("0x") ? "ETH" : "SOL"; const verificationPassed = addressType === "ETH" - ? verifyEthSignatureWithAddress( + ? await verifyEthSignatureWithAddress( messageToSign, signature.r, signature.s, diff --git a/examples/react-components/src/app/utils.ts b/examples/react-components/src/app/utils.ts index 004aca7cb..ee0986366 100644 --- a/examples/react-components/src/app/utils.ts +++ b/examples/react-components/src/app/utils.ts @@ -1,8 +1,8 @@ -import { PublicKey, PublicKeyInitData } from "@solana/web3.js"; +import { PublicKey } from "@solana/web3.js"; import nacl from "tweetnacl"; import { Buffer } from "buffer"; -import { hashMessage, keccak256, recoverAddress, toUtf8Bytes } from "ethers"; +import { recoverMessageAddress, keccak256, stringToHex } from "viem"; /** * Verifies an Ethereum signature and returns the address it was signed with. @@ -11,22 +11,28 @@ import { hashMessage, keccak256, recoverAddress, toUtf8Bytes } from "ethers"; * @param {string} s - The s value of the signature. * @param {string} v - The v value of the signature. * @param {string} address - The Ethereum address of the signer. - * @returns {boolean} - The recovered Ethereum address. + * @returns {Promise} - The recovered Ethereum address. */ -export function verifyEthSignatureWithAddress( +export async function verifyEthSignatureWithAddress( message: string, r: string, s: string, v: string, address: string, -): boolean { +): Promise { try { // Construct the full signature - const signature = `0x${r}${s}${v === "00" ? "1b" : "1c"}`; // 1b/1c corresponds to v for Ethereum - const hashedMessage = keccak256(toUtf8Bytes(message)); + const signature: `0x${string}` = `0x${r}${s}${v === "00" ? "1b" : "1c"}`; // 1b/1c corresponds to v for Ethereum + const hashedMessage = keccak256(stringToHex(message)); // Recover the address from the signature - return address == recoverAddress(hashedMessage, signature); + return ( + address == + (await recoverMessageAddress({ + message: hashedMessage, + signature, + })) + ); } catch (error) { console.error("Ethereum signature verification failed:", error); return false; diff --git a/examples/react-wallet-kit/src/components/demo/DemoPanel.tsx b/examples/react-wallet-kit/src/components/demo/DemoPanel.tsx index 6ff9fa4bb..9c1d64817 100644 --- a/examples/react-wallet-kit/src/components/demo/DemoPanel.tsx +++ b/examples/react-wallet-kit/src/components/demo/DemoPanel.tsx @@ -332,7 +332,7 @@ export default function DemoPanel() { const verificationPassed = selectedWalletAccount.addressFormat === "ADDRESS_FORMAT_ETHEREUM" - ? verifyEthSignatureWithAddress( + ? await verifyEthSignatureWithAddress( messageToSign, res.r, res.s, diff --git a/examples/react-wallet-kit/src/utils.ts b/examples/react-wallet-kit/src/utils.ts index 28dab3c95..1e42856a3 100644 --- a/examples/react-wallet-kit/src/utils.ts +++ b/examples/react-wallet-kit/src/utils.ts @@ -3,7 +3,8 @@ import { PublicKey } from "@solana/web3.js"; import nacl from "tweetnacl"; import { Buffer } from "buffer"; -import { hashMessage, recoverAddress } from "ethers"; +import { hashMessage } from "ethers"; +import { recoverMessageAddress } from "viem"; // Custom hook to get the current screen size export function useScreenSize() { @@ -231,23 +232,25 @@ function oklchToHex({ L, C, h }: { L: number; C: number; h: number }) { * @param {string} address - The Ethereum address of the signer. * @returns {boolean} - The recovered Ethereum address. */ -export function verifyEthSignatureWithAddress( +export async function verifyEthSignatureWithAddress( message: string, r: string, s: string, v: string, address: string, -): boolean { +): Promise { try { // Construct the full signature - const signature = `0x${r}${s}${v}`; + const signature: `0x${string}` = `0x${r}${s}${v}`; const hashedMessage = hashMessage(message); // Recover the address from the signature return ( address.toLowerCase() === - recoverAddress(hashedMessage, signature).toLowerCase() + ( + await recoverMessageAddress({ message: hashedMessage, signature }) + ).toLowerCase() ); } catch (error) { console.error("Ethereum signature verification failed:", error);