Skip to content

Instantly share code, notes, and snippets.

@TimonPeng
Last active January 14, 2022 12:16
Show Gist options
  • Save TimonPeng/8a033bbc8821e6c55ac139e54875635f to your computer and use it in GitHub Desktop.
Save TimonPeng/8a033bbc8821e6c55ac139e54875635f to your computer and use it in GitHub Desktop.
Solana Associated Token Account Flag
// ==UserScript==
// @name Solana Associated Token Account Flag
// @namespace http://tampermonkey.net/
// @version 1.1
// @description Show associated token account flag.
// @author Timon
// @match https://solscan.io/account/*
// @grant none
// @require https://cdn.bootcdn.net/ajax/libs/jquery/3.5.0/jquery.min.js
// @require https://unpkg.com/@solana/web3.js@latest/lib/index.iife.min.js
// @updateURL https://gist.githubusercontent.com/TimonPeng/8a033bbc8821e6c55ac139e54875635f/raw/f8132715f1398410ff81d5aa6ec13ac0a421f315/solana-explorer-ata-flag.js
// ==/UserScript==
const associatedProgramId = new solanaWeb3.PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
const tokenProgramId = new solanaWeb3.PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
async function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function getAssociatedTokenAddress(mint, owner) {
return (
await solanaWeb3.PublicKey.findProgramAddress(
[owner.toBuffer(), tokenProgramId.toBuffer(), mint.toBuffer()],
associatedProgramId,
)
)[0];
}
(function () {
"use strict";
$(document).ready(async function () {
while (true) {
await sleep(100);
const title = $("h2.ant-typography").text();
const accountArea = $(".my-sx-1");
if (title === "Token Account") {
if (accountArea.find(".ata-flag").length !== 0) continue;
const tokenAccountStr = accountArea.text();
const overviews = $(".site-card-wrapper .box-overview .ant-col.ant-col-16");
const tokenArea = $(overviews[1]);
const tokenUrl = $(tokenArea.find("a")).attr("href");
const mintStr = tokenUrl.slice(7);
const infos = $(".site-card-wrapper .box-info .ant-col.ant-col-md-17");
const ownerArea = $(infos[0]);
const ownerUrl = $(ownerArea.find("a")).attr("href");
const ownerStr = ownerUrl.slice(9);
try {
const mint = new solanaWeb3.PublicKey(mintStr);
const owner = new solanaWeb3.PublicKey(ownerStr);
const ata = await getAssociatedTokenAddress(mint, owner);
if (ata.toBase58() === tokenAccountStr) {
accountArea.prepend('<span class="ata-flag" style="margin-right: 5px; color: green;">ATA</span>');
} else {
accountArea.prepend('<span class="ata-flag" style="margin-right: 5px; color: red;">not ATA</span>');
}
} catch {}
} else if (title === "Account") {
if (accountArea.find(".ata-flag").length !== 0) accountArea.find(".ata-flag").remove();
if (!document.location.hash || !document.location.hash.includes("tokenAccounts")) continue;
const walletAddress = document.location.pathname.slice(9);
const owner = new solanaWeb3.PublicKey(walletAddress);
const tables = $("table");
for (const table of tables) {
const _table = $(table);
const headers = _table.find("th");
if (headers.length !== 5) continue;
if ($(headers[3]).text() !== "Token Balance") continue;
const rows = _table.find("tbody .ant-table-row");
for (const row of rows) {
const _row = $(row);
const cells = _row.find("td div");
const accountCell = $(cells[0]);
const tokenCell = $(cells[2]);
if (accountCell.find(".ata-flag").length !== 0) continue;
const accountUrl = $(accountCell.find("a")).attr("href");
const tokenUrl = $(tokenCell.find("a")).attr("href");
const tokenAccountStr = accountUrl.slice(9);
const mintStr = tokenUrl.slice(7);
try {
const mint = new solanaWeb3.PublicKey(mintStr);
const ata = await getAssociatedTokenAddress(mint, owner);
if (ata.toBase58() === tokenAccountStr) {
accountCell.prepend('<span class="ata-flag" style="margin-right: 5px; color: green;">ATA</span>');
} else {
accountCell.prepend('<span class="ata-flag" style="margin-right: 5px; color: red;">not ATA</span>');
}
} catch {}
}
}
}
}
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment