feat: align ts and tests to js-waku (#99)

* adjust config

* fix all lint issues

* fix ts build

* fix test issue

* fix ci

* add browser

* imporve wasm test

* fix wasm karma server

* try

* try

* add output folder

* try production config

* fix test runner
This commit is contained in:
Sasha 2024-03-01 01:07:33 +01:00 committed by GitHub
parent 65b7d8bcbc
commit 6454446c1c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 3079 additions and 3485 deletions

View File

@ -45,4 +45,4 @@
}
],
"ignoreRegExpList": ["import"]
}
}

View File

@ -2,19 +2,10 @@
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.dev.json"
"project": ["./tsconfig.json"]
},
"env": {
"es6": true
},
"ignorePatterns": [
"node_modules",
"build",
"coverage",
"proto",
"*/**/credential_validation_generated.ts",
"*/**/keystore_validation_generated.ts"
],
"env": { "es6": true },
"ignorePatterns": ["node_modules", "build", "coverage", "proto"],
"plugins": ["import", "eslint-comments", "functional"],
"extends": [
"eslint:recommended",
@ -23,18 +14,15 @@
"plugin:import/typescript",
"plugin:prettier/recommended"
],
"globals": {
"BigInt": true,
"console": true,
"WebAssembly": true
},
"globals": { "BigInt": true, "console": true, "WebAssembly": true },
"rules": {
"@typescript-eslint/explicit-function-return-type": [
"prettier/prettier": [
"error",
{
"allowExpressions": true
"trailingComma": "none"
}
],
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"eslint-comments/disable-enable-pair": [
"error",
@ -52,26 +40,63 @@
}
}
],
"no-constant-condition": [
"no-constant-condition": ["error", { "checkLoops": false }],
"import/no-extraneous-dependencies": [
"error",
{
"checkLoops": false
"devDependencies": [
"**/*.test.ts",
"**/*.spec.ts",
"**/tests/**",
"**/rollup.config.js",
"**/playwright.config.ts",
"**/.eslintrc.cjs",
"**/karma.conf.cjs"
]
}
],
"sort-imports": [
"error",
{
"ignoreDeclarationSort": true,
"ignoreCase": true
}
]
{ "ignoreDeclarationSort": true, "ignoreCase": true }
],
"no-console": "error",
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/await-thenable": "error",
"@typescript-eslint/no-misused-promises": "error",
"@typescript-eslint/no-explicit-any": "warn",
"id-match": ["error", "^(?!.*[pP]ubSub)"]
},
"overrides": [
{
"files": ["*.spec.ts", "**/test_utils/*.ts"],
"files": ["*.spec.ts", "**/test_utils/*.ts", "*.js", "*.cjs"],
"rules": {
"@typescript-eslint/no-non-null-assertion": "off"
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-explicit-any": "off",
"no-console": "off",
"import/no-extraneous-dependencies": [
"error",
{
"devDependencies": true
}
]
}
},
{
"files": ["*.ts", "*.mts", "*.cts", "*.tsx"],
"rules": {
"@typescript-eslint/explicit-function-return-type": [
"error",
{
"allowExpressions": true
}
]
}
},
{
"files": ["**/ci/*.js"],
"rules": {
"no-undef": "off"
}
}
]
}
}

View File

@ -21,7 +21,6 @@ jobs:
node-version: ${{ env.NODE_JS }}
- uses: bahmutov/npm-install@v1
- run: npm run test:lint
- run: npm run test:prettier
- run: npm run test:spelling
- run: npm run test:tsc
@ -43,6 +42,7 @@ jobs:
with:
node-version: ${{ env.NODE_JS }}
- uses: bahmutov/npm-install@v1
- run: npx playwright install --with-deps
- run: npm run test:browser
release_next:

View File

@ -1,13 +1,11 @@
process.env.CHROME_BIN = require("puppeteer").executablePath();
const os = require("os");
const path = require("path");
const ResolveTypeScriptPlugin = require("resolve-typescript-plugin");
const webpack = require("webpack");
const playwright = require('playwright');
process.env.CHROME_BIN = playwright.chromium.executablePath();
const output = {
path:
path.join(os.tmpdir(), "_karma_webpack_") +
Math.floor(Math.random() * 1000000),
path: path.join(__dirname, "dist"),
};
module.exports = function (config) {
@ -16,7 +14,6 @@ module.exports = function (config) {
preprocessors: {
"**/*.ts": ["webpack"],
},
files: [
"src/**/*.spec.ts",
"src/**/*.ts",
@ -38,12 +35,8 @@ module.exports = function (config) {
},
},
webpack: {
output,
mode: "production",
resolve: {
// Add `.ts` and `.tsx` as a resolvable extension.
extensions: [".ts", ".tsx", ".js"],
plugins: [new ResolveTypeScriptPlugin()],
},
module: {
rules: [
{
@ -62,7 +55,25 @@ module.exports = function (config) {
},
],
},
output,
plugins: [
new webpack.DefinePlugin({
"process.env.CI": process.env.CI || false,
"process.env.DISPLAY": "Browser",
}),
new webpack.ProvidePlugin({
process: "process/browser.js"
})
],
resolve: {
extensions: [".ts", ".tsx", ".js"],
extensionAlias: {
".js": [".js", ".ts"],
".cjs": [".cjs", ".cts"],
".mjs": [".mjs", ".mts"]
}
},
stats: { warnings: false },
devtool: "inline-source-map"
},
});
};

