Skip to content

Gas Tank API Documentation ​

The Gas Tank is a versatile platform that empowers users to manage gas tank balances seamlessly across different blockchain networks. This project facilitates actions such as depositing, withdrawing, internal transferring, and consuming gas tank balances, allowing users to efficiently utilize their resources on EVM, Cosmos-like, and UTXO chains. With support for multiple blockchain environments, The Gas Tank offers users a unified solution for gas utilization across diverse networks. Check the Gas Tank API Swagger for more information.

The base URL for all Gas Tank API is: https://gas-tank.xdefi.services

Below are the available services provided by the Gas Tank API. You need to have a valid JWT token to access the services. You can get the JWT token by using the Multiple Address Login endpoint.

Gas Tank Platform Actions ​

1. Overview ​

The Gas Tank platform provides users with an efficient way to manage their balances across multiple blockchain networks. It allows users to:

  • Deposit funds into Gas Tank for future use.
  • Withdraw or transfer tokens to an on-chain address.
  • Consume (Send Gas) to exchange stored tokens for native gas fees.
  • Perform internal transfers & migrations between Gas Tank accounts.

Gas Tank ensures seamless cross-chain operations while managing transaction execution, fee coverage, and user balance tracking.


2. Deposit in Gas Tank Platform ​

A Deposit is the process of moving user funds into the Gas Tank system. This is done via a Permit + Transfer From transaction, allowing the Gas Tank to manage user balances for future transactions.

Key Points ​

βœ… Deposits are completely free for users – CTRL Wallet covers all gas fees.
βœ… A deposit consists of two transactions – Permit + Transfer From.
βœ… Deposited funds become available after confirmation.

Supported Deposit Chains & Tokens ​

ChainSupported Tokens
EthereumUSDC, CTRL
AvalancheUSDC
PolygonUSDC
OptimismUSDC
ArbitrumUSDC
FantomaxlUSDC
BaseUSDC

Deposit Process ​

  1. User selects a chain and token from the supported list.
  2. User signs a Permit transaction, allowing Gas Tank to spend the selected token.
  3. Gas Tank backend creates a Balance Update Queue (BUQ) task to process the deposit.
  4. Workers execute the deposit:
    • Step 1: Execute the Permit transaction and verify token allowance.
    • Step 2: Execute the Transfer From transaction, moving funds to Gas Tank.
    • Step 3: Store deposited funds as pending balance.
  5. Confirmation Worker verifies the deposit:
    • Once confirmed on-chain, pending balance is converted into available balance.
  6. Users can now spend their Gas Tank balance for withdrawals or gas consumption.

🚨 Note: Transactions may fail due to various reasons (e.g., insufficient allowance, network issues). Error handling is covered in a separate section.


3. Withdraw/Transfer in Gas Tank Platform ​

A Withdrawal allows users to transfer their funds from the Gas Tank back to an on-chain address. Users must pay gas fees, which are deducted from their Gas Tank balance.

Key Points ​

βœ… Users pay gas fees for withdrawals (calculated based on destination chain).
βœ… Supports cross-chain withdrawals in the latest version.
βœ… Only deposit-supported chains and tokens can be withdrawn.

Understanding Withdrawals ​

Before withdrawing, users should understand:

  • How deposits work and how balances are stored.
  • How transaction fees are deducted from Gas Tank balances.

Withdrawal Process ​

  1. User requests a withdrawal:
    • Selects the destination chain and desired token.
    • Specifies the amount to withdraw.
  2. Gas Tank calculates the transaction fee:
    • Determines the native gas fee required.
    • Converts it into one of the user’s available Gas Tank tokens (USDC, CTRL, axlUSDC).
    • If the user does not have enough balance, the transaction fails.
  3. Gas Tank backend creates a withdrawal task.
  4. Worker executes the withdrawal transaction.
  5. User receives their funds on the destination blockchain.

Withdrawal Versions ​

VersionEndpointFeatures
V1 - Withdraw (Deprecated)/balances/withdrawOnly allows withdrawing tokens from the same chain as the deposit. Example: If a user deposits CTRL on Ethereum, they can only withdraw CTRL on Ethereum.
V2 - Transfer (Active)/v2/balances/consumeWhy is it called "Consume" instead of "Withdraw"? This version combines Withdrawals and Gas Sending (Consume) into one endpoint. Supports cross-chain withdrawals. Works like a Swap, allowing users to withdraw to different chains.

🚨 Note: If the Gas Tank lacks native gas on the destination chain, the transaction will fail.


4. Consume (Send Gas) in Gas Tank Platform ​

Consume (Send Gas) allows users to exchange their Gas Tank tokens (CTRL, USDC, axlUSDC) for native gas tokens on 40+ supported chains.

Key Points ​

βœ… Users can get native gas coins to fund on-chain transactions.
βœ… Supports EVM, UTXO, Cosmos, Solana, Near, ThorChain, Tron, etc.
βœ… Transaction fees apply (similar to withdrawals).

Consume Process ​

  1. User selects the destination chain where they need native gas.
  2. Gas Tank checks available balance and calculates transaction cost.
  3. System converts user’s Gas Tank balance (USDC, CTRL, axlUSDC) into native gas tokens.
  4. Worker executes the gas transfer transaction.
  5. User receives the native token on the destination chain.

🚨 Note: If the destination chain lacks sufficient native tokens, the transaction will fail.


5. Internal Transfer & Migration ​

These actions allow users to move balances between Gas Tank accounts without performing an on-chain transaction. Internal transfers are free.

Internal Transfer ​

  • Endpoint: /balances/internal_transfer
  • Allows users to:
    • Select chain, token, amount, and destination address.
    • Sign a message to authorize Gas Tank to execute the transfer.
    • Transfer is processed instantly (since it’s internal).

Internal Migration ​

  • Endpoint: /balances/internal-migration
  • Allows users to:
    • Migrate their entire balance from Wallet A β†’ Wallet B within Gas Tank.
    • Gas Tank automatically calculates the full balance and prepares the migration.
    • After execution, all balances are transferred, and Wallet A’s balance is set to zero.

🚨 Note: Internal transfers/migrations do not require blockchain transactions and are always free.


6. Execution & Processing ​

Regardless of the action type (Deposit, Withdraw, Consume, Internal Transfer):

  • A Balance Update Queue (BUQ) is created, returning a BUQ ID.
  • Tasks are added to the queue and processed by workers.
  • Execution time depends on the destination chain (chain for Deposits, destination chain for Withdraws/Consumes).
  • Multiple actions can be executed simultaneously, ensuring efficient user balance management.

7. Summary ​

ActionFree for Users?Requires Blockchain Transaction?Paid by User?
Depositβœ… Yesβœ… Yes (Permit + Transfer)❌ No (Paid by CTRL Wallet)
Withdrawal (Transfer)❌ Noβœ… Yesβœ… Yes (Gas Fee Deducted)
Consume (Send Gas)❌ Noβœ… Yesβœ… Yes (Gas Fee Deducted)
Internal Transferβœ… Yes❌ No❌ No
Internal Migrationβœ… Yes❌ No❌ No

This document provides a detailed yet easy-to-read overview of Gas Tank actions including Deposits, Withdrawals, Consume, and Internal Transfers. πŸš€

Authentication ​

Multiple Addresses Login ​

This endpoint facilitates the generation of JWT tokens for multiple wallet addresses in a single request. The request payload should consist of an array of objects, each containing an address and its corresponding signature. Upon successful validation of the signatures, the server will generate JWT tokens for the provided addresses.

To get signatures, you can use personal_sign method from web3.js or ethers.js. Below is an example of how to get a signature using web3.js:

javascript
const web3 = new Web3(window.ethereum);
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

const address1 = "0x1234567890123456789012345678901234567890";
const address2 = "0x0987654321098765432109876543210987654321";

const messageToSign = await (
  await fetch(`${GAS_TANK_ENDPOINT}/v2/auth/message`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify([address1, address2]),
  })
).json();

const message = messageToSign.message;


const signature1 = await web3.eth.personal.sign(message, address1);
const signature2 = await web3.eth.personal.sign(message, address2);

await fetch(`${GAS_TANK_ENDPOINT}/v2/auth/login`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify([
    {
      address: address1, // Address of the user
      signature: signature1, // Signature
    },
    {
      address: address2, 
      signature: signature2, 
    },
    ...
  ]),
})
  .then((response) => {
    console.log(response);
    // Handle & do something with the response
  })
json
{
  "access": "jwt.access.token",
  "refresh": "jwt.refresh.token"
}

You can also add new wallets to an existing JWT token. Request will be secured by JWT header. Clients need to submit an array of objects containing the address and signature for each new wallet. The server will validate the signatures and, if successful, update the existing JWT token to include the new wallets and generate new JWT.

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(`${GAS_TANK_ENDPOINT}/v2/auth/update`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${jwtToken}`, // JWT token
  },
  body: JSON.stringify([
    {
      address: newAddress, 
      signature: newSignature, 
    },
    ...
  ]),
})
  .then((response) => {
    console.log(response);
    // Handle & do something with the response
  })
json
{
  "access": "jwt.access.token",
  "refresh": "jwt.refresh.token"
}

Refresh JWT Token ​

Clients can use this endpoint to obtain a new JWT token without re-authenticating, providing a refresh token.

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(`${GAS_TANK_ENDPOINT}/v2/auth/refresh`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${jwtToken}`, // JWT token
  },
  body: JSON.stringify({
    refresh: refreshToken, // Refresh token
  }),
}).then((response) => {
  console.log(response);
  // Handle & do something with the response
});
json
{
  "access": "jwt.access.token",
  "refresh": "jwt.refresh.token"
}

Messages ​

Construct Deposit Message ​

This endpoint will generate messages parameter for Deposit balances.

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(`${GAS_TANK_ENDPOINT}/msg/increase`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    owner: "0xOwnerWalletAddress", // The wallet address of the owner
    tokenAddress: "0xTokenContractAddress", // The contract address of the token
    amount: "1", // Amount of the token to deposit
    chain: "ethereum", // The blockchain network, e.g., 'ethereum'
  }),
}).then((response) => {
  console.log(response);
  // Handle & do something with the response
});
json
{
  "type": "string",
  "message": "string"
}

Construct Withdraw Message ​

This endpoint will generate messages parameter for Withdraw balances.

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(`${GAS_TANK_ENDPOINT}/msg/withdraw`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    address: "0xYourWalletAddress", // Your wallet address
    tokenAddress: "0xTokenContractAddress", // The contract address of the token
    amount: "1", // Amount of the token to withdraw
    chain: "ethereum", // The blockchain network, e.g., 'ethereum'
    recipient: "0xRecipientWalletAddress", // The recipient's wallet address
  }),
}).then((response) => {
  console.log(response);
  // Handle & do something with the response
});
json
{
  "type": "string",
  "message": "string"
}

Construct Internal Transfer Message ​

This endpoint will generate messages parameter for Internal Transfer balances.

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(`${GAS_TANK_ENDPOINT}/msg/internal-transfer`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    address: "0xYourWalletAddress", // Your wallet address
    tokenAddress: "0xTokenContractAddress", // The contract address of the token
    amount: "1", // Amount of the token to transfer
    chain: "ethereum", // The blockchain network, e.g., 'ethereum'
    recipient: "0xRecipientWalletAddress", // The recipient's wallet address
  }),
}).then((response) => {
  console.log(response);
  // Handle & do something with the response
});
json
{
  "type": "string",
  "message": "string"
}

Construct Consume Message ​

This endpoint will generate messages parameter for Consume balances.

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(`${GAS_TANK_ENDPOINT}/msg/consume`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    address: "0xYourWalletAddress", // Your wallet address
    minDestinationAmount: "1", // Minimum amount of the token to consume
    destinationChain: "ethereum", // The blockchain network, e.g., 'ethereum'
  }),
}).then((response) => {
  console.log(response);
  // Handle & do something with the response
});
json
{
  "type": "string",
  "message": "string"
}

Chains / Token / Status ​

Get all Tokens ​

This endpoint allows users to retrieve information about all tokens available on the Gas Tank platform.

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(`${GAS_TANK_ENDPOINT}/chains/tokens`, {
  method: "GET",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${jwtToken}`, // JWT token
  },
}).then((response) => {
  console.log(response);
  // Handle & do something with the response
});
json
{
  "additionalProp1": {
    "name": "string",
    "key": "string",
    "chainId": "string",
    "native": {
      "symbol": "string",
      "decimals": 0,
      "address": "string",
      "actions": [
        "string"
      ]
    },
    "tokens": [
      {
        "name": "string",
        "symbol": "string",
        "decimals": 0,
        "address": "string",
        "actions": [
          "string"
        ]
      }
    ]
  },
  "additionalProp2": {
    "name": "string",
    "key": "string",
    "chainId": "string",
    "native": {
      "symbol": "string",
      "decimals": 0,
      "address": "string",
      "actions": [
        "string"
      ]
    },
    "tokens": [
      {
        "name": "string",
        "symbol": "string",
        "decimals": 0,
        "address": "string",
        "actions": [
          "string"
        ]
      }
    ]
  },
  ...
}

Get dispatchers information ​

This endpoint provides information about the dispatchers on the Gas Tank platform.

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(`${GAS_TANK_ENDPOINT}/chains/dispatchers-info`, {
  method: "GET",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${jwtToken}`, // JWT token
  },
}).then((response) => {
  console.log(response);
  // Handle & do something with the response
});
json
{
  "additionalProp1": {
    "chain": "string",
    "address": "string",
    "balance": "string",
    "status": "string",
    "threshold": "string"
  },
  "additionalProp2": {
    "chain": "string",
    "address": "string",
    "balance": "string",
    "status": "string",
    "threshold": "string"
  },
  ...
}

Get chains Operational status ​

This endpoint provides information about the status of all supported chains on the Gas Tank platform.

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(`${GAS_TANK_ENDPOINT}/chains/status`, {
  method: "GET",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${jwtToken}`, // JWT token
  },
}).then((response) => {
  console.log(response);
  // Handle & do something with the response
});
json
{
  "operational": true,
  "chains": [
    {
      "chain": "string",
      "operational": true,
      "actions": {
        "increase": true,
        "withdraw": true,
        "consume": true
      },
      "extras": {
        "address": "string",
        "balance": "string",
        "threshold": "string",
        "status": "string"
      },
      "comment": "string"
    },
    ...
  ]
}

Balance & Transactions - Deposit, Withdraw, Send Gas ​

Get all balance entries for user ​

This endpoint returns a list of all balance entries per address by using JWT

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(`${GAS_TANK_ENDPOINT}/balances`, {
  method: "GET",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${jwtToken}`, // JWT token
  },
}).then((response) => {
  console.log(response);
  // Handle & do something with the response
});
json
{
  "additionalProp1": [
    {
      "id": "string",
      "address": "string",
      "tokenAddress": "string",
      "balance": 0,
      "chain": "string"
    }
  ],
  "additionalProp2": [
    {
      "id": "string",
      "address": "string",
      "tokenAddress": "string",
      "balance": 0,
      "chain": "string"
    }
  ],
  ...
}

Get balances by address ​

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(`${GAS_TANK_ENDPOINT}/balances/${address}`, { // Address to retrieve balances
  method: "GET",
  headers: {
    "Content-Type": "application/json"
    "Authorization": `Bearer ${jwtToken}`, // JWT token
  },
})
  .then((response) => {
    console.log(response);
    // Handle & do something with the response
  })
json
[
  {
    "id": "string",
    "address": "string",
    "tokenAddress": "string",
    "balance": 0,
    "chain": "string"
  },
  ...
]

Get total balances using JWT ​

This endpoint returns a list of total balances for the specified JWT.

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(`${GAS_TANK_ENDPOINT}/balances/totals`, {
  method: "GET",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${jwtToken}`, // JWT token
  },
}).then((response) => {
  console.log(response);
  // Handle & do something with the response
});
json
[
  {
    "address": "string",
    "symbol": "string",
    "value": "string",
    "decimals": 0
  },
  ...
]

Deposit balance ​

This endpoint allows users to deposit balance to the Gas Tank platform.

To deposit the balance, you need to sign the message with the private key of the address you want to deposit the balance for. v, r, s are the signature fields of the message signed by the address owner and message is generated in Construct Deposit Message.

You can sign a string of data using ethers.js, below is an example of how to sign a message using ethers.js and deposit the balance.

javascript
import { ethers } from "ethers";

const web3 = new Web3(window.ethereum);
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";
const address = "0x1234567890123456789012345678901234567890"; // Address to deposit balance
const message = message; // Message is generated in Construct Deposit Message
const privateKey = "0x1234"; // Private key of the address
const wallet = new ethers.Wallet(privateKey);
const signature = await wallet.signMessage(message);
const { v, r, s } = ethers.utils.splitSignature(signature);

await fetch(`${GAS_TANK_ENDPOINT}/balances/increase`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json"
    "Authorization": `Bearer ${jwtToken}`, // JWT token
  },
  body: JSON.stringify({
    address: address, 
    tokenAddress: "string", // Token contract address for deposit
    chain: "string", // The blockchain network [!code highlight]
    owner: "string", // The owner's address (can match the 'address' field) [!code highlight]
    spender: "string", // Gas Tank's internal address [!code highlight]
    value: "string", // Amount of deposited token [!code highlight]
    deadline: 0, // Date for checking the validity of the signature [!code highlight]
    v: v, 
    r: r, 
    s: s 
  }),
})
  .then((response) => {
    // Balance deposit successfully
  })
  .catch((error) => {
    // Catch & handle the error
  });

Withdraw balance ​

This endpoint allows users to withdraw their balance from the Gas Tank platform.

To withdraw the balance, you need to sign the message with the private key of the address you want to withdraw the balance from. The signature field is the signature of the message signed by the address owner and message is generated in Aonstruct Withdraw Message.

Same as the Deposit balance, you can sign a string of data using ethers.js, below is an example of how to sign a message using ethers.js and withdraw the balance.

javascript
import { ethers } from "ethers";

const web3 = new Web3(window.ethereum);
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";
const address = "0x1234567890123456789012345678901234567890"; // Address to withdraw balance
const message = message; // Message is generated in Construct Withdraw Message
const privateKey = "0x1234"; // Private key of the address
const wallet = new ethers.Wallet(privateKey);
const signature = await wallet.signMessage(message);

await fetch(`${GAS_TANK_ENDPOINT}/balances/withdraw`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json"
    "Authorization": `Bearer ${jwtToken}`, // JWT token
  },
  body: JSON.stringify({
    address: address, 
    tokenAddress: "string", // Token contract address for withdraw [!code highlight]
    amount: "string", // Amount of withdraw token [!code highlight]
    chain: "string", // The blockchain network [!code highlight]
    recipient: "string", // The recipient's wallet address [!code highlight]
    message: message, 
    signature: signature 
  }),
})
  .then((response) => {
    // Balance withdrawn successfully
  })
  .catch((error) => {
    // Catch & handle the error
  });

Internal transfer ​

This endpoint allows users to create an internal transfer task on the Gas Tank platform. The internal transfer task is used to transfer balance from one address to another address on the Gas Tank platform. The signature field is the signature of the message signed by the address owner and message is generated in Construct Internal Transfer Message.

javascript
import { ethers } from "ethers";

const web3 = new Web3(window.ethereum);
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";
const address = "0x1234567890123456789012345678901234567890"; // Address to transfer balance
const message = message; // Message is generated in Construct Internal Transfer Message
const privateKey = "0x1234"; // Private key of the address
const wallet = new ethers.Wallet(privateKey);
const signature = await wallet.signMessage(message);

await fetch(`${GAS_TANK_ENDPOINT}/balances/transfer`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${jwtToken}`, // JWT token
  },
  body: JSON.stringify({
    address: address, 
    tokenAddress: "string", // Token contract address for transfer [!code highlight]
    amount: "string", // Amount of transfer [!code highlight]
    chain: "string", // The blockchain network [!code highlight]
    recipient: "string", // The recipient's wallet address  [!code highlight]
    message: message, 
    signature: signature, 
  }),
})
  .then((response) => {
    // Internal transfer task created successfully
  })
  .catch((error) => {
    // Catch & handle the error
  });

