import { ethers } from "ethers";
import { erc20Allowance } from "@evo/api/ethers/erc20";
import { pad0xBegin } from "@evo/utils/common/utils";
import { toHexAndPadLeft, padLeft } from "@evo/utils/ethers/utils";
import {
getContractAddressAndAbiByContractName,
triggerContractByContractName,
viewContractByContractName,
} from "@evo/utils/ethers/contractHelper";
import type { ElementType } from "@evo/types";
import type { CallbackType } from "@evo/utils/ethers/contractHelper";
import { LandId } from "@evo/config/constants";
import { TransactionResponse } from "@ethersproject/providers";
import { getAddressesByLandId } from "@evo/utils/ethers/addressHelper";
/**
* Apostle Allowance To Clock Auction
* @param provider Ethers provider
* @param from From
* @param callback Callback
* @returns Promise<string | undefined>
*/
export const apostleAllowanceToClockAuction = async (
landId: LandId,
provider: ethers.providers.Provider,
from: string,
callback?: CallbackType
): Promise<string | undefined> => {
const spender = getContractAddressAndAbiByContractName(landId, provider, "apostleAuction").address;
if (spender) {
return erc20Allowance(landId, provider, "ring", from, spender as string);
} else {
callback &&
callback.errorCallback({ error: new Error("failed to call apostleAllowanceToClockAuction. spender undefined") });
}
};
/**
* Apostle Bid
* @param signer Ethers signer
* @param tokenId Apostle token id
* @param referrer Refer address
* @param amountMax RING Amount
* @param callback Callback
*/
export const apostleBidWithToken = (
landId: LandId,
signer: ethers.Signer,
tokenId: string,
referrer: string,
amountMax: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
const finalReferrer =
referrer && ethers.utils.isAddress(referrer) ? referrer : "0x0000000000000000000000000000000000000000";
if (landId === LandId.ETHEREUM || landId === LandId._ETHEREUM) {
const data = referrer
? `${pad0xBegin(tokenId)}${ethers.utils.hexZeroPad(referrer, 32).slice(2)}`
: pad0xBegin(tokenId);
const addresses = getAddressesByLandId(landId);
if (!addresses || !addresses.APOSTLE_CLOCK_AUCTION) {
throw "address error";
}
return triggerContractByContractName(
landId,
signer,
"ring",
"transfer(address,uint256,bytes)",
[addresses.APOSTLE_CLOCK_AUCTION, amountMax, data],
callback
);
}
return triggerContractByContractName(
landId,
signer,
"apostleClockAuctionV3",
"bidWithToken",
[pad0xBegin(tokenId), finalReferrer, amountMax],
callback
);
};
/**
* Apostle Breed - Apostle reproduction in own
* @param signer Ethers signer
* @param tokenId Token id
* @param targetTokenId Target token id
* @param amountMax Amount max
* @param callback Callback
*/
export const apostleBreed = (
landId: LandId,
signer: ethers.Signer,
tokenId: string,
targetTokenId: string,
amountMax: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
if (landId === LandId.ETHEREUM || landId === LandId._ETHEREUM) {
const addresses = getAddressesByLandId(landId);
if (!addresses || !addresses.APOSTLE_BASE) {
throw "address error";
}
return triggerContractByContractName(
landId,
signer,
"ring",
"transfer(address,uint256,bytes)",
[
addresses.APOSTLE_BASE,
amountMax,
`${pad0xBegin(tokenId)}${ethers.utils.hexZeroPad(pad0xBegin(targetTokenId), 32).slice(2)}`,
],
callback
);
}
return triggerContractByContractName(
landId,
signer,
"apostleBaseV3",
"breedWithAuto",
[pad0xBegin(tokenId), pad0xBegin(targetTokenId), amountMax],
callback
);
};
/**
* Apostle Breed Bid - Apostle reproduction
* @param signer Ethers signer
* @param tokenId Token id
* @param targetTokenId Target token id
* @param amountMax Amount max (bidPrice + autoBirthFee)
* @param callback Callback
*/
export const apostleBreedBid = (
landId: LandId,
signer: ethers.Signer,
tokenId: string,
targetTokenId: string,
amountMax: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
if (landId === LandId.ETHEREUM || landId === LandId._ETHEREUM) {
const addresses = getAddressesByLandId(landId);
if (!addresses || !addresses.SIRING_CLOCK_AUCTION) {
throw "address error";
}
return triggerContractByContractName(
landId,
signer,
"ring",
"transfer(address,uint256,bytes)",
[
addresses.SIRING_CLOCK_AUCTION,
amountMax,
`${pad0xBegin(tokenId)}${ethers.utils.hexZeroPad(pad0xBegin(targetTokenId), 32).slice(2)}`,
],
callback
);
}
return triggerContractByContractName(
landId,
signer,
"apostleSiringAuctionV3",
"bidWithToken",
[pad0xBegin(tokenId), pad0xBegin(targetTokenId), amountMax],
callback
);
};
/**
* Apostle Hire Bid - Bid apostle on Renting
* @param signer Ethers signer
* @param tokenId Apostle token id
* @param amountMax Amount max (bid price)
* @param callback Callback
*/
export const apostleHireBid = (
landId: LandId,
signer: ethers.Signer,
tokenId: string,
amountMax: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
if (landId === LandId.ETHEREUM || landId === LandId._ETHEREUM) {
const addresses = getAddressesByLandId(landId);
if (!addresses || !addresses.TOKEN_USE) {
throw "address error";
}
return triggerContractByContractName(
landId,
signer,
"ring",
"transfer(address,uint256,bytes)",
[addresses.TOKEN_USE, amountMax, pad0xBegin(tokenId)],
callback
);
}
return triggerContractByContractName(
landId,
signer,
"apostleTokenUseV2",
"takeTokenUseOffer",
[pad0xBegin(tokenId), amountMax],
callback
);
};
/**
* Apostle Born Without Element
* @param signer Ethers signer
* @param motherTokenId Mother token id
* @param callback Callback
*/
export const apostleBorn = (
landId: LandId,
signer: ethers.Signer,
motherTokenId: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
return triggerContractByContractName(
landId,
signer,
"apostleBaseV3",
"giveBirth",
[pad0xBegin(motherTokenId), ethers.utils.hexZeroPad("0x", 20), 0, 0],
callback
);
};
/**
* Apostle Born And Enhance
* @param signer Ethers signer
* @param motherTokenId Mother token id
* @param element Element
* @param level Level
* @param levelUnitPrice Level unit price
* @param callback Callback
* @returns Void
*/
export const apostleBornAndEnhance = async (
landId: LandId,
signer: ethers.Signer,
motherTokenId: string,
element: ElementType,
level: number,
levelUnitPrice: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
const elementAddress = getContractAddressAndAbiByContractName(landId, signer, element).address;
const cost = ethers.BigNumber.from(level).mul(ethers.BigNumber.from(levelUnitPrice)).toString();
if (landId === LandId.ETHEREUM || landId === LandId._ETHEREUM) {
const addresses = getAddressesByLandId(landId);
if (!addresses || !addresses.APOSTLE_BASE) {
throw "address error";
}
return triggerContractByContractName(
landId,
signer,
element,
"transfer(address,uint256,bytes)",
[
addresses.APOSTLE_BASE,
cost,
`${pad0xBegin(motherTokenId)}${ethers.utils.hexZeroPad(ethers.utils.hexlify(level), 32).slice(2)}`,
],
callback
);
}
return triggerContractByContractName(
landId,
signer,
"apostleBaseV3",
"giveBirth",
[pad0xBegin(motherTokenId), elementAddress, level, cost],
callback
);
};
/**
* Returns the current price of an auction.
* @param provider Ethers signer
* @param tokenId Apostle Token Id
* @param callback Callback
* @returns any
*/
export const apostleGetCurrentPriceByTokenId = async (
landId: LandId,
provider: ethers.providers.Provider,
tokenId: string,
callback?: CallbackType
): Promise<string> => {
const results = await viewContractByContractName(
landId,
provider,
"apostleClockAuctionV3",
"getCurrentPriceInToken",
[pad0xBegin(tokenId)],
callback
);
return (results[0] as ethers.BigNumber).toHexString();
};
/**
* Returns the current siring price of an auction.
* @param provider Ethers signer
* @param tokenId Token Id
* @param callback Callback
* @returns any
*/
export const apostleGetCurrentSiringPriceByTokenId = async (
landId: LandId,
provider: ethers.providers.Provider,
tokenId: string,
callback?: CallbackType
): Promise<string> => {
const results = await viewContractByContractName(
landId,
provider,
"apostleSiringAuctionV3",
"getCurrentPriceInToken",
[pad0xBegin(tokenId)],
callback
);
return (results[0] as ethers.BigNumber).toHexString();
};
/**
* Sell Apostle asset
* @param signer Ethers signer
* @param from
* @param tokenId - Apostle tokenId
* @param start - start price
* @param end - end price
* @param duration - bid duration time in second
* @param callback Callback
* @returns {Promise<void>}
*/
export const apostleAskWithToken = async (
landId: LandId,
signer: ethers.Signer,
from: string,
tokenId: string,
startPrice: string,
endPrice: string,
duration: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
const _from = padLeft(from.slice(2), 64, "0");
const _start = toHexAndPadLeft(startPrice).slice(2);
const _end = toHexAndPadLeft(endPrice).slice(2);
const _duration = toHexAndPadLeft(duration).slice(2);
const data = `0x${_start}${_end}${_duration}${_from}`;
const apostleClockAuctionV3 = getContractAddressAndAbiByContractName(landId, signer, "apostleClockAuctionV3");
return triggerContractByContractName(
landId,
signer,
"objectOwnership",
"approveAndCall",
[apostleClockAuctionV3.address, pad0xBegin(tokenId), data],
callback
);
};
/**
* Cancel the auction by apostle token ID
* @param landId Land Id
* @param signer Signer
* @param tokenId apostle token Id
* @param callback Callback
* @returns any
*/
export const apostleCancelAskWithToken = (
landId: LandId,
signer: ethers.Signer,
tokenId: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
return triggerContractByContractName(
landId,
signer,
"apostleAuction",
"cancelAuction",
[pad0xBegin(tokenId)],
callback
);
};
/**
* Renting apostles to work
* @param landId Land Id
* @param signer Signer
* @param resourceAddress Resource contract address
* @param tokenId Apostle tokenId
* @param price Hire price
* @param duration Duration in second
* @param callback Callback
*/
export const apostleHire = async (
landId: LandId,
signer: ethers.Signer,
resourceAddress: string,
tokenId: string,
price: string,
duration: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
const _price = toHexAndPadLeft(price).slice(2);
const _duration = toHexAndPadLeft(duration).slice(2);
const _resourceAddress = padLeft(resourceAddress.slice(2), 64, "0");
const data = `0x${_duration}${_price}${_resourceAddress}`;
const apostleTokenUseV2Contract = getContractAddressAndAbiByContractName(landId, signer, "apostleTokenUseV2");
return triggerContractByContractName(
landId,
signer,
"objectOwnership",
"approveAndCall",
[apostleTokenUseV2Contract.address, pad0xBegin(tokenId), data],
callback
);
};
/**
* Cancel an apostle on Renting
* @param landId Land Id
* @param signer Signer
* @param tokenId Apostle tokenId
* @param callback Callback
* @returns any
*/
export const apostleCancelHire = (
landId: LandId,
signer: ethers.Signer,
tokenId: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
return triggerContractByContractName(
landId,
signer,
"apostleTokenUseV2",
"cancelTokenUseOffer",
[pad0xBegin(tokenId)],
callback
);
};
/**
* Let apostle go to work
* @param landId Land Id
* @param signer Signer
* @param apostleTokenId Apostle token Id
* @param landTokenId Land token Id
* @param elementContractAddress Element contract address
* @param callback Callback
* @returns any
*/
export const apostleWork = (
landId: LandId,
signer: ethers.Signer,
apostleTokenId: string,
landTokenId: string,
elementContractAddress: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
return triggerContractByContractName(
landId,
signer,
"apostleLandResource",
"startMining",
[pad0xBegin(apostleTokenId), pad0xBegin(landTokenId), elementContractAddress],
callback
);
};
/**
* Stop apostle mining
* @param landId Land Id
* @param signer Signer
* @param tokenId Apostle tokenId
* @param callback Callback
* @returns any
*/
export const apostleStopWork = async (
landId: LandId,
signer: ethers.Signer,
tokenId: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
return triggerContractByContractName(
landId,
signer,
"apostleLandResource",
"stopMining",
[pad0xBegin(tokenId)],
callback
);
};
/**
* Get apostle breed fee
* @param landId Land Id
* @param provider Provider
* @param callback Callback
* @returns fee in string
*/
export const apostleGetAutoBreedFee = async (
landId: LandId,
provider: ethers.providers.Provider,
callback?: CallbackType
): Promise<string> => {
const results = await viewContractByContractName(
landId,
provider,
"settingsRegistry",
"uintOf",
["0x55494e545f4155544f42495254485f4645450000000000000000000000000000"], // UINT_AUTOBIRTH_FEE
callback
);
return (results[0] as ethers.BigNumber).toHexString();
};
/**
* Receive apostle
* @param landId Land Id
* @param signer Singer
* @param tokenId Apostle tokenId
* @param callback Callback
* @returns any
*/
export const apostleClaim = async (
landId: LandId,
signer: ethers.Signer,
tokenId: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
return triggerContractByContractName(
landId,
signer,
"apostleAuction",
"claimApostleAsset",
[pad0xBegin(tokenId)],
callback
);
};
/**
* Apostle Breed Auction
* @param landId Land Id
* @param signer Signer
* @param from
* @param tokenId Apostle tokenId
* @param startPrice Start price
* @param endPrice End price
* @param duration Auction duration time in second
* @param callback Callback
* @returns any
*/
export const apostleBreedAsk = async (
landId: LandId,
signer: ethers.Signer,
from: string,
tokenId: string,
startPrice: string,
endPrice: string,
duration: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
const _from = padLeft(from.slice(2), 64, "0");
const _start = toHexAndPadLeft(startPrice).slice(2);
const _end = toHexAndPadLeft(endPrice).slice(2);
const _duration = toHexAndPadLeft(duration).slice(2);
const data = `0x${_start}${_end}${_duration}${_from}`;
const apostleSiringAuctionV3Contract = getContractAddressAndAbiByContractName(
landId,
signer,
"apostleSiringAuctionV3"
);
return triggerContractByContractName(
landId,
signer,
"objectOwnership",
"approveAndCall",
[apostleSiringAuctionV3Contract.address, pad0xBegin(tokenId), data],
callback
);
};
/**
* Cancel Apostle Breed Auction
* @param landId Land Id
* @param signer Signer
* @param tokenId Apostle tokenId
* @param callback Callback
* @returns any
*/
export const apostleCancelBreedAsk = async (
landId: LandId,
signer: ethers.Signer,
tokenId: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
return triggerContractByContractName(
landId,
signer,
"apostleSiringAuctionV3",
"cancelAuction",
[pad0xBegin(tokenId)],
callback
);
};
/**
* Transfer Apsotle
* @param landId Land Id
* @param signer Signer
* @param from Apostle owner
* @param to Recipient
* @param tokenId Apostle tokenId
* @param callback Callback
* @returns any
*/
export const apostleTransfer = async (
landId: LandId,
signer: ethers.Signer,
from: string,
to: string,
tokenId: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
return triggerContractByContractName(
landId,
signer,
"objectOwnership",
"transferFrom",
[from, to, pad0xBegin(tokenId)],
callback
);
};
/**
* Claim an apostle that expires at work
* @param landId Land Id
* @param signer Signer
* @param tokenId Apostle tokenId
* @param callback Callback
* @returns any
*/
export const apostleClaimHire = async (
landId: LandId,
signer: ethers.Signer,
tokenId: string,
callback?: CallbackType
): Promise<TransactionResponse> => {
return triggerContractByContractName(
landId,
signer,
"apostleTokenUseV2",
"removeTokenUseAndActivity",
[pad0xBegin(tokenId)],
callback
);
};