@waku/rln 0.1.5-ff0222a.0 → 0.1.6-b7e9b08.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.
- package/CHANGELOG.md +22 -0
- package/bundle/_virtual/index2.js +1 -1
- package/bundle/index.js +2 -2
- package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/lib/checksum.js +3 -3
- package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/lib/cipher.js +4 -4
- package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/lib/class.js +7 -7
- package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/lib/functional.js +7 -7
- package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/lib/index.js +6 -6
- package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/lib/kdf.js +5 -5
- package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/lib/password.js +1 -1
- package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/lib/schema-validation-generated.js +1 -1
- package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/lib/schema-validation.js +2 -2
- package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/lib/types.js +1 -1
- package/bundle/{packages/rln → node_modules/@chainsafe/bls-keystore}/node_modules/@noble/hashes/_assert.js +1 -1
- package/bundle/{packages/rln → node_modules/@chainsafe/bls-keystore}/node_modules/@noble/hashes/_sha2.js +3 -3
- package/bundle/{packages/rln → node_modules/@chainsafe/bls-keystore}/node_modules/@noble/hashes/_u64.js +1 -1
- package/bundle/{packages/rln → node_modules/@chainsafe/bls-keystore}/node_modules/@noble/hashes/cryptoBrowser.js +1 -1
- package/bundle/{packages/rln → node_modules/@chainsafe/bls-keystore}/node_modules/@noble/hashes/hmac.js +3 -3
- package/bundle/{packages/rln → node_modules/@chainsafe/bls-keystore}/node_modules/@noble/hashes/pbkdf2.js +4 -4
- package/bundle/{packages/rln → node_modules/@chainsafe/bls-keystore}/node_modules/@noble/hashes/scrypt.js +5 -5
- package/bundle/{packages/rln → node_modules/@chainsafe/bls-keystore}/node_modules/@noble/hashes/sha256.js +3 -3
- package/bundle/{packages/rln → node_modules/@chainsafe/bls-keystore}/node_modules/@noble/hashes/sha512.js +4 -4
- package/bundle/{packages/rln → node_modules/@chainsafe/bls-keystore}/node_modules/@noble/hashes/utils.js +2 -2
- package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/aes.js +3 -3
- package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/pbkdf2.js +7 -7
- package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/random.js +3 -3
- package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/scrypt.js +3 -3
- package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/sha256.js +3 -3
- package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/utils.js +7 -7
- package/bundle/node_modules/@ethersproject/abi/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/abstract-provider/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/abstract-signer/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/address/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/bignumber/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/contracts/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/contracts/lib.esm/index.js +1 -1
- package/bundle/node_modules/@ethersproject/hash/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/networks/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/networks/lib.esm/index.js +19 -1
- package/bundle/node_modules/@ethersproject/properties/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/providers/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/signing-key/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/signing-key/lib.esm/elliptic.js +58 -10
- package/bundle/node_modules/@ethersproject/strings/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/transactions/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/web/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@noble/hashes/esm/_assert.js +6 -32
- package/bundle/node_modules/@noble/hashes/esm/_md.js +22 -11
- package/bundle/node_modules/@noble/hashes/esm/_u64.js +4 -3
- package/bundle/{packages/rln/node_modules → node_modules}/@noble/hashes/esm/hmac.js +19 -10
- package/bundle/{packages/rln/node_modules/@noble/hashes/esm/sha256.js → node_modules/@noble/hashes/esm/sha2.js} +36 -50
- package/bundle/node_modules/@noble/hashes/esm/sha256.js +5 -102
- package/bundle/node_modules/@noble/hashes/esm/sha3.js +30 -24
- package/bundle/node_modules/@noble/hashes/esm/utils.js +69 -18
- package/bundle/node_modules/bn.js/lib/bn.js +1 -0
- package/bundle/node_modules/ethereum-cryptography/esm/sha256.js +1 -1
- package/bundle/packages/core/dist/lib/connection_manager/connection_manager.js +3 -0
- package/bundle/packages/core/dist/lib/connection_manager/keep_alive_manager.js +3 -3
- package/bundle/packages/core/dist/lib/filter/filter.js +3 -0
- package/bundle/packages/core/dist/lib/light_push/light_push.js +3 -0
- package/bundle/packages/core/dist/lib/metadata/metadata.js +3 -0
- package/bundle/packages/core/dist/lib/store/store.js +3 -3
- package/bundle/packages/proto/dist/generated/sds_message.js +59 -3
- package/bundle/packages/rln/dist/codec.js +3 -3
- package/bundle/packages/rln/dist/contract/constants.js +1 -1
- package/bundle/packages/rln/dist/contract/{rln_light_contract.js → rln_base_contract.js} +180 -180
- package/bundle/packages/rln/dist/contract/rln_contract.js +12 -422
- package/bundle/packages/rln/dist/contract/types.js +9 -0
- package/bundle/packages/rln/dist/create.js +1 -1
- package/bundle/packages/rln/dist/credentials_manager.js +215 -0
- package/bundle/packages/rln/dist/identity.js +0 -9
- package/bundle/packages/rln/dist/keystore/cipher.js +3 -3
- package/bundle/packages/rln/dist/keystore/keystore.js +32 -18
- package/bundle/packages/rln/dist/rln.js +59 -169
- package/bundle/packages/rln/dist/utils/epoch.js +3 -3
- package/bundle/packages/rln/dist/zerokit.js +5 -5
- package/bundle/packages/utils/dist/common/sharding/index.js +4 -4
- package/bundle/packages/utils/node_modules/@waku/interfaces/dist/connection_manager.js +19 -0
- package/bundle/packages/utils/node_modules/@waku/interfaces/dist/health_indicator.js +12 -0
- package/bundle/packages/utils/node_modules/@waku/interfaces/dist/protocols.js +92 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/contract/constants.d.ts +1 -1
- package/dist/contract/constants.js +1 -1
- package/dist/contract/constants.js.map +1 -1
- package/dist/contract/{rln_light_contract.d.ts → rln_base_contract.d.ts} +25 -53
- package/dist/contract/{rln_light_contract.js → rln_base_contract.js} +177 -177
- package/dist/contract/rln_base_contract.js.map +1 -0
- package/dist/contract/rln_contract.d.ts +5 -122
- package/dist/contract/rln_contract.js +8 -417
- package/dist/contract/rln_contract.js.map +1 -1
- package/dist/contract/types.d.ts +40 -0
- package/dist/contract/types.js +8 -0
- package/dist/contract/types.js.map +1 -0
- package/dist/create.js +1 -1
- package/dist/create.js.map +1 -1
- package/dist/credentials_manager.d.ts +44 -0
- package/dist/credentials_manager.js +197 -0
- package/dist/credentials_manager.js.map +1 -0
- package/dist/identity.d.ts +0 -1
- package/dist/identity.js +0 -9
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/keystore/keystore.d.ts +1 -0
- package/dist/keystore/keystore.js +27 -13
- package/dist/keystore/keystore.js.map +1 -1
- package/dist/rln.d.ts +9 -52
- package/dist/rln.js +54 -163
- package/dist/rln.js.map +1 -1
- package/dist/types.d.ts +27 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/zerokit.d.ts +3 -3
- package/dist/zerokit.js +5 -5
- package/dist/zerokit.js.map +1 -1
- package/package.json +1 -1
- package/src/contract/constants.ts +1 -1
- package/src/contract/{rln_light_contract.ts → rln_base_contract.ts} +294 -312
- package/src/contract/rln_contract.ts +9 -663
- package/src/contract/types.ts +48 -0
- package/src/create.ts +1 -1
- package/src/credentials_manager.ts +282 -0
- package/src/identity.ts +0 -10
- package/src/index.ts +4 -4
- package/src/keystore/keystore.ts +49 -25
- package/src/rln.ts +67 -258
- package/src/types.ts +31 -0
- package/src/zerokit.ts +3 -3
- package/bundle/packages/rln/dist/rln_light.js +0 -149
- package/bundle/packages/rln/node_modules/@noble/hashes/esm/_assert.js +0 -43
- package/bundle/packages/rln/node_modules/@noble/hashes/esm/_sha2.js +0 -116
- package/bundle/packages/rln/node_modules/@noble/hashes/esm/utils.js +0 -43
- package/dist/contract/rln_light_contract.js.map +0 -1
- package/dist/rln_light.d.ts +0 -64
- package/dist/rln_light.js +0 -144
- package/dist/rln_light.js.map +0 -1
- package/src/rln_light.ts +0 -235
- /package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/index.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/md5.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/nil.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/parse.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/regex.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/rng.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/sha1.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/stringify.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/v1.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/v3.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/v35.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/v4.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/v5.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/validate.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/version.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/uuid/dist/esm-browser/native.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/uuid/dist/esm-browser/rng.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/uuid/dist/esm-browser/stringify.js +0 -0
- /package/bundle/{packages/rln/node_modules → node_modules}/uuid/dist/esm-browser/v4.js +0 -0
- /package/bundle/packages/{interfaces → utils/node_modules/@waku/interfaces}/dist/constants.js +0 -0
@@ -1,6 +1,6 @@
|
|
1
|
-
import '../../../interfaces/dist/protocols.js';
|
2
|
-
import '../../../interfaces/dist/connection_manager.js';
|
3
|
-
import '../../../interfaces/dist/health_indicator.js';
|
1
|
+
import '../../../utils/node_modules/@waku/interfaces/dist/protocols.js';
|
2
|
+
import '../../../utils/node_modules/@waku/interfaces/dist/connection_manager.js';
|
3
|
+
import '../../../utils/node_modules/@waku/interfaces/dist/health_indicator.js';
|
4
4
|
import '../../../../node_modules/multiformats/dist/src/bases/base10.js';
|
5
5
|
import '../../../../node_modules/multiformats/dist/src/bases/base16.js';
|
6
6
|
import '../../../../node_modules/multiformats/dist/src/bases/base2.js';
|
@@ -15,18 +15,12 @@ import '../../../../node_modules/multiformats/dist/src/codecs/json.js';
|
|
15
15
|
import { Logger } from '../../../utils/dist/logger/index.js';
|
16
16
|
import { RLN_ABI } from './abi.js';
|
17
17
|
import { DEFAULT_RATE_LIMIT, RATE_LIMIT_PARAMS } from './constants.js';
|
18
|
+
import { MembershipState } from './types.js';
|
18
19
|
import { Contract } from '../../../../node_modules/@ethersproject/contracts/lib.esm/index.js';
|
19
20
|
import { BigNumber } from '../../../../node_modules/@ethersproject/bignumber/lib.esm/bignumber.js';
|
20
21
|
|
21
|
-
const log = new Logger("waku:rln:contract");
|
22
|
-
|
23
|
-
(function (MembershipState) {
|
24
|
-
MembershipState["Active"] = "Active";
|
25
|
-
MembershipState["GracePeriod"] = "GracePeriod";
|
26
|
-
MembershipState["Expired"] = "Expired";
|
27
|
-
MembershipState["ErasedAwaitsWithdrawal"] = "ErasedAwaitsWithdrawal";
|
28
|
-
})(MembershipState || (MembershipState = {}));
|
29
|
-
class RLNLightContract {
|
22
|
+
const log = new Logger("waku:rln:contract:base");
|
23
|
+
class RLNBaseContract {
|
30
24
|
contract;
|
31
25
|
deployBlock;
|
32
26
|
rateLimit;
|
@@ -35,24 +29,22 @@ class RLNLightContract {
|
|
35
29
|
_membershipErasedFilter;
|
36
30
|
_membersExpiredFilter;
|
37
31
|
/**
|
38
|
-
*
|
32
|
+
* Constructor for RLNBaseContract.
|
39
33
|
* Allows injecting a mocked contract for testing purposes.
|
40
34
|
*/
|
41
|
-
static async init(options) {
|
42
|
-
const rlnContract = new RLNLightContract(options);
|
43
|
-
await rlnContract.fetchMembers();
|
44
|
-
rlnContract.subscribeToMembers();
|
45
|
-
return rlnContract;
|
46
|
-
}
|
47
35
|
constructor(options) {
|
36
|
+
// Initialize members and subscriptions
|
37
|
+
this.fetchMembers()
|
38
|
+
.then(() => {
|
39
|
+
this.subscribeToMembers();
|
40
|
+
})
|
41
|
+
.catch((error) => {
|
42
|
+
log.error("Failed to initialize members", { error });
|
43
|
+
});
|
48
44
|
const { address, signer, rateLimit = DEFAULT_RATE_LIMIT, contract } = options;
|
49
|
-
|
50
|
-
rateLimit > RATE_LIMIT_PARAMS.MAX_RATE) {
|
51
|
-
throw new Error(`Rate limit must be between ${RATE_LIMIT_PARAMS.MIN_RATE} and ${RATE_LIMIT_PARAMS.MAX_RATE} messages per epoch`);
|
52
|
-
}
|
53
|
-
this.rateLimit = rateLimit;
|
54
|
-
// Use the injected contract if provided; otherwise, instantiate a new one.
|
45
|
+
this.validateRateLimit(rateLimit);
|
55
46
|
this.contract = contract || new Contract(address, RLN_ABI, signer);
|
47
|
+
this.rateLimit = rateLimit;
|
56
48
|
// Initialize event filters
|
57
49
|
this._membersFilter = this.contract.filters.MembershipRegistered();
|
58
50
|
this._membershipErasedFilter = this.contract.filters.MembershipErased();
|
@@ -98,7 +90,7 @@ class RLNLightContract {
|
|
98
90
|
*/
|
99
91
|
async getMaxTotalRateLimit() {
|
100
92
|
const maxTotalRate = await this.contract.maxTotalRateLimit();
|
101
|
-
return
|
93
|
+
return maxTotalRate.toNumber();
|
102
94
|
}
|
103
95
|
/**
|
104
96
|
* Gets the current total rate limit usage across all memberships
|
@@ -106,7 +98,7 @@ class RLNLightContract {
|
|
106
98
|
*/
|
107
99
|
async getCurrentTotalRateLimit() {
|
108
100
|
const currentTotal = await this.contract.currentTotalRateLimit();
|
109
|
-
return
|
101
|
+
return currentTotal.toNumber();
|
110
102
|
}
|
111
103
|
/**
|
112
104
|
* Gets the remaining available total rate limit that can be allocated
|
@@ -117,51 +109,32 @@ class RLNLightContract {
|
|
117
109
|
this.contract.maxTotalRateLimit(),
|
118
110
|
this.contract.currentTotalRateLimit()
|
119
111
|
]);
|
120
|
-
return
|
121
|
-
.sub(BigNumber.from(currentTotal))
|
122
|
-
.toNumber();
|
112
|
+
return Number(maxTotal) - Number(currentTotal);
|
123
113
|
}
|
124
114
|
/**
|
125
115
|
* Updates the rate limit for future registrations
|
126
116
|
* @param newRateLimit The new rate limit to use
|
127
117
|
*/
|
128
118
|
async setRateLimit(newRateLimit) {
|
119
|
+
this.validateRateLimit(newRateLimit);
|
129
120
|
this.rateLimit = newRateLimit;
|
130
121
|
}
|
131
122
|
get members() {
|
132
123
|
const sortedMembers = Array.from(this._members.values()).sort((left, right) => left.index.toNumber() - right.index.toNumber());
|
133
124
|
return sortedMembers;
|
134
125
|
}
|
135
|
-
get membersFilter() {
|
136
|
-
if (!this._membersFilter) {
|
137
|
-
throw Error("Members filter was not initialized.");
|
138
|
-
}
|
139
|
-
return this._membersFilter;
|
140
|
-
}
|
141
|
-
get membershipErasedFilter() {
|
142
|
-
if (!this._membershipErasedFilter) {
|
143
|
-
throw Error("MembershipErased filter was not initialized.");
|
144
|
-
}
|
145
|
-
return this._membershipErasedFilter;
|
146
|
-
}
|
147
|
-
get membersExpiredFilter() {
|
148
|
-
if (!this._membersExpiredFilter) {
|
149
|
-
throw Error("MembersExpired filter was not initialized.");
|
150
|
-
}
|
151
|
-
return this._membersExpiredFilter;
|
152
|
-
}
|
153
126
|
async fetchMembers(options = {}) {
|
154
|
-
const registeredMemberEvents = await queryFilter(this.contract, {
|
127
|
+
const registeredMemberEvents = await RLNBaseContract.queryFilter(this.contract, {
|
155
128
|
fromBlock: this.deployBlock,
|
156
129
|
...options,
|
157
130
|
membersFilter: this.membersFilter
|
158
131
|
});
|
159
|
-
const removedMemberEvents = await queryFilter(this.contract, {
|
132
|
+
const removedMemberEvents = await RLNBaseContract.queryFilter(this.contract, {
|
160
133
|
fromBlock: this.deployBlock,
|
161
134
|
...options,
|
162
135
|
membersFilter: this.membershipErasedFilter
|
163
136
|
});
|
164
|
-
const expiredMemberEvents = await queryFilter(this.contract, {
|
137
|
+
const expiredMemberEvents = await RLNBaseContract.queryFilter(this.contract, {
|
165
138
|
fromBlock: this.deployBlock,
|
166
139
|
...options,
|
167
140
|
membersFilter: this.membersExpiredFilter
|
@@ -173,6 +146,29 @@ class RLNLightContract {
|
|
173
146
|
];
|
174
147
|
this.processEvents(events);
|
175
148
|
}
|
149
|
+
static async queryFilter(contract, options) {
|
150
|
+
const FETCH_CHUNK = 5;
|
151
|
+
const BLOCK_RANGE = 3000;
|
152
|
+
const { fromBlock, membersFilter, fetchRange = BLOCK_RANGE, fetchChunks = FETCH_CHUNK } = options;
|
153
|
+
if (fromBlock === undefined) {
|
154
|
+
return contract.queryFilter(membersFilter);
|
155
|
+
}
|
156
|
+
if (!contract.provider) {
|
157
|
+
throw Error("No provider found on the contract.");
|
158
|
+
}
|
159
|
+
const toBlock = await contract.provider.getBlockNumber();
|
160
|
+
if (toBlock - fromBlock < fetchRange) {
|
161
|
+
return contract.queryFilter(membersFilter, fromBlock, toBlock);
|
162
|
+
}
|
163
|
+
const events = [];
|
164
|
+
const chunks = RLNBaseContract.splitToChunks(fromBlock, toBlock, fetchRange);
|
165
|
+
for (const portion of RLNBaseContract.takeN(chunks, fetchChunks)) {
|
166
|
+
const promises = portion.map(([left, right]) => RLNBaseContract.ignoreErrors(contract.queryFilter(membersFilter, left, right), []));
|
167
|
+
const fetchedEvents = await Promise.all(promises);
|
168
|
+
events.push(fetchedEvents.flatMap((v) => v));
|
169
|
+
}
|
170
|
+
return events.flatMap((v) => v);
|
171
|
+
}
|
176
172
|
processEvents(events) {
|
177
173
|
const toRemoveTable = new Map();
|
178
174
|
const toInsertTable = new Map();
|
@@ -208,6 +204,38 @@ class RLNLightContract {
|
|
208
204
|
}
|
209
205
|
});
|
210
206
|
}
|
207
|
+
static splitToChunks(from, to, step) {
|
208
|
+
const chunks = [];
|
209
|
+
let left = from;
|
210
|
+
while (left < to) {
|
211
|
+
const right = left + step < to ? left + step : to;
|
212
|
+
chunks.push([left, right]);
|
213
|
+
left = right;
|
214
|
+
}
|
215
|
+
return chunks;
|
216
|
+
}
|
217
|
+
static *takeN(array, size) {
|
218
|
+
let start = 0;
|
219
|
+
while (start < array.length) {
|
220
|
+
const portion = array.slice(start, start + size);
|
221
|
+
yield portion;
|
222
|
+
start += size;
|
223
|
+
}
|
224
|
+
}
|
225
|
+
static async ignoreErrors(promise, defaultValue) {
|
226
|
+
try {
|
227
|
+
return await promise;
|
228
|
+
}
|
229
|
+
catch (err) {
|
230
|
+
if (err instanceof Error) {
|
231
|
+
log.info(`Ignoring an error during query: ${err.message}`);
|
232
|
+
}
|
233
|
+
else {
|
234
|
+
log.info(`Ignoring an unknown error during query`);
|
235
|
+
}
|
236
|
+
return defaultValue;
|
237
|
+
}
|
238
|
+
}
|
211
239
|
subscribeToMembers() {
|
212
240
|
this.contract.on(this.membersFilter, (_idCommitment, _membershipRateLimit, _index, event) => {
|
213
241
|
this.processEvents([event]);
|
@@ -219,6 +247,81 @@ class RLNLightContract {
|
|
219
247
|
this.processEvents([event]);
|
220
248
|
});
|
221
249
|
}
|
250
|
+
/**
|
251
|
+
* Helper method to get remaining messages in current epoch
|
252
|
+
* @param membershipId The ID of the membership to check
|
253
|
+
* @returns number of remaining messages allowed in current epoch
|
254
|
+
*/
|
255
|
+
async getRemainingMessages(membershipId) {
|
256
|
+
try {
|
257
|
+
const [startTime, , rateLimit] = await this.contract.getMembershipInfo(membershipId);
|
258
|
+
// Calculate current epoch
|
259
|
+
const currentTime = Math.floor(Date.now() / 1000);
|
260
|
+
const epochsPassed = Math.floor((currentTime - startTime) / RATE_LIMIT_PARAMS.EPOCH_LENGTH);
|
261
|
+
const currentEpochStart = startTime + epochsPassed * RATE_LIMIT_PARAMS.EPOCH_LENGTH;
|
262
|
+
// Get message count in current epoch using contract's function
|
263
|
+
const messageCount = await this.contract.getMessageCount(membershipId, currentEpochStart);
|
264
|
+
return Math.max(0, BigNumber.from(rateLimit)
|
265
|
+
.sub(BigNumber.from(messageCount))
|
266
|
+
.toNumber());
|
267
|
+
}
|
268
|
+
catch (error) {
|
269
|
+
log.error(`Error getting remaining messages: ${error.message}`);
|
270
|
+
return 0; // Fail safe: assume no messages remaining on error
|
271
|
+
}
|
272
|
+
}
|
273
|
+
async getMembershipInfo(idCommitment) {
|
274
|
+
try {
|
275
|
+
const [startBlock, endBlock, rateLimit] = await this.contract.getMembershipInfo(idCommitment);
|
276
|
+
const currentBlock = await this.contract.provider.getBlockNumber();
|
277
|
+
let state;
|
278
|
+
if (currentBlock < startBlock) {
|
279
|
+
state = MembershipState.Active;
|
280
|
+
}
|
281
|
+
else if (currentBlock < endBlock) {
|
282
|
+
state = MembershipState.GracePeriod;
|
283
|
+
}
|
284
|
+
else {
|
285
|
+
state = MembershipState.Expired;
|
286
|
+
}
|
287
|
+
const index = await this.getMemberIndex(idCommitment);
|
288
|
+
if (!index)
|
289
|
+
return undefined;
|
290
|
+
return {
|
291
|
+
index,
|
292
|
+
idCommitment,
|
293
|
+
rateLimit: rateLimit.toNumber(),
|
294
|
+
startBlock: startBlock.toNumber(),
|
295
|
+
endBlock: endBlock.toNumber(),
|
296
|
+
state
|
297
|
+
};
|
298
|
+
}
|
299
|
+
catch (error) {
|
300
|
+
return undefined;
|
301
|
+
}
|
302
|
+
}
|
303
|
+
async extendMembership(idCommitment) {
|
304
|
+
return this.contract.extendMemberships([idCommitment]);
|
305
|
+
}
|
306
|
+
async eraseMembership(idCommitment, eraseFromMembershipSet = true) {
|
307
|
+
return this.contract.eraseMemberships([idCommitment], eraseFromMembershipSet);
|
308
|
+
}
|
309
|
+
async registerMembership(idCommitment, rateLimit = DEFAULT_RATE_LIMIT) {
|
310
|
+
if (rateLimit < RATE_LIMIT_PARAMS.MIN_RATE ||
|
311
|
+
rateLimit > RATE_LIMIT_PARAMS.MAX_RATE) {
|
312
|
+
throw new Error(`Rate limit must be between ${RATE_LIMIT_PARAMS.MIN_RATE} and ${RATE_LIMIT_PARAMS.MAX_RATE}`);
|
313
|
+
}
|
314
|
+
return this.contract.register(idCommitment, rateLimit, []);
|
315
|
+
}
|
316
|
+
async withdraw(token, holder) {
|
317
|
+
try {
|
318
|
+
const tx = await this.contract.withdraw(token, { from: holder });
|
319
|
+
await tx.wait();
|
320
|
+
}
|
321
|
+
catch (error) {
|
322
|
+
log.error(`Error in withdraw: ${error.message}`);
|
323
|
+
}
|
324
|
+
}
|
222
325
|
async registerWithIdentity(identity) {
|
223
326
|
try {
|
224
327
|
log.info(`Registering identity with rate limit: ${this.rateLimit} messages/epoch`);
|
@@ -253,12 +356,12 @@ class RLNLightContract {
|
|
253
356
|
`and rate limit ${decodedData.membershipRateLimit}`);
|
254
357
|
const network = await this.contract.provider.getNetwork();
|
255
358
|
const address = this.contract.address;
|
256
|
-
const membershipId = decodedData.index
|
359
|
+
const membershipId = Number(decodedData.index);
|
257
360
|
return {
|
258
361
|
identity,
|
259
362
|
membership: {
|
260
363
|
address,
|
261
|
-
treeIndex:
|
364
|
+
treeIndex: membershipId,
|
262
365
|
chainId: network.chainId.toString(),
|
263
366
|
rateLimit: decodedData.membershipRateLimit.toNumber()
|
264
367
|
}
|
@@ -293,29 +396,6 @@ class RLNLightContract {
|
|
293
396
|
}
|
294
397
|
}
|
295
398
|
}
|
296
|
-
/**
|
297
|
-
* Helper method to get remaining messages in current epoch
|
298
|
-
* @param membershipId The ID of the membership to check
|
299
|
-
* @returns number of remaining messages allowed in current epoch
|
300
|
-
*/
|
301
|
-
async getRemainingMessages(membershipId) {
|
302
|
-
try {
|
303
|
-
const [startTime, , rateLimit] = await this.contract.getMembershipInfo(membershipId);
|
304
|
-
// Calculate current epoch
|
305
|
-
const currentTime = Math.floor(Date.now() / 1000);
|
306
|
-
const epochsPassed = Math.floor((currentTime - startTime) / RATE_LIMIT_PARAMS.EPOCH_LENGTH);
|
307
|
-
const currentEpochStart = startTime + epochsPassed * RATE_LIMIT_PARAMS.EPOCH_LENGTH;
|
308
|
-
// Get message count in current epoch using contract's function
|
309
|
-
const messageCount = await this.contract.getMessageCount(membershipId, currentEpochStart);
|
310
|
-
return Math.max(0, BigNumber.from(rateLimit)
|
311
|
-
.sub(BigNumber.from(messageCount))
|
312
|
-
.toNumber());
|
313
|
-
}
|
314
|
-
catch (error) {
|
315
|
-
log.error(`Error getting remaining messages: ${error.message}`);
|
316
|
-
return 0; // Fail safe: assume no messages remaining on error
|
317
|
-
}
|
318
|
-
}
|
319
399
|
async registerWithPermitAndErase(identity, permit, idCommitmentsToErase) {
|
320
400
|
try {
|
321
401
|
log.info(`Registering identity with permit and rate limit: ${this.rateLimit} messages/epoch`);
|
@@ -335,12 +415,12 @@ class RLNLightContract {
|
|
335
415
|
`Rate limit: ${decodedData.membershipRateLimit}, Erased ${idCommitmentsToErase.length} commitments`);
|
336
416
|
const network = await this.contract.provider.getNetwork();
|
337
417
|
const address = this.contract.address;
|
338
|
-
const membershipId = decodedData.index
|
418
|
+
const membershipId = Number(decodedData.index);
|
339
419
|
return {
|
340
420
|
identity,
|
341
421
|
membership: {
|
342
422
|
address,
|
343
|
-
treeIndex:
|
423
|
+
treeIndex: membershipId,
|
344
424
|
chainId: network.chainId.toString(),
|
345
425
|
rateLimit: decodedData.membershipRateLimit.toNumber()
|
346
426
|
}
|
@@ -351,57 +431,33 @@ class RLNLightContract {
|
|
351
431
|
return undefined;
|
352
432
|
}
|
353
433
|
}
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
434
|
+
/**
|
435
|
+
* Validates that the rate limit is within the allowed range
|
436
|
+
* @throws Error if the rate limit is outside the allowed range
|
437
|
+
*/
|
438
|
+
validateRateLimit(rateLimit) {
|
439
|
+
if (rateLimit < RATE_LIMIT_PARAMS.MIN_RATE ||
|
440
|
+
rateLimit > RATE_LIMIT_PARAMS.MAX_RATE) {
|
441
|
+
throw new Error(`Rate limit must be between ${RATE_LIMIT_PARAMS.MIN_RATE} and ${RATE_LIMIT_PARAMS.MAX_RATE} messages per epoch`);
|
361
442
|
}
|
362
443
|
}
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
const currentBlock = await this.contract.provider.getBlockNumber();
|
367
|
-
let state;
|
368
|
-
if (currentBlock < startBlock) {
|
369
|
-
state = MembershipState.Active;
|
370
|
-
}
|
371
|
-
else if (currentBlock < endBlock) {
|
372
|
-
state = MembershipState.GracePeriod;
|
373
|
-
}
|
374
|
-
else {
|
375
|
-
state = MembershipState.Expired;
|
376
|
-
}
|
377
|
-
const index = await this.getMemberIndex(idCommitment);
|
378
|
-
if (!index)
|
379
|
-
return undefined;
|
380
|
-
return {
|
381
|
-
index,
|
382
|
-
idCommitment,
|
383
|
-
rateLimit: rateLimit.toNumber(),
|
384
|
-
startBlock: startBlock.toNumber(),
|
385
|
-
endBlock: endBlock.toNumber(),
|
386
|
-
state
|
387
|
-
};
|
388
|
-
}
|
389
|
-
catch (error) {
|
390
|
-
return undefined;
|
444
|
+
get membersFilter() {
|
445
|
+
if (!this._membersFilter) {
|
446
|
+
throw Error("Members filter was not initialized.");
|
391
447
|
}
|
448
|
+
return this._membersFilter;
|
392
449
|
}
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
return this.
|
450
|
+
get membershipErasedFilter() {
|
451
|
+
if (!this._membershipErasedFilter) {
|
452
|
+
throw Error("MembershipErased filter was not initialized.");
|
453
|
+
}
|
454
|
+
return this._membershipErasedFilter;
|
398
455
|
}
|
399
|
-
|
400
|
-
if (
|
401
|
-
|
402
|
-
throw new Error(`Rate limit must be between ${RATE_LIMIT_PARAMS.MIN_RATE} and ${RATE_LIMIT_PARAMS.MAX_RATE}`);
|
456
|
+
get membersExpiredFilter() {
|
457
|
+
if (!this._membersExpiredFilter) {
|
458
|
+
throw Error("MembersExpired filter was not initialized.");
|
403
459
|
}
|
404
|
-
return this.
|
460
|
+
return this._membersExpiredFilter;
|
405
461
|
}
|
406
462
|
async getMemberIndex(idCommitment) {
|
407
463
|
try {
|
@@ -417,61 +473,5 @@ class RLNLightContract {
|
|
417
473
|
}
|
418
474
|
}
|
419
475
|
}
|
420
|
-
// These values should be tested on other networks
|
421
|
-
const FETCH_CHUNK = 5;
|
422
|
-
const BLOCK_RANGE = 3000;
|
423
|
-
async function queryFilter(contract, options) {
|
424
|
-
const { fromBlock, membersFilter, fetchRange = BLOCK_RANGE, fetchChunks = FETCH_CHUNK } = options;
|
425
|
-
if (fromBlock === undefined) {
|
426
|
-
return contract.queryFilter(membersFilter);
|
427
|
-
}
|
428
|
-
if (!contract.provider) {
|
429
|
-
throw Error("No provider found on the contract.");
|
430
|
-
}
|
431
|
-
const toBlock = await contract.provider.getBlockNumber();
|
432
|
-
if (toBlock - fromBlock < fetchRange) {
|
433
|
-
return contract.queryFilter(membersFilter, fromBlock, toBlock);
|
434
|
-
}
|
435
|
-
const events = [];
|
436
|
-
const chunks = splitToChunks(fromBlock, toBlock, fetchRange);
|
437
|
-
for (const portion of takeN(chunks, fetchChunks)) {
|
438
|
-
const promises = portion.map(([left, right]) => ignoreErrors(contract.queryFilter(membersFilter, left, right), []));
|
439
|
-
const fetchedEvents = await Promise.all(promises);
|
440
|
-
events.push(fetchedEvents.flatMap((v) => v));
|
441
|
-
}
|
442
|
-
return events.flatMap((v) => v);
|
443
|
-
}
|
444
|
-
function splitToChunks(from, to, step) {
|
445
|
-
const chunks = [];
|
446
|
-
let left = from;
|
447
|
-
while (left < to) {
|
448
|
-
const right = left + step < to ? left + step : to;
|
449
|
-
chunks.push([left, right]);
|
450
|
-
left = right;
|
451
|
-
}
|
452
|
-
return chunks;
|
453
|
-
}
|
454
|
-
function* takeN(array, size) {
|
455
|
-
let start = 0;
|
456
|
-
while (start < array.length) {
|
457
|
-
const portion = array.slice(start, start + size);
|
458
|
-
yield portion;
|
459
|
-
start += size;
|
460
|
-
}
|
461
|
-
}
|
462
|
-
async function ignoreErrors(promise, defaultValue) {
|
463
|
-
try {
|
464
|
-
return await promise;
|
465
|
-
}
|
466
|
-
catch (err) {
|
467
|
-
if (err instanceof Error) {
|
468
|
-
log.info(`Ignoring an error during query: ${err.message}`);
|
469
|
-
}
|
470
|
-
else {
|
471
|
-
log.info(`Ignoring an unknown error during query`);
|
472
|
-
}
|
473
|
-
return defaultValue;
|
474
|
-
}
|
475
|
-
}
|
476
476
|
|
477
|
-
export {
|
477
|
+
export { RLNBaseContract };
|