createAssociatedToken.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  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. combineCodec,
  10. getStructDecoder,
  11. getStructEncoder,
  12. getU8Decoder,
  13. getU8Encoder,
  14. transformEncoder,
  15. type AccountMeta,
  16. type AccountSignerMeta,
  17. type Address,
  18. type FixedSizeCodec,
  19. type FixedSizeDecoder,
  20. type FixedSizeEncoder,
  21. type Instruction,
  22. type InstructionWithAccounts,
  23. type InstructionWithData,
  24. type ReadonlyAccount,
  25. type ReadonlyUint8Array,
  26. type TransactionSigner,
  27. type WritableAccount,
  28. type WritableSignerAccount,
  29. } from '@solana/kit';
  30. import { findAssociatedTokenPda } from '../pdas';
  31. import { ASSOCIATED_TOKEN_PROGRAM_ADDRESS } from '../programs';
  32. import {
  33. expectAddress,
  34. getAccountMetaFactory,
  35. type ResolvedAccount,
  36. } from '../shared';
  37. export const CREATE_ASSOCIATED_TOKEN_DISCRIMINATOR = 0;
  38. export function getCreateAssociatedTokenDiscriminatorBytes() {
  39. return getU8Encoder().encode(CREATE_ASSOCIATED_TOKEN_DISCRIMINATOR);
  40. }
  41. export type CreateAssociatedTokenInstruction<
  42. TProgram extends string = typeof ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
  43. TAccountPayer extends string | AccountMeta<string> = string,
  44. TAccountAta extends string | AccountMeta<string> = string,
  45. TAccountOwner extends string | AccountMeta<string> = string,
  46. TAccountMint extends string | AccountMeta<string> = string,
  47. TAccountSystemProgram extends
  48. | string
  49. | AccountMeta<string> = '11111111111111111111111111111111',
  50. TAccountTokenProgram extends
  51. | string
  52. | AccountMeta<string> = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
  53. TRemainingAccounts extends readonly AccountMeta<string>[] = [],
  54. > = Instruction<TProgram> &
  55. InstructionWithData<ReadonlyUint8Array> &
  56. InstructionWithAccounts<
  57. [
  58. TAccountPayer extends string
  59. ? WritableSignerAccount<TAccountPayer> &
  60. AccountSignerMeta<TAccountPayer>
  61. : TAccountPayer,
  62. TAccountAta extends string ? WritableAccount<TAccountAta> : TAccountAta,
  63. TAccountOwner extends string
  64. ? ReadonlyAccount<TAccountOwner>
  65. : TAccountOwner,
  66. TAccountMint extends string
  67. ? ReadonlyAccount<TAccountMint>
  68. : TAccountMint,
  69. TAccountSystemProgram extends string
  70. ? ReadonlyAccount<TAccountSystemProgram>
  71. : TAccountSystemProgram,
  72. TAccountTokenProgram extends string
  73. ? ReadonlyAccount<TAccountTokenProgram>
  74. : TAccountTokenProgram,
  75. ...TRemainingAccounts,
  76. ]
  77. >;
  78. export type CreateAssociatedTokenInstructionData = { discriminator: number };
  79. export type CreateAssociatedTokenInstructionDataArgs = {};
  80. export function getCreateAssociatedTokenInstructionDataEncoder(): FixedSizeEncoder<CreateAssociatedTokenInstructionDataArgs> {
  81. return transformEncoder(
  82. getStructEncoder([['discriminator', getU8Encoder()]]),
  83. (value) => ({
  84. ...value,
  85. discriminator: CREATE_ASSOCIATED_TOKEN_DISCRIMINATOR,
  86. })
  87. ) as FixedSizeEncoder<CreateAssociatedTokenInstructionDataArgs>;
  88. }
  89. export function getCreateAssociatedTokenInstructionDataDecoder(): FixedSizeDecoder<CreateAssociatedTokenInstructionData> {
  90. return getStructDecoder([
  91. ['discriminator', getU8Decoder()],
  92. ]) as FixedSizeDecoder<CreateAssociatedTokenInstructionData>;
  93. }
  94. export function getCreateAssociatedTokenInstructionDataCodec(): FixedSizeCodec<
  95. CreateAssociatedTokenInstructionDataArgs,
  96. CreateAssociatedTokenInstructionData
  97. > {
  98. return combineCodec(
  99. getCreateAssociatedTokenInstructionDataEncoder(),
  100. getCreateAssociatedTokenInstructionDataDecoder()
  101. ) as FixedSizeCodec<
  102. CreateAssociatedTokenInstructionDataArgs,
  103. CreateAssociatedTokenInstructionData
  104. >;
  105. }
  106. export type CreateAssociatedTokenAsyncInput<
  107. TAccountPayer extends string = string,
  108. TAccountAta extends string = string,
  109. TAccountOwner extends string = string,
  110. TAccountMint extends string = string,
  111. TAccountSystemProgram extends string = string,
  112. TAccountTokenProgram extends string = string,
  113. > = {
  114. /** Funding account (must be a system account). */
  115. payer: TransactionSigner<TAccountPayer>;
  116. /** Associated token account address to be created. */
  117. ata?: Address<TAccountAta>;
  118. /** Wallet address for the new associated token account. */
  119. owner: Address<TAccountOwner>;
  120. /** The token mint for the new associated token account. */
  121. mint: Address<TAccountMint>;
  122. /** System program. */
  123. systemProgram?: Address<TAccountSystemProgram>;
  124. /** SPL Token program. */
  125. tokenProgram?: Address<TAccountTokenProgram>;
  126. };
  127. export async function getCreateAssociatedTokenInstructionAsync<
  128. TAccountPayer extends string,
  129. TAccountAta extends string,
  130. TAccountOwner extends string,
  131. TAccountMint extends string,
  132. TAccountSystemProgram extends string,
  133. TAccountTokenProgram extends string,
  134. TProgramAddress extends Address = typeof ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
  135. >(
  136. input: CreateAssociatedTokenAsyncInput<
  137. TAccountPayer,
  138. TAccountAta,
  139. TAccountOwner,
  140. TAccountMint,
  141. TAccountSystemProgram,
  142. TAccountTokenProgram
  143. >,
  144. config?: { programAddress?: TProgramAddress }
  145. ): Promise<
  146. CreateAssociatedTokenInstruction<
  147. TProgramAddress,
  148. TAccountPayer,
  149. TAccountAta,
  150. TAccountOwner,
  151. TAccountMint,
  152. TAccountSystemProgram,
  153. TAccountTokenProgram
  154. >
  155. > {
  156. // Program address.
  157. const programAddress =
  158. config?.programAddress ?? ASSOCIATED_TOKEN_PROGRAM_ADDRESS;
  159. // Original accounts.
  160. const originalAccounts = {
  161. payer: { value: input.payer ?? null, isWritable: true },
  162. ata: { value: input.ata ?? null, isWritable: true },
  163. owner: { value: input.owner ?? null, isWritable: false },
  164. mint: { value: input.mint ?? null, isWritable: false },
  165. systemProgram: { value: input.systemProgram ?? null, isWritable: false },
  166. tokenProgram: { value: input.tokenProgram ?? null, isWritable: false },
  167. };
  168. const accounts = originalAccounts as Record<
  169. keyof typeof originalAccounts,
  170. ResolvedAccount
  171. >;
  172. // Resolve default values.
  173. if (!accounts.tokenProgram.value) {
  174. accounts.tokenProgram.value =
  175. 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;
  176. }
  177. if (!accounts.ata.value) {
  178. accounts.ata.value = await findAssociatedTokenPda({
  179. owner: expectAddress(accounts.owner.value),
  180. tokenProgram: expectAddress(accounts.tokenProgram.value),
  181. mint: expectAddress(accounts.mint.value),
  182. });
  183. }
  184. if (!accounts.systemProgram.value) {
  185. accounts.systemProgram.value =
  186. '11111111111111111111111111111111' as Address<'11111111111111111111111111111111'>;
  187. }
  188. const getAccountMeta = getAccountMetaFactory(programAddress, 'programId');
  189. const instruction = {
  190. accounts: [
  191. getAccountMeta(accounts.payer),
  192. getAccountMeta(accounts.ata),
  193. getAccountMeta(accounts.owner),
  194. getAccountMeta(accounts.mint),
  195. getAccountMeta(accounts.systemProgram),
  196. getAccountMeta(accounts.tokenProgram),
  197. ],
  198. programAddress,
  199. data: getCreateAssociatedTokenInstructionDataEncoder().encode({}),
  200. } as CreateAssociatedTokenInstruction<
  201. TProgramAddress,
  202. TAccountPayer,
  203. TAccountAta,
  204. TAccountOwner,
  205. TAccountMint,
  206. TAccountSystemProgram,
  207. TAccountTokenProgram
  208. >;
  209. return instruction;
  210. }
  211. export type CreateAssociatedTokenInput<
  212. TAccountPayer extends string = string,
  213. TAccountAta extends string = string,
  214. TAccountOwner extends string = string,
  215. TAccountMint extends string = string,
  216. TAccountSystemProgram extends string = string,
  217. TAccountTokenProgram extends string = string,
  218. > = {
  219. /** Funding account (must be a system account). */
  220. payer: TransactionSigner<TAccountPayer>;
  221. /** Associated token account address to be created. */
  222. ata: Address<TAccountAta>;
  223. /** Wallet address for the new associated token account. */
  224. owner: Address<TAccountOwner>;
  225. /** The token mint for the new associated token account. */
  226. mint: Address<TAccountMint>;
  227. /** System program. */
  228. systemProgram?: Address<TAccountSystemProgram>;
  229. /** SPL Token program. */
  230. tokenProgram?: Address<TAccountTokenProgram>;
  231. };
  232. export function getCreateAssociatedTokenInstruction<
  233. TAccountPayer extends string,
  234. TAccountAta extends string,
  235. TAccountOwner extends string,
  236. TAccountMint extends string,
  237. TAccountSystemProgram extends string,
  238. TAccountTokenProgram extends string,
  239. TProgramAddress extends Address = typeof ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
  240. >(
  241. input: CreateAssociatedTokenInput<
  242. TAccountPayer,
  243. TAccountAta,
  244. TAccountOwner,
  245. TAccountMint,
  246. TAccountSystemProgram,
  247. TAccountTokenProgram
  248. >,
  249. config?: { programAddress?: TProgramAddress }
  250. ): CreateAssociatedTokenInstruction<
  251. TProgramAddress,
  252. TAccountPayer,
  253. TAccountAta,
  254. TAccountOwner,
  255. TAccountMint,
  256. TAccountSystemProgram,
  257. TAccountTokenProgram
  258. > {
  259. // Program address.
  260. const programAddress =
  261. config?.programAddress ?? ASSOCIATED_TOKEN_PROGRAM_ADDRESS;
  262. // Original accounts.
  263. const originalAccounts = {
  264. payer: { value: input.payer ?? null, isWritable: true },
  265. ata: { value: input.ata ?? null, isWritable: true },
  266. owner: { value: input.owner ?? null, isWritable: false },
  267. mint: { value: input.mint ?? null, isWritable: false },
  268. systemProgram: { value: input.systemProgram ?? null, isWritable: false },
  269. tokenProgram: { value: input.tokenProgram ?? null, isWritable: false },
  270. };
  271. const accounts = originalAccounts as Record<
  272. keyof typeof originalAccounts,
  273. ResolvedAccount
  274. >;
  275. // Resolve default values.
  276. if (!accounts.tokenProgram.value) {
  277. accounts.tokenProgram.value =
  278. 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;
  279. }
  280. if (!accounts.systemProgram.value) {
  281. accounts.systemProgram.value =
  282. '11111111111111111111111111111111' as Address<'11111111111111111111111111111111'>;
  283. }
  284. const getAccountMeta = getAccountMetaFactory(programAddress, 'programId');
  285. const instruction = {
  286. accounts: [
  287. getAccountMeta(accounts.payer),
  288. getAccountMeta(accounts.ata),
  289. getAccountMeta(accounts.owner),
  290. getAccountMeta(accounts.mint),
  291. getAccountMeta(accounts.systemProgram),
  292. getAccountMeta(accounts.tokenProgram),
  293. ],
  294. programAddress,
  295. data: getCreateAssociatedTokenInstructionDataEncoder().encode({}),
  296. } as CreateAssociatedTokenInstruction<
  297. TProgramAddress,
  298. TAccountPayer,
  299. TAccountAta,
  300. TAccountOwner,
  301. TAccountMint,
  302. TAccountSystemProgram,
  303. TAccountTokenProgram
  304. >;
  305. return instruction;
  306. }
  307. export type ParsedCreateAssociatedTokenInstruction<
  308. TProgram extends string = typeof ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
  309. TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[],
  310. > = {
  311. programAddress: Address<TProgram>;
  312. accounts: {
  313. /** Funding account (must be a system account). */
  314. payer: TAccountMetas[0];
  315. /** Associated token account address to be created. */
  316. ata: TAccountMetas[1];
  317. /** Wallet address for the new associated token account. */
  318. owner: TAccountMetas[2];
  319. /** The token mint for the new associated token account. */
  320. mint: TAccountMetas[3];
  321. /** System program. */
  322. systemProgram: TAccountMetas[4];
  323. /** SPL Token program. */
  324. tokenProgram: TAccountMetas[5];
  325. };
  326. data: CreateAssociatedTokenInstructionData;
  327. };
  328. export function parseCreateAssociatedTokenInstruction<
  329. TProgram extends string,
  330. TAccountMetas extends readonly AccountMeta[],
  331. >(
  332. instruction: Instruction<TProgram> &
  333. InstructionWithAccounts<TAccountMetas> &
  334. InstructionWithData<ReadonlyUint8Array>
  335. ): ParsedCreateAssociatedTokenInstruction<TProgram, TAccountMetas> {
  336. if (instruction.accounts.length < 6) {
  337. // TODO: Coded error.
  338. throw new Error('Not enough accounts');
  339. }
  340. let accountIndex = 0;
  341. const getNextAccount = () => {
  342. const accountMeta = instruction.accounts![accountIndex]!;
  343. accountIndex += 1;
  344. return accountMeta;
  345. };
  346. return {
  347. programAddress: instruction.programAddress,
  348. accounts: {
  349. payer: getNextAccount(),
  350. ata: getNextAccount(),
  351. owner: getNextAccount(),
  352. mint: getNextAccount(),
  353. systemProgram: getNextAccount(),
  354. tokenProgram: getNextAccount(),
  355. },
  356. data: getCreateAssociatedTokenInstructionDataDecoder().decode(
  357. instruction.data
  358. ),
  359. };
  360. }