1+ import * as fs from "fs-extra"
2+ import { utils , Wallet , Provider , EIP712Signer , types , Contract , ContractFactory } from "zksync-ethers"
3+ import * as ethers from "ethers"
4+ import "dotenv/config"
5+
6+ const ZK_MINIMAL_ADDRESS = "0x7653816f9a95083b726F30ACf6bAb6c6A20447F4"
7+
8+ const RANDOM_APPROVER = "0x7653816f9a95083b726F30ACf6bAb6c6A20447F4"
9+
10+ const USDC_ZKSYNC = "0x7653816f9a95083b726F30ACf6bAb6c6A20447F4"
11+
12+
13+ const AMOUNT_TO_APPROVE = "1000000"
14+
15+ async function main ( ) {
16+ console . log ( "Let's do this!" )
17+
18+ let provider = new Provider ( process . env . ZKSYNC_SEPOLIA_RPC_URL ! )
19+ const encryptedJson = fs . readFileSync ( ".encryptedKey.json" , "utf8" )
20+ let wallet = Wallet . fromEncryptedJsonSync (
21+ encryptedJson ,
22+ process . env . PRIVATE_KEY_PASSWORD !
23+ )
24+
25+ wallet = wallet . connect ( provider )
26+
27+ const abi = JSON . parse ( fs . readFileSync ( "./out/ZkMinimalAccount.sol/ZkMinimalAccount.json" , "utf8" ) ) [ "abi" ]
28+ console . log ( "Setting up contract details..." )
29+ const zkMinimalAccount = new Contract ( ZK_MINIMAL_ADDRESS , abi , provider )
30+
31+ // If this doesn't log the owner, you have an issue!
32+ console . log ( `The owner of this minimal account is: ` , await zkMinimalAccount . owner ( ) )
33+ const usdcAbi = JSON . parse ( fs . readFileSync ( "./out/ERC20/IERC20.sol/IERC20.json" , "utf8" ) ) [ "abi" ]
34+ const usdcContract = new Contract ( USDC_ZKSYNC , usdcAbi , provider )
35+
36+ console . log ( "Populating transaction..." )
37+ let approvalData = await usdcContract . approve . populateTransaction (
38+ RANDOM_APPROVER ,
39+ AMOUNT_TO_APPROVE
40+ )
41+
42+ let aaTx = approvalData
43+
44+ const gasLimit = await provider . estimateGas ( {
45+ ...aaTx ,
46+ from : wallet . address ,
47+ } )
48+ const gasPrice = ( await provider . getFeeData ( ) ) . gasPrice !
49+
50+ aaTx = {
51+ ...aaTx ,
52+ from : ZK_MINIMAL_ADDRESS ,
53+ gasLimit : gasLimit ,
54+ gasPrice : gasPrice ,
55+ chainId : ( await provider . getNetwork ( ) ) . chainId ,
56+ nonce : await provider . getTransactionCount ( ZK_MINIMAL_ADDRESS ) ,
57+ type : 113 ,
58+ customData : {
59+ gasPerPubdata : utils . DEFAULT_GAS_PER_PUBDATA_LIMIT ,
60+ } as types . Eip712Meta ,
61+ value : 0n ,
62+ }
63+ const signedTxHash = EIP712Signer . getSignedDigest ( aaTx )
64+
65+ console . log ( "Signing transaction..." )
66+ const signature = ethers . concat ( [
67+ ethers . Signature . from ( wallet . signingKey . sign ( signedTxHash ) ) . serialized ,
68+ ] )
69+ console . log ( signature )
70+
71+ aaTx . customData = {
72+ ...aaTx . customData ,
73+ customSignature : signature ,
74+ }
75+
76+ console . log (
77+ `The minimal account nonce before the first tx is ${ await provider . getTransactionCount (
78+ ZK_MINIMAL_ADDRESS ,
79+ ) } `,
80+ )
81+
82+ const sentTx = await provider . broadcastTransaction (
83+ types . Transaction . from ( aaTx ) . serialized ,
84+ )
85+
86+ console . log ( `Transaction sent from minimal account with hash ${ sentTx . hash } ` )
87+ await sentTx . wait ( )
88+
89+ // Checking that the nonce for the account has increased
90+ console . log (
91+ `The account's nonce after the first tx is ${ await provider . getTransactionCount (
92+ ZK_MINIMAL_ADDRESS ,
93+ ) } `,
94+ )
95+ }
96+
97+ main ( )
98+ . then ( ( ) => process . exit ( 0 ) )
99+ . catch ( ( error ) => {
100+ console . error ( error )
101+ process . exit ( 1 )
102+ } )
0 commit comments