/* eslint-disable @typescript-eslint/no-explicit-any */
/**
 * This file was generated by scripts/codegen.ts
 *
 * Original abi file:
 * - artifacts/contracts/InterchainTokenService.sol/InterchainTokenService.json
 *
 * DO NOT EDIT MANUALLY
 */

import { encodeFunctionData } from "viem";

import type { PublicContractClient } from "@axelarjs/evm";
import ABI_FILE from "./InterchainTokenService.abi";

export type InterchainTokenServiceAcceptOperatorshipArgs = {
  fromOperator: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.acceptOperatorship function args
 */
export const encodeInterchainTokenServiceAcceptOperatorshipArgs = ({
  fromOperator,
}: InterchainTokenServiceAcceptOperatorshipArgs) => [fromOperator] as const;

/**
 * Encoder function for InterchainTokenService.acceptOperatorship function data
 */
export const encodeInterchainTokenServiceAcceptOperatorshipData = ({
  fromOperator,
}: InterchainTokenServiceAcceptOperatorshipArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "acceptOperatorship",
    abi: ABI_FILE.abi,
    args: [fromOperator],
  });

export type InterchainTokenServiceContractCallValueArgs = {
  sourceChain: string;
  sourceAddress: string;
  payload: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.contractCallValue function args
 */
export const encodeInterchainTokenServiceContractCallValueArgs = ({
  sourceChain,
  sourceAddress,
  payload,
}: InterchainTokenServiceContractCallValueArgs) =>
  [sourceChain, sourceAddress, payload] as const;

/**
 * Encoder function for InterchainTokenService.contractCallValue function data
 */
export const encodeInterchainTokenServiceContractCallValueData = ({
  sourceChain,
  sourceAddress,
  payload,
}: InterchainTokenServiceContractCallValueArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "contractCallValue",
    abi: ABI_FILE.abi,
    args: [sourceChain, sourceAddress, payload],
  });

export type InterchainTokenServiceDeployInterchainTokenArgs = {
  salt: `0x${string}`;
  destinationChain: string;
  name: string;
  symbol: string;
  decimals: number;
  minter: `0x${string}`;
  gasValue: bigint;
};

/**
 * Factory function for InterchainTokenService.deployInterchainToken function args
 */
export const encodeInterchainTokenServiceDeployInterchainTokenArgs = ({
  salt,
  destinationChain,
  name,
  symbol,
  decimals,
  minter,
  gasValue,
}: InterchainTokenServiceDeployInterchainTokenArgs) =>
  [salt, destinationChain, name, symbol, decimals, minter, gasValue] as const;

/**
 * Encoder function for InterchainTokenService.deployInterchainToken function data
 */
export const encodeInterchainTokenServiceDeployInterchainTokenData = ({
  salt,
  destinationChain,
  name,
  symbol,
  decimals,
  minter,
  gasValue,
}: InterchainTokenServiceDeployInterchainTokenArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "deployInterchainToken",
    abi: ABI_FILE.abi,
    args: [salt, destinationChain, name, symbol, decimals, minter, gasValue],
  });

export type InterchainTokenServiceDeployedTokenManagerArgs = {
  tokenId: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.deployedTokenManager function args
 */
export const encodeInterchainTokenServiceDeployedTokenManagerArgs = ({
  tokenId,
}: InterchainTokenServiceDeployedTokenManagerArgs) => [tokenId] as const;

/**
 * Encoder function for InterchainTokenService.deployedTokenManager function data
 */
export const encodeInterchainTokenServiceDeployedTokenManagerData = ({
  tokenId,
}: InterchainTokenServiceDeployedTokenManagerArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "deployedTokenManager",
    abi: ABI_FILE.abi,
    args: [tokenId],
  });

export type InterchainTokenServiceExecuteArgs = {
  commandId: `0x${string}`;
  sourceChain: string;
  sourceAddress: string;
  payload: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.execute function args
 */
export const encodeInterchainTokenServiceExecuteArgs = ({
  commandId,
  sourceChain,
  sourceAddress,
  payload,
}: InterchainTokenServiceExecuteArgs) =>
  [commandId, sourceChain, sourceAddress, payload] as const;

/**
 * Encoder function for InterchainTokenService.execute function data
 */
export const encodeInterchainTokenServiceExecuteData = ({
  commandId,
  sourceChain,
  sourceAddress,
  payload,
}: InterchainTokenServiceExecuteArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "execute",
    abi: ABI_FILE.abi,
    args: [commandId, sourceChain, sourceAddress, payload],
  });

