import ../group_manager_base, ../../rln, std/sequtils export group_manager_base type StaticGroupManager* = ref object of GroupManager groupKeys*: seq[IdentityCredential] groupSize*: uint template initializedGuard*(g: StaticGroupManager): untyped = if not g.initialized: raise newException(ValueError, "StaticGroupManager is not initialized") method init*(g: StaticGroupManager): Future[void] {.async,gcsafe.} = let groupSize = g.groupSize groupKeys = g.groupKeys membershipIndex = if g.membershipIndex.isSome(): g.membershipIndex.get() else: raise newException(ValueError, "Membership index is not set") if membershipIndex < MembershipIndex(0) or membershipIndex >= MembershipIndex(groupSize): raise newException(ValueError, "Invalid membership index. Must be within 0 and " & $(groupSize - 1) & "but was " & $membershipIndex) g.idCredentials = some(groupKeys[membershipIndex]) # Seed the received commitments into the merkle tree let idCommitments = groupKeys.mapIt(it.idCommitment) let membersInserted = g.rlnInstance.insertMembers(g.latestIndex, idCommitments) if not membersInserted: raise newException(ValueError, "Failed to insert members into the merkle tree") discard g.slideRootQueue() g.latestIndex += MembershipIndex(idCommitments.len() - 1) g.initialized = true return method startGroupSync*(g: StaticGroupManager): Future[void] = initializedGuard(g) var retFuture = newFuture[void]("StaticGroupManager.startGroupSync") # No-op retFuture.complete() return retFuture method register*(g: StaticGroupManager, idCommitment: IDCommitment): Future[void] {.async.} = initializedGuard(g) await g.registerBatch(@[idCommitment]) method registerBatch*(g: StaticGroupManager, idCommitments: seq[IDCommitment]): Future[void] {.async.} = initializedGuard(g) let membersInserted = g.rlnInstance.insertMembers(g.latestIndex + 1, idCommitments) if not membersInserted: raise newException(ValueError, "Failed to insert members into the merkle tree") if g.registerCb.isSome(): var memberSeq = newSeq[Membership]() for i in 0..