# pve/v1.ts

    import { ethers } from "ethers";
    import { pad0xBegin } from "@evo/utils/common/utils";
    import type { CallbackType } from "@evo/utils/ethers/contractHelper";
    import { triggerContractByContractName, viewContractByContractName } from "@evo/utils/ethers/contractHelper";
    import { LandId } from "@evo/config/constants";
    import { TransactionResponse } from "@ethersproject/providers";

    export type SlotType = 0 | 1 | 2 | 3; // there're 4 members a team for now

    /**
     * PVE Team Join
     * @param signer Ethers signer
     * @param slot Slot
     * @param tokenId Apostle token id
     * @param callback Callback
     */
    export const pveTeamJoin = (
      landId: LandId,
      signer: ethers.Signer,
      slot: SlotType,
      tokenId: string,
      callback?: CallbackType
    ): Promise<TransactionResponse> => {
      return triggerContractByContractName(landId, signer, "pveTeam", "join", [slot, pad0xBegin(tokenId)], callback);
    };

    /**
     * PVE Team Joins
     * @param signer Ethers signer
     * @param slots Slot
     * @param tokenIds Apostles token id
     * @param callback Callback
     */
    export const pveTeamJoins = (
      landId: LandId,
      signer: ethers.Signer,
      slots: SlotType[],
      tokenIds: string[],
      callback?: CallbackType
    ): Promise<TransactionResponse> => {
      return triggerContractByContractName(
        landId,
        signer,
        "pveTeam",
        "joins",
        [slots, tokenIds.map((tokenId) => pad0xBegin(tokenId))],
        callback
      );
    };

    /**
     * PVE Team Exit
     * @param signer Ethers signer
     * @param tokenId Apostle token id
     * @param callback Callback
     */
    export const pveTeamExit = (
      landId: LandId,
      signer: ethers.Signer,
      tokenId: string,
      callback?: CallbackType
    ): Promise<TransactionResponse> => {
      return triggerContractByContractName(landId, signer, "pveTeam", "exit", [pad0xBegin(tokenId)], callback);
    };

    /**
     * PVE Team Exits
     * @param signer Ethers signer
     * @param tokenIds Apostles token id
     * @param callback Callback
     */
    export const pveTeamExits = (
      landId: LandId,
      signer: ethers.Signer,
      tokenIds: string[],
      callback?: CallbackType
    ): Promise<TransactionResponse> => {
      return triggerContractByContractName(
        landId,
        signer,
        "pveTeam",
        "exits",
        [tokenIds.map((tokenId) => pad0xBegin(tokenId))],
        callback
      );
    };

    /**
     * PVE Team Swap
     * @param signer Ethers signer
     * @param slot Slot
     * @param newTokenId Apostle token id
     * @param callback Callback
     */
    export const pveTeamSwap = (
      landId: LandId,
      signer: ethers.Signer,
      slot: SlotType,
      newTokenId: string,
      callback?: CallbackType
    ): Promise<TransactionResponse> => {
      return triggerContractByContractName(landId, signer, "pveTeam", "swap", [slot, pad0xBegin(newTokenId)], callback);
    };

    /**
     * PVE Team Evict (Force exit after the end of the lease period)
     * @param signer Ethers signer
     * @param tokenId Apostle token id
     * @param callback Callback
     */
    export const pveTeamEvict = (
      landId: LandId,
      signer: ethers.Signer,
      tokenId: string,
      callback?: CallbackType
    ): Promise<TransactionResponse> => {
      return triggerContractByContractName(landId, signer, "pveTeam", "evict", [pad0xBegin(tokenId)], callback);
    };

    /**
     * PVE Team At
     * @param provider Ethers provider
     * @param user Account address
     * @param slot Slot
     * @param callback Callback
     * @returns Apostle token id or hex 0
     */
    export const pveTeamAt = async (
      landId: LandId,
      provider: ethers.providers.Provider,
      user: string,
      slot: SlotType,
      callback?: CallbackType
    ): Promise<string> => {
      const results = await viewContractByContractName(landId, provider, "pveTeam", "at", [user, slot], callback);
      return (results[0] as ethers.BigNumber).toHexString();
    };

    /**
     * PVE Team Exist
     * @param provider Ethers provider
     * @param user Account address
     * @param slot Slot
     * @param callback Callback
     * @returns Boolean true or false
     */
    export const pveTeamExist = async (
      landId: LandId,
      provider: ethers.providers.Provider,
      user: string,
      slot: SlotType,
      callback?: CallbackType
    ): Promise<boolean> => {
      const results = await viewContractByContractName(landId, provider, "pveTeam", "exist", [user, slot], callback);
      return results[0] as boolean;
    };

    export const pveForgeBatch = (
      landId: LandId,
      signer: ethers.Signer,
      equipmentTypeList: number[],
      rarityList: number[],
      tokenContractAddressList: string[],
      callback?: CallbackType
    ): Promise<TransactionResponse> => {
      return triggerContractByContractName(
        landId,
        signer,
        "pveCraft",
        "craft_batch",
        [equipmentTypeList, rarityList, tokenContractAddressList],
        callback,
        {
          gasLimit: ethers.BigNumber.from(210000).mul(equipmentTypeList.length).add(ethers.BigNumber.from(350000)),
        }
      );
    };