Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 32 additions & 12 deletions sdk/src/gateway/layerzero.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import ecc from '@bitcoinerlab/secp256k1';
import * as bitcoin from 'bitcoinjs-lib';
import { Address, encodeAbiParameters, encodePacked, Hex, padHex, parseAbiParameters } from 'viem';
import {
Address,
ContractFunctionExecutionError,
encodeAbiParameters,
encodePacked,
Hex,
padHex,
parseAbiParameters,
} from 'viem';
import { bob, bobSepolia } from 'viem/chains';
import { layerZeroOftAbi, quoterV2Abi } from './abi';
import { AllWalletClientParams, GatewayApiClient } from './client';
Expand Down Expand Up @@ -456,19 +464,31 @@ export class LayerZeroGatewayClient extends GatewayApiClient {
args: [sendParam, false],
});

const { request } = await publicClient.simulateContract({
account: walletClient.account,
abi: layerZeroOftAbi,
address: wbtcOftAddress as Hex,
functionName: 'send',
args: [sendParam, sendFees, params.fromUserAddress as Address],
value: sendFees.nativeFee,
});
try {
const { request } = await publicClient.simulateContract({
account: walletClient.account,
abi: layerZeroOftAbi,
address: wbtcOftAddress as Hex,
functionName: 'send',
args: [sendParam, sendFees, params.fromUserAddress as Address],
value: sendFees.nativeFee,
});

const txHash = await walletClient.writeContract(request);
await publicClient.waitForTransactionReceipt({ hash: txHash });
const txHash = await walletClient.writeContract(request);
await publicClient.waitForTransactionReceipt({ hash: txHash });

return txHash;
} catch (error) {
if (error instanceof ContractFunctionExecutionError) {
// https://github.com/wevm/viem/blob/3aa882692d2c4af3f5e9cc152099e07cde28e551/src/actions/public/simulateContract.test.ts#L711
// throw new error
throw new Error(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally in the future we should throw error codes to allow the UI to handle with the right copy and tranlastions

Copy link
Contributor

@slavastartsev slavastartsev Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally we need to validate which error class was used to crate an error.
you can do similar check to the way we check for user rejection event https://github.com/bob-collective/ui/blob/710a43ce4a529177117da6ce5f583509d2e6e39c/apps/evm/src/lib/viem/utils.ts#L3-L4

string matching is not the best solution as error message is a subject to change

I think for the error message you can stick to viem error message as those are nicely formatted, so you're safe to re-throw

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok slightly unsure what changes you recommend to make now @slavastartsev ? you can just make a commit yourself if easier also

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I wanted to say is that viem chains the errors. Described in this test.
the way we need to adjust the catch block

} catch (error) {
    if (error instanceof ContractFunctionExecutionError) {
        throw error; // re-throw the error throw by viem or throw new Error with custom error message
    }

    throw error;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the The total cost (gas * gas fee + value) of executing this transaction exceeds the balance of the account error the only instance of ContractFunctionExecutionError that could come up?

'Insufficient native funds for source and destination gas fees, please add more native funds to your account'
);
}

return txHash;
throw error;
}
} else {
throw new Error(`Unsupported chain combination: ${fromChain} -> ${toChain}`);
}
Expand Down