Get a quote for consuming balance ​

This endpoint allows users to generate a quote for consuming their balance on the Gas Tank platform.

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(`${GAS_TANK_ENDPOINT}/balances/consume/quote`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${jwtToken}`, // JWT token
  },
  body: JSON.stringify({
    address: "string", // Your wallet address
    minDestinationAmount: "string", // Minimum amount of the token to consume
    destinationChain: "string", // The blockchain network
  }),
})
  .then((response) => {
    console.log(response);
    // Handle & do something with the response
  })
  .catch((error) => {
    // Catch & handle the error
  });
json
{
  "expectedOutput": "string",
  "fee": "string",
  "spentAssets": [
    {
      "tokenAddress": "string",
      "amount": "string",
      "chain": "string"
    }
  ]
}

Consume balance ​

This endpoint allows users to consume their balance on the Gas Tank platform.

To consume the balance, you need to sign the message with the private key of the address you want to consume the balance from. The signature field is the signature of the message signed by the address owner and message is generated in Construct Consume Message.

Same as the Deposit balance/Withdraw balance, you can sign a string of data using ethers.js, below is an example of how to sign a message using ethers.js and consume the balance.

javascript
import { ethers } from "ethers";

const web3 = new Web3(window.ethereum);
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";
const address = "0x1234567890123456789012345678901234567890"; // Address to consume balance
const message = message; // Message is generated in Construct Consume Message
const privateKey = "0x1234"; // Private key of the address
const wallet = new ethers.Wallet(privateKey);
const signature = await wallet.signMessage(message);

await fetch(`${GAS_TANK_ENDPOINT}/balances/consume`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${jwtToken}`, // JWT token
  },
  body: JSON.stringify({
    address: address, 
    minDestinationAmount: "string", // Minimum amount of the token to consume
    destinationAddress: "string", // The recipient's wallet address
    destinationChain: "string", // The blockchain network
    message: message, 
    signature: signature, 
  }),
})
  .then((response) => {
    // Balance consumed successfully
  })
  .catch((error) => {
    // Catch & handle the error
  });

Get user balance queue update ​

