This guide explains how to use the /v1/tokenization/tokens
endpoint through the SDK to issue a new ERC20F token. This will allow you to deploy and link the token to an asset, enabling easy management of issuance, minting, and burning operations.
What is ERC20F?
ERC20F is a fungible token reference implementation developed by Fireblocks. It builds upon the widely used ERC-20 token standard, with added functionality for upgradability and enhanced control over token operations. This implementation is designed to be flexible, allowing for token minting, burning, and secure integration within Fireblocks' ecosystem. It is optimized for compliance, making it ideal for organizations requiring scalable and customizable token management solutions.
It's important to note that the ERC20F token uses a proxy pattern, which decouples the state (in the proxy) from the
smart contract logic (referred to as implementation
in this guide) to support upgradability. Read more about the upgradability features of this contract here.
We built a contract template for ERC20F tokens that you can use to issue new tokens. To find more information about Templates, refer to the Contract Template guide.
Prerequisites
Before issuing a new ERC20F token using the Fireblocks SDK, ensure you know the following:
- Asset ID: The
assetId
of the blockchain where the token will be deployed (e.g. ETH_TEST5 for Sepolia). This is the Fireblocks ID of the gas token of the blockchain where the token will be deployed. (To get the asset ID, refer to this assetId list) - Vault Account: The
vaultAccountId
that will deploy the token. Ensure the vault has sufficient native gas for transaction fees. You can retrieve the vaultAccountId from the Fireblocks console by checking the URL of the selected vault, e.g.,https://console.fireblocks.io/v2/accounts/vault/<vaultAccountId>
. For more details about Vault Accounts, refer to the Create Vault Account guide. - Contract Template: Ensure the contract template is uploaded, and you have the
templateId
from the template. for details. (ForERC20F
, the contract template ID is41c76f08-3144-4641-96c9-260c8fe846a7
forProd US
workspaces). - Ensure you have access to the
Fireblocks Smart Contracts package
, which includes the reference protocol contracts.
With these in place, you can use the Fireblocks SDK to issue a new token.
Example: Issuing a New ERC20F Token
Here's an example of how to issue a new ERC20F token using the Fireblocks SDK:
1. Initialize the Fireblocks SDK
First, the Fireblocks SDK and initialize the SDK with your Fireblocks API key and private key:
import {
Fireblocks,
BasePath,
} from '@fireblocks/ts-sdk';
const privateKey = '...'; // Your Fireblocks API private key
const apiKey = '...'; // Your Fireblocks API key
const fireblocksSdk = new Fireblocks({
apiKey,
basePath: BasePath.US, // Use BasePath.EU for the EU region
secretKey: privateKey,
});
2. Retrieve ERC20F Contract Template
We need to retrieve the ERC20F contract template using the getContractTemplate
method:
For more information, refer to the Get Contract Template API reference page.
const template = await fireblocksSdk.contractTemplates.getContractTemplate({contractTemplateId: '41c76f08-3144-4641-96c9-260c8fe846a7'});
As part of the response, you'll receive the implementationContractId
which is required for the next steps.
3. Retrieve Implementation Contract Address
To get the address of the implementation contract, you need to call the getDeployedContracts
method:
This extra step is required only for templates of contracts that follow the proxy pattern (such as ERC20F).
const contractDetails = await fireblocksSdk.deployedContracts.getDeployedContracts({
assetId: 'ETH_TEST5',
templateId: 'implementationContractId'
})
As part of the response, you'll receive the contractAddress
which is required for the next step.
4. Issue New Token
To proceed with deploying the new token, you need to define the following deployment variables:
name
: The token name (e.g., "MyToken").symbol
: The token symbol (e.g., "MTK").defaultAdminAddress
: The address that will receive the DEFAULT_ADMIN_ROLE.minterAddress
: The address that will receive the MINTER_ROLE.pauserAddress
: The address that will receive the PAUSER_ROLE.
For more information about the roles, refer to the Roles in Fireblocks smart contracts article.
Example:
const name = 'MyToken';
const symbol = 'MTK';
const defaultAdminAddress = '0x1234567890123456789012345678901234567890';
const minterAddress = '0x1234567890123456789012345678901234567890';
const pauserAddress = '0x1234567890123456789012345678901234567890';
It's important to recall that the ERC20F token uses a proxy pattern. This means that when deploying the token, you must provide both the implementation contract address and the encoded initialize function in the constructorParams
field. The proxy will reference the implementation contract and use the initialize method to set up the token parameters.
Now let's issue the new token:
let deployRequest: CreateTokenRequestDto = {
assetId: 'ETH_TEST5', // Fireblocks asset ID for Sepolia network
vaultAccountId: '0', // The vault account ID to manage the token
createParams: {
contractId: '41c76f08-3144-4641-96c9-260c8fe846a7', // The ERC20F contract template ID
deployFunctionParams: [
{
name: 'implementation',
type: 'address',
internalType: 'address',
value: 'implementationContractAddress', // Address of the implementation contract retrieved in Step 3
},
{
"name": "_data",
"type": "bytes",
"functionValue": {
"name": "initialize",
"type": "function",
"inputs": [
{
"name": "_name",
"type": "string",
"internalType": "string",
"value": name // _name (e.g., 'MyToken')
},
{
"name": "_symbol",
"type": "string",
"internalType": "string",
"value": symbol // _symbol (e.g., 'MTK')
},
{
"name": "defaultAdmin",
"type": "address",
"internalType": "address",
"value": defaultAdminAddress // Address with DEFAULT_ADMIN_ROLE
},
{
"name": "minter",
"type": "address",
"internalType": "address",
"value": minterAddress // Address with MINTER_ROLE
},
{
"name": "pauser",
"type": "address",
"internalType": "address",
"value": pauserAddress // Address with PAUSER_ROLE
}
],
}
}
],
},
};
// Issue the token
const response = await fireblocksSdk.tokenization.issueNewToken({createTokenRequestDto: deployRequest});
console.log('New token issued:', response);
Highlights:
- Ensure that
contractId
passed in thecreateParams
corresponds to the template ID of the contract you want to deploy. In this case, it is the ERC20F contract template ID. - Replace the example addresses with your own values for
defaultAdminAddress
,minterAddress
, andpauserAddress
. - Ensure that the vault account has sufficient native gas for transaction fees.
- If you need to obtain the ABI for the
initialize
function of the proxy used in step 4, you can find it in the
contract template:const implementationTemplate = await fireblocksSdk.contractTemplates.getContractTemplate({contractTemplateId: 'implementationContractId'});
Further Reading
For more detailed information on API parameters and responses, including examples for using plain HTTP requests or in other programming languages, please have a look at the Fireblocks API Reference.
For more specific guidance on ERC20F contract operations, refer to the Operating the Upgradable ERC20F Contract Support Center Articles.