Reconcile a Substrate transaction fee without adding the tip twice
Fee previews estimate the cost of signing a call. For an executed extrinsic on a runtime using native transaction payment, a fee event identifies the payer and charged amount.
Locate the payment event for one extrinsic
Select recordsForExtrinsic from its ApplyExtrinsic phase at the finalized inclusion block. Use the runtime’s matching polkadot-js event types. Keep the transaction hash and block hash alongside the fee record.
for (const {event} of recordsForExtrinsic) {
if (api.events.transactionPayment.TransactionFeePaid.is(event)) {
const [payer, actualFee, tip] = event.data
console.log(payer.toString(), actualFee.toString(), tip.toString())
}
}
Separate the tip from the rest of the fee
For actual_fee of 130 units and tip of 10, the total debit for the reported fee is 130. The non-tip component is 120. Treating the two event fields as separate charges would post 140. Keep all values in the native smallest unit until formatting.
Compare the actual fee with the pre-signing paymentInfo quote as separate measurements. Runtimes supporting asset-denominated fees may expose different events and units, so choose the decoder from that runtime’s payment mechanism.