diff --git a/packages/ens-sync-script/prepare.sh b/packages/ens-sync-script/prepare.sh index 94df7c117..7dcb998e5 100755 --- a/packages/ens-sync-script/prepare.sh +++ b/packages/ens-sync-script/prepare.sh @@ -1,5 +1,5 @@ -mkdir -p network-contracts/artifacts/contracts/StreamRegistry/StreamRegistryV4.sol +mkdir -p network-contracts/artifacts/contracts/StreamRegistry/StreamRegistryV5.sol mkdir -p network-contracts/artifacts/contracts/chainlinkClient/ENSCacheV2Streamr.sol -cp ../network-contracts/artifacts/contracts/StreamRegistry/StreamRegistryV4.sol/StreamRegistryV4.json ./network-contracts/artifacts/contracts/StreamRegistry/StreamRegistryV4.sol +cp ../network-contracts/artifacts/contracts/StreamRegistry/StreamRegistryV5.sol/StreamRegistryV5.json ./network-contracts/artifacts/contracts/StreamRegistry/StreamRegistryV5.sol cp -r ../network-contracts/artifacts/contracts/chainlinkClient/ENSCacheV2Streamr.sol/ENSCacheV2Streamr.json ./network-contracts/artifacts/contracts/chainlinkClient/ENSCacheV2Streamr.sol diff --git a/packages/network-contracts/README.md b/packages/network-contracts/README.md index eccaf2748..f74ffa406 100644 --- a/packages/network-contracts/README.md +++ b/packages/network-contracts/README.md @@ -5,7 +5,7 @@ Solidity files plus Typescript interfaces for the Streamr Network smart contract ## Contracts Listed by file path: -* [StreamRegistry](./contracts/StreamRegistry/StreamRegistryV4.sol): Streams are added here along with metadata how to join them +* [StreamRegistry](./contracts/StreamRegistry/StreamRegistryV5.sol): Streams are added here along with metadata how to join them * [NodeRegistry](./contracts/NodeRegistry/NodeRegistry.sol): Storage nodes can register themselves here * [StreamStorageRegistry](./contracts/StreamStorageRegistry/StreamStorageRegistryV2.sol): Connects storage nodes to streams that they store * OperatorTokenomics: [Operator](./contracts/OperatorTokenomics/Operator.sol) and [Sponsorship](./contracts/OperatorTokenomics/Sponsorship.sol) contracts that govern how to pay for better service in the Network, and how to get paid for providing it @@ -29,6 +29,8 @@ contract.on("Staked", async (sponsorship: string) => { }) ``` +The functions that end with `ForUserId` take an arbitrary `bytes` argument for the user ID. Addresses can also be given to these functions but they need to be padded to 32 bytes first, e.g.: `ethers.utils.hexZeroPad("0x1234567890123456789012345678901234567890", 32)` => `0x0000000000000000000000001234567890123456789012345678901234567890`. + ## Developer notes The package exports all of the artifacts needed to interact with the contracts, and also a class that deploys them into a chain and then gives an object with all addresses and with all contract objects. @@ -53,6 +55,7 @@ npm run localUpgradeImpl # Changelog +StreamRegistryV5: added functions for arbitrary bytes user IDs (they can only publish and subscribe, not grant/edit/delete) 7.0.8 export ENS type 4.2.0 export ERC677 ABI and type diff --git a/packages/network-contracts/scripts/check.ts b/packages/network-contracts/scripts/check.ts index 32ad82afe..4b5fc03fd 100644 --- a/packages/network-contracts/scripts/check.ts +++ b/packages/network-contracts/scripts/check.ts @@ -3,10 +3,13 @@ import { Contract } from "@ethersproject/contracts" import { JsonRpcProvider } from "@ethersproject/providers" +import { hexZeroPad } from "@ethersproject/bytes" import { config } from "@streamr/config" -import { streamRegistryABI, ensRegistryABI, ENSCacheV2ABI } from "@streamr/network-contracts" -import type { ENS, StreamRegistry, ENSCacheV2 } from "@streamr/network-contracts" +import { streamRegistryABI, ENSCacheV2ABI } from "@streamr/network-contracts" +import type { StreamRegistry, ENSCacheV2 } from "@streamr/network-contracts" + +import { formatPermissions } from "./prettyPrint" // import debug from "debug" // const log = debug("log:streamr:ens-sync-script") @@ -14,65 +17,76 @@ const { log } = console const { STREAM_ID, + USER_ID, TX, // Easy setting: read addresses and URLs from @streamr/config - ENS_CHAIN = "dev2", - REGISTRY_CHAIN = "dev2", + CHAIN = "dev2", + // ENS_CHAIN = "dev2", // Individual overrides - ENS_RPC_URL, + // ENS_RPC_URL, REGISTRY_RPC_URL, - ENS_ADDRESS, + // ENS_ADDRESS, REGISTRY_ADDRESS, ENS_CACHE_ADDRESS, // ENS_REGISTRAR_ADDRESS, - ENS_RESOLVER_ADDRESS, + // ENS_RESOLVER_ADDRESS, } = process.env -const ensChainRpc = ENS_RPC_URL ?? (config as any)[ENS_CHAIN]?.rpcEndpoints?.[0]?.url -if (!ensChainRpc) { throw new Error("Either ENS_CHAIN or ENS_RPC_URL must be set in environment") } -const ensChainProvider = new JsonRpcProvider(ensChainRpc) +// const ensChainRpc = ENS_RPC_URL ?? (config as any)[ENS_CHAIN]?.rpcEndpoints?.[0]?.url +// if (!ensChainRpc) { throw new Error("Either ENS_CHAIN or ENS_RPC_URL must be set in environment") } +// const ensChainProvider = new JsonRpcProvider(ensChainRpc) -const registryChainRpc = REGISTRY_RPC_URL ?? (config as any)[REGISTRY_CHAIN]?.rpcEndpoints?.[0]?.url -if (!registryChainRpc) { throw new Error("Either REGISTRY_CHAIN or REGISTRY_RPC_URL must be set in environment") } -const registryChainProvider = new JsonRpcProvider(registryChainRpc) +const registryChainRpcUrl = REGISTRY_RPC_URL ?? (config as any)[CHAIN]?.rpcEndpoints?.[0]?.url +if (!registryChainRpcUrl) { throw new Error("Either REGISTRY_CHAIN or REGISTRY_RPC_URL must be set in environment") } +const provider = new JsonRpcProvider(registryChainRpcUrl) // const registryChainWallet = new Wallet(KEY, registryChainProvider) // log("Wallet address used by script: ", registryChainWallet.address) -const ensAddress = ENS_ADDRESS ?? (config as any)[ENS_CHAIN]?.contracts?.ENS -if (!ensAddress) { throw new Error("Either ENS_CHAIN or ENS_ADDRESS must be set in environment") } -const ensContract = new Contract(ensAddress, ensRegistryABI, ensChainProvider) as unknown as ENS +// const ensAddress = ENS_ADDRESS ?? (config as any)[ENS_CHAIN]?.contracts?.ENS +// if (!ensAddress) { throw new Error("Either ENS_CHAIN or ENS_ADDRESS must be set in environment") } +// const ensContract = new Contract(ensAddress, ensRegistryABI, ensChainProvider) as unknown as ENS -const registryAddress = REGISTRY_ADDRESS ?? (config as any)[REGISTRY_CHAIN]?.contracts?.StreamRegistry +const registryAddress = REGISTRY_ADDRESS ?? (config as any)[CHAIN]?.contracts?.StreamRegistry if (!registryAddress) { throw new Error("Either REGISTRY_CHAIN or REGISTRY_ADDRESS must be set in environment") } -const streamRegistryContract = new Contract(registryAddress, streamRegistryABI, registryChainProvider) as StreamRegistry +const streamRegistry = new Contract(registryAddress, streamRegistryABI, provider) as StreamRegistry -const ensCacheAddress = ENS_CACHE_ADDRESS ?? (config as any)[REGISTRY_CHAIN]?.contracts?.ENSCacheV2 +const ensCacheAddress = ENS_CACHE_ADDRESS ?? (config as any)[CHAIN]?.contracts?.ENSCacheV2 if (!ensCacheAddress) { throw new Error("Either REGISTRY_CHAIN or ENS_CACHE_ADDRESS must be set in environment") } -const ensCacheContract = new Contract(ensCacheAddress, ENSCacheV2ABI, registryChainProvider) as ENSCacheV2 +const ensCacheContract = new Contract(ensCacheAddress, ENSCacheV2ABI, provider) as ENSCacheV2 -const ensResolverAddress = ENS_RESOLVER_ADDRESS ?? (config as any)[ENS_CHAIN]?.contracts?.PublicResolver -if (!ensResolverAddress) { throw new Error("Either CHAIN (with PublicResolver address) or ENS_RESOLVER_ADDRESS must be set in environment") } +// const ensResolverAddress = ENS_RESOLVER_ADDRESS ?? (config as any)[ENS_CHAIN]?.contracts?.PublicResolver +// if (!ensResolverAddress) { throw new Error("Either CHAIN (with PublicResolver address) or ENS_RESOLVER_ADDRESS must be set in environment") } const AddressZero = "0x0000000000000000000000000000000000000000" -const Bytes32Zero = "0x0000000000000000000000000000000000000000000000000000000000000000" +// const Bytes32Zero = "0x0000000000000000000000000000000000000000000000000000000000000000" +const TRUSTED_ROLE = "0x2de84d9fbdf6d06e2cc584295043dbd76046423b9f8bae9426d4fa5e7c03f4a7" async function main() { log("Checking ENS (cache/bridge) state") - log("Checking the network setup: %o", await ensChainProvider.getNetwork()) - log("ENS contract at: %s (deployer %s)", ensContract.address, await ensContract.owner(Bytes32Zero)) - log("StreamRegistry contract at: %s (%s)", streamRegistryContract.address, await streamRegistryContract.TRUSTED_ROLE()) + log("Checking the network setup: %o", await provider.getNetwork()) + // log("ENS contract at: %s (deployer %s)", ensContract.address, await ensContract.owner(Bytes32Zero)) + log("StreamRegistry contract at: %s (%s)", streamRegistry.address, TRUSTED_ROLE == await streamRegistry.TRUSTED_ROLE()) log("ENSCacheV2 contract at: %s (%s)", ensCacheContract.address, await ensCacheContract.owners(AddressZero)) if (STREAM_ID) { log("Checking stream '%s'", STREAM_ID) - log(" Metadata: %s", await streamRegistryContract.getStreamMetadata(STREAM_ID)) + log(" Metadata: %s", await streamRegistry.getStreamMetadata(STREAM_ID)) + if (USER_ID) { + // pad to 32 bytes, TODO: below lines should Just Work in the same way (ETH-777) + const userIdBytes = hexZeroPad(USER_ID, 32) + log("User ID bytes: %s", userIdBytes) + log(" %s permissions: %o", USER_ID, await streamRegistry.getPermissionsForUser(STREAM_ID, USER_ID).then(formatPermissions)) + log(" %s permissions: %o", USER_ID, await streamRegistry.getPermissionsForUserId(STREAM_ID, userIdBytes) + .then(formatPermissions).catch(() => "error") + ) + } } if (TX) { log("Checking transaction %s", TX) - log(" Receipt: %o", await ensChainProvider.getTransactionReceipt(TX)) + log(" Receipt: %o", await provider.getTransactionReceipt(TX)) } }