mirror of https://github.com/waku-org/nwaku.git
Feat (Rln relay): enabling signed tx (#1023)
This commit is contained in:
parent
993781a137
commit
a40686e26e
|
@ -7,6 +7,7 @@ import
|
||||||
testutils/unittests, chronos, chronicles, stint, web3, json,
|
testutils/unittests, chronos, chronicles, stint, web3, json,
|
||||||
stew/byteutils, stew/shims/net as stewNet,
|
stew/byteutils, stew/shims/net as stewNet,
|
||||||
libp2p/crypto/crypto,
|
libp2p/crypto/crypto,
|
||||||
|
eth/keys,
|
||||||
../../waku/v2/protocol/waku_rln_relay/[waku_rln_relay_utils,
|
../../waku/v2/protocol/waku_rln_relay/[waku_rln_relay_utils,
|
||||||
waku_rln_relay_types, rln_relay_contract],
|
waku_rln_relay_types, rln_relay_contract],
|
||||||
../../waku/v2/node/wakunode2,
|
../../waku/v2/node/wakunode2,
|
||||||
|
@ -75,6 +76,31 @@ proc uploadRLNContract*(ethClientAddress: string): Future[Address] {.async.} =
|
||||||
|
|
||||||
return contractAddress
|
return contractAddress
|
||||||
|
|
||||||
|
|
||||||
|
proc createEthAccount(): Future[(keys.PrivateKey, Address)] {.async.} =
|
||||||
|
let theRNG = keys.newRng()
|
||||||
|
|
||||||
|
let web3 = await newWeb3(ETH_CLIENT)
|
||||||
|
let accounts = await web3.provider.eth_accounts()
|
||||||
|
let gasPrice = int(await web3.provider.eth_gasPrice())
|
||||||
|
web3.defaultAccount = accounts[0]
|
||||||
|
|
||||||
|
let pk = keys.PrivateKey.random(theRNG[])
|
||||||
|
let acc = Address(toCanonicalAddress(pk.toPublicKey()))
|
||||||
|
|
||||||
|
var tx: EthSend
|
||||||
|
tx.source = accounts[0]
|
||||||
|
tx.value = some(ethToWei(10.u256))
|
||||||
|
tx.to = some(acc)
|
||||||
|
tx.gasPrice = some(gasPrice)
|
||||||
|
|
||||||
|
# Send 10 eth to acc
|
||||||
|
discard await web3.send(tx)
|
||||||
|
var balance = await web3.provider.eth_getBalance(acc, "latest")
|
||||||
|
assert(balance == ethToWei(10.u256))
|
||||||
|
|
||||||
|
return (pk, acc)
|
||||||
|
|
||||||
procSuite "Waku-rln-relay":
|
procSuite "Waku-rln-relay":
|
||||||
asyncTest "event subscription":
|
asyncTest "event subscription":
|
||||||
# preparation ------------------------------
|
# preparation ------------------------------
|
||||||
|
@ -259,12 +285,16 @@ procSuite "Waku-rln-relay":
|
||||||
check:
|
check:
|
||||||
membershipKeyPair.isSome
|
membershipKeyPair.isSome
|
||||||
|
|
||||||
|
# create an Ethereum private key and the corresponding account
|
||||||
|
let (ethPrivKey, ethacc) = await createEthAccount()
|
||||||
|
|
||||||
# test ------------------------------
|
# test ------------------------------
|
||||||
# initialize the WakuRLNRelay
|
# initialize the WakuRLNRelay
|
||||||
var rlnPeer = WakuRLNRelay(membershipKeyPair: membershipKeyPair.get(),
|
var rlnPeer = WakuRLNRelay(membershipKeyPair: membershipKeyPair.get(),
|
||||||
membershipIndex: MembershipIndex(0),
|
membershipIndex: MembershipIndex(0),
|
||||||
ethClientAddress: ETH_CLIENT,
|
ethClientAddress: ETH_CLIENT,
|
||||||
ethAccountAddress: ethAccountAddress,
|
ethAccountPrivateKey: ethPrivKey,
|
||||||
|
ethAccountAddress: ethacc,
|
||||||
membershipContractAddress: contractAddress)
|
membershipContractAddress: contractAddress)
|
||||||
|
|
||||||
# register the rln-relay peer to the membership contract
|
# register the rln-relay peer to the membership contract
|
||||||
|
@ -348,6 +378,8 @@ procSuite "Waku-rln-relay":
|
||||||
ethAccountAddress = accounts[0]
|
ethAccountAddress = accounts[0]
|
||||||
web3.defaultAccount = accounts[0]
|
web3.defaultAccount = accounts[0]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# create an rln instance
|
# create an rln instance
|
||||||
var rlnInstance = createRLNInstance()
|
var rlnInstance = createRLNInstance()
|
||||||
check:
|
check:
|
||||||
|
@ -389,11 +421,16 @@ procSuite "Waku-rln-relay":
|
||||||
let tx2Hash = await contractObj.register(pk2).send(value = MEMBERSHIP_FEE)
|
let tx2Hash = await contractObj.register(pk2).send(value = MEMBERSHIP_FEE)
|
||||||
debug "a member is registered", tx2 = tx2Hash
|
debug "a member is registered", tx2 = tx2Hash
|
||||||
|
|
||||||
|
# create an Ethereum private key and the corresponding account
|
||||||
|
let (ethPrivKey, ethacc) = await createEthAccount()
|
||||||
|
|
||||||
|
|
||||||
# test ------------------------------
|
# test ------------------------------
|
||||||
# start rln-relay
|
# start rln-relay
|
||||||
node.mountRelay(@[RLNRELAY_PUBSUB_TOPIC])
|
node.mountRelay(@[RLNRELAY_PUBSUB_TOPIC])
|
||||||
await node.mountRlnRelayDynamic(ethClientAddr = EthClient,
|
await node.mountRlnRelayDynamic(ethClientAddr = EthClient,
|
||||||
ethAccAddr = ethAccountAddress,
|
ethAccAddr = ethacc,
|
||||||
|
ethAccountPrivKey = ethPrivKey,
|
||||||
memContractAddr = contractAddress,
|
memContractAddr = contractAddress,
|
||||||
memKeyPair = keyPair1,
|
memKeyPair = keyPair1,
|
||||||
memIndex = some(MembershipIndex(0)),
|
memIndex = some(MembershipIndex(0)),
|
||||||
|
@ -439,10 +476,14 @@ procSuite "Waku-rln-relay":
|
||||||
node2 = WakuNode.new(nodeKey2, ValidIpAddress.init("0.0.0.0"), Port(60001))
|
node2 = WakuNode.new(nodeKey2, ValidIpAddress.init("0.0.0.0"), Port(60001))
|
||||||
await node2.start()
|
await node2.start()
|
||||||
|
|
||||||
|
# create an Ethereum private key and the corresponding account
|
||||||
|
let (ethPrivKey, ethacc) = await createEthAccount()
|
||||||
|
|
||||||
# start rln-relay on the first node, leave rln-relay credentials empty
|
# start rln-relay on the first node, leave rln-relay credentials empty
|
||||||
node.mountRelay(@[RLNRELAY_PUBSUB_TOPIC])
|
node.mountRelay(@[RLNRELAY_PUBSUB_TOPIC])
|
||||||
await node.mountRlnRelayDynamic(ethClientAddr = EthClient,
|
await node.mountRlnRelayDynamic(ethClientAddr = EthClient,
|
||||||
ethAccAddr = ethAccountAddress1,
|
ethAccAddr = ethacc,
|
||||||
|
ethAccountPrivKey = ethPrivKey,
|
||||||
memContractAddr = contractAddress,
|
memContractAddr = contractAddress,
|
||||||
memKeyPair = none(MembershipKeyPair),
|
memKeyPair = none(MembershipKeyPair),
|
||||||
memIndex = none(MembershipIndex),
|
memIndex = none(MembershipIndex),
|
||||||
|
@ -454,7 +495,8 @@ procSuite "Waku-rln-relay":
|
||||||
# start rln-relay on the second node, leave rln-relay credentials empty
|
# start rln-relay on the second node, leave rln-relay credentials empty
|
||||||
node2.mountRelay(@[RLNRELAY_PUBSUB_TOPIC])
|
node2.mountRelay(@[RLNRELAY_PUBSUB_TOPIC])
|
||||||
await node2.mountRlnRelayDynamic(ethClientAddr = EthClient,
|
await node2.mountRlnRelayDynamic(ethClientAddr = EthClient,
|
||||||
ethAccAddr = ethAccountAddress2,
|
ethAccAddr = ethacc,
|
||||||
|
ethAccountPrivKey = ethPrivKey,
|
||||||
memContractAddr = contractAddress,
|
memContractAddr = contractAddress,
|
||||||
memKeyPair = none(MembershipKeyPair),
|
memKeyPair = none(MembershipKeyPair),
|
||||||
memIndex = none(MembershipIndex),
|
memIndex = none(MembershipIndex),
|
||||||
|
|
|
@ -145,10 +145,15 @@ type
|
||||||
name: "rln-relay-id-commitment" }: string
|
name: "rln-relay-id-commitment" }: string
|
||||||
|
|
||||||
rlnRelayEthAccount* {.
|
rlnRelayEthAccount* {.
|
||||||
desc: "Ethereum testnet account address",
|
desc: "Account address for the Ethereum testnet Goerli",
|
||||||
defaultValue: ""
|
defaultValue: ""
|
||||||
name: "eth-account-address" }: string
|
name: "eth-account-address" }: string
|
||||||
|
|
||||||
|
rlnRelayEthAccountPrivKey* {.
|
||||||
|
desc: "Account private key for the Ethereum testnet Goerli",
|
||||||
|
defaultValue: ""
|
||||||
|
name: "eth-account-privatekey" }: string
|
||||||
|
|
||||||
rlnRelayEthClientAddress* {.
|
rlnRelayEthClientAddress* {.
|
||||||
desc: "Ethereum testnet client address e.g., ws://localhost:8540/",
|
desc: "Ethereum testnet client address e.g., ws://localhost:8540/",
|
||||||
defaultValue: "ws://localhost:8540/"
|
defaultValue: "ws://localhost:8540/"
|
||||||
|
|
|
@ -90,8 +90,8 @@ type MessageValidationResult* {.pure.} = enum
|
||||||
# inputs of the membership contract constructor
|
# inputs of the membership contract constructor
|
||||||
# TODO may be able to make these constants private and put them inside the waku_rln_relay_utils
|
# TODO may be able to make these constants private and put them inside the waku_rln_relay_utils
|
||||||
const
|
const
|
||||||
MEMBERSHIP_FEE* = 5.u256
|
MEMBERSHIP_FEE* = 1000000000000000.u256
|
||||||
# the current implementation of the rln lib only supports a circuit for Merkle tree with depth 32
|
# the current implementation of the rln lib supports a circuit for Merkle tree with depth 20
|
||||||
MERKLE_TREE_DEPTH* = 20
|
MERKLE_TREE_DEPTH* = 20
|
||||||
# TODO the ETH_CLIENT should be an input to the rln-relay, though hardcoded for now
|
# TODO the ETH_CLIENT should be an input to the rln-relay, though hardcoded for now
|
||||||
# the current address is the address of ganache-cli when run locally
|
# the current address is the address of ganache-cli when run locally
|
||||||
|
|
|
@ -119,11 +119,15 @@ proc toMembershipIndex(v: UInt256): MembershipIndex =
|
||||||
let result: MembershipIndex = cast[MembershipIndex](v)
|
let result: MembershipIndex = cast[MembershipIndex](v)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
proc register*(idComm: IDCommitment, ethAccountAddress: Address, ethClientAddress: string, membershipContractAddress: Address): Future[Result[MembershipIndex, string]] {.async.} =
|
proc register*(idComm: IDCommitment, ethAccountAddress: Address, ethAccountPrivKey: keys.PrivateKey, ethClientAddress: string, membershipContractAddress: Address): Future[Result[MembershipIndex, string]] {.async.} =
|
||||||
# TODO may need to also get eth Account Private Key as PrivateKey
|
# TODO may need to also get eth Account Private Key as PrivateKey
|
||||||
## registers the idComm into the membership contract whose address is in rlnPeer.membershipContractAddress
|
## registers the idComm into the membership contract whose address is in rlnPeer.membershipContractAddress
|
||||||
let web3 = await newWeb3(ethClientAddress)
|
let web3 = await newWeb3(ethClientAddress)
|
||||||
web3.defaultAccount = ethAccountAddress
|
web3.defaultAccount = ethAccountAddress
|
||||||
|
# set the account private key
|
||||||
|
web3.privateKey = some(ethAccountPrivKey)
|
||||||
|
# set the gas price twice the suggested price in order for the fast mining
|
||||||
|
let gasPrice = int(await web3.provider.eth_gasPrice()) * 2
|
||||||
|
|
||||||
# when the private key is set in a web3 instance, the send proc (sender.register(pk).send(MEMBERSHIP_FEE))
|
# when the private key is set in a web3 instance, the send proc (sender.register(pk).send(MEMBERSHIP_FEE))
|
||||||
# does the signing using the provided key
|
# does the signing using the provided key
|
||||||
|
@ -133,7 +137,7 @@ proc register*(idComm: IDCommitment, ethAccountAddress: Address, ethClientAddres
|
||||||
debug "registering an id commitment", idComm=idComm
|
debug "registering an id commitment", idComm=idComm
|
||||||
let
|
let
|
||||||
pk = idComm.toUInt256()
|
pk = idComm.toUInt256()
|
||||||
txHash = await sender.register(pk).send(MEMBERSHIP_FEE)
|
txHash = await sender.register(pk).send(value = MEMBERSHIP_FEE, gasPrice = gasPrice)
|
||||||
tsReceipt = await web3.getMinedTransactionReceipt(txHash)
|
tsReceipt = await web3.getMinedTransactionReceipt(txHash)
|
||||||
|
|
||||||
# the receipt topic holds the hash of signature of the raised events
|
# the receipt topic holds the hash of signature of the raised events
|
||||||
|
@ -165,7 +169,7 @@ proc register*(rlnPeer: WakuRLNRelay): Future[bool] {.async.} =
|
||||||
## registers the public key of the rlnPeer which is rlnPeer.membershipKeyPair.publicKey
|
## registers the public key of the rlnPeer which is rlnPeer.membershipKeyPair.publicKey
|
||||||
## into the membership contract whose address is in rlnPeer.membershipContractAddress
|
## into the membership contract whose address is in rlnPeer.membershipContractAddress
|
||||||
let pk = rlnPeer.membershipKeyPair.idCommitment
|
let pk = rlnPeer.membershipKeyPair.idCommitment
|
||||||
discard await register(idComm = pk, ethAccountAddress = rlnPeer.ethAccountAddress, ethClientAddress = rlnPeer.ethClientAddress, membershipContractAddress = rlnPeer.membershipContractAddress )
|
discard await register(idComm = pk, ethAccountAddress = rlnPeer.ethAccountAddress, ethAccountPrivKey = rlnPeer.ethAccountPrivateKey, ethClientAddress = rlnPeer.ethClientAddress, membershipContractAddress = rlnPeer.membershipContractAddress )
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
@ -607,16 +611,19 @@ proc addAll*(rlnInstance: RLN[Bn256], list: seq[IDCommitment]): bool =
|
||||||
type RegistrationEventHandler = proc(pubkey: Uint256, index: Uint256): void {.gcsafe, closure, raises: [Defect].}
|
type RegistrationEventHandler = proc(pubkey: Uint256, index: Uint256): void {.gcsafe, closure, raises: [Defect].}
|
||||||
|
|
||||||
|
|
||||||
proc subscribeToGroupEvents(ethClientUri: string, contractAddress: Address, blockNumber: string = "0x0", handler: RegistrationEventHandler) {.async, gcsafe.} =
|
proc subscribeToGroupEvents(ethClientUri: string, ethAccountAddress: Address, contractAddress: Address, blockNumber: string = "0x0", handler: RegistrationEventHandler) {.async, gcsafe.} =
|
||||||
## connects to the eth client whose URI is supplied as `ethClientUri`
|
## connects to the eth client whose URI is supplied as `ethClientUri`
|
||||||
## subscribes to the `MemberRegistered` event emitted from the `MembershipContract` which is available on the supplied `contractAddress`
|
## subscribes to the `MemberRegistered` event emitted from the `MembershipContract` which is available on the supplied `contractAddress`
|
||||||
## it collects all the events starting from the given `blockNumber`
|
## it collects all the events starting from the given `blockNumber`
|
||||||
## for every received event, it calls the `handler`
|
## for every received event, it calls the `handler`
|
||||||
|
|
||||||
# connect to the eth client
|
# connect to the eth client
|
||||||
let web3 = await newWeb3(ETH_CLIENT)
|
let web3 = await newWeb3(ethClientUri)
|
||||||
# prepare a contract sender to interact with it
|
# prepare a contract sender to interact with it
|
||||||
var contractObj = web3.contractSender(MembershipContract, contractAddress)
|
var contractObj = web3.contractSender(MembershipContract, contractAddress)
|
||||||
|
web3.defaultAccount = ethAccountAddress
|
||||||
|
# set the gas price twice the suggested price in order for the fast mining
|
||||||
|
# let gasPrice = int(await web3.provider.eth_gasPrice()) * 2
|
||||||
|
|
||||||
# subscribe to the MemberRegistered events
|
# subscribe to the MemberRegistered events
|
||||||
# TODO can do similarly for deletion events, though it is not yet supported
|
# TODO can do similarly for deletion events, though it is not yet supported
|
||||||
|
@ -632,7 +639,7 @@ proc subscribeToGroupEvents(ethClientUri: string, contractAddress: Address, bloc
|
||||||
|
|
||||||
proc handleGroupUpdates*(rlnPeer: WakuRLNRelay, handler: RegistrationEventHandler) {.async, gcsafe.} =
|
proc handleGroupUpdates*(rlnPeer: WakuRLNRelay, handler: RegistrationEventHandler) {.async, gcsafe.} =
|
||||||
# mounts the supplied handler for the registration events emitting from the membership contract
|
# mounts the supplied handler for the registration events emitting from the membership contract
|
||||||
await subscribeToGroupEvents(ethClientUri = rlnPeer.ethClientAddress, contractAddress = rlnPeer.membershipContractAddress, handler = handler)
|
await subscribeToGroupEvents(ethClientUri = rlnPeer.ethClientAddress, ethAccountAddress = rlnPeer.ethAccountAddress, contractAddress = rlnPeer.membershipContractAddress, handler = handler)
|
||||||
|
|
||||||
proc addRLNRelayValidator*(node: WakuNode, pubsubTopic: string, contentTopic: ContentTopic, spamHandler: Option[SpamHandler] = none(SpamHandler)) =
|
proc addRLNRelayValidator*(node: WakuNode, pubsubTopic: string, contentTopic: ContentTopic, spamHandler: Option[SpamHandler] = none(SpamHandler)) =
|
||||||
## this procedure is a thin wrapper for the pubsub addValidator method
|
## this procedure is a thin wrapper for the pubsub addValidator method
|
||||||
|
@ -737,6 +744,7 @@ proc mountRlnRelayStatic*(node: WakuNode,
|
||||||
proc mountRlnRelayDynamic*(node: WakuNode,
|
proc mountRlnRelayDynamic*(node: WakuNode,
|
||||||
ethClientAddr: string = "",
|
ethClientAddr: string = "",
|
||||||
ethAccAddr: web3.Address,
|
ethAccAddr: web3.Address,
|
||||||
|
ethAccountPrivKey: keys.PrivateKey,
|
||||||
memContractAddr: web3.Address,
|
memContractAddr: web3.Address,
|
||||||
memKeyPair: Option[MembershipKeyPair] = none(MembershipKeyPair),
|
memKeyPair: Option[MembershipKeyPair] = none(MembershipKeyPair),
|
||||||
memIndex: Option[MembershipIndex] = none(MembershipIndex),
|
memIndex: Option[MembershipIndex] = none(MembershipIndex),
|
||||||
|
@ -770,7 +778,7 @@ proc mountRlnRelayDynamic*(node: WakuNode,
|
||||||
doAssert(keyPairOpt.isSome)
|
doAssert(keyPairOpt.isSome)
|
||||||
keyPair = keyPairOpt.get()
|
keyPair = keyPairOpt.get()
|
||||||
# register the rln-relay peer to the membership contract
|
# register the rln-relay peer to the membership contract
|
||||||
let regIndexRes = await register(idComm = keyPair.idCommitment, ethAccountAddress = ethAccAddr, ethClientAddress = ethClientAddr, membershipContractAddress = memContractAddr)
|
let regIndexRes = await register(idComm = keyPair.idCommitment, ethAccountAddress = ethAccAddr, ethAccountPrivKey = ethAccountPrivKey, ethClientAddress = ethClientAddr, membershipContractAddress = memContractAddr)
|
||||||
# check whether registration is done
|
# check whether registration is done
|
||||||
doAssert(regIndexRes.isOk())
|
doAssert(regIndexRes.isOk())
|
||||||
rlnIndex = regIndexRes.value
|
rlnIndex = regIndexRes.value
|
||||||
|
@ -785,6 +793,7 @@ proc mountRlnRelayDynamic*(node: WakuNode,
|
||||||
membershipContractAddress: memContractAddr,
|
membershipContractAddress: memContractAddr,
|
||||||
ethClientAddress: ethClientAddr,
|
ethClientAddress: ethClientAddr,
|
||||||
ethAccountAddress: ethAccAddr,
|
ethAccountAddress: ethAccAddr,
|
||||||
|
ethAccountPrivateKey: ethAccountPrivKey,
|
||||||
rlnInstance: rln,
|
rlnInstance: rln,
|
||||||
pubsubTopic: pubsubTopic,
|
pubsubTopic: pubsubTopic,
|
||||||
contentTopic: contentTopic)
|
contentTopic: contentTopic)
|
||||||
|
@ -839,6 +848,7 @@ proc mountRlnRelay*(node: WakuNode, conf: WakuNodeConf) {.raises: [Defect, Value
|
||||||
# read related inputs to run rln-relay in on-chain mode and do type conversion when needed
|
# read related inputs to run rln-relay in on-chain mode and do type conversion when needed
|
||||||
let
|
let
|
||||||
ethAccountAddr = web3.fromHex(web3.Address, conf.rlnRelayEthAccount)
|
ethAccountAddr = web3.fromHex(web3.Address, conf.rlnRelayEthAccount)
|
||||||
|
ethAccountPrivKey = keys.PrivateKey(SkSecretKey.fromHex(conf.rlnRelayEthAccountPrivKey).value)
|
||||||
ethClientAddr = conf.rlnRelayEthClientAddress
|
ethClientAddr = conf.rlnRelayEthClientAddress
|
||||||
ethMemContractAddress = web3.fromHex(web3.Address, conf.rlnRelayEthMemContractAddress)
|
ethMemContractAddress = web3.fromHex(web3.Address, conf.rlnRelayEthMemContractAddress)
|
||||||
rlnRelayId = conf.rlnRelayIdKey
|
rlnRelayId = conf.rlnRelayIdKey
|
||||||
|
@ -850,9 +860,9 @@ proc mountRlnRelay*(node: WakuNode, conf: WakuNodeConf) {.raises: [Defect, Value
|
||||||
let keyPair = @[(rlnRelayId, rlnRelayIdCommitmentKey)]
|
let keyPair = @[(rlnRelayId, rlnRelayIdCommitmentKey)]
|
||||||
let memKeyPair = keyPair.toMembershipKeyPairs()[0]
|
let memKeyPair = keyPair.toMembershipKeyPairs()[0]
|
||||||
# mount the rln relay protocol in the on-chain/dynamic mode
|
# mount the rln relay protocol in the on-chain/dynamic mode
|
||||||
waitFor node.mountRlnRelayDynamic(memContractAddr = ethMemContractAddress, ethClientAddr = ethClientAddr, memKeyPair = some(memKeyPair), memIndex = some(rlnRelayIndex), ethAccAddr = ethAccountAddr, pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic)
|
waitFor node.mountRlnRelayDynamic(memContractAddr = ethMemContractAddress, ethClientAddr = ethClientAddr, memKeyPair = some(memKeyPair), memIndex = some(rlnRelayIndex), ethAccAddr = ethAccountAddr, ethAccountPrivKey = ethAccountPrivKey, pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic)
|
||||||
else:
|
else:
|
||||||
# no rln credential is provided
|
# no rln credential is provided
|
||||||
# mount the rln relay protocol in the on-chain/dynamic mode
|
# mount the rln relay protocol in the on-chain/dynamic mode
|
||||||
waitFor node.mountRlnRelayDynamic(memContractAddr = ethMemContractAddress, ethClientAddr = ethClientAddr, ethAccAddr = ethAccountAddr, pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic)
|
waitFor node.mountRlnRelayDynamic(memContractAddr = ethMemContractAddress, ethClientAddr = ethClientAddr, ethAccAddr = ethAccountAddr, ethAccountPrivKey = ethAccountPrivKey, pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue