3

I'm developing a website that uses personal_sign to authenticate users. I send the "address" and "signature" to my server to verify the user owns the address. I'm currently adding WalletConnect support, and ran into an issue with Gnosis Safe. When signing with Gnosis Safe, the value of signature is just "0x" instead of the full signature:

const signature = await connector.signPersonalMessage([
  convertUtf8ToHex(message),
  address,
]);

Is personal_sign supported by Gnosis Safe? This technique works with WalletConnect when connecting with Ledger Live or the Metamask mobile app. Is there an alternative way to verify a user owns an address?

Thank you.

2 Answers 2

3

If safeProxyContract.isValidSignature(msgHash, signature) (See CompatibilityFallbackHandler.sol#L66) returns the EIP1271 magic value, then the message with the msgHash is signed. If it doesn't, then it isn't signed

const UPDATED_EIP1271_MAGIC_VALUE = '0x1626ba7e'

let isValidSignature = await safeProxyContract.isValidSignature(msgHash, signature)

// if isValidSignature() returns the EIP-1271 magic value, the signature is valid
if (isValidSignature == UPDATED_EIP1271_MAGIC_VALUE) {
  signatureValid = true
}

But what I couldn't figure out was when to make the call to isValidSignature(). Because the WalletConnect modal actually resolves 0x right after the user issues the txn, without waiting for the txn to be confirmed. So there is no way to know the txn hash, nor when/if the sign message txn was mined or not

But GnosisSafe contract emits an event during those txn. So I added a once event listener to the contract to listen for that event, and then check isValidSignature()

const msgHash = ethers.utils.hashMessage(rawMessage)
const getMessageHash = await wsSafeProxyContract.getMessageHash(msgHash)
// login() only after the _signMessage() txn is mined and SignMsg(msgHash) event emitted
wsSafeProxyContract.once(wsSafeProxyContract.filters.SignMsg(getMessageHash), async () => {
  await login()
})

Thanks @Richard for helping out!

1
  • 1
    Something I'm still confused is how to handle nonces with allowing using Gnosis Safe to login. Most ethereum logins would require the user to sign a random nonce. But that is a bad UX for users, because users would have to issue an on-chain txn on each login. Is there any way to get around this? Feb 1, 2022 at 6:40
2

As the Safe is a contract based wallet it does not generate a normal signature. The WalletConnect Safe App uses EIP-1271 to return a signature. The returned signature can then be checked against the Safe contract.

The Safe app is returning 0x, because this indicates to the contract that it should check in the local storage of the contract if the message was signed. That is also the reason why a Safe transaction is triggered when signing a message with the Safe currently.

Here an example how this could be done: https://github.com/snapshot-labs/snapshot.js/blob/9deb0d53f80ce82dc84fe6090ef8d3884345ba53/src/sign/eip1271.ts#L52-L56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.