Skip to content

Commit

Permalink
Merge pull request #4 from FhenixProtocol/faucet-task
Browse files Browse the repository at this point in the history
Added task to use the faucet for a given address (this adds an ethers dependency -need to make sure this doesn't break anything)
  • Loading branch information
Cashmaney authored Feb 24, 2024
2 parents 36695e2 + 893224f commit 56af5ae
Show file tree
Hide file tree
Showing 12 changed files with 160 additions and 26 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ jobs:
npm-publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
- uses: pnpm/action-setup@v2
- uses: pnpm/action-setup@v3
with:
version: 8
- name: Set publishing config
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: docker/login-action@v3.0.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: pnpm/action-setup@v2
- uses: pnpm/action-setup@v3
with:
version: 8
run_install: true
Expand Down
14 changes: 14 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fhenix-hardhat-plugin-root",
"version": "0.1.0-beta.15",
"version": "0.1.1",
"license": "MIT",
"scripts": {
"preinstall": "npx only-allow pnpm",
Expand Down
2 changes: 1 addition & 1 deletion packages/fhenix-hardhat-docker/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fhenix-hardhat-docker",
"version": "0.1.0-beta.15",
"version": "0.1.1",
"description": "Hardhat plugin to run Fhenix node locally",
"repository": "github:FhenixProtocol/fhenix-hardhat-plugin",
"author": "Fhe Labs",
Expand Down
4 changes: 3 additions & 1 deletion packages/fhenix-hardhat-plugin/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fhenix-hardhat-plugin",
"version": "0.1.0-beta.15",
"version": "0.1.1",
"description": "Hardhat TypeScript plugin boilerplate",
"repository": "github:FhenixProtocol/fhenix-hardhat-plugin",
"author": "Fhe Labs",
Expand Down Expand Up @@ -45,6 +45,8 @@
},
"dependencies": {
"axios": "^1.6.5",
"chalk": "^4.1.2",
"ethers": "^6.0.0",
"fhenixjs": "0.1.0-beta.5"
},
"peerDependencies": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import axios from "axios";
import {
FhenixClient,
getPermit,
Expand All @@ -7,6 +6,8 @@ import {
} from "fhenixjs";
import { HardhatRuntimeEnvironment } from "hardhat/types";

import { getFunds } from "./common";

interface FhenixHardhatRuntimeEnvironmentConfig {
rpcPort: number;
wsPort: number;
Expand Down Expand Up @@ -37,21 +38,7 @@ export class FhenixHardhatRuntimeEnvironment extends FhenixClient {
}

public async getFunds(address: string) {
const response = await axios.get(
`http://localhost:${this.config.faucetPort}/faucet?address=${address}`,
);

if (response.status !== 200) {
throw new Error(
`Failed to get funds from faucet: ${response.status}: ${response.statusText}`,
);
}

if (!response.data?.message?.includes("ETH successfully sent to address")) {
throw new Error(
`Failed to get funds from faucet: ${JSON.stringify(response.data)}`,
);
}
await getFunds(address, `http://localhost:${this.config.faucetPort}`);
}

public async createPermit(
Expand Down
19 changes: 19 additions & 0 deletions packages/fhenix-hardhat-plugin/src/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import axios from "axios";

export const getFunds = async (address: string, url?: string) => {
const faucetUrl = url || `http://localhost:42000`;

const response = await axios.get(`${faucetUrl}/faucet?address=${address}`);

if (response.status !== 200) {
throw new Error(
`Failed to get funds from faucet: ${response.status}: ${response.statusText}`,
);
}

if (!response.data?.message?.includes("ETH successfully sent to address")) {
throw new Error(
`Failed to get funds from faucet: ${JSON.stringify(response.data)}`,
);
}
};
1 change: 1 addition & 0 deletions packages/fhenix-hardhat-plugin/src/const.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const TASK_FHENIX_USE_FAUCET = "task:fhenix:usefaucet";
99 changes: 97 additions & 2 deletions packages/fhenix-hardhat-plugin/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { extendConfig, extendEnvironment } from "hardhat/config";
import chalk from "chalk";
import { HDNodeWallet, Wallet } from "ethers";
import { extendConfig, extendEnvironment, task, types } from "hardhat/config";
import { lazyObject } from "hardhat/plugins";
import { HttpNetworkConfig, HttpNetworkHDAccountsConfig } from "hardhat/types";

import { getFunds } from "./common";
import { TASK_FHENIX_USE_FAUCET } from "./const";
import { FhenixHardhatRuntimeEnvironment } from "./FhenixHardhatRuntimeEnvironment";
import "./type-extensions";

// This import is needed to let the TypeScript compiler know that it should include your type
// extensions in your npm package's types file.
import "./type-extensions";

extendEnvironment((hre) => {
hre.fhenixjs = lazyObject(() => {
Expand All @@ -19,6 +25,10 @@ extendEnvironment((hre) => {
});

extendConfig((config, userConfig) => {
if (userConfig.networks && userConfig.networks.localfhenix) {
return;
}

config.networks.localfhenix = {
gas: "auto",
gasMultiplier: 1.2,
Expand All @@ -36,3 +46,88 @@ extendConfig((config, userConfig) => {
},
};
});

// Main task of the plugin. It starts the server and listens for requests.
task(TASK_FHENIX_USE_FAUCET, "Fund an account from the faucet")
.addOptionalParam("address", "Address to fund", undefined, types.string)
.addOptionalParam("account", "account number to fund", 0, types.int)
.addOptionalParam(
"url",
"Optional Faucet URL",
"http://localhost:42000",
types.string,
)
.setAction(
async (
{
address,
account,
url,
}: // log,
{
address: string;
account: number;
url: string;
},
{ network },
) => {
if (network.name !== "localfhenix" && !url) {
console.info(
chalk.yellow(
`Programmatic faucet only supported for localfhenix. Please provide a faucet url, or use the public testnet faucet at https://faucet.fhenix.zone`,
),
);
return;
}

const networkConfig = network.config;

let foundAddress = "";
if (Object(networkConfig).hasOwnProperty("url")) {
const x = networkConfig as HttpNetworkConfig;
if (x.accounts === "remote") {
console.log(
chalk.yellow(`Remote network detected, cannot use faucet`),
);
return;
} else if (Object(x.accounts).hasOwnProperty("mnemonic")) {
const networkObject = x.accounts as HttpNetworkHDAccountsConfig;

const mnemonic = networkObject.mnemonic;

const path = `${networkObject.path || "m/44'/60'/0'/0"}/${
account || networkObject.initialIndex || 0
}`;

const wallet = HDNodeWallet.fromPhrase(mnemonic, "", path);

foundAddress = wallet.address;
} else {
const accounts = x.accounts as string[];
const privateKey = accounts[account || 0];
const wallet = new Wallet(privateKey);
foundAddress = wallet.address;
}
}

const myAddress = address || foundAddress;

if (!myAddress) {
console.info(chalk.red(`Failed to get address from hardhat`));
return;
}

console.info(chalk.green(`Getting funds from faucet for ${myAddress}`));

try {
await getFunds(myAddress, url);
console.info(chalk.green(`Success!`));
} catch (e) {
console.info(
chalk.red(
`failed to get funds from faucet @ ${url} for ${address}: ${e}`,
),
);
}
},
);
10 changes: 10 additions & 0 deletions packages/fhenix-hardhat-plugin/test/project.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { assert, expect } from "chai";
import { EncryptedUint8 } from "fhenixjs";

import { TASK_FHENIX_USE_FAUCET } from "../src/const";
import { FhenixHardhatRuntimeEnvironment } from "../src/FhenixHardhatRuntimeEnvironment";

import { useEnvironment } from "./helpers";
Expand Down Expand Up @@ -43,6 +44,15 @@ describe("Test Fhenix Plugin", function () {
assert.equal(this.hre.fhenixjs.sayHello(), "hello");
});
});

describe("Test Faucet command", async function () {
useEnvironment("localfhenix");
// todo: add a test that mocks the fhenixjs client and checks that the plugin works

it("checks that the faucet works", async function () {
await this.hre.run(TASK_FHENIX_USE_FAUCET);
});
});
});

describe("Unit tests examples", function () {
Expand Down
8 changes: 7 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 56af5ae

Please sign in to comment.