---
title: CPI Guard
description:
  Enable the CpiGuard account extension to block token instructions invoked
  through cross-program invocations.
url: /docs/tokens/extensions/cpi-guard
type: tutorial
prerequisites:
  - /docs/tokens/basics/create-token-account
related:
  - /docs/tokens/extensions/immutable-owner
  - /docs/tokens/extensions
---

## What Is CPI Guard?

The Token Extension Program's _rs`CpiGuard`_ account extension prevents another
onchain program from using a token account for certain token instructions
through a cross-program invocation (CPI).

When CPI guard is enabled, the Token Extension Program rejects these
instructions when another onchain program invokes them through CPI:

- _rs`Transfer`_, _rs`TransferChecked`_, and _rs`TransferCheckedWithFee`_ when
  the token account owner is used as the instruction authority
- _rs`Burn`_ and _rs`BurnChecked`_ when the token account owner is used as the
  instruction authority
- _rs`Approve`_ and _rs`ApproveChecked`_
- _rs`CloseAccount`_ when lamports would be sent somewhere other than the token
  account owner
- _rs`SetAuthority`_ when adding or replacing the close authority

When CPI guard is enabled, these cases are still allowed:

- _rs`Transfer`_, _rs`TransferChecked`_, _rs`TransferCheckedWithFee`_,
  _rs`Burn`_, and _rs`BurnChecked`_ through CPI when a delegate or permanent
  delegate signs instead of the token account owner
- _rs`CloseAccount`_ through CPI when lamports are sent to the token account
  owner
- _rs`SetAuthority`_ to remove an existing close authority
- _rs`Revoke`_

When the token account owner is used as the instruction authority, Token
Extension Program instructions can still be processed if the instruction is
added directly to the transaction instead of being invoked through CPI. Changing
the token account owner with _rs`SetAuthority`_ stays blocked while CPI guard is
enabled, even outside CPI. _rs`EnableCpiGuard`_ and _rs`DisableCpiGuard`_ also
cannot be invoked through CPI.

## How to Enable CPI Guard

To enable CPI guard:

1. Create and initialize a mint.
2. Calculate the token account size and rent needed for a token account with
   _rs`CpiGuard`_.
3. Create and initialize a token account for the mint.
4. Invoke _rs`EnableCpiGuard`_ on the token account.
5. Invoke _rs`DisableCpiGuard`_ on the token account to allow those instructions
   through CPI again.

<ScrollyCoding>

## !!steps Create and initialize the mint

Create and initialize the mint that the token account will use.

<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();

// !focus(1:15)
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
  })
]);
```

## !!steps Calculate token account size

Calculate the token account size for the base token account plus the
_rs`CpiGuard`_ 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:4)
const cpiGuardExtension = extension("CpiGuard", {
  lockCpi: false
});
const tokenSpace = BigInt(getTokenSize([cpiGuardExtension]));
```

## !!steps Calculate rent

Calculate rent using the token account size needed for the _rs`CpiGuard`_
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 cpiGuardExtension = extension("CpiGuard", {
  lockCpi: false
});
const tokenSpace = BigInt(getTokenSize([cpiGuardExtension]));

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

## !!steps Create and initialize the token account

Create the token account with the calculated space and lamports, then initialize
it for the mint.

<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 cpiGuardExtension = extension("CpiGuard", {
  lockCpi: false
});
const tokenSpace = BigInt(getTokenSize([cpiGuardExtension]));

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

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

## !!steps Enable CPI guard

Enable _rs`CpiGuard`_ 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 cpiGuardExtension = extension("CpiGuard", {
  lockCpi: false
});
const tokenSpace = BigInt(getTokenSize([cpiGuardExtension]));

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
  }),
  getInitializeAccountInstruction({
    account: tokenAccount.address,
    mint: mint.address,
    owner: client.payer.address
  })
]);