export type InterchainTokenServiceExpressExecuteArgs = {
  commandId: `0x${string}`;
  sourceChain: string;
  sourceAddress: string;
  payload: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.expressExecute function args
 */
export const encodeInterchainTokenServiceExpressExecuteArgs = ({
  commandId,
  sourceChain,
  sourceAddress,
  payload,
}: InterchainTokenServiceExpressExecuteArgs) =>
  [commandId, sourceChain, sourceAddress, payload] as const;

/**
 * Encoder function for InterchainTokenService.expressExecute function data
 */
export const encodeInterchainTokenServiceExpressExecuteData = ({
  commandId,
  sourceChain,
  sourceAddress,
  payload,
}: InterchainTokenServiceExpressExecuteArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "expressExecute",
    abi: ABI_FILE.abi,
    args: [commandId, sourceChain, sourceAddress, payload],
  });

export type InterchainTokenServiceGetExpressExecutorArgs = {
  commandId: `0x${string}`;
  sourceChain: string;
  sourceAddress: string;
  payloadHash: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.getExpressExecutor function args
 */
export const encodeInterchainTokenServiceGetExpressExecutorArgs = ({
  commandId,
  sourceChain,
  sourceAddress,
  payloadHash,
}: InterchainTokenServiceGetExpressExecutorArgs) =>
  [commandId, sourceChain, sourceAddress, payloadHash] as const;

/**
 * Encoder function for InterchainTokenService.getExpressExecutor function data
 */
export const encodeInterchainTokenServiceGetExpressExecutorData = ({
  commandId,
  sourceChain,
  sourceAddress,
  payloadHash,
}: InterchainTokenServiceGetExpressExecutorArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "getExpressExecutor",
    abi: ABI_FILE.abi,
    args: [commandId, sourceChain, sourceAddress, payloadHash],
  });

export type InterchainTokenServiceHasRoleArgs = {
  account: `0x${string}`;
  role: number;
};

/**
 * Factory function for InterchainTokenService.hasRole function args
 */
export const encodeInterchainTokenServiceHasRoleArgs = ({
  account,
  role,
}: InterchainTokenServiceHasRoleArgs) => [account, role] as const;

/**
 * Encoder function for InterchainTokenService.hasRole function data
 */
export const encodeInterchainTokenServiceHasRoleData = ({
  account,
  role,
}: InterchainTokenServiceHasRoleArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "hasRole",
    abi: ABI_FILE.abi,
    args: [account, role],
  });

export type InterchainTokenServiceInterchainTokenAddressArgs = {
  tokenId: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.interchainTokenAddress function args
 */
export const encodeInterchainTokenServiceInterchainTokenAddressArgs = ({
  tokenId,
}: InterchainTokenServiceInterchainTokenAddressArgs) => [tokenId] as const;

/**
 * Encoder function for InterchainTokenService.interchainTokenAddress function data
 */
export const encodeInterchainTokenServiceInterchainTokenAddressData = ({
  tokenId,
}: InterchainTokenServiceInterchainTokenAddressArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "interchainTokenAddress",
    abi: ABI_FILE.abi,
    args: [tokenId],
  });

export type InterchainTokenServiceInterchainTokenIdArgs = {
  sender: `0x${string}`;
  salt: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.interchainTokenId function args
 */
export const encodeInterchainTokenServiceInterchainTokenIdArgs = ({
  sender,
  salt,
}: InterchainTokenServiceInterchainTokenIdArgs) => [sender, salt] as const;

/**
 * Encoder function for InterchainTokenService.interchainTokenId function data
 */
export const encodeInterchainTokenServiceInterchainTokenIdData = ({
  sender,
  salt,
}: InterchainTokenServiceInterchainTokenIdArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "interchainTokenId",
    abi: ABI_FILE.abi,
    args: [sender, salt],
  });

export type InterchainTokenServiceInterchainTransferArgs = {
  tokenId: `0x${string}`;
  destinationChain: string;
  destinationAddress: `0x${string}`;
  amount: bigint;
  metadata: `0x${string}`;
  gasValue: bigint;
};

/**
 * Factory function for InterchainTokenService.interchainTransfer function args
 */
export const encodeInterchainTokenServiceInterchainTransferArgs = ({
  tokenId,
  destinationChain,
  destinationAddress,
  amount,
  metadata,
  gasValue,
}: InterchainTokenServiceInterchainTransferArgs) =>
  [
    tokenId,
    destinationChain,
    destinationAddress,
    amount,
    metadata,
    gasValue,
  ] as const;

/**
 * Encoder function for InterchainTokenService.interchainTransfer function data
 */
