EDeveloper
EDeveloper

Reputation: 71

Sign and verifiy message on ethereum using wallet connect not working

I am trying to sign and verify messages using wallet connect for my DAPP. So far I have tried using ethers and web3 to wrap WalletConnect and on my mobile device I'm using the metamask and trust wallet apps. So far none of the approaches is working.

<template>
  <div id="app">
    <div>Steps:
      <br>Connect wallet (i used metamask mobile and trust wallet)
      <br>Once connected Sign the message
      <br>
      <br>Issues:
      <br>On metamask mobile wallet you receive a message to sign but nothing is sent back once signed
      <br>On Trust wallet the the signature is returned to the DAPP but it does not verifiy to the current account? Verification fails
      <br>
      <br>
    </div>
    <button @click="connectWallet">Connect wallet</button>

    <template v-if="coinbase">
      <div>Account: {{ coinbase }}</div>

      <button @click="sign">Sign</button>

      <div>Signature: {{ signature }}</div>

      <div>verified message: {{ verified }}</div>

      <div>verified2 message: {{ verified }}</div>

      <div>verificationMatch: {{ verificationMatch }}</div>
    </template>
  </div>
</template>

<script>
import { ethers } from "ethers";
import Web3 from "web3";
import WalletConnectProvider from "@walletconnect/web3-provider";

export default {
  name: "App",
  data: () => ({
    coinbase: "",
    web3: {},
    signer: {},
    verified: "",
    verified2: "",
    signature: ""
  }),

  computed: {
    verificationMatch() {
      // these should match
      return this.coinbase === this.verified;
    }
  },

  methods: {
    async connectWallet() {
      const walletConnectProvider = new WalletConnectProvider({
        infuraId: "3cd774e14cf34ff78167908f8377051c" // Required
        // qrcode: true
      });
      await walletConnectProvider.enable();
      this.web3 = new Web3(walletConnectProvider);
      this.coinbase = walletConnectProvider.wc.accounts[0];
      console.log(this.web3.eth.accounts[0]);
      // this.coinbase = await this.web3.eth.getAccounts()[0];
    },
    async sign() {
      var message = "Hello World";
      this.signature = await this.web3.eth.sign(message, this.coinbase);
      this.verified = ethers.utils.verifyMessage(message, this.signature);
      this.verified2 = this.web3.eth.accounts.recover(message, this.signature);
    }
  }
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

You can find some code sandboxes here

This link is for ethersjs https://codesandbox.io/s/peaceful-cdn-jtkvb?file=/src/App.vue

This link if for web3 https://codesandbox.io/s/objective-franklin-gkr3s?file=/src/App.vue

Upvotes: 4

Views: 16482

Answers (2)

wslyvh
wslyvh

Reputation: 267

Instead of calling the lower level connector call, as described by @Vyacheslav, another option is to call personal_sign directly.

// configure web3, e.g. with web3Modal or in your case WalletConnect
const web3 = await web3Modal.connect();

const provider = new providers.Web3Provider(web3);
const signer = provider.getSigner()
const address = await signer.getAddress();

let signedMessage;
if (web3.wc) {
    signedMessage = await provider.send(
        'personal_sign',
        [ ethers.utils.hexlify(ethers.utils.toUtf8Bytes(rawMessage)), address.toLowerCase() ]
    );
}
else { 
    signedMessage = await signer.signMessage(rawMessage)
}

const verified = ethers.utils.verifyMessage(rawMessage, signedMessage);

Upvotes: 5

Vyacheslav Voronchuk
Vyacheslav Voronchuk

Reputation: 2463

I have the same issue for WalletConnectProvider, but it works with a low-level connector call:

var rawMessage = "Hello World";
var rawMessageLength = new Blob([rawMessage]).size
var message = ethers.utils.toUtf8Bytes("\x19Ethereum Signed Message:\n" + rawMessageLength + rawMessage)
message = ethers.utils.keccak256(message)
var params = [
    await this.signer.getAddress(),
    message
]
this.signature = await this.wc.connector.signMessage(params);
this.verified = ethers.utils.verifyMessage(rawMessage, this.signature);

this.wc is reference to walletConnectProvider

Upvotes: 4

Related Questions