This is the code. I believe the issue is the server is using Moralis V2 for authentication. Currently the server is using Moralis.Auth
. What is the equivalent of this in Moralis V1?
CLIENT SIDE
import React, { useState } from 'react';
import { useMoralis } from 'react-moralis';
import Moralis from 'moralis-v1';
interface AuthenticateModalProps {
isOpen: boolean;
onClose: () => void;
}
export const AuthenticateModal = ({ isOpen, onClose }: AuthenticateModalProps) => {
const { authenticate, enableWeb3 } = useMoralis();
const [authError, setAuthError] = useState<null | Error>(null);
const [isAuthenticating, setIsAuthenticating] = useState(false);
/**
* 1) Connect to a Evm
* 2) Request message to sign using the Moralis Auth Api of moralis (handled on server)
* 3) Login via parse using the signed message (verification handled on server via Moralis Auth Api)
*/
const handleAuth = async (provider: 'metamask' | 'walletconnect' | 'magicLink' | 'web3Auth' = 'metamask') => {
try {
setAuthError(null);
setIsAuthenticating(true);
// Enable web3 to get user address and chain
await enableWeb3({ throwOnError: true, provider });
const { account, chainId } = Moralis;
if (!account) {
throw new Error('Connecting to chain failed, as no connected account was found');
}
if (!chainId) {
throw new Error('Connecting to chain failed, as no connected chain was found');
}
// Get message to sign from the auth api
const { message } = await Moralis.Cloud.run('requestMessage', {
address: account,
chain: parseInt(chainId, 16),
networkType: 'evm',
});
// Authenticate and login via parse
await authenticate({
signingMessage: message,
throwOnError: true,
});
onClose();
// } catch (error) {
// setAuthError(error);
} finally {
setIsAuthenticating(false);
}
};
SERVER SIDE (Moralis Eth Adapter)
// Note: do not import Parse dependency. see https://github.com/parse-community/parse-server/issues/6467
/* global Parse */
import Moralis from 'moralis';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function validateAuthData(authData: any) {
const { signature, data } = authData;
return Moralis.Auth.verify({
message: data,
signature,
networkType: 'evm',
})
.then((result) => {
const authenticated = result.toJSON();
authData.chainId = result.result.chain.decimal;
authData.nonce = authenticated.nonce;
authData.address = result.result.address.checksum;
authData.version = authenticated.version;
authData.domain = authenticated.domain;
authData.expirationTime = authenticated.expirationTime;
authData.notBefore = authenticated.notBefore;
authData.resources = authenticated.resources;
authData.statement = authenticated.statement;
authData.uri = authenticated.uri;
authData.moralisProfileId = authenticated.profileId;
})
.catch(() => {
// @ts-ignore (see note at top of file)
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Moralis auth failed, invalid data');
});
}
SERVER SIDE (Moralis Eth Adapter)
import Moralis from 'moralis';
import { authRequests } from '../store';
import { ParseServerRequest } from '../utils/ParseServerRequest';
const serverRequest = new ParseServerRequest();
interface ParseUser {
objectId: string;
}
export interface RequestMessage {
address: string;
chain: string;
network: string;
}
const DOMAIN = 'defi.finance';
const STATEMENT = 'Please sign this message to confirm your identity.';
const URI = 'https://defi.finance';
const EXPIRATION_TIME = '2023-01-01T00:00:00.000Z';
const TIMEOUT = 15;
export async function requestMessage({
address,
chain,
networkType,
}: {
address: string;
chain?: string;
networkType: 'evm' | 'solana';
}) {
if (networkType === 'evm' && chain) {
return requestMessageEvm({ address, chain, networkType });
}
if (networkType === 'solana') {
return requestMessageSol({ address, networkType });
}
throw new Error('Invalid network');
}
async function requestMessageEvm({
address,
chain,
networkType,
}: {
address: string;
chain: string;
networkType: 'evm';
}) {
const result = await Moralis.Auth.requestMessage({
address,
chain,
networkType,
domain: DOMAIN,
statement: STATEMENT,
uri: URI,
expirationTime: EXPIRATION_TIME,
timeout: TIMEOUT,
});
const { message, id, profileId } = result.toJSON();
authRequests.set(message, { id, profileId });
return message;
}
async function requestMessageSol({ address, networkType }: { address: string; networkType: 'solana' }) {
const result = await Moralis.Auth.requestMessage({
address,
networkType,
solNetwork: 'devnet',
domain: DOMAIN,
statement: STATEMENT,
uri: URI,
expirationTime: EXPIRATION_TIME,
timeout: TIMEOUT,
});
const { message, id, profileId } = result.toJSON();
authRequests.set(message, { id, profileId });
return message;
}
export interface VerifyMessage {
network: string;
signature: string;
message: string;
}
export async function verifyMessage({ network, signature, message }: VerifyMessage) {
const storedData = authRequests.get(message);
if (!storedData) {
throw new Error('Invalid message');
}
const { id: storedId, profileId: storedProfileId } = storedData;
const authData = {
id: storedProfileId,
authId: storedId,
message,
signature,
network,
};
// Authenticate
const user = await serverRequest.post<ParseUser>({
endpoint: `/users`,
params: {
authData: {
moralis: authData,
},
},
useMasterKey: true,
});
// Update user moralisProfile column
await serverRequest.put({
endpoint: `/users/${user.objectId}`,
params: {
moralisProfileId: storedProfileId,
},
useMasterKey: true,
});
// Get authenticated user
const updatedUser = await serverRequest.get({
endpoint: `/users/${user.objectId}`,
useMasterKey: true,
});
return updatedUser;
}
NOTE: This is the exact code from the tutorial.