export const encodeInterchainTokenServiceInterchainTransferData = ({
  tokenId,
  destinationChain,
  destinationAddress,
  amount,
  metadata,
  gasValue,
}: InterchainTokenServiceInterchainTransferArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "interchainTransfer",
    abi: ABI_FILE.abi,
    args: [
      tokenId,
      destinationChain,
      destinationAddress,
      amount,
      metadata,
      gasValue,
    ],
  });

export type InterchainTokenServiceIsOperatorArgs = { addr: `0x${string}` };

/**
 * Factory function for InterchainTokenService.isOperator function args
 */
export const encodeInterchainTokenServiceIsOperatorArgs = ({
  addr,
}: InterchainTokenServiceIsOperatorArgs) => [addr] as const;

/**
 * Encoder function for InterchainTokenService.isOperator function data
 */
export const encodeInterchainTokenServiceIsOperatorData = ({
  addr,
}: InterchainTokenServiceIsOperatorArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "isOperator",
    abi: ABI_FILE.abi,
    args: [addr],
  });

export type InterchainTokenServiceIsTrustedAddressArgs = {
  chain: string;
  address_: string;
};

/**
 * Factory function for InterchainTokenService.isTrustedAddress function args
 */
export const encodeInterchainTokenServiceIsTrustedAddressArgs = ({
  chain,
  address_,
}: InterchainTokenServiceIsTrustedAddressArgs) => [chain, address_] as const;

/**
 * Encoder function for InterchainTokenService.isTrustedAddress function data
 */
export const encodeInterchainTokenServiceIsTrustedAddressData = ({
  chain,
  address_,
}: InterchainTokenServiceIsTrustedAddressArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "isTrustedAddress",
    abi: ABI_FILE.abi,
    args: [chain, address_],
  });

export type InterchainTokenServiceLinkTokenArgs = {
  salt: `0x${string}`;
  destinationChain: string;
  destinationTokenAddress: `0x${string}`;
  tokenManagerType: number;
  linkParams: `0x${string}`;
  gasValue: bigint;
};

/**
 * Factory function for InterchainTokenService.linkToken function args
 */
export const encodeInterchainTokenServiceLinkTokenArgs = ({
  salt,
  destinationChain,
  destinationTokenAddress,
  tokenManagerType,
  linkParams,
  gasValue,
}: InterchainTokenServiceLinkTokenArgs) =>
  [
    salt,
    destinationChain,
    destinationTokenAddress,
    tokenManagerType,
    linkParams,
    gasValue,
  ] as const;

/**
 * Encoder function for InterchainTokenService.linkToken function data
 */
export const encodeInterchainTokenServiceLinkTokenData = ({
  salt,
  destinationChain,
  destinationTokenAddress,
  tokenManagerType,
  linkParams,
  gasValue,
}: InterchainTokenServiceLinkTokenArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "linkToken",
    abi: ABI_FILE.abi,
    args: [
      salt,
      destinationChain,
      destinationTokenAddress,
      tokenManagerType,
      linkParams,
      gasValue,
    ],
  });

export type InterchainTokenServiceMigrateInterchainTokenArgs = {
  tokenId: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.migrateInterchainToken function args
 */
export const encodeInterchainTokenServiceMigrateInterchainTokenArgs = ({
  tokenId,
}: InterchainTokenServiceMigrateInterchainTokenArgs) => [tokenId] as const;

/**
 * Encoder function for InterchainTokenService.migrateInterchainToken function data
 */
export const encodeInterchainTokenServiceMigrateInterchainTokenData = ({
  tokenId,
}: InterchainTokenServiceMigrateInterchainTokenArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "migrateInterchainToken",
    abi: ABI_FILE.abi,
    args: [tokenId],
  });

export type InterchainTokenServiceMulticallArgs = { data: any };

/**
 * Factory function for InterchainTokenService.multicall function args
 */
export const encodeInterchainTokenServiceMulticallArgs = ({
  data,
}: InterchainTokenServiceMulticallArgs) => [data] as const;

/**
 * Encoder function for InterchainTokenService.multicall function data
 */
export const encodeInterchainTokenServiceMulticallData = ({
  data,
}: InterchainTokenServiceMulticallArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "multicall",
    abi: ABI_FILE.abi,
    args: [data],
  });

export type InterchainTokenServiceProposeOperatorshipArgs = {
  operator: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.proposeOperatorship function args
 */
export const encodeInterchainTokenServiceProposeOperatorshipArgs = ({
  operator,
}: InterchainTokenServiceProposeOperatorshipArgs) => [operator] as const;

/**
 * Encoder function for InterchainTokenService.proposeOperatorship function data
 */
export const encodeInterchainTokenServiceProposeOperatorshipData = ({
  operator,
}: InterchainTokenServiceProposeOperatorshipArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "proposeOperatorship",
    abi: ABI_FILE.abi,
    args: [operator],
  });

export type InterchainTokenServiceProposeOwnershipArgs = {
  newOwner: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.proposeOwnership function args
 */
export const encodeInterchainTokenServiceProposeOwnershipArgs = ({
  newOwner,
}: InterchainTokenServiceProposeOwnershipArgs) => [newOwner] as const;

/**
 * Encoder function for InterchainTokenService.proposeOwnership function data
 */
export const encodeInterchainTokenServiceProposeOwnershipData = ({
  newOwner,
}: InterchainTokenServiceProposeOwnershipArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "proposeOwnership",
    abi: ABI_FILE.abi,
    args: [newOwner],
  });

export type InterchainTokenServiceRegisterCustomTokenArgs = {
  salt: `0x${string}`;
  tokenAddress: `0x${string}`;
  tokenManagerType: number;
  linkParams: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.registerCustomToken function args
 */
export const encodeInterchainTokenServiceRegisterCustomTokenArgs = ({
  salt,
  tokenAddress,
  tokenManagerType,
  linkParams,
}: InterchainTokenServiceRegisterCustomTokenArgs) =>
  [salt, tokenAddress, tokenManagerType, linkParams] as const;

/**
 * Encoder function for InterchainTokenService.registerCustomToken function data
 */
export const encodeInterchainTokenServiceRegisterCustomTokenData = ({
  salt,
  tokenAddress,
  tokenManagerType,
  linkParams,
}: InterchainTokenServiceRegisterCustomTokenArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "registerCustomToken",
    abi: ABI_FILE.abi,
    args: [salt, tokenAddress, tokenManagerType, linkParams],
  });

export type InterchainTokenServiceRegisterTokenMetadataArgs = {
  tokenAddress: `0x${string}`;
  gasValue: bigint;
};

/**
 * Factory function for InterchainTokenService.registerTokenMetadata function args
 */
export const encodeInterchainTokenServiceRegisterTokenMetadataArgs = ({
  tokenAddress,
  gasValue,
}: InterchainTokenServiceRegisterTokenMetadataArgs) =>
  [tokenAddress, gasValue] as const;

/**
 * Encoder function for InterchainTokenService.registerTokenMetadata function data
 */
export const encodeInterchainTokenServiceRegisterTokenMetadataData = ({
  tokenAddress,
  gasValue,
}: InterchainTokenServiceRegisterTokenMetadataArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "registerTokenMetadata",
    abi: ABI_FILE.abi,
    args: [tokenAddress, gasValue],
  });

export type InterchainTokenServiceRegisteredTokenAddressArgs = {
  tokenId: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.registeredTokenAddress function args
 */
export const encodeInterchainTokenServiceRegisteredTokenAddressArgs = ({
  tokenId,
}: InterchainTokenServiceRegisteredTokenAddressArgs) => [tokenId] as const;

/**
 * Encoder function for InterchainTokenService.registeredTokenAddress function data
 */
export const encodeInterchainTokenServiceRegisteredTokenAddressData = ({
  tokenId,
}: InterchainTokenServiceRegisteredTokenAddressArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "registeredTokenAddress",
    abi: ABI_FILE.abi,
    args: [tokenId],
  });

export type InterchainTokenServiceRemoveTrustedAddressArgs = { chain: string };

/**
 * Factory function for InterchainTokenService.removeTrustedAddress function args
 */
export const encodeInterchainTokenServiceRemoveTrustedAddressArgs = ({
  chain,
}: InterchainTokenServiceRemoveTrustedAddressArgs) => [chain] as const;

/**
 * Encoder function for InterchainTokenService.removeTrustedAddress function data
 */
export const encodeInterchainTokenServiceRemoveTrustedAddressData = ({
  chain,
}: InterchainTokenServiceRemoveTrustedAddressArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "removeTrustedAddress",
    abi: ABI_FILE.abi,
    args: [chain],
  });

export type InterchainTokenServiceSetFlowLimitsArgs = {
  tokenIds: any;
  flowLimits: any;
};

/**
 * Factory function for InterchainTokenService.setFlowLimits function args
 */
export const encodeInterchainTokenServiceSetFlowLimitsArgs = ({
  tokenIds,
  flowLimits,
}: InterchainTokenServiceSetFlowLimitsArgs) => [tokenIds, flowLimits] as const;

/**
 * Encoder function for InterchainTokenService.setFlowLimits function data
 */
export const encodeInterchainTokenServiceSetFlowLimitsData = ({
  tokenIds,
  flowLimits,
}: InterchainTokenServiceSetFlowLimitsArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "setFlowLimits",
    abi: ABI_FILE.abi,
    args: [tokenIds, flowLimits],
  });

export type InterchainTokenServiceSetPauseStatusArgs = { paused: boolean };

/**
 * Factory function for InterchainTokenService.setPauseStatus function args
 */
export const encodeInterchainTokenServiceSetPauseStatusArgs = ({
  paused,
}: InterchainTokenServiceSetPauseStatusArgs) => [paused] as const;

/**
 * Encoder function for InterchainTokenService.setPauseStatus function data
 */
export const encodeInterchainTokenServiceSetPauseStatusData = ({
  paused,
}: InterchainTokenServiceSetPauseStatusArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "setPauseStatus",
    abi: ABI_FILE.abi,
    args: [paused],
  });

export type InterchainTokenServiceSetTrustedAddressArgs = {
  chain: string;
  address_: string;
};

/**
 * Factory function for InterchainTokenService.setTrustedAddress function args
 */
export const encodeInterchainTokenServiceSetTrustedAddressArgs = ({
  chain,
  address_,
}: InterchainTokenServiceSetTrustedAddressArgs) => [chain, address_] as const;

/**
 * Encoder function for InterchainTokenService.setTrustedAddress function data
 */
export const encodeInterchainTokenServiceSetTrustedAddressData = ({
  chain,
  address_,
}: InterchainTokenServiceSetTrustedAddressArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "setTrustedAddress",
    abi: ABI_FILE.abi,
    args: [chain, address_],
  });

export type InterchainTokenServiceSetupArgs = { data: `0x${string}` };

/**
 * Factory function for InterchainTokenService.setup function args
 */
export const encodeInterchainTokenServiceSetupArgs = ({
  data,
}: InterchainTokenServiceSetupArgs) => [data] as const;

/**
 * Encoder function for InterchainTokenService.setup function data
 */
export const encodeInterchainTokenServiceSetupData = ({
  data,
}: InterchainTokenServiceSetupArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "setup",
    abi: ABI_FILE.abi,
    args: [data],
  });

export type InterchainTokenServiceTokenManagerAddressArgs = {
  tokenId: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.tokenManagerAddress function args
 */
export const encodeInterchainTokenServiceTokenManagerAddressArgs = ({
  tokenId,
}: InterchainTokenServiceTokenManagerAddressArgs) => [tokenId] as const;

/**
 * Encoder function for InterchainTokenService.tokenManagerAddress function data
 */
export const encodeInterchainTokenServiceTokenManagerAddressData = ({
  tokenId,
}: InterchainTokenServiceTokenManagerAddressArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "tokenManagerAddress",
    abi: ABI_FILE.abi,
    args: [tokenId],
  });

export type InterchainTokenServiceTransferOperatorshipArgs = {
  operator: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.transferOperatorship function args
 */
export const encodeInterchainTokenServiceTransferOperatorshipArgs = ({
  operator,
}: InterchainTokenServiceTransferOperatorshipArgs) => [operator] as const;

/**
 * Encoder function for InterchainTokenService.transferOperatorship function data
 */
export const encodeInterchainTokenServiceTransferOperatorshipData = ({
  operator,
}: InterchainTokenServiceTransferOperatorshipArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "transferOperatorship",
    abi: ABI_FILE.abi,
    args: [operator],
  });

export type InterchainTokenServiceTransferOwnershipArgs = {
  newOwner: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.transferOwnership function args
 */
export const encodeInterchainTokenServiceTransferOwnershipArgs = ({
  newOwner,
}: InterchainTokenServiceTransferOwnershipArgs) => [newOwner] as const;

/**
 * Encoder function for InterchainTokenService.transferOwnership function data
 */
export const encodeInterchainTokenServiceTransferOwnershipData = ({
  newOwner,
}: InterchainTokenServiceTransferOwnershipArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "transferOwnership",
    abi: ABI_FILE.abi,
    args: [newOwner],
  });

