@@ -3,14 +3,19 @@ import { stringify as yamlStringify } from 'yaml';
33import { CommandModule } from 'yargs' ;
44
55import {
6- ChainName ,
76 RawForkedChainConfigByChain ,
87 RawForkedChainConfigByChainSchema ,
98 expandVirtualWarpDeployConfig ,
109 expandWarpDeployConfig ,
1110 getRouterAddressesFromWarpCoreConfig ,
1211} from '@hyperlane-xyz/sdk' ;
13- import { ProtocolType , assert , objFilter } from '@hyperlane-xyz/utils' ;
12+ import {
13+ ProtocolType ,
14+ assert ,
15+ difference ,
16+ intersection ,
17+ objFilter ,
18+ } from '@hyperlane-xyz/utils' ;
1419
1520import { runWarpRouteCheck } from '../check/warp.js' ;
1621import { createWarpRouteDeployConfig } from '../config/warp.js' ;
@@ -33,7 +38,6 @@ import { getWarpRouteConfigsByCore, runWarpRouteRead } from '../read/warp.js';
3338import { RebalancerRunner } from '../rebalancer/runner.js' ;
3439import { sendTestTransfer } from '../send/transfer.js' ;
3540import { ExtendedChainSubmissionStrategySchema } from '../submitters/types.js' ;
36- import { runSingleChainSelectionStep } from '../utils/chains.js' ;
3741import {
3842 indentYamlOrJson ,
3943 readYamlOrJson ,
@@ -258,6 +262,7 @@ const send: CommandModuleWithWriteContext<
258262 router ?: string ;
259263 amount : string ;
260264 recipient ?: string ;
265+ chains ?: string ;
261266 }
262267> = {
263268 command : 'send' ,
@@ -274,6 +279,12 @@ const send: CommandModuleWithWriteContext<
274279 type : 'string' ,
275280 description : 'Token recipient address (defaults to sender)' ,
276281 } ,
282+ chains : {
283+ type : 'string' ,
284+ description : 'Comma separated list of chains to send messages to' ,
285+ demandOption : false ,
286+ conflicts : [ 'origin' , 'destination' ] ,
287+ } ,
277288 } ,
278289 handler : async ( {
279290 context,
@@ -287,43 +298,41 @@ const send: CommandModuleWithWriteContext<
287298 amount,
288299 recipient,
289300 roundTrip,
301+ chains : chainsAsString ,
290302 } ) => {
291303 const warpCoreConfig = await getWarpCoreConfigOrExit ( {
292304 symbol,
293305 warp,
294306 context,
295307 } ) ;
308+ const chainsToSend = chainsAsString ?. split ( ',' ) . map ( ( _ ) => _ . trim ( ) ) ;
309+ let chains = chainsToSend || [ ] ;
296310
297- let chains : ChainName [ ] = warpCoreConfig . tokens . map ( ( t ) => t . chainName ) ;
298- if ( roundTrip ) {
299- // Appends the reverse of the array, excluding the 1st (e.g. [1,2,3] becomes [1,2,3,2,1])
300- const reversed = [ ...chains ] . reverse ( ) . slice ( 1 , chains . length + 1 ) ; // We make a copy because .reverse() is mutating
301- chains . push ( ...reversed ) ;
302- } else {
303- // Assume we want to use use `--origin` and `--destination` params, prompt as needed.
304- const chainMetadata = objFilter (
305- context . chainMetadata ,
306- ( key , _metadata ) : _metadata is any => chains . includes ( key ) ,
307- ) ;
311+ if ( origin && destination ) {
312+ chains . push ( origin ) ;
313+ chains . push ( destination ) ;
314+ }
308315
309- if ( ! origin )
310- origin = await runSingleChainSelectionStep (
311- chainMetadata ,
312- 'Select the origin chain:' ,
313- ) ;
316+ const supportedChains = new Set (
317+ warpCoreConfig . tokens . map ( ( t ) => t . chainName ) ,
318+ ) ;
314319
315- if ( ! destination )
316- destination = await runSingleChainSelectionStep (
317- chainMetadata ,
318- 'Select the destination chain:' ,
319- ) ;
320+ const unsupportedChains = difference (
321+ new Set ( [ ...( chainsToSend || [ ] ) , origin , destination ] . filter ( Boolean ) ) ,
322+ supportedChains ,
323+ ) ;
324+ assert (
325+ unsupportedChains . size === 0 ,
326+ `Chain(s) ${ [ ...unsupportedChains ] . join ( ', ' ) } are not part of the warp route.` ,
327+ ) ;
320328
321- chains = [ origin , destination ] . filter ( ( c ) => chains . includes ( c ) ) ;
329+ chains = [ ...intersection ( new Set ( chains ) , supportedChains ) ] ;
330+ assert ( chains . length > 1 , `Not enough chains to send messages.` ) ;
322331
323- assert (
324- chains . length === 2 ,
325- `Origin ( ${ origin } ) or destination ( ${ destination } ) are not part of the warp route.` ,
326- ) ;
332+ if ( roundTrip ) {
333+ // Appends the reverse of the array, excluding the 1st (e.g. [1,2,3] becomes [1,2,3,2,1])
334+ const reversed = [ ... chains ] . reverse ( ) . slice ( 1 , chains . length + 1 ) ;
335+ chains = [ ... chains , ... reversed ] ;
327336 }
328337
329338 logBlue ( `🚀 Sending a message for chains: ${ chains . join ( ' ➡️ ' ) } ` ) ;
0 commit comments