pallet-xcm now offers a flexible transfer_assets() extrinsic that does what you want ![]()
It can combine multiple types of transfers in same XCM as long as the path of all the assets is the same ( A->B or A->OtherReserve->B). Works even if some assets have reserve on A while others have it on B or others are teleportable between A and B.
More details here: pallet-xcm: add new flexible `transfer_assets()` call/extrinsic by acatangiu 路 Pull Request #2388 路 paritytech/polkadot-sdk 路 GitHub
The main reason one cannot (or should not) combine assets that take different paths in a single transfer is that with multiple paths there is no ordering guarantee (e.g. assets can arrive before the fees) and no transfer atomicity guarantee (only half the transfer works, so it鈥檚 undefined state: not successful, not failed).