/**
 * 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 {
  combineCodec,
  getAddressDecoder,
  getAddressEncoder,
  getOptionDecoder,
  getOptionEncoder,
  getProgramDerivedAddress,
  getStructDecoder,
  getStructEncoder,
  getU64Decoder,
  getU64Encoder,
  getU8Decoder,
  getU8Encoder,
  SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS,
  SolanaError,
  transformEncoder,
  type AccountMeta,
  type AccountSignerMeta,
  type Address,
  type Codec,
  type Decoder,
  type Encoder,
  type Instruction,
  type InstructionWithAccounts,
  type InstructionWithData,
  type Option,
  type OptionOrNullable,
  type ReadonlyAccount,
  type ReadonlySignerAccount,
  type ReadonlyUint8Array,
  type TransactionSigner,
  type WritableAccount,
  type WritableSignerAccount,
} from "@solana/kit";
import {
  getAccountMetaFactory,
  getAddressFromResolvedInstructionAccount,
  type ResolvedInstructionAccount,
} from "@solana/kit/program-client-core";
import { findAllowedMintPda, findEventAuthorityPda } from "../pdas";
import { PRIVATE_CHANNEL_ESCROW_PROGRAM_PROGRAM_ADDRESS } from "../programs";

export const DEPOSIT_DISCRIMINATOR = 6;

export function getDepositDiscriminatorBytes(): ReadonlyUint8Array {
  return getU8Encoder().encode(DEPOSIT_DISCRIMINATOR);
}

export type DepositInstruction<
  TProgram extends string =
    typeof PRIVATE_CHANNEL_ESCROW_PROGRAM_PROGRAM_ADDRESS,
  TAccountPayer extends string | AccountMeta<string> = string,
  TAccountUser extends string | AccountMeta<string> = string,
  TAccountInstance extends string | AccountMeta<string> = string,
  TAccountMint extends string | AccountMeta<string> = string,
  TAccountAllowedMint extends string | AccountMeta<string> = string,
  TAccountUserAta extends string | AccountMeta<string> = string,
  TAccountInstanceAta extends string | AccountMeta<string> = string,
  TAccountSystemProgram extends string | AccountMeta<string> =
    "11111111111111111111111111111111",
  TAccountTokenProgram extends string | AccountMeta<string> =
    "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
  TAccountAssociatedTokenProgram extends string | AccountMeta<string> =
    "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",
  TAccountEventAuthority extends string | AccountMeta<string> = string,
  TAccountPrivateChannelEscrowProgram extends string | AccountMeta<string> =
    "9tgHa1DcnaSSUtmMsst8ovKTe1Gfxzezn27KnH9xXYeU",
  TRemainingAccounts extends readonly AccountMeta<string>[] = [],
> = Instruction<TProgram> &
  InstructionWithData<ReadonlyUint8Array> &
  InstructionWithAccounts<
    [
      TAccountPayer extends string
        ? WritableSignerAccount<TAccountPayer> &
            AccountSignerMeta<TAccountPayer>
        : TAccountPayer,
      TAccountUser extends string
        ? ReadonlySignerAccount<TAccountUser> & AccountSignerMeta<TAccountUser>
        : TAccountUser,
      TAccountInstance extends string
        ? ReadonlyAccount<TAccountInstance>
        : TAccountInstance,
      TAccountMint extends string
        ? ReadonlyAccount<TAccountMint>
        : TAccountMint,
      TAccountAllowedMint extends string
        ? ReadonlyAccount<TAccountAllowedMint>
        : TAccountAllowedMint,
      TAccountUserAta extends string
        ? WritableAccount<TAccountUserAta>
        : TAccountUserAta,
      TAccountInstanceAta extends string
        ? WritableAccount<TAccountInstanceAta>
        : TAccountInstanceAta,
      TAccountSystemProgram extends string
        ? ReadonlyAccount<TAccountSystemProgram>
        : TAccountSystemProgram,
      TAccountTokenProgram extends string
        ? ReadonlyAccount<TAccountTokenProgram>
        : TAccountTokenProgram,
      TAccountAssociatedTokenProgram extends string
        ? ReadonlyAccount<TAccountAssociatedTokenProgram>
        : TAccountAssociatedTokenProgram,
      TAccountEventAuthority extends string
        ? ReadonlyAccount<TAccountEventAuthority>
        : TAccountEventAuthority,
      TAccountPrivateChannelEscrowProgram extends string
        ? ReadonlyAccount<TAccountPrivateChannelEscrowProgram>
        : TAccountPrivateChannelEscrowProgram,
      ...TRemainingAccounts,
    ]
  >;

export type DepositInstructionData = {
  discriminator: number;
  amount: bigint;
  recipient: Option<Address>;
};

export type DepositInstructionDataArgs = {
  amount: number | bigint;
  recipient: OptionOrNullable<Address>;
};

export function getDepositInstructionDataEncoder(): Encoder<DepositInstructionDataArgs> {
  return transformEncoder(
    getStructEncoder([
      ["discriminator", getU8Encoder()],
      ["amount", getU64Encoder()],
      ["recipient", getOptionEncoder(getAddressEncoder())],
    ]),
    (value) => ({ ...value, discriminator: DEPOSIT_DISCRIMINATOR }),
  );
}

export function getDepositInstructionDataDecoder(): Decoder<DepositInstructionData> {
  return getStructDecoder([
    ["discriminator", getU8Decoder()],
    ["amount", getU64Decoder()],
    ["recipient", getOptionDecoder(getAddressDecoder())],
  ]);
}

export function getDepositInstructionDataCodec(): Codec<
  DepositInstructionDataArgs,
  DepositInstructionData
> {
  return combineCodec(
    getDepositInstructionDataEncoder(),
    getDepositInstructionDataDecoder(),
  );
}

export type DepositAsyncInput<
  TAccountPayer extends string = string,
  TAccountUser extends string = string,
  TAccountInstance extends string = string,
  TAccountMint extends string = string,
  TAccountAllowedMint extends string = string,
  TAccountUserAta extends string = string,
  TAccountInstanceAta extends string = string,
  TAccountSystemProgram extends string = string,
  TAccountTokenProgram extends string = string,
  TAccountAssociatedTokenProgram extends string = string,
  TAccountEventAuthority extends string = string,
  TAccountPrivateChannelEscrowProgram extends string = string,
> = {
  /** Transaction fee payer */
  payer: TransactionSigner<TAccountPayer>;
  /** User depositing tokens */
  user: TransactionSigner<TAccountUser>;
  /** Instance PDA to validate */
  instance: Address<TAccountInstance>;
  /** Token mint being deposited */
  mint: Address<TAccountMint>;
  /** AllowedMint PDA to validate mint is allowed */
  allowedMint?: Address<TAccountAllowedMint>;
  /** User's Associated Token Account for this mint */
  userAta?: Address<TAccountUserAta>;
  /** Instance's Associated Token Account (escrow) for this mint */
  instanceAta?: Address<TAccountInstanceAta>;
  /** System program */
  systemProgram?: Address<TAccountSystemProgram>;
  /** Token program for the mint */
  tokenProgram?: Address<TAccountTokenProgram>;
  /** Associated Token program */
  associatedTokenProgram?: Address<TAccountAssociatedTokenProgram>;
  /** Event authority PDA for emitting events */
  eventAuthority?: Address<TAccountEventAuthority>;
  /** Current program for CPI */
  privateChannelEscrowProgram?: Address<TAccountPrivateChannelEscrowProgram>;
  amount: DepositInstructionDataArgs["amount"];
  recipient: DepositInstructionDataArgs["recipient"];
};

