fix(dapp): makes sig validation compatible with ERC-1271 (#156)

Co-authored-by: basheer <basheer@audteye.com>
This commit is contained in:
Ben Kremer 2023-04-28 14:05:21 +02:00 committed by GitHub
parent 96f9e0b028
commit c6e9c2d614
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 33 deletions

View File

@ -1,7 +1,6 @@
import { BigNumber, utils } from "ethers"; import { BigNumber, utils } from "ethers";
import { createContext, ReactNode, useContext, useState } from "react"; import { createContext, ReactNode, useContext, useState } from "react";
import * as encoding from "@walletconnect/encoding"; import * as encoding from "@walletconnect/encoding";
import { TypedDataField } from "@ethersproject/abstract-signer";
import { Transaction as EthTransaction } from "@ethereumjs/tx"; import { Transaction as EthTransaction } from "@ethereumjs/tx";
import { recoverTransaction } from "@celo/wallet-base"; import { recoverTransaction } from "@celo/wallet-base";
import { import {
@ -25,6 +24,9 @@ import {
eip712, eip712,
formatTestTransaction, formatTestTransaction,
getLocalStorageTestnetFlag, getLocalStorageTestnetFlag,
hashPersonalMessage,
hashTypedDataMessage,
verifySignature,
} from "../helpers"; } from "../helpers";
import { useWalletConnectClient } from "./ClientContext"; import { useWalletConnectClient } from "./ClientContext";
import { import {
@ -38,6 +40,7 @@ import {
DEFAULT_TEZOS_METHODS, DEFAULT_TEZOS_METHODS,
} from "../constants"; } from "../constants";
import { useChainData } from "./ChainDataContext"; import { useChainData } from "./ChainDataContext";
import { rpcProvidersByChainId } from "../../src/helpers/api";
import { signatureVerify, cryptoWaitReady } from "@polkadot/util-crypto"; import { signatureVerify, cryptoWaitReady } from "@polkadot/util-crypto";
import { import {
@ -298,7 +301,6 @@ export function JsonRpcContextProvider({
// encode message (hex) // encode message (hex)
const hexMsg = encoding.utf8ToHex(message, true); const hexMsg = encoding.utf8ToHex(message, true);
// personal_sign params // personal_sign params
const params = [hexMsg, address]; const params = [hexMsg, address];
@ -314,17 +316,20 @@ export function JsonRpcContextProvider({
// split chainId // split chainId
const [namespace, reference] = chainId.split(":"); const [namespace, reference] = chainId.split(":");
const rpc = rpcProvidersByChainId[Number(reference)];
const targetChainData = chainData[namespace][reference]; if (typeof rpc === "undefined") {
throw new Error(
if (typeof targetChainData === "undefined") { `Missing rpcProvider definition for chainId: ${chainId}`
throw new Error(`Missing chain data for chainId: ${chainId}`); );
} }
const valid = _verifyEip155MessageSignature( const hashMsg = hashPersonalMessage(message);
message, const valid = await verifySignature(
address,
signature, signature,
address hashMsg,
rpc.baseURL
); );
// format displayed result // format displayed result
@ -357,17 +362,20 @@ export function JsonRpcContextProvider({
// split chainId // split chainId
const [namespace, reference] = chainId.split(":"); const [namespace, reference] = chainId.split(":");
const rpc = rpcProvidersByChainId[Number(reference)];
const targetChainData = chainData[namespace][reference]; if (typeof rpc === "undefined") {
throw new Error(
if (typeof targetChainData === "undefined") { `Missing rpcProvider definition for chainId: ${chainId}`
throw new Error(`Missing chain data for chainId: ${chainId}`); );
} }
const valid = _verifyEip155MessageSignature( const hashMsg = hashPersonalMessage(message);
message, const valid = await verifySignature(
address,
signature, signature,
address hashMsg,
rpc.baseURL
); );
// format displayed result // format displayed result
@ -396,23 +404,23 @@ export function JsonRpcContextProvider({
}, },
}); });
// Separate `EIP712Domain` type from remaining types to verify, otherwise `ethers.utils.verifyTypedData` // split chainId
// will throw due to "unused" `EIP712Domain` type. const [namespace, reference] = chainId.split(":");
// See: https://github.com/ethers-io/ethers.js/issues/687#issuecomment-714069471 const rpc = rpcProvidersByChainId[Number(reference)];
const {
EIP712Domain,
...nonDomainTypes
}: Record<string, TypedDataField[]> = eip712.example.types;
const valid = if (typeof rpc === "undefined") {
utils throw new Error(
.verifyTypedData( `Missing rpcProvider definition for chainId: ${chainId}`
eip712.example.domain, );
nonDomainTypes, }
eip712.example.message,
signature const hashedTypedData = hashTypedDataMessage(message);
) const valid = await verifySignature(
.toLowerCase() === address.toLowerCase(); address,
signature,
hashedTypedData,
rpc.baseURL
);
return { return {
method: DEFAULT_EIP155_METHODS.ETH_SIGN_TYPED_DATA, method: DEFAULT_EIP155_METHODS.ETH_SIGN_TYPED_DATA,

View File

@ -1,7 +1,7 @@
import axios, { AxiosInstance } from "axios"; import axios, { AxiosInstance } from "axios";
import { AssetData } from "./types"; import { AssetData } from "./types";
const rpcProvidersByChainId: Record<number, any> = { export const rpcProvidersByChainId: Record<number, any> = {
1: { 1: {
name: "Ethereum Mainnet", name: "Ethereum Mainnet",
baseURL: "https://mainnet.infura.io/v3/5dc0df7abe4645dfb06a9a8c39ede422", baseURL: "https://mainnet.infura.io/v3/5dc0df7abe4645dfb06a9a8c39ede422",