// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
//   protoc-gen-ts_proto  v2.3.0
//   protoc               unknown
// source: tendermint/types/params.proto

/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
import { Duration } from "../../google/protobuf/duration.js";

/**
 * ConsensusParams contains consensus critical parameters that determine the
 * validity of blocks.
 */
export interface ConsensusParams {
  block: BlockParams | undefined;
  evidence: EvidenceParams | undefined;
  validator: ValidatorParams | undefined;
  version: VersionParams | undefined;
  abci: ABCIParams | undefined;
}

/** BlockParams contains limits on the block size. */
export interface BlockParams {
  /**
   * Max block size, in bytes.
   * Note: must be greater than 0
   */
  maxBytes: bigint;
  /**
   * Max gas per block.
   * Note: must be greater or equal to -1
   */
  maxGas: bigint;
}

/** EvidenceParams determine how we handle evidence of malfeasance. */
export interface EvidenceParams {
  /**
   * Max age of evidence, in blocks.
   *
   * The basic formula for calculating this is: MaxAgeDuration / {average block
   * time}.
   */
  maxAgeNumBlocks: bigint;
  /**
   * Max age of evidence, in time.
   *
   * It should correspond with an app's "unbonding period" or other similar
   * mechanism for handling [Nothing-At-Stake
   * attacks](https://github.com/ethereum/wiki/wiki/Proof-of-Stake-FAQ#what-is-the-nothing-at-stake-problem-and-how-can-it-be-fixed).
   */
  maxAgeDuration:
    | Duration
    | undefined;
  /**
   * This sets the maximum size of total evidence in bytes that can be committed in a single block.
   * and should fall comfortably under the max block bytes.
   * Default is 1048576 or 1MB
   */
  maxBytes: bigint;
}

/**
 * ValidatorParams restrict the public key types validators can use.
 * NOTE: uses ABCI pubkey naming, not Amino names.
 */
export interface ValidatorParams {
  pubKeyTypes: string[];
}

/** VersionParams contains the ABCI application version. */
export interface VersionParams {
  app: bigint;
}

/**
 * HashedParams is a subset of ConsensusParams.
 *
 * It is hashed into the Header.ConsensusHash.
 */
export interface HashedParams {
  blockMaxBytes: bigint;
  blockMaxGas: bigint;
}

/** ABCIParams configure functionality specific to the Application Blockchain Interface. */
export interface ABCIParams {
  /**
   * vote_extensions_enable_height configures the first height during which
   * vote extensions will be enabled. During this specified height, and for all
   * subsequent heights, precommit messages that do not contain valid extension data
   * will be considered invalid. Prior to this height, vote extensions will not
   * be used or accepted by validators on the network.
   *
   * Once enabled, vote extensions will be created by the application in ExtendVote,
   * passed to the application for validation in VerifyVoteExtension and given
   * to the application to use when proposing a block during PrepareProposal.
   */
  voteExtensionsEnableHeight: bigint;
}

function createBaseConsensusParams(): ConsensusParams {
  return { block: undefined, evidence: undefined, validator: undefined, version: undefined, abci: undefined };
}

