Skip to content

Instantly share code, notes, and snippets.

@kayandra
Forked from losman0s/token_account_helper.ts
Created January 8, 2022 20:20
Show Gist options
  • Save kayandra/b1894b98f97385f7816713572cb3d970 to your computer and use it in GitHub Desktop.
Save kayandra/b1894b98f97385f7816713572cb3d970 to your computer and use it in GitHub Desktop.
Token accounts for owner
import * as BufferLayout from "buffer-layout";
import {
AccountInfo,
ASSOCIATED_TOKEN_PROGRAM_ID,
Token,
TOKEN_PROGRAM_ID,
u64,
} from "@solana/spl-token";
import { Connection, PublicKey } from "@solana/web3.js";
import { BN } from "bn.js";
export const getAssociatedTokenAccountAddress = async (
walletAddress: PublicKey,
mint: PublicKey
) =>
Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mint,
walletAddress
);
export async function getOwnedAssociatedTokenAccounts(
connection: Connection,
publicKey: PublicKey
) {
let filters = getOwnedAccountsFilters(publicKey);
let resp = await connection.getProgramAccounts(TOKEN_PROGRAM_ID, {
commitment: connection.commitment,
filters,
});
const accsParsed: AccountInfoPartial[] = resp.map(({ pubkey, account }) => {
return { ...parseTokenAccountData(account.data), address: pubkey };
});
return (
await Promise.all(
accsParsed
// @ts-ignore
.map(async (ta) => {
const ata = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
ta.mint,
publicKey
);
return { ta, ata };
})
)
)
.filter(({ ta, ata }) => ta.address.equals(ata))
.map(({ ta }) => ta);
}
const ACCOUNT_LAYOUT = BufferLayout.struct([
BufferLayout.blob(32, "mint"),
BufferLayout.blob(32, "owner"),
BufferLayout.nu64("amount"),
BufferLayout.blob(93),
]);
export type AccountInfoPartial = Pick<
AccountInfo,
"address" | "amount" | "mint" | "owner"
>;
export function parseTokenAccountData(data: Buffer): AccountInfoPartial {
// @ts-ignore
let { mint, owner, amount } = ACCOUNT_LAYOUT.decode(data);
// @ts-ignore
return {
mint: new PublicKey(mint),
owner: new PublicKey(owner),
amount: new BN(amount),
};
}
function getOwnedAccountsFilters(publicKey: PublicKey) {
return [
{
memcmp: {
// @ts-ignore
offset: ACCOUNT_LAYOUT.offsetOf("owner"),
bytes: publicKey.toBase58(),
},
},
{
dataSize: ACCOUNT_LAYOUT.span,
},
];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment