@@ -79,6 +79,8 @@ export namespace MultiTokenNttExecutorRoute {
7979 sourceTokenId : TokenId ;
8080 destinationTokenId : TokenId ;
8181 originalTokenId : MultiTokenNtt . OriginalTokenId ;
82+ gasLimit : bigint ;
83+ msgValue : bigint ;
8284 } ;
8385
8486 export interface ValidatedParams
@@ -184,7 +186,6 @@ export class MultiTokenNttExecutorRoute<N extends Network>
184186
185187 const parsedAmount = amount . parse ( params . amount , request . source . decimals ) ;
186188
187- // IMPORTANT: The EVM NttManager will revert if there is dust
188189 const trimmedAmount = NttRoute . trimAmount (
189190 parsedAmount ,
190191 request . destination . decimals
@@ -212,6 +213,32 @@ export class MultiTokenNttExecutorRoute<N extends Network>
212213
213214 const originalTokenId = await sourceNtt . getOriginalToken ( sourceToken ) ;
214215
216+ const destinationNttWithExecutor = await request . fromChain . getProtocol (
217+ "MultiTokenNttWithExecutor" ,
218+ {
219+ multiTokenNtt : destinationContracts ,
220+ }
221+ ) ;
222+
223+ const destinationNtt = await request . fromChain . getProtocol (
224+ "MultiTokenNtt" ,
225+ {
226+ multiTokenNtt : destinationContracts ,
227+ }
228+ ) ;
229+
230+ let { msgValue, gasLimit } =
231+ await destinationNttWithExecutor . estimateMsgValueAndGasLimit (
232+ originalTokenId ,
233+ destinationNtt
234+ ) ;
235+
236+ ( { msgValue, gasLimit } = this . getGasOverrides (
237+ request ,
238+ msgValue ,
239+ gasLimit
240+ ) ) ;
241+
215242 const validatedParams : Vp = {
216243 amount : params . amount ,
217244 normalizedParams : {
@@ -222,6 +249,8 @@ export class MultiTokenNttExecutorRoute<N extends Network>
222249 sourceTokenId : request . source . id ,
223250 destinationTokenId : request . destination . id ,
224251 originalTokenId,
252+ gasLimit,
253+ msgValue,
225254 } ,
226255 options,
227256 } ;
@@ -415,70 +444,6 @@ export class MultiTokenNttExecutorRoute<N extends Network>
415444 return { msgValue, gasLimit } ;
416445 }
417446
418- buildRelayInstructions (
419- gasLimit : bigint ,
420- msgValue : bigint ,
421- gasDropOff : bigint ,
422- recipient ?: ChainAddress
423- ) : Uint8Array {
424- const relayRequests = [ ] ;
425-
426- // Add the gas instruction
427- relayRequests . push ( {
428- request : {
429- type : "GasInstruction" as const ,
430- gasLimit,
431- msgValue,
432- } ,
433- } ) ;
434-
435- // Add the gas drop-off instruction if applicable
436- if ( gasDropOff > 0n ) {
437- relayRequests . push ( {
438- request : {
439- type : "GasDropOffInstruction" as const ,
440- dropOff : gasDropOff ,
441- // If the recipient is undefined (e.g. the user hasn't connected their wallet yet),
442- // we temporarily use a dummy address to fetch a quote.
443- // The recipient address is validated later in the `initiate` method, which will throw if it's still missing.
444- recipient : recipient
445- ? recipient . address . toUniversalAddress ( )
446- : new UniversalAddress ( new Uint8Array ( 32 ) ) ,
447- } ,
448- } ) ;
449- }
450-
451- return serializeLayout ( relayInstructionsLayout , {
452- requests : relayRequests ,
453- } ) ;
454- }
455-
456- async fetchDeliveryPriceAndInstructions (
457- fromChain : ChainContext < N > ,
458- toChain : ChainContext < N > ,
459- params : Vp
460- ) : Promise < {
461- deliveryPrice : bigint ;
462- transceiverInstructions : Ntt . TransceiverInstruction [ ] ;
463- } > {
464- // Get the source NTT protocol instance to quote delivery price
465- const sourceNtt = await fromChain . getProtocol ( "MultiTokenNtt" , {
466- multiTokenNtt : params . normalizedParams . sourceContracts ,
467- } ) ;
468-
469- // Get transceiver instructions for the transfer
470- const transceiverInstructions =
471- await sourceNtt . createTransceiverInstructions ( toChain . chain , 800_000n ) ;
472-
473- // Calculate core bridge fee (delivery price) using the transceiver instructions
474- const deliveryPrice = await sourceNtt . quoteDeliveryPrice (
475- toChain . chain ,
476- transceiverInstructions
477- ) ;
478-
479- return { deliveryPrice, transceiverInstructions } ;
480- }
481-
482447 async fetchExecutorQuote (
483448 request : routes . RouteTransferRequest < N > ,
484449 params : Vp
@@ -504,38 +469,39 @@ export class MultiTokenNttExecutorRoute<N extends Network>
504469
505470 const { recipient } = request ;
506471
507- const destinationNttWithExecutor = await toChain . getProtocol (
508- "MultiTokenNttWithExecutor" ,
509- {
510- multiTokenNtt : params . normalizedParams . destinationContracts ,
511- }
512- ) ;
513-
514472 const gasDropOffLimit = BigInt ( destinationCapabilities . gasDropOffLimit ) ;
515473 const gasDropOff = this . calculateGasDropOff ( gasDropOffLimit , params ) ;
516474
517- const destinationNtt = await toChain . getProtocol ( "MultiTokenNtt" , {
518- multiTokenNtt : params . normalizedParams . destinationContracts ,
519- } ) ;
475+ const relayRequests = [ ] ;
520476
521- let { msgValue, gasLimit } =
522- await destinationNttWithExecutor . estimateMsgValueAndGasLimit (
523- params . normalizedParams . originalTokenId ,
524- destinationNtt
525- ) ;
477+ // Add the gas instruction
478+ relayRequests . push ( {
479+ request : {
480+ type : "GasInstruction" as const ,
481+ gasLimit : params . normalizedParams . gasLimit ,
482+ msgValue : params . normalizedParams . msgValue ,
483+ } ,
484+ } ) ;
526485
527- ( { msgValue, gasLimit } = this . getGasOverrides (
528- request ,
529- msgValue ,
530- gasLimit
531- ) ) ;
486+ // Add the gas drop-off instruction if applicable
487+ if ( gasDropOff > 0n ) {
488+ relayRequests . push ( {
489+ request : {
490+ type : "GasDropOffInstruction" as const ,
491+ dropOff : gasDropOff ,
492+ // If the recipient is undefined (e.g. the user hasn't connected their wallet yet),
493+ // we temporarily use a dummy address to fetch a quote.
494+ // The recipient address is validated later in the `initiate` method, which will throw if it's still missing.
495+ recipient : recipient
496+ ? recipient . address . toUniversalAddress ( )
497+ : new UniversalAddress ( new Uint8Array ( 32 ) ) ,
498+ } ,
499+ } ) ;
500+ }
532501
533- const relayInstructions = this . buildRelayInstructions (
534- gasLimit ,
535- msgValue ,
536- gasDropOff ,
537- recipient
538- ) ;
502+ const relayInstructions = serializeLayout ( relayInstructionsLayout , {
503+ requests : relayRequests ,
504+ } ) ;
539505
540506 const quote = await fetchSignedQuote (
541507 fromChain . network ,
@@ -566,6 +532,32 @@ export class MultiTokenNttExecutorRoute<N extends Network>
566532 } ;
567533 }
568534
535+ async fetchDeliveryPriceAndInstructions (
536+ fromChain : ChainContext < N > ,
537+ toChain : ChainContext < N > ,
538+ params : Vp
539+ ) : Promise < {
540+ deliveryPrice : bigint ;
541+ transceiverInstructions : Ntt . TransceiverInstruction [ ] ;
542+ } > {
543+ const sourceNtt = await fromChain . getProtocol ( "MultiTokenNtt" , {
544+ multiTokenNtt : params . normalizedParams . sourceContracts ,
545+ } ) ;
546+
547+ const transceiverInstructions =
548+ await sourceNtt . createTransceiverInstructions (
549+ toChain . chain ,
550+ params . normalizedParams . gasLimit
551+ ) ;
552+
553+ const deliveryPrice = await sourceNtt . quoteDeliveryPrice (
554+ toChain . chain ,
555+ transceiverInstructions
556+ ) ;
557+
558+ return { deliveryPrice, transceiverInstructions } ;
559+ }
560+
569561 async initiate (
570562 request : routes . RouteTransferRequest < N > ,
571563 signer : Signer ,
@@ -761,6 +753,8 @@ export class MultiTokenNttExecutorRoute<N extends Network>
761753 destinationTokenId,
762754 originalTokenId,
763755 referrerFeeDbps : 0n ,
756+ gasLimit : 0n ,
757+ msgValue : 0n ,
764758 } ,
765759 options : {
766760 nativeGas : undefined ,
0 commit comments