6109
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -29,11 +29,9 @@
"build:bundle": "rollup --config rollup.config.js",
"size": "npm run build && size-limit",
"fix": "run-s fix:*",
"fix:prettier": "prettier \"src/**/*.ts\" \"./*.json\" \"*.*js\" \".github/**/*.yml\" --write",
"fix:lint": "eslint src --ext .ts --ext .cjs --fix",
"test": "run-s test:*",
"test:lint": "eslint src --ext .ts",
"test:prettier": "prettier \"src/**/*.ts\" \"./*.json\" \"*.*js\" \".github/**/*.yml\" --list-different",
"test:spelling": "cspell \"{*.md,.github/*.md,src/**/*.ts}\"",
"test:tsc": "tsc -p tsconfig.dev.json",
"test:browser": "karma start karma.conf.cjs",
@ -70,9 +68,8 @@
"@types/node": "^17.0.6",
"@types/tail": "^2.0.0",
"@types/uuid": "^8.3.0",
"@typescript-eslint/eslint-plugin": "^5.8.1",
"@typescript-eslint/parser": "^5.8.1",
"@waku/core": "^0.0.25",
"@typescript-eslint/eslint-plugin": "^6.6.0",
"@typescript-eslint/parser": "^6.21.0",
"@waku/interfaces": "^0.0.20",
"@waku/message-encryption": "^0.0.23",
"@web/rollup-plugin-import-meta-assets": "^1.0.7",
@ -85,12 +82,12 @@
"chai-subset": "^1.6.0",
"cspell": "^5.14.0",
"deep-equal-in-any-order": "^2.0.6",
"eslint": "^8.6.0",
"eslint-config-prettier": "^8.3.0",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-functional": "^4.0.2",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-functional": "^6.0.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-prettier": "^5.0.1",
"fast-check": "^2.25.0",
"gh-pages": "^3.2.3",
"husky": "^7.0.4",
@ -98,26 +95,26 @@
"isomorphic-fetch": "^3.0.0",
"jsdom": "^19.0.0",
"jsdom-global": "^3.0.2",
"karma": "^6.3.12",
"karma-chrome-launcher": "^3.1.0",
"karma": "^6.4.2",
"karma-chrome-launcher": "^3.2.0",
"karma-firefox-launcher": "^2.1.2",
"karma-mocha": "^2.0.1",
"karma-webpack": "^5.0.0",
"karma-webkit-launcher": "^2.4.0",
"karma-webpack": "github:codymikol/karma-webpack#2337a82beb078c0d8e25ae8333a06249b8e72828",
"lint-staged": "^13.0.3",
"mocha": "10.1.0",
"npm-run-all": "^4.1.5",
"p-timeout": "^4.1.0",
"prettier": "^2.1.1",
"playwright": "^1.40.1",
"process": "^0.11.10",
"puppeteer": "^13.0.1",
"resolve-typescript-plugin": "^1.2.0",
"rollup": "^2.75.0",
"rollup-plugin-copy": "^3.4.0",
"size-limit": "^8.0.0",
"tail": "^2.2.0",
"ts-loader": "^9.3.1",
"ts-node": "^10.9.1",
"typedoc": "^0.23.10",
"typescript": "^4.5.5"
"typedoc": "^0.25.7",
"typescript": "^5.3.2"
},
"files": [
"dist",
@ -133,19 +130,17 @@
"lint-staged": {
"*.ts": [
"eslint --fix"
],
"*.{ts,md,json,conf*.*js}": [
"prettier --write"
]
},
"dependencies": {
"@chainsafe/bls-keystore": "^3.0.0",
"@waku/core": "^0.0.25",
"@waku/utils": "^0.0.13",
"@waku/zerokit-rln-wasm": "^0.0.13",
"debug": "^4.3.4",
"ethereum-cryptography": "^2.1.2",
"ethers": "^5.7.2",
"lodash": "^4.17.21",
"rlnjs": "^3.2.3",
"uuid": "^9.0.1"
}
}
}

View File

