@@ -22,7 +22,6 @@ import {
2222 ZIRCUIT_L2_STANDARD_BRIDGE ,
2323 ZIRCUIT_OPTIMISM_PORTAL ,
2424 ZIRCUIT_L2_OUTPUT_ORACLE ,
25- ZIRCUIT_L2_TO_L1_MESSAGE_PASSER ,
2625 ETHEREUM_CHAIN_ID ,
2726 ZIRCUIT_CHAIN_ID ,
2827 CHALLENGE_PERIOD_SECONDS ,
@@ -31,7 +30,6 @@ import {
3130 zircuitOptimismPortalAbi ,
3231 zircuitL2OutputOracleAbi ,
3332 zircuitL2ToL1MessagePasserAbi ,
34- L2_ETH_TOKEN ,
3533 ZERO_ADDRESS ,
3634} from './constants' ;
3735
@@ -51,6 +49,12 @@ interface OutputRootProof {
5149 latestBlockhash : `0x${string } `;
5250}
5351
52+ interface ZircuitProofResult {
53+ l2OutputIndex : bigint ;
54+ outputRootProof : OutputRootProof ;
55+ withdrawalProof : `0x${string } `[ ] ;
56+ }
57+
5458export class ZircuitNativeBridgeAdapter implements BridgeAdapter {
5559 constructor (
5660 protected readonly chains : Record < string , ChainConfiguration > ,
@@ -82,6 +86,10 @@ export class ZircuitNativeBridgeAdapter implements BridgeAdapter {
8286 ) : Promise < MemoizedTransactionRequest [ ] > {
8387 try {
8488 const isL1ToL2 = route . origin === ETHEREUM_CHAIN_ID && route . destination === ZIRCUIT_CHAIN_ID ;
89+ const isL2ToL1 = route . origin === ZIRCUIT_CHAIN_ID && route . destination === ETHEREUM_CHAIN_ID ;
90+ if ( ! isL1ToL2 && ! isL2ToL1 ) {
91+ throw new Error ( `Unsupported Zircuit route: ${ route . origin } ->${ route . destination } ` ) ;
92+ }
8593 const isETH = route . asset . toLowerCase ( ) === ZERO_ADDRESS ;
8694 const transactions : MemoizedTransactionRequest [ ] = [ ] ;
8795
@@ -128,7 +136,13 @@ export class ZircuitNativeBridgeAdapter implements BridgeAdapter {
128136 }
129137
130138 // Resolve the L2 token address via tickerHash mapping
131- const l2Token = getDestinationAssetAddress ( route . asset , route . origin , route . destination , this . chains , this . logger ) ;
139+ const l2Token = getDestinationAssetAddress (
140+ route . asset ,
141+ route . origin ,
142+ route . destination ,
143+ this . chains ,
144+ this . logger ,
145+ ) ;
132146 if ( ! l2Token ) {
133147 throw new Error ( `No L2 token mapping found for ${ route . asset } on chain ${ route . destination } ` ) ;
134148 }
@@ -195,7 +209,13 @@ export class ZircuitNativeBridgeAdapter implements BridgeAdapter {
195209 }
196210
197211 // Resolve the L1 token address via tickerHash mapping
198- const l1Token = getDestinationAssetAddress ( route . asset , route . origin , route . destination , this . chains , this . logger ) ;
212+ const l1Token = getDestinationAssetAddress (
213+ route . asset ,
214+ route . origin ,
215+ route . destination ,
216+ this . chains ,
217+ this . logger ,
218+ ) ;
199219 if ( ! l1Token ) {
200220 throw new Error ( `No L1 token mapping found for ${ route . asset } on chain ${ route . destination } ` ) ;
201221 }
@@ -235,6 +255,10 @@ export class ZircuitNativeBridgeAdapter implements BridgeAdapter {
235255 ) : Promise < boolean > {
236256 try {
237257 const isL1ToL2 = route . origin === ETHEREUM_CHAIN_ID && route . destination === ZIRCUIT_CHAIN_ID ;
258+ const isL2ToL1 = route . origin === ZIRCUIT_CHAIN_ID && route . destination === ETHEREUM_CHAIN_ID ;
259+ if ( ! isL1ToL2 && ! isL2ToL1 ) {
260+ throw new Error ( `Unsupported Zircuit route: ${ route . origin } ->${ route . destination } ` ) ;
261+ }
238262
239263 if ( isL1ToL2 ) {
240264 // L1→L2: Auto-relayed by the sequencer
@@ -279,11 +303,7 @@ export class ZircuitNativeBridgeAdapter implements BridgeAdapter {
279303 args : [ withdrawalHash ] ,
280304 } ) ;
281305
282- const [ outputRoot , timestamp , l2OutputIndex ] = provenWithdrawal as [
283- `0x${string } `,
284- bigint ,
285- bigint ,
286- ] ;
306+ const [ , timestamp ] = provenWithdrawal as [ `0x${string } `, bigint , bigint ] ;
287307
288308 if ( timestamp > 0 ) {
289309 // Withdrawal is proven, check if challenge period has passed
@@ -339,7 +359,11 @@ export class ZircuitNativeBridgeAdapter implements BridgeAdapter {
339359 originTransaction : TransactionReceipt ,
340360 ) : Promise < MemoizedTransactionRequest | void > {
341361 try {
362+ const isL1ToL2 = route . origin === ETHEREUM_CHAIN_ID && route . destination === ZIRCUIT_CHAIN_ID ;
342363 const isL2ToL1 = route . origin === ZIRCUIT_CHAIN_ID && route . destination === ETHEREUM_CHAIN_ID ;
364+ if ( ! isL1ToL2 && ! isL2ToL1 ) {
365+ throw new Error ( `Unsupported Zircuit route: ${ route . origin } ->${ route . destination } ` ) ;
366+ }
343367
344368 if ( isL2ToL1 ) {
345369 const l1Client = await this . getClient ( ETHEREUM_CHAIN_ID ) ;
@@ -378,11 +402,7 @@ export class ZircuitNativeBridgeAdapter implements BridgeAdapter {
378402 args : [ withdrawalHash ] ,
379403 } ) ;
380404
381- const [ outputRoot , timestamp , l2OutputIndex ] = provenWithdrawal as [
382- `0x${string } `,
383- bigint ,
384- bigint ,
385- ] ;
405+ const [ , timestamp ] = provenWithdrawal as [ `0x${string } `, bigint , bigint ] ;
386406
387407 if ( timestamp > 0 ) {
388408 // Withdrawal is proven, check if we can finalize
@@ -459,6 +479,10 @@ export class ZircuitNativeBridgeAdapter implements BridgeAdapter {
459479
460480 async isCallbackComplete ( route : RebalanceRoute , originTransaction : TransactionReceipt ) : Promise < boolean > {
461481 const isL1ToL2 = route . origin === ETHEREUM_CHAIN_ID && route . destination === ZIRCUIT_CHAIN_ID ;
482+ const isL2ToL1 = route . origin === ZIRCUIT_CHAIN_ID && route . destination === ETHEREUM_CHAIN_ID ;
483+ if ( ! isL1ToL2 && ! isL2ToL1 ) {
484+ throw new Error ( `Unsupported Zircuit route: ${ route . origin } ->${ route . destination } ` ) ;
485+ }
462486 if ( isL1ToL2 ) {
463487 return true ;
464488 }
@@ -546,10 +570,14 @@ export class ZircuitNativeBridgeAdapter implements BridgeAdapter {
546570
547571 private hashWithdrawal ( tx : WithdrawalTransaction ) : `0x${string } ` {
548572 return keccak256 (
549- encodeAbiParameters (
550- parseAbiParameters ( 'uint256, address, address, uint256, uint256, bytes' ) ,
551- [ tx . nonce , tx . sender , tx . target , tx . value , tx . gasLimit , tx . data ] ,
552- ) ,
573+ encodeAbiParameters ( parseAbiParameters ( 'uint256, address, address, uint256, uint256, bytes' ) , [
574+ tx . nonce ,
575+ tx . sender ,
576+ tx . target ,
577+ tx . value ,
578+ tx . gasLimit ,
579+ tx . data ,
580+ ] ) ,
553581 ) ;
554582 }
555583
@@ -564,21 +592,22 @@ export class ZircuitNativeBridgeAdapter implements BridgeAdapter {
564592 l2Client : PublicClient ,
565593 l1Client : PublicClient ,
566594 originTransaction : TransactionReceipt ,
567- ) : Promise <
568- | {
569- l2OutputIndex : bigint ;
570- outputRootProof : OutputRootProof ;
571- withdrawalProof : `0x${string } `[ ] ;
572- }
573- | undefined
574- > {
595+ ) : Promise < ZircuitProofResult | undefined > {
575596 try {
576- // eslint-disable-next-line @typescript-eslint/no-explicit-any
577- const result = await buildProveZircuitWithdrawal ( l2Client as any , {
597+ const buildProof = buildProveZircuitWithdrawal as unknown as (
598+ l2Client : PublicClient ,
599+ params : {
600+ receipt : TransactionReceipt ;
601+ l1Client : PublicClient ;
602+ l2OutputOracleAddress : `0x${string } `;
603+ } ,
604+ ) => Promise < ZircuitProofResult > ;
605+
606+ const result = await buildProof ( l2Client , {
578607 receipt : originTransaction ,
579- l1Client : l1Client as any ,
608+ l1Client,
580609 l2OutputOracleAddress : ZIRCUIT_L2_OUTPUT_ORACLE as `0x${string } `,
581- } as any ) ;
610+ } ) ;
582611
583612 this . logger . info ( 'Zircuit proof built successfully' , {
584613 txHash : originTransaction . transactionHash ,
@@ -591,9 +620,9 @@ export class ZircuitNativeBridgeAdapter implements BridgeAdapter {
591620 } ) ;
592621
593622 return {
594- l2OutputIndex : result . l2OutputIndex as bigint ,
595- outputRootProof : result . outputRootProof as OutputRootProof ,
596- withdrawalProof : result . withdrawalProof as `0x${ string } ` [ ] ,
623+ l2OutputIndex : result . l2OutputIndex ,
624+ outputRootProof : result . outputRootProof ,
625+ withdrawalProof : result . withdrawalProof ,
597626 } ;
598627 } catch ( error ) {
599628 this . logger . warn ( 'Failed to build Zircuit withdrawal proof' , {
0 commit comments