import type { AccountClient, Address, BN, Context as AnchorContext, MethodsNamespace, Program as AProgram, ProgramAccount, } from "@coral-xyz/anchor"; import type { Idl, IdlAccountItem, IdlAccounts, IdlEvent, IdlEventField, IdlField, IdlInstruction, IdlType, IdlTypeDef, IdlTypeDefTyStruct, } from "@coral-xyz/anchor/dist/esm/idl.js"; import type { AccountMeta, PublicKey, Transaction, TransactionInstruction, TransactionSignature, } from "@solana/web3.js"; export type IdlWithState = Idl & { state?: { methods: IdlInstruction[]; struct: IdlTypeDef; }; }; type InstructionsParsed = Record< string, { accounts: IdlAccountItem[]; args: Array; } >; export type ContextAccounts = { [K in A[number]["name"]]: A[number] & { name: K } extends IdlAccounts ? ContextAccounts< NonNullable<(A[number] & { name: K } & IdlAccounts)["accounts"]> > : Address; }; type Context = Omit & { accounts: ContextAccounts; }; type MakeInstructionsNamespace< R extends InstructionsParsed, Ret, Mk extends { [M in keyof R]: unknown } = { [M in keyof R]: unknown }, > = { [M in keyof R]: (( ...args: [...R[M]["args"], Context] ) => Ret) & Mk[M]; }; type RpcNamespace = MakeInstructionsNamespace< R, Promise >; type InstructionNamespace = MakeInstructionsNamespace< R, TransactionInstruction, { [M in keyof R]: { accounts: (ctx: ContextAccounts) => AccountMeta[]; }; } >; type TransactionNamespace = MakeInstructionsNamespace; type AccountsNamespace = { [K in keyof A]: Omit< AccountClient, "fetch" | "fetchNullable" | "all" | "associated" > & { /** * Returns a deserialized account. * * @param address The address of the account to fetch. */ fetch: (address: PublicKey) => Promise; /** * Returns a deserialized account, returning null if it doesn't exist. * * @param address The address of the account to fetch. */ fetchNullable: (address: PublicKey) => Promise; /** * Returns all instances of this account type for the program. */ all: ( ...args: Parameters ) => Promise[]>; /** * @deprecated since version 14.0. * * Function returning the associated account. Args are keys to associate. * Order matters. */ associated: (...args: PublicKey[]) => Promise; }; }; type TypeMap = { publicKey: PublicKey; bool: boolean; string: string; bytes: Uint8Array; } & { [K in "u8" | "i8" | "u16" | "i16" | "u32" | "i32"]: number; } & { [K in "u64" | "i64" | "u128" | "i128"]: BN; }; type DecodeType = T extends keyof TypeMap ? TypeMap[T] : T extends { defined: keyof Defined } ? Defined[T["defined"]] : T extends { option: { defined: keyof Defined } } ? Defined[T["option"]["defined"]] | null : T extends { option: keyof TypeMap } ? TypeMap[T["option"]] | null : T extends { vec: { defined: keyof Defined } } ? Defined[T["vec"]["defined"]][] : T extends { vec: keyof TypeMap } ? TypeMap[T["vec"]][] : T extends { array: [idlType: keyof TypeMap, size: number] } ? TypeMap[T["array"][0]][] : unknown; type MakeArgs = { [K in keyof A]: A[K] extends IdlField ? DecodeType : unknown; }; type MakeNamedArgs = { [K in A["name"]]: DecodeType<(A & { name: K })["type"], Defined>; }; type MakeInstructions = { [K in I[number]["name"]]: { accounts: (I[number] & { name: K })["accounts"]; args: MakeArgs<(I[number] & { name: K })["args"], Defined> & unknown[]; namedArgs: MakeNamedArgs< (I[number] & { name: K })["args"][number], Defined >; }; }; export type AnchorProgram< IDL extends IdlWithState, A, Defined = AnchorDefined, RPCInstructions extends MakeInstructions< IDL["instructions"], Defined > = MakeInstructions, Methods extends MakeInstructions< NonNullable["methods"], Defined > = MakeInstructions["methods"], Defined>, > = Omit< AProgram, "rpc" | "state" | "account" | "transaction" | "instruction" > & { rpc: RpcNamespace; state: MethodsNamespace; account: AccountsNamespace; transaction: TransactionNamespace; instruction: InstructionNamespace; }; export type AnchorError = NonNullable[number]; type FieldsOfType = I extends { type: IdlTypeDefTyStruct; } ? NonNullable[number] : never; type AnchorTypeDef = { [F in FieldsOfType["name"]]: DecodeType< (FieldsOfType & { name: F })["type"], Defined >; }; type AnchorTypeDefs = { [K in T[number]["name"]]: AnchorTypeDef; }; export type AnchorDefined< T extends Idl, D = Record, > = AnchorTypeDefs, D>; export type AnchorAccounts = AnchorTypeDefs< NonNullable, Defined >; export type AnchorState = AnchorTypeDef< NonNullable["struct"], Defined >; export type AnchorTypes< T extends IdlWithState, AccountMap = Record, D = Record, DEF = AnchorDefined, > = { Defined: DEF; Accounts: AnchorAccounts; State: AnchorState; Error: AnchorError; Program: AnchorProgram; Instructions: MakeInstructions; Methods: MakeInstructions["methods"], DEF>; Events: AnchorEvents[number], DEF>; AccountMap: AccountMap; IDL: T; }; type AnchorEvent = { [N in T["name"]]: DecodeType<(T & { name: N })["type"], Defined>; }; type AnchorEvents = { [K in T["name"]]: { name: K; data: AnchorEvent<(T & { name: K })["fields"][number], Defined>; }; };