diff --git a/governance/scripts/deployments/index.js b/governance/scripts/deployments/index.js index 499bf4b8950..72244c8c24d 100644 --- a/governance/scripts/deployments/index.js +++ b/governance/scripts/deployments/index.js @@ -2,7 +2,11 @@ const { ethers, run, upgrades, network } = require('hardhat') const { networks } = require('@unlock-protocol/networks') const createLock = require('../lock/create') -const { getUnlock, ADDRESS_ZERO } = require('@unlock-protocol/hardhat-helpers') +const { + getUnlock, + ADDRESS_ZERO, + getNetwork, +} = require('@unlock-protocol/hardhat-helpers') const log = (...message) => { // eslint-disable-next-line no-console @@ -26,8 +30,7 @@ async function main({ const [deployer, minter] = await ethers.getSigners() // fetch chain info - const { chainId } = await ethers.provider.getNetwork() - const networkName = networks[chainId].name + const { id: chainId, name: networkName, multisig } = await getNetwork() const isLocalNet = networkName === 'localhost' log( `Deploying contracts on ${networkName} with the account: ${deployer.address}` @@ -107,7 +110,6 @@ async function main({ } // Transfer ownership of Unlock + Proxy admin - const multisig = networks[chainId.toString()].multisig if (!owner && multisig) { owner = multisig if (owner) { diff --git a/governance/tasks/deploy.js b/governance/tasks/deploy.js index 1c9aa338896..c3cc48b96e2 100644 --- a/governance/tasks/deploy.js +++ b/governance/tasks/deploy.js @@ -34,30 +34,21 @@ task('deploy', 'Deploy the entire Unlock protocol') ) .addFlag('setTemplate', 'set the PublicLock instance in Unlock') .setAction( - async ( - { - unlockAddress, - unlockVersion, - publicLockVersion, - udtAddress, - publicLockAddress, - wethAddress, - oracleAddress, - premintAmount, - liquidity, - setTemplate, - estimatedGasForPurchase, - locksmithURI, - owner, - }, - { ethers } - ) => { - const { chainId } = await ethers.provider.getNetwork() - const networkName = networks[chainId].name - - // eslint-disable-next-line no-console - console.log(`Starting deployments on ${networkName}...`) - + async ({ + unlockAddress, + unlockVersion, + publicLockVersion, + udtAddress, + publicLockAddress, + wethAddress, + oracleAddress, + premintAmount, + liquidity, + setTemplate, + estimatedGasForPurchase, + locksmithURI, + owner, + }) => { // eslint-disable-next-line global-require const mainDeployer = require('../scripts/deployments') const { diff --git a/locksmith/__tests__/fulfillment/dispatcher.test.ts b/locksmith/__tests__/fulfillment/dispatcher.test.ts index 5cfc9ed8b16..00b6793b736 100644 --- a/locksmith/__tests__/fulfillment/dispatcher.test.ts +++ b/locksmith/__tests__/fulfillment/dispatcher.test.ts @@ -62,6 +62,15 @@ vi.mock('@unlock-protocol/unlock-js', () => ({ }, })) +vi.mock('@unlock-protocol/networks', () => ({ + default: { + 31337: { + provider: 'http://127.0.0.1:8545', + publicProvider: 'http://127.0.0.1:8545', + }, + }, +})) + vi.mock('../../src/utils/gasSettings', () => ({ getGasSettings: vi.fn(() => { return { diff --git a/packages/hardhat-helpers/src/networks.js b/packages/hardhat-helpers/src/networks.js index 1b6c587f628..601d510db8d 100644 --- a/packages/hardhat-helpers/src/networks.js +++ b/packages/hardhat-helpers/src/networks.js @@ -50,7 +50,7 @@ const hardhatNetworks = { } Object.keys(networks).forEach((key) => { - if (['default', 'networks', 'localhost'].indexOf(key) === -1) { + if (['default', 'networks'].indexOf(key) === -1) { hardhatNetworks[key] = { chainId: networks[key].id, name: networks[key].name, diff --git a/packages/hardhat-helpers/src/unlock.js b/packages/hardhat-helpers/src/unlock.js index d9f014bbfb8..7bdd11ba55b 100644 --- a/packages/hardhat-helpers/src/unlock.js +++ b/packages/hardhat-helpers/src/unlock.js @@ -30,7 +30,7 @@ export const getNetwork = async (chainId) => { if (!chainId) { ;({ chainId } = await ethers.provider.getNetwork()) } - return networks[chainId] + return networks[chainId] || { name: 'localhost', id: chainId } } export default { diff --git a/packages/hardhat-plugin/test/fixture-projects/hardhat-project/hardhat.config.ts b/packages/hardhat-plugin/test/fixture-projects/hardhat-project/hardhat.config.ts index 7657c57730b..703918d9c94 100644 --- a/packages/hardhat-plugin/test/fixture-projects/hardhat-project/hardhat.config.ts +++ b/packages/hardhat-plugin/test/fixture-projects/hardhat-project/hardhat.config.ts @@ -23,6 +23,9 @@ const config: HardhatUserConfig = { endpoint: 'here goes a subgraph URI', }, }, + 1: { + unlockAddress: 'newAddress', + }, 12345: { name: 'New Network', id: 12345, diff --git a/packages/hardhat-plugin/test/index.test.ts b/packages/hardhat-plugin/test/index.test.ts index 4bb72e7b0e8..aaa8e9ef1a4 100644 --- a/packages/hardhat-plugin/test/index.test.ts +++ b/packages/hardhat-plugin/test/index.test.ts @@ -34,13 +34,18 @@ describe('Unlock Hardhat plugin', function () { assert.instanceOf(this.hre.unlock, Object) }) - it('should store networks info', function () { + it('should store and extend existing networks info', function () { + assert.isTrue(Object.keys(this.hre.unlock.networks).includes('1')) + assert.equal(this.hre.unlock.networks['1'].name, networks['1'].name) + assert.equal(this.hre.unlock.networks['1'].id, networks['1'].id) + assert.equal(this.hre.unlock.networks['1'].unlockAddress, 'newAddress') + }) + it('should store additional networks info', function () { assert.isTrue(Object.keys(this.hre.unlock.networks).includes('31337')) assert.equal( this.hre.unlock.networks['31337'].name, 'Custom Localhost Name' ) - assert.equal(this.hre.unlock.networks['31337'].id, networks['31337'].id) assert.equal( this.hre.unlock.networks['31337'].subgraph?.endpoint, 'here goes a subgraph URI' @@ -213,7 +218,7 @@ describe('HardhatConfig unlock extension', function () { assert.isTrue(Object.keys(this.hre.config).includes('unlock')) assert.deepEqual( Object.keys(this.hre.config.unlock).sort(), - [...Object.keys(networks), '12345'].sort() + [...Object.keys(networks), '12345', '31337'].sort() ) }) diff --git a/packages/networks/.gitignore b/packages/networks/.gitignore index 2cf1da454af..b12273ebe11 100644 --- a/packages/networks/.gitignore +++ b/packages/networks/.gitignore @@ -1,2 +1,3 @@ dist -build \ No newline at end of file +build +src/networks/localhost.ts \ No newline at end of file diff --git a/packages/networks/README.md b/packages/networks/README.md index 4c714459082..5a9b89fe9df 100644 --- a/packages/networks/README.md +++ b/packages/networks/README.md @@ -19,6 +19,39 @@ console.log(networks[1].name) // mainnet yarn start ``` +## Localhost + +You can create a `localhost` network file with the following command: + +```sh +# create file +yarn create-localhost + +# export file by appending to network index +echo "export * from './localhost'" >> src/networks/index.ts + +# rebuild +yarn build +``` + +#### Read Unlock Address from a file + +Optionally, you can parse the Unlock address from a subgraph manifest file formatted as follow + +```json +{ + "localhost": { + "Unlock": { "address": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" } + } +} +``` + +with the following command + +```sh +yarn workspace @unlock-protocol/networks unlock-address .json +``` + ## Scripts - Check that networks are configured correctly: `yarn run check`. Some networks might be missing some properties. diff --git a/packages/networks/bin/localhost.js b/packages/networks/bin/localhost.js new file mode 100644 index 00000000000..31678b11ca6 --- /dev/null +++ b/packages/networks/bin/localhost.js @@ -0,0 +1,73 @@ +import fs from 'fs-extra' +import path from 'path' + +// We use Partial for localhost as we don't have all the information +const defaultLocalhost = { + chain: 'localhost', + description: 'Localhost network.', + featured: false, + fullySubsidizedGas: true, + id: 31337, + isTestNetwork: true, + name: 'Localhost', + nativeCurrency: { + coingecko: 'ethereum', + decimals: 18, + name: 'ETH', + symbol: 'ETH', + }, + provider: 'http://127.0.0.1:8545', + publicLockVersionToDeploy: 13, + publicProvider: 'http://127.0.0.1:8545', + subgraph: { + endpoint: '', + }, +} + +const generateLocalhostNetworkFile = ({ + unlockAddress, + subgraphEnpoint = 'http://localhost:8000/subgraphs/name/testgraph', +}) => { + const localhost = { + ...defaultLocalhost, + subgraph: { + endpoint: subgraphEnpoint, + }, + unlockAddress, + } + + // log for debug purposes on CI + console.log(localhost) + + // output to js file + const parsed = `import { NetworkConfig } from '@unlock-protocol/types' + +// We use Partial for localhost as we don't have all the information +export const localhost: Partial = ${JSON.stringify(localhost)} +export default localhost + ` + return parsed +} + +const run = async () => { + const [unlockAddress, subgraphEnpoint] = process.argv.slice(2) + console.log(`Creating localhost file for unlockAddress ${unlockAddress}`) + + if (!unlockAddress) { + throw new Error('Missing unlockAddress arg') + } + + const fileContent = generateLocalhostNetworkFile({ + subgraphEnpoint, + unlockAddress, + }) + + const filePath = path.resolve('./src/networks/localhost.ts') + + await fs.writeFile(filePath, fileContent) +} +run() + .then(() => console.log('done')) + .catch((err) => { + throw err + }) diff --git a/packages/networks/bin/readSubgraphInfo.js b/packages/networks/bin/readSubgraphInfo.js new file mode 100644 index 00000000000..85f0ef5476a --- /dev/null +++ b/packages/networks/bin/readSubgraphInfo.js @@ -0,0 +1,19 @@ +import fs from 'fs-extra' + +// this is used to read a network +const run = async () => { + const [networkInfoPath] = process.argv.slice(2) + const networkInfo = await fs.readJSON(networkInfoPath) + const { + localhost: { + Unlock: { address: unlockAddress }, + }, + } = networkInfo + return unlockAddress +} + +run() + .then((unlockAddress) => console.log(unlockAddress)) + .catch((err) => { + throw err + }) diff --git a/packages/networks/package.json b/packages/networks/package.json index 887df4a7616..8f7040d34df 100644 --- a/packages/networks/package.json +++ b/packages/networks/package.json @@ -18,6 +18,8 @@ "build": "tsup src/index.ts --dts --format esm,cjs", "check-tokens": "tsx ./bin/check-tokens", "clean": "rm -rf ./dist", + "create-localhost": "tsx ./bin/localhost", + "unlock-address": "tsx ./bin/readSubgraphInfo", "check": "tsx ./bin/keys", "prepublish": "yarn build", "doc": "node ./bin/doc.js", @@ -32,6 +34,7 @@ "@unlock-protocol/tsconfig": "workspace:^", "@unlock-protocol/types": "workspace:^", "eslint": "8.54.0", + "fs-extra": "11.2.0", "tsup": "8.0.2", "typescript": "5.3.3" }, diff --git a/packages/networks/src/networks/index.ts b/packages/networks/src/networks/index.ts index 51f7e466866..3208f9d0dd4 100644 --- a/packages/networks/src/networks/index.ts +++ b/packages/networks/src/networks/index.ts @@ -1,4 +1,3 @@ -export * from './localhost' export * from './mainnet' export * from './gnosis' export * from './polygon' diff --git a/packages/networks/src/networks/localhost.ts b/packages/networks/src/networks/localhost.ts deleted file mode 100644 index 242302b7b3f..00000000000 --- a/packages/networks/src/networks/localhost.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { NetworkConfig } from '@unlock-protocol/types' - -// We use Partial for localhost as we don't have all the information -export const localhost: Partial = { - chain: 'localhost', - description: 'Localhost network.', - featured: false, - fullySubsidizedGas: true, - id: 31337, - isTestNetwork: true, - name: 'localhost', - nativeCurrency: { - coingecko: 'ethereum', - decimals: 18, - name: 'ETH', - symbol: 'ETH', - }, - provider: 'http://127.0.0.1:8545', - publicLockVersionToDeploy: 13, - publicProvider: 'http://127.0.0.1:8545', - subgraph: { - endpoint: 'http://localhost:8000/subgraphs/name/unlock-protocol/unlock', - }, -} diff --git a/scripts/integration-tests.sh b/scripts/integration-tests.sh index 5235697af28..5cd1059c48e 100755 --- a/scripts/integration-tests.sh +++ b/scripts/integration-tests.sh @@ -3,11 +3,21 @@ set -e # First this script will deploy REPO_ROOT=`dirname "$0"`/.. -INTEGRATION_TESTS_FOLDER=$REPO_ROOT/tests -EXTRA_ARGS=$* + +# fetch compose config paths +BASE_DOCKER_FOLDER=$REPO_ROOT/docker +BASE_DOCKER_COMPOSE=$BASE_DOCKER_FOLDER/docker-compose.yml +DOCKER_COMPOSE_FILE=$BASE_DOCKER_FOLDER/docker-compose.integration.yml +COMPOSE_CONFIG="-f $BASE_DOCKER_COMPOSE -f $DOCKER_COMPOSE_FILE" # run Unlock Protocol stack sh -c "$REPO_ROOT/scripts/run-stack-dockerized.sh" +# Setting the right env var +export UNLOCK_ENV=test + # run the actual tests -sh $INTEGRATION_TESTS_FOLDER/bin/tests.sh \ No newline at end of file +echo "Running integration tests \n" +COMMAND="yarn workspace tests ci --network docker" +docker-compose $COMPOSE_CONFIG build integration-tests +docker-compose $COMPOSE_CONFIG run -e UNLOCK_ENV=test -e CI=true $EXTRA_ARGS integration-tests bash -c "$COMMAND" diff --git a/tests/.eslintrc.js b/tests/.eslintrc.js index 429743d1f37..6e2d28788ce 100644 --- a/tests/.eslintrc.js +++ b/tests/.eslintrc.js @@ -6,7 +6,6 @@ const rulesToIgnore = [ module.exports = { extends: ['@unlock-protocol/eslint-config'], - plugins: ['mocha'], globals: { it: true, artifacts: true, diff --git a/tests/bin/prepare.sh b/tests/bin/prepare.sh new file mode 100644 index 00000000000..caf7982a48d --- /dev/null +++ b/tests/bin/prepare.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +set -e + +FOLDER_ROOT="$(pwd)/.." + +# parse networks file when running on CI +INFO_FILE_PATH="$FOLDER_ROOT/docker/development/eth-node/networks.json" + +# use docker mounted file on CI +if [ ! -z "${CI}" ]; then + INFO_FILE_PATH='/home/unlock/networks.json' +fi + +# make sure file exists +if [ -f "$INFO_FILE_PATH" ]; then + echo "Using subgraph file at: $INFO_FILE_PATH" +else + echo "File does not exist: $INFO_FILE_PATH" + exit 1 +fi + +# parse Unlock address from network info file +unlock_adress=$(yarn workspace @unlock-protocol/networks unlock-address "$INFO_FILE_PATH") +if [ ! -n $unlock_adress ]; then + echo "Missing Unlock Address" + exit 1 +fi + +# create localhost file in networks package +yarn workspace @unlock-protocol/networks create-localhost "$unlock_adress" http://graph-node:8000/subgraphs/name/testgraph + +# append to networks index +echo "export * from './localhost'" >> "$FOLDER_ROOT/packages/networks/src/networks/index.ts" + +# rebuild networks +yarn workspace @unlock-protocol/networks build + +# rebuild unlock-js to get latest networks package +yarn workspace @unlock-protocol/unlock-js build + diff --git a/tests/bin/tests.sh b/tests/bin/tests.sh deleted file mode 100644 index 5b12e86ce76..00000000000 --- a/tests/bin/tests.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash -REPO_ROOT=`dirname "$0"`/../.. - -# fetch compose config paths -BASE_DOCKER_FOLDER=$REPO_ROOT/docker -BASE_DOCKER_COMPOSE=$BASE_DOCKER_FOLDER/docker-compose.yml -DOCKER_COMPOSE_FILE=$BASE_DOCKER_FOLDER/docker-compose.integration.yml -COMPOSE_CONFIG="-f $BASE_DOCKER_COMPOSE -f $DOCKER_COMPOSE_FILE" - -# Setting the right env var -export UNLOCK_ENV=test - -echo "Running integration tests \n" -COMMAND="yarn workspace tests test --network docker" -docker-compose $COMPOSE_CONFIG build integration-tests -docker-compose $COMPOSE_CONFIG run -e UNLOCK_ENV=test -e CI=true $EXTRA_ARGS integration-tests bash -c "$COMMAND" diff --git a/tests/hardhat.config.ts b/tests/hardhat.config.ts index b9d789ab117..10278cc3a34 100644 --- a/tests/hardhat.config.ts +++ b/tests/hardhat.config.ts @@ -2,18 +2,7 @@ import { HardhatUserConfig } from 'hardhat/config' import '@nomicfoundation/hardhat-toolbox' import '@unlock-protocol/hardhat-plugin' -import path from 'path' -import fs from 'fs-extra' - -const SUBGRAPH_NETWORKS_CONFIG_PATH = process.env.CI - ? '/home/unlock/networks.json' - : path.join(__dirname, '..', './subgraph/networks.json') - -const { localhost: subgraphConfig } = fs.readJSONSync( - SUBGRAPH_NETWORKS_CONFIG_PATH -) - -const unlockAddress = subgraphConfig.Unlock.address +import { localhost } from '@unlock-protocol/networks' const config: HardhatUserConfig = { solidity: '0.8.9', @@ -23,12 +12,9 @@ const config: HardhatUserConfig = { }, }, unlock: { - 31337: { - unlockAddress, - }, - docker: { - unlockAddress, - }, + localhost, + 31337: localhost, + docker: localhost, }, mocha: { timeout: 2000000, diff --git a/tests/package.json b/tests/package.json index 6298724a5a8..50b55be9aaa 100644 --- a/tests/package.json +++ b/tests/package.json @@ -4,9 +4,9 @@ "scripts": { "lint:fix": "yarn lint --fix", "lint": "eslint --resolve-plugins-relative-to ../eslint-config --ext .tsx,.ts,.js scripts/ test/", - "test": "yarn test:subgraph", - "test:subgraph": "hardhat test", - "ci": "hardhat test --network 0.0.0.0" + "test": "hardhat test", + "test:prepare": "sh bin/prepare.sh", + "ci": "yarn test:prepare && yarn test" }, "dependencies": { "@apollo/client": "3.6.9", @@ -27,6 +27,7 @@ "@types/node": "12.0.0", "@unlock-protocol/eslint-config": "workspace:^", "@unlock-protocol/hardhat-plugin": "workspace:^", + "@unlock-protocol/networks": "workspace:^", "apollo-link-http": "1.5.17", "chai": "4.2.0", "eslint": "8.46.0", diff --git a/tests/test/helpers/subgraph.ts b/tests/test/helpers/subgraph.ts index adf115b80e2..29e79b35620 100644 --- a/tests/test/helpers/subgraph.ts +++ b/tests/test/helpers/subgraph.ts @@ -9,11 +9,11 @@ import { HttpLink } from 'apollo-link-http' import { genKeyId } from './keys' import type { BigNumber } from 'ethers' -const subgraphURI = `http://${ - process.env.CI ? 'graph-node' : '127.0.0.1' -}:8000/subgraphs/name/testgraph` +import { localhost } from '@unlock-protocol/networks' -console.log(subgraphURI) +const { + subgraph: { endpoint: subgraphURI }, +} = localhost const link = new HttpLink({ uri: subgraphURI, diff --git a/yarn.lock b/yarn.lock index 607a57bf7b6..0ef599be442 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20065,6 +20065,7 @@ __metadata: eslint: "npm:8.54.0" eslint-plugin-sort-keys-fix: "npm:1.1.2" ethers: "npm:6.10.0" + fs-extra: "npm:11.2.0" tsup: "npm:8.0.2" tsx: "npm:4.7.1" typescript: "npm:5.3.3"