export type InterchainTokenServiceTransmitInterchainTransferArgs = {
  tokenId: `0x${string}`;
  sourceAddress: `0x${string}`;
  destinationChain: string;
  destinationAddress: `0x${string}`;
  amount: bigint;
  metadata: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.transmitInterchainTransfer function args
 */
export const encodeInterchainTokenServiceTransmitInterchainTransferArgs = ({
  tokenId,
  sourceAddress,
  destinationChain,
  destinationAddress,
  amount,
  metadata,
}: InterchainTokenServiceTransmitInterchainTransferArgs) =>
  [
    tokenId,
    sourceAddress,
    destinationChain,
    destinationAddress,
    amount,
    metadata,
  ] as const;

/**
 * Encoder function for InterchainTokenService.transmitInterchainTransfer function data
 */
export const encodeInterchainTokenServiceTransmitInterchainTransferData = ({
  tokenId,
  sourceAddress,
  destinationChain,
  destinationAddress,
  amount,
  metadata,
}: InterchainTokenServiceTransmitInterchainTransferArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "transmitInterchainTransfer",
    abi: ABI_FILE.abi,
    args: [
      tokenId,
      sourceAddress,
      destinationChain,
      destinationAddress,
      amount,
      metadata,
    ],
  });

export type InterchainTokenServiceTrustedAddressArgs = { chain: string };

/**
 * Factory function for InterchainTokenService.trustedAddress function args
 */
export const encodeInterchainTokenServiceTrustedAddressArgs = ({
  chain,
}: InterchainTokenServiceTrustedAddressArgs) => [chain] as const;

/**
 * Encoder function for InterchainTokenService.trustedAddress function data
 */
export const encodeInterchainTokenServiceTrustedAddressData = ({
  chain,
}: InterchainTokenServiceTrustedAddressArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "trustedAddress",
    abi: ABI_FILE.abi,
    args: [chain],
  });

export type InterchainTokenServiceTrustedAddressHashArgs = { chain: string };

/**
 * Factory function for InterchainTokenService.trustedAddressHash function args
 */
export const encodeInterchainTokenServiceTrustedAddressHashArgs = ({
  chain,
}: InterchainTokenServiceTrustedAddressHashArgs) => [chain] as const;

/**
 * Encoder function for InterchainTokenService.trustedAddressHash function data
 */
export const encodeInterchainTokenServiceTrustedAddressHashData = ({
  chain,
}: InterchainTokenServiceTrustedAddressHashArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "trustedAddressHash",
    abi: ABI_FILE.abi,
    args: [chain],
  });

export type InterchainTokenServiceUpgradeArgs = {
  newImplementation: `0x${string}`;
  newImplementationCodeHash: `0x${string}`;
  params: `0x${string}`;
};

/**
 * Factory function for InterchainTokenService.upgrade function args
 */
export const encodeInterchainTokenServiceUpgradeArgs = ({
  newImplementation,
  newImplementationCodeHash,
  params,
}: InterchainTokenServiceUpgradeArgs) =>
  [newImplementation, newImplementationCodeHash, params] as const;

/**
 * Encoder function for InterchainTokenService.upgrade function data
 */
export const encodeInterchainTokenServiceUpgradeData = ({
  newImplementation,
  newImplementationCodeHash,
  params,
}: InterchainTokenServiceUpgradeArgs): `0x${string}` =>
  encodeFunctionData({
    functionName: "upgrade",
    abi: ABI_FILE.abi,
    args: [newImplementation, newImplementationCodeHash, params],
  });

