diff --git a/.env.dev b/.env.dev index a3bd313..d1b41db 100644 --- a/.env.dev +++ b/.env.dev @@ -16,4 +16,7 @@ VUE_APP_MARKET_CURRENCY='0xFd42bfb03212dA7e1A4608a44d7658641D99CF34' VUE_APP_MAKEFEE_ADDRESS='0x50A8e60041A206AcaA5F844a1104896224be6F39' VUE_APP_LOCKER_ADDRESS='0xC8607507451059CfAe6Ca4D07EC6f631ce8ef9f9' VUE_APP_EXPLORER_URL='https://explorer.testnet.immutable.com' -VUE_APP_PRODUCTION=sandbox \ No newline at end of file +VUE_APP_PRODUCTION=sandbox + +VUE_APP_NET_ID_MAIN='11155111' +VUE_APP_LOCKER_ADDRESS_MAIN='0x7F2b4DB626d878778e178B4F0C7bA3a2870C6dd0' \ No newline at end of file diff --git a/.env.development b/.env.development index 22a82f3..e8663ff 100644 --- a/.env.development +++ b/.env.development @@ -16,4 +16,7 @@ VUE_APP_MARKET_CURRENCY='0xFd42bfb03212dA7e1A4608a44d7658641D99CF34' VUE_APP_MAKEFEE_ADDRESS='0x50A8e60041A206AcaA5F844a1104896224be6F39' VUE_APP_LOCKER_ADDRESS='0xC8607507451059CfAe6Ca4D07EC6f631ce8ef9f9' VUE_APP_EXPLORER_URL='https://explorer.testnet.immutable.com' -VUE_APP_PRODUCTION=sandbox \ No newline at end of file +VUE_APP_PRODUCTION=sandbox + +VUE_APP_NET_ID_MAIN='11155111' +VUE_APP_LOCKER_ADDRESS_MAIN='0x7F2b4DB626d878778e178B4F0C7bA3a2870C6dd0' \ No newline at end of file diff --git a/src/components/chain/BlockChain.js b/src/components/chain/BlockChain.js index d33a192..3d01f16 100644 --- a/src/components/chain/BlockChain.js +++ b/src/components/chain/BlockChain.js @@ -71,6 +71,9 @@ export class BlockChain { if (this.store.walletType == 3) { this.store.passportAddress = accounts[0]; this.passportProvider = provider; + } else { + this.store.eoaAddress = accounts[0]; + this.eoaProvider = provider; } this.store.$persist(); this.market.updateProvider(provider); @@ -110,7 +113,9 @@ export class BlockChain { throw new Error(result.errmsg); } } - + /** + * 用于eoa登录后, 添加passport地址 + */ async appendPassport() { if (this.store.walletType == 3) { return; @@ -121,6 +126,28 @@ export class BlockChain { this.store.passportAddress = accounts[0]; this.store.$persist(); } + /** + * 用于passport登录后, 添加eoa地址 + */ + async appendEoa() { + if (this.store.walletType != 3) { + return; + } + const rewardModal = createModal(WalletSelectModel, { + title: title || 'Select Address', + message: subTitle || 'Please select the address you want to use', + initData: { 1: 'MetaMask', 2: 'OKX Wallet', 3: 'Passport' }, + disabled: [3] + }); + const { errcode, errmsg, walletInstance, provider, accounts } = await rewardModal.show(); + if (errcode) { + console.log(`select address result : ${errmsg}`); + throw new Error(errmsg); + } + this.eoaProvider = provider; + this.store.eoaAddress = accounts[0]; + this.store.$persist(); + } async token() { const suffix = (this.store.walletType == 2 || this.store.walletType == 1) ? '.cf' : '' @@ -135,6 +162,19 @@ export class BlockChain { return token+suffix } + // 检查是否已登录aoa + get eoaLogined() { + return this.store.walletType != 3 || !!this.store.eoaAddress + } + + /** + * 检查passport是否已登录 + */ + get passportLogined() { + return this.store.walletType == 3 || !!this.store.passportAddress + } + + /** * 如果是用passport登录的, 直接返回store中的token, 否则调用passport的getAccessToken * @returns @@ -144,7 +184,7 @@ export class BlockChain { return this.token() } if (!this.passportProvider) { - return '' + throw new Error('need login to Passport') } const res = await new PassportWallet().getAccessToken(); return res.token diff --git a/src/components/chain/WalletSelectModel.vue b/src/components/chain/WalletSelectModel.vue index e0b7874..71a2d7c 100644 --- a/src/components/chain/WalletSelectModel.vue +++ b/src/components/chain/WalletSelectModel.vue @@ -41,7 +41,8 @@ const props = defineProps({ close: Function, title: ref(String), subTitle: ref(String), - initData: Object + initData: Object, + disabled: Array }); const currentDatas = computed(() => { @@ -64,7 +65,8 @@ const currentDatas = computed(() => { tip, }; }); - + const disabled = props.disabled || []; + list = list.filter((item) => !disabled.includes(item.id)); return list; }); diff --git a/src/components/chain/contract/Locker.js b/src/components/chain/contract/Locker.js index 28b413e..a399857 100644 --- a/src/components/chain/contract/Locker.js +++ b/src/components/chain/contract/Locker.js @@ -12,7 +12,8 @@ const erc721Abi = [ 'function getApproved(uint256 tokenId) public view returns (address)' ] -const lockAddress = import.meta.env.VUE_APP_LOCKER_ADDRESS +const lockAddressImtbl = import.meta.env.VUE_APP_LOCKER_ADDRESS +const lockAddressMain = import.meta.env.VUE_APP_LOCKER_ADDRESS_MAIN export class Locker { @@ -20,28 +21,39 @@ export class Locker { 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()) + 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 this.bc.web3Provider.waitForTransaction(resApproval.hash) + await provider.waitForTransaction(resApproval.hash) console.debug('approve', resApproval.hash) } } - const contract = new ethers.Contract(lockAddress, lockAbi, this.bc.web3Provider.getSigner()) + const contract = new ethers.Contract(lockAddress, lockAbi, provider.getSigner()) const res = await contract.lock(nft, address, tokenIds) - await this.bc.web3Provider.waitForTransaction(res.hash) + 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); + return this.execLock(this.bc.eoaProvider, lockAddressMain, nft, tokenIds) + } async sendUnlockOrMint(provider, {from, to, data}) { @@ -57,19 +69,9 @@ export class Locker { await provider.waitForTransaction(txHash) return txHash } - - // 游戏内资产上链, 用于解锁或铸造 - // 创世英雄, 普通英雄, 金砖 - // imtbl上unlock必须使用passport的provider - async unlockOrMintGameNft(nft, tokenIds) { - console.log('unlock nft', nft, tokenIds) - const blockChain = new BlockChain() - const { provider, address } = await this.bc.selectAddress({}) - await this.bc.checkPassportLogin(); - await this.bc.checkAndChangeChain(); + async execUnlock(chainId, nft, tokenIds) { const preDatas = { - net_id: import.meta.env.VUE_APP_NET_ID, - to: address, + net_id: chainId, contract_address: nft, tokens: tokenIds.map(token_id => {return { token_id }}), } @@ -81,22 +83,48 @@ export class Locker { 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); + // const address = this.bc.store.eoaAddress + return this.execUnlock(chainId, nft, tokenIds) + } + // 游戏内资产上链, 只用于mint // 该方法会显示一个确认弹窗, 由用户选择mint到哪个地址 async mintNft(tokenIds) { console.log('mint hero', tokenIds) - const blockChain = new BlockChain() - const { provider, address } = await blockChain.selectAddress({}) + const { provider, address } = await this.bc.selectAddress({}) const preDatas = { to: address, hero_uniids: tokenIds, } - const passportToken = await blockChain.passportToken() + 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(blockChain.web3Provider, trans_req) + return this.sendUnlockOrMint(this.bc.web3Provider, trans_req) } } diff --git a/src/store/wallet.js b/src/store/wallet.js index 9c3068d..39c3f8b 100644 --- a/src/store/wallet.js +++ b/src/store/wallet.js @@ -10,6 +10,7 @@ export const walletStore = defineStore( const token = ref(); const refreshToken = ref(); const passportAddress = ref(); + const eoaAddress = ref(); const showAddress = computed(() => { @@ -26,6 +27,7 @@ export const walletStore = defineStore( token.value = ''; passportAddress.value = ''; refreshToken.value = ''; + eoaAddress.value = ''; } return { walletType, @@ -35,6 +37,7 @@ export const walletStore = defineStore( token, refreshToken, showAddress, + eoaAddress, reset, }; },