diff --git a/.changeset/config.json b/.changeset/config.json index 83e90e5dd2..14003dd0c3 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -4,7 +4,7 @@ "access": "public", "baseBranch": "main", "updateInternalDependencies": "patch", - "changelog": false, + "changelog": "@changesets/changelog-git", "bumpVersionsWithWorkspaceProtocolOnly": true, "privatePackages": { "version": true, diff --git a/.github/workflows/cd-deploy-contracts.yaml b/.github/workflows/cd-deploy-contracts.yaml index 324ffdae2d..5d51c20117 100644 --- a/.github/workflows/cd-deploy-contracts.yaml +++ b/.github/workflows/cd-deploy-contracts.yaml @@ -4,10 +4,10 @@ on: workflow_dispatch: inputs: network: - description: 'network' + description: "network" required: true escrowFactory: - description: 'deploy escrow factory' + description: "deploy escrow factory" required: true jobs: @@ -40,7 +40,7 @@ jobs: node-version-file: .nvmrc cache: yarn - name: Install dependencies - run: yarn --immutable + run: yarn workspaces focus @human-protocol/core - name: Build core package run: yarn workspace @human-protocol/core build - name: Networks list @@ -140,9 +140,7 @@ jobs: uses: EndBug/add-and-commit@v9 with: add: "['./packages/core/.openzeppelin']" - message: 'Update upgrade file from CD' + message: "Update upgrade file from CD" default_author: github_actions - tag_push: '--force' + tag_push: "--force" github_token: ${{ secrets.GH_TOKEN_CD_CONTRACTS }} - - diff --git a/.github/workflows/cd-python-sdk.yaml b/.github/workflows/cd-python-sdk.yaml index dca5e340a5..30b69eb072 100644 --- a/.github/workflows/cd-python-sdk.yaml +++ b/.github/workflows/cd-python-sdk.yaml @@ -30,14 +30,10 @@ jobs: run: | git config --global user.name "github-actions[bot]" git config --global user.email "github-actions[bot]@users.noreply.github.com" - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v6 with: node-version-file: .nvmrc cache: yarn - - name: Install JS dependencies - run: yarn install - - name: Build core package - run: yarn workspace @human-protocol/core build - name: Set up Python uses: actions/setup-python@v6 with: diff --git a/.github/workflows/cd-subgraph.yaml b/.github/workflows/cd-subgraph.yaml index 6969c1582c..4bd0f85114 100644 --- a/.github/workflows/cd-subgraph.yaml +++ b/.github/workflows/cd-subgraph.yaml @@ -3,10 +3,10 @@ on: workflow_dispatch: inputs: label: - description: 'New version label' + description: "New version label" required: true networks: - description: 'Comma-separated list of networks to deploy' + description: "Comma-separated list of networks to deploy" required: true jobs: @@ -48,10 +48,10 @@ jobs: echo "::set-output name=continue::$MATCH" - name: Install dependencies if: steps.filter_networks.outputs.continue == 'true' - run: yarn install --immutable - - name: Build core package + run: yarn workspaces focus @tools/subgraph + - name: Build packages (scoped) if: steps.filter_networks.outputs.continue == 'true' - run: yarn workspace @human-protocol/core build + run: yarn workspaces foreach -Rpt --from @tools/subgraph run build - name: Generate and build Subgraph if: steps.filter_networks.outputs.continue == 'true' run: yarn generate && yarn build @@ -61,12 +61,12 @@ jobs: - name: Authenticate & Deploy if: steps.filter_networks.outputs.continue == 'true' env: - API_KEY: ${{ secrets.HP_GRAPH_API_KEY }} - NETWORK: ${{ matrix.network.name }} - LABEL: ${{ github.event.inputs.label }} + API_KEY: ${{ secrets.HP_GRAPH_API_KEY }} + NETWORK: ${{ matrix.network.name }} + LABEL: ${{ github.event.inputs.label }} working-directory: ./packages/sdk/typescript/subgraph run: | yarn dlx @graphprotocol/graph-cli@0.71.2 \ auth --studio "$API_KEY" yarn dlx @graphprotocol/graph-cli@0.71.2 \ - deploy --studio ${NETWORK} -l ${LABEL} \ No newline at end of file + deploy --studio ${NETWORK} -l ${LABEL} diff --git a/.github/workflows/ci-test-core.yaml b/.github/workflows/ci-test-core.yaml index f3bf6c8f9c..a62dd859de 100644 --- a/.github/workflows/ci-test-core.yaml +++ b/.github/workflows/ci-test-core.yaml @@ -2,9 +2,9 @@ name: Protocol check on: push: - branches: '**' + branches: "**" paths: - - 'packages/core/**' + - "packages/core/**" jobs: core-test: @@ -17,6 +17,6 @@ jobs: node-version-file: .nvmrc cache: yarn - name: Install dependencies - run: yarn install --immutable + run: yarn workspaces focus @human-protocol/core - name: Run protocol test run: yarn workspace @human-protocol/core test diff --git a/.github/workflows/ci-test-cvat-recording-oracle.yaml b/.github/workflows/ci-test-cvat-recording-oracle.yaml index 590120a277..2fe2ec5be8 100644 --- a/.github/workflows/ci-test-cvat-recording-oracle.yaml +++ b/.github/workflows/ci-test-cvat-recording-oracle.yaml @@ -2,10 +2,10 @@ name: CVAT Recording Oracle Tests on: push: - branches: '**' + branches: "**" paths: - - 'packages/examples/cvat/recording-oracle/**' - - 'packages/core/**' + - "packages/examples/cvat/recording-oracle/**" + - "packages/core/**" jobs: cvat-exo-test: diff --git a/.github/workflows/ci-test-dashboard.yaml b/.github/workflows/ci-test-dashboard.yaml index 85a1cbdb7a..d09e72eb9b 100644 --- a/.github/workflows/ci-test-dashboard.yaml +++ b/.github/workflows/ci-test-dashboard.yaml @@ -2,7 +2,7 @@ name: Dashboard Check on: push: - branches: '**' + branches: "**" paths: - "packages/core/**" - "packages/sdk/typescript/human-protocol-sdk/**" @@ -19,8 +19,8 @@ jobs: node-version-file: .nvmrc cache: yarn - name: Install dependencies - run: yarn install --immutable - - name: Build libs - run: yarn build:libs + run: yarn workspaces focus @apps/dashboard-server + - name: Build libs (scoped) + run: yarn workspaces foreach -Rpt --from @apps/dashboard-server run build - name: Run dashboard Server test run: yarn workspace @apps/dashboard-server test diff --git a/.github/workflows/ci-test-faucet-server.yaml b/.github/workflows/ci-test-faucet-server.yaml index b93b8e9197..77a63db5b5 100644 --- a/.github/workflows/ci-test-faucet-server.yaml +++ b/.github/workflows/ci-test-faucet-server.yaml @@ -2,7 +2,7 @@ name: Faucet server check on: push: - branches: '**' + branches: "**" paths: - "packages/core/**" - "packages/sdk/typescript/human-protocol-sdk/**" @@ -19,9 +19,9 @@ jobs: node-version-file: .nvmrc cache: yarn - name: Install dependencies - run: yarn install --immutable - - name: Build libs - run: yarn build:libs + run: yarn workspaces focus @apps/faucet-server + - name: Build libs (scoped) + run: yarn workspaces foreach -Rpt --from @apps/faucet-server run build - name: Create .env file run: cp .env.example .env working-directory: packages/apps/faucet/server diff --git a/.github/workflows/ci-test-fortune.yaml b/.github/workflows/ci-test-fortune.yaml index 86df190e5c..516d181e88 100644 --- a/.github/workflows/ci-test-fortune.yaml +++ b/.github/workflows/ci-test-fortune.yaml @@ -2,7 +2,7 @@ name: Fortune check on: push: - branches: '**' + branches: "**" paths: - "packages/core/**" - "packages/sdk/typescript/human-protocol-sdk/**" @@ -19,9 +19,9 @@ jobs: node-version-file: .nvmrc cache: yarn - name: Install dependencies - run: yarn install --immutable - - name: Build libs - run: yarn build:libs + run: yarn workspaces focus @apps/fortune-exchange-oracle-server + - name: Build libs (scoped) + run: yarn workspaces foreach -Rpt --from @apps/fortune-exchange-oracle-server run build - name: Run Exchange Oracle tests run: yarn workspace @apps/fortune-exchange-oracle-server test @@ -35,8 +35,8 @@ jobs: node-version-file: .nvmrc cache: yarn - name: Install dependencies - run: yarn install --immutable - - name: Build libs - run: yarn build:libs + run: yarn workspaces focus @apps/fortune-recording-oracle + - name: Build libs (scoped) + run: yarn workspaces foreach -Rpt --from @apps/fortune-recording-oracle run build - name: Run Recording Oracle tests run: yarn workspace @apps/fortune-recording-oracle test diff --git a/.github/workflows/ci-test-human-app.yaml b/.github/workflows/ci-test-human-app.yaml index 2c32e1c0f1..015043ebe8 100644 --- a/.github/workflows/ci-test-human-app.yaml +++ b/.github/workflows/ci-test-human-app.yaml @@ -2,7 +2,7 @@ name: Human App Check on: push: - branches: '**' + branches: "**" paths: - "packages/core/**" - "packages/sdk/typescript/human-protocol-sdk/**" @@ -19,8 +19,8 @@ jobs: node-version-file: .nvmrc cache: yarn - name: Install dependencies - run: yarn install --immutable - - name: Build libs - run: yarn build:libs + run: yarn workspaces focus @apps/human-app-server + - name: Build libs (scoped) + run: yarn workspaces foreach -Rpt --from @apps/human-app-server run build - name: Run Job Human App unit tests run: yarn workspace @apps/human-app-server test diff --git a/.github/workflows/ci-test-job-launcher.yaml b/.github/workflows/ci-test-job-launcher.yaml index 6c64f8dd2f..c2ca1a5574 100644 --- a/.github/workflows/ci-test-job-launcher.yaml +++ b/.github/workflows/ci-test-job-launcher.yaml @@ -2,7 +2,7 @@ name: Job Launcher Check on: push: - branches: '**' + branches: "**" paths: - "packages/core/**" - "packages/sdk/typescript/human-protocol-sdk/**" @@ -19,8 +19,8 @@ jobs: node-version-file: .nvmrc cache: yarn - name: Install dependencies - run: yarn install --immutable - - name: Build libs - run: yarn build:libs + run: yarn workspaces focus @apps/job-launcher-server + - name: Build libs (scoped) + run: yarn workspaces foreach -Rpt --from @apps/job-launcher-server run build - name: Run Job Launcher Server test run: yarn workspace @apps/job-launcher-server test diff --git a/.github/workflows/ci-test-node-sdk.yaml b/.github/workflows/ci-test-node-sdk.yaml index 3ad8fcd4f3..b549bb1fae 100644 --- a/.github/workflows/ci-test-node-sdk.yaml +++ b/.github/workflows/ci-test-node-sdk.yaml @@ -2,10 +2,10 @@ name: Node.js SDK check on: push: - branches: '**' + branches: "**" paths: - - 'packages/core/**' - - 'packages/sdk/typescript/human-protocol-sdk/**' + - "packages/core/**" + - "packages/sdk/typescript/human-protocol-sdk/**" jobs: node-sdk-test: @@ -18,8 +18,8 @@ jobs: node-version-file: .nvmrc cache: yarn - name: Install dependencies - run: yarn install --immutable - - name: Build core package - run: yarn workspace @human-protocol/core build + run: yarn workspaces focus @human-protocol/sdk + - name: Build packages (scoped) + run: yarn workspaces foreach -Rpt --from @human-protocol/sdk run build - name: Run Node.js SDK test run: yarn workspace @human-protocol/sdk test diff --git a/.github/workflows/ci-test-python-sdk.yaml b/.github/workflows/ci-test-python-sdk.yaml index f5126f610e..e9e31688f7 100644 --- a/.github/workflows/ci-test-python-sdk.yaml +++ b/.github/workflows/ci-test-python-sdk.yaml @@ -2,10 +2,10 @@ name: Python SDK check on: push: - branches: '**' + branches: "**" paths: - - 'packages/core/**' - - 'packages/sdk/python/human-protocol-sdk/**' + - "packages/core/**" + - "packages/sdk/python/human-protocol-sdk/**" jobs: python-test: @@ -13,18 +13,18 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v6 with: node-version-file: .nvmrc cache: yarn - name: Install core package dependencies - run: yarn install --immutable + run: yarn workspaces focus @human-protocol/core - name: Build core package run: yarn workspace @human-protocol/core build - name: Set up Python 3.10 uses: actions/setup-python@v6 with: - python-version: '3.10' + python-version: "3.10" - name: Install pipenv run: pip install pipenv - name: Python test diff --git a/.github/workflows/ci-test-reputation-oracle.yaml b/.github/workflows/ci-test-reputation-oracle.yaml index 0b68888f9e..3d6497c45c 100644 --- a/.github/workflows/ci-test-reputation-oracle.yaml +++ b/.github/workflows/ci-test-reputation-oracle.yaml @@ -2,7 +2,7 @@ name: Reputation Oracle Check on: push: - branches: '**' + branches: "**" paths: - "packages/core/**" - "packages/sdk/typescript/human-protocol-sdk/**" @@ -19,8 +19,8 @@ jobs: node-version-file: .nvmrc cache: yarn - name: Install dependencies - run: yarn install --immutable - - name: Build libs - run: yarn build:libs + run: yarn workspaces focus @apps/reputation-oracle + - name: Build libs (scoped) + run: yarn workspaces foreach -Rpt --from @apps/reputation-oracle run build - name: Run reputation oracle test run: yarn workspace @apps/reputation-oracle test diff --git a/.github/workflows/ci-test-subgraph.yaml b/.github/workflows/ci-test-subgraph.yaml index b02d7e38a0..d569f765f2 100644 --- a/.github/workflows/ci-test-subgraph.yaml +++ b/.github/workflows/ci-test-subgraph.yaml @@ -2,7 +2,7 @@ name: Subgraph check on: push: - branches: '**' + branches: "**" paths: - "packages/core/**" - "packages/sdk/typescript/subgraph/**" @@ -19,7 +19,7 @@ jobs: node-version-file: .nvmrc cache: yarn - name: Install dependencies - run: yarn install --immutable + run: yarn workspaces focus @tools/subgraph - name: Build core package run: yarn workspace @human-protocol/core build - name: Generate manifest for Polygon for tests diff --git a/.github/workflows/release-packages.yaml b/.github/workflows/release-packages.yaml new file mode 100644 index 0000000000..9c166da053 --- /dev/null +++ b/.github/workflows/release-packages.yaml @@ -0,0 +1,108 @@ +name: Create package releases + +permissions: + contents: write + +on: + push: + tags: + - "js/**" + - "python/**" + +jobs: + release: + name: Publish GitHub release for npm package + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Check if release already exists + id: release_check + uses: actions/github-script@v8 + with: + github-token: ${{ secrets.RELEASE_GH_TOKEN }} + script: | + const tag = context.ref.replace('refs/tags/', ''); + try { + const release = await github.rest.repos.getReleaseByTag({ + owner: context.repo.owner, + repo: context.repo.repo, + tag, + }); + core.notice(`Release already exists: ${release.data.html_url}`); + core.setOutput('exists', 'true'); + } catch (error) { + if (error.status === 404) { + core.setOutput('exists', 'false'); + } else { + throw error; + } + } + + - name: Build release body from package CHANGELOG + id: release_body + if: ${{ steps.release_check.outputs.exists != 'true' }} + shell: bash + run: | + set -euo pipefail + + tag="${GITHUB_REF_NAME}" + body_file="${RUNNER_TEMP}/release-body.md" + + if [[ "$tag" != *"@"* ]]; then + echo "Invalid tag '${tag}': missing '@' suffix" >&2 + exit 1 + fi + + version="${tag##*@}" + changelog_path="" + + if [[ "$tag" == js/* ]]; then + pkg_and_version="${tag#js/}" + pkg_name="${pkg_and_version%@*}" + scoped_name="@human-protocol/${pkg_name}" + pkg_json=$(grep -R --include package.json -n "\"name\": \"${scoped_name}\"" packages | head -n 1 | cut -d: -f1 || true) + if [[ -n "$pkg_json" ]]; then + changelog_path="$(dirname "$pkg_json")/CHANGELOG.md" + fi + elif [[ "$tag" == python/* ]]; then + changelog_path="packages/sdk/python/human-protocol-sdk/CHANGELOG.md" + fi + + if [[ -z "$changelog_path" ]]; then + echo "Unable to resolve CHANGELOG.md path for tag '${tag}'" >&2 + exit 1 + fi + + if [[ ! -f "$changelog_path" ]]; then + echo "CHANGELOG.md not found at '${changelog_path}' for tag '${tag}'" >&2 + exit 1 + fi + + # Extract the section for the exact version in the tag. + section_body=$(awk -v ver="$version" ' + $0 ~ "^##[[:space:]]+" ver "[[:space:]]*$" { in_section=1; next } + in_section && $0 ~ "^##[[:space:]]+" { exit } + in_section { print } + ' "$changelog_path" | sed '/./,$!d' || true) + + if [[ -z "$section_body" ]]; then + echo "No CHANGELOG entry found for version '${version}' in '${changelog_path}'" >&2 + exit 1 + fi + + printf "%s\n" "$section_body" > "$body_file" + + echo "path=$body_file" >> "$GITHUB_OUTPUT" + + - name: Create GitHub release + id: release + if: ${{ steps.release_check.outputs.exists != 'true' }} + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ github.ref_name }} + name: ${{ github.ref_name }} + body_path: ${{ steps.release_body.outputs.path }} + env: + GITHUB_TOKEN: ${{ secrets.RELEASE_GH_TOKEN }} diff --git a/.nvmrc b/.nvmrc index f3c67fcf74..98116556ce 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -22.14 \ No newline at end of file +24.13 \ No newline at end of file diff --git a/packages/core/Dockerfile.local b/docker-setup/Dockerfile.core similarity index 85% rename from packages/core/Dockerfile.local rename to docker-setup/Dockerfile.core index b0d52e02dc..a0ad47dc50 100644 --- a/packages/core/Dockerfile.local +++ b/docker-setup/Dockerfile.core @@ -1,4 +1,4 @@ -FROM node:22.14-slim +FROM node:24.13-slim ARG APP_PATH=packages/core # curl is needed for healthcheck @@ -14,7 +14,7 @@ COPY .yarnrc.yml ./ COPY package.json yarn.lock ./ COPY ${APP_PATH}/package.json ./${APP_PATH}/ -RUN yarn install +RUN yarn workspaces focus @human-protocol/core # Copy base TS config that is required to build package COPY tsconfig.base.json ./ @@ -26,4 +26,4 @@ WORKDIR ./${APP_PATH} RUN yarn build EXPOSE 8545 -CMD yarn local +CMD yarn local \ No newline at end of file diff --git a/docker-setup/docker-compose.dev.yml b/docker-setup/docker-compose.dev.yml index 3a20df61dc..285fcb690a 100644 --- a/docker-setup/docker-compose.dev.yml +++ b/docker-setup/docker-compose.dev.yml @@ -38,7 +38,7 @@ services: <<: *default-logging build: context: ../ - dockerfile: packages/core/Dockerfile.local + dockerfile: docker-setup/Dockerfile.core healthcheck: test: yarn local:readiness interval: 15s diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000000..9a0fc76017 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,4 @@ +sync-python-changelog: + cp -f packages/sdk/python/human-protocol-sdk/CHANGELOG.md packages/sdk/python/human-protocol-sdk/docs/CHANGELOG.md +sync-typescript-changelog: + cp -f packages/sdk/typescript/human-protocol-sdk/CHANGELOG.md packages/sdk/typescript/human-protocol-sdk/docs/CHANGELOG.md \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index 3f0b1726cc..aecb83a5c7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -10,12 +10,22 @@ - Python docs: `mkdocs serve -f docs/mkdocs-python.yaml` ## Deploying a new version (mike) -- TypeScript: - `yarn workspace @human-protocol/sdk build:doc` +- TypeScript: + + `yarn workspace @human-protocol/sdk build:doc` + + `make -f ./docs/Makefile sync-typescript-changelog` + `mike deploy -F ./docs/mkdocs-ts.yaml --deploy-prefix docs/ts [VERSION]` + `mike set-default -F ./docs/mkdocs-ts.yaml --deploy-prefix docs/ts [VERSION]` -- Python: - `mike deploy -F ./docs/mkdocs-python.yaml --deploy-prefix docs/python [VERSION]` + +- Python: + + `make -f ./docs/Makefile sync-python-changelog` + + `mike deploy -F ./docs/mkdocs-python.yaml --deploy-prefix docs/python [VERSION]` + `mike set-default -F ./docs/mkdocs-python.yaml --deploy-prefix docs/python [VERSION]` ### Final step diff --git a/docs/mkdocs-python.yaml b/docs/mkdocs-python.yaml index 5661c3eb87..ef32ecca8d 100644 --- a/docs/mkdocs-python.yaml +++ b/docs/mkdocs-python.yaml @@ -94,5 +94,6 @@ nav: - Worker: - WorkerUtils: worker_utils.md - Core utilities: core.md + - Changelog: CHANGELOG.md extra_css: - assets/css/custom.css diff --git a/docs/mkdocs-ts.yaml b/docs/mkdocs-ts.yaml index f55a4650d5..7c6d2b5893 100644 --- a/docs/mkdocs-ts.yaml +++ b/docs/mkdocs-ts.yaml @@ -85,5 +85,6 @@ nav: - TransactionUtils: classes/TransactionUtils.md - Worker: - WorkerUtils: classes/WorkerUtils.md + - Changelog: CHANGELOG.md extra_css: - assets/css/custom.css diff --git a/package.json b/package.json index f70643a3a2..8d8c4fe1f4 100644 --- a/package.json +++ b/package.json @@ -19,9 +19,10 @@ "packages/**" ], "devDependencies": { + "@changesets/changelog-git": "^0.2.1", "@changesets/cli": "^2.29.6", "husky": "^9.1.6", - "lint-staged": "^15.4.3" + "lint-staged": "^16.2.7" }, "resolutions": { "gluegun/ejs": "^3.1.10", diff --git a/packages/apps/dashboard/client/package.json b/packages/apps/dashboard/client/package.json index b733e08e02..0e0346a378 100644 --- a/packages/apps/dashboard/client/package.json +++ b/packages/apps/dashboard/client/package.json @@ -12,7 +12,7 @@ "lint": "eslint . --report-unused-disable-directives --max-warnings 0", "lint:fix": "eslint . --fix", "preview": "vite preview", - "vercel-build": "yarn workspace human-protocol build:libs && yarn build", + "vercel-build": "yarn workspaces foreach -Rpt --from @apps/dashboard-client run build", "test": "exit 0", "typecheck": "tsc --noEmit" }, @@ -25,7 +25,7 @@ "@mui/styled-engine-sc": "7.2.0", "@mui/system": "^7.2.0", "@mui/x-data-grid": "^8.7.0", - "@mui/x-date-pickers": "^8.7.0", + "@mui/x-date-pickers": "^8.26.0", "@tanstack/react-query": "^5.67.2", "@types/react-router-dom": "^5.3.3", "@types/recharts": "^1.8.29", @@ -40,10 +40,10 @@ "simplebar-react": "^3.3.2", "styled-components": "^6.1.11", "swiper": "^11.1.3", - "use-debounce": "^10.0.2", - "vite-plugin-node-polyfills": "^0.23.0", + "use-debounce": "^10.1.0", + "vite-plugin-node-polyfills": "^0.25.0", "zod": "^4.0.17", - "zustand": "^4.5.4" + "zustand": "^5.0.10" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -54,13 +54,14 @@ "@vitejs/plugin-react": "^4.2.1", "eslint": "^9.39.1", "eslint-plugin-import": "^2.31.0", - "eslint-plugin-prettier": "^5.4.0", + "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.11", "globals": "^16.2.0", "prettier": "^3.7.4", "sass": "^1.89.2", + "terser": "^5.36.0", "typescript": "^5.6.3", "typescript-eslint": "^8.33.0", "vite": "^6.2.4" diff --git a/packages/apps/dashboard/server/package.json b/packages/apps/dashboard/server/package.json index 2dadd9282a..1aa0bbc590 100644 --- a/packages/apps/dashboard/server/package.json +++ b/packages/apps/dashboard/server/package.json @@ -24,27 +24,35 @@ "@human-protocol/core": "workspace:*", "@human-protocol/logger": "workspace:*", "@human-protocol/sdk": "workspace:*", - "@nestjs/axios": "^3.1.2", - "@nestjs/cache-manager": "^2.2.2", - "@nestjs/common": "^10.2.7", - "@nestjs/config": "^3.2.3", - "@nestjs/core": "^11.1.9", - "@nestjs/mapped-types": "*", - "@nestjs/platform-express": "^10.3.10", + "@keyv/redis": "^5.1.5", + "@nestjs/axios": "^4.0.1", + "@nestjs/cache-manager": "^3.1.0", + "@nestjs/common": "^11.1.12", + "@nestjs/config": "^4.0.2", + "@nestjs/core": "^11.1.12", + "@nestjs/mapped-types": "^2.1.0", + "@nestjs/platform-express": "^11.1.12", + "@nestjs/schedule": "^6.1.0", + "@nestjs/swagger": "^11.2.5", "axios": "^1.3.1", - "cache-manager": "^5.4.0", - "cache-manager-redis-yet": "^5.1.5", + "cache-manager": "7.2.8", + "class-transformer": "^0.5.1", + "class-validator": "0.14.1", "dayjs": "^1.11.12", "ethers": "~6.15.0", + "joi": "^17.13.3", + "keyv": "^5.5.5", "lodash": "^4.17.21", + "minio": "8.0.6", "reflect-metadata": "^0.2.2", "rxjs": "^7.2.0" }, "devDependencies": { - "@nestjs/cli": "^10.3.2", - "@nestjs/schematics": "^11.0.2", - "@nestjs/testing": "^10.4.6", - "@types/express": "^4.17.13", + "@golevelup/ts-jest": "^1.2.1", + "@nestjs/cli": "^11.0.16", + "@nestjs/schematics": "^11.0.9", + "@nestjs/testing": "^11.1.12", + "@types/express": "^5.0.6", "@types/jest": "30.0.0", "@types/node": "22.10.5", "@typescript-eslint/eslint-plugin": "^5.0.0", @@ -52,7 +60,7 @@ "eslint": "^9.39.1", "eslint-config-prettier": "^9.1.0", "eslint-plugin-jest": "^28.9.0", - "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-prettier": "^5.5.5", "jest": "^29.7.0", "prettier": "^3.7.4", "source-map-support": "^0.5.20", diff --git a/packages/apps/dashboard/server/src/common/config/cache-factory.config.ts b/packages/apps/dashboard/server/src/common/config/cache-factory.config.ts index 76ed739658..f7c6350826 100644 --- a/packages/apps/dashboard/server/src/common/config/cache-factory.config.ts +++ b/packages/apps/dashboard/server/src/common/config/cache-factory.config.ts @@ -1,8 +1,8 @@ import { CacheModuleAsyncOptions } from '@nestjs/common/cache'; import { ConfigModule } from '@nestjs/config'; -import { redisStore } from 'cache-manager-redis-yet'; import * as _ from 'lodash'; +import KeyvRedis, { Keyv } from '@keyv/redis'; import logger from '../../logger'; import { RedisConfigService } from './redis-config.service'; @@ -17,7 +17,7 @@ export const CacheFactoryConfig: CacheModuleAsyncOptions = { isGlobal: true, imports: [ConfigModule], useFactory: async (configService: RedisConfigService) => { - const store = await redisStore({ + const redisAdapter = new KeyvRedis({ socket: { host: configService.redisHost, port: configService.redisPort, @@ -26,10 +26,17 @@ export const CacheFactoryConfig: CacheModuleAsyncOptions = { disableOfflineQueue: true, }); - store.client.on('error', throttledRedisErrorLog); + redisAdapter.on('error', throttledRedisErrorLog); + redisAdapter.client.on?.('error', throttledRedisErrorLog); + + const keyvStore = new Keyv({ + store: redisAdapter, + namespace: undefined, + useKeyPrefix: false, + }); return { - store: () => store, + stores: [keyvStore], }; }, inject: [RedisConfigService], diff --git a/packages/apps/faucet/client/package.json b/packages/apps/faucet/client/package.json index bb8469153c..0e0aad48dd 100644 --- a/packages/apps/faucet/client/package.json +++ b/packages/apps/faucet/client/package.json @@ -14,10 +14,12 @@ "format:prettier": "prettier --write '**/*.{ts,tsx}'", "format:lint": "eslint --fix '**/*.{ts,tsx}'", "format": "yarn format:prettier && yarn format:lint", - "vercel-build": "yarn workspace human-protocol build:libs && yarn build", + "vercel-build": "yarn workspaces foreach -Rpt --from @apps/faucet-client run build", "test": "exit 0" }, "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.1", "@human-protocol/sdk": "workspace:*", "@mui/icons-material": "^7.0.1", "@mui/material": "^5.16.7", @@ -31,6 +33,7 @@ "devDependencies": { "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react": "^4.3.4", "dotenv": "^17.2.2", "eslint": "^9.39.1", "eslint-config-react-app": "^7.0.1", @@ -41,7 +44,7 @@ "prettier": "^3.7.4", "typescript": "^5.8.3", "vite": "^6.2.4", - "vite-plugin-node-polyfills": "^0.23.0" + "vite-plugin-node-polyfills": "^0.25.0" }, "lint-staged": { "*.{ts,tsx}": [ diff --git a/packages/apps/faucet/server/jest.config.ts b/packages/apps/faucet/server/jest.config.js similarity index 55% rename from packages/apps/faucet/server/jest.config.ts rename to packages/apps/faucet/server/jest.config.js index 7610fa3cb1..0a679bc144 100644 --- a/packages/apps/faucet/server/jest.config.ts +++ b/packages/apps/faucet/server/jest.config.js @@ -1,15 +1,14 @@ -import type { Config } from 'jest'; - -const config: Config = { - verbose: true, +module.exports = { + coverageDirectory: '../coverage', collectCoverageFrom: ['**/*.(t|j)s'], moduleFileExtensions: ['js', 'json', 'ts'], rootDir: 'src', testEnvironment: 'node', testRegex: '.*\\.spec\\.ts$', transform: { - '^.+\\.(t|j)s$': 'ts-jest', + '^.+\\.(t)s$': 'ts-jest', + }, + moduleNameMapper: { + '^uuid$': require.resolve('uuid'), }, }; - -export default config; diff --git a/packages/apps/faucet/server/package.json b/packages/apps/faucet/server/package.json index 9441a70e1b..9ae1f12a7c 100644 --- a/packages/apps/faucet/server/package.json +++ b/packages/apps/faucet/server/package.json @@ -10,7 +10,7 @@ "lint": "eslint src", "test": "concurrently -k -s first --hide 0 \"hardhat node --port 8549\" \"jest\"", "start": "ts-node src/index.ts", - "vercel-build": "yarn workspace human-protocol build:libs && yarn build" + "vercel-build": "yarn workspaces foreach -Rpt --from @apps/faucet-server run build" }, "author": "", "license": "ISC", @@ -19,19 +19,21 @@ "axios": "^1.3.4", "body-parser": "^1.20.0", "cors": "^2.8.5", - "express": "^4.21.0", + "express": "^5.2.1", "express-rate-limit": "^7.3.0", "node-cache": "^5.1.2", "web3": "^4.12.1" }, "devDependencies": { "@types/cors": "^2.8.19", - "@types/express": "^4.17.14", + "@types/express": "^5.0.6", + "@types/jest": "^29.5.14", "@types/node": "^22.15.16", "concurrently": "^9.1.2", "eslint": "^9.39.1", "hardhat": "^2.26.0", "jest": "^29.7.0", + "ts-jest": "29.2.5", "ts-node": "^10.9.2", "typescript": "^5.8.3" } diff --git a/packages/apps/fortune/exchange-oracle/client/Dockerfile b/packages/apps/fortune/exchange-oracle/client/Dockerfile index 46f448db16..1e5800c6bb 100644 --- a/packages/apps/fortune/exchange-oracle/client/Dockerfile +++ b/packages/apps/fortune/exchange-oracle/client/Dockerfile @@ -1,5 +1,5 @@ # Using bullseye instead of slim because it needs Python and build tools for node-gyp -FROM node:22.14-bullseye +FROM node:24.13-bullseye ARG APP_PATH=packages/apps/fortune/exchange-oracle/client # Create app directory @@ -18,12 +18,12 @@ COPY ${APP_PATH}/package.json ./${APP_PATH}/ COPY packages/core ./packages/core COPY packages/sdk ./packages/sdk -RUN yarn install +RUN yarn workspaces focus @apps/fortune-exchange-oracle-client # Copy base TS config that is required to build packages COPY tsconfig.base.json ./ -# Build libs -RUN yarn build:libs +# Build libs (scoped) +RUN yarn workspaces foreach -Rpt --from @apps/fortune-exchange-oracle-client run build # Copy everything else COPY ${APP_PATH} ./${APP_PATH} diff --git a/packages/apps/fortune/exchange-oracle/client/package.json b/packages/apps/fortune/exchange-oracle/client/package.json index 79f1eef5e0..7ffddc7d88 100644 --- a/packages/apps/fortune/exchange-oracle/client/package.json +++ b/packages/apps/fortune/exchange-oracle/client/package.json @@ -57,7 +57,7 @@ "prettier": "^3.7.4", "typescript": "^5.6.3", "vite": "^6.2.4", - "vite-plugin-node-polyfills": "^0.23.0" + "vite-plugin-node-polyfills": "^0.25.0" }, "lint-staged": { "*.{ts,tsx}": [ diff --git a/packages/apps/fortune/exchange-oracle/server/Dockerfile b/packages/apps/fortune/exchange-oracle/server/Dockerfile index ec1f060ae8..969544f4b1 100644 --- a/packages/apps/fortune/exchange-oracle/server/Dockerfile +++ b/packages/apps/fortune/exchange-oracle/server/Dockerfile @@ -1,4 +1,4 @@ -FROM node:22.14-slim +FROM node:24.13-slim ARG APP_PATH=packages/apps/fortune/exchange-oracle/server # Create app directory @@ -18,12 +18,12 @@ COPY packages/core ./packages/core COPY packages/sdk ./packages/sdk COPY packages/libs ./packages/libs -RUN yarn install +RUN yarn workspaces focus @apps/fortune-exchange-oracle-server # Copy base TS config that is required to build packages COPY tsconfig.base.json ./ -# Build libs -RUN yarn build:libs +# Build libs (scoped) +RUN yarn workspaces foreach -Rpt --from @apps/fortune-exchange-oracle-server run build # Copy everything else COPY ${APP_PATH} ./${APP_PATH} diff --git a/packages/apps/fortune/exchange-oracle/server/package.json b/packages/apps/fortune/exchange-oracle/server/package.json index 5357d7d6c0..6a3d223834 100644 --- a/packages/apps/fortune/exchange-oracle/server/package.json +++ b/packages/apps/fortune/exchange-oracle/server/package.json @@ -19,6 +19,7 @@ "migration:generate": "yarn typeorm migration:generate -p -d typeorm.config.ts", "migration:revert": "yarn typeorm migration:revert -d typeorm.config.ts", "migration:run": "yarn typeorm migration:run -d typeorm.config.ts", + "migration:run:prod": "typeorm migration:run -d dist/typeorm.config.js", "migration:show": "yarn typeorm migration:show -d typeorm.config.ts", "test:watch": "jest --watch", "test:cov": "jest --coverage", @@ -31,16 +32,16 @@ "dependencies": { "@human-protocol/logger": "workspace:*", "@human-protocol/sdk": "workspace:*", - "@nestjs/axios": "^3.1.2", - "@nestjs/common": "^10.2.7", - "@nestjs/config": "^3.1.1", - "@nestjs/core": "^11.1.9", - "@nestjs/passport": "^10.0.0", - "@nestjs/platform-express": "^10.3.10", - "@nestjs/schedule": "^4.0.1", - "@nestjs/swagger": "^7.4.2", + "@nestjs/axios": "^4.0.1", + "@nestjs/common": "^11.1.12", + "@nestjs/config": "^4.0.2", + "@nestjs/core": "^11.1.12", + "@nestjs/passport": "^11.0.5", + "@nestjs/platform-express": "^11.1.12", + "@nestjs/schedule": "^6.1.0", + "@nestjs/swagger": "^11.2.5", "@nestjs/terminus": "^11.0.0", - "@nestjs/typeorm": "^10.0.1", + "@nestjs/typeorm": "^11.0.0", "@types/passport-jwt": "^4.0.1", "axios": "^1.3.1", "body-parser": "^1.20.3", @@ -56,27 +57,27 @@ "pg": "8.13.1", "reflect-metadata": "^0.2.2", "rxjs": "^7.2.0", - "typeorm": "^0.3.25", + "typeorm": "^0.3.28", "typeorm-naming-strategies": "^4.1.0" }, "devDependencies": { "@golevelup/ts-jest": "^0.6.1", - "@nestjs/cli": "^10.3.2", - "@nestjs/schematics": "^11.0.2", - "@nestjs/testing": "^10.4.6", + "@nestjs/cli": "^11.0.16", + "@nestjs/schematics": "^11.0.9", + "@nestjs/testing": "^11.1.12", "@types/body-parser": "^1", - "@types/express": "^4.17.13", + "@types/express": "^5.0.6", "@types/jest": "30.0.0", "@types/jsonwebtoken": "^9.0.7", "@types/node": "22.10.5", - "@types/passport": "^0", + "@types/passport": "^1", "@types/pg": "8.11.10", "@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/parser": "^8.46.3", "eslint": "^9.39.1", "eslint-config-prettier": "^9.1.0", "eslint-plugin-jest": "^28.9.0", - "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-prettier": "^5.5.5", "jest": "^29.7.0", "prettier": "^3.7.4", "source-map-support": "^0.5.20", diff --git a/packages/apps/fortune/exchange-oracle/server/src/common/guards/signature.auth.spec.ts b/packages/apps/fortune/exchange-oracle/server/src/common/guards/signature.auth.spec.ts index 07e48dd987..a7e1dd4612 100644 --- a/packages/apps/fortune/exchange-oracle/server/src/common/guards/signature.auth.spec.ts +++ b/packages/apps/fortune/exchange-oracle/server/src/common/guards/signature.auth.spec.ts @@ -121,7 +121,9 @@ describe('SignatureAuthGuard', () => { const result = await guard.canActivate(context); expect(result).toBeTruthy(); - expect(assignmentRepository.findOneById).toHaveBeenCalledWith(assignmentId); + expect(assignmentRepository.findOneById).toHaveBeenCalledWith( + assignmentId, + ); }); it('should throw BadRequest error if assignment id is not number', async () => { diff --git a/packages/apps/fortune/exchange-oracle/server/src/common/guards/signature.auth.ts b/packages/apps/fortune/exchange-oracle/server/src/common/guards/signature.auth.ts index aa1a6d68da..045015657f 100644 --- a/packages/apps/fortune/exchange-oracle/server/src/common/guards/signature.auth.ts +++ b/packages/apps/fortune/exchange-oracle/server/src/common/guards/signature.auth.ts @@ -42,7 +42,10 @@ export class SignatureAuthGuard implements CanActivate { if (roles.includes(AuthSignatureRole.Worker)) { if (!Number.isInteger(Number(data.assignment_id))) { - throw new HttpException('Invalid assignment id', HttpStatus.BAD_REQUEST); + throw new HttpException( + 'Invalid assignment id', + HttpStatus.BAD_REQUEST, + ); } const assignment = await this.assignmentRepository.findOneById( diff --git a/packages/apps/fortune/exchange-oracle/server/src/common/interceptors/snake-case.ts b/packages/apps/fortune/exchange-oracle/server/src/common/interceptors/snake-case.ts index 05b5b1ff1f..4e67b96cad 100644 --- a/packages/apps/fortune/exchange-oracle/server/src/common/interceptors/snake-case.ts +++ b/packages/apps/fortune/exchange-oracle/server/src/common/interceptors/snake-case.ts @@ -21,7 +21,13 @@ export class SnakeCaseInterceptor implements NestInterceptor { } if (request.query) { - request.query = transformKeysFromSnakeToCamel(request.query); + const transformedQuery = transformKeysFromSnakeToCamel(request.query); + Object.defineProperty(request, 'query', { + value: transformedQuery, + configurable: true, + enumerable: true, + writable: true, + }); } return next diff --git a/packages/apps/fortune/exchange-oracle/server/tsconfig.json b/packages/apps/fortune/exchange-oracle/server/tsconfig.json index 63d442695b..a1e0956c73 100644 --- a/packages/apps/fortune/exchange-oracle/server/tsconfig.json +++ b/packages/apps/fortune/exchange-oracle/server/tsconfig.json @@ -17,6 +17,7 @@ "noImplicitAny": true, "strictBindCallApply": true, "forceConsistentCasingInFileNames": true, - "noFallthroughCasesInSwitch": true + "noFallthroughCasesInSwitch": true, + "esModuleInterop": true } } diff --git a/packages/apps/fortune/exchange-oracle/server/typeorm.config.ts b/packages/apps/fortune/exchange-oracle/server/typeorm.config.ts index a06dfb3ca3..367e580311 100644 --- a/packages/apps/fortune/exchange-oracle/server/typeorm.config.ts +++ b/packages/apps/fortune/exchange-oracle/server/typeorm.config.ts @@ -1,6 +1,7 @@ import { DataSource } from 'typeorm'; import { SnakeNamingStrategy } from 'typeorm-naming-strategies'; import * as dotenv from 'dotenv'; +import path from 'path'; import Environment from './src/common/utils/environment'; @@ -11,6 +12,13 @@ dotenv.config({ path: [`.env.${Environment.name}`, '.env'], }); +const tsOrJs = path.extname(__filename).slice(1); +const migrationsPath = path.join( + __dirname, + `src/database/migrations/*.${tsOrJs}`, +); +const entitiesPath = path.join(__dirname, `src/modules/**/*.entity.${tsOrJs}`); + export default new DataSource({ type: 'postgres', useUTC: true, @@ -23,8 +31,8 @@ export default new DataSource({ ssl: process.env.POSTGRES_SSL?.toLowerCase() === 'true', synchronize: false, migrationsRun: true, - migrations: ['src/database/migrations/*.ts'], + migrations: [migrationsPath], migrationsTableName: 'migrations_typeorm', namingStrategy: new SnakeNamingStrategy(), - entities: ['src/modules/**/*.entity.ts'], + entities: [entitiesPath], }); diff --git a/packages/apps/fortune/recording-oracle/Dockerfile b/packages/apps/fortune/recording-oracle/Dockerfile index 2b7cfc933b..b6569d2c63 100644 --- a/packages/apps/fortune/recording-oracle/Dockerfile +++ b/packages/apps/fortune/recording-oracle/Dockerfile @@ -1,4 +1,4 @@ -FROM node:22.14-slim +FROM node:24.13-slim ARG APP_PATH=packages/apps/fortune/recording-oracle # Create app directory @@ -18,12 +18,12 @@ COPY packages/core ./packages/core COPY packages/sdk ./packages/sdk COPY packages/libs ./packages/libs -RUN yarn install +RUN yarn workspaces focus @apps/fortune-recording-oracle # Copy base TS config that is required to build packages COPY tsconfig.base.json ./ -# Build libs -RUN yarn build:libs +# Build libs (scoped) +RUN yarn workspaces foreach -Rpt --from @apps/fortune-recording-oracle run build # Copy everything else COPY ${APP_PATH} ./${APP_PATH} diff --git a/packages/apps/fortune/recording-oracle/package.json b/packages/apps/fortune/recording-oracle/package.json index 2561c13d73..7ae73fc159 100644 --- a/packages/apps/fortune/recording-oracle/package.json +++ b/packages/apps/fortune/recording-oracle/package.json @@ -25,12 +25,12 @@ "dependencies": { "@human-protocol/logger": "workspace:*", "@human-protocol/sdk": "workspace:*", - "@nestjs/axios": "^3.1.2", - "@nestjs/common": "^10.2.7", - "@nestjs/config": "^3.1.1", - "@nestjs/core": "^11.1.9", - "@nestjs/platform-express": "^10.3.10", - "@nestjs/swagger": "^7.4.2", + "@nestjs/axios": "^4.0.1", + "@nestjs/common": "^11.1.12", + "@nestjs/config": "^4.0.2", + "@nestjs/core": "^11.1.12", + "@nestjs/platform-express": "^11.1.12", + "@nestjs/swagger": "^11.2.5", "axios": "^1.3.1", "body-parser": "^1.20.2", "class-transformer": "^0.5.1", @@ -43,16 +43,18 @@ "rxjs": "^7.2.0" }, "devDependencies": { - "@nestjs/cli": "^10.3.2", - "@nestjs/schematics": "^11.0.2", - "@nestjs/testing": "^10.4.6", - "@types/express": "^4.17.13", + "@nestjs/cli": "^11.0.16", + "@nestjs/schematics": "^11.0.9", + "@nestjs/testing": "^11.1.12", + "@types/express": "^5.0.6", + "@types/jest": "^29.5.14", "@types/node": "^22.15.16", "eslint": "^9.39.1", "eslint-plugin-jest": "^28.9.0", - "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-prettier": "^5.5.5", "jest": "^29.7.0", "prettier": "^3.7.4", + "ts-jest": "29.2.5", "ts-node": "^10.9.2", "typescript": "^5.8.3" } diff --git a/packages/apps/fortune/recording-oracle/src/common/interceptors/snake-case.ts b/packages/apps/fortune/recording-oracle/src/common/interceptors/snake-case.ts index 05b5b1ff1f..4e67b96cad 100644 --- a/packages/apps/fortune/recording-oracle/src/common/interceptors/snake-case.ts +++ b/packages/apps/fortune/recording-oracle/src/common/interceptors/snake-case.ts @@ -21,7 +21,13 @@ export class SnakeCaseInterceptor implements NestInterceptor { } if (request.query) { - request.query = transformKeysFromSnakeToCamel(request.query); + const transformedQuery = transformKeysFromSnakeToCamel(request.query); + Object.defineProperty(request, 'query', { + value: transformedQuery, + configurable: true, + enumerable: true, + writable: true, + }); } return next diff --git a/packages/apps/human-app/frontend/Dockerfile b/packages/apps/human-app/frontend/Dockerfile index 7bb315121b..a2371a5cec 100644 --- a/packages/apps/human-app/frontend/Dockerfile +++ b/packages/apps/human-app/frontend/Dockerfile @@ -1,5 +1,5 @@ # Using bullseye instead of slim because it needs Python and build tools for node-gyp -FROM node:22.14-bullseye +FROM node:24.13-bullseye ARG APP_PATH=packages/apps/human-app/frontend # Create app directory @@ -18,12 +18,12 @@ COPY ${APP_PATH}/package.json ./${APP_PATH}/ COPY packages/core ./packages/core COPY packages/sdk ./packages/sdk -RUN yarn install +RUN yarn workspaces focus @apps/human-app-frontend # Copy base TS config that is required to build packages COPY tsconfig.base.json ./ -# Build libs -RUN yarn build:libs +# Build libs (scoped) +RUN yarn workspaces foreach -Rpt --from @apps/human-app-frontend run build # Copy everything else COPY ${APP_PATH} ./${APP_PATH} diff --git a/packages/apps/human-app/frontend/package.json b/packages/apps/human-app/frontend/package.json index 3f28bd9c70..c43bff58fb 100644 --- a/packages/apps/human-app/frontend/package.json +++ b/packages/apps/human-app/frontend/package.json @@ -10,7 +10,8 @@ "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview", "test": "vitest --run", - "test:watch": "vitest" + "test:watch": "vitest", + "vercel-build": "yarn workspaces foreach -Rpt --from @apps/human-app-frontend run build" }, "lint-staged": { "*.{ts,tsx}": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0" @@ -27,7 +28,7 @@ "@mui/icons-material": "^7.0.1", "@mui/material": "^5.16.7", "@mui/system": "^5.15.14", - "@mui/x-date-pickers": "^7.23.6", + "@mui/x-date-pickers": "^8.26.0", "@reown/appkit": "^1.7.11", "@reown/appkit-adapter-wagmi": "^1.7.11", "@synaps-io/verify-sdk": "^4.0.45", @@ -35,7 +36,7 @@ "@wagmi/core": "^2.17.1", "date-fns": "^4.1.0", "ethers": "^6.15.0", - "i18next": "^23.8.2", + "i18next": "^25.8.0", "jwt-decode": "^4.0.0", "lodash": "^4.17.21", "material-react-table": "3.0.1", @@ -45,7 +46,7 @@ "query-string": "^9.0.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-hook-form": "^7.62.0", + "react-hook-form": "^7.71.1", "react-i18next": "^15.1.0", "react-imask": "^7.4.0", "react-number-format": "^5.4.3", @@ -55,7 +56,7 @@ "vite-plugin-svgr": "^4.2.0", "wagmi": "^2.15.6", "zod": "^4.0.17", - "zustand": "^4.5.0" + "zustand": "^5.0.10" }, "devDependencies": { "@tanstack/eslint-plugin-query": "^5.60.1", @@ -72,11 +73,10 @@ "@vitejs/plugin-react": "^4.2.1", "eslint": "^9.39.1", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-react-refresh": "^0.4.11", "husky": "^9.1.6", "jsdom": "^25.0.1", - "lint-staged": "^15.4.3", "prettier": "^3.7.4", "typescript": "^5.6.3", "vite": "^6.2.4", diff --git a/packages/apps/human-app/frontend/src/modules/worker/jobs/available-jobs/components/mobile/available-jobs-assign-job-button-mobile.tsx b/packages/apps/human-app/frontend/src/modules/worker/jobs/available-jobs/components/mobile/available-jobs-assign-job-button-mobile.tsx index ea5216a575..3acd1102e0 100644 --- a/packages/apps/human-app/frontend/src/modules/worker/jobs/available-jobs/components/mobile/available-jobs-assign-job-button-mobile.tsx +++ b/packages/apps/human-app/frontend/src/modules/worker/jobs/available-jobs/components/mobile/available-jobs-assign-job-button-mobile.tsx @@ -1,20 +1,14 @@ import { t } from 'i18next'; -import { useParams } from 'react-router-dom'; import { TableButton } from '@/shared/components/ui/table-button'; import { useJobsNotifications } from '../../../hooks'; import { useAssignJobMutation } from '../../hooks/use-assign-job'; import { type AssignJobBody } from '../../../types'; -import { useAddThirstyfiInfoModal } from '../../hooks/use-add-thirstyfi-info-modal'; - -const THIRSTYFI_ADDRESS = '0x5C08438d7d18734c5ee42ECAf81FB1D6A922A9cC'; export function AvailableJobsAssignJobButtonMobile({ assignJobPayload, }: Readonly<{ assignJobPayload: AssignJobBody; }>) { - const { address: oracleAddress } = useParams<{ address: string }>(); - const { openModal } = useAddThirstyfiInfoModal(); const { onJobAssignmentError, onJobAssignmentSuccess } = useJobsNotifications(); @@ -26,20 +20,12 @@ export function AvailableJobsAssignJobButtonMobile({ [`assignJob-${assignJobPayload.escrow_address}`] ); - const isThirstyfi = oracleAddress === THIRSTYFI_ADDRESS; - return ( { - if (isThirstyfi) { - openModal({ ...assignJobPayload }); - } else { - assignJobMutation(assignJobPayload); - } - }} + onClick={() => assignJobMutation(assignJobPayload)} size="small" sx={{ marginTop: '15px', diff --git a/packages/apps/human-app/frontend/src/modules/worker/jobs/available-jobs/hooks/use-add-thirstyfi-info-modal.tsx b/packages/apps/human-app/frontend/src/modules/worker/jobs/available-jobs/hooks/use-add-thirstyfi-info-modal.tsx deleted file mode 100644 index 49be0eaf6f..0000000000 --- a/packages/apps/human-app/frontend/src/modules/worker/jobs/available-jobs/hooks/use-add-thirstyfi-info-modal.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { useModal } from '@/shared/contexts/modal-context'; -import { ThirstyfiInfoModal } from '../thirstyfi-info-modal'; - -interface AddThirstyfiInfoModalProps { - escrow_address: string; - chain_id: number; -} - -export function useAddThirstyfiInfoModal() { - const { openModal, closeModal } = useModal(); - - return { - openModal: ({ escrow_address, chain_id }: AddThirstyfiInfoModalProps) => { - openModal({ - content: ( - - ), - }); - }, - }; -} diff --git a/packages/apps/human-app/frontend/src/modules/worker/jobs/available-jobs/hooks/use-get-available-jobs-columns.tsx b/packages/apps/human-app/frontend/src/modules/worker/jobs/available-jobs/hooks/use-get-available-jobs-columns.tsx index 41226f9e8f..753ad47200 100644 --- a/packages/apps/human-app/frontend/src/modules/worker/jobs/available-jobs/hooks/use-get-available-jobs-columns.tsx +++ b/packages/apps/human-app/frontend/src/modules/worker/jobs/available-jobs/hooks/use-get-available-jobs-columns.tsx @@ -2,7 +2,6 @@ import type { MRT_ColumnDef } from 'material-react-table'; import { t } from 'i18next'; import { Grid } from '@mui/material'; import { useMemo } from 'react'; -import { useParams } from 'react-router-dom'; import { getNetworkName } from '@/modules/smart-contracts/get-network-name'; import { Chip } from '@/shared/components/ui/chip'; import { TableButton } from '@/shared/components/ui/table-button'; @@ -17,18 +16,13 @@ import { } from '../components'; import { type AvailableJob } from '../../types'; import { useAssignJobMutation } from './use-assign-job'; -import { useAddThirstyfiInfoModal } from './use-add-thirstyfi-info-modal'; const COL_SIZE = 100; const COL_SIZE_LG = 200; -const THIRSTYFI_ADDRESS = '0x5C08438d7d18734c5ee42ECAf81FB1D6A922A9cC'; export const useGetAvailableJobsColumns = ( chainIdsEnabled: number[] ): MRT_ColumnDef[] => { - const { openModal } = useAddThirstyfiInfoModal(); - const { address: oracleAddress } = useParams<{ address: string }>(); - return useMemo( () => [ { @@ -127,20 +121,12 @@ export const useGetAvailableJobsColumns = ( [`assignJob-${escrow_address}`] ); - const isThirstyfi = oracleAddress === THIRSTYFI_ADDRESS; - return ( { - if (isThirstyfi) { - openModal({ escrow_address, chain_id }); - } else { - assignJobMutation({ escrow_address, chain_id }); - } - }} + onClick={() => assignJobMutation({ escrow_address, chain_id })} > {t('worker.jobs.selectJob')} @@ -149,6 +135,6 @@ export const useGetAvailableJobsColumns = ( }, }, ], - [chainIdsEnabled, openModal, oracleAddress] + [chainIdsEnabled] ); }; diff --git a/packages/apps/human-app/frontend/src/modules/worker/jobs/available-jobs/thirstyfi-info-modal.tsx b/packages/apps/human-app/frontend/src/modules/worker/jobs/available-jobs/thirstyfi-info-modal.tsx deleted file mode 100644 index c8faa3bd4b..0000000000 --- a/packages/apps/human-app/frontend/src/modules/worker/jobs/available-jobs/thirstyfi-info-modal.tsx +++ /dev/null @@ -1,142 +0,0 @@ -import { z } from 'zod'; -import { FormProvider, useForm } from 'react-hook-form'; -import Stack from '@mui/material/Stack'; -import Typography from '@mui/material/Typography'; -import { useTranslation } from 'react-i18next'; -import { zodResolver } from '@hookform/resolvers/zod'; -import { useQueryClient } from '@tanstack/react-query'; -import Link from '@mui/material/Link'; -import { Button } from '@/shared/components/ui/button'; -import { Input } from '@/shared/components/data-entry/input'; -import { useIsMobile } from '@/shared/hooks/use-is-mobile'; -import { useJobsNotifications } from '../hooks'; -import { useAssignJobMutation } from './hooks/use-assign-job'; - -interface ThirstyfiInfoModalProps { - escrow_address: string; - chain_id: number; - onClose?: () => void; -} - -export function ThirstyfiInfoModal({ - escrow_address, - chain_id, - onClose, -}: ThirstyfiInfoModalProps) { - const { t } = useTranslation(); - const isMobile = useIsMobile(); - - const methods = useForm({ - defaultValues: { - wallet_address: '', - api_key: '', - api_secret: '', - }, - resolver: zodResolver( - z.object({ - wallet_address: z - .string() - .trim() - .length(42, t('thirstyfiModal.walletAddressError')) - .regex(/^0x/, t('thirstyfiModal.walletAddressRegexError')), - api_key: z.string().trim().min(1, t('validation.required')), - api_secret: z.string().trim().min(1, t('validation.required')), - }) - ), - }); - - const { onJobAssignmentError, onJobAssignmentSuccess } = - useJobsNotifications(); - const queryClient = useQueryClient(); - - const { mutate: assignJobMutation, isPending } = useAssignJobMutation( - { - onSuccess: () => { - const queryKey = isMobile - ? ['availableJobsInfinite'] - : ['availableJobs']; - onJobAssignmentSuccess(); - void queryClient.invalidateQueries({ queryKey }).then(() => { - methods.reset(); - onClose?.(); - }); - }, - onError: onJobAssignmentError, - }, - [`assignJob-${escrow_address}`] - ); - - const onSubmit = (data: { - wallet_address: string; - api_key: string; - api_secret: string; - }) => { - assignJobMutation({ escrow_address, chain_id, ...data }); - }; - - const handleSubmit = (event: React.FormEvent) => { - void methods.handleSubmit(onSubmit)(event); - }; - - return ( - -
- - - {t('thirstyfiModal.title')} - - - {t('thirstyfiModal.tutorialText1')} - - {t('thirstyfiModal.tutorialLink')} - - {t('thirstyfiModal.tutorialText2')} - - - - - {t('thirstyfiModal.walletAddressHelp', { - defaultValue: t('thirstyfiModal.walletAddressTooltip'), - })} - - - - - - {t('thirstyfiModal.apiKeyHelp', { - defaultValue: t('thirstyfiModal.apiKeyTooltip'), - })} - - - - - - {t('thirstyfiModal.apiSecretHelp', { - defaultValue: t('thirstyfiModal.apiSecretTooltip'), - })} - - - - -
-
- ); -} diff --git a/packages/apps/human-app/frontend/src/modules/worker/jobs/components/my-jobs-table-actions.tsx b/packages/apps/human-app/frontend/src/modules/worker/jobs/components/my-jobs-table-actions.tsx index f625eca99b..886dc72875 100644 --- a/packages/apps/human-app/frontend/src/modules/worker/jobs/components/my-jobs-table-actions.tsx +++ b/packages/apps/human-app/frontend/src/modules/worker/jobs/components/my-jobs-table-actions.tsx @@ -35,9 +35,7 @@ export function MyJobsTableActions({ > {t('worker.jobs.solve')}
- {job.escrow_address !== 'thirstyfi-task' && ( - - )} + ); } diff --git a/packages/apps/human-app/frontend/src/modules/worker/profile/components/api-key-data.tsx b/packages/apps/human-app/frontend/src/modules/worker/profile/components/api-key-data.tsx index 55cb3efb93..a6fa175b58 100644 --- a/packages/apps/human-app/frontend/src/modules/worker/profile/components/api-key-data.tsx +++ b/packages/apps/human-app/frontend/src/modules/worker/profile/components/api-key-data.tsx @@ -10,7 +10,11 @@ import { } from '../hooks/use-api-key-modals'; import { useGetExchangeApiKeys } from '../../hooks/use-exchange-api-keys'; -export function ApiKeyData() { +export function ApiKeyData({ + stakingExchangeError, +}: { + stakingExchangeError?: string; +}) { const { isDarkMode } = useColorMode(); const { t } = useTranslation(); const { openModal: openEditApiKeyModal } = useEditApiKeyModal(); @@ -58,14 +62,14 @@ export function ApiKeyData() { = Number(uiConfig?.minThreshold || '0'); + useEffect(() => { + const stakingSummaryError = + stakingSummary?.on_chain_error || stakingSummary?.exchange_error; + if (stakingSummaryError && !isLoading && !isRefetching) { + showNotification({ + type: TopNotificationType.WARNING, + message: stakingSummaryError, + }); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ + isLoading, + isRefetching, + stakingSummary?.on_chain_error, + stakingSummary?.exchange_error, + ]); + useEffect(() => { if (isRefetching || isLoading) return; @@ -88,7 +112,7 @@ export function StakingInfo() { ) : ( +
+ + {t('worker.profile.stakingInfo.howToCreateApiKeys')} + +
+ + )}