This endpoint allows users to get the balance queue update for any job ongoing (e.g., deposit, withdrawal, transfer, consume).

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(`${GAS_TANK_ENDPOINT}/transactions`, {
  method: "GET",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${jwtToken}`, // JWT token
  },
})
  .then((response) => {
    console.log(response);
    // Handle & do something with the response
  })
  .catch((error) => {
    // Catch & handle the error
  });
json
{
  "additionalProp1": [
    {
      "id": "string",
      "type": "string",
      "address": "string",
      "tokenAddress": "string",
      "amount": "string",
      "chain": "string",
      "destinationChain": "string",
      "destinationAddress": "string",
      "permitObject": {},
      "processed": true,
      "processedMetadata": {},
      "pendingTransactions": [
        {
          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
          "chain": "ethereum",
          "transactionHash": "0x6b175474e89094c44da98b954eedeac495271d0f",
          "blockNumber": 123456,
          "balanceUpdateId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
          "confirmed": false,
          "createdAt": "2023-01-01T00:00:00Z",
          "updatedAt": "2023-01-01T00:00:00Z"
        }
      ],
      "createdAt": "2024-04-11T04:13:07.102Z",
      "updatedAt": "2024-04-11T04:13:07.102Z"
    }
  ],
  ...
}

Get balance queue update by ID ​

This endpoint allows users to get the balance queue update for a specific ID (e.g., deposit, withdrawal, transfer, consume).

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(`${GAS_TANK_ENDPOINT}/transactions/${id}`, {
  method: "GET",
  headers: {
    "Content-Type": "application",
    Authorization: `Bearer ${jwtToken}`, // JWT token
  },
})
  .then((response) => {
    console.log(response);
    // Handle & do something with the response
  })
  .catch((error) => {
    // Catch & handle the error
  });
json
{
  "id": "string",
  "type": "string",
  "address": "string",
  "tokenAddress": "string",
  "amount": "string",
  "chain": "string",
  "destinationChain": "string",
  "destinationAddress": "string",
  "permitObject": {},
  "processed": true,
  "processedMetadata": {},
  "pendingTransactions": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "chain": "ethereum",
      "transactionHash": "0x6b175474e89094c44da98b954eedeac495271d0f",
      "blockNumber": 123456,
      "balanceUpdateId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "confirmed": false,
      "createdAt": "2023-01-01T00:00:00Z",
      "updatedAt": "2023-01-01T00:00:00Z"
    }
  ],
  "createdAt": "2024-04-11T04:17:30.107Z",
  "updatedAt": "2024-04-11T04:17:30.107Z"
}

Get pending transactions by address ​

This endpoint allows users to get pending transactions for a specific address. Results returned a list of pending transactions.

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(
  `${GAS_TANK_ENDPOINT}/transactions/pending/${address}`, // Address to retrieve pending transaction
  {
    method: "GET",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${jwtToken}`, // JWT token
    },
  },
)
  .then((response) => {
    console.log(response);
    // Handle & do something with the response
  })
  .catch((error) => {
    // Catch & handle the error
  });
json
[
  {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "chain": "ethereum",
    "transactionHash": "0x6b175474e89094c44da98b954eedeac495271d0f",
    "blockNumber": 123456,
    "balanceUpdateId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "confirmed": false,
    "createdAt": "2023-01-01T00:00:00Z",
    "updatedAt": "2023-01-01T00:00:00Z"
  },
  ...
]

Get fee for a given chain ​

This endpoint allows users to get the fee for a specific chain.

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(
  `${GAS_TANK_ENDPOINT}/v2/fees/${chain}`, // Chain to get fee
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
  },
)
  .then((response) => {
    console.log(response);
    // Handle & do something with the response
  })
  .catch((error) => {
    // Catch & handle the error
  });
json
{
  "symbol": "string", // Chain native symbol [BTC, USD]
  "decimals": "integer",
  "value": {
    "high": "string",
    "medium": "string",
    "low": "string"
  }
}

There is also a query parameter to get the fee in USD. You can use ${GAS_TANK_ENDPOINT}/v2/fees/${chain}?currency=USD to specify the currency.

Get fees for all supported chains ​

This endpoint allows users to get the fees for all Gas Tank supported chains.

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(
  `${GAS_TANK_ENDPOINT}/v2/fees`, // Chain to get fee
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
  },
)
  .then((response) => {
    console.log(response);
    // Handle & do something with the response
  })
  .catch((error) => {
    // Catch & handle the error
  });
json
{
  "chain": { // Chain keys [ETH, USD]
    "symbol": "string", // Chain native symbol [ETH, USD]
    "decimals": "integer",
    "value": {
      "high": "string",
      "medium": "string",
      "low": "string"
    }
  },
  ...
}

There is also a query parameter to get the fees in USD. You can use ${GAS_TANK_ENDPOINT}/v2/fees?currency=USD to specify the currency.

Gas Fee Calculation Across Different Blockchains ​

1. Overview ​

