@waku/rln 0.1.6-acc9100.0 → 0.1.6-b0a2e39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/bundle/_virtual/utils.js +2 -2
  2. package/bundle/_virtual/utils2.js +2 -2
  3. package/bundle/index.js +1 -1
  4. package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/@noble/hashes/_sha2.js +1 -1
  5. package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/@noble/hashes/hmac.js +1 -1
  6. package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/@noble/hashes/pbkdf2.js +1 -1
  7. package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/@noble/hashes/scrypt.js +1 -1
  8. package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/@noble/hashes/sha256.js +1 -1
  9. package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/@noble/hashes/sha512.js +1 -1
  10. package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/@noble/hashes/utils.js +1 -1
  11. package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/random.js +1 -1
  12. package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/utils.js +2 -2
  13. package/bundle/packages/core/dist/lib/connection_manager/connection_manager.js +1 -0
  14. package/bundle/packages/core/dist/lib/connection_manager/keep_alive_manager.js +1 -0
  15. package/bundle/packages/core/dist/lib/filter/filter.js +2 -0
  16. package/bundle/packages/core/dist/lib/light_push/light_push.js +12 -9
  17. package/bundle/packages/core/dist/lib/light_push/light_push_v3.js +30 -0
  18. package/bundle/packages/core/dist/lib/light_push/utils.js +18 -0
  19. package/bundle/packages/core/dist/lib/message/version_0.js +1 -0
  20. package/bundle/packages/core/dist/lib/metadata/metadata.js +2 -0
  21. package/bundle/packages/core/dist/lib/store/store.js +2 -0
  22. package/bundle/packages/interfaces/dist/light_push_v3.js +29 -0
  23. package/bundle/packages/interfaces/dist/protocols.js +10 -0
  24. package/bundle/packages/proto/dist/generated/light_push.js +3 -3
  25. package/bundle/packages/proto/dist/generated/light_push_v3.js +348 -0
  26. package/bundle/packages/rln/dist/codec.js +1 -0
  27. package/bundle/packages/rln/dist/contract/constants.js +1 -7
  28. package/bundle/packages/rln/dist/contract/rln_base_contract.js +7 -28
  29. package/bundle/packages/rln/dist/contract/rln_contract.js +1 -0
  30. package/bundle/packages/rln/dist/credentials_manager.js +15 -16
  31. package/bundle/packages/rln/dist/identity.js +8 -5
  32. package/bundle/packages/rln/dist/keystore/keystore.js +12 -15
  33. package/bundle/packages/rln/dist/message.js +2 -0
  34. package/bundle/packages/rln/dist/rln.js +2 -0
  35. package/bundle/packages/rln/dist/utils/bytes.js +16 -14
  36. package/bundle/packages/rln/dist/utils/epoch.js +1 -0
  37. package/bundle/packages/utils/dist/common/sharding/index.js +1 -0
  38. package/dist/.tsbuildinfo +1 -1
  39. package/dist/contract/constants.d.ts +0 -6
  40. package/dist/contract/constants.js +0 -6
  41. package/dist/contract/constants.js.map +1 -1
  42. package/dist/contract/rln_base_contract.d.ts +0 -6
  43. package/dist/contract/rln_base_contract.js +6 -28
  44. package/dist/contract/rln_base_contract.js.map +1 -1
  45. package/dist/contract/test-utils.d.ts +39 -0
  46. package/dist/contract/test-utils.js +118 -0
  47. package/dist/contract/test-utils.js.map +1 -0
  48. package/dist/credentials_manager.js +14 -16
  49. package/dist/credentials_manager.js.map +1 -1
  50. package/dist/identity.d.ts +2 -4
  51. package/dist/identity.js +6 -5
  52. package/dist/identity.js.map +1 -1
  53. package/dist/keystore/keystore.js +11 -15
  54. package/dist/keystore/keystore.js.map +1 -1
  55. package/dist/utils/bytes.d.ts +6 -2
  56. package/dist/utils/bytes.js +15 -13
  57. package/dist/utils/bytes.js.map +1 -1
  58. package/dist/utils/index.d.ts +1 -1
  59. package/dist/utils/index.js +1 -1
  60. package/dist/utils/index.js.map +1 -1
  61. package/package.json +1 -1
  62. package/src/contract/constants.ts +0 -9
  63. package/src/contract/rln_base_contract.ts +13 -41
  64. package/src/contract/test-utils.ts +179 -0
  65. package/src/credentials_manager.ts +21 -27
  66. package/src/identity.ts +7 -5
  67. package/src/keystore/keystore.ts +24 -28
  68. package/src/utils/bytes.ts +25 -21
  69. package/src/utils/index.ts +1 -1
@@ -4,9 +4,13 @@
4
4
  * @returns concatenation of all Uint8Array received as input
5
5
  */
6
6
  export declare function concatenate(...input: Uint8Array[]): Uint8Array;
