What you’ll be able to do
- Estimate a transfer’s transaction fee.
- Check that the signing account can cover the transfer and maximum gas cost.
- Verify the final fee from the transaction receipt.
*USDZ.
The bank or PSP sets its customer-facing service charge separately. It can
use the transaction fee as an input to that pricing.
Choose the gas token
Transaction fees are deducted directly from the signing account’s balance in the gas token. No separate token-spending approval is required. Keep the transaction’s nativevalue at zero.
On testnet, the default gas token is
*USDZ at
0x000000000000000000000000000000000000B5D5, with 18 decimals. The
Metal SDK supports explicit selection through its
gasToken argument. Only tokens recognised by the MIP20 allowlist
can pay gas.
RPC credit in the console pays for endpoint requests. Transaction fees are
paid from the signing account’s balance in the gas token.
120000 base units
is 0.12 of a six-decimal token but 0.00000000000012 of an 18-decimal token.
Read the gas token’s decimals() when displaying costs.
Calculate the quote and balance requirement
The gas limit caps the work a transaction may consume. The gas price is the token amount paid per unit of work. Metal’s execution base fee is zero. For a transaction with fee-cap fields:eth_gasPrice (client.getGasPrice() in viem).
Metal requires a positive effective price, a priority fee no greater than the
fee cap, and a fee cap no greater than 1_000_000_000_000 base units per gas.
The SDK sets both fields from its maxFeePerGas argument.
For a direct transfer paid in the same token, require:
Add quoting and fee accounting to an application
Use a dedicated test account, following the quickstart account instructions if you need to create one. Fund it with*USDZ through the
faucet and supply its key as PRIVATE_KEY through
secret configuration. For an application with a custody or signing service,
provide that signer through the SDK’s wallet client.
Set RECIPIENT_ADDRESS to a different EVM address you control. The test transfer
sends 0.01 test tokens and compares the resulting account balances, so
both accounts must have no other activity during the test.
From the application directory, install the public packages:
Configure the test signer
Create a wallet client for the signer using the application’srpcUrl.
The transaction transfers *USDZ and pays gas in *USDZ.
Reading balances and estimating fees require only the sender’s public address.
The private key is needed to sign the transaction.
Estimate the transfer
gas required exceeds allowance (0), even
when the signing account’s balance in the gas token is sufficient. If estimation
fails, stop before signing and investigate the cause. Add 20% plus 10,000 gas
to the estimate as headroom, as shown above.
Check affordability
Before preparing the transaction, read the sender’s spendable balance and check that it covers the transfer and maximum gas cost. Record the recipient’s balance at the same block to reconcile both changes later:maximumFee in the second. Keep these calculations in integer
base units. Read the gas token’s decimals and use formatUnits for display.
Submit with the quoted gas budget
The wallet client must usesender as its signing account. Pass the same token,
amount, price, and limit used in the quote:
gasLimit makes the SDK use the quoted limit. The SDK still requires
gasFallback, but does not use it on this path.
Save signed.txHash and signed.raw in the transaction record
before calling await signed.send(). Submit transactions sequentially for each
signing account.
Record the actual fee
After submission, look up the saved transaction hash:actualFee
in base units. Calculate and record the fee even when execution reverted.
Treat a successful transaction as a completed payment only after
payment verification and
finality checks pass. If receipt polling times out,
keep looking up the saved hash until the outcome is known.
For this direct transfer between otherwise inactive accounts, verify the fee
against balances at the receipt block:
Handle failures and uncertain submissions
Exercise the application’s checks with missing configuration, the wrong
network, and an amount larger than the funded balance. Each should stop before
submission. Keep receipt status separate from fee calculation as a failure can
still incur a cost.