export const ConsensusParams: MessageFns<ConsensusParams> = {
  encode(message: ConsensusParams, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    if (message.block !== undefined) {
      BlockParams.encode(message.block, writer.uint32(10).fork()).join();
    }
    if (message.evidence !== undefined) {
      EvidenceParams.encode(message.evidence, writer.uint32(18).fork()).join();
    }
    if (message.validator !== undefined) {
      ValidatorParams.encode(message.validator, writer.uint32(26).fork()).join();
    }
    if (message.version !== undefined) {
      VersionParams.encode(message.version, writer.uint32(34).fork()).join();
    }
    if (message.abci !== undefined) {
      ABCIParams.encode(message.abci, writer.uint32(42).fork()).join();
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): ConsensusParams {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseConsensusParams();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 10) {
            break;
          }

          message.block = BlockParams.decode(reader, reader.uint32());
          continue;
        }
        case 2: {
          if (tag !== 18) {
            break;
          }

          message.evidence = EvidenceParams.decode(reader, reader.uint32());
          continue;
        }
        case 3: {
          if (tag !== 26) {
            break;
          }

          message.validator = ValidatorParams.decode(reader, reader.uint32());
          continue;
        }
        case 4: {
          if (tag !== 34) {
            break;
          }

          message.version = VersionParams.decode(reader, reader.uint32());
          continue;
        }
        case 5: {
          if (tag !== 42) {
            break;
          }

          message.abci = ABCIParams.decode(reader, reader.uint32());
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): ConsensusParams {
    return {
      block: isSet(object.block) ? BlockParams.fromJSON(object.block) : undefined,
      evidence: isSet(object.evidence) ? EvidenceParams.fromJSON(object.evidence) : undefined,
      validator: isSet(object.validator) ? ValidatorParams.fromJSON(object.validator) : undefined,
      version: isSet(object.version) ? VersionParams.fromJSON(object.version) : undefined,
      abci: isSet(object.abci) ? ABCIParams.fromJSON(object.abci) : undefined,
    };
  },

  toJSON(message: ConsensusParams): unknown {
    const obj: any = {};
    if (message.block !== undefined) {
      obj.block = BlockParams.toJSON(message.block);
    }
    if (message.evidence !== undefined) {
      obj.evidence = EvidenceParams.toJSON(message.evidence);
    }
    if (message.validator !== undefined) {
      obj.validator = ValidatorParams.toJSON(message.validator);
    }
    if (message.version !== undefined) {
      obj.version = VersionParams.toJSON(message.version);
    }
    if (message.abci !== undefined) {
      obj.abci = ABCIParams.toJSON(message.abci);
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<ConsensusParams>, I>>(base?: I): ConsensusParams {
    return ConsensusParams.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<ConsensusParams>, I>>(object: I): ConsensusParams {
    const message = createBaseConsensusParams();
    message.block = (object.block !== undefined && object.block !== null)
      ? BlockParams.fromPartial(object.block)
      : undefined;
    message.evidence = (object.evidence !== undefined && object.evidence !== null)
      ? EvidenceParams.fromPartial(object.evidence)
      : undefined;
    message.validator = (object.validator !== undefined && object.validator !== null)
      ? ValidatorParams.fromPartial(object.validator)
      : undefined;
    message.version = (object.version !== undefined && object.version !== null)
      ? VersionParams.fromPartial(object.version)
      : undefined;
    message.abci = (object.abci !== undefined && object.abci !== null)
      ? ABCIParams.fromPartial(object.abci)
      : undefined;
    return message;
  },
};

function createBaseBlockParams(): BlockParams {
  return { maxBytes: 0n, maxGas: 0n };
}

export const BlockParams: MessageFns<BlockParams> = {
  encode(message: BlockParams, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    if (message.maxBytes !== 0n) {
      if (BigInt.asIntN(64, message.maxBytes) !== message.maxBytes) {
        throw new globalThis.Error("value provided for field message.maxBytes of type int64 too large");
      }
      writer.uint32(8).int64(message.maxBytes);
    }
    if (message.maxGas !== 0n) {
      if (BigInt.asIntN(64, message.maxGas) !== message.maxGas) {
        throw new globalThis.Error("value provided for field message.maxGas of type int64 too large");
      }
      writer.uint32(16).int64(message.maxGas);
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): BlockParams {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseBlockParams();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 8) {
            break;
          }

          message.maxBytes = reader.int64() as bigint;
          continue;
        }
        case 2: {
          if (tag !== 16) {
            break;
          }

          message.maxGas = reader.int64() as bigint;
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): BlockParams {
    return {
      maxBytes: isSet(object.maxBytes) ? BigInt(object.maxBytes) : 0n,
      maxGas: isSet(object.maxGas) ? BigInt(object.maxGas) : 0n,
    };
  },

  toJSON(message: BlockParams): unknown {
    const obj: any = {};
    if (message.maxBytes !== 0n) {
      obj.maxBytes = message.maxBytes.toString();
    }
    if (message.maxGas !== 0n) {
      obj.maxGas = message.maxGas.toString();
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<BlockParams>, I>>(base?: I): BlockParams {
    return BlockParams.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<BlockParams>, I>>(object: I): BlockParams {
    const message = createBaseBlockParams();
    message.maxBytes = object.maxBytes ?? 0n;
    message.maxGas = object.maxGas ?? 0n;
    return message;
  },
};

function createBaseEvidenceParams(): EvidenceParams {
  return { maxAgeNumBlocks: 0n, maxAgeDuration: undefined, maxBytes: 0n };
}

export const EvidenceParams: MessageFns<EvidenceParams> = {
  encode(message: EvidenceParams, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    if (message.maxAgeNumBlocks !== 0n) {
      if (BigInt.asIntN(64, message.maxAgeNumBlocks) !== message.maxAgeNumBlocks) {
        throw new globalThis.Error("value provided for field message.maxAgeNumBlocks of type int64 too large");
      }
      writer.uint32(8).int64(message.maxAgeNumBlocks);
    }
    if (message.maxAgeDuration !== undefined) {
      Duration.encode(message.maxAgeDuration, writer.uint32(18).fork()).join();
    }
    if (message.maxBytes !== 0n) {
      if (BigInt.asIntN(64, message.maxBytes) !== message.maxBytes) {
        throw new globalThis.Error("value provided for field message.maxBytes of type int64 too large");
      }
      writer.uint32(24).int64(message.maxBytes);
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): EvidenceParams {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseEvidenceParams();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 8) {
            break;
          }

          message.maxAgeNumBlocks = reader.int64() as bigint;
          continue;
        }
        case 2: {
          if (tag !== 18) {
            break;
          }

          message.maxAgeDuration = Duration.decode(reader, reader.uint32());
          continue;
        }
        case 3: {
          if (tag !== 24) {
            break;
          }

          message.maxBytes = reader.int64() as bigint;
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): EvidenceParams {
    return {
      maxAgeNumBlocks: isSet(object.maxAgeNumBlocks) ? BigInt(object.maxAgeNumBlocks) : 0n,
      maxAgeDuration: isSet(object.maxAgeDuration) ? Duration.fromJSON(object.maxAgeDuration) : undefined,
      maxBytes: isSet(object.maxBytes) ? BigInt(object.maxBytes) : 0n,
    };
  },

  toJSON(message: EvidenceParams): unknown {
    const obj: any = {};
    if (message.maxAgeNumBlocks !== 0n) {
      obj.maxAgeNumBlocks = message.maxAgeNumBlocks.toString();
    }
    if (message.maxAgeDuration !== undefined) {
      obj.maxAgeDuration = Duration.toJSON(message.maxAgeDuration);
    }
    if (message.maxBytes !== 0n) {
      obj.maxBytes = message.maxBytes.toString();
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<EvidenceParams>, I>>(base?: I): EvidenceParams {
    return EvidenceParams.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<EvidenceParams>, I>>(object: I): EvidenceParams {
    const message = createBaseEvidenceParams();
    message.maxAgeNumBlocks = object.maxAgeNumBlocks ?? 0n;
    message.maxAgeDuration = (object.maxAgeDuration !== undefined && object.maxAgeDuration !== null)
      ? Duration.fromPartial(object.maxAgeDuration)
      : undefined;
    message.maxBytes = object.maxBytes ?? 0n;
    return message;
  },
};

function createBaseValidatorParams(): ValidatorParams {
  return { pubKeyTypes: [] };
}

export const ValidatorParams: MessageFns<ValidatorParams> = {
  encode(message: ValidatorParams, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    for (const v of message.pubKeyTypes) {
      writer.uint32(10).string(v!);
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): ValidatorParams {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseValidatorParams();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 10) {
            break;
          }

          message.pubKeyTypes.push(reader.string());
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): ValidatorParams {
    return {
      pubKeyTypes: globalThis.Array.isArray(object?.pubKeyTypes)
        ? object.pubKeyTypes.map((e: any) => globalThis.String(e))
        : [],
    };
  },

  toJSON(message: ValidatorParams): unknown {
    const obj: any = {};
    if (message.pubKeyTypes?.length) {
      obj.pubKeyTypes = message.pubKeyTypes;
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<ValidatorParams>, I>>(base?: I): ValidatorParams {
    return ValidatorParams.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<ValidatorParams>, I>>(object: I): ValidatorParams {
    const message = createBaseValidatorParams();
    message.pubKeyTypes = object.pubKeyTypes?.map((e) => e) || [];
    return message;
  },
};

function createBaseVersionParams(): VersionParams {
  return { app: 0n };
}

export const VersionParams: MessageFns<VersionParams> = {
  encode(message: VersionParams, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    if (message.app !== 0n) {
      if (BigInt.asUintN(64, message.app) !== message.app) {
        throw new globalThis.Error("value provided for field message.app of type uint64 too large");
      }
      writer.uint32(8).uint64(message.app);
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): VersionParams {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseVersionParams();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 8) {
            break;
          }

          message.app = reader.uint64() as bigint;
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): VersionParams {
    return { app: isSet(object.app) ? BigInt(object.app) : 0n };
  },

  toJSON(message: VersionParams): unknown {
    const obj: any = {};
    if (message.app !== 0n) {
      obj.app = message.app.toString();
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<VersionParams>, I>>(base?: I): VersionParams {
    return VersionParams.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<VersionParams>, I>>(object: I): VersionParams {
    const message = createBaseVersionParams();
    message.app = object.app ?? 0n;
    return message;
  },
};

function createBaseHashedParams(): HashedParams {
  return { blockMaxBytes: 0n, blockMaxGas: 0n };
}

export const HashedParams: MessageFns<HashedParams> = {
  encode(message: HashedParams, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    if (message.blockMaxBytes !== 0n) {
      if (BigInt.asIntN(64, message.blockMaxBytes) !== message.blockMaxBytes) {
        throw new globalThis.Error("value provided for field message.blockMaxBytes of type int64 too large");
      }
      writer.uint32(8).int64(message.blockMaxBytes);
    }
    if (message.blockMaxGas !== 0n) {
      if (BigInt.asIntN(64, message.blockMaxGas) !== message.blockMaxGas) {
        throw new globalThis.Error("value provided for field message.blockMaxGas of type int64 too large");
      }
      writer.uint32(16).int64(message.blockMaxGas);
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): HashedParams {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseHashedParams();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 8) {
            break;
          }

          message.blockMaxBytes = reader.int64() as bigint;
          continue;
        }
        case 2: {
          if (tag !== 16) {
            break;
          }

          message.blockMaxGas = reader.int64() as bigint;
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): HashedParams {
    return {
      blockMaxBytes: isSet(object.blockMaxBytes) ? BigInt(object.blockMaxBytes) : 0n,
      blockMaxGas: isSet(object.blockMaxGas) ? BigInt(object.blockMaxGas) : 0n,
    };
  },

  toJSON(message: HashedParams): unknown {
    const obj: any = {};
    if (message.blockMaxBytes !== 0n) {
      obj.blockMaxBytes = message.blockMaxBytes.toString();
    }
    if (message.blockMaxGas !== 0n) {
      obj.blockMaxGas = message.blockMaxGas.toString();
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<HashedParams>, I>>(base?: I): HashedParams {
    return HashedParams.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<HashedParams>, I>>(object: I): HashedParams {
    const message = createBaseHashedParams();
    message.blockMaxBytes = object.blockMaxBytes ?? 0n;
    message.blockMaxGas = object.blockMaxGas ?? 0n;
    return message;
  },
};

function createBaseABCIParams(): ABCIParams {
  return { voteExtensionsEnableHeight: 0n };
}

export const ABCIParams: MessageFns<ABCIParams> = {
  encode(message: ABCIParams, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    if (message.voteExtensionsEnableHeight !== 0n) {
      if (BigInt.asIntN(64, message.voteExtensionsEnableHeight) !== message.voteExtensionsEnableHeight) {
        throw new globalThis.Error(
          "value provided for field message.voteExtensionsEnableHeight of type int64 too large",
        );
      }
      writer.uint32(8).int64(message.voteExtensionsEnableHeight);
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): ABCIParams {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseABCIParams();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 8) {
            break;
          }

          message.voteExtensionsEnableHeight = reader.int64() as bigint;
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): ABCIParams {
    return {
      voteExtensionsEnableHeight: isSet(object.voteExtensionsEnableHeight)
        ? BigInt(object.voteExtensionsEnableHeight)
        : 0n,
    };
  },

  toJSON(message: ABCIParams): unknown {
    const obj: any = {};
    if (message.voteExtensionsEnableHeight !== 0n) {
      obj.voteExtensionsEnableHeight = message.voteExtensionsEnableHeight.toString();
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<ABCIParams>, I>>(base?: I): ABCIParams {
    return ABCIParams.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<ABCIParams>, I>>(object: I): ABCIParams {
    const message = createBaseABCIParams();
    message.voteExtensionsEnableHeight = object.voteExtensionsEnableHeight ?? 0n;
    return message;
  },
};

type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;

type DeepPartial<T> = T extends Builtin ? T
  : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
  : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
  : T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
  : Partial<T>;

type KeysOfUnion<T> = T extends T ? keyof T : never;
type Exact<P, I extends P> = P extends Builtin ? P
  : P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };

function isSet(value: any): boolean {
  return value !== null && value !== undefined;
}

interface MessageFns<T> {
  encode(message: T, writer?: BinaryWriter): BinaryWriter;
  decode(input: BinaryReader | Uint8Array, length?: number): T;
  fromJSON(object: any): T;
  toJSON(message: T): unknown;
  create<I extends Exact<DeepPartial<T>, I>>(base?: I): T;
  fromPartial<I extends Exact<DeepPartial<T>, I>>(object: I): T;
}
