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:
- 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.
- 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 166
th byte is 02
and so, it is a valid Token Account.