Docs

payment_queryInfo - Manta Atlantic RPC Method

Estimate transaction fees on Manta Atlantic. Get the weight, dispatch class, and partial fee for an extrinsic before submitting it to the network.

Estimates the fee for an encoded extrinsic on Manta Atlantic. Returns the weight, dispatch class, and partial fee so you can display costs to users or verify sufficient balance before submitting transactions.

Why Manta Atlantic? Build on the ZK Layer 1 on Polkadot enabling private transactions and on-chain compliance identities with zkSNARK-powered privacy, modular compliance identities, MANTA token staking hub, and end-to-end transaction privacy.

When to Use This Method

payment_queryInfo is essential for privacy-focused developers, DeFi builders requiring private swaps, and teams needing zkSNARK capabilities:

  • Fee Display -- Show users the estimated transaction cost before they sign on Manta Atlantic
  • Balance Validation -- Verify the sender has sufficient funds to cover the fee plus the transfer amount for private asset transfers, zkNFTs, on-chain compliance identities, and private parachain asset swaps
  • Transaction Planning -- Compare fees across different extrinsic types to optimize costs
  • Batch Cost Estimation -- Estimate the total cost of batch transactions before submission

Code Examples

Common Use Cases

1. Pre-Transaction Fee Display

Show fees to users before they confirm a transaction:

JavaScript
import { ApiPromise, WsProvider } from '@polkadot/api';
import { BN } from '@polkadot/util';

async function displayFeeEstimate(api, extrinsic, senderAddress) {
  const [info, properties] = await Promise.all([
    extrinsic.paymentInfo(senderAddress),
    api.rpc.system.properties()
  ]);

  const decimals = properties.tokenDecimals.toJSON()[0];
  const symbol = properties.tokenSymbol.toJSON()[0];
  const fee = info.partialFee;

  // Convert to human-readable
  const divisor = new BN(10).pow(new BN(decimals));
  const whole = fee.div(divisor);
  const fractional = fee.mod(divisor).toString().padStart(decimals, '0');

  const formatted = `${whole}.${fractional.slice(0, 6)} ${symbol}`;
  console.log(`Estimated fee: ${formatted}`);
  console.log(`Dispatch class: ${info.class.toString()}`);

  return { fee: fee.toString(), formatted, class: info.class.toString() };
}

2. Sufficient Balance Check

Verify the sender can afford the transaction plus fees:

JavaScript
async function canAffordTransaction(api, senderAddress, recipient, amount) {
  const transfer = api.tx.balances.transferKeepAlive(recipient, amount);
  const [info, account] = await Promise.all([
    transfer.paymentInfo(senderAddress),
    api.query.system.account(senderAddress)
  ]);

  const fee = info.partialFee.toBigInt();
  const transferAmount = BigInt(amount);
  const totalCost = fee + transferAmount;
  const freeBalance = account.data.free.toBigInt();

  // Account for existential deposit
  const existentialDeposit = api.consts.balances.existentialDeposit.toBigInt();
  const available = freeBalance - existentialDeposit;

  const canAfford = available >= totalCost;

  console.log(`Free balance: ${freeBalance}`);
  console.log(`Total cost (amount + fee): ${totalCost}`);
  console.log(`Can afford: ${canAfford}`);

  return canAfford;
}

3. Compare Fees Across Transaction Types

Estimate fees for different operations to find the cheapest approach:

JavaScript
async function compareFees(api, sender) {
  const recipient = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY';
  const amount = 1000000000000;

  // Different transaction types
  const extrinsics = {
    'transfer': api.tx.balances.transferKeepAlive(recipient, amount),
    'transferAll': api.tx.balances.transferAll(recipient, false),
    'batchTransfer': api.tx.utility.batchAll([
      api.tx.balances.transferKeepAlive(recipient, amount / 2),
      api.tx.balances.transferKeepAlive(recipient, amount / 2)
    ])
  };

  const fees = {};
  for (const [name, ext] of Object.entries(extrinsics)) {
    const info = await ext.paymentInfo(sender);
    fees[name] = {
      partialFee: info.partialFee.toHuman(),
      weight: info.weight.toString(),
      class: info.class.toString()
    };
  }

  console.table(fees);
  return fees;
}

Error Handling

Common errors and solutions:

Error CodeDescriptionSolution
-32603Unable to query dispatch infoEnsure the extrinsic is properly encoded; verify it is a valid call for the current runtime
-32602Invalid paramsCheck the extrinsic hex is properly formatted with 0x prefix
-32005Rate limit exceededImplement client-side rate limiting or cache fee estimates for similar transactions
Execution errorRuntime unable to compute feeThe extrinsic may reference invalid pallets or calls; verify against current metadata