Freezing & Thawing

Put a temporary or permanent stop to token transfers.

"Freezing" refers to the process of temporarily suspending the transferability of a collection or a specific token.

This action provides you greater control over the movement of assets, enhancing security and enabling unique use-cases.

One such use-case is the implementation of "Soulbound" tokens. A Soulbound token is bound to a specific address and cannot be transferred out of the wallet it's minted on. This feature can be used to create unique gameplay mechanics, loyalty rewards, and more.

📘

What you'll need:

There are two ways to Freeze / Thaw:

  1. Using the Platform User Interface
  2. Using the GraphQL API

Option A. Using the Platform User Interface

📘

Note: Applying Freeze/Thaw Actions to Collections and Tokens

This tutorial illustrates the process of freezing a collection.

However, the same steps can be applied to freeze or thaw tokens.

Simply navigate to the corresponding menu for tokens instead of collections, or for thawing instead of freezing.

Freezing an entire collection

In the Platform menu, navigate to "Collections".
Locate the collection you wish to freeze, click the 3 vertical dots () to it's right, then click the "Freeze" button.

Choose the freeze state, and click on the "Freeze" button.

Freeze form on Enjin Platform

Freeze form on Enjin Platform

The Transaction Request will then appear in the "Transactions" menu.

A notification appears after you create a <<glossary:Mutation>>.

A notification appears after you create a Mutation.

Clicking "**View**" on the notification will take you to your Transactions List.

Clicking "View" on the notification will take you to your Transactions List.

Since this transaction is a Mutation, you will need to sign the transaction using your Wallet.

  • If a Wallet Daemon is running and configured, the transaction request will be signed automatically.
  • If a wallet is connected such as the Enjin Wallet or Polkadot.js, the transaction must be signed manually by clicking the "Sign" button and approving the signature request in your wallet.

Option B. Using the GraphQL API / SDKs

Freezing a Collection or Token

By freezing a collection, all tokens within that collection will be frozen, meaning they cannot be burned or transferred out of the wallet they're currently in.

Freezing an entire collection

Use the Freeze mutation and the freezeType: COLLECTION argument to freeze a collection.

mutation FreezeCollection{
  Freeze(
    collectionId: 36105 #Specify the collection ID
    freezeType: COLLECTION #For collection freezing
  ){
    id
    method
    state
  }
}
using System.Text.Json;
using Enjin.Platform.Sdk;

// Setup the mutation
var freezeCollection = new Freeze()
    .SetCollectionId(36105)
    .SetFreezeType(FreezeType.Collection);

// Define and assign the return data fragment to the mutation
var transactionFragment = new TransactionFragment()
    .WithId()
    .WithMethod()
    .WithState();

freezeCollection.Fragment(transactionFragment);

// Create and auth a client to send the request to the platform
var client = PlatformClient.Builder()
    .SetBaseAddress("https://platform.canary.enjin.io")
    .Build();
client.Auth("Your_Platform_Token_Here");

// Send the request and write the output to the console.
// Only the fields that were requested in the fragment will be filled in,
// other fields which weren't requested in the fragment will be set to null.
var response = await client.SendFreeze(freezeCollection);
Console.WriteLine(JsonSerializer.Serialize(response.Result.Data));
#include "EnjinPlatformSdk/CoreMutations.hpp"
#include <iostream>

using namespace enjin::platform::sdk;
using namespace std;

int main() {

    // Set up the mutation
    Freeze freezeCollection = Freeze()
            .SetCollectionId(make_shared<SerializableString>("36105"))
            .SetFreezeType(FreezeType::Collection);

    // Define Fragment for the returned data
    TransactionFragment transactionFragment = TransactionFragment()
            .WithId()
            .WithMethod()
            .WithState();

    freezeCollection.SetFragment(make_shared<TransactionFragment>(transactionFragment));

    // Create and auth a client to send the request to the platform
    unique_ptr<PlatformClient> client = PlatformClient::Builder()
            .SetBaseAddress("https://platform.canary.enjin.io")
            .Build();
    client->Auth("Your_Platform_Token_Here");

    // Send the request then get the response and write the output to the console.
    // Only the fields that were requested in the fragment will be filled in,
    // other fields which weren't requested in the fragment will be set to null.
    future<PlatformResponsePtr<GraphQlResponse<Transaction>>> futureResponse = SendFreeze(*client, freezeCollection);

    // Get the platform response holding the HTTP data
    PlatformResponsePtr<GraphQlResponse<Transaction>> response = futureResponse.get();

    // Get the result, a GraphQL response, holding the GraphQL data
    const optional<GraphQlResponse<Transaction>>& gqlResult = response->GetResult();

    // Write the result data to the console
    if (gqlResult.has_value() && gqlResult->IsSuccess())
    {
        const optional<Transaction>& freezeCollectionResult = gqlResult->GetData()->GetResult();

        std::cout << freezeCollectionResult->GetId().value() << std::endl;
    }

    // Write any error messages to the console
    if (gqlResult.has_value() && gqlResult->HasErrors())
    {
        const optional<vector<GraphQlError>>& errors = gqlResult->GetErrors();

        for (const GraphQlError& error : errors.value()) {
            std::cout << error.GetMessage().value() << std::endl;
        }
    }

    client.reset();

    return 0;
}

fetch('https://platform.canary.enjin.io/graphql', {
  method: 'POST',
  headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'},
  body: JSON.stringify({
    query: `
      mutation FreezeCollection
      (
        $collection_id: BigInt!
        $freeze_type: FreezeType!
      )  {
        Freeze(
          collectionId: $collection_id 
          freezeType: $freeze_type
        ){
          id
          method
          state
        }
      }
    `,
    variables: {
      collection_id: 36105, //Specify the collection ID
      freeze_type: "COLLECTION" //For collection freezing
    }
  }),
})
.then(response => response.json())
.then(data => console.log(data));
const axios = require('axios');

