---
title: Immutable Owner
description:
  Initialize a Token Extension Program token account with immutable ownership so
  its owner can never be reassigned.
url: /docs/tokens/extensions/immutable-owner
type: tutorial
prerequisites:
  - /docs/tokens/basics/create-token-account
related:
  - /docs/tokens/extensions/non-transferrable-tokens
  - /docs/tokens/extensions
---

## What Is Immutable Owner?

The Token Extension Program's _rs`ImmutableOwner`_ account extension makes a
token account's owner permanent.

Once a token account is initialized with _rs`ImmutableOwner`_, later
_rs`SetAuthority`_ instructions cannot change its _rs`AccountOwner`_ authority.

<Callout type="info" title="Associated Token Accounts">
  Associated token accounts created through the Associated Token Program for the
  Token Extension Program automatically initialize _rs`ImmutableOwner`_ on the
  token account.
</Callout>

## How to Initialize an Immutable Owner Account

To initialize an immutable owner account:

1. Create and initialize a mint.
2. Create a token account with enough space for _rs`ImmutableOwner`_.
3. Initialize _rs`ImmutableOwner`_ on the token account before
   _rs`InitializeAccount`_.
4. Attempting to change the account owner later with _rs`SetAuthority`_ fails
   with _rs`TokenError::ImmutableOwner`_.

<ScrollyCoding>

## !!steps Calculate token account size

Calculate the token account size for the base token account plus the
_rs`ImmutableOwner`_ extension. This is the size used in _rs`CreateAccount`_.

<CodePlaceholder title="Example" />

```ts !! title="Example"
const client = await createClient()
  .use(generatedPayer())
  .use(
    solanaRpc({
      rpcUrl: "http://localhost:8899",
      rpcSubscriptionsUrl: "ws://localhost:8900"
    })
  )
  .use(rpcAirdrop())
  .use(airdropPayer(lamports(1_000_000_000n)));

const mint = await generateKeyPairSigner();
const tokenAccount = await generateKeyPairSigner();

const mintSpace = BigInt(getMintSize());
const mintRent = await client.rpc
  .getMinimumBalanceForRentExemption(mintSpace)
  .send();

await client.sendTransaction([
  getCreateAccountInstruction({
    payer: client.payer,
    newAccount: mint,
    lamports: mintRent,
    space: mintSpace,
    programAddress: TOKEN_2022_PROGRAM_ADDRESS
  }),
  getInitializeMintInstruction({
    mint: mint.address,
    decimals: 0,
    mintAuthority: client.payer.address,
    freezeAuthority: client.payer.address
  })
]);

// !focus(1:1)
const immutableOwnerExtension = extension("ImmutableOwner", {});

// !focus(1:1)
const tokenSpace = BigInt(getTokenSize([immutableOwnerExtension]));
```

## !!steps Calculate rent

Calculate rent using the token account size needed for the _rs`ImmutableOwner`_
extension.

<CodePlaceholder title="Example" />

```ts !! title="Example"
const client = await createClient()
  .use(generatedPayer())
  .use(
    solanaRpc({
      rpcUrl: "http://localhost:8899",
      rpcSubscriptionsUrl: "ws://localhost:8900"
    })
  )
  .use(rpcAirdrop())
  .use(airdropPayer(lamports(1_000_000_000n)));

const mint = await generateKeyPairSigner();
const tokenAccount = await generateKeyPairSigner();

const mintSpace = BigInt(getMintSize());
const mintRent = await client.rpc
  .getMinimumBalanceForRentExemption(mintSpace)
  .send();

await client.sendTransaction([
  getCreateAccountInstruction({
    payer: client.payer,
    newAccount: mint,
    lamports: mintRent,
    space: mintSpace,
    programAddress: TOKEN_2022_PROGRAM_ADDRESS
  }),
  getInitializeMintInstruction({
    mint: mint.address,
    decimals: 0,
    mintAuthority: client.payer.address,
    freezeAuthority: client.payer.address
  })
]);

const immutableOwnerExtension = extension("ImmutableOwner", {});

const tokenSpace = BigInt(getTokenSize([immutableOwnerExtension]));

// !focus(1:3)
const tokenRent = await client.rpc
  .getMinimumBalanceForRentExemption(tokenSpace)
  .send();
```

## !!steps Create the token account

Create the token account with the calculated space and lamports.

<CodePlaceholder title="Example" />