export async function getDepositInstructionAsync<
  TAccountPayer extends string,
  TAccountUser extends string,
  TAccountInstance extends string,
  TAccountMint extends string,
  TAccountAllowedMint extends string,
  TAccountUserAta extends string,
  TAccountInstanceAta extends string,
  TAccountSystemProgram extends string,
  TAccountTokenProgram extends string,
  TAccountAssociatedTokenProgram extends string,
  TAccountEventAuthority extends string,
  TAccountPrivateChannelEscrowProgram extends string,
  TProgramAddress extends Address =
    typeof PRIVATE_CHANNEL_ESCROW_PROGRAM_PROGRAM_ADDRESS,
>(
  input: DepositAsyncInput<
    TAccountPayer,
    TAccountUser,
    TAccountInstance,
    TAccountMint,
    TAccountAllowedMint,
    TAccountUserAta,
    TAccountInstanceAta,
    TAccountSystemProgram,
    TAccountTokenProgram,
    TAccountAssociatedTokenProgram,
    TAccountEventAuthority,
    TAccountPrivateChannelEscrowProgram
  >,
  config?: { programAddress?: TProgramAddress },
): Promise<
  DepositInstruction<
    TProgramAddress,
    TAccountPayer,
    TAccountUser,
    TAccountInstance,
    TAccountMint,
    TAccountAllowedMint,
    TAccountUserAta,
    TAccountInstanceAta,
    TAccountSystemProgram,
    TAccountTokenProgram,
    TAccountAssociatedTokenProgram,
    TAccountEventAuthority,
    TAccountPrivateChannelEscrowProgram
  >