axios.post('https://platform.canary.enjin.io/graphql', {
  query: `
    mutation FreezeCollection
    (
      $collection_id: BigInt!
      $freeze_type: FreezeType!
    )  {
      Freeze(
        collectionId: $collection_id 
        freezeType: $freeze_type
      ){
        id
        method
        state
      }
    }
  `,
  variables: {
    collection_id: 36105, //Specify the collection ID
    freeze_type: "COLLECTION" //For collection freezing
  }
}, {
  headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
import requests

query = '''
mutation FreezeCollection
(
  $collection_id: BigInt!
  $freeze_type: FreezeType!
)  {
  Freeze(
    collectionId: $collection_id 
    freezeType: $freeze_type
  ){
    id
    method
    state
  }
}
'''

variables = {
  'collection_id': 36105, #Specify the collection ID
  'freeze_type': "COLLECTION" #For collection freezing
}

response = requests.post('https://platform.canary.enjin.io/graphql',
  json={'query': query, 'variables': variables},
  headers={'Content-Type': 'application/json', 'Authorization': 'Your_Platform_Token_Here'}
)
print(response.json())

Once the transaction is executed, all tokens within the specified collection will be frozen.

Freezing a single token

Use the Freeze mutation and the freezeType: TOKEN argument to freeze a token.

mutation FreezeToken{
  Freeze(
    collectionId: 36105 #Specify the collection ID
    tokenId:{integer: 0} #Specify the token ID
    freezeType: TOKEN #For token freezing
    freezeState: TEMPORARY #Select the freeze state
  ){
    id
    method
    state
  }
}
using System.Text.Json;
using Enjin.Platform.Sdk;

// Setup the mutation
var freezeToken = new Freeze()
    .SetCollectionId(36105)
    .SetTokenId(new EncodableTokenIdInput().SetInteger(0))
    .SetFreezeType(FreezeType.Token)
    .SetFreezeState(FreezeState.Temporary);

// Define and assign the return data fragment to the mutation
var transactionFragment = new TransactionFragment()
    .WithId()
    .WithMethod()
    .WithState();

freezeToken.Fragment(transactionFragment);

// Create and auth a client to send the request to the platform
var client = PlatformClient.Builder()
    .SetBaseAddress("https://platform.canary.enjin.io")
    .Build();
client.Auth("Your_Platform_Token_Here");

// Send the request and write the output to the console.
// Only the fields that were requested in the fragment will be filled in,
// other fields which weren't requested in the fragment will be set to null.
var response = await client.SendFreeze(freezeToken);
Console.WriteLine(JsonSerializer.Serialize(response.Result.Data));
#include "EnjinPlatformSdk/CoreMutations.hpp"
#include <iostream>

using namespace enjin::platform::sdk;
using namespace std;

int main() {

    // Setup an Encodable Token ID
    EncodableTokenIdInput tokenId = EncodableTokenIdInput()
            .SetInteger(make_shared<SerializableString>("0"));

    // Set up the mutation
    Freeze freezeToken = Freeze()
            .SetCollectionId(make_shared<SerializableString>("36105"))
            .SetTokenId(make_shared<EncodableTokenIdInput>(tokenId))
            .SetFreezeType(FreezeType::Token)
            .SetFreezeState(FreezeState::Temporary);

    // Define Fragment for the returned data
    TransactionFragment transactionFragment = TransactionFragment()
            .WithId()
            .WithMethod()
            .WithState();

    freezeToken.SetFragment(make_shared<TransactionFragment>(transactionFragment));

    // Create and auth a client to send the request to the platform
    unique_ptr<PlatformClient> client = PlatformClient::Builder()
            .SetBaseAddress("https://platform.canary.enjin.io")
            .Build();
    client->Auth("Your_Platform_Token_Here");

    // Send the request then get the response and write the output to the console.
    // Only the fields that were requested in the fragment will be filled in,
    // other fields which weren't requested in the fragment will be set to null.
    future<PlatformResponsePtr<GraphQlResponse<Transaction>>> futureResponse = SendFreeze(*client, freezeToken);

    // Get the platform response holding the HTTP data
    PlatformResponsePtr<GraphQlResponse<Transaction>> response = futureResponse.get();

    // Get the result, a GraphQL response, holding the GraphQL data
    const optional<GraphQlResponse<Transaction>>& gqlResult = response->GetResult();

    // Write the result data to the console
    if (gqlResult.has_value() && gqlResult->IsSuccess())
    {
        const optional<Transaction>& freezeTokenResult = gqlResult->GetData()->GetResult();

        std::cout << freezeTokenResult->GetId().value() << std::endl;
    }

    // Write any error messages to the console
    if (gqlResult.has_value() && gqlResult->HasErrors())
    {
        const optional<vector<GraphQlError>>& errors = gqlResult->GetErrors();

        for (const GraphQlError& error : errors.value()) {
            std::cout << error.GetMessage().value() << std::endl;
        }
    }

    client.reset();

    return 0;
}

fetch('https://platform.canary.enjin.io/graphql', {
  method: 'POST',
  headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'},
  body: JSON.stringify({
    query: `
      mutation FreezeToken
      (
        $collection_id: BigInt!
        $token_id: BigInt!
        $freeze_type: FreezeType!
        $freeze_state: FreezeStateType

      ) {
        Freeze(
          collectionId: $collection_id
          tokenId:{integer: $token_id}
          freezeType: $freeze_type
          freezeState: $freeze_state
        ){
          id
          method
          state
        }
      }
    `,
    variables: {
      collection_id: 36105, //Specify the collection ID
      token_id: 0, //Specify the token ID
      freeze_type: "TOKEN", //For token freezing
      freeze_state: "TEMPORARY" //Select the freeze state
    }
  }),
})
.then(response => response.json())
.then(data => console.log(data));
const axios = require('axios');

axios.post('https://platform.canary.enjin.io/graphql', {
  query: `
    mutation FreezeToken
    (
      $collection_id: BigInt!
      $token_id: BigInt!
      $freeze_type: FreezeType!
      $freeze_state: FreezeStateType

    ) {
      Freeze(
        collectionId: $collection_id
        tokenId:{integer: $token_id}
        freezeType: $freeze_type
        freezeState: $freeze_state
      ){
        id
        method
        state
      }
    }
  `,
  variables: {
    collection_id: 36105, //Specify the collection ID
    token_id: 0, //Specify the token ID
    freeze_type: "TOKEN", //For token freezing
    freeze_state: "TEMPORARY" //Select the freeze state
  }
}, {
  headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
import requests

query = '''
mutation FreezeToken
(
  $collection_id: BigInt!
  $token_id: BigInt!
  $freeze_type: FreezeType!
  $freeze_state: FreezeStateType
  
) {
  Freeze(
    collectionId: $collection_id
    tokenId:{integer: $token_id}
    freezeType: $freeze_type
    freezeState: $freeze_state
  ){
    id
    method
    state
  }
}
'''

variables = {
  'collection_id': 36105, #Specify the collection ID
  'token_id': 0, #Specify the token ID
  'freeze_type': "TOKEN", #For token freezing
  'freeze_state': "TEMPORARY" #Select the freeze state
}

response = requests.post('https://platform.canary.enjin.io/graphql',
  json={'query': query, 'variables': variables},
  headers={'Content-Type': 'application/json', 'Authorization': 'Your_Platform_Token_Here'}
)
print(response.json())

Once the transaction is executed, the specified token will be frozen.

Thawing a Collection or Token

Thawing a collection means allowing all tokens within that collection to be active again, so they can be transferred or burned as desired, removing the restrictions that kept them locked in a particular wallet.

Thawing an entire collection

By thawing a collection, all tokens within that collection will be thawed, meaning they can be burned and transferred out of the wallet they're currently in.

Use the Thaw mutation and the freezeType: COLLECTION argument to thaw a collection.

mutation ThawCollection{
  Thaw(
    collectionId: 36105 #Specify the collection ID
    freezeType: COLLECTION #For collection thawing
  ){
    id
    method
    state
  }
}
using System.Text.Json;
using Enjin.Platform.Sdk;

// Setup the mutation
var thawCollection = new Thaw()
    .SetCollectionId(36105)
    .SetFreezeType(FreezeType.Collection);

// Define and assign the return data fragment to the mutation
var transactionFragment = new TransactionFragment()
    .WithId()
    .WithMethod()
    .WithState();

thawCollection.Fragment(transactionFragment);

// Create and auth a client to send the request to the platform
var client = PlatformClient.Builder()
    .SetBaseAddress("https://platform.canary.enjin.io")
    .Build();
client.Auth("Your_Platform_Token_Here");

// Send the request and write the output to the console.
// Only the fields that were requested in the fragment will be filled in,
// other fields which weren't requested in the fragment will be set to null.
var response = await client.SendThaw(thawCollection);
Console.WriteLine(JsonSerializer.Serialize(response.Result.Data));
#include "EnjinPlatformSdk/CoreMutations.hpp"
#include <iostream>

using namespace enjin::platform::sdk;
using namespace std;

int main() {

    // Set up the mutation
    Thaw thawCollection = Thaw()
            .SetCollectionId(make_shared<SerializableString>("36105"))
            .SetFreezeType(FreezeType::Collection);

    // Define Fragment for the returned data
    TransactionFragment transactionFragment = TransactionFragment()
            .WithId()
            .WithMethod()
            .WithState();

    thawCollection.SetFragment(make_shared<TransactionFragment>(transactionFragment));

    // Create and auth a client to send the request to the platform
    unique_ptr<PlatformClient> client = PlatformClient::Builder()
            .SetBaseAddress("https://platform.canary.enjin.io")
            .Build();
    client->Auth("Your_Platform_Token_Here");

    // Send the request then get the response and write the output to the console.
    // Only the fields that were requested in the fragment will be filled in,
    // other fields which weren't requested in the fragment will be set to null.
    future<PlatformResponsePtr<GraphQlResponse<Transaction>>> futureResponse = SendThaw(*client, thawCollection);

    // Get the platform response holding the HTTP data
    PlatformResponsePtr<GraphQlResponse<Transaction>> response = futureResponse.get();

    // Get the result, a GraphQL response, holding the GraphQL data
    const optional<GraphQlResponse<Transaction>>& gqlResult = response->GetResult();

    // Write the result data to the console
    if (gqlResult.has_value() && gqlResult->IsSuccess())
    {
        const optional<Transaction>& thawCollectionResult = gqlResult->GetData()->GetResult();

        std::cout << thawCollectionResult->GetId().value() << std::endl;
    }

    // Write any error messages to the console
    if (gqlResult.has_value() && gqlResult->HasErrors())
    {
        const optional<vector<GraphQlError>>& errors = gqlResult->GetErrors();

        for (const GraphQlError& error : errors.value()) {
            std::cout << error.GetMessage().value() << std::endl;
        }
    }

    client.reset();

    return 0;
}

fetch('https://platform.canary.enjin.io/graphql', {
  method: 'POST',
  headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'},
  body: JSON.stringify({
    query: `
      mutation ThawCollection
      (
        $collection_id: BigInt!
        $freeze_type: FreezeType!
      ) {
        Thaw(
          collectionId: $collection_id 
          freezeType: $freeze_type
        ){
          id
          method
          state
        }
      }
    `,
    variables: {
      collection_id: 36105, //Specify the collection ID
      freeze_type: "COLLECTION" //For collection thawing
    }
  }),
})
.then(response => response.json())
.then(data => console.log(data));
const axios = require('axios');

axios.post('https://platform.canary.enjin.io/graphql', {
  query: `
    mutation ThawCollection
    (
      $collection_id: BigInt!
      $freeze_type: FreezeType!
    ) {
      Thaw(
        collectionId: $collection_id 
        freezeType: $freeze_type
      ){
        id
        method
        state
      }
    }
  `,
  variables: {
    collection_id: 36105, //Specify the collection ID
    freeze_type: "COLLECTION" //For collection thawing
  }
}, {
  headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
import requests

query = '''
mutation ThawCollection
(
  $collection_id: BigInt!
  $freeze_type: FreezeType!
) {
  Thaw(
    collectionId: $collection_id 
    freezeType: $freeze_type
  ){
    id
    method
    state
  }
}
'''

variables = {
  'collection_id': 36105, #Specify the collection ID
  'freeze_type': "COLLECTION" #For collection thawing
}

response = requests.post('https://platform.canary.enjin.io/graphql',
  json={'query': query, 'variables': variables},
  headers={'Content-Type': 'application/json', 'Authorization': 'Your_Platform_Token_Here'}
)
print(response.json())

Once the transaction is executed, all tokens within the specified collection will be thawed.

Thawing a single token

Use the Thaw mutation and the freezeType: TOKEN argument to thaw a token.

mutation ThawToken{
  Thaw(
    collectionId: 36105 #Specify the collection ID
    tokenId:{integer: 0} #Specify the token ID
    freezeType: TOKEN #For token thawing
  ) {
    id
    method
    state
  }
}
using System.Text.Json;
using Enjin.Platform.Sdk;

// Setup the mutation
var thawToken = new Thaw()
    .SetCollectionId(36105)
    .SetTokenId(new EncodableTokenIdInput().SetInteger(0))
    .SetFreezeType(FreezeType.Token);

// Define and assign the return data fragment to the mutation
var transactionFragment = new TransactionFragment()
    .WithId()
    .WithMethod()
    .WithState();

thawToken.Fragment(transactionFragment);

// Create and auth a client to send the request to the platform
var client = PlatformClient.Builder()
    .SetBaseAddress("https://platform.canary.enjin.io")
    .Build();
client.Auth("Your_Platform_Token_Here");

// Send the request and write the output to the console.
// Only the fields that were requested in the fragment will be filled in,
// other fields which weren't requested in the fragment will be set to null.
var response = await client.SendThaw(thawToken);
Console.WriteLine(JsonSerializer.Serialize(response.Result.Data));
#include "EnjinPlatformSdk/CoreMutations.hpp"
#include <iostream>

using namespace enjin::platform::sdk;
using namespace std;

int main() {

    // Setup an Encodable Token ID
    EncodableTokenIdInput tokenId = EncodableTokenIdInput()
            .SetInteger(make_shared<SerializableString>("0"));

    // Set up the mutation
    Thaw thawToken = Thaw()
            .SetCollectionId(make_shared<SerializableString>("36105"))
            .SetTokenId(make_shared<EncodableTokenIdInput>(tokenId))
            .SetFreezeType(FreezeType::Token);

    // Define Fragment for the returned data
    TransactionFragment transactionFragment = TransactionFragment()
            .WithId()
            .WithMethod()
            .WithState();

    thawToken.SetFragment(make_shared<TransactionFragment>(transactionFragment));

    // Create and auth a client to send the request to the platform
    unique_ptr<PlatformClient> client = PlatformClient::Builder()
            .SetBaseAddress("https://platform.canary.enjin.io")
            .Build();
    client->Auth("Your_Platform_Token_Here");

    // Send the request then get the response and write the output to the console.
    // Only the fields that were requested in the fragment will be filled in,
    // other fields which weren't requested in the fragment will be set to null.
    future<PlatformResponsePtr<GraphQlResponse<Transaction>>> futureResponse = SendThaw(*client, thawToken);

    // Get the platform response holding the HTTP data
    PlatformResponsePtr<GraphQlResponse<Transaction>> response = futureResponse.get();

    // Get the result, a GraphQL response, holding the GraphQL data
    const optional<GraphQlResponse<Transaction>>& gqlResult = response->GetResult();

    // Write the result data to the console
    if (gqlResult.has_value() && gqlResult->IsSuccess())
    {
        const optional<Transaction>& thawTokenResult = gqlResult->GetData()->GetResult();

        std::cout << thawTokenResult->GetId().value() << std::endl;
    }

    // Write any error messages to the console
    if (gqlResult.has_value() && gqlResult->HasErrors())
    {
        const optional<vector<GraphQlError>>& errors = gqlResult->GetErrors();

        for (const GraphQlError& error : errors.value()) {
            std::cout << error.GetMessage().value() << std::endl;
        }
    }

    client.reset();

    return 0;
}

fetch('https://platform.canary.enjin.io/graphql', {
  method: 'POST',
  headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'},
  body: JSON.stringify({
    query: `
      mutation ThawToken
      (
        $collection_id: BigInt!
        $token_id: BigInt!
        $freeze_type: FreezeType!
      ) {
        Thaw(
          collectionId: $collection_id
          tokenId:{integer: $token_id}
          freezeType: $freeze_type
        ) {
          id
          method
          state
        }
      }
    `,
    variables: {
      collection_id: 36105, //Specify the collection ID
      token_id: 0, //Specify the collection ID
      freeze_type: "TOKEN" //For token thawing
    }
  }),
})
.then(response => response.json())
.then(data => console.log(data));
const axios = require('axios');

axios.post('https://platform.canary.enjin.io/graphql', {
  query: `
    mutation ThawToken
    (
      $collection_id: BigInt!
      $token_id: BigInt!
      $freeze_type: FreezeType!
    ) {
      Thaw(
        collectionId: $collection_id
        tokenId:{integer: $token_id}
        freezeType: $freeze_type
      ) {
        id
        method
        state
      }
    }
  `,
  variables: {
    collection_id: 36105, //Specify the collection ID
    token_id: 0, //Specify the collection ID
    freeze_type: "TOKEN" //For token thawing
  }
}, {
  headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
import requests

query = '''
mutation ThawToken
(
  $collection_id: BigInt!
  $token_id: BigInt!
  $freeze_type: FreezeType!
) {
  Thaw(
    collectionId: $collection_id
    tokenId:{integer: $token_id}
    freezeType: $freeze_type
  ) {
    id
    method
    state
  }
}
'''

variables = {
  'collection_id': 36105, #Specify the collection ID
  'token_id': 0, #Specify the collection ID
  'freeze_type': "TOKEN" #For token thawing
}

response = requests.post('https://platform.canary.enjin.io/graphql',
  json={'query': query, 'variables': variables},
  headers={'Content-Type': 'application/json', 'Authorization': 'Your_Platform_Token_Here'}
)
print(response.json())

Once the transaction is executed, the specified token will be thawed.

📘

More Fields and Arguments Available!

While the examples here cover the core functionalities of the Freeze and Thaw mutations, there are a few more settings you can adjust.

To view and understand all the available settings for the Freeze and Thaw mutations, refer to our GraphQL Schema on Apollo.

These resources will guide you in tailoring the Freeze and Thaw mutations to your specific requirements.