methods.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import {
  2. ConfirmOptions,
  3. AccountMeta,
  4. Signer,
  5. Transaction,
  6. TransactionInstruction,
  7. TransactionSignature,
  8. PublicKey,
  9. } from "@solana/web3.js";
  10. import { SimulateResponse } from "./simulate.js";
  11. import { TransactionFn } from "./transaction.js";
  12. import { Idl } from "../../idl.js";
  13. import { AllInstructions, MethodsFn, MakeMethodsNamespace } from "./types.js";
  14. import { InstructionFn } from "./instruction.js";
  15. import { RpcFn } from "./rpc.js";
  16. import { SimulateFn } from "./simulate.js";
  17. import { ViewFn } from "./views.js";
  18. import Provider from "../../provider.js";
  19. import { AccountNamespace } from "./account.js";
  20. import { AccountsResolver } from "../accounts-resolver.js";
  21. import { Accounts } from "../context.js";
  22. export type MethodsNamespace<
  23. IDL extends Idl = Idl,
  24. I extends AllInstructions<IDL> = AllInstructions<IDL>
  25. > = MakeMethodsNamespace<IDL, I>;
  26. export class MethodsBuilderFactory {
  27. public static build<IDL extends Idl, I extends AllInstructions<IDL>>(
  28. provider: Provider,
  29. programId: PublicKey,
  30. idlIx: AllInstructions<IDL>,
  31. ixFn: InstructionFn<IDL>,
  32. txFn: TransactionFn<IDL>,
  33. rpcFn: RpcFn<IDL>,
  34. simulateFn: SimulateFn<IDL>,
  35. viewFn: ViewFn<IDL> | undefined,
  36. accountNamespace: AccountNamespace<IDL>
  37. ): MethodsFn<IDL, I, MethodsBuilder<IDL, I>> {
  38. return (...args) =>
  39. new MethodsBuilder(
  40. args,
  41. ixFn,
  42. txFn,
  43. rpcFn,
  44. simulateFn,
  45. viewFn,
  46. provider,
  47. programId,
  48. idlIx,
  49. accountNamespace
  50. );
  51. }
  52. }
  53. export class MethodsBuilder<IDL extends Idl, I extends AllInstructions<IDL>> {
  54. private readonly _accounts: { [name: string]: PublicKey } = {};
  55. private _remainingAccounts: Array<AccountMeta> = [];
  56. private _signers: Array<Signer> = [];
  57. private _preInstructions: Array<TransactionInstruction> = [];
  58. private _postInstructions: Array<TransactionInstruction> = [];
  59. private _accountsResolver: AccountsResolver<IDL, I>;
  60. constructor(
  61. private _args: Array<any>,
  62. private _ixFn: InstructionFn<IDL>,
  63. private _txFn: TransactionFn<IDL>,
  64. private _rpcFn: RpcFn<IDL>,
  65. private _simulateFn: SimulateFn<IDL>,
  66. private _viewFn: ViewFn<IDL> | undefined,
  67. _provider: Provider,
  68. _programId: PublicKey,
  69. _idlIx: AllInstructions<IDL>,
  70. _accountNamespace: AccountNamespace<IDL>
  71. ) {
  72. this._accountsResolver = new AccountsResolver(
  73. _args,
  74. this._accounts,
  75. _provider,
  76. _programId,
  77. _idlIx,
  78. _accountNamespace
  79. );
  80. }
  81. public accounts(
  82. accounts: Partial<Accounts<I["accounts"][number]>>
  83. ): MethodsBuilder<IDL, I> {
  84. Object.assign(this._accounts, accounts);
  85. return this;
  86. }
  87. public signers(signers: Array<Signer>): MethodsBuilder<IDL, I> {
  88. this._signers = this._signers.concat(signers);
  89. return this;
  90. }
  91. public remainingAccounts(
  92. accounts: Array<AccountMeta>
  93. ): MethodsBuilder<IDL, I> {
  94. this._remainingAccounts = this._remainingAccounts.concat(accounts);
  95. return this;
  96. }
  97. public preInstructions(
  98. ixs: Array<TransactionInstruction>
  99. ): MethodsBuilder<IDL, I> {
  100. this._preInstructions = this._preInstructions.concat(ixs);
  101. return this;
  102. }
  103. public postInstructions(
  104. ixs: Array<TransactionInstruction>
  105. ): MethodsBuilder<IDL, I> {
  106. this._postInstructions = this._postInstructions.concat(ixs);
  107. return this;
  108. }
  109. public async rpc(options?: ConfirmOptions): Promise<TransactionSignature> {
  110. await this._accountsResolver.resolve();
  111. // @ts-ignore
  112. return this._rpcFn(...this._args, {
  113. accounts: this._accounts,
  114. signers: this._signers,
  115. remainingAccounts: this._remainingAccounts,
  116. preInstructions: this._preInstructions,
  117. postInstructions: this._postInstructions,
  118. options: options,
  119. });
  120. }
  121. public async view(options?: ConfirmOptions): Promise<any> {
  122. await this._accountsResolver.resolve();
  123. if (!this._viewFn) {
  124. throw new Error("Method does not support views");
  125. }
  126. // @ts-ignore
  127. return this._viewFn(...this._args, {
  128. accounts: this._accounts,
  129. signers: this._signers,
  130. remainingAccounts: this._remainingAccounts,
  131. preInstructions: this._preInstructions,
  132. postInstructions: this._postInstructions,
  133. options: options,
  134. });
  135. }
  136. public async simulate(
  137. options?: ConfirmOptions
  138. ): Promise<SimulateResponse<any, any>> {
  139. await this._accountsResolver.resolve();
  140. // @ts-ignore
  141. return this._simulateFn(...this._args, {
  142. accounts: this._accounts,
  143. signers: this._signers,
  144. remainingAccounts: this._remainingAccounts,
  145. preInstructions: this._preInstructions,
  146. postInstructions: this._postInstructions,
  147. options: options,
  148. });
  149. }
  150. public async instruction(): Promise<TransactionInstruction> {
  151. await this._accountsResolver.resolve();
  152. // @ts-ignore
  153. return this._ixFn(...this._args, {
  154. accounts: this._accounts,
  155. signers: this._signers,
  156. remainingAccounts: this._remainingAccounts,
  157. preInstructions: this._preInstructions,
  158. postInstructions: this._postInstructions,
  159. });
  160. }
  161. public async transaction(): Promise<Transaction> {
  162. await this._accountsResolver.resolve();
  163. // @ts-ignore
  164. return this._txFn(...this._args, {
  165. accounts: this._accounts,
  166. signers: this._signers,
  167. remainingAccounts: this._remainingAccounts,
  168. preInstructions: this._preInstructions,
  169. postInstructions: this._postInstructions,
  170. });
  171. }
  172. }