diff --git a/src/utils/errors.ts b/src/utils/errors.ts index 82018af..650d863 100644 --- a/src/utils/errors.ts +++ b/src/utils/errors.ts @@ -7,6 +7,20 @@ export class XLinkSDKErrorBase extends Error { } } +export class InvalidMethodParametersError extends XLinkSDKErrorBase { + constructor( + public methodPath: string[], + public params: { + name: string + expected: string + received: string + }[], + ) { + super(`Invalid method parameters of method ${methodPath.join(".")}`) + this.name = "InvalidMethodParametersError" + } +} + export class UnsupportedBridgeRouteError extends XLinkSDKErrorBase { constructor( public fromChain: ChainId, diff --git a/src/xlinkSdkUtils/bridgeFromEVM.ts b/src/xlinkSdkUtils/bridgeFromEVM.ts index a3a0bb5..457ccfb 100644 --- a/src/xlinkSdkUtils/bridgeFromEVM.ts +++ b/src/xlinkSdkUtils/bridgeFromEVM.ts @@ -1,4 +1,4 @@ -import { encodeFunctionData } from "viem" +import { encodeFunctionData, toHex } from "viem" import { bridgeEndpointAbi } from "../evmUtils/contractAbi/bridgeEndpoint" import { evmContractAddresses } from "../evmUtils/evmContractAddresses" import { isSupportedEVMRoute } from "../evmUtils/peggingHelpers" @@ -11,7 +11,10 @@ import { buildSupportedRoutes, defineRoute, } from "../utils/buildSupportedRoutes" -import { UnsupportedBridgeRouteError } from "../utils/errors" +import { + InvalidMethodParametersError, + UnsupportedBridgeRouteError, +} from "../utils/errors" import { decodeHex } from "../utils/hexHelpers" import { assertExclude, checkNever } from "../utils/typeHelpers" import { @@ -92,12 +95,16 @@ export const supportedRoutes = buildSupportedRoutes( }, ) -export interface BridgeFromEVMInput { +export type BridgeFromEVMInput = { fromChain: ChainId toChain: ChainId fromToken: TokenId toToken: TokenId toAddress: string + /** + * **Required** when `toChain` is one of bitcoin chains + */ + toAddressScriptPubKey?: Uint8Array amount: SDKNumber sendTransaction: (tx: { to: EVMAddress; data: Uint8Array }) => Promise<{ txHash: string @@ -243,13 +250,33 @@ async function bridgeFromEVM_toBitcoinOrEVM( ) } + let finalToAddressHex: string + if (KnownChainId.isBitcoinChain(info.toChain)) { + if (info.toAddressScriptPubKey == null) { + throw new InvalidMethodParametersError( + ["bridgeFromEVM (to Bitcoin)"], + [ + { + name: "toAddressScriptPubKey", + expected: "Uint8Array", + received: "undefined", + }, + ], + ) + } + + finalToAddressHex = toHex(info.toAddressScriptPubKey) + } else { + finalToAddressHex = info.toAddress + } + const functionData = await encodeFunctionData({ abi: bridgeEndpointAbi, functionName: "transferToCross", args: [ fromTokenContractAddress.tokenContractAddress, numberToSolidityContractNumber(info.amount), - info.toAddress, + finalToAddressHex, contractAssignedChainIdFromKnownChain(info.fromChain), ], })