2024-07-17 15:08:17 +08:00

96 lines
3.2 KiB
JavaScript

import { ethers } from 'ethers'
import { apiUnlockOrMint, apiMintNft } from '@/utils/marketplace'
const lockAbi = [
'function lock(address nft, address to, uint256[] tokenIds) external',
'function unlockOrMint(address nft, tuple[] nftList, uint256 signTime, uint256 saltNonce, bytes signature) external'
]
const erc721Abi = [
'function approve(address to, uint256 tokenId) external',
'function getApproved(uint256 tokenId) public view returns (address)'
]
const lockAddress = import.meta.env.VUE_APP_LOCKER_ADDRESS
export class Locker {
constructor(_chainInstance) {
this.bc = _chainInstance
}
async lock(nft, tokenIds) {
// call single method with abi and address
console.log('lock nft', nft, tokenIds)
await this.bc.checkPassportLogin();
await this.bc.checkAndChangeChain();
const nftContract = new ethers.Contract(nft, erc721Abi, this.bc.web3Provider.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 this.bc.web3Provider.waitForTransaction(resApproval.hash)
console.debug('approve', resApproval.hash)
}
}
const contract = new ethers.Contract(lockAddress, lockAbi, this.bc.web3Provider.getSigner())
const res = await contract.lock(nft, address, tokenIds)
await this.bc.web3Provider.waitForTransaction(res.hash)
return res.hash
}
async sendUnlockOrMint(provider, {to, data}) {
const txHash = await provider.request({
method: 'eth_sendTransaction',
params: [{
to,
data
}]
})
console.log(txHash)
return txHash
}
// 游戏内资产上链, 用于解锁或铸造
// 创世英雄, 普通英雄, 金砖
// imtbl上unlock必须使用passport的provider
async unlockOrMintGameNft(nft, tokenIds) {
console.log('unlock nft', nft, tokenIds)
await this.bc.checkPassportLogin();
await this.bc.checkAndChangeChain();
const preDatas = {
net_id: import.meta.env.VUE_APP_NET_ID,
contract_address: nft,
tokens: tokenIds.map(tokenId => {return { tokenId }}),
}
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)
}
// 游戏内资产上链, 只用于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)
}
return this.sendUnlockOrMint(provider, trans_req)
}
}