fix(dapps): aligns EIP712 example with the one used in spec
Reference: https://eips.ethereum.org/EIPS/eip-712
This commit is contained in:
parent
86987454eb
commit
929779f213
@ -10,6 +10,7 @@ import Modal from "./components/Modal";
|
|||||||
import { DEFAULT_MAIN_CHAINS, DEFAULT_TEST_CHAINS } from "./constants";
|
import { DEFAULT_MAIN_CHAINS, DEFAULT_TEST_CHAINS } from "./constants";
|
||||||
import {
|
import {
|
||||||
AccountAction,
|
AccountAction,
|
||||||
|
eip712,
|
||||||
formatTestTransaction,
|
formatTestTransaction,
|
||||||
getLocalStorageTestnetFlag,
|
getLocalStorageTestnetFlag,
|
||||||
setLocaleStorageTestnetFlag,
|
setLocaleStorageTestnetFlag,
|
||||||
@ -28,6 +29,7 @@ import {
|
|||||||
} from "./components/app";
|
} from "./components/app";
|
||||||
import { useWalletConnectClient } from "./contexts/ClientContext";
|
import { useWalletConnectClient } from "./contexts/ClientContext";
|
||||||
import { BigNumber, utils } from "ethers";
|
import { BigNumber, utils } from "ethers";
|
||||||
|
import { TypedDataField } from "@ethersproject/abstract-signer";
|
||||||
|
|
||||||
interface IFormattedRpcResponse {
|
interface IFormattedRpcResponse {
|
||||||
method: string;
|
method: string;
|
||||||
@ -177,39 +179,7 @@ export default function App() {
|
|||||||
throw new Error("web3Provider not connected");
|
throw new Error("web3Provider not connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
const typedData = {
|
const message = JSON.stringify(eip712.example);
|
||||||
types: {
|
|
||||||
Person: [
|
|
||||||
{ name: "name", type: "string" },
|
|
||||||
{ name: "wallet", type: "address" },
|
|
||||||
],
|
|
||||||
Mail: [
|
|
||||||
{ name: "from", type: "Person" },
|
|
||||||
{ name: "to", type: "Person" },
|
|
||||||
{ name: "contents", type: "string" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
primaryType: "Mail",
|
|
||||||
domain: {
|
|
||||||
name: "Ether Mail",
|
|
||||||
version: "1",
|
|
||||||
chainId: 1,
|
|
||||||
verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
|
|
||||||
},
|
|
||||||
message: {
|
|
||||||
from: {
|
|
||||||
name: "Cow",
|
|
||||||
wallet: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
|
|
||||||
},
|
|
||||||
to: {
|
|
||||||
name: "Bob",
|
|
||||||
wallet: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
|
|
||||||
},
|
|
||||||
contents: "Hello, Bob!",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const message = JSON.stringify(typedData);
|
|
||||||
|
|
||||||
const [address] = await web3Provider.listAccounts();
|
const [address] = await web3Provider.listAccounts();
|
||||||
|
|
||||||
@ -218,9 +188,19 @@ export default function App() {
|
|||||||
|
|
||||||
// send message
|
// send message
|
||||||
const signature = await web3Provider.send("eth_signTypedData", params);
|
const signature = await web3Provider.send("eth_signTypedData", params);
|
||||||
|
|
||||||
|
// Separate `EIP712Domain` type from remaining types to verify, otherwise `ethers.utils.verifyTypedData`
|
||||||
|
// will throw due to "unused" `EIP712Domain` type.
|
||||||
|
const { EIP712Domain, ...nonDomainTypes }: Record<string, TypedDataField[]> =
|
||||||
|
eip712.example.types;
|
||||||
|
|
||||||
const valid =
|
const valid =
|
||||||
utils.verifyTypedData(typedData.domain, typedData.types, typedData.message, signature) ===
|
utils.verifyTypedData(
|
||||||
address;
|
eip712.example.domain,
|
||||||
|
nonDomainTypes,
|
||||||
|
eip712.example.message,
|
||||||
|
signature,
|
||||||
|
) === address;
|
||||||
return {
|
return {
|
||||||
method: "eth_signTypedData",
|
method: "eth_signTypedData",
|
||||||
address,
|
address,
|
||||||
|
@ -1,47 +1,33 @@
|
|||||||
|
// From spec: https://eips.ethereum.org/EIPS/eip-712
|
||||||
const example = {
|
const example = {
|
||||||
types: {
|
types: {
|
||||||
EIP712Domain: [
|
EIP712Domain: [
|
||||||
{ name: "name", type: "string" },
|
{ name: "name", type: "string" },
|
||||||
{ name: "version", type: "string" },
|
{ name: "version", type: "string" },
|
||||||
|
{ name: "chainId", type: "uint256" },
|
||||||
{ name: "verifyingContract", type: "address" },
|
{ name: "verifyingContract", type: "address" },
|
||||||
],
|
],
|
||||||
RelayRequest: [
|
Person: [
|
||||||
{ name: "target", type: "address" },
|
{ name: "name", type: "string" },
|
||||||
{ name: "encodedFunction", type: "bytes" },
|
{ name: "wallet", type: "address" },
|
||||||
{ name: "gasData", type: "GasData" },
|
|
||||||
{ name: "relayData", type: "RelayData" },
|
|
||||||
],
|
],
|
||||||
GasData: [
|
Mail: [
|
||||||
{ name: "gasLimit", type: "uint256" },
|
{ name: "from", type: "Person" },
|
||||||
{ name: "gasPrice", type: "uint256" },
|
{ name: "to", type: "Person" },
|
||||||
{ name: "pctRelayFee", type: "uint256" },
|
{ name: "contents", type: "string" },
|
||||||
{ name: "baseRelayFee", type: "uint256" },
|
|
||||||
],
|
|
||||||
RelayData: [
|
|
||||||
{ name: "senderAddress", type: "address" },
|
|
||||||
{ name: "senderNonce", type: "uint256" },
|
|
||||||
{ name: "relayWorker", type: "address" },
|
|
||||||
{ name: "paymaster", type: "address" },
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
primaryType: "Mail",
|
||||||
domain: {
|
domain: {
|
||||||
name: "GSN Relayed Transaction",
|
name: "Ether Mail",
|
||||||
version: "1",
|
version: "1",
|
||||||
chainId: 42,
|
chainId: 1,
|
||||||
verifyingContract: "0x6453D37248Ab2C16eBd1A8f782a2CBC65860E60B",
|
verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
|
||||||
},
|
},
|
||||||
primaryType: "RelayRequest",
|
|
||||||
message: {
|
message: {
|
||||||
target: "0x9cf40ef3d1622efe270fe6fe720585b4be4eeeff",
|
from: { name: "Cow", wallet: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" },
|
||||||
encodedFunction:
|
to: { name: "Bob", wallet: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" },
|
||||||
"0xa9059cbb0000000000000000000000002e0d94754b348d208d64d52d78bcd443afa9fa520000000000000000000000000000000000000000000000000000000000000007",
|
contents: "Hello, Bob!",
|
||||||
gasData: { gasLimit: "39507", gasPrice: "1700000000", pctRelayFee: "70", baseRelayFee: "0" },
|
|
||||||
relayData: {
|
|
||||||
senderAddress: "0x22d491bde2303f2f43325b2108d26f1eaba1e32b",
|
|
||||||
senderNonce: "3",
|
|
||||||
relayWorker: "0x3baee457ad824c94bd3953183d725847d023a2cf",
|
|
||||||
paymaster: "0x957F270d45e9Ceca5c5af2b49f1b5dC1Abb0421c",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,7 +8,12 @@ import Column from "./components/Column";
|
|||||||
import Header from "./components/Header";
|
import Header from "./components/Header";
|
||||||
import Modal from "./components/Modal";
|
import Modal from "./components/Modal";
|
||||||
import { DEFAULT_MAIN_CHAINS, DEFAULT_TEST_CHAINS } from "./constants";
|
import { DEFAULT_MAIN_CHAINS, DEFAULT_TEST_CHAINS } from "./constants";
|
||||||
import { AccountAction, getLocalStorageTestnetFlag, setLocaleStorageTestnetFlag } from "./helpers";
|
import {
|
||||||
|
AccountAction,
|
||||||
|
eip712,
|
||||||
|
getLocalStorageTestnetFlag,
|
||||||
|
setLocaleStorageTestnetFlag,
|
||||||
|
} from "./helpers";
|
||||||
import Toggle from "./components/Toggle";
|
import Toggle from "./components/Toggle";
|
||||||
import RequestModal from "./modals/RequestModal";
|
import RequestModal from "./modals/RequestModal";
|
||||||
import PingModal from "./modals/PingModal";
|
import PingModal from "./modals/PingModal";
|
||||||
@ -23,6 +28,7 @@ import {
|
|||||||
} from "./components/app";
|
} from "./components/app";
|
||||||
import { useWalletConnectClient } from "./contexts/ClientContext";
|
import { useWalletConnectClient } from "./contexts/ClientContext";
|
||||||
import { utils } from "ethers";
|
import { utils } from "ethers";
|
||||||
|
import { TypedDataField } from "@ethersproject/abstract-signer";
|
||||||
|
|
||||||
interface IFormattedRpcResponse {
|
interface IFormattedRpcResponse {
|
||||||
method: string;
|
method: string;
|
||||||
@ -175,39 +181,7 @@ export default function App() {
|
|||||||
throw new Error("web3Provider.currentProvider is not set");
|
throw new Error("web3Provider.currentProvider is not set");
|
||||||
}
|
}
|
||||||
|
|
||||||
const typedData = {
|
const message = JSON.stringify(eip712.example);
|
||||||
types: {
|
|
||||||
Person: [
|
|
||||||
{ name: "name", type: "string" },
|
|
||||||
{ name: "wallet", type: "address" },
|
|
||||||
],
|
|
||||||
Mail: [
|
|
||||||
{ name: "from", type: "Person" },
|
|
||||||
{ name: "to", type: "Person" },
|
|
||||||
{ name: "contents", type: "string" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
primaryType: "Mail",
|
|
||||||
domain: {
|
|
||||||
name: "Ether Mail",
|
|
||||||
version: "1",
|
|
||||||
chainId: 1,
|
|
||||||
verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
|
|
||||||
},
|
|
||||||
message: {
|
|
||||||
from: {
|
|
||||||
name: "Cow",
|
|
||||||
wallet: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
|
|
||||||
},
|
|
||||||
to: {
|
|
||||||
name: "Bob",
|
|
||||||
wallet: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
|
|
||||||
},
|
|
||||||
contents: "Hello, Bob!",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const message = JSON.stringify(typedData);
|
|
||||||
|
|
||||||
const [address] = await web3Provider.eth.getAccounts();
|
const [address] = await web3Provider.eth.getAccounts();
|
||||||
|
|
||||||
@ -222,9 +196,20 @@ export default function App() {
|
|||||||
method: "eth_signTypedData",
|
method: "eth_signTypedData",
|
||||||
params,
|
params,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Separate `EIP712Domain` type from remaining types to verify, otherwise `ethers.utils.verifyTypedData`
|
||||||
|
// will throw due to "unused" `EIP712Domain` type.
|
||||||
|
const { EIP712Domain, ...nonDomainTypes }: Record<string, TypedDataField[]> =
|
||||||
|
eip712.example.types;
|
||||||
|
|
||||||
const valid =
|
const valid =
|
||||||
utils.verifyTypedData(typedData.domain, typedData.types, typedData.message, signature) ===
|
utils.verifyTypedData(
|
||||||
address;
|
eip712.example.domain,
|
||||||
|
nonDomainTypes,
|
||||||
|
eip712.example.message,
|
||||||
|
signature,
|
||||||
|
) === address;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
method: "eth_signTypedData",
|
method: "eth_signTypedData",
|
||||||
address,
|
address,
|
||||||
|
@ -1,47 +1,33 @@
|
|||||||
|
// From spec: https://eips.ethereum.org/EIPS/eip-712
|
||||||
const example = {
|
const example = {
|
||||||
types: {
|
types: {
|
||||||
EIP712Domain: [
|
EIP712Domain: [
|
||||||
{ name: "name", type: "string" },
|
{ name: "name", type: "string" },
|
||||||
{ name: "version", type: "string" },
|
{ name: "version", type: "string" },
|
||||||
|
{ name: "chainId", type: "uint256" },
|
||||||
{ name: "verifyingContract", type: "address" },
|
{ name: "verifyingContract", type: "address" },
|
||||||
],
|
],
|
||||||
RelayRequest: [
|
Person: [
|
||||||
{ name: "target", type: "address" },
|
{ name: "name", type: "string" },
|
||||||
{ name: "encodedFunction", type: "bytes" },
|
{ name: "wallet", type: "address" },
|
||||||
{ name: "gasData", type: "GasData" },
|
|
||||||
{ name: "relayData", type: "RelayData" },
|
|
||||||
],
|
],
|
||||||
GasData: [
|
Mail: [
|
||||||
{ name: "gasLimit", type: "uint256" },
|
{ name: "from", type: "Person" },
|
||||||
{ name: "gasPrice", type: "uint256" },
|
{ name: "to", type: "Person" },
|
||||||
{ name: "pctRelayFee", type: "uint256" },
|
{ name: "contents", type: "string" },
|
||||||
{ name: "baseRelayFee", type: "uint256" },
|
|
||||||
],
|
|
||||||
RelayData: [
|
|
||||||
{ name: "senderAddress", type: "address" },
|
|
||||||
{ name: "senderNonce", type: "uint256" },
|
|
||||||
{ name: "relayWorker", type: "address" },
|
|
||||||
{ name: "paymaster", type: "address" },
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
primaryType: "Mail",
|
||||||
domain: {
|
domain: {
|
||||||
name: "GSN Relayed Transaction",
|
name: "Ether Mail",
|
||||||
version: "1",
|
version: "1",
|
||||||
chainId: 42,
|
chainId: 1,
|
||||||
verifyingContract: "0x6453D37248Ab2C16eBd1A8f782a2CBC65860E60B",
|
verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
|
||||||
},
|
},
|
||||||
primaryType: "RelayRequest",
|
|
||||||
message: {
|
message: {
|
||||||
target: "0x9cf40ef3d1622efe270fe6fe720585b4be4eeeff",
|
from: { name: "Cow", wallet: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" },
|
||||||
encodedFunction:
|
to: { name: "Bob", wallet: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" },
|
||||||
"0xa9059cbb0000000000000000000000002e0d94754b348d208d64d52d78bcd443afa9fa520000000000000000000000000000000000000000000000000000000000000007",
|
contents: "Hello, Bob!",
|
||||||
gasData: { gasLimit: "39507", gasPrice: "1700000000", pctRelayFee: "70", baseRelayFee: "0" },
|
|
||||||
relayData: {
|
|
||||||
senderAddress: "0x22d491bde2303f2f43325b2108d26f1eaba1e32b",
|
|
||||||
senderNonce: "3",
|
|
||||||
relayWorker: "0x3baee457ad824c94bd3953183d725847d023a2cf",
|
|
||||||
paymaster: "0x957F270d45e9Ceca5c5af2b49f1b5dC1Abb0421c",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import { formatDirectSignDoc, stringifySignDocValues } from "cosmos-wallet";
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
ChainNamespaces,
|
ChainNamespaces,
|
||||||
|
eip712,
|
||||||
formatTestTransaction,
|
formatTestTransaction,
|
||||||
getAllChainNamespaces,
|
getAllChainNamespaces,
|
||||||
hashPersonalMessage,
|
hashPersonalMessage,
|
||||||
@ -12,6 +13,7 @@ import {
|
|||||||
} from "../helpers";
|
} from "../helpers";
|
||||||
import { useWalletConnectClient } from "./ClientContext";
|
import { useWalletConnectClient } from "./ClientContext";
|
||||||
import { apiGetChainNamespace, ChainsMap } from "caip-api";
|
import { apiGetChainNamespace, ChainsMap } from "caip-api";
|
||||||
|
import { TypedDataField } from "@ethersproject/abstract-signer";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Types
|
* Types
|
||||||
@ -294,39 +296,7 @@ export function JsonRpcContextProvider({ children }: { children: ReactNode | Rea
|
|||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
testSignTypedData: _createJsonRpcRequestHandler(async (chainId: string, address: string) => {
|
testSignTypedData: _createJsonRpcRequestHandler(async (chainId: string, address: string) => {
|
||||||
const typedData = {
|
const message = JSON.stringify(eip712.example);
|
||||||
types: {
|
|
||||||
Person: [
|
|
||||||
{ name: "name", type: "string" },
|
|
||||||
{ name: "wallet", type: "address" },
|
|
||||||
],
|
|
||||||
Mail: [
|
|
||||||
{ name: "from", type: "Person" },
|
|
||||||
{ name: "to", type: "Person" },
|
|
||||||
{ name: "contents", type: "string" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
primaryType: "Mail",
|
|
||||||
domain: {
|
|
||||||
name: "Ether Mail",
|
|
||||||
version: "1",
|
|
||||||
chainId: 1,
|
|
||||||
verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
|
|
||||||
},
|
|
||||||
message: {
|
|
||||||
from: {
|
|
||||||
name: "Cow",
|
|
||||||
wallet: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
|
|
||||||
},
|
|
||||||
to: {
|
|
||||||
name: "Bob",
|
|
||||||
wallet: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
|
|
||||||
},
|
|
||||||
contents: "Hello, Bob!",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const message = JSON.stringify(typedData);
|
|
||||||
|
|
||||||
// eth_signTypedData params
|
// eth_signTypedData params
|
||||||
const params = [address, message];
|
const params = [address, message];
|
||||||
@ -340,9 +310,19 @@ export function JsonRpcContextProvider({ children }: { children: ReactNode | Rea
|
|||||||
params,
|
params,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Separate `EIP712Domain` type from remaining types to verify, otherwise `ethers.utils.verifyTypedData`
|
||||||
|
// will throw due to "unused" `EIP712Domain` type.
|
||||||
|
const { EIP712Domain, ...nonDomainTypes }: Record<string, TypedDataField[]> =
|
||||||
|
eip712.example.types;
|
||||||
|
|
||||||
const valid =
|
const valid =
|
||||||
utils.verifyTypedData(typedData.domain, typedData.types, typedData.message, signature) ===
|
utils.verifyTypedData(
|
||||||
address;
|
eip712.example.domain,
|
||||||
|
nonDomainTypes,
|
||||||
|
eip712.example.message,
|
||||||
|
signature,
|
||||||
|
) === address;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
method: "eth_signTypedData",
|
method: "eth_signTypedData",
|
||||||
|
@ -1,47 +1,33 @@
|
|||||||
|
// From spec: https://eips.ethereum.org/EIPS/eip-712
|
||||||
const example = {
|
const example = {
|
||||||
types: {
|
types: {
|
||||||
EIP712Domain: [
|
EIP712Domain: [
|
||||||
{ name: "name", type: "string" },
|
{ name: "name", type: "string" },
|
||||||
{ name: "version", type: "string" },
|
{ name: "version", type: "string" },
|
||||||
|
{ name: "chainId", type: "uint256" },
|
||||||
{ name: "verifyingContract", type: "address" },
|
{ name: "verifyingContract", type: "address" },
|
||||||
],
|
],
|
||||||
RelayRequest: [
|
Person: [
|
||||||
{ name: "target", type: "address" },
|
{ name: "name", type: "string" },
|
||||||
{ name: "encodedFunction", type: "bytes" },
|
{ name: "wallet", type: "address" },
|
||||||
{ name: "gasData", type: "GasData" },
|
|
||||||
{ name: "relayData", type: "RelayData" },
|
|
||||||
],
|
],
|
||||||
GasData: [
|
Mail: [
|
||||||
{ name: "gasLimit", type: "uint256" },
|
{ name: "from", type: "Person" },
|
||||||
{ name: "gasPrice", type: "uint256" },
|
{ name: "to", type: "Person" },
|
||||||
{ name: "pctRelayFee", type: "uint256" },
|
{ name: "contents", type: "string" },
|
||||||
{ name: "baseRelayFee", type: "uint256" },
|
|
||||||
],
|
|
||||||
RelayData: [
|
|
||||||
{ name: "senderAddress", type: "address" },
|
|
||||||
{ name: "senderNonce", type: "uint256" },
|
|
||||||
{ name: "relayWorker", type: "address" },
|
|
||||||
{ name: "paymaster", type: "address" },
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
primaryType: "Mail",
|
||||||
domain: {
|
domain: {
|
||||||
name: "GSN Relayed Transaction",
|
name: "Ether Mail",
|
||||||
version: "1",
|
version: "1",
|
||||||
chainId: 42,
|
chainId: 1,
|
||||||
verifyingContract: "0x6453D37248Ab2C16eBd1A8f782a2CBC65860E60B",
|
verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
|
||||||
},
|
},
|
||||||
primaryType: "RelayRequest",
|
|
||||||
message: {
|
message: {
|
||||||
target: "0x9cf40ef3d1622efe270fe6fe720585b4be4eeeff",
|
from: { name: "Cow", wallet: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" },
|
||||||
encodedFunction:
|
to: { name: "Bob", wallet: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" },
|
||||||
"0xa9059cbb0000000000000000000000002e0d94754b348d208d64d52d78bcd443afa9fa520000000000000000000000000000000000000000000000000000000000000007",
|
contents: "Hello, Bob!",
|
||||||
gasData: { gasLimit: "39507", gasPrice: "1700000000", pctRelayFee: "70", baseRelayFee: "0" },
|
|
||||||
relayData: {
|
|
||||||
senderAddress: "0x22d491bde2303f2f43325b2108d26f1eaba1e32b",
|
|
||||||
senderNonce: "3",
|
|
||||||
relayWorker: "0x3baee457ad824c94bd3953183d725847d023a2cf",
|
|
||||||
paymaster: "0x957F270d45e9Ceca5c5af2b49f1b5dC1Abb0421c",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user