jcwallet/src/standards/JCStandard.ts

720 lines
17 KiB
TypeScript

import assert from "assert";
import Web3 from "web3";
import { abiNftMall } from "../abis/abiBENftMall";
import { abiChipLocker } from "../abis/abiChipLocker";
import { abiERC1155 } from "../abis/abiERC1155";
import { abiEvolveFactory } from "../abis/abiUserEvolveFactory";
import { abiMinterFactory } from "../abis/abiUserMinterFactory";
import { ZERO_ADDRESS } from "../config/constants";
import { getAddressByName, universalChainCb } from "../util/chain.util";
import { SAMPLE_GAS } from "./ChainCommon";
export class JCStandard {
private web3: Web3;
constructor(web3: Web3) {
this.web3 = web3;
}
async buyNft721({
addresses,
values,
signature,
gas,
estimate,
}: {
addresses: string[];
values: string[];
signature: string;
gas?: number;
estimate: number;
}) {
let address = jc.wallet.currentChainCfg.contracts.nftMall;
const contract = new this.web3.eth.Contract(abiNftMall, address, {
//@ts-ignore
from: jc.wallet.currentAccAddr,
});
if (!gas) {
try {
gas = await contract.methods
.buy721NFT(addresses, values, signature)
.estimateGas();
} catch (err) {}
gas = gas ? (gas * 1.1) | 1 : SAMPLE_GAS;
}
//@ts-ignore
if (jc.wallet.isInternal) {
if (estimate) {
return jc.wallet.generateGasShow(gas);
}
//@ts-ignore
let ethEnough = await jc.wallet.chainCommon.checkEthEnough(gas);
if (!ethEnough) {
throw "eth not enough";
}
}
//@ts-ignore
if (!jc.wallet.isInternal) {
setTimeout(() => {
// @ts-ignore
jumpToWallet();
}, 1500);
}
const details = [];
// payment token
const feeAddress = await jc.wallet.getFeeAddress("nftMall");
details.push({
address: addresses[2],
from: jc.wallet.currentAccAddr,
to: feeAddress,
value: values[1],
});
// nft minted
details.push({
address: addresses[1],
from: ZERO_ADDRESS,
to: jc.wallet.currentAccAddr,
id: values[0],
});
const logData = {
gas,
title: "buy_erc721",
details,
};
return universalChainCb(
logData,
contract.methods.buy721NFT(addresses, values, signature).send({ gas })
);
}
async buyNft1155({
addresses,
values,
ids,
amounts,
signature,
gas,
estimate,
}: {
addresses: string[];
values: string[];
ids: string[];
amounts: string[];
signature: string;
gas?: number;
estimate: number;
}) {
let address = jc.wallet.currentChainCfg.contracts.nftMall;
const contract = new this.web3.eth.Contract(abiNftMall, address, {
//@ts-ignore
from: jc.wallet.currentAccAddr,
});
if (!gas) {
try {
gas = await contract.methods
.buy1155NFT(addresses, values, ids, amounts, signature)
.estimateGas();
} catch (err) {}
gas = gas ? (gas * 1.1) | 1 : SAMPLE_GAS;
}
//@ts-ignore
if (jc.wallet.isInternal) {
if (estimate) {
return jc.wallet.generateGasShow(gas);
}
//@ts-ignore
let ethEnough = await jc.wallet.chainCommon.checkEthEnough(gas);
if (!ethEnough) {
throw "eth not enough";
}
}
//@ts-ignore
if (!jc.wallet.isInternal) {
setTimeout(() => {
// @ts-ignore
jumpToWallet();
}, 1500);
}
const details = [];
// payment token
const feeAddress = await jc.wallet.getFeeAddress("nftMall");
details.push({
address: addresses[2],
from: jc.wallet.currentAccAddr,
to: feeAddress, // can't fetch address in contract, use seller instead
value: values[0],
});
// 1155 token minted
for (let i = 0, l = ids.length; i < l; i++) {
details.push({
address: addresses[1],
from: ZERO_ADDRESS,
to: jc.wallet.currentAccAddr,
id: ids[i],
value: amounts[i],
});
}
const logData = {
gas,
title: "buy_erc1155",
details,
};
return universalChainCb(
logData,
contract.methods
.buy1155NFT(addresses, values, ids, amounts, signature)
.send({ gas })
);
}
async evolve721NFT({
nftAddress,
tokenIds,
startTime,
nonce,
signature,
gas,
estimate,
}: {
nftAddress: string;
tokenIds: string[];
startTime: number;
nonce: string;
signature: string;
gas?: number;
estimate: number;
}) {
let address = jc.wallet.currentChainCfg.contracts.evolveFactory;
const contract = new this.web3.eth.Contract(abiEvolveFactory, address, {
//@ts-ignore
from: jc.wallet.currentAccAddr,
});
if (!gas) {
try {
gas = await contract.methods
.evolve721NFT(nftAddress, tokenIds, startTime, nonce, signature)
.estimateGas();
} catch (err) {}
gas = gas ? (gas * 1.1) | 1 : SAMPLE_GAS;
}
//@ts-ignore
if (jc.wallet.isInternal) {
if (estimate) {
return jc.wallet.generateGasShow(gas);
}
//@ts-ignore
let ethEnough = await jc.wallet.chainCommon.checkEthEnough(gas);
if (!ethEnough) {
throw "eth not enough";
}
}
//@ts-ignore
if (!jc.wallet.isInternal) {
setTimeout(() => {
// @ts-ignore
jumpToWallet();
}, 1500);
}
const details = [];
// nft evolved
details.push({
address: nftAddress,
from: jc.wallet.currentAccAddr,
to: jc.wallet.currentAccAddr,
id: tokenIds[0],
});
// nft burn
details.push({
address: nftAddress,
from: jc.wallet.currentAccAddr,
to: ZERO_ADDRESS,
id: tokenIds[1],
});
const logData = {
gas,
title: "evolve_721",
details,
};
return universalChainCb(
logData,
contract.methods
.evolve721NFT(nftAddress, tokenIds, startTime, nonce, signature)
.send({ gas })
);
}
async evolveChip({
tokenIds,
startTime,
nonce,
signature,
gas,
estimate,
}: {
tokenIds: string[];
startTime: number;
nonce: string;
signature: string;
gas?: number;
estimate: number;
}) {
let address = jc.wallet.currentChainCfg.contracts.evolveFactory;
const contract = new this.web3.eth.Contract(abiEvolveFactory, address, {
//@ts-ignore
from: jc.wallet.currentAccAddr,
});
if (gas) {
try {
gas = await contract.methods
.evolveChip(tokenIds, startTime, nonce, signature)
.estimateGas();
} catch (err) {}
gas = gas ? (gas * 1.1) | 1 : SAMPLE_GAS;
}
//@ts-ignore
if (jc.wallet.isInternal) {
if (estimate) {
return jc.wallet.generateGasShow(gas);
}
//@ts-ignore
let ethEnough = await jc.wallet.chainCommon.checkEthEnough(gas);
if (!ethEnough) {
throw "eth not enough";
}
}
//@ts-ignore
if (!jc.wallet.isInternal) {
setTimeout(() => {
// @ts-ignore
jumpToWallet();
}, 1500);
}
const details = [];
const chipAddress = getAddressByName("chip");
assert(!!chipAddress, "chip address not found");
// chip evolved
details.push({
address: chipAddress,
from: jc.wallet.currentAccAddr,
to: jc.wallet.currentAccAddr,
id: tokenIds[0],
value: 1,
});
// chip burn
for (let i = 1, l = tokenIds.length; i < l; i++) {
details.push({
address: chipAddress,
from: jc.wallet.currentAccAddr,
to: ZERO_ADDRESS,
id: tokenIds[i],
value: 1,
});
}
const logData = {
gas,
title: "evolve_chip",
details,
};
return universalChainCb(
logData,
contract.methods
.evolveChip(tokenIds, startTime, nonce, signature)
.send({ gas })
);
}
async mintShardBatchUser({
tokenIds,
amounts,
startTime,
nonce,
signature,
gas,
estimate,
}: {
tokenIds: string[];
amounts: number[];
startTime: number;
nonce: string;
signature: string;
gas?: number;
estimate: number;
}) {
let address = jc.wallet.currentChainCfg.contracts.minterFactory;
const contract = new this.web3.eth.Contract(abiMinterFactory, address, {
//@ts-ignore
from: jc.wallet.currentAccAddr,
});
if (!gas) {
try {
gas = await contract.methods
.mintShardBatchUser(tokenIds, amounts, startTime, nonce, signature)
.estimateGas();
} catch (err) {}
gas = gas ? (gas * 1.1) | 1 : SAMPLE_GAS;
}
//@ts-ignore
if (jc.wallet.isInternal) {
if (estimate) {
return jc.wallet.generateGasShow(gas);
}
//@ts-ignore
let ethEnough = await jc.wallet.chainCommon.checkEthEnough(gas);
if (!ethEnough) {
throw "eth not enough";
}
}
//@ts-ignore
if (!jc.wallet.isInternal) {
setTimeout(() => {
// @ts-ignore
jumpToWallet();
}, 1500);
}
const details = [];
const shardAddress = getAddressByName("shard");
assert(!!shardAddress, "shard address not found");
// shard
for (let i = 0, l = tokenIds.length; i < l; i++) {
details.push({
address: shardAddress,
from: ZERO_ADDRESS,
to: jc.wallet.currentAccAddr,
id: tokenIds[i],
value: amounts[i],
});
}
const logData = {
gas,
title: "mint_shard",
details,
};
return universalChainCb(
logData,
contract.methods
.mintShardBatchUser(tokenIds, amounts, startTime, nonce, signature)
.send({ gas })
);
}
async shardMixByUser({
tokenId,
nftType,
payToken,
payAmount,
ids,
amounts,
startTime,
nonce,
signature,
gas,
estimate,
}: {
tokenId: string;
nftType: number;
payToken: string;
payAmount: number;
ids: string[];
amounts: number[];
startTime: number;
nonce: string;
signature: string;
gas?: number;
estimate: number;
}) {
let address = jc.wallet.currentChainCfg.contracts.minterFactory;
const contract = new this.web3.eth.Contract(abiMinterFactory, address, {
//@ts-ignore
from: jc.wallet.currentAccAddr,
});
if (!gas) {
try {
gas = await contract.methods
.shardMixByUser(
tokenId,
nftType,
payToken,
payAmount,
ids,
amounts,
startTime,
nonce,
signature
)
.estimateGas();
} catch (err) {}
gas = gas ? (gas * 1.1) | 1 : SAMPLE_GAS;
}
//@ts-ignore
if (jc.wallet.isInternal) {
if (estimate) {
return jc.wallet.generateGasShow(gas);
}
//@ts-ignore
let ethEnough = await jc.wallet.chainCommon.checkEthEnough(gas);
if (!ethEnough) {
throw "eth not enough";
}
}
//@ts-ignore
if (!jc.wallet.isInternal) {
setTimeout(() => {
// @ts-ignore
jumpToWallet();
}, 1500);
}
const details = [];
const shardAddress = getAddressByName("shard");
assert(!!shardAddress, "shard address not found");
// nft mint
const nftTypeName = nftType === 0 ? "hero" : "weapon";
const nftAddress = getAddressByName(nftTypeName);
assert(!!nftAddress, "nft address not found");
details.push({
address: nftAddress,
from: ZERO_ADDRESS,
to: jc.wallet.currentAccAddr,
id: tokenId,
value: 1,
});
// payment token
const feeAddress = await jc.wallet.getFeeAddress("nftFactory");
details.push({
address: payToken,
from: jc.wallet.currentAccAddr,
to: feeAddress,
value: payAmount,
});
// shard burn
for (let i = 0, l = ids.length; i < l; i++) {
details.push({
address: shardAddress,
from: jc.wallet.currentAccAddr,
to: ZERO_ADDRESS,
id: ids[i],
value: amounts[i],
});
}
const logData = {
gas,
title: "shard_mix",
details,
};
return universalChainCb(
logData,
contract.methods
.shardMixByUser(
tokenId,
nftType,
payToken,
payAmount,
ids,
amounts,
startTime,
nonce,
signature
)
.send({ gas })
);
}
async pluginChip({
addresses,
values,
chipIds,
slots,
signature,
gas,
estimate,
}: {
addresses: string[];
values: string[];
chipIds: string[];
slots: string[];
signature: string;
gas?: number;
estimate: number;
}) {
let lockerAddress = jc.wallet.currentChainCfg.contracts.chipLocker;
const contract = new this.web3.eth.Contract(abiChipLocker, lockerAddress, {
from: jc.wallet.currentAccAddr,
});
let chipInstance = new this.web3.eth.Contract(abiERC1155, addresses[1], {
from: jc.wallet.currentAccAddr,
});
if (!jc.wallet.isInternal) {
setTimeout(() => {
// @ts-ignore
jumpToWallet();
}, 1500);
}
let gas1 = SAMPLE_GAS;
let gas0 = SAMPLE_GAS;
try {
gas1 = await chipInstance.methods
.setApprovalForAll(lockerAddress, true)
.estimateGas();
gas0 = await contract.methods
.pluginChip(addresses, values, chipIds, slots, signature)
.estimateGas();
} catch (err) {}
if (!gas) {
gas1 = gas1 ? (gas1 * 1.1) | 1 : SAMPLE_GAS;
gas0 = gas0 ? (gas0 * 1.1) | 1 : SAMPLE_GAS;
gas = gas0 + gas1;
} else {
gas0 = gas - gas1;
}
if (gas < gas1) {
throw "gas is too low";
}
if (jc.wallet.isInternal) {
if (estimate) {
return jc.wallet.generateGasShow(gas);
}
let ethEnough = await jc.wallet.chainCommon.checkEthEnough(gas1);
if (!ethEnough) {
throw "eth not enough";
}
}
await chipInstance.methods
.setApprovalForAll(lockerAddress, true)
.send({ gas: gas1 });
if (jc.wallet.isInternal) {
let ethEnough = await jc.wallet.chainCommon.checkEthEnough(gas0);
if (!ethEnough) {
throw "eth not enough";
}
}
if (!jc.wallet.isInternal) {
setTimeout(() => {
// @ts-ignore
jumpToWallet();
}, 1500);
}
const details = [];
// target nft
details.push({
address: addresses[0],
from: jc.wallet.currentAccAddr,
to: jc.wallet.currentAccAddr,
id: values[0],
});
// chip plugin
for (let i = 0, l = chipIds.length; i < l; i++) {
details.push({
address: addresses[1],
from: jc.wallet.currentAccAddr,
to: lockerAddress,
id: chipIds[i],
value: 1,
});
}
const logData = {
gas,
title: "plug_chip",
details,
};
return universalChainCb(
logData,
contract.methods
.pluginChip(addresses, values, chipIds, slots, signature)
.send({ gas })
);
}
async unplugChip({
addresses,
values,
chipIds,
slots,
signature,
gas,
estimate,
}: {
addresses: string[];
values: string[];
chipIds: string[];
slots: string[];
signature: string;
gas?: number;
estimate: number;
}) {
let lockerAddress = jc.wallet.currentChainCfg.contracts.chipLocker;
const contract = new this.web3.eth.Contract(abiChipLocker, lockerAddress, {
from: jc.wallet.currentAccAddr,
});
if (!gas) {
try {
gas = await contract.methods
.unplugChip(addresses, values, chipIds, slots, signature)
.estimateGas();
} catch (err) {
console.log(err);
}
gas = gas ? (gas * 1.1) | 1 : SAMPLE_GAS;
}
if (jc.wallet.isInternal) {
if (estimate) {
return jc.wallet.generateGasShow(gas);
}
let ethEnough = await jc.wallet.chainCommon.checkEthEnough(gas);
if (!ethEnough) {
throw "eth not enough";
}
}
if (!jc.wallet.isInternal) {
setTimeout(() => {
// @ts-ignore
jumpToWallet();
}, 1500);
}
const details = [];
// target nft
details.push({
address: addresses[0],
from: jc.wallet.currentAccAddr,
to: jc.wallet.currentAccAddr,
id: values[0],
});
// chip plugin
for (let i = 0, l = chipIds.length; i < l; i++) {
details.push({
address: addresses[1],
from: lockerAddress,
to: jc.wallet.currentAccAddr,
id: chipIds[i],
value: 1,
});
}
const logData = {
gas,
title: "unplug_chip",
details,
};
return universalChainCb(
logData,
contract.methods
.unplugChip(addresses, values, chipIds, slots, signature)
.send({ gas })
);
}
}