1

What I'm basically trying to do is what Rugcheck does. When given a token address, it shows the creator of that token. My initial approach was getting all transactions of the token with getSignaturesForAddress from the @solana/web3.js library, then reversing the array and finding the first transaction without an error. That only works sometimes and I don't know why. I'm new to this and completely clueless. What's a better way to get an SPL Token Program's (TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA) creator?

Take for example this token: 7ayGpQ5NbMNeBSXsJWuWE6ZQ7y1f37UGSaHUc4fGypgd My code returns the creator correctly for this.

But then the same code returns the wrong creator for this: CYQqL1bdkL2zB1mJfi88jk2bsps2UbMC1iSLqJr8Gr16 (I'm assuming that rugcheck returns the correct creator.)

Here's the code I currently have. I don't know if it's good or bad. I'm only experimenting.

async function getCreator(tokenAddress: string): Promise<string> {
  const connection = new Connection(clusterApiUrl("mainnet-beta"));

  // Get the transaction signatures involving the token address
  const signatures = await connection.getSignaturesForAddress(
    new PublicKey(tokenAddress)
  );

  if (signatures.length === 0) {
    console.log("No transactions found for this address");
    return "no transactions found";
  }

  // reverse the array to get the first transaction
  signatures.reverse();

  // Retrieve the first transaction signature by iterating and returning the first one that has err: null
  const firstSignature = signatures.find(
    (signature) => signature.err === null
  )?.signature; // Add null check using optional chaining operator

  console.log(firstSignature);

  //   Get the transaction details
  const transaction = firstSignature
    ? await connection.getParsedTransaction(firstSignature, {
        maxSupportedTransactionVersion: 0,
      })
    : null;

  console.log(transaction);

  const signer = transaction?.transaction.message.accountKeys
    .map((key) => key.pubkey.toBase58())
    .filter((key) => key !== tokenAddress)[0] as string; // Add type assertion to ensure 'signer' is of type 'string'

  return signer;
}
1

1 Answer 1

1

For what you're wanting to achieve, you want to inspect the token meta-data. The answer to this question - Is there a way to query Metaplex token metadata? - has what you need.

I would personally recommend the Helius API answer as it is low-lift implementation.

Here's an example response from their API based on the code example and the token accounts you provided in your question - the key thing to look out for here is updateAuthority:

metadata:  [
  {
    mint: '7ayGpQ5NbMNeBSXsJWuWE6ZQ7y1f37UGSaHUc4fGypgd',
    onChainData: {
      tokenStandard: 'Fungible',
      key: 'MetadataV1',
      updateAuthority: '6EBfw9vJd3xsiMLYsKp4zEQi7986xjMh3uvc2WjmkG7A',
      mint: '7ayGpQ5NbMNeBSXsJWuWE6ZQ7y1f37UGSaHUc4fGypgd',
      data: [Object],
      primarySaleHappened: false,
      isMutable: true,
      editionNonce: 254,
      uses: [Object],
      collection: null,
      collectionDetails: null
    },
    offChainData: {
      description: "There's no better host for the Year of the Dragon than Pepenite. Come join the party and set the new trend for 2024 with $PNITE! - https://t.me/PepeNite | https://twitter.com/PepeniteSol",
      image: 'https://bafkreihvqlebzgcxkobgsimcrccbms5mn5wn3z4zspppi73ofzd7yv5epa.ipfs.nftstorage.link',
      name: 'Pepe Nite',
      symbol: 'PNITE'
    }
  },
  {
    mint: 'CYQqL1bdkL2zB1mJfi88jk2bsps2UbMC1iSLqJr8Gr16',
    onChainData: {
      tokenStandard: 'Fungible',
      key: 'MetadataV1',
      updateAuthority: 'EpFWDb9CQ36ScN32xvzJrbgztbP1SM5rtLUaTsrE9JxN',
      mint: 'CYQqL1bdkL2zB1mJfi88jk2bsps2UbMC1iSLqJr8Gr16',
      data: [Object],
      primarySaleHappened: false,
      isMutable: true,
      editionNonce: 255,
      uses: [Object],
      collection: null,
      collectionDetails: null
    },
    offChainData: {
      description: 'Squirtlesaxophonesol.com',
      image: 'https://bafkreifemv36x6awzi6sdmxkh52jriwomll7j7rabluhzwoyy4v7qa7b6u.ipfs.nftstorage.link',
      name: 'Squirtle Saxophone',
      symbol: 'Saxoph'
    }
  }
]

As for why your solution wasn't returning expected responses, there are not many transactions involving 7ayGpQ5NbMNeBSXsJWuWE6ZQ7y1f37UGSaHUc4fGypgd, so when you get them - you get them all going back to the creation of the token, so reversing the list gives you the first transaction.

But CYQqL1bdkL2zB1mJfi88jk2bsps2UbMC1iSLqJr8Gr16 has a lot of transactions associated with it so you're only getting recent transactions, not all of them, meaning the last one in the list isn't necessarily the first-ever transaction.

3
  • Thanks for the response Dru! I did find out about Helius' API as well. But I'm also trying to find a solution using SDKs instead of APIs. Do you have any solution in mind for that? Only coins, not NFT
    – materwelon
    Commented Jan 3 at 15:13
  • No worries, I believe the metaplex sdk answer in the original linked answer should give you what you need - solana.stackexchange.com/a/2460/7498
    – Dru
    Commented Jan 3 at 19:10
  • Yep. I used metaplex-token-metadata's SDK to get the token's metadata using the fetchDigitalAsset method. Appreciate the help!
    – materwelon
    Commented Jan 17 at 20:32

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.