279 lines
6.9 KiB
TypeScript
279 lines
6.9 KiB
TypeScript
import { Blockchain } from "@/chain/blockchain";
|
|
import { getNonce } from "@/api/User";
|
|
import pinia from "@/store";
|
|
import { useAppStore } from "@/store/app";
|
|
import { useUserStore } from "@/store/user";
|
|
import { message } from "ant-design-vue";
|
|
import { Chain } from "@/chain/Chain";
|
|
import { AVAILABLE_CHAINS } from "@/configs/configchain";
|
|
import { AllChains } from "@/configs/allchain";
|
|
import {
|
|
ACTIVATE_PROXY_ABI,
|
|
MYSTERY_BOX_ABI,
|
|
MYSTERY_PROXY_ABI
|
|
} from "@/configs/contracts";
|
|
|
|
const AppModule = useAppStore(pinia);
|
|
const UserModule = useUserStore();
|
|
|
|
export default class ChainManager {
|
|
bc: Blockchain;
|
|
instanceMap: Map<string, any>;
|
|
public chainMap: Map<number, any> = new Map();
|
|
private _availableChains: Map<number, any> = new Map();
|
|
|
|
constructor() {
|
|
this.bc = new Blockchain();
|
|
this.instanceMap = new Map();
|
|
for (const data of AllChains) {
|
|
this.chainMap.set(data.id, data);
|
|
}
|
|
}
|
|
|
|
get availableChains() {
|
|
if (this._availableChains.size === 0) {
|
|
for (const id of AVAILABLE_CHAINS) {
|
|
const d = this.chainMap.get(id);
|
|
if (d) {
|
|
this._availableChains.set(id, d);
|
|
}
|
|
}
|
|
}
|
|
return this._availableChains;
|
|
}
|
|
|
|
public async init() {
|
|
if (this.bc.isWalletConnect) {
|
|
try {
|
|
await this.bc.connect();
|
|
} catch (err) {
|
|
console.log("connect chain error: ", err);
|
|
}
|
|
}
|
|
}
|
|
|
|
get isLogined() {
|
|
return !!UserModule.token && !!AppModule.step;
|
|
}
|
|
|
|
public async logout() {
|
|
await this.bc.disconnect();
|
|
}
|
|
|
|
public get currentChain() {
|
|
return this.bc.currentChain;
|
|
}
|
|
|
|
public async login(type:any) {
|
|
if (!AppModule.step) {
|
|
try {
|
|
await this.bc.connect(true,type);
|
|
await this.checkNance();
|
|
} catch (err) {
|
|
message.error(err.message, 5);
|
|
this.bc.walletType = 0
|
|
await this.bc.disconnect();
|
|
await Promise.reject(err);
|
|
}
|
|
}
|
|
}
|
|
|
|
public async checkNance() {
|
|
try {
|
|
const preRequest: any = await getNonce();
|
|
let nonce = preRequest.nonce + "";
|
|
const tips = preRequest.data?.tips;
|
|
AppModule.updateNonce(nonce);
|
|
|
|
await UserModule.Login({
|
|
bcInstance: this.bc,
|
|
account: AppModule.accountId,
|
|
chainId: AppModule.chainId,
|
|
nonce,
|
|
tips,
|
|
});
|
|
AppModule.updateStep(1);
|
|
} catch (err) {
|
|
this.bc.walletType = 0
|
|
console.log(err);
|
|
await Promise.reject(err);
|
|
}
|
|
}
|
|
|
|
public async getInstance(address: string, chainId: number, abi?: any) {
|
|
const key = `${chainId}_${address}`;
|
|
if (!this.instanceMap.has(key)) {
|
|
const chain = new Chain(this.chainMap.get(chainId)!.rpc);
|
|
const coinInstance = await chain.initContractInstance(address, abi);
|
|
this.instanceMap.set(key, coinInstance);
|
|
}
|
|
return this.instanceMap.get(key);
|
|
}
|
|
|
|
public async getBalance(address: string, chainId: number) {
|
|
const coinInstance = await this.getInstance(address, chainId);
|
|
const balance = await coinInstance.methods
|
|
.balanceOf(AppModule.accountId)
|
|
.call();
|
|
console.log("balance: ", balance);
|
|
return balance;
|
|
}
|
|
|
|
|
|
/**
|
|
* get amount of mystery boxes
|
|
* this method can get amount of general erc721 also
|
|
* @param {string} address
|
|
* @param {number} chainId
|
|
* @return {Promise<any>}
|
|
*/
|
|
public async getNftBalance(address: string, chainId: number) {
|
|
const coinInstance = await this.getInstance(
|
|
address,
|
|
chainId,
|
|
MYSTERY_BOX_ABI
|
|
);
|
|
const balance = await coinInstance.methods
|
|
.balanceOf(AppModule.accountId)
|
|
.call();
|
|
console.log("nft balance: ", balance);
|
|
return balance;
|
|
}
|
|
|
|
/**
|
|
* Get NFT list of current user
|
|
* @param {string} address NFT address
|
|
* @param {number} chainId chain id
|
|
* @param {number} start
|
|
* @param {number} page
|
|
*/
|
|
public async getNftList(
|
|
address: string,
|
|
chainId: number,
|
|
start = 0,
|
|
page = 8
|
|
) {
|
|
const nftInstance = await this.getInstance(
|
|
address,
|
|
chainId,
|
|
MYSTERY_BOX_ABI
|
|
);
|
|
return nftInstance.methods
|
|
.userTokens(AppModule.accountId, start, page)
|
|
.call();
|
|
}
|
|
|
|
/**
|
|
* Get NFT of current user with index
|
|
* @param {string} address
|
|
* @param {number} chainId
|
|
* @param {number} index
|
|
* @return {Promise<any>}
|
|
*/
|
|
public async getNftIdOfIndex(
|
|
address: string,
|
|
chainId: number,
|
|
index: number
|
|
) {
|
|
const nftInstance = await this.getInstance(
|
|
address,
|
|
chainId,
|
|
MYSTERY_BOX_ABI
|
|
);
|
|
const nftId = await nftInstance.methods
|
|
.tokenOfOwnerByIndex(AppModule.accountId, index)
|
|
.call();
|
|
console.log(
|
|
`address: ${address}, chainId: ${chainId}, index: ${index}, token: ${nftId}`
|
|
);
|
|
return nftId;
|
|
}
|
|
|
|
/**
|
|
* Open one mystery box
|
|
* @param {string} address address of mystery box contract on current chain
|
|
* @param {string} boxId nftid of mystery box
|
|
* @param {number[]} tokenIds
|
|
* @param {string} nonce
|
|
* @param {string} signature
|
|
* @return {Promise<any>}
|
|
*/
|
|
public async openMysteryBox(
|
|
address: string,
|
|
boxId: string,
|
|
tokenIds: number[],
|
|
nonce: string,
|
|
signature: string
|
|
) {
|
|
const proxyInstance = await this.bc.getContractInstance(
|
|
address,
|
|
MYSTERY_PROXY_ABI
|
|
);
|
|
// get transactionHash and upload to server for verify
|
|
return proxyInstance.methods
|
|
.openBox(boxId, tokenIds, nonce, signature)
|
|
.send({ gas: 1000000 });
|
|
}
|
|
|
|
/**
|
|
* activate one nft with 18 digital id
|
|
* @param {string} address
|
|
* @param {string} nftOld
|
|
* @param {string} nftNew
|
|
* @param {number} nftType
|
|
* @param {string} nonce
|
|
* @param {string} signature
|
|
* @return {Promise<any>}
|
|
*/
|
|
public async activateOneNft(
|
|
address: string,
|
|
nftOld: string,
|
|
nftNew: string,
|
|
nftType: number,
|
|
nonce: string,
|
|
signature: string
|
|
) {
|
|
const nftProxyInstance = await this.bc.getContractInstance(
|
|
address,
|
|
ACTIVATE_PROXY_ABI
|
|
);
|
|
const gas = await nftProxyInstance.methods
|
|
.activateOne(nftOld, nftNew, nftType, nonce, signature)
|
|
.estimateGas({ gas: 1000000 });
|
|
console.log("nftProxyInstance activateOne need gas: ", gas);
|
|
return nftProxyInstance.methods
|
|
.activateOne(nftOld, nftNew, nftType, nonce, signature)
|
|
.send({ gas: (gas * 1.1) | 0 });
|
|
}
|
|
|
|
public async transferToAccount({
|
|
to,
|
|
amount,
|
|
chainId,
|
|
address,
|
|
}: {
|
|
to: string;
|
|
amount: number;
|
|
chainId: number;
|
|
address: string;
|
|
}) {
|
|
const self = this;
|
|
if (chainId !== this.bc.currentChain) {
|
|
return new Promise((resolve, reject) => {
|
|
this.bc.switchEthereumChain(chainId, function () {
|
|
self.bc
|
|
.transferToAccount(to, amount, address)
|
|
.then((res) => {
|
|
resolve && resolve(res);
|
|
})
|
|
.catch((err) => {
|
|
reject && reject(err);
|
|
});
|
|
});
|
|
});
|
|
} else {
|
|
return this.bc.transferToAccount(to, amount, address);
|
|
}
|
|
}
|
|
}
|