diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 417d97d5..ac2109ea 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -34,11 +34,12 @@ body:
label: Domain
description: Which GovTool instance were you connected to?
options:
+ - gov.tools
+ - preview.gov.tools
- sanchogov.tools
- dev-sanchogov.tools
- test-sanchogov.tools
- stage-sanchogov.tools
- - preview.gov.tools
- Custom setup
validations:
required: true
diff --git a/generate_latest_report_redirect.sh b/.github/scripts/generate_latest_report_redirect.sh
similarity index 100%
rename from generate_latest_report_redirect.sh
rename to .github/scripts/generate_latest_report_redirect.sh
diff --git a/generate_report_details.sh b/.github/scripts/generate_report_details.sh
similarity index 55%
rename from generate_report_details.sh
rename to .github/scripts/generate_report_details.sh
index f9e4416b..bf813195 100644
--- a/generate_report_details.sh
+++ b/.github/scripts/generate_report_details.sh
@@ -7,5 +7,6 @@ else
latest_number=$(echo "$gh_pages_content" | grep -Eo '[0-9]+' | sort -nr | head -n 1)
fi
-echo "::set-output name=report_number::$((latest_number+1))"
-echo "::set-output name=report_url::https://$(dirname "$GH_PAGES").github.io/$(basename "$GH_PAGES")/$REPORT_NAME"
+echo "report_number=$((latest_number+1))" >> $GITHUB_OUTPUT
+echo "report_url=https://$(dirname "$GH_PAGES").github.io/$(basename "$GH_PAGES")/$REPORT_NAME" >> $GITHUB_OUTPUT
+
diff --git a/register_report.sh b/.github/scripts/register_report.sh
similarity index 74%
rename from register_report.sh
rename to .github/scripts/register_report.sh
index a36016eb..f5e5756f 100644
--- a/register_report.sh
+++ b/.github/scripts/register_report.sh
@@ -8,8 +8,8 @@ cp -r gh-pages/* "$PROJECT_DIR" || true
if grep -q "$REPORT_NAME" "$PROJECT_DIR/$PROJECT_FILE"; then
echo "Project already exists"
- echo "::set-output name=project_exists::true"
+ echo "project_exists=true">> $GITHUB_OUTPUT
else
echo "$REPORT_NAME" >> "$PROJECT_DIR/$PROJECT_FILE"
- echo "::set-output name=project_exists::false"
+ echo "project_exists=false">> $GITHUB_OUTPUT
fi
diff --git a/.github/workflows/build-and-deploy-test-stack.yml b/.github/workflows/build-and-deploy-test-stack.yml
index f003258c..a4d3c07a 100644
--- a/.github/workflows/build-and-deploy-test-stack.yml
+++ b/.github/workflows/build-and-deploy-test-stack.yml
@@ -15,39 +15,64 @@ jobs:
deploy:
name: Deploy app
runs-on: ubuntu-latest
- env:
- GRAFANA_ADMIN_PASSWORD: ${{ secrets.GRAFANA_ADMIN_PASSWORD }}
- GRAFANA_SLACK_RECIPIENT: ${{ secrets.GRAFANA_SLACK_RECIPIENT }}
- GRAFANA_SLACK_OAUTH_TOKEN: ${{ secrets.GRAFANA_SLACK_OAUTH_TOKEN }}
- SENTRY_DSN_BACKEND: ${{ secrets.SENTRY_DSN_BACKEND }}
- GTM_ID: ${{ secrets.GTM_ID }}
- NPMRC_TOKEN: ${{ secrets.NPMRC_TOKEN }}
- SENTRY_DSN_FRONTEND: ${{ secrets.SENTRY_DSN_FRONTEND }}
- PIPELINE_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
- USERSNAP_SPACE_API_KEY: ${{ secrets.USERSNAP_SPACE_API_KEY }}
- APP_ENV: test
- PDF_API_URL: ${{ secrets.PDF_API_URL}}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- - name: Setup SSH agent
- uses: webfactory/ssh-agent@v0.8.0
+ - name: Set up SSH and deploy
+ uses: appleboy/ssh-action@v1.0.3
with:
- ssh-private-key: ${{ secrets.TEST_STACK_SSH_KEY }}
-
- - name: Run Ansible playbook
- uses: dawidd6/action-ansible-playbook@v2
- with:
- playbook: playbook.yml
- directory: ./tests/test-infrastructure
+ host: ${{ secrets.TEST_STACK_SERVER_IP }}
+ username: ec2-user
key: ${{ secrets.TEST_STACK_SSH_KEY }}
- inventory: |
- [test_server]
- ${{ secrets.TEST_STACK_SERVER_IP }} ansible_user=ec2-user
- options: |
- --verbose
+ command_timeout: 100m ## Haskell container build takes a lot of time.
+ script: |
+ REPO_URL="https://github.com/${{ github.repository }}"
+ DEST_DIR="$HOME/Documents/govtool"
+
+ # Create parent directory if it does not exist
+ mkdir -p "$(dirname "$DEST_DIR")"
+
+ # Check if $DEST_DIR exists
+ if [ -d "$DEST_DIR" ]; then
+ if [ -d "$DEST_DIR/.git" ]; then
+ cd $DEST_DIR || exit
+ echo "Updating repository..."
+ git fetch --all
+ git checkout --force "$GOVTOOL_TAG"
+ else
+ echo "Not a git repository. Re-cloning..."
+ rm -rf "$DEST_DIR"
+ git clone "$REPO_URL" "$DEST_DIR"
+ cd "$DEST_DIR" || exit
+ git checkout --force "$GOVTOOL_TAG"
+ fi
+ else
+ echo "Directory does not exist. Cloning repository..."
+ git clone "$REPO_URL" "$DEST_DIR"
+ cd "$DEST_DIR" || exit
+ git checkout --force "$GOVTOOL_TAG"
+ fi
+
+ # Execute the build-and-deploy.sh script
+ cd $DEST_DIR/tests/test-infrastructure
+ ./build-and-deploy.sh update-images
+ docker system prune
+ (docker image ls -q | xargs docker image rm --force ) || echo "Images cleaned-up"
+ envs: GOVTOOL_TAG, GRAFANA_ADMIN_PASSWORD, GRAFANA_SLACK_RECIPIENT, GRAFANA_SLACK_OAUTH_TOKEN, SENTRY_DSN_BACKEND, GTM_ID, NPMRC_TOKEN, SENTRY_DSN_FRONTEND, PIPELINE_URL, USERSNAP_SPACE_API_KEY, APP_ENV, PDF_API_URL
env:
GOVTOOL_TAG: ${{ github.sha }}
+ GRAFANA_ADMIN_PASSWORD: ${{ secrets.GRAFANA_ADMIN_PASSWORD }}
+ GRAFANA_SLACK_RECIPIENT: ${{ secrets.GRAFANA_SLACK_RECIPIENT }}
+ GRAFANA_SLACK_OAUTH_TOKEN: ${{ secrets.GRAFANA_SLACK_OAUTH_TOKEN }}
+ SENTRY_DSN_BACKEND: ${{ secrets.SENTRY_DSN_BACKEND }}
+ GTM_ID: ${{ secrets.GTM_ID }}
+ NPMRC_TOKEN: ${{ secrets.NPMRC_TOKEN }}
+ SENTRY_DSN_FRONTEND: ${{ secrets.SENTRY_DSN_FRONTEND }}
+ PIPELINE_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ USERSNAP_SPACE_API_KEY: ${{ secrets.USERSNAP_SPACE_API_KEY }}
+ APP_ENV: test
+ PDF_API_URL: ${{ secrets.PDF_API_URL }}
+ KUBER_API_KEY: ${{secrets.KUBER_API_KEY}}
diff --git a/.github/workflows/frontend_sonar_scan.yml b/.github/workflows/frontend_sonar_scan.yml
index 5a78a37b..a2504652 100644
--- a/.github/workflows/frontend_sonar_scan.yml
+++ b/.github/workflows/frontend_sonar_scan.yml
@@ -12,35 +12,35 @@ jobs:
runs-on: ubuntu-latest
permissions: read-all
steps:
- - uses: actions/checkout@v4
- with:
- fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- - name: Cache dependencies
- uses: actions/cache@v2
- with:
- path: govtool/frontend/node_modules
- key: ${{ runner.os }}-node-${{ hashFiles('govtool/frontend/package-lock.json') }}
+ - name: Cache dependencies
+ uses: actions/cache@v2
+ with:
+ path: govtool/frontend/node_modules
+ key: ${{ runner.os }}-node-${{ hashFiles('govtool/frontend/package-lock.json') }}
- - name: Set up Node.js
- uses: actions/setup-node@v4
- with:
- node-version-file: "govtool/frontend/.nvmrc"
- registry-url: "https://registry.npmjs.org/"
- scope: "@intersect.mbo"
- - name: 🧪 Test
- working-directory: govtool/frontend
- env:
- NODE_OPTIONS: "--max_old_space_size=6144"
- NODE_AUTH_TOKEN: ${{ secrets.NPMRC_TOKEN }}
- run: |
- npm ci
- npm run test:coverage
+ - name: Set up Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: "govtool/frontend/.nvmrc"
+ registry-url: "https://registry.npmjs.org/"
+ scope: "@intersect.mbo"
+ - name: 🧪 Test
+ working-directory: govtool/frontend
+ env:
+ NODE_OPTIONS: "--max_old_space_size=6144"
+ NODE_AUTH_TOKEN: ${{ secrets.NPMRC_TOKEN }}
+ run: |
+ npm ci
+ npm run test:coverage
- - uses: sonarsource/sonarqube-scan-action@master
- if: always()
- with:
- projectBaseDir: govtool/frontend
- env:
- SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- SONAR_HOST_URL: https://sonarcloud.io
\ No newline at end of file
+ - uses: sonarsource/sonarqube-scan-action@master
+ if: always()
+ with:
+ projectBaseDir: govtool/frontend
+ env:
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ SONAR_HOST_URL: https://sonarcloud.io
diff --git a/.github/workflows/merge.yaml b/.github/workflows/merge.yaml
index 29a7969d..d89b4ee3 100644
--- a/.github/workflows/merge.yaml
+++ b/.github/workflows/merge.yaml
@@ -20,6 +20,7 @@ jobs:
check-build-deploy:
environment: ${{ (github.ref_name == 'main' && 'prod-govtool') || (github.ref_name == 'staging' && 'pre-prod-govtool') || (github.ref_name == 'test' && 'qa-govtool') || (github.ref_name == 'develop' && 'dev-govtool') }}
strategy:
+ fail-fast: false
matrix:
include:
- workdir: ./govtool/backend
@@ -120,9 +121,10 @@ jobs:
context: ${{ matrix.workdir }}
file: ${{ matrix.dockerfile }}
tags: ${{ steps.image_lowercase.outputs.lowercase }}:${{ env.TAG }}
- load: true
+ load: false
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
+ outputs: type=docker,dest=/tmp/image-${{ matrix.name }}-${{ env.ENVIRONMENT }}.tar
build-args: |
VITE_APP_ENV=${{ secrets.VITE_APP_ENV }}
VITE_BASE_URL=${{ secrets.VITE_BASE_URL }}
@@ -145,11 +147,11 @@ jobs:
- name: Scan Docker image with Dockle
id: dockle
run: |
- wget https://github.com/goodwithtech/dockle/releases/download/v0.4.14/dockle_0.4.14_Linux-64bit.tar.gz
- tar zxvf dockle_0.4.14_Linux-64bit.tar.gz
+ wget -q https://github.com/goodwithtech/dockle/releases/download/v0.4.14/dockle_0.4.14_Linux-64bit.tar.gz
+ tar zxf dockle_0.4.14_Linux-64bit.tar.gz
sudo mv dockle /usr/local/bin
- dockle --exit-level fatal --format json --output ${{ matrix.workdir }}/dockle_scan_output.json ${{ steps.image_lowercase.outputs.lowercase }}:${{ env.TAG }}
+ dockle --exit-code 1 --exit-level fatal --format json -ak GHC_RELEASE_KEY -ak CABAL_INSTALL_RELEASE_KEY -ak STACK_RELEASE_KEY -ak KEY_SHA512 --input '/tmp/image-${{ matrix.name }}-${{ env.ENVIRONMENT }}.tar' --output ${{ matrix.workdir }}/dockle_scan_output.json
echo " dockle exited w/ $?"
cat ${{ matrix.workdir }}/dockle_scan_output.json
@@ -157,30 +159,6 @@ jobs:
- name: Push Docker image to GHCR
run: |
+ docker load -i '/tmp/image-${{ matrix.name }}-${{ env.ENVIRONMENT }}.tar'
+ rm -rf '/tmp/image-${{ matrix.name }}-${{ env.ENVIRONMENT }}.tar'
docker push ${{ steps.image_lowercase.outputs.lowercase }}:${{ env.TAG }}
-
- - name: Deploy with Qovery
- if: github.ref == 'refs/heads/develop'
- env:
- QOVERY_CLI_ACCESS_TOKEN: ${{secrets.QOVERY_CLI_ACCESS_TOKEN }}
- run: |
-
- echo "Deploying on $ENVIRONMENT"
- echo "Organization - ${{ vars.ORGANIZATION }}"
- echo "Project - ${{ vars.PROJECT }}"
-
- # Download and install Qovery CLI
- curl -s https://get.qovery.com | bash
-
- qovery container list \
- --organization ${{ vars.ORGANIZATION }} \
- --project ${{ vars.PROJECT }} \
- --environment $ENVIRONMENT
-
- qovery container deploy \
- --organization ${{ vars.ORGANIZATION }} \
- --project ${{ vars.PROJECT }} \
- --environment $ENVIRONMENT \
- --container ${{ matrix.qovery_container_name }} \
- --tag ${{ env.TAG }} \
- --watch
diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml
index 44601ee2..7b5c5685 100644
--- a/.github/workflows/pr.yaml
+++ b/.github/workflows/pr.yaml
@@ -16,6 +16,7 @@ permissions:
jobs:
static-checks:
strategy:
+ fail-fast: false
matrix:
include:
- workdir: ./govtool/backend
@@ -107,9 +108,10 @@ jobs:
context: ${{ matrix.workdir }}
file: ${{ matrix.dockerfile }}
tags: ${{ steps.image_lowercase.outputs.lowercase }}
- load: true
- # cache-from: type=local,src=/tmp/.buildx-cache
- # cache-to: type=local,dest=/tmp/.buildx-cache
+ load: false
+ cache-from: type=local,src=/tmp/.buildx-cache
+ cache-to: type=local,dest=/tmp/.buildx-cache
+ outputs: type=docker,dest=/tmp/image-${{ matrix.name }}-${{ github.sha }}-pr.tar
build-args: |
VITE_APP_ENV=${{ secrets.VITE_APP_ENV }}
VITE_BASE_URL=${{ secrets.VITE_BASE_URL }}
@@ -125,17 +127,12 @@ jobs:
- name: Scan Docker image with Dockle
id: dockle
run: |
- set -ex
- wget https://github.com/goodwithtech/dockle/releases/download/v0.4.14/dockle_0.4.14_Linux-64bit.tar.gz
- tar zxvf dockle_0.4.14_Linux-64bit.tar.gz
+ wget -q https://github.com/goodwithtech/dockle/releases/download/v0.4.14/dockle_0.4.14_Linux-64bit.tar.gz
+ tar zxf dockle_0.4.14_Linux-64bit.tar.gz
sudo mv dockle /usr/local/bin
- docker images
- docker image prune -af --filter "until=1h"
- docker save ${{ steps.image_lowercase.outputs.lowercase }} -o image.tar || :
- touch ${{ matrix.workdir }}/dockle_scan_output.json
- dockle --input image.tar --exit-level fatal --format json --output ${{ matrix.workdir }}/dockle_scan_output.json || :
- rm -rf image.tar
- echo " dockle exited w/ $?"
+
+ dockle --exit-code 1 --exit-level fatal -ak GHC_RELEASE_KEY -ak CABAL_INSTALL_RELEASE_KEY -ak STACK_RELEASE_KEY -ak KEY_SHA512 --format json --input '/tmp/image-${{ matrix.name }}-${{ github.sha }}-pr.tar' --output ${{ matrix.workdir }}/dockle_scan_output.json
+ rm -rf '/tmp/image-${{ matrix.name }}-${{ github.sha }}-pr.tar'
cat ${{ matrix.workdir }}/dockle_scan_output.json
echo "outcome=success" >> $GITHUB_OUTPUT
diff --git a/.github/workflows/test_backend.yml b/.github/workflows/test_backend.yml
index a8e0560f..faf2cbb8 100644
--- a/.github/workflows/test_backend.yml
+++ b/.github/workflows/test_backend.yml
@@ -72,8 +72,8 @@ jobs:
id: register-project
if: ${{success()}}
run: |
- chmod +x ./register_report.sh
- ./register_report.sh
+ chmod +x .github/scripts/register_report.sh
+ .github/scripts/register_report.sh
- if: steps.register-project.outputs.project_exists != 'true'
uses: JamesIves/github-pages-deploy-action@v4
with:
@@ -85,8 +85,8 @@ jobs:
- name: Generate report details
id: report-details
run: |
- chmod +x ./generate_report_details.sh
- ./generate_report_details.sh
+ chmod +x .github/scripts/generate_report_details.sh
+ .github/scripts/generate_report_details.sh
- name: Build report
uses: simple-elf/allure-report-action@master
@@ -102,8 +102,8 @@ jobs:
- name: Generate Latest Report
run: |
- chmod +x ./generate_latest_report_redirect.sh
- ./generate_latest_report_redirect.sh ${{steps.report-details.outputs.report_number}}
+ chmod +x .github/scripts/generate_latest_report_redirect.sh
+ .github/scripts/generate_latest_report_redirect.sh ${{steps.report-details.outputs.report_number}}
- name: Deploy report to Github Pages
uses: JamesIves/github-pages-deploy-action@v4
diff --git a/.github/workflows/test_integration_playwright.yml b/.github/workflows/test_integration_playwright.yml
index 474bbbfb..95a5151a 100644
--- a/.github/workflows/test_integration_playwright.yml
+++ b/.github/workflows/test_integration_playwright.yml
@@ -106,8 +106,8 @@ jobs:
id: register-project
if: ${{success()}}
run: |
- chmod +x ./register_report.sh
- ./register_report.sh
+ chmod +x .github/scripts/register_report.sh
+ .github/scripts/register_report.sh
- if: steps.register-project.outputs.project_exists != 'true'
uses: JamesIves/github-pages-deploy-action@v4
with:
@@ -119,8 +119,8 @@ jobs:
- name: Generate report details
id: report-details
run: |
- chmod +x ./generate_report_details.sh
- ./generate_report_details.sh
+ chmod +x .github/scripts/generate_report_details.sh
+ .github/scripts/generate_report_details.sh
- name: Build report
uses: simple-elf/allure-report-action@master
@@ -137,8 +137,8 @@ jobs:
- name: Generate Latest Report
run: |
- chmod +x ./generate_latest_report_redirect.sh
- ./generate_latest_report_redirect.sh ${{steps.report-details.outputs.report_number}}
+ chmod +x .github/scripts/generate_latest_report_redirect.sh
+ .github/scripts/generate_latest_report_redirect.sh ${{steps.report-details.outputs.report_number}}
- name: Deploy report to Github Pages
uses: JamesIves/github-pages-deploy-action@v4
diff --git a/.github/workflows/test_storybook.yml b/.github/workflows/test_storybook.yml
index 88b58a87..85f7f97c 100644
--- a/.github/workflows/test_storybook.yml
+++ b/.github/workflows/test_storybook.yml
@@ -23,7 +23,7 @@ jobs:
run: |
npm config set @intersect.mbo:registry "https://registry.npmjs.org/" --location=global
npm config set //registry.npmjs.org/:_authToken ${NPMRC_TOKEN} --location=global
- npm install
+ npm ci
- name: Install Playwright
run: npx playwright install --with-deps
- name: Build Storybook
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 00000000..c4d175a6
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,24 @@
+# See https://pre-commit.com for more information
+# See https://pre-commit.com/hooks.html for more hooks
+repos:
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v3.2.0
+ hooks:
+ - id: trailing-whitespace
+ - id: end-of-file-fixer
+
+ - repo: local
+ hooks:
+ - id: hlint
+ name: hlint
+ description: HLint gives suggestions on how to improve your source code.
+ entry: hlint
+ language: system
+ files: '\.l?hs$'
+
+ - id: stylish-haskell
+ name: stylish-haskell
+ description: Haskell code format checker.
+ entry: stylish-haskell --config govtool/backend/.stylish-haskell.yaml
+ language: system
+ files: '\.l?hs$'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1295a98c..4ec1ed24 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,6 +22,103 @@ changes.
-
+### Removed
+
+-
+
+## [sancho-v1.0.17](https://github.com/IntersectMBO/govtool/releases/tag/sancho-v1.0.17) 2024-09-05
+
+### Added
+
+-
+
+### Fixed
+
+- Make testIds for link and identity references in drep form unique [Issue 1928](https://github.com/IntersectMBO/govtool/issues/1928)
+- Fix saving the Do Not List checkbox value on DRep registration [Issue 1940](https://github.com/IntersectMBO/govtool/issues/1940)
+
+### Changed
+
+- Make displaying own DRep in DRep directory available [Issue 1934](https://github.com/IntersectMBO/govtool/issues/1934)
+
+### Removed
+
+-
+
+## [sancho-v1.0.16](https://github.com/IntersectMBO/govtool/releases/tag/sancho-v1.0.16) 2024-09-04
+
+### Fixed
+
+- Fix incorrect documentation link for "Learn More" button on proposal [Issue 1877](https://github.com/IntersectMBO/govtool/issues/1877)
+- Fix getVotes sql to query time from vote tx instead of govAaction tx [Issue 1925](https://github.com/IntersectMBO/govtool/issues/1925)
+- Map references from validation service to format expected by FE [Issue 1924](https://github.com/IntersectMBO/govtool/issues/1924)
+
+### Changed
+
+- Change the spelling of ADA to Ada or ada [Issue 1916](https://github.com/IntersectMBO/govtool/issues/1916)
+
+### Removed
+
+-
+
+## [sancho-v1.0.15](https://github.com/IntersectMBO/govtool/releases/tag/sancho-v1.0.15) 2024-09-03
+
+### Added
+
+- Add missing test DRep Details test IDs [Issue 1863](https://github.com/IntersectMBO/govtool/issues/1863)
+- Add missing system banners test IDs [Issue 1839](https://github.com/IntersectMBO/govtool/issues/1839)
+
+### Fixed
+
+- Delete duplicate text on DRep registration form [Issue 1847](https://github.com/IntersectMBO/govtool/issues/1847)
+- Fix modal content invisible on ios [Issue 1842](https://github.com/IntersectMBO/govtool/issues/1842)
+- Fix counting votes by CC committee members and SPOs [Issue 1838](https://github.com/IntersectMBO/govtool/issues/1838)
+- Fix displaying non relevant data in protocol parameter change Governance Action [Issue 1601](https://github.com/IntersectMBO/govtool/issues/1601)
+- Fix voting on info actions in bootstrapping phase [Issue 1876](https://github.com/IntersectMBO/govtool/issues/1876)
+- Fix missing DRep name whitespace validation [Issue 1873](https://github.com/IntersectMBO/govtool/issues/1873)
+- Fix displaying wrongly formatted Governance Action ID [Issue 1866](https://github.com/IntersectMBO/govtool/issues/1866k)
+- Make payment address optional in DRep registration and edit form [Issue 1871](https://github.com/IntersectMBO/govtool/issues/1871)
+- Fix displaying wrongly formatted Governance Action ID [Issue 1866](https://github.com/IntersectMBO/govtool/issues/1866)
+- Fix displaying the proper Governance Action Details on renavigating between pages
+- Fix displaying protocol params Governance Action details when metadata validation fails [Issue 1889](https://github.com/IntersectMBO/govtool/issues/1889)
+- Fix runtime error when navigating to GA details from Voted on by me tab [Issue 1910](https://github.com/IntersectMBO/govtool/issues/1910)
+
+### Changed
+
+- Replace diff library to avoid usage of `--force` in package installation
+- Bump @intersect.mbo/pdf-ui to v0.3.8
+- Change logo to Cardano GovTool [Issue 1851](https://github.com/IntersectMBO/govtool/issues/1851)
+- Change copy to Cardano GovTool [Issue 1852](https://github.com/IntersectMBO/govtool/issues/1852)
+- Replace mocked MrDRep label in DRep retired card with given name if exists, or make the description more neutral if the given name is not provided [Issue 1887](https://github.com/IntersectMBO/govtool/issues/1887)
+- Change home page hero copy [Issue 1903](https://github.com/IntersectMBO/govtool/issues/1903)
+- Bump cardano-node to 9.1.1 [Issue 1895](https://github.com/IntersectMBO/govtool/issues/1895)
+- Bump cardano-db-sync 13.5.0.1 [Issue 1906](https://github.com/IntersectMBO/govtool/issues/1906)
+- Adjust CIP119 support to match final designs [Issue 1850](https://github.com/IntersectMBO/govtool/issues/1850)
+
+## [sancho-v1.0.14](https://github.com/IntersectMBO/govtool/releases/tag/sancho-v1.0.14) 2024-08-26
+
+### Added
+
+- Add support for displaying protocol parameters governance actions [Issue 1601](https://github.com/IntersectMBO/govtool/issues/1601)
+- Add SPO and CC committee total votes to gov actions [Issue 1704](https://github.com/IntersectMBO/govtool/issues/1704)
+- Add support for hard fork initiation governance action details [Issue 1600](https://github.com/IntersectMBO/govtool/issues/1600)
+- Add support for hard fork initiation previous governance action data [Issue 1600](https://github.com/IntersectMBO/govtool/issues/1600)
+- Add support for CIP-119 on the backend and metadata validation [Issue 1758](https://github.com/IntersectMBO/govtool/issues/1758)
+- Add support for CIP-119 on the frontend [Issue 1760](https://github.com/IntersectMBO/govtool/issues/1758)
+- Add support for HF Initiation and Protocol Parameter Change governance action builders [Issue 1600](https://github.com/IntersectMBO/govtool/issues/1600) & [Issue 1601](https://github.com/IntersectMBO/govtool/issues/1601)
+
+### Fixed
+
+- Fix typescript bug leading to runtime error when entering Governance Action details page via direct link [Issue 1801](https://github.com/IntersectMBO/govtool/issues/1801)
+- Fix accessing missing epochParams drep_deposit [Issue 1733](https://github.com/IntersectMBO/govtool/issues/1733)
+
+### Changed
+
+- Bump @intersect.mbo/pdf-ui to v0.3.7
+- Decrease level of wallet related sentry reports [Issue 1699](https://github.com/IntersectMBO/govtool/issues/1699)
+- Bump cardano-db-sync to 13.3.0.0 [Issue 1809](https://github.com/IntersectMBO/govtool/issues/1809)
+- Update Gitbook links [Issue 1774](https://github.com/IntersectMBO/govtool/issues/1774)
+
## [sancho-v1.0.13](https://github.com/IntersectMBO/govtool/releases/tag/sancho-v1.0.13) 2024-08-22
### Added
@@ -30,6 +127,8 @@ changes.
- Add network metrics model to frontend service
- Added workflows to add labels to issues
- Make voting on governance actions enabled based on protocol version [Issue 1703](https://github.com/IntersectMBO/govtool/issues/1703)
+- Add banner informing about network [Issue 1702](https://github.com/IntersectMBO/govtool/issues/1702)
+- Add banner informing about bootstrapping phase [Issue 1708](https://github.com/IntersectMBO/govtool/issues/1708)
### Fixed
diff --git a/README.md b/README.md
index 0f81436c..8a8aea50 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
- Monorepo containing Voltaire GovTool and supporting utilities
+ Monorepo containing Cardano GovTool and supporting utilities
@@ -18,7 +18,7 @@
## 🌄 Purpose
-The Voltaire GovTool enables ada holders to experience the governance features described in [CIP-1694](https://github.com/cardano-foundation/CIPs/blob/master/CIP-1694/README.md).
+The Cardano GovTool enables ada holders to experience the governance features described in [CIP-1694](https://github.com/cardano-foundation/CIPs/blob/master/CIP-1694/README.md).
### Instances
@@ -48,7 +48,7 @@ Learn more; [docs.gov.tools](https://docs.gov.tools/).
### Utilities
-- [Governance Action Loader](./governance-action-loader/)
+- [Governance Action Loader](./gov-action-loader/)
### Backend
diff --git a/docs/GOVERNANCE_ACTION_SUBMISSION.md b/docs/GOVERNANCE_ACTION_SUBMISSION.md
index 2262d5dd..c2aa0825 100644
--- a/docs/GOVERNANCE_ACTION_SUBMISSION.md
+++ b/docs/GOVERNANCE_ACTION_SUBMISSION.md
@@ -15,7 +15,15 @@ For creating the Governance Action, you need to consume 2 utility methods provid
### Types
```typescript
-import { VotingProposalBuilder } from "@emurgo/cardano-serialization-lib-nodejs";
+import {
+ VotingProposalBuilder,
+ Costmdls,
+ DrepVotingThresholds,
+ ExUnitPrices,
+ UnitInterval,
+ ExUnits,
+ PoolVotingThresholds,
+} from "@emurgo/cardano-serialization-lib-nodejs";
interface GovernanceAction {
title: string;
@@ -37,6 +45,48 @@ interface TreasuryProps {
url: string;
}
+type ProtocolParamsUpdate = {
+ adaPerUtxo: string;
+ collateralPercentage: number;
+ committeeTermLimit: number;
+ costModels: Costmdls;
+ drepDeposit: string;
+ drepInactivityPeriod: number;
+ drepVotingThresholds: DrepVotingThresholds;
+ executionCosts: ExUnitPrices;
+ expansionRate: UnitInterval;
+ governanceActionDeposit: string;
+ governanceActionValidityPeriod: number;
+ keyDeposit: string;
+ maxBlockBodySize: number;
+ maxBlockExUnits: ExUnits;
+ maxBlockHeaderSize: number;
+ maxCollateralInputs: number;
+ maxEpoch: number;
+ maxTxExUnits: ExUnits;
+ maxTxSize: number;
+ maxValueSize: number;
+ minCommitteeSize: number;
+ minPoolCost: string;
+ minFeeA: string;
+ minFeeB: string;
+ nOpt: number;
+ poolDeposit: string;
+ poolPledgeInfluence: UnitInterval;
+ poolVotingThresholds: PoolVotingThresholds;
+ refScriptCoinsPerByte: UnitInterval;
+ treasuryGrowthRate: UnitInterval;
+};
+
+interface ProtocolParameterChangeProps {
+ prevGovernanceActionHash: string;
+ prevGovernanceActionIndex: number;
+ url: string;
+ hash: string;
+
+ protocolParamsUpdate: Partial
;
+}
+
const createGovernanceActionJsonLD: (
governanceAction: GovernanceAction
) => NodeObject;
@@ -111,10 +161,14 @@ Example:
```typescript
// When used within a CardanoProvider
-const { buildSignSubmitConwayCertTx, buildNewInfoGovernanceAction } =
- useCardano();
-
-// hash of the generated Governance Action metadata, url of the metadata
+const {
+ buildSignSubmitConwayCertTx,
+ buildNewInfoGovernanceAction,
+ buildProtocolParameterChangeGovernanceAction,
+ buildHardForkInitiationGovernanceAction,
+} = useCardano();
+
+// Info Governance Action
const govActionBuilder = await buildNewInfoGovernanceAction({ hash, url });
// sign and submit the transaction
@@ -123,7 +177,7 @@ await buildSignSubmitConwayCertTx({
type: "createGovAction",
});
-// or if you want to use the Treasury Governance Action
+// Treasury Governance Action
const { buildTreasuryGovernanceAction } = useCardano();
// hash of the generated Governance Action metadata, url of the metadata, amount of the transaction, receiving address is the stake key address
@@ -134,6 +188,31 @@ const govActionBuilder = await buildTreasuryGovernanceAction({
receivingAddress,
});
+// Protocol Parameter Change Governance Action
+const { buildProtocolParameterChangeGovernanceAction } = useCardano();
+
+// hash of the previous Governance Action, index of the previous Governance Action, url of the metadata, hash of the metadata, and the updated protocol parameters
+const govActionBuilder = await buildProtocolParameterChangeGovernanceAction({
+ prevGovernanceActionHash,
+ prevGovernanceActionIndex,
+ url,
+ hash,
+ protocolParamsUpdate,
+});
+
+// Hard Fork Initiation Governance Action
+const { buildHardForkInitiationGovernanceAction } = useCardano();
+
+// hash of the previous Governance Action, index of the previous Governance Action, url of the metadata, hash of the metadata, and the major and minor numbers of the hard fork initiation
+const govActionBuilder = await buildHardForkInitiationGovernanceAction({
+ prevGovernanceActionHash,
+ prevGovernanceActionIndex,
+ url,
+ hash,
+ major,
+ minor,
+});
+
// sign and submit the transaction
await buildSignSubmitConwayCertTx({
govActionBuilder,
diff --git a/govtool/backend/Dockerfile b/govtool/backend/Dockerfile
index fbeb614a..38c09931 100644
--- a/govtool/backend/Dockerfile
+++ b/govtool/backend/Dockerfile
@@ -4,4 +4,4 @@ FROM $BASE_IMAGE_REPO:$BASE_IMAGE_TAG
WORKDIR /src
COPY . .
RUN cabal build
-RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-1.0.13/x/vva-be/build/vva-be/vva-be /usr/local/bin
+RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-1.0.17/x/vva-be/build/vva-be/vva-be /usr/local/bin
diff --git a/govtool/backend/Dockerfile.base b/govtool/backend/Dockerfile.base
index 8f4e4c35..6dd3c75a 100644
--- a/govtool/backend/Dockerfile.base
+++ b/govtool/backend/Dockerfile.base
@@ -6,5 +6,13 @@
FROM haskell:9.2.7-buster
WORKDIR /src
+
+RUN apt-get update && \
+ apt-get install -y wget lsb-release && \
+ sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' && \
+ wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - && \
+ apt-get update && \
+ apt-get install -y postgresql-14 libpq-dev
+
COPY . .
RUN cabal update && cabal configure && cabal install --only-dependencies && rm -rf /src/*
diff --git a/govtool/backend/Dockerfile.qovery b/govtool/backend/Dockerfile.qovery
index a6789ec6..cdf1acc7 100644
--- a/govtool/backend/Dockerfile.qovery
+++ b/govtool/backend/Dockerfile.qovery
@@ -4,7 +4,7 @@ FROM $BASE_IMAGE_REPO:$BASE_IMAGE_TAG
WORKDIR /src
COPY . .
RUN cabal build
-RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-1.0.13/x/vva-be/build/vva-be/vva-be /usr/local/bin
+RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-1.0.17/x/vva-be/build/vva-be/vva-be /usr/local/bin
# Expose the necessary port
EXPOSE 9876
diff --git a/govtool/backend/sql/get-drep-info.sql b/govtool/backend/sql/get-drep-info.sql
index 2e8ee08f..ca4505d6 100644
--- a/govtool/backend/sql/get-drep-info.sql
+++ b/govtool/backend/sql/get-drep-info.sql
@@ -176,7 +176,14 @@ SELECT
DRepRegister.tx_hash,
DRepRetire.tx_hash,
SoleVoterRegister.tx_hash,
- SoleVoterRetire.tx_hash
+ SoleVoterRetire.tx_hash,
+ off_chain_vote_drep_data.payment_address,
+ off_chain_vote_drep_data.given_name,
+ off_chain_vote_drep_data.objectives,
+ off_chain_vote_drep_data.motivations,
+ off_chain_vote_drep_data.qualifications,
+ off_chain_vote_drep_data.image_url,
+ off_chain_vote_drep_data.image_hash
FROM
IsRegisteredAsDRep
CROSS JOIN IsRegisteredAsSoleVoter
@@ -189,3 +196,6 @@ FROM
CROSS JOIN DRepRetire
CROSS JOIN SoleVoterRegister
CROSS JOIN SoleVoterRetire
+ CROSS JOIN LatestRegistrationEntry
+ LEFT JOIN off_chain_vote_data ON off_chain_vote_data.voting_anchor_id = LatestRegistrationEntry.voting_anchor_id
+ LEFT JOIN off_chain_vote_drep_data ON off_chain_vote_drep_data.off_chain_vote_data_id = off_chain_vote_data.id
diff --git a/govtool/backend/sql/get-votes.sql b/govtool/backend/sql/get-votes.sql
index 7a875aba..31aaba85 100644
--- a/govtool/backend/sql/get-votes.sql
+++ b/govtool/backend/sql/get-votes.sql
@@ -11,6 +11,6 @@ on gov_action_tx.id = gov_action_proposal.tx_id
join tx as vote_tx
on vote_tx.id = voting_procedure.tx_id
join block
-on block.id = gov_action_tx.block_id
+on block.id = vote_tx.block_id
where drep_hash.raw = decode(?, 'hex')
order by voting_procedure.gov_action_proposal_id, voting_procedure.drep_voter, voting_procedure.id desc
diff --git a/govtool/backend/sql/list-dreps.sql b/govtool/backend/sql/list-dreps.sql
index 399b5087..917f0641 100644
--- a/govtool/backend/sql/list-dreps.sql
+++ b/govtool/backend/sql/list-dreps.sql
@@ -29,7 +29,14 @@ SELECT
encode(dr_voting_anchor.tx_hash, 'hex') AS tx_hash,
newestRegister.time AS last_register_time,
COALESCE(latestDeposit.deposit, 0),
- non_deregister_voting_anchor.url IS NOT NULL AS has_non_deregister_voting_anchor
+ non_deregister_voting_anchor.url IS NOT NULL AS has_non_deregister_voting_anchor,
+ off_chain_vote_drep_data.payment_address,
+ off_chain_vote_drep_data.given_name,
+ off_chain_vote_drep_data.objectives,
+ off_chain_vote_drep_data.motivations,
+ off_chain_vote_drep_data.qualifications,
+ off_chain_vote_drep_data.image_url,
+ off_chain_vote_drep_data.image_hash
FROM
drep_hash dh
JOIN (
@@ -89,6 +96,8 @@ FROM
AND DRepDistr.rn = 1
LEFT JOIN voting_anchor va ON va.id = dr_voting_anchor.voting_anchor_id
LEFT JOIN voting_anchor non_deregister_voting_anchor on non_deregister_voting_anchor.id = dr_non_deregister_voting_anchor.voting_anchor_id
+ LEFT JOIN off_chain_vote_data ON off_chain_vote_data.voting_anchor_id = va.id
+ LEFT JOIN off_chain_vote_drep_data on off_chain_vote_drep_data.off_chain_vote_data_id = off_chain_vote_data.id
CROSS JOIN DRepActivity
LEFT JOIN voting_procedure AS voting_procedure ON voting_procedure.drep_voter = dh.id
LEFT JOIN tx AS tx ON tx.id = voting_procedure.tx_id
@@ -128,4 +137,11 @@ GROUP BY
dr_voting_anchor.tx_hash,
newestRegister.time,
latestDeposit.deposit,
- non_deregister_voting_anchor.url
+ non_deregister_voting_anchor.url,
+ off_chain_vote_drep_data.payment_address,
+ off_chain_vote_drep_data.given_name,
+ off_chain_vote_drep_data.objectives,
+ off_chain_vote_drep_data.motivations,
+ off_chain_vote_drep_data.qualifications,
+ off_chain_vote_drep_data.image_url,
+ off_chain_vote_drep_data.image_hash
diff --git a/govtool/backend/sql/list-proposals-my.sql b/govtool/backend/sql/list-proposals-my.sql
deleted file mode 100644
index fd2454ae..00000000
--- a/govtool/backend/sql/list-proposals-my.sql
+++ /dev/null
@@ -1,113 +0,0 @@
-WITH LatestDrepDistr AS (
- SELECT
- *,
- ROW_NUMBER() OVER (PARTITION BY hash_id ORDER BY epoch_no DESC) AS rn
- FROM
- drep_distr
-),
-EpochUtils AS (
- SELECT
- (Max(end_time) - Min(end_time)) / (Max(NO) - Min(NO)) AS epoch_duration,
- Max(NO) AS last_epoch_no,
- Max(end_time) AS last_epoch_end_time
- FROM
- epoch
-),
-always_no_confidence_voting_power AS (
- SELECT
- coalesce((
- SELECT
- amount
- FROM drep_hash
- LEFT JOIN drep_distr ON drep_hash.id = drep_distr.hash_id
- WHERE
- drep_hash.view = 'drep_always_no_confidence' ORDER BY epoch_no DESC LIMIT 1), 0) AS amount
-),
-always_abstain_voting_power AS (
- SELECT
- coalesce((
- SELECT
- amount
- FROM drep_hash
- LEFT JOIN drep_distr ON drep_hash.id = drep_distr.hash_id
- WHERE
- drep_hash.view = 'drep_always_abstain' ORDER BY epoch_no DESC LIMIT 1), 0) AS amount
-)
-SELECT
- gov_action_proposal.id AS proposal_id,
- encode(creator_tx.hash, 'hex') AS tx_hash,
- gov_action_proposal.index,
- gov_action_proposal.type::text,
- CASE
- WHEN gov_action_proposal.type = 'TreasuryWithdrawals' THEN
- json_build_object('Reward Address', stake_address.view, 'Amount', treasury_withdrawal.amount)
- WHEN gov_action_proposal.type::text = 'InfoAction' THEN
- json_build_object()
- ELSE
- NULL
- END AS description,
- epoch_utils.last_epoch_end_time + epoch_utils.epoch_duration * (gov_action_proposal.expiration - epoch_utils.last_epoch_no) AS expiry_date,
- gov_action_proposal.expiration AS expiry_epoch_no,
- creator_block.time AS created_date,
- creator_block.epoch_no AS created_epoch_no,
- voting_anchor.url,
- encode(voting_anchor.data_hash, 'hex') AS metadata_hash,
- off_chain_vote_gov_action_data.title,
- off_chain_vote_gov_action_data.abstract,
- off_chain_vote_gov_action_data.motivation,
- off_chain_vote_gov_action_data.rationale,
- coalesce(Sum(ldd.amount) FILTER (WHERE voting_procedure.vote::text = 'Yes'), 0) +
- CASE
- WHEN gov_action_proposal.type = 'NoConfidence' THEN always_no_confidence_voting_power.amount
- ELSE 0
- END AS yes_votes,
- coalesce(Sum(ldd.amount) FILTER (WHERE voting_procedure.vote::text = 'No'), 0) +
- CASE
- WHEN gov_action_proposal.type = 'NoConfidence' THEN 0
- ELSE always_no_confidence_voting_power.amount
- END AS no_votes,
- coalesce(Sum(ldd.amount) FILTER (WHERE voting_procedure.vote::text = 'Abstain'), 0) + always_abstain_voting_power.amount AS abstain_votes
-FROM
- gov_action_proposal
- LEFT JOIN treasury_withdrawal ON gov_action_proposal.id = treasury_withdrawal.gov_action_proposal_id
- LEFT JOIN stake_address ON stake_address.id = treasury_withdrawal.stake_address_id
- CROSS JOIN EpochUtils AS epoch_utils
- CROSS JOIN always_no_confidence_voting_power
- CROSS JOIN always_abstain_voting_power
- CROSS JOIN off_chain_vote_gov_action_data ON off_chain_vote_gov_action_data.off_chain_vote_data_id = off_chain_vote_data.id
- JOIN tx AS creator_tx ON creator_tx.id = gov_action_proposal.tx_id
- JOIN block AS creator_block ON creator_block.id = creator_tx.block_id
- LEFT JOIN voting_anchor ON voting_anchor.id = gov_action_proposal.voting_anchor_id
- LEFT JOIN off_chain_vote_data ON off_chain_vote_data.voting_anchor_id = voting_anchor.id
- LEFT JOIN voting_procedure ON voting_procedure.gov_action_proposal_id = gov_action_proposal.id
- LEFT JOIN LatestDrepDistr ldd ON ldd.hash_id = voting_procedure.drep_voter AND ldd.rn = 1
-WHERE (NOT ?
- OR (concat(encode(creator_tx.hash, 'hex'), '#', gov_action_proposal.index) IN ?))
-AND gov_action_proposal.expiration > (
- SELECT
- Max(NO)
- FROM
- epoch)
- AND gov_action_proposal.ratified_epoch IS NULL
- AND gov_action_proposal.enacted_epoch IS NULL
- AND gov_action_proposal.expired_epoch IS NULL
- AND gov_action_proposal.dropped_epoch IS NULL
-GROUP BY
- (gov_action_proposal.id,
- stake_address.view,
- treasury_withdrawal.amount,
- creator_block.epoch_no,
- off_chain_vote_gov_action_data.title,
- off_chain_vote_gov_action_data.abstract,
- off_chain_vote_gov_action_data.motivation,
- off_chain_vote_gov_action_data.rationale,
- gov_action_proposal.index,
- creator_tx.hash,
- creator_block.time,
- epoch_utils.epoch_duration,
- epoch_utils.last_epoch_no,
- epoch_utils.last_epoch_end_time,
- voting_anchor.url,
- voting_anchor.data_hash,
- always_no_confidence_voting_power.amount,
- always_abstain_voting_power.amount)
diff --git a/govtool/backend/sql/list-proposals.sql b/govtool/backend/sql/list-proposals.sql
index f09ec6f6..7926fd6b 100644
--- a/govtool/backend/sql/list-proposals.sql
+++ b/govtool/backend/sql/list-proposals.sql
@@ -44,6 +44,12 @@ SELECT
when gov_action_proposal.type::text = 'InfoAction' then
json_build_object()
+
+ when gov_action_proposal.type::text = 'HardForkInitiation' then
+ json_build_object(
+ 'major', (gov_action_proposal.description->'contents'->1->>'major')::int,
+ 'minor', (gov_action_proposal.description->'contents'->1->>'minor')::int
+ )
else
null
end
@@ -54,23 +60,32 @@ SELECT
creator_block.epoch_no,
voting_anchor.url,
encode(voting_anchor.data_hash, 'hex'),
+ ROW_TO_JSON(proposal_params),
off_chain_vote_gov_action_data.title,
off_chain_vote_gov_action_data.abstract,
off_chain_vote_gov_action_data.motivation,
off_chain_vote_gov_action_data.rationale,
- coalesce(Sum(ldd.amount) FILTER (WHERE voting_procedure.vote::text = 'Yes'), 0) +(
+ coalesce(Sum(ldd_drep.amount) FILTER (WHERE voting_procedure.vote::text = 'Yes'), 0) +(
CASE WHEN gov_action_proposal.type = 'NoConfidence' THEN
always_no_confidence_voting_power.amount
ELSE
0
END) "yes_votes",
- coalesce(Sum(ldd.amount) FILTER (WHERE voting_procedure.vote::text = 'No'), 0) +(
+ coalesce(Sum(ldd_drep.amount) FILTER (WHERE voting_procedure.vote::text = 'No'), 0) +(
CASE WHEN gov_action_proposal.type = 'NoConfidence' THEN
0
ELSE
always_no_confidence_voting_power.amount
END) "no_votes",
- coalesce(Sum(ldd.amount) FILTER (WHERE voting_procedure.vote::text = 'Abstain'), 0) + always_abstain_voting_power.amount "abstain_votes"
+ coalesce(Sum(ldd_drep.amount) FILTER (WHERE voting_procedure.vote::text = 'Abstain'), 0) + always_abstain_voting_power.amount "abstain_votes",
+ coalesce(vp_by_pool.poolYesVotes, 0),
+ coalesce(vp_by_pool.poolNoVotes, 0),
+ coalesce(vp_by_pool.poolAbstainVotes, 0),
+ coalesce(vp_by_cc.ccYesVotes, 0),
+ coalesce(vp_by_cc.ccNoVotes, 0),
+ coalesce(vp_by_cc.ccAbstainVotes, 0),
+ prev_gov_action.index as prev_gov_action_index,
+ encode(prev_gov_action_tx.hash, 'hex') as prev_gov_action_tx_hash
FROM
gov_action_proposal
LEFT JOIN treasury_withdrawal
@@ -83,11 +98,47 @@ FROM
JOIN tx AS creator_tx ON creator_tx.id = gov_action_proposal.tx_id
JOIN block AS creator_block ON creator_block.id = creator_tx.block_id
LEFT JOIN voting_anchor ON voting_anchor.id = gov_action_proposal.voting_anchor_id
+ LEFT JOIN param_proposal as proposal_params ON gov_action_proposal.param_proposal = proposal_params.id
LEFT JOIN off_chain_vote_data ON off_chain_vote_data.voting_anchor_id = voting_anchor.id
LEFT JOIN off_chain_vote_gov_action_data ON off_chain_vote_gov_action_data.off_chain_vote_data_id = off_chain_vote_data.id
LEFT JOIN voting_procedure ON voting_procedure.gov_action_proposal_id = gov_action_proposal.id
- LEFT JOIN LatestDrepDistr ldd ON ldd.hash_id = voting_procedure.drep_voter
- AND ldd.rn = 1
+ LEFT JOIN LatestDrepDistr ldd_drep ON ldd_drep.hash_id = voting_procedure.drep_voter
+ AND ldd_drep.rn = 1
+ LEFT JOIN
+ (
+ SELECT
+ gov_action_proposal_id,
+ SUM(CASE WHEN vote = 'Yes' THEN 1 ELSE 0 END) AS poolYesVotes,
+ SUM(CASE WHEN vote = 'No' THEN 1 ELSE 0 END) AS poolNoVotes,
+ SUM(CASE WHEN vote = 'Abstain' THEN 1 ELSE 0 END) AS poolAbstainVotes
+ FROM
+ voting_procedure
+ WHERE
+ pool_voter IS NOT NULL
+ GROUP BY
+ gov_action_proposal_id
+ ) vp_by_pool
+ ON gov_action_proposal.id = vp_by_pool.gov_action_proposal_id
+ LEFT JOIN
+ (
+ SELECT
+ gov_action_proposal_id,
+ SUM(CASE WHEN vote = 'Yes' THEN 1 ELSE 0 END) AS ccYesVotes,
+ SUM(CASE WHEN vote = 'No' THEN 1 ELSE 0 END) AS ccNoVotes,
+ SUM(CASE WHEN vote = 'Abstain' THEN 1 ELSE 0 END) AS ccAbstainVotes
+ FROM
+ voting_procedure
+ WHERE
+ committee_voter IS NOT NULL
+ GROUP BY
+ gov_action_proposal_id
+ ) vp_by_cc
+ ON gov_action_proposal.id = vp_by_cc.gov_action_proposal_id
+
+ LEFT JOIN LatestDrepDistr ldd_cc ON ldd_cc.hash_id = voting_procedure.committee_voter
+ AND ldd_cc.rn = 1
+ LEFT JOIN gov_action_proposal AS prev_gov_action ON gov_action_proposal.prev_gov_action_proposal = prev_gov_action.id
+ LEFT JOIN tx AS prev_gov_action_tx ON prev_gov_action.tx_id = prev_gov_action_tx.id
WHERE (NOT ?
OR (concat(encode(creator_tx.hash, 'hex'), '#', gov_action_proposal.index) IN ?))
AND gov_action_proposal.expiration >(
@@ -108,13 +159,22 @@ GROUP BY
off_chain_vote_gov_action_data.abstract,
off_chain_vote_gov_action_data.motivation,
off_chain_vote_gov_action_data.rationale,
+ vp_by_pool.poolYesVotes,
+ vp_by_pool.poolNoVotes,
+ vp_by_pool.poolAbstainVotes,
+ vp_by_cc.ccYesVotes,
+ vp_by_cc.ccNoVotes,
+ vp_by_cc.ccAbstainVotes,
gov_action_proposal.index,
creator_tx.hash,
creator_block.time,
epoch_utils.epoch_duration,
epoch_utils.last_epoch_no,
epoch_utils.last_epoch_end_time,
+ proposal_params,
voting_anchor.url,
voting_anchor.data_hash,
always_no_confidence_voting_power.amount,
- always_abstain_voting_power.amount)
\ No newline at end of file
+ always_abstain_voting_power.amount,
+ prev_gov_action.index,
+ prev_gov_action_tx.hash)
\ No newline at end of file
diff --git a/govtool/backend/src/VVA/API.hs b/govtool/backend/src/VVA/API.hs
index 702af1b7..64f6236d 100644
--- a/govtool/backend/src/VVA/API.hs
+++ b/govtool/backend/src/VVA/API.hs
@@ -22,6 +22,7 @@ import Data.Ord (Down (..))
import Data.Text hiding (any, drop, elem, filter, length, map, null, take)
import qualified Data.Text as Text
import qualified Data.Vector as V
+import Data.Time.LocalTime (TimeZone, getCurrentTimeZone)
import Numeric.Natural (Natural)
@@ -44,6 +45,7 @@ import qualified VVA.Types as Types
import VVA.Types (App, AppEnv (..),
AppError (CriticalError, InternalError, ValidationError),
CacheEnv (..))
+import Data.Time (TimeZone, localTimeToUTC)
type VVAApi =
"drep" :> "list"
@@ -112,7 +114,14 @@ drepRegistrationToDrep Types.DRepRegistration {..} =
dRepStatus = mapDRepStatus dRepRegistrationStatus,
dRepType = mapDRepType dRepRegistrationType,
dRepLatestTxHash = HexText <$> dRepRegistrationLatestTxHash,
- dRepLatestRegistrationDate = dRepRegistrationLatestRegistrationDate
+ dRepLatestRegistrationDate = dRepRegistrationLatestRegistrationDate,
+ dRepPaymentAddress = dRepRegistrationPaymentAddress,
+ dRepGivenName = dRepRegistrationGivenName,
+ dRepObjectives = dRepRegistrationObjectives,
+ dRepMotivations = dRepRegistrationMotivations,
+ dRepQualifications = dRepRegistrationQualifications,
+ dRepImageUrl = dRepRegistrationImageUrl,
+ dRepImageHash = HexText <$> dRepRegistrationImageHash
}
delegationToResponse :: Types.Delegation -> DelegationResponse
@@ -179,27 +188,36 @@ getVotingPower (unHexText -> dRepId) = do
CacheEnv {dRepVotingPowerCache} <- asks vvaCache
cacheRequest dRepVotingPowerCache dRepId $ DRep.getVotingPower dRepId
-proposalToResponse :: Types.Proposal -> ProposalResponse
-proposalToResponse Types.Proposal {..} =
+proposalToResponse :: TimeZone -> Types.Proposal -> ProposalResponse
+proposalToResponse timeZone Types.Proposal {..} =
ProposalResponse
{ proposalResponseId = pack $ show proposalId,
proposalResponseTxHash = HexText proposalTxHash,
proposalResponseIndex = proposalIndex,
proposalResponseType = fromMaybe InfoAction $ readMaybe $ unpack proposalType,
proposalResponseDetails = GovernanceActionDetails <$> proposalDetails,
- proposalResponseExpiryDate = proposalExpiryDate,
+ proposalResponseExpiryDate = localTimeToUTC timeZone <$> proposalExpiryDate,
proposalResponseExpiryEpochNo = proposalExpiryEpochNo,
- proposalResponseCreatedDate = proposalCreatedDate,
+ proposalResponseCreatedDate = localTimeToUTC timeZone proposalCreatedDate,
proposalResponseCreatedEpochNo = proposalCreatedEpochNo,
proposalResponseUrl = proposalUrl,
proposalResponseMetadataHash = HexText proposalDocHash,
+ proposalResponseProtocolParams = ProtocolParams <$> proposalProtocolParams,
proposalResponseTitle = proposalTitle,
proposalResponseAbstract = proposalAbstract,
proposalResponseMotivation = proposalMotivation,
proposalResponseRationale = proposalRationale,
- proposalResponseYesVotes = proposalYesVotes,
- proposalResponseNoVotes = proposalNoVotes,
- proposalResponseAbstainVotes = proposalAbstainVotes
+ proposalResponseDRepYesVotes = proposalDRepYesVotes,
+ proposalResponseDRepNoVotes = proposalDRepNoVotes,
+ proposalResponseDRepAbstainVotes = proposalDRepAbstainVotes,
+ proposalResponsePoolYesVotes = proposalPoolYesVotes,
+ proposalResponsePoolNoVotes = proposalPoolNoVotes,
+ proposalResponsePoolAbstainVotes = proposalPoolAbstainVotes,
+ proposalResponseCcYesVotes = proposalCcYesVotes,
+ proposalResponseCcNoVotes = proposalCcNoVotes,
+ proposalResponseCcAbstainVotes = proposalCcAbstainVotes,
+ proposalResponsePrevGovActionIndex = proposalPrevGovActionIndex,
+ proposalResponsePrevGovActionTxHash = HexText <$> proposalPrevGovActionTxHash
}
voteToResponse :: Types.Vote -> VoteParams
@@ -222,7 +240,9 @@ mapSortAndFilterProposals
-> [Types.Proposal]
-> m [ProposalResponse]
mapSortAndFilterProposals selectedTypes sortMode proposals = do
- let mappedProposals = map proposalToResponse proposals
+ timeZone <- liftIO getCurrentTimeZone
+
+ let mappedProposals = map (proposalToResponse timeZone) proposals
let filteredProposals =
if null selectedTypes
then mappedProposals
@@ -232,11 +252,14 @@ mapSortAndFilterProposals selectedTypes sortMode proposals = do
proposalResponseType `elem` selectedTypes
)
mappedProposals
+
+ let totalYesVotes (ProposalResponse{..}) = proposalResponseDRepYesVotes + proposalResponsePoolYesVotes + proposalResponseCcYesVotes
+
let sortedProposals = case sortMode of
Nothing -> filteredProposals
Just NewestCreated -> sortOn (Down . proposalResponseCreatedDate) filteredProposals
Just SoonestToExpire -> sortOn proposalResponseExpiryDate filteredProposals
- Just MostYesVotes -> sortOn (Down . proposalResponseYesVotes) filteredProposals
+ Just MostYesVotes -> sortOn (Down . totalYesVotes) filteredProposals
return sortedProposals
getVotes :: App m => HexText -> [GovernanceActionType] -> Maybe GovernanceActionSortMode -> Maybe Text -> m [VoteResponse]
@@ -270,6 +293,13 @@ drepInfo (unHexText -> dRepId) = do
, dRepInfoResponseDRepRetireTxHash = HexText <$> dRepInfoDRepRetireTx
, dRepInfoResponseSoleVoterRegisterTxHash = HexText <$> dRepInfoSoleVoterRegisterTx
, dRepInfoResponseSoleVoterRetireTxHash = HexText <$> dRepInfoSoleVoterRetireTx
+ , dRepInfoResponsePaymentAddress = dRepInfoPaymentAddress
+ , dRepInfoResponseGivenName = dRepInfoGivenName
+ , dRepInfoResponseObjectives = dRepInfoObjectives
+ , dRepInfoResponseMotivations = dRepInfoMotivations
+ , dRepInfoResponseQualifications = dRepInfoQualifications
+ , dRepInfoResponseImageUrl = dRepInfoImageUrl
+ , dRepInfoResponseImageHash = HexText <$> dRepInfoImageHash
}
getCurrentDelegation :: App m => HexText -> m (Maybe DelegationResponse)
@@ -346,7 +376,10 @@ getProposal g@(GovActionId govActionTxHash govActionIndex) mDrepId' = do
let mDrepId = unHexText <$> mDrepId'
CacheEnv {getProposalCache} <- asks vvaCache
proposal@Types.Proposal {proposalUrl, proposalDocHash} <- cacheRequest getProposalCache (unHexText govActionTxHash, govActionIndex) (Proposal.getProposal (unHexText govActionTxHash) govActionIndex)
- let proposalResponse = proposalToResponse proposal
+
+ timeZone <- liftIO getCurrentTimeZone
+
+ let proposalResponse = proposalToResponse timeZone proposal
voteResponse <- case mDrepId of
Nothing -> return Nothing
Just drepId -> do
diff --git a/govtool/backend/src/VVA/API/Types.hs b/govtool/backend/src/VVA/API/Types.hs
index a2c410d6..308c1766 100644
--- a/govtool/backend/src/VVA/API/Types.hs
+++ b/govtool/backend/src/VVA/API/Types.hs
@@ -111,103 +111,6 @@ instance ToSchema AnyValue where
& example
?~ toJSON exampleAnyValue
-data MetadataValidationStatus = IncorrectFormat | IncorrectJSONLD | IncorrectHash | UrlNotFound deriving
- ( Eq
- , Show
- )
-
-instance ToJSON MetadataValidationStatus where
- toJSON IncorrectFormat = "INCORRECT_FORMTAT"
- toJSON IncorrectJSONLD = "INVALID_JSONLD"
- toJSON IncorrectHash = "INVALID_HASH"
- toJSON UrlNotFound = "URL_NOT_FOUND"
-
-instance FromJSON MetadataValidationStatus where
- parseJSON (String s) = case s of
- "INCORRECT_FORMTAT" -> pure IncorrectFormat
- "INVALID_JSONLD" -> pure IncorrectJSONLD
- "INVALID_HASH" -> pure IncorrectHash
- "URL_NOT_FOUND" -> pure UrlNotFound
- _ -> fail "Invalid MetadataValidationStatus"
- parseJSON _ = fail "Invalid MetadataValidationStatus"
-
-instance ToSchema MetadataValidationStatus where
- declareNamedSchema _ = pure $ NamedSchema (Just "MetadataValidationStatus") $ mempty
- & type_ ?~ OpenApiString
- & description ?~ "Metadata Validation Status"
- & enum_ ?~ map toJSON [IncorrectFormat, IncorrectJSONLD, IncorrectHash, UrlNotFound]
-
-
-
-data InternalMetadataValidationResponse
- = InternalMetadataValidationResponse
- { internalMetadataValidationResponseStatus :: Maybe MetadataValidationStatus
- , internalMmetadataValidationResponseValid :: Bool
- }
- deriving (Generic, Show)
-
-deriveJSON (jsonOptions "internalMetadataValidationResponse") ''InternalMetadataValidationResponse
-
-instance ToSchema InternalMetadataValidationResponse where
- declareNamedSchema _ = do
- NamedSchema name_ schema_ <-
- genericDeclareNamedSchema
- ( fromAesonOptions $ jsonOptions "internalMetadataValidationResponse" )
- (Proxy :: Proxy InternalMetadataValidationResponse)
- return $
- NamedSchema name_ $
- schema_
- & description ?~ "Metadata Validation Response"
- & example
- ?~ toJSON ("{\"status\": \"INCORRECT_FORMTAT\", \"valid\":false, \"raw\":{\"some\":\"key\"}}" :: Text)
-
-
-data MetadataValidationResponse
- = MetadataValidationResponse
- { metadataValidationResponseStatus :: Maybe Text
- , metadataValidationResponseValid :: Bool
- }
- deriving (Generic, Show)
-
-deriveJSON (jsonOptions "metadataValidationResponse") ''MetadataValidationResponse
-
-instance ToSchema MetadataValidationResponse where
- declareNamedSchema _ = do
- NamedSchema name_ schema_ <-
- genericDeclareNamedSchema
- ( fromAesonOptions $ jsonOptions "metadataValidationResponse" )
- (Proxy :: Proxy MetadataValidationResponse)
- return $
- NamedSchema name_ $
- schema_
- & description ?~ "Metadata Validation Response"
- & example
- ?~ toJSON ("{\"status\": \"INCORRECT_FORMTAT\", \"valid\":false}" :: Text)
-
-data MetadataValidationParams
- = MetadataValidationParams
- { metadataValidationParamsUrl :: Text
- , metadataValidationParamsHash :: HexText
- }
- deriving (Generic, Show)
-
-deriveJSON (jsonOptions "metadataValidationParams") ''MetadataValidationParams
-
-instance ToSchema MetadataValidationParams where
- declareNamedSchema proxy = do
- NamedSchema name_ schema_ <-
- genericDeclareNamedSchema
- ( fromAesonOptions $ jsonOptions "metadataValidationParams" )
- proxy
- return $
- NamedSchema name_ $
- schema_
- & description ?~ "Metadata Validation Params"
- & example
- ?~ toJSON ("{\"url\": \"https://metadata.xyz\", \"hash\": \"9af10e89979e51b8cdc827c963124a1ef4920d1253eef34a1d5cfe76438e3f11\"}" :: Text)
-
-
-
data GovActionId
= GovActionId
{ govActionIdTxHash :: HexText
@@ -414,6 +317,45 @@ instance ToSchema GovernanceActionMetadata where
?~ toJSON
("{\"some_key\": \"some value\", \"some_key2\": [1,2,3]}" :: Text)
+newtype GetCurrentEpochParamsResponse
+ = GetCurrentEpochParamsResponse { getCurrentEpochParamsResponse :: Maybe Value }
+ deriving newtype (Show)
+
+instance FromJSON GetCurrentEpochParamsResponse where
+ parseJSON = pure . GetCurrentEpochParamsResponse . Just
+
+instance ToJSON GetCurrentEpochParamsResponse where
+ toJSON (GetCurrentEpochParamsResponse Nothing) = Null
+ toJSON (GetCurrentEpochParamsResponse (Just params)) = toJSON params
+
+exampleGetCurrentEpochParamsResponse :: Text
+exampleGetCurrentEpochParamsResponse =
+ "{ \"id\":90,\"epoch_no\":90,\"min_fee_a\":44,\"min_fee_b\":155381,\"max_block_size\":90112,\"max_tx_size\":16384,\"max_bh_size\":1100,\"key_deposit\":2000000,\"pool_deposit\":500000000,\"max_epoch\":18,\"optimal_pool_count\":5\r\n00,\"influence\":0.3,\"monetary_expand_rate\":0.003,\"treasury_growth_rate\":0.2,\"decentralisation\":0,\"protocol_major\":8,\"protocol_minor\":0,\"min_utxo_value\":0,\"min_pool_cost\":340000000,\"nonce\":\"\\\\x664c2d0eedc1c\r\n9ee7fc8b4f242c8d13ba17fd31454c84357fa8f1ac62f682cf9\",\"cost_model_id\":2,\"price_mem\":0.0577,\"price_step\":7.21e-05,\"max_tx_ex_mem\":14000000,\"max_tx_ex_steps\":10000000000,\"max_block_ex_mem\":62000000,\"max_bloc\r\nk_ex_steps\":20000000000,\"max_val_size\":5000,\"collateral_percent\":150,\"max_collateral_inputs\":3,\"block_id\":387943,\"extra_entropy\":null,\"coins_per_utxo_size\":4310}"
+
+instance ToSchema GetCurrentEpochParamsResponse where
+ declareNamedSchema _ = pure $ NamedSchema (Just "GetCurrentEpochParamsResponse") $ mempty
+ & type_ ?~ OpenApiObject
+ & description ?~ "Protocol parameters encoded as JSON"
+ & example
+ ?~ toJSON exampleGetCurrentEpochParamsResponse
+
+
+newtype ProtocolParams
+ = ProtocolParams { getProtocolParams :: Value }
+ deriving newtype (Show)
+
+instance FromJSON ProtocolParams where
+ parseJSON = pure . ProtocolParams
+
+instance ToJSON ProtocolParams where
+ toJSON (ProtocolParams params) = toJSON params
+
+instance ToSchema ProtocolParams where
+ declareNamedSchema _ = pure $ NamedSchema (Just "ProtocolParams") $ mempty
+ & type_ ?~ OpenApiObject
+ & description ?~ "Protocol parameters encoded as JSON"
+ & example
+ ?~ toJSON exampleGetCurrentEpochParamsResponse
newtype GovernanceActionReferences
@@ -435,28 +377,35 @@ instance ToSchema GovernanceActionReferences where
?~ toJSON
("[{\"uri\": \"google.com\", \"@type\": \"Other\", \"label\": \"example label\"}]" :: Text)
-
-
data ProposalResponse
= ProposalResponse
- { proposalResponseId :: Text
- , proposalResponseTxHash :: HexText
- , proposalResponseIndex :: Integer
- , proposalResponseType :: GovernanceActionType
- , proposalResponseDetails :: Maybe GovernanceActionDetails
- , proposalResponseExpiryDate :: Maybe UTCTime
- , proposalResponseExpiryEpochNo :: Maybe Integer
- , proposalResponseCreatedDate :: UTCTime
- , proposalResponseCreatedEpochNo :: Integer
- , proposalResponseUrl :: Text
- , proposalResponseMetadataHash :: HexText
- , proposalResponseTitle :: Maybe Text
- , proposalResponseAbstract :: Maybe Text
- , proposalResponseMotivation :: Maybe Text
- , proposalResponseRationale :: Maybe Text
- , proposalResponseYesVotes :: Integer
- , proposalResponseNoVotes :: Integer
- , proposalResponseAbstainVotes :: Integer
+ { proposalResponseId :: Text
+ , proposalResponseTxHash :: HexText
+ , proposalResponseIndex :: Integer
+ , proposalResponseType :: GovernanceActionType
+ , proposalResponseDetails :: Maybe GovernanceActionDetails
+ , proposalResponseExpiryDate :: Maybe UTCTime
+ , proposalResponseExpiryEpochNo :: Maybe Integer
+ , proposalResponseCreatedDate :: UTCTime
+ , proposalResponseCreatedEpochNo :: Integer
+ , proposalResponseUrl :: Text
+ , proposalResponseMetadataHash :: HexText
+ , proposalResponseProtocolParams :: Maybe ProtocolParams
+ , proposalResponseTitle :: Maybe Text
+ , proposalResponseAbstract :: Maybe Text
+ , proposalResponseMotivation :: Maybe Text
+ , proposalResponseRationale :: Maybe Text
+ , proposalResponseDRepYesVotes :: Integer
+ , proposalResponseDRepNoVotes :: Integer
+ , proposalResponseDRepAbstainVotes :: Integer
+ , proposalResponsePoolYesVotes :: Integer
+ , proposalResponsePoolNoVotes :: Integer
+ , proposalResponsePoolAbstainVotes :: Integer
+ , proposalResponseCcYesVotes :: Integer
+ , proposalResponseCcNoVotes :: Integer
+ , proposalResponseCcAbstainVotes :: Integer
+ , proposalResponsePrevGovActionIndex :: Maybe Integer
+ , proposalResponsePrevGovActionTxHash :: Maybe HexText
}
deriving (Generic, Show)
@@ -474,13 +423,22 @@ exampleProposalResponse = "{ \"id\": \"proposalId123\","
<> "\"createdEpochNo\": 0,"
<> "\"url\": \"https://proposal.metadata.xyz\","
<> "\"metadataHash\": \"9af10e89979e51b8cdc827c963124a1ef4920d1253eef34a1d5cfe76438e3f11\","
+ <> "\"protocolParams\": " <> exampleGetCurrentEpochParamsResponse <> ","
<> "\"title\": \"Proposal Title\","
<> "\"abstract\": \"Proposal About\","
<> "\"motivation\": \"Proposal Motivation\","
<> "\"rationale\": \"Proposal Rationale\","
- <> "\"yesVotes\": 0,"
- <> "\"noVotes\": 0,"
- <> "\"abstainVotes\": 0}"
+ <> "\"dRepYesVotes\": 0,"
+ <> "\"dRepNoVotes\": 0,"
+ <> "\"dRepAbstainVotes\": 0,"
+ <> "\"poolYesVotes\": 0,"
+ <> "\"poolNoVotes\": 0,"
+ <> "\"poolAbstainVotes\": 0,"
+ <> "\"cCYesVotes\": 0,"
+ <> "\"cCNoVotes\": 0,"
+ <> "\"cCAbstainVotes\": 0,"
+ <> "\"prevGovActionIndex\": 0,"
+ <> "\"prevGovActionTxHash\": \"47c14a128cd024f1b990c839d67720825921ad87ed875def42641ddd2169b39c\"}"
instance ToSchema ProposalResponse where
declareNamedSchema proxy = do
@@ -615,6 +573,13 @@ data DRepInfoResponse
, dRepInfoResponseDRepRetireTxHash :: Maybe HexText
, dRepInfoResponseSoleVoterRegisterTxHash :: Maybe HexText
, dRepInfoResponseSoleVoterRetireTxHash :: Maybe HexText
+ , dRepInfoResponsePaymentAddress :: Maybe Text
+ , dRepInfoResponseGivenName :: Maybe Text
+ , dRepInfoResponseObjectives :: Maybe Text
+ , dRepInfoResponseMotivations :: Maybe Text
+ , dRepInfoResponseQualifications :: Maybe Text
+ , dRepInfoResponseImageUrl :: Maybe Text
+ , dRepInfoResponseImageHash :: Maybe HexText
}
deriving (Generic, Show)
@@ -633,7 +598,14 @@ exampleDRepInfoResponse =
<> "\"dRepRegisterTxHash\": \"47c14a128cd024f1b990c839d67720825921ad87ed875def42641ddd2169b39c\","
<> "\"dRepRetireTxHash\": \"47c14a128cd024f1b990c839d67720825921ad87ed875def42641ddd2169b39c\","
<> "\"soleVoterRegisterTxHash\": \"47c14a128cd024f1b990c839d67720825921ad87ed875def42641ddd2169b39c\","
- <> "\"soleVoterRetireTxHash\": \"47c14a128cd024f1b990c839d67720825921ad87ed875def42641ddd2169b39c\"}"
+ <> "\"soleVoterRetireTxHash\": \"47c14a128cd024f1b990c839d67720825921ad87ed875def42641ddd2169b39c\","
+ <> "\"paymentAddress\": \"addr1qy49kr45ue0wq78d34dpg79syx3yekxryjadv9ykzczhjwm09pmyt6f6xvq5x9yah2vrxyg0np44ynm6n7hzafl2rqxs4v6nn3\","
+ <> "\"givenName\": \"John Doe\","
+ <> "\"objectives\": \"Objectives of the DRep\","
+ <> "\"motivations\": \"Motivations of the DRep\","
+ <> "\"qualifications\": \"Qualifications of the DRep\","
+ <> "\"imageUrl\": \"https://drep.image.xyz\","
+ <> "\"imageHash\": \"9af10e89979e51b8cdc827c963124a1ef4920d1253eef34a1d5cfe76438e3f11\"}"
instance ToSchema DRepInfoResponse where
declareNamedSchema proxy = do
@@ -648,7 +620,6 @@ instance ToSchema DRepInfoResponse where
& example
?~ toJSON exampleDRepInfoResponse
-
data GetProposalResponse
= GetProposalResponse
{ getProposalResponseVote :: Maybe VoteParams
@@ -661,7 +632,6 @@ exampleGetProposalResponse =
"{\"vote\": " <> exampleVoteParams <> ","
<> "\"proposal\": " <> exampleProposalResponse <> "}"
-
deriveJSON (jsonOptions "getProposalResponse") ''GetProposalResponse
instance ToSchema GetProposalResponse where
@@ -679,29 +649,6 @@ instance ToSchema GetProposalResponse where
& example
?~ toJSON exampleGetProposalResponse
-
-newtype GetCurrentEpochParamsResponse
- = GetCurrentEpochParamsResponse { getCurrentEpochParamsResponse :: Maybe Value }
- deriving newtype (Show)
-
-instance FromJSON GetCurrentEpochParamsResponse where
- parseJSON = pure . GetCurrentEpochParamsResponse . Just
-
-instance ToJSON GetCurrentEpochParamsResponse where
- toJSON (GetCurrentEpochParamsResponse Nothing) = Null
- toJSON (GetCurrentEpochParamsResponse (Just params)) = toJSON params
-
-exampleGetCurrentEpochParamsResponse :: Text
-exampleGetCurrentEpochParamsResponse =
- "{ \"id\":90,\"epoch_no\":90,\"min_fee_a\":44,\"min_fee_b\":155381,\"max_block_size\":90112,\"max_tx_size\":16384,\"max_bh_size\":1100,\"key_deposit\":2000000,\"pool_deposit\":500000000,\"max_epoch\":18,\"optimal_pool_count\":5\r\n00,\"influence\":0.3,\"monetary_expand_rate\":0.003,\"treasury_growth_rate\":0.2,\"decentralisation\":0,\"protocol_major\":8,\"protocol_minor\":0,\"min_utxo_value\":0,\"min_pool_cost\":340000000,\"nonce\":\"\\\\x664c2d0eedc1c\r\n9ee7fc8b4f242c8d13ba17fd31454c84357fa8f1ac62f682cf9\",\"cost_model_id\":2,\"price_mem\":0.0577,\"price_step\":7.21e-05,\"max_tx_ex_mem\":14000000,\"max_tx_ex_steps\":10000000000,\"max_block_ex_mem\":62000000,\"max_bloc\r\nk_ex_steps\":20000000000,\"max_val_size\":5000,\"collateral_percent\":150,\"max_collateral_inputs\":3,\"block_id\":387943,\"extra_entropy\":null,\"coins_per_utxo_size\":4310}"
-
-instance ToSchema GetCurrentEpochParamsResponse where
- declareNamedSchema _ = pure $ NamedSchema (Just "GetCurrentEpochParamsResponse") $ mempty
- & type_ ?~ OpenApiObject
- & description ?~ "Protocol parameters encoded as JSON"
- & example
- ?~ toJSON exampleGetCurrentEpochParamsResponse
-
newtype GetTransactionStatusResponse
= GetTransactionStatusResponse { getTransactionstatusResponseTransactionConfirmed :: Bool }
deriving (Generic, Show)
@@ -784,8 +731,6 @@ instance ToParamSchema DRepStatus where
& type_ ?~ OpenApiString
& enum_ ?~ map toJSON (enumFromTo minBound maxBound :: [DRepStatus])
-
-
data DRepType = NormalDRep | SoleVoter
instance Show DRepType where
@@ -823,6 +768,13 @@ data DRep
, dRepType :: DRepType
, dRepLatestTxHash :: Maybe HexText
, dRepLatestRegistrationDate :: UTCTime
+ , dRepPaymentAddress :: Maybe Text
+ , dRepGivenName :: Maybe Text
+ , dRepObjectives :: Maybe Text
+ , dRepMotivations :: Maybe Text
+ , dRepQualifications :: Maybe Text
+ , dRepImageUrl :: Maybe Text
+ , dRepImageHash :: Maybe HexText
}
deriving (Generic, Show)
@@ -840,7 +792,15 @@ exampleDrep =
<> "\"status\": \"Active\","
<> "\"type\": \"DRep\","
<> "\"latestTxHash\": \"47c14a128cd024f1b990c839d67720825921ad87ed875def42641ddd2169b39c\","
- <> "\"latestRegistrationDate\": \"1970-01-01T00:00:00Z\"}"
+ <> "\"latestRegistrationDate\": \"1970-01-01T00:00:00Z\","
+ <> "\"paymentAddress\": \"addr1qy49kr45ue0wq78d34dpg79syx3yekxryjadv9ykzczhjwm09pmyt6f6xvq5x9yah2vrxyg0np44ynm6n7hzafl2rqxs4v6nn3\","
+ <> "\"givenName\": \"John Doe\","
+ <> "\"objectives\": \"Some Objectives\","
+ <> "\"motivations\": \"Some Motivations\","
+ <> "\"qualifications\": \"Some Qualifications\","
+ <> "\"qualifications\": \"Some Qualifications\","
+ <> "\"imageUrl\": \"https://image.url\","
+ <> "\"imageHash\": \"9198b1b204273ba5c67a13310b5a806034160f6a063768297e161d9b759cad61\"}"
-- ToSchema instance for DRep
instance ToSchema DRep where
diff --git a/govtool/backend/src/VVA/DRep.hs b/govtool/backend/src/VVA/DRep.hs
index 07b20408..fd262bc9 100644
--- a/govtool/backend/src/VVA/DRep.hs
+++ b/govtool/backend/src/VVA/DRep.hs
@@ -61,8 +61,26 @@ listDReps = withPool $ \conn -> do
results <- liftIO $ SQL.query_ conn listDRepsSql
timeZone <- liftIO getCurrentTimeZone
return
- [ DRepRegistration drepHash drepView url dataHash (floor @Scientific deposit) votingPower status drepType txHash (localTimeToUTC timeZone date)
- | (drepHash, drepView, url, dataHash, deposit, votingPower, isActive, txHash, date, latestDeposit, latestNonDeregisterVotingAnchorWasNotNull) <- results
+ [ DRepRegistration drepHash drepView url dataHash (floor @Scientific deposit) votingPower status drepType txHash (localTimeToUTC timeZone date) paymentAddress givenName objectives motivations qualifications imageUrl imageHash
+ | ( drepHash
+ , drepView
+ , url
+ , dataHash
+ , deposit
+ , votingPower
+ , isActive
+ , txHash
+ , date
+ , latestDeposit
+ , latestNonDeregisterVotingAnchorWasNotNull
+ , paymentAddress
+ , givenName
+ , objectives
+ , motivations
+ , qualifications
+ , imageUrl
+ , imageHash
+ ) <- results
, let status = case (isActive, deposit) of
(_, d) | d < 0 -> Retired
(isActive, d) | d >= 0 && isActive -> Active
@@ -125,6 +143,13 @@ getDRepInfo drepId = withPool $ \conn -> do
, drepRetireTx
, soleVoterRegisterTx
, soleVoterRetireTx
+ , paymentAddress
+ , givenName
+ , objectives
+ , motivations
+ , qualifications
+ , imageUrl
+ , imageHash
)] ->
return $ DRepInfo
{ dRepInfoIsRegisteredAsDRep = fromMaybe False isRegisteredAsDRep
@@ -139,5 +164,12 @@ getDRepInfo drepId = withPool $ \conn -> do
, dRepInfoDRepRetireTx = drepRetireTx
, dRepInfoSoleVoterRegisterTx = soleVoterRegisterTx
, dRepInfoSoleVoterRetireTx = soleVoterRetireTx
+ , dRepInfoPaymentAddress = paymentAddress
+ , dRepInfoGivenName = givenName
+ , dRepInfoObjectives = objectives
+ , dRepInfoMotivations = motivations
+ , dRepInfoQualifications = qualifications
+ , dRepInfoImageUrl = imageUrl
+ , dRepInfoImageHash = imageHash
}
- [] -> return $ DRepInfo False False False False Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
+ [] -> return $ DRepInfo False False False False Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
diff --git a/govtool/backend/src/VVA/Proposal.hs b/govtool/backend/src/VVA/Proposal.hs
index b68074e0..bc9fb6a2 100644
--- a/govtool/backend/src/VVA/Proposal.hs
+++ b/govtool/backend/src/VVA/Proposal.hs
@@ -64,53 +64,7 @@ getProposals ::
(Has ConnectionPool r, Has VVAConfig r, MonadReader r m, MonadIO m, MonadFail m, MonadError AppError m) =>
Maybe [Text] ->
m [Proposal]
-getProposals mProposalIds = withPool $ \conn -> do
- proposalResults <- liftIO $ case mProposalIds of
+getProposals mProposalIds = withPool $ \conn ->
+ liftIO $ case mProposalIds of
Nothing -> SQL.query @(Bool, SQL.In [Text]) conn listProposalsSql (False, SQL.In [])
Just proposalIds -> SQL.query conn listProposalsSql (True, SQL.In proposalIds)
-
- timeZone <- liftIO getCurrentTimeZone
- return $ map
- ( \( id'
- , txHash'
- , index'
- , type'
- , details'
- , expiryDate'
- , expiryEpochNo'
- , createdDate'
- , createdEpochNo'
- , url'
- , docHash'
- , title'
- , about'
- , motivation'
- , rationale'
- , yesVotes'
- , noVotes'
- , abstainVotes'
- ) ->
- let eDate = localTimeToUTC timeZone <$> expiryDate'
- cDate = localTimeToUTC timeZone createdDate'
- in
- Proposal
- id'
- txHash'
- (floor @Scientific index')
- type'
- details'
- eDate
- expiryEpochNo'
- cDate
- createdEpochNo'
- url'
- docHash'
- title'
- about'
- motivation'
- rationale'
- (floor @Scientific yesVotes')
- (floor @Scientific noVotes')
- (floor @Scientific abstainVotes')
- )
- proposalResults
diff --git a/govtool/backend/src/VVA/Types.hs b/govtool/backend/src/VVA/Types.hs
index c23eae9f..d3965ff3 100644
--- a/govtool/backend/src/VVA/Types.hs
+++ b/govtool/backend/src/VVA/Types.hs
@@ -3,6 +3,7 @@
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE TypeApplications #-}
module VVA.Types where
@@ -18,9 +19,11 @@ import qualified Data.Cache as Cache
import Data.Has
import Data.Pool (Pool)
import Data.Text (Text)
-import Data.Time (UTCTime)
+import Data.Time (UTCTime, LocalTime)
+import Data.Scientific
import Database.PostgreSQL.Simple (Connection)
+import Database.PostgreSQL.Simple.FromRow
import VVA.Cache
import VVA.Config
@@ -81,6 +84,13 @@ data DRepInfo
, dRepInfoDRepRetireTx :: Maybe Text
, dRepInfoSoleVoterRegisterTx :: Maybe Text
, dRepInfoSoleVoterRetireTx :: Maybe Text
+ , dRepInfoPaymentAddress :: Maybe Text
+ , dRepInfoGivenName :: Maybe Text
+ , dRepInfoObjectives :: Maybe Text
+ , dRepInfoMotivations :: Maybe Text
+ , dRepInfoQualifications :: Maybe Text
+ , dRepInfoImageUrl :: Maybe Text
+ , dRepInfoImageHash :: Maybe Text
}
data DRepStatus = Active | Inactive | Retired deriving (Eq, Ord)
@@ -99,31 +109,78 @@ data DRepRegistration
, dRepRegistrationType :: DRepType
, dRepRegistrationLatestTxHash :: Maybe Text
, dRepRegistrationLatestRegistrationDate :: UTCTime
+ , dRepRegistrationPaymentAddress :: Maybe Text
+ , dRepRegistrationGivenName :: Maybe Text
+ , dRepRegistrationObjectives :: Maybe Text
+ , dRepRegistrationMotivations :: Maybe Text
+ , dRepRegistrationQualifications :: Maybe Text
+ , dRepRegistrationImageUrl :: Maybe Text
+ , dRepRegistrationImageHash :: Maybe Text
}
data Proposal
= Proposal
- { proposalId :: Integer
- , proposalTxHash :: Text
- , proposalIndex :: Integer
- , proposalType :: Text
- , proposalDetails :: Maybe Value
- , proposalExpiryDate :: Maybe UTCTime
- , proposalExpiryEpochNo :: Maybe Integer
- , proposalCreatedDate :: UTCTime
- , proposalCreatedEpochNo :: Integer
- , proposalUrl :: Text
- , proposalDocHash :: Text
- , proposalTitle :: Maybe Text
- , proposalAbstract :: Maybe Text
- , proposalMotivation :: Maybe Text
- , proposalRationale :: Maybe Text
- , proposalYesVotes :: Integer
- , proposalNoVotes :: Integer
- , proposalAbstainVotes :: Integer
+ { proposalId :: Integer
+ , proposalTxHash :: Text
+ , proposalIndex :: Integer
+ , proposalType :: Text
+ , proposalDetails :: Maybe Value
+ , proposalExpiryDate :: Maybe LocalTime
+ , proposalExpiryEpochNo :: Maybe Integer
+ , proposalCreatedDate :: LocalTime
+ , proposalCreatedEpochNo :: Integer
+ , proposalUrl :: Text
+ , proposalDocHash :: Text
+ , proposalProtocolParams :: Maybe Value
+ , proposalTitle :: Maybe Text
+ , proposalAbstract :: Maybe Text
+ , proposalMotivation :: Maybe Text
+ , proposalRationale :: Maybe Text
+ , proposalDRepYesVotes :: Integer
+ , proposalDRepNoVotes :: Integer
+ , proposalDRepAbstainVotes :: Integer
+ , proposalPoolYesVotes :: Integer
+ , proposalPoolNoVotes :: Integer
+ , proposalPoolAbstainVotes :: Integer
+ , proposalCcYesVotes :: Integer
+ , proposalCcNoVotes :: Integer
+ , proposalCcAbstainVotes :: Integer
+ , proposalPrevGovActionIndex :: Maybe Integer
+ , proposalPrevGovActionTxHash :: Maybe Text
}
deriving (Show)
+instance FromRow Proposal where
+ fromRow =
+ Proposal
+ <$> field
+ <*> field
+ <*> (floor @Scientific <$> field)
+ <*> field
+ <*> field
+ <*> field
+ <*> field
+ <*> field
+ <*> field
+ <*> field
+ <*> field
+ <*> field
+ <*> field
+ <*> field
+ <*> field
+ <*> field
+ <*> (floor @Scientific <$> field)
+ <*> (floor @Scientific <$> field)
+ <*> (floor @Scientific <$> field)
+ <*> (floor @Scientific <$> field)
+ <*> (floor @Scientific <$> field)
+ <*> (floor @Scientific <$> field)
+ <*> (floor @Scientific <$> field)
+ <*> (floor @Scientific <$> field)
+ <*> (floor @Scientific <$> field)
+ <*> field
+ <*> field
+
data TransactionStatus = TransactionConfirmed | TransactionUnconfirmed
data CacheEnv
diff --git a/govtool/backend/vva-be.cabal b/govtool/backend/vva-be.cabal
index 022b13ac..97e5c569 100644
--- a/govtool/backend/vva-be.cabal
+++ b/govtool/backend/vva-be.cabal
@@ -1,6 +1,6 @@
cabal-version: 3.6
name: vva-be
-version: 1.0.13
+version: 1.0.17
-- A short (one-line) description of the package.
-- synopsis:
diff --git a/govtool/frontend/index.html b/govtool/frontend/index.html
index e3ff6728..8032b4a3 100644
--- a/govtool/frontend/index.html
+++ b/govtool/frontend/index.html
@@ -10,7 +10,7 @@
rel="stylesheet"
/>
- Voltaire Govtool
+ Cardano Govtool