Skip to content

Commit 72f510d

Browse files
authored
Merge pull request #265 from solana-foundation/t22-support
Add Token-2022 Program Support
2 parents e9c211a + 1aef700 commit 72f510d

File tree

2 files changed

+513
-178
lines changed

2 files changed

+513
-178
lines changed

core/src/createTransfer.ts

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
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';
29
import type { Commitment, Connection, GetLatestBlockhashConfig, PublicKey } from '@solana/web3.js';
310
import { LAMPORTS_PER_SOL, SystemProgram, Transaction, TransactionInstruction } from '@solana/web3.js';
411
import 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

Comments
 (0)