```ts !! title="Example"
const client = await createClient()
  .use(generatedPayer())
  .use(
    solanaRpc({
      rpcUrl: "http://localhost:8899",
      rpcSubscriptionsUrl: "ws://localhost:8900"
    })
  )
  .use(rpcAirdrop())
  .use(airdropPayer(lamports(1_000_000_000n)));

const mint = await generateKeyPairSigner();
const tokenAccount = await generateKeyPairSigner();

const mintSpace = BigInt(getMintSize());
const mintRent = await client.rpc
  .getMinimumBalanceForRentExemption(mintSpace)
  .send();

await client.sendTransaction([
  getCreateAccountInstruction({
    payer: client.payer,
    newAccount: mint,
    lamports: mintRent,
    space: mintSpace,
    programAddress: TOKEN_2022_PROGRAM_ADDRESS
  }),
  getInitializeMintInstruction({
    mint: mint.address,
    decimals: 0,
    mintAuthority: client.payer.address,
    freezeAuthority: client.payer.address
  })
]);

const immutableOwnerExtension = extension("ImmutableOwner", {});

const tokenSpace = BigInt(getTokenSize([immutableOwnerExtension]));

const tokenRent = await client.rpc
  .getMinimumBalanceForRentExemption(tokenSpace)
  .send();

// !focus(1:9)
await client.sendTransaction([
  getCreateAccountInstruction({
    payer: client.payer,
    newAccount: tokenAccount,
    lamports: tokenRent,
    space: tokenSpace,
    programAddress: TOKEN_2022_PROGRAM_ADDRESS
  })
]);
```

## !!steps Initialize ImmutableOwner

Initialize the _rs`ImmutableOwner`_ extension on the token account.

<CodePlaceholder title="Example" />

```ts !! title="Example"
const client = await createClient()
  .use(generatedPayer())
  .use(
    solanaRpc({
      rpcUrl: "http://localhost:8899",
      rpcSubscriptionsUrl: "ws://localhost:8900"
    })
  )
  .use(rpcAirdrop())
  .use(airdropPayer(lamports(1_000_000_000n)));

const mint = await generateKeyPairSigner();
const tokenAccount = await generateKeyPairSigner();

const mintSpace = BigInt(getMintSize());
const mintRent = await client.rpc
  .getMinimumBalanceForRentExemption(mintSpace)
  .send();

await client.sendTransaction([
  getCreateAccountInstruction({
    payer: client.payer,
    newAccount: mint,
    lamports: mintRent,
    space: mintSpace,
    programAddress: TOKEN_2022_PROGRAM_ADDRESS
  }),
  getInitializeMintInstruction({
    mint: mint.address,
    decimals: 0,
    mintAuthority: client.payer.address,
    freezeAuthority: client.payer.address
  })
]);

const immutableOwnerExtension = extension("ImmutableOwner", {});

const tokenSpace = BigInt(getTokenSize([immutableOwnerExtension]));

const tokenRent = await client.rpc
  .getMinimumBalanceForRentExemption(tokenSpace)
  .send();

await client.sendTransaction([
  getCreateAccountInstruction({
    payer: client.payer,
    newAccount: tokenAccount,
    lamports: tokenRent,
    space: tokenSpace,
    programAddress: TOKEN_2022_PROGRAM_ADDRESS
  }),
  // !focus(1:3)
  getInitializeImmutableOwnerInstruction({
    account: tokenAccount.address
  })
]);
```

## !!steps Initialize the token account

Initialize the token account with _rs`InitializeAccount`_ in the same
transaction.

<CodePlaceholder title="Example" />