// !focus(1:6)
await client.sendTransaction([
  getEnableCpiGuardInstruction({
    token: tokenAccount.address,
    owner: client.payer
  })
]);
```

## !!steps Disable CPI guard

Disable _rs`CpiGuard`_ 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 cpiGuardExtension = extension("CpiGuard", {
  lockCpi: false
});
const tokenSpace = BigInt(getTokenSize([cpiGuardExtension]));

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
  }),
  getInitializeAccountInstruction({
    account: tokenAccount.address,
    mint: mint.address,
    owner: client.payer.address
  })
]);

await client.sendTransaction([
  getEnableCpiGuardInstruction({
    token: tokenAccount.address,
    owner: client.payer
  })
]);

// !focus(1:6)
await client.sendTransaction([
  getDisableCpiGuardInstruction({
    token: tokenAccount.address,
    owner: client.payer
  })
]);
```

</ScrollyCoding>

### Source Reference

| Item                               | Description                                                                                                                                                                                                              | Source                                                                                                                                 |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| _rs`CpiGuard`_                     | Account extension that stores whether CPI guard is currently enabled for the token account.                                                                                                                              | [Source](https://github.com/solana-program/token-2022/blob/program%40v10.0.0/interface/src/extension/cpi_guard/mod.rs#L20-L25)         |
| _rs`CpiGuardInstruction::Enable`_  | Instruction that enables CPI guard on a token account.                                                                                                                                                                   | [Source](https://github.com/solana-program/token-2022/blob/program%40v10.0.0/interface/src/extension/cpi_guard/instruction.rs#L20-L38) |
| _rs`CpiGuardInstruction::Disable`_ | Instruction that disables CPI guard on a token account.                                                                                                                                                                  | [Source](https://github.com/solana-program/token-2022/blob/program%40v10.0.0/interface/src/extension/cpi_guard/instruction.rs#L39-L53) |
| _rs`process_toggle_cpi_guard`_     | Processor logic used by _rs`Enable`_ and _rs`Disable`_ that validates account ownership, rejects CPI changes to the guard itself, and initializes _rs`CpiGuard`_ if it is not already present before setting `lock_cpi`. | [Source](https://github.com/solana-program/token-2022/blob/program%40v10.0.0/program/src/extension/cpi_guard/processor.rs#L19-L52)     |

### 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 {
  extension,
  fetchToken,
  getDisableCpiGuardInstruction,
  getEnableCpiGuardInstruction,
  getInitializeAccountInstruction,
  getInitializeMintInstruction,
  getMintSize,
  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 mintSpace = BigInt(getMintSize());
const mintRent = await client.rpc
  .getMinimumBalanceForRentExemption(mintSpace)
  .send();

await client.sendTransaction([
  getCreateAccountInstruction({
    payer: client.payer, // Account funding account creation.
    newAccount: mint, // New mint account to create.
    lamports: mintRent, // Lamports funding the mint account rent.
    space: mintSpace, // Account size in bytes for the mint account.
    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 cpiGuardExtension = extension("CpiGuard", {
  lockCpi: false
});
const tokenSpace = BigInt(getTokenSize([cpiGuardExtension]));
const tokenRent = await client.rpc
  .getMinimumBalanceForRentExemption(tokenSpace)
  .send();

await client.sendTransaction([
  getCreateAccountInstruction({
    payer: client.payer, // Account funding account creation.
    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 CpiGuard.
    programAddress: TOKEN_2022_PROGRAM_ADDRESS // Program that owns the token account.
  }),
  getInitializeAccountInstruction({
    account: tokenAccount.address, // Token account to initialize.
    mint: mint.address, // Mint for the token account.
    owner: client.payer.address // Owner allowed to control the token account.
  })
]);

await client.sendTransaction([
  // !mark(1:4)
  getEnableCpiGuardInstruction({
    token: tokenAccount.address, // Token account that stores the CpiGuard extension.
    owner: client.payer // Token account owner authorized to enable CPI guard.
  })
]);

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

await client.sendTransaction([
  // !mark(1:4)
  getDisableCpiGuardInstruction({
    token: tokenAccount.address, // Token account that stores the CpiGuard extension.
    owner: client.payer // Token account owner authorized to disable CPI guard.
  })
]);

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

console.log("\nMint Address:", mint.address);
console.log("\nToken Account:", tokenAccount.address);
console.log("\nEnabled CPI Guard:", enabledCpiGuard);
console.log("\nDisabled CPI Guard:", disabledCpiGuard);
```

</CodeTabs>

#### Web3.js

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

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

const connection = new Connection("http://localhost:8899", "confirmed");
const latestBlockhash = await connection.getLatestBlockhash();

const feePayer = Keypair.generate();
const mint = Keypair.generate();
const tokenAccount = Keypair.generate();

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

const mintSpace = getMintLen([]);
const mintRent = await connection.getMinimumBalanceForRentExemption(mintSpace);

await sendAndConfirmTransaction(
  connection,
  new Transaction().add(
    SystemProgram.createAccount({
      fromPubkey: feePayer.publicKey, // Account funding account creation.
      newAccountPubkey: mint.publicKey, // New mint account to create.
      space: mintSpace, // Account size in bytes for the mint account.
      lamports: mintRent, // Lamports funding the mint account rent.
      programId: TOKEN_2022_PROGRAM_ID // Program that owns the mint account.
    }),
    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.
    )
  ),
  [feePayer, mint],
  { commitment: "confirmed" }
);

const tokenAccountSpace = getAccountLen([ExtensionType.CpiGuard]);
const tokenAccountRent =
  await connection.getMinimumBalanceForRentExemption(tokenAccountSpace);

await sendAndConfirmTransaction(
  connection,
  new Transaction().add(
    SystemProgram.createAccount({
      fromPubkey: feePayer.publicKey, // Account funding account creation.
      newAccountPubkey: tokenAccount.publicKey, // New token account to create.
      space: tokenAccountSpace, // Account size in bytes for the token account plus CpiGuard.
      lamports: tokenAccountRent, // Lamports funding the token account rent.
      programId: TOKEN_2022_PROGRAM_ID // Program that owns the token account.
    }),
    createInitializeAccountInstruction(
      tokenAccount.publicKey, // Token account to initialize.
      mint.publicKey, // Mint for the token account.
      feePayer.publicKey, // Owner allowed to control the token account.
      TOKEN_2022_PROGRAM_ID // Program that owns the token account.
    )
  ),
  [feePayer, tokenAccount],
  { commitment: "confirmed" }
);

await sendAndConfirmTransaction(
  connection,
  new Transaction().add(
    // !mark(1:6)
    createEnableCpiGuardInstruction(
      tokenAccount.publicKey, // Token account that stores the CpiGuard extension.
      feePayer.publicKey, // Token account owner authorized to enable CPI guard.
      [], // Additional multisig signers.
      TOKEN_2022_PROGRAM_ID // Token program that owns the token account.
    )
  ),
  [feePayer],
  { commitment: "confirmed" }
);

const enabledTokenAccount = await getAccount(
  connection,
  tokenAccount.publicKey,
  "confirmed",
  TOKEN_2022_PROGRAM_ID
);
const enabledCpiGuard = getCpiGuard(enabledTokenAccount);

await sendAndConfirmTransaction(
  connection,
  new Transaction().add(
    // !mark(1:6)
    createDisableCpiGuardInstruction(
      tokenAccount.publicKey, // Token account that stores the CpiGuard extension.
      feePayer.publicKey, // Token account owner authorized to disable CPI guard.
      [], // Additional multisig signers.
      TOKEN_2022_PROGRAM_ID // Token program that owns the token account.
    )
  ),
  [feePayer],
  { commitment: "confirmed" }
);

const disabledTokenAccount = await getAccount(
  connection,
  tokenAccount.publicKey,
  "confirmed",
  TOKEN_2022_PROGRAM_ID
);
const disabledCpiGuard = getCpiGuard(disabledTokenAccount);

console.log("\nMint Address:", mint.publicKey.toBase58());
console.log("\nToken Account:", tokenAccount.publicKey.toBase58());
console.log("\nEnabled CPI Guard:", enabledCpiGuard);
console.log("\nDisabled CPI Guard:", disabledCpiGuard);
```

</CodeTabs>

### Rust

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

```rust !! title="Rust"
use 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::{
        cpi_guard::{
            instruction::{disable_cpi_guard, enable_cpi_guard},
            CpiGuard,
        },
        BaseStateWithExtensions, ExtensionType, StateWithExtensions,
    },
    instruction::{initialize_account, initialize_mint},
    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 token_account = Keypair::new();

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

    let create_mint_transaction = Transaction::new_signed_with_payer(
        &[
            create_account(
                &fee_payer.pubkey(), // Account funding account creation.
                &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 account.
                &TOKEN_2022_PROGRAM_ID, // Program that owns the mint account.
            ),
            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.
            )?,
        ],
        Some(&fee_payer.pubkey()),
        &[&fee_payer, &mint],
        client.get_latest_blockhash().await?,
    );
    client
        .send_and_confirm_transaction(&create_mint_transaction)
        .await?;

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

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

    let create_token_account_transaction = Transaction::new_signed_with_payer(
        &[
            create_account(
                &fee_payer.pubkey(), // Account funding account creation.
                &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 CpiGuard.
                &TOKEN_2022_PROGRAM_ID, // Program that owns the token account.
            ),
            initialize_account(
                &TOKEN_2022_PROGRAM_ID, // Program that owns the token account.
                &token_account.pubkey(), // Token account to initialize.
                &mint.pubkey(), // Mint for the token account.
                &fee_payer.pubkey(), // Owner allowed to control the token account.
            )?,
        ],
        Some(&fee_payer.pubkey()),
        &[&fee_payer, &token_account],
        client.get_latest_blockhash().await?,
    );
    client
        .send_and_confirm_transaction(&create_token_account_transaction)
        .await?;

    // !mark(1:6)
    let enable_cpi_guard_instruction = enable_cpi_guard(
        &TOKEN_2022_PROGRAM_ID, // Token program that owns the token account.
        &token_account.pubkey(), // Token account that stores the CpiGuard extension.
        &fee_payer.pubkey(), // Token account owner authorized to enable CPI guard.
        &[], // Additional multisig signers.
    )?;

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

    let enabled_token_account_data = client.get_account(&token_account.pubkey()).await?;
    let enabled_token_account_state =
        StateWithExtensions::<Account>::unpack(&enabled_token_account_data.data)?;
    let enabled_cpi_guard = enabled_token_account_state.get_extension::<CpiGuard>()?;

    // !mark(1:6)
    let disable_cpi_guard_instruction = disable_cpi_guard(
        &TOKEN_2022_PROGRAM_ID, // Token program that owns the token account.
        &token_account.pubkey(), // Token account that stores the CpiGuard extension.
        &fee_payer.pubkey(), // Token account owner authorized to disable CPI guard.
        &[], // Additional multisig signers.
    )?;

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

    let disabled_token_account_data = client.get_account(&token_account.pubkey()).await?;
    let disabled_token_account_state =
        StateWithExtensions::<Account>::unpack(&disabled_token_account_data.data)?;
    let disabled_cpi_guard = disabled_token_account_state.get_extension::<CpiGuard>()?;

    println!("\nMint Address: {}", mint.pubkey());
    println!("\nToken Account: {}", token_account.pubkey());
    println!("\nEnabled CPI Guard: {:#?}", enabled_cpi_guard);
    println!("\nDisabled CPI Guard: {:#?}", disabled_cpi_guard);

    Ok(())
}
```

</CodeTabs>
