# Cannot verify Defender Relayer signatures on OZs ECDSA Solidity library

**URL:** <https://forum.openzeppelin.com/t/cannot-verify-defender-relayer-signatures-on-ozs-ecdsa-solidity-library/40093>\
**Category:** Support\
**Tags:** defender, etherscan-verify\
**Created:** [April 2, 2024, 5:05pm UTC](https://forum.openzeppelin.com/t/cannot-verify-defender-relayer-signatures-on-ozs-ecdsa-solidity-library/40093 "2024-04-02T17:05:33Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![elmariachi111](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/elmariachi111/32/17885_2.png) [@elmariachi111](https://forum.openzeppelin.com/u/elmariachi111)\
**Post date:** [April 2, 2024, 5:05pm UTC](https://forum.openzeppelin.com/t/cannot-verify-defender-relayer-signatures-on-ozs-ecdsa-solidity-library/40093/1 "2024-04-02T17:05:33Z")

</div>

We're using Relayer (Defender 2) to sign authentication messages to guard access to a certain function. According to [https://docs.openzeppelin.com/defender/v2/manage/relayers#signing](https://docs.openzeppelin.com/defender/v2/manage/relayers#signing) it creates non-deterministic signatures. We can confirm that: with every client call we receive different signature bytes but on the frontend they all are recoverable to the correct relay address (`0xd7B298c9fB0377124d01D4E826d9D5beFB7CD6FE`) using viem's `recoverMessageAddress` and `recoverAddress`. When trying to verify them using the OZ ECDSA _contract library_, we however cannot recover the relay / signer address correctly. Using the latest version of `@openzeppelin/defender-sdk` / 1.11.0, using Cancun VM.

Client:

```ts
const { Defender } = require('@openzeppelin/defender-sdk')
const { hashMessage, recoverMessageAddress, recoverAddress } = require('viem')
require('dotenv-flow').config({
  default_node_env: 'development'
})

const main = async () => {
  const creds = {
    relayerApiKey: process.env.DEFENDER_RELAY_API_KEY,
    relayerApiSecret: process.env.DEFENDER_RELAY_SECRET_KEY
  }
  const client = new Defender(creds)
  const validUntil = new Date(Date.now() + 120 * 1000).toISOString()
  const signer = await client.relaySigner.getSigner(
    client.relaySigner.getProvider(),
    { speed: 'fast', validUntil }
  )

  const plainMessage = 'hello world'
  const signature = await signer.signMessage(plainMessage)
  console.log('signature', signature)

  const address = await recoverMessageAddress({
    message: plainMessage,
    signature: signature
  })
  console.log('recovered address 1', address)

  console.log(
    'recovered address 2',
    await recoverAddress({
      hash: hashMessage(plainMessage),
      signature
    })
  )
}

;(async () => {
  await main()
})()

```

Output:

```auto
$ yarn ts-node cli/testRelayer.ts
signature 0x5d52923f24f9edb9e0ac19160183c0731b77795b7c4acaa0e81587aa3e64e6e710c0df2567f3396e5be7dd3816b2de9d69270cfb7d34e58c8b5d20711a19498f1b
recovered address 1 0xd7B298c9fB0377124d01D4E826d9D5beFB7CD6FE
recovered address 2 0xd7B298c9fB0377124d01D4E826d9D5beFB7CD6FE
$ yarn ts-node cli/testRelayer.ts
signature 0x5e0c589c5790b134223a866bd253ff73ad6a00482d96234d3b72c0cb64eccbc63cede8769090ed91d62983af41bbd2d200359469b2d77bd0096587a297554cef1b
recovered address 1 0xd7B298c9fB0377124d01D4E826d9D5beFB7CD6FE
recovered address 2 0xd7B298c9fB0377124d01D4E826d9D5beFB7CD6FE
$ yarn ts-node cli/testRelayer.ts
signature 0x36efe70274ca04d2590bfebfe63e2c0099a60c51009bfcfdf63e9734d30de91e3fd861722c7f0d1e727d01fc9eb1e50663ba879c61b08a7ee07ba51f7b635b9d1c
recovered address 1 0xd7B298c9fB0377124d01D4E826d9D5beFB7CD6FE
recovered address 2 0xd7B298c9fB0377124d01D4E826d9D5beFB7CD6FE

```

Contract:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8;

import {SignatureChecker} from "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v5.0.2/contracts/utils/cryptography/SignatureChecker.sol";
import {ECDSA} from "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v5.0.2/contracts/utils/cryptography/ECDSA.sol";
import {MessageHashUtils} from "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v5.0.2/contracts/utils/cryptography/MessageHashUtils.sol";

contract SignedMintAuthorizer {
    function authorizeMint(string memory authMessage, bytes memory signature) external pure returns (address) {
        bytes32 signedHash = MessageHashUtils.toEthSignedMessageHash(keccak256(bytes(authMessage)));
        (address signer,ECDSA.RecoverError err,bytes32 any) = ECDSA.tryRecover(signedHash, signature);
        return signer;
    }
}

```

Call Results:

```auto
{
	"string authMessage": "hello world",
	"bytes signature": "0x5e0c589c5790b134223a866bd253ff73ad6a00482d96234d3b72c0cb64eccbc63cede8769090ed91d62983af41bbd2d200359469b2d77bd0096587a297554cef1b"
}
->
{
	"0": "address: 0xC548fB656F3CbB7cCd8FAe6335B30883d1EB4008"
}
---
{
	"string authMessage": "hello world",
	"bytes signature": "0x36efe70274ca04d2590bfebfe63e2c0099a60c51009bfcfdf63e9734d30de91e3fd861722c7f0d1e727d01fc9eb1e50663ba879c61b08a7ee07ba51f7b635b9d1c"
}
-> 
{
	"0": "address: 0x00FB5b0EEE636D748C8B23CdD23C4b54348f0135"
}

```