> {
  // Program address.
  const programAddress =
    config?.programAddress ?? PRIVATE_CHANNEL_ESCROW_PROGRAM_PROGRAM_ADDRESS;

  // Original accounts.
  const originalAccounts = {
    payer: { value: input.payer ?? null, isWritable: true },
    user: { value: input.user ?? null, isWritable: false },
    instance: { value: input.instance ?? null, isWritable: false },
    mint: { value: input.mint ?? null, isWritable: false },
    allowedMint: { value: input.allowedMint ?? null, isWritable: false },
    userAta: { value: input.userAta ?? null, isWritable: true },
    instanceAta: { value: input.instanceAta ?? null, isWritable: true },
    systemProgram: { value: input.systemProgram ?? null, isWritable: false },
    tokenProgram: { value: input.tokenProgram ?? null, isWritable: false },
    associatedTokenProgram: {
      value: input.associatedTokenProgram ?? null,
      isWritable: false,
    },
    eventAuthority: { value: input.eventAuthority ?? null, isWritable: false },
    privateChannelEscrowProgram: {
      value: input.privateChannelEscrowProgram ?? null,
      isWritable: false,
    },
  };
  const accounts = originalAccounts as Record<
    keyof typeof originalAccounts,
    ResolvedInstructionAccount
  >;

  // Original args.
  const args = { ...input };

  // Resolve default values.
  if (!accounts.allowedMint.value) {
    accounts.allowedMint.value = await findAllowedMintPda({
      instance: getAddressFromResolvedInstructionAccount(
        "instance",
        accounts.instance.value,
      ),
      mint: getAddressFromResolvedInstructionAccount(
        "mint",
        accounts.mint.value,
      ),
    });
  }
  if (!accounts.tokenProgram.value) {
    accounts.tokenProgram.value =
      "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" as Address<"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA">;
  }
  if (!accounts.userAta.value) {
    accounts.userAta.value = await getProgramDerivedAddress({
      programAddress:
        "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" as Address<"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL">,
      seeds: [
        getAddressEncoder().encode(
          getAddressFromResolvedInstructionAccount("user", accounts.user.value),
        ),
        getAddressEncoder().encode(
          getAddressFromResolvedInstructionAccount(
            "tokenProgram",
            accounts.tokenProgram.value,
          ),
        ),
        getAddressEncoder().encode(
          getAddressFromResolvedInstructionAccount("mint", accounts.mint.value),
        ),
      ],
    });
  }
  if (!accounts.instanceAta.value) {
    accounts.instanceAta.value = await getProgramDerivedAddress({
      programAddress:
        "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" as Address<"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL">,
      seeds: [
        getAddressEncoder().encode(
          getAddressFromResolvedInstructionAccount(
            "instance",
            accounts.instance.value,
          ),
        ),
        getAddressEncoder().encode(
          getAddressFromResolvedInstructionAccount(
            "tokenProgram",
            accounts.tokenProgram.value,
          ),
        ),
        getAddressEncoder().encode(
          getAddressFromResolvedInstructionAccount("mint", accounts.mint.value),
        ),
      ],
    });
  }
  if (!accounts.systemProgram.value) {
    accounts.systemProgram.value =
      "11111111111111111111111111111111" as Address<"11111111111111111111111111111111">;
  }
  if (!accounts.associatedTokenProgram.value) {
    accounts.associatedTokenProgram.value =
      "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" as Address<"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL">;
  }
  if (!accounts.eventAuthority.value) {
    accounts.eventAuthority.value = await findEventAuthorityPda();
  }
  if (!accounts.privateChannelEscrowProgram.value) {
    accounts.privateChannelEscrowProgram.value =
      "9tgHa1DcnaSSUtmMsst8ovKTe1Gfxzezn27KnH9xXYeU" as Address<"9tgHa1DcnaSSUtmMsst8ovKTe1Gfxzezn27KnH9xXYeU">;
  }

  const getAccountMeta = getAccountMetaFactory(programAddress, "programId");
  return Object.freeze({
    accounts: [
      getAccountMeta("payer", accounts.payer),
      getAccountMeta("user", accounts.user),
      getAccountMeta("instance", accounts.instance),
      getAccountMeta("mint", accounts.mint),
      getAccountMeta("allowedMint", accounts.allowedMint),
      getAccountMeta("userAta", accounts.userAta),
      getAccountMeta("instanceAta", accounts.instanceAta),
      getAccountMeta("systemProgram", accounts.systemProgram),
      getAccountMeta("tokenProgram", accounts.tokenProgram),
      getAccountMeta("associatedTokenProgram", accounts.associatedTokenProgram),
      getAccountMeta("eventAuthority", accounts.eventAuthority),
      getAccountMeta(
        "privateChannelEscrowProgram",
        accounts.privateChannelEscrowProgram,
      ),
    ],
    data: getDepositInstructionDataEncoder().encode(
      args as DepositInstructionDataArgs,
    ),
    programAddress,
  } as DepositInstruction<
    TProgramAddress,
    TAccountPayer,
    TAccountUser,
    TAccountInstance,
    TAccountMint,
    TAccountAllowedMint,
    TAccountUserAta,
    TAccountInstanceAta,
    TAccountSystemProgram,
    TAccountTokenProgram,
    TAccountAssociatedTokenProgram,
    TAccountEventAuthority,
    TAccountPrivateChannelEscrowProgram
  >);
}

export type DepositInput<
  TAccountPayer extends string = string,
  TAccountUser extends string = string,
  TAccountInstance extends string = string,
  TAccountMint extends string = string,
  TAccountAllowedMint extends string = string,
  TAccountUserAta extends string = string,
  TAccountInstanceAta extends string = string,
  TAccountSystemProgram extends string = string,
  TAccountTokenProgram extends string = string,
  TAccountAssociatedTokenProgram extends string = string,
  TAccountEventAuthority extends string = string,
  TAccountPrivateChannelEscrowProgram extends string = string,
> = {
  /** Transaction fee payer */
  payer: TransactionSigner<TAccountPayer>;
  /** User depositing tokens */
  user: TransactionSigner<TAccountUser>;
  /** Instance PDA to validate */
  instance: Address<TAccountInstance>;
  /** Token mint being deposited */
  mint: Address<TAccountMint>;
  /** AllowedMint PDA to validate mint is allowed */
  allowedMint: Address<TAccountAllowedMint>;
  /** User's Associated Token Account for this mint */
  userAta: Address<TAccountUserAta>;
  /** Instance's Associated Token Account (escrow) for this mint */
  instanceAta: Address<TAccountInstanceAta>;
  /** System program */
  systemProgram?: Address<TAccountSystemProgram>;
  /** Token program for the mint */
  tokenProgram?: Address<TAccountTokenProgram>;
  /** Associated Token program */
  associatedTokenProgram?: Address<TAccountAssociatedTokenProgram>;
  /** Event authority PDA for emitting events */
  eventAuthority: Address<TAccountEventAuthority>;
  /** Current program for CPI */
  privateChannelEscrowProgram?: Address<TAccountPrivateChannelEscrowProgram>;
  amount: DepositInstructionDataArgs["amount"];
  recipient: DepositInstructionDataArgs["recipient"];
};

