import type { Accounts , Idl } from "@project-serum/anchor" ; import { AccountsCoder , Coder , EventParser } from "@project-serum/anchor" ; import type { InstructionDisplay } from "@project-serum/anchor/dist/cjs/coder/instruction" ; import type { IdlAccountItem } from "@project-serum/anchor/dist/cjs/idl" ; import InstructionNamespaceFactory from "@project-serum/anchor/dist/cjs/program/namespace/instruction" ; import type { Provider as SaberProvider } from "@saberhq/solana-contrib" ; import type { PublicKey } from "@solana/web3.js" ; import { TransactionInstruction } from "@solana/web3.js" ; import mapValues from "lodash.mapvalues" ; import type { ErrorMap } from "../errors" ; import { generateErrorMap } from "../errors" ; import type { AccountParsers } from "../generateAccountParsers" ; import { generateAccountParsersFromCoder } from "../generateAccountParsers" ; import { newProgram } from "./programs" ; /**
 * Formatted instruction with its name.
 */ export type InstructionParsed = InstructionDisplay & { name : string ; } ; type CoderAnchorTypes = { AccountMap : Record < string , object > ; Events : Record < string , unknown > ; IDL : Idl ; Instructions : Record < string , { accounts : IdlAccountItem [ ] ; args : unknown [ ] ; namedArgs : Record < string , unknown > ; } > ; Program : unknown ; } ; /**
 * Coder wrapper.
 *
 * Allows interacting with a program without a provider.
 */ export class SuperCoder < T extends CoderAnchorTypes > { /**
     * Underlying Coder.
     */ readonly coder : Coder ; /**
     * Parses events.
     */ readonly eventParser : EventParser ; /**
     * Parses accounts.
     */ readonly accountParsers : AccountParsers < T [ "AccountMap" ] > ; /**
     * Mapping of error name to error details.
     */ readonly errorMap : ErrorMap < T [ "IDL" ] > ; /**
     * Mapping of hex discriminator to the account name.
     */ readonly discriminators : { [ hexDiscriminator ] : string ; } ; param address param idl constructor ( /**
     * Program address.
     */ readonly address , /**
     * Program IDL.
     */ readonly idl ) { this . coder = new Coder ( idl ) ; this . eventParser = new EventParser ( address , this . coder ) ; this . accountParsers = generateAccountParsersFromCoder ( idl . accounts ?. map ( ( acc ) => acc . name ) , this . coder . accounts ) ; this . errorMap = generateErrorMap < T [ "IDL" ] > ( idl ) ; this . discriminators = ( idl . accounts ?. map ( ( account ) => ( { name : account . name , discriminator : AccountsCoder . accountDiscriminator ( account . name ) . toString ( "hex" ) , } ) ) ?? [ ] ) . reduce ( ( acc , el ) => ( { ... acc , [ el . discriminator ] : el . name } ) , { } ) ; } param logs returns parseProgramLogEvents < E extends T [ "Events" ] [ keyof T [ "Events" ] ] = T [ "Events" ] [ keyof T [ "Events" ] ] > ( logs ? ) { if ( ! logs ) { return [ ] ; } const events = [ ] ; this . eventParser . parseLogs ( logs ?? [ ] , ( event ) => events . push ( event as unknown as E ) ) ; return events ; } /**
     * Encodes a  TransactionInstruction .
     *  returns encodeIX < K extends keyof T [ "Instructions" ] & string = keyof T [ "Instructions" ] & string , I extends T [ "Instructions" ] [ K ] = T [ "Instructions" ] [ K ] > ( name , args , accounts ) { const idlIx = this . idl . instructions . find ( ( ix ) => ix . name === name ) ; if ( ! idlIx ) { throw new Error ( `could not find ix: ${ name }` ) ; } const encoded = this . coder . instruction . encode ( name , args ) ; const keys = InstructionNamespaceFactory . accountsArray ( accounts , idlIx . accounts , name ) ; return new TransactionInstruction ( { programId : this . address , keys , data : encoded , } ) ; } /**
     * Parses a  TransactionInstruction .
     *  returns parseInstruction ( txInstruction ) { const decoded = this . coder . instruction . decode ( txInstruction . data ) ; if ( ! decoded ) { throw new Error ( "could not decode ix data" ) ; } const fmt = this . coder . instruction . format ( decoded , txInstruction . keys ) ; if ( ! fmt ) { throw new Error ( "invalid instruction" ) ; } return { ... fmt , name : decoded . name } ; } /**
     * Gets a  Program from a provider.
     *  param provider returns getProgram ( provider ) { return newProgram ( this . idl , this . address , provider ) ; } } param provider param programs returns export const buildCoderMap = < P extends { [ K in keyof P ] : CoderAnchorTypes ; } > ( idls , addresses ) : { [ K in keyof P ] : SuperCoder < P [ K ] > ; } => { return mapValues ( idls , < K extends keyof P > ( idl , k ) => new SuperCoder < P [ K ] > ( addresses [ k ] , idl ) ) as unknown as { [ K in keyof P ] : SuperCoder < P [ K ] > ; } ; } ;