Given a mint key of an NFT, how can I get the PublicKey of the wallet that owns it?
2 Answers
Since NFTs can only have 1 owner at a time, just use getTokenLargestAccounts to find the one that holds it
const connection = new Connection("https://api.mainnet-beta.solana.com");
const mintKey = new PublicKey("FfWP2mXizKnHZLsG3mTDFC2vWoZFfZTQi1Rpvm2nQTgM");
const largestAccounts = await connection.getTokenLargestAccounts(mintKey)
const largestAccountInfo = await connection.getParsedAccountInfo(
largestAccounts.value[0].address //first element is the largest account, assumed with 1
);
console.log((largestAccountInfo.value.data as web3.ParsedAccountData).parsed.info.owner);
I have not benchmarked this one and the above answer, however I expect this one is a tad better on performance. It only requires one call on the chain.
public async getNftOwner(mintAddress: string) {
let owner: string;
try {
// Fetch and parse all the accounts owned by the specified program id
const accountInfo = await this.privateConnection.getParsedProgramAccounts(
TOKEN_PROGRAM_ID,
{
filters: [
{ dataSize: 165 },
{ memcmp: { offset: 0, bytes: mintAddress } },
],
},
);
// Get the account that has an amount of 1
const tokenAccount = accountInfo.find((element) => {
const data: { parsed: { info: { tokenAmount: { amount: string } } } } =
element.account.data as {
parsed: { info: { tokenAmount: { amount: string } } };
};
return data.parsed.info.tokenAmount.amount !== '0';
});
// Parsed data for the token account
const data: { parsed: { info: { owner: string } } } = tokenAccount.account
.data as {
parsed: { info: { owner: string } };
};
// Set the owner
owner = data.parsed.info.owner;
} catch (error) {
throw new HttpException(
'Could not get wallet info from solana.',
HttpStatus.SERVICE_UNAVAILABLE,
);
}
return owner;
}