How do you call authenticate?
const serverUrl = "hxxx";
const appId = "xxx";
Moralis.start({ serverUrl, appId });
async function login() {
let user = Moralis.User.current();
if (!user) {
try {
user = await Moralis.authenticate({ signingMessage: "Hello World!" })
console.log(user)
console.log(user.get('ethAddress'))
} catch(error) {
console.log(error)
}
}
}
async function loginWC() {
let user = Moralis.User.current();
if (!user) {
try {
user = await Moralis.authenticate({ provider: 'walletconnect', chainId: 4 })
console.log(user)
console.log(user.get('ethAddress'))
} catch(error) {
console.log(error)
}
}
}
function loginMagic() {
let user = Moralis.User.current();
if (!user) {
Moralis.authenticate({
provider: 'magicLink',
email: 'xxx',
apiKey: 'pk_live_xxx',
network: 'rinkeby',
})
.then((user) => {
const address = user.get('ethAddress')
console.log(address)
})
}
}
async function logOut() {
await Moralis.User.logOut();
console.log("logged out");
}
document.getElementById("btn-login").onclick = login;
document.getElementById("btn-loginWC").onclick = loginWC;
document.getElementById("btn-loginMagic").onclick = loginMagic;
document.getElementById("btn-logout").onclick = logOut;
window.addEventListener('load',
async function() {
if (Moralis.User.current()) {
const web3 = await Moralis.enableWeb3({ provider: 'magicLink' })
/// throws Uncaught (in promise) Error: "email" not provided, please provide Email
});
found these fixes related to magic by now:
whichever way I look at the code, Moralis.enableWeb3() is always wanting to do a new login and I have to provide all options. So basically there is no session that can be restored on refresh, itās always forcing a new login and forcing those options.
For example for Magic Link thereās magic.user.isLoggedIn()
to check a valid session https://magic.crisp.help/en/article/how-are-sessions-handled-with-magic-1h92t2s/
But what the MagicWeb3Connector does is always log in again when calling enableWeb3().
well not really either, on a buy order Web3Auth is throwing:
never seen that messageā¦
I will go back to just trying WC first, but the ājust one line to integrateā is a bit oversold at the moment
Can 100% confirm now I have have WC working, session is restored on refresh, transactions all good, can switch back and forth between a WC and Metamask user without issues
If the RPC stays healthy, should be fine. I did loose connection one time between the mobile and website and had to logout and login again. Will see later if I can catch that somehow to warn the user.
As for Web3Auth and Magic Link, the main issue remains that I cannot call Moralis.enableWeb3() when a user is found on refresh. Unlike WC, itās asking for all options to be passed, not only the provider name.
As discussed already in this thread, this does not work for both Web3Auth and Magic:
function loginMagic() {
Moralis.authenticate({
provider: 'magicLink',
email: '[email protected]',
apiKey: 'pk_live_xxx',
network: 'rinkeby',
})
.then((user) => {
// all fine
console.log('Magic user', user);
console.log(user.get('ethAddress'))
})
}
// enable web3 if user present
window.addEventListener('load',
async function() {
if (Moralis.User.current()) {
const web3 = await Moralis.enableWeb3({ provider: 'magicLink' })
// throws error missing options
}
}
})
Looking at the code, I would suggest to check for magic.user.isLoggedIn()
and call magic.auth.loginWithMagicLink()
when no user session has been found?
Hard to debug the rest if I cant refresh properly, but have been able to done some tx.
Itās crazy this Magic Linkā¦ there are no confirmation windows, no wallet(?), it just goes wowā¦Feels funny. Question is, can I see my wallet elsewhere or should I build additional wallet features inside my app?
Hi matiyin, were you able to do any workaround to make Magic Link work? I am having the same issue you are having here.
@cryptokid did you relay or test the issue already? Magic Link is useless at the moment, and so is Web3Authā¦
@react The workaround is to change the Moralis code or implement a custom provider. I didnt find time yet to look myself and create a PL.
I made a little review here by the way: Magic Link Authetntication
I created an internal issue for this, I donāt expect a fix this week.
Hello! Now Iām working to implement Moralis with Magic in React Native application. Can this issue affect my application?
Can you give an example of code/application that replicates this problem?
Itās working now. Found out that I have to save the user email myself when signing up with Magic Link and also save the used provider to the User object. This way I can enabledWeb() with the right params on reload. Hereās some boilerplate to set up and test multiple auth options for Rinkeby:
<!DOCTYPE html>
<html>
<head>
<title>Moralis Multi Auth Test</title>
<script src="https://unpkg.com/moralis/dist/moralis.js"></script>
<script src="https://auth.magic.link/sdk"></script>
<script src="https://github.com/WalletConnect/walletconnect-monorepo/releases/download/1.7.1/web3-provider.min.js"></script>
</head>
<body>
<button id="btn-loginMM">Moralis Metamask Login</button>
<button id="btn-loginWC">Moralis WC Login</button>
<button id="btn-loginMagic">Moralis Magic Login</button>
<button id="btn-logout">Logout</button>
<input type="email" id="email" placeholder="email..." />
<div id="balance">User balance: <span>logged out</span></div>
<script type="text/javascript" src="./script.js"></script>
</body>
</html>
const serverUrl = 'xxx';
const appId = 'xxx';
Moralis.start({ serverUrl, appId });
// metamask
async function loginMM() {
let user = Moralis.User.current();
if (!user) {
try {
await Moralis.authenticate()
initUser()
} catch(error) {
console.log(error)
}
}
}
// wallet connect
async function loginWC() {
if (!Moralis.User.current()) {
Moralis.authenticate({ provider: 'walletconnect', chainId: 4 })
.then((user) => {
// save the provider to User object, optionally check if already set
user.set('provider', 'walletconnect')
user.save()
initUser()
})
}
}
// magic link
function loginMagic() {
if (!Moralis.User.current()) {
const email = document.getElementById('email').value
Moralis.authenticate({
provider: 'magicLink',
email: email,
apiKey: 'xxx',
network: 'rinkeby',
})
.then((user) => {
// save the email and provider to User object, optionally check if already set
user.set('email', email)
user.set('provider', 'magicLink')
user.save()
initUser()
})
}
}
// set web3 and get user balance to test it
async function initUser () {
const user = Moralis.User.current()
if (user) {
if (!Moralis.ensureWeb3IsInstalled()) {
const userProvider = user.get('provider')
let providerOptions
switch (userProvider) {
case 'magicLink':
providerOptions = {
provider: 'magicLink',
email: user.get('email'),
apiKey: 'xxx',
network: 'rinkeby',
}
break
case 'walletconnect':
providerOptions = {
provider: 'walletconnect',
chainId: 4,
}
break
default:
// metamask
providerOptions = null
}
try {
await Moralis.enableWeb3(providerOptions)
} catch (err) {
console.log(err);
}
}
Moralis.web3.getBalance(user.get('ethAddress'))
.then((balance) => {
document.getElementById('balance').firstElementChild.textContent = Moralis.web3Library.utils.formatEther(balance)
})
}
}
async function logOut() {
await Moralis.User.logOut();
document.getElementById('balance').firstElementChild.textContent = 'logged out'
}
document.getElementById('btn-loginMM').onclick = loginMM;
document.getElementById('btn-loginWC').onclick = loginWC;
document.getElementById('btn-loginMagic').onclick = loginMagic;
document.getElementById('btn-logout').onclick = logOut;
// init user on reload
window.addEventListener('load', initUser);
Not sure why Moralis implementation doesnāt save the email or set a provider. Maybe the React boilerplate does this already, but Iām allergic to anything related to FB
Further findings on Magic Link are still mentioned in Magic Link Authetntication
This still needs attention -
await Moralis.enableWeb3(providerOptions)
This doesnāt work for wallet connect. Isnāt web3 supposed to be enabled for desktop browser wallet transactions like metamask.
How can you keep the same log-in authenticated state as someone who logs in with a mobile wallet with wallet connect?
I have no problems using WC with my mobile to connect to desktop. After a browser refresh it regains the session fine, see my boilerplate code as reference.
What doesnāt work?
I have repeated the steps you did with your boilerplate code but could not repeat the same result unless I did something wrong.
I am testing it by linking my metamask mobile wallet with the QR code via wallet connect then refreshing the page. What it seems to do upon refreshing the page is that with your code, the āinitUserā function is enabling web3.
If I was to then call for a transaction (await Moralis.executeFunction(options);
) then it would try to make the transaction via metamask instead of the mobile metamask app. Its the same if I connected trustwallet and or any other mobile wallet app.
Enabling Web3 for a transaction is suited for wallets that are an extension in the browser I believe.
not much I can say without details and code, but it sounds like youāre not passing the correct provider to enableWeb3 that is current used by the logged in user:
await Moralis.enableWeb3({ provider: 'walletconnect', chainId: 4 })
.
If you just do await Moralis.enableWeb3()
it will default to metamask, hence the confusion I also had in the beginning, exactly like you describe.
I save the provider type myself to the user Object when authenticating, so you know which provider options to use for enableWeb3.
I am seeing the EXACT same problem as Matiyin with a React App using Moralis React component.
Upon refresh enableWeb3 NEEDS to be recalled for all mode of connection, being Metamask, WalletConnect or MagicLink.
If you provide the initial authenticate parameters to authenticate (in each mode), it works fine.
This is undesirable definitely and not documented either.
Using the above from @matiyin seems to fix the login/refresh issues. Although I now have a weird behavior where Metamask and WalletConnect are refusing my transactions but it works with MagicLink, almost like the RPC node is not properly updated when changing connection/wallet.
Oh, it looks like my metamask RPC decided to go down during my tests switching back and forth between magicLink and Metamask (which had different RPC)