diff --git a/src/index.ts b/src/index.ts index 685c303..2fcd2e4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -21,7 +21,6 @@ import { WALLET_STORAGE_KEY_NAME } from "./config/constants"; import { DEFALUT_TOKENS } from "./config/chain_config"; import { loadInternalWallet, - newMnemonic, restoreWalletByMnemonic, } from "./manage/WalletManage"; import { buildLoginSignMsg, signLogin } from "./util/sign.util"; @@ -32,6 +31,7 @@ import { getJCErc721Info, getTypeByAddress, UNKNOW } from "./util/chain.util"; import { JCStandard } from "./standards/JCStandard"; import { NativeSvr } from "./services/NativeSvr"; import { ChainCommon } from "./standards/ChainCommon"; +import { fromTokenMinimalUnit } from "./util/number.util"; var global = (typeof globalThis !== "undefined" && globalThis) || @@ -393,7 +393,14 @@ export default class JCWallet { return address; } - public async sendEth(to: string, amount: number | string) { + public async generateGasShow(gas: any) { + let price = await this.web3.eth.getGasPrice(); + let ehtBN = this.web3.utils.toBN(price).mul(this.web3.utils.toBN(gas)); + let eth = fromTokenMinimalUnit(ehtBN, 18); + return { gas, price, eth }; + } + + public async sendEth(to: string, amount: number | string, estimate: number) { let from = this.currentAccAddr; const amountToSend = this.web3.utils.toWei(amount + "", "ether"); let gas = await this.web3.eth.estimateGas({ @@ -401,7 +408,15 @@ export default class JCWallet { to, value: amountToSend, }); - this.web3.eth.sendTransaction({ from, to, gas, value: amountToSend }); + if (estimate) { + return this.generateGasShow(gas); + } + return this.web3.eth.sendTransaction({ + from, + to, + gas, + value: amountToSend, + }); } public async getBalance(account?: string) { @@ -470,13 +485,19 @@ export default class JCWallet { return result; } - public async sendErc20(address: string, to: string, amount: string) { + public async sendErc20( + address: string, + to: string, + amount: string, + estimate: number + ) { let from = this.currentAccAddr; let result = await this.erc20Standard.transfer({ address, from, to, amount, + estimate, }); return result; } @@ -544,15 +565,20 @@ export default class JCWallet { return nfts; } - public async sendNFT(address: string, to: string, tokenId: string) { + public async sendNFT( + address: string, + to: string, + tokenId: string, + estimate: number + ) { let from = this.currentAccAddr; - let result = await this.erc721Standard.transfer({ + return this.erc721Standard.transfer({ address, from, to, tokenId, + estimate, }); - return result; } public async erc1155Info(address: string) {} @@ -562,8 +588,24 @@ export default class JCWallet { account = this.currentAccAddr; } } - //TODO:: - public async sendErc1155() {} + + public async sendErc1155( + address: string, + to: string, + tokenIds: string[], + amounts: string[], + estimate: number + ) { + let from = this.currentAccAddr; + return this.erc1155Standard.transferBatch({ + address, + from, + to, + tokenIds, + amounts, + estimate, + }); + } } // window.jc = window.jc || {wallet: new JCWallet()}; diff --git a/src/standards/ChainCommon.ts b/src/standards/ChainCommon.ts index 417b7fd..69a3610 100644 --- a/src/standards/ChainCommon.ts +++ b/src/standards/ChainCommon.ts @@ -1,6 +1,8 @@ import Web3 from "web3"; import { BN } from "ethereumjs-util"; +export const SAMPLE_GAS = 1000000; + export class ChainCommon { private web3: Web3; diff --git a/src/standards/ERC1155Standard.ts b/src/standards/ERC1155Standard.ts index 42f437c..5ce5f59 100644 --- a/src/standards/ERC1155Standard.ts +++ b/src/standards/ERC1155Standard.ts @@ -1,14 +1,12 @@ +import Web3 from "web3"; +import { abiERC1155 } from "../abis/abiERC1155"; +import { timeoutFetch } from "../util/net.util"; +import { getFormattedIpfsUrl } from "../util/wallet.util"; -import Web3 from 'web3'; -import { abiERC1155 } from '../abis/abiERC1155'; -import { timeoutFetch } from '../util/net.util'; -import { getFormattedIpfsUrl } from '../util/wallet.util'; - -export const ERC1155 = 'ERC1155'; -export const ERC1155_INTERFACE_ID = '0xd9b67a26'; -export const ERC1155_METADATA_URI_INTERFACE_ID = '0x0e89341c'; -export const ERC1155_TOKEN_RECEIVER_INTERFACE_ID = '0x4e2312e0'; - +export const ERC1155 = "ERC1155"; +export const ERC1155_INTERFACE_ID = "0xd9b67a26"; +export const ERC1155_METADATA_URI_INTERFACE_ID = "0x0e89341c"; +export const ERC1155_TOKEN_RECEIVER_INTERFACE_ID = "0x4e2312e0"; export class ERC1155Standard { private web3: Web3; @@ -24,11 +22,11 @@ export class ERC1155Standard { * @returns Promise resolving to whether the contract implements ERC1155 URI Metadata interface. */ contractSupportsURIMetadataInterface = async ( - address: string, + address: string ): Promise => { return this.contractSupportsInterface( address, - ERC1155_METADATA_URI_INTERFACE_ID, + ERC1155_METADATA_URI_INTERFACE_ID ); }; @@ -39,11 +37,11 @@ export class ERC1155Standard { * @returns Promise resolving to whether the contract implements ERC1155 Token Receiver interface. */ contractSupportsTokenReceiverInterface = async ( - address: string, + address: string ): Promise => { return this.contractSupportsInterface( address, - ERC1155_TOKEN_RECEIVER_INTERFACE_ID, + ERC1155_TOKEN_RECEIVER_INTERFACE_ID ); }; @@ -54,7 +52,7 @@ export class ERC1155Standard { * @returns Promise resolving to whether the contract implements the base ERC1155 interface. */ contractSupportsBase1155Interface = async ( - address: string, + address: string ): Promise => { return this.contractSupportsInterface(address, ERC1155_INTERFACE_ID); }; @@ -69,14 +67,16 @@ export class ERC1155Standard { getTokenURI = async (address: string, tokenId: string): Promise => { const contract = new this.web3.eth.Contract(abiERC1155, address); return new Promise((resolve, reject) => { - contract.methods.tokenURI(tokenId).call( (error: Error, result: string) => { - /* istanbul ignore if */ - if (error) { - reject(error); - return; - } - resolve(result); - }); + contract.methods + .tokenURI(tokenId) + .call((error: Error, result: string) => { + /* istanbul ignore if */ + if (error) { + reject(error); + return; + } + resolve(result); + }); }); }; @@ -91,18 +91,22 @@ export class ERC1155Standard { getBalanceOf = async ( contractAddress: string, address: string, - tokenId: string, + tokenId: string ): Promise => { const contract = new this.web3.eth.Contract(abiERC1155, address); return new Promise((resolve, reject) => { - contract.methods.balanceOf(address, tokenId, (error: Error, result: number) => { - /* istanbul ignore if */ - if (error) { - reject(error); - return; + contract.methods.balanceOf( + address, + tokenId, + (error: Error, result: number) => { + /* istanbul ignore if */ + if (error) { + reject(error); + return; + } + resolve(result); } - resolve(result); - }); + ); }); }; @@ -123,7 +127,7 @@ export class ERC1155Standard { from: string, to: string, id: string, - value: string, + value: string ): Promise => { const contract = new this.web3.eth.Contract(abiERC1155, operator); return new Promise((resolve, reject) => { @@ -140,7 +144,7 @@ export class ERC1155Standard { return; } resolve(result); - }, + } ); }); }; @@ -154,7 +158,7 @@ export class ERC1155Standard { */ private contractSupportsInterface = async ( address: string, - interfaceId: string, + interfaceId: string ): Promise => { const contract = new this.web3.eth.Contract(abiERC1155, address); return new Promise((resolve, reject) => { @@ -167,7 +171,7 @@ export class ERC1155Standard { return; } resolve(result); - }, + } ); }); }; @@ -183,7 +187,7 @@ export class ERC1155Standard { getDetails = async ( address: string, ipfsGateway: string, - tokenId?: string, + tokenId?: string ): Promise<{ standard: string; tokenURI: string | undefined; @@ -198,7 +202,7 @@ export class ERC1155Standard { if (tokenId) { tokenURI = await this.getTokenURI(address, tokenId); - if (tokenURI.startsWith('ipfs://')) { + if (tokenURI.startsWith("ipfs://")) { tokenURI = getFormattedIpfsUrl(ipfsGateway, tokenURI, true); } @@ -206,7 +210,7 @@ export class ERC1155Standard { const response = await timeoutFetch(tokenURI); const object = await response.json(); image = object?.image; - if (image?.startsWith('ipfs://')) { + if (image?.startsWith("ipfs://")) { image = getFormattedIpfsUrl(ipfsGateway, image, true); } } catch { @@ -221,4 +225,39 @@ export class ERC1155Standard { image, }; }; + + async transferBatch({ + address, + from, + to, + tokenIds, + amounts, + gas, + estimate, + }: { + address: string; + from: string; + to: string; + tokenIds: string[]; + amounts: string[]; + gas?: number; + estimate: number; + }) { + const contract = new this.web3.eth.Contract(abiERC1155, address); + if (!gas) { + gas = await contract.methods + .safeBatchTransferFrom(from, to, tokenIds, amounts) + .estimateGas({ gas: 1000000 }); + } + gas = gas * 1.1; + if (estimate) { + return jc.wallet.generateGasShow(gas); + } + return contract.methods + .safeBatchTransferFrom(from, to, tokenIds, amounts) + .send({ + from, + gas, + }); + } } diff --git a/src/standards/ERC20Standard.ts b/src/standards/ERC20Standard.ts index 1e69b74..a0395ec 100644 --- a/src/standards/ERC20Standard.ts +++ b/src/standards/ERC20Standard.ts @@ -146,18 +146,29 @@ export class ERC20Standard { to, amount, gas, + estimate, }: { address: string; from: string; to: string; amount: number | string; gas?: number; + estimate: number; }) { const contract = new this.web3.eth.Contract(abiERC20, address); const amountBN = Web3.utils.toBN(Web3.utils.toWei(amount + "")); + if (!gas) { + gas = await contract.methods + .transfer(to, amountBN) + .estimateGas({ gas: 1000000 }); + } + gas = gas * 1.1; + if (estimate) { + return jc.wallet.generateGasShow(gas); + } return contract.methods.transfer(to, amountBN).send({ from, - gas: gas || 1000000, + gas, }); } } diff --git a/src/standards/ERC721Standard.ts b/src/standards/ERC721Standard.ts index 6329ccf..7ec8f3d 100644 --- a/src/standards/ERC721Standard.ts +++ b/src/standards/ERC721Standard.ts @@ -1,13 +1,12 @@ - -import Web3 from 'web3'; +import Web3 from "web3"; import { abiERC721 } from "../abis/abiERC721"; -import { timeoutFetch } from '../util/net.util'; -import { getFormattedIpfsUrl } from '../util/wallet.util'; +import { timeoutFetch } from "../util/net.util"; +import { getFormattedIpfsUrl } from "../util/wallet.util"; -export const ERC721 = 'ERC721'; -export const ERC721_INTERFACE_ID = '0x80ac58cd'; -export const ERC721_METADATA_INTERFACE_ID = '0x5b5e139f'; -export const ERC721_ENUMERABLE_INTERFACE_ID = '0x780e9d63'; +export const ERC721 = "ERC721"; +export const ERC721_INTERFACE_ID = "0x80ac58cd"; +export const ERC721_METADATA_INTERFACE_ID = "0x5b5e139f"; +export const ERC721_ENUMERABLE_INTERFACE_ID = "0x780e9d63"; export class ERC721Standard { private web3: Web3; @@ -23,11 +22,11 @@ export class ERC721Standard { * @returns Promise resolving to whether the contract implements ERC721Metadata interface. */ contractSupportsMetadataInterface = async ( - address: string, + address: string ): Promise => { return this.contractSupportsInterface( address, - ERC721_METADATA_INTERFACE_ID, + ERC721_METADATA_INTERFACE_ID ); }; @@ -38,11 +37,11 @@ export class ERC721Standard { * @returns Promise resolving to whether the contract implements ERC721Enumerable interface. */ contractSupportsEnumerableInterface = async ( - address: string, + address: string ): Promise => { return this.contractSupportsInterface( address, - ERC721_ENUMERABLE_INTERFACE_ID, + ERC721_ENUMERABLE_INTERFACE_ID ); }; @@ -53,7 +52,7 @@ export class ERC721Standard { * @returns Promise resolving to whether the contract implements ERC721 interface. */ contractSupportsBase721Interface = async ( - address: string, + address: string ): Promise => { return this.contractSupportsInterface(address, ERC721_INTERFACE_ID); }; @@ -69,21 +68,20 @@ export class ERC721Standard { getCollectibleTokenId = async ( address: string, selectedAddress: string, - index: number, + index: number ): Promise => { const contract = new this.web3.eth.Contract(abiERC721, address); return new Promise((resolve, reject) => { - contract.methods.tokenOfOwnerByIndex( - selectedAddress, - index).call((error: Error, result: string) => { + contract.methods + .tokenOfOwnerByIndex(selectedAddress, index) + .call((error: Error, result: string) => { /* istanbul ignore if */ if (error) { reject(error); return; } resolve(result); - }, - ); + }); }); }; @@ -93,16 +91,16 @@ export class ERC721Standard { ): Promise => { const contract = new this.web3.eth.Contract(abiERC721, address); return new Promise((resolve, reject) => { - contract.methods.balanceOf( - selectedAddress).call((error: Error, result: number) => { + contract.methods + .balanceOf(selectedAddress) + .call((error: Error, result: number) => { /* istanbul ignore if */ if (error) { reject(error); return; } resolve(result); - }, - ); + }); }); }; @@ -116,20 +114,22 @@ export class ERC721Standard { getTokenURI = async (address: string, tokenId: string): Promise => { const contract = new this.web3.eth.Contract(abiERC721, address); const supportsMetadata = await this.contractSupportsMetadataInterface( - address, + address ); if (!supportsMetadata) { - throw new Error('Contract does not support ERC721 metadata interface.'); + throw new Error("Contract does not support ERC721 metadata interface."); } return new Promise((resolve, reject) => { - contract.methods.tokenURI(tokenId).call( (error: Error, result: string) => { - /* istanbul ignore if */ - if (error) { - reject(error); - return; - } - resolve(result); - }); + contract.methods + .tokenURI(tokenId) + .call((error: Error, result: string) => { + /* istanbul ignore if */ + if (error) { + reject(error); + return; + } + resolve(result); + }); }); }; @@ -183,7 +183,7 @@ export class ERC721Standard { async getOwnerOf(address: string, tokenId: string): Promise { const contract = new this.web3.eth.Contract(abiERC721, address); return new Promise((resolve, reject) => { - contract.methods.ownerOf(tokenId).call( (error: Error, result: string) => { + contract.methods.ownerOf(tokenId).call((error: Error, result: string) => { /* istanbul ignore if */ if (error) { reject(error); @@ -203,20 +203,20 @@ export class ERC721Standard { */ private contractSupportsInterface = async ( address: string, - interfaceId: string, + interfaceId: string ): Promise => { const contract = new this.web3.eth.Contract(abiERC721, address); return new Promise((resolve, reject) => { - contract.methods.supportsInterface( - interfaceId).call((error: Error, result: boolean) => { + contract.methods + .supportsInterface(interfaceId) + .call((error: Error, result: boolean) => { /* istanbul ignore if */ if (error) { reject(error); return; } resolve(result); - }, - ); + }); }); }; @@ -231,7 +231,7 @@ export class ERC721Standard { getDetails = async ( address: string, ipfsGateway: string, - tokenId?: string, + tokenId?: string ): Promise<{ standard: string; tokenURI: string | undefined; @@ -262,14 +262,14 @@ export class ERC721Standard { if (tokenId) { try { tokenURI = await this.getTokenURI(address, tokenId); - if (tokenURI.startsWith('ipfs://')) { + if (tokenURI.startsWith("ipfs://")) { tokenURI = getFormattedIpfsUrl(ipfsGateway, tokenURI, true); } const response = await timeoutFetch(tokenURI); const object = await response.json(); - image = object ? object.image : '' - if (image.startsWith('ipfs://')) { + image = object ? object.image : ""; + if (image.startsWith("ipfs://")) { image = getFormattedIpfsUrl(ipfsGateway, image, true); } } catch { @@ -286,24 +286,34 @@ export class ERC721Standard { }; }; - async transfer({ address, from, to, tokenId, gas, + estimate, }: { address: string; from: string; to: string; tokenId: string; gas?: number; + estimate: number; }) { const contract = new this.web3.eth.Contract(abiERC721, address); + if (!gas) { + gas = await contract.methods + .safeTransferFrom(from, to, tokenId) + .estimateGas({ gas: 1000000 }); + } + gas = gas * 1.1; + if (estimate) { + return jc.wallet.generateGasShow(gas); + } return contract.methods.safeTransferFrom(from, to, tokenId).send({ from, - gas: gas || 1000000, + gas, }); } -} \ No newline at end of file +} diff --git a/src/standards/JCStandard.ts b/src/standards/JCStandard.ts index c9777bf..5dcf8a4 100644 --- a/src/standards/JCStandard.ts +++ b/src/standards/JCStandard.ts @@ -5,6 +5,7 @@ import { abiERC1155 } from "../abis/abiERC1155"; import { abiEvolveFactory } from "../abis/abiUserEvolveFactory"; import { abiMinterFactory } from "../abis/abiUserMinterFactory"; import { JC_CONTRACTS } from "../config/chain_config"; +import { SAMPLE_GAS } from "./ChainCommon"; export class JCStandard { private web3: Web3; @@ -17,28 +18,33 @@ export class JCStandard { addresses, values, signature, + gas, + estimate, }: { addresses: string[]; values: string[]; signature: string; + gas?: number; + estimate: number; }) { let address = JC_CONTRACTS[window.jc.wallet.currentChain.id].nftMall; const contract = new this.web3.eth.Contract(abiNftMall, address, { //@ts-ignore from: jc.wallet.currentAccAddr, }); - //TODO:: increaseAllowance before call - let gas; - try { - gas = await contract.methods - .buy721NFT(addresses, values, signature) - .estimateGas({ gas: 1000000 }); - } catch (err) { - console.log("estimategas with error: " + JSON.stringify(err)); + if (!gas) { + try { + gas = await contract.methods + .buy721NFT(addresses, values, signature) + .estimateGas({ gas: SAMPLE_GAS }); + } catch (err) {} + gas = gas ? gas * 1.1 : SAMPLE_GAS; } - gas = gas || 1000000; //@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) { @@ -55,7 +61,7 @@ export class JCStandard { } return contract.methods .buy721NFT(addresses, values, signature) - .send({ gas: (gas * 1.1) | 0 }); + .send({ gas }); } async buyNft1155({ @@ -64,24 +70,36 @@ export class JCStandard { ids, amounts, signature, + gas, + estimate, }: { addresses: string[]; values: string[]; ids: string[]; amounts: string[]; signature: string; + gas?: number; + estimate: number; }) { let address = JC_CONTRACTS[window.jc.wallet.currentChain.id].nftMall; const contract = new this.web3.eth.Contract(abiNftMall, address, { //@ts-ignore from: jc.wallet.currentAccAddr, }); - let gas = await contract.methods - .buy1155NFT(addresses, values, ids, amounts, signature) - .estimateGas({ gas: 1000000 }); - gas = gas || 1000000; + if (!gas) { + try { + gas = await contract.methods + .buy1155NFT(addresses, values, ids, amounts, signature) + .estimateGas({ gas: SAMPLE_GAS }); + } catch (err) {} + gas = gas ? gas * 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) { @@ -97,7 +115,7 @@ export class JCStandard { } return contract.methods .buy1155NFT(addresses, values, ids, amounts, signature) - .send({ gas: (gas * 1.1) | 0 }); + .send({ gas }); } async evolve721NFT({ @@ -106,24 +124,36 @@ export class JCStandard { startTime, nonce, signature, + gas, + estimate, }: { nftAddress: string; tokenIds: string[]; startTime: number; nonce: string; signature: string; + gas?: number; + estimate: number; }) { let address = JC_CONTRACTS[window.jc.wallet.currentChain.id].evolveFactory; const contract = new this.web3.eth.Contract(abiEvolveFactory, address, { //@ts-ignore from: jc.wallet.currentAccAddr, }); - let gas = await contract.methods - .evolve721NFT(nftAddress, tokenIds, startTime, nonce, signature) - .estimateGas({ gas: 1000000 }); - gas = gas || 1000000; + if (!gas) { + try { + gas = await contract.methods + .evolve721NFT(nftAddress, tokenIds, startTime, nonce, signature) + .estimateGas({ gas: SAMPLE_GAS }); + } catch (err) {} + gas = gas ? gas * 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) { @@ -147,23 +177,35 @@ export class JCStandard { startTime, nonce, signature, + gas, + estimate, }: { tokenIds: string[]; startTime: number; nonce: string; signature: string; + gas?: number; + estimate: number; }) { let address = JC_CONTRACTS[window.jc.wallet.currentChain.id].evolveFactory; const contract = new this.web3.eth.Contract(abiEvolveFactory, address, { //@ts-ignore from: jc.wallet.currentAccAddr, }); - let gas = await contract.methods - .evolveChip(tokenIds, startTime, nonce, signature) - .estimateGas({ gas: 1000000 }); - gas = gas || 1000000; + if (gas) { + try { + gas = await contract.methods + .evolveChip(tokenIds, startTime, nonce, signature) + .estimateGas({ gas: SAMPLE_GAS }); + } catch (err) {} + gas = gas ? gas * 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) { @@ -179,7 +221,7 @@ export class JCStandard { } return contract.methods .evolveChip(tokenIds, startTime, nonce, signature) - .send({ gas: (gas * 1.1) | 0 }); + .send({ gas }); } async mintShardBatchUser({ @@ -188,24 +230,36 @@ export class JCStandard { startTime, nonce, signature, + gas, + estimate, }: { tokenIds: string[]; amounts: number[]; startTime: number; nonce: string; signature: string; + gas?: number; + estimate: number; }) { let address = JC_CONTRACTS[window.jc.wallet.currentChain.id].minterFactory; const contract = new this.web3.eth.Contract(abiMinterFactory, address, { //@ts-ignore from: jc.wallet.currentAccAddr, }); - let gas = await contract.methods - .mintShardBatchUser(tokenIds, amounts, startTime, nonce, signature) - .estimateGas({ gas: 1000000 }); - gas = gas || 1000000; + if (!gas) { + try { + gas = await contract.methods + .mintShardBatchUser(tokenIds, amounts, startTime, nonce, signature) + .estimateGas({ gas: SAMPLE_GAS }); + } catch (err) {} + gas = gas ? gas * 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) { @@ -221,7 +275,7 @@ export class JCStandard { } return contract.methods .mintShardBatchUser(tokenIds, amounts, startTime, nonce, signature) - .send({ gas: (gas * 1.1) | 0 }); + .send({ gas }); } async shardMixByUser({ @@ -234,6 +288,8 @@ export class JCStandard { startTime, nonce, signature, + gas, + estimate, }: { tokenId: string; nftType: number; @@ -244,28 +300,38 @@ export class JCStandard { startTime: number; nonce: string; signature: string; + gas?: number; + estimate: number; }) { let address = JC_CONTRACTS[window.jc.wallet.currentChain.id].minterFactory; const contract = new this.web3.eth.Contract(abiMinterFactory, address, { //@ts-ignore from: jc.wallet.currentAccAddr, }); - let gas = await contract.methods - .shardMixByUser( - tokenId, - nftType, - payToken, - payAmount, - ids, - amounts, - startTime, - nonce, - signature - ) - .estimateGas({ gas: 1000000 }); - gas = gas || 1000000; + if (!gas) { + try { + let gas = await contract.methods + .shardMixByUser( + tokenId, + nftType, + payToken, + payAmount, + ids, + amounts, + startTime, + nonce, + signature + ) + .estimateGas({ gas: SAMPLE_GAS }); + } catch (err) {} + gas = gas ? gas * 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) { @@ -292,7 +358,7 @@ export class JCStandard { nonce, signature ) - .send({ gas: (gas * 1.1) | 0 }); + .send({ gas }); } async pluginChip({ @@ -301,12 +367,16 @@ export class JCStandard { chipIds, slots, signature, + gas, + estimate, }: { addresses: string[]; values: string[]; chipIds: string[]; slots: string[]; signature: string; + gas?: number; + estimate: number; }) { let lockerAddress = JC_CONTRACTS[window.jc.wallet.currentChain.id].chipLocker; @@ -322,11 +392,31 @@ export class JCStandard { jumpToWallet(); }, 1500); } - let gas1 = await chipInstance.methods - .setApprovalForAll(lockerAddress, true) - .estimateGas({ gas: 1000000 }); - gas1 = gas1 || 1000000; + let gas1 = SAMPLE_GAS; + let gas0 = SAMPLE_GAS; + try { + gas1 = await chipInstance.methods + .setApprovalForAll(lockerAddress, true) + .estimateGas({ gas: SAMPLE_GAS }); + gas0 = await contract.methods + .pluginChip(addresses, values, chipIds, slots, signature) + .estimateGas({ gas: SAMPLE_GAS }); + } catch (err) {} + if (!gas) { + gas1 = gas1 ? gas1 * 1.1 : SAMPLE_GAS; + gas0 = gas0 ? gas0 * 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"; @@ -334,12 +424,8 @@ export class JCStandard { } await chipInstance.methods .setApprovalForAll(lockerAddress, true) - .send({ gas: (gas1 * 1.1) | 0 }); + .send({ gas: gas1 }); - let gas0 = await contract.methods - .pluginChip(addresses, values, chipIds, slots, signature) - .estimateGas({ gas: 1000000 }); - gas0 = gas0 || 1000000; if (jc.wallet.isInternal) { let ethEnough = await jc.wallet.chainCommon.checkEthEnough(gas0); if (!ethEnough) { @@ -354,7 +440,7 @@ export class JCStandard { } return await contract.methods .pluginChip(addresses, values, chipIds, slots, signature) - .send({ gas: (gas0 * 1.1) | 0 }); + .send({ gas: gas0 }); } async unplugChip({ @@ -363,28 +449,38 @@ export class JCStandard { chipIds, slots, signature, + gas, + estimate, }: { addresses: string[]; values: string[]; chipIds: string[]; slots: string[]; signature: string; + gas?: number; + estimate: number; }) { let lockerAddress = JC_CONTRACTS[window.jc.wallet.currentChain.id].chipLocker; const contract = new this.web3.eth.Contract(abiChipLocker, lockerAddress, { from: jc.wallet.currentAccAddr, }); - let gas0 = 1000000; - try { - gas0 = await contract.methods - .unplugChip(addresses, values, chipIds, slots, signature) - .estimateGas({ gas: 1000000 }); - } catch (err) { - console.log(err); + if (!gas) { + try { + gas = await contract.methods + .unplugChip(addresses, values, chipIds, slots, signature) + .estimateGas({ gas: 1000000 }); + } catch (err) { + console.log(err); + } + gas = gas ? gas * 1.1 : SAMPLE_GAS; } + if (jc.wallet.isInternal) { - let ethEnough = await jc.wallet.chainCommon.checkEthEnough(gas0); + if (estimate) { + return jc.wallet.generateGasShow(gas); + } + let ethEnough = await jc.wallet.chainCommon.checkEthEnough(gas); if (!ethEnough) { throw "eth not enough"; } @@ -397,6 +493,6 @@ export class JCStandard { } return await contract.methods .unplugChip(addresses, values, chipIds, slots, signature) - .send({ gas: (gas0 * 1.1) | 0 }); + .send({ gas }); } }