Binance, Bitpanda and Coinbase still repeated two identical hooks after the first
extraction: aspspCountry() (from $validated['country']) and buildPendingAccounts()
(a single "Crypto Portfolio" pending account). That was the very duplication the
refactor set out to remove.
Add CryptoPortfolioConnectController between the shared base and the three crypto
controllers to implement both hooks once. The pending-account uid is derived from
the provider enum value (binance/bitpanda/coinbase), so the generated uids
("binance-portfolio", etc.) are unchanged. Each crypto controller now declares
only its client, names, logo and error copy.
Behavior unchanged; OpenBanking feature tests still pass (304/304).