Skip to content

Commit

Permalink
feature(hardhat-zksync-network-helpers): initial implementation and t…
Browse files Browse the repository at this point in the history
…ests
  • Loading branch information
nikola-bozin-txfusion committed Dec 19, 2023
1 parent 9e15365 commit 4a5fcc0
Show file tree
Hide file tree
Showing 15 changed files with 243 additions and 1 deletion.
7 changes: 7 additions & 0 deletions packages/hardhat-zksync-network-helpers/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
extends: [`${__dirname}/../../config/eslint/eslintrc.cjs`],
parserOptions: {
project: `${__dirname}/eslint-tsconfig.json`,
sourceType: "module",
},
};
5 changes: 5 additions & 0 deletions packages/hardhat-zksync-network-helpers/.mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"require": "ts-node/register/files",
"ignore": ["test/fixture-projects/**/*"],
"timeout": 10000
}
5 changes: 5 additions & 0 deletions packages/hardhat-zksync-network-helpers/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/node_modules
/dist
/test/fixture-projects/**/artifacts
/test/fixture-projects/**/cache
CHANGELOG.md
5 changes: 5 additions & 0 deletions packages/hardhat-zksync-network-helpers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# hardhat-zksync-network-helpers

[Hardhat](https://hardhat.org/) plugin that is a plugin that provides set of utility functions to interact with [In-Memory Node] (https://era.zksync.io/docs/tools/testing/era-test-node.html).

Check out the [documentation page](https://era.zksync.io/docs/tools/hardhat/) for more detailed explanation on how to use hardhat-zksync-network-helpers.
6 changes: 6 additions & 0 deletions packages/hardhat-zksync-network-helpers/eslint-tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"exclude": [
"./dist"
],
"extends": "./tsconfig.json"
}
78 changes: 78 additions & 0 deletions packages/hardhat-zksync-network-helpers/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"name": "@matterlabs/hardhat-zksync-network-helpers",
"version": "0.0.1-beta.1",
"description": "Hardhat plugin for interacting with In Memory Node",
"repository": "github:matter-labs/hardhat-zksync",
"homepage": "https://github.com/matter-labs/hardhat-zksync/tree/main/packages/hardhat-zksync-ethers",
"author": "Matter Labs",
"license": "MIT",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"keywords": [
"ethereum",
"smart-contracts",
"hardhat",
"hardhat-plugin",
"zkSync",
"zksync-ethers"
],
"scripts": {
"lint": "yarn eslint",
"prettier:check": "yarn prettier --check",
"lint:fix": "yarn eslint --fix",
"fmt": "yarn prettier --write",
"eslint": "eslint 'src/**/*.ts' 'test/**/*.ts'",
"prettier": "prettier 'src/**/*.ts' 'test/**/*.ts'",
"test": "NODE_ENV=test mocha test/**/*.ts --no-timeout --exit",
"build": "tsc --build .",
"clean": "rimraf dist"
},
"files": [
"dist/",
"src/",
"LICENSE",
"README.md"
],
"dependencies": {
"chalk": "5.3.0",
"ethereumjs-util": "^7.1.5"
},
"devDependencies": {
"@types/chai": "^4.2.0",
"@types/chai-as-promised": "^7.1.3",
"@types/lodash.isequal": "^4.5.6",
"@types/mocha": ">=9.1.0",
"@types/node": "^16.0.0",
"@types/sinon": "^9.0.8",
"@typescript-eslint/eslint-plugin": "6.13.1",
"@typescript-eslint/parser": "6.13.1",
"c8": "^8.0.1",
"chai": "^4.2.0",
"eslint": "^8.54.0",
"eslint-config-prettier": "9.0.0",
"eslint-plugin-import": "2.29.0",
"eslint-plugin-no-only-tests": "3.1.0",
"eslint-plugin-prettier": "5.0.1",
"ethers": "^6.7.1",
"hardhat": "^2.19.2",
"mocha": "^10.0.0",
"prettier": "3.1.0",
"rimraf": "^5.0.5",
"rlp": "3.0.0",
"sinon": "^9.0.0",
"ts-node": "^10.9.1",
"typescript": "^5.1.6",
"zksync-ethers": "^6.0.0"
},
"peerDependencies": {
"ethers": "^6.7.1",
"zksync-ethers": "^6.0.0"
},
"prettier": {
"tabWidth": 4,
"printWidth": 120,
"parser": "typescript",
"singleQuote": true,
"bracketSpacing": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { assertValidAddress, getProvider } from "../utils";

export async function impersonateAccount(address: string): Promise<void> {
const provider = await getProvider();

assertValidAddress(address);

await provider.send(
"hardhat_impersonateAccount",
[address],
);
}
13 changes: 13 additions & 0 deletions packages/hardhat-zksync-network-helpers/src/helpers/mine.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { NumberLike } from "../types";
import { getProvider, toRpcQuantity } from "../utils";

export async function mine(blocks:NumberLike=1,options:{interval?:NumberLike}={}):Promise<void>{
const provider = await getProvider();
const interval = options.interval ?? 1;

const hexBlocks = toRpcQuantity(blocks);
const hexInterval = toRpcQuantity(interval);

const result = await provider.send("hardhat_mine", [hexBlocks, hexInterval]);
return result;
}
21 changes: 21 additions & 0 deletions packages/hardhat-zksync-network-helpers/src/helpers/setBalance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { NumberLike } from "../types";
import {
getProvider,
assertValidAddress,
toRpcQuantity,
} from "../utils";

export async function setBalance(
address: string,
balance: NumberLike
): Promise<void> {
const provider = await getProvider();

assertValidAddress(address);
const balanceHex = toRpcQuantity(balance);

await provider.send(
"hardhat_setBalance",
[address, balanceHex],
);
}
3 changes: 3 additions & 0 deletions packages/hardhat-zksync-network-helpers/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export {mine} from './helpers/mine'
export {impersonateAccount} from './helpers/impersonateAccount'
export {setBalance} from './helpers/setBalance'
4 changes: 4 additions & 0 deletions packages/hardhat-zksync-network-helpers/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type NumberLike =
| number
| bigint
| string
50 changes: 50 additions & 0 deletions packages/hardhat-zksync-network-helpers/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Provider } from 'zksync-ethers';
import { NumberLike } from './types';
import type EthereumJSUtil from "ethereumjs-util";


export async function getProvider(): Promise<Provider> {
const { Provider } = await import('zksync-ethers');
const provider = new Provider('http://localhost:8011');
return provider;
}

export function toRpcQuantity(x: NumberLike): string {
let hex: string;

if (typeof x === "number" || typeof x === "bigint") {
// TODO: check that number is safe
hex = `0x${x.toString(16)}`;
} else if (typeof x === "string") {
if (!x.startsWith("0x")) {
throw new Error("Only 0x-prefixed hex-encoded strings are accepted");
}
hex = x;
} else if (x && typeof (x as any).toHexString === 'function') {
hex = (x as { toHexString: () => string }).toHexString();
} else if (x && typeof (x as any).toString === 'function') {
hex = (x as { toString: (radix: number) => string }).toString(16);
} else {
throw new Error(`Cannot convert ${x} to an RPC quantity`);
}

if (hex === "0x0") return hex;

return hex.startsWith("0x") ? hex.replace(/0x0+/, "0x") : `0x${hex}`;
}

export function assertValidAddress(address: string): void {
const { isValidChecksumAddress, isValidAddress } =
require("ethereumjs-util") as typeof EthereumJSUtil;

if (!isValidAddress(address)) {
throw new Error(`${address} is not a valid address`);
}

const hasChecksum = address !== address.toLowerCase();
if (hasChecksum && !isValidChecksumAddress(address)) {
throw new Error(
`Address ${address} has an invalid checksum`
);
}
}
26 changes: 26 additions & 0 deletions packages/hardhat-zksync-network-helpers/test/tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { assert } from 'console';
import * as helpers from '../src/index'
import { Provider } from 'zksync-ethers';

describe('Plugin tests', async function () {
const provider = new Provider('http://localhost:8011');

it('tests mining blocks',async function() {
const blockNumber = await provider.getBlockNumber();
await helpers.mine(5);
await new Promise((resolve) => setTimeout(resolve, 1500));
const blockNumber2 = await provider.getBlockNumber();
assert(blockNumber+5===blockNumber2)
})


it('tests set balance',async function() {
const result = await provider.getAllAccountBalances("0x36615Cf349d7F6344891B1e7CA7C72883F5dc049");
console.info(result);
helpers.setBalance("0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",100n)
await new Promise((resolve) => setTimeout(resolve, 1500));
const result2 = await provider.getAllAccountBalances("0x36615Cf349d7F6344891B1e7CA7C72883F5dc049");
console.info(result2);
assert(result2['0x000000000000000000000000000000000000800a']===100n);
})
})
7 changes: 7 additions & 0 deletions packages/hardhat-zksync-network-helpers/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../config/typescript/tsconfig.json",
"compilerOptions": {
"outDir": "./dist"
},
"exclude": ["./dist", "./node_modules", "./test/**/*"]
}
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3633,7 +3633,7 @@ ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.1:
ethjs-util "0.1.6"
rlp "^2.2.3"

ethereumjs-util@^7.0.3:
ethereumjs-util@^7.0.3, ethereumjs-util@^7.1.5:
version "7.1.5"
resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181"
integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==
Expand Down

0 comments on commit 4a5fcc0

Please sign in to comment.