```ts !! title="Example"
const client = await createClient()
  .use(generatedPayer())
  .use(
    solanaRpc({
      rpcUrl: "http://localhost:8899",
      rpcSubscriptionsUrl: "ws://localhost:8900"
    })
  )
  .use(rpcAirdrop())
  .use(airdropPayer(lamports(1_000_000_000n)));

const mint = await generateKeyPairSigner();
const tokenAccount = await generateKeyPairSigner();

const mintSpace = BigInt(getMintSize());
const mintRent = await client.rpc
  .getMinimumBalanceForRentExemption(mintSpace)
  .send();

await client.sendTransaction([
  getCreateAccountInstruction({
    payer: client.payer,
    newAccount: mint,
    lamports: mintRent,
    space: mintSpace,
    programAddress: TOKEN_2022_PROGRAM_ADDRESS
  }),
  getInitializeMintInstruction({
    mint: mint.address,
    decimals: 0,
    mintAuthority: client.payer.address,
    freezeAuthority: client.payer.address
  })
]);

const immutableOwnerExtension = extension("ImmutableOwner", {});

const tokenSpace = BigInt(getTokenSize([immutableOwnerExtension]));

const tokenRent = await client.rpc
  .getMinimumBalanceForRentExemption(tokenSpace)
  .send();

await client.sendTransaction([
  getCreateAccountInstruction({
    payer: client.payer,
    newAccount: tokenAccount,
    lamports: tokenRent,
    space: tokenSpace,
    programAddress: TOKEN_2022_PROGRAM_ADDRESS
  }),
  getInitializeImmutableOwnerInstruction({
    account: tokenAccount.address
  }),
  // !focus(1:5)
  getInitializeAccountInstruction({
    account: tokenAccount.address,
    mint: mint.address,
    owner: client.payer.address
  })
]);
```

</ScrollyCoding>

<Callout type="info" title="Instruction Order">
  _rs`InitializeImmutableOwner`_ must come before _rs`InitializeAccount`_.
  _rs`CreateAccount`_, _rs`InitializeImmutableOwner`_, and
  _rs`InitializeAccount`_ must be included in the same transaction.
</Callout>

### Source Reference

