diff --git a/.dockerignore b/.dockerignore index ada5c3325a..1087f90813 100644 --- a/.dockerignore +++ b/.dockerignore @@ -23,3 +23,6 @@ scripts .dockerignore **/Dockerfile* **/docker-compose* + +# Local .env files +**/.env.local diff --git a/.gitignore b/.gitignore index ff75977ec2..70399e1fe6 100644 --- a/.gitignore +++ b/.gitignore @@ -47,9 +47,5 @@ dist *.tsbuildinfo hardhat-dependency-compiler -#cache -cache - -#docker databases -docker-db -graph-node-db \ No newline at end of file +# cache +cache \ No newline at end of file diff --git a/docker-setup/Makefile b/docker-setup/Makefile index 28786f2966..365895d059 100644 --- a/docker-setup/Makefile +++ b/docker-setup/Makefile @@ -9,22 +9,22 @@ check-env-file: cp ./.env.compose ./.env.compose.local ; \ fi -infra-up: - docker-compose --env-file .env.compose.local up -d postgres redis minio minio-client +infra-up: check-env-file + @docker compose --env-file .env.compose.local up -d postgres redis minio minio-client infra-stop: - docker-compose --env-file .env.compose.local stop postgres redis minio minio-client + @docker compose --env-file .env.compose.local stop postgres redis minio minio-client -build-services: - docker-compose --env-file .env.compose.local --parallel $(DOCKER_PARALLEL) up --no-start +build-services: check-env-file + @docker compose --env-file .env.compose.local --parallel $(DOCKER_PARALLEL) up --no-start -services-up: +services-up: check-env-file @service_names="$(wordlist 2, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS))"; \ - docker-compose --env-file .env.compose.local --parallel $(DOCKER_PARALLEL) up -d $$service_names + docker compose --env-file .env.compose.local --parallel $(DOCKER_PARALLEL) up -d $$service_names services-stop: @service_names="$(wordlist 2, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS))"; \ - docker-compose --env-file .env.compose.local stop $$service_names + docker compose --env-file .env.compose.local stop $$service_names # catch-all and noop; to avoid warnings when using MAKECMDGOALS %: diff --git a/docker-setup/Makefile.dev b/docker-setup/Makefile.dev new file mode 100644 index 0000000000..567f633f0c --- /dev/null +++ b/docker-setup/Makefile.dev @@ -0,0 +1,23 @@ +.PHONY: web3-up web3-down \ + infra-up infra-stop infra-down + +web3-up: + @docker compose -f docker-compose.dev.yml up -d blockchain-node ipfs graph-node-db graph-node + +web3-down: +# also remove volumes to get the clean start after + @docker compose -f docker-compose.dev.yml down -v blockchain-node ipfs graph-node-db graph-node + +infra-up: + @docker compose -f docker-compose.dev.yml up -d postgres minio minio-client + +infra-stop: + @docker compose -f docker-compose.dev.yml stop postgres minio minio-client + +infra-down: +# also remove volumes to get the clean start after + @docker compose -f docker-compose.dev.yml down -v postgres minio minio-client + +# catch-all and noop; to avoid warnings when using MAKECMDGOALS +%: + @: diff --git a/docker-setup/docker-compose.dev.yml b/docker-setup/docker-compose.dev.yml new file mode 100644 index 0000000000..b329016fb9 --- /dev/null +++ b/docker-setup/docker-compose.dev.yml @@ -0,0 +1,229 @@ +name: human-protocol-local-dev + +x-service-default-config: + restart: &default-restart unless-stopped + logging: &default-logging + options: + max-size: 10m + max-file: 3 + +x-hardcoded-vars: + graph_db_user: &graph_db_user graph-node + graph_db_passwrod: &graph_db_passwrod let-me-in + graph_db_name: &graph_db_name graph-node + +x-general-env-variables: + postgres_user: &postgres_user ${POSTGRES_USER:-default} + postgres_password: &postgres_password ${POSTGRES_PASSWORD:-qwerty} + # MINIO VARS + minio_port: &minio_port ${MINIO_PORT:-9000} + minio_console_port: &minio_console_port ${MINIO_CONSOLE_PORT:-9001} + minio_root_user: &minio_root_user ${MINIO_ROOT_USER:-minioadmin} + minio_root_password: &minio_root_password ${MINIO_ROOT_PASSWORD:-minioadmin} + minio_services_access_key: &minio_services_access_key ${MINIO_SERVICES_ACCESS_KEY:-human-oracle} + minio_services_secret_key: &minio_services_secret_key ${MINIO_SERVICES_SECRET_KEY:-human-oracle-s3-secret} + # BUCKET NAMES + bucket_name_manifests: &bucket_name_manifests ${BUCKET_NAME_MANIFESTS:-manifests} + bucket_name_datasets: &bucket_name_datasets ${BUCKET_NAME_DATASETS:-datasets} + bucket_name_rep_o: &bucket_name_rep_o ${BUCKET_NAME_REPUTATION_ORACLE:-reputation-oracle} + bucket_name_fortune: &bucket_name_fortune ${BUCKEN_NAME_FORTUNE:-fortune} + +services: + blockchain-node: + container_name: hp-dev-blockchain-node + image: human-protocol/hardhat-blockchain-node + pull_policy: build + restart: *default-restart + logging: + <<: *default-logging + build: + context: ../ + dockerfile: packages/core/Dockerfile.local + healthcheck: + test: yarn local:readiness + interval: 15s + timeout: 30s + retries: 0 + networks: + - human_protocol_web3 + ports: + - name: node-port + target: 8545 + published: ${BLOCKCHAIN_NODE_PORT:-8545} + + ipfs: + container_name: hp-dev-ipfs + image: ipfs/kubo:v0.14.0 + restart: *default-restart + logging: + <<: *default-logging + healthcheck: + test: ["CMD-SHELL", "ipfs id > /dev/null"] + interval: 10s + timeout: 5s + retries: 3 + networks: + - human_protocol_web3 + ports: + - name: ipfs-port + target: 5001 + published: ${IPFS_PORT:-5010} + volumes: + - ipfs-data:/data/ipfs:Z + + graph-node-db: + container_name: hp-dev-graph-node-db + image: postgres:latest + restart: *default-restart + logging: + <<: *default-logging + networks: + - human_protocol_web3 + command: + [ + "postgres", + "-cshared_preload_libraries=pg_stat_statements", + "-cmax_connections=200" + ] + healthcheck: + test: ["CMD", "pg_isready"] + interval: 10s + timeout: 5s + retries: 5 + volumes: + - graph-node-db-data:/var/lib/postgresql/data:Z + environment: + POSTGRES_USER: *graph_db_user + POSTGRES_PASSWORD: *graph_db_passwrod + POSTGRES_DB: *graph_db_name + POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C" + + graph-node: + container_name: hp-dev-graph-node + # In case of issues on Mac M1 rebuild the image for it locally + # https://github.com/graphprotocol/graph-node/blob/master/docker/README.md#running-graph-node-on-an-macbook-m1 + image: graphprotocol/graph-node + restart: *default-restart + logging: + <<: *default-logging + networks: + - human_protocol_web3 + ports: + - '8000:8000' + - '8001:8001' + - '8020:8020' + - '8030:8030' + - '8040:8040' + depends_on: + - blockchain-node + - ipfs + - graph-node-db + environment: + postgres_host: graph-node-db + postgres_user: *graph_db_user + postgres_pass: *graph_db_passwrod + postgres_db: *graph_db_name + ipfs: ipfs:5001 + ethereum: localhost:http://blockchain-node:8545 + GRAPH_LOG: info + healthcheck: + test: ["CMD-SHELL", "nc -z localhost 8000 || exit 1"] + interval: 5s + timeout: 5s + retries: 10 + start_period: 10s + + postgres: + container_name: hp-dev-postgres + image: postgres:16 + restart: *default-restart + logging: + <<: *default-logging + ports: + - name: instance_port + target: 5432 + # default 5432 is used by CVAT installation + published: ${POSTGRES_PORT:-5433} + volumes: + - ./initdb:/docker-entrypoint-initdb.d + - postgres-data:/var/lib/postgresql/data + environment: + POSTGRES_USER: *postgres_user + POSTGRES_PASSWORD: *postgres_password + healthcheck: + test: ["CMD", "pg_isready"] + interval: 10s + timeout: 5s + retries: 5 + + minio: + container_name: hp-dev-minio + image: minio/minio:RELEASE.2024-12-18T13-15-44Z + restart: *default-restart + logging: + <<: *default-logging + entrypoint: 'sh' + ports: + - name: instance_port + target: 9000 + published: *minio_port + - name: console_port + target: 9001 + published: *minio_console_port + volumes: + - minio-data:/data + environment: + MINIO_ROOT_USER: *minio_root_user + MINIO_ROOT_PASSWORD: *minio_root_password + command: + -c "minio server /data --console-address ':9001'" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] + interval: 5s + timeout: 5s + retries: 3 + + minio-client: + container_name: hp-dev-minio-client + image: minio/mc:RELEASE.2024-11-21T17-21-54Z + depends_on: + minio: + condition: service_healthy + environment: + MINIO_ROOT_USER: *minio_root_user + MINIO_ROOT_PASSWORD: *minio_root_password + SERVICES_ACCESS_KEY: *minio_services_access_key + SERVICES_SECRET_KEY: *minio_services_secret_key + BUCKET_MANIFESTS: *bucket_name_manifests + BUCKET_DATASETS: *bucket_name_datasets + BUCKET_REPUTATION_ORACLE: *bucket_name_rep_o + BUCKET_FORTUNE: *bucket_name_fortune + entrypoint: > + /bin/sh -c " + mc alias set myminio http://minio:9000 $$MINIO_ROOT_USER $$MINIO_ROOT_PASSWORD + + mc admin user add myminio $$SERVICES_ACCESS_KEY $$SERVICES_SECRET_KEY + mc admin policy attach myminio readwrite --user=$$SERVICES_ACCESS_KEY + + mc mb myminio/$$BUCKET_MANIFESTS; + mc anonymous set public myminio/$$BUCKET_MANIFESTS; + + mc mb myminio/$$BUCKET_DATASETS; + mc anonymous set public myminio/$$BUCKET_DATASETS; + + mc mb myminio/$$BUCKET_REPUTATION_ORACLE; + mc anonymous set public myminio/$$BUCKET_REPUTATION_ORACLE; + + mc mb myminio/$$BUCKET_FORTUNE; + mc anonymous set public myminio/$$BUCKET_FORTUNE; + " + +volumes: + ipfs-data: + graph-node-db-data: + postgres-data: + minio-data: + +networks: + human_protocol_web3: + name: human-protocol-web3 diff --git a/package.json b/package.json index d92d51468a..e101aba252 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,11 @@ "build:core": "yarn workspace @human-protocol/core build", "build:sdk": "yarn workspace @human-protocol/sdk build", "build:libs": "yarn build:core && yarn build:sdk", - "docker:infra-up": "make -C ./docker-setup check-env-file infra-up", - "docker:stop": "make -C ./docker-setup services-stop" + "docker:infra-up": "make -C ./docker-setup -f Makefile.dev infra-up", + "docker:infra-stop": "make -C ./docker-setup -f Makefile.dev infra-stop", + "docker:infra-down": "make -C ./docker-setup -f Makefile.dev infra-down", + "docker:web3-up": "make -C ./docker-setup -f Makefile.dev web3-up", + "docker:web3-down": "make -C ./docker-setup -f Makefile.dev web3-down" }, "workspaces": [ "packages/**" diff --git a/packages/apps/dashboard/server/src/app.module.ts b/packages/apps/dashboard/server/src/app.module.ts index 0f973c696c..6a9b8b9fb1 100644 --- a/packages/apps/dashboard/server/src/app.module.ts +++ b/packages/apps/dashboard/server/src/app.module.ts @@ -15,9 +15,10 @@ import { NetworksModule } from './modules/networks/networks.module'; @Module({ imports: [ ConfigModule.forRoot({ - envFilePath: process.env.NODE_ENV - ? `.env.${process.env.NODE_ENV as string}` - : '.env', + /** + * First value found takes precendece + */ + envFilePath: [`.env.${process.env.NODE_ENV}`, '.env.local', '.env'], isGlobal: true, validationSchema: Joi.object({ HOST: Joi.string().required(), diff --git a/packages/apps/fortune/exchange-oracle/client/Dockerfile b/packages/apps/fortune/exchange-oracle/client/Dockerfile index b47c3f4c23..46f448db16 100644 --- a/packages/apps/fortune/exchange-oracle/client/Dockerfile +++ b/packages/apps/fortune/exchange-oracle/client/Dockerfile @@ -20,7 +20,7 @@ COPY packages/sdk ./packages/sdk RUN yarn install -# Copy base TS config that is required to build pacakges +# Copy base TS config that is required to build packages COPY tsconfig.base.json ./ # Build libs RUN yarn build:libs diff --git a/packages/apps/fortune/exchange-oracle/server/.env.example b/packages/apps/fortune/exchange-oracle/server/.env.example index 6c0f17db8b..90f7f08c99 100644 --- a/packages/apps/fortune/exchange-oracle/server/.env.example +++ b/packages/apps/fortune/exchange-oracle/server/.env.example @@ -22,6 +22,7 @@ S3_USE_SSL=false WEB3_ENV=testnet WEB3_PRIVATE_KEY=replace_me RPC_URL_POLYGON_AMOY=https://rpc-amoy.polygon.technology +RPC_URL_LOCALHOST=http://0.0.0.0:8545 # PGP PGP_ENCRYPT=true diff --git a/packages/apps/fortune/exchange-oracle/server/Dockerfile b/packages/apps/fortune/exchange-oracle/server/Dockerfile index 29c97e32f6..2be71aa6b6 100644 --- a/packages/apps/fortune/exchange-oracle/server/Dockerfile +++ b/packages/apps/fortune/exchange-oracle/server/Dockerfile @@ -19,7 +19,7 @@ COPY packages/sdk ./packages/sdk RUN yarn install -# Copy base TS config that is required to build pacakges +# Copy base TS config that is required to build packages COPY tsconfig.base.json ./ # Build libs RUN yarn build:libs diff --git a/packages/apps/fortune/exchange-oracle/server/package.json b/packages/apps/fortune/exchange-oracle/server/package.json index f808bbe57a..52e07a4a4a 100644 --- a/packages/apps/fortune/exchange-oracle/server/package.json +++ b/packages/apps/fortune/exchange-oracle/server/package.json @@ -23,7 +23,7 @@ "test:watch": "jest --watch", "test:cov": "jest --coverage", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", - "setup:local": "ts-node ./test/setup.ts", + "setup:local": "ts-node ./scripts/setup-staking.ts && LOCAL=true yarn setup:kvstore", "setup:kvstore": "ts-node ./scripts/setup-kv-store.ts", "generate-env-doc": "ts-node scripts/generate-env-doc.ts" }, diff --git a/packages/apps/fortune/exchange-oracle/server/scripts/setup-kv-store.ts b/packages/apps/fortune/exchange-oracle/server/scripts/setup-kv-store.ts index d7344a3d54..8a96dfc4c9 100644 --- a/packages/apps/fortune/exchange-oracle/server/scripts/setup-kv-store.ts +++ b/packages/apps/fortune/exchange-oracle/server/scripts/setup-kv-store.ts @@ -1,23 +1,37 @@ -import 'dotenv/config'; import { KVStoreClient, KVStoreKeys, Role } from '@human-protocol/sdk'; +import * as dotenv from 'dotenv'; import { Wallet, ethers } from 'ethers'; import * as Minio from 'minio'; +const isLocalEnv = process.env.LOCAL === 'true'; + +let ENV_FILE_PATH = '.env'; +if (isLocalEnv) { + ENV_FILE_PATH += '.local'; +} +dotenv.config({ path: ENV_FILE_PATH }); + +const RPC_URL = isLocalEnv + ? process.env.RPC_URL_LOCALHOST + : process.env.RPC_URL_POLYGON_AMOY; + const SUPPORTED_JOB_TYPES = 'fortune'; const ROLE = Role.ExchangeOracle; async function setupCommonValues(kvStoreClient: KVStoreClient): Promise { - const { SERVER_URL = 'http://localhost:5006', FEE = '1' } = process.env; + const { SERVER_URL, HOST, PORT, FEE = '1' } = process.env; if (SUPPORTED_JOB_TYPES.split(',').length === 0) { throw new Error('SUPPORTED_JOB_TYPES should be comma-separated list'); } + + const serverUrl = SERVER_URL || `http://${HOST}:${PORT}`; try { - new URL(SERVER_URL || ''); - } catch (noop) { + new URL(serverUrl); + } catch (_noop) { throw new Error('Invalid SERVER_URL'); } - let url = SERVER_URL.endsWith('/') ? SERVER_URL.slice(0, -1) : SERVER_URL; + let url = serverUrl.endsWith('/') ? serverUrl.slice(0, -1) : serverUrl; if (!url.startsWith('http')) { url = `http://${url}`; } @@ -74,14 +88,15 @@ async function setupPublicKeyFile( } async function setup(): Promise { - const { WEB3_PRIVATE_KEY, RPC_URL_POLYGON_AMOY: RPC_URL } = process.env; - if (!WEB3_PRIVATE_KEY) { - throw new Error('Private key is empty'); - } if (!RPC_URL) { throw new Error('RPC url is empty'); } + const { WEB3_PRIVATE_KEY } = process.env; + if (!WEB3_PRIVATE_KEY) { + throw new Error('Private key is empty'); + } + const provider = new ethers.JsonRpcProvider(RPC_URL); const wallet = new Wallet(WEB3_PRIVATE_KEY, provider); @@ -125,7 +140,7 @@ async function setup(): Promise { PGP_PUBLIC_KEY, PGP_PUBLIC_KEY_FILE = 'pgp-public-key-exco', } = process.env; - if (PGP_ENCRYPT && PGP_ENCRYPT === 'true') { + if (PGP_ENCRYPT === 'true') { if (!PGP_PUBLIC_KEY) { throw new Error('PGP public key is empty'); } @@ -146,7 +161,7 @@ async function setup(): Promise { await setup(); process.exit(0); } catch (error) { - console.error('Failed to setup KV', error); + console.error('Failed to setup KV.', error); process.exit(1); } })(); diff --git a/packages/apps/fortune/exchange-oracle/server/scripts/setup-staking.ts b/packages/apps/fortune/exchange-oracle/server/scripts/setup-staking.ts new file mode 100644 index 0000000000..8d266da004 --- /dev/null +++ b/packages/apps/fortune/exchange-oracle/server/scripts/setup-staking.ts @@ -0,0 +1,39 @@ +import { + ChainId, + NetworkData, + NETWORKS, + StakingClient, +} from '@human-protocol/sdk'; +import { HMToken__factory } from '@human-protocol/core/typechain-types'; +import * as dotenv from 'dotenv'; +import { Wallet, ethers } from 'ethers'; + +dotenv.config({ path: '.env.local' }); + +const RPC_URL = process.env.RPC_URL_LOCALHOST || 'http://0.0.0.0:8545'; + +export async function setup(): Promise { + if (!RPC_URL) { + throw new Error('RPC url is empty'); + } + + const { WEB3_PRIVATE_KEY } = process.env; + if (!WEB3_PRIVATE_KEY) { + throw new Error('Private key is empty'); + } + + const provider = new ethers.JsonRpcProvider(RPC_URL); + const { hmtAddress: hmtTokenAddress, stakingAddress } = NETWORKS[ + ChainId.LOCALHOST + ] as NetworkData; + const wallet = new Wallet(WEB3_PRIVATE_KEY, provider); + + const hmtContract = HMToken__factory.connect(hmtTokenAddress, wallet); + const hmtTx = await hmtContract.approve(stakingAddress, 1); + await hmtTx.wait(); + + const stakingClient = await StakingClient.build(wallet); + await stakingClient.stake(BigInt(1)); +} + +setup(); diff --git a/packages/apps/fortune/exchange-oracle/server/src/app.module.ts b/packages/apps/fortune/exchange-oracle/server/src/app.module.ts index 03f66a01ae..93f9f3f51f 100644 --- a/packages/apps/fortune/exchange-oracle/server/src/app.module.ts +++ b/packages/apps/fortune/exchange-oracle/server/src/app.module.ts @@ -54,7 +54,7 @@ import { HttpValidationPipe } from './common/pipes'; /** * First value found takes precendece */ - envFilePath: [`.env.${process.env.NODE_ENV}`, '.env'], + envFilePath: [`.env.${process.env.NODE_ENV}`, '.env.local', '.env'], validationSchema: envValidator, }), DatabaseModule, diff --git a/packages/apps/fortune/exchange-oracle/server/test/setup.ts b/packages/apps/fortune/exchange-oracle/server/test/setup.ts deleted file mode 100644 index 3792cdf6b3..0000000000 --- a/packages/apps/fortune/exchange-oracle/server/test/setup.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { KVStoreClient, KVStoreKeys, Role } from '@human-protocol/sdk'; -import { Wallet, ethers } from 'ethers'; -import * as dotenv from 'dotenv'; -import * as Minio from 'minio'; -dotenv.config({ path: '.env.local' }); - -export async function setup(): Promise { - const privateKey = process.env.WEB3_PRIVATE_KEY; - if (!privateKey) { - throw new Error('Private key is empty'); - } - const provider = new ethers.JsonRpcProvider('http://0.0.0.0:8545'); - const wallet = new Wallet(privateKey, provider); - - const kvStoreClient = await KVStoreClient.build(wallet); - await kvStoreClient.setBulk( - [ - KVStoreKeys.role, - KVStoreKeys.fee, - KVStoreKeys.webhookUrl, - KVStoreKeys.url, - KVStoreKeys.jobTypes, - ], - [ - Role.ExchangeOracle, - '1', - 'http://localhost:5001/webhook', - 'http://localhost:5001', - 'FORTUNE', - ], - { nonce: 0 }, - ); - if (process.env.PGP_ENCRYPT && process.env.PGP_ENCRYPT === 'true') { - if (!process.env.PGP_PUBLIC_KEY) { - throw new Error('PGP public key is empty'); - } - const minioClient = new Minio.Client({ - endPoint: process.env.S3_ENDPOINT || 'localhost', - port: parseInt(process.env.S3_PORT || '9000', 10), - useSSL: process.env.S3_USE_SSL === 'true', - accessKey: process.env.S3_ACCESS_KEY || 'access-key', - secretKey: process.env.S3_SECRET_KEY || 'secret-key', - }); - const bucket = process.env.S3_BUCKET || 'bucket'; - const fileName = 'exo-pgp-public-key.txt'; - const exists = await minioClient.bucketExists(bucket); - if (!exists) { - throw new Error('Bucket does not exists'); - } - try { - await minioClient.putObject( - bucket, - fileName, - process.env.PGP_PUBLIC_KEY, - { - 'Content-Type': 'application/json', - 'Cache-Control': 'no-store', - }, - ); - await kvStoreClient.setFileUrlAndHash( - `http://localhost:9000/bucket/${fileName}`, - KVStoreKeys.publicKey, - { nonce: 1 }, - ); - } catch (e) { - console.log(e); - } - } -} - -setup(); diff --git a/packages/apps/fortune/recording-oracle/.env.example b/packages/apps/fortune/recording-oracle/.env.example index c2a7c1bc38..8705bc4911 100644 --- a/packages/apps/fortune/recording-oracle/.env.example +++ b/packages/apps/fortune/recording-oracle/.env.example @@ -13,6 +13,7 @@ S3_USE_SSL=false # Web3 WEB3_PRIVATE_KEY=replace_me RPC_URL_POLYGON_AMOY=https://rpc-amoy.polygon.technology +RPC_URL_LOCALHOST=http://0.0.0.0:8545 # Encryption PGP_ENCRYPT=true diff --git a/packages/apps/fortune/recording-oracle/Dockerfile b/packages/apps/fortune/recording-oracle/Dockerfile index bfe85f163b..2467774a14 100644 --- a/packages/apps/fortune/recording-oracle/Dockerfile +++ b/packages/apps/fortune/recording-oracle/Dockerfile @@ -19,7 +19,7 @@ COPY packages/sdk ./packages/sdk RUN yarn install -# Copy base TS config that is required to build pacakges +# Copy base TS config that is required to build packages COPY tsconfig.base.json ./ # Build libs RUN yarn build:libs diff --git a/packages/apps/fortune/recording-oracle/package.json b/packages/apps/fortune/recording-oracle/package.json index 0ffebff104..8d18412b67 100644 --- a/packages/apps/fortune/recording-oracle/package.json +++ b/packages/apps/fortune/recording-oracle/package.json @@ -18,7 +18,7 @@ "test": "jest", "test:watch": "jest --watch", "test:cov": "jest --coverage", - "setup:local": "ts-node ./test/setup.ts", + "setup:local": "ts-node ./scripts/setup-staking.ts && LOCAL=true yarn setup:kvstore", "setup:kvstore": "ts-node ./scripts/setup-kv-store.ts", "generate-env-doc": "ts-node scripts/generate-env-doc.ts" }, diff --git a/packages/apps/fortune/recording-oracle/scripts/setup-kv-store.ts b/packages/apps/fortune/recording-oracle/scripts/setup-kv-store.ts index c1ad796570..99a865bd08 100644 --- a/packages/apps/fortune/recording-oracle/scripts/setup-kv-store.ts +++ b/packages/apps/fortune/recording-oracle/scripts/setup-kv-store.ts @@ -1,23 +1,37 @@ -import 'dotenv/config'; import { KVStoreClient, KVStoreKeys, Role } from '@human-protocol/sdk'; +import * as dotenv from 'dotenv'; import { Wallet, ethers } from 'ethers'; import * as Minio from 'minio'; +const isLocalEnv = process.env.LOCAL === 'true'; + +let ENV_FILE_PATH = '.env'; +if (isLocalEnv) { + ENV_FILE_PATH += '.local'; +} +dotenv.config({ path: ENV_FILE_PATH }); + +const RPC_URL = isLocalEnv + ? process.env.RPC_URL_LOCALHOST + : process.env.RPC_URL_POLYGON_AMOY; + const SUPPORTED_JOB_TYPES = 'fortune'; const ROLE = Role.RecordingOracle; async function setupCommonValues(kvStoreClient: KVStoreClient): Promise { - const { SERVER_URL = 'http://localhost:5007', FEE = '1' } = process.env; + const { SERVER_URL, HOST, PORT, FEE = '1' } = process.env; if (SUPPORTED_JOB_TYPES.split(',').length === 0) { throw new Error('SUPPORTED_JOB_TYPES should be comma-separated list'); } + + const serverUrl = SERVER_URL || `http://${HOST}:${PORT}`; try { - new URL(SERVER_URL || ''); - } catch (noop) { + new URL(serverUrl); + } catch (_noop) { throw new Error('Invalid SERVER_URL'); } - let url = SERVER_URL.endsWith('/') ? SERVER_URL.slice(0, -1) : SERVER_URL; + let url = serverUrl.endsWith('/') ? serverUrl.slice(0, -1) : serverUrl; if (!url.startsWith('http')) { url = `http://${url}`; } @@ -74,14 +88,15 @@ async function setupPublicKeyFile( } async function setup(): Promise { - const { WEB3_PRIVATE_KEY, RPC_URL_POLYGON_AMOY: RPC_URL } = process.env; - if (!WEB3_PRIVATE_KEY) { - throw new Error('Private key is empty'); - } if (!RPC_URL) { throw new Error('RPC url is empty'); } + const { WEB3_PRIVATE_KEY } = process.env; + if (!WEB3_PRIVATE_KEY) { + throw new Error('Private key is empty'); + } + const provider = new ethers.JsonRpcProvider(RPC_URL); const wallet = new Wallet(WEB3_PRIVATE_KEY, provider); @@ -125,7 +140,7 @@ async function setup(): Promise { PGP_PUBLIC_KEY, PGP_PUBLIC_KEY_FILE = 'pgp-public-key-reco', } = process.env; - if (PGP_ENCRYPT && PGP_ENCRYPT === 'true') { + if (PGP_ENCRYPT === 'true') { if (!PGP_PUBLIC_KEY) { throw new Error('PGP public key is empty'); } @@ -146,7 +161,7 @@ async function setup(): Promise { await setup(); process.exit(0); } catch (error) { - console.error('Failed to setup KV', error); + console.error('Failed to setup KV.', error); process.exit(1); } })(); diff --git a/packages/apps/fortune/recording-oracle/scripts/setup-staking.ts b/packages/apps/fortune/recording-oracle/scripts/setup-staking.ts new file mode 100644 index 0000000000..8d266da004 --- /dev/null +++ b/packages/apps/fortune/recording-oracle/scripts/setup-staking.ts @@ -0,0 +1,39 @@ +import { + ChainId, + NetworkData, + NETWORKS, + StakingClient, +} from '@human-protocol/sdk'; +import { HMToken__factory } from '@human-protocol/core/typechain-types'; +import * as dotenv from 'dotenv'; +import { Wallet, ethers } from 'ethers'; + +dotenv.config({ path: '.env.local' }); + +const RPC_URL = process.env.RPC_URL_LOCALHOST || 'http://0.0.0.0:8545'; + +export async function setup(): Promise { + if (!RPC_URL) { + throw new Error('RPC url is empty'); + } + + const { WEB3_PRIVATE_KEY } = process.env; + if (!WEB3_PRIVATE_KEY) { + throw new Error('Private key is empty'); + } + + const provider = new ethers.JsonRpcProvider(RPC_URL); + const { hmtAddress: hmtTokenAddress, stakingAddress } = NETWORKS[ + ChainId.LOCALHOST + ] as NetworkData; + const wallet = new Wallet(WEB3_PRIVATE_KEY, provider); + + const hmtContract = HMToken__factory.connect(hmtTokenAddress, wallet); + const hmtTx = await hmtContract.approve(stakingAddress, 1); + await hmtTx.wait(); + + const stakingClient = await StakingClient.build(wallet); + await stakingClient.stake(BigInt(1)); +} + +setup(); diff --git a/packages/apps/fortune/recording-oracle/src/app.module.ts b/packages/apps/fortune/recording-oracle/src/app.module.ts index 8646dcfc09..68951d8b53 100644 --- a/packages/apps/fortune/recording-oracle/src/app.module.ts +++ b/packages/apps/fortune/recording-oracle/src/app.module.ts @@ -36,7 +36,7 @@ import { ExceptionFilter } from './common/exceptions/exception.filter'; /** * First value found takes precendece */ - envFilePath: [`.env.${process.env.NODE_ENV}`, '.env'], + envFilePath: [`.env.${process.env.NODE_ENV}`, '.env.local', '.env'], validationSchema: envValidator, }), JobModule, diff --git a/packages/apps/fortune/recording-oracle/test/setup.ts b/packages/apps/fortune/recording-oracle/test/setup.ts deleted file mode 100644 index 6c9e5348be..0000000000 --- a/packages/apps/fortune/recording-oracle/test/setup.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { KVStoreClient, KVStoreKeys, Role } from '@human-protocol/sdk'; -import { Wallet, ethers } from 'ethers'; -import * as dotenv from 'dotenv'; -import * as Minio from 'minio'; -dotenv.config({ path: '.env.local' }); - -export async function setup(): Promise { - const privateKey = process.env.WEB3_PRIVATE_KEY; - if (!privateKey) { - throw new Error('Private key is empty'); - } - const provider = new ethers.JsonRpcProvider('http://0.0.0.0:8545'); - const wallet = new Wallet(privateKey, provider); - - const kvStoreClient = await KVStoreClient.build(wallet); - await kvStoreClient.setBulk( - [KVStoreKeys.role, KVStoreKeys.fee, KVStoreKeys.webhookUrl], - [Role.RecordingOracle, '1', 'http://localhost:5002/webhook'], - { - nonce: 0, - }, - ); - - if (process.env.PGP_ENCRYPT && process.env.PGP_ENCRYPT === 'true') { - if (!process.env.PGP_PUBLIC_KEY) { - throw new Error('PGP public key is empty'); - } - const minioClient = new Minio.Client({ - endPoint: process.env.S3_ENDPOINT || 'localhost', - port: parseInt(process.env.S3_PORT || '9000', 10), - useSSL: process.env.S3_USE_SSL === 'true', - accessKey: process.env.S3_ACCESS_KEY || 'access-key', - secretKey: process.env.S3_SECRET_KEY || 'secret-key', - }); - const bucket = process.env.S3_BUCKET || 'bucket'; - const fileName = 'reco-pgp-public-key.txt'; - const exists = await minioClient.bucketExists(bucket); - if (!exists) { - throw new Error('Bucket does not exists'); - } - try { - await minioClient.putObject( - bucket, - fileName, - process.env.PGP_PUBLIC_KEY, - { - 'Content-Type': 'application/json', - 'Cache-Control': 'no-store', - }, - ); - await kvStoreClient.setFileUrlAndHash( - `http://localhost:9000/bucket/${fileName}`, - KVStoreKeys.publicKey, - { - nonce: 1, - }, - ); - } catch (e) { - // eslint-disable-next-line no-console - console.log(e); - } - } -} - -setup(); diff --git a/packages/apps/human-app/frontend/Dockerfile b/packages/apps/human-app/frontend/Dockerfile index a00aea0d4f..7bb315121b 100644 --- a/packages/apps/human-app/frontend/Dockerfile +++ b/packages/apps/human-app/frontend/Dockerfile @@ -20,7 +20,7 @@ COPY packages/sdk ./packages/sdk RUN yarn install -# Copy base TS config that is required to build pacakges +# Copy base TS config that is required to build packages COPY tsconfig.base.json ./ # Build libs RUN yarn build:libs diff --git a/packages/apps/human-app/server/Dockerfile b/packages/apps/human-app/server/Dockerfile index 0ea9aba025..c04bf24b04 100644 --- a/packages/apps/human-app/server/Dockerfile +++ b/packages/apps/human-app/server/Dockerfile @@ -19,7 +19,7 @@ COPY packages/sdk ./packages/sdk RUN yarn install -# Copy base TS config that is required to build pacakges +# Copy base TS config that is required to build packages COPY tsconfig.base.json ./ # Build libs RUN yarn build:libs diff --git a/packages/apps/human-app/server/src/app.module.ts b/packages/apps/human-app/server/src/app.module.ts index 245654afe5..37292b384a 100644 --- a/packages/apps/human-app/server/src/app.module.ts +++ b/packages/apps/human-app/server/src/app.module.ts @@ -52,7 +52,10 @@ const JOI_BOOLEAN_STRING_SCHEMA = Joi.string().valid('true', 'false'); @Module({ imports: [ ConfigModule.forRoot({ - envFilePath: [`.env.${process.env.NODE_ENV}`, '.env'], + /** + * First value found takes precendece + */ + envFilePath: [`.env.${process.env.NODE_ENV}`, '.env.local', '.env'], isGlobal: true, validationSchema: Joi.object({ HOST: Joi.string().required(), diff --git a/packages/apps/job-launcher/client/Dockerfile b/packages/apps/job-launcher/client/Dockerfile index 6161f685f3..6229e58442 100644 --- a/packages/apps/job-launcher/client/Dockerfile +++ b/packages/apps/job-launcher/client/Dockerfile @@ -20,7 +20,7 @@ COPY packages/sdk ./packages/sdk RUN yarn install -# Copy base TS config that is required to build pacakges +# Copy base TS config that is required to build packages COPY tsconfig.base.json ./ # Build libs RUN yarn build:libs diff --git a/packages/apps/job-launcher/server/.env.example b/packages/apps/job-launcher/server/.env.example index 00453220c9..73585bf6e8 100644 --- a/packages/apps/job-launcher/server/.env.example +++ b/packages/apps/job-launcher/server/.env.example @@ -23,6 +23,7 @@ S3_USE_SSL=false WEB3_ENV=testnet WEB3_PRIVATE_KEY=replace_me RPC_URL_POLYGON_AMOY=https://rpc-amoy.polygon.technology +RPC_URL_LOCALHOST=http://0.0.0.0:8545 REPUTATION_ORACLES=replace_me REPUTATION_ORACLE_ADDRESS=replace_me CVAT_EXCHANGE_ORACLE_ADDRESS=replace_me_if_needed diff --git a/packages/apps/job-launcher/server/Dockerfile b/packages/apps/job-launcher/server/Dockerfile index a9843df1f4..72663d1e27 100644 --- a/packages/apps/job-launcher/server/Dockerfile +++ b/packages/apps/job-launcher/server/Dockerfile @@ -19,7 +19,7 @@ COPY packages/sdk ./packages/sdk RUN yarn install -# Copy base TS config that is required to build pacakges +# Copy base TS config that is required to build packages COPY tsconfig.base.json ./ # Build libs RUN yarn build:libs diff --git a/packages/apps/job-launcher/server/package.json b/packages/apps/job-launcher/server/package.json index 76da90322b..45917b536c 100644 --- a/packages/apps/job-launcher/server/package.json +++ b/packages/apps/job-launcher/server/package.json @@ -18,7 +18,7 @@ "migration:revert": "yarn build && typeorm-ts-node-commonjs migration:revert -d typeorm.config.ts", "migration:run": "yarn build && typeorm-ts-node-commonjs migration:run -d typeorm.config.ts", "migration:show": "yarn build && typeorm-ts-node-commonjs migration:show -d typeorm.config.ts", - "setup:local": "ts-node ./test/setup.ts", + "setup:local": "ts-node ./scripts/setup-staking.ts && LOCAL=true yarn setup:kvstore", "setup:kvstore": "ts-node ./scripts/setup-kv-store.ts", "lint": "eslint \"{src,test}/**/*.ts\" --fix", "test": "jest", diff --git a/packages/apps/job-launcher/server/scripts/setup-kv-store.ts b/packages/apps/job-launcher/server/scripts/setup-kv-store.ts index 2312158bfa..c2e0a89434 100644 --- a/packages/apps/job-launcher/server/scripts/setup-kv-store.ts +++ b/packages/apps/job-launcher/server/scripts/setup-kv-store.ts @@ -1,8 +1,20 @@ -import 'dotenv/config'; import { KVStoreClient, KVStoreKeys, Role } from '@human-protocol/sdk'; +import * as dotenv from 'dotenv'; import { Wallet, ethers } from 'ethers'; import * as Minio from 'minio'; +const isLocalEnv = process.env.LOCAL === 'true'; + +let ENV_FILE_PATH = '.env'; +if (isLocalEnv) { + ENV_FILE_PATH += '.local'; +} +dotenv.config({ path: ENV_FILE_PATH }); + +const RPC_URL = isLocalEnv + ? process.env.RPC_URL_LOCALHOST + : process.env.RPC_URL_POLYGON_AMOY; + const DEFAULT_SUPPORTED_JOB_TYPES = 'fortune,image_boxes,image_boxes_from_points,image_points,image_polygons,image_skeletons_from_boxes'; const ROLE = Role.JobLauncher; @@ -10,19 +22,23 @@ const ROLE = Role.JobLauncher; async function setupCommonValues(kvStoreClient: KVStoreClient): Promise { const { SUPPORTED_JOB_TYPES = DEFAULT_SUPPORTED_JOB_TYPES, - SERVER_URL = 'http://localhost:5003', + SERVER_URL, + HOST, + PORT, FEE = '1', } = process.env; if (SUPPORTED_JOB_TYPES.split(',').length === 0) { throw new Error('SUPPORTED_JOB_TYPES should be comma-separated list'); } + + const serverUrl = SERVER_URL || `http://${HOST}:${PORT}`; try { - new URL(SERVER_URL || ''); + new URL(serverUrl); } catch (_noop) { throw new Error('Invalid SERVER_URL'); } - let url = SERVER_URL.endsWith('/') ? SERVER_URL.slice(0, -1) : SERVER_URL; + let url = serverUrl.endsWith('/') ? serverUrl.slice(0, -1) : serverUrl; if (!url.startsWith('http')) { url = `http://${url}`; } @@ -79,14 +95,15 @@ async function setupPublicKeyFile( } async function setup(): Promise { - const { WEB3_PRIVATE_KEY, RPC_URL_POLYGON_AMOY: RPC_URL } = process.env; - if (!WEB3_PRIVATE_KEY) { - throw new Error('Private key is empty'); - } if (!RPC_URL) { throw new Error('RPC url is empty'); } + const { WEB3_PRIVATE_KEY } = process.env; + if (!WEB3_PRIVATE_KEY) { + throw new Error('Private key is empty'); + } + const provider = new ethers.JsonRpcProvider(RPC_URL); const wallet = new Wallet(WEB3_PRIVATE_KEY, provider); @@ -130,7 +147,7 @@ async function setup(): Promise { PGP_PUBLIC_KEY, PGP_PUBLIC_KEY_FILE = 'pgp-public-key', } = process.env; - if (PGP_ENCRYPT && PGP_ENCRYPT === 'true') { + if (PGP_ENCRYPT === 'true') { if (!PGP_PUBLIC_KEY) { throw new Error('PGP public key is empty'); } @@ -151,7 +168,7 @@ async function setup(): Promise { await setup(); process.exit(0); } catch (error) { - console.error('Failed to setup KV', error); + console.error('Failed to setup KV.', error); process.exit(1); } })(); diff --git a/packages/apps/job-launcher/server/scripts/setup-staking.ts b/packages/apps/job-launcher/server/scripts/setup-staking.ts new file mode 100644 index 0000000000..8d266da004 --- /dev/null +++ b/packages/apps/job-launcher/server/scripts/setup-staking.ts @@ -0,0 +1,39 @@ +import { + ChainId, + NetworkData, + NETWORKS, + StakingClient, +} from '@human-protocol/sdk'; +import { HMToken__factory } from '@human-protocol/core/typechain-types'; +import * as dotenv from 'dotenv'; +import { Wallet, ethers } from 'ethers'; + +dotenv.config({ path: '.env.local' }); + +const RPC_URL = process.env.RPC_URL_LOCALHOST || 'http://0.0.0.0:8545'; + +export async function setup(): Promise { + if (!RPC_URL) { + throw new Error('RPC url is empty'); + } + + const { WEB3_PRIVATE_KEY } = process.env; + if (!WEB3_PRIVATE_KEY) { + throw new Error('Private key is empty'); + } + + const provider = new ethers.JsonRpcProvider(RPC_URL); + const { hmtAddress: hmtTokenAddress, stakingAddress } = NETWORKS[ + ChainId.LOCALHOST + ] as NetworkData; + const wallet = new Wallet(WEB3_PRIVATE_KEY, provider); + + const hmtContract = HMToken__factory.connect(hmtTokenAddress, wallet); + const hmtTx = await hmtContract.approve(stakingAddress, 1); + await hmtTx.wait(); + + const stakingClient = await StakingClient.build(wallet); + await stakingClient.stake(BigInt(1)); +} + +setup(); diff --git a/packages/apps/job-launcher/server/src/app.module.ts b/packages/apps/job-launcher/server/src/app.module.ts index 32fcb810cc..03fcb7b581 100644 --- a/packages/apps/job-launcher/server/src/app.module.ts +++ b/packages/apps/job-launcher/server/src/app.module.ts @@ -54,7 +54,7 @@ import { TransformEnumInterceptor } from './common/interceptors/transform-enum.i /** * First value found takes precendece */ - envFilePath: [`.env.${process.env.NODE_ENV}`, '.env'], + envFilePath: [`.env.${process.env.NODE_ENV}`, '.env.local', '.env'], validationSchema: envValidator, }), DatabaseModule, diff --git a/packages/apps/job-launcher/server/test/setup.ts b/packages/apps/job-launcher/server/test/setup.ts deleted file mode 100644 index 05d8861d22..0000000000 --- a/packages/apps/job-launcher/server/test/setup.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { - StakingClient, - KVStoreClient, - KVStoreKeys, - Role, -} from '@human-protocol/sdk'; -import { Wallet, ethers } from 'ethers'; -import { HMToken__factory } from '@human-protocol/core/typechain-types'; -import * as dotenv from 'dotenv'; -import * as Minio from 'minio'; -dotenv.config({ path: '.env.local' }); - -export async function setup(): Promise { - const privateKey = process.env.WEB3_PRIVATE_KEY; - if (!privateKey) { - throw new Error('Private key is empty'); - } - const provider = new ethers.JsonRpcProvider('http://0.0.0.0:8545'); - const hmtTokenAddress = '0x5FbDB2315678afecb367f032d93F642f64180aa3'; - const stakingAddress = '0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512'; - const wallet = new Wallet(privateKey, provider); - - const hmtContract = HMToken__factory.connect(hmtTokenAddress, wallet); - await ( - await hmtContract.approve(stakingAddress, 1, { - nonce: 0, - }) - ).wait(); - - const stakingClient = await StakingClient.build(wallet); - await stakingClient.stake(BigInt(1), { - nonce: 1, - }); - const kvStoreClient = await KVStoreClient.build(wallet); - - await kvStoreClient.setBulk( - [ - KVStoreKeys.role, - KVStoreKeys.fee, - KVStoreKeys.webhookUrl, - KVStoreKeys.url, - KVStoreKeys.jobTypes, - ], - [ - Role.JobLauncher, - '1', - 'http://localhost:5000/webhook', - 'http://localhost:5000', - 'type1, type2', - ], - { nonce: 2 }, - ); - - if (process.env.PGP_ENCRYPT && process.env.PGP_ENCRYPT === 'true') { - if (!process.env.PGP_PUBLIC_KEY) { - throw new Error('PGP public key is empty'); - } - const minioClient = new Minio.Client({ - endPoint: process.env.S3_ENDPOINT || 'localhost', - port: parseInt(process.env.S3_PORT || '9000', 10), - useSSL: process.env.S3_USE_SSL === 'true', - accessKey: process.env.S3_ACCESS_KEY || 'access-key', - secretKey: process.env.S3_SECRET_KEY || 'secret-key', - }); - const bucket = process.env.S3_BUCKET || 'bucket'; - const fileName = 'jl-pgp-public-key.txt'; - const exists = await minioClient.bucketExists(bucket); - if (!exists) { - throw new Error('Bucket does not exists'); - } - try { - await minioClient.putObject( - bucket, - fileName, - process.env.PGP_PUBLIC_KEY, - { - 'Content-Type': 'application/json', - 'Cache-Control': 'no-store', - }, - ); - await kvStoreClient.setFileUrlAndHash( - `http://localhost:9000/bucket/${fileName}`, - KVStoreKeys.publicKey, - { nonce: 3 }, - ); - } catch (e) { - console.log(e); - } - } -} - -setup(); diff --git a/packages/apps/reputation-oracle/server/.env.example b/packages/apps/reputation-oracle/server/.env.example index e08449b539..c3c6a028ce 100644 --- a/packages/apps/reputation-oracle/server/.env.example +++ b/packages/apps/reputation-oracle/server/.env.example @@ -48,6 +48,7 @@ EMAIL_FROM_NAME="Reputation Oracle Local" WEB3_ENV=testnet WEB3_PRIVATE_KEY=replace_me RPC_URL_POLYGON_AMOY=https://rpc-amoy.polygon.technology +RPC_URL_LOCALHOST=http://0.0.0.0:8545 # Encryption PGP_ENCRYPT=true diff --git a/packages/apps/reputation-oracle/server/Dockerfile b/packages/apps/reputation-oracle/server/Dockerfile index 075c163e0e..dff82f8a3e 100644 --- a/packages/apps/reputation-oracle/server/Dockerfile +++ b/packages/apps/reputation-oracle/server/Dockerfile @@ -19,7 +19,7 @@ COPY packages/sdk ./packages/sdk RUN yarn install -# Copy base TS config that is required to build pacakges +# Copy base TS config that is required to build packages COPY tsconfig.base.json ./ # Build libs RUN yarn build:libs diff --git a/packages/apps/reputation-oracle/server/package.json b/packages/apps/reputation-oracle/server/package.json index f4d91c2a12..966238f64d 100644 --- a/packages/apps/reputation-oracle/server/package.json +++ b/packages/apps/reputation-oracle/server/package.json @@ -18,7 +18,7 @@ "migration:revert": "yarn build && typeorm-ts-node-commonjs migration:revert -d typeorm-migrations-datasource.ts", "migration:run": "yarn build && typeorm-ts-node-commonjs migration:run -d typeorm-migrations-datasource.ts", "migration:show": "yarn build && typeorm-ts-node-commonjs migration:show -d typeorm-migrations-datasource.ts", - "setup:local": "ts-node ./scripts/setup-kv-store.ts", + "setup:local": "ts-node ./scripts/setup-staking.ts && LOCAL=true yarn setup:kvstore", "setup:kvstore": "ts-node ./scripts/setup-kv-store.ts", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "test": "jest", diff --git a/packages/apps/reputation-oracle/server/scripts/setup-kv-store.ts b/packages/apps/reputation-oracle/server/scripts/setup-kv-store.ts index 38e117cc00..e64b8aaf7f 100644 --- a/packages/apps/reputation-oracle/server/scripts/setup-kv-store.ts +++ b/packages/apps/reputation-oracle/server/scripts/setup-kv-store.ts @@ -1,8 +1,20 @@ -import 'dotenv/config'; import { KVStoreClient, KVStoreKeys, Role } from '@human-protocol/sdk'; +import * as dotenv from 'dotenv'; import { Wallet, ethers } from 'ethers'; import * as Minio from 'minio'; +const isLocalEnv = process.env.LOCAL === 'true'; + +let ENV_FILE_PATH = '.env'; +if (isLocalEnv) { + ENV_FILE_PATH += '.local'; +} +dotenv.config({ path: ENV_FILE_PATH }); + +const RPC_URL = isLocalEnv + ? process.env.RPC_URL_LOCALHOST + : process.env.RPC_URL_POLYGON_AMOY; + const DEFAULT_SUPPORTED_JOB_TYPES = 'fortune,image_boxes,image_boxes_from_points,image_points,image_polygons,image_skeletons_from_boxes'; const ROLE = Role.ReputationOracle; @@ -10,19 +22,23 @@ const ROLE = Role.ReputationOracle; async function setupCommonValues(kvStoreClient: KVStoreClient): Promise { const { SUPPORTED_JOB_TYPES = DEFAULT_SUPPORTED_JOB_TYPES, - SERVER_URL = 'http://localhost:5001', + SERVER_URL, + HOST, + PORT, FEE = '1', } = process.env; if (SUPPORTED_JOB_TYPES.split(',').length === 0) { throw new Error('SUPPORTED_JOB_TYPES should be comma-separated list'); } + + const serverUrl = SERVER_URL || `http://${HOST}:${PORT}`; try { - new URL(SERVER_URL || ''); + new URL(serverUrl); } catch (noop) { throw new Error('Invalid SERVER_URL'); } - let url = SERVER_URL.endsWith('/') ? SERVER_URL.slice(0, -1) : SERVER_URL; + let url = serverUrl.endsWith('/') ? serverUrl.slice(0, -1) : serverUrl; if (!url.startsWith('http')) { url = `http://${url}`; } @@ -79,14 +95,15 @@ async function setupPublicKeyFile( } async function setup(): Promise { - const { WEB3_PRIVATE_KEY, RPC_URL_POLYGON_AMOY: RPC_URL } = process.env; - if (!WEB3_PRIVATE_KEY) { - throw new Error('Private key is empty'); - } if (!RPC_URL) { throw new Error('RPC url is empty'); } + const { WEB3_PRIVATE_KEY } = process.env; + if (!WEB3_PRIVATE_KEY) { + throw new Error('Private key is empty'); + } + const provider = new ethers.JsonRpcProvider(RPC_URL); const wallet = new Wallet(WEB3_PRIVATE_KEY, provider); @@ -94,6 +111,18 @@ async function setup(): Promise { await setupCommonValues(kvStoreClient); + if (isLocalEnv) { + const { ACTIVE_ORACLE_ADDRESSES } = process.env; + if (ACTIVE_ORACLE_ADDRESSES) { + const oracleAddresses = ACTIVE_ORACLE_ADDRESSES.split(',') + .map((addr) => addr.trim()) + .filter(Boolean); + for (const address of oracleAddresses) { + await kvStoreClient.set(address, 'active'); + } + } + } + const { S3_ENDPOINT, S3_PORT, @@ -130,7 +159,7 @@ async function setup(): Promise { PGP_PUBLIC_KEY, PGP_PUBLIC_KEY_FILE = 'pgp-public-key', } = process.env; - if (PGP_ENCRYPT && PGP_ENCRYPT === 'true') { + if (PGP_ENCRYPT === 'true') { if (!PGP_PUBLIC_KEY) { throw new Error('PGP public key is empty'); } @@ -163,7 +192,7 @@ async function setup(): Promise { await setup(); process.exit(0); } catch (error) { - console.error('Failed to setup KV', error); + console.error('Failed to setup KV.', error); process.exit(1); } })(); diff --git a/packages/apps/reputation-oracle/server/scripts/setup-staking.ts b/packages/apps/reputation-oracle/server/scripts/setup-staking.ts new file mode 100644 index 0000000000..8d266da004 --- /dev/null +++ b/packages/apps/reputation-oracle/server/scripts/setup-staking.ts @@ -0,0 +1,39 @@ +import { + ChainId, + NetworkData, + NETWORKS, + StakingClient, +} from '@human-protocol/sdk'; +import { HMToken__factory } from '@human-protocol/core/typechain-types'; +import * as dotenv from 'dotenv'; +import { Wallet, ethers } from 'ethers'; + +dotenv.config({ path: '.env.local' }); + +const RPC_URL = process.env.RPC_URL_LOCALHOST || 'http://0.0.0.0:8545'; + +export async function setup(): Promise { + if (!RPC_URL) { + throw new Error('RPC url is empty'); + } + + const { WEB3_PRIVATE_KEY } = process.env; + if (!WEB3_PRIVATE_KEY) { + throw new Error('Private key is empty'); + } + + const provider = new ethers.JsonRpcProvider(RPC_URL); + const { hmtAddress: hmtTokenAddress, stakingAddress } = NETWORKS[ + ChainId.LOCALHOST + ] as NetworkData; + const wallet = new Wallet(WEB3_PRIVATE_KEY, provider); + + const hmtContract = HMToken__factory.connect(hmtTokenAddress, wallet); + const hmtTx = await hmtContract.approve(stakingAddress, 1); + await hmtTx.wait(); + + const stakingClient = await StakingClient.build(wallet); + await stakingClient.stake(BigInt(1)); +} + +setup(); diff --git a/packages/apps/reputation-oracle/server/src/app.module.ts b/packages/apps/reputation-oracle/server/src/app.module.ts index eef8a16222..87b88ef05d 100644 --- a/packages/apps/reputation-oracle/server/src/app.module.ts +++ b/packages/apps/reputation-oracle/server/src/app.module.ts @@ -73,7 +73,7 @@ import Environment from './utils/environment'; /** * First value found takes precendece */ - envFilePath: [`.env.${Environment.name}`, '.env'], + envFilePath: [`.env.${Environment.name}`, '.env.local', '.env'], validationSchema: envValidator, }), EnvConfigModule, diff --git a/packages/apps/reputation-oracle/server/src/utils/environment.ts b/packages/apps/reputation-oracle/server/src/utils/environment.ts index b28db18424..05d5c87255 100644 --- a/packages/apps/reputation-oracle/server/src/utils/environment.ts +++ b/packages/apps/reputation-oracle/server/src/utils/environment.ts @@ -1,4 +1,5 @@ enum EnvironmentName { + LOCAL = 'local', DEVELOPMENT = 'development', TEST = 'test', STAGING = 'staging', @@ -10,9 +11,11 @@ class Environment { process.env.NODE_ENV || EnvironmentName.DEVELOPMENT; static isDevelopment(): boolean { - return [EnvironmentName.DEVELOPMENT, EnvironmentName.TEST].includes( - Environment.name as EnvironmentName, - ); + return [ + EnvironmentName.DEVELOPMENT, + EnvironmentName.TEST, + EnvironmentName.LOCAL, + ].includes(Environment.name as EnvironmentName); } static isTest(): boolean { diff --git a/packages/core/Dockerfile.local b/packages/core/Dockerfile.local new file mode 100644 index 0000000000..b0d52e02dc --- /dev/null +++ b/packages/core/Dockerfile.local @@ -0,0 +1,29 @@ +FROM node:22.14-slim +ARG APP_PATH=packages/core + +# curl is needed for healthcheck +RUN apt-get update && apt-get install -y curl + +WORKDIR /usr/src/app + +# Copy expected yarn dist +COPY .yarn ./.yarn +COPY .yarnrc.yml ./ + +# Copy files for deps installation +COPY package.json yarn.lock ./ +COPY ${APP_PATH}/package.json ./${APP_PATH}/ + +RUN yarn install + +# Copy base TS config that is required to build package +COPY tsconfig.base.json ./ +# Copy package itself +COPY packages/core ./packages/core + +WORKDIR ./${APP_PATH} + +RUN yarn build + +EXPOSE 8545 +CMD yarn local diff --git a/packages/core/package.json b/packages/core/package.json index 1d41ca699f..e86c6d50f4 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -18,6 +18,8 @@ "test": "hardhat test", "test:coverage": "hardhat coverage", "local": "concurrently --hide 0 \"hardhat node --hostname 0.0.0.0\" \"yarn deploy:local\"", + "local:liveness": "sh ./scripts/local-healthcheck.sh liveness", + "local:readiness": "sh ./scripts/local-healthcheck.sh readiness", "deploy": "hardhat run scripts/deploy.ts", "deploy:local": "yarn deploy --network localhost", "deploy:proxy": "hardhat run scripts/deploy-proxies.ts", diff --git a/packages/core/scripts/local-healthcheck.sh b/packages/core/scripts/local-healthcheck.sh new file mode 100755 index 0000000000..7b38b75058 --- /dev/null +++ b/packages/core/scripts/local-healthcheck.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +PORT="${PORT:-8545}" +RPC_URL="http://localhost:$PORT" + +liveness() { + echo "Waiting for $RPC_URL to respond with its version" + while true + do + RESPONSE_BODY=$(curl -s -X POST "$RPC_URL" -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":1}') + RPC_VERSION=$(echo "$RESPONSE_BODY" | grep -o '"result":"[^"]*"' | awk -F'"' '{print $4}') + + if [ -n "$RPC_VERSION" ]; then + echo "RPC is live: $RPC_VERSION" + break + fi + + echo "Waiting..." + sleep 2 + done +} + +# Using a magic nubmer of 23 here because this is a block number when local node is ready to use +READINESS_BLOCK_NUMBER=23 + +readiness() { + echo "Waiting for $RPC_URL to reach the desired block #$READINESS_BLOCK_NUMBER" + while true + do + RESPONSE_BODY=$(curl -s -X POST "$RPC_URL" -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}') + BLOCK_NUMBER_HEX=$(echo "$RESPONSE_BODY" | grep -o '"result":"[^"]*"' | awk -F'"' '{print $4}') + BLOCK_NUMBER=$((BLOCK_NUMBER_HEX)) + + if [ "$BLOCK_NUMBER" -ge $READINESS_BLOCK_NUMBER ]; then + echo "RPC is ready" + break + fi + + echo "Waiting..." + sleep 2 + done +} + +# Call the function passed as the first argument +"$@" diff --git a/packages/examples/cvat/exchange-oracle/docker-compose.dev.yml b/packages/examples/cvat/exchange-oracle/docker-compose.dev.yml index cce17d493e..065297be48 100644 --- a/packages/examples/cvat/exchange-oracle/docker-compose.dev.yml +++ b/packages/examples/cvat/exchange-oracle/docker-compose.dev.yml @@ -59,7 +59,7 @@ services: minio-mc: container_name: minio-mc - image: minio/mc + image: minio/mc:RELEASE.2022-06-10T22-29-12Z depends_on: minio: condition: service_healthy diff --git a/packages/examples/cvat/exchange-oracle/docker-compose.test.yml b/packages/examples/cvat/exchange-oracle/docker-compose.test.yml index b0008b65e7..f6a1ad6e3d 100644 --- a/packages/examples/cvat/exchange-oracle/docker-compose.test.yml +++ b/packages/examples/cvat/exchange-oracle/docker-compose.test.yml @@ -50,7 +50,7 @@ services: minio-mc: container_name: minio-mc - image: minio/mc + image: minio/mc:RELEASE.2022-06-10T22-29-12Z depends_on: minio: condition: service_healthy diff --git a/packages/examples/cvat/recording-oracle/README.MD b/packages/examples/cvat/recording-oracle/README.MD index c7c4e6ad1a..55faf0c916 100644 --- a/packages/examples/cvat/recording-oracle/README.MD +++ b/packages/examples/cvat/recording-oracle/README.MD @@ -19,14 +19,14 @@ For deployment it is required to have PostgreSQL(v14.4) ### Run the oracle locally: ``` -docker-compose -f docker-compose.dev.yml up -d +docker compose -f docker-compose.dev.yml up -d ./bin/start_dev.sh ``` or ``` -docker-compose -f docker-compose.dev.yml up -d +docker compose -f docker-compose.dev.yml up -d ./bin/start_debug.sh ``` @@ -70,5 +70,5 @@ Available at `/docs` route To run tests ``` -docker-compose -f docker-compose.test.yml up --build test --attach test --exit-code-from test +docker compose -f docker-compose.test.yml up --build test --attach test --exit-code-from test ``` diff --git a/packages/examples/cvat/recording-oracle/docker-compose.test.yml b/packages/examples/cvat/recording-oracle/docker-compose.test.yml index 1afd482cee..78864bc313 100644 --- a/packages/examples/cvat/recording-oracle/docker-compose.test.yml +++ b/packages/examples/cvat/recording-oracle/docker-compose.test.yml @@ -14,13 +14,12 @@ services: blockchain-node: build: context: ../../../../ - dockerfile: packages/examples/cvat/recording-oracle/dockerfiles/blockchain-node.Dockerfile + dockerfile: packages/core/Dockerfile.local healthcheck: - # Using a magic nubmer of 23 here because this is a block number when blockchain-node container is ready to use - test: if [ $(( $(wget -q --post-data='{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' -O- http://localhost:8545 | grep -o '"result":"[^"]*"' | awk -F'"' '{print $4}' ) )) -ge 23 ]; then exit 0; else exit 1; fi + test: yarn local:readiness interval: 15s - timeout: 5s - retries: 5 + timeout: 30s + retries: 0 networks: - test-network @@ -46,7 +45,7 @@ services: minio-mc: container_name: minio-mc - image: minio/mc + image: minio/mc:RELEASE.2022-06-10T22-29-12Z depends_on: minio: condition: service_healthy diff --git a/packages/examples/cvat/recording-oracle/dockerfiles/blockchain-node.Dockerfile b/packages/examples/cvat/recording-oracle/dockerfiles/blockchain-node.Dockerfile index e56d03e5c9..a12cd5271c 100644 --- a/packages/examples/cvat/recording-oracle/dockerfiles/blockchain-node.Dockerfile +++ b/packages/examples/cvat/recording-oracle/dockerfiles/blockchain-node.Dockerfile @@ -1,8 +1,8 @@ # TODO: make this shared and part of local setup FROM node:22.14-slim -# wget is needed for healthcheck -RUN apt-get update && apt-get install -y wget +# curl is needed for healthcheck +RUN apt-get update && apt-get install -y curl WORKDIR /usr/src/app diff --git a/packages/sdk/typescript/human-protocol-sdk/example/local-node.ts b/packages/sdk/typescript/human-protocol-sdk/example/local-node.ts new file mode 100644 index 0000000000..74e3ea049d --- /dev/null +++ b/packages/sdk/typescript/human-protocol-sdk/example/local-node.ts @@ -0,0 +1,83 @@ +import { Wallet, ethers } from 'ethers'; +import { setTimeout } from 'timers/promises'; + +import { ChainId } from '../src/enums'; +import { KVStoreClient, KVStoreUtils } from '../src/kvstore'; + +const LOCALHOST_RPC_URL = 'http://localhost:8545'; + +/** + * Default is last signer account of local hardhat node. + */ +const PRIVATE_KEY = + process.env.PRIVATE_KEY || + '0xdf57089febbacf7ba0bc227dafbffa9fc08a93fdc68e1e42411a14efcf23656e'; + +const CREATED_AT_KV_KEY = 'created_at'; +const UPDATED_AT_KV_KEY = 'last_touched_at'; +const TOUCHED_TIMES_KV_KEY = 'touches_count'; + +const run = async () => { + const provider = new ethers.JsonRpcProvider(LOCALHOST_RPC_URL); + const wallet = new Wallet(PRIVATE_KEY, provider); + + const walletAddress = wallet.address; + console.log(`Wallet address: ${walletAddress}`); + + const kvStoreClient = await KVStoreClient.build(wallet); + const currentDate = new Date().toISOString(); + + const existingKeys = await KVStoreUtils.getKVStoreData( + ChainId.LOCALHOST, + walletAddress + ); + + if (existingKeys.length === 0) { + console.log('No KV data; initializing'); + await kvStoreClient.setBulk( + [CREATED_AT_KV_KEY, TOUCHED_TIMES_KV_KEY], + [currentDate, '0'] + ); + } else { + console.log('KV data found; updating'); + const touchedTimesData = existingKeys.find( + (d) => d.key === TOUCHED_TIMES_KV_KEY + ) || { value: '0' }; + + let touchedTimes = Number(touchedTimesData.value); + + if (!Number.isSafeInteger(touchedTimes)) { + touchedTimes = 0; + } + touchedTimes += 1; + + await kvStoreClient.setBulk( + [UPDATED_AT_KV_KEY, TOUCHED_TIMES_KV_KEY], + [currentDate, touchedTimes.toString()] + ); + } + + console.log('Finished setting values in KV store. Wait and read'); + /** + * Usually data is indexed almost immediately on local subgraph, + * but there might be a delay if machine is slow or loaded, + * so adding small delay here as well just in case. + */ + await setTimeout(1000 * 2); + + const kvData = await KVStoreUtils.getKVStoreData( + ChainId.LOCALHOST, + walletAddress + ); + console.log('Final KV store data:', kvData); +}; + +(async () => { + try { + await run(); + process.exit(0); + } catch (error) { + console.log('Failed', error); + process.exit(1); + } +})(); diff --git a/packages/sdk/typescript/human-protocol-sdk/package.json b/packages/sdk/typescript/human-protocol-sdk/package.json index 8c5060ab0f..c1a59d5d76 100644 --- a/packages/sdk/typescript/human-protocol-sdk/package.json +++ b/packages/sdk/typescript/human-protocol-sdk/package.json @@ -52,6 +52,7 @@ "devDependencies": { "eslint": "^8.55.0", "prettier": "^3.4.2", + "ts-node": "^10.9.2", "typedoc": "^0.28.4", "typedoc-plugin-markdown": "^4.2.3", "typescript": "^5.8.3" diff --git a/packages/sdk/typescript/human-protocol-sdk/src/utils.ts b/packages/sdk/typescript/human-protocol-sdk/src/utils.ts index 4cff1453ed..c687293e3c 100644 --- a/packages/sdk/typescript/human-protocol-sdk/src/utils.ts +++ b/packages/sdk/typescript/human-protocol-sdk/src/utils.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { ethers } from 'ethers'; +import { ChainId } from './enums'; import { ContractExecutionError, EthereumError, @@ -66,7 +67,7 @@ export const getSubgraphUrl = (networkData: NetworkData) => { SUBGRAPH_API_KEY_PLACEHOLDER, process.env.SUBGRAPH_API_KEY ); - } else { + } else if (networkData.chainId !== ChainId.LOCALHOST) { // eslint-disable-next-line no-console console.warn(WarnSubgraphApiKeyNotProvided); } diff --git a/packages/sdk/typescript/subgraph/README.md b/packages/sdk/typescript/subgraph/README.md index f41e99f4ed..5d0357cc2b 100644 --- a/packages/sdk/typescript/subgraph/README.md +++ b/packages/sdk/typescript/subgraph/README.md @@ -26,9 +26,42 @@ To get more information about how the graph works : Package installation ``` -yarn install +yarn install && yarn workspace human-protocol build:core ``` +## Development +### Tests + +To run tests next commands should be executed: + +```bash +NETWORK=polygon yarn generate + +yarn codegen + +yarn build + +yarn test +``` + +### e2e test using local node +You can e2e test subgraph changes by running blockchain and graph node locally. To do so, first you will need to run necessary infra in Docker: +```bash +yarn workspace human-protocol docker:web3-up +``` +> In case you already have such infra running and want a clean start w/o previous data - run `yarn workspace human-protocol docker:web3-down` first + +After you have the infra running: +```bash +# Generate artifacts for running subgraph on localhost +NETWORK=localhost yarn generate +# Create graph for localhost +yarn create-local +# Deploy the graph +yarn deploy-local +``` +After that subgraph should be available on `http://0.0.0.0:8000/subgraphs/name/humanprotocol/localhost` + ## 🏊 Deploying graphs for live networks 1. Generate & deploy on matic @@ -49,20 +82,6 @@ You can access it on `http://localhost:8020/` The deployment of the graph on each network is automatically triggered by the github CI when mofications are made on the subgraph. -### Tests - -To run tests next commands should be executed: - -```bash -NETWORK=polygon yarn generate - -yarn codegen - -yarn build - -yarn test -``` - ### Supported networks Following networks are supported : diff --git a/packages/sdk/typescript/subgraph/docker-compose.yml b/packages/sdk/typescript/subgraph/docker-compose.yml deleted file mode 100644 index 4a95d4a5f8..0000000000 --- a/packages/sdk/typescript/subgraph/docker-compose.yml +++ /dev/null @@ -1,46 +0,0 @@ -version: '3' -services: - graph-node: - hostname: graph-node - image: graphprotocol/graph-node - ports: - - 8000:8000 - - 8001:8001 - - 8020:8020 - - 8030:8030 - - 8040:8040 - depends_on: - - ipfs - - postgres - # extra_hosts: - # - host.docker.internal:host-gateway - environment: - postgres_host: postgres - postgres_user: graph-node - postgres_pass: let-me-in - postgres_db: graph-node - ipfs: 'ipfs:5001' - ethereum: 'localhost:http://host.docker.internal:8545' - GRAPH_LOG: info - ipfs: - hostname: ipfs - image: ipfs/kubo:v0.14.0 - ports: - - 5010:5001 - postgres: - hostname: postgres - image: postgres:14 - ports: - - 5435:5432 - command: - [ - "postgres", - "-cshared_preload_libraries=pg_stat_statements", - "-cmax_connections=200" - ] - environment: - POSTGRES_USER: graph-node - POSTGRES_PASSWORD: let-me-in - POSTGRES_DB: graph-node - PGDATA: "/var/lib/postgresql/data" - POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C" \ No newline at end of file diff --git a/packages/sdk/typescript/subgraph/local-graph-status.sh b/packages/sdk/typescript/subgraph/local-graph-status.sh new file mode 100755 index 0000000000..4025b2cfa7 --- /dev/null +++ b/packages/sdk/typescript/subgraph/local-graph-status.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +GRAPHQL_URL="http://localhost:8030/graphql" + + +node_health() { + RESPONSE_BODY=$(curl -s -X POST "$GRAPHQL_URL" -H 'Content-Type: application/json' --data '{"query": "{ version { version } }"}') + VERSION=$(echo "$RESPONSE_BODY" | grep -o '"version":"[^"]*"' | awk -F'"' '{print $4}') + + if [ -n "$VERSION" ]; then + echo "Graph node is healthy. Version is $VERSION" + exit 0 + else + echo "Graph node is not healthy" + exit 1 + fi +} + +subgraph_health() { + if [ -z "$SUBGRAPH_NAME" ]; then + echo "Error: SUBGRAPH_NAME environment variable is not set" + exit 1 + fi + + RESPONSE_BODY=$(curl -s -X POST "$GRAPHQL_URL" -H 'Content-Type: application/json' --data "{ \"query\": \"{indexingStatusForCurrentVersion(subgraphName: \\\"$SUBGRAPH_NAME\\\") { health } }\" }") + STATUS=$(echo "$RESPONSE_BODY" | grep -o '"health":"[^"]*"' | awk -F'"' '{print $4}') + + if [[ "$STATUS" == "healthy" ]]; then + echo "Subgraph is healthy" + exit 0 + else + echo "Subgraph is not healthy: $STATUS" + exit 1 + fi +} + +# Call the function passed as the first argument +"$@" diff --git a/packages/sdk/typescript/subgraph/package.json b/packages/sdk/typescript/subgraph/package.json index 422205b212..9978300489 100644 --- a/packages/sdk/typescript/subgraph/package.json +++ b/packages/sdk/typescript/subgraph/package.json @@ -18,11 +18,11 @@ "create-local": "graph create --node http://localhost:8020/ humanprotocol/localhost", "remove-local": "graph remove --node http://localhost:8020/ humanprotocol/localhost", "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5010 humanprotocol/localhost -l 0", + "health-local:node": "sh ./local-graph-status.sh node_health", + "health-local:subgraph": "SUBGRAPH_NAME=humanprotocol/localhost sh ./local-graph-status.sh subgraph_health", "lint": "eslint .", "lint:fix": "eslint . --fix", - "format": "prettier --write '**/*.{ts,json,graphql}'", - "local:node:up": "sleep 3 && docker compose up -d && NETWORK=localhost yarn generate && sleep 10 && yarn create-local && yarn deploy-local", - "local:node:down": "docker compose down" + "format": "prettier --write '**/*.{ts,json,graphql}'" }, "repository": { "type": "git", diff --git a/scripts/Makefile b/scripts/Makefile deleted file mode 100644 index d8c6d6f6bd..0000000000 --- a/scripts/Makefile +++ /dev/null @@ -1,102 +0,0 @@ -.PHONY: check-file fortune - -check-core-folders: - @if [ ! -d "../packages/core/abis/legacy" ] || [ ! -d "../packages/core/typechain-types" ]; then \ - yarn workspace human-protocol build:libs; \ - fi - -create-env-files: - @if [ ! -f "../packages/apps/job-launcher/server/.env.local" ]; then \ - cp ./fortune/.env.jl-server ../packages/apps/job-launcher/server/.env.local ; \ - fi - - @if [ ! -f "../packages/apps/job-launcher/client/.env.local" ]; then \ - cp ./fortune/.env.jl-client ../packages/apps/job-launcher/client/.env.local ; \ - fi - - @if [ ! -f "../packages/apps/fortune/exchange-oracle/server/.env.local" ]; then \ - cp ./fortune/.env.exco-server ../packages/apps/fortune/exchange-oracle/server/.env.local ; \ - fi - - @if [ ! -f "../packages/apps/fortune/recording-oracle/.env.local" ]; then \ - cp ./fortune/.env.rec-oracle ../packages/apps/fortune/recording-oracle/.env.local ; \ - fi - - @if [ ! -f "../packages/apps/reputation-oracle/server/.env.local" ]; then \ - cp ./fortune/.env.rep-oracle ../packages/apps/reputation-oracle/server/.env.local ; \ - fi - -hardhat-node: - yarn workspace @human-protocol/core local - -subgraph: - docker compose -f ./fortune/docker-compose.yml up -d graph-node - NETWORK=localhost yarn workspace @human-protocol/subgraph generate - @while [ $$(docker inspect --format='{{.State.Health.Status}}' graph-node) != "healthy" ]; do \ - sleep 2; \ - done; \ - echo "Container is healthy." - yarn workspace @human-protocol/subgraph create-local - yarn workspace @human-protocol/subgraph deploy-local - -minio: - docker compose -f ./fortune/docker-compose.yml up -d minio-mc - -database: - docker compose -f ./fortune/docker-compose.yml up -d postgres - -job-launcher-server: rpc-health-check - yarn workspace @human-protocol/job-launcher-server setup:local - NODE_ENV=local yarn workspace @human-protocol/job-launcher-server migration:run - NODE_ENV=local yarn workspace @human-protocol/job-launcher-server start:dev - -job-launcher-client: - NODE_ENV=local yarn workspace @human-protocol/job-launcher-client start - -fortune-exchange-oracle: rpc-health-check - yarn workspace @human-protocol/fortune-exchange-oracle-server setup:local - NODE_ENV=local yarn workspace @human-protocol/fortune-exchange-oracle-server migration:run - NODE_ENV=local yarn workspace @human-protocol/fortune-exchange-oracle-server start:dev - -fortune-recording-oracle: rpc-health-check - yarn workspace @human-protocol/fortune-recording-oracle setup:local - NODE_ENV=local yarn workspace @human-protocol/fortune-recording-oracle start:dev - -reputation-oracle: rpc-health-check - yarn workspace @human-protocol/reputation-oracle setup:local - NODE_ENV=local yarn workspace @human-protocol/reputation-oracle migration:run - NODE_ENV=local yarn workspace @human-protocol/reputation-oracle start:dev - -rpc-health-check: - @until curl -s -X POST "http://localhost:8545" -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":1}' | grep -q "result"; do \ - sleep 2; \ - done - -fortune: check-core-folders minio - @echo "RUNNING FORTUNE..." - @trap 'echo "STOPPING FORTUNE.."; kill -9 $$PID_HARDHAT $$PID_JL_CLIENT $$PID_JL_SERVER $$PID_EXO $$PID_RECO $$PID_REPO; docker compose -f ./fortune/docker-compose.yml down; exit 0' SIGINT ERR; \ - $(MAKE) hardhat-node & PID_HARDHAT=$$!; \ - $(MAKE) job-launcher-client & PID_JL_CLIENT=$$!; \ - $(MAKE) job-launcher-server & PID_JL_SERVER=$$!; \ - $(MAKE) fortune-exchange-oracle & PID_EXO=$$!; \ - $(MAKE) fortune-recording-oracle & PID_RECO=$$!; \ - $(MAKE) reputation-oracle & PID_REPO=$$!; \ - $(MAKE) subgraph & \ - wait - -web3-subgraph: - docker compose -f ./web3/docker-compose.yml up -d graph-node - NETWORK=localhost yarn workspace @human-protocol/subgraph generate - @while [ $$(docker inspect --format='{{.State.Health.Status}}' graph-node) != "healthy" ]; do \ - sleep 2; \ - done; \ - echo "Container is healthy." - yarn workspace @human-protocol/subgraph create-local - yarn workspace @human-protocol/subgraph deploy-local - -web3: check-core-folders - @echo "RUNNING WEB3..." - @trap 'echo "STOPPING WEB3.."; kill -9 $$PID_HARDHAT; docker compose -f ./web3/docker-compose.yml down; exit 0' SIGINT ERR; \ - $(MAKE) hardhat-node & PID_HARDHAT=$$!; \ - $(MAKE) web3-subgraph & \ - wait diff --git a/scripts/README.md b/scripts/README.md deleted file mode 100644 index 3d48a5e42c..0000000000 --- a/scripts/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# LOCAL ENVIRONMENT SETUP SCRIPTS - -## Fortune - -### Command: `make fortune` - -Previous steps: -- Run `make create-env-files` -- Edit `../packages/apps/job-launcher/server/.env.local`: - - Set a working key for `SENDGRID_API_KEY`. - - Set a working key for `STRIPE_SECRET_KEY` in case Stripe is needed. -- Edit `../packages/apps/job-launcher/client/.env.local`: - - Set a working key for `VITE_APP_STRIPE_PUBLISHABLE_KEY` in case Stripe is needed. - - -This command runs the following services: -- Hardhat node: port 8545 -- Subgraph node: http://localhost:8000/subgraphs/name/humanprotocol/localhost -- Postgres database: port 5432 -- IPFS: port 5010 -- Minio bucket: http://localhost:9001 (user: access-key, password: secret-key) -- Job Launcher Client: http://localhost:3005 -- Job Launcher Server: http://localhost:5000/swagger - - diff --git a/scripts/fortune-all-local.sh b/scripts/fortune-all-local.sh new file mode 100755 index 0000000000..55b568b37e --- /dev/null +++ b/scripts/fortune-all-local.sh @@ -0,0 +1,141 @@ +#!/bin/sh +set +x + +check_core_folders() { + SCRIPT_PATH="$0" + PROJECT_ROOT=$(cd "$(dirname "$SCRIPT_PATH")" && cd .. && pwd) + CORE_DIR="$PROJECT_ROOT/packages/core" + + if [ ! -d "$CORE_DIR/abis/legacy" ] || [ ! -d "$CORE_DIR/typechain-types" ]; then + echo "Libs are not built, building..." + yarn workspace human-protocol build:libs; + fi +} + +deploy_subgraph() { + echo "Waiting for graph node to be healthy..." + retries=0 + while ! yarn workspace @human-protocol/subgraph health-local:node + do + ((retries++)) + if [ "$retries" -ge 10 ]; then + exit 1 + fi + sleep 2; + done; + + echo "Deploying subgraph..." + + NETWORK=localhost yarn workspace @human-protocol/subgraph generate + yarn workspace @human-protocol/subgraph create-local + yarn workspace @human-protocol/subgraph deploy-local +} + +setup_oracles() { + echo "Setting up oracles..." + # It's important to run these commands sequentially + # to successfully execute all parallel blockchain transactions + # that might conflict on same nonce value + echo "Setup JL" && yarn workspace @human-protocol/job-launcher-server setup:local + echo "Setup RepO" && yarn workspace @human-protocol/reputation-oracle setup:local + echo "Setup ExcO" && yarn workspace @human-protocol/fortune-exchange-oracle-server setup:local + echo "Setup RecO" && yarn workspace @human-protocol/fortune-recording-oracle setup:local + + echo "Oracles successfully set up" +} + +run_jl_server() { + NODE_ENV=local yarn workspace @human-protocol/job-launcher-server migration:run + NODE_ENV=local yarn workspace @human-protocol/job-launcher-server start:dev +} + +run_jl_client() { + NODE_ENV=local yarn workspace @human-protocol/job-launcher-client start +} + +run_reputation_oracle() { + NODE_ENV=local yarn workspace @human-protocol/reputation-oracle migration:run + NODE_ENV=local yarn workspace @human-protocol/reputation-oracle start:dev +} + +run_fortune_exchange_oracle() { + NODE_ENV=local yarn workspace @human-protocol/fortune-exchange-oracle-server migration:run + NODE_ENV=local yarn workspace @human-protocol/fortune-exchange-oracle-server start:dev +} + +run_fortune_recording_oracle() { + NODE_ENV=local yarn workspace @human-protocol/fortune-recording-oracle start:dev +} + +full_run() { + check_core_folders + + echo "Running Fortune w/ deps locally" + + # Run web3 infra + yarn workspace human-protocol docker:web3-up + + deploy_subgraph + + # Run services infra + yarn workspace human-protocol docker:infra-up + + setup_oracles + + # Run services + run_jl_client & + PID_JL_CLIENT=$! + + run_jl_server & + PID_JL_SERVER=$! + + run_reputation_oracle & + PID_REPO=$! + + run_fortune_exchange_oracle & + PID_EXO=$! + + run_fortune_recording_oracle & + PID_RECO=$! + + echo "Running..." +} + +shutdown() { + # Ignore subsequent Ctrl+C to properly shutdown + trap '' SIGINT + echo "\nShutting down Fortune w/ deps" + + PIDS="$PID_JL_CLIENT $PID_JL_SERVER $PID_REPO $PID_EXO $PID_RECO" + # Graceful shutdown + for PID in $PIDS + do + kill -SIGINT "$PID" 2>/dev/null + done + + echo "Waiting for apps graceful shutdown" + # Wait for a while + sleep 5 + + # After waiting kill any still alive + for PID in $PIDS + do + if kill -0 "$PID" 2>/dev/null; then + kill -SIGKILL "$PID" + fi + done + + echo "Shutting down docker deps" + yarn workspace human-protocol docker:web3-down || true + yarn workspace human-protocol docker:infra-down || true + + echo "Shutdown finished" + exit 0 +} + +trap shutdown SIGINT ERR + +full_run + +# wait for Ctrl+C +wait diff --git a/scripts/fortune/.env.exco-server b/scripts/fortune/.env.exco-server deleted file mode 100644 index 2c44b1fc02..0000000000 --- a/scripts/fortune/.env.exco-server +++ /dev/null @@ -1,28 +0,0 @@ -# General -NODE_ENV=development -PORT=5001 -CRON_SECRET=secret - -# Database -POSTGRES_HOST=0.0.0.0 -POSTGRES_USER=default -POSTGRES_PASSWORD=qwerty -POSTGRES_DATABASE=exchange-oracle -POSTGRES_PORT=5432 -POSTGRES_SSL=false -POSTGRES_LOGGING='all' - -# S3 -S3_ENDPOINT=localhost -S3_PORT=9000 -S3_ACCESS_KEY=access-key -S3_SECRET_KEY=secret-key -S3_BUCKET=bucket -S3_USE_SSL=false - -WEB3_ENV=localhost -WEB3_PRIVATE_KEY=0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a #0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC - -PGP_ENCRYPT=false -# PGP_PRIVATE_KEY= -# PGP_PASSPHRASE= diff --git a/scripts/fortune/.env.jl-client b/scripts/fortune/.env.jl-client deleted file mode 100644 index 86ae686f30..0000000000 --- a/scripts/fortune/.env.jl-client +++ /dev/null @@ -1,7 +0,0 @@ -VITE_APP_JOB_LAUNCHER_SERVER_URL=http://localhost:5000/ -VITE_APP_WALLETCONNECT_PROJECT_ID=68415bedd1597a33e8e83cc53e52071b -VITE_APP_STRIPE_PUBLISHABLE_KEY=pk_test_GvCQRGFcSwDzNE9wBSaH6MbBzk6yUntQp5GSGjDU7VzMpkJpVq32kYx52EBP9t4Gin5UQ9nYwprq7ZRNPTQG4gvdUuTwYEGy7rp -VITE_APP_HCAPTCHA_SITE_KEY=10000000-ffff-ffff-ffff-000000000001 -VITE_APP_HCAPTCHA_EXCHANGE_URL=https://foundation-yellow-exchange.hmt.ai -VITE_APP_HCAPTCHA_LABELING_BASE_URL=https://foundation-yellow-accounts.hmt.ai -VITE_APP_ENVIRONMENT=localhost \ No newline at end of file diff --git a/scripts/fortune/.env.jl-server b/scripts/fortune/.env.jl-server deleted file mode 100644 index dbb026aa83..0000000000 --- a/scripts/fortune/.env.jl-server +++ /dev/null @@ -1,76 +0,0 @@ -# General -NODE_ENV=development -HOST=localhost -PORT=5000 -FE_URL=http://localhost:3002 -SESSION_SECRET=test - -# Database -POSTGRES_HOST=0.0.0.0 -POSTGRES_USER=default -POSTGRES_PASSWORD=qwerty -POSTGRES_DATABASE=job-launcher -POSTGRES_DB=job-launcher -POSTGRES_PORT=5432 -POSTGRES_SSL=false -POSTGRES_LOGGING='all' - -# Web3 -WEB3_ENV=localhost -WEB3_PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d #0x70997970C51812dc3A010C7d01b50e0d17dc79C8 -GAS_PRICE_MULTIPLIER=1 -# PGP_PRIVATE_KEY= -PGP_ENCRYPT=false -# PGP_PASSPHRASE= -CVAT_EXCHANGE_ORACLE_ADDRESS=0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC -CVAT_RECORDING_ORACLE_ADDRESS=0x90F79bf6EB2c4f870365E785982E1f101E93b906 -REPUTATION_ORACLE_ADDRESS=0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65 -HCAPTCHA_RECORDING_ORACLE_URI=a -HCAPTCHA_REPUTATION_ORACLE_URI=a -HCAPTCHA_ORACLE_ADDRESS=a -HCAPTCHA_SITE_KEY=a - -# Auth -HASH_SECRET=a328af3fc1dad15342cc3d68936008fa -JWT_PRIVATE_KEY="-----BEGIN EC PARAMETERS----- -BggqhkjOPQMBBw== ------END EC PARAMETERS----- ------BEGIN EC PRIVATE KEY----- -MHcCAQEEID2jVcOtjupW4yqNTz70nvmt1GSvqET5G7lpC0Gp31LFoAoGCCqGSM49 -AwEHoUQDQgAEUznVCoagfRCuMA3TfG51xWShNrMJt86lkzfAep9bfBxbaCBbUhJ1 -s9+9eeLMG/nUMAaGxWeOwJ92L/KvzN6RFw== ------END EC PRIVATE KEY-----" -JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUznVCoagfRCuMA3TfG51xWShNrMJ -t86lkzfAep9bfBxbaCBbUhJ1s9+9eeLMG/nUMAaGxWeOwJ92L/KvzN6RFw== ------END PUBLIC KEY-----" -JWT_ACCESS_TOKEN_EXPIRES_IN=600 -JWT_REFRESH_TOKEN_EXPIRES_IN=3600 - -# APIKEY -# APIKEY_ITERATIONS= -# APIKEY_KEY_LENGTH= - -# S3 -S3_ENDPOINT=localhost -S3_PORT=9000 -S3_ACCESS_KEY=access-key -S3_SECRET_KEY=secret-key -S3_BUCKET=bucket -S3_USE_SSL=false - -MINIO_ROOT_USER=access-key -MINIO_ROOT_PASSWORD=secrets-key - -# Stripe -STRIPE_SECRET_KEY=sk_test_GvCQRGFcSwDzNE9wBSaH6MbBzk6yUntQp5GSGjDU7VzMpkJpVq32kYx52EBP9t4Gin5UQ9nYwprq7ZRNPTQG4gvdUuTwYEGy7rp -STRIPE_API_VERSION=2022-11-15 -STRIPE_APP_NAME=Staging Launcher Server -STRIPE_APP_VERSION=1.0.0 -STRIPE_APP_INFO_URL=https://github.com/humanprotocol/human-protocol/tree/main/packages/apps/job-launcher/server - -#Sendgrid -SENDGRID_API_KEY=sendgrid-disabled - -#Cron jobs secret -CRON_SECRET=secret \ No newline at end of file diff --git a/scripts/fortune/.env.rec-oracle b/scripts/fortune/.env.rec-oracle deleted file mode 100644 index b75f2f6047..0000000000 --- a/scripts/fortune/.env.rec-oracle +++ /dev/null @@ -1,18 +0,0 @@ -# General -NODE_ENV=development -PORT=5002 -SESSION_SECRET=secret - -# S3 -S3_ENDPOINT=localhost -S3_PORT=9000 -S3_ACCESS_KEY=access-key -S3_SECRET_KEY=secret-key -S3_BUCKET=bucket -S3_USE_SSL=false - -WEB3_PRIVATE_KEY=0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6 #0x90F79bf6EB2c4f870365E785982E1f101E93b906 - -PGP_ENCRYPT=false -# PGP_PRIVATE_KEY= -# PGP_PASSPHRASE= diff --git a/scripts/fortune/.env.rep-oracle b/scripts/fortune/.env.rep-oracle deleted file mode 100644 index 28866f5c7e..0000000000 --- a/scripts/fortune/.env.rep-oracle +++ /dev/null @@ -1,68 +0,0 @@ -# General -NODE_ENV=development -HOST=localhost -PORT=5003 -SESSION_SECRET=test -MAX_RETRY_COUNT=5 -CRON_SECRET=secret - -# Database -POSTGRES_HOST=0.0.0.0 -POSTGRES_USER=default -POSTGRES_PASSWORD=qwerty -POSTGRES_DATABASE=reputation-oracle -POSTGRES_DB=reputation-oracle -POSTGRES_PORT=5432 -POSTGRES_SSL=false -POSTGRES_LOGGING='all' - -# Auth -HASH_SECRET=a328af3fc1dad15342cc3d68936008fa -JWT_PRIVATE_KEY="-----BEGIN EC PARAMETERS----- -BggqhkjOPQMBBw== ------END EC PARAMETERS----- ------BEGIN EC PRIVATE KEY----- -MHcCAQEEIHGJVym8HlDFqIq7VWYSzfVG2/sW5qLrihq2g6ssRLQ0oAoGCCqGSM49 -AwEHoUQDQgAEmxypAnb2RpdFhhOfY4JpfKG1SlH7pDsp3Y6apiRBPO7DXgmBrwY3 -cljrl3cdbeEgkp5SSYBGSdoGDsce8NnQdA== ------END EC PRIVATE KEY-----" -JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmxypAnb2RpdFhhOfY4JpfKG1SlH7 -pDsp3Y6apiRBPO7DXgmBrwY3cljrl3cdbeEgkp5SSYBGSdoGDsce8NnQdA== ------END PUBLIC KEY-----" -JWT_ACCESS_TOKEN_EXPIRES_IN=600 -JWT_REFRESH_TOKEN_EXPIRES_IN=3600 - -# S3 -S3_ENDPOINT=localhost -S3_PORT=9000 -S3_ACCESS_KEY=access-key -S3_SECRET_KEY=secret-key -S3_BUCKET=bucket -S3_USE_SSL=false - -# Sendgrid -SENDGRID_API_KEY=sendgrid-disabled -SENDGRID_FROM_EMAIL=reputation-oracle@hmt.ai -SENDGRID_FROM_NAME="Human Protocol Reputation Oracle" - -# Web3 -WEB3_ENV=localhost -WEB3_PRIVATE_KEY=0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a #0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65 -GAS_PRICE_MULTIPLIER=1 - -# Reputation Level -REPUTATION_LEVEL_LOW=300 -REPUTATION_LEVEL_HIGH=700 - -# Encryption -# ENCRYPTION_PRIVATE_KEY= -# ENCRYPTION_PASSPHRASE= -PGP_ENCRYPT=false - -# Synaps Kyc -SYNAPS_API_KEY=synaps-disabled -SYNAPS_WEBHOOK_SECRET=test - -HCAPTCHA_SITE_KEY=test -HCAPTCHA_SECRET=test \ No newline at end of file diff --git a/scripts/fortune/docker-compose.yml b/scripts/fortune/docker-compose.yml deleted file mode 100644 index a53d8b0157..0000000000 --- a/scripts/fortune/docker-compose.yml +++ /dev/null @@ -1,89 +0,0 @@ -services: - postgres: - container_name: postgres - image: postgres:latest - restart: always - logging: - options: - max-size: 10m - max-file: "3" - ports: - - 5432:5432 - command: - [ - "postgres", - "-cshared_preload_libraries=pg_stat_statements", - "-cmax_connections=200" - ] - environment: - POSTGRES_HOST: 0.0.0.0 - POSTGRES_USER: default - POSTGRES_PASSWORD: qwerty - POSTGRES_PORT: 5432 - POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C" - volumes: - - ./initdb:/docker-entrypoint-initdb.d - - ./docker-db:/var/lib/postgresql/data - minio: - container_name: minio - image: minio/minio:RELEASE.2022-05-26T05-48-41Z - ports: - - 9001:9001 - - 9000:9000 - entrypoint: 'sh' - command: - -c "mkdir -p /data/bucket && minio server /data --console-address ':9001'" - environment: - MINIO_ROOT_USER: access-key - MINIO_ROOT_PASSWORD: secret-key - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] - interval: 5s - timeout: 5s - retries: 3 - minio-mc: - container_name: minio-mc - image: minio/mc - depends_on: - minio: - condition: service_healthy - entrypoint: > - /bin/sh -c " - /usr/bin/mc config host add myminio http://minio:9000 access-key secret-key; - /usr/bin/mc mb myminio/bucket; - /usr/bin/mc anonymous set public myminio/bucket; - " - graph-node: - container_name: graph-node - hostname: graph-node - image: graphprotocol/graph-node - healthcheck: - test: ["CMD-SHELL", "nc -z localhost 8000 || exit 1"] - interval: 5s - timeout: 5s - retries: 10 - start_period: 10s - ports: - - 8000:8000 - - 8001:8001 - - 8020:8020 - - 8030:8030 - - 8040:8040 - depends_on: - - ipfs - - postgres - extra_hosts: - - host.docker.internal:host-gateway - environment: - postgres_host: postgres - postgres_user: default - postgres_pass: qwerty - postgres_db: graph-node - ipfs: 'ipfs:5001' - ethereum: 'localhost:http://host.docker.internal:8545' - GRAPH_LOG: info - ipfs: - hostname: ipfs - image: ipfs/kubo:v0.14.0 - ports: - - 5010:5001 diff --git a/scripts/fortune/initdb/create-dbs.sql b/scripts/fortune/initdb/create-dbs.sql deleted file mode 100644 index d941350a68..0000000000 --- a/scripts/fortune/initdb/create-dbs.sql +++ /dev/null @@ -1,4 +0,0 @@ -CREATE DATABASE "job-launcher"; -CREATE DATABASE "graph-node"; -CREATE DATABASE "exchange-oracle"; -CREATE DATABASE "reputation-oracle"; \ No newline at end of file diff --git a/scripts/web3/.gitignore b/scripts/web3/.gitignore deleted file mode 100644 index 70512312f3..0000000000 --- a/scripts/web3/.gitignore +++ /dev/null @@ -1 +0,0 @@ -graph-node-db diff --git a/scripts/web3/docker-compose.yml b/scripts/web3/docker-compose.yml deleted file mode 100644 index 97068ac3f5..0000000000 --- a/scripts/web3/docker-compose.yml +++ /dev/null @@ -1,60 +0,0 @@ -version: '3.8' -name: human-protocol -services: - graph-node-db: - container_name: graph-node-db - image: postgres:latest - restart: always - logging: - options: - max-size: 10m - max-file: "3" - ports: - - 5433:5432 - command: - [ - "postgres", - "-cshared_preload_libraries=pg_stat_statements", - "-cmax_connections=200" - ] - environment: - POSTGRES_USER: user - POSTGRES_PASSWORD: password - POSTGRES_DB: graph-node - POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C" - volumes: - - ./graph-node-db:/var/lib/postgresql/data - graph-node: - container_name: graph-node - hostname: graph-node - image: graphprotocol/graph-node - healthcheck: - test: ["CMD-SHELL", "nc -z localhost 8000 || exit 1"] - interval: 5s - timeout: 5s - retries: 10 - start_period: 10s - ports: - - 8000:8000 - - 8001:8001 - - 8020:8020 - - 8030:8030 - - 8040:8040 - depends_on: - - ipfs - - graph-node-db - extra_hosts: - - host.docker.internal:host-gateway - environment: - postgres_host: graph-node-db - postgres_user: user - postgres_pass: password - postgres_db: graph-node - ipfs: 'ipfs:5001' - ethereum: 'localhost:http://host.docker.internal:8545' - GRAPH_LOG: info - ipfs: - hostname: ipfs - image: ipfs/kubo:v0.14.0 - ports: - - 5010:5001 \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 387e52425f..cdce5887c4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4446,6 +4446,7 @@ __metadata: openpgp: "npm:^5.11.2" prettier: "npm:^3.4.2" secp256k1: "npm:^5.0.1" + ts-node: "npm:^10.9.2" typedoc: "npm:^0.28.4" typedoc-plugin-markdown: "npm:^4.2.3" typescript: "npm:^5.8.3"