My code:
import { useEffect, useState } from 'react'
import axios from 'axios'
import cookie from 'js-cookie'
import { decode as base64_decode, encode as base64_encode } from 'base-64'
import { CHAIN_NAMESPACES } from '@web3auth/base'
import { CommonPrivateKeyProvider } from '@web3auth/base-provider'
import { Web3Auth } from '@web3auth/modal'
import Web3 from 'web3'
import { ethers } from 'ethers'
const clientId = process.env.NEXT_PUBLIC_API_KEY_WEB3AUTH
async function init() {
try {
if (!clientId) {
console.error('Missing Web3Auth clientId')
return null
}
const privateKeyProvider = new CommonPrivateKeyProvider({
config: {
chainConfig: {
chainNamespace: CHAIN_NAMESPACES.EIP155,
chainId: process.env.NEXT_PUBLIC_MAIN_NET_CHAINID,
rpcTarget: process.env.NEXT_PUBLIC_RPC_TARGET,
},
},
})
const web3auth = new Web3Auth({
clientId,
web3AuthNetwork: process.env.NEXT_PUBLIC_NET,
privateKeyProvider,
})
await web3auth.initModal()
if (!web3auth.provider) {
console.error('Web3Auth provider is null after init')
return null
}
return web3auth
} catch (error) {
console.error('Error initializing Web3Auth:', error)
return null
}
}
// async function init() {
// // slicing it to 10 characters. Otherwise you can maintain the original length by omitting the toUppercase, slice and replace methods
// // .toUpperCase()
// // .slice(0, 11)
// // .replace(/-/g, '');
// // console.log('deviceIdInstance', deviceIdInstance);
// try {
// const web3auth = new Web3Auth({
// clientId,
// chainConfig: {
// chainNamespace: CHAIN_NAMESPACES.EIP155,
// chainId: process.env.NEXT_PUBLIC_MAIN_NET_CHAINID,
// rpcTarget: process.env.NEXT_PUBLIC_RPC_TARGET, // This is the public RPC we have added, please pass on your own endpoint while creating an app
// },
// mfaLevel: 'none',
// // uiConfig refers to the whitelabeling options, which is available only on Growth Plan and above
// // Please remove this parameter if you're on the Base Plan
// // uiConfig: {
// // name: 'NoGame',
// // logoLight: process.env.NEXT_PUBLIC_URL + '/logo.png',
// // logoDark: process.env.NEXT_PUBLIC_URL + '/logo.png',
// // defaultLanguage: 'en',
// // dark: true, // whether to enable dark mode. defaultValue: false
// // loginMethodsOrder: ['apple', 'google', 'twitter'],
// // loginGridCol: 1,
// // primaryButton: 'socialLogin', // "externalLogin" | "socialLogin" | "emailLogin"
// // },
// web3AuthNetwork: process.env.NEXT_PUBLIC_NET,
// })
// await web3auth.initModal()
// return web3auth
// // await web3auth.initModal();
// // if (web3auth.connected) {
// // console.log('web3auth Init connected');
// // // setLoggedIn(true);
// // }
// } catch (error) {
// console.error(error)
// return null
// }
// }
function uiConsole(...args) {
const el = document.querySelector('#console>p')
if (el) {
el.innerHTML = JSON.stringify(args || {}, null, 2)
}
}
async function getPrivateKey(provider) {
try {
const privateKey = await provider.request({
method: 'eth_private_key',
})
return privateKey
} catch (error) {
return error
}
}
async function getChainId(provider) {
try {
const web3 = new Web3(provider)
// Get the connected Chain's ID
const chainId = await web3.eth.getChainId()
return chainId.toString()
} catch (error) {
return error
}
}
async function signMessage(provider, message, private_key) {
try {
const web3 = new Web3(provider)
const fromAddress = (await web3.eth.getAccounts())[0]
// sign
let sigObj = await web3.eth.accounts.sign(message, private_key)
return sigObj.signature
} catch (error) {
return error
}
}
async function getAccounts(provider) {
try {
if (!provider) {
console.error('⛔ Provider is not available')
return null
}
console.log('🟢 Provider detected:', provider)
// Kiểm tra provider có hỗ trợ request không
if (typeof provider.request !== 'function') {
console.error('⛔ Provider does not support request()')
return null
}
// 🚀 Yêu cầu quyền truy cập tài khoản
// const accounts = await provider.request({ method: 'eth_requestAccounts' })
// console.log('✅ User Account:', accounts[0])
// 🚀 Tạo Web3 instance từ provider
const web3 = new Web3(provider.provider)
const allAccounts = await web3.eth.getAccounts()
console.log('✅ Fetched Accounts from web3:', allAccounts)
if (!allAccounts || allAccounts.length === 0) {
console.error('⛔ No accounts found')
return null
}
return allAccounts[0] // Trả về địa chỉ đầu tiên
} catch (error) {
console.error('❌ Error fetching accounts:', error)
return null
}
}
const getUserInfo = async (web3auth) => {
if (!web3auth) {
console.log('web3auth not initialized yet1')
return
}
const user = await web3auth.getUserInfo()
return user
}
const login = async (web3auth, moralis) => {
// const provider = await web3auth.connect() // Kết nối
// if (!provider) {
// console.error('Web3Auth connection failedffff')
// return
// }
if (!web3auth) {
console.log('web3auth not initialized yet2')
return
}
const web3authProvider = await web3auth.connect()
if (web3authProvider) {
const account = await getAccounts(web3auth)
const userinfo = await getUserInfo(web3auth)
const privateKey = await getPrivateKey(web3authProvider)
const chainID = await getChainId(web3authProvider)
const jwt = await web3auth.authenticateUser()
const { message } = await moralis.Cloud.run('requestMessage', {
address: account,
chain: parseInt(process.env.NEXT_PUBLIC_MAIN_NET_CHAINID, 16),
network: 'evm',
})
const signedMessage = await signMessage(
web3authProvider,
message,
privateKey
)
let encodedMessage = base64_encode(message)
// setLoading(true);
const DeviceUUID = await import('device-uuid')
const deviceIdInstance = new DeviceUUID.DeviceUUID().get()
const content = {
jwt: jwt.idToken,
uuid: deviceIdInstance,
signature: signedMessage,
message: encodedMessage,
email: userinfo.email,
verifyId: userinfo.verifierId,
}
const formData = new FormData()
formData.append('jwt', jwt.idToken)
formData.append('uuid', deviceIdInstance)
formData.append('signature', signedMessage)
formData.append('message', message)
formData.append('email', userinfo.email)
formData.append('verifyId', userinfo.verifierId)
const result = await axios
.post(process.env.NEXT_PUBLIC_URL + '/api/serverSideCallAuth', content)
.then(
async (response) => {
if (response.data.error == 1) {
// console.log('auth', response.data.data);
cookie.set(
'access_token',
response.data.data.objectId +
'|' +
response.data.data.sessionToken,
{ expires: 1 }
)
cookie.set('token', response.data.data.sessionToken, { expires: 1 })
return response.data.data.sessionToken
}
},
(error) => {
// setLoading(false);
}
)
return result
// console.log('address', signedMessage, account, jwt.idToken, userinfo, message);
}
}
const logout = async (web3auth) => {
if (!web3auth) {
console.log('web3auth not initialized yet30')
uiConsole('web3auth not initialized yet3')
return
}
await web3auth.logout()
cookie.remove('access_token')
cookie.remove('token')
}
const userInfo = async () => {
let tokenCookie = cookie.get('access_token')
if (tokenCookie !== undefined) {
const splitToken = tokenCookie.split('|')
const content = {
zgameId: splitToken[0],
}
let userinfo = await axios
.post(process.env.NEXT_PUBLIC_URL + '/api/client/GetUserInfo', content, {
headers: { token: splitToken[1] },
})
.then(
async (response) => {
if (response.data.errorCode == 0) {
return response.data.data
}
},
(error) => {
console.log(error)
return null
}
)
return userinfo
}
return null
}
const loggedIn = (web3auth) => {
if (!web3auth) {
console.log('web3auth not initialized yet loggedIn')
return false
}
if (web3auth.connected) {
return true
} else {
return false
}
}
const accessToken = () => {
let token = cookie.get('token')
if (token) {
return token
} else {
return null
}
}
async function erc20transfer(
provider,
contractABI,
contractAddress,
receiver,
amount
) {
if (provider) {
const web3 = new Web3(provider)
const account = await getAccounts(provider)
const privateKey = await getPrivateKey(provider)
let tokenAddress = contractAddress
let toAddress = receiver // where to send it
let fromAddress = account // Your address
let contract = new web3.eth.Contract(contractABI, contractAddress)
let value = web3.utils.toHex(web3.utils.toWei(amount.toString()))
let data = contract.methods.transfer(toAddress, value).encodeABI()
let txObj = {
gas: web3.utils.toHex(100000),
to: tokenAddress,
value: '0x00',
data: data,
from: fromAddress,
}
return { web3, txObj, privateKey }
}
}
export { login, logout, loggedIn, init, userInfo, accessToken, erc20transfer }