7
- export declare function switchEndianness(bytes: Uint8Array): Uint8Array;
8
- export declare function buildBigIntFromUint8ArrayBE(bytes: Uint8Array): bigint;
9
7
  export declare function writeUIntLE(buf: Uint8Array, value: number, offset: number, byteLength: number, noAssert?: boolean): Uint8Array;
8
+ /**
9
+ * Transforms Uint8Array into BigInt
10
+ * @param array: Uint8Array
11
+ * @returns BigInt
12
+ */
13
+ export declare function buildBigIntFromUint8Array(array: Uint8Array, byteOffset?: number): bigint;
10
14
  /**
11
15
  * Fills with zeros to set length
12
16
  * @param array little endian Uint8Array
@@ -16,12 +16,12 @@ export function concatenate(...input) {
16
16
  }
17
17
  return result;
18
18
  }
19
- export function switchEndianness(bytes) {
20
- return new Uint8Array(bytes.reverse());
21
- }
22
- export function buildBigIntFromUint8ArrayBE(bytes) {
23
- // Interpret bytes as big-endian
24
- return bytes.reduce((acc, byte) => (acc << 8n) + BigInt(byte), 0n);
19
+ // Adapted from https://github.com/feross/buffer
20
+ function checkInt(buf, value, offset, ext, max, min) {
21
+ if (value > max || value < min)
22
+ throw new RangeError('"value" argument is out of bounds');
23
+ if (offset + ext > buf.length)
24
+ throw new RangeError("Index out of range");
25
25
  }
26
26
  export function writeUIntLE(buf, value, offset, byteLength, noAssert) {
27
27
  value = +value;
@@ -39,6 +39,15 @@ export function writeUIntLE(buf, value, offset, byteLength, noAssert) {
39
39
  }
40
40
  return buf;
41
41
  }
42
+ /**
43
+ * Transforms Uint8Array into BigInt
44
+ * @param array: Uint8Array
45
+ * @returns BigInt
46
+ */
47
+ export function buildBigIntFromUint8Array(array, byteOffset = 0) {
48
+ const dataView = new DataView(array.buffer);
49
+ return dataView.getBigUint64(byteOffset, true);
50
+ }
42
51
  /**
43
52
  * Fills with zeros to set length
44
53
  * @param array little endian Uint8Array
@@ -52,11 +61,4 @@ export function zeroPadLE(array, length) {
52
61
  }
53
62
  return result;
54
63
  }
55
- // Adapted from https://github.com/feross/buffer
56
- function checkInt(buf, value, offset, ext, max, min) {
57
- if (value > max || value < min)
58
- throw new RangeError('"value" argument is out of bounds');
59
- if (offset + ext > buf.length)
60
- throw new RangeError("Index out of range");
61
- }
62
64
  //# sourceMappingURL=bytes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bytes.js","sourceRoot":"","sources":["../../src/utils/bytes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,GAAG,KAAmB;IAChD,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,WAAW,IAAI,GAAG,CAAC,MAAM,CAAC;IAC5B,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;IAC3C,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACxB,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC;IACvB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAiB;IAChD,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,KAAiB;IAC3D,gCAAgC;IAChC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,GAAe,EACf,KAAa,EACb,MAAc,EACd,UAAkB,EAClB,QAAkB;IAElB,KAAK,GAAG,CAAC,KAAK,CAAC;IACf,MAAM,GAAG,MAAM,KAAK,CAAC,CAAC;IACtB,UAAU,GAAG,UAAU,KAAK,CAAC,CAAC;IAC9B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QACjD,QAAQ,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,CAAC,GAAG,UAAU,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC,EAAE,CAAC;QAC1C,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC;IACzC,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,KAAiB,EAAE,MAAc;IACzD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gDAAgD;AAChD,SAAS,QAAQ,CACf,GAAe,EACf,KAAa,EACb,MAAc,EACd,GAAW,EACX,GAAW,EACX,GAAW;IAEX,IAAI,KAAK,GAAG,GAAG,IAAI,KAAK,GAAG,GAAG;QAC5B,MAAM,IAAI,UAAU,CAAC,mCAAmC,CAAC,CAAC;IAC5D,IAAI,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM;QAAE,MAAM,IAAI,UAAU,CAAC,oBAAoB,CAAC,CAAC;AAC5E,CAAC"}
1
+ {"version":3,"file":"bytes.js","sourceRoot":"","sources":["../../src/utils/bytes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,GAAG,KAAmB;IAChD,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,WAAW,IAAI,GAAG,CAAC,MAAM,CAAC;IAC5B,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;IAC3C,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACxB,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC;IACvB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gDAAgD;AAChD,SAAS,QAAQ,CACf,GAAe,EACf,KAAa,EACb,MAAc,EACd,GAAW,EACX,GAAW,EACX,GAAW;IAEX,IAAI,KAAK,GAAG,GAAG,IAAI,KAAK,GAAG,GAAG;QAC5B,MAAM,IAAI,UAAU,CAAC,mCAAmC,CAAC,CAAC;IAC5D,IAAI,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM;QAAE,MAAM,IAAI,UAAU,CAAC,oBAAoB,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,GAAe,EACf,KAAa,EACb,MAAc,EACd,UAAkB,EAClB,QAAkB;IAElB,KAAK,GAAG,CAAC,KAAK,CAAC;IACf,MAAM,GAAG,MAAM,KAAK,CAAC,CAAC;IACtB,UAAU,GAAG,UAAU,KAAK,CAAC,CAAC;IAC9B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QACjD,QAAQ,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,CAAC,GAAG,UAAU,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC,EAAE,CAAC;QAC1C,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC;IACzC,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACvC,KAAiB,EACjB,aAAqB,CAAC;IAEtB,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC5C,OAAO,QAAQ,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AACjD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,KAAiB,EAAE,MAAc;IACzD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1,4 +1,4 @@
1
1
  export { extractMetaMaskSigner } from "./metamask.js";
2
- export { concatenate, writeUIntLE, switchEndianness, zeroPadLE } from "./bytes.js";
2
+ export { concatenate, writeUIntLE, buildBigIntFromUint8Array, zeroPadLE } from "./bytes.js";
3
3
  export { sha256, poseidonHash } from "./hash.js";
4
4
  export { dateToEpoch, epochIntToBytes, epochBytesToInt } from "./epoch.js";
@@ -1,5 +1,5 @@
1
1
  export { extractMetaMaskSigner } from "./metamask.js";
2
- export { concatenate, writeUIntLE, switchEndianness, zeroPadLE } from "./bytes.js";
2
+ export { concatenate, writeUIntLE, buildBigIntFromUint8Array, zeroPadLE } from "./bytes.js";
3
3
  export { sha256, poseidonHash } from "./hash.js";
4
4
  export { dateToEpoch, epochIntToBytes, epochBytesToInt } from "./epoch.js";
5
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EACL,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,SAAS,EACV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EACL,WAAW,EACX,WAAW,EACX,yBAAyB,EACzB,SAAS,EACV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@waku/rln","version":"0.1.6-acc9100.0","description":"RLN (Rate Limiting Nullifier) implementation for Waku","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"type":"module","homepage":"https://github.com/waku-org/js-waku/tree/master/packages/rln#readme","repository":{"type":"git","url":"https://github.com/waku-org/js-waku.git"},"bugs":{"url":"https://github.com/waku-org/js-waku/issues"},"license":"MIT OR Apache-2.0","keywords":["waku","rln","rate-limiting","privacy","web3"],"scripts":{"build":"run-s build:**","build:copy":"mkdir -p dist/resources && cp -r src/resources/* dist/resources/","build:esm":"tsc","build:bundle":"rollup --config rollup.config.js","fix":"run-s fix:*","fix:lint":"eslint src *.js --fix","check":"run-s check:*","check:tsc":"tsc -p tsconfig.dev.json","check:lint":"eslint \"src/!(resources)/**/*.{ts,js}\" *.js","check:spelling":"cspell \"{README.md,src/**/*.ts}\"","test":"NODE_ENV=test run-s test:*","test:browser":"karma start karma.conf.cjs","watch:build":"tsc -p tsconfig.json -w","watch:test":"mocha --watch","prepublish":"npm run build","reset-hard":"git clean -dfx -e .idea && git reset --hard && npm i && npm run build"},"engines":{"node":">=20"},"devDependencies":{"@rollup/plugin-commonjs":"^25.0.7","@rollup/plugin-json":"^6.0.0","@rollup/plugin-node-resolve":"^15.2.3","@types/chai":"^5.0.1","@types/chai-spies":"^1.0.6","@waku/interfaces":"0.0.31-acc9100.0","@types/deep-equal-in-any-order":"^1.0.4","@types/lodash":"^4.17.15","@types/sinon":"^17.0.3","@waku/build-utils":"^1.0.0","@waku/message-encryption":"0.0.34-acc9100.0","deep-equal-in-any-order":"^2.0.6","fast-check":"^3.23.2","rollup-plugin-copy":"^3.5.0"},"files":["dist","bundle","src/**/*.ts","!**/*.spec.*","!**/*.json","CHANGELOG.md","LICENSE","README.md"],"dependencies":{"@chainsafe/bls-keystore":"3.0.0","@waku/core":"0.0.36-acc9100.0","@waku/utils":"0.0.24-acc9100.0","@noble/hashes":"^1.2.0","@waku/zerokit-rln-wasm":"^0.0.13","ethereum-cryptography":"^3.1.0","ethers":"^5.7.2","lodash":"^4.17.21","uuid":"^11.0.5","chai":"^5.1.2","chai-as-promised":"^8.0.1","chai-spies":"^1.1.0","chai-subset":"^1.6.0","sinon":"^19.0.2"}}
1
+ {"name":"@waku/rln","version":"0.1.6-b0a2e39.0","description":"RLN (Rate Limiting Nullifier) implementation for Waku","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"type":"module","homepage":"https://github.com/waku-org/js-waku/tree/master/packages/rln#readme","repository":{"type":"git","url":"https://github.com/waku-org/js-waku.git"},"bugs":{"url":"https://github.com/waku-org/js-waku/issues"},"license":"MIT OR Apache-2.0","keywords":["waku","rln","rate-limiting","privacy","web3"],"scripts":{"build":"run-s build:**","build:copy":"mkdir -p dist/resources && cp -r src/resources/* dist/resources/","build:esm":"tsc","build:bundle":"rollup --config rollup.config.js","fix":"run-s fix:*","fix:lint":"eslint src *.js --fix","check":"run-s check:*","check:tsc":"tsc -p tsconfig.dev.json","check:lint":"eslint \"src/!(resources)/**/*.{ts,js}\" *.js","check:spelling":"cspell \"{README.md,src/**/*.ts}\"","test":"NODE_ENV=test run-s test:*","test:browser":"karma start karma.conf.cjs","watch:build":"tsc -p tsconfig.json -w","watch:test":"mocha --watch","prepublish":"npm run build","reset-hard":"git clean -dfx -e .idea && git reset --hard && npm i && npm run build"},"engines":{"node":">=20"},"devDependencies":{"@rollup/plugin-commonjs":"^25.0.7","@rollup/plugin-json":"^6.0.0","@rollup/plugin-node-resolve":"^15.2.3","@types/chai":"^5.0.1","@types/chai-spies":"^1.0.6","@waku/interfaces":"0.0.31-b0a2e39.0","@types/deep-equal-in-any-order":"^1.0.4","@types/lodash":"^4.17.15","@types/sinon":"^17.0.3","@waku/build-utils":"^1.0.0","@waku/message-encryption":"0.0.34-b0a2e39.0","deep-equal-in-any-order":"^2.0.6","fast-check":"^3.23.2","rollup-plugin-copy":"^3.5.0"},"files":["dist","bundle","src/**/*.ts","!**/*.spec.*","!**/*.json","CHANGELOG.md","LICENSE","README.md"],"dependencies":{"@chainsafe/bls-keystore":"3.0.0","@waku/core":"0.0.36-b0a2e39.0","@waku/utils":"0.0.24-b0a2e39.0","@noble/hashes":"^1.2.0","@waku/zerokit-rln-wasm":"^0.0.13","ethereum-cryptography":"^3.1.0","ethers":"^5.7.2","lodash":"^4.17.21","uuid":"^11.0.5","chai":"^5.1.2","chai-as-promised":"^8.0.1","chai-spies":"^1.1.0","chai-subset":"^1.6.0","sinon":"^19.0.2"}}
@@ -25,13 +25,4 @@ export const RATE_LIMIT_PARAMS = {
25
25
  EPOCH_LENGTH: 600 // Epoch length in seconds (10 minutes)
26
26
  } as const;
27
27
 
28
- /**
29
- * Default Q value for the RLN contract
30
- * This is the upper bound for the ID commitment
31
- * @see https://github.com/waku-org/specs/blob/master/standards/core/rln-contract.md#implementation-suggestions
32
- */
33
- export const DEFAULT_Q = BigInt(
34
- "21888242871839275222246405745257275088548364400416034343698204186575808495617"
35
- );
36
-
37
28
  export const DEFAULT_RATE_LIMIT = RATE_LIMIT_PARAMS.MAX_RATE;
@@ -3,14 +3,9 @@ import { ethers } from "ethers";
3
3
 
4
4
  import { IdentityCredential } from "../identity.js";
5
5
  import { DecryptedCredentials } from "../keystore/types.js";
6
- import { buildBigIntFromUint8ArrayBE } from "../utils/bytes.js";
7
6
 
8
7
  import { RLN_ABI } from "./abi.js";
9
- import {
10
- DEFAULT_Q,
11
- DEFAULT_RATE_LIMIT,
12
- RATE_LIMIT_PARAMS
13
- } from "./constants.js";
8
+ import { DEFAULT_RATE_LIMIT, RATE_LIMIT_PARAMS } from "./constants.js";
14
9
  import {
15
10
  CustomQueryOptions,
16
11
  FetchMembersOptions,
@@ -30,12 +25,6 @@ export class RLNBaseContract {
30
25
  private minRateLimit?: number;
31
26
  private maxRateLimit?: number;
32
27
 
33
- /**
34
- * Default Q value for the RLN contract.
35
- * @see https://github.com/waku-org/waku-rlnv2-contract/blob/b7e9a9b1bc69256a2a3076c1f099b50ce84e7eff/src/WakuRlnV2.sol#L25
36
- */
37
- public idCommitmentBigIntLimit = DEFAULT_Q;
38
-
39
28
  protected _members: Map<number, Member> = new Map();
40
29
  private _membersFilter: ethers.EventFilter;
41
30
  private _membershipErasedFilter: ethers.EventFilter;
@@ -90,8 +79,7 @@ export class RLNBaseContract {
90
79
  const instance = new RLNBaseContract(options);
91
80
  const [min, max] = await Promise.all([
92
81
  instance.contract.minMembershipRateLimit(),
93
- instance.contract.maxMembershipRateLimit(),
94
- instance.contract.Q()
82
+ instance.contract.maxMembershipRateLimit()
95
83
  ]);
96
84
  instance.minRateLimit = ethers.BigNumber.from(min).toNumber();
97
85
  instance.maxRateLimit = ethers.BigNumber.from(max).toNumber();
@@ -503,23 +491,6 @@ export class RLNBaseContract {
503
491
  }
504
492
  }
505
493
 
506
- private getIdCommitmentBigInt(bytes: Uint8Array): bigint {
507
- let idCommitmentBigIntBE = buildBigIntFromUint8ArrayBE(bytes);
508
-
509
- if (!this.contract) {
510
- throw Error("RLN contract is not initialized");
511
- }
512
-
513
- if (idCommitmentBigIntBE >= this.idCommitmentBigIntLimit) {
514
- log.warn(
515
- `ID commitment is greater than Q, reducing it by Q(idCommitmentBigIntLimit): ${idCommitmentBigIntBE} % ${this.idCommitmentBigIntLimit}`
516
- );
517
- idCommitmentBigIntBE =
518
- idCommitmentBigIntBE % this.idCommitmentBigIntLimit;
519
- }
520
- return idCommitmentBigIntBE;
521
- }
522
-
523
494
  public async registerWithIdentity(
524
495
  identity: IdentityCredential
525
496
  ): Promise<DecryptedCredentials | undefined> {
@@ -528,12 +499,10 @@ export class RLNBaseContract {
528
499
  `Registering identity with rate limit: ${this.rateLimit} messages/epoch`
529
500
  );
530
501
 
531
- const idCommitmentBigInt = this.getIdCommitmentBigInt(
532
- identity.IDCommitment
533
- );
534
-
535
502
  // Check if the ID commitment is already registered
536
- const existingIndex = await this.getMemberIndex(idCommitmentBigInt);
503
+ const existingIndex = await this.getMemberIndex(
504
+ identity.IDCommitmentBigInt
505
+ );
537
506
  if (existingIndex) {
538
507
  throw new Error(
539
508
  `ID commitment is already registered with index ${existingIndex}`
@@ -549,16 +518,19 @@ export class RLNBaseContract {
549
518
  }
550
519
 
551
520
  const estimatedGas = await this.contract.estimateGas.register(
552
- idCommitmentBigInt,
521
+ identity.IDCommitmentBigInt,
553
522
  this.rateLimit,
554
523
  []
555
524
  );
556
525
  const gasLimit = estimatedGas.add(10000);
557
526
 
558
527
  const txRegisterResponse: ethers.ContractTransaction =
559
- await this.contract.register(idCommitmentBigInt, this.rateLimit, [], {
560
- gasLimit
561
- });
528
+ await this.contract.register(
529
+ identity.IDCommitmentBigInt,
530
+ this.rateLimit,
531
+ [],
532
+ { gasLimit }
533
+ );
562
534
 
563
535
  const txRegisterReceipt = await txRegisterResponse.wait();
564
536
 
@@ -654,7 +626,7 @@ export class RLNBaseContract {
654
626
  permit.v,
655
627
  permit.r,
656
628
  permit.s,
657
- this.getIdCommitmentBigInt(identity.IDCommitment),
629
+ identity.IDCommitmentBigInt,
658
630
  this.rateLimit,
659
631
  idCommitmentsToErase.map((id) => ethers.BigNumber.from(id))
660
632
  );
@@ -0,0 +1,179 @@
1
+ import { hexToBytes } from "@waku/utils/bytes";
2
+ import { expect } from "chai";
3
+ import * as ethers from "ethers";
4
+ import sinon from "sinon";
5
+
6
+ import type { IdentityCredential } from "../identity.js";
7
+
8
+ import { DEFAULT_RATE_LIMIT, LINEA_CONTRACT } from "./constants.js";
9
+
10
+ export const mockRateLimits = {
11
+ minRate: 20,
12
+ maxRate: 600,
13
+ maxTotalRate: 1200,
14
+ currentTotalRate: 500
15
+ };
16
+
17
+ type MockProvider = {
18
+ getLogs: () => never[];
19
+ getBlockNumber: () => Promise<number>;
20
+ getNetwork: () => Promise<{ chainId: number }>;
21
+ };
22
+
23
+ type MockFilters = {
24
+ MembershipRegistered: () => { address: string };
25
+ MembershipErased: () => { address: string };
26
+ MembershipExpired: () => { address: string };
27
+ };
28
+
29
+ export function createMockProvider(): MockProvider {
30
+ return {
31
+ getLogs: () => [],
32
+ getBlockNumber: () => Promise.resolve(1000),
33
+ getNetwork: () => Promise.resolve({ chainId: 11155111 })
34
+ };
35
+ }
36
+
37
+ export function createMockFilters(): MockFilters {
38
+ return {
39
+ MembershipRegistered: () => ({ address: LINEA_CONTRACT.address }),
40
+ MembershipErased: () => ({ address: LINEA_CONTRACT.address }),
41
+ MembershipExpired: () => ({ address: LINEA_CONTRACT.address })
42
+ };
43
+ }
44
+
45
+ type ContractOverrides = Partial<{
46
+ filters: Record<string, unknown>;
47
+ [key: string]: unknown;
48
+ }>;
49
+
50
+ export function createMockRegistryContract(
51
+ overrides: ContractOverrides = {}
52
+ ): ethers.Contract {
53
+ const filters = {
54
+ MembershipRegistered: () => ({ address: LINEA_CONTRACT.address }),
55
+ MembershipErased: () => ({ address: LINEA_CONTRACT.address }),
56
+ MembershipExpired: () => ({ address: LINEA_CONTRACT.address })
57
+ };
58
+
59
+ const baseContract = {
60
+ minMembershipRateLimit: () =>
61
+ Promise.resolve(ethers.BigNumber.from(mockRateLimits.minRate)),
62
+ maxMembershipRateLimit: () =>
63
+ Promise.resolve(ethers.BigNumber.from(mockRateLimits.maxRate)),
64
+ maxTotalRateLimit: () =>
65
+ Promise.resolve(ethers.BigNumber.from(mockRateLimits.maxTotalRate)),
66
+ currentTotalRateLimit: () =>
67
+ Promise.resolve(ethers.BigNumber.from(mockRateLimits.currentTotalRate)),
68
+ queryFilter: () => [],
69
+ provider: createMockProvider(),
70
+ filters,
71
+ on: () => ({}),
72
+ removeAllListeners: () => ({}),
73
+ register: () => ({
74
+ wait: () =>
75
+ Promise.resolve({
76
+ events: [mockRLNRegisteredEvent()]
77
+ })
78
+ }),
79
+ estimateGas: {
80
+ register: () => Promise.resolve(ethers.BigNumber.from(100000))
81
+ },
82
+ functions: {
83
+ register: () => Promise.resolve()
84
+ },
85
+ getMemberIndex: () => Promise.resolve(null),
86
+ interface: {
87
+ getEvent: (eventName: string) => ({
88
+ name: eventName,
89
+ format: () => {}
90
+ })
91
+ },
92
+ address: LINEA_CONTRACT.address
93
+ };
94
+
95
+ // Merge overrides while preserving filters
96
+ const merged = {
97
+ ...baseContract,
98
+ ...overrides,
99
+ filters: { ...filters, ...(overrides.filters || {}) }
100
+ };
101
+
102
+ return merged as unknown as ethers.Contract;
103
+ }
104
+
105
+ export function mockRLNRegisteredEvent(idCommitment?: string): ethers.Event {
106
+ return {
107
+ args: {
108
+ idCommitment:
109
+ idCommitment ||
110
+ "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
111
+ membershipRateLimit: ethers.BigNumber.from(DEFAULT_RATE_LIMIT),
112
+ index: ethers.BigNumber.from(1)
113
+ },
114
+ event: "MembershipRegistered"
115
+ } as unknown as ethers.Event;
116
+ }
117
+
118
+ export function formatIdCommitment(idCommitmentBigInt: bigint): string {
119
+ return "0x" + idCommitmentBigInt.toString(16).padStart(64, "0");
120
+ }
121
+
122
+ export function createRegisterStub(
123
+ identity: IdentityCredential
124
+ ): sinon.SinonStub {
125
+ return sinon.stub().callsFake(() => ({
126
+ wait: () =>
127
+ Promise.resolve({
128
+ events: [
129
+ {
130
+ event: "MembershipRegistered",
131
+ args: {
132
+ idCommitment: formatIdCommitment(identity.IDCommitmentBigInt),
133
+ membershipRateLimit: ethers.BigNumber.from(DEFAULT_RATE_LIMIT),
134
+ index: ethers.BigNumber.from(1)
135
+ }
136
+ }
137
+ ]
138
+ })
139
+ }));
140
+ }
141
+
142
+ export function verifyRegistration(
143
+ decryptedCredentials: any,
144
+ identity: IdentityCredential,
145
+ registerStub: sinon.SinonStub,
146
+ insertMemberSpy: sinon.SinonStub
147
+ ): void {
148
+ if (!decryptedCredentials) {
149
+ throw new Error("Decrypted credentials should not be undefined");
150
+ }
151
+
152
+ // Verify registration call
153
+ expect(
154
+ registerStub.calledWith(
155
+ sinon.match.same(identity.IDCommitmentBigInt),
156
+ sinon.match.same(DEFAULT_RATE_LIMIT),
157
+ sinon.match.array,
158
+ sinon.match.object
159
+ )
160
+ ).to.be.true;
161
+
162
+ // Verify credential properties
163
+ expect(decryptedCredentials).to.have.property("identity");
164
+ expect(decryptedCredentials).to.have.property("membership");
165
+ expect(decryptedCredentials.membership).to.include({
166
+ address: LINEA_CONTRACT.address,
167
+ treeIndex: 1
168
+ });
169
+
170
+ // Verify member insertion
171
+ const expectedIdCommitment = ethers.utils.zeroPad(
172
+ hexToBytes(formatIdCommitment(identity.IDCommitmentBigInt)),
173
+ 32
174
+ );
175
+ expect(insertMemberSpy.callCount).to.equal(1);
176
+ expect(insertMemberSpy.getCall(0).args[0]).to.deep.equal(
177
+ expectedIdCommitment
178
+ );
179
+ }
@@ -1,5 +1,5 @@
1
1
  import { hmac } from "@noble/hashes/hmac";
2
- import { sha256 } from "@noble/hashes/sha2";
2
+ import { sha256 } from "@noble/hashes/sha256";
3
3
  import { Logger } from "@waku/utils";
4
4
  import { ethers } from "ethers";
5
5
 
@@ -13,7 +13,10 @@ import type {
13
13
  } from "./keystore/index.js";
14
14
  import { KeystoreEntity, Password } from "./keystore/types.js";
15
15
  import { RegisterMembershipOptions, StartRLNOptions } from "./types.js";
16
- import { extractMetaMaskSigner, switchEndianness } from "./utils/index.js";
16
+ import {
17
+ buildBigIntFromUint8Array,
18
+ extractMetaMaskSigner
19
+ } from "./utils/index.js";
17
20
  import { Zerokit } from "./zerokit.js";
18
21
 
19
22
  const log = new Logger("waku:credentials");
@@ -113,9 +116,7 @@ export class RLNCredentialsManager {
113
116
  );
114
117
  } else {
115
118
  log.info("Using local implementation to generate identity");
116
- identity = await this.generateSeededIdentityCredential(
117
- options.signature
118
- );
119
+ identity = this.generateSeededIdentityCredential(options.signature);
119
120
  }
120
121
  }
121
122
 
@@ -248,9 +249,7 @@ export class RLNCredentialsManager {
248
249
  * @param seed A string seed to generate the identity from
249
250
  * @returns IdentityCredential
250
251
  */
251
- private async generateSeededIdentityCredential(
252
- seed: string
253
- ): Promise<IdentityCredential> {
252
+ private generateSeededIdentityCredential(seed: string): IdentityCredential {
254
253
  log.info("Generating seeded identity credential");
255
254
  // Convert the seed to bytes
256
255
  const encoder = new TextEncoder();
@@ -258,31 +257,26 @@ export class RLNCredentialsManager {
258
257
 
259
258
  // Generate deterministic values using HMAC-SHA256
260
259
  // We use different context strings for each component to ensure they're different
261
- const idTrapdoorBE = hmac(sha256, seedBytes, encoder.encode("IDTrapdoor"));
262
- const idNullifierBE = hmac(
263
- sha256,
264
- seedBytes,
265
- encoder.encode("IDNullifier")
266
- );
260
+ const idTrapdoor = hmac(sha256, seedBytes, encoder.encode("IDTrapdoor"));
261
+ const idNullifier = hmac(sha256, seedBytes, encoder.encode("IDNullifier"));
267
262
 
268
- const combinedBytes = new Uint8Array([...idTrapdoorBE, ...idNullifierBE]);
269
- const idSecretHashBE = sha256(combinedBytes);
263
+ // Generate IDSecretHash as a hash of IDTrapdoor and IDNullifier
264
+ const combinedBytes = new Uint8Array([...idTrapdoor, ...idNullifier]);
265
+ const idSecretHash = sha256(combinedBytes);
270
266
 
271
- const idCommitmentBE = sha256(idSecretHashBE);
267
+ // Generate IDCommitment as a hash of IDSecretHash
268
+ const idCommitment = sha256(idSecretHash);
272
269
 
273
- // All hashing functions return big-endian bytes
274
- // We need to switch to little-endian for the identity credential
275
- const idTrapdoorLE = switchEndianness(idTrapdoorBE);
276
- const idNullifierLE = switchEndianness(idNullifierBE);
277
- const idSecretHashLE = switchEndianness(idSecretHashBE);
278
- const idCommitmentLE = switchEndianness(idCommitmentBE);
270
+ // Convert IDCommitment to BigInt
271
+ const idCommitmentBigInt = buildBigIntFromUint8Array(idCommitment);
279
272
 
280
273
  log.info("Successfully generated identity credential");
281
274
  return new IdentityCredential(
282
- idTrapdoorLE,
283
- idNullifierLE,
284
- idSecretHashLE,
285
- idCommitmentLE
275
+ idTrapdoor,
276
+ idNullifier,
277
+ idSecretHash,
278
+ idCommitment,
279
+ idCommitmentBigInt
286
280
  );
287
281
  }
288
282
  }
package/src/identity.ts CHANGED
@@ -1,12 +1,12 @@
1
+ import { buildBigIntFromUint8Array } from "./utils/index.js";
2
+
1
3
  export class IdentityCredential {
2
- /**
3
- * All variables are in little-endian format
4
- */
5
4
  public constructor(
6
5
  public readonly IDTrapdoor: Uint8Array,
7
6
  public readonly IDNullifier: Uint8Array,
8
7
  public readonly IDSecretHash: Uint8Array,
9
- public readonly IDCommitment: Uint8Array
8
+ public readonly IDCommitment: Uint8Array,
9
+ public readonly IDCommitmentBigInt: bigint
10
10
  ) {}
11
11
 
12
12
  public static fromBytes(memKeys: Uint8Array): IdentityCredential {
@@ -18,12 +18,14 @@ export class IdentityCredential {
18
18
  const idNullifier = memKeys.subarray(32, 64);
19
19
  const idSecretHash = memKeys.subarray(64, 96);
20
20
  const idCommitment = memKeys.subarray(96, 128);
21
+ const idCommitmentBigInt = buildBigIntFromUint8Array(idCommitment, 32);
21
22
 
22
23
  return new IdentityCredential(
23
24
  idTrapdoor,
24
25
  idNullifier,
25
26
  idSecretHash,
26
- idCommitment
27
+ idCommitment,
28
+ idCommitmentBigInt
27
29
  );
28
30
  }
29
31
  }
@@ -14,6 +14,8 @@ import {
14
14
  import _ from "lodash";
15
15
  import { v4 as uuidV4 } from "uuid";
16
16
 
17
+ import { buildBigIntFromUint8Array } from "../utils/bytes.js";
18
+
17
19
  import { decryptEipKeystore, keccak256Checksum } from "./cipher.js";
18
20
  import { isCredentialValid, isKeystoreValid } from "./schema_validator.js";
19
21
  import type {
@@ -248,25 +250,26 @@ export class Keystore {
248
250
  const str = bytesToUtf8(bytes);
249
251
  const obj = JSON.parse(str);
250
252
 
251
- const idCommitmentLE = Keystore.fromArraylikeToBytes(
252
- _.get(obj, "identityCredential.idCommitment", [])
253
- );
254
- const idTrapdoorLE = Keystore.fromArraylikeToBytes(
255
- _.get(obj, "identityCredential.idTrapdoor", [])
256
- );
257
- const idNullifierLE = Keystore.fromArraylikeToBytes(
258
- _.get(obj, "identityCredential.idNullifier", [])
259
- );
260
- const idSecretHashLE = Keystore.fromArraylikeToBytes(
261
- _.get(obj, "identityCredential.idSecretHash", [])
262
- );
263
-
253
+ // TODO: add runtime validation of nwaku credentials
264
254
  return {
265
255
  identity: {
266
- IDCommitment: idCommitmentLE,
267
- IDTrapdoor: idTrapdoorLE,
268
- IDNullifier: idNullifierLE,
269
- IDSecretHash: idSecretHashLE
256
+ IDCommitment: Keystore.fromArraylikeToBytes(
257
+ _.get(obj, "identityCredential.idCommitment", [])
258
+ ),
259
+ IDTrapdoor: Keystore.fromArraylikeToBytes(
260
+ _.get(obj, "identityCredential.idTrapdoor", [])
261
+ ),
262
+ IDNullifier: Keystore.fromArraylikeToBytes(
263
+ _.get(obj, "identityCredential.idNullifier", [])
264
+ ),
265
+ IDCommitmentBigInt: buildBigIntFromUint8Array(
266
+ Keystore.fromArraylikeToBytes(
267
+ _.get(obj, "identityCredential.idCommitment", [])
268
+ )
269
+ ),
270
+ IDSecretHash: Keystore.fromArraylikeToBytes(
271
+ _.get(obj, "identityCredential.idSecretHash", [])
272
+ )
270
273
  },
271
274
  membership: {
272
275
  treeIndex: _.get(obj, "treeIndex"),
@@ -318,21 +321,14 @@ export class Keystore {
318
321
  // follows nwaku implementation
319
322
  // https://github.com/waku-org/nwaku/blob/f05528d4be3d3c876a8b07f9bb7dfaae8aa8ec6e/waku/waku_keystore/protocol_types.nim#L98
320
323
  private static fromIdentityToBytes(options: KeystoreEntity): Uint8Array {
321
- function toLittleEndian(bytes: Uint8Array): Uint8Array {
322
- return new Uint8Array(bytes).reverse();
323
- }
324
324
  return utf8ToBytes(
325
325
  JSON.stringify({
326
326
  treeIndex: options.membership.treeIndex,
327
327
  identityCredential: {
328
- idCommitment: Array.from(
329
- toLittleEndian(options.identity.IDCommitment)
330
- ),
331
- idNullifier: Array.from(toLittleEndian(options.identity.IDNullifier)),
332
- idSecretHash: Array.from(
333
- toLittleEndian(options.identity.IDSecretHash)
334
- ),
335
- idTrapdoor: Array.from(toLittleEndian(options.identity.IDTrapdoor))
328
+ idCommitment: Array.from(options.identity.IDCommitment),
329
+ idNullifier: Array.from(options.identity.IDNullifier),
330
+ idSecretHash: Array.from(options.identity.IDSecretHash),
331
+ idTrapdoor: Array.from(options.identity.IDTrapdoor)
336
332
  },
337
333
  membershipContract: {
338
334
  chainId: options.membership.chainId,