diff --git a/.github/workflows/app-e2e.yml b/.github/workflows/app-e2e.yml index 42842c52cd..5ca7ad825d 100644 --- a/.github/workflows/app-e2e.yml +++ b/.github/workflows/app-e2e.yml @@ -33,7 +33,7 @@ env: jobs: e2e: - runs-on: [self-hosted, ci-runner] + runs-on: [matterlabs-ci-runner] permissions: contents: read defaults: @@ -64,6 +64,12 @@ jobs: with: fetch-depth: 0 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: '18' + cache: 'npm' + - name: Cache node modules id: cache-nodemodules uses: actions/cache@v3 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 441cab4269..4c9060f634 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -55,7 +55,7 @@ jobs: deployBackendToStaging: name: Deploy Block Explorer backend to staging - runs-on: [self-hosted, ci-runner] + runs-on: [matterlabs-ci-runner] permissions: contents: read needs: createReleaseVersion diff --git a/docker-compose.yaml b/docker-compose.yaml index e6991b3d22..0c32b27bd3 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -26,6 +26,7 @@ services: - DATABASE_PASSWORD=postgres - DATABASE_NAME=block-explorer - BLOCKCHAIN_RPC_URL=http://zksync:3050 + - BATCHES_PROCESSING_POLLING_INTERVAL=1000 ports: - '3001:3001' - '9229:9229' diff --git a/packages/integration-tests/jest.config.json b/packages/integration-tests/jest.config.json index d6589b6ee7..6657349178 100644 --- a/packages/integration-tests/jest.config.json +++ b/packages/integration-tests/jest.config.json @@ -1,5 +1,6 @@ { "moduleFileExtensions": ["js", "json", "ts"], + "globalSetup": "/tests/hooks/global.ts", "rootDir": ".", "testEnvironment": "node", "testRegex": ".test.ts$", diff --git a/packages/integration-tests/package.json b/packages/integration-tests/package.json index 71f17b519a..24ee6ad63a 100644 --- a/packages/integration-tests/package.json +++ b/packages/integration-tests/package.json @@ -9,7 +9,7 @@ "license": "MIT", "scripts": { "postinstall": "cd src/playbook && npm install", - "integration-test:api": "jest --verbose --testPathPattern=tokens.test.ts && jest --verbose --testPathPattern=deposit.test.ts && jest --verbose --testPathPattern=common && jest --verbose --testPathPattern=transactions", + "integration-test:api": "jest --verbose", "integration-test:ui": "npx playwright test", "block-explorer:start": "docker-compose up", "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-pattern 'repos' --ignore-pattern 'git add .'" diff --git a/packages/integration-tests/src/config.ts b/packages/integration-tests/src/config.ts index 543bdd9509..ca7034d8ec 100644 --- a/packages/integration-tests/src/config.ts +++ b/packages/integration-tests/src/config.ts @@ -1,8 +1,8 @@ import { Wallets } from "./entities"; export const localConfig = { - gasLimit: { gasLimit: 8000000 }, - l2GasLimit: 8000000, + gasLimit: { gasLimit: 10000000 }, + l2GasLimit: 10000000, L1Network: "http://localhost:8545", L2Network: "http://localhost:3050", privateKey: Wallets.richWalletPrivateKey, diff --git a/packages/integration-tests/src/entities.ts b/packages/integration-tests/src/entities.ts index f0f4d545c5..4bf2a48e8a 100644 --- a/packages/integration-tests/src/entities.ts +++ b/packages/integration-tests/src/entities.ts @@ -19,6 +19,12 @@ export enum Buffer { txMultiCallCaller = "./buffer/txMultiCallCaller.txt", txMultiCallRoot = "./buffer/txmultiCallRoot.txt", txUseMultiCallContracts = "./buffer/txUseMultiCallContracts.txt", + txEthTransfer = "./buffer/txEthTransfer.txt", + txERC20Withdraw = "./buffer/txERC20Withdraw.txt", + txERC20WithdrawOtherAddress = "./buffer/txERC20WithdrawOtherAddress.txt", + txEthWithdraw = "./buffer/txEthWithdraw.txt", + txEthWithdrawOtherAddress = "./buffer/txEthWithdrawOtherAddress.txt", + txERC20Transfer = "./buffer/txERC20Transfer.txt", emptyWalletPrivateKey = "./buffer/emptyWalletPrivateKey.txt", emptyWalletAddress = "./buffer/emptyWalletAddress.txt", failedState = "./buffer/failedState.txt", diff --git a/packages/integration-tests/src/playbook/scenarios/transfers/transferERC20.ts b/packages/integration-tests/src/playbook/scenarios/transfers/transferERC20.ts index 44316badf4..13a1ab0ed3 100644 --- a/packages/integration-tests/src/playbook/scenarios/transfers/transferERC20.ts +++ b/packages/integration-tests/src/playbook/scenarios/transfers/transferERC20.ts @@ -1,8 +1,9 @@ import * as ethers from "ethers"; +import { promises as fs } from "fs"; import * as zksync from "zksync-web3"; import { localConfig } from "../../../config"; -import { Logger, Wallets } from "../../../entities"; +import { Buffer, Logger, Wallets } from "../../../entities"; import { Helper } from "../../../helper"; export const transferERC20 = async function (sum: string, tokenAddress: string, tokenName?: string /*, units = 18*/) { @@ -11,6 +12,8 @@ export const transferERC20 = async function (sum: string, tokenAddress: string, const ethProvider = ethers.getDefaultProvider(localConfig.L1Network); const syncWallet = new zksync.Wallet(localConfig.privateKey, syncProvider, ethProvider); const syncWallet2 = new zksync.Wallet(Wallets.secondWalletPrivateKey, syncProvider, ethProvider); + const playbookRoot = "src/playbook/"; + const bufferFile = playbookRoot + Buffer.txEthTransfer; const transfer = await syncWallet.transfer({ to: syncWallet2.address, @@ -21,6 +24,7 @@ export const transferERC20 = async function (sum: string, tokenAddress: string, const txHash = transfer.hash; await helper.txHashLogger(Logger.transfer, txHash, tokenName); + await fs.writeFile(bufferFile, txHash); return txHash; }; diff --git a/packages/integration-tests/src/playbook/scenarios/transfers/transferETH.ts b/packages/integration-tests/src/playbook/scenarios/transfers/transferETH.ts index b6d801eb97..fdd21c6e51 100644 --- a/packages/integration-tests/src/playbook/scenarios/transfers/transferETH.ts +++ b/packages/integration-tests/src/playbook/scenarios/transfers/transferETH.ts @@ -1,8 +1,9 @@ import * as ethers from "ethers"; +import { promises as fs } from "fs"; import * as zksync from "zksync-web3"; import { localConfig } from "../../../config"; -import { Logger, Wallets } from "../../../entities"; +import { Buffer, Logger, Wallets } from "../../../entities"; import { Helper } from "../../../helper"; export const transferEth = async function (sum = "0.000009", address: string = Wallets.mainWalletPrivateKey) { @@ -11,6 +12,8 @@ export const transferEth = async function (sum = "0.000009", address: string = W const ethProvider = ethers.getDefaultProvider(localConfig.L1Network); const syncWallet = new zksync.Wallet(localConfig.privateKey, syncProvider, ethProvider); const syncWallet2 = new zksync.Wallet(address, syncProvider, ethProvider); + const playbookRoot = "src/playbook/"; + const bufferFile = playbookRoot + Buffer.txEthTransfer; const transfer = await syncWallet.transfer({ to: syncWallet2.address, @@ -20,6 +23,7 @@ export const transferEth = async function (sum = "0.000009", address: string = W const txHash = transfer.hash; await helper.txHashLogger(Logger.transfer, txHash, "ETH"); + await fs.writeFile(bufferFile, txHash); return txHash; }; diff --git a/packages/integration-tests/src/playbook/scenarios/transfers/transferFailedState.ts b/packages/integration-tests/src/playbook/scenarios/transfers/transferFailedState.ts index 77bf391107..c798cf6a61 100644 --- a/packages/integration-tests/src/playbook/scenarios/transfers/transferFailedState.ts +++ b/packages/integration-tests/src/playbook/scenarios/transfers/transferFailedState.ts @@ -1,8 +1,9 @@ import * as ethers from "ethers"; +import { promises as fs } from "fs"; import * as zksync from "zksync-web3"; import { localConfig } from "../../../config"; -import { Logger } from "../../../entities"; +import { Buffer, Logger } from "../../../entities"; import { Helper } from "../../../helper"; export const transferFailedState = async function (tokenAddress: string, tokenName?: string) { @@ -11,6 +12,8 @@ export const transferFailedState = async function (tokenAddress: string, tokenNa const ethProvider = ethers.getDefaultProvider(localConfig.L1Network); const syncWallet = new zksync.Wallet(localConfig.privateKey, syncProvider, ethProvider); const amount = ethers.utils.parseEther("1.0"); + const playbookRoot = "src/playbook/"; + const bufferFile = playbookRoot + Buffer.failedState; const transfer = await syncWallet.transfer({ to: "0x0000000000000000000000000000000000000000", @@ -21,6 +24,7 @@ export const transferFailedState = async function (tokenAddress: string, tokenNa const txHash = transfer.hash; await helper.txHashLogger(Logger.txFailedState, txHash, tokenName); + await fs.writeFile(bufferFile, txHash); return txHash; }; diff --git a/packages/integration-tests/src/playbook/scenarios/withdrawal/withdrawERC20.ts b/packages/integration-tests/src/playbook/scenarios/withdrawal/withdrawERC20.ts index 27d498dda3..7bcb910033 100644 --- a/packages/integration-tests/src/playbook/scenarios/withdrawal/withdrawERC20.ts +++ b/packages/integration-tests/src/playbook/scenarios/withdrawal/withdrawERC20.ts @@ -1,8 +1,9 @@ import * as ethers from "ethers"; +import { promises as fs } from "fs"; import * as zksync from "zksync-web3"; import { localConfig } from "../../../config"; -import { Logger, Wallets } from "../../../entities"; +import { Buffer, Logger, Wallets } from "../../../entities"; import { Helper } from "../../../helper"; export const withdrawERC20 = async function (tokenAddress: string, sum = "0.2") { @@ -11,6 +12,8 @@ export const withdrawERC20 = async function (tokenAddress: string, sum = "0.2") const ethProvider = ethers.getDefaultProvider(localConfig.L1Network); const syncWallet = new zksync.Wallet(localConfig.privateKey, syncProvider, ethProvider); const bridges = await syncProvider.getDefaultBridgeAddresses(); + const playbookRoot = "src/playbook/"; + const bufferFile = playbookRoot + Buffer.txERC20Withdraw; const balance = await syncWallet.getBalance(tokenAddress); @@ -21,7 +24,7 @@ export const withdrawERC20 = async function (tokenAddress: string, sum = "0.2") amount: ethers.utils.parseEther(sum), token: tokenAddress, bridgeAddress: bridges.erc20L2, - overrides: localConfig.gasLimit, + // overrides: localConfig.gasLimit, }); const txHash = withdrawL2.hash; @@ -34,6 +37,7 @@ export const withdrawERC20 = async function (tokenAddress: string, sum = "0.2") console.log(`Your balance is ${balanceAfter.toString()}`); await helper.txHashLogger(Logger.withdraw, txHash, "Custom token"); + await fs.writeFile(bufferFile, txHash); return txHash; }; diff --git a/packages/integration-tests/src/playbook/scenarios/withdrawal/withdrawERC20toOtherAddress.ts b/packages/integration-tests/src/playbook/scenarios/withdrawal/withdrawERC20toOtherAddress.ts index ab92a9c326..cf377733b6 100644 --- a/packages/integration-tests/src/playbook/scenarios/withdrawal/withdrawERC20toOtherAddress.ts +++ b/packages/integration-tests/src/playbook/scenarios/withdrawal/withdrawERC20toOtherAddress.ts @@ -1,8 +1,9 @@ import * as ethers from "ethers"; +import { promises as fs } from "fs"; import * as zksync from "zksync-web3"; import { localConfig } from "../../../config"; -import { Logger, Wallets } from "../../../entities"; +import { Buffer, Logger, Wallets } from "../../../entities"; import { Helper } from "../../../helper"; export const withdrawERC20toOtherAddress = async function (tokenAddress: string, sum = "0.2") { @@ -11,6 +12,8 @@ export const withdrawERC20toOtherAddress = async function (tokenAddress: string, const ethProvider = ethers.getDefaultProvider(localConfig.L1Network); const syncWallet = new zksync.Wallet(localConfig.privateKey, syncProvider, ethProvider); const bridges = await syncProvider.getDefaultBridgeAddresses(); + const playbookRoot = "src/playbook/"; + const bufferFile = playbookRoot + Buffer.txERC20WithdrawOtherAddress; const balance = await syncWallet.getBalance(tokenAddress); @@ -34,6 +37,7 @@ export const withdrawERC20toOtherAddress = async function (tokenAddress: string, console.log(`Your balance is ${balanceAfter.toString()}`); await helper.txHashLogger(Logger.withdraw, txHash, "Custom token"); + await fs.writeFile(bufferFile, txHash); return txHash; }; diff --git a/packages/integration-tests/src/playbook/scenarios/withdrawal/withdrawETH.ts b/packages/integration-tests/src/playbook/scenarios/withdrawal/withdrawETH.ts index b5daeaa52f..5c2598a6d6 100644 --- a/packages/integration-tests/src/playbook/scenarios/withdrawal/withdrawETH.ts +++ b/packages/integration-tests/src/playbook/scenarios/withdrawal/withdrawETH.ts @@ -1,8 +1,9 @@ import * as ethers from "ethers"; +import { promises as fs } from "fs"; import * as zksync from "zksync-web3"; import { localConfig } from "../../../config"; -import { Logger } from "../../../entities"; +import { Buffer, Logger } from "../../../entities"; import { Helper } from "../../../helper"; export const withdrawETH = async function (sum = "0.000009") { @@ -10,6 +11,8 @@ export const withdrawETH = async function (sum = "0.000009") { const syncProvider = new zksync.Provider(localConfig.L2Network); const ethProvider = ethers.getDefaultProvider(localConfig.L1Network); const syncWallet = new zksync.Wallet(localConfig.privateKey, syncProvider, ethProvider); + const playbookRoot = "src/playbook/"; + const bufferFile = playbookRoot + Buffer.txEthWithdraw; const withdrawL2 = await syncWallet.withdraw({ token: zksync.utils.ETH_ADDRESS, @@ -20,6 +23,7 @@ export const withdrawETH = async function (sum = "0.000009") { await withdrawL2.waitFinalize(); await helper.txHashLogger(Logger.withdraw, txHash, "ETH"); + await fs.writeFile(bufferFile, txHash); return txHash; }; diff --git a/packages/integration-tests/src/playbook/scenarios/withdrawal/withdrawETHtoOtherAddress.ts b/packages/integration-tests/src/playbook/scenarios/withdrawal/withdrawETHtoOtherAddress.ts index 53c217110c..6adde5510c 100644 --- a/packages/integration-tests/src/playbook/scenarios/withdrawal/withdrawETHtoOtherAddress.ts +++ b/packages/integration-tests/src/playbook/scenarios/withdrawal/withdrawETHtoOtherAddress.ts @@ -1,8 +1,9 @@ import * as ethers from "ethers"; +import { promises as fs } from "fs"; import * as zksync from "zksync-web3"; import { localConfig } from "../../../config"; -import { Logger, Wallets } from "../../../entities"; +import { Buffer, Logger, Wallets } from "../../../entities"; import { Helper } from "../../../helper"; export const withdrawETHtoOtherAddress = async function (sum = "0.000009") { @@ -10,6 +11,8 @@ export const withdrawETHtoOtherAddress = async function (sum = "0.000009") { const syncProvider = new zksync.Provider(localConfig.L2Network); const ethProvider = ethers.getDefaultProvider(localConfig.L1Network); const syncWallet = new zksync.Wallet(localConfig.privateKey, syncProvider, ethProvider); + const playbookRoot = "src/playbook/"; + const bufferFile = playbookRoot + Buffer.txEthWithdrawOtherAddress; const withdrawL2 = await syncWallet.withdraw({ token: zksync.utils.ETH_ADDRESS, @@ -21,6 +24,7 @@ export const withdrawETHtoOtherAddress = async function (sum = "0.000009") { await withdrawL2.waitFinalize(); await helper.txHashLogger(Logger.withdraw, txHash, "ETH"); + await fs.writeFile(bufferFile, txHash); return txHash; }; diff --git a/packages/integration-tests/tests/api/addresses.test.ts b/packages/integration-tests/tests/api/addresses.test.ts new file mode 100644 index 0000000000..2fb5edca53 --- /dev/null +++ b/packages/integration-tests/tests/api/addresses.test.ts @@ -0,0 +1,263 @@ +import * as request from "supertest"; +import { setTimeout } from "timers/promises"; + +import { environment } from "../../src/config"; +import { localConfig } from "../../src/config"; +import { Buffer, Token, Wallets } from "../../src/entities"; +import { Helper } from "../../src/helper"; +import { Playbook } from "../../src/playbook/playbook"; + +describe("Address", () => { + jest.setTimeout(localConfig.extendedTimeout); + + const helper = new Helper(); + const playbook = new Playbook(); + const bufferFile = "src/playbook/"; + let token: string; + let contract: string; + let txHash: string; + + describe("/address/{address}", () => { + beforeAll(async () => { + await playbook.deployNFTtoL2(); + await playbook.deployMultiCallContracts(); + await playbook.deployMultiTransferETH(); + await playbook.deployGreeterToL2(); + await playbook.useMultiCallContracts(); + await playbook.useMultiTransferETH(); + }); + + //@id1457 + it("Verify deployed to L2 NFT via /address/{address}", async () => { + await setTimeout(localConfig.extendedPause); + + token = await helper.getStringFromFile(bufferFile + Buffer.NFTtoL2); + const apiRoute = `/address/${token}`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => + expect(res.body).toEqual( + expect.objectContaining({ + type: "contract", + address: token, + balances: { + [`${token}`]: { + balance: "1", + token: null, + }, + }, + }) + ) + ); + }); + + //@id1464 + it("Verify the deployed Root contract via /address/{address}", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + contract = await helper.getStringFromFile(bufferFile + Buffer.addressMultiCallRoot); + txHash = await helper.getStringFromFile(bufferFile + Buffer.txMultiCallRoot); + + const apiRoute = `/address/${contract}`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ type: "contract" }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ address: contract }))) + .expect((res) => + expect(res.body).toStrictEqual(expect.objectContaining({ creatorAddress: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ creatorTxHash: txHash }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ balances: {} }))); + }); + + //@id1465 + it("Verify the deployed Middle contract via /address/{address}", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + contract = await helper.getStringFromFile(bufferFile + Buffer.addressMultiCallMiddle); + txHash = await helper.getStringFromFile(bufferFile + Buffer.txMultiCallMiddle); + + const apiRoute = `/address/${contract}`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ type: "contract" }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ address: contract }))) + .expect((res) => + expect(res.body).toStrictEqual(expect.objectContaining({ creatorAddress: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ creatorTxHash: txHash }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ balances: {} }))); + }); + + //@id1466 + it("Verify the deployed Caller contract via /address/{address}", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + contract = await helper.getStringFromFile(bufferFile + Buffer.addressMultiCallCaller); + txHash = await helper.getStringFromFile(bufferFile + Buffer.txMultiCallCaller); + + const apiRoute = `/address/${contract}`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ type: "contract" }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ address: contract }))) + .expect((res) => + expect(res.body).toStrictEqual(expect.objectContaining({ creatorAddress: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ creatorTxHash: txHash }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ balances: {} }))); + }); + + //@id1476 + it("Verify the deployed multitransfer contract via /address/{address}", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + contract = await helper.getStringFromFile(bufferFile + Buffer.addressMultiTransferETH); + const apiRoute = `/address/${contract}`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ address: contract }))) + .expect((res) => + expect(res.body).toStrictEqual(expect.objectContaining({ creatorAddress: Wallets.richWalletAddress })) + ); + }); + + //@id1449 + it("Verify the deployed Greeter contract via /address/{address}", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + contract = await helper.getStringFromFile(bufferFile + Buffer.greeterL2); + const apiRoute = `/address/${contract}`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ address: contract }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ balances: {} }))); + }); + }); + + describe("/address/{address}/logs", () => { + beforeAll(async () => { + await playbook.useGreeter(); + }); + + //@id1510 + it("Verify the transaction via /address/{address}/logs", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + contract = await helper.getStringFromFile(bufferFile + Buffer.greeterL2); + txHash = await helper.getStringFromFile(bufferFile + Buffer.executeGreeterTx); + + const apiRoute = `/address/${contract}/logs`; + const decapitalizedAddress = apiRoute.slice(1).toLowerCase(); + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ address: contract }))) + .expect((res) => expect(Array.isArray(res.body.items[0].topics)).toStrictEqual(true)) + .expect((res) => expect(typeof res.body.items[0].data).toStrictEqual("string")) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(typeof res.body.items[0].transactionIndex).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.items[0].logIndex).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.items[0].timestamp).toStrictEqual("string")) + .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ totalItems: 1 }))) + .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ itemCount: 1 }))) + .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ itemsPerPage: 10 }))) + .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ totalPages: 1 }))) + .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ currentPage: 1 }))) + .expect((res) => + expect(res.body.links).toStrictEqual(expect.objectContaining({ first: `${decapitalizedAddress}?limit=10` })) + ) + .expect((res) => expect(res.body.links).toStrictEqual(expect.objectContaining({ previous: "" }))) + .expect((res) => expect(res.body.links).toStrictEqual(expect.objectContaining({ next: "" }))) + .expect((res) => + expect(res.body.links).toStrictEqual( + expect.objectContaining({ last: `${decapitalizedAddress}?page=1&limit=10` }) + ) + ); + }); + }); + + describe("/address/{address}/transfers", () => { + beforeAll(async () => { + await playbook.deployViaPaymaster(); + await playbook.usePaymaster(); + }); + + //@id1509 + it("Verify the transaction via /address/{address}/transfers", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + contract = await helper.getStringFromFile(bufferFile + Buffer.paymaster); + const emptyWallet = await helper.getStringFromFile(bufferFile + Buffer.emptyWalletAddress); + txHash = await helper.getStringFromFile(bufferFile + Buffer.paymasterTx); + + const customTokenAddress = await helper.getStringFromFile(bufferFile + Buffer.customToken); + const apiRoute = `/address/${contract}/transfers`; + const decapitalizedAddress = apiRoute.slice(1).toLowerCase(); + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: emptyWallet }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: contract }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(typeof res.body.items[0].timestamp).toStrictEqual("string")) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ amount: "1" }))) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: customTokenAddress })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: "transfer" }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => + expect(res.body.items[0].token).toStrictEqual(expect.objectContaining({ l2Address: customTokenAddress })) + ) + .expect((res) => expect(res.body.items[0].token).toStrictEqual(expect.objectContaining({ l1Address: null }))) + .expect((res) => expect(res.body.items[0].token).toStrictEqual(expect.objectContaining({ symbol: "MyToken" }))) + .expect((res) => expect(res.body.items[0].token).toStrictEqual(expect.objectContaining({ name: "MyToken" }))) + .expect((res) => expect(res.body.items[0].token).toStrictEqual(expect.objectContaining({ decimals: 18 }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: contract }))) + .expect((res) => expect(typeof res.body.items[1].timestamp).toStrictEqual("string")) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ amount: "30000000000000000" })) + ) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: "transfer" }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ totalItems: 2 }))) + .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ itemCount: 2 }))) + .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ itemsPerPage: 10 }))) + .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ totalPages: 1 }))) + .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ currentPage: 1 }))) + .expect((res) => + expect(res.body.links).toStrictEqual(expect.objectContaining({ first: `${decapitalizedAddress}?limit=10` })) + ) + .expect((res) => expect(res.body.links).toStrictEqual(expect.objectContaining({ previous: "" }))) + .expect((res) => expect(res.body.links).toStrictEqual(expect.objectContaining({ next: "" }))) + .expect((res) => + expect(res.body.links).toStrictEqual( + expect.objectContaining({ last: `${decapitalizedAddress}?page=1&limit=10` }) + ) + ); + }); + }); +}); diff --git a/packages/integration-tests/tests/api/batches.test.ts b/packages/integration-tests/tests/api/batches.test.ts new file mode 100644 index 0000000000..3a8326a8ec --- /dev/null +++ b/packages/integration-tests/tests/api/batches.test.ts @@ -0,0 +1,61 @@ +import * as request from "supertest"; +import { setTimeout } from "timers/promises"; + +import { environment } from "../../src/config"; +import { localConfig } from "../../src/config"; + +describe("/batches", () => { + jest.setTimeout(localConfig.standardTimeout); + + //@id1513 + it("Verify the response via /batches", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + const apiRoute = `/batches`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(Array.isArray(res.body.items)).toStrictEqual(true)) + .expect((res) => expect(res.body.items.length).toBeGreaterThanOrEqual(1)) + .expect((res) => expect(typeof res.body.meta.totalItems).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.meta.itemCount).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.meta.itemsPerPage).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.meta.totalPages).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.meta.currentPage).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.links.first).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.links.previous).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.links.next).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.links.last).toStrictEqual("string")); + }); + + //@id1514 + it("Verify the response via /batches/{batchNumber}", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + const batches = await request(environment.blockExplorerAPI).get("/batches"); + + const batchNumber = batches.body.items[0].number; + + const apiRoute = `/batches/${batchNumber}`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body.number).toStrictEqual(batchNumber)) + .expect((res) => expect(typeof res.body.timestamp).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.rootHash).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.executedAt).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.l1TxCount).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.l2TxCount).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.commitTxHash).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.committedAt).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.proveTxHash).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.provenAt).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.executeTxHash).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.l1GasPrice).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.l2FairGasPrice).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.size).toStrictEqual("number")) + .expect((res) => expect(res.body.status).toStrictEqual("verified")); + }); +}); diff --git a/packages/integration-tests/tests/api/before-all/deposit.test.ts b/packages/integration-tests/tests/api/before-all/deposit.test.ts deleted file mode 100644 index daaf5367f6..0000000000 --- a/packages/integration-tests/tests/api/before-all/deposit.test.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { localConfig } from "../../../src/config"; -import { Buffer } from "../../../src/entities"; -import { Logger } from "../../../src/entities"; -import { Helper } from "../../../src/helper"; -import { Playbook } from "../../../src/playbook/playbook"; - -describe("Deposit", () => { - const playbook = new Playbook(); - const helper = new Helper(); - const bufferRoute = "src/playbook/"; - - let result: string; - let token: string; - jest.setTimeout(localConfig.extendedTimeout); - - //@id633 - it("Make a deposit with 0.0000001 ETH ", async () => { - result = await playbook.depositETH("0.0000001"); - await expect(result).not.toBeUndefined(); - await expect(result.includes(Logger.txHashStartsWith)).toBe(true); - }); - - //@id638 - it("Make a deposit with the Custom token ", async () => { - const bufferFile = bufferRoute + Buffer.L1; - token = await helper.getStringFromFile(bufferFile); - result = await playbook.depositERC20("100", token, 18); - await expect(result).not.toBeUndefined(); - await expect(result.includes(Logger.txHashStartsWith)).toBe(true); - }); -}); diff --git a/packages/integration-tests/tests/api/before-all/tokens.test.ts b/packages/integration-tests/tests/api/before-all/tokens.test.ts deleted file mode 100644 index 9f2aee8dca..0000000000 --- a/packages/integration-tests/tests/api/before-all/tokens.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -import * as request from "supertest"; -import { setTimeout } from "timers/promises"; - -import { environment } from "../../../src/config"; -import { localConfig } from "../../../src/config"; -import { Logger, Token } from "../../../src/entities"; -import { Playbook } from "../../../src/playbook/playbook"; - -describe("Tokens", () => { - jest.setTimeout(localConfig.standardTimeout); - - let deployedToken: string; - - describe("Deploy/check the custom ERC20 tokens", () => { - const playbook = new Playbook(); - - //@id603 - it("Deploy custom ERC20 token to L2", async () => { - deployedToken = await playbook.deployERC20toL2(); - expect(deployedToken).toContain(Logger.txHashStartsWith); - }); - - //@id1456 - it("Verify deployed to L2 custom token via /tokens/{tokenAddress}", async () => { - await setTimeout(localConfig.extendedPause); //works unstable without timeout - const apiRoute = `/tokens/${deployedToken}`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => - expect(res.body).toStrictEqual({ - l2Address: deployedToken, - l1Address: null, - symbol: Token.customL2TokenSymbol, - name: Token.customL2TokenName, - decimals: Token.customL2TokenDecimals, - }) - ); - }); - - //@id657 - it("Deploy custom ERC20 token to L1", async () => { - deployedToken = await playbook.deployERC20toL1(); - expect(deployedToken).toContain(Logger.txHashStartsWith); - }); - }); -}); diff --git a/packages/integration-tests/tests/api/blocks.test.ts b/packages/integration-tests/tests/api/blocks.test.ts new file mode 100644 index 0000000000..989c07bf9f --- /dev/null +++ b/packages/integration-tests/tests/api/blocks.test.ts @@ -0,0 +1,68 @@ +import * as request from "supertest"; +import { setTimeout } from "timers/promises"; + +import { environment } from "../../src/config"; +import { localConfig } from "../../src/config"; + +describe("/blocks", () => { + jest.setTimeout(localConfig.standardTimeout); + + //@id1511 + it("Verify the response via /blocks", async () => { + await setTimeout(localConfig.extendedPause); //works unstable without timeout + + const apiRoute = `/blocks`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(Array.isArray(res.body.items)).toStrictEqual(true)) + .expect((res) => expect(res.body.items.length).toBeGreaterThan(1)) + .expect((res) => expect(typeof res.body.meta.totalItems).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.meta.itemCount).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.meta.itemsPerPage).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.meta.totalPages).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.meta.currentPage).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.links.first).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.links.previous).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.links.next).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.links.last).toStrictEqual("string")); + }); + + //@id1512 + it("Verify the response via /blocks/{/blockNumber}", async () => { + await setTimeout(localConfig.extendedPause); //works unstable without timeout + + const blocks = await request(environment.blockExplorerAPI).get("/blocks"); + + const blockNumber = blocks.body.items[0].number; + + const apiRoute = `/blocks/${blockNumber}`; + + return ( + request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body.number).toStrictEqual(blockNumber)) + .expect((res) => expect(typeof res.body.hash).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.timestamp).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.gasUsed).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.l1BatchNumber).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.l1TxCount).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.l2TxCount).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.parentHash).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.gasLimit).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.baseFeePerGas).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.extraData).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.size).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.status).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.isL1BatchSealed).toStrictEqual("boolean")) + .expect((res) => expect(typeof res.body.commitTxHash).toStrictEqual("string")) + // .expect((res) => expect(typeof res.body.commitTxHash).toStrictEqual("string")) //unstable on a CI + .expect((res) => expect(typeof res.body.proveTxHash).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.committedAt).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.executedAt).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.provenAt).toStrictEqual("string")) + ); + }); +}); diff --git a/packages/integration-tests/tests/api/common/endpoints.test.ts b/packages/integration-tests/tests/api/common/endpoints.test.ts deleted file mode 100644 index 187d0418ce..0000000000 --- a/packages/integration-tests/tests/api/common/endpoints.test.ts +++ /dev/null @@ -1,185 +0,0 @@ -import * as request from "supertest"; -import { setTimeout } from "timers/promises"; - -import { environment, localConfig } from "../../../src/config"; -import { Buffer } from "../../../src/entities"; -import { Helper } from "../../../src/helper"; - -describe("Endpoints", () => { - const helper = new Helper(); - const bufferRoute = "src/playbook/"; - - jest.setTimeout(localConfig.extendedTimeout); - - describe("/stats", () => { - //@id1515 - it("Verify the response via /stats", async () => { - const apiRoute = `/stats`; - - await setTimeout(localConfig.standardPause); //works unstable without timeout - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(typeof res.body.lastSealedBatch).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.lastVerifiedBatch).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.lastSealedBlock).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.lastVerifiedBlock).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.totalTransactions).toStrictEqual("number")); - }); - }); - - describe("/tokens", () => { - //@id1508 - it("Verify the response via /tokens", async () => { - const l2DepositedToken = await helper.getStringFromFile(bufferRoute + Buffer.L2deposited); - const l1Token = await helper.getStringFromFile(bufferRoute + Buffer.L1); - const l2Token = await helper.getStringFromFile(bufferRoute + Buffer.L2); - - const apiRoute = `/tokens`; - - await setTimeout(localConfig.standardPause); //works unstable without timeout - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(Array.isArray(res.body.items)).toStrictEqual(true)) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ l2Address: l2DepositedToken })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ l1Address: l1Token }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ symbol: "L1" }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ name: "L1 ERC20 token" }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ decimals: 18 }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ l2Address: l2Token }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ l1Address: null }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ symbol: "L2" }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ name: "L2 ERC20 token" }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ decimals: 18 }))) - .expect((res) => expect(typeof res.body.meta.totalItems).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.meta.itemCount).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.meta.itemsPerPage).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.meta.totalPages).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.meta.currentPage).toStrictEqual("number")) - .expect((res) => expect(res.body.links.first).toStrictEqual("tokens?limit=10")) - .expect((res) => expect(res.body.links.previous).toStrictEqual("")) - .expect((res) => expect(typeof res.body.links.next).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.links.last).toStrictEqual("string")); - }); - }); - - describe("/batches", () => { - //@id1513 - it("Verify the response via /batches", async () => { - const apiRoute = `/batches`; - - await setTimeout(localConfig.standardPause); //works unstable without timeout - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(Array.isArray(res.body.items)).toStrictEqual(true)) - .expect((res) => expect(res.body.items.length).toBeGreaterThanOrEqual(1)) - .expect((res) => expect(typeof res.body.meta.totalItems).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.meta.itemCount).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.meta.itemsPerPage).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.meta.totalPages).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.meta.currentPage).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.links.first).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.links.previous).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.links.next).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.links.last).toStrictEqual("string")); - }); - - //@id1514 - it("Verify the response via /batches/{batchNumber}", async () => { - const batches = await request(environment.blockExplorerAPI).get("/batches"); - - const batchNumber = batches.body.items[0].number; - - const apiRoute = `/batches/${batchNumber}`; - - await setTimeout(localConfig.standardPause); //works unstable without timeout - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body.number).toStrictEqual(batchNumber)) - .expect((res) => expect(typeof res.body.timestamp).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.rootHash).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.executedAt).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.l1TxCount).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.l2TxCount).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.commitTxHash).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.committedAt).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.proveTxHash).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.provenAt).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.executeTxHash).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.l1GasPrice).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.l2FairGasPrice).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.size).toStrictEqual("number")) - .expect((res) => expect(res.body.status).toStrictEqual("verified")); - }); - }); - - describe("/blocks", () => { - //@id1511 - it("Verify the response via /blocks", async () => { - const apiRoute = `/blocks`; - - await setTimeout(localConfig.extendedPause); //works unstable without timeout - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(Array.isArray(res.body.items)).toStrictEqual(true)) - .expect((res) => expect(res.body.items.length).toBeGreaterThan(1)) - .expect((res) => expect(typeof res.body.meta.totalItems).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.meta.itemCount).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.meta.itemsPerPage).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.meta.totalPages).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.meta.currentPage).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.links.first).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.links.previous).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.links.next).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.links.last).toStrictEqual("string")); - }); - - //@id1512 - it("Verify the response via /blocks/{/blockNumber}", async () => { - const blocks = await request(environment.blockExplorerAPI).get("/blocks"); - - const blockNumber = blocks.body.items[0].number; - - const apiRoute = `/blocks/${blockNumber}`; - - await setTimeout(localConfig.extendedPause); //works unstable without timeout - - return ( - request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body.number).toStrictEqual(blockNumber)) - .expect((res) => expect(typeof res.body.hash).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.timestamp).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.gasUsed).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.l1BatchNumber).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.l1TxCount).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.l2TxCount).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.parentHash).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.gasLimit).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.baseFeePerGas).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.extraData).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.size).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.status).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.isL1BatchSealed).toStrictEqual("boolean")) - .expect((res) => expect(typeof res.body.commitTxHash).toStrictEqual("string")) - // .expect((res) => expect(typeof res.body.commitTxHash).toStrictEqual("string")) //unstable on a CI - .expect((res) => expect(typeof res.body.proveTxHash).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.committedAt).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.executedAt).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.provenAt).toStrictEqual("string")) - ); - }); - }); -}); diff --git a/packages/integration-tests/tests/api/common/nft.test.ts b/packages/integration-tests/tests/api/common/nft.test.ts deleted file mode 100644 index ed6271a478..0000000000 --- a/packages/integration-tests/tests/api/common/nft.test.ts +++ /dev/null @@ -1,54 +0,0 @@ -import * as request from "supertest"; -import { setTimeout } from "timers/promises"; - -import { environment } from "../../../src/config"; -import { localConfig } from "../../../src/config"; -import { Logger } from "../../../src/entities"; -import { Playbook } from "../../../src/playbook/playbook"; - -describe("NFTs", () => { - jest.setTimeout(localConfig.standardTimeout); - - let deployedToken: string; - - describe("Deploy/check the NFT", () => { - jest.setTimeout(localConfig.standardTimeout); - const playbook = new Playbook(); - - //@id672 - it("Deploy the NFT to L1", async () => { - deployedToken = await playbook.deployNFTtoL1(); - expect(deployedToken).toContain(Logger.txHashStartsWith); - }); - - //@id671 - it("Deploy the NFT to L2", async () => { - deployedToken = await playbook.deployNFTtoL2(); - expect(deployedToken).toContain(Logger.txHashStartsWith); - }); - - //@id1457 - it("Verify deployed to L2 NFT via /address/{address}", async () => { - await setTimeout(localConfig.extendedPause); - const apiRoute = `/address/${deployedToken}`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => - expect(res.body).toEqual( - expect.objectContaining({ - type: "contract", - address: deployedToken, - balances: { - [`${deployedToken}`]: { - balance: "1", - token: null, - }, - }, - }) - ) - ); - }); - }); -}); diff --git a/packages/integration-tests/tests/api/common/transfers.test.ts b/packages/integration-tests/tests/api/common/transfers.test.ts deleted file mode 100644 index 2f4bb9b1d0..0000000000 --- a/packages/integration-tests/tests/api/common/transfers.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -import * as request from "supertest"; -import { setTimeout } from "timers/promises"; - -import { environment } from "../../../src/config"; -import { localConfig } from "../../../src/config"; -import { Buffer, Wallets } from "../../../src/entities"; -import { Helper } from "../../../src/helper"; -import { Playbook } from "../../../src/playbook/playbook"; - -describe("Transfer", () => { - jest.setTimeout(localConfig.standardTimeout); - const helper = new Helper(); - const playbook = new Playbook(); - const bufferFile = "src/playbook/" + Buffer.L2; - let txHashEth: string; - let txHashCust: string; - let token: string; - - beforeAll(async () => { - token = await helper.getStringFromFile(bufferFile); - txHashEth = await playbook.transferETH("0.000001"); - txHashCust = await playbook.transferERC20("0.01", token, "L2"); - - return [txHashCust, txHashEth]; - }); - - //@id1447 - it("Verify transfer ETH L2-L2 via /transactions/{transactionHash}/transfers", async () => { - const apiRoute = `/transactions/${txHashEth}/transfers`; - await setTimeout(localConfig.standardPause); - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body.items[1].from).toBe(Wallets.richWalletAddress)) - .expect((res) => expect(res.body.items[1].to).toBe(Wallets.mainWalletAddress)) - .expect((res) => expect(res.body.items[1].transactionHash).toBe(txHashEth)) - .expect((res) => expect(res.body.items[1].amount).toBe("1000000000000")) - .expect((res) => expect(res.body.items[1].type).toBe("transfer")); - }); - - //@id1448 - it("Verify the custom ERC20 token transfer via /tokens/{address}/transfers", async () => { - const apiRoute = `/tokens/${token}/transfers?page=1&limit=10`; - token = await helper.getStringFromFile(bufferFile); - - await setTimeout(localConfig.standardPause); //works unstable without timeout - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body.items[0].amount).toBe("10000000000000000")) - .expect((res) => expect(res.body.items[0].from).toBe(Wallets.richWalletAddress)) - .expect((res) => expect(res.body.items[0].to).toBe(Wallets.secondWalletAddress)) - .expect((res) => expect(res.body.items[0].token).toEqual(expect.objectContaining({ l2Address: token }))) - .expect((res) => expect(res.body.items[0]).toEqual(expect.objectContaining({ transactionHash: txHashCust }))) - .expect((res) => expect(res.body.items[0]).toEqual(expect.objectContaining({ type: "transfer" }))); - }); -}); diff --git a/packages/integration-tests/tests/api/common/withdrawal.test.ts b/packages/integration-tests/tests/api/common/withdrawal.test.ts deleted file mode 100644 index 68e716b0ee..0000000000 --- a/packages/integration-tests/tests/api/common/withdrawal.test.ts +++ /dev/null @@ -1,345 +0,0 @@ -import * as request from "supertest"; -import { setTimeout } from "timers/promises"; - -import { environment, localConfig } from "../../../src/config"; -import { Buffer, Token, Wallets } from "../../../src/entities"; -import { Logger } from "../../../src/entities"; -import { Helper } from "../../../src/helper"; -import { Playbook } from "../../../src/playbook/playbook"; - -describe("Withdrawal", () => { - const playbook = new Playbook(); - const helper = new Helper(); - const playbookRoot = "src/playbook"; - const l2Token = playbookRoot + "/" + Buffer.L2deposited; - const l1Token = playbookRoot + "/" + Buffer.L1; - - let result: string; - jest.setTimeout(localConfig.extendedTimeout); - - describe("Withdrawal ETH to the own address", () => { - //@id639 - it("Make a withdrawal to the own address with 0.0000001 ETH ", async () => { - result = await playbook.withdrawETH(); - await expect(result).not.toBeUndefined(); - await expect(result.includes(Logger.txHashStartsWith)).toBe(true); - }); - - //@id1458 - it("Verify the ETH withdrawal via /transactions/{transactionHash}", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - const apiRoute = `/transactions/${result}`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body.hash).toBe(result)) - .expect((res) => expect(res.body.to).toBe("0x000000000000000000000000000000000000800A")) - .expect((res) => expect(res.body.from).toBe(Wallets.richWalletAddress)) - .expect((res) => expect(res.body.value).toBe("9000000000000")); - }); - - //@id1459 - it("Verify the ETH withdrawal via /transactions/{transactionHash}/transfers", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - const apiRoute = `/transactions/${result}/transfers`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: result }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: "fee" }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_ERC20_Address })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: result }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ amount: "9000000000000" }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: "transfer" }))) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ transactionHash: result }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ amount: "9000000000000" }))) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ type: "withdrawal" }))) - .expect((res) => - expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) - ) - .expect((res) => - expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ transactionHash: result }))) - .expect((res) => expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ type: "refund" }))); - }); - }); - - describe("Withdrawal ETH to the other address", () => { - //@id640 - it("Make a withdrawal to the other address with 0.0000001 ETH ", async () => { - result = await playbook.withdrawETHtoOtherAddress(); - await expect(result).not.toBeUndefined(); - await expect(result.includes(Logger.txHashStartsWith)).toBe(true); - }); - - //@id1460 - it("Verify the ETH withdrawal to the other address via /transactions/{transactionHash}", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - const apiRoute = `/transactions/${result}`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body.hash).toBe(result)) - .expect((res) => expect(res.body.to).toBe("0x000000000000000000000000000000000000800A")) - .expect((res) => expect(res.body.from).toBe(Wallets.richWalletAddress)) - .expect((res) => expect(res.body.value).toBe("9000000000000")); - }); - - //@id1461 - it("Verify the ETH withdrawal to the other address via /transactions/{transactionHash}/transfers", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - const apiRoute = `/transactions/${result}/transfers`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: result }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: "fee" }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_ERC20_Address })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: result }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ amount: "9000000000000" }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: "transfer" }))) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ to: Wallets.mainWalletAddress })) - ) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ transactionHash: result }))) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ amount: "9000000000000" }))) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ type: "withdrawal" }))) - .expect((res) => - expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) - ) - .expect((res) => - expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ transactionHash: result }))) - .expect((res) => expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ type: "refund" }))); - }); - }); - - describe("Withdrawal the custom token to the own address", () => { - //@id641 - it("Make the custom token withdrawal to the own address", async () => { - const customToken = await helper.getStringFromFile(l2Token); - result = await playbook.withdrawERC20(customToken); - await expect(result).not.toBeUndefined(); - await expect(result.includes(Logger.txHashStartsWith)).toBe(true); - }); - - //@id1462 - it("Verify the custom token withdrawal via /transactions/{transactionHash}", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - const apiRoute = `/transactions/${result}`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body.hash).toBe(result)) - .expect((res) => expect(res.body.from).toBe(Wallets.richWalletAddress)); - }); - - //@id1463 - it("Verify the custom token withdrawal via /transactions/{transactionHash}/transfers", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - const customTokenL2 = await helper.getStringFromFile(l2Token); - const customTokenL1 = await helper.getStringFromFile(l1Token); - const apiRoute = `/transactions/${result}/transfers`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: result }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: "fee" }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_Address }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: result }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ amount: "200000000000000000" })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: "transfer" }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual( - expect.objectContaining({ - token: { - l2Address: customTokenL2, - l1Address: customTokenL1, - symbol: "L1", - name: "L1 ERC20 token", - decimals: 18, - }, - }) - ) - ) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ transactionHash: result }))) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ amount: "200000000000000000" })) - ) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ type: "withdrawal" }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual( - expect.objectContaining({ - token: { - l2Address: customTokenL2, - l1Address: customTokenL1, - symbol: "L1", - name: "L1 ERC20 token", - decimals: 18, - }, - }) - ) - ) - .expect((res) => - expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) - ) - .expect((res) => - expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ transactionHash: result }))) - .expect((res) => expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ type: "refund" }))); - }); - }); - - describe("Withdrawal the custom token to the other address", () => { - //@id643 - it("Make the custom token withdrawal to the other address", async () => { - const customToken = await helper.getStringFromFile(l2Token); - result = await playbook.withdrawERC20toOtherAddress(customToken); - await expect(result).not.toBeUndefined(); - await expect(result.includes(Logger.txHashStartsWith)).toBe(true); - }); - - //@id1462 - it("Verify the custom token withdrawal via /transactions/{transactionHash}", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - const apiRoute = `/transactions/${result}`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body.hash).toBe(result)) - .expect((res) => expect(res.body.from).toBe(Wallets.richWalletAddress)); - }); - - //@id1463 - it("Verify the custom token withdrawal via /transactions/{transactionHash}/transfers", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - const customTokenL2 = await helper.getStringFromFile(l2Token); - const customTokenL1 = await helper.getStringFromFile(l1Token); - const apiRoute = `/transactions/${result}/transfers`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: result }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: "fee" }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_Address }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: result }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ amount: "200000000000000000" })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: "transfer" }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual( - expect.objectContaining({ - token: { - l2Address: customTokenL2, - l1Address: customTokenL1, - symbol: "L1", - name: "L1 ERC20 token", - decimals: 18, - }, - }) - ) - ) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ to: Wallets.mainWalletAddress })) - ) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ transactionHash: result }))) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ amount: "200000000000000000" })) - ) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ type: "withdrawal" }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual( - expect.objectContaining({ - token: { - l2Address: customTokenL2, - l1Address: customTokenL1, - symbol: "L1", - name: "L1 ERC20 token", - decimals: 18, - }, - }) - ) - ) - .expect((res) => - expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) - ) - .expect((res) => - expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ transactionHash: result }))) - .expect((res) => expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ type: "refund" }))); - }); - }); -}); diff --git a/packages/integration-tests/tests/api/stats.test.ts b/packages/integration-tests/tests/api/stats.test.ts new file mode 100644 index 0000000000..970e947af4 --- /dev/null +++ b/packages/integration-tests/tests/api/stats.test.ts @@ -0,0 +1,25 @@ +import * as request from "supertest"; +import { setTimeout } from "timers/promises"; + +import { environment } from "../../src/config"; +import { localConfig } from "../../src/config"; + +describe("/stats", () => { + jest.setTimeout(localConfig.standardTimeout); //works unstable without timeout + + //@id1515 + it("Verify the response via /stats", async () => { + await setTimeout(localConfig.extendedPause); //works unstable without timeout + + const apiRoute = `/stats`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(typeof res.body.lastSealedBatch).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.lastVerifiedBatch).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.lastSealedBlock).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.lastVerifiedBlock).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.totalTransactions).toStrictEqual("number")); + }); +}); diff --git a/packages/integration-tests/tests/api/tokens.test.ts b/packages/integration-tests/tests/api/tokens.test.ts new file mode 100644 index 0000000000..4a89c5150c --- /dev/null +++ b/packages/integration-tests/tests/api/tokens.test.ts @@ -0,0 +1,129 @@ +import * as request from "supertest"; +import { setTimeout } from "timers/promises"; + +import { environment } from "../../src/config"; +import { localConfig } from "../../src/config"; +import { Buffer, Token, TransactionsType, Wallets } from "../../src/entities"; +import { Helper } from "../../src/helper"; +import { Playbook } from "../../src/playbook/playbook"; + +describe("Tokens", () => { + jest.setTimeout(localConfig.standardTimeout); + + const helper = new Helper(); + const playbook = new Playbook(); + const bufferFile = "src/playbook/"; + let l2Token: string; + let txHash: string; + + beforeAll(async () => { + l2Token = await helper.getStringFromFile(bufferFile + Buffer.L2); + }); + + describe("/tokens", () => { + //@id1508 + it("Verify the response via /tokens", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + const l2DepositedToken = await helper.getStringFromFile(bufferFile + Buffer.L2deposited); + const l1Token = await helper.getStringFromFile(bufferFile + Buffer.L1); + const apiRoute = `/tokens`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(Array.isArray(res.body.items)).toStrictEqual(true)) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ l2Address: l2DepositedToken })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ l1Address: l1Token }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ symbol: "L1" }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ name: "L1 ERC20 token" }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ decimals: 18 }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ l2Address: l2Token }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ l1Address: null }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ symbol: "L2" }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ name: "L2 ERC20 token" }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ decimals: 18 }))) + .expect((res) => expect(typeof res.body.meta.totalItems).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.meta.itemCount).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.meta.itemsPerPage).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.meta.totalPages).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.meta.currentPage).toStrictEqual("number")) + .expect((res) => expect(res.body.links.first).toStrictEqual("tokens?limit=10")) + .expect((res) => expect(res.body.links.previous).toStrictEqual("")) + .expect((res) => expect(typeof res.body.links.next).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.links.last).toStrictEqual("string")); + }); + //@id1456 + it("Verify deployed to L2 custom token via /tokens/{tokenAddress}", async () => { + await setTimeout(localConfig.extendedPause); //works unstable without timeout + + const apiRoute = `/tokens/${l2Token}`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => + expect(res.body).toStrictEqual({ + l2Address: l2Token, + l1Address: null, + symbol: Token.customL2TokenSymbol, + name: Token.customL2TokenName, + decimals: Token.customL2TokenDecimals, + }) + ); + }); + + describe("/tokens/{address}/transfers", () => { + beforeAll(async () => { + txHash = await playbook.transferERC20("0.01", l2Token, "L2"); + await playbook.deployViaPaymaster(); + await playbook.usePaymaster(); + }); + + //@id1448 + it("Verify the custom ERC20 token transfer via /tokens/{address}/transfers", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + const apiRoute = `/tokens/${l2Token}/transfers?page=1&limit=10`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body.items[0].amount).toBe("10000000000000000")) + .expect((res) => expect(res.body.items[0].from).toBe(Wallets.richWalletAddress)) + .expect((res) => expect(res.body.items[0].to).toBe(Wallets.secondWalletAddress)) + .expect((res) => expect(res.body.items[0].token).toEqual(expect.objectContaining({ l2Address: l2Token }))) + .expect((res) => expect(res.body.items[0]).toEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(res.body.items[0]).toEqual(expect.objectContaining({ type: "transfer" }))); + }); + + //@id1451 + it("Verify the custom token includes paymaster transaction via /tokens/{address}/transfers", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + l2Token = await helper.getStringFromFile(bufferFile + Buffer.customToken); + const emptyWallet = await helper.getStringFromFile(bufferFile + Buffer.emptyWalletAddress); + const paymaster = await helper.getStringFromFile(bufferFile + Buffer.paymaster); + txHash = await helper.getStringFromFile(bufferFile + Buffer.paymasterTx); + const apiRoute = `/tokens/${l2Token}/transfers?page=1&limit=10`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: emptyWallet }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: paymaster }))) + .expect((res) => + expect(res.body.items[0].token).toStrictEqual(expect.objectContaining({ l2Address: l2Token })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.transfer })) + ); + }); + }); + }); +}); diff --git a/packages/integration-tests/tests/api/transactions.test.ts b/packages/integration-tests/tests/api/transactions.test.ts new file mode 100644 index 0000000000..c6562bd36e --- /dev/null +++ b/packages/integration-tests/tests/api/transactions.test.ts @@ -0,0 +1,1000 @@ +import * as request from "supertest"; +import { setTimeout } from "timers/promises"; + +import { environment } from "../../src/config"; +import { localConfig } from "../../src/config"; +import { Buffer, Token, TransactionsStatus, TransactionsType, Wallets } from "../../src/entities"; +import { Helper } from "../../src/helper"; +import { Playbook } from "../../src/playbook/playbook"; + +describe("Transactions", () => { + jest.setTimeout(localConfig.extendedTimeout); + + const helper = new Helper(); + const bufferFile = "src/playbook/"; + const playbook = new Playbook(); + + let contract: string; + let token: string; + let txHash: string; + + beforeAll(async () => { + const customToken = await helper.getStringFromFile(bufferFile + Buffer.L2deposited); + await playbook.withdrawETHtoOtherAddress(); + await playbook.withdrawERC20(customToken); + await playbook.withdrawERC20toOtherAddress(customToken); + await playbook.withdrawETH(); + await playbook.deployMultiTransferETH(); + await playbook.useMultiTransferETH(); + await playbook.deployGreeterToL2(); + await playbook.useGreeter(); + await playbook.deployMultiCallContracts(); + await playbook.useMultiCallContracts(); + }); + + describe("/transactions/{transactionHash}/transfers", () => { + beforeAll(async () => { + await playbook.transferETH("0.000001"); + }); + + //@id1447 + it("Verify transfer ETH L2-L2 via /transactions/{transactionHash}/transfers", async () => { + txHash = await helper.getStringFromFile(bufferFile + Buffer.txEthTransfer); + const apiRoute = `/transactions/${txHash}/transfers`; + await setTimeout(localConfig.standardPause); + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body.items[1].from).toBe(Wallets.richWalletAddress)) + .expect((res) => expect(res.body.items[1].to).toBe(Wallets.mainWalletAddress)) + .expect((res) => expect(res.body.items[1].transactionHash).toBe(txHash)) + .expect((res) => expect(res.body.items[1].amount).toBe("1000000000000")) + .expect((res) => expect(res.body.items[1].type).toBe("transfer")); + }); + + //@id1459 + it("Verify the ETH withdrawal via /transactions/{transactionHash}/transfers", async () => { + txHash = await helper.getStringFromFile(bufferFile + Buffer.txEthWithdraw); + + await setTimeout(localConfig.standardPause); //works unstable without timeout + const apiRoute = `/transactions/${txHash}/transfers`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: "fee" }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_ERC20_Address })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ amount: "9000000000000" }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: "transfer" }))) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ amount: "9000000000000" }))) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ type: "withdrawal" }))) + .expect((res) => + expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) + ) + .expect((res) => + expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ type: "refund" }))); + }); + + //@id1461 + it("Verify the ETH withdrawal to the other address via /transactions/{transactionHash}/transfers", async () => { + txHash = await helper.getStringFromFile(bufferFile + Buffer.txEthWithdrawOtherAddress); + + await setTimeout(localConfig.standardPause); //works unstable without timeout + const apiRoute = `/transactions/${txHash}/transfers`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: "fee" }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_ERC20_Address })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ amount: "9000000000000" }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: "transfer" }))) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ to: Wallets.mainWalletAddress })) + ) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ amount: "9000000000000" }))) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ type: "withdrawal" }))) + .expect((res) => + expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) + ) + .expect((res) => + expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ type: "refund" }))); + }); + + //@id1463 + it("Verify the custom token withdrawal via /transactions/{transactionHash}/transfers", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + const l1Token = bufferFile + "/" + Buffer.L1; + const customTokenL1 = await helper.getStringFromFile(l1Token); + const l2Token = bufferFile + "/" + Buffer.L2deposited; + const customTokenL2 = await helper.getStringFromFile(l2Token); + txHash = await helper.getStringFromFile(bufferFile + Buffer.txERC20WithdrawOtherAddress); + + const apiRoute = `/transactions/${txHash}/transfers`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: "fee" }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_Address }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ amount: "200000000000000000" })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: "transfer" }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual( + expect.objectContaining({ + token: { + l2Address: customTokenL2, + l1Address: customTokenL1, + symbol: "L1", + name: "L1 ERC20 token", + decimals: 18, + }, + }) + ) + ) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ to: Wallets.mainWalletAddress })) + ) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ amount: "200000000000000000" })) + ) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ type: "withdrawal" }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual( + expect.objectContaining({ + token: { + l2Address: customTokenL2, + l1Address: customTokenL1, + symbol: "L1", + name: "L1 ERC20 token", + decimals: 18, + }, + }) + ) + ) + .expect((res) => + expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) + ) + .expect((res) => + expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(res.body.items[3]).toStrictEqual(expect.objectContaining({ type: "refund" }))); + }); + }); + + describe("/transactions/{transactionHash}", () => { + beforeAll(async () => { + const customToken = await helper.getStringFromFile(bufferFile + Buffer.L2deposited); + await playbook.transferFailedState(customToken); + }); + + //@id1460 + it("Verify the ETH withdrawal to the other address via /transactions/{transactionHash}", async () => { + txHash = await helper.getStringFromFile(bufferFile + Buffer.txEthWithdrawOtherAddress); + await setTimeout(localConfig.standardPause); //works unstable without timeout + const apiRoute = `/transactions/${txHash}`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body.hash).toBe(txHash)) + .expect((res) => expect(res.body.to).toBe("0x000000000000000000000000000000000000800A")) + .expect((res) => expect(res.body.from).toBe(Wallets.richWalletAddress)) + .expect((res) => expect(res.body.value).toBe("9000000000000")); + }); + + //@id1462 + it("Verify the custom token withdrawal via /transactions/{transactionHash}", async () => { + txHash = await helper.getStringFromFile(bufferFile + Buffer.txERC20Withdraw); + await setTimeout(localConfig.standardPause); //works unstable without timeout + + const apiRoute = `/transactions/${txHash}`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body.hash).toBe(txHash)) + .expect((res) => expect(res.body.from).toBe(Wallets.richWalletAddress)); + }); + + //@id1458 + it("Verify the ETH withdrawal via /transactions/{transactionHash}", async () => { + txHash = await helper.getStringFromFile(bufferFile + Buffer.txEthWithdraw); + const apiRoute = `/transactions/${txHash}`; + + await setTimeout(localConfig.standardPause); //works unstable without timeout + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body.hash).toBe(txHash)) + .expect((res) => expect(res.body.to).toBe("0x000000000000000000000000000000000000800A")) + .expect((res) => expect(res.body.from).toBe(Wallets.richWalletAddress)) + .expect((res) => expect(res.body.value).toBe("9000000000000")); + }); + + //@id1478 + it("Verify transaction for the ETH via /transactions/{transactionHash}", async () => { + txHash = await helper.getStringFromFile(bufferFile + Buffer.txMultiTransferETH); + contract = await helper.getStringFromFile(bufferFile + Buffer.addressMultiTransferETH); + const apiRoute = `/transactions/${txHash}`; + + await setTimeout(localConfig.standardPause); //works unstable without timeout + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ hash: txHash }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ to: contract }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ isL1Originated: false }))); + }); + + //@id1479 + it("Verify transaction for the Custom Token I via /transactions/{transactionHash}", async () => { + contract = await helper.getStringFromFile(bufferFile + Buffer.L2); + txHash = await helper.getStringFromFile(bufferFile + Buffer.txMultiTransferCustomTokenI); + const apiRoute = `/transactions/${txHash}`; + + await setTimeout(localConfig.standardPause); //works unstable without timeout + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ hash: txHash }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ to: contract }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ isL1Originated: false }))); + }); + + //@id1480 + it("Verify transaction for the Custom Token II via /transactions/{transactionHash}", async () => { + contract = await helper.getStringFromFile(bufferFile + Buffer.L2deposited); + txHash = await helper.getStringFromFile(bufferFile + Buffer.txMultiTransferCustomTokenII); + const apiRoute = `/transactions/${txHash}`; + + await setTimeout(localConfig.standardPause); //works unstable without timeout + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ hash: txHash }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ to: contract }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ isL1Originated: false }))); + }); + + //@id1454 + it("Verify the transaction after SetGreeting execution via transactions/{transactionHash}", async () => { + contract = await helper.getStringFromFile(bufferFile + Buffer.greeterL2); + txHash = await helper.getStringFromFile(bufferFile + Buffer.executeGreeterTx); + const apiRoute = `/transactions/${txHash}?page=1&limit=10`; + + await setTimeout(localConfig.standardPause); //works unstable without timeout + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ hash: txHash }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ to: contract }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ value: "0" }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ isL1Originated: false }))); + }); + + //@id1464:I --> @id1468 + it("Verify transaction for the Root contract via /transactions/{transactionHash}", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + txHash = await helper.getStringFromFile(bufferFile + Buffer.txMultiCallRoot); + const apiRoute = `/transactions/${txHash}`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ hash: txHash }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ value: "0" }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ isL1Originated: false }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ transactionIndex: 0 }))); + }); + + //@id1465:I --> @id1469 + it("Verify transaction for the Middle contract via /transactions/{transactionHash}", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + txHash = await helper.getStringFromFile(bufferFile + Buffer.txMultiCallMiddle); + + const apiRoute = `/transactions/${txHash}`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ hash: txHash }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ value: "0" }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ isL1Originated: false }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ transactionIndex: 0 }))); + }); + + //@id1466:I --> @id1470 + it("Verify transaction for the Caller contract via /transactions/{transactionHash}", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + txHash = await helper.getStringFromFile(bufferFile + Buffer.txMultiCallCaller); + + const apiRoute = `/transactions/${txHash}`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ hash: txHash }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ value: "0" }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ isL1Originated: false }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ transactionIndex: 0 }))); + }); + + //@id1471 + it("Verify transaction for the use multicall contract via /transactions/{transactionHash}", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + txHash = await helper.getStringFromFile(bufferFile + Buffer.txUseMultiCallContracts); + const apiRoute = `/transactions/${txHash}`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ hash: txHash }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ value: "0" }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ isL1Originated: false }))) + .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ transactionIndex: 0 }))); + }); + + //@id645 + it("Verify the transactions with failed state via /transactions/{transactionHash}", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + token = await helper.getStringFromFile(bufferFile + Buffer.L2deposited); + txHash = await helper.getStringFromFile(bufferFile + Buffer.failedState); + + const apiRoute = `/transactions/${txHash}?page=1&limit=10`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body.from).toStrictEqual(Wallets.richWalletAddress)) + .expect((res) => expect(res.body.to).toStrictEqual(token)) + .expect((res) => expect(res.body.hash).toStrictEqual(txHash)) + .expect((res) => expect(res.body.status).toStrictEqual(TransactionsStatus.failed)); + }); + }); + + describe("/transactions/{transactionHash}/transfers", () => { + beforeAll(async () => { + await playbook.deployViaPaymaster(); + await playbook.usePaymaster(); + }); + + //@id1481 + it("Verify transaction for the ETH via /transactions/{transactionHash}/transfers", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + contract = await helper.getStringFromFile(bufferFile + Buffer.addressMultiTransferETH); + txHash = await helper.getStringFromFile(bufferFile + Buffer.txMultiTransferETH); + const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: contract }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.transfer })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ token: null }))) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) + ) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) + ) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ token: null }))); + }); + + //@id1482 + it("Verify transaction for the Custom tokenI via /transactions/{transactionHash}/transfers", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + token = await helper.getStringFromFile(bufferFile + Buffer.L2); + contract = await helper.getStringFromFile(bufferFile + Buffer.addressMultiTransferETH); + txHash = await helper.getStringFromFile(bufferFile + Buffer.txMultiTransferCustomTokenI); + const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: contract }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: token }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.transfer })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual( + expect.objectContaining({ + token: { + l2Address: token, + l1Address: null, + symbol: "L2", + name: "L2 ERC20 token", + decimals: 18, + }, + }) + ) + ) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) + ) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) + ) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ token: null }))); + }); + + //@id1483 + it("Verify transaction for the Custom tokenII via /transactions/{transactionHash}/transfers", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + const tokenL1 = await helper.getStringFromFile(bufferFile + Buffer.L1); + + token = await helper.getStringFromFile(bufferFile + Buffer.L2deposited); + contract = await helper.getStringFromFile(bufferFile + Buffer.addressMultiTransferETH); + txHash = await helper.getStringFromFile(bufferFile + Buffer.txMultiTransferCustomTokenII); + + const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; + + await setTimeout(localConfig.standardPause); //works unstable without timeout + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: contract }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: token }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.transfer })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual( + expect.objectContaining({ + token: { + l2Address: token, + l1Address: tokenL1, + symbol: "L1", + name: "L1 ERC20 token", + decimals: 18, + }, + }) + ) + ) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) + ) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) + ) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ token: null }))); + }); + + //@id1452 + it("Verify transaction through Paymaster via /transactions/{transactionHash}/transfers", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + const paymasterAddress = await helper.getStringFromFile(bufferFile + Buffer.paymaster); + const emptyWallet = await helper.getStringFromFile(bufferFile + Buffer.emptyWalletAddress); + token = await helper.getStringFromFile(bufferFile + Buffer.customToken); + txHash = await helper.getStringFromFile(bufferFile + Buffer.paymasterTx); + const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: emptyWallet }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: paymasterAddress }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ amount: "1" }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: token }))) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.transfer })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => + expect(res.body.items[0]).toStrictEqual( + expect.objectContaining({ + token: { + l2Address: token, + l1Address: null, + symbol: "MyToken", + name: "MyToken", + decimals: 18, + }, + }) + ) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: paymasterAddress }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ token: null }))) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) + ) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ to: paymasterAddress }))) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) + ) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ token: null }))); + }); + + //@id1455 + it("Verify the transaction after SetGreeting execution via transactions/{transactionHash}/transfers", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + txHash = await helper.getStringFromFile(bufferFile + Buffer.executeGreeterTx); + + const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) + ) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ token: null }))); + }); + + //@id1472 + it("Verify transaction for the Root contract via /transactions/{transactionHash}/transfers", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + contract = await helper.getStringFromFile(bufferFile + Buffer.addressMultiCallRoot); + txHash = await helper.getStringFromFile(bufferFile + Buffer.txMultiCallRoot); + + const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) + ) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))); + }); + + //@id1473 + it("Verify transaction for the Middle contract via /transactions/{transactionHash}/transfers", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + contract = await helper.getStringFromFile(bufferFile + Buffer.addressMultiCallRoot); + txHash = await helper.getStringFromFile(bufferFile + Buffer.txMultiCallMiddle); + + const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) + ) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))); + }); + + //@id1474 + it("Verify transaction for the Caller contract via /transactions/{transactionHash}/transfers", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + contract = await helper.getStringFromFile(bufferFile + Buffer.addressMultiCallRoot); + txHash = await helper.getStringFromFile(bufferFile + Buffer.txMultiCallCaller); + + const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) + ) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))); + }); + + //@id1475 + it("Verify transaction for the use multicall contract via /transactions/{transactionHash}/transfers", async () => { + await setTimeout(localConfig.standardPause); //works unstable without timeout + + txHash = await helper.getStringFromFile(bufferFile + Buffer.txUseMultiCallContracts); + + const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) + ) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) + ) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) + ) + .expect((res) => + expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) + ) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))); + }); + }); + + describe("/transactions/${txHash}/logs", () => { + //@id1507 + it("Verify the transaction via /transactions/{transactionHash}/logs", async () => { + contract = await helper.getStringFromFile(bufferFile + Buffer.greeterL2); + txHash = await helper.getStringFromFile(bufferFile + Buffer.executeGreeterTx); + + const apiRoute = `/transactions/${txHash}/logs`; + const decapitalizedAddress = apiRoute.slice(1).toLowerCase(); + + await setTimeout(localConfig.standardPause); //works unstable without timeout + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => + expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ address: Token.ETHER_ERC20_Address })) + ) + .expect((res) => expect(Array.isArray(res.body.items[0].topics)).toStrictEqual(true)) + .expect((res) => expect(typeof res.body.items[0].data).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.items[0].blockNumber).toStrictEqual("number")) + .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(typeof res.body.items[0].transactionIndex).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.items[0].logIndex).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.items[0].timestamp).toStrictEqual("string")) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ address: contract }))) + .expect((res) => expect(Array.isArray(res.body.items[1].topics)).toStrictEqual(true)) + .expect((res) => expect(typeof res.body.items[1].data).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.items[1].blockNumber).toStrictEqual("number")) + .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(typeof res.body.items[1].transactionIndex).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.items[1].logIndex).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.items[1].timestamp).toStrictEqual("string")) + .expect((res) => + expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ address: Token.ETHER_ERC20_Address })) + ) + .expect((res) => expect(Array.isArray(res.body.items[2].topics)).toStrictEqual(true)) + .expect((res) => expect(typeof res.body.items[2].data).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.items[2].blockNumber).toStrictEqual("number")) + .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) + .expect((res) => expect(typeof res.body.items[2].transactionIndex).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.items[2].logIndex).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.items[2].timestamp).toStrictEqual("string")) + .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ totalItems: 3 }))) + .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ itemCount: 3 }))) + .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ itemsPerPage: 10 }))) + .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ totalPages: 1 }))) + .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ currentPage: 1 }))) + .expect((res) => + expect(res.body.links).toStrictEqual(expect.objectContaining({ first: `${decapitalizedAddress}?limit=10` })) + ) + .expect((res) => expect(res.body.links).toStrictEqual(expect.objectContaining({ previous: "" }))) + .expect((res) => expect(res.body.links).toStrictEqual(expect.objectContaining({ next: "" }))) + .expect((res) => + expect(res.body.links).toStrictEqual( + expect.objectContaining({ last: `${decapitalizedAddress}?page=1&limit=10` }) + ) + ); + }); + }); + + describe("/transactions", () => { + //@id1506 + it("Verify the transaction via /transactions", async () => { + const apiRoute = `/transactions`; + + await setTimeout(localConfig.standardPause); //works unstable without timeout + + return request(environment.blockExplorerAPI) + .get(apiRoute) + .expect(200) + .expect((res) => expect(Array.isArray(res.body.items)).toStrictEqual(true)) + .expect((res) => expect(res.body.items.length).toBe(10)) + .expect((res) => expect(typeof res.body.meta.totalItems).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.meta.itemCount).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.meta.itemsPerPage).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.meta.totalPages).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.meta.currentPage).toStrictEqual("number")) + .expect((res) => expect(typeof res.body.links.first).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.links.previous).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.links.next).toStrictEqual("string")) + .expect((res) => expect(typeof res.body.links.last).toStrictEqual("string")); + }); + }); +}); diff --git a/packages/integration-tests/tests/api/transactions/multiCall.test.ts b/packages/integration-tests/tests/api/transactions/multiCall.test.ts deleted file mode 100644 index 310a5fea9b..0000000000 --- a/packages/integration-tests/tests/api/transactions/multiCall.test.ts +++ /dev/null @@ -1,333 +0,0 @@ -import * as request from "supertest"; -import { setTimeout } from "timers/promises"; - -import { environment, localConfig } from "../../../src/config"; -import { Buffer, Logger, Token, TransactionsType, Wallets } from "../../../src/entities"; -import { Helper } from "../../../src/helper"; -import { Playbook } from "../../../src/playbook/playbook"; - -describe("Multicall transactions", () => { - jest.setTimeout(localConfig.extendedTimeout); - const playbook = new Playbook(); - const helper = new Helper(); - const bufferRoute = "src/playbook/"; - let txHash: string; - let txMulticall: string; - let contract: string; - - //@id689 - it("Deploy the Multicall contracts", async () => { - const contract: string[] = await playbook.deployMultiCallContracts(); - expect(contract[0]).toContain(Logger.txHashStartsWith); - expect(contract[1]).toContain(Logger.txHashStartsWith); - expect(contract[2]).toContain(Logger.txHashStartsWith); - }); - - //@id1464 - it("Verify the deployed Root contract via /address/{address}", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - contract = await helper.getStringFromFile(bufferRoute + Buffer.addressMultiCallRoot); - txHash = await helper.getStringFromFile(bufferRoute + Buffer.txMultiCallRoot); - - const apiRoute = `/address/${contract}`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ type: "contract" }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ address: contract }))) - .expect((res) => - expect(res.body).toStrictEqual(expect.objectContaining({ creatorAddress: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ creatorTxHash: txHash }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ balances: {} }))); - }); - - //@id1465 - it("Verify the deployed Middle contract via /address/{address}", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - contract = await helper.getStringFromFile(bufferRoute + Buffer.addressMultiCallMiddle); - txHash = await helper.getStringFromFile(bufferRoute + Buffer.txMultiCallMiddle); - - const apiRoute = `/address/${contract}`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ type: "contract" }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ address: contract }))) - .expect((res) => - expect(res.body).toStrictEqual(expect.objectContaining({ creatorAddress: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ creatorTxHash: txHash }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ balances: {} }))); - }); - - //@id1466 - it("Verify the deployed Caller contract via /address/{address}", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - contract = await helper.getStringFromFile(bufferRoute + Buffer.addressMultiCallCaller); - txHash = await helper.getStringFromFile(bufferRoute + Buffer.txMultiCallCaller); - - const apiRoute = `/address/${contract}`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ type: "contract" }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ address: contract }))) - .expect((res) => - expect(res.body).toStrictEqual(expect.objectContaining({ creatorAddress: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ creatorTxHash: txHash }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ balances: {} }))); - }); - - //@id690:I --> @id1467 - it("Use the multicall contracts", async () => { - txMulticall = await playbook.useMultiCallContracts(); - expect(txMulticall).toContain(Logger.txHashStartsWith); - }); - - describe("Verify the multicall transactions via /transactions/${txHash}", () => { - //@id1464:I --> @id1468 - it("Verify transaction for the Root contract via /transactions/${txHash}", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - - txHash = await helper.getStringFromFile(bufferRoute + Buffer.txMultiCallRoot); - const apiRoute = `/transactions/${txHash}`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ hash: txHash }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ value: "0" }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ isL1Originated: false }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ transactionIndex: 0 }))); - }); - - //@id1465:I --> @id1469 - it("Verify transaction for the Middle contract via /transactions/${txHash}", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - - txHash = await helper.getStringFromFile(bufferRoute + Buffer.txMultiCallMiddle); - const apiRoute = `/transactions/${txHash}`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ hash: txHash }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ value: "0" }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ isL1Originated: false }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ transactionIndex: 0 }))); - }); - - //@id1466:I --> @id1470 - it("Verify transaction for the Caller contract via /transactions/${txHash}", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - - txHash = await helper.getStringFromFile(bufferRoute + Buffer.txMultiCallCaller); - const apiRoute = `/transactions/${txHash}`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ hash: txHash }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ value: "0" }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ isL1Originated: false }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ transactionIndex: 0 }))); - }); - - //@id1471 - it("Verify transaction for the use multicall contract via /transactions/${txHash}", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - - txHash = await helper.getStringFromFile(bufferRoute + Buffer.txUseMultiCallContracts); - const apiRoute = `/transactions/${txHash}`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ hash: txHash }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ value: "0" }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ isL1Originated: false }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ transactionIndex: 0 }))); - }); - }); - - describe("Verify the multicall transactions via /transactions/${txHash}/transfers", () => { - //@id1472 - it("Verify transaction for the Root contract via /transactions/${txHash}/transfers", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - - txHash = await helper.getStringFromFile(bufferRoute + Buffer.txMultiCallRoot); - const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) - ) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))); - }); - - //@id1473 - it("Verify transaction for the Middle contract via /transactions/${txHash}/transfers", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - - txHash = await helper.getStringFromFile(bufferRoute + Buffer.txMultiCallMiddle); - const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) - ) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))); - }); - - //@id1474 - it("Verify transaction for the Caller contract via /transactions/${txHash}/transfers", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - - txHash = await helper.getStringFromFile(bufferRoute + Buffer.txMultiCallCaller); - const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) - ) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))); - }); - - //@id1475 - it("Verify transaction for the use multicall contract via /transactions/${txHash}/transfers", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - - txHash = await helper.getStringFromFile(bufferRoute + Buffer.txUseMultiCallContracts); - - const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; - await setTimeout(localConfig.standardPause); //works unstable without timeout - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) - ) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))); - }); - }); -}); diff --git a/packages/integration-tests/tests/api/transactions/multiTransfer.test.ts b/packages/integration-tests/tests/api/transactions/multiTransfer.test.ts deleted file mode 100644 index 7bdde1c14f..0000000000 --- a/packages/integration-tests/tests/api/transactions/multiTransfer.test.ts +++ /dev/null @@ -1,306 +0,0 @@ -import * as request from "supertest"; -import { setTimeout } from "timers/promises"; - -import { environment, localConfig } from "../../../src/config"; -import { Buffer, Logger, Token, TransactionsType, Wallets } from "../../../src/entities"; -import { Helper } from "../../../src/helper"; -import { Playbook } from "../../../src/playbook/playbook"; - -describe("Mulitransfer ETH", () => { - jest.setTimeout(localConfig.extendedTimeout); - const playbook = new Playbook(); - const helper = new Helper(); - const bufferRoute = "src/playbook/"; - let txHash: string; - let txMultiTransfer: string[]; - let token: string; - let contract: string; - - beforeEach(async () => { - contract = await helper.getStringFromFile(bufferRoute + Buffer.addressMultiTransferETH); - }); - - //@id690 - it("Deploy the multitransfer ETH contract to the L2", async () => { - contract = await playbook.deployMultiTransferETH(); - expect(contract).toContain(Logger.txHashStartsWith); - }); - - //@id1476 - it("Verify the deployed multitransfer contract via /address/{address}", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - - const apiRoute = `/address/${contract}`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ address: contract }))) - .expect((res) => - expect(res.body).toStrictEqual(expect.objectContaining({ creatorAddress: Wallets.richWalletAddress })) - ); - }); - - //@id690 --> //@id1477 - it("Call the multitransfer contract to the L2", async () => { - txMultiTransfer = await playbook.useMultiTransferETH(); - expect(txMultiTransfer[0]).toContain(Logger.txHashStartsWith); - expect(txMultiTransfer[1]).toContain(Logger.txHashStartsWith); - expect(txMultiTransfer[2]).toContain(Logger.txHashStartsWith); - }); - - describe("Verify the multitransfer transactions via /transactions/${txHash}", () => { - //@id1478 - it("Verify transaction for the ETH via /transactions/${txHash}", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - - txHash = await helper.getStringFromFile(bufferRoute + Buffer.txMultiTransferETH); - const apiRoute = `/transactions/${txHash}`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ hash: txHash }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ to: contract }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ isL1Originated: false }))); - }); - - //@id1479 - it("Verify transaction for the Custom Token I via /transactions/${txHash}", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - - txHash = await helper.getStringFromFile(bufferRoute + Buffer.txMultiTransferCustomTokenI); - contract = await helper.getStringFromFile(bufferRoute + Buffer.L2); - const apiRoute = `/transactions/${txHash}`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ hash: txHash }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ to: contract }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ isL1Originated: false }))); - }); - - //@id1480 - it("Verify transaction for the Custom Token II via /transactions/${txHash}", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - - txHash = await helper.getStringFromFile(bufferRoute + Buffer.txMultiTransferCustomTokenII); - contract = await helper.getStringFromFile(bufferRoute + Buffer.L2deposited); - const apiRoute = `/transactions/${txHash}`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ hash: txHash }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ to: contract }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ isL1Originated: false }))); - }); - }); - - describe("Verify the multitransfer transactions via /transactions/${txHash}/transfer", () => { - beforeAll(async () => { - token = await helper.getStringFromFile(bufferRoute + Buffer.L2); - }); - - //@id1481 - it("Verify transaction for the ETH via /transactions/${txHash}/transfers", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - - txHash = await helper.getStringFromFile(bufferRoute + Buffer.txMultiTransferETH); - const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: contract }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.transfer })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ token: null }))) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) - ) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) - ) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ token: null }))); - }); - - //@id1482 - it("Verify transaction for the Custom tokenI via /transactions/${txHash}/transfers", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - contract = await helper.getStringFromFile(bufferRoute + Buffer.addressMultiTransferETH); - txHash = await helper.getStringFromFile(bufferRoute + Buffer.txMultiTransferCustomTokenI); - const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: contract }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: token }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.transfer })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual( - expect.objectContaining({ - token: { - l2Address: token, - l1Address: null, - symbol: "L2", - name: "L2 ERC20 token", - decimals: 18, - }, - }) - ) - ) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) - ) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) - ) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ token: null }))); - }); - - //@id1483 - it("Verify transaction for the Custom tokenII via /transactions/${txHash}/transfers", async () => { - await setTimeout(localConfig.standardPause); //works unstable without timeout - - const tokenL1 = await helper.getStringFromFile(bufferRoute + Buffer.L1); - token = await helper.getStringFromFile(bufferRoute + Buffer.L2deposited); - txHash = await helper.getStringFromFile(bufferRoute + Buffer.txMultiTransferCustomTokenII); - const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; - - return ( - request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual( - expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address }) - ) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: contract }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash })) - ) - // .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.transfer })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual( - expect.objectContaining({ - token: { - l2Address: token, - l1Address: tokenL1, - symbol: "L1", - name: "L1 ERC20 token", - decimals: 18, - }, - }) - ) - ) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) - ) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ transactionHash: txHash })) - ) - .expect((res) => - expect(res.body.items[2]).toStrictEqual( - expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address }) - ) - ) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) - ) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ token: null }))) - ); - }); - }); -}); diff --git a/packages/integration-tests/tests/api/transactions/transaction.test.ts b/packages/integration-tests/tests/api/transactions/transaction.test.ts deleted file mode 100644 index c8431a49b7..0000000000 --- a/packages/integration-tests/tests/api/transactions/transaction.test.ts +++ /dev/null @@ -1,422 +0,0 @@ -import * as request from "supertest"; -import { setTimeout } from "timers/promises"; - -import { environment, localConfig } from "../../../src/config"; -import { Buffer, Logger, Token, TransactionsStatus, TransactionsType, Wallets } from "../../../src/entities"; -import { Helper } from "../../../src/helper"; -import { Playbook } from "../../../src/playbook/playbook"; - -describe("Transactions", () => { - jest.setTimeout(localConfig.standardTimeout); - const playbook = new Playbook(); - const helper = new Helper(); - const bufferRoute = "src/playbook/"; - let txHash: string; - let token: string; - let contract: string; - let emptyWallet: string; - - describe("Paymaster", () => { - jest.setTimeout(localConfig.extendedTimeout); - - beforeEach(async () => { - token = await helper.getStringFromFile(bufferRoute + Buffer.customToken); - txHash = await helper.getStringFromFile(bufferRoute + Buffer.paymasterTx); - emptyWallet = await helper.getStringFromFile(bufferRoute + Buffer.emptyWalletAddress); - }); - - //@id1450 - it("Deploy contract via Paymaster", async () => { - const result = await playbook.deployViaPaymaster(); - expect(result[0]).toContain(Logger.txHashStartsWith); - }); - - //@id644 - it("Transaction via Paymaster usage", async () => { - const result = await playbook.usePaymaster(); - expect(result).toContain(Logger.txHashStartsWith); - }); - - //@id1451 - it("Verify the custom token includes paymaster transaction", async () => { - const paymaster = await helper.getStringFromFile(bufferRoute + Buffer.paymaster); - const apiRoute = `/tokens/${token}/transfers?page=1&limit=10`; - - await setTimeout(localConfig.standardPause); //works unstable without timeout - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: emptyWallet }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: paymaster }))) - .expect((res) => expect(res.body.items[0].token).toStrictEqual(expect.objectContaining({ l2Address: token }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.transfer })) - ); - }); - - //@id1452 - it("Verify transaction through Paymaster", async () => { - const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; - const paymasterAddress = await helper.getStringFromFile(bufferRoute + Buffer.paymaster); - - await setTimeout(localConfig.standardPause); //works unstable without timeout - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: emptyWallet }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: paymasterAddress }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: token }))) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.transfer })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => - expect(res.body.items[0]).toStrictEqual( - expect.objectContaining({ - token: { - l2Address: token, - l1Address: null, - symbol: "MyToken", - name: "MyToken", - decimals: 18, - }, - }) - ) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: paymasterAddress }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ token: null }))) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) - ) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ to: paymasterAddress }))) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) - ) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ token: null }))); - }); - }); - - describe("Transaction with failed state", () => { - beforeAll(async () => { - const bufferFile = bufferRoute + Buffer.L2; - token = await helper.getStringFromFile(bufferFile); - txHash = await playbook.transferFailedState(token); - return [txHash, token]; - }); - - //@id645 - it("Verify the transactions with failed state", async () => { - const apiRoute = `/transactions/${txHash}?page=1&limit=10`; - - await setTimeout(localConfig.standardPause); //works unstable without timeout - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body.from).toStrictEqual(Wallets.richWalletAddress)) - .expect((res) => expect(res.body.to).toStrictEqual(token)) - .expect((res) => expect(res.body.hash).toStrictEqual(txHash)) - .expect((res) => expect(res.body.status).toStrictEqual(TransactionsStatus.failed)); - }); - }); - - describe("Greeter", () => { - jest.setTimeout(localConfig.extendedTimeout); - - beforeEach(async () => { - contract = await helper.getStringFromFile(bufferRoute + Buffer.greeterL2); - txHash = await helper.getStringFromFile(bufferRoute + Buffer.executeGreeterTx); - }); - - //@id597 - it("Deploy the Greeter contract to the L2", async () => { - contract = await playbook.deployGreeterToL2(); - expect(contract).toContain(Logger.txHashStartsWith); - }); - - //@id1449 - it("Verify the deployed Greeter contract via /address/{address}", async () => { - const apiRoute = `/address/${contract}`; - - await setTimeout(localConfig.standardPause); //works unstable without timeout - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ address: contract }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ balances: {} }))); - }); - - //@id604 - it("Use the Greeter contract - execute SetGreeting", async () => { - const executedContract = await playbook.useGreeter(); - expect(executedContract).toContain(Logger.txHashStartsWith); - }); - - //@id1454 - it("Verify the transaction after SetGreeting execution via transactions/{transactionHash}", async () => { - const apiRoute = `/transactions/${txHash}?page=1&limit=10`; - - await setTimeout(localConfig.standardPause); //works unstable without timeout - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ hash: txHash }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ to: contract }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ value: "0" }))) - .expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ isL1Originated: false }))); - }); - - //@id1455 - it("Verify the transaction after SetGreeting execution via transactions/{transactionHash}/transfers", async () => { - const apiRoute = `/transactions/${txHash}/transfers?page=1&limit=10`; - await setTimeout(localConfig.standardPause); //works unstable without timeout - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: Token.ETHER_PULL_Address })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: TransactionsType.fee })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ token: null }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Token.ETHER_PULL_Address })) - ) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: TransactionsType.refund })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ token: null }))); - }); - }); - - describe("Transactions for the /address/{address} endpoints", () => { - jest.setTimeout(localConfig.extendedTimeout); - - //@id1510 - it("Verify the transaction via /address/{address}/logs", async () => { - contract = await helper.getStringFromFile(bufferRoute + Buffer.greeterL2); - txHash = await helper.getStringFromFile(bufferRoute + Buffer.executeGreeterTx); - - const apiRoute = `/address/${contract}/logs`; - const decapitalizedAddress = apiRoute.slice(1).toLowerCase(); - - await setTimeout(localConfig.standardPause); //works unstable without timeout - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ address: contract }))) - .expect((res) => expect(Array.isArray(res.body.items[0].topics)).toStrictEqual(true)) - .expect((res) => expect(typeof res.body.items[0].data).toStrictEqual("string")) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => expect(typeof res.body.items[0].transactionIndex).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.items[0].logIndex).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.items[0].timestamp).toStrictEqual("string")) - .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ totalItems: 1 }))) - .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ itemCount: 1 }))) - .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ itemsPerPage: 10 }))) - .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ totalPages: 1 }))) - .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ currentPage: 1 }))) - .expect((res) => - expect(res.body.links).toStrictEqual(expect.objectContaining({ first: `${decapitalizedAddress}?limit=10` })) - ) - .expect((res) => expect(res.body.links).toStrictEqual(expect.objectContaining({ previous: "" }))) - .expect((res) => expect(res.body.links).toStrictEqual(expect.objectContaining({ next: "" }))) - .expect((res) => - expect(res.body.links).toStrictEqual( - expect.objectContaining({ last: `${decapitalizedAddress}?page=1&limit=10` }) - ) - ); - }); - - //@id1509 - it("Verify the transaction via /address/{address}/transfers", async () => { - contract = await helper.getStringFromFile(bufferRoute + Buffer.paymaster); - emptyWallet = await helper.getStringFromFile(bufferRoute + Buffer.emptyWalletAddress); - txHash = await helper.getStringFromFile(bufferRoute + Buffer.paymasterTx); - - const customTokenAddress = await helper.getStringFromFile(bufferRoute + Buffer.customToken); - const apiRoute = `/address/${contract}/transfers`; - const decapitalizedAddress = apiRoute.slice(1).toLowerCase(); - - await setTimeout(localConfig.standardPause); //works unstable without timeout - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ from: emptyWallet }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ to: contract }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => expect(typeof res.body.items[0].timestamp).toStrictEqual("string")) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ amount: "1" }))) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ tokenAddress: customTokenAddress })) - ) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ type: "transfer" }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => - expect(res.body.items[0].token).toStrictEqual(expect.objectContaining({ l2Address: customTokenAddress })) - ) - .expect((res) => expect(res.body.items[0].token).toStrictEqual(expect.objectContaining({ l1Address: null }))) - .expect((res) => expect(res.body.items[0].token).toStrictEqual(expect.objectContaining({ symbol: "MyToken" }))) - .expect((res) => expect(res.body.items[0].token).toStrictEqual(expect.objectContaining({ name: "MyToken" }))) - .expect((res) => expect(res.body.items[0].token).toStrictEqual(expect.objectContaining({ decimals: 18 }))) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ from: Wallets.richWalletAddress })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ to: contract }))) - .expect((res) => expect(typeof res.body.items[1].timestamp).toStrictEqual("string")) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ amount: "30000000000000000" })) - ) - .expect((res) => - expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ tokenAddress: Token.ETHER_ERC20_Address })) - ) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ type: "transfer" }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ fields: null }))) - .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ totalItems: 2 }))) - .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ itemCount: 2 }))) - .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ itemsPerPage: 10 }))) - .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ totalPages: 1 }))) - .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ currentPage: 1 }))) - .expect((res) => - expect(res.body.links).toStrictEqual(expect.objectContaining({ first: `${decapitalizedAddress}?limit=10` })) - ) - .expect((res) => expect(res.body.links).toStrictEqual(expect.objectContaining({ previous: "" }))) - .expect((res) => expect(res.body.links).toStrictEqual(expect.objectContaining({ next: "" }))) - .expect((res) => - expect(res.body.links).toStrictEqual( - expect.objectContaining({ last: `${decapitalizedAddress}?page=1&limit=10` }) - ) - ); - }); - }); - describe("Transactions for the /transactions endpoint", () => { - jest.setTimeout(localConfig.extendedTimeout); - - //@id1506 - it("Verify the transaction via /transactions", async () => { - contract = await helper.getStringFromFile(bufferRoute + Buffer.greeterL2); - txHash = await helper.getStringFromFile(bufferRoute + Buffer.executeGreeterTx); - - const apiRoute = `/transactions`; - - await setTimeout(localConfig.standardPause); //works unstable without timeout - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => expect(Array.isArray(res.body.items)).toStrictEqual(true)) - .expect((res) => expect(res.body.items.length).toBe(10)) - .expect((res) => expect(typeof res.body.meta.totalItems).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.meta.itemCount).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.meta.itemsPerPage).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.meta.totalPages).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.meta.currentPage).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.links.first).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.links.previous).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.links.next).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.links.last).toStrictEqual("string")); - }); - - //@id1507 - it("Verify the transaction via /transactions/{transactionHash}/logs", async () => { - contract = await helper.getStringFromFile(bufferRoute + Buffer.greeterL2); - txHash = await helper.getStringFromFile(bufferRoute + Buffer.executeGreeterTx); - - const apiRoute = `/transactions/${txHash}/logs`; - const decapitalizedAddress = apiRoute.slice(1).toLowerCase(); - - await setTimeout(localConfig.standardPause); //works unstable without timeout - - return request(environment.blockExplorerAPI) - .get(apiRoute) - .expect(200) - .expect((res) => - expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ address: Token.ETHER_ERC20_Address })) - ) - .expect((res) => expect(Array.isArray(res.body.items[0].topics)).toStrictEqual(true)) - .expect((res) => expect(typeof res.body.items[0].data).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.items[0].blockNumber).toStrictEqual("number")) - .expect((res) => expect(res.body.items[0]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => expect(typeof res.body.items[0].transactionIndex).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.items[0].logIndex).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.items[0].timestamp).toStrictEqual("string")) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ address: contract }))) - .expect((res) => expect(Array.isArray(res.body.items[1].topics)).toStrictEqual(true)) - .expect((res) => expect(typeof res.body.items[1].data).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.items[1].blockNumber).toStrictEqual("number")) - .expect((res) => expect(res.body.items[1]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => expect(typeof res.body.items[1].transactionIndex).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.items[1].logIndex).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.items[1].timestamp).toStrictEqual("string")) - .expect((res) => - expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ address: Token.ETHER_ERC20_Address })) - ) - .expect((res) => expect(Array.isArray(res.body.items[2].topics)).toStrictEqual(true)) - .expect((res) => expect(typeof res.body.items[2].data).toStrictEqual("string")) - .expect((res) => expect(typeof res.body.items[2].blockNumber).toStrictEqual("number")) - .expect((res) => expect(res.body.items[2]).toStrictEqual(expect.objectContaining({ transactionHash: txHash }))) - .expect((res) => expect(typeof res.body.items[2].transactionIndex).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.items[2].logIndex).toStrictEqual("number")) - .expect((res) => expect(typeof res.body.items[2].timestamp).toStrictEqual("string")) - .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ totalItems: 3 }))) - .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ itemCount: 3 }))) - .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ itemsPerPage: 10 }))) - .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ totalPages: 1 }))) - .expect((res) => expect(res.body.meta).toStrictEqual(expect.objectContaining({ currentPage: 1 }))) - .expect((res) => - expect(res.body.links).toStrictEqual(expect.objectContaining({ first: `${decapitalizedAddress}?limit=10` })) - ) - .expect((res) => expect(res.body.links).toStrictEqual(expect.objectContaining({ previous: "" }))) - .expect((res) => expect(res.body.links).toStrictEqual(expect.objectContaining({ next: "" }))) - .expect((res) => - expect(res.body.links).toStrictEqual( - expect.objectContaining({ last: `${decapitalizedAddress}?page=1&limit=10` }) - ) - ); - }); - }); -}); diff --git a/packages/integration-tests/tests/hooks/global.ts b/packages/integration-tests/tests/hooks/global.ts new file mode 100644 index 0000000000..2512d8878f --- /dev/null +++ b/packages/integration-tests/tests/hooks/global.ts @@ -0,0 +1,16 @@ +import { Buffer } from "../../src/entities"; +import { Helper } from "../../src/helper"; +import { Playbook } from "../../src/playbook/playbook"; + +export default async () => { + const playbook = new Playbook(); + const helper = new Helper(); + const bufferRoute = "src/playbook/"; + + await playbook.deployERC20toL2(); + await playbook.deployERC20toL1(); + await playbook.depositETH("0.0000001"); + const bufferFile = bufferRoute + Buffer.L1; + const token = await helper.getStringFromFile(bufferFile); + await playbook.depositERC20("100", token, 18); +};