Skip to content

Commit

Permalink
fhenixsdk.initializeWithHHSigner fixes (#20)
Browse files Browse the repository at this point in the history
* Update fhenixjs version with sdk fixes

* `initializeWithHHSigner` references correct `fhenixsdk` instance, fixes fields

* Update tests to use result object instead of raw result

* Run localfhenix

* Update faucet port

* Update container v
  • Loading branch information
architect-dev authored Jan 15, 2025
1 parent c3defdc commit 1f9f4c4
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 24 deletions.
87 changes: 87 additions & 0 deletions packages/fhenix-hardhat-plugin/mocha-fixtures.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import util from "util";
import { JsonRpcProvider } from "ethers";
import { exec } from "child_process";

const TEST_ENDPOINT_URL = process.env.TEST_ENDPOINT || "http://localhost:8545";

const execPromise = util.promisify(exec);
const CONTAINER_NAME = "fhenixjs-test-env";

async function runDockerContainerAsync() {
const imageName = "ghcr.io/fhenixprotocol/localfhenix:v0.3.2";

const ports = "-p 8545:8547 -p 5000:3000";

const removePrevious = `docker kill ${CONTAINER_NAME}`;

const command = `docker run --rm --env FHEOS_SECURITY_ZONES=2 --name ${CONTAINER_NAME} ${ports} -d ${imageName}`;

try {
try {
await execPromise(removePrevious);
} catch (_) {}
const result = await execPromise(command);
// console.log(result.stdout);
// console.error(result.stderr);
} catch (error) {
console.error(error);
throw new Error("Failed to start docker container");
}
}

async function killDockerContainerAsync() {
const removePrevious = `docker kill ${CONTAINER_NAME}`;

try {
await execPromise(removePrevious);
} catch (error) {
console.error(error);
throw new Error("Failed to remove docker container");
}
}

async function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

async function waitForChainToStart(url) {
// eslint-disable-next-line no-constant-condition
while (true) {
try {
const client = new JsonRpcProvider(url);
console.log(`connecting to ${url}...`);
const networkId = await client.getNetwork();
return Number(networkId.chainId);
} catch (e) {
console.log(`client not ready`);
}
await sleep(250);
}
}

export async function mochaGlobalSetup() {
if (process.env.SKIP_LOCAL_ENV === "true") {
return;
}

runDockerContainerAsync();

console.log("\nWaiting for Fhenix to start...");

await waitForChainToStart(TEST_ENDPOINT_URL);

console.log("Fhenix is running!");
}

// this is a cjs because jest sucks at typescript

export async function mochaGlobalTeardown() {
if (process.env.SKIP_LOCAL_ENV === "true") {
return;
}
console.log("\nWaiting for Fhenix to stop...");

await killDockerContainerAsync();

console.log("Stopped test container. Goodbye!");
}
4 changes: 2 additions & 2 deletions packages/fhenix-hardhat-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
],
"scripts": {
"lint": "eslint --config ./.eslintrc.json --ignore-path ./.eslintignore ./**/*.ts",
"test": "mocha --exit --recursive --timeout 60000 'test/*.test.ts'",
"test": "mocha --exit --recursive --timeout 60000 --require 'mocha-fixtures.mjs' 'test/*.test.ts'",
"build": "tsc",
"watch": "tsc -w",
"prepublishOnly": "npm run build"
Expand Down Expand Up @@ -53,7 +53,7 @@
"chalk": "^4.1.2",
"ethers": "^6.10.0",
"fast-glob": "^3.3.2",
"fhenixjs": "^0.4.2-alpha.1"
"fhenixjs": "^0.4.2-alpha.2"
},
"peerDependencies": {
"hardhat": "^2.11.0"
Expand Down
30 changes: 21 additions & 9 deletions packages/fhenix-hardhat-plugin/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import chalk from "chalk";
import { HDNodeWallet, Wallet } from "ethers";
import { HDNodeWallet, TypedDataField, Wallet } from "ethers";
import { TASK_COMPILE_SOLIDITY_EMIT_ARTIFACTS } from "hardhat/builtin-tasks/task-names";
import { extendConfig, extendEnvironment, task, types } from "hardhat/config";
import { lazyObject } from "hardhat/plugins";
Expand Down Expand Up @@ -42,20 +42,32 @@ extendEnvironment((hre) => {

hre.fhenixsdk = lazyObject(() => ({
...fhenixsdk,
initializeWithHHSigner: async ({ signer, ...params }) => {
fhenixsdk.initialize({
initializeWithHHSigner: async ({ signer, ...params }) =>
hre.fhenixsdk.initialize({
provider: {
call: signer.provider.call,
call: async (...args) => {
try {
return signer.provider.call(...args);
} catch (e) {
throw new Error(
`fhenixsdk initializeWithHHSigner :: call :: ${e}`,
);
}
},
getChainId: async () =>
(await signer.provider.getNetwork()).chainId.toString(),
},
signer: {
signTypedData: signer.signTypedData,
getAddress: signer.getAddress,
signTypedData: async (domain, types, value) =>
signer.signTypedData(
domain,
types as Record<string, TypedDataField[]>,
value,
),
getAddress: async () => signer.getAddress(),
},
...params,
});
},
}),
}));
});

Expand Down Expand Up @@ -90,7 +102,7 @@ task(TASK_FHENIX_USE_FAUCET, "Fund an account from the faucet")
.addOptionalParam(
"url",
"Optional Faucet URL",
"http://localhost:42000",
"http://localhost:3000",
types.string,
)
.setAction(
Expand Down
4 changes: 3 additions & 1 deletion packages/fhenix-hardhat-plugin/src/type-extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ type FhenixsdkInitWithHHSignerParams = Expand<
> &
PermitV2AccessRequirementsParams;

type FhenixsdkInitReturnType = ReturnType<typeof fhenixsdk["initialize"]>;

declare module "hardhat/types/runtime" {
// Fhenix extension to the Hardhat Runtime Environment.
// This new field will be available in tasks' actions, scripts, and tests.
Expand All @@ -37,7 +39,7 @@ declare module "hardhat/types/runtime" {
*/
initializeWithHHSigner: (
params: FhenixsdkInitWithHHSignerParams,
) => Promise<void>;
) => FhenixsdkInitReturnType;
};
}
}
26 changes: 19 additions & 7 deletions packages/fhenix-hardhat-plugin/test/project.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ describe("Test Fhenix Plugin", function () {
expect(bobPermit).to.be.an("object");
});
it("fhenixsdk encrypt", function () {
const fakeEnc = this.hre.fhenixsdk.encrypt(Encryptable.uint8(5));
const fakeEncResult = this.hre.fhenixsdk.encrypt(Encryptable.uint8(5));
expect(fakeEncResult.success).to.be.equal(true);
if (!fakeEncResult.success) return;

const fakeEnc = fakeEncResult.data;
expect(fakeEnc).to.be.an("object");
expect(fakeEnc).to.have.property("data");
expect(fakeEnc).to.have.property("securityZone");
Expand All @@ -83,15 +87,18 @@ describe("Test Fhenix Plugin", function () {
const bobSigner = await bobProvider.getSigner();

// Should initialize correctly, but fhe public key for hardhat not set
await this.hre.fhenixsdk.initialize({
// Should create and return a permit as a Result object
const bobPermitResult = await this.hre.fhenixsdk.initialize({
provider: bobProvider,
signer: bobSigner,
projects: ["TEST"],
});
expect(bobPermitResult.success).to.equal(true);
if (!bobPermitResult.success) return;

// Should create a permit
const bobPermit = await this.hre.fhenixsdk.createPermit();
const bobPermit = bobPermitResult.data;
expect(bobPermit).to.be.an("object");
if (bobPermit == null) return;

// Active hash should match
const activeHash = this.hre.fhenixsdk.getPermit()?.data?.getHash();
Expand Down Expand Up @@ -129,14 +136,19 @@ describe("Test Fhenix Plugin", function () {
});
it("fhenixsdk.initializeWithHHSigner utility function", async function () {
const [signer] = await this.hre.ethers.getSigners();
await this.hre.fhenixsdk.initializeWithHHSigner({
const permitResult = await this.hre.fhenixsdk.initializeWithHHSigner({
signer,
projects: ["TEST"],
});

// Initialization creates a permit
expect(permitResult.data == null).to.equal(false);
expect(permitResult.data).to.be.an("object");

// Should create a permit
const bobPermit = await this.hre.fhenixsdk.createPermit();
expect(bobPermit).to.be.an("object");
const bobPermitResult = await this.hre.fhenixsdk.createPermit();
expect(bobPermitResult.data == null).to.equal(false);
expect(bobPermitResult.data).to.be.an("object");
});
});

Expand Down
10 changes: 5 additions & 5 deletions pnpm-lock.yaml

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

0 comments on commit 1f9f4c4

Please sign in to comment.