1
+ import { readContract , writeContract } from "@wagmi/core" ;
2
+ import { zeroAddress , type Address , type Hash } from "viem" ;
3
+ import { L1Signer } from "zksync-ethers" ;
4
+ import { getERC20DefaultBridgeData , REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT } from "zksync-ethers/build/utils" ;
5
+
1
6
import { useSentryLogger } from "@/composables/useSentryLogger" ;
7
+ import { L1_BRIDGE_ABI } from "@/data/abis/l1BridgeAbi" ;
8
+ import { wagmiConfig } from "@/data/wagmi" ;
2
9
3
10
import type { DepositFeeValues } from "@/composables/zksync/deposit/useFee" ;
4
11
import type { BigNumberish } from "ethers" ;
5
- import type { L1Signer } from "zksync-ethers" ;
6
12
7
13
export default ( getL1Signer : ( ) => Promise < L1Signer | undefined > ) => {
8
14
const status = ref < "not-started" | "processing" | "waiting-for-signature" | "done" > ( "not-started" ) ;
9
15
const error = ref < Error | undefined > ( ) ;
10
- const ethTransactionHash = ref < string | undefined > ( ) ;
16
+ const ethTransactionHash = ref < Hash | undefined > ( ) ;
11
17
const eraWalletStore = useZkSyncWalletStore ( ) ;
12
18
const { captureException } = useSentryLogger ( ) ;
13
19
14
20
const { validateAddress } = useScreening ( ) ;
15
21
22
+ const handleCustomBridgeDeposit = async (
23
+ transaction : {
24
+ to : Address ;
25
+ tokenAddress : Address ;
26
+ amount : BigNumberish ;
27
+ bridgeAddress : Address ;
28
+ gasPerPubdata ?: bigint ;
29
+ l2GasLimit ?: bigint ;
30
+ refundRecipient ?: Address ;
31
+ } ,
32
+ fee : DepositFeeValues
33
+ ) => {
34
+ const l1Signer = await getL1Signer ( ) ;
35
+ if ( ! l1Signer ) throw new Error ( "L1 signer is not available" ) ;
36
+
37
+ const l2BridgeAddress = await readContract ( wagmiConfig , {
38
+ address : transaction . bridgeAddress as Address ,
39
+ abi : L1_BRIDGE_ABI ,
40
+ functionName : "l2Bridge" ,
41
+ } ) ;
42
+ const bridgeData = await getERC20DefaultBridgeData ( transaction . tokenAddress , l1Signer . provider ) ;
43
+
44
+ const gasPerPubdata = transaction . gasPerPubdata ?? BigInt ( REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT ) ;
45
+ const l2Value = 0n ; // L2 value is not used in this context
46
+ const l2GasLimit = await l1Signer . providerL2 . estimateCustomBridgeDepositL2Gas (
47
+ transaction . bridgeAddress ,
48
+ l2BridgeAddress ,
49
+ transaction . tokenAddress ,
50
+ transaction . amount . toString ( ) ,
51
+ transaction . to ,
52
+ bridgeData ,
53
+ l1Signer . address ,
54
+ gasPerPubdata ,
55
+ l2Value
56
+ ) ;
57
+
58
+ const baseCost = await l1Signer . getBaseCost ( {
59
+ gasLimit : l2GasLimit ,
60
+ gasPerPubdataByte : gasPerPubdata ,
61
+ } ) ;
62
+
63
+ const overrides = {
64
+ gasPrice : fee . gasPrice ,
65
+ gasLimit : fee . l1GasLimit ,
66
+ maxFeePerGas : fee . maxFeePerGas ,
67
+ maxPriorityFeePerGas : fee . maxPriorityFeePerGas ,
68
+ } ;
69
+ if ( overrides . gasPrice && overrides . maxFeePerGas ) {
70
+ overrides . gasPrice = undefined ;
71
+ }
72
+
73
+ const hash = await writeContract ( wagmiConfig , {
74
+ address : transaction . bridgeAddress as Address ,
75
+ abi : L1_BRIDGE_ABI ,
76
+ functionName : "deposit" ,
77
+ args : [
78
+ transaction . to ,
79
+ transaction . tokenAddress ,
80
+ BigInt ( transaction . amount . toString ( ) ) ,
81
+ transaction . l2GasLimit ?? 400000n ,
82
+ gasPerPubdata ,
83
+ transaction . refundRecipient ?? zeroAddress ,
84
+ ] ,
85
+ value : baseCost + ( overrides . maxPriorityFeePerGas ? BigInt ( overrides . maxPriorityFeePerGas ) : 0n ) ,
86
+ } ) ;
87
+
88
+ return {
89
+ from : l1Signer . address ,
90
+ to : transaction . to ,
91
+ hash,
92
+ // eslint-disable-next-line require-await
93
+ wait : async ( ) => ( {
94
+ from : l1Signer . address ,
95
+ to : transaction . to ,
96
+ hash,
97
+ } ) ,
98
+ } ;
99
+ } ;
100
+
16
101
const commitTransaction = async (
17
102
transaction : {
18
- to : string ;
19
- tokenAddress : string ;
103
+ to : Address ;
104
+ tokenAddress : Address ;
20
105
amount : BigNumberish ;
106
+ bridgeAddress ?: Address ;
21
107
} ,
22
108
fee : DepositFeeValues
23
109
) => {
@@ -42,18 +128,29 @@ export default (getL1Signer: () => Promise<L1Signer | undefined>) => {
42
128
}
43
129
44
130
status . value = "waiting-for-signature" ;
45
- const depositResponse = await wallet . deposit ( {
46
- to : transaction . to ,
47
- token : transaction . tokenAddress ,
48
- amount : transaction . amount ,
49
- l2GasLimit : fee . l2GasLimit ,
50
- approveBaseERC20 : true ,
51
- overrides,
52
- } ) ;
53
131
54
- ethTransactionHash . value = depositResponse . hash ;
55
- status . value = "done" ;
56
- return depositResponse ;
132
+ if ( transaction . bridgeAddress ) {
133
+ const depositResponse = await handleCustomBridgeDeposit (
134
+ { ...transaction , bridgeAddress : transaction . bridgeAddress } ,
135
+ fee
136
+ ) ;
137
+ ethTransactionHash . value = depositResponse . hash ;
138
+ status . value = "done" ;
139
+ return depositResponse ;
140
+ } else {
141
+ const depositResponse = await wallet . deposit ( {
142
+ to : transaction . to ,
143
+ token : transaction . tokenAddress ,
144
+ amount : transaction . amount ,
145
+ l2GasLimit : fee . l2GasLimit ,
146
+ approveBaseERC20 : true ,
147
+ overrides,
148
+ } ) ;
149
+
150
+ ethTransactionHash . value = depositResponse . hash as Hash ;
151
+ status . value = "done" ;
152
+ return depositResponse ;
153
+ }
57
154
} catch ( err ) {
58
155
error . value = formatError ( err as Error ) ;
59
156
status . value = "not-started" ;
0 commit comments