Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot update "Update Authority" on SPL token created with Metaplex #131

Open
0xlucyy opened this issue Aug 1, 2024 · 7 comments
Open

Comments

@0xlucyy
Copy link

0xlucyy commented Aug 1, 2024

I create an SPL token using metaplex with specific metadata using the following code. In the process I also revoke Mint and Freeze authority.

  const createToken = async () => {
    if (!userPublicKey) {
        console.error('User public key not found');
        return;
    }

    try {
      const metadata = {
          name: "RNG Gaming",
          symbol: "RNG",
          uri: "https://ensagent.mypinata.cloud/ipfs/Qm..."
      };

      const mint = generateSigner(umi);
      const initialSupply = 1000000000000000;

      console.log('Creating token: ', metadata.name)
      await createAndMint(umi, {
        mint,
        authority: umi.identity,
        name: metadata.name,
        symbol: metadata.symbol,
        uri: metadata.uri,
        sellerFeeBasisPoints: percentAmount(0),
        decimals: 7,
        amount: initialSupply,
        tokenOwner: userPublicKey,
        tokenStandard: TokenStandard.Fungible,
      }).sendAndConfirm(umi);

      const token_mint_pub_key = new PublicKey(mint.publicKey)
      await setToken(token_mint_pub_key);

      // Revoke the mint & freeze authority
      const transaction = new Transaction().add(
        createSetAuthorityInstruction(
          token_mint_pub_key,
          userPublicKey,
          AuthorityType.MintTokens,
          null,
          [],
          TOKEN_PROGRAM_ID
        ),
        createSetAuthorityInstruction(
          token_mint_pub_key,
          userPublicKey,
          AuthorityType.FreezeAccount,
          null,
          [],
          TOKEN_PROGRAM_ID
        )
      );

      const { blockhash } = await connection.getRecentBlockhash();
      transaction.recentBlockhash = blockhash;
      transaction.feePayer = userPublicKey;

      const signature = await sendTransaction(transaction, connection);
      console.log('Transaction signature:', signature);

    } catch (error) {
       ...
       ...
    }
  };

This successfully creates the appropriate token

Screenshot 2024-07-31 at 11 06 36 PM

Now, what I am attempting but failing at is revoking the Update Authority.

This is my code to revoke Update Authority

  const revokeUpdate = async () => {
    try {
      const mintAddress = publicKey(MAINNET_RNG_TOKEN_MINT);
  
      const initialMetadata = await fetchMetadataFromSeeds(umi, { mint: mintAddress });
      console.log("Initial metadata:", initialMetadata);
  
      const updateInstruction = updateV1(umi, {
        mint: mintAddress,
        authority: metadata_wallet_signer,
        data: {
          ...initialMetadata,
        },
        newUpdateAuthority: null,
        isMutable: false,
      });
  
      const result = await updateInstruction.sendAndConfirm(umi);
  
      const newMetadata = await fetchMetadataFromSeeds(umi, { mint: mintAddress });
      console.log("new metadata:", newMetadata);
    } catch (error) {
      console.error("Error in revokeAuthorities:", error);
      if (error.stack) {
        console.error("Stack trace:", error.stack);
      }
    }
  };

Please note the relevant console logs

Initial metadata: {
  name : "RNG Gaming",
  symbol: "RNG",
  isMutable: true,
  updateAuthority: "DQ3...",
  uri : "https://ensagent.mypinata.cloud/ipfs/Qm..."
  ....
  ....
}

AND 

new metadata: {
  name : "RNG Gaming",
  symbol: "RNG",
  isMutable: false,
  updateAuthority: "DQ3...",
  uri : "https://ensagent.mypinata.cloud/ipfs/Qm..."
  ....
  ....
}

Please note that the ONLY thing that changes is the isMutable field. The updateAuthority field remains unchanged. This behavior is true even if I send two separate updateInstruction, the first ONLY changing the updateAuthority and the second ONLY changing the isMutable fields.

I should note, the account I am using to sign/send the transactions is the same account which has the Update Authority on the token.

What is happening, what am I doing wrong? And how can I fix it!

@MarkSackerberg
Copy link
Contributor

