# goldrush/v1.ts

    import { ethers } from "ethers";
    import { pad0xBegin } from "@evo/utils/common/utils";
    import type { GoldrushEventInfoType } from "@evo/types";
    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";

    /**
     * Goldrush Join
     * @param signer Ethers signer
     * @param eventId The event id which to join
     * @param landTokenId The land token id which to join
     * @param amount The ring amount which to submit
     * @param subAddr The dvm address for receiving the new land
     * @param callback Callback
     */
    export const goldRushRaffleJoin = (
      landId: LandId,
      signer: ethers.Signer,
      eventId: number,
      landTokenId: string,
      amount: string,
      subAddr: string,
      callback?: CallbackType
    ): Promise<TransactionResponse> => {
      return triggerContractByContractName(
        landId,
        signer,
        "goldRushRaffle",
        "join",
        [eventId, pad0xBegin(landTokenId), amount, subAddr],
        callback
      );
    };

    /**
     * Goldrush Change Amount
     * @param signer Ethers signer
     * @param eventId Event id
     * @param landTokenId Land token id
     * @param amount Amount (to change)
     * @param callback Callback
     */
    export const goldRushRaffleChangeAmount = (
      landId: LandId,
      signer: ethers.Signer,
      eventId: number,
      landTokenId: string,
      amount: string,
      callback?: CallbackType
    ): Promise<TransactionResponse> => {
      return triggerContractByContractName(
        landId,
        signer,
        "goldRushRaffle",
        "changeAmount",
        [eventId, pad0xBegin(landTokenId), amount],
        callback
      );
    };

    /**
     * Goldrush Change Subaddress
     * @param signer Ethers signer
     * @param eventId Event id
     * @param landTokenId Land token id
     * @param subAddr Sub address (to change)
     * @param callback Callback
     */
    export const goldRushRaffleChangeSubAddr = (
      landId: LandId,
      signer: ethers.Signer,
      eventId: number,
      landTokenId: string,
      subAddr: string,
      callback?: CallbackType
    ): Promise<TransactionResponse> => {
      return triggerContractByContractName(
        landId,
        signer,
        "goldRushRaffle",
        "changeSubAddr",
        [eventId, pad0xBegin(landTokenId), subAddr],
        callback
      );
    };

    /**
     * Goldrush Change Info
     * @param signer Ethers signer
     * @param eventId Event id
     * @param landTokenId Land token id
     * @param amount Amount (to change)
     * @param subAddr Sub address (to change)
     * @param callback Callback
     */
    export const goldRushRaffleChangeInfo = (
      landId: LandId,
      signer: ethers.Signer,
      eventId: number,
      landTokenId: string,
      amount: string,
      subAddr: string,
      callback?: CallbackType
    ): Promise<TransactionResponse> => {
      return triggerContractByContractName(
        landId,
        signer,
        "goldRushRaffle",
        "change",
        [eventId, pad0xBegin(landTokenId), amount, subAddr],
        callback
      );
    };

    /**
     * Goldrush Exit
     * @param signer Ethers signer
     * @param eventId Event id
     * @param landTokenId Land token id
     * @param callback Callback
     */
    export const goldRushRaffleExit = (
      landId: LandId,
      signer: ethers.Signer,
      eventId: number,
      landTokenId: string,
      callback?: CallbackType
    ): Promise<TransactionResponse> => {
      return triggerContractByContractName(
        landId,
        signer,
        "goldRushRaffle",
        "exit",
        [eventId, pad0xBegin(landTokenId)],
        callback
      );
    };

    /**
     * Goldrush Draw
     * @param signer Ethers signer
     * @param eventId Event id
     * @param landTokenId Land token id
     * @param isWon Is won or not
     * @param param4  hashmessage, v, r, s
     * @param callback Callback
     */
    export const goldRushRaffleDraw = (
      landId: LandId,
      signer: ethers.Signer,
      eventId: number,
      landTokenId: string,
      isWon: boolean,
      { hashmessage, v, r, s }: { hashmessage: string; v: number; r: string; s: string },
      callback?: CallbackType
    ): Promise<TransactionResponse> => {
      return triggerContractByContractName(
        landId,
        signer,
        "goldRushRaffle",
        "draw",
        [eventId, pad0xBegin(landTokenId), isWon, hashmessage, v, r, s],
        callback
      );
    };

    /**
     * Goldrush History
     * @param provider Ethers provider
     * @param eventId Event id
     * @param landTokenId Land token id
     * @param callback Callback
     * @returns String balance or '0'
     */
    export const goldRushRaffleGetHistory = async (
      landId: LandId,
      provider: ethers.providers.Provider,
      eventId: number,
      landTokenId: string,
      callback?: CallbackType
    ): Promise<string> => {
      const results = await viewContractByContractName(
        landId,
        provider,
        "goldRushRaffle",
        "lands",
        [eventId, pad0xBegin(landTokenId)],
        callback
      );
      return (results.balance as ethers.BigNumber).toString();
    };

    export const goldRushRaffleGetEvents = async (
      landId: LandId,
      provider: ethers.providers.Provider,
      callback?: CallbackType
    ): Promise<GoldrushEventInfoType[]> => {
      const eventsInfo: GoldrushEventInfoType[] = [];
      const fromLandRes = await viewContractByContractName(landId, provider, "goldRushRaffle", "fromLandId", [], callback);
      const fromLandId = fromLandRes.length ? (fromLandRes[0] as ethers.BigNumber).toNumber() : Number(0);

      // TODO: 'eventId < 10' is not a wise approach
      for (let eventId = 0; eventId < 10; eventId++) {
        const eventsRes = await viewContractByContractName(
          landId,
          provider,
          "goldRushRaffle",
          "events",
          [eventId],
          callback
        );
        const toLandId = (eventsRes.toLandId as ethers.BigNumber).toNumber();

        if (toLandId) {
          eventsInfo.push({
            eventId,
            fromLandId,
            toLandId,
            startTime: (eventsRes.startBlock as ethers.BigNumber).toNumber(),
            endTime: (eventsRes.endBlock as ethers.BigNumber).toNumber(),
            finalTime: (eventsRes.finalBlock as ethers.BigNumber).toNumber(),
            expireTime: (eventsRes.expireBlock as ethers.BigNumber).toNumber(),
          });
        }
      }

      return eventsInfo;
    };