diff --git a/src/errors/checkXcmTxInputs.spec.ts b/src/errors/checkXcmTxInputs.spec.ts index a5778124..b40a72d2 100644 --- a/src/errors/checkXcmTxInputs.spec.ts +++ b/src/errors/checkXcmTxInputs.spec.ts @@ -14,6 +14,7 @@ import { checkAssetIdsLengthIsValid, checkAssetsAmountMatch, checkBridgeTxInputs, + checkDestAddrIsValid, checkDryRunCallOptionIncludesSendersAddressAndXcmFeeAsset, checkIfNativeRelayChainAssetPresentInMultiAssetIdList, checkLiquidTokenTransferDirectionValidity, @@ -903,6 +904,35 @@ describe('checkDryRunCallOptionIncludesSendersAddressAndXcmFeeAsset', () => { }); }); +describe('checkDestAddrIsValid', () => { + it('Should correctly throw an error when destAddr is an ethereum address and the destination is a system chain', () => { + const destAddr = '0x6E733286C3Dc52C67b8DAdFDd634eD9c3Fb05B5B'; + const direction = Direction.ParaToSystem; + + const err = () => checkDestAddrIsValid(destAddr, direction); + + expect(err).toThrow( + '`destAddr` must be a valid substrate address when the destination chain is not a Parachain or Ethereum.', + ); + }); + it('Should correctly not throw an error when destAddr is a substrate address and the destination is a system chain', () => { + const destAddr = '5HBuLJz9LdkUNseUEL6DLeVkx2bqEi6pQr8Ea7fS4bzx7i7E'; + const direction = Direction.ParaToSystem; + + const err = () => checkDestAddrIsValid(destAddr, direction); + + expect(err).not.toThrow(); + }); + it('Should correctly not throw an error when the destAddr is an ethereum address and the destination is a parachain', () => { + const destAddr = '5HBuLJz9LdkUNseUEL6DLeVkx2bqEi6pQr8Ea7fS4bzx7i7E'; + const direction = Direction.SystemToPara; + + const err = () => checkDestAddrIsValid(destAddr, direction); + + expect(err).not.toThrow(); + }); +}); + describe('checkParaAssets', () => { it('Should correctly resolve when a valid symbol assetId is provided', async () => { const assetId = 'xcUSDt'; diff --git a/src/errors/checkXcmTxInputs.ts b/src/errors/checkXcmTxInputs.ts index c3e38d6f..e24dec00 100644 --- a/src/errors/checkXcmTxInputs.ts +++ b/src/errors/checkXcmTxInputs.ts @@ -28,6 +28,28 @@ import { validateNumber } from '../validate'; import { BaseError, BaseErrorsEnum } from './BaseError'; import type { CheckXcmTxInputsOpts } from './types'; +/** + * Ensure `destAddr` is a non ethereum address when the destination is a System or Relay chain. + * + * @param destAddr + * @param direction + */ +export const checkDestAddrIsValid = (destAddr: string, direction: Direction) => { + if ( + isEthereumAddress(destAddr) && + (direction === Direction.RelayToSystem || + direction === Direction.SystemToSystem || + direction === Direction.SystemToRelay || + direction === Direction.ParaToSystem || + direction === Direction.ParaToRelay) + ) { + throw new BaseError( + '`destAddr` must be a valid substrate address when the destination chain is not a Parachain or Ethereum.', + BaseErrorsEnum.InvalidInput, + ); + } +}; + /** * Ensure when sending tx's to or from the relay chain that the length of the assetIds array * is zero or 1, and contains the correct token. @@ -1125,6 +1147,8 @@ export const checkXcmTxInputs = async (baseArgs: XcmBaseArgsWithPallet, opts: Ch } = opts; const relayChainInfo = registry.currentRelayRegistry; + checkDestAddrIsValid(destAddr, direction); + /** * Require `sendersAddr` and `xcmFeeAsset` when dryRunCall option is true */