/**
 * This code was AUTOGENERATED using the Codama library.
 * Please DO NOT EDIT THIS FILE, instead use visitors
 * to add features, then rerun Codama to update it.
 *
 * @see https://github.com/codama-idl/codama
 */

import {
  assertAccountExists,
  assertAccountsExist,
  combineCodec,
  decodeAccount,
  fetchEncodedAccount,
  fetchEncodedAccounts,
  fixDecoderSize,
  fixEncoderSize,
  getArrayDecoder,
  getArrayEncoder,
  getBytesDecoder,
  getBytesEncoder,
  getStructDecoder,
  getStructEncoder,
  getU32Decoder,
  getU32Encoder,
  transformEncoder,
  type Account,
  type Address,
  type Codec,
  type Decoder,
  type EncodedAccount,
  type Encoder,
  type FetchAccountConfig,
  type FetchAccountsConfig,
  type MaybeAccount,
  type MaybeEncodedAccount,
  type ReadonlyUint8Array,
} from "@solana/kit";
import {
  getRelayerRefundLeafDecoder,
  getRelayerRefundLeafEncoder,
  type RelayerRefundLeaf,
  type RelayerRefundLeafArgs,
} from "../types";

export const EXECUTE_RELAYER_REFUND_LEAF_PARAMS_DISCRIMINATOR = new Uint8Array([
  192, 59, 93, 9, 171, 77, 28, 250,
]);

export function getExecuteRelayerRefundLeafParamsDiscriminatorBytes() {
  return fixEncoderSize(getBytesEncoder(), 8).encode(
    EXECUTE_RELAYER_REFUND_LEAF_PARAMS_DISCRIMINATOR,
  );
}

export type ExecuteRelayerRefundLeafParams = {
  discriminator: ReadonlyUint8Array;
  rootBundleId: number;
  relayerRefundLeaf: RelayerRefundLeaf;
  proof: Array<ReadonlyUint8Array>;
};

export type ExecuteRelayerRefundLeafParamsArgs = {
  rootBundleId: number;
  relayerRefundLeaf: RelayerRefundLeafArgs;
  proof: Array<ReadonlyUint8Array>;
};

/** Gets the encoder for {@link ExecuteRelayerRefundLeafParamsArgs} account data. */
export function getExecuteRelayerRefundLeafParamsEncoder(): Encoder<ExecuteRelayerRefundLeafParamsArgs> {
  return transformEncoder(
    getStructEncoder([
      ["discriminator", fixEncoderSize(getBytesEncoder(), 8)],
      ["rootBundleId", getU32Encoder()],
      ["relayerRefundLeaf", getRelayerRefundLeafEncoder()],
      ["proof", getArrayEncoder(fixEncoderSize(getBytesEncoder(), 32))],
    ]),
    (value) => ({
      ...value,
      discriminator: EXECUTE_RELAYER_REFUND_LEAF_PARAMS_DISCRIMINATOR,
    }),
  );
}

/** Gets the decoder for {@link ExecuteRelayerRefundLeafParams} account data. */
export function getExecuteRelayerRefundLeafParamsDecoder(): Decoder<ExecuteRelayerRefundLeafParams> {
  return getStructDecoder([
    ["discriminator", fixDecoderSize(getBytesDecoder(), 8)],
    ["rootBundleId", getU32Decoder()],
    ["relayerRefundLeaf", getRelayerRefundLeafDecoder()],
    ["proof", getArrayDecoder(fixDecoderSize(getBytesDecoder(), 32))],
  ]);
}

/** Gets the codec for {@link ExecuteRelayerRefundLeafParams} account data. */
export function getExecuteRelayerRefundLeafParamsCodec(): Codec<
  ExecuteRelayerRefundLeafParamsArgs,
  ExecuteRelayerRefundLeafParams
> {
  return combineCodec(
    getExecuteRelayerRefundLeafParamsEncoder(),
    getExecuteRelayerRefundLeafParamsDecoder(),
  );
}

export function decodeExecuteRelayerRefundLeafParams<
  TAddress extends string = string,
>(
  encodedAccount: EncodedAccount<TAddress>,
): Account<ExecuteRelayerRefundLeafParams, TAddress>;
export function decodeExecuteRelayerRefundLeafParams<
  TAddress extends string = string,
>(
  encodedAccount: MaybeEncodedAccount<TAddress>,
): MaybeAccount<ExecuteRelayerRefundLeafParams, TAddress>;
export function decodeExecuteRelayerRefundLeafParams<
  TAddress extends string = string,
>(
  encodedAccount: EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress>,
):
  | Account<ExecuteRelayerRefundLeafParams, TAddress>
  | MaybeAccount<ExecuteRelayerRefundLeafParams, TAddress> {
  return decodeAccount(
    encodedAccount as MaybeEncodedAccount<TAddress>,
    getExecuteRelayerRefundLeafParamsDecoder(),
  );
}

export async function fetchExecuteRelayerRefundLeafParams<
  TAddress extends string = string,
>(
  rpc: Parameters<typeof fetchEncodedAccount>[0],
  address: Address<TAddress>,
  config?: FetchAccountConfig,
): Promise<Account<ExecuteRelayerRefundLeafParams, TAddress>> {
  const maybeAccount = await fetchMaybeExecuteRelayerRefundLeafParams(
    rpc,
    address,
    config,
  );
  assertAccountExists(maybeAccount);
  return maybeAccount;
}

export async function fetchMaybeExecuteRelayerRefundLeafParams<
  TAddress extends string = string,
>(
  rpc: Parameters<typeof fetchEncodedAccount>[0],
  address: Address<TAddress>,
  config?: FetchAccountConfig,
): Promise<MaybeAccount<ExecuteRelayerRefundLeafParams, TAddress>> {
  const maybeAccount = await fetchEncodedAccount(rpc, address, config);
  return decodeExecuteRelayerRefundLeafParams(maybeAccount);
}

export async function fetchAllExecuteRelayerRefundLeafParams(
  rpc: Parameters<typeof fetchEncodedAccounts>[0],
  addresses: Array<Address>,
  config?: FetchAccountsConfig,
): Promise<Account<ExecuteRelayerRefundLeafParams>[]> {
  const maybeAccounts = await fetchAllMaybeExecuteRelayerRefundLeafParams(
    rpc,
    addresses,
    config,
  );
  assertAccountsExist(maybeAccounts);
  return maybeAccounts;
}

export async function fetchAllMaybeExecuteRelayerRefundLeafParams(
  rpc: Parameters<typeof fetchEncodedAccounts>[0],
  addresses: Array<Address>,
  config?: FetchAccountsConfig,
): Promise<MaybeAccount<ExecuteRelayerRefundLeafParams>[]> {
  const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);
  return maybeAccounts.map((maybeAccount) =>
    decodeExecuteRelayerRefundLeafParams(maybeAccount),
  );
}