Hey,
To remove the update authority account key you probably need to pass in none() instead of null.
In general this should not be required though. As soon as the metadata is set to isMutable: false the update authority cannot be used for anything either way.

@0xlucyy
Copy link
Author

0xlucyy commented Aug 1, 2024

Thank you for your feedback.

Unfortunetly your provided solution does not work...

  import { none } from '@metaplex-foundation/umi'

  const revokUpdateAuthority = async () => {
    try {
      const mintAddress = publicKey(MAINNET_RNG_TOKEN_MINT);
  
      const initialMetadata = await fetchMetadataFromSeeds(umi, { mint: mintAddress });
      console.log("Initial metadata:", initialMetadata);
      
      const updateInstruction = updateV1(umi, {
        mint: mintAddress,
        authority: metadata_wallet_signer,
        data: {
          ...initialMetadata,
        },
        newUpdateAuthority: none(),
        isMutable: false,
      });
  
      const result = await updateInstruction.sendAndConfirm(umi);
     
      const newMetadata = await fetchMetadataFromSeeds(umi, { mint: mintAddress });
      console.log("new metadata:", newMetadata);
    } catch (error) {
          ...
          ...
      }
    }
  };

This produces the exact same Initial metadata & new metadata as before.

Please open this ticket, as there has been no working solution provided.

@MarkSackerberg
Copy link
Contributor

Let’s start over. What is it that’s not working?
You can not update metadata after isMutable was set to false, as mentioned before. So what do you want to achieve in addition with removing your address?

@MarkSackerberg MarkSackerberg reopened this Aug 1, 2024
@0xlucyy
Copy link
Author

0xlucyy commented Aug 1, 2024

I need to ensure that a token successfully has its Update Authority set to None/null.

Right now, every SPL token I create with metaplex has its Update Authority as the minter of the token. I can successfully revoke Mint & Freeze Authority, meaning those two authorities are set to null.

So when a wallet checks those Authorities, the wallets correctly show the user that this token has renounced those Authorities and that the token is safe from those attacks.

Several popular wallets, including Phantom, show the user if the token has renounced its Update Authority. Even though I can set isMutable: false,, the wallets and rug checking websites show that the token metadata is mutable because an Update Authority is set.

So from a users perspective, they are buying into a token that can change its picture and other metadata.

That is highly problematic for me. All I need to do is set the Update Authority to null just as I have for Freeze & Mint Authorities.

Does that make sense friend? I am struggling with setting the Update Authority to None/null and I have a feeling that metaplex is at fault here. This should be a trivial matter to do, yet it is not.

I want to create the safest token possible for users, and I want that token to be presented accurately to users... meaning that all relevant Authorities are revoked and set to None/null. This will present the token in the best possible light in wallets and rug checking websites.

The fact I can set the token to isMutable: false does nothing for how the token is presented and I should be able to change the update authority if I want to. But right now I cannot and ive tried for several days now, that is why I am here asking for help.

I appreciate your response but I need a viable replicable solution and I still do not have one after days of trying. This is very bad for me.

@cd11103
Copy link

cd11103 commented Sep 11, 2024

hi @0xlucyy can u give me a clue on how to revoke the Mint & Freeze? Because when i use Token Metadata Program to mint NFT, it auto set the PDA as mint & freeze key, when i try to unlock/thaw, it need the mint & freeze authority signer and they are derived key and i don't know how to sign with it.

@rogaldh
Copy link

rogaldh commented Sep 11, 2024

Hey, To remove the update authority account key you probably need to pass in none() instead of null. In general this should not be required though. As soon as the metadata is set to isMutable: false the update authority cannot be used for anything either way.

Passing none() as newUpdateAuthority does not work as you said.

import { none } from "@metaplex-foundation/umi";
import { updateAsUpdateAuthorityV2 } from "@metaplex-foundation/mpl-token-metadata";

const newOnChainMetadata = {/*...*/}
const txBuilder = updateAsUpdateAuthorityV2(umi, {
    mint: fromWeb3JsPublicKey(mint),
    data: newOnChainMetadata,
    newUpdateAuthority: none(),
})

Upon executing this, updateAuthority will not be changed and explorer.solana.com will show the same authority as it was.

@rileyg98
Copy link

Also having this issue. Either passing null or none() does not change the metadata's update authority address.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants