@@ -21,6 +21,7 @@ import {
2121 runSolanaNode ,
2222} from '@hyperlane-xyz/sealevel-sdk/testing' ;
2323import {
24+ TokenFeeType ,
2425 TokenType ,
2526 type WarpCoreConfig ,
2627 type WarpRouteDeployConfig ,
@@ -355,4 +356,75 @@ describe('hyperlane warp crossCollateral EVM+SVM e2e tests', function () {
355356 `EVM Route B should have EVM Route A enrolled as CC router on domain ${ evmDomainId } ` ,
356357 ) . to . include ( evmRouterAHex32 ) ;
357358 } ) ;
359+
360+ it ( 'should deploy EVM collateral + SVM synthetic with RoutingFee tokenFee without error' , async function ( ) {
361+ const evmOwner = new Wallet ( EVM_KEY ) . address ;
362+ const svmOwner = svmSigner . getSignerAddress ( ) ;
363+ const DECIMALS = 9 ;
364+ const SYMBOL = 'RTKN' ;
365+
366+ const evmToken = await deployToken (
367+ EVM_KEY ,
368+ EVM_CHAIN ,
369+ DECIMALS ,
370+ SYMBOL ,
371+ 'Routing Token' ,
372+ REGISTRY_PATH ,
373+ ) ;
374+
375+ const warpId = createWarpRouteConfigId ( SYMBOL , `${ EVM_CHAIN } -${ SVM_CHAIN } ` ) ;
376+ const warpDeployConfig : WarpRouteDeployConfig = {
377+ [ EVM_CHAIN ] : {
378+ type : TokenType . collateral ,
379+ token : evmToken . address ,
380+ mailbox : evmCoreAddresses . mailbox ,
381+ owner : evmOwner ,
382+ tokenFee : {
383+ type : TokenFeeType . RoutingFee ,
384+ owner : evmOwner ,
385+ feeContracts : {
386+ [ SVM_CHAIN ] : {
387+ type : TokenFeeType . LinearFee ,
388+ bps : 50 ,
389+ } ,
390+ } ,
391+ } ,
392+ } ,
393+ [ SVM_CHAIN ] : {
394+ type : TokenType . synthetic ,
395+ mailbox : svmCoreAddresses . mailbox ,
396+ owner : svmOwner ,
397+ name : 'Routing Token' ,
398+ symbol : SYMBOL ,
399+ decimals : DECIMALS ,
400+ metadataUri : 'https://test.example.com/rtkn-metadata.json' ,
401+ } ,
402+ } ;
403+
404+ writeYamlOrJson ( WARP_DEPLOY_OUTPUT_PATH , warpDeployConfig ) ;
405+
406+ // Before the fix, enrollCrossChainRouters would fail with a
407+ // RoutingFeeInputConfigSchema validation error because the EVM reader
408+ // returns empty feeContracts when no SVM routers are enrolled yet.
409+ await warpCommands . deployRaw ( {
410+ warpRouteId : warpId ,
411+ warpDeployPath : WARP_DEPLOY_OUTPUT_PATH ,
412+ skipConfirmationPrompts : true ,
413+ extraArgs : [
414+ `--key.${ ProtocolType . Ethereum } ` ,
415+ EVM_KEY ,
416+ `--key.${ ProtocolType . Sealevel } ` ,
417+ SVM_KEY ,
418+ ] ,
419+ } ) ;
420+
421+ const warpCorePath = getWarpCoreConfigPath ( SYMBOL , [ EVM_CHAIN , SVM_CHAIN ] ) ;
422+ const deployedConfig = await warpCommands . readConfig (
423+ EVM_CHAIN ,
424+ warpCorePath ,
425+ ) ;
426+ expect ( deployedConfig [ EVM_CHAIN ] . tokenFee ?. type ) . to . equal (
427+ TokenFeeType . RoutingFee ,
428+ ) ;
429+ } ) ;
358430} ) ;
0 commit comments