diff --git a/.gitignore b/.gitignore index 136496c..ab4e8fc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ .idea delete-me -test/testfiles/token.json \ No newline at end of file +test/token.json \ No newline at end of file diff --git a/scripts/wait.go b/scripts/wait.go deleted file mode 100644 index 4a5aa62..0000000 --- a/scripts/wait.go +++ /dev/null @@ -1,33 +0,0 @@ -package main - -import ( - "context" - "fmt" - "github.com/zksync-sdk/zksync2-go/clients" - "log" - "time" -) - -const maxAttempts = 30 - -func main() { - nodeURL := "http://localhost:3050" - client, err := clients.Dial(nodeURL) - if err != nil { - log.Fatal(err) - } - defer client.Close() - - for i := 0; i < maxAttempts; i++ { - _, err := client.NetworkID(context.Background()) - if err == nil { - fmt.Println("Node is ready to receive traffic.") - return - } - - fmt.Println("Node not ready yet. Retrying...") - time.Sleep(20 * time.Second) - } - - log.Fatal("Maximum retries exceeded.") -} diff --git a/test/setup_test.go b/test/setup_test.go index 2d2a576..e8649e8 100644 --- a/test/setup_test.go +++ b/test/setup_test.go @@ -15,6 +15,7 @@ import ( "math/big" "os" "testing" + "time" ) const TokenPath = "./token.json" @@ -191,7 +192,32 @@ func createTokenL2(wallet *accounts.Wallet, client clients.Client, ethClient *et return tokenL2Address, tx.Hash(), l2Tx.Hash } +func wait() { + const maxAttempts = 30 + + nodeURL := "http://localhost:3050" + client, err := clients.Dial(nodeURL) + if err != nil { + log.Fatal(err) + } + defer client.Close() + + for i := 0; i < maxAttempts; i++ { + _, err := client.NetworkID(context.Background()) + if err == nil { + log.Println("Node is ready to receive traffic.") + return + } + + log.Println("Node not ready yet. Retrying...") + time.Sleep(20 * time.Second) + } + + log.Fatal("Maximum retries exceeded.") +} + func TestMain(m *testing.M) { + wait() client, err := clients.Dial(ZkSyncEraProvider) if err != nil { diff --git a/test/testfiles/Demo.zbin b/test/testfiles/Demo.zbin new file mode 100644 index 0000000..dfab04a Binary files /dev/null and b/test/testfiles/Demo.zbin differ diff --git a/test/testfiles/Foo.zbin b/test/testfiles/Foo.zbin new file mode 100644 index 0000000..550a9af Binary files /dev/null and b/test/testfiles/Foo.zbin differ diff --git a/test/testfiles/Incrementer.zbin b/test/testfiles/Incrementer.zbin new file mode 100644 index 0000000..e886dfa Binary files /dev/null and b/test/testfiles/Incrementer.zbin differ diff --git a/test/testfiles/Storage.zbin b/test/testfiles/Storage.zbin new file mode 100644 index 0000000..79caf2f Binary files /dev/null and b/test/testfiles/Storage.zbin differ diff --git a/test/wallet_test.go b/test/wallet_test.go index 7dff4dd..e3394f1 100644 --- a/test/wallet_test.go +++ b/test/wallet_test.go @@ -11,6 +11,7 @@ import ( "github.com/zksync-sdk/zksync2-go/contracts/erc20" "github.com/zksync-sdk/zksync2-go/utils" "math/big" + "os" "testing" ) @@ -272,203 +273,178 @@ func TestIntegrationWallet_DepositToken(t *testing.T) { assert.True(t, new(big.Int).Sub(l1BalanceBeforeDeposit, l1BalanceAfterDeposit).Cmp(amount) >= 0, "Balance on L1 should be decreased") } -func TestIntegrationWallet_EstimateGasDeposit(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") -} +func TestIntegrationWallet_Withdraw(t *testing.T) { + amount := big.NewInt(7_000_000_000) -func TestIntegrationWallet_FullRequiredDepositFee(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") -} + client, err := clients.Dial(ZkSyncEraProvider) + defer client.Close() + assert.NoError(t, err, "clients.Dial should not return an error") -func TestIntegrationWallet_IsWithdrawFinalized(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") -} + ethClient, err := ethclient.Dial(EthereumProvider) + assert.NoError(t, err, "ethclient.Dial should not return an error") + defer ethClient.Close() -// WRITE NEGATIVE TEST -func TestIntegrationWallet_ClaimFailedDeposit(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") -} + wallet, err := accounts.NewWallet(common.Hex2Bytes(PrivateKey), &client, ethClient) + assert.NoError(t, err, "NewWallet should not return an error") -func TestIntegrationWallet_RequestExecute(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") -} + l2BalanceBeforeWithdrawal, err := wallet.Balance(context.Background(), utils.EthAddress, nil) + assert.NoError(t, err, "Balance should not return an error") -func TestIntegrationWallet_EstimateGasRequestExecute(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") -} + //l1BalanceBeforeWithdrawal, err := wallet.BalanceL1(nil, l1TokenAddress) + //assert.NoError(t, err, "BalanceL1 should not return an error") -func TestIntegrationWallet_Address(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") -} + tx, err := wallet.Withdraw(nil, accounts.WithdrawalTransaction{ + To: wallet.Address(), + Amount: amount, + Token: utils.EthAddress, + }) + assert.NoError(t, err, "Withdraw should not return an error") -func TestIntegrationWallet_Signer(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") -} + receipt, err := client.WaitMined(context.Background(), tx.Hash()) + assert.NoError(t, err, "client.WaitMined should not return an error") + assert.NotNil(t, receipt.BlockHash, "Transaction should be mined") -func TestIntegrationWallet_Balance(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") -} + l2BalanceAfterWithdrawal, err := wallet.Balance(context.Background(), utils.EthAddress, nil) + assert.NoError(t, err, "Balance should not return an error") -func TestIntegrationWallet_AllBalances(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") -} + //l1BalanceAfterWithdrawal, err := wallet.BalanceL1(nil, l1TokenAddress) + //assert.NoError(t, err, "BalanceL1 should not return an error") -func TestIntegrationWallet_L2BridgeContracts(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") + assert.True(t, new(big.Int).Sub(l2BalanceBeforeWithdrawal, l2BalanceAfterWithdrawal).Cmp(amount) >= 0, "Balance on L2 should be decreased") + //assert.True(t, new(big.Int).Sub(l1BalanceBeforeDeposit, l1BalanceAfterDeposit).Cmp(amount) >= 0, "Balance on L1 should be decreased") } -func TestIntegrationWallet_Withdraw(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") -} +func TestIntegrationWallet_WithdrawToken(t *testing.T) { + tokenData := readToken() + amount := big.NewInt(5) + //l1TokenAddress := common.HexToAddress(tokenData.L1Address) + l2TokenAddress := common.HexToAddress(tokenData.L2Address) -func TestIntegrationWallet_EstimateGasWithdraw(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") + client, err := clients.Dial(ZkSyncEraProvider) + defer client.Close() + assert.NoError(t, err, "clients.Dial should not return an error") + + ethClient, err := ethclient.Dial(EthereumProvider) + assert.NoError(t, err, "ethclient.Dial should not return an error") + defer ethClient.Close() + + wallet, err := accounts.NewWallet(common.Hex2Bytes(PrivateKey), &client, ethClient) + assert.NoError(t, err, "NewWallet should not return an error") + + l2BalanceBeforeWithdrawal, err := wallet.Balance(context.Background(), l2TokenAddress, nil) + assert.NoError(t, err, "Balance should not return an error") + + //l1BalanceBeforeWithdrawal, err := wallet.BalanceL1(nil, l1TokenAddress) + //assert.NoError(t, err, "BalanceL1 should not return an error") + + tx, err := wallet.Withdraw(nil, accounts.WithdrawalTransaction{ + To: wallet.Address(), + Amount: amount, + Token: l2TokenAddress, + }) + assert.NoError(t, err, "Withdraw should not return an error") + + receipt, err := client.WaitMined(context.Background(), tx.Hash()) + assert.NoError(t, err, "client.WaitMined should not return an error") + assert.NotNil(t, receipt.BlockHash, "Transaction should be mined") + + l2BalanceAfterWithdrawal, err := wallet.Balance(context.Background(), l2TokenAddress, nil) + assert.NoError(t, err, "Balance should not return an error") + + //l1BalanceAfterWithdrawal, err := wallet.BalanceL1(nil, l1TokenAddress) + //assert.NoError(t, err, "BalanceL1 should not return an error") + + assert.True(t, new(big.Int).Sub(l2BalanceBeforeWithdrawal, l2BalanceAfterWithdrawal).Cmp(amount) >= 0, "Balance on L2 should be decreased") + //assert.True(t, new(big.Int).Sub(l1BalanceBeforeDeposit, l1BalanceAfterDeposit).Cmp(amount) >= 0, "Balance on L1 should be decreased") } func TestIntegrationWallet_Transfer(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") -} + amount := big.NewInt(7_000_000_000) + receiver := common.HexToAddress(Receiver) -func TestIntegrationWallet_EstimateGasTransfer(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") -} + client, err := clients.Dial(ZkSyncEraProvider) + defer client.Close() + assert.NoError(t, err, "clients.Dial should not return an error") -func TestIntegrationWallet_CallContract(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") -} + ethClient, err := ethclient.Dial(EthereumProvider) + assert.NoError(t, err, "ethclient.Dial should not return an error") + defer ethClient.Close() + + wallet, err := accounts.NewWallet(common.Hex2Bytes(PrivateKey), &client, ethClient) + assert.NoError(t, err, "NewWallet should not return an error") + + balanceBeforeTransferSender, err := wallet.Balance(context.Background(), utils.EthAddress, nil) + assert.NoError(t, err, "Balance should not return an error") + + balanceBeforeTransferReceiver, err := client.BalanceAt(context.Background(), receiver, nil) + assert.NoError(t, err, "BalanceAt should not return an error") + + tx, err := wallet.Transfer(nil, accounts.TransferTransaction{ + To: receiver, + Amount: amount, + Token: utils.EthAddress, + }) + assert.NoError(t, err, "Transfer should not return an error") + + receipt, err := client.WaitMined(context.Background(), tx.Hash()) + assert.NoError(t, err, "client.WaitMined should not return an error") + assert.NotNil(t, receipt.BlockHash, "Transaction should be mined") + + balanceAfterTransferSender, err := wallet.Balance(context.Background(), utils.EthAddress, nil) + assert.NoError(t, err, "Balance should not return an error") + + balanceAfterTransferReceiver, err := wallet.BalanceL1(nil, utils.EthAddress) + assert.NoError(t, err, "BalanceL1 should not return an error") -func TestIntegrationWallet_PopulateTransaction(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") + assert.True(t, new(big.Int).Sub(balanceBeforeTransferSender, balanceAfterTransferSender).Cmp(amount) >= 0, "Sender balance should be decreased") + assert.True(t, new(big.Int).Sub(balanceAfterTransferReceiver, balanceBeforeTransferReceiver).Cmp(amount) >= 0, "Receiver balance should be increased") } -func TestIntegrationWallet_SignTransaction(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") +func TestIntegrationWallet_TransferToken(t *testing.T) { + tokenData := readToken() + amount := big.NewInt(5) + tokenAddress := common.HexToAddress(tokenData.L2Address) + receiver := common.HexToAddress(Receiver) + + client, err := clients.Dial(ZkSyncEraProvider) + defer client.Close() + assert.NoError(t, err, "clients.Dial should not return an error") + + ethClient, err := ethclient.Dial(EthereumProvider) + assert.NoError(t, err, "ethclient.Dial should not return an error") + defer ethClient.Close() + + wallet, err := accounts.NewWallet(common.Hex2Bytes(PrivateKey), &client, ethClient) + assert.NoError(t, err, "NewWallet should not return an error") + + tokenContract, err := erc20.NewIERC20(tokenAddress, client) + assert.NoError(t, err, "NewIERC20 should not return an error") + + balanceBeforeTransferSender, err := wallet.Balance(context.Background(), tokenAddress, nil) + assert.NoError(t, err, "Balance should not return an error") + + balanceBeforeTransferReceiver, err := tokenContract.BalanceOf(nil, receiver) + assert.NoError(t, err, "BalanceOf should not return an error") + + tx, err := wallet.Transfer(nil, accounts.TransferTransaction{ + To: receiver, + Amount: amount, + Token: tokenAddress, + }) + assert.NoError(t, err, "Transfer should not return an error") + + receipt, err := client.WaitMined(context.Background(), tx.Hash()) + assert.NoError(t, err, "client.WaitMined should not return an error") + assert.NotNil(t, receipt.BlockHash, "Transaction should be mined") + + balanceAfterTransferSender, err := wallet.Balance(context.Background(), tokenAddress, nil) + assert.NoError(t, err, "Balance should not return an error") + + balanceAfterTransferReceiver, err := tokenContract.BalanceOf(nil, receiver) + assert.NoError(t, err, "BalanceOf should not return an error") + + assert.True(t, new(big.Int).Sub(balanceBeforeTransferSender, balanceAfterTransferSender).Cmp(amount) >= 0, "Sender balance should be decreased") + assert.True(t, new(big.Int).Sub(balanceAfterTransferReceiver, balanceBeforeTransferReceiver).Cmp(amount) >= 0, "Receiver balance should be increased") } func TestIntegrationWallet_SendTransaction(t *testing.T) { @@ -500,46 +476,23 @@ func TestIntegrationWallet_SendTransaction(t *testing.T) { assert.NotNil(t, txReceipt.BlockHash, "Transaction should be mined") } -func TestIntegrationWallet_Deploy(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") -} - func TestIntegrationWallet_DeployWithCreate(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") -} + client, err := clients.Dial(ZkSyncEraProvider) + defer client.Close() + assert.NoError(t, err, "clients.Dial should not return an error") -func TestIntegrationWallet_DeployAccount(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") -} + wallet, err := accounts.NewWallet(common.Hex2Bytes(PrivateKey), &client, nil) + assert.NoError(t, err, "NewWallet should not return an error") + + bytecode, err := os.ReadFile("./testfiles/Storage.zbin") + assert.NoError(t, err, "ReadFile should not return an error") + + hash, err := wallet.DeployWithCreate(nil, accounts.CreateTransaction{Bytecode: bytecode}) + assert.NoError(t, err, "DeployWithCreate should not return an error") + + receipt, err := client.WaitMined(context.Background(), hash) + assert.NoError(t, err, "client.WaitMined should not return an error") -func TestIntegrationWallet_DeployAccountWithCreate(t *testing.T) { - //client, err := clients.Dial(ZkSyncEraProvider) - //defer client.Close() - //assert.NoError(t, err, "clients.Dial should not return an error") - // - //block, err := client.BlockByNumber(context.Background(), nil) - // - //assert.NoError(t, err, "BlockByNumber should not return an error") - //assert.NotNil(t, block, "BlockByNumber should return a non-nil block") + contractAddress := receipt.ContractAddress + assert.NotNil(t, contractAddress, "Contract should be deployed") }