Gas fees represent the cost required to execute transactions on a blockchain. The calculation depends on the blockchain type, gas price, gas limits, and the size of the transaction. This document outlines how gas fees are determined for different types of blockchains.

We use our fees-service, a worker-based service that fetches gas prices from blockchain RPC nodes for EVM, UTXO, and other chain types. For Cosmos-based chains, we use a fixed gas price list from the chain-registry package on GitHub.

Gas prices are stored in Redis, which serves as a central store for our system. The fees-service updates gas prices approximately every 10 seconds in production. All fee calculations fetch the latest gas price data from Redis and apply chain-specific logic to determine transaction costs.


2. Gas Tank Platform Business Logic ​

Deposit Fees ​
  • Deposits are completely free for users.
  • The Gas Tank Platform (CTRL Wallet) covers all deposit fees.
  • Deposits are supported on the following chains:
    • Ethereum (USDC, CTRL)
    • Avalanche (USDC)
    • Polygon (USDC)
    • Optimism (USDC)
    • Arbitrum (USDC)
    • Fantom (axlUSDC)
    • Base (USDC)
  • Each deposit consists of two separate transactions:
    1. Permit transaction – Allows spending of tokens.
    2. Transfer transaction – Moves funds into the Gas Tank.
  • CTRL Wallet pays for both transactions, allowing deposits even if the user has no native tokens on the deposit chain.
Withdrawal & Consume (Send Gas) Fees ​
  • Withdrawals and gas consumption (sending gas) are not free.
  • Users must have sufficient balance in the Gas Tank to cover transaction fees.
  • The system supports USDC, CTRL, and axlUSDC as balance types.
  • Fee Calculation Steps:
    1. Determine the transaction fee for the destination chain.
    2. Convert the fee to a supported token (USDC, CTRL, axlUSDC).
    3. Check if the user has enough balance to cover the fee.
    4. Execute the transaction on the destination chain.
    5. Deduct the transaction fee from the user's Gas Tank balance.
Internal Transfers & Migrations ​
  • Internal transfers and wallet migrations are completely free.
  • These actions do not involve blockchain transactions and are processed entirely within the Gas Tank Platform.
  • No fees are required, as no on-chain transactions occur.

3. Fee Calculation by Chain Type ​

A. EVM-Based Blockchains (Ethereum, Polygon, BSC, etc.) ​

EVM-based chains follow two main fee models:

1. EIP-1559 Fee Model (Ethereum, Polygon, Arbitrum, Optimism, etc.) ​
  • Uses Base Fee + Priority Tip.
  • The total fee is calculated as:
    Total Fee = Gas Used Γ— (Max Fee Per Gas + Priority Tip)
  • The maxFeePerGas and priorityTip values are dynamically adjusted based on network demand.
2. Legacy Gas Price Model (BSC, zkSync, Aurora, etc.) ​
  • Uses a simple formula:
    Total Fee = Gas Used Γ— Gas Price
  • The gasPrice is a fixed amount set by the network or suggested by wallets.

βœ… How We Calculate Fees:

  1. Fetch the latest gas price from Redis.
  2. Multiply the gas price by the chain’s predefined gas limit (e.g., 21,000 for ETH transfers).
  3. Convert the fee into the desired token.
B. UTXO-Based Blockchains (Bitcoin, Litecoin, Dogecoin, etc.) ​

UTXO-based chains use a different fee model where fees depend on the size of the transaction in bytes rather than computational effort.

  • Formula:
    Total Fee = Transaction Size Γ— Fee Rate (per byte)
  • Example:
  • If a Bitcoin transaction is 226 bytes and the fee rate is 50 satoshis/byte, the total fee is:
    226 Γ— 50 = 11,300 satoshis (or 0.000113 BTC)

βœ… How We Calculate Fees:

  1. Fetch the fee rate (satoshis per byte) from Redis.
  2. Multiply by the standard transaction size (e.g., 226 bytes for Bitcoin).
  3. Convert the fee into the desired token.
C. Solana ​
  • Solana uses a fixed fee model where transaction fees are predefined by the network.
  • Solana fees are generally very low (e.g., 0.000005 SOL per transaction).

βœ… How We Calculate Fees:

  1. Fetch the standard Solana transaction fee from Redis.
  2. Convert it into the desired token if necessary.
D. Cosmos-Based Chains (Osmosis, Terra, Cosmos Hub, etc.) ​
  • Cosmos chains use a gas limit Γ— gas price model similar to EVM chains.
  • However, the gas limit varies based on the complexity of the transaction.

