useTxFee

Estimates transaction fees with automatic loading and error state management. Accepts a transaction created with useTx and automatically estimates fees based on the provided arguments.

Props

Name
Type
Description

tx

UseTxReturnType

Transaction instance from useTx hook.

args

any[]

Arguments for the transaction. Required if transaction has parameters.

txOptions

Partial<PayloadOptions>?

Transaction options to include in fee estimation (e.g., tip, nonce).

enabled

boolean?

Whether to automatically fetch the fee estimate. Default: true.

networkId

NetworkId?

Optional network ID to specify which client to use.

Return Type

Name
Type
Description

fee

bigint | null

The estimated fee in the smallest unit (e.g., Planck for Polkadot). null if not available.

isLoading

boolean

Whether fee estimation is in progress.

error

string | null

Error message if estimation failed, null otherwise.

refresh

() => Promise<void>

Function to manually trigger fee estimation.

Basic Usage

Fee estimation with validation:

import { useTx, useTxFee, formatBalance } from 'typink';

function RemarkWithFee() {
  const [message, setMessage] = useState('Hello!');
  const remarkTx = useTx((tx) => tx.system.remark);

  const { fee, isLoading, error } = useTxFee({
    tx: remarkTx,
    args: [message],
    enabled: message.trim().length > 0,
  });

  return (
    <div>
      <input
        value={message}
        onChange={(e) => setMessage(e.target.value)}
        placeholder="Enter message"
      />

      {isLoading && <p>Calculating fee...</p>}
      {error && <p style={{ color: 'red' }}>Error: {error}</p>}
      {fee && <p>Estimated Fee: {formatBalance(fee)}</p>}

      <button onClick={() => remarkTx.signAndSend({ args: [message] })}>
        Send Remark
      </button>
    </div>
  );
}

Conditional fee estimation:

function TransferWithFee() {
  const [recipient, setRecipient] = useState('');
  const [amount, setAmount] = useState('');

  const transferTx = useTx((tx) => tx.balances.transferKeepAlive);

  const isValidRecipient = recipient.length === 48;
  const parsedAmount = amount ? BigInt(amount) : 0n;

  const { fee, isLoading, error } = useTxFee({
    tx: transferTx,
    args: [recipient, parsedAmount],
    enabled: isValidRecipient && parsedAmount > 0n,
  });

  return (
    <div>
      <input
        value={recipient}
        onChange={(e) => setRecipient(e.target.value)}
        placeholder="Recipient address"
      />
      <input
        value={amount}
        onChange={(e) => setAmount(e.target.value)}
        placeholder="Amount"
        type="number"
      />

      {fee && (
        <div>
          <p>Estimated Fee: {formatBalance(fee)}</p>
          <p>Total: {formatBalance(fee + parsedAmount)}</p>
        </div>
      )}

      <button
        onClick={() => transferTx.signAndSend({ args: [recipient, parsedAmount] })}
        disabled={isLoading || transferTx.inProgress}>
        Transfer
      </button>
    </div>
  );
}

Last updated

Was this helpful?