11import {
2+ TOKEN_2022_PROGRAM_ID ,
23 TOKEN_PROGRAM_ID ,
34 TokenAccountNotFoundError ,
45 createAssociatedTokenAccountInstruction ,
5- createTransferInstruction ,
6+ createTransferCheckedInstruction ,
67 getAccount ,
78 getAssociatedTokenAddressSync ,
89 getMint
910} from '@solana/spl-token'
1011import {
1112 ComputeBudgetProgram ,
13+ Connection ,
1214 PublicKey ,
1315 Transaction ,
1416 type TransactionInstruction
@@ -17,6 +19,24 @@ import {
1719import { SPL_COMPUTE_BUDGET_CONSTANTS } from '@reown/appkit-utils/solana'
1820import type { SPLTokenTransactionArgs } from '@reown/appkit-utils/solana'
1921
22+ async function getMintOwnerProgramId ( connection : Connection , mint : PublicKey ) {
23+ const info = await connection . getAccountInfo ( mint )
24+
25+ if ( ! info ) {
26+ throw new Error ( 'Mint account not found' )
27+ }
28+
29+ if ( info . owner . equals ( TOKEN_PROGRAM_ID ) ) {
30+ return TOKEN_PROGRAM_ID
31+ }
32+
33+ if ( info . owner . equals ( TOKEN_2022_PROGRAM_ID ) ) {
34+ return TOKEN_2022_PROGRAM_ID
35+ }
36+
37+ throw new Error ( 'Unknown mint owner program' )
38+ }
39+
2040export async function createSPLTokenTransaction ( {
2141 provider,
2242 to,
@@ -27,30 +47,29 @@ export async function createSPLTokenTransaction({
2747 if ( ! provider . publicKey ) {
2848 throw new Error ( 'No public key found' )
2949 }
30-
3150 if ( amount <= 0 ) {
3251 throw new Error ( 'Amount must be greater than 0' )
3352 }
34-
3553 try {
3654 const fromPubkey = provider . publicKey
3755 const toPubkey = new PublicKey ( to )
3856 const mintPubkey = new PublicKey ( tokenMint )
3957
40- const mintInfo = await getMint ( connection , mintPubkey )
41- const decimals = mintInfo . decimals
58+ const programId = await getMintOwnerProgramId ( connection , mintPubkey )
4259
60+ const mintInfo = await getMint ( connection , mintPubkey , undefined , programId )
61+ const decimals = mintInfo . decimals
4362 if ( decimals < 0 ) {
4463 throw new Error ( 'Invalid token decimals' )
4564 }
4665
4766 const tokenAmount = Math . floor ( amount * 10 ** decimals )
4867
49- const fromTokenAccount = getAssociatedTokenAddressSync ( mintPubkey , fromPubkey )
50- const toTokenAccount = getAssociatedTokenAddressSync ( mintPubkey , toPubkey )
68+ const fromTokenAccount = getAssociatedTokenAddressSync ( mintPubkey , fromPubkey , false , programId )
69+ const toTokenAccount = getAssociatedTokenAddressSync ( mintPubkey , toPubkey , false , programId )
5170
5271 try {
53- const fromAccount = await getAccount ( connection , fromTokenAccount )
72+ const fromAccount = await getAccount ( connection , fromTokenAccount , undefined , programId )
5473 if ( fromAccount . amount < BigInt ( tokenAmount ) ) {
5574 throw new Error ( 'Insufficient token balance' )
5675 }
@@ -63,7 +82,7 @@ export async function createSPLTokenTransaction({
6382
6483 let shouldCreateATA = false
6584 try {
66- await getAccount ( connection , toTokenAccount )
85+ await getAccount ( connection , toTokenAccount , undefined , programId )
6786 } catch ( error ) {
6887 if ( error instanceof TokenAccountNotFoundError ) {
6988 shouldCreateATA = true
@@ -87,18 +106,26 @@ export async function createSPLTokenTransaction({
87106
88107 if ( shouldCreateATA ) {
89108 instructions . push (
90- createAssociatedTokenAccountInstruction ( fromPubkey , toTokenAccount , toPubkey , mintPubkey )
109+ createAssociatedTokenAccountInstruction (
110+ fromPubkey ,
111+ toTokenAccount ,
112+ toPubkey ,
113+ mintPubkey ,
114+ programId
115+ )
91116 )
92117 }
93118
94119 instructions . push (
95- createTransferInstruction (
120+ createTransferCheckedInstruction (
96121 fromTokenAccount ,
122+ mintPubkey ,
97123 toTokenAccount ,
98124 fromPubkey ,
99125 tokenAmount ,
126+ decimals ,
100127 [ ] ,
101- TOKEN_PROGRAM_ID
128+ programId
102129 )
103130 )
104131
0 commit comments