βœ… How We Calculate Fees:

  1. Fetch the gas price from Redis.
  2. Multiply it by the predefined gas limit for the specific Cosmos chain.
  3. Convert the fee into the desired token.
E. Near Protocol ​
  • Near’s gas fees are based on a fixed gas unit model.
  • The base fee is calculated using Tgas (teragas), where 1 Tgas = 0.0001 Ⓝ NEAR.

βœ… How We Calculate Fees:

  1. Multiply the gas price by Near’s predefined gas limit (e.g., 150 Tgas for simple transactions).
  2. Convert to the desired token.
F. Multi-Chain Protocols (ThorChain, MayaChain) ​
  • These protocols have a fixed native transaction fee.
  • The fee amount is the same regardless of transaction complexity.

βœ… How We Calculate Fees:

  1. Fetch the fixed native transaction fee from Redis.
  2. Convert to the desired token.

4. Fee Conversion to Other Tokens ​

Since fees are usually quoted in the blockchain’s native currency, they may need to be converted into another token.

  • Formula:
    Converted Fee = Raw Fee (native token) * Exchange Rate (Target Token Price)
  • Example:
  • If the Ethereum gas fee is 0.001 ETH and ETH = $2,500, the fee in USDC:
    0.001 Γ— 2500 = 2.5 USDC

βœ… How We Convert Fees:

  1. Fetch exchange rates for the given tokens.
  2. Convert the calculated fee into the desired token.

5. Error Handling ​

  • If gas price data is unavailable β†’ return an error (Gas price not found).
  • If gas limit is missing β†’ return an error (Gas limit not found).
  • If the chain is unsupported β†’ return an error (Unsupported chain).

6. Summary ​

  • Fees are calculated using real-time or pre-defined gas prices.
  • Redis is the main data store, populated by the fees-service.
  • Update intervals vary, with EVM chains getting the most frequent updates (every 10 seconds).
Blockchain TypeFee ModelFormula
EVM (Ethereum, BSC, Polygon, etc.)Gas Limit Γ— Gas PriceGas Used Γ— Gas Price
Bitcoin, Litecoin, Dogecoin (UTXO)Fee per byteTransaction Size Γ— Fee Rate
SolanaFixed FeeFixed amount per transaction
Cosmos (Osmosis, Terra, etc.)Gas Limit Γ— Gas PriceGas Used Γ— Gas Price
Near ProtocolFixed Gas UnitsGas Used Γ— Gas Price (Tgas)
Multi-Chain (ThorChain, MayaChain)Fixed FeeFixed amount per transaction

This document provides a complete overview of gas fees and business logic within the Gas Tank Platform. πŸš€

Other services ​

This section provides information about the other services provided by the Gas Tank API. APIs in this section not require JWT token for authentication.

Get information about the Gas Tank ​

This endpoint provides information about the conversion rates between different tokens and fees for deposit, withdrawal and consume actions.

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(`${GAS_TANK_ENDPOINT}/balances/info`, {
  method: "GET",
  headers: {
    "Content-Type": "application/json",
  },
})
  .then((response) => {
    console.log(response);
    // Handle & do something with the response
  })
  .catch((error) => {
    // Catch & handle the error
  });
json
{
  "conversionRates": {
    "xdefi": {
      "eth": 0.00003406230336183101,
      "bnb": 0.00020052618581142264,
      "usdc": 0.13496037812654052,
      "usdt": 0.1349557894736842,
      ...
    },
    "eth": {
      "xdefi": 29357.967644682656,
      "usdt": 3763.926315789474,
      ...
    },
    ... // Other pairs
  },
  "spenderAddresses": [
    "0x0E87C393120410d1edd00Ae5b616419795c5B57D"
  ],
  "fees": {
    "deposit": {
      "fees": {
        "high": "357840000000000",
        "medium": "357420000000000",
        "low": "357210000000000"
      }
    },
    "withdraw": {
      "fees": {
        "high": "357840000000000",
        "medium": "357420000000000",
        "low": "357210000000000"
      }
    },
    "consume": {
      "fees": {
        "high": "357840000000000",
        "medium": "357420000000000",
        "low": "357210000000000"
      }
    }
  }
}

Check the status of the application ​

This endpoint provides information about the status of the Gas Tank application and its dependencies.

javascript
const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services";

await fetch(`${GAS_TANK_ENDPOINT}/healthcheck`, {
  method: "GET",
  headers: {
    "Content-Type": "application/json",
  },
})
  .then((response) => {
    console.log(response);
    // Handle & do something with the response
  })
  .catch((error) => {
    // Catch & handle the error
  });
json
{
  "status": "OK",
  "database": "Connected",
  "mnemonic": "Set",
  "nats": "Connected"
}