transfer.ts 6.7 KB

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