Skip to content

Commit

Permalink
Revert "[WALL-31641] Fix invalid signature signing error for message …
Browse files Browse the repository at this point in the history
…signature verification (#119)" (#1125)

This reverts commit 4fb000a.
  • Loading branch information
bangtoven authored Feb 29, 2024
1 parent 9271613 commit e71a004
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 254 deletions.
4 changes: 2 additions & 2 deletions apps/testapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
"@coinbase/wallet-sdk": "workspace:^",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@metamask/eth-sig-util": "^7.0.0",
"framer-motion": "^10.13.1",
"next": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.45.2",
"viem": "^2.7.15"
"react-hook-form": "^7.45.2"
},
"devDependencies": {
"@types/react": "18.2.15"
Expand Down
37 changes: 0 additions & 37 deletions apps/testapp/src/ViemPublicClient/ViemClientContext.tsx

This file was deleted.

42 changes: 16 additions & 26 deletions apps/testapp/src/components/RpcMethods/RpcMethodCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,49 +18,39 @@ import {
InputLeftAddon,
VStack,
} from '@chakra-ui/react';
import React, { useCallback, useState } from 'react';
import React, { useCallback } from 'react';
import { useForm } from 'react-hook-form';

import { useCBWSDK } from '../../context/CBWSDKReactContextProvider';
import { useViemPublicClient } from '../../ViemPublicClient/ViemClientContext';
import { verifySignMsg } from './method/signMessageMethods';
import { ADDR_TO_FILL } from './shortcut/const';

type ResponseType = string;

export function RpcMethodCard({ format, method, params, shortcuts }) {
const [response, setResponse] = useState<Response | null>(null);
const [verifyResult, setVerifyResult] = useState<string | null>(null);
const [error, setError] = useState<Record<string, unknown> | string | number | null>(null);
const [response, setResponse] = React.useState<Response | null>(null);
const [verifyResult, setVerifyResult] = React.useState<string | null>(null);
const [error, setError] = React.useState<Record<string, unknown> | string | number | null>(null);
const { provider } = useCBWSDK();
const viemPublicClient = useViemPublicClient();

const {
handleSubmit,
register,
formState: { errors },
} = useForm();

const verify = useCallback(
async (response: ResponseType, data: Record<string, string>) => {
if (!viemPublicClient) {
throw new Error('ViemPublicClient not found');
}
const verifyResult = await verifySignMsg({
method,
from: data.address?.toLowerCase(),
sign: response,
message: data.message,
viemPublicClient,
});

if (verifyResult) {
setVerifyResult(verifyResult);
return;
}
},
[viemPublicClient]
);
const verify = useCallback(async (response: ResponseType, data: Record<string, string>) => {
const verifyResult = verifySignMsg({
method,
from: data.address?.toLowerCase(),
sign: response,
message: data.message,
});
if (verifyResult) {
setVerifyResult(verifyResult);
return;
}
}, []);

const submit = useCallback(
async (data: Record<string, string>) => {
Expand Down
79 changes: 37 additions & 42 deletions apps/testapp/src/components/RpcMethods/method/signMessageMethods.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { PublicClient } from 'viem/_types/clients/createPublicClient';
import {
MessageTypes,
recoverPersonalSignature,
recoverTypedSignature,
SignTypedDataVersion,
TypedDataV1,
TypedMessage,
} from '@metamask/eth-sig-util';

import { parseMessage } from '../shortcut/ShortcutType';
import { RpcRequestInput } from './RpcRequestInput';
Expand All @@ -21,7 +28,10 @@ const personalSign: RpcRequestInput = {
{ key: 'message', required: true },
{ key: 'address', required: true },
],
format: (data: Record<string, string>) => [data.message, data.address],
format: (data: Record<string, string>) => [
`0x${Buffer.from(data.message, 'utf8').toString('hex')}`,
data.address,
],
};

const ethSignTypedDataV1: RpcRequestInput = {
Expand Down Expand Up @@ -59,79 +69,64 @@ export const signMessageMethods = [
ethSignTypedDataV4,
];

export const verifySignMsg = async ({
export const verifySignMsg = ({
method,
from,
sign,
message,
viemPublicClient,
}: {
method: string;
from: string;
sign: string;
message: unknown;
viemPublicClient: PublicClient;
}) => {
switch (method) {
case 'personal_sign': {
const valid = await viemPublicClient.verifyMessage({
address: from,
message,
const msg = `0x${Buffer.from(message as string, 'utf8').toString('hex')}`;
const recoveredAddr = recoverPersonalSignature({
data: msg,
signature: sign,
});

if (valid) {
return `ViemPublicClient Successfully verified signer: ${from}`;
if (recoveredAddr === from) {
return `SigUtil Successfully verified signer as ${recoveredAddr}`;
} else {
return `ViemPublicClient Failed to verify signer: ${from}`;
return `SigUtil Failed to verify signer when comparing ${recoveredAddr} to ${from}`;
}
}
case 'eth_signTypedData_v1': {
const valid = await viemPublicClient.verifyTypedData({
address: from,
domain: message.domain,
types: message.types,
primaryType: message.primaryType,
message: message.message,
const recoveredAddr = recoverTypedSignature({
data: message as TypedDataV1,
signature: sign,
version: SignTypedDataVersion.V1,
});

if (valid) {
return `ViemPublicClient Successfully verified signer: ${from}`;
if (recoveredAddr === from) {
return `SigUtil Successfully verified signer as ${recoveredAddr}`;
} else {
return `ViemPublicClient Failed to verify signer: ${from}`;
return `SigUtil Failed to verify signer when comparing ${recoveredAddr} to ${from}`;
}
}
case 'eth_signTypedData_v3': {
const valid = await viemPublicClient.verifyTypedData({
address: from,
domain: message.domain,
types: message.types,
primaryType: message.primaryType,
message: message.message,
const recoveredAddr = recoverTypedSignature({
data: message as TypedMessage<MessageTypes>,
signature: sign,
version: SignTypedDataVersion.V3,
});

if (valid) {
return `ViemPublicClient Successfully verified signer: ${from}`;
if (recoveredAddr === from) {
return `SigUtil Successfully verified signer as ${recoveredAddr}`;
} else {
return `ViemPublicClient Failed to verify signer: ${from}`;
return `SigUtil Failed to verify signer when comparing ${recoveredAddr} to ${from}`;
}
}
case 'eth_signTypedData_v4': {
const valid = await viemPublicClient.verifyTypedData({
address: from,
domain: message.domain,
types: message.types,
primaryType: message.primaryType,
message: message.message,
const recoveredAddr = recoverTypedSignature({
data: message as TypedMessage<MessageTypes>,
signature: sign,
version: SignTypedDataVersion.V4,
});

if (valid) {
return `ViemPublicClient Successfully verified signer: ${from}`;
if (recoveredAddr === from) {
return `SigUtil Successfully verified signer as ${recoveredAddr}`;
} else {
return `ViemPublicClient Failed to verify signer: ${from}`;
return `SigUtil Failed to verify signer when comparing ${recoveredAddr} to ${from}`;
}
}
default:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { SignTypedDataReturnType } from 'viem';
import { MessageTypes, TypedDataV1, TypedMessage } from '@metamask/eth-sig-util';

type messageType = TypedDataV1 | TypedMessage<MessageTypes>;

export type ShortcutType = {
key: string;
data: Record<string, string> | any;
data: Record<string, string | messageType>;
};

export const parseMessage = (message: string | SignTypedDataReturnType) => {
export const parseMessage = (message: string | messageType) => {
if (typeof message === 'string') {
return JSON.parse(message);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const ethSignTypedDataV1Shortcuts: ShortcutType[] = [
},
];

const ethSignTypedDataV3Shortcuts: (chainId: number) => ShortcutType[] = (chainId: number) => [
const ethSignTypedDataV3Shortcuts: (chainId) => ShortcutType[] = (chainId: number) => [
{
key: EXAMPLE_MESSAGE,
data: {
Expand Down
67 changes: 30 additions & 37 deletions apps/testapp/src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Container, Grid, GridItem, Heading, Text } from '@chakra-ui/react';
import { Box, Container, Grid, GridItem, Heading } from '@chakra-ui/react';
import React, { useEffect } from 'react';

import { EventListenersCard } from '../components/EventListeners/EventListenersCard';
Expand All @@ -16,7 +16,6 @@ import { sendShortcutsMap } from '../components/RpcMethods/shortcut/sendShortcut
import { ShortcutType } from '../components/RpcMethods/shortcut/ShortcutType';
import { signMessageShortcutsMap } from '../components/RpcMethods/shortcut/signMessageShortcuts';
import { useCBWSDK } from '../context/CBWSDKReactContextProvider';
import { ViemClientProvider } from '../ViemPublicClient/ViemClientContext';

export default function Home() {
const { provider } = useCBWSDK();
Expand All @@ -30,42 +29,36 @@ export default function Home() {
});
}, [provider]);

if (!provider) {
return <Text>Loading...</Text>;
}

return (
<ViemClientProvider provider={provider}>
<Container maxW={WIDTH_2XL} mb={8}>
<Box>
<Heading size="md">Event Listeners</Heading>
<Grid mt={2} templateColumns={{ base: '100%' }} gap={2}>
<EventListenersCard />
</Grid>
</Box>
<MethodsSection title="Wallet Connection" methods={connectionMethods} />
{connected && (
<>
<MethodsSection
title="Switch/Add Chain"
methods={multiChainMethods}
shortcutsMap={multiChainShortcutsMap}
/>
<MethodsSection
title="Sign Message"
methods={signMessageMethods}
shortcutsMap={signMessageShortcutsMap(provider?.chainId)}
/>
<MethodsSection title="Send" methods={sendMethods} shortcutsMap={sendShortcutsMap} />
<MethodsSection
title="Read-only JSON-RPC Requests"
methods={readonlyJsonRpcMethods}
shortcutsMap={readonlyJsonRpcShortcutsMap}
/>
</>
)}
</Container>
</ViemClientProvider>
<Container maxW={WIDTH_2XL} mb={8}>
<Box>
<Heading size="md">Event Listeners</Heading>
<Grid mt={2} templateColumns={{ base: '100%' }} gap={2}>
<EventListenersCard />
</Grid>
</Box>
<MethodsSection title="Wallet Connection" methods={connectionMethods} />
{connected && (
<>
<MethodsSection
title="Switch/Add Chain"
methods={multiChainMethods}
shortcutsMap={multiChainShortcutsMap}
/>
<MethodsSection
title="Sign Message"
methods={signMessageMethods}
shortcutsMap={signMessageShortcutsMap(provider?.chainId)}
/>
<MethodsSection title="Send" methods={sendMethods} shortcutsMap={sendShortcutsMap} />
<MethodsSection
title="Read-only JSON-RPC Requests"
methods={readonlyJsonRpcMethods}
shortcutsMap={readonlyJsonRpcShortcutsMap}
/>
</>
)}
</Container>
);
}

Expand Down
2 changes: 1 addition & 1 deletion apps/testapp/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"incremental": true,
Expand Down
Loading

0 comments on commit e71a004

Please sign in to comment.