mirror of
https://github.com/0xbow-io/privacy-pools-core.git
synced 2026-01-09 01:17:58 -05:00
fix: update sdk to receive browser param and base url
This commit is contained in:
2
packages/sdk/__mocks__/fs.ts
Normal file
2
packages/sdk/__mocks__/fs.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
import { fs } from "memfs";
|
||||
export default fs;
|
||||
@@ -9,6 +9,12 @@ import {
|
||||
Version,
|
||||
VersionString,
|
||||
} from "./circuits.interface.js";
|
||||
import { importFetchVersionedArtifact } from "./fetchArtifacts.js";
|
||||
|
||||
interface CircuitOptions {
|
||||
baseUrl?: string;
|
||||
browser?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing circuit management and artifact handling.
|
||||
@@ -40,6 +46,22 @@ export class Circuits implements CircuitsInterface {
|
||||
*/
|
||||
protected baseUrl: string = import.meta.url;
|
||||
|
||||
protected readonly browser: boolean = true;
|
||||
|
||||
/**
|
||||
* Constructor to initialize the Circuits class with an optional custom base URL.
|
||||
* @param {string} [options.baseUrl] - The base URL for fetching circuit artifacts (optional).
|
||||
* @param {boolean} [options.browser] - Controls how the circuits will be loaded, using either `fetch` if true or `fs` otherwise. Defaults to true.
|
||||
*/
|
||||
constructor(options?: CircuitOptions) {
|
||||
if (options?.baseUrl) {
|
||||
this.baseUrl = options.baseUrl;
|
||||
}
|
||||
if (options?.browser !== undefined) {
|
||||
this.browser = options.browser;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the environment is a browser.
|
||||
* @returns {boolean} True if running in a browser environment, false otherwise.
|
||||
@@ -96,23 +118,10 @@ export class Circuits implements CircuitsInterface {
|
||||
*/
|
||||
async _fetchVersionedArtifact(artifactPath: string): Promise<Uint8Array> {
|
||||
const artifactUrl = new URL(artifactPath, this.baseUrl);
|
||||
if (this._browser()) {
|
||||
const res = await fetch(artifactUrl);
|
||||
if (res.status !== 200) {
|
||||
throw new FetchArtifact(artifactUrl);
|
||||
}
|
||||
const aBuf = await res.arrayBuffer();
|
||||
return new Uint8Array(aBuf);
|
||||
} else {
|
||||
try {
|
||||
const fs = (await import("node:fs/promises")).default;
|
||||
const buf = await fs.readFile(artifactUrl);
|
||||
return new Uint8Array(buf);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
throw new FetchArtifact(artifactUrl);
|
||||
}
|
||||
}
|
||||
const { fetchVersionedArtifact } = await importFetchVersionedArtifact(
|
||||
this.browser,
|
||||
);
|
||||
return fetchVersionedArtifact(artifactUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
12
packages/sdk/src/circuits/fetchArtifacts.esm.ts
Normal file
12
packages/sdk/src/circuits/fetchArtifacts.esm.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { FetchArtifact } from "../exceptions/fetchArtifacts.exception.js";
|
||||
|
||||
export async function fetchVersionedArtifact(
|
||||
artifactUrl: URL,
|
||||
): Promise<Uint8Array> {
|
||||
const res = await fetch(artifactUrl);
|
||||
if (res.status !== 200) {
|
||||
throw new FetchArtifact(artifactUrl);
|
||||
}
|
||||
const aBuf = await res.arrayBuffer();
|
||||
return new Uint8Array(aBuf);
|
||||
}
|
||||
23
packages/sdk/src/circuits/fetchArtifacts.node.ts
Normal file
23
packages/sdk/src/circuits/fetchArtifacts.node.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { FetchArtifact } from "../exceptions/fetchArtifacts.exception.js";
|
||||
|
||||
export async function fetchVersionedArtifact(
|
||||
artifactUrl: URL,
|
||||
): Promise<Uint8Array> {
|
||||
try {
|
||||
const fs = (await import("fs")).default;
|
||||
const readPromise: Promise<Buffer> = new Promise((resolve, reject) => {
|
||||
fs.readFile(artifactUrl.pathname, (err, data) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
const buf = await readPromise;
|
||||
return new Uint8Array(buf);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
throw new FetchArtifact(artifactUrl);
|
||||
}
|
||||
}
|
||||
7
packages/sdk/src/circuits/fetchArtifacts.ts
Normal file
7
packages/sdk/src/circuits/fetchArtifacts.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export async function importFetchVersionedArtifact(isBrowser: boolean) {
|
||||
if (isBrowser) {
|
||||
return import(`./fetchArtifacts.esm.js`);
|
||||
} else {
|
||||
return import(`./fetchArtifacts.node.js`);
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ describe("Circuits for browser", () => {
|
||||
});
|
||||
|
||||
it("throws a FetchArtifact exception if artifact is not found at URI", async () => {
|
||||
expect(async () => {
|
||||
await expect(async () => {
|
||||
return await circuits._fetchVersionedArtifact(
|
||||
"artifacts/artifact_not_here.wasm",
|
||||
);
|
||||
@@ -46,7 +46,7 @@ describe("Circuits for browser", () => {
|
||||
});
|
||||
|
||||
it("loads artifact if correctly served", async () => {
|
||||
expect(
|
||||
await expect(
|
||||
circuits._fetchVersionedArtifact("artifacts/withdraw.wasm"),
|
||||
).resolves.toBeInstanceOf(Uint8Array);
|
||||
});
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { fs, vol } from "memfs";
|
||||
import { fs as memfs, vol } from "memfs";
|
||||
import { Circuits } from "../../src/circuits/index.js";
|
||||
import { FetchArtifact } from "../../src/internal.js";
|
||||
import { CircuitsMock } from "../mocks/index.js";
|
||||
|
||||
vi.mock("node:fs/promises");
|
||||
vi.mock("fs");
|
||||
|
||||
const ARTIFACT_DIR = "/dist/node/artifacts";
|
||||
const WASM_PATH = `${ARTIFACT_DIR}/withdraw.wasm`;
|
||||
|
||||
class CircuitsMockNode extends CircuitsMock {
|
||||
override baseUrl: string = `file://${ARTIFACT_DIR}`;
|
||||
}
|
||||
|
||||
describe("Circuits for Node", () => {
|
||||
let circuits: Circuits;
|
||||
afterEach(() => {
|
||||
@@ -22,26 +18,27 @@ describe("Circuits for Node", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
vol.reset();
|
||||
fs.mkdirSync(ARTIFACT_DIR, { recursive: true });
|
||||
fs.writeFileSync(WASM_PATH, "somedata");
|
||||
circuits = new CircuitsMockNode();
|
||||
memfs.mkdirSync(ARTIFACT_DIR, { recursive: true });
|
||||
memfs.writeFileSync(WASM_PATH, "somedata");
|
||||
circuits = new CircuitsMock({
|
||||
baseUrl: `file://${ARTIFACT_DIR}`,
|
||||
browser: false,
|
||||
});
|
||||
});
|
||||
|
||||
it("virtual file exists", () => {
|
||||
expect(fs.existsSync(WASM_PATH)).toStrictEqual(true);
|
||||
expect(fs.existsSync("non_existent_file")).toStrictEqual(false);
|
||||
expect(memfs.existsSync(WASM_PATH)).toStrictEqual(true);
|
||||
expect(memfs.existsSync("non_existent_file")).toStrictEqual(false);
|
||||
});
|
||||
|
||||
it("throws a FetchArtifact exception if artifact is not found in filesystem", async () => {
|
||||
expect(async () => {
|
||||
return await circuits._fetchVersionedArtifact(
|
||||
"artifacts/artifact_not_here.wasm",
|
||||
);
|
||||
}).rejects.toThrowError(FetchArtifact);
|
||||
await expect(
|
||||
circuits._fetchVersionedArtifact("artifacts/artifact_not_here.wasm"),
|
||||
).rejects.toThrowError(FetchArtifact);
|
||||
});
|
||||
|
||||
it("loads artifact if it exists on filesystem", async () => {
|
||||
expect(
|
||||
await expect(
|
||||
circuits._fetchVersionedArtifact("artifacts/withdraw.wasm"),
|
||||
).resolves.toBeInstanceOf(Uint8Array);
|
||||
});
|
||||
|
||||
@@ -54,32 +54,32 @@ describe("Circuits", () => {
|
||||
expect(circuits.introspectBinaries).toStrictEqual(binariesMock);
|
||||
});
|
||||
|
||||
it("_downloadCircuitArtifacts raises FetchArtifact if _fetchVersionedArtifact throws", () => {
|
||||
it("_downloadCircuitArtifacts raises FetchArtifact if _fetchVersionedArtifact throws", async () => {
|
||||
const fetchVersionedSpy = vi
|
||||
.spyOn(circuits, "_fetchVersionedArtifact")
|
||||
.mockRejectedValue(fetchArtifactError);
|
||||
expect(
|
||||
await expect(
|
||||
async () =>
|
||||
await circuits._downloadCircuitArtifacts(CircuitName.Withdraw),
|
||||
).rejects.toThrowError(FetchArtifact);
|
||||
expect(fetchVersionedSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("downloadArtifacts raises FetchArtifact if _downloadCircuitArtifacts throws", () => {
|
||||
it("downloadArtifacts raises FetchArtifact if _downloadCircuitArtifacts throws", async () => {
|
||||
const downloadCircuitArtifactsSpy = vi
|
||||
.spyOn(circuits, "_downloadCircuitArtifacts")
|
||||
.mockRejectedValue(fetchArtifactError);
|
||||
expect(
|
||||
await expect(
|
||||
async () => await circuits.downloadArtifacts("latest"),
|
||||
).rejects.toThrowError(FetchArtifact);
|
||||
expect(downloadCircuitArtifactsSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("initArtifacts raises FetchArtifact", () => {
|
||||
it("initArtifacts raises FetchArtifact", async () => {
|
||||
const downloadArtifactsSpy = vi
|
||||
.spyOn(circuits, "downloadArtifacts")
|
||||
.mockRejectedValue(fetchArtifactError);
|
||||
expect(
|
||||
await expect(
|
||||
async () => await circuits.initArtifacts("latest"),
|
||||
).rejects.toThrowError(FetchArtifact);
|
||||
expect(downloadArtifactsSpy).toHaveBeenCalled();
|
||||
@@ -87,15 +87,15 @@ describe("Circuits", () => {
|
||||
expect(downloadArtifactsSpy).toHaveBeenCalledWith("latest");
|
||||
});
|
||||
|
||||
it("_handleInitialization raises CircuitInitialization error when something happens", () => {
|
||||
it("_handleInitialization raises CircuitInitialization error when something happens", async () => {
|
||||
vi.spyOn(circuits, "initArtifacts").mockRejectedValue(fetchArtifactError);
|
||||
expect(
|
||||
await expect(
|
||||
async () => await circuits._handleInitialization("latest"),
|
||||
).rejects.toThrowError(CircuitInitialization);
|
||||
vi.spyOn(circuits, "initArtifacts").mockRejectedValue(
|
||||
new Error("DifferentError"),
|
||||
);
|
||||
expect(
|
||||
await expect(
|
||||
async () => await circuits._handleInitialization("latest"),
|
||||
).rejects.toThrowError(CircuitInitialization);
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ describe("PrivacyPoolSDK", () => {
|
||||
let sdk: PrivacyPoolSDK;
|
||||
|
||||
beforeEach(() => {
|
||||
circuits = new CircuitsMock();
|
||||
circuits = new CircuitsMock({ browser: false });
|
||||
sdk = new PrivacyPoolSDK(circuits);
|
||||
});
|
||||
|
||||
@@ -82,7 +82,7 @@ describe("PrivacyPoolSDK", () => {
|
||||
proof: {} as snarkjs.Groth16Proof,
|
||||
publicSignals: [],
|
||||
}),
|
||||
).rejects.toThrow(ProofError);
|
||||
).rejects.toThrowError(ProofError);
|
||||
});
|
||||
|
||||
it("should return true for a valid commitment proof", async () => {
|
||||
|
||||
Reference in New Issue
Block a user