>>FIRST MISSION//LOGS//SYSTEM_LOG//how-to-change-the-mint-authority-of-a-solana-token-account.MD
[ + ] TARGET_LOCKED200 OK
JAN 30, 2025timer 3 MIN READSYS_TAG: SYSTEM_LOG STATUS: VERIFIED_WORKING

How to Change the Mint Authority of a Solana Token Account

ENGINE: KERNEL // STABLE
BASE_ARCH: x86_64
HOST: VASTORIGINS.COM
GPG: OKSIG_ID: 0x4EB27DB0

When you are testing Solana programs locally, there is a classic problem: your test validator loads a token from mainnet, and that token’s mint authority is held by someone else, so you cannot mint test tokens freely. The clean solution is not to beg the authority for permission; it is to rewrite the account bytes locally so the mint authority becomes your own address.

In this tutorial, we’ll walk through a TypeScript code snippet that changes the mint authority of a Solana token account. This can be useful when you want to modify the mint authority for testing purposes using solana-test-validator. Note that this is a test environment trick; on a real network, mint authority changes go through the SPL token program, not through editing raw bytes.

✅ Prerequisites

Before we dive into the code, make sure you have the following:

  • Node.js installed
  • TypeScript installed
  • ethers (or bs58) library installed
  • fs module (comes with Node.js)
  • A JSON file containing the token account data (e.g., usdc.json)

🧩 Step-by-Step Explanation

📥 Import Required Modules

import { base58 } from 'ethers/lib/utils';
import USDC_TOKEN from './usdc.json';
import { writeFileSync } from 'fs';

We import the base58 utility from the ethers library, the token data from usdc.json, and the writeFileSync function from the fs module.

🗂️ Define the TokenData Interface

interface TokenData {
  pubkey: string;
  account: {
    lamports: number;
    data: [string, string]; // [base64 encoded data, encoding type]
    owner: string;
    executable: boolean;
    rentEpoch: number;
    space: number;
  };
}

We define an interface TokenData to represent the structure of the token account data, so TypeScript knows exactly what we are working with.

⚙️ Create the changeMintAuthority Function

async function changeMintAuthority(
  myAddress: string,
  tokenData: unknown,
  outputFile: string
) {
  try {
    // Read JSON file
    const token = tokenData as TokenData;

We create an asynchronous function changeMintAuthority that takes three parameters: myAddress (the new mint authority address), tokenData (the token account data), and outputFile (the output file path).

🔢 Convert Base64 to Byte Array

// Convert base64 to byte array
    const data = Buffer.from(token.account.data[0], 'base64');
    console.log('Data:', data.toString('hex'));
    console.log('Authority', base58.encode(data.slice(4, 36)));

We convert the base64-encoded data to a byte array and log the data and current mint authority. The bytes at offset 4 through 36 are where the authority’s public key lives, which is why we slice exactly that range.

✏️ Replace Mint Authority

// Replace mint authority (bytes 4-36) with new address
    const newAuthorityBytes = base58.decode(myAddress);
    data.set(newAuthorityBytes, 4);
    console.log('Data:', data.toString('hex'));
    console.log('Authority', base58.encode(data.slice(4, 36)));

We replace the mint authority (bytes 4-36) with the new address and log the updated data and new mint authority. Decode your address from base58, write the 32 bytes at offset 4, and the authority field now points at you.

💾 Update the Data with New Mint Authority

// Update the data with new mint authority
    token.account.data[0] = data.toString('base64');

We update the token account data with the new mint authority, encoding the modified bytes back into base64.

📄 Write Modified JSON to New File

// Write modified JSON to new file
    writeFileSync(outputFile, JSON.stringify(token, null, 2));
    console.log(`Successfully changed mint authority to ${myAddress}`);
    console.log(`Modified JSON saved to ${outputFile}`);
  } catch (error) {
    console.error('Failed to change mint authority:', error);
    throw error;
  }
}

We write the modified token account data to a new JSON file and log a success message. If an error occurs, we log the error and throw it, so the failure is loud instead of silent.

▶️ Run the Function

const MY_ADDRESS = '8vTM2FwzXT8bwT5jXyv556eo6LdPPPCnhynaCZcW2zRa';
changeMintAuthority(MY_ADDRESS, USDC_TOKEN, './usdc-mod.json');

We define the new mint authority address and call the changeMintAuthority function with the appropriate parameters.

🚀 Running the Code

To run the code, follow these steps:

Capture the token account data using the following command:

solana account AKEWE7Bgh87GPp171b4cJPSSZfmZwQ3KaqYqXoKLNAEE --output json --output-file usdc.json --url https://eclipse.helius-rpc.com

Execute the TypeScript code to change the mint authority:

ts-node changeMintAuthority.ts

Use the modified token account data with solana-test-validator:

solana-test-validator --url https://eclipse.helius-rpc.com --account AKEWE7Bgh87GPp171b4cJPSSZfmZwQ3KaqYqXoKLNAEE ./usdc-mod.json --reset

And that’s it! You’ve successfully changed the mint authority of a Solana token account. Happy coding! 🎉

Here’s the full source:

interface TokenData {
  pubkey: string;
  account: {
    lamports: number;
    data: [string, string]; // [base64 encoded data, encoding type]
    owner: string;
    executable: boolean;
    rentEpoch: number;
    space: number;
  };
}

async function changeMintAuthority(
  myAddress: string,
  tokenData: unknown,
  outputFile: string
) {
  try {
    // Read JSON file
    const token = tokenData as TokenData;

    // Convert base64 to byte array
    const data = Buffer.from(token.account.data[0], 'base64');
    console.log('Data:', data.toString('hex'));
    console.log('Authority', base58.encode(data.slice(4, 36)));

    // Replace mint authority (bytes 4-36) with new address
    const newAuthorityBytes = base58.decode(myAddress);
    data.set(newAuthorityBytes, 4);
    console.log('Data:', data.toString('hex'));
    console.log('Authority', base58.encode(data.slice(4, 36)));

    // Update the data with new mint authority
    token.account.data[0] = data.toString('base64');

    // Write modified JSON to new file
    writeFileSync(outputFile, JSON.stringify(token, null, 2));

    console.log(`Successfully changed mint authority to ${myAddress}`);
    console.log(`Modified JSON saved to ${outputFile}`);
  } catch (error) {
    console.error('Failed to change mint authority:', error);
    throw error;
  }
}

const MY_ADDRESS = '8vTM2FwzXT8bwT5jXyv556eo6LdPPPCnhynaCZcW2zRa';
changeMintAuthority(MY_ADDRESS, USDC_TOKEN, './scripts/usdc-modded.json');

🧠 Final Thoughts

This byte editing trick is a lifesaver for local testing, because it lets you take any mainnet token, hand its mint authority to yourself, and start minting immediately in solana-test-validator. Just remember the important boundary: this modifies the local account file for your test environment only. On a live network, changing mint authority is a privileged operation handled by the SPL token program, so keep this technique in the sandbox where it belongs.

If the offsets ever feel magical, remember the layout: the mint authority lives at bytes 4 to 36, and everything else is just plumbing around it. Happy coding! 🎉

[ SIGNATURE VERIFIED // GPG 0x4EB27DB0 // PROVENANCE SECURE ]
➔ RETURN TO LOGS