A user reported to me that they are unable to create a PSBT with a legacy watchonly wallet when they use the GUI. They get an error "The amount exceeds your balance".

I think the issue is that the GUI will retrieve the wallet's balance via `AvailableCoins` before calling `CreateTransaction`. This call to `AvailableCoins` is resulting in fewer coins being returned with recent changes to how `AvailableCoins` works, particularly with additional filtering of spendable coins and preset coins.

***

Note that this does not effect descriptor wallets. A workaround for this issue is to switch to using descriptor wallets. An existing legacy wallet can be turned into a descriptor wallet using the `migratewallet` RPC. However many watchonly legacy wallets are likely the result of importing descriptors via `importmulti`. For such wallets, I recommend creating a new descriptor wallet and re-importing the descriptors.
PreSelectedInputs preset_inputs;
    if (coin_control.HasSelected()) {
        auto res_fetch_inputs = FetchSelectedInputs(wallet, coin_control, coin_selection_params);
        if (!res_fetch_inputs) return util::Error{util::ErrorString(res_fetch_inputs)};
        preset_inputs = *res_fetch_inputs;
    }
    
    
    CoinsResult available_coins;
    if (coin_control.m_allow_other_inputs) {
        available_coins = AvailableCoins(wallet, &coin_control, coin_selection_params.m_effective_feerate);
    }
    
    auto select_coins_res = SelectCoins(wallet, available_coins, preset_inputs, selection_target, coin_control, coin_selection_params);
    if (!select_coins_res) {
        
        const bilingual_str& err = util::ErrorString(select_coins_res);
        return util::Error{err.empty() ?_("Insufficient funds") : err};
    }
    const SelectionResult& result = *select_coins_res;
    TRACE5(coin_selection, selected_coins, wallet.GetName().c_str(), GetAlgorithmName(result.GetAlgo()).c_str(), result.GetTarget(), result.GetWaste(), result.GetSelectedValue());
    const CAmount change_amount = result.GetChange(coin_selection_params.min_viable_change, coin_selection_params.m_change_fee);
    if (change_amount > 0) {
        CTxOut newTxOut(change_amount, scriptChange);
        if (nChangePosInOut == -1) {
            
            nChangePosInOut = rng_fast.randrange(txNew.vout.size() + 1);
        } else if ((unsigned int)nChangePosInOut > txNew.vout.size()) {
            return util::Error{_("Transaction change output index out of range")};
        }