1- import { useMemoize } from "@vueuse/core" ;
2- import { Wallet , typechain } from "zksync-ethers" ;
3- import IL1Nullifier from "zksync-ethers/abi/IL1Nullifier.json" ;
4-
5- import { L1_BRIDGE_ABI } from "@/data/abis/l1BridgeAbi" ;
6- import { customBridgeTokens } from "@/data/customBridgeTokens" ;
1+ import { createEthersClient , createEthersSdk } from "@dutterbutter/zksync-sdk/ethers" ;
72
83import { useSentryLogger } from "../useSentryLogger" ;
94
10- import type { Hash } from "@/types" ;
11- import type { Address } from "viem" ;
12- import type { FinalizeWithdrawalParams } from "zksync-ethers/build/types" ;
5+ import type { Hash } from "viem" ;
136
147export default ( transactionInfo : ComputedRef < TransactionInfo > ) => {
158 const status = ref < "not-started" | "processing" | "waiting-for-signature" | "sending" | "done" > ( "not-started" ) ;
169 const error = ref < Error | undefined > ( ) ;
1710 const transactionHash = ref < Hash | undefined > ( ) ;
1811 const onboardStore = useOnboardStore ( ) ;
19- const providerStore = useZkSyncProviderStore ( ) ;
2012 const walletStore = useZkSyncWalletStore ( ) ;
2113 const tokensStore = useZkSyncTokensStore ( ) ;
2214 const { isCorrectNetworkSet } = storeToRefs ( onboardStore ) ;
2315 const { ethToken } = storeToRefs ( tokensStore ) ;
2416 const { captureException } = useSentryLogger ( ) ;
2517
26- const retrieveBridgeAddresses = useMemoize ( ( ) =>
27- providerStore . requestProvider ( ) . then ( ( provider ) => provider . getDefaultBridgeAddresses ( ) )
28- ) ;
29- const retrieveL1NullifierAddress = useMemoize ( async ( ) => {
30- const providerL1 = await walletStore . getL1VoidSigner ( ) ;
31- return await typechain . IL1AssetRouter__factory . connect (
32- (
33- await retrieveBridgeAddresses ( )
34- ) . sharedL1 ,
35- providerL1
36- ) . L1_NULLIFIER ( ) ;
37- } ) ;
38-
3918 const gasLimit = ref < bigint | undefined > ( ) ;
4019 const gasPrice = ref < bigint | undefined > ( ) ;
41- const finalizeWithdrawalParams = ref < FinalizeWithdrawalParams | undefined > ( ) ;
4220
4321 const totalFee = computed ( ( ) => {
4422 if ( ! gasLimit . value || ! gasPrice . value ) return undefined ;
@@ -48,79 +26,6 @@ export default (transactionInfo: ComputedRef<TransactionInfo>) => {
4826 return ethToken . value ;
4927 } ) ;
5028
51- const getFinalizationParams = async ( ) => {
52- const provider = await providerStore . requestProvider ( ) ;
53- const wallet = new Wallet (
54- // random private key cause we don't care about actual signer
55- // finalizeWithdrawalParams method only exists on Wallet class
56- "0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110" ,
57- provider
58- ) ;
59- return await wallet . getFinalizeWithdrawalParams ( transactionInfo . value . transactionHash ) ;
60- } ;
61-
62- const getTransactionParams = async ( ) => {
63- finalizeWithdrawalParams . value = await getFinalizationParams ( ) ;
64- const provider = await providerStore . requestProvider ( ) ;
65- const chainId = BigInt ( await provider . getNetwork ( ) . then ( ( n ) => n . chainId ) ) ;
66- const p = finalizeWithdrawalParams . value ! ;
67-
68- // Check if this is a custom bridge withdrawal
69- // First check if the token already has the bridge address stored
70- let l1BridgeAddress = transactionInfo . value . token . l1BridgeAddress ;
71-
72- // If not, look it up from the custom bridge tokens configuration
73- if ( ! l1BridgeAddress ) {
74- const { eraNetwork } = storeToRefs ( providerStore ) ;
75-
76- const customBridgeToken = customBridgeTokens . find (
77- ( token ) =>
78- token . l2Address . toLowerCase ( ) === transactionInfo . value . token . address . toLowerCase ( ) &&
79- token . chainId === eraNetwork . value . l1Network ?. id
80- ) ;
81-
82- l1BridgeAddress = customBridgeToken ?. l1BridgeAddress ;
83- }
84-
85- const isCustomBridge = ! ! l1BridgeAddress ;
86-
87- if ( isCustomBridge ) {
88- // Use custom bridge finalization
89- return {
90- address : l1BridgeAddress as Address ,
91- abi : L1_BRIDGE_ABI ,
92- account : onboardStore . account . address ! ,
93- functionName : "finalizeWithdrawal" ,
94- args : [
95- BigInt ( p . l1BatchNumber ?? 0n ) ,
96- BigInt ( p . l2MessageIndex ) ,
97- Number ( p . l2TxNumberInBlock ) as number ,
98- p . message as Hash ,
99- p . proof as Hash [ ] ,
100- ] ,
101- } as const ;
102- } else {
103- // Use standard bridge finalization through L1Nullifier
104- const finalizeDepositParams = {
105- chainId : BigInt ( chainId ) ,
106- l2BatchNumber : BigInt ( p . l1BatchNumber ?? 0n ) ,
107- l2MessageIndex : BigInt ( p . l2MessageIndex ) ,
108- l2Sender : p . sender as Address ,
109- l2TxNumberInBatch : Number ( p . l2TxNumberInBlock ) ,
110- message : p . message as Hash ,
111- merkleProof : p . proof as Hash [ ] ,
112- } ;
113-
114- return {
115- address : ( await retrieveL1NullifierAddress ( ) ) as Hash ,
116- abi : IL1Nullifier ,
117- account : onboardStore . account . address ! ,
118- functionName : "finalizeDeposit" ,
119- args : [ finalizeDepositParams ] ,
120- } as const ;
121- }
122- } ;
123-
12429 const {
12530 inProgress : estimationInProgress ,
12631 error : estimationError ,
@@ -130,19 +35,23 @@ export default (transactionInfo: ComputedRef<TransactionInfo>) => {
13035 tokensStore . requestTokens ( ) ;
13136 const publicClient = onboardStore . getPublicClient ( ) ;
13237
133- const transactionParams = await getTransactionParams ( ) ;
13438 const [ price , limit ] = await Promise . all ( [
13539 retry ( async ( ) => BigInt ( ( await publicClient . getGasPrice ( ) ) . toString ( ) ) ) ,
13640 retry ( async ( ) => {
137- return BigInt ( ( await publicClient . estimateContractGas ( transactionParams as any ) ) . toString ( ) ) ;
41+ const signer = await walletStore . getL1VoidSigner ( true ) ;
42+ const client = createEthersClient ( { l1 : signer . provider , l2 : signer . providerL2 , signer } ) ;
43+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
44+ const sdk = createEthersSdk ( client ) ;
45+ // const estimation = await sdk.withdrawals.finalize
46+ // TODO: finish finalization gas estimation when available in SDK
47+ return BigInt ( 200_000_000 ) ; // Placeholder value
13848 } ) ,
13949 ] ) ;
14050
14151 gasPrice . value = price ;
14252 gasLimit . value = limit ;
14353
14454 return {
145- transactionParams,
14655 gasPrice : gasPrice . value ,
14756 gasLimit : gasLimit . value ,
14857 } ;
@@ -158,14 +67,15 @@ export default (transactionInfo: ComputedRef<TransactionInfo>) => {
15867 if ( ! isCorrectNetworkSet . value ) {
15968 await onboardStore . setCorrectNetwork ( ) ;
16069 }
161- const wallet = await onboardStore . getWallet ( ) ;
162- const { transactionParams, gasLimit, gasPrice } = ( await estimateFee ( ) ) ! ;
16370 status . value = "waiting-for-signature" ;
164- transactionHash . value = await wallet . writeContract ( {
165- ...( transactionParams as any ) ,
166- gasPrice : BigInt ( gasPrice . toString ( ) ) ,
167- gas : BigInt ( gasLimit . toString ( ) ) ,
168- } ) ;
71+ const signer = ( await walletStore . getL1Signer ( ) ) ! ;
72+ const client = createEthersClient ( { l1 : signer . provider , l2 : signer . providerL2 , signer } ) ;
73+ const sdk = createEthersSdk ( client ) ;
74+ const transaction = await sdk . withdrawals . finalize ( transactionInfo . value ! . transactionHash as Hash ) ;
75+ if ( ! transaction . receipt ) {
76+ throw new Error ( "Finalization transaction failed" ) ;
77+ }
78+ transactionHash . value = transaction . receipt ?. hash as Hash ;
16979
17080 status . value = "sending" ;
17181 const receipt = await retry ( ( ) =>
@@ -186,6 +96,8 @@ export default (transactionInfo: ComputedRef<TransactionInfo>) => {
18696 status . value = "done" ;
18797 return receipt ;
18898 } catch ( err ) {
99+ // eslint-disable-next-line no-console
100+ console . error ( err ) ;
189101 error . value = formatError ( err as Error ) ;
190102 status . value = "not-started" ;
191103 captureException ( {
0 commit comments