@waku/rln 0.1.5-cad3e7a.0 → 0.1.5-d0da8f8.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/bundle/_virtual/utils.js +2 -2
- package/bundle/_virtual/utils2.js +2 -2
- package/bundle/index.js +4 -3
- package/bundle/packages/rln/dist/contract/constants.js +2 -1
- package/bundle/packages/rln/dist/contract/{rln_light_contract.js → rln_base_contract.js} +189 -186
- package/bundle/packages/rln/dist/contract/rln_contract.js +10 -420
- package/bundle/packages/rln/dist/contract/types.js +9 -0
- package/bundle/packages/rln/dist/create.js +1 -1
- package/bundle/packages/rln/dist/{rln_light.js → credentials_manager.js} +114 -48
- package/bundle/packages/rln/dist/identity.js +0 -9
- package/bundle/packages/rln/dist/keystore/keystore.js +31 -17
- package/bundle/packages/rln/dist/rln.js +57 -167
- package/bundle/packages/rln/dist/utils/bytes.js +8 -2
- package/bundle/packages/rln/dist/utils/metamask.js +2 -2
- package/bundle/packages/rln/dist/zerokit.js +5 -5
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/random.js +1 -1
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/utils.js +2 -2
- package/bundle/packages/rln/node_modules/@noble/hashes/_sha2.js +1 -1
- package/bundle/packages/rln/node_modules/@noble/hashes/hmac.js +1 -1
- package/bundle/packages/rln/node_modules/@noble/hashes/pbkdf2.js +1 -1
- package/bundle/packages/rln/node_modules/@noble/hashes/scrypt.js +1 -1
- package/bundle/packages/rln/node_modules/@noble/hashes/sha256.js +1 -1
- package/bundle/packages/rln/node_modules/@noble/hashes/sha512.js +1 -1
- package/bundle/packages/rln/node_modules/@noble/hashes/utils.js +1 -1
- 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/index.d.ts +1 -0
- package/dist/contract/index.js +1 -0
- package/dist/contract/index.js.map +1 -1
- package/dist/contract/{rln_light_contract.d.ts → rln_base_contract.d.ts} +24 -58
- package/dist/contract/{rln_light_contract.js → rln_base_contract.js} +187 -184
- 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 +45 -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 +5 -4
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/keystore/keystore.d.ts +1 -0
- package/dist/keystore/keystore.js +31 -17
- package/dist/keystore/keystore.js.map +1 -1
- package/dist/keystore/types.d.ts +3 -3
- package/dist/rln.d.ts +9 -52
- package/dist/rln.js +55 -164
- 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/utils/bytes.js +8 -2
- package/dist/utils/bytes.js.map +1 -1
- 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/index.ts +1 -0
- package/src/contract/{rln_light_contract.ts → rln_base_contract.ts} +306 -323
- package/src/contract/rln_contract.ts +9 -663
- package/src/contract/types.ts +53 -0
- package/src/create.ts +1 -1
- package/src/credentials_manager.ts +282 -0
- package/src/identity.ts +0 -10
- package/src/index.ts +7 -5
- package/src/keystore/keystore.ts +57 -31
- package/src/keystore/types.ts +3 -3
- package/src/rln.ts +68 -259
- package/src/types.ts +31 -0
- package/src/utils/bytes.ts +10 -2
- package/src/zerokit.ts +3 -3
- package/bundle/_virtual/__node-resolve_empty.js +0 -6
- package/bundle/_virtual/_node-resolve_empty.js +0 -3
- package/bundle/_virtual/bn.js +0 -3
- package/bundle/_virtual/common.js +0 -3
- package/bundle/_virtual/common2.js +0 -3
- package/bundle/_virtual/hash.js +0 -3
- package/bundle/_virtual/inherits_browser.js +0 -3
- package/bundle/_virtual/ripemd.js +0 -3
- package/bundle/_virtual/sha.js +0 -3
- package/bundle/_virtual/sha3.js +0 -3
- package/bundle/_virtual/utils3.js +0 -3
- package/bundle/node_modules/@ethersproject/abi/lib.esm/_version.js +0 -3
- package/bundle/node_modules/@ethersproject/abi/lib.esm/abi-coder.js +0 -96
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/abstract-coder.js +0 -148
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/address.js +0 -26
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/anonymous.js +0 -20
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/array.js +0 -210
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/boolean.js +0 -18
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/bytes.js +0 -30
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/fixed-bytes.js +0 -26
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/null.js +0 -22
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/number.js +0 -43
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/string.js +0 -19
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/tuple.js +0 -58
- package/bundle/node_modules/@ethersproject/abi/lib.esm/fragments.js +0 -854
- package/bundle/node_modules/@ethersproject/abi/lib.esm/interface.js +0 -609
- package/bundle/node_modules/@ethersproject/abstract-provider/lib.esm/_version.js +0 -3
- package/bundle/node_modules/@ethersproject/abstract-provider/lib.esm/index.js +0 -66
- package/bundle/node_modules/@ethersproject/abstract-signer/lib.esm/_version.js +0 -3
- package/bundle/node_modules/@ethersproject/abstract-signer/lib.esm/index.js +0 -302
- package/bundle/node_modules/@ethersproject/address/lib.esm/_version.js +0 -3
- package/bundle/node_modules/@ethersproject/address/lib.esm/index.js +0 -110
- package/bundle/node_modules/@ethersproject/base64/lib.esm/base64.js +0 -20
- package/bundle/node_modules/@ethersproject/basex/lib.esm/index.js +0 -120
- package/bundle/node_modules/@ethersproject/bignumber/lib.esm/_version.js +0 -3
- package/bundle/node_modules/@ethersproject/bignumber/lib.esm/bignumber.js +0 -287
- package/bundle/node_modules/@ethersproject/bytes/lib.esm/_version.js +0 -3
- package/bundle/node_modules/@ethersproject/bytes/lib.esm/index.js +0 -402
- package/bundle/node_modules/@ethersproject/constants/lib.esm/addresses.js +0 -3
- package/bundle/node_modules/@ethersproject/constants/lib.esm/bignumbers.js +0 -8
- package/bundle/node_modules/@ethersproject/constants/lib.esm/hashes.js +0 -3
- package/bundle/node_modules/@ethersproject/contracts/lib.esm/_version.js +0 -3
- package/bundle/node_modules/@ethersproject/contracts/lib.esm/index.js +0 -893
- package/bundle/node_modules/@ethersproject/hash/lib.esm/_version.js +0 -3
- package/bundle/node_modules/@ethersproject/hash/lib.esm/ens-normalize/decoder.js +0 -256
- package/bundle/node_modules/@ethersproject/hash/lib.esm/ens-normalize/include.js +0 -36
- package/bundle/node_modules/@ethersproject/hash/lib.esm/ens-normalize/lib.js +0 -135
- package/bundle/node_modules/@ethersproject/hash/lib.esm/id.js +0 -8
- package/bundle/node_modules/@ethersproject/hash/lib.esm/namehash.js +0 -64
- package/bundle/node_modules/@ethersproject/hash/lib.esm/typed-data.js +0 -443
- package/bundle/node_modules/@ethersproject/keccak256/lib.esm/index.js +0 -8
- package/bundle/node_modules/@ethersproject/keccak256/node_modules/js-sha3/src/sha3.js +0 -660
- package/bundle/node_modules/@ethersproject/logger/lib.esm/_version.js +0 -3
- package/bundle/node_modules/@ethersproject/logger/lib.esm/index.js +0 -352
- package/bundle/node_modules/@ethersproject/networks/lib.esm/_version.js +0 -3
- package/bundle/node_modules/@ethersproject/networks/lib.esm/index.js +0 -248
- package/bundle/node_modules/@ethersproject/properties/lib.esm/_version.js +0 -3
- package/bundle/node_modules/@ethersproject/properties/lib.esm/index.js +0 -127
- package/bundle/node_modules/@ethersproject/providers/lib.esm/_version.js +0 -3
- package/bundle/node_modules/@ethersproject/providers/lib.esm/base-provider.js +0 -2007
- package/bundle/node_modules/@ethersproject/providers/lib.esm/formatter.js +0 -422
- package/bundle/node_modules/@ethersproject/providers/lib.esm/json-rpc-provider.js +0 -674
- package/bundle/node_modules/@ethersproject/providers/lib.esm/web3-provider.js +0 -132
- package/bundle/node_modules/@ethersproject/rlp/lib.esm/_version.js +0 -3
- package/bundle/node_modules/@ethersproject/rlp/lib.esm/index.js +0 -120
- package/bundle/node_modules/@ethersproject/sha2/lib.esm/sha2.js +0 -8
- package/bundle/node_modules/@ethersproject/signing-key/lib.esm/_version.js +0 -3
- package/bundle/node_modules/@ethersproject/signing-key/lib.esm/elliptic.js +0 -2430
- package/bundle/node_modules/@ethersproject/signing-key/lib.esm/index.js +0 -76
- package/bundle/node_modules/@ethersproject/strings/lib.esm/_version.js +0 -3
- package/bundle/node_modules/@ethersproject/strings/lib.esm/utf8.js +0 -219
- package/bundle/node_modules/@ethersproject/transactions/lib.esm/_version.js +0 -3
- package/bundle/node_modules/@ethersproject/transactions/lib.esm/index.js +0 -279
- package/bundle/node_modules/@ethersproject/web/lib.esm/_version.js +0 -3
- package/bundle/node_modules/@ethersproject/web/lib.esm/geturl.js +0 -69
- package/bundle/node_modules/@ethersproject/web/lib.esm/index.js +0 -404
- package/bundle/node_modules/bech32/index.js +0 -187
- package/bundle/node_modules/bn.js/lib/bn.js +0 -3361
- package/bundle/node_modules/hash.js/lib/hash/common.js +0 -97
- package/bundle/node_modules/hash.js/lib/hash/hmac.js +0 -51
- package/bundle/node_modules/hash.js/lib/hash/ripemd.js +0 -152
- package/bundle/node_modules/hash.js/lib/hash/sha/1.js +0 -81
- package/bundle/node_modules/hash.js/lib/hash/sha/224.js +0 -33
- package/bundle/node_modules/hash.js/lib/hash/sha/256.js +0 -113
- package/bundle/node_modules/hash.js/lib/hash/sha/384.js +0 -39
- package/bundle/node_modules/hash.js/lib/hash/sha/512.js +0 -336
- package/bundle/node_modules/hash.js/lib/hash/sha/common.js +0 -53
- package/bundle/node_modules/hash.js/lib/hash/sha.js +0 -14
- package/bundle/node_modules/hash.js/lib/hash/utils.js +0 -282
- package/bundle/node_modules/hash.js/lib/hash.js +0 -33
- package/bundle/node_modules/inherits/inherits_browser.js +0 -33
- package/bundle/node_modules/minimalistic-assert/index.js +0 -13
- 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/_virtual/utils.js
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
var utils = {};
|
1
|
+
var utils = {exports: {}};
|
2
2
|
|
3
|
-
export { utils as
|
3
|
+
export { utils as __module };
|
@@ -1,3 +1,3 @@
|
|
1
|
-
var utils = {
|
1
|
+
var utils = {};
|
2
2
|
|
3
|
-
export { utils as
|
3
|
+
export { utils as __exports };
|
package/bundle/index.js
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
export { RLNDecoder, RLNEncoder } from './packages/rln/dist/codec.js';
|
2
2
|
export { RLN_ABI } from './packages/rln/dist/contract/abi.js';
|
3
3
|
export { RLNContract } from './packages/rln/dist/contract/rln_contract.js';
|
4
|
-
export { LINEA_CONTRACT } from './packages/rln/dist/contract/constants.js';
|
5
|
-
export {
|
4
|
+
export { DEFAULT_RATE_LIMIT, LINEA_CONTRACT, RATE_LIMIT_PARAMS, RATE_LIMIT_TIERS } from './packages/rln/dist/contract/constants.js';
|
5
|
+
export { MembershipState } from './packages/rln/dist/contract/types.js';
|
6
|
+
export { RLNBaseContract } from './packages/rln/dist/contract/rln_base_contract.js';
|
6
7
|
export { createRLN } from './packages/rln/dist/create.js';
|
8
|
+
export { RLNCredentialsManager } from './packages/rln/dist/credentials_manager.js';
|
7
9
|
export { IdentityCredential } from './packages/rln/dist/identity.js';
|
8
10
|
export { Keystore } from './packages/rln/dist/keystore/keystore.js';
|
9
11
|
export { Proof } from './packages/rln/dist/proof.js';
|
10
12
|
export { RLNInstance } from './packages/rln/dist/rln.js';
|
11
|
-
export { RLNLightInstance } from './packages/rln/dist/rln_light.js';
|
12
13
|
export { MerkleRootTracker } from './packages/rln/dist/root_tracker.js';
|
13
14
|
export { extractMetaMaskSigner } from './packages/rln/dist/utils/metamask.js';
|
14
15
|
import './packages/rln/dist/utils/epoch.js';
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { RLN_ABI } from './abi.js';
|
2
2
|
|
3
3
|
const LINEA_CONTRACT = {
|
4
|
-
chainId:
|
4
|
+
chainId: 59141,
|
5
5
|
address: "0xb9cd878c90e49f797b4431fbf4fb333108cb90e6",
|
6
6
|
abi: RLN_ABI
|
7
7
|
};
|
@@ -12,6 +12,7 @@ const LINEA_CONTRACT = {
|
|
12
12
|
*/
|
13
13
|
const RATE_LIMIT_TIERS = {
|
14
14
|
LOW: 20, // Suggested minimum rate - 20 messages per epoch
|
15
|
+
MEDIUM: 200,
|
15
16
|
HIGH: 600 // Suggested maximum rate - 600 messages per epoch
|
16
17
|
};
|
17
18
|
// Global rate limit parameters
|
@@ -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 {
|
19
|
-
import {
|
18
|
+
import { MembershipState } from './types.js';
|
19
|
+
import { Contract } from '@ethersproject/contracts';
|
20
|
+
import { BigNumber } from '@ethersproject/bignumber';
|
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,28 +29,38 @@ 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) {
|
48
36
|
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.
|
37
|
+
log.info("Initializing RLNBaseContract", { address, rateLimit });
|
55
38
|
this.contract = contract || new Contract(address, RLN_ABI, signer);
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
39
|
+
this.rateLimit = rateLimit;
|
40
|
+
try {
|
41
|
+
log.info("Setting up event filters");
|
42
|
+
// Initialize event filters
|
43
|
+
this._membersFilter = this.contract.filters.MembershipRegistered();
|
44
|
+
this._membershipErasedFilter = this.contract.filters.MembershipErased();
|
45
|
+
this._membersExpiredFilter = this.contract.filters.MembershipExpired();
|
46
|
+
log.info("Event filters initialized successfully");
|
47
|
+
}
|
48
|
+
catch (error) {
|
49
|
+
log.error("Failed to initialize event filters", { error });
|
50
|
+
throw new Error("Failed to initialize event filters: " + error.message);
|
51
|
+
}
|
52
|
+
// Initialize members and subscriptions
|
53
|
+
this.fetchMembers()
|
54
|
+
.then(() => {
|
55
|
+
this.subscribeToMembers();
|
56
|
+
})
|
57
|
+
.catch((error) => {
|
58
|
+
log.error("Failed to initialize members", { error });
|
59
|
+
});
|
60
|
+
// Validate rate limit asynchronously
|
61
|
+
this.validateRateLimit(rateLimit).catch((error) => {
|
62
|
+
log.error("Failed to validate initial rate limit", { error });
|
63
|
+
});
|
60
64
|
}
|
61
65
|
/**
|
62
66
|
* Gets the current rate limit for this contract instance
|
@@ -98,7 +102,7 @@ class RLNLightContract {
|
|
98
102
|
*/
|
99
103
|
async getMaxTotalRateLimit() {
|
100
104
|
const maxTotalRate = await this.contract.maxTotalRateLimit();
|
101
|
-
return
|
105
|
+
return maxTotalRate.toNumber();
|
102
106
|
}
|
103
107
|
/**
|
104
108
|
* Gets the current total rate limit usage across all memberships
|
@@ -106,7 +110,7 @@ class RLNLightContract {
|
|
106
110
|
*/
|
107
111
|
async getCurrentTotalRateLimit() {
|
108
112
|
const currentTotal = await this.contract.currentTotalRateLimit();
|
109
|
-
return
|
113
|
+
return currentTotal.toNumber();
|
110
114
|
}
|
111
115
|
/**
|
112
116
|
* Gets the remaining available total rate limit that can be allocated
|
@@ -117,51 +121,32 @@ class RLNLightContract {
|
|
117
121
|
this.contract.maxTotalRateLimit(),
|
118
122
|
this.contract.currentTotalRateLimit()
|
119
123
|
]);
|
120
|
-
return
|
121
|
-
.sub(BigNumber.from(currentTotal))
|
122
|
-
.toNumber();
|
124
|
+
return Number(maxTotal) - Number(currentTotal);
|
123
125
|
}
|
124
126
|
/**
|
125
127
|
* Updates the rate limit for future registrations
|
126
128
|
* @param newRateLimit The new rate limit to use
|
127
129
|
*/
|
128
130
|
async setRateLimit(newRateLimit) {
|
131
|
+
await this.validateRateLimit(newRateLimit);
|
129
132
|
this.rateLimit = newRateLimit;
|
130
133
|
}
|
131
134
|
get members() {
|
132
135
|
const sortedMembers = Array.from(this._members.values()).sort((left, right) => left.index.toNumber() - right.index.toNumber());
|
133
136
|
return sortedMembers;
|
134
137
|
}
|
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
138
|
async fetchMembers(options = {}) {
|
154
|
-
const registeredMemberEvents = await queryFilter(this.contract, {
|
139
|
+
const registeredMemberEvents = await RLNBaseContract.queryFilter(this.contract, {
|
155
140
|
fromBlock: this.deployBlock,
|
156
141
|
...options,
|
157
142
|
membersFilter: this.membersFilter
|
158
143
|
});
|
159
|
-
const removedMemberEvents = await queryFilter(this.contract, {
|
144
|
+
const removedMemberEvents = await RLNBaseContract.queryFilter(this.contract, {
|
160
145
|
fromBlock: this.deployBlock,
|
161
146
|
...options,
|
162
147
|
membersFilter: this.membershipErasedFilter
|
163
148
|
});
|
164
|
-
const expiredMemberEvents = await queryFilter(this.contract, {
|
149
|
+
const expiredMemberEvents = await RLNBaseContract.queryFilter(this.contract, {
|
165
150
|
fromBlock: this.deployBlock,
|
166
151
|
...options,
|
167
152
|
membersFilter: this.membersExpiredFilter
|
@@ -173,6 +158,29 @@ class RLNLightContract {
|
|
173
158
|
];
|
174
159
|
this.processEvents(events);
|
175
160
|
}
|
161
|
+
static async queryFilter(contract, options) {
|
162
|
+
const FETCH_CHUNK = 5;
|
163
|
+
const BLOCK_RANGE = 3000;
|
164
|
+
const { fromBlock, membersFilter, fetchRange = BLOCK_RANGE, fetchChunks = FETCH_CHUNK } = options;
|
165
|
+
if (fromBlock === undefined) {
|
166
|
+
return contract.queryFilter(membersFilter);
|
167
|
+
}
|
168
|
+
if (!contract.provider) {
|
169
|
+
throw Error("No provider found on the contract.");
|
170
|
+
}
|
171
|
+
const toBlock = await contract.provider.getBlockNumber();
|
172
|
+
if (toBlock - fromBlock < fetchRange) {
|
173
|
+
return contract.queryFilter(membersFilter, fromBlock, toBlock);
|
174
|
+
}
|
175
|
+
const events = [];
|
176
|
+
const chunks = RLNBaseContract.splitToChunks(fromBlock, toBlock, fetchRange);
|
177
|
+
for (const portion of RLNBaseContract.takeN(chunks, fetchChunks)) {
|
178
|
+
const promises = portion.map(([left, right]) => RLNBaseContract.ignoreErrors(contract.queryFilter(membersFilter, left, right), []));
|
179
|
+
const fetchedEvents = await Promise.all(promises);
|
180
|
+
events.push(fetchedEvents.flatMap((v) => v));
|
181
|
+
}
|
182
|
+
return events.flatMap((v) => v);
|
183
|
+
}
|
176
184
|
processEvents(events) {
|
177
185
|
const toRemoveTable = new Map();
|
178
186
|
const toInsertTable = new Map();
|
@@ -208,6 +216,38 @@ class RLNLightContract {
|
|
208
216
|
}
|
209
217
|
});
|
210
218
|
}
|
219
|
+
static splitToChunks(from, to, step) {
|
220
|
+
const chunks = [];
|
221
|
+
let left = from;
|
222
|
+
while (left < to) {
|
223
|
+
const right = left + step < to ? left + step : to;
|
224
|
+
chunks.push([left, right]);
|
225
|
+
left = right;
|
226
|
+
}
|
227
|
+
return chunks;
|
228
|
+
}
|
229
|
+
static *takeN(array, size) {
|
230
|
+
let start = 0;
|
231
|
+
while (start < array.length) {
|
232
|
+
const portion = array.slice(start, start + size);
|
233
|
+
yield portion;
|
234
|
+
start += size;
|
235
|
+
}
|
236
|
+
}
|
237
|
+
static async ignoreErrors(promise, defaultValue) {
|
238
|
+
try {
|
239
|
+
return await promise;
|
240
|
+
}
|
241
|
+
catch (err) {
|
242
|
+
if (err instanceof Error) {
|
243
|
+
log.info(`Ignoring an error during query: ${err.message}`);
|
244
|
+
}
|
245
|
+
else {
|
246
|
+
log.info(`Ignoring an unknown error during query`);
|
247
|
+
}
|
248
|
+
return defaultValue;
|
249
|
+
}
|
250
|
+
}
|
211
251
|
subscribeToMembers() {
|
212
252
|
this.contract.on(this.membersFilter, (_idCommitment, _membershipRateLimit, _index, event) => {
|
213
253
|
this.processEvents([event]);
|
@@ -219,11 +259,72 @@ class RLNLightContract {
|
|
219
259
|
this.processEvents([event]);
|
220
260
|
});
|
221
261
|
}
|
262
|
+
async getMembershipInfo(idCommitmentBigInt) {
|
263
|
+
try {
|
264
|
+
const membershipData = await this.contract.memberships(idCommitmentBigInt);
|
265
|
+
const currentBlock = await this.contract.provider.getBlockNumber();
|
266
|
+
const [depositAmount, activeDuration, gracePeriodStartTimestamp, gracePeriodDuration, rateLimit, index, holder, token] = membershipData;
|
267
|
+
const gracePeriodEnd = gracePeriodStartTimestamp.add(gracePeriodDuration);
|
268
|
+
let state;
|
269
|
+
if (currentBlock < gracePeriodStartTimestamp.toNumber()) {
|
270
|
+
state = MembershipState.Active;
|
271
|
+
}
|
272
|
+
else if (currentBlock < gracePeriodEnd.toNumber()) {
|
273
|
+
state = MembershipState.GracePeriod;
|
274
|
+
}
|
275
|
+
else {
|
276
|
+
state = MembershipState.Expired;
|
277
|
+
}
|
278
|
+
return {
|
279
|
+
index,
|
280
|
+
idCommitment: idCommitmentBigInt.toString(),
|
281
|
+
rateLimit: Number(rateLimit),
|
282
|
+
startBlock: gracePeriodStartTimestamp.toNumber(),
|
283
|
+
endBlock: gracePeriodEnd.toNumber(),
|
284
|
+
state,
|
285
|
+
depositAmount,
|
286
|
+
activeDuration,
|
287
|
+
gracePeriodDuration,
|
288
|
+
holder,
|
289
|
+
token
|
290
|
+
};
|
291
|
+
}
|
292
|
+
catch (error) {
|
293
|
+
log.error("Error in getMembershipInfo:", error);
|
294
|
+
return undefined;
|
295
|
+
}
|
296
|
+
}
|
297
|
+
async extendMembership(idCommitmentBigInt) {
|
298
|
+
const tx = await this.contract.extendMemberships([idCommitmentBigInt]);
|
299
|
+
await tx.wait();
|
300
|
+
return tx;
|
301
|
+
}
|
302
|
+
async eraseMembership(idCommitmentBigInt, eraseFromMembershipSet = true) {
|
303
|
+
const tx = await this.contract["eraseMemberships(uint256[],bool)"]([idCommitmentBigInt], eraseFromMembershipSet);
|
304
|
+
await tx.wait();
|
305
|
+
return tx;
|
306
|
+
}
|
307
|
+
async registerMembership(idCommitmentBigInt, rateLimit = DEFAULT_RATE_LIMIT) {
|
308
|
+
if (rateLimit < RATE_LIMIT_PARAMS.MIN_RATE ||
|
309
|
+
rateLimit > RATE_LIMIT_PARAMS.MAX_RATE) {
|
310
|
+
throw new Error(`Rate limit must be between ${RATE_LIMIT_PARAMS.MIN_RATE} and ${RATE_LIMIT_PARAMS.MAX_RATE}`);
|
311
|
+
}
|
312
|
+
return this.contract.register(idCommitmentBigInt, rateLimit, []);
|
313
|
+
}
|
314
|
+
async withdraw(token, from) {
|
315
|
+
try {
|
316
|
+
const tx = await this.contract.withdraw(token, from);
|
317
|
+
await tx.wait();
|
318
|
+
}
|
319
|
+
catch (error) {
|
320
|
+
log.error(`Error in withdraw: ${error.message}`);
|
321
|
+
}
|
322
|
+
}
|
222
323
|
async registerWithIdentity(identity) {
|
223
324
|
try {
|
224
325
|
log.info(`Registering identity with rate limit: ${this.rateLimit} messages/epoch`);
|
225
326
|
// Check if the ID commitment is already registered
|
226
|
-
const existingIndex = await this.getMemberIndex(identity.IDCommitmentBigInt
|
327
|
+
const existingIndex = await this.getMemberIndex(identity.IDCommitmentBigInt);
|
227
328
|
if (existingIndex) {
|
228
329
|
throw new Error(`ID commitment is already registered with index ${existingIndex}`);
|
229
330
|
}
|
@@ -253,12 +354,12 @@ class RLNLightContract {
|
|
253
354
|
`and rate limit ${decodedData.membershipRateLimit}`);
|
254
355
|
const network = await this.contract.provider.getNetwork();
|
255
356
|
const address = this.contract.address;
|
256
|
-
const membershipId = decodedData.index
|
357
|
+
const membershipId = Number(decodedData.index);
|
257
358
|
return {
|
258
359
|
identity,
|
259
360
|
membership: {
|
260
361
|
address,
|
261
|
-
treeIndex:
|
362
|
+
treeIndex: membershipId,
|
262
363
|
chainId: network.chainId.toString(),
|
263
364
|
rateLimit: decodedData.membershipRateLimit.toNumber()
|
264
365
|
}
|
@@ -293,29 +394,6 @@ class RLNLightContract {
|
|
293
394
|
}
|
294
395
|
}
|
295
396
|
}
|
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
397
|
async registerWithPermitAndErase(identity, permit, idCommitmentsToErase) {
|
320
398
|
try {
|
321
399
|
log.info(`Registering identity with permit and rate limit: ${this.rateLimit} messages/epoch`);
|
@@ -335,12 +413,12 @@ class RLNLightContract {
|
|
335
413
|
`Rate limit: ${decodedData.membershipRateLimit}, Erased ${idCommitmentsToErase.length} commitments`);
|
336
414
|
const network = await this.contract.provider.getNetwork();
|
337
415
|
const address = this.contract.address;
|
338
|
-
const membershipId = decodedData.index
|
416
|
+
const membershipId = Number(decodedData.index);
|
339
417
|
return {
|
340
418
|
identity,
|
341
419
|
membership: {
|
342
420
|
address,
|
343
|
-
treeIndex:
|
421
|
+
treeIndex: membershipId,
|
344
422
|
chainId: network.chainId.toString(),
|
345
423
|
rateLimit: decodedData.membershipRateLimit.toNumber()
|
346
424
|
}
|
@@ -351,61 +429,42 @@ class RLNLightContract {
|
|
351
429
|
return undefined;
|
352
430
|
}
|
353
431
|
}
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
432
|
+
/**
|
433
|
+
* Validates that the rate limit is within the allowed range
|
434
|
+
* @throws Error if the rate limit is outside the allowed range
|
435
|
+
*/
|
436
|
+
async validateRateLimit(rateLimit) {
|
437
|
+
const [minRate, maxRate] = await Promise.all([
|
438
|
+
this.contract.minMembershipRateLimit(),
|
439
|
+
this.contract.maxMembershipRateLimit()
|
440
|
+
]);
|
441
|
+
const minRateNum = BigNumber.from(minRate).toNumber();
|
442
|
+
const maxRateNum = BigNumber.from(maxRate).toNumber();
|
443
|
+
if (rateLimit < minRateNum || rateLimit > maxRateNum) {
|
444
|
+
throw new Error(`Rate limit must be between ${minRateNum} and ${maxRateNum} messages per epoch`);
|
361
445
|
}
|
362
446
|
}
|
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;
|
447
|
+
get membersFilter() {
|
448
|
+
if (!this._membersFilter) {
|
449
|
+
throw Error("Members filter was not initialized.");
|
391
450
|
}
|
451
|
+
return this._membersFilter;
|
392
452
|
}
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
return this.
|
453
|
+
get membershipErasedFilter() {
|
454
|
+
if (!this._membershipErasedFilter) {
|
455
|
+
throw Error("MembershipErased filter was not initialized.");
|
456
|
+
}
|
457
|
+
return this._membershipErasedFilter;
|
398
458
|
}
|
399
|
-
|
400
|
-
if (
|
401
|
-
|
402
|
-
throw new Error(`Rate limit must be between ${RATE_LIMIT_PARAMS.MIN_RATE} and ${RATE_LIMIT_PARAMS.MAX_RATE}`);
|
459
|
+
get membersExpiredFilter() {
|
460
|
+
if (!this._membersExpiredFilter) {
|
461
|
+
throw Error("MembersExpired filter was not initialized.");
|
403
462
|
}
|
404
|
-
return this.
|
463
|
+
return this._membersExpiredFilter;
|
405
464
|
}
|
406
|
-
async getMemberIndex(
|
465
|
+
async getMemberIndex(idCommitmentBigInt) {
|
407
466
|
try {
|
408
|
-
const events = await this.contract.queryFilter(this.contract.filters.MembershipRegistered(
|
467
|
+
const events = await this.contract.queryFilter(this.contract.filters.MembershipRegistered(idCommitmentBigInt));
|
409
468
|
if (events.length === 0)
|
410
469
|
return undefined;
|
411
470
|
// Get the most recent registration event
|
@@ -417,61 +476,5 @@ class RLNLightContract {
|
|
417
476
|
}
|
418
477
|
}
|
419
478
|
}
|
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
479
|
|
477
|
-
export {
|
480
|
+
export { RLNBaseContract };
|