[SOLVED] Moralis v2 nodejs auth

Hi, I’m trying Moralis v2 for auth with node.js
I’m following this examples


If I make a request as is, copy the result and pass the params to the verify function it gives me error 400

{
  "statusCode": 400,
  "name": "Error",
  "message": "Invalid message: {\"success\":false,\"state\":103,\"length\":321,\"matched\":0,\"maxMatched\":104,\"maxTreeDepth\":15,\"nodeHits\":479,\"inputLength\":321,\"subBegin\":0,\"subEnd\":321,\"subLength\":321}"
}

Same error in my code, this is the param

{
  message: 'localhost wants you to sign in with your Ethereum account:\n' +
    '0xf1E424E818F2182ED5033a755A52f92c77c30753\n' +
    '\n' +
    'Please sign this message to confirm your identity.\n' +
    '\n' +
    'URI: https://localhost:5500\n' +
    'Version: 1\n' +
    'Chain ID: 1\n' +
    'Nonce: jfIlyBt51iUV0xzEd\n' +
    'Issued At: 2023-01-16T20:48:39.429Z\n' +
    'Expiration Time: 2024-01-01T00:00:00.000Z',
  signature: '0xac6695bb5e0188111a4c512813748fcb70b68f8366165ff28d90c8e8c8c3f279263745fa01032542e802423902fb0c1f221de8809fcc4d3f04debb101b9446a31c',
  networkType: 'evm'
}

And this is the error

MoralisError [Moralis SDK Core Error]: [C0006] Request failed, Bad Request(400): message must be present, message must contain only ASCII characters, signature must be a valid hex string, signature must be present

What’s wrong?
Thanks

the message has to be in the original expected format, you can check directly in the swagger interface:

https://authapi.moralis.io/api-docs/

This is my nodejs code to get the message
What have I to modify?

try {
    const result = await Moralis.Auth.requestMessage({
      address,
      chain,
      network,
      domain: req.body.DOMAIN,
      statement: req.body.STATEMENT,
      uri: req.body.URI,
      expirationTime: req.body.EXPIRATION_TIME,
      timeout: req.body.TIMEOUT,      
    });

    let { message, id, profileId } = result.toJSON();
    res.status(201).send({
      message
    });

this seems to be the default message from the swagger:

{
  "message": "defi.finance wants you to sign in with your Ethereum account:\n0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B\n\n\nURI: https://defi.finance\nVersion: 1\nChain ID: 1\nNonce: Px7Nh1RPzlCLwqgOb\nIssued At: 2022-11-30T10:20:00.262Z",
  "signature": "0xa8f89a58bf9b433d3100f9e41ee35b5e31fb8c7cd62547acb113162ec6f2e4140207e2dfbd4e387e1801ebc7f08a9dd105ac1d22b2e2ff0df5fa8b6d9bdcfe491c"
}

it looks like the message that you pasted looks like this:

'localhost wants you to sign in with your Ethereum account:\n0xf1E424E818F2182ED5033a755A52f92c77c30753\n\nPlease sign this message to confirm your identity.\n\nURI: https://localhost:5500\nVersion: 1\nChain ID: 1\nNonce: jfIlyBt51iUV0xzEd\nIssued At: 2023-01-16T20:48:39.429Z\nExpiration Time: 2024-01-01T00:00:00.000Z'

it looks like this part is missing?

So I should remove “Please sign this message to confirm your identity” from my message to make it works?

maybe it will work, you can try, if it doesn’t work we’ll have to check more what could be the issue

No, same as before

I don’t understand how to pass the message

This is my script.js taken from your parse-server

  const { message } = await requestMessage(account, 'evm', chain);

  const signature = await signer.signMessage(message);

  const { user } = await verifyMessage(message, signature, 'evm');

this is my nodejs class

const config = require("../config/config.js");

const MoralisDapp = require('moralis');
const Moralis = MoralisDapp.default;

exports.request = async (req, res) => {

  if (!req.body) {
    res.status(400).send({
      res: "KO",
      msg: "No data"
    });
    return;
  }

  const address = req.body.address;
  const chain = req.body.chain;
  const network = req.body.network;
  try {
    const result = await Moralis.Auth.requestMessage({
      address,
      chain,
      network,
      domain: req.body.DOMAIN,
      statement: req.body.STATEMENT,
      uri: req.body.URI,
      expirationTime: req.body.EXPIRATION_TIME,
      timeout: req.body.TIMEOUT,      
    });

    let { message, id, profileId } = result.toJSON();
    res.status(201).send({
      message
    });

  } catch (e) {
    console.error(e);
  }
}

exports.verify = async (req, res) => {
  if (!req.body) {
    res.status(400).send({
      res: "KO",
      msg: "No data"
    });
    return;
  }
  const params = req.body;
  console.log("verify params", params);
  try {
    const result = await Moralis.Auth.verify({
      params      
    });
    res.status(200).send({
      result
    });    

  } catch (e) {
    console.error(e);
  }
}

Any suggestion?

what does this line do?

this is in front end or in backend?

you can test directly with the swagger interface to get the message, sign it and validate it (you have to move fast as the timeout has some limits)

This line sign the message to get signature.
In the swagger to verify the evm I need the signature
I took this code from https://github.com/MoralisWeb3/Moralis-JS-SDK/blob/main/demos/parse-server/public/script.js
It’s frontend

So far I can’t make it work…

Hey there, how are you signing the message exactly?

did you manage to use your Metamask to sign the message?

Essentially you’ll need to pass the message given by Moralis Auth API from the backend to frontend and sign it on the frontend.

Hi, yes, I’m using Metamask
Ok, I’ve got the steps, but I always get some kind of issue

If I call Moralis.Auth.requestMessage from my backend in nodejs with this parameters

{
  domain: 'localhost',
  chainId: '1',
  address: '0xf1e424e818f2182ed5033a755a52f92c77c30753',
  statement: 'Please sign this message to confirm your identity.',
  uri: 'https://mywebsite',
  expirationTime: '2024-01-01T00:00:00.000Z',
  timeout: 15
}

the function gives me error :

TypeError: Cannot read properties of undefined (reading 'toString')

If I use same parameters to Moralis swagger (https://authapi.moralis.io/api-docs/#/Challenge/requestChallengeEvm) it works
What’s the trick?

With the SDK you may also have to specify that it is of type EVM, there is also authentication for Solana

From the looks of your error, you are trying to .toString() a variable, did you by any chance have that within your existing codebase? your error might come from there :raised_hands:

coz when I tested with your parameters, the code is running all good :grinning_face_with_smiling_eyes:

At the end I got it, now it works
The Auth API expects parameters a little bit differents from the Moralis.Auth.requestMessage function.
Then I’ve sorted some little bugs out and now it’s ok
Thank you all for your support

2 Likes

Perfect :star_struck:

If you have any other issues, feel free to create a new thread

We’ll be happy to assist you :grinning_face_with_smiling_eyes: