Skip to main content

Using Fuel Tanks

A Fuel tank is a pool that holds Enjin Coins (ENJ) which is used to cover transaction fees for eligible users. Each Fuel Tank

is designed to minimize transaction costs, resulting in lower expenses for platform operations.

Fuel Tanks are flexible and dynamic, allowing customization based on specific rules and requirements. They operate based on a set of rules, making it possible to target specific actions or accounts meeting specific criteria.

When dispatching a transaction via a Fuel Tank, the following checks must pass:

  • The Fuel Tank is not frozen.
  • The Fuel Tank is funded with enough Enjin Coins.
  • The dispatcher account is allowed to use the Fuel Tank.
  • The Fuel Tank allows dispatching this transaction.
What you'll need:
  • Some Enjin Coin on Enjin / Canary Matrixchain to pay for Transaction Fees, and for funding the tank.
    You can obtain cENJ (Canary ENJ) for testing from the Canary faucet.
  • An Enjin Platform Account.

Tank Rules

Fuel Tanks offer versatile rules for various use cases, allowing customization.

Dispatch Rules

Rule Set

When a call is made to a fuel tank (also known as "Dispatching"), it must be made in accordance with a set of rules. These rules, known as rule sets, can include multiple individual Dispatch Rules that determine the validity of the call. A fuel tank can have multiple rule sets, each of which controls access and permissions to the fuel tank's functionality and resources.

Types of Dispatch Rules:

  • Whitelisted Callers: Subsidize Transactions dispatched from certain Wallet Accounts.
  • Whitelisted Collections: Subsidize Transactions involving specific Collection.
  • Require Token: Subsidize Transactions only if the user holds a specific NFT.
  • WhitelistedPallets: Subsidize Transactions involving specific Pallet.
  • Permitted Extrinsics: Subsidize Transactions involving specific Extrinsics, e.g. marketplace CreateListing transactions.
  • Permitted Calls: Subsidize Transactions involving specific Extrinsics and parameters.
  • User Fuel Budget: Set limits on individual fuel consumption for security.
  • Tank Fuel Budget: Define collective fuel usage to extend Fuel Tank lifespan.
  • Max Fuel Burn Per Transaction: Control fuel consumption per transaction for predictability.
  • Require Signature: Subsidize Transactions which were signed by a specific Wallet Account.

These rules enhance the Enjin Blockchain experience, sparking new products and business models.

RequireAccount Parameter

In addition to Dispatch Rules, a Rule Set may require the dispatching account to have an existing Fuel Tank User Account in order to dispatch a call. This is configured by setting the Rule Set's requireAccount parameter to true.

Account Rules

Adding an account to the Fuel Tank User Accounts can be done in two ways:

  1. In advance with the add_account extrinsic.
  2. When dispatching a call with the dispatch_and_touch extrinsic.

In both ways, the account is added to the tank's User Accounts only if it's successfully validated by the tank's Account Rules.

Note: if the dispatcher is not the tank owner, he may add itself to the User Accounts only if UserAccountManagement is configured

Types of Account Rules:

  • Whitelisted Callers: Only listed accounts are able to add their account to the Fuel Tank's User Accounts.
  • Require Token: Only accounts that hold the specified token are able to add their account to the Fuel Tank's User Accounts.

User Account Management

By default, only the Fuel Tank owner has the permission to add accounts to the Fuel Tank User Accounts. However, the Fuel Tank can be configured to allow accounts to add themselves by setting the tankReservesAccountCreationDeposit argument.

  • Default Behavior: If the tankReservesAccountCreationDeposit argument is not provided, only the Fuel Tank owner can add accounts to the Fuel Tank User Accounts.
  • Self-Addition without Deposit Funding: If the tankReservesAccountCreationDeposit argument is set to false, the Fuel Tank allows accounts to add themselves to the Fuel Tank User Accounts. However, the Fuel Tank will not provide the funds required for the Tank User Account Storage Deposit.
  • Self-Addition with Deposit Funding: If the tankReservesAccountCreationDeposit argument is set to true, the Fuel Tank allows accounts to add themselves to the Fuel Tank User Accounts, and it also covers the necessary funds required for the Tank User Account Storage Deposit.

Coverage Policy

By default, the fuel tank will subsidize only Transaction Fees

.
To cover both Transaction Fees and any Storage Deposit the dispatched call may require, set the Coverage Policy to FEES_AND_DEPOSIT

Creating Fuel Tanks

Now that we have a basic understanding of how Fuel Tanks are structured, let's go through setting up some Fuel Tanks with specific functionality, including creating rules and customizing it to fit your needs, enabling you to reduce transaction costs for your users.

User Interface

This guide will demonstrate how to create various fuel tanks with the GraphQL API.
Note that you may also use the User Interface to create Fuel Tanks.

To create a Fuel Tank using the Platform's User Interface, navigate to "Fuel Tanks" in the Platform Menu. Then, click the "Create Fuel Tank" button.

Feature Availability Notice

Please be aware that the following arguments are currently unavailable on the Enjin Platform:

  • PermittedExtrinsics cannot be set via the Enjin Platform UI.
  • WhitelistedPallets is not supported on the Enjin Platform, both on the UI and API.
  • requireAccount is also not supported on the Enjin Platform, both on the UI and API. We will update the documentation once these options are available.
    Code snippets with these arguments are provided for illustrative purposes only. If you wish to create a fuel tank with these options now, please use the Enjin Console at console.enjin.io.
Make sure to use the Fuel Tank Endpoint

Subsidize Token Transfers For A Collection

The following mutation will set up a fuel tank that only subsidizes transactions that contain a BatchTransfer extrinsic, and only if it involves a token from the collection with ID 36,105.

mutation CreateFuelTank{
CreateFuelTank(
name: "Collection Token Transfers" #Specify the Fuel Tank name
coveragePolicy: FEES #This is set to FEES since we only want to subsidize transaction fees, and we don't need to provide storage deposits for token transfer transactions
reservesAccountCreationDeposit: null #This is set to null since we don't want to allow tank account creations
dispatchRules: [{
permittedExtrinsics: [BatchTransfer] #This rule specifies that only batch transfers are subsidized
whitelistedCollections: [36105] #This rule ensures that only the specified collection is subsidized
}]
){
id
method
state
}
}

Subsidize Any Transaction Involving MultiTokens From A Certain Collection

Upcoming Feature Notice: WhitelistedPallets Option

The WhitelistedPallets argument is not yet supported on the Enjin Platform.
The following code snippet is provided for illustrative purposes only.
If you wish to create a fuel tank with this option now, please use the Enjin Console at console.enjin.io.
We will update the documentation once this option is available.

The following mutation will set up a fuel tank that only subsidizes transactions that involves any token from the collection with ID 36,105. To achieve this, we are using the same dispatch rule from the previous example (whitelistedCollections) and the WhitelistedPallets rule, allowing only extrinsics from the MultiTokens pallet (for actions such as send, mint, transfer, etc.) and Marketplace pallet (for actions such as list, buy, offer, etc. ).

mutation CreateFuelTank{
CreateFuelTank(
name: "Collection Token Actions" #Specify the Fuel Tank name
coveragePolicy: FEES_AND_DEPOSIT #This is set to FEES_AND_DEPOSIT since we want the tank to provide ENJ for both transaction fees, and storage deposits for transactions that require it (such as listing a token for sale).
reservesAccountCreationDeposit: true #This is set to true since we want to allow tank account creations, and we want the tank to subsidize the ENJ required for the required for the Tank User Account storage deposit
dispatchRules: [{
WhitelistedPallets: [MultiTokens, Marketplace] #This rule specifies that only extrinsics from the MultiTokens and Marketplace pallets are subsidized
whitelistedCollections: [36105] #This rule ensures that only the specified collection is subsidized
}]
){
id
method
state
}
}

Subsidize All Transactions For Whitelisted Accounts With Budget Limitations

The following mutation will set up a fuel tank that subsidizes any transaction, the tank is allowed to subsidize up to 5 ENJ per 30 days for each User Account in the tank, which can be created only if the account is within the whitelisted callers list.

Upcoming Feature Notice: requireAccount Option

The requireAccount argument is not yet supported on the Enjin Platform.
The following code snippet is provided for illustrative purposes only.
If you wish to create a fuel tank with this option now, please use the Enjin Console at console.enjin.io.
We will update the documentation once this option is available.

mutation CreateFuelTank{
CreateFuelTank(
name: "Only Specific Accounts Allowed" #Specify the Fuel Tank name
coveragePolicy: FEES_AND_DEPOSIT #This is set to FEES_AND_DEPOSIT since we want the tank to provide ENJ for both transaction fees, and storage deposits for transactions that require it.
accountRules: {
whitelistedCallers: [ #This will validate that the caller is whitelisted at the time of adding the caller's account to the tank's User Accounts.
"cxKy7aqhQTtoJYUjpebxFK2ooKhcvQ2FQj3FePrXhDhd9nLfu",
"cxKRcxyqEuj8qwS4qAmxZMLKNoMJPMhQBLhoQdKekubbo3BtP"
]
}
dispatchRules: [{
requireAccount: true #This is set to true since we want the tank to allow dispatching only if the caller has a User Account in the tank.
userFuelBudget: { #In here we configure how much ENJ to subsidize for each User Account.
amount: 5000000000000000000 #This will allow the tank to subsidize up to 5 ENJ from the Tank's pool per period for each User Account.
resetPeriod: 432000 #This sets the period to 432,000 blocks, which is 30 days on average with 6 seconds average block time. Meaning the tank will be able to subsidize up to 5 ENJ per 30 days for each User Account.
}
}]
){
id
method
state
}
}

