import { ethers } from "ethers";
import type { CallbackType } from "@evo/utils/ethers/contractHelper";
import { triggerContractByContractName, viewContractByContractName } from "@evo/utils/ethers/contractHelper";
import { pad0xBegin } from "@evo/utils/common/utils";
import { LandId } from "@evo/config/constants";
import { TransactionResponse } from "@ethersproject/providers";
import { getAddressesByLandId } from "@evo/utils/ethers/addressHelper";
export interface furnaceGetTreasurePriceResponse {
priceGoldBox: string;
priceSilverBox: string;
}
/**
* Get treasure price
* @param landId Land Id
* @param provider Provider
* @param callback Callback
* @returns any
*/
export const furnaceGetTreasurePrice = async (
landId: LandId,
provider: ethers.providers.Provider,
callback?: CallbackType
): Promise<furnaceGetTreasurePriceResponse> => {
const results = await viewContractByContractName(landId, provider, "furnaceTreasure", "getPrice", [], callback);
return {
priceGoldBox: results.priceGoldBox.toHexString(),
priceSilverBox: results.priceSilverBox.toHexString(),
};
};
/**
* Buy treasure
* @param landId Land Id
* @param signer Signer
* @param to Recipient
* @param goldBoxAmount Gold box amount
* @param silverBoxAmount Silver box amount
* @param cost Max cost
* @param callback Callback
* @returns any
*/
export const furnaceBuyTreasure = (
landId: LandId,
signer: ethers.Signer,
to: string,
goldBoxAmount: string,
silverBoxAmount: string,
cost: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
if (landId === LandId.ETHEREUM || landId === LandId._ETHEREUM) {
const addresses = getAddressesByLandId(landId);
const goldBoxAmountHex = ethers.BigNumber.from(goldBoxAmount).toHexString();
const silverBoxAmountHex = ethers.BigNumber.from(silverBoxAmount).toHexString();
if (!addresses || !addresses.FURNACE_TREASURE) {
throw "address error";
}
return triggerContractByContractName(
landId,
signer,
"ring",
"transfer(address,uint256,bytes)",
[
addresses.FURNACE_TREASURE,
cost,
`${ethers.utils.hexZeroPad(goldBoxAmountHex, 32)}${ethers.utils.hexZeroPad(silverBoxAmountHex, 32).slice(2)}`,
],
callback
);
}
return triggerContractByContractName(
landId,
signer,
"furnaceTreasure",
"buyBox",
[to, goldBoxAmount, silverBoxAmount, cost],
callback
);
};
/**
* Use nft and elements or LP tokens in the furnace formula to the props.
* @param signer
* @param formulaIndex Formula for props - https://github.com/evolutionlandorg/furnace/blob/dev/src/Formula.sol
* @param majorTokenId ERC721 token Id
* @param minorTokenAddress Elements or LP tokens contract address
* @param callback callback
*/
export const furnaceEnchantProps = (
landId: LandId,
signer: ethers.Signer,
formulaIndex: number,
majorTokenId: string,
minorTokenAddress: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
return triggerContractByContractName(
landId,
signer,
"furnaceItemBase",
"enchant",
[formulaIndex, pad0xBegin(majorTokenId), minorTokenAddress],
callback
);
};
/**
* Disenchant furnace props, and will get elements or LP and nft
* @param signer
* @param propsTokenId Token Id of the Props
* @param depth Supports one-time decomposition of high-level props. If a prop is in the second level, it needs to be restored to its original state, and the depth needs to be passed in 2
* @param callback
*/
export const furnaceDisenchantProps = (
landId: LandId,
signer: ethers.Signer,
propsTokenId: string,
depth: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
return triggerContractByContractName(
landId,
signer,
"furnaceItemBase",
"disenchant",
[pad0xBegin(propsTokenId), depth],
callback
);
};
/**
* Get treasure is opened
* @param landId Land Id
* @param provider Provider
* @param treasureTokenId Id of treasure
* @param callback Callback
* @returns any
*/
export const furnaceGetTreasureStatus = async (
landId: LandId,
provider: ethers.providers.Provider,
treasureTokenId: string,
callback?: CallbackType
): Promise<boolean> => {
const results = await viewContractByContractName(
landId,
provider,
"furnaceTakeback",
"ids",
[pad0xBegin(treasureTokenId)],
callback
);
return results[0];
};
/**
* Open furnace treasure
* @param landId Land Id
* @param signer Signer
* @param param2 Signature content
* @param callback Callback
* @returns any
*/
export const furnaceOpenTreasure = (
landId: LandId,
signer: ethers.Signer,
{
boxIds,
amounts,
hashmessage,
v,
r,
s,
}: {
boxIds: string[];
amounts: string[];
hashmessage: string;
v: number;
r: string;
s: string;
},
callback?: CallbackType
): Promise<TransactionResponse> => {
const silverBoxGasLimit = ethers.BigNumber.from(350000);
const goldBoxGasLimit = ethers.BigNumber.from(400000);
let gasLimit = ethers.BigNumber.from(amounts[0]).lt("1000000000000000000000") ? silverBoxGasLimit : goldBoxGasLimit;
if (amounts.length > 1) {
for (let index = 1; index < amounts.length; index++) {
const amount = amounts[index];
gasLimit = gasLimit.add(
ethers.BigNumber.from(amount).lt("1000000000000000000000") ? silverBoxGasLimit : silverBoxGasLimit
);
}
}
const processedBoxIds = boxIds.map((id) => {
return pad0xBegin(id);
});
return triggerContractByContractName(
landId,
signer,
"furnaceTakeback",
"openBoxes",
[processedBoxIds, amounts, hashmessage, v, r, s],
callback,
{
gasLimit: gasLimit,
}
);
};
/**
* Disenchant Equipment and will get elements and material
* @param landId Land Id
* @param signer Signer
* @param equipmentTokenId Id of Equipment
* @param callback Callback
* @returns any
*/
export const furnaceDismantleEquipment = (
landId: LandId,
signer: ethers.Signer,
equipmentTokenId: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
return triggerContractByContractName(
landId,
signer,
"pveCraft",
"disenchant",
[pad0xBegin(equipmentTokenId)],
callback
);
};
/**
* Use material and elements tokens in the furnace formula to the equipment.
* @param landId Land Id
* @param signer Signer
* @param equipmentTokenId Id of Equipment
* @param tokenContractAddress Element token address
* @param callback Callback
* @returns any
*/
export const furnaceEnchantEquipment = (
landId: LandId,
signer: ethers.Signer,
equipmentTokenId: string,
tokenContractAddress: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
return triggerContractByContractName(
landId,
signer,
"pveCraft",
"enchant",
[pad0xBegin(equipmentTokenId), tokenContractAddress],
callback
);
};