decodeCalldata() and tokenAmountText() move out of the TxApproval view into src/shared/calldataDecoder.js. TxApproval, TransactionDetail and the decoder tests import them from there. tokenSourcesByChainId() moves from the popup view helpers to src/shared/state.js, beside currentNetwork(), so the decoder requires nothing under src/popup/. It reads only the state singleton and the network table. Model: opus-5-5