export function getDepositInstruction<
  TAccountPayer extends string,
  TAccountUser extends string,
  TAccountInstance extends string,
  TAccountMint extends string,
  TAccountAllowedMint extends string,
  TAccountUserAta extends string,
  TAccountInstanceAta extends string,
  TAccountSystemProgram extends string,
  TAccountTokenProgram extends string,
  TAccountAssociatedTokenProgram extends string,
  TAccountEventAuthority extends string,
  TAccountPrivateChannelEscrowProgram extends string,
  TProgramAddress extends Address =
    typeof PRIVATE_CHANNEL_ESCROW_PROGRAM_PROGRAM_ADDRESS,
>(
  input: DepositInput<
    TAccountPayer,
    TAccountUser,
    TAccountInstance,
    TAccountMint,
    TAccountAllowedMint,
    TAccountUserAta,
    TAccountInstanceAta,
    TAccountSystemProgram,
    TAccountTokenProgram,
    TAccountAssociatedTokenProgram,
    TAccountEventAuthority,
    TAccountPrivateChannelEscrowProgram
  >,
  config?: { programAddress?: TProgramAddress },
): DepositInstruction<
  TProgramAddress,
  TAccountPayer,
  TAccountUser,
  TAccountInstance,
  TAccountMint,
  TAccountAllowedMint,
  TAccountUserAta,
  TAccountInstanceAta,
  TAccountSystemProgram,
  TAccountTokenProgram,
  TAccountAssociatedTokenProgram,
  TAccountEventAuthority,
  TAccountPrivateChannelEscrowProgram
> {
  // Program address.
  const programAddress =
    config?.programAddress ?? PRIVATE_CHANNEL_ESCROW_PROGRAM_PROGRAM_ADDRESS;

  // Original accounts.
  const originalAccounts = {
    payer: { value: input.payer ?? null, isWritable: true },
    user: { value: input.user ?? null, isWritable: false },
    instance: { value: input.instance ?? null, isWritable: false },
    mint: { value: input.mint ?? null, isWritable: false },
    allowedMint: { value: input.allowedMint ?? null, isWritable: false },
    userAta: { value: input.userAta ?? null, isWritable: true },
    instanceAta: { value: input.instanceAta ?? null, isWritable: true },
    systemProgram: { value: input.systemProgram ?? null, isWritable: false },
    tokenProgram: { value: input.tokenProgram ?? null, isWritable: false },
    associatedTokenProgram: {
      value: input.associatedTokenProgram ?? null,
      isWritable: false,
    },
    eventAuthority: { value: input.eventAuthority ?? null, isWritable: false },
    privateChannelEscrowProgram: {
      value: input.privateChannelEscrowProgram ?? null,
      isWritable: false,
    },
  };
  const accounts = originalAccounts as Record<
    keyof typeof originalAccounts,
    ResolvedInstructionAccount
  >;

  // Original args.
  const args = { ...input };

  // Resolve default values.
  if (!accounts.tokenProgram.value) {
    accounts.tokenProgram.value =
      "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" as Address<"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA">;
  }
  if (!accounts.systemProgram.value) {
    accounts.systemProgram.value =
      "11111111111111111111111111111111" as Address<"11111111111111111111111111111111">;
  }
  if (!accounts.associatedTokenProgram.value) {
    accounts.associatedTokenProgram.value =
      "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" as Address<"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL">;
  }
  if (!accounts.privateChannelEscrowProgram.value) {
    accounts.privateChannelEscrowProgram.value =
      "9tgHa1DcnaSSUtmMsst8ovKTe1Gfxzezn27KnH9xXYeU" as Address<"9tgHa1DcnaSSUtmMsst8ovKTe1Gfxzezn27KnH9xXYeU">;
  }

  const getAccountMeta = getAccountMetaFactory(programAddress, "programId");
  return Object.freeze({
    accounts: [
      getAccountMeta("payer", accounts.payer),
      getAccountMeta("user", accounts.user),
      getAccountMeta("instance", accounts.instance),
      getAccountMeta("mint", accounts.mint),
      getAccountMeta("allowedMint", accounts.allowedMint),
      getAccountMeta("userAta", accounts.userAta),
      getAccountMeta("instanceAta", accounts.instanceAta),
      getAccountMeta("systemProgram", accounts.systemProgram),
      getAccountMeta("tokenProgram", accounts.tokenProgram),
      getAccountMeta("associatedTokenProgram", accounts.associatedTokenProgram),
      getAccountMeta("eventAuthority", accounts.eventAuthority),
      getAccountMeta(
        "privateChannelEscrowProgram",
        accounts.privateChannelEscrowProgram,
      ),
    ],
    data: getDepositInstructionDataEncoder().encode(
      args as DepositInstructionDataArgs,
    ),
    programAddress,
  } as DepositInstruction<
    TProgramAddress,
    TAccountPayer,
    TAccountUser,
    TAccountInstance,
    TAccountMint,
    TAccountAllowedMint,
    TAccountUserAta,
    TAccountInstanceAta,
    TAccountSystemProgram,
    TAccountTokenProgram,
    TAccountAssociatedTokenProgram,
    TAccountEventAuthority,
    TAccountPrivateChannelEscrowProgram
  >);
}

