Skip to content

Commit

Permalink
ETH-726: @streamr/network-contracts package export with ethers v6 com…
Browse files Browse the repository at this point in the history
…patible types (#910)

Added a new package subdirectory to workspace, the
@streamr/network-contracts NPM package is created in that new package
subdirectory.

The new package exports typechain types in ethers v6 format.

Why we need a new package instead of exporting ethers v6 compatible
types from the existing package: in the network-contracts package, we
need ethers v5 compatible types for the version of hardhat tools (esp.
hardhat-upgrades) that we use, and we can't get both v5 and v6 types out
of the same typechain config

* fixed random lint warnings
* updated (old) network-contracts tsconfig.build.json so that it's the
same as in the (new) npm-network-contracts package
  • Loading branch information
jtakalai authored Jan 20, 2025
1 parent fc534b8 commit d0eb2c0
Show file tree
Hide file tree
Showing 12 changed files with 299 additions and 25 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ This is a monorepo containing various smart contracts and subgraphs used by the

## Main packages

- [Network contracts](https://github.com/streamr-dev/network-contracts/tree/master/packages/network-contracts) The actual smart contracts used by the Streamr Network
- [Network contracts](https://github.com/streamr-dev/network-contracts/tree/master/packages/network-contracts) The actual smart contracts used by the Streamr Network. Package exported from here has version 7.x.x and exports Typechain interfaces for Ethers v5.
- [Network contracts NPM package](https://github.com/streamr-dev/network-contracts/tree/master/packages/npm-network-contracts) ABI and Typechain interfaces for the Streamr Network smart contracts for Ethers v6, plus scripts for interacting with the smart contracts.
- [Network subgraphs](https://github.com/streamr-dev/network-contracts/tree/master/packages/network-subgraphs) The Graph subgraphs for many contracts in the `network-contracts` package
- [config](https://github.com/streamr-dev/network-contracts/tree/master/packages/config) Addresses of deployed Streamr contracts on various chains, importable as an npm package

Expand Down
4 changes: 3 additions & 1 deletion packages/hub-subgraph/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
## Deprecated, moved to [network-subgraphs](../network-subgraphs/README.md)

# Subgraph definitions for the project registry

## Setup
Expand Down Expand Up @@ -45,7 +47,7 @@ npm run deploy-local

then you can paste graphQL queries at http://127.0.0.1:8000/subgraphs/name/<githubname>/<subgraphname>/graphql
or send queries to http://localhost:8000/subgraphs/name/<githubname>/<subgraphname>
for example with a gui like https://github.com/graphql/graphql-playground
for example with a gui like https://github.com/graphql/graphql-playground
or from a webapplication

example queries:
Expand Down
18 changes: 4 additions & 14 deletions packages/network-contracts/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## This package directory is for smart contracts development.

## The npm package published here should have version number 7.x.x, and it will export Typechain interfaces for Ethers v5. For later versions that use Ethers v6, look into the [npm-network-contracts](../npm-network-contracts) package.

# Streamr Network contracts

Solidity files plus Typescript interfaces for the Streamr Network smart contracts.
Expand Down Expand Up @@ -58,17 +62,3 @@ npm run localUpgradeImpl
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


## Publish package

- `npm version [major/minor]`
- `npm run clean`
- `npm run build`
- `npm publish --dry-run`
- `npm publish`
- `git add .`
- `git commit -m"release(network-contracts): vx.x.x"`
- `git tag network-contracts/vx.x.x`
- `git push`
- `git push --tags`
11 changes: 5 additions & 6 deletions packages/network-contracts/tsconfig.build.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Node 12",
"display": "Node 20",
"compilerOptions": {
"lib": ["es2019", "es2020.promise", "es2020.bigint", "es2020.string"],
"module": "CommonJS",
"target": "es2019",
"preserveSymlinks": true,
"strict": true,
"module": "commonjs",
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"declaration": true,
"outDir": "dist"
},
"include": ["./src"]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const { operatorABI } = require('../../../network-contracts/dist/src/exports')

const LARGE_NUMBER = "0x01104d6706312fa73d0e00"

const log = require("debug")("event-queue-test")

async function main() {
const provider = new providers.JsonRpcProvider("http://10.200.10.1:8547")

Expand All @@ -25,16 +27,16 @@ async function main() {

const operator = new Contract("0xb63c856cf861a88f4fa8587716fdc4e69cdf9ef1", operatorABI, provider)

console.log("Queue before: %o", await operator.undelegationQueue())
log("Queue before: %o", await operator.undelegationQueue())

// clog up the undelegation queue
await operator.connect(delegator).undelegate(LARGE_NUMBER)

console.log("Queue after tx 1: %o", await operator.undelegationQueue())
log("Queue after tx 1: %o", await operator.undelegationQueue())

// this "non-undelegation" won't be processed
await operator.connect(nonDelegator).undelegate(LARGE_NUMBER)

console.log("Queue after tx 2: %o", await operator.undelegationQueue())
log("Queue after tx 2: %o", await operator.undelegationQueue())
}
main().catch(console.error)
3 changes: 3 additions & 0 deletions packages/npm-network-contracts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
artifacts
contracts
typechain
76 changes: 76 additions & 0 deletions packages/npm-network-contracts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Streamr Network contracts

Solidity files plus Typescript interfaces for the Streamr Network smart contracts.

Exported interfaces are Ethers v5 format for versions 7.x.x and below, and Ethers v6 format for versions 8.0.0 and above.

## Contracts

Listed by file path:
* [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
* Spoiler: you '''sponsor''' streams by deploying a Sponsorship and sending DATA tokens to it, and operators '''stake''' into that Sponsorship to receive that DATA over time
* if operators stake but don't actually provide service, they get kicked out and their stake gets slashed
* additionally, 3rd parties can '''delegate''' their DATA tokens to the Operator contracts and receive a share of the operator's earnings. This way the operator gets more DATA to stake to more Sponsorships, in order to more fully utilize their network resources to earn more DATA.

## Usage from Typescript

Snippet from the [Operator client]():

```typescript
import { operatorABI, sponsorshipABI } from "@streamr/network-contracts"
import type { Operator, Sponsorship } from "@streamr/network-contracts"

...

const contract = new Contract(operatorContractAddress, operatorABI, this.provider) as unknown as Operator
contract.on("Staked", async (sponsorship: string) => {
log(`got Staked event ${sponsorship}`)
})
```

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.

An example of how to use it can be seen in network-contracts/packages/network-contracts/scripts/tatum/streamrEnvDeployer.ts, that can be run with the streamrEnvDeployer npm task


<h3>Proxy contracts</h3>

The proxy enables upgradability of contract code without the need to change all addresses in software that talks to the contract and without the need to migrate data that is inside the old contract, that is being upgraded. Also the upgrade can only be controlled by a ProxyAdmin contract. To find out more visit
https://docs.openzeppelin.com/contracts/3.x/api/proxy and
https://docs.openzeppelin.com/upgrades-plugins/1.x/proxies

To deploy the contract with a proxy into a locally running eth environment run
```
npm run localDeployProxy
```
then copy the Proxy and Proxyadmin addresses to the upgradeProxy.ts script and run it with
```
npm run localUpgradeImpl
````
# Changelog
StreamRegistryV5: added functions for arbitrary bytes user IDs (they can only publish and subscribe, not grant/edit/delete)
8.0.0 switch ethers v5 -> v6
7.0.8 export ENS type
4.2.0 export ERC677 ABI and type
## Publish package
- `npm version [major/minor]`
- `npm run build`
- `npm publish --dry-run`
- `npm publish`
- `git add package.json`
- `git commit -m"release(network-contracts): vx.x.x"`
- `git tag network-contracts/vx.x.x`
- `git push`
- `git push --tags`
13 changes: 13 additions & 0 deletions packages/npm-network-contracts/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash
set -ex

rm -rf contracts artifacts typechain
cp -r ../network-contracts/contracts .

hardhat compile

# copy the artifact file for deployed PublicResolver to avoid npm dependency (the file is NOT going to change or update!)
cp ./node_modules/@ensdomains/ens-contracts/deployments/archive/PublicResolver_mainnet_9412610.sol/PublicResolver_mainnet_9412610.json artifacts/PublicResolver_mainnet_9412610.json

rm -rf dist
tsc
48 changes: 48 additions & 0 deletions packages/npm-network-contracts/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { HardhatUserConfig } from "hardhat/config"
import "@nomicfoundation/hardhat-toolbox"
import "hardhat-dependency-compiler"

const config: HardhatUserConfig = {
solidity: {
compilers: [
{
version: "0.8.13",
settings: {
optimizer: {
enabled: true,
runs: 100,
},
},
},
{
version: "0.8.9",
settings: {
optimizer: {
enabled: true,
runs: 100,
},
},
},
],
},
typechain: {
outDir: "./typechain",
target: "ethers-v6",
},
dependencyCompiler: {
paths: [
"@openzeppelin/contracts/metatx/MinimalForwarder.sol",
"@opengsn/contracts/src/forwarder/Forwarder.sol",
"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol",
"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol",
"@openzeppelin/contracts-upgradeable/metatx/MinimalForwarderUpgradeable.sol",
"@openzeppelin/contracts/interfaces/IERC1271.sol",
"@ensdomains/ens-contracts/contracts/registry/ENS.sol",
"@ensdomains/ens-contracts/contracts/registry/FIFSRegistrar.sol",
"@ensdomains/ens-contracts/contracts/resolvers/Resolver.sol",
"@ensdomains/ens-contracts/contracts/registry/ENSRegistry.sol", // exported in exports.ts
],
},
}

export default config
28 changes: 28 additions & 0 deletions packages/npm-network-contracts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "@streamr/network-contracts",
"version": "8.2.0",
"description": "Smart contracts for Streamr Network",
"author": "Streamr Network AG <[email protected]>",
"license": "STREAMR NETWORK OPEN SOURCE LICENSE",
"private": false,
"publishConfig": {
"access": "public"
},
"files": [
"dist",
"contracts"
],
"main": "./dist/src/exports.js",
"types": "./dist/src/exports.d.ts",
"scripts": {
"build": "./build.sh"
},
"devDependencies": {
"@ensdomains/ens-contracts": "1.1.4",
"@nomicfoundation/hardhat-toolbox": "5.0.0",
"@opengsn/provider": "2.2.6",
"@openzeppelin/contracts-upgradeable-4.4.2": "npm:@openzeppelin/[email protected]",
"hardhat": "2.22.2",
"hardhat-dependency-compiler": "1.1.4"
}
}
95 changes: 95 additions & 0 deletions packages/npm-network-contracts/src/exports.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
export { abi as operatorABI, bytecode as operatorBytecode } from "../artifacts/contracts/OperatorTokenomics/Operator.sol/Operator.json"
export type { Operator } from "../typechain/contracts/OperatorTokenomics/Operator"

export { abi as sponsorshipABI, bytecode as sponsorshipBytecode } from "../artifacts/contracts/OperatorTokenomics/Sponsorship.sol/Sponsorship.json"
export type { Sponsorship } from "../typechain/contracts/OperatorTokenomics/Sponsorship"

export { abi as operatorFactoryABI, bytecode as operatorFactoryBytecode }
from "../artifacts/contracts/OperatorTokenomics/OperatorFactory.sol/OperatorFactory.json"
export type { OperatorFactory } from "../typechain/contracts/OperatorTokenomics/OperatorFactory"

export { abi as sponsorshipFactoryABI, bytecode as sponsorshipFactoryBytecode }
from "../artifacts/contracts/OperatorTokenomics/SponsorshipFactory.sol/SponsorshipFactory.json"
export type { SponsorshipFactory } from "../typechain/contracts/OperatorTokenomics/SponsorshipFactory"

export { abi as streamrConfigABI, bytecode as streamrConfigBytecode }
from "../artifacts/contracts/OperatorTokenomics/StreamrConfigV1_1.sol/StreamrConfigV1_1.json"
export type { StreamrConfigV1_1 as StreamrConfig } from "../typechain/contracts/OperatorTokenomics/StreamrConfigV1_1"

export { abi as streamRegistryABI, bytecode as streamRegistryBytecode }
from "../artifacts/contracts/StreamRegistry/StreamRegistryV5.sol/StreamRegistryV5.json"
export type { StreamRegistryV5 as StreamRegistry } from "../typechain/contracts/StreamRegistry/StreamRegistryV5"

export { abi as streamStorageRegistryABI, bytecode as streamStorageRegistryBytecode }
from "../artifacts/contracts/StreamStorageRegistry/StreamStorageRegistryV2.sol/StreamStorageRegistryV2.json"
export type { StreamStorageRegistryV2 as StreamStorageRegistry } from "../typechain/contracts/StreamStorageRegistry/StreamStorageRegistryV2"

export { abi as ENSCacheV2ABI, bytecode as ENSCacheV2Bytecode }
from "../artifacts/contracts/chainlinkClient/ENSCacheV2Streamr.sol/ENSCacheV2Streamr.json"
export type { ENSCacheV2Streamr as ENSCacheV2 } from "../typechain/contracts/chainlinkClient/ENSCacheV2Streamr"

export { abi as nodeRegistryABI, bytecode as nodeRegistryBytecode }
from "../artifacts/contracts/NodeRegistry/NodeRegistry.sol/NodeRegistry.json"
export type { NodeRegistry } from "../typechain/contracts/NodeRegistry/NodeRegistry"

export { abi as tokenABI, bytecode as tokenBytecode }
from "../artifacts/contracts/OperatorTokenomics/testcontracts/TestToken.sol/TestToken.json"
export type { TestToken } from "../typechain/contracts/OperatorTokenomics/testcontracts/TestToken"

export { abi as maxOperatorsJoinPolicyABI, bytecode as maxOperatorsJoinPolicyBytecode }
from "../artifacts/contracts/OperatorTokenomics/SponsorshipPolicies/MaxOperatorsJoinPolicy.sol/MaxOperatorsJoinPolicy.json"
export type { MaxOperatorsJoinPolicy } from "../typechain/contracts/OperatorTokenomics/SponsorshipPolicies/MaxOperatorsJoinPolicy"

export { abi as stakeWeightedAllocationPolicyABI, bytecode as stakeWeightedAllocationPolicyBytecode }
from "../artifacts/contracts/OperatorTokenomics/SponsorshipPolicies/StakeWeightedAllocationPolicy.sol/StakeWeightedAllocationPolicy.json"
export type { StakeWeightedAllocationPolicy } from "../typechain/contracts/OperatorTokenomics/SponsorshipPolicies/StakeWeightedAllocationPolicy"

export { abi as defaultLeavePolicyABI, bytecode as defaultLeavePolicyBytecode }
from "../artifacts/contracts/OperatorTokenomics/SponsorshipPolicies/DefaultLeavePolicy.sol/DefaultLeavePolicy.json"
export type { DefaultLeavePolicy } from "../typechain/contracts/OperatorTokenomics/SponsorshipPolicies/DefaultLeavePolicy"

export { abi as voteKickPolicyABI, bytecode as voteKickPolicyBytecode }
from "../artifacts/contracts/OperatorTokenomics/SponsorshipPolicies/VoteKickPolicy.sol/VoteKickPolicy.json"
export type { VoteKickPolicy } from "../typechain/contracts/OperatorTokenomics/SponsorshipPolicies/VoteKickPolicy"

export { abi as defaultDelegationPolicyABI, bytecode as defaultDelegationPolicyBytecode }
from "../artifacts/contracts/OperatorTokenomics/OperatorPolicies/DefaultDelegationPolicy.sol/DefaultDelegationPolicy.json"
export type { DefaultDelegationPolicy } from "../typechain/contracts/OperatorTokenomics/OperatorPolicies/DefaultDelegationPolicy"

export { abi as defaultExchangeRatePolicyABI, bytecode as defaultExchangeRatePolicyBytecode }
from "../artifacts/contracts/OperatorTokenomics/OperatorPolicies/DefaultExchangeRatePolicy.sol/DefaultExchangeRatePolicy.json"
export type { DefaultExchangeRatePolicy } from "../typechain/contracts/OperatorTokenomics/OperatorPolicies/DefaultExchangeRatePolicy"

export { abi as defaultUndelegationPolicyABI, bytecode as defaultUndelegationPolicyBytecode }
from "../artifacts/contracts/OperatorTokenomics/OperatorPolicies/DefaultUndelegationPolicy.sol/DefaultUndelegationPolicy.json"
export type { DefaultUndelegationPolicy } from "../typechain/contracts/OperatorTokenomics/OperatorPolicies/DefaultUndelegationPolicy"

export { abi as operatorContractOnlyJoinPolicyABI, bytecode as operatorContractOnlyJoinPolicyBytecode }
from "../artifacts/contracts/OperatorTokenomics/SponsorshipPolicies/OperatorContractOnlyJoinPolicy.sol/OperatorContractOnlyJoinPolicy.json"
export type { OperatorContractOnlyJoinPolicy }
from "../typechain/contracts/OperatorTokenomics/SponsorshipPolicies/OperatorContractOnlyJoinPolicy.sol/OperatorContractOnlyJoinPolicy"

export { abi as ERC677ABI } from "../artifacts/contracts/OperatorTokenomics/IERC677.sol/IERC677.json"
export type { IERC677 as ERC677 } from "../typechain/contracts/OperatorTokenomics/IERC677"

export { abi as ensRegistryABI, bytecode as ensRegistryBytecode }
from "../artifacts/@ensdomains/ens-contracts/contracts/registry/ENSRegistry.sol/ENSRegistry.json"
export type { ENS } from "../typechain/@ensdomains/ens-contracts/contracts/registry/ENS"

export { abi as fifsRegistrarABI, bytecode as fifsRegistrarBytecode }
from "../artifacts/@ensdomains/ens-contracts/contracts/registry/FIFSRegistrar.sol/FIFSRegistrar.json"
export type { FIFSRegistrar } from "../typechain/@ensdomains/ens-contracts/contracts/registry/FIFSRegistrar"

export { abi as publicResolverABI, bytecode as publicResolverBytecode }
from "../artifacts/PublicResolver_mainnet_9412610.json"
export type { Resolver } from "../typechain/@ensdomains/ens-contracts/contracts/resolvers/Resolver"

export { abi as nodeModuleABI, bytecode as nodeModuleBytecode }
from "../artifacts/contracts/OperatorTokenomics/OperatorPolicies/NodeModule.sol/NodeModule.json"
export type { NodeModule } from "../typechain/contracts/OperatorTokenomics/OperatorPolicies/NodeModule"
export { abi as queueModuleABI, bytecode as queueModuleBytecode }
from "../artifacts/contracts/OperatorTokenomics/OperatorPolicies/QueueModule.sol/QueueModule.json"
export type { QueueModule } from "../typechain/contracts/OperatorTokenomics/OperatorPolicies/QueueModule"
export { abi as stakeModuleABI, bytecode as stakeModuleBytecode }
from "../artifacts/contracts/OperatorTokenomics/OperatorPolicies/StakeModule.sol/StakeModule.json"
export type { StakeModule } from "../typechain/contracts/OperatorTokenomics/OperatorPolicies/StakeModule"
17 changes: 17 additions & 0 deletions packages/npm-network-contracts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Node 20",
"compilerOptions": {
"lib": ["es2019", "es2020.promise", "es2020.bigint", "es2020.string"],
"target": "es2019",
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"declaration": true,
"outDir": "dist"
},
"include": ["./src"]
}

0 comments on commit d0eb2c0

Please sign in to comment.