Some cross-chain bridges, including Avalanche Bridge and Anyswap, do not support smart contracts, and as such if the recipient address is a smart contract address, they do not credit the funds. In Ambire and other smart wallets such as Gnosis Safe, each account is a smart contract.
In such cases, only the bridge operator can unlock the funds, but more importantly, the issue stems from a misunderstanding: while the bridges truly do not support smart contracts, and smart contract support is not always straightforward, smart wallets (Ambire in particular) can and must be treated as normal wallets (EOAs, i.e. External Owned Accounts). Unlike other smart contracts, there are no special calls (authorisations) or special code paths required.
Normally, to support smart contracts as a bridge you would need some sort of a receipt protocol with the contract, so that the contract can account for the received funds. This is not straightforward to do and this is the reason why a lot of bridges do not support that.
However, Ambire Wallet accounts can be treated as normal EOAs, because the user accounts can just receive ERC20s and the chain native asset (ETH/MATIC/BNB/etc.) without loss of funds: each user has a separate address. No special logic is required and there is no extra risk, because the receipt of native assets (ETH/MATIC/BNB/etc.) does not trigger any code execution.
Ambire Wallets accounts are also easily detectable, so as a bridge operator you can add an exception for them. Every wallet has one of those exact bytecodes:
0x363d3d373d3d3d363d732a2b85eb1054d6f0c6c2e37da05ed3e5fea684ef5af43d82803e903d91602b57fd5bf3
0x363d3d373d3d3d363d730f2aa7bcda3d9d210df69a394b6965cb2566c8285af43d82803e903d91602b57fd5bf3
But what about cross-chain? in some cases smart contracts are blocked because the same address contract will not exist on another chain. Well, Ambire Wallet accounts are cross-chain and the same address will be accessible on all EVM chains - so once again, you can treat Ambire Wallet accounts as normal EOAs.
In pseudocode, modifying your bridge would look like this:
const code = getCode(recipient)
// change this
if (code != '0x') throw Unsupported()
// to this
if (code != '0x' && code != '0x363d3d373d3d3d363d732a2b85eb1054d6f0c6c2e37da05ed3e5fea684ef5af43d82803e903d91602b57fd5bf3') throw Unsupported()
A note about security: in case you intentionally block contracts for security reasons, such as avoiding reentrancies and/or flash loan attacks, you should know that there is no reliable way to do this. Checking contract code is not a security mechanism because contracts have no code during constructor execution, and can delete their own code and reappear later at the same address using create2. You can read more about why this isn't a reliable security mechanism here: https://docs.openzeppelin.com/contracts/2.x/api/utils#Address-isContract-address-
In summary, by blocking contracts you gain no security, but you break support for Ambire, Gnosis Safe and other smart wallets.
Whitelisting Ambire Wallet accounts is also completely safe, because they have the same bytecode, are immutable (non-upgradable), and do not run any code upon receipt of funds.