import { ConfirmOptions, AccountMeta, Signer, Transaction, TransactionInstruction, TransactionSignature, PublicKey, } from "@solana/web3.js"; import { SimulateResponse } from "./simulate.js"; import { TransactionFn } from "./transaction.js"; import { Idl } from "../../idl.js"; import { AllInstructions, MethodsFn, MakeMethodsNamespace } from "./types.js"; import { InstructionFn } from "./instruction.js"; import { RpcFn } from "./rpc.js"; import { SimulateFn } from "./simulate.js"; import { ViewFn } from "./views.js"; import Provider from "../../provider.js"; import { AccountNamespace } from "./account.js"; import { AccountsResolver } from "../accounts-resolver.js"; import { Accounts } from "../context.js"; export type MethodsNamespace< IDL extends Idl = Idl, I extends AllInstructions = AllInstructions > = MakeMethodsNamespace; export class MethodsBuilderFactory { public static build>( provider: Provider, programId: PublicKey, idlIx: AllInstructions, ixFn: InstructionFn, txFn: TransactionFn, rpcFn: RpcFn, simulateFn: SimulateFn, viewFn: ViewFn | undefined, accountNamespace: AccountNamespace ): MethodsFn> { return (...args) => new MethodsBuilder( args, ixFn, txFn, rpcFn, simulateFn, viewFn, provider, programId, idlIx, accountNamespace ); } } export class MethodsBuilder> { private readonly _accounts: { [name: string]: PublicKey } = {}; private _remainingAccounts: Array = []; private _signers: Array = []; private _preInstructions: Array = []; private _postInstructions: Array = []; private _accountsResolver: AccountsResolver; constructor( private _args: Array, private _ixFn: InstructionFn, private _txFn: TransactionFn, private _rpcFn: RpcFn, private _simulateFn: SimulateFn, private _viewFn: ViewFn | undefined, _provider: Provider, _programId: PublicKey, _idlIx: AllInstructions, _accountNamespace: AccountNamespace ) { this._accountsResolver = new AccountsResolver( _args, this._accounts, _provider, _programId, _idlIx, _accountNamespace ); } public accounts( accounts: Partial> ): MethodsBuilder { Object.assign(this._accounts, accounts); return this; } public signers(signers: Array): MethodsBuilder { this._signers = this._signers.concat(signers); return this; } public remainingAccounts( accounts: Array ): MethodsBuilder { this._remainingAccounts = this._remainingAccounts.concat(accounts); return this; } public preInstructions( ixs: Array ): MethodsBuilder { this._preInstructions = this._preInstructions.concat(ixs); return this; } public postInstructions( ixs: Array ): MethodsBuilder { this._postInstructions = this._postInstructions.concat(ixs); return this; } public async rpc(options?: ConfirmOptions): Promise { await this._accountsResolver.resolve(); // @ts-ignore return this._rpcFn(...this._args, { accounts: this._accounts, signers: this._signers, remainingAccounts: this._remainingAccounts, preInstructions: this._preInstructions, postInstructions: this._postInstructions, options: options, }); } public async view(options?: ConfirmOptions): Promise { await this._accountsResolver.resolve(); if (!this._viewFn) { throw new Error("Method does not support views"); } // @ts-ignore return this._viewFn(...this._args, { accounts: this._accounts, signers: this._signers, remainingAccounts: this._remainingAccounts, preInstructions: this._preInstructions, postInstructions: this._postInstructions, options: options, }); } public async simulate( options?: ConfirmOptions ): Promise> { await this._accountsResolver.resolve(); // @ts-ignore return this._simulateFn(...this._args, { accounts: this._accounts, signers: this._signers, remainingAccounts: this._remainingAccounts, preInstructions: this._preInstructions, postInstructions: this._postInstructions, options: options, }); } public async instruction(): Promise { await this._accountsResolver.resolve(); // @ts-ignore return this._ixFn(...this._args, { accounts: this._accounts, signers: this._signers, remainingAccounts: this._remainingAccounts, preInstructions: this._preInstructions, postInstructions: this._postInstructions, }); } public async transaction(): Promise { await this._accountsResolver.resolve(); // @ts-ignore return this._txFn(...this._args, { accounts: this._accounts, signers: this._signers, remainingAccounts: this._remainingAccounts, preInstructions: this._preInstructions, postInstructions: this._postInstructions, }); } }