130 lines
4.3 KiB
JavaScript
130 lines
4.3 KiB
JavaScript
|
|
import { ethers } from 'ethers'
|
|
import { apiUnlockOrMint, apiMintNft } from '@/utils/marketplace'
|
|
import { BlockChain } from "@/components/chain/BlockChain"
|
|
|
|
const lockAbi = [
|
|
'function lock(address nft, address to, uint256[] tokenIds) external'
|
|
]
|
|
|
|
const erc721Abi = [
|
|
'function approve(address to, uint256 tokenId) external',
|
|
'function getApproved(uint256 tokenId) public view returns (address)'
|
|
]
|
|
|
|
const lockAddressImtbl = import.meta.env.VUE_APP_LOCKER_ADDRESS
|
|
const lockAddressMain = import.meta.env.VUE_APP_LOCKER_ADDRESS_MAIN
|
|
|
|
export class Locker {
|
|
|
|
constructor(_chainInstance) {
|
|
this.bc = _chainInstance
|
|
}
|
|
|
|
async execLock(provider, lockAddress, nft, tokenIds) {
|
|
const nftContract = new ethers.Contract(nft, erc721Abi, provider.getSigner())
|
|
const address = this.bc.store.passportAddress
|
|
console.log('lock', nft, address, tokenIds)
|
|
for (let tokenId of tokenIds) {
|
|
const addressApproval = await nftContract.getApproved(tokenId)
|
|
if ((addressApproval || "").toLowerCase() != lockAddress.toLowerCase()) {
|
|
const resApproval = await nftContract.approve(lockAddress, tokenId);
|
|
await provider.waitForTransaction(resApproval.hash)
|
|
console.debug('approve', resApproval.hash)
|
|
}
|
|
}
|
|
|
|
const contract = new ethers.Contract(lockAddress, lockAbi, provider.getSigner())
|
|
const res = await contract.lock(nft, address, tokenIds)
|
|
await provider.waitForTransaction(res.hash)
|
|
return res.hash
|
|
}
|
|
|
|
async lock(nft, tokenIds) {
|
|
console.log('lock nft', nft, tokenIds)
|
|
await this.bc.checkPassportLogin();
|
|
await this.bc.checkAndChangeChain();
|
|
return this.execLock(this.bc.web3Provider, lockAddressImtbl, nft, tokenIds)
|
|
}
|
|
|
|
async lockMain(nft, tokenIds) {
|
|
console.log('lock nft on main', nft, tokenIds)
|
|
const chainId = parseInt(import.meta.env.VUE_APP_NET_ID_MAIN);
|
|
await this.bc.checkPassportLogin();
|
|
await this.bc.checkAndChangeChain(chainId, this.bc.eoaProvider);
|
|
return this.execLock(this.bc.eoaProvider, lockAddressMain, nft, tokenIds)
|
|
}
|
|
|
|
async sendUnlockOrMint(provider, {from, to, data}) {
|
|
|
|
const txHash = await provider.provider.request({
|
|
method: 'eth_sendTransaction',
|
|
params: [{
|
|
from,
|
|
to,
|
|
data
|
|
}]
|
|
})
|
|
console.log(txHash)
|
|
await provider.waitForTransaction(txHash)
|
|
return txHash
|
|
}
|
|
async execUnlock(chainId, nft, tokenIds) {
|
|
const preDatas = {
|
|
net_id: chainId,
|
|
contract_address: nft,
|
|
tokens: tokenIds.map(token_id => {return { token_id }}),
|
|
}
|
|
const passportToken = await this.bc.passportToken()
|
|
const { errcode, errmsg, trans_req } = await apiUnlockOrMint(preDatas, passportToken)
|
|
if (errcode) {
|
|
throw new Error(errmsg)
|
|
}
|
|
const web3Provider = this.bc.passportProvider || this.bc.web3Provider
|
|
return this.sendUnlockOrMint(web3Provider, trans_req)
|
|
}
|
|
|
|
// imbtl上游戏内资产上链, 用于解锁或铸造
|
|
// 创世英雄, 普通英雄, 金砖
|
|
// 必须使用passport的provider
|
|
async unlockOrMintGameNft(nft, tokenIds) {
|
|
console.log('unlock nft', nft, tokenIds)
|
|
await this.bc.checkPassportLogin();
|
|
await this.bc.checkAndChangeChain();
|
|
const chainId = import.meta.env.VUE_APP_NET_ID;
|
|
return this.execUnlock(chainId, nft, tokenIds)
|
|
}
|
|
|
|
/**
|
|
* Ethereum上解锁
|
|
* @param {*} nft
|
|
* @param {*} tokenIds
|
|
* @returns
|
|
*/
|
|
async unlockMain(nft, tokenIds) {
|
|
console.log('unlock nft on main', nft, tokenIds)
|
|
const chainId = parseInt(import.meta.env.VUE_APP_NET_ID_MAIN);
|
|
await this.bc.checkPassportLogin();
|
|
await this.bc.checkAndChangeChain(chainId, this.bc.eoaProvider);
|
|
return this.execUnlock(chainId, nft, tokenIds)
|
|
}
|
|
|
|
// 游戏内资产上链, 只用于mint
|
|
// 该方法会显示一个确认弹窗, 由用户选择mint到哪个地址
|
|
async mintNft(tokenIds) {
|
|
console.log('mint hero', tokenIds)
|
|
const { provider, address } = await this.bc.selectAddress({})
|
|
const preDatas = {
|
|
to: address,
|
|
hero_uniids: tokenIds,
|
|
}
|
|
const passportToken = await this.bc.passportToken()
|
|
const { errcode, errmsg, trans_req } = await apiMintNft(preDatas, passportToken)
|
|
if (errcode) {
|
|
throw new Error(errmsg)
|
|
}
|
|
trans_req.from = address
|
|
return this.sendUnlockOrMint(this.bc.passportProvider, trans_req)
|
|
}
|
|
}
|