@ -1,21 +1,21 @@
import {
createDecoder,
createEncoder,
DecodedMessage,
DecodedMessage
} from "@waku/core/lib/message/version_0";
import type { IProtoMessage } from "@waku/interfaces";
import {
generatePrivateKey,
generateSymmetricKey,
getPublicKey,
getPublicKey
} from "@waku/message-encryption";
import {
createDecoder as createAsymDecoder,
createEncoder as createAsymEncoder,
createEncoder as createAsymEncoder
} from "@waku/message-encryption/ecies";
import {
createDecoder as createSymDecoder,
createEncoder as createSymEncoder,
createEncoder as createSymEncoder
} from "@waku/message-encryption/symmetric";
import { expect } from "chai";
@ -23,7 +23,7 @@ import {
createRLNDecoder,
createRLNEncoder,
RLNDecoder,
RLNEncoder,
RLNEncoder
} from "./codec.js";
import { createRLN } from "./create.js";
import { RlnMessage } from "./message.js";
@ -38,7 +38,7 @@ const EMPTY_PROTO_MESSAGE = {
ephemeral: undefined,
meta: undefined,
rateLimitProof: undefined,
version: undefined,
version: undefined
};
describe("RLN codec with version 0", () => {
@ -54,11 +54,11 @@ describe("RLN codec with version 0", () => {
encoder: createEncoder({ contentTopic: TestContentTopic }),
rlnInstance,
index,
credential,
credential
});
const rlnDecoder = createRLNDecoder({
rlnInstance,
decoder: createDecoder(TestContentTopic),
decoder: createDecoder(TestContentTopic)
});
const bytes = await rlnEncoder.toWire({ payload });
@ -139,7 +139,7 @@ describe("RLN codec with version 1", () => {
const rlnEncoder = new RLNEncoder(
createSymEncoder({
contentTopic: TestContentTopic,
symKey,
symKey
}),
rlnInstance,
index,
@ -186,7 +186,7 @@ describe("RLN codec with version 1", () => {
const rlnEncoder = new RLNEncoder(
createSymEncoder({
contentTopic: TestContentTopic,
symKey,
symKey
}),
rlnInstance,
index,
@ -233,7 +233,7 @@ describe("RLN codec with version 1", () => {
const rlnEncoder = new RLNEncoder(
createAsymEncoder({
contentTopic: TestContentTopic,
publicKey,
publicKey
}),
rlnInstance,
index,
@ -281,7 +281,7 @@ describe("RLN codec with version 1", () => {
const rlnEncoder = new RLNEncoder(
createAsymEncoder({
contentTopic: TestContentTopic,
publicKey,
publicKey
}),
rlnInstance,
index,
@ -384,11 +384,11 @@ describe("RLN codec with version 0 and meta setter", () => {
encoder: createEncoder({ contentTopic: TestContentTopic, metaSetter }),
rlnInstance,
index,
credential,
credential
});
const rlnDecoder = createRLNDecoder({
rlnInstance,
decoder: createDecoder(TestContentTopic),
decoder: createDecoder(TestContentTopic)
});
const bytes = await rlnEncoder.toWire({ payload });
@ -403,7 +403,7 @@ describe("RLN codec with version 0 and meta setter", () => {
const expectedMeta = metaSetter({
...EMPTY_PROTO_MESSAGE,
payload: protoResult!.payload,
payload: protoResult!.payload
});
expect(msg!.meta).to.deep.eq(expectedMeta);
@ -449,7 +449,7 @@ describe("RLN codec with version 0 and meta setter", () => {
const expectedMeta = metaSetter({
...EMPTY_PROTO_MESSAGE,
payload: msg!.payload,
payload: msg!.payload
});
expect(msg!.meta).to.deep.eq(expectedMeta);

View File

@ -4,7 +4,7 @@ import type {
IEncoder,
IMessage,
IProtoMessage,
IRateLimitProof,
IRateLimitProof
} from "@waku/interfaces";
import debug from "debug";
@ -86,7 +86,10 @@ export const createRLNEncoder = (options: RLNEncoderOptions): RLNEncoder => {
export class RLNDecoder<T extends IDecodedMessage>
implements IDecoder<RlnMessage<T>>
{
constructor(private rlnInstance: RLNInstance, private decoder: IDecoder<T>) {}
constructor(
private rlnInstance: RLNInstance,
private decoder: IDecoder<T>
) {}
get pubsubTopic(): string {
return this.decoder.pubsubTopic;

View File

@ -26,7 +26,7 @@ export const RLN_REGISTRY_ABI = [
"function transferOwnership(address newOwner)",
"function upgradeTo(address newImplementation)",
"function upgradeToAndCall(address newImplementation, bytes data) payable",
"function usingStorageIndex() view returns (uint16)",
"function usingStorageIndex() view returns (uint16)"
];
// ref https://github.com/waku-org/waku-rln-contract/blob/19fded82bca07e7b535b429dc507cfb83f10dfcf/deployments/sepolia/WakuRlnStorage_0.json#L3
@ -58,11 +58,11 @@ export const RLN_STORAGE_ABI = [
"function transferOwnership(address newOwner)",
"function verifier() view returns (address)",
"function withdraw() pure",
"function withdrawalBalance(address) view returns (uint256)",
"function withdrawalBalance(address) view returns (uint256)"
];
export const SEPOLIA_CONTRACT = {
chainId: 11155111,
address: "0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4",
abi: RLN_REGISTRY_ABI,
abi: RLN_REGISTRY_ABI
};

View File

@ -19,15 +19,15 @@ describe("RLN Contract abstraction", () => {
const voidSigner = new ethers.VoidSigner(SEPOLIA_CONTRACT.address);
const rlnContract = new RLNContract(rlnInstance, {
registryAddress: SEPOLIA_CONTRACT.address,
signer: voidSigner,
signer: voidSigner
});
rlnContract["storageContract"] = {
queryFilter: () => Promise.resolve([mockEvent()]),
queryFilter: () => Promise.resolve([mockEvent()])
} as unknown as ethers.Contract;
rlnContract["_membersFilter"] = {
address: "",
topics: [],
topics: []
} as unknown as ethers.EventFilter;
await rlnContract.fetchMembers(rlnInstance);
@ -43,17 +43,17 @@ describe("RLN Contract abstraction", () => {
const voidSigner = new ethers.VoidSigner(SEPOLIA_CONTRACT.address);
const rlnContract = new RLNContract(rlnInstance, {
registryAddress: SEPOLIA_CONTRACT.address,
signer: voidSigner,
signer: voidSigner
});
rlnContract["storageIndex"] = 1;
rlnContract["_membersFilter"] = {
address: "",
topics: [],
topics: []
} as unknown as ethers.EventFilter;
rlnContract["registryContract"] = {
"register(uint16,uint256)": () =>
Promise.resolve({ wait: () => Promise.resolve(undefined) }),
Promise.resolve({ wait: () => Promise.resolve(undefined) })
} as unknown as ethers.Contract;
const contractSpy = chai.spy.on(
rlnContract["registryContract"],
@ -72,7 +72,7 @@ function mockEvent(): ethers.Event {
return {
args: {
idCommitment: { _hex: "0xb3df1c4e5600ef2b" },
index: ethers.BigNumber.from(1),
},
index: ethers.BigNumber.from(1)
}
} as unknown as ethers.Event;
}

View File

@ -1,4 +1,5 @@
import { hexToBytes } from "@waku/utils/bytes";
import debug from "debug";
import { ethers } from "ethers";
import type { IdentityCredential } from "../identity.js";
@ -9,6 +10,8 @@ import { zeroPadLE } from "../utils/index.js";
import { RLN_REGISTRY_ABI, RLN_STORAGE_ABI } from "./constants.js";
const log = debug("waku:rln:contract");
type Member = {
idCommitment: string;
index: ethers.BigNumber;
@ -130,7 +133,7 @@ export class RLNContract {
const registeredMemberEvents = await queryFilter(this.contract, {
fromBlock: this.deployBlock,
...options,
membersFilter: this.membersFilter,
membersFilter: this.membersFilter
});
this.processEvents(rlnInstance, registeredMemberEvents);
}
@ -185,7 +188,7 @@ export class RLNContract {
rlnInstance.zerokit.insertMember(idCommitment);
this._members.set(index.toNumber(), {
index,
idCommitment: _idCommitment?._hex,
idCommitment: _idCommitment?._hex
});
});
@ -254,8 +257,8 @@ export class RLNContract {
membership: {
address,
treeIndex: membershipId,
chainId: network.chainId,
},
chainId: network.chainId
}
};
}
@ -280,7 +283,7 @@ async function queryFilter(
fromBlock,
membersFilter,
fetchRange = BLOCK_RANGE,
fetchChunks = FETCH_CHUNK,
fetchChunks = FETCH_CHUNK
} = options;
if (!fromBlock) {
@ -346,7 +349,7 @@ function* takeN<T>(array: T[], size: number): Iterable<T[]> {
function ignoreErrors<T>(promise: Promise<T>, defaultValue: T): Promise<T> {
return promise.catch((err) => {
console.error(`Ignoring an error during query: ${err?.message}`);
log(`Ignoring an error during query: ${err?.message}`);
return defaultValue;
});
}

View File

@ -2,7 +2,7 @@ import { RLNDecoder, RLNEncoder } from "./codec.js";
import {
RLN_REGISTRY_ABI,
RLN_STORAGE_ABI,
SEPOLIA_CONTRACT,
SEPOLIA_CONTRACT
} from "./contract/index.js";
import { RLNContract } from "./contract/index.js";
import { createRLN } from "./create.js";
@ -26,5 +26,5 @@ export {
RLN_STORAGE_ABI,
RLN_REGISTRY_ABI,
SEPOLIA_CONTRACT,
extractMetaMaskSigner,
extractMetaMaskSigner
};

View File

@ -6,7 +6,7 @@ import { keccak256 } from "ethereum-cryptography/keccak";
import {
bytesToHex,
concatBytes,
hexToBytes,
hexToBytes
} from "ethereum-cryptography/utils";
import type { Keccak256Hash, Password } from "./types.js";

View File

@ -23,7 +23,7 @@ const NWAKU_KEYSTORE = {
crypto: {
cipher: "aes-128-ctr",
cipherparams: {
iv: "fd6b39eb71d44c59f6bf5ff3d8945c80",
iv: "fd6b39eb71d44c59f6bf5ff3d8945c80"
},
ciphertext:
"9c72f47ce95de03ed34502d0288e7576b66b51b9e7d5ae882c27bd89f94e6a03c2c44c2ddf0c982e72003d67212105f1b64614f57cabb0ceadab7e07be165eee1121ad6b81951368a9f3be2dd99ea294515f6013d5f2bd4702a40e36cfde2ea298b23b31e5ce719d8040c3331f73d6bf44f88bca39bac0e917d8bf545500e4f40d321c235426a80f315ac70666acbd3bdf803fbc1e7e7103fed466525ed332b25d72b2dbedf6fa383b2305987c1fe276b029570519b3e79930edf08c1029868d05c2c08ab61d7c64f63c054b4f6a5a12d43cdc79751b6fe58d3ed26b69443eb7c9f7efce27912340129c91b6b813ac94efd5776a40b1dda896d61357de208c7c47a14af911cc231355c8093ee6626e89c07e1037f9e0b22c690e3e049014399ca0212c509cb04c71c7860d1b17a0c47711c490c27bad2825926148a1f15a507f36ba2cdaa04897fce2914e53caed0beaf1bebd2a83af76511cc15bff2165ff0860ad6eca1f30022d7739b2a6b6a72f2feeef0f5941183cda015b4631469e1f4cf27003cab9a90920301cb30d95e4554686922dc5a05c13dfb575cdf113c700d607896011970e6ee7d6edb61210ab28ac8f0c84c606c097e3e300f0a5f5341edfd15432bef6225a498726b62a98283829ad51023b2987f30686cfb4ea3951f3957654035ec291f9b0964a3a8665d81b16cec20fb40f944d5f9bf03ac1e444ad45bae3fa85e7465ce620c0966d8148d6e2856f676c4fbbe3ebe470453efb4bbda1866680037917e37765f680e3da96ef3991f3fe5cda80c523996c2234758bf5f7b6d052dc6942f5a92c8b8eec5d2d8940203bbb6b1cba7b7ebc1334334ca69cdb509a5ea58ec6b2ebaea52307589eaae9430eb15ad234c0c39c83accdf3b77e52a616e345209c5bc9b442f9f0fa96836d9342f983a7",
@ -32,16 +32,16 @@ const NWAKU_KEYSTORE = {
dklen: 32,
c: 1000000,
prf: "hmac-sha256",
salt: "60f0aa92fbf63a8356dfdbed2ab18058",
salt: "60f0aa92fbf63a8356dfdbed2ab18058"
},
mac: "51a227ac6db7f2797c63925880b3db664e034231a4c68daa919ab42d8df38bc6",
},
mac: "51a227ac6db7f2797c63925880b3db664e034231a4c68daa919ab42d8df38bc6"
}
},
"263335559F0578FD785F9CDFEDBB45CFF276799A27580B8F580CDFDCB990257C": {
crypto: {
cipher: "aes-128-ctr",
cipherparams: {
iv: "69f95461f811ac35a21987b1fdaa605e",
iv: "69f95461f811ac35a21987b1fdaa605e"
},
ciphertext:
"edfe844f8e2aedd62f26753e7247554920352b6b167f54ea4f728cd715577e9d2b7192b782471914870794205e77c2708b6db2d0ada19fec6b3533098cb2b7350bbaf81526d6bde7f1d0e83c366e3a2ddcced942cfb09a3c7704db7041132c3b511fed2f6d8599e6cddf649250b240687c2c335bf0aa75c892bc97f81c537898aefed20d1488e816d54eec72572acf36f140dc98cba0430cdeb8a00b8e8c8edf9b1292ca0e9c9a606acec51ea3dbe46438cb74b95d708cec18f8f126aecabbff11dd068d9194b25803f959f0bb62d49785dbc694486754f46bfe084cfa780cae27eca48cdcc88f4083d166d1747b8e2e637619e5d3848b9b6cdf7c7161eda8e476edfc083d417691d47b84fb224bfd26bf7713958893b934388e50783e49c5c84999971538ccda14c54b48b0d4aa37503e2a40212e9a1407d5a1ea4e96760de3d87e1b2287465a4e51cf330b7f1d14e3f2fb6521d10d32c798856464927b1e0286086a78f07a8f6f436d8c0c7b530f585320515e276d82c7b1f244702fa9ca6e6ad164fd2b1d9badcbdc17e01e95abf58e6825d8eeba5bc22db3a66dd41c64887d4c862298e921b3bae17d9fb7be1f619c60c82bd60dee351b77514d36e25d4092d6cde8ab613c40a117f7b784c80d65310e5b9cf1a31ba555f848e6984cc0c2d48315167d60131f3ffaaca5c81e359134bbfc81fa217f29b533868604ced4a2c5da8c89bd1238147b9f348168864ebea40c36a6abbf3d59d43086f26777104ce0a9f60cbf350058a337bc66abd5e4976950e5908192f98a9a8c1913abbc0d918479aeaa99e89a0e5cd65fd84a347d73df1d9c829863728a6fcd90150e52ecdec48bd07802110384f6c0aff0ca05ad42feb521223b58719fd4fc4ae88df8225ea58e303e4c61e8288e80f854bf0b",
@ -50,16 +50,16 @@ const NWAKU_KEYSTORE = {
dklen: 32,
c: 1000000,
prf: "hmac-sha256",
salt: "3cf796e4857f296bef3bdb9ca844b1bf",
salt: "3cf796e4857f296bef3bdb9ca844b1bf"
},
mac: "3d6cb0492afcf89c891365f097ae8989dc50038010c419b18228be6816c24c32",
},
mac: "3d6cb0492afcf89c891365f097ae8989dc50038010c419b18228be6816c24c32"
}
},
F62A7FCE85E5B796AFCB38F54A44210515CB688EA0224E9A436CCA0A542F2C9D: {
crypto: {
cipher: "aes-128-ctr",
cipherparams: {
iv: "49816dacf881c85db9f11f7f068dcf71",
iv: "49816dacf881c85db9f11f7f068dcf71"
},
ciphertext:
"d7d805ee24dd34368e3d1829aa6d0856ca2ea54d9bcdc2655f8f197af0d293aff56c6e06de3137b0eddffbcad7cc0b8e3f6ba761ac7983d8e59ce04c8936868297b9f70238cb295e17567f2404b278b93c985496a6e1e46185965491449ccbc1e7155224acdba354ed18b1b9867ff6f1a833a77c9b21e2e9c4b6af27d5bd6303efd574465920928e5c467bd3c7888c3f31e8bece6af2e0c35fa03661399e9b420eeecd4376cb2b3266692f46c03161bb32cc2c79521f7b19cb0e6ec911213e105967f8887d94c73e793b18e4c14ee045dca13fcfb62ae267d3175f8a4fefd0e8bd636bd9431cc0cc7119e75f116a16dcbdcac1c15a3dcec57e1c49dbf5dccd1c75c0cfcb3473e81e8546048ce5231a4d4c8dd5d66311354e9ab70ad5745d5be27746954a08b0b29218562bfb632ae0a498cf09d7955a27377ed7a50fc1b4adaa0a3fb3e87a3b4d923136be0767a1428050944b9fd247332dea1b5016dfa1ec4da167e70e11e07cd58034b8470366dc16d77978b49a61e213ab5a7817fd69af26c2a8c3cd3a488d6e1491e0215071e1f3e9d49d0dfab3a7e324644c98a088e20259980495dcc379dcdce2e61752711bdf8abf057a2e696624078601245828193d838cc806065ee3f2bb138302ec72c70f34f14c0ab816211011f0ac55423732875e220175c717f6bc86f071bb4fab51c1963eb5c5d70d504c1e4d2307a8c8c4b8b5a84566a4606deb3fc6d7a420adc2b2b37c0ef3018f82a3ce0044e082407e8e7cb6214a3abc139b7f75b2c36c6902080e7696c730ab062e75e597274e0c945b6a7a366d20bd210dd02b097071142d033597e2fc4174be683a866510fa1c2fe150a2fb81dbd2b5da25da27f29367fb22dd4e9d4785856e4deea56219f9495fb3ab772f7867db11cb14026b",
@ -68,16 +68,16 @@ const NWAKU_KEYSTORE = {
dklen: 32,
c: 1000000,
prf: "hmac-sha256",
salt: "2dcb5ba5c98fe5e46d961dad36e79a5b",
salt: "2dcb5ba5c98fe5e46d961dad36e79a5b"
},
mac: "2d6e9de6440f52c5db64b13f80399967c8770e82616294e14f40a2e213e7d925",
},
mac: "2d6e9de6440f52c5db64b13f80399967c8770e82616294e14f40a2e213e7d925"
}
},
"8479C6B9125D43E7B7739F1BAB41779F2F5A4D27FF0E2B6F6CA353032010A22C": {
crypto: {
cipher: "aes-128-ctr",
cipherparams: {
iv: "b0eef2c385a04909c4ae9b318e179fa7",
iv: "b0eef2c385a04909c4ae9b318e179fa7"
},
ciphertext:
"90b982222072366566fa194be5c170506888e184cadbd52aa38f184ac4e9bc160cc719d809fb6a128e0cbd908e70a71efdc5d51c4dab8aab71e3e6a2ebd9ea4238cb47585137990e896dfa53961bb2b328abfbba82f49db6a9b6e3790cf9e29c145796c6dbf409dc875e7998db827c944a835a29ab4192a11ad1efde5ebdd1a775ecbfefd139c50fbdcbebd6c124d9d65ba6ddaaa83e57695293e7c85dfd6f418d58fa5ffb9ab9b2395c84b57da796d31b6351fde3f1dbab29da6c3f259859bd0719c34f5111a9a12075b53ee91b4598fb2f452dbea823ec094cb757f370b5386a8e5db25cf732681d0cd9bda651ae55cdd125138fd2c8f1ffe87a5eea14df7d355762b37e3e71c33c6fe46a10c2083538910fec12e294de84ff587cab2dd268203699cb180e481f4a3a093b86854cea64341dd9482305abd4a9d7bb304b078bc255bf7cde78689225f17006f24c2cd82d38a59f1e0899965c38fcfd1ec67069143ee05a34922963a527549a002e3221e1461463f573e5f66ba87dcb83a63cb8e3a721c13cd9d4d0c9a0334a558f32027424a5bc9fc12b91981a3f74ac4b62eea3aae8be6c44504696b96afadce5d9222bb67dddf5a7d98dd43d544d79f8720a946c37eba8eb5ae6d70f4bdbbe554cbd4b3abb35ed357c8cb8f55e016ab83bef12bf5c0cdf26c7624c86f16437f545d796addb1aa7370de329930c68b174c871706e7afdf78cc07e0f0c58e45495d0d3bcf3faf9fb6d20369b0adc89766b0c9132677e52112770d017da7658f2a0c0eaeac57416f203700f98bf7b30119407733d4f0bd4322c622120cdf81646c4a1adfb80e757954e41ba0e7816c403b2e4b9ceb2d36e4198921ea719a410ae6f6983e49e7b99c266deb0465af716799e36a5bab70923291da808edeba54267e31e8b64c37123fd45d86e0638",
@ -86,12 +86,12 @@ const NWAKU_KEYSTORE = {
dklen: 32,
c: 1000000,
prf: "hmac-sha256",
salt: "142a0a65b7f6f480546cc4ef743d7ef9",
salt: "142a0a65b7f6f480546cc4ef743d7ef9"
},
mac: "7119b7b78598850de5f6af742e42748a3b005394b6b8b272490f24527ebd8b15",
},
},
},
mac: "7119b7b78598850de5f6af742e42748a3b005394b6b8b272490f24527ebd8b15"
}
}
}
};
describe("Keystore", () => {
@ -102,7 +102,7 @@ describe("Keystore", () => {
application: "waku-rln-relay",
appIdentifier: "01234567890abcdef",
version: "0.2",
credentials: {},
credentials: {}
});
});
@ -110,43 +110,43 @@ describe("Keystore", () => {
[
{
some: "3123",
dadw: "1212",
dadw: "1212"
},
{
application: 123,
version: "01234567890abcdef",
appIdentifier: "0.2",
credentials: {},
credentials: {}
},
{
application: "waku-rln-relay",
version: 213,
appIdentifier: "0.2",
credentials: {},
credentials: {}
},
{
application: "waku-rln-relay",
version: "01234567890abcdef",
appIdentifier: 12,
credentials: {},
credentials: {}
},
{
application: "waku-rln-relay",
version: "01234567890abcdef",
appIdentifier: "12",
credentials: [],
credentials: []
},
{
application: "waku-rln-relay",
version: "01234567890abcdef",
appIdentifier: "12",
credentials: 123,
credentials: 123
},
{
application: "waku-rln-relay",
version: "01234567890abcdef",
appIdentifier: "12",
credentials: "123",
credentials: "123"
},
{
application: "waku-rln-relay",
@ -154,10 +154,10 @@ describe("Keystore", () => {
appIdentifier: "12",
credentials: {
hash: {
invalid: "here",
},
},
},
invalid: "here"
}
}
}
].map((options) => {
it("should fail to create store from invalid object", () => {
expect(() => Keystore.fromObject(options as any)).to.throw(
@ -189,7 +189,7 @@ describe("Keystore", () => {
application: "waku-rln-relay",
appIdentifier: "01234567890abcdef",
version: "0.2",
credentials: {},
credentials: {}
})
);
@ -205,34 +205,33 @@ describe("Keystore", () => {
IDTrapdoor: new Uint8Array([
211, 23, 66, 42, 179, 130, 131, 111, 201, 205, 244, 34, 27, 238, 244,
216, 131, 240, 188, 45, 193, 172, 4, 168, 225, 225, 43, 197, 114, 176,
126, 9,
126, 9
]),
IDNullifier: new Uint8Array([
238, 168, 239, 65, 73, 63, 105, 19, 132, 62, 213, 205, 191, 255, 209, 9,
178, 155, 239, 201, 131, 125, 233, 136, 246, 217, 9, 237, 55, 89, 81,
42,
178, 155, 239, 201, 131, 125, 233, 136, 246, 217, 9, 237, 55, 89, 81, 42
]),
IDSecretHash: new Uint8Array([
150, 54, 194, 28, 18, 216, 138, 253, 95, 139, 120, 109, 98, 129, 146,
101, 41, 194, 36, 36, 96, 152, 152, 89, 151, 160, 118, 15, 222, 124,
187, 4,
187, 4
]),
IDCommitment: new Uint8Array([
112, 216, 27, 89, 188, 135, 203, 19, 168, 211, 117, 13, 231, 135, 229,
58, 94, 20, 246, 8, 33, 65, 238, 37, 112, 97, 65, 241, 255, 93, 171, 15,
58, 94, 20, 246, 8, 33, 65, 238, 37, 112, 97, 65, 241, 255, 93, 171, 15
]),
IDCommitmentBigInt: buildBigIntFromUint8Array(
new Uint8Array([
112, 216, 27, 89, 188, 135, 203, 19, 168, 211, 117, 13, 231, 135, 229,
58, 94, 20, 246, 8, 33, 65, 238, 37, 112, 97, 65, 241, 255, 93, 171,
15,
15
])
),
)
} as unknown as IdentityCredential;
const membership = {
chainId: "0xAA36A7",
treeIndex: 8,
address: "0x8e1F3742B987d8BA376c0CBbD7357fE1F003ED71",
address: "0x8e1F3742B987d8BA376c0CBbD7357fE1F003ED71"
} as unknown as MembershipInfo;
const store = Keystore.create();
@ -249,7 +248,7 @@ describe("Keystore", () => {
);
expect(actualCredentials).to.deep.equalInAnyOrder({
identity,
membership,
membership
});
});
@ -258,27 +257,26 @@ describe("Keystore", () => {
IDTrapdoor: [
211, 23, 66, 42, 179, 130, 131, 111, 201, 205, 244, 34, 27, 238, 244,
216, 131, 240, 188, 45, 193, 172, 4, 168, 225, 225, 43, 197, 114, 176,
126, 9,
126, 9
],
IDNullifier: [
238, 168, 239, 65, 73, 63, 105, 19, 132, 62, 213, 205, 191, 255, 209, 9,
178, 155, 239, 201, 131, 125, 233, 136, 246, 217, 9, 237, 55, 89, 81,
42,
178, 155, 239, 201, 131, 125, 233, 136, 246, 217, 9, 237, 55, 89, 81, 42
],
IDSecretHash: [
150, 54, 194, 28, 18, 216, 138, 253, 95, 139, 120, 109, 98, 129, 146,
101, 41, 194, 36, 36, 96, 152, 152, 89, 151, 160, 118, 15, 222, 124,
187, 4,
187, 4
],
IDCommitment: [
112, 216, 27, 89, 188, 135, 203, 19, 168, 211, 117, 13, 231, 135, 229,
58, 94, 20, 246, 8, 33, 65, 238, 37, 112, 97, 65, 241, 255, 93, 171, 15,
],
58, 94, 20, 246, 8, 33, 65, 238, 37, 112, 97, 65, 241, 255, 93, 171, 15
]
} as unknown as IdentityCredential;
const membership = {
chainId: "0xAA36A7",
treeIndex: 8,
address: "0x8e1F3742B987d8BA376c0CBbD7357fE1F003ED71",
address: "0x8e1F3742B987d8BA376c0CBbD7357fE1F003ED71"
} as unknown as MembershipInfo;
const store = Keystore.fromObject(NWAKU_KEYSTORE as any);

View File

@ -1,14 +1,15 @@
import type {
ICipherModule,
IKeystore as IEipKeystore,
IPbkdf2KdfModule,
IPbkdf2KdfModule
} from "@chainsafe/bls-keystore";
import { create as createEipKeystore } from "@chainsafe/bls-keystore";
import debug from "debug";
import { sha256 } from "ethereum-cryptography/sha256";
import {
bytesToHex,
bytesToUtf8,
utf8ToBytes,
utf8ToBytes
} from "ethereum-cryptography/utils";
import _ from "lodash";
import { v4 as uuidV4 } from "uuid";
@ -23,9 +24,11 @@ import type {
MembershipHash,
MembershipInfo,
Password,
Sha256Hash,
Sha256Hash
} from "./types.js";
const log = debug("waku:rln:keystore");
type NwakuCredential = {
crypto: {
cipher: ICipherModule["function"];
@ -66,7 +69,7 @@ export class Keystore {
application: "waku-rln-relay",
appIdentifier: "01234567890abcdef",
version: "0.2",
credentials: {},
credentials: {}
},
options
);
@ -88,7 +91,7 @@ export class Keystore {
return new Keystore(obj);
} catch (err) {
console.error("Cannot create Keystore from string:", err);
log("Cannot create Keystore from string:", err);
return;
}
}
@ -192,12 +195,12 @@ export class Keystore {
kdf: {
function: nwakuCrypto.kdf,
params: nwakuCrypto.kdfparams,
message: "",
message: ""
},
cipher: {
function: nwakuCrypto.cipher,
params: nwakuCrypto.cipherparams,
message: nwakuCrypto.ciphertext,
message: nwakuCrypto.ciphertext
},
checksum: {
// @chainsafe/bls-keystore supports only sha256
@ -205,8 +208,8 @@ export class Keystore {
// https://github.com/waku-org/nwaku/blob/25d6e52e3804d15f9b61bc4cc6dd448540c072a1/waku/waku_keystore/keyfile.nim#L367
function: "sha256",
params: {},
message: nwakuCrypto.mac,
},
message: nwakuCrypto.mac
}
};
return {
@ -215,7 +218,7 @@ export class Keystore {
description: undefined,
path: "safe to ignore, not important for decrypt",
pubkey: "safe to ignore, not important for decrypt",
crypto: eipCrypto,
crypto: eipCrypto
};
}
@ -235,8 +238,8 @@ export class Keystore {
// @chainsafe/bls-keystore generates only sha256
// but nwaku uses keccak256
// https://github.com/waku-org/nwaku/blob/25d6e52e3804d15f9b61bc4cc6dd448540c072a1/waku/waku_keystore/keyfile.nim#L367
mac: checksum,
},
mac: checksum
}
};
}
@ -266,16 +269,16 @@ export class Keystore {
),
IDSecretHash: Keystore.fromArraylikeToBytes(
_.get(obj, "identityCredential.idSecretHash", [])
),
)
},
membership: {
treeIndex: _.get(obj, "treeIndex"),
chainId: _.get(obj, "membershipContract.chainId"),
address: _.get(obj, "membershipContract.address"),
},
address: _.get(obj, "membershipContract.address")
}
};
} catch (err) {
console.error("Cannot parse bytes to Nwaku Credentials:", err);
log("Cannot parse bytes to Nwaku Credentials:", err);
return;
}
}
@ -315,12 +318,12 @@ export class Keystore {
idCommitment: options.identity.IDCommitment,
idNullifier: options.identity.IDNullifier,
idSecretHash: options.identity.IDSecretHash,
idTrapdoor: options.identity.IDTrapdoor,
idTrapdoor: options.identity.IDTrapdoor
},
membershipContract: {
chainId: options.membership.chainId,
address: options.membership.address,
},
address: options.membership.address
}
})
);
}

View File

@ -1,7 +1,7 @@
import type {
IDecodedMessage,
IMessage,
IRateLimitProof,
IRateLimitProof
} from "@waku/interfaces";
import * as utils from "@waku/utils/bytes";

View File

@ -4,5 +4,5 @@ export async function builder(
): Promise<WitnessCalculator>;
export class WitnessCalculator {
calculateWitness(input, sanityCheck): Array<bigint>;
calculateWitness(input, sanityCheck): Promise<Array<bigint>>;
}

View File

@ -2,7 +2,7 @@ import { createDecoder, createEncoder } from "@waku/core";
import type {
ContentTopic,
IDecodedMessage,
EncoderOptions as WakuEncoderOptions,
EncoderOptions as WakuEncoderOptions
} from "@waku/interfaces";
import init from "@waku/zerokit-rln-wasm";
import * as zerokitRLN from "@waku/zerokit-rln-wasm";
@ -12,14 +12,14 @@ import {
createRLNDecoder,
createRLNEncoder,
type RLNDecoder,
type RLNEncoder,
type RLNEncoder
} from "./codec.js";
import { RLNContract, SEPOLIA_CONTRACT } from "./contract/index.js";
import { IdentityCredential } from "./identity.js";
import { Keystore } from "./keystore/index.js";
import type {
DecryptedCredentials,
EncryptedCredentials,
EncryptedCredentials
} from "./keystore/index.js";
import { KeystoreEntity, Password } from "./keystore/types.js";
import verificationKey from "./resources/verification_key.js";
@ -45,6 +45,7 @@ async function loadZkey(): Promise<Uint8Array> {
* @returns RLNInstance
*/
export async function create(): Promise<RLNInstance> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await (init as any)?.();
zerokitRLN.init_panic_hook();
@ -128,7 +129,7 @@ export class RLNInstance {
this._signer = signer!;
this._contract = await RLNContract.init(this, {
registryAddress: registryAddress!,
signer: signer!,
signer: signer!
});
this.started = true;
} finally {
@ -161,7 +162,7 @@ export class RLNInstance {
return {
signer,
registryAddress,
registryAddress
};
}
@ -189,7 +190,7 @@ export class RLNInstance {
return {
keystore,
credentials: decryptedCredentials,
credentials: decryptedCredentials
};
}
@ -203,7 +204,7 @@ export class RLNInstance {
let identity = "identity" in options && options.identity;
if ("signature" in options) {
identity = await this.zerokit.generateSeededIdentityCredential(
identity = this.zerokit.generateSeededIdentityCredential(
options.signature
);
}
@ -243,7 +244,7 @@ export class RLNInstance {
encoder: createEncoder(options),
rlnInstance: this,
index: credentials.membership.treeIndex,
credential: credentials.identity,
credential: credentials.identity
});
}
@ -279,7 +280,7 @@ export class RLNInstance {
): RLNDecoder<IDecodedMessage> {
return createRLNDecoder({
rlnInstance: this,
decoder: createDecoder(contentTopic),
decoder: createDecoder(contentTopic)
});
}
}

View File

@ -23,7 +23,7 @@ describe("js-rln", () => {
assert.sameDeepMembers(tracker.roots(), [
new Uint8Array([0, 0, 0, 30]),
new Uint8Array([0, 0, 0, 29]),
new Uint8Array([0, 0, 0, 28]),
new Uint8Array([0, 0, 0, 28])
]);
// Buffer should keep track of 20 blocks previous to the current valid merkle root window
@ -35,7 +35,7 @@ describe("js-rln", () => {
assert.sameDeepMembers(tracker.roots(), [
new Uint8Array([0, 0, 0, 28]),
new Uint8Array([0, 0, 0, 27]),
new Uint8Array([0, 0, 0, 26]),
new Uint8Array([0, 0, 0, 26])
]);
expect(tracker.buffer()).to.have.length(18);
@ -47,7 +47,7 @@ describe("js-rln", () => {
assert.sameDeepMembers(tracker.roots(), [
new Uint8Array([0, 0, 0, 14]),
new Uint8Array([0, 0, 0, 13]),
new Uint8Array([0, 0, 0, 12]),
new Uint8Array([0, 0, 0, 12])
]);
expect(tracker.buffer()).to.have.length(4);
expect(tracker.buffer()[0]).to.be.eql(new Uint8Array([0, 0, 0, 8]));

View File

@ -1,5 +1,8 @@
class RootPerBlock {
constructor(public root: Uint8Array, public blockNumber: number) {}
constructor(
public root: Uint8Array,
public blockNumber: number
) {}
}
const maxBufferSize = 20;

View File

@ -3,7 +3,7 @@ export {
concatenate,
writeUIntLE,
buildBigIntFromUint8Array,
zeroPadLE,
zeroPadLE
} from "./bytes.js";
export { sha256, poseidonHash } from "./hash.js";
export { dateToEpoch, epochIntToBytes, epochBytesToInt } from "./epoch.js";

View File

@ -1,6 +1,7 @@
import { ethers } from "ethers";
export const extractMetaMaskSigner = async (): Promise<ethers.Signer> => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const ethereum = (window as any).ethereum;
if (!ethereum) {

View File

@ -8,7 +8,7 @@ import {
concatenate,
dateToEpoch,
epochIntToBytes,
writeUIntLE,
writeUIntLE
} from "./utils/index.js";
export class Zerokit {

View File

@ -1,8 +1,8 @@
{
"extends": "./tsconfig",
"compilerOptions": {
"module": "esnext",
"module": "ESNext",
"moduleResolution": "Bundler",
"noEmit": true
},
"exclude": []
}
}
}

View File

@ -1,18 +1,15 @@
{
"compilerOptions": {
"incremental": true,
"target": "es2020",
"outDir": "dist/",
"rootDir": "src",
"moduleResolution": "node16",
"module": "es2020",
"target": "ES2022",
"moduleResolution": "Bundler",
"module": "ES2022",
"declaration": true,
"allowJs": true,
"sourceMap": true,
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
"resolveJsonModule": true /* Include modules imported with .json extension. */,
"tsBuildInfoFile": "dist/.tsbuildinfo",
"strict": true /* Enable all strict type-checking options. */,
/* Strict Type-Checking Options */
"noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
"strictNullChecks": true /* Enable strict null checks. */,
@ -20,30 +17,37 @@
"strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */,
"noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */,
"alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */,
/* Additional Checks */
"noUnusedLocals": true /* Report errors on unused locals. */,
"noUnusedParameters": true /* Report errors on unused parameters. */,
"noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
"noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,
"forceConsistentCasingInFileNames": true,
/* Debugging Options */
"traceResolution": false /* Report module resolution log messages. */,
"listEmittedFiles": false /* Print names of generated files part of the compilation. */,
"listFiles": false /* Print names of files part of the compilation. */,
"pretty": true /* Stylize errors and messages using color and context. */,
// Due to broken types in indirect dependencies
"skipLibCheck": true,
"allowJs": true,
/* Experimental Options */
// "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */,
// "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */,
"lib": ["es2020", "dom"],
"lib": ["es2022", "dom"],
"types": ["node", "mocha"],
"typeRoots": ["node_modules/@types", "src/types"]
"typeRoots": ["node_modules/@types"],
"outDir": "dist/",
"rootDir": "src",
},
"include": ["src"],
"exclude": ["src/**/*.spec.ts", "src/test_utils"],
"compileOnSave": false,
"ts-node": {
"files": true
}
}
}