export const INTERCHAIN_TOKEN_SERVICE_ENCODERS = {
  acceptOperatorship: {
    args: encodeInterchainTokenServiceAcceptOperatorshipArgs,
    data: encodeInterchainTokenServiceAcceptOperatorshipData,
  },
  contractCallValue: {
    args: encodeInterchainTokenServiceContractCallValueArgs,
    data: encodeInterchainTokenServiceContractCallValueData,
  },
  deployInterchainToken: {
    args: encodeInterchainTokenServiceDeployInterchainTokenArgs,
    data: encodeInterchainTokenServiceDeployInterchainTokenData,
  },
  deployedTokenManager: {
    args: encodeInterchainTokenServiceDeployedTokenManagerArgs,
    data: encodeInterchainTokenServiceDeployedTokenManagerData,
  },
  execute: {
    args: encodeInterchainTokenServiceExecuteArgs,
    data: encodeInterchainTokenServiceExecuteData,
  },
  expressExecute: {
    args: encodeInterchainTokenServiceExpressExecuteArgs,
    data: encodeInterchainTokenServiceExpressExecuteData,
  },
  getExpressExecutor: {
    args: encodeInterchainTokenServiceGetExpressExecutorArgs,
    data: encodeInterchainTokenServiceGetExpressExecutorData,
  },
  hasRole: {
    args: encodeInterchainTokenServiceHasRoleArgs,
    data: encodeInterchainTokenServiceHasRoleData,
  },
  interchainTokenAddress: {
    args: encodeInterchainTokenServiceInterchainTokenAddressArgs,
    data: encodeInterchainTokenServiceInterchainTokenAddressData,
  },
  interchainTokenId: {
    args: encodeInterchainTokenServiceInterchainTokenIdArgs,
    data: encodeInterchainTokenServiceInterchainTokenIdData,
  },
  interchainTransfer: {
    args: encodeInterchainTokenServiceInterchainTransferArgs,
    data: encodeInterchainTokenServiceInterchainTransferData,
  },
  isOperator: {
    args: encodeInterchainTokenServiceIsOperatorArgs,
    data: encodeInterchainTokenServiceIsOperatorData,
  },
  isTrustedAddress: {
    args: encodeInterchainTokenServiceIsTrustedAddressArgs,
    data: encodeInterchainTokenServiceIsTrustedAddressData,
  },
  linkToken: {
    args: encodeInterchainTokenServiceLinkTokenArgs,
    data: encodeInterchainTokenServiceLinkTokenData,
  },
  migrateInterchainToken: {
    args: encodeInterchainTokenServiceMigrateInterchainTokenArgs,
    data: encodeInterchainTokenServiceMigrateInterchainTokenData,
  },
  multicall: {
    args: encodeInterchainTokenServiceMulticallArgs,
    data: encodeInterchainTokenServiceMulticallData,
  },
  proposeOperatorship: {
    args: encodeInterchainTokenServiceProposeOperatorshipArgs,
    data: encodeInterchainTokenServiceProposeOperatorshipData,
  },
  proposeOwnership: {
    args: encodeInterchainTokenServiceProposeOwnershipArgs,
    data: encodeInterchainTokenServiceProposeOwnershipData,
  },
  registerCustomToken: {
    args: encodeInterchainTokenServiceRegisterCustomTokenArgs,
    data: encodeInterchainTokenServiceRegisterCustomTokenData,
  },
  registerTokenMetadata: {
    args: encodeInterchainTokenServiceRegisterTokenMetadataArgs,
    data: encodeInterchainTokenServiceRegisterTokenMetadataData,
  },
  registeredTokenAddress: {
    args: encodeInterchainTokenServiceRegisteredTokenAddressArgs,
    data: encodeInterchainTokenServiceRegisteredTokenAddressData,
  },
  removeTrustedAddress: {
    args: encodeInterchainTokenServiceRemoveTrustedAddressArgs,
    data: encodeInterchainTokenServiceRemoveTrustedAddressData,
  },
  setFlowLimits: {
    args: encodeInterchainTokenServiceSetFlowLimitsArgs,
    data: encodeInterchainTokenServiceSetFlowLimitsData,
  },
  setPauseStatus: {
    args: encodeInterchainTokenServiceSetPauseStatusArgs,
    data: encodeInterchainTokenServiceSetPauseStatusData,
  },
  setTrustedAddress: {
    args: encodeInterchainTokenServiceSetTrustedAddressArgs,
    data: encodeInterchainTokenServiceSetTrustedAddressData,
  },
  setup: {
    args: encodeInterchainTokenServiceSetupArgs,
    data: encodeInterchainTokenServiceSetupData,
  },
  tokenManagerAddress: {
    args: encodeInterchainTokenServiceTokenManagerAddressArgs,
    data: encodeInterchainTokenServiceTokenManagerAddressData,
  },
  transferOperatorship: {
    args: encodeInterchainTokenServiceTransferOperatorshipArgs,
    data: encodeInterchainTokenServiceTransferOperatorshipData,
  },
  transferOwnership: {
    args: encodeInterchainTokenServiceTransferOwnershipArgs,
    data: encodeInterchainTokenServiceTransferOwnershipData,
  },
  transmitInterchainTransfer: {
    args: encodeInterchainTokenServiceTransmitInterchainTransferArgs,
    data: encodeInterchainTokenServiceTransmitInterchainTransferData,
  },
  trustedAddress: {
    args: encodeInterchainTokenServiceTrustedAddressArgs,
    data: encodeInterchainTokenServiceTrustedAddressData,
  },
  trustedAddressHash: {
    args: encodeInterchainTokenServiceTrustedAddressHashArgs,
    data: encodeInterchainTokenServiceTrustedAddressHashData,
  },
  upgrade: {
    args: encodeInterchainTokenServiceUpgradeArgs,
    data: encodeInterchainTokenServiceUpgradeData,
  },
};

