11import type { Request , Response } from "express" ;
2- import { type Address , createPublicClient , createWalletClient , type Hex , http } from "viem" ;
2+ import { type Address , createPublicClient , createWalletClient , type Hex , http , parseEther } from "viem" ;
33import { privateKeyToAccount } from "viem/accounts" ;
44import { waitForTransactionReceipt } from "viem/actions" ;
55import { getAccountAddressFromLogs , prepareDeploySmartAccount } from "zksync-sso-4337/client" ;
66
7- import { env , EOA_VALIDATOR_ADDRESS , FACTORY_ADDRESS , getChain , SESSION_VALIDATOR_ADDRESS , WEBAUTHN_VALIDATOR_ADDRESS } from "../config.js" ;
7+ import { env , EOA_VALIDATOR_ADDRESS , FACTORY_ADDRESS , getChain , prividiumConfig , SESSION_VALIDATOR_ADDRESS , WEBAUTHN_VALIDATOR_ADDRESS } from "../config.js" ;
88import { deployAccountSchema } from "../schemas.js" ;
9+ import { addAddressToUser , createProxyTransport , getAdminAuthService , whitelistContract } from "../services/prividium/index.js" ;
910
1011type DeployAccountRequest = {
1112 chainId : number ;
@@ -14,7 +15,6 @@ type DeployAccountRequest = {
1415 originDomain : string ;
1516 userId ?: string ;
1617 eoaSigners ?: Address [ ] ;
17- paymaster ?: Address ;
1818} ;
1919
2020// Deploy account endpoint
@@ -34,25 +34,46 @@ export const deployAccountHandler = async (req: Request, res: Response): Promise
3434 // Get chain from request
3535 const chain = getChain ( body . chainId ) ;
3636
37+ // Get admin token if in Prividium mode (needed for RPC proxy, whitelisting, and address association)
38+ let adminToken : string | undefined ;
39+ if ( prividiumConfig . enabled && req . prividiumUser ) {
40+ try {
41+ const adminAuth = getAdminAuthService ( prividiumConfig ) ;
42+ adminToken = await adminAuth . getValidToken ( ) ;
43+ } catch ( error ) {
44+ console . error ( "Admin authentication failed:" , error ) ;
45+ res . status ( 500 ) . json ( {
46+ error : "Admin authentication failed" ,
47+ } ) ;
48+ return ;
49+ }
50+ }
51+
52+ // Create transport - use Prividium proxy if enabled, otherwise direct RPC
53+ const transport = prividiumConfig . enabled && adminToken
54+ ? createProxyTransport ( prividiumConfig . proxyUrl , adminToken )
55+ : http ( env . RPC_URL ) ;
56+
3757 // Create clients
3858 const publicClient = createPublicClient ( {
3959 chain,
40- transport : http ( env . RPC_URL ) ,
60+ transport,
4161 } ) ;
4262
4363 const deployerAccount = privateKeyToAccount ( env . DEPLOYER_PRIVATE_KEY as Hex ) ;
4464 const walletClient = createWalletClient ( {
4565 account : deployerAccount ,
4666 chain,
47- transport : http ( env . RPC_URL ) ,
67+ transport,
4868 } ) ;
4969
5070 // Check deployer balance
5171 const balance = await publicClient . getBalance ( { address : deployerAccount . address } ) ;
52- const minBalance = BigInt ( "100000000000000000 ") ; // 0.1 ETH minimum
72+ const minBalance = parseEther ( "0.01 ") ; // Minimum balance required for deployment
5373 if ( balance < minBalance ) {
74+ console . error ( `Deployer balance too low: ${ balance . toString ( ) } < ${ minBalance . toString ( ) } ` ) ;
5475 res . status ( 500 ) . json ( {
55- error : `Insufficient balance to cover deployment. Current: ${ balance . toString ( ) } , Required: ${ minBalance . toString ( ) } ` ,
76+ error : "Deployer doesn't have enough balance to cover deployment" ,
5677 } ) ;
5778 return ;
5879 }
@@ -82,17 +103,11 @@ export const deployAccountHandler = async (req: Request, res: Response): Promise
82103 // Send transaction
83104 let txHash : Hex ;
84105 try {
85- const txParams : any = {
106+ const txParams = {
86107 to : transaction . to ,
87108 data : transaction . data ,
88109 } ;
89110
90- // Add paymaster if provided
91- if ( body . paymaster ) {
92- txParams . paymaster = body . paymaster ;
93- txParams . paymasterInput = "0x" ;
94- }
95-
96111 txHash = await walletClient . sendTransaction ( txParams ) ;
97112 } catch ( error ) {
98113 console . error ( "Transaction send failed:" , error ) ;
@@ -104,7 +119,7 @@ export const deployAccountHandler = async (req: Request, res: Response): Promise
104119 return ;
105120 }
106121 res . status ( 500 ) . json ( {
107- error : `Transaction failed: ${ errorMessage } ` ,
122+ error : "Internal server error" ,
108123 } ) ;
109124 return ;
110125 }
@@ -119,17 +134,16 @@ export const deployAccountHandler = async (req: Request, res: Response): Promise
119134 } ) ;
120135 } catch ( error ) {
121136 console . error ( "Transaction receipt failed:" , error ) ;
122- const errorMessage = error instanceof Error ? error . message : "Unknown error" ;
123137 res . status ( 500 ) . json ( {
124- error : `Transaction failed to be mined: ${ errorMessage } ` ,
138+ error : "Internal server error" ,
125139 } ) ;
126140 return ;
127141 }
128142
129143 // Check if transaction was successful
130144 if ( receipt . status === "reverted" ) {
131145 res . status ( 500 ) . json ( {
132- error : "Deployment reverted: Transaction execution failed " ,
146+ error : "Deployment reverted" ,
133147 } ) ;
134148 return ;
135149 }
@@ -140,22 +154,55 @@ export const deployAccountHandler = async (req: Request, res: Response): Promise
140154 deployedAddress = getAccountAddressFromLogs ( receipt . logs ) ;
141155 } catch ( error ) {
142156 console . error ( "Failed to extract address from logs:" , error ) ;
143- const errorMessage = error instanceof Error ? error . message : "" ;
144157 res . status ( 500 ) . json ( {
145- error : `Deployment failed: Could not extract account address from logs. ${ errorMessage } ` ,
158+ error : "Internal server error" ,
146159 } ) ;
147160 return ;
148161 }
149162
150163 console . log ( "Account deployed at:" , deployedAddress ) ;
151164
165+ // Prividium post-deployment steps (all blocking)
166+ if ( prividiumConfig . enabled && req . prividiumUser && adminToken ) {
167+ // Step 1: Whitelist the contract with template (blocking)
168+ try {
169+ await whitelistContract (
170+ deployedAddress ,
171+ prividiumConfig . templateKey ,
172+ adminToken ,
173+ prividiumConfig . permissionsApiUrl ,
174+ ) ;
175+ } catch ( error ) {
176+ console . error ( "Failed to whitelist contract:" , error ) ;
177+ res . status ( 500 ) . json ( {
178+ error : "Failed to whitelist contract" ,
179+ } ) ;
180+ return ;
181+ }
182+
183+ // Step 2: Associate address with user (blocking)
184+ try {
185+ await addAddressToUser (
186+ req . prividiumUser . userId ,
187+ [ deployedAddress ] ,
188+ adminToken ,
189+ prividiumConfig . permissionsApiUrl ,
190+ ) ;
191+ } catch ( error ) {
192+ console . error ( "Failed to associate address with user:" , error ) ;
193+ res . status ( 500 ) . json ( {
194+ error : "Failed to associate address with user" ,
195+ } ) ;
196+ return ;
197+ }
198+ }
199+
152200 // Return success response
153201 res . json ( { address : deployedAddress } ) ;
154202 } catch ( error ) {
155203 console . error ( "Deployment error:" , error ) ;
156- const errorMessage = error instanceof Error ? error . message : "Unknown error" ;
157204 res . status ( 500 ) . json ( {
158- error : `Deployment failed: ${ errorMessage } ` ,
205+ error : "Internal server error" ,
159206 } ) ;
160207 }
161208} ;
0 commit comments