export type ParsedDepositInstruction<
  TProgram extends string =
    typeof PRIVATE_CHANNEL_ESCROW_PROGRAM_PROGRAM_ADDRESS,
  TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[],
> = {
  programAddress: Address<TProgram>;
  accounts: {
    /** Transaction fee payer */
    payer: TAccountMetas[0];
    /** User depositing tokens */
    user: TAccountMetas[1];
    /** Instance PDA to validate */
    instance: TAccountMetas[2];
    /** Token mint being deposited */
    mint: TAccountMetas[3];
    /** AllowedMint PDA to validate mint is allowed */
    allowedMint: TAccountMetas[4];
    /** User's Associated Token Account for this mint */
    userAta: TAccountMetas[5];
    /** Instance's Associated Token Account (escrow) for this mint */
    instanceAta: TAccountMetas[6];
    /** System program */
    systemProgram: TAccountMetas[7];
    /** Token program for the mint */
    tokenProgram: TAccountMetas[8];
    /** Associated Token program */
    associatedTokenProgram: TAccountMetas[9];
    /** Event authority PDA for emitting events */
    eventAuthority: TAccountMetas[10];
    /** Current program for CPI */
    privateChannelEscrowProgram: TAccountMetas[11];
  };
  data: DepositInstructionData;
};

export function parseDepositInstruction<
  TProgram extends string,
  TAccountMetas extends readonly AccountMeta[],
>(
  instruction: Instruction<TProgram> &
    InstructionWithAccounts<TAccountMetas> &
    InstructionWithData<ReadonlyUint8Array>,
): ParsedDepositInstruction<TProgram, TAccountMetas> {
  if (instruction.accounts.length < 12) {
    throw new SolanaError(
      SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS,
      {
        actualAccountMetas: instruction.accounts.length,
        expectedAccountMetas: 12,
      },
    );
  }
  let accountIndex = 0;
  const getNextAccount = () => {
    const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!;
    accountIndex += 1;
    return accountMeta;
  };
  return {
    programAddress: instruction.programAddress,
    accounts: {
      payer: getNextAccount(),
      user: getNextAccount(),
      instance: getNextAccount(),
      mint: getNextAccount(),
      allowedMint: getNextAccount(),
      userAta: getNextAccount(),
      instanceAta: getNextAccount(),
      systemProgram: getNextAccount(),
      tokenProgram: getNextAccount(),
      associatedTokenProgram: getNextAccount(),
      eventAuthority: getNextAccount(),
      privateChannelEscrowProgram: getNextAccount(),
    },
    data: getDepositInstructionDataDecoder().decode(instruction.data),
  };
}
