transfer.ts 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /**
  2. * This code was AUTOGENERATED using the kinobi library.
  3. * Please DO NOT EDIT THIS FILE, instead use visitors
  4. * to add features, then rerun kinobi to update it.
  5. *
  6. * @see https://github.com/kinobi-so/kinobi
  7. */
  8. import {
  9. AccountRole,
  10. combineCodec,
  11. getStructDecoder,
  12. getStructEncoder,
  13. getU64Decoder,
  14. getU64Encoder,
  15. getU8Decoder,
  16. getU8Encoder,
  17. transformEncoder,
  18. type Address,
  19. type Codec,
  20. type Decoder,
  21. type Encoder,
  22. type IAccountMeta,
  23. type IAccountSignerMeta,
  24. type IInstruction,
  25. type IInstructionWithAccounts,
  26. type IInstructionWithData,
  27. type ReadonlyAccount,
  28. type ReadonlySignerAccount,
  29. type TransactionSigner,
  30. type WritableAccount,
  31. } from '@solana/web3.js';
  32. import { TOKEN_PROGRAM_ADDRESS } from '../programs';
  33. import { getAccountMetaFactory, type ResolvedAccount } from '../shared';
  34. export type TransferInstruction<
  35. TProgram extends string = typeof TOKEN_PROGRAM_ADDRESS,
  36. TAccountSource extends string | IAccountMeta<string> = string,
  37. TAccountDestination extends string | IAccountMeta<string> = string,
  38. TAccountAuthority extends string | IAccountMeta<string> = string,
  39. TRemainingAccounts extends readonly IAccountMeta<string>[] = [],
  40. > = IInstruction<TProgram> &
  41. IInstructionWithData<Uint8Array> &
  42. IInstructionWithAccounts<
  43. [
  44. TAccountSource extends string
  45. ? WritableAccount<TAccountSource>
  46. : TAccountSource,
  47. TAccountDestination extends string
  48. ? WritableAccount<TAccountDestination>
  49. : TAccountDestination,
  50. TAccountAuthority extends string
  51. ? ReadonlyAccount<TAccountAuthority>
  52. : TAccountAuthority,
  53. ...TRemainingAccounts,
  54. ]
  55. >;
  56. export type TransferInstructionData = {
  57. discriminator: number;
  58. /** The amount of tokens to transfer. */
  59. amount: bigint;
  60. };
  61. export type TransferInstructionDataArgs = {
  62. /** The amount of tokens to transfer. */
  63. amount: number | bigint;
  64. };
  65. export function getTransferInstructionDataEncoder(): Encoder<TransferInstructionDataArgs> {
  66. return transformEncoder(
  67. getStructEncoder([
  68. ['discriminator', getU8Encoder()],
  69. ['amount', getU64Encoder()],
  70. ]),
  71. (value) => ({ ...value, discriminator: 3 })
  72. );
  73. }
  74. export function getTransferInstructionDataDecoder(): Decoder<TransferInstructionData> {
  75. return getStructDecoder([
  76. ['discriminator', getU8Decoder()],
  77. ['amount', getU64Decoder()],
  78. ]);
  79. }
  80. export function getTransferInstructionDataCodec(): Codec<
  81. TransferInstructionDataArgs,
  82. TransferInstructionData
  83. > {
  84. return combineCodec(
  85. getTransferInstructionDataEncoder(),
  86. getTransferInstructionDataDecoder()
  87. );
  88. }
  89. export type TransferInput<
  90. TAccountSource extends string = string,
  91. TAccountDestination extends string = string,
  92. TAccountAuthority extends string = string,
  93. > = {
  94. /** The source account. */
  95. source: Address<TAccountSource>;
  96. /** The destination account. */
  97. destination: Address<TAccountDestination>;
  98. /** The source account's owner/delegate or its multisignature account. */
  99. authority: Address<TAccountAuthority> | TransactionSigner<TAccountAuthority>;
  100. amount: TransferInstructionDataArgs['amount'];
  101. multiSigners?: Array<TransactionSigner>;
  102. };
  103. export function getTransferInstruction<
  104. TAccountSource extends string,
  105. TAccountDestination extends string,
  106. TAccountAuthority extends string,
  107. >(
  108. input: TransferInput<TAccountSource, TAccountDestination, TAccountAuthority>
  109. ): TransferInstruction<
  110. typeof TOKEN_PROGRAM_ADDRESS,
  111. TAccountSource,
  112. TAccountDestination,
  113. (typeof input)['authority'] extends TransactionSigner<TAccountAuthority>
  114. ? ReadonlySignerAccount<TAccountAuthority> &
  115. IAccountSignerMeta<TAccountAuthority>
  116. : TAccountAuthority
  117. > {
  118. // Program address.
  119. const programAddress = TOKEN_PROGRAM_ADDRESS;
  120. // Original accounts.
  121. const originalAccounts = {
  122. source: { value: input.source ?? null, isWritable: true },
  123. destination: { value: input.destination ?? null, isWritable: true },
  124. authority: { value: input.authority ?? null, isWritable: false },
  125. };
  126. const accounts = originalAccounts as Record<
  127. keyof typeof originalAccounts,
  128. ResolvedAccount
  129. >;
  130. // Original args.
  131. const args = { ...input };
  132. // Remaining accounts.
  133. const remainingAccounts: IAccountMeta[] = (args.multiSigners ?? []).map(
  134. (signer) => ({
  135. address: signer.address,
  136. role: AccountRole.READONLY_SIGNER,
  137. signer,
  138. })
  139. );
  140. const getAccountMeta = getAccountMetaFactory(programAddress, 'programId');
  141. const instruction = {
  142. accounts: [
  143. getAccountMeta(accounts.source),
  144. getAccountMeta(accounts.destination),
  145. getAccountMeta(accounts.authority),
  146. ...remainingAccounts,
  147. ],
  148. programAddress,
  149. data: getTransferInstructionDataEncoder().encode(
  150. args as TransferInstructionDataArgs
  151. ),
  152. } as TransferInstruction<
  153. typeof TOKEN_PROGRAM_ADDRESS,
  154. TAccountSource,
  155. TAccountDestination,
  156. (typeof input)['authority'] extends TransactionSigner<TAccountAuthority>
  157. ? ReadonlySignerAccount<TAccountAuthority> &
  158. IAccountSignerMeta<TAccountAuthority>
  159. : TAccountAuthority
  160. >;
  161. return instruction;
  162. }
  163. export type ParsedTransferInstruction<
  164. TProgram extends string = typeof TOKEN_PROGRAM_ADDRESS,
  165. TAccountMetas extends readonly IAccountMeta[] = readonly IAccountMeta[],
  166. > = {
  167. programAddress: Address<TProgram>;
  168. accounts: {
  169. /** The source account. */
  170. source: TAccountMetas[0];
  171. /** The destination account. */
  172. destination: TAccountMetas[1];
  173. /** The source account's owner/delegate or its multisignature account. */
  174. authority: TAccountMetas[2];
  175. };
  176. data: TransferInstructionData;
  177. };
  178. export function parseTransferInstruction<
  179. TProgram extends string,
  180. TAccountMetas extends readonly IAccountMeta[],
  181. >(
  182. instruction: IInstruction<TProgram> &
  183. IInstructionWithAccounts<TAccountMetas> &
  184. IInstructionWithData<Uint8Array>
  185. ): ParsedTransferInstruction<TProgram, TAccountMetas> {
  186. if (instruction.accounts.length < 3) {
  187. // TODO: Coded error.
  188. throw new Error('Not enough accounts');
  189. }
  190. let accountIndex = 0;
  191. const getNextAccount = () => {
  192. const accountMeta = instruction.accounts![accountIndex]!;
  193. accountIndex += 1;
  194. return accountMeta;
  195. };
  196. return {
  197. programAddress: instruction.programAddress,
  198. accounts: {
  199. source: getNextAccount(),
  200. destination: getNextAccount(),
  201. authority: getNextAccount(),
  202. },
  203. data: getTransferInstructionDataDecoder().decode(instruction.data),
  204. };
  205. }