| Item                                     | Description                                                                                         | Source                                                                                                                           |
| ---------------------------------------- | --------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| _rs`ImmutableOwner`_                     | Account extension that marks a token account owner as immutable.                                    | [Source](https://github.com/solana-program/token-2022/blob/program%40v10.0.0/interface/src/extension/immutable_owner.rs#L13-L16) |
| _rs`InitializeImmutableOwner`_           | Instruction that initializes the immutable-owner extension on an uninitialized token account.       | [Source](https://github.com/solana-program/token-2022/blob/program%40v10.0.0/interface/src/instruction.rs#L1982-L1991)           |
| _rs`process_initialize_immutable_owner`_ | Processor logic that allocates and initializes _rs`ImmutableOwner`_ on the account.                 | [Source](https://github.com/solana-program/token-2022/blob/program%40v10.0.0/program/src/processor.rs#L1532-L1543)               |
| _rs`SetAuthority`_                       | Base token instruction used to change authorities, including a token account owner.                 | [Source](https://github.com/solana-program/token-2022/blob/program%40v10.0.0/interface/src/instruction.rs#L1611-L1633)           |
| _rs`process_set_authority`_              | Processor logic that rejects owner changes when the token account has _rs`ImmutableOwner`_ enabled. | [Source](https://github.com/solana-program/token-2022/blob/program%40v10.0.0/program/src/processor.rs#L703-L900)                 |

### Typescript

The `Kit` example below uses the generated instructions directly. Legacy
examples using `@solana/web3.js` and `@solana/spl-token` are included for
reference.

#### Kit

<CodeTabs storage="token-ts-kit" flags="r">

```ts !! title="Instructions"
import {
  lamports,
  createClient,
  generateKeyPairSigner,
  unwrapOption
} from "@solana/kit";
import { solanaRpc, rpcAirdrop } from "@solana/kit-plugin-rpc";
import { generatedPayer, airdropPayer } from "@solana/kit-plugin-signer";
import { getCreateAccountInstruction } from "@solana-program/system";
import {
  AuthorityType,
  extension,
  fetchToken,
  getInitializeAccountInstruction,
  getInitializeImmutableOwnerInstruction,
  getInitializeMintInstruction,
  getMintSize,
  getSetAuthorityInstruction,
  getTokenSize,
  isExtension,
  TOKEN_2022_PROGRAM_ADDRESS
} from "@solana-program/token-2022";

const client = await createClient()
  .use(generatedPayer())
  .use(
    solanaRpc({
      rpcUrl: "http://localhost:8899",
      rpcSubscriptionsUrl: "ws://localhost:8900"
    })
  )
  .use(rpcAirdrop())
  .use(airdropPayer(lamports(1_000_000_000n)));

const mint = await generateKeyPairSigner();
const tokenAccount = await generateKeyPairSigner();
const newOwner = await generateKeyPairSigner();

const mintSpace = BigInt(getMintSize());
const mintRent = await client.rpc
  .getMinimumBalanceForRentExemption(mintSpace)
  .send();

await client.sendTransaction([
  getCreateAccountInstruction({
    payer: client.payer, // Account funding the new mint account.
    newAccount: mint, // New mint account to create.
    lamports: mintRent, // Lamports funding the mint account rent.
    space: mintSpace, // Account size in bytes for the mint.
    programAddress: TOKEN_2022_PROGRAM_ADDRESS // Program that owns the mint account.
  }),
  getInitializeMintInstruction({
    mint: mint.address, // Mint account to initialize.
    decimals: 0, // Number of decimals for the token.
    mintAuthority: client.payer.address, // Authority allowed to mint new tokens.
    freezeAuthority: client.payer.address // Authority allowed to freeze token accounts.
  })
]);

const immutableOwnerExtension = extension("ImmutableOwner", {});
const tokenSpace = BigInt(getTokenSize([immutableOwnerExtension]));
const tokenRent = await client.rpc
  .getMinimumBalanceForRentExemption(tokenSpace)
  .send();

await client.sendTransaction([
  getCreateAccountInstruction({
    payer: client.payer, // Account funding the new token account.
    newAccount: tokenAccount, // New token account to create.
    lamports: tokenRent, // Lamports funding the token account rent.
    space: tokenSpace, // Account size in bytes for the token account plus ImmutableOwner.
    programAddress: TOKEN_2022_PROGRAM_ADDRESS // Program that owns the token account.
  }),
  // !mark(1:3)
  getInitializeImmutableOwnerInstruction({
    account: tokenAccount.address // Token account that stores the ImmutableOwner extension.
  }),
  getInitializeAccountInstruction({
    account: tokenAccount.address, // Token account to initialize.
    mint: mint.address, // Mint for the token account.
    owner: client.payer.address // Owner of the token account.
  })
]);

let failure: string | undefined;
try {
  await client.sendTransaction([
    // !mark(1:6)
    getSetAuthorityInstruction({
      owned: tokenAccount.address, // Token account whose authority is being updated.
      owner: client.payer, // Current token account owner signing the instruction.
      authorityType: AuthorityType.AccountOwner, // Account authority field to change.
      newAuthority: newOwner.address // New token account owner to set.
    })
  ]);
} catch (error) {
  failure = String(error);
}
if (!failure) {
  throw new Error("Expected the owner change to fail");
}

const token = await fetchToken(client.rpc, tokenAccount.address);
const immutableOwnerExtensionState = (
  unwrapOption(token.data.extensions) ?? []
).find((item) => isExtension("ImmutableOwner", item));

console.log("Mint Address:", mint.address);
console.log("Token Account:", tokenAccount.address);
console.log("ImmutableOwner Extension:", immutableOwnerExtensionState);
console.log("SetAuthority Failure:", failure);
```

</CodeTabs>

#### Web3.js

<CodeTabs storage="token-ts-legacy" flags="r">

```ts !! title="Instructions"
import {
  Connection,
  Keypair,
  sendAndConfirmTransaction,
  SystemProgram,
  Transaction,
  LAMPORTS_PER_SOL
} from "@solana/web3.js";
import {
  AuthorityType,
  createInitializeMintInstruction,
  createInitializeAccountInstruction,
  createInitializeImmutableOwnerInstruction,
  createSetAuthorityInstruction,
  ExtensionType,
  getAccount,
  getAccountLen,
  getImmutableOwner,
  getMintLen,
  TOKEN_2022_PROGRAM_ID
} from "@solana/spl-token";

const connection = new Connection("http://localhost:8899", "confirmed");
const feePayer = Keypair.generate();
const newOwner = Keypair.generate();

const airdropSignature = await connection.requestAirdrop(
  feePayer.publicKey,
  5 * LAMPORTS_PER_SOL
);
const latestBlockhash = await connection.getLatestBlockhash();
await connection.confirmTransaction({
  blockhash: latestBlockhash.blockhash,
  lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
  signature: airdropSignature
});

const mint = Keypair.generate();

const mintLength = getMintLen([]);

const mintRent = await connection.getMinimumBalanceForRentExemption(mintLength);

const extensions = [ExtensionType.ImmutableOwner];
const tokenAccount = new Keypair();
const tokenAccountLen = getAccountLen(extensions);
const tokenAccountRent =
  await connection.getMinimumBalanceForRentExemption(tokenAccountLen);

const createMintAccountInstruction = SystemProgram.createAccount({
  fromPubkey: feePayer.publicKey, // Account funding the new mint account.
  newAccountPubkey: mint.publicKey, // New mint account to create.
  space: mintLength, // Account size in bytes for the mint.
  lamports: mintRent, // Lamports funding the mint account rent.
  programId: TOKEN_2022_PROGRAM_ID // Program that owns the mint account.
});

const initializeMintInstruction = createInitializeMintInstruction(
  mint.publicKey, // Mint account to initialize.
  0, // Number of decimals for the token.
  feePayer.publicKey, // Authority allowed to mint new tokens.
  feePayer.publicKey, // Authority allowed to freeze token accounts.
  TOKEN_2022_PROGRAM_ID // Program that owns the mint account.
);

const createTokenAccountInstruction = SystemProgram.createAccount({
  fromPubkey: feePayer.publicKey, // Account funding the new token account.
  newAccountPubkey: tokenAccount.publicKey, // New token account to create.
  space: tokenAccountLen, // Account size in bytes for the token account plus ImmutableOwner.
  lamports: tokenAccountRent, // Lamports funding the token account rent.
  programId: TOKEN_2022_PROGRAM_ID // Program that owns the token account.
});

// !mark(1:5)
const initializeImmutableOwnerInstruction =
  createInitializeImmutableOwnerInstruction(
    tokenAccount.publicKey, // Token account that stores the ImmutableOwner extension.
    TOKEN_2022_PROGRAM_ID // Token program that owns the token account.
  );

const initializeTokenAccountInstruction = createInitializeAccountInstruction(
  tokenAccount.publicKey, // Token account to initialize.
  mint.publicKey, // Mint for the token account.
  feePayer.publicKey, // Owner of the token account.
  TOKEN_2022_PROGRAM_ID // Token program that owns the token account.
);

await sendAndConfirmTransaction(
  connection,
  new Transaction().add(
    createMintAccountInstruction,
    initializeMintInstruction
  ),
  [feePayer, mint]
);

await sendAndConfirmTransaction(
  connection,
  new Transaction().add(
    createTokenAccountInstruction,
    initializeImmutableOwnerInstruction,
    initializeTokenAccountInstruction
  ),
  [feePayer, tokenAccount]
);

let failure: string | undefined;
try {
  await sendAndConfirmTransaction(
    connection,
    new Transaction().add(
      // !mark(1:8)
      createSetAuthorityInstruction(
        tokenAccount.publicKey, // Token account whose authority is being updated.
        feePayer.publicKey, // Current token account owner signing the instruction.
        AuthorityType.AccountOwner, // Account authority field to change.
        newOwner.publicKey, // New token account owner to set.
        [], // Additional multisig signers.
        TOKEN_2022_PROGRAM_ID // Token program that owns the token account.
      )
    ),
    [feePayer]
  );
} catch (error) {
  failure = String(error);
}
if (!failure) {
  throw new Error("Expected the owner change to fail");
}

const tokenAccountData = await getAccount(
  connection,
  tokenAccount.publicKey,
  "confirmed",
  TOKEN_2022_PROGRAM_ID
);
const immutableOwnerExtension = getImmutableOwner(tokenAccountData);

console.log("Mint Address:", mint.publicKey.toBase58());
console.log("Token Account:", tokenAccount.publicKey.toBase58());
console.log("ImmutableOwner Extension:", immutableOwnerExtension);
console.log("SetAuthority Failure:", failure);
```

</CodeTabs>

### Rust

<CodeTabs storage="token-rs" flags="r">

```rust !! title="Rust"
use anyhow::{anyhow, Result};
use solana_client::nonblocking::rpc_client::RpcClient;
use solana_commitment_config::CommitmentConfig;
use solana_sdk::{
    program_pack::Pack,
    signature::{Keypair, Signer},
    transaction::Transaction,
};
use solana_system_interface::instruction::create_account;
use spl_token_2022_interface::{
    extension::{
        immutable_owner::ImmutableOwner, BaseStateWithExtensions, ExtensionType,
        StateWithExtensions,
    },
    instruction::{
        initialize_account, initialize_immutable_owner, initialize_mint, set_authority,
        AuthorityType,
    },
    state::{Account, Mint},
    ID as TOKEN_2022_PROGRAM_ID,
};

#[tokio::main]
async fn main() -> Result<()> {
    let client = RpcClient::new_with_commitment(
        String::from("http://localhost:8899"),
        CommitmentConfig::confirmed(),
    );
    let fee_payer = Keypair::new();

    let airdrop_signature = client
        .request_airdrop(&fee_payer.pubkey(), 5_000_000_000)
        .await?;

    loop {
        let confirmed = client.confirm_transaction(&airdrop_signature).await?;
        if confirmed {
            break;
        }
    }

    let mint = Keypair::new();

    let mint_space = Mint::LEN;
    let mint_rent = client
        .get_minimum_balance_for_rent_exemption(mint_space)
        .await?;

    let create_mint_account_instruction = create_account(
        &fee_payer.pubkey(),    // Account funding the new mint account.
        &mint.pubkey(),         // New mint account to create.
        mint_rent,              // Lamports funding the mint account rent.
        mint_space as u64,      // Account size in bytes for the mint.
        &TOKEN_2022_PROGRAM_ID, // Program that owns the mint account.
    );

    let initialize_mint_instruction = initialize_mint(
        &TOKEN_2022_PROGRAM_ID,    // Program that owns the mint account.
        &mint.pubkey(),            // Mint account to initialize.
        &fee_payer.pubkey(),       // Authority allowed to mint new tokens.
        Some(&fee_payer.pubkey()), // Authority allowed to freeze token accounts.
        0,                         // Number of decimals for the token.
    )?;

    let token_account = Keypair::new();

    let token_account_space =
        ExtensionType::try_calculate_account_len::<Account>(&[ExtensionType::ImmutableOwner])?;

    let token_account_rent = client
        .get_minimum_balance_for_rent_exemption(token_account_space)
        .await?;

    let create_token_account_instruction = create_account(
        &fee_payer.pubkey(),        // Account funding the new token account.
        &token_account.pubkey(),    // New token account to create.
        token_account_rent,         // Lamports funding the token account rent.
        token_account_space as u64, // Account size in bytes for the token account plus ImmutableOwner.
        &TOKEN_2022_PROGRAM_ID,     // Program that owns the token account.
    );

    let initialize_token_account = initialize_account(
        &TOKEN_2022_PROGRAM_ID,  // Token program that owns the token account.
        &token_account.pubkey(), // Token account to initialize.
        &mint.pubkey(),          // Mint for the token account.
        &fee_payer.pubkey(),     // Owner of the token account.
    )?;

    // !mark(1:4)
    let init_immutable_owner_instruction =
        initialize_immutable_owner(
            &TOKEN_2022_PROGRAM_ID, // Token program that owns the token account.
            &token_account.pubkey(), // Token account that stores the ImmutableOwner extension.
        )?;

    let transaction = Transaction::new_signed_with_payer(
        &[
            create_mint_account_instruction,
            initialize_mint_instruction,
            create_token_account_instruction,
            init_immutable_owner_instruction,
            initialize_token_account,
        ],
        Some(&fee_payer.pubkey()),
        &[&fee_payer, &mint, &token_account],
        client.get_latest_blockhash().await?,
    );

    client.send_and_confirm_transaction(&transaction).await?;

    let token_account_data = client.get_account(&token_account.pubkey()).await?;
    let token_account_state = StateWithExtensions::<Account>::unpack(&token_account_data.data)?;

    let new_owner = Keypair::new();
    // !mark(1:8)
    let set_authority_instruction = set_authority(
        &TOKEN_2022_PROGRAM_ID, // Token program that owns the token account.
        &token_account.pubkey(), // Token account whose authority is being updated.
        Some(&new_owner.pubkey()), // New token account owner to set.
        AuthorityType::AccountOwner, // Account authority field to change.
        &fee_payer.pubkey(), // Current token account owner signing the instruction.
        &[], // Additional multisig signers.
    )?;

    let set_authority_transaction = Transaction::new_signed_with_payer(
        &[set_authority_instruction],
        Some(&fee_payer.pubkey()),
        &[&fee_payer],
        client.get_latest_blockhash().await?,
    );

    let failure = match client
        .send_and_confirm_transaction(&set_authority_transaction)
        .await
    {
        Ok(sig) => return Err(anyhow!("Expected the owner change to fail: {}", sig)),
        Err(e) => format!("{:#?}", e),
    };

    let immutable_owner_extension = token_account_state.get_extension::<ImmutableOwner>()?;

    println!("Mint Address: {}", mint.pubkey());
    println!("Token Account: {}", token_account.pubkey());
    println!("ImmutableOwner Extension: {:#?}", immutable_owner_extension);
    println!("SetAuthority Failure: {}", failure);

    Ok(())
}
```

</CodeTabs>
