Using Fuel Tanks
Subsidize fees for your players while reducing overall costs.
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.
What you'll need:
- Some Enjin Coin on Enjin / Canary Matrixchain to pay for Transaction Fees.
You can obtain cENJ (Canary ENJ) for testing from the Canary faucet.- An Enjin Platform Account.
Fuel Tanks offer versatile rule sets for various use cases, allowing customization:
Whitelisted Callers
: Select which wallets can receive subsidized transactions, ideal for rewarding users.Whitelisted Collections
: Choose collections with covered transaction fees to boost their activity.Require Token
: Users must hold a specific NFT for free transactions access.Permitted Extrinsics
: Subsidize specific transaction types, e.g., marketplace transactions.Permitted Calls
: Define transactions based on inputs and parameters, promoting certain trades.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
: Control fuel consumption per transaction for predictability.Freezing
: Pause Fuel Tank usage as a safety measure.
These rules enhance the Enjin Blockchain experience, sparking new products and business models.
This tutorial guides you through setting up a Fuel Tank with specific functionality, including creating rules and customizing it to fit your needs, enabling you to reduce transaction costs for your users.
There are two ways to create a Fuel Tank:
Option A. Using the Enjin Dashboard
PermittedExtrinsics
is Only Available via GraphQLPlease note that while creating a Fuel Tank is possible through the Enjin Platform User Interface, the specific rule required for this tutorial,
PermittedExtrinsics
, is currently only available via the GraphQL API or SDKs.Therefore, this tutorial will only cover instructions for setting up a Fuel Tank with
PermittedExtrinsics
rule using the GraphQL API or SDKs.
In the Platform menu, navigate to "Fuel Tanks". Then, click the "Create Fuel Tank" button.
Option B. Using the Enjin API & SDKs
Make sure to use the Fuel Tank Endpoint
- Testnet:
http://platform.canary.enjin.io/graphql/fuel-tanks
- Mainnet:
http://platform.enjin.io/graphql/fuel-tanks
Try the Beam Playground here:
This mutation will set up a new transaction that once finalized on-chain will create the new fuel tank on-chain.
mutation CreateFuelTank{
CreateFuelTank(
name: "Collection Token Transfers" #Specify the Fuel Tank name
providesDeposit: false #This is set to false since we don't need to provide token deposits for token transfer transactions
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
}
}
curl -X POST "https://platform.enjin.io/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: enjin_api_key" \
-d '{"query": "mutation CreateFuelTank { CreateFuelTank(name: \"Collection Token Transfers\", providesDeposit: false, dispatchRules: [{ permittedExtrinsics: [BatchTransfer], whitelistedCollections: [36105] }]) { id method state } }"}'
using System.Text.Json;
using Enjin.Platform.Sdk;
using Enjin.Platform.Sdk.FuelTanks;
// Create the array of dispatch rules for the fuel tank
var dispatchRules = new List<DispatchRuleInputType>()
{
new DispatchRuleInputType()
.SetPermittedExtrinsics(TransactionMethod.BatchTransfer) // This rule specifies that only batch transfers are subsidized
.SetWhitelistedCollections(36105) // This rule ensures that only the specified collection is subsidized
};
// Setup the mutation
var createFuelTank = new CreateFuelTank()
.SetName("Collection Token Transfers")
.SetProvidesDeposit(false)
.SetDispatchRules(dispatchRules.ToArray());
// Define and assign the return data fragment to the mutation
var transactionFragment = new TransactionFragment()
.WithId()
.WithMethod()
.WithState();
createFuelTank.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.SendCreateFuelTank(createFuelTank);
Console.WriteLine(JsonSerializer.Serialize(response.Result.Data));
fetch('https://platform.canary.enjin.io/graphql', {
method: 'POST',
headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'},
body: JSON.stringify({
query: `
mutation CreateFuelTank
(
$name: String!
$provide_deposit: Boolean!
) {
CreateFuelTank(
name: $name
providesDeposit: $provide_deposit
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
}
}
`,
variables: {
name: "Collection Token Transfers", //Specify the Fuel Tank name
provide_deposit: false //This is set to false since we don't need to provide token deposits for token transfer transactions
}
}),
})
.then(response => response.json())
.then(data => console.log(data));
const axios = require('axios');
axios.post('https://platform.canary.enjin.io/graphql', {
query: `
mutation CreateFuelTank
(
$name: String!
$provide_deposit: Boolean!
) {
CreateFuelTank(
name: $name
providesDeposit: $provide_deposit
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
}
}
`,
variables: {
name: "Collection Token Transfers", //Specify the Fuel Tank name
provide_deposit: false //This is set to false since we don't need to provide token deposits for token transfer transactions
}
}, {
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 CreateFuelTank
(
$name: String!
$provide_deposit: Boolean!
) {
CreateFuelTank(
name: $name
providesDeposit: $provide_deposit
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
}
}
'''
variables = {
'name': "Collection Token Transfers", #Specify the Fuel Tank name
'provide_deposit': False #This is set to false since we don't need to provide token deposits for token transfer transactions
}
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())
// Coming Soon!
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.
More Fields and Arguments Available!
The examples here illustrate basic uses of the
CreateFuelTank
mutation. However, this mutation supports many more arguments and settings not shown in these examples.For a comprehensive overview of all available settings and their descriptions for the
CreateFuelTank
mutation, please refer to our GraphQL Schema on Apollo.This resource will help you to fully utilize the capabilities of the
CreateFuelTank
mutation and tailor it to your specific needs.For instance, you'll find settings such as allowing the fuel tank to provide Storage Deposits with the
providesDeposit
flag, or setting various account rules and dispatch rules with the accountRules and dispatchRules objects.
Dispatching a Call Using a Fuel Tank
To request a transaction call to be subsidized by a fuel tank, use the Dispatch
/DispatchAndTouch
mutation.
The Fuel Tank requires a UserAccount to dispatch?
Use the
DispatchAndTouch
mutation to create aUserAccount
andDispatch
at the same time in a single transaction.
Step #1: Prepare The Mutation
First, prepare the mutation you wish to dispatch. In this example, we'll dispatch a call to send a MultiTokenfrom one account to another:
mutation TransferNFT{
SimpleTransferToken(
collectionId: 3298
recipient: "efQh8FzLm6oH3dmTU3HWqGrtm6Xcuu1WG33N2Ka9fzo5MFFAr"
params: {tokenId: {integer: 1} amount: 1}
){
id
encodedData
}
}
curl -X POST "https://platform.enjin.io/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: enjin_api_key" \
-d '{"query": "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 Disaptch 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.
}
){
id
method
state
}
}
curl -X POST "https://platform.enjin.io/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: enjin_api_key" \
-d '{"query": "mutation Dispatch { Dispatch(tankId: \"efQqqMFeDXMSQ43rShznQQ5Aq5pnMUKBfvTQHntatMmF4JZou\", ruleSetId: 0, dispatch: { call: MULTI_TOKENS, query: \"mutation TransferNFT{SimpleTransferToken(collectionId: 3298 recipient: \\\"efQh8FzLm6oH3dmTU3HWqGrtm6Xcuu1WG33N2Ka9fzo5MFFAr\\\" params: {tokenId: {integer: 1} amount: 1}){id encodedData}}\" }) { id method state } }"}'
Updated 24 days ago