2

We are given some public key that may be a token account (could be ATA or not) and want to find out if it is. Currently I am doing this by calling getAccount from @solana/spl-token and seeing if it throws an error. Is there a better way to do this?

Note: I've previously asked this to find out if an account is an ATA to another account, in this case it is for any type of TA, not only ATA.

2 Answers 2

4

Maybe there are better ways to do this and hopefully someone like @jon-c can confirm or rebut this answer but I think you can check if an account is a Token Account by these simple rules:

  1. If the owner of the account is TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA:
  • And the account length is 165 bytes, this is a Token Account. Anything else, it is not.
  1. Otherwise, if the owner of the account is TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb:
  • If the account length is 165 bytes, this is a Token Account

  • If the account length is greater than 165 bytes and the 166th byte is 02 (hex format), this is a Token Account.

Explanation:

When I say owner above, I don't mean what wallet owns the tokens, but rather what program owns the account within the Solana blockchain.

G85MX3RL2BnTsd69BganxYh2ZdFcycqsRHFerfahMC3j is an example of a Token Account on mainnet. Getting the information for it using the command line tools, we get:

% solana account G85MX3RL2BnTsd69BganxYh2ZdFcycqsRHFerfahMC3j -um              

Public Key: G85MX3RL2BnTsd69BganxYh2ZdFcycqsRHFerfahMC3j
Balance: 0.00203928 SOL
Owner: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
Executable: false
Rent Epoch: 0
Length: 165 (0xa5) bytes
0000:   0c 7e 92 c5  ad 2e 82 ff  96 94 bc 37  17 bb db 34   .~.........7...4
0010:   d0 be 4a 34  cc e5 c9 18  24 c3 18 fb  6d b1 45 81   ..J4....$...m.E.
0020:   87 94 ca 2d  27 71 39 07  92 4e 1b 3e  d4 f2 b0 0c   ...-'q9..N.>....
0030:   9a dc fa 78  61 fc 0d 39  1e 50 54 ae  d8 34 4b 9a   ...xa..9.PT..4K.
0040:   c9 d7 87 08  00 00 00 00  00 00 00 00  00 00 00 00   ................
0050:   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00   ................
0060:   00 00 00 00  00 00 00 00  00 00 00 00  01 00 00 00   ................
0070:   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00   ................
0080:   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00   ................
0090:   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00   ................
00a0:   00 00 00 00  00                                      .....

Where you can see the Owner is the Token program and not the same value as owner in the explorer which specifies the wallet that owns the tokens rather. So anytime I mean owner, I mean the program that controls the account on the blockchain.

In the rules above, the 1st rule applies to tokens created using the Token Program, and the 2nd rule applies to tokens created using the newer Token-2022 Program.

For most cases, the 1st rule will suffice. The new Token-2022 Program creates tokens that are backwards compatible with the original Token Program, that's why the check for account length 165 still works, however it also adds the possibility of extensions, meaning bigger accounts that carry more data, however, the extra data includes in it's first byte, the account type (Uninitialized, Mint or Account), and the byte we're looking for is 02.

An example of a Token-2022 token account that has more than 165 bytes is this:

 % solana account VyMPPLqn8CLk62FvsWH9P5SLtZAL4X4XeXeuA9uiNp6 -um


Public Key: VyMPPLqn8CLk62FvsWH9P5SLtZAL4X4XeXeuA9uiNp6
Balance: 0.00207408 SOL
Owner: TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb
Executable: false
Rent Epoch: 0
Length: 170 (0xaa) bytes
0000:   35 4e 03 3a  83 c2 65 27  75 47 4b 4b  00 d4 4d 2e   5N.:..e'uGKK..M.
0010:   ad 81 c4 64  40 9a 37 cc  8d e3 e0 87  a9 ee 32 5e   [email protected]^
0020:   08 e0 3d ea  81 76 12 ff  3a 6f 87 f7  bd ee 36 9f   ..=..v..:o....6.
0030:   1f 5b 4a d9  7e 7a ec ce  0e c5 f8 c2  d2 3b 33 42   .[J.~z.......;3B
0040:   f1 26 24 00  00 00 00 00  00 00 00 00  00 00 00 00   .&$.............
0050:   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00   ................
0060:   00 00 00 00  00 00 00 00  00 00 00 00  01 00 00 00   ................
0070:   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00   ................
0080:   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00   ................
0090:   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00   ................
00a0:   00 00 00 00  00 02 07 00  00 00  
                        ☝️        

Is has length of 170 and not 165 and the 166th byte is 02 and so, it is a valid Token Account.

1
  • Your answer is perfect, thanks!
    – Jon C
    Commented Dec 11, 2023 at 20:45
0

To check if the given key is a token account, I normally use getAccountInfo from @solana/web3.js to get account information and check if the owner is a token program. This was handy as I could manually find the token account when the given account is owned by system program and can easily extend to handle other cases as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.