720 lines
17 KiB
TypeScript
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 })
|
|
);
|
|
}
|
|
}
|