A WebSocket event will also be fired so you can pick up the Fuel Tank creation in real time by listening to the app channel on the WebSocket.

Explore More Arguments

For a comprehensive view of all available arguments for queries and mutations, please refer to our API Reference. This resource will guide you on how to use the GraphiQL Playground to explore the full structure and functionality of our API.

Dispatching a Call Using a Fuel Tank

To broadcast a transaction call using a fuel tank, use the Dispatch/DispatchAndTouch mutation.

The Fuel Tank requires a UserAccount to dispatch?

Use the DispatchAndTouch mutation to create a UserAccount and Dispatch at the same time in a single transaction.

Not sure which Fuel Tank to select?

If you need help figuring out the best fuel tank to use for a transaction, check out this page: Selecting a fuel tank to dispatch with.

Step #1: Prepare The Mutation

First, prepare the mutation you wish to dispatch, with the id and encodedData fields in the response.
In this example, we'll dispatch a call to send a MultiToken

from one account to another:

Ask for the id and encodedData fields!

Make sure to add the id and encodedData fields in the response, or the mutation will fail with an error.

mutation TransferNFT{
SimpleTransferToken(
collectionId: 3298
recipient: "efQh8FzLm6oH3dmTU3HWqGrtm6Xcuu1WG33N2Ka9fzo5MFFAr"
params: {tokenId: {integer: 1} amount: 1}
){
id
encodedData
}
}

Step #2: Prepare The Dispatch Mutation

Next, you need to convert the mutation call into a String. Remove all new lines and escape double quotation marks:

mutation TransferNFT{SimpleTransferToken(collectionId: 3298 recipient: \"efQh8FzLm6oH3dmTU3HWqGrtm6Xcuu1WG33N2Ka9fzo5MFFAr\" params: {tokenId: {integer: 1} amount: 1}){id encodedData}}

To escape quotation marks you can use online tools such as https://tools.knowledgewalls.com/online-escape-single-or-double-quotes-from-string.

Step #3: Send the Dispatch Call

Insert the mutation String from Step #2 into a Dispatch mutation call "query" parameter and send it:

mutation Dispatch {
Dispatch(
tankId: "efQqqMFeDXMSQ43rShznQQ5Aq5pnMUKBfvTQHntatMmF4JZou" #Specify the Fuel Tank ID to dispatch with
ruleSetId: 0 #Specify the ruleset to dispatch with
dispatch: {
call: MULTI_TOKENS #Specify the pallet to use for the transaction
query: "mutation TransferNFT{SimpleTransferToken(collectionId: 3298 recipient: \"efQh8FzLm6oH3dmTU3HWqGrtm6Xcuu1WG33N2Ka9fzo5MFFAr\" params: {tokenId: {integer: 1} amount: 1}){id encodedData}}" #Insert the mutation to dispatch.
variables: null #If the mutation has variables, insert them here.
}
){
id
method
state
}
}

Once the mutation is sent, signed and broadcasted, If the transaction is eligible, the fuel tank will subsidize the transaction fees; otherwise, the transaction will fail.

Need to broadcast from Managed Wallet?

To broadcast the transaction from a managed wallet account, add the signingAccount argument as instructed in the Using Managed Wallets page.
It's important to note that the signingAccount argument should be added on the Dispatch mutation level, and NOT in the dispatch argument.
In the above example, to transfer the token from a managed wallet via a fuel tank:

mutation Dispatch {
Dispatch(
tankId: "efQqqMFeDXMSQ43rShznQQ5Aq5pnMUKBfvTQHntatMmF4JZou" #Specify the Fuel Tank ID to dispatch with
ruleSetId: 0 #Specify the ruleset to dispatch with
signingAccount: "Managed Wallet Address Here"
dispatch: {
call: MULTI_TOKENS #Specify the pallet to use for the transaction
query: "mutation TransferNFT{SimpleTransferToken(collectionId: 3298 recipient: \"efQh8FzLm6oH3dmTU3HWqGrtm6Xcuu1WG33N2Ka9fzo5MFFAr\" params: {tokenId: {integer: 1} amount: 1}){id encodedData}}" #Insert the mutation to dispatch.
variables: null #If the mutation has variables, insert them here.
}
){
id
method
state
}
}