Commit 32bf67f0 authored by Sharafitdinova's avatar Sharafitdinova Committed by GitHub

Update routing (#265)

* update routing

* debug routing

* debug profile page

* add app protocol

* prefix nextjs api path

* remove debug

* debug routing

* debug deploy

* debug routing

* fix after merge

* delete port and protocol

* hard reload page for nav links

* fix logo

* add marketplace to sokol

* debug values for review

* add login link

* seamless page transition inside new ui app

* logout link

* debug values for review

* add redirect from profile to auth

* static assets

* debug review workflow

* update values for all envs
Co-authored-by: default avatarYuliya Sharafitdinova <juleek777@gmail.com>
Co-authored-by: default avatartom <tom@ohhhh.me>
parent a416e78a
......@@ -29,6 +29,8 @@ NEXT_PUBLIC_FEATURED_NETWORKS=__PLACEHOLDER_FOR_NEXT_PUBLIC_FEATURED_NETWORKS__
NEXT_PUBLIC_NETWORK_EXPLORERS=__PLACEHOLDER_FOR_NEXT_PUBLIC_NETWORK_EXPLORERS__
NEXT_PUBLIC_MARKETPLACE_APP_LIST=__PLACEHOLDER_FOR_NEXT_PUBLIC_MARKETPLACE_APP_LIST__
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=__PLACEHOLDER_FOR_NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM__
NEXT_PUBLIC_LOGOUT_URL=__PLACEHOLDER_FOR_NEXT_PUBLIC_LOGOUT_URL__
NEXT_PUBLIC_LOGOUT_RETURN_URL=__PLACEHOLDER_FOR_NEXT_PUBLIC_LOGOUT_RETURN_URL__
# api config
NEXT_PUBLIC_API_ENDPOINT=__PLACEHOLDER_FOR_NEXT_PUBLIC_API_ENDPOINT__
......@@ -36,3 +38,4 @@ NEXT_PUBLIC_API_BASE_PATH=__PLACEHOLDER_FOR_NEXT_PUBLIC_API_BASE_PATH__
# external services config
NEXT_PUBLIC_SENTRY_DSN=__PLACEHOLDER_FOR_NEXT_PUBLIC_SENTRY_DSN__
NEXT_PUBLIC_AUTH0_CLIENT_ID=__PLACEHOLDER_FOR_NEXT_PUBLIC_AUTH0_CLIENT_ID__
......@@ -11,5 +11,5 @@ jobs:
cleanup:
uses: blockscout/blockscout-ci-cd/.github/workflows/cleanup.yaml@master
with:
appNamespace: review-front-$GITHUB_HEAD_REF_SLUG
appNamespace: review-front-$GITHUB_REF_SLUG
secrets: inherit
name: Deploy review environment
on:
# push:
pull_request:
# push:
# branches-ignore:
# - 'main'
workflow_dispatch:
env:
......@@ -67,9 +69,9 @@ jobs:
uses: blockscout/blockscout-ci-cd/.github/workflows/deploy.yaml@master
with:
env_vars: VALUES_DIR=deploy/values/review,APP_NAME=bs-stack
appNamespace: review-front-$GITHUB_HEAD_REF_SLUG
appNamespace: review-front-$GITHUB_REF_SLUG
blockscoutIngressHost: blockscout
frontendIngressHost: frontend
frontendIngressHost: blockscout
frontendImage: ghcr.io/blockscout/frontend:prerelease-${{ needs.push_to_registry.outputs.shortSha }}
gethIngressHost: geth
scVerifierIngressHost: sc-verifier
......
......@@ -71,6 +71,8 @@ The app instance could be customized by passing following variables to NodeJS en
| NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM | `string` | Link to form where authors can submit their dapps to the marketplace | `https://airtable.com/shrqUAcjgGJ4jU88C` |
| NEXT_PUBLIC_NETWORK_EXPLORERS | `Array<NetworkExplorer>` where `NetworkExplorer` can have following [properties](#network-explorer-configuration-properties) | Used to build up links to transactions, blocks, addresses in other chain explorers. | `[{'title':'Anyblock','baseUrl':'https://explorer.anyblock.tools','paths':{'tx':'/ethereum/poa/core/tx'}}]` |
| NEXT_PUBLIC_NETWORK_VERIFICATION_TYPE | `validation` or `mining` *(optional)* | Verification type in the network | `mining` |
| NEXT_PUBLIC_LOGOUT_URL | `string` *(optional)* | Account logout url | `https://blockscoutcom.us.auth0.com/v2/logout` |
| NEXT_PUBLIC_LOGOUT_RETURN_URL | `string` *(optional)* | Account logout return url | `https://blockscout.com/poa/core/auth/logout` |
### App configuration
......@@ -115,6 +117,7 @@ The app instance could be customized by passing following variables to NodeJS en
| --- | --- | --- | --- |
| NEXT_PUBLIC_SENTRY_DSN | `string` *(optional)* | Client key for your Sentry.io app | `<secret>` |
| SENTRY_CSP_REPORT_URI | `string` *(optional)* | URL for sending CSP-reports to your Sentry.io app | `<secret>` |
| NEXT_PUBLIC_AUTH0_CLIENT_ID | `string` *(optional)* | Client id for [Auth0](https://auth0.com/) provider | `<secret>` |
### Marketplace app configuration properties
......
......@@ -24,6 +24,24 @@ const baseUrl = [
appPort && ':' + appPort,
].filter(Boolean).join('');
const logoutUrl = (() => {
try {
const envUrl = getEnvValue(process.env.NEXT_PUBLIC_LOGOUT_URL);
const auth0ClientId = getEnvValue(process.env.NEXT_PUBLIC_AUTH0_CLIENT_ID);
const returnUrl = getEnvValue(process.env.NEXT_PUBLIC_LOGOUT_RETURN_URL);
if (!envUrl || !auth0ClientId || !returnUrl) {
throw Error();
}
const url = new URL(envUrl);
url.searchParams.set('client_id', auth0ClientId);
url.searchParams.set('returnTo', returnUrl);
return url.toString();
} catch (error) {
return;
}
})();
const networkType = getEnvValue(process.env.NEXT_PUBLIC_NETWORK_TYPE);
const networkSubType = getEnvValue(process.env.NEXT_PUBLIC_NETWORK_SUBTYPE);
......@@ -65,6 +83,7 @@ const config = Object.freeze({
host: appHost,
port: appPort,
baseUrl,
logoutUrl,
api: {
endpoint: getEnvValue(process.env.NEXT_PUBLIC_API_ENDPOINT) || 'https://blockscout.com',
basePath: getEnvValue(process.env.NEXT_PUBLIC_API_BASE_PATH) || '',
......
......@@ -10,6 +10,7 @@ async function rewrites() {
// it seems like it's solved but it's not actually
return [
{ source: '/node-api/:slug*', destination: '/api/:slug*' },
{ source: '/astar/:slug*', destination: '/astar/mainnet/:slug*' },
{ source: '/shiden/:slug*', destination: '/shiden/mainnet/:slug*' },
];
......
......@@ -15,9 +15,9 @@ blockscout:
ACCOUNT_AUTH0_CLIENT_SECRET:
_default: ENC[AES256_GCM,data:Nmajob/xrOfx3sZgGHWw4/VnSgoyehubNdhJSqasxLFInJeZgxCW/QXpu5KG6j1fDdALLOT89Es+m0IO9VrG8A==,iv:RxYWdOo5G6t0FFwHQfhvUTiCOsxRzJJT0Y1nc0F5sDc=,tag:6v6+yHaHgwnw0cDSD1hXwg==,type:str]
ACCOUNT_AUTH0_CALLBACK_URL:
_default: ENC[AES256_GCM,data:MkvI0EZaWmsd8tDMU+qiLLZ2anCl00PW3u3Og9GXNtnZ+a7CUyY6rdFBOfE3fSOh4haoNuBxMCyxsAhHk/x0MNRNVqKjqT9I3VBAfzUzM+Ft4g==,iv:RuHXRpEAYKlm2UwN3s6AofiGiSmuRkVyO531rnUIklc=,tag:L3NnykZU4WFOOfPGDCdMUg==,type:str]
_default: ENC[AES256_GCM,data:DEyk+7A3zm2R0WXGbqsP5+NXRKQqZ6uaGJvwrniBiB816BCBV27bYWqmXutQPvCga1SLsWzliekc2iUAkTyxopDjODuUxDZlsHmjE5vRaCVTLfGCHf5k6eNN3a0=,iv:RKvqCitIB07FXXKOy8e5HXMkI3wr7HEl695Uylsu3kg=,tag:/3EhIIdlOFMXcbxJZ2N5bg==,type:str]
ACCOUNT_AUTH0_LOGOUT_RETURN_URL:
_default: ENC[AES256_GCM,data:9cWXw4j6LAg9qUzKTGevJE4U1leMV+i9DD26VDyFqlin4M6O1r/xzoWQtHfrHzxP1RRBuGPIjBqV/WCM1u9cVmhgrs2FQvzZkHk=,iv:Qrxdp4CfnSkCXMxhzMZvvpFSkglzdviq4UYGhffLDNk=,tag:RJhq0+B9Sa5D8k8cAhZW5A==,type:str]
_default: ENC[AES256_GCM,data:f5O3nHg9ldCDDOZjUtyKqKNI6D+5eQpWjGxf6fKSh3y2neZ1d81M8Ljt4VF50Dy9QV2Rhu3lyZI47kV8E0BhwEqYNYJ24YBoB+cM2cttuCJxlHvI,iv:l75drqjzuNzNqMYPuLeF41D4bEaVskbHtX60liAuqNM=,tag:uGVjlN8kvR4h6VPwhOnZzA==,type:str]
ACCOUNT_AUTH0_LOGOUT_URL:
_default: ENC[AES256_GCM,data:6vj0qvxktXptFDX4Tq3kGIyhaJN7Adcwfgb3qWEYH78pWtmFprwfKNdPa/4=,iv:Eb3NcZP9oSmh0ZfY8vCWwR5Ciwe7Lr/QJmcNWXiir9E=,tag:uXoFnMfwo/GD9IPuvs/9Wg==,type:str]
ACCOUNT_SENDGRID_API_KEY:
......@@ -70,14 +70,16 @@ frontend:
_default: ENC[AES256_GCM,data:n/H2AH2n9ovn265iFbbrqeOOWS3s7FXgDv5FXJ2Dz133GuhTaqIU5psWjTraZ/Vh+dVM8M9zBLFfUanCWOz7cerq/QUoSVZjKvIvcyp6F072DGU=,iv:Co/pSR+U0vfkmWR+LDpxcQKDJl0WNbaEZihpzrRJcbc=,tag:HUiCX8WGJXWCDB59Y6iIbw==,type:str]
SENTRY_CSP_REPORT_URI:
_default: ENC[AES256_GCM,data:Hf4azYsGh2lysotK7afaHI85IaLBJeQmPlGE/lwokmX2eaQHVZJ/i5RsaoKoOCSiNyfAowr7P+6IBEC16BUTQMpbhYveBd7c/xjIsoomoHbTdoAdZA/QxNVpS4a2qVthruFudyT1BoZUHIGQ,iv:Mid+PfbslOyivrFSXopdeW96YvOcLP+g2RGcw1o7B98=,tag:IuPUsGdbZQodCMyi1DR04Q==,type:str]
NEXT_PUBLIC_AUTH0_CLIENT_ID:
_default: ENC[AES256_GCM,data:1doicz45IfwPza75+bYEe/3Ot1auCP3CtW1V1ilRevo=,iv:BlK5h1YRWAL00DuZnujnHWsKXrsTnP1G+F59+MNnHcU=,tag:gu/0BQ6mQXEmQhpWmBU3NQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2022-10-25T09:55:15Z"
mac: ENC[AES256_GCM,data:ZZqPTIRw4KvC7jNJMs6rtgKG4JuWmDZaW8NgMFTW1E6rgea3E4aFbJCM61wyncltYNcTdndc40YCkCHEXtO0gptBBJviL8fvo2bcc0m0V18X2zzjg8GU816t7PTKFQ79cALgtEPl5xLz75zJO83Gluskka47+AgPk5xBmG+sHAo=,iv:ZchfAH/GoMRQyqJNcGFSHMBreUQrkruQIhk2A/HcLjA=,tag:Id0YtPyVrXCxQit3mL43UQ==,type:str]
lastmodified: "2022-10-27T18:39:52Z"
mac: ENC[AES256_GCM,data:iOh30zo2Mew+RO/LeXNCVrtMR52cb2RhuvCN99AdiQWXMVShE8PdWWPW6V5m+LVtwPuxusZi1/fGzTCwpE4cOX3BF8HNI9B8sC6t9NR0SO9/g427p2+vevN/fPBZXkO196KosMLB0+SSh+znmtt0U5yTT8l8v9y2B6H+P89VhxI=,iv:kqwGAaJQihvD9vkFVJZuQTR5rb706mWP7gmBFC+0Pas=,tag:Kg9JHoy2s5avDmpnZaO9Ng==,type:str]
pgp:
- created_at: "2022-09-14T13:42:28Z"
enc: |
......
......@@ -2,9 +2,11 @@ global:
env: e2e
# enable Blockscout deploy
blockscout:
app: blockscout
enabled: true
image:
_default: blockscout/blockscout:latest
_default: blockscout/blockscout-sokol:latest
#blockscout/blockscout:review-prerelease-9ad99cc8@sha256:608d335025a135f1cde6608b2449b8988b7cb8bfa6ea38e92ce1f184ec577781
replicas:
app: 1
docker:
......@@ -16,12 +18,16 @@ blockscout:
# enable ingress
ingress:
enabled: true
annotations:
- 'nginx.ingress.kubernetes.io/rewrite-target: /$2'
host:
_default: blockscout.test.blockscout.aws-k8s.blockscout.com
# enable https
#
tls:
enabled: true
path:
- "/poa/sokol(/|$)(.*)"
- "/"
# probes
livenessProbe:
......@@ -43,7 +49,7 @@ blockscout:
_default: "2"
# enable service to connect to RDS
rds:
enable: false
enabled: false
endpoint:
_default: <endpoint>.<region>.rds.amazonaws.com
# node label
......@@ -83,15 +89,23 @@ blockscout:
RUST_VERIFICATION_SERVICE_URL:
_default: http://sc-verifier-svc:8043
ACCOUNT_ENABLED:
_default: true
_default: 'true'
DISABLE_REALTIME_INDEXER:
_default: 'false'
SOCKET_ROOT:
_default: "/"
_default: "/poa/sokol"
NETWORK_PATH:
_default: "/"
_default: "/poa/sokol"
API_PATH:
_default: "/poa/sokol"
ETHEREUM_JSONRPC_DISABLE_ARCHIVE_BALANCES:
_default: 'true'
API_BASE_PATH:
_default: "/poa/sokol"
APPS_MENU:
_default: 'true'
EXTERNAL_APPS:
_default: '[{"title": "Marketplace", "url": "/poa/sokol/apps"}]'
postgres:
enabled: true
......@@ -155,7 +169,7 @@ geth:
ingress:
enabled: true
host:
_default: asdfg-node.test.blockscout.aws-k8s.blockscout.com
_default: node.test.blockscout.aws-k8s.blockscout.com
# enable https
tls:
enabled: false
......@@ -182,7 +196,6 @@ scVerifier:
enabled: true
host:
_default: verifier.test.blockscout.aws-k8s.blockscout.com
testnet: asdfg-verifier.test.blockscout.aws-k8s.blockscout.com
# enable https
tls:
enabled: true
......@@ -249,6 +262,7 @@ scVerifier:
SMART_CONTRACT_VERIFIER__JAEGER__ENABLED:
_default: 'false'
frontend:
app: blockscout
enabled: true
image:
_default: ghcr.io/blockscout/frontend:main
......@@ -261,12 +275,14 @@ frontend:
enabled: true
host:
_default: frontend.test.blockscout.aws-k8s.blockscout.com
testnet: asdfg-frontend.test.blockscout.aws-k8s.blockscout.com
# enable https
tls:
enabled: true
path:
- "/"
- "/poa/sokol/(apps|auth/profile|account)"
- "/_next"
- "/node-api"
- "/static"
resources:
limits:
memory:
......@@ -283,22 +299,16 @@ frontend:
enabled: true
app: blockscout
environment:
NEXT_PUBLIC_APP_PROTOCOL:
_default: http
NEXT_PUBLIC_APP_HOST:
_default: localhost
NEXT_PUBLIC_APP_PORT:
_default: 80
NEXT_PUBLIC_BLOCKSCOUT_VERSION:
_default: v4.1.8-beta
NEXT_PUBLIC_FOOTER_GITHUB_LINK:
_default: https://github.com/blockscout/blockscout
NEXT_PUBLIC_FOOTER_TWITTER_LINK:
_default: https://www.twitter.com/blockscoutcom
NEXT_PUBLIC_APP_ENV:
_default: preview
NEXT_PUBLIC_APP_INSTANCE:
_default: unknown
NEXT_PUBLIC_APP_ENV:
_default: e2e
NEXT_PUBLIC_FOOTER_TELEGRAM_LINK:
_default: https://t.me/poa_network
NEXT_PUBLIC_FOOTER_STAKING_LINK:
......@@ -308,7 +318,7 @@ frontend:
NEXT_PUBLIC_NETWORK_SHORT_NAME:
_default: POA
NEXT_PUBLIC_NETWORK_ASSETS_PATHNAME:
_default: poa
_default: sokol
NEXT_PUBLIC_NETWORK_TYPE:
_default: poa
NEXT_PUBLIC_NETWORK_SUBTYPE:
......@@ -330,8 +340,12 @@ frontend:
NEXT_PUBLIC_API_ENDPOINT:
_default: https://blockscout.com
NEXT_PUBLIC_API_BASE_PATH:
_default: /
_default: /poa/sokol
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM:
_default: https://airtable.com/shrqUAcjgGJ4jU88C
NEXT_PUBLIC_MARKETPLACE_APP_LIST:
_default: "[{'author': 'Blockscout', 'id': 'token-approval-tracker', 'title': 'Token Approval Tracker', 'logo': 'https://approval-tracker.vercel.app/icon-192.png', 'categories': ['security', 'tools'], 'shortDescription': 'Token Approval Tracker shows all approvals for any ERC20-compliant tokens and NFTs and lets to revoke them or adjust the approved amount.', 'site': 'https://docs.blockscout.com/for-users/blockscout-apps/token-approval-tracker', 'description': 'Token Approval Tracker shows all approvals for any ERC20-compliant tokens and NFTs and lets to revoke them or adjust the approved amount.', 'url': 'https://approval-tracker.vercel.app/'}]"
NEXT_PUBLIC_LOGOUT_URL:
_default: https://blockscoutcom.us.auth0.com/v2/logout
NEXT_PUBLIC_LOGOUT_RETURN_URL:
_default: https://blockscout.com/poa/sokol/auth/logout
......@@ -15,9 +15,9 @@ blockscout:
ACCOUNT_AUTH0_CLIENT_SECRET:
_default: ENC[AES256_GCM,data:Nmajob/xrOfx3sZgGHWw4/VnSgoyehubNdhJSqasxLFInJeZgxCW/QXpu5KG6j1fDdALLOT89Es+m0IO9VrG8A==,iv:RxYWdOo5G6t0FFwHQfhvUTiCOsxRzJJT0Y1nc0F5sDc=,tag:6v6+yHaHgwnw0cDSD1hXwg==,type:str]
ACCOUNT_AUTH0_CALLBACK_URL:
_default: ENC[AES256_GCM,data:MkvI0EZaWmsd8tDMU+qiLLZ2anCl00PW3u3Og9GXNtnZ+a7CUyY6rdFBOfE3fSOh4haoNuBxMCyxsAhHk/x0MNRNVqKjqT9I3VBAfzUzM+Ft4g==,iv:RuHXRpEAYKlm2UwN3s6AofiGiSmuRkVyO531rnUIklc=,tag:L3NnykZU4WFOOfPGDCdMUg==,type:str]
_default: ENC[AES256_GCM,data:Eopmjs+pJxi0cV9eGzB5cv+uTR+PWd/4WzfEnvQUiwNiswB2G3gP0NoCNBcDR+2+ydeIHYndCcn42RaoM+i96eDbUPy1GWk704IpaYlZoUuhJ8XO9JPPj5ApfH8=,iv:Rc7fgf4rgd+nLh67hOZ9nvSMXZzBBeJ5pkOtybjbz1U=,tag:Xpb1CHELI96KWrpVF7XksQ==,type:str]
ACCOUNT_AUTH0_LOGOUT_RETURN_URL:
_default: ENC[AES256_GCM,data:9cWXw4j6LAg9qUzKTGevJE4U1leMV+i9DD26VDyFqlin4M6O1r/xzoWQtHfrHzxP1RRBuGPIjBqV/WCM1u9cVmhgrs2FQvzZkHk=,iv:Qrxdp4CfnSkCXMxhzMZvvpFSkglzdviq4UYGhffLDNk=,tag:RJhq0+B9Sa5D8k8cAhZW5A==,type:str]
_default: ENC[AES256_GCM,data:13zluPWED9xcoPHZgJmhpKsSNR7JjwAYIoF73Dcs7R9rGGg9h++RWM6a0y3DQMYctKcxAm4u7l6jitmfFmkr6Tp6Urjyw+Fsu8+97CyvlBfWpEjc,iv:AC9+6neb4aHQLl1jDmPNtE/CGxEEv4GFe2k4a2QPh1w=,tag:MgiVG2oBMXG08Q4BtxlKhg==,type:str]
ACCOUNT_AUTH0_LOGOUT_URL:
_default: ENC[AES256_GCM,data:6vj0qvxktXptFDX4Tq3kGIyhaJN7Adcwfgb3qWEYH78pWtmFprwfKNdPa/4=,iv:Eb3NcZP9oSmh0ZfY8vCWwR5Ciwe7Lr/QJmcNWXiir9E=,tag:uXoFnMfwo/GD9IPuvs/9Wg==,type:str]
ACCOUNT_SENDGRID_API_KEY:
......@@ -70,14 +70,16 @@ frontend:
_default: ENC[AES256_GCM,data:n/H2AH2n9ovn265iFbbrqeOOWS3s7FXgDv5FXJ2Dz133GuhTaqIU5psWjTraZ/Vh+dVM8M9zBLFfUanCWOz7cerq/QUoSVZjKvIvcyp6F072DGU=,iv:Co/pSR+U0vfkmWR+LDpxcQKDJl0WNbaEZihpzrRJcbc=,tag:HUiCX8WGJXWCDB59Y6iIbw==,type:str]
SENTRY_CSP_REPORT_URI:
_default: ENC[AES256_GCM,data:Hf4azYsGh2lysotK7afaHI85IaLBJeQmPlGE/lwokmX2eaQHVZJ/i5RsaoKoOCSiNyfAowr7P+6IBEC16BUTQMpbhYveBd7c/xjIsoomoHbTdoAdZA/QxNVpS4a2qVthruFudyT1BoZUHIGQ,iv:Mid+PfbslOyivrFSXopdeW96YvOcLP+g2RGcw1o7B98=,tag:IuPUsGdbZQodCMyi1DR04Q==,type:str]
NEXT_PUBLIC_AUTH0_CLIENT_ID:
_default: ENC[AES256_GCM,data:cRcbMzOW2AFyDz/lqv4T9SpDCabXdBKLFN9dbq/rFg4=,iv:G9afggfvZ+BpuE5u31KDVfIxhlP38IE28Yt9pMQsd6E=,tag:t1kkjXPolc/58fuQVULLfA==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2022-10-25T09:55:50Z"
mac: ENC[AES256_GCM,data:dv6Xyf42vAfgKWe0p9mcxtesrdDMV8wF0E/rH6vUgGp1VXmFZnStjiX2Gu5qhKh6YXvuDfpTNdaj9WlnfyL5uX4hpMK+evkUzJk4cAwNPQ7F48khZQQ8T3CtmYgzBUxeKlVTSWg98w+Y6NydURB1Xp58Hi+72sskeJGNekGijkM=,iv:Fpv59cjv7MvG2cUIrNlCdgLaWuhfUJhALTmD2HGxYpc=,tag:5IILWg9gth2RZdTjk3IxyA==,type:str]
lastmodified: "2022-10-27T18:39:43Z"
mac: ENC[AES256_GCM,data:dQvWp8uP4LJ58Fagb0+e26UiHX5d27z04ei0Hz7EPBmFdEA2/1WTXFHBzJZhkxAU51JdbQxFLBWchO1Pv/26RqDi2zscZ53Ln1Ulc21gCMeY95/q1xENDEuss8srr9LtIDRVfr+KjpPnSer2t8er7B3lAaxPPtc0FMHVa3kf+Jw=,iv:kIL05arLDhqZQhECIeifyN0eH7EZbWt9/ltzsEuUONk=,tag:qkI3Z4vcnCK4tE+PnxPXfA==,type:str]
pgp:
- created_at: "2022-09-14T13:42:28Z"
enc: |
......
global:
env: e2e
env: main
# enable Blockscout deploy
blockscout:
app: blockscout
enabled: true
image:
_default: blockscout/blockscout:review-prerelease-4dad4e9b@sha256:0afd8e344f7856eeb5326dff370f6258e588a77fa1611ecf16f8433944ddbaf9
_default: blockscout/blockscout-sokol:latest
#blockscout/blockscout:review-prerelease-9ad99cc8@sha256:608d335025a135f1cde6608b2449b8988b7cb8bfa6ea38e92ce1f184ec577781
replicas:
app: 1
docker:
......@@ -103,7 +105,7 @@ blockscout:
APPS_MENU:
_default: 'true'
EXTERNAL_APPS:
_default: '[{"title": "Marketplace", "url": "..."}]'
_default: '[{"title": "Marketplace", "url": "/poa/sokol/apps"}]'
postgres:
enabled: true
......@@ -260,6 +262,7 @@ scVerifier:
SMART_CONTRACT_VERIFIER__JAEGER__ENABLED:
_default: 'false'
frontend:
app: blockscout
enabled: true
image:
_default: ghcr.io/blockscout/frontend:main
......@@ -276,7 +279,10 @@ frontend:
tls:
enabled: true
path:
- "/"
- "/poa/sokol/(apps|auth/profile|account)"
- "/_next"
- "/node-api"
- "/static"
resources:
limits:
memory:
......@@ -293,22 +299,16 @@ frontend:
enabled: true
app: blockscout
environment:
NEXT_PUBLIC_APP_PROTOCOL:
_default: http
NEXT_PUBLIC_APP_HOST:
_default: localhost
NEXT_PUBLIC_APP_PORT:
_default: 80
NEXT_PUBLIC_BLOCKSCOUT_VERSION:
_default: v4.1.8-beta
NEXT_PUBLIC_FOOTER_GITHUB_LINK:
_default: https://github.com/blockscout/blockscout
NEXT_PUBLIC_FOOTER_TWITTER_LINK:
_default: https://www.twitter.com/blockscoutcom
NEXT_PUBLIC_APP_ENV:
_default: preview
NEXT_PUBLIC_APP_INSTANCE:
_default: unknown
NEXT_PUBLIC_APP_ENV:
_default: e2e
NEXT_PUBLIC_FOOTER_TELEGRAM_LINK:
_default: https://t.me/poa_network
NEXT_PUBLIC_FOOTER_STAKING_LINK:
......@@ -318,7 +318,7 @@ frontend:
NEXT_PUBLIC_NETWORK_SHORT_NAME:
_default: POA
NEXT_PUBLIC_NETWORK_ASSETS_PATHNAME:
_default: poa
_default: sokol
NEXT_PUBLIC_NETWORK_TYPE:
_default: poa
NEXT_PUBLIC_NETWORK_SUBTYPE:
......@@ -345,3 +345,7 @@ frontend:
_default: https://airtable.com/shrqUAcjgGJ4jU88C
NEXT_PUBLIC_MARKETPLACE_APP_LIST:
_default: "[{'author': 'Blockscout', 'id': 'token-approval-tracker', 'title': 'Token Approval Tracker', 'logo': 'https://approval-tracker.vercel.app/icon-192.png', 'categories': ['security', 'tools'], 'shortDescription': 'Token Approval Tracker shows all approvals for any ERC20-compliant tokens and NFTs and lets to revoke them or adjust the approved amount.', 'site': 'https://docs.blockscout.com/for-users/blockscout-apps/token-approval-tracker', 'description': 'Token Approval Tracker shows all approvals for any ERC20-compliant tokens and NFTs and lets to revoke them or adjust the approved amount.', 'url': 'https://approval-tracker.vercel.app/'}]"
NEXT_PUBLIC_LOGOUT_URL:
_default: https://blockscoutcom.us.auth0.com/v2/logout
NEXT_PUBLIC_LOGOUT_RETURN_URL:
_default: https://blockscout.com/poa/sokol/auth/logout
......@@ -15,9 +15,9 @@ blockscout:
ACCOUNT_AUTH0_CLIENT_SECRET:
_default: ENC[AES256_GCM,data:Nmajob/xrOfx3sZgGHWw4/VnSgoyehubNdhJSqasxLFInJeZgxCW/QXpu5KG6j1fDdALLOT89Es+m0IO9VrG8A==,iv:RxYWdOo5G6t0FFwHQfhvUTiCOsxRzJJT0Y1nc0F5sDc=,tag:6v6+yHaHgwnw0cDSD1hXwg==,type:str]
ACCOUNT_AUTH0_CALLBACK_URL:
_default: ENC[AES256_GCM,data:MkvI0EZaWmsd8tDMU+qiLLZ2anCl00PW3u3Og9GXNtnZ+a7CUyY6rdFBOfE3fSOh4haoNuBxMCyxsAhHk/x0MNRNVqKjqT9I3VBAfzUzM+Ft4g==,iv:RuHXRpEAYKlm2UwN3s6AofiGiSmuRkVyO531rnUIklc=,tag:L3NnykZU4WFOOfPGDCdMUg==,type:str]
_default: ENC[AES256_GCM,data:FgOUi6sp2SAAMQXtsll9HpIIGPcO+7AeOlZgcYHc5uWtDffQmcNtQSHqG72Aw5HeF3PSnwdeg2mLJDUHitE2usrdaE2SSV3ekBebBrobJjw9/4I57z8AJy0exEY=,iv:tqJV1VY4DPVeJBOa/LElmQ2AX5T83qzon4m4w+bGgYg=,tag:Lw0l3tjsZBwnv9Iu9Xxj5w==,type:str]
ACCOUNT_AUTH0_LOGOUT_RETURN_URL:
_default: ENC[AES256_GCM,data:9cWXw4j6LAg9qUzKTGevJE4U1leMV+i9DD26VDyFqlin4M6O1r/xzoWQtHfrHzxP1RRBuGPIjBqV/WCM1u9cVmhgrs2FQvzZkHk=,iv:Qrxdp4CfnSkCXMxhzMZvvpFSkglzdviq4UYGhffLDNk=,tag:RJhq0+B9Sa5D8k8cAhZW5A==,type:str]
_default: ENC[AES256_GCM,data:vCwBiNb5aSfeBTY0ozEkxV8RForss9A/WeZ3jVKTHddBIJ73hEzo/QA0c8nktiwil+H2ZfKeTOFgwvvO7AQqMYrCd5erQmXksF8qGu617csDlYcH,iv:SbFuuJbFWYbz+BkUFT9oNYdYXiDThIBWGA7Owb/F+qk=,tag:v5uY+2Be4Z4AHmjd7Ua7FQ==,type:str]
ACCOUNT_AUTH0_LOGOUT_URL:
_default: ENC[AES256_GCM,data:6vj0qvxktXptFDX4Tq3kGIyhaJN7Adcwfgb3qWEYH78pWtmFprwfKNdPa/4=,iv:Eb3NcZP9oSmh0ZfY8vCWwR5Ciwe7Lr/QJmcNWXiir9E=,tag:uXoFnMfwo/GD9IPuvs/9Wg==,type:str]
ACCOUNT_SENDGRID_API_KEY:
......@@ -70,14 +70,16 @@ frontend:
_default: ENC[AES256_GCM,data:n/H2AH2n9ovn265iFbbrqeOOWS3s7FXgDv5FXJ2Dz133GuhTaqIU5psWjTraZ/Vh+dVM8M9zBLFfUanCWOz7cerq/QUoSVZjKvIvcyp6F072DGU=,iv:Co/pSR+U0vfkmWR+LDpxcQKDJl0WNbaEZihpzrRJcbc=,tag:HUiCX8WGJXWCDB59Y6iIbw==,type:str]
SENTRY_CSP_REPORT_URI:
_default: ENC[AES256_GCM,data:Hf4azYsGh2lysotK7afaHI85IaLBJeQmPlGE/lwokmX2eaQHVZJ/i5RsaoKoOCSiNyfAowr7P+6IBEC16BUTQMpbhYveBd7c/xjIsoomoHbTdoAdZA/QxNVpS4a2qVthruFudyT1BoZUHIGQ,iv:Mid+PfbslOyivrFSXopdeW96YvOcLP+g2RGcw1o7B98=,tag:IuPUsGdbZQodCMyi1DR04Q==,type:str]
NEXT_PUBLIC_AUTH0_CLIENT_ID:
_default: ENC[AES256_GCM,data:4cTeqxQnGcpzPK4bMqxZpLgMeFSSDbajN/fmb1UunH8=,iv:bPTQfahGfWF1OfArvYQeSQItMa0Ymkt6eUfDZFBQSOY=,tag:8xHe5AUkbH/rl6cOfkVAKg==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2022-10-25T09:56:28Z"
mac: ENC[AES256_GCM,data:RE31H3E5ADznpOUQWmXOfK3bEh/0sSsphOLdjP81fWOcYGlbPFfsmssFoN6GCGNNcM2lXCGnc+b9xuqzYH/A9zjALccoNhQTRl3q20YZAsD7zlRRjxDPFIivQaDKYB2lWYwlHeLUOgohHGTwzoFTC0LDxWqgYLxrVZQwtVEXPdE=,iv:xV9ubuTmHUmNetdox5lSV+mv+rXTJjVxNcurZyWueDw=,tag:lqj1wgDjybmKoRk6W8h37g==,type:str]
lastmodified: "2022-10-27T08:40:17Z"
mac: ENC[AES256_GCM,data:t9Ex5kGubl/kxcHhJK6uoh7BkMXSonHbZAQk9yB9Zm6NdYp9gINmfCrsloMW213KqPfsgBlxTsdYi7CeR96Zj1lnwUB/v4L13hUuA/tyb8G28gzHjQjHcBmD9AIh6UbTL77uAW+UqIOYnjdHX4Snwv1qTK+TWg+wLPClVSMsXcw=,iv:f3h9C77B6vEXhJ3OXHGnFUpiQV7igtiH961K757BKgk=,tag:eAQ8YwH55cDf8wh0wVdWJg==,type:str]
pgp:
- created_at: "2022-09-14T13:42:28Z"
enc: |
......
global:
env: e2e
env: review
# enable Blockscout deploy
blockscout:
app: blockscout
enabled: true
image:
_default: blockscout/blockscout:latest
_default: blockscout/blockscout-sokol:latest
#blockscout/blockscout:review-prerelease-9ad99cc8@sha256:608d335025a135f1cde6608b2449b8988b7cb8bfa6ea38e92ce1f184ec577781
replicas:
app: 1
docker:
......@@ -16,12 +18,16 @@ blockscout:
# enable ingress
ingress:
enabled: true
annotations:
- 'nginx.ingress.kubernetes.io/rewrite-target: /$2'
host:
_default: blockscout.test.blockscout.aws-k8s.blockscout.com
# enable https
#
tls:
enabled: true
path:
- "/poa/sokol(/|$)(.*)"
- "/"
# probes
livenessProbe:
......@@ -43,7 +49,7 @@ blockscout:
_default: "2"
# enable service to connect to RDS
rds:
enable: false
enabled: false
endpoint:
_default: <endpoint>.<region>.rds.amazonaws.com
# node label
......@@ -83,15 +89,23 @@ blockscout:
RUST_VERIFICATION_SERVICE_URL:
_default: http://sc-verifier-svc:8043
ACCOUNT_ENABLED:
_default: true
_default: 'true'
DISABLE_REALTIME_INDEXER:
_default: 'false'
SOCKET_ROOT:
_default: "/"
_default: "/poa/sokol"
NETWORK_PATH:
_default: "/"
_default: "/poa/sokol"
API_PATH:
_default: "/poa/sokol"
ETHEREUM_JSONRPC_DISABLE_ARCHIVE_BALANCES:
_default: 'true'
API_BASE_PATH:
_default: "/poa/sokol"
APPS_MENU:
_default: 'true'
EXTERNAL_APPS:
_default: '[{"title": "Marketplace", "url": "/poa/sokol/apps"}]'
postgres:
enabled: true
......@@ -155,7 +169,7 @@ geth:
ingress:
enabled: true
host:
_default: asdfg-node.test.blockscout.aws-k8s.blockscout.com
_default: node.test.blockscout.aws-k8s.blockscout.com
# enable https
tls:
enabled: false
......@@ -182,7 +196,6 @@ scVerifier:
enabled: true
host:
_default: verifier.test.blockscout.aws-k8s.blockscout.com
testnet: asdfg-verifier.test.blockscout.aws-k8s.blockscout.com
# enable https
tls:
enabled: true
......@@ -249,6 +262,7 @@ scVerifier:
SMART_CONTRACT_VERIFIER__JAEGER__ENABLED:
_default: 'false'
frontend:
app: blockscout
enabled: true
image:
_default: ghcr.io/blockscout/frontend:main
......@@ -261,12 +275,14 @@ frontend:
enabled: true
host:
_default: frontend.test.blockscout.aws-k8s.blockscout.com
testnet: asdfg-frontend.test.blockscout.aws-k8s.blockscout.com
# enable https
tls:
enabled: true
path:
- "/"
- "/poa/sokol/(apps|auth/profile|account)"
- "/_next"
- "/node-api"
- "/static"
resources:
limits:
memory:
......@@ -324,8 +340,12 @@ frontend:
NEXT_PUBLIC_API_ENDPOINT:
_default: https://blockscout.com
NEXT_PUBLIC_API_BASE_PATH:
_default: /
_default: /poa/sokol
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM:
_default: https://airtable.com/shrqUAcjgGJ4jU88C
NEXT_PUBLIC_MARKETPLACE_APP_LIST:
_default: "[{'author': 'Blockscout', 'id': 'token-approval-tracker', 'title': 'Token Approval Tracker', 'logo': 'https://approval-tracker.vercel.app/icon-192.png', 'categories': ['security', 'tools'], 'shortDescription': 'Token Approval Tracker shows all approvals for any ERC20-compliant tokens and NFTs and lets to revoke them or adjust the approved amount.', 'site': 'https://docs.blockscout.com/for-users/blockscout-apps/token-approval-tracker', 'description': 'Token Approval Tracker shows all approvals for any ERC20-compliant tokens and NFTs and lets to revoke them or adjust the approved amount.', 'url': 'https://approval-tracker.vercel.app/'}]"
NEXT_PUBLIC_LOGOUT_URL:
_default: https://blockscoutcom.us.auth0.com/v2/logout
NEXT_PUBLIC_LOGOUT_RETURN_URL:
_default: https://blockscout.com/poa/sokol/auth/logout
......@@ -17,7 +17,7 @@ export default function useFetchProfileInfo() {
const fetch = useFetch();
return useQuery<unknown, Error, UserInfo>([ QueryKeys.profile ], async() => {
return fetch('/api/account/profile');
return fetch('/node-api/account/profile');
}, {
refetchOnMount: false,
enabled: Boolean(cookies.get(cookies.NAMES.API_TOKEN)),
......
......@@ -23,11 +23,11 @@ export default function useNavItems() {
return React.useMemo(() => {
const mainNavItems = [
{ text: 'Blocks', url: link('blocks'), icon: blocksIcon, isActive: currentRoute.startsWith('block') },
{ text: 'Transactions', url: link('txs'), icon: transactionsIcon, isActive: currentRoute.startsWith('tx') },
{ text: 'Tokens', url: link('tokens'), icon: tokensIcon, isActive: currentRoute === 'tokens' },
{ text: 'Blocks', url: link('blocks'), icon: blocksIcon, isActive: currentRoute.startsWith('block'), isNewUi: false },
{ text: 'Transactions', url: link('txs'), icon: transactionsIcon, isActive: currentRoute.startsWith('tx'), isNewUi: false },
{ text: 'Tokens', url: link('tokens'), icon: tokensIcon, isActive: currentRoute === 'tokens', isNewUi: false },
isMarketplaceFilled ?
{ text: 'Apps', url: link('apps'), icon: appsIcon, isActive: currentRoute === 'apps' } : null,
{ text: 'Apps', url: link('apps'), icon: appsIcon, isActive: currentRoute === 'apps', isNewUi: true } : null,
// there should be custom site sections like Stats, Faucet, More, etc but never an 'other'
// examples https://explorer-edgenet.polygon.technology/ and https://explorer.celo.org/
// at this stage custom menu items is under development, we will implement it later
......@@ -35,14 +35,14 @@ export default function useNavItems() {
].filter(notEmpty);
const accountNavItems = [
{ text: 'Watchlist', url: link('watchlist'), icon: watchlistIcon, isActive: currentRoute === 'watchlist' },
{ text: 'Private tags', url: link('private_tags'), icon: privateTagIcon, isActive: currentRoute.startsWith('private_tags') },
{ text: 'Public tags', url: link('public_tags'), icon: publicTagIcon, isActive: currentRoute === 'public_tags' },
{ text: 'API keys', url: link('api_keys'), icon: apiKeysIcon, isActive: currentRoute === 'api_keys' },
{ text: 'Custom ABI', url: link('custom_abi'), icon: abiIcon, isActive: currentRoute === 'custom_abi' },
{ text: 'Watchlist', url: link('watchlist'), icon: watchlistIcon, isActive: currentRoute === 'watchlist', isNewUi: true },
{ text: 'Private tags', url: link('private_tags'), icon: privateTagIcon, isActive: currentRoute.startsWith('private_tags'), isNewUi: true },
{ text: 'Public tags', url: link('public_tags'), icon: publicTagIcon, isActive: currentRoute === 'public_tags', isNewUi: true },
{ text: 'API keys', url: link('api_keys'), icon: apiKeysIcon, isActive: currentRoute === 'api_keys', isNewUi: true },
{ text: 'Custom ABI', url: link('custom_abi'), icon: abiIcon, isActive: currentRoute === 'custom_abi', isNewUi: true },
];
const profileItem = { text: 'My profile', url: link('profile'), icon: profileIcon, isActive: currentRoute === 'profile' };
const profileItem = { text: 'My profile', url: link('profile'), icon: profileIcon, isActive: currentRoute === 'profile', isNewUi: true };
return { mainNavItems, accountNavItems, profileItem };
}, [ isMarketplaceFilled, currentRoute ]);
......
......@@ -21,8 +21,7 @@ const paths = {
app_index: `${ BASE_PATH }/apps/[id]`,
search_results: `${ BASE_PATH }/search-results`,
other: `${ BASE_PATH }/search-results`,
// no slash required, it is correct
auth: `${ BASE_PATH }auth/auth0`,
auth: `${ BASE_PATH }/auth/auth0`,
};
module.exports = paths;
......@@ -29,9 +29,10 @@ export function middleware(req: NextRequest) {
// we don't have any info from router here, so just do straight forward sub-string search (sorry)
const isAccountRoute = req.nextUrl.pathname.includes('/account/');
const isProfileRoute = req.nextUrl.pathname.includes('/auth/profile');
const apiToken = req.cookies.get(NAMES.API_TOKEN);
if (isAccountRoute && !apiToken) {
if ((isAccountRoute || isProfileRoute) && !apiToken) {
const authUrl = link('auth', networkParams);
return NextResponse.redirect(authUrl);
}
......
......@@ -13,10 +13,10 @@ class MyDocument extends Document {
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap"
rel="stylesheet"
/>
<link rel="icon" sizes="32x32" type="image/png" href="/favicon-32x32.png"/>
<link rel="icon" sizes="16x16" type="image/png"href="/favicon-16x16.png"/>
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"/>
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5"/>
<link rel="icon" sizes="32x32" type="image/png" href="/static/favicon-32x32.png"/>
<link rel="icon" sizes="16x16" type="image/png"href="/static/favicon-16x16.png"/>
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png"/>
<link rel="mask-icon" href="/static/safari-pinned-tab.svg" color="#5bbad5"/>
</Head>
<body>
<ColorModeScript initialColorMode={ theme.config.initialColorMode }/>
......
......@@ -48,10 +48,10 @@ const ApiKeyForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
const body = { name: data.name };
if (!data.token) {
return fetch('/api/account/api-keys', { method: 'POST', body });
return fetch('/node-api/account/api-keys', { method: 'POST', body });
}
return fetch(`/api/account/api-keys/${ data.token }`, { method: 'PUT', body });
return fetch(`/node-api/account/api-keys/${ data.token }`, { method: 'PUT', body });
};
const mutation = useMutation(updateApiKey, {
......
......@@ -19,7 +19,7 @@ const DeleteAddressModal: React.FC<Props> = ({ isOpen, onClose, data }) => {
const fetch = useFetch();
const mutationFn = useCallback(() => {
return fetch(`/api/account/api-keys/${ data.api_key }`, { method: 'DELETE' });
return fetch(`/node-api/account/api-keys/${ data.api_key }`, { method: 'DELETE' });
}, [ data.api_key, fetch ]);
const onSuccess = useCallback(async() => {
......
......@@ -38,7 +38,7 @@ const BlockDetails = () => {
const { data, isLoading, isError, error } = useQuery<unknown, ErrorType<{ status: number }>, Block>(
[ QueryKeys.block, router.query.id ],
async() => await fetch(`/api/blocks/${ router.query.id }`),
async() => await fetch(`/node-api/blocks/${ router.query.id }`),
{
enabled: Boolean(router.query.id),
},
......
......@@ -22,7 +22,7 @@ const BlocksContent = ({ type }: Props) => {
const { data, isLoading, isError } = useQuery<unknown, unknown, BlocksResponse>(
[ QueryKeys.blocks, type ],
async() => await fetch(`/api/blocks${ type ? `?type=${ type }` : '' }`),
async() => await fetch(`/node-api/blocks${ type ? `?type=${ type }` : '' }`),
);
if (isLoading) {
......
......@@ -53,10 +53,10 @@ const CustomAbiForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
const body = { name: data.name, contract_address_hash: data.contract_address_hash, abi: data.abi };
if (!data.id) {
return fetch<CustomAbi, CustomAbiErrors>('/api/account/custom-abis', { method: 'POST', body });
return fetch<CustomAbi, CustomAbiErrors>('/node-api/account/custom-abis', { method: 'POST', body });
}
return fetch<CustomAbi, CustomAbiErrors>(`/api/account/custom-abis/${ data.id }`, { method: 'PUT', body });
return fetch<CustomAbi, CustomAbiErrors>(`/node-api/account/custom-abis/${ data.id }`, { method: 'PUT', body });
};
const formBackgroundColor = useColorModeValue('white', 'gray.900');
......
......@@ -18,7 +18,7 @@ const DeleteCustomAbiModal: React.FC<Props> = ({ isOpen, onClose, data }) => {
const queryClient = useQueryClient();
const mutationFn = useCallback(() => {
return fetch(`/api/account/custom-abis/${ data.id }`, { method: 'DELETE' });
return fetch(`/node-api/account/custom-abis/${ data.id }`, { method: 'DELETE' });
}, [ data ]);
const onSuccess = useCallback(async() => {
......
......@@ -31,7 +31,7 @@ const ApiKeysPage: React.FC = () => {
const [ apiKeyModalData, setApiKeyModalData ] = useState<ApiKey>();
const [ deleteModalData, setDeleteModalData ] = useState<ApiKey>();
const { data, isLoading, isError } = useQuery<unknown, unknown, ApiKeys>([ QueryKeys.apiKeys ], async() => await fetch('/api/account/api-keys'));
const { data, isLoading, isError } = useQuery<unknown, unknown, ApiKeys>([ QueryKeys.apiKeys ], async() => await fetch('/node-api/account/api-keys'));
const onEditClick = useCallback((data: ApiKey) => {
setApiKeyModalData(data);
......
......@@ -32,7 +32,7 @@ const Apps = () => {
useQuery<unknown, unknown, JsonRpcUrlResponse>(
[ 'json-rpc-url' ],
async() => await fetch(`/api/config/json-rpc-url`),
async() => await fetch(`/node-api/config/json-rpc-url`),
);
return (
......
......@@ -28,7 +28,8 @@ const CustomAbiPage: React.FC = () => {
const [ customAbiModalData, setCustomAbiModalData ] = useState<CustomAbi>();
const [ deleteModalData, setDeleteModalData ] = useState<CustomAbi>();
const { data, isLoading, isError } = useQuery<unknown, unknown, CustomAbis>([ QueryKeys.customAbis ], async() => await fetch('/api/account/custom-abis'));
const { data, isLoading, isError } = useQuery<unknown, unknown, CustomAbis>([ QueryKeys.customAbis ], async() =>
await fetch('/node-api/account/custom-abis'));
const onEditClick = useCallback((data: CustomAbi) => {
setCustomAbiModalData(data);
......
......@@ -28,7 +28,7 @@ const MarketplaceApp = ({ app, isLoading }: Props) => {
const { data: jsonRpcUrlResponse } = useQuery<unknown, unknown, JsonRpcUrlResponse>(
[ 'json-rpc-url' ],
async() => await fetch(`/api/config/json-rpc-url`),
async() => await fetch(`/node-api/config/json-rpc-url`),
{ refetchOnMount: false },
);
......
......@@ -20,7 +20,7 @@ import WatchlistTable from 'ui/watchlist/WatchlistTable/WatchlistTable';
const WatchList: React.FC = () => {
const { data, isLoading, isError } =
useQuery<unknown, unknown, TWatchlist>([ QueryKeys.watchlist ], async() => fetch('/api/account/watchlist/get-with-tokens'));
useQuery<unknown, unknown, TWatchlist>([ QueryKeys.watchlist ], async() => fetch('/node-api/account/watchlist/get-with-tokens'));
const addressModalProps = useDisclosure();
const deleteModalProps = useDisclosure();
......
......@@ -54,10 +54,10 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
const isEdit = data?.id;
if (isEdit) {
return fetch(`/api/account/private-tags/address/${ data.id }`, { method: 'PUT', body });
return fetch(`/node-api/account/private-tags/address/${ data.id }`, { method: 'PUT', body });
}
return fetch('/api/account/private-tags/address', { method: 'POST', body });
return fetch('/node-api/account/private-tags/address', { method: 'POST', body });
}, {
onError: (e: ErrorType<AddressTagErrors>) => {
setPending(false);
......
......@@ -23,7 +23,7 @@ const DeletePrivateTagModal: React.FC<Props> = ({ isOpen, onClose, data, type })
const fetch = useFetch();
const mutationFn = useCallback(() => {
return fetch(`/api/account/private-tags/${ type }/${ id }`, { method: 'DELETE' });
return fetch(`/node-api/account/private-tags/${ type }/${ id }`, { method: 'DELETE' });
}, [ fetch, type, id ]);
const onSuccess = useCallback(async() => {
......
......@@ -19,7 +19,7 @@ import DeletePrivateTagModal from './DeletePrivateTagModal';
const PrivateAddressTags = () => {
const { data: addressTagsData, isLoading, isError } =
useQuery<unknown, unknown, AddressTags>([ QueryKeys.addressTags ], async() => fetch('/api/account/private-tags/address'), { refetchOnMount: false });
useQuery<unknown, unknown, AddressTags>([ QueryKeys.addressTags ], async() => fetch('/node-api/account/private-tags/address'), { refetchOnMount: false });
const addressModalProps = useDisclosure();
const deleteModalProps = useDisclosure();
......
......@@ -21,7 +21,7 @@ const PrivateTransactionTags = () => {
const { data: transactionTagsData, isLoading, isError } =
useQuery<unknown, unknown, TransactionTags>(
[ QueryKeys.transactionTags ],
async() => fetch('/api/account/private-tags/transaction'), { refetchOnMount: false },
async() => fetch('/node-api/account/private-tags/transaction'), { refetchOnMount: false },
);
const transactionModalProps = useDisclosure();
......
......@@ -54,10 +54,10 @@ const TransactionForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) =>
const isEdit = data?.id;
if (isEdit) {
return fetch(`/api/account/private-tags/transaction/${ data.id }`, { method: 'PUT', body });
return fetch(`/node-api/account/private-tags/transaction/${ data.id }`, { method: 'PUT', body });
}
return fetch('/api/account/private-tags/transaction', { method: 'POST', body });
return fetch('/node-api/account/private-tags/transaction', { method: 'POST', body });
}, {
onError: (e: ErrorType<TransactionTagErrors>) => {
setPending(false);
......
......@@ -28,7 +28,7 @@ const DeletePublicTagModal: React.FC<Props> = ({ isOpen, onClose, data, onDelete
const deleteApiKey = useCallback(() => {
const body = { remove_reason: reason };
return fetch(`/api/account/public-tags/${ data.id }`, { method: 'DELETE', body });
return fetch(`/node-api/account/public-tags/${ data.id }`, { method: 'DELETE', body });
}, [ data.id, fetch, reason ]);
const onSuccess = useCallback(async() => {
......
......@@ -27,7 +27,8 @@ const PublicTagsData = ({ changeToFormScreen, onTagDelete }: Props) => {
const isMobile = useIsMobile();
const fetch = useFetch();
const { data, isLoading, isError } = useQuery<unknown, unknown, PublicTags>([ QueryKeys.publicTags ], async() => await fetch('/api/account/public-tags'));
const { data, isLoading, isError } = useQuery<unknown, unknown, PublicTags>([ QueryKeys.publicTags ], async() =>
await fetch('/node-api/account/public-tags'));
const onDeleteModalClose = useCallback(() => {
setDeleteModalData(undefined);
......
......@@ -99,10 +99,10 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
};
if (!data?.id) {
return fetch<PublicTag, PublicTagErrors>('/api/account/public-tags', { method: 'POST', body });
return fetch<PublicTag, PublicTagErrors>('/node-api/account/public-tags', { method: 'POST', body });
}
return fetch<PublicTag, PublicTagErrors>(`/api/account/public-tags/${ data.id }`, { method: 'PUT', body });
return fetch<PublicTag, PublicTagErrors>(`/node-api/account/public-tags/${ data.id }`, { method: 'PUT', body });
};
const mutation = useMutation(updatePublicTag, {
......
......@@ -18,7 +18,7 @@ interface Props {
const Page = ({ children, wrapChildren = true }: Props) => {
const fetch = useFetch();
useQuery<unknown, unknown, unknown>([ QueryKeys.csrf ], async() => await fetch('/api/account/csrf'), {
useQuery<unknown, unknown, unknown>([ QueryKeys.csrf ], async() => await fetch('/node-api/account/csrf'), {
enabled: Boolean(cookies.get(cookies.NAMES.API_TOKEN)),
});
......
......@@ -13,17 +13,17 @@ interface Props {
text: string;
icon: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
px?: string | number;
isNewUi: boolean;
}
const NavLink = ({ text, url, icon, isCollapsed, isActive, px }: Props) => {
const NavLink = ({ text, url, icon, isCollapsed, isActive, px, isNewUi }: Props) => {
const colors = useColors();
const isExpanded = isCollapsed === false;
return (
<Box as="li" listStyleType="none" w="100%">
<NextLink href={ url } passHref>
const content = (
<Link
{ ...(isNewUi ? {} : { href: url }) }
w={{ base: '100%', lg: isExpanded ? '180px' : '60px', xl: isCollapsed ? '60px' : '180px' }}
px={ px || { base: 3, lg: isExpanded ? 3 : '15px', xl: isCollapsed ? '15px' : 3 } }
py={ 2.5 }
......@@ -57,7 +57,17 @@ const NavLink = ({ text, url, icon, isCollapsed, isActive, px }: Props) => {
</HStack>
</Tooltip>
</Link>
);
return (
<Box as="li" listStyleType="none" w="100%">
{ /* why not NextLink in all cases? since prev UI and new one are hosting in the same domain and global routing is managed by nginx */ }
{ /* we have to hard reload page on every transition between urls from different part of the app */ }
{ isNewUi ? (
<NextLink href={ url } passHref>
{ content }
</NextLink>
) : content }
</Box>
);
};
......
import { Icon, Box, Image, useColorModeValue } from '@chakra-ui/react';
import NextLink from 'next/link';
import React from 'react';
import type { FunctionComponent, SVGAttributes } from 'react';
......@@ -41,37 +40,42 @@ const NetworkLogo = ({ isCollapsed, onClick }: Props) => {
if (logo && typeof logo === 'string') {
logoEl = (
<Image
h="20px"
w="auto"
h="100%"
src={ logo }
alt={ `${ appConfig.network.name } network icon` }
/>
);
} else if (typeof logo !== undefined) {
} else if (typeof logo !== 'undefined') {
logoEl = (
<Icon
as={ logo as FunctionComponent<SVGAttributes<SVGElement>> }
width="auto"
height="20px"
height="100%"
{ ...getDefaultTransitionProps() }
style={ style }
/>
);
} else {
logoEl = (
<Icon
as={ blockscoutLogo }
width="113px"
height="20px"
width="auto"
height="100%"
color={ logoColor }
{ ...getDefaultTransitionProps() }
style={ style }
/>;
/>
);
}
return (
<NextLink href={ href } passHref>
// TODO switch to <NextLink href={ href } passHref> when main page for network will be ready
<Box
as="a"
width={{ base: '113px', lg: isCollapsed === false ? '113px' : 0, xl: isCollapsed ? '0' : '113px' }}
href={ href }
width={{ base: 'auto', lg: isCollapsed === false ? '113px' : 0, xl: isCollapsed ? '0' : '113px' }}
height="20px"
display="inline-flex"
overflow="hidden"
onClick={ onClick }
......@@ -80,7 +84,6 @@ const NetworkLogo = ({ isCollapsed, onClick }: Props) => {
>
{ logoEl }
</Box>
</NextLink>
);
};
......
import { Box, Flex, Icon, Text, Image } from '@chakra-ui/react';
import NextLink from 'next/link';
import React from 'react';
import type { FeaturedNetwork } from 'types/networks';
......@@ -31,9 +30,9 @@ const NetworkMenuLink = ({ title, icon, isActive, isMobile, url }: Props) => {
return (
<Box as="li" listStyleType="none">
<NextLink href={ url } passHref>
<Flex
as="a"
href={ url }
px={ isMobile ? 3 : 4 }
py={ 2 }
alignItems="center"
......@@ -62,7 +61,6 @@ const NetworkMenuLink = ({ title, icon, isActive, isMobile, url }: Props) => {
/>
) }
</Flex>
</NextLink>
</Box>
);
};
......
......@@ -3,6 +3,7 @@ import React from 'react';
import type { UserInfo } from 'types/api/account';
import appConfig from 'configs/app/config';
import useNavItems from 'lib/hooks/useNavItems';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
import NavLink from 'ui/snippets/navigation/NavLink';
......@@ -40,7 +41,7 @@ const ProfileMenuContent = ({ name, nickname, email }: Props) => {
</VStack>
</Box>
<Box mt={ 2 } pt={ 3 } borderTopColor={ borderColor } borderTopWidth="1px" { ...getDefaultTransitionProps() }>
<Button size="sm" width="full" variant="outline">Sign Out</Button>
<Button size="sm" width="full" variant="outline" as="a" href={ appConfig.logoutUrl }>Sign Out</Button>
</Box>
</Box>
);
......
......@@ -2,16 +2,25 @@ import { Popover, PopoverContent, PopoverBody, PopoverTrigger, Button } from '@c
import React from 'react';
import useFetchProfileInfo from 'lib/hooks/useFetchProfileInfo';
import link from 'lib/link/link';
import UserAvatar from 'ui/shared/UserAvatar';
import ProfileMenuContent from 'ui/snippets/profileMenu/ProfileMenuContent';
const ProfileMenuDesktop = () => {
const { data } = useFetchProfileInfo();
const loginUrl = link('auth');
return (
<Popover openDelay={ 300 } placement="bottom-end" gutter={ 10 } isLazy>
<PopoverTrigger>
<Button variant="unstyled" display="inline-flex" height="auto" flexShrink={ 0 }>
<Button
variant="unstyled"
display="inline-flex"
height="auto"
flexShrink={ 0 }
as={ data ? undefined : 'a' }
href={ data ? undefined : loginUrl }
>
<UserAvatar size={ 50 } data={ data }/>
</Button>
</PopoverTrigger>
......
import { Flex, Box, Drawer, DrawerOverlay, DrawerContent, DrawerBody, useDisclosure } from '@chakra-ui/react';
import { Flex, Box, Drawer, DrawerOverlay, DrawerContent, DrawerBody, useDisclosure, Button } from '@chakra-ui/react';
import React from 'react';
import useFetchProfileInfo from 'lib/hooks/useFetchProfileInfo';
import link from 'lib/link/link';
import UserAvatar from 'ui/shared/UserAvatar';
import ColorModeToggler from 'ui/snippets/header/ColorModeToggler';
import ProfileMenuContent from 'ui/snippets/profileMenu/ProfileMenuContent';
......@@ -10,13 +11,13 @@ const ProfileMenuMobile = () => {
const { isOpen, onOpen, onClose } = useDisclosure();
const { data } = useFetchProfileInfo();
const loginUrl = link('auth');
return (
<>
<Box padding={ 2 } onClick={ onOpen }>
<UserAvatar size={ 24 } data={ data }/>
</Box>
{ data && (
<Drawer
isOpen={ isOpen }
placement="right"
......@@ -36,11 +37,12 @@ const ProfileMenuMobile = () => {
<UserAvatar size={ 24 } data={ data }/>
</Box>
</Flex>
<ProfileMenuContent { ...data }/>
{ data ? <ProfileMenuContent { ...data }/> : (
<Button size="sm" width="full" variant="outline" as="a" href={ loginUrl }>Sign In</Button>
) }
</DrawerBody>
</DrawerContent>
</Drawer>
) }
</>
);
};
......
......@@ -49,7 +49,7 @@ const TxDetails = () => {
const { data, isLoading, isError } = useQuery<unknown, unknown, Transaction>(
[ QueryKeys.tx, router.query.id ],
async() => await fetch(`/api/transactions/${ router.query.id }`),
async() => await fetch(`/node-api/transactions/${ router.query.id }`),
{
enabled: Boolean(router.query.id),
},
......
......@@ -75,7 +75,7 @@ const TxInternals = () => {
const [ sort, setSort ] = React.useState<Sort>();
const { data, isLoading, isError } = useQuery<unknown, unknown, InternalTransactionsResponse>(
[ QueryKeys.txInternals, router.query.id ],
async() => await fetch(`/api/transactions/${ router.query.id }/internal-transactions`),
async() => await fetch(`/node-api/transactions/${ router.query.id }/internal-transactions`),
{
enabled: Boolean(router.query.id),
},
......
......@@ -17,7 +17,7 @@ const TxLogs = () => {
const { data, isLoading, isError } = useQuery<unknown, unknown, LogsResponse>(
[ QueryKeys.txLog, router.query.id ],
async() => await fetch(`/api/transactions/${ router.query.id }/logs`),
async() => await fetch(`/node-api/transactions/${ router.query.id }/logs`),
{
enabled: Boolean(router.query.id),
},
......
......@@ -16,7 +16,7 @@ const TxRawTrace = () => {
const { data, isLoading, isError } = useQuery<unknown, unknown, RawTracesResponse>(
[ QueryKeys.txRawTrace, router.query.id ],
async() => await fetch(`/api/transactions/${ router.query.id }/raw-trace`),
async() => await fetch(`/node-api/transactions/${ router.query.id }/raw-trace`),
{
enabled: Boolean(router.query.id),
},
......
......@@ -97,11 +97,11 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
};
if (data) {
// edit address
return fetch<TWatchlistItem, WatchlistErrors>(`/api/account/watchlist/${ data.id }`, { method: 'PUT', body });
return fetch<TWatchlistItem, WatchlistErrors>(`/node-api/account/watchlist/${ data.id }`, { method: 'PUT', body });
} else {
// add address
return fetch<TWatchlistItem, WatchlistErrors>('/api/account/watchlist', { method: 'POST', body });
return fetch<TWatchlistItem, WatchlistErrors>('/node-api/account/watchlist', { method: 'POST', body });
}
}
......
......@@ -21,7 +21,7 @@ const DeleteAddressModal: React.FC<Props> = ({ isOpen, onClose, data }) => {
const fetch = useFetch();
const mutationFn = useCallback(() => {
return fetch(`/api/account1/watchlist/${ data?.id }`, { method: 'DELETE' });
return fetch(`/node-api/account/watchlist/${ data?.id }`, { method: 'DELETE' });
}, [ data?.id, fetch ]);
const onSuccess = useCallback(async() => {
......
......@@ -27,7 +27,7 @@ const WatchListItem = ({ item, onEditClick, onDeleteClick }: Props) => {
const { mutate } = useMutation(() => {
const data = { ...item, notification_methods: { email: !notificationEnabled } };
return fetch(`/api/account/watchlist/${ item.id }`, { method: 'PUT', body: JSON.stringify(data) });
return fetch(`/node-api/account/watchlist/${ item.id }`, { method: 'PUT', body: JSON.stringify(data) });
}, {
onError: () => {
// eslint-disable-next-line no-console
......
......@@ -52,7 +52,7 @@ const WatchlistTableItem = ({ item, onEditClick, onDeleteClick }: Props) => {
setSwitchDisabled(true);
const body = { ...item, notification_methods: { email: !notificationEnabled } };
setNotificationEnabled(prevState => !prevState);
return fetch(`/api/account1/watchlist/${ item.id }`, { method: 'PUT', body });
return fetch(`/node-api/account/watchlist/${ item.id }`, { method: 'PUT', body });
}, {
onError: () => {
showToast();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment