1- import { createTransferCheckedInstruction , getAccount , getAssociatedTokenAddress , getMint } from '@solana/spl-token' ;
1+ import {
2+ createTransferCheckedInstruction ,
3+ getAccount ,
4+ getAssociatedTokenAddress ,
5+ getMint ,
6+ TOKEN_2022_PROGRAM_ID ,
7+ TOKEN_PROGRAM_ID ,
8+ } from '@solana/spl-token' ;
29import type { Commitment , Connection , GetLatestBlockhashConfig , PublicKey } from '@solana/web3.js' ;
310import { LAMPORTS_PER_SOL , SystemProgram , Transaction , TransactionInstruction } from '@solana/web3.js' ;
411import BigNumber from 'bignumber.js' ;
@@ -133,8 +140,14 @@ async function createSPLTokenInstruction(
133140 sender : PublicKey ,
134141 connection : Connection
135142) : Promise < TransactionInstruction > {
143+ // Check if token owns the Token-2022 Program
144+ const accountInfo = await connection . getParsedAccountInfo ( splToken ) ;
145+ const accountOwner = accountInfo . value ?. owner ;
146+ const tokenProgram =
147+ accountOwner && accountOwner === TOKEN_2022_PROGRAM_ID ? TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID ;
148+
136149 // Check that the token provided is an initialized mint
137- const mint = await getMint ( connection , splToken ) ;
150+ const mint = await getMint ( connection , splToken , undefined , tokenProgram ) ;
138151 if ( ! mint . isInitialized ) throw new CreateTransferError ( 'mint not initialized' ) ;
139152
140153 // Check that the amount provided doesn't have greater precision than the mint
@@ -144,14 +157,14 @@ async function createSPLTokenInstruction(
144157 amount = amount . times ( TEN . pow ( mint . decimals ) ) . integerValue ( BigNumber . ROUND_FLOOR ) ;
145158
146159 // Get the sender's ATA and check that the account exists and can send tokens
147- const senderATA = await getAssociatedTokenAddress ( splToken , sender ) ;
148- const senderAccount = await getAccount ( connection , senderATA ) ;
160+ const senderATA = await getAssociatedTokenAddress ( splToken , sender , undefined , tokenProgram ) ;
161+ const senderAccount = await getAccount ( connection , senderATA , undefined , tokenProgram ) ;
149162 if ( ! senderAccount . isInitialized ) throw new CreateTransferError ( 'sender not initialized' ) ;
150163 if ( senderAccount . isFrozen ) throw new CreateTransferError ( 'sender frozen' ) ;
151164
152165 // Get the recipient's ATA and check that the account exists and can receive tokens
153- const recipientATA = await getAssociatedTokenAddress ( splToken , recipient ) ;
154- const recipientAccount = await getAccount ( connection , recipientATA ) ;
166+ const recipientATA = await getAssociatedTokenAddress ( splToken , recipient , undefined , tokenProgram ) ;
167+ const recipientAccount = await getAccount ( connection , recipientATA , undefined , tokenProgram ) ;
155168 if ( ! recipientAccount . isInitialized ) throw new CreateTransferError ( 'recipient not initialized' ) ;
156169 if ( recipientAccount . isFrozen ) throw new CreateTransferError ( 'recipient frozen' ) ;
157170
@@ -160,5 +173,14 @@ async function createSPLTokenInstruction(
160173 if ( tokens > senderAccount . amount ) throw new CreateTransferError ( 'insufficient funds' ) ;
161174
162175 // Create an instruction to transfer SPL tokens, asserting the mint and decimals match
163- return createTransferCheckedInstruction ( senderATA , splToken , recipientATA , sender , tokens , mint . decimals ) ;
176+ return createTransferCheckedInstruction (
177+ senderATA ,
178+ splToken ,
179+ recipientATA ,
180+ sender ,
181+ tokens ,
182+ mint . decimals ,
183+ [ ] ,
184+ tokenProgram
185+ ) ;
164186}
0 commit comments