export function createInterchainTokenServiceReadClient(
  publicClient: PublicContractClient<typeof ABI_FILE.abi>
) {
  return {
    contractCallValue(
      contractCallValueArgs: InterchainTokenServiceContractCallValueArgs
    ) {
      const encoder = INTERCHAIN_TOKEN_SERVICE_ENCODERS["contractCallValue"];
      const encodedArgs = encoder.args(contractCallValueArgs);

      return publicClient.read("contractCallValue", { args: encodedArgs });
    },
    deployedTokenManager(
      deployedTokenManagerArgs: InterchainTokenServiceDeployedTokenManagerArgs
    ) {
      const encoder = INTERCHAIN_TOKEN_SERVICE_ENCODERS["deployedTokenManager"];
      const encodedArgs = encoder.args(deployedTokenManagerArgs);

      return publicClient.read("deployedTokenManager", { args: encodedArgs });
    },
    getExpressExecutor(
      getExpressExecutorArgs: InterchainTokenServiceGetExpressExecutorArgs
    ) {
      const encoder = INTERCHAIN_TOKEN_SERVICE_ENCODERS["getExpressExecutor"];
      const encodedArgs = encoder.args(getExpressExecutorArgs);

      return publicClient.read("getExpressExecutor", { args: encodedArgs });
    },
    hasRole(hasRoleArgs: InterchainTokenServiceHasRoleArgs) {
      const encoder = INTERCHAIN_TOKEN_SERVICE_ENCODERS["hasRole"];
      const encodedArgs = encoder.args(hasRoleArgs);

      return publicClient.read("hasRole", { args: encodedArgs });
    },
    interchainTokenAddress(
      interchainTokenAddressArgs: InterchainTokenServiceInterchainTokenAddressArgs
    ) {
      const encoder =
        INTERCHAIN_TOKEN_SERVICE_ENCODERS["interchainTokenAddress"];
      const encodedArgs = encoder.args(interchainTokenAddressArgs);

      return publicClient.read("interchainTokenAddress", { args: encodedArgs });
    },
    interchainTokenId(
      interchainTokenIdArgs: InterchainTokenServiceInterchainTokenIdArgs
    ) {
      const encoder = INTERCHAIN_TOKEN_SERVICE_ENCODERS["interchainTokenId"];
      const encodedArgs = encoder.args(interchainTokenIdArgs);

      return publicClient.read("interchainTokenId", { args: encodedArgs });
    },
    isOperator(isOperatorArgs: InterchainTokenServiceIsOperatorArgs) {
      const encoder = INTERCHAIN_TOKEN_SERVICE_ENCODERS["isOperator"];
      const encodedArgs = encoder.args(isOperatorArgs);

      return publicClient.read("isOperator", { args: encodedArgs });
    },
    isTrustedAddress(
      isTrustedAddressArgs: InterchainTokenServiceIsTrustedAddressArgs
    ) {
      const encoder = INTERCHAIN_TOKEN_SERVICE_ENCODERS["isTrustedAddress"];
      const encodedArgs = encoder.args(isTrustedAddressArgs);

      return publicClient.read("isTrustedAddress", { args: encodedArgs });
    },
    registeredTokenAddress(
      registeredTokenAddressArgs: InterchainTokenServiceRegisteredTokenAddressArgs
    ) {
      const encoder =
        INTERCHAIN_TOKEN_SERVICE_ENCODERS["registeredTokenAddress"];
      const encodedArgs = encoder.args(registeredTokenAddressArgs);

      return publicClient.read("registeredTokenAddress", { args: encodedArgs });
    },
    tokenManagerAddress(
      tokenManagerAddressArgs: InterchainTokenServiceTokenManagerAddressArgs
    ) {
      const encoder = INTERCHAIN_TOKEN_SERVICE_ENCODERS["tokenManagerAddress"];
      const encodedArgs = encoder.args(tokenManagerAddressArgs);

      return publicClient.read("tokenManagerAddress", { args: encodedArgs });
    },
    trustedAddress(
      trustedAddressArgs: InterchainTokenServiceTrustedAddressArgs
    ) {
      const encoder = INTERCHAIN_TOKEN_SERVICE_ENCODERS["trustedAddress"];
      const encodedArgs = encoder.args(trustedAddressArgs);

      return publicClient.read("trustedAddress", { args: encodedArgs });
    },
    trustedAddressHash(
      trustedAddressHashArgs: InterchainTokenServiceTrustedAddressHashArgs
    ) {
      const encoder = INTERCHAIN_TOKEN_SERVICE_ENCODERS["trustedAddressHash"];
      const encodedArgs = encoder.args(trustedAddressHashArgs);

      return publicClient.read("trustedAddressHash", { args: encodedArgs });
    },
  };
}
