'How to verify message in wallet connect with ethers primarily on ambire wallet?
I am trying to sign a message with wallet connect using ethers, but I am facing an issue when verifying the message with ambire wallet, it's not returning any response.
const signMessage = async () => {
try {
console.log("started");
// 1.] create a provider
const walletConnectProvider = new WalletConnectProvider({
infuraId: "3cd774e14cf34ff78167908f8377051c", // Required
// qrcode: true
});
// 2.] enable provider
await walletConnectProvider.enable();
// console.log(walletConnectProvider.wc.accounts[0]);
let rawMessage = "Hello World";
let rawMessageLength = new Blob([rawMessage]).size;
let message = ethers.utils.toUtf8Bytes(
"\x19Ethereum Signed Message:\n" + rawMessageLength + rawMessage
);
message = ethers.utils.keccak256(message);
var params = [
walletConnectProvider.wc.accounts[0],
message,
];
// 3.] sign message
const provider = new providers.Web3Provider(walletConnectProvider);
const signer = provider.getSigner();
let signature = await signer.signMessage(message);
console.log("signature", signature);
// 4.] verify message
let verified = await ethers.utils.verifyMessage(message, signature);
console.log("verified", verified);
} catch (err) {}
};
Solution 1:[1]
there are a couple of things you additionally need:
- You need to pass the original message (before prefix) to
signer.signMessage
, in other words the rawMessage:await signer.signMessage(rawMessage)
- because the wallet (no matter if it's Ambire or not) will add the prefix - In order to support smart wallets like Ambire, Gnosis Safe, Argent and others, you need to implement EIP 1271.
In JS (warning: not tested), this will look somewhat like this:
const signerAddr = await signer.getAddress();
if (provider.getCode(signerAddr) === '0x') {
// Regular RSV sig verification
verified = signerAddr === (await ethers.utils.verifyMessage(message, signature));
} else {
// Smart contract wallet (EIP 1271) verification: see https://eips.ethereum.org/EIPS/eip-1271 for more info
const EIP1271ABI = ['function isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4 magicValue)'];
const EIP1271MagicValue = '0x1626ba7e';
const signerEIP1271Contract = new ethers.Contract(signerAddr, EIP1271ABI, provider);
const rawMessageLength = new Blob([rawMessage]).size;
const message = ethers.utils.toUtf8Bytes(
"\x19Ethereum Signed Message:\n" + rawMessageLength + rawMessage
);
const messageHash = ethers.utils.keccak256(message);
verified = EIP1271MagicValue === (await signerEIP1271Contract.isValidSignature(messageHash, signature));
}
NOTE: We, the Ambire team, are currently working on a comprehensive guide on how to verify all styles of signature (EIP1271, EIP712, 712+1271, regular), which will hopefully be linked by the ethers.js documentation.
EDIT: We've published a library that makes this a whole lot easier, please check it out: https://github.com/AmbireTech/signature-validator/ - we recommend that you use that
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |