feat: explorer FE — stateless SSR, chain selector, localnet, registry cleanup

This commit is contained in:
Hanzo AI
2026-03-01 18:00:00 -08:00
parent 1e40ddb1c9
commit 888ef29c20
2039 changed files with 26630 additions and 31245 deletions
+2
View File
@@ -0,0 +1,2 @@
ECDL
-39
View File
@@ -1,39 +0,0 @@
# Create PR
## Overview
Create a well-structured pull request with proper description, labels, and reviewers.
## Steps
_Note_ in the command output, format all URLs as clickable Markdown links: `[Link Text](URL)`
1. **Check that the pull request is not already open in the remote repository**
- If it is opened, write only PR summary (see step 3) and skip all other steps
2. **Prepare branch**
- Ensure all changes are committed
- Push branch to remote
- Verify branch is up to date with main
3. **Write PR description**
- Use template from `./docs/PULL_REQUEST_TEMPLATE.md`
- Check if the branch name contains an issue number (use the regexp `/issue-\d+/`)
- If found, fetch the issue details using `gh issue view [issue_number]`
- Include "Resolves #[issue_number]" at the very beginning of the description (in the "Description and Related Issue(s)" section)
- Summarize the changes clearly and concisely, using no more than two paragraphs. If necessary, use bullet points to highlight the main changes in the codebase. Be precise, this description should not be very long.
- List any changes in the environment variables (look at the `./docs/ENVS.md` file) in a separate section, describe purpose of each variable change
- Bad example: "Added `NEXT_PUBLIC_VIEWS_TX_GROUPED_FEES` environment variable to the documentation"
- Good example: "Added `NEXT_PUBLIC_VIEWS_TX_GROUPED_FEES` to group transaction fees into one section on the transaction page"
- Good example: "Extended possible values for `NEXT_PUBLIC_VIEWS_TX_ADDITIONAL_FIELDS` with set_max_gas_limit to display the maximum gas price set by the transaction sender"
- Good example: "Introduced a new option, `"fee reception"`, for the `NEXT_PUBLIC_NETWORK_VERIFICATION_TYPE` variable"
- Keep the "Checklist for PR Author" section and check the appropriate items in it.
- When finished, ask the user for confirmation or changes before moving on to the next step.
4. **Set up PR**
- Create a pull request with a descriptive title. Use draft mode for the pull request if specified in the prompt.
- Add appropriate labels
- If something has added or changed in `./docs/ENVS.md` file, add label "ENVs"
- If the `package.json` file has changed, add label "dependencies"
- If the branch name has the issue number (use the regexp `/issue-\d+/`), copy all tags from the related issue
- Include a link to the created pull request in the command output.
-36
View File
@@ -1,36 +0,0 @@
# Deploy demo
## Overview
Create Github deployment for current branch using `.github/workflows/deploy-review.yml` workflow.
## Steps
_Note_ in the command output, format all URLs as clickable Markdown links: `[Link Text](URL)`
1. **Ensure all changes are pushed to remote**
2. **Check if there is a running deployment workflow for current branch**
- If yes, abort the command
3. **Detect value for "envs_preset" workflow input**
- Get all possible options from workflow file
- Figure out from the prompt with which preset user wants to deploy demo. Examples:
- "/deploy-demo for base" - preset name "base"
- "/deploy-demo using main preset" - preset name "main"
- "/deploy-demo without preset" - preset name "none"
- Be aware that this input is optional, and if user didn't mention any preset, skip this step completely
- If the preset is not listed in the worklow input options, notify user and abort the command
4. **Run workflow from the current branch with appropriate inputs**
- Get the workflow run ID after triggering
5. **Monitor workflow execution**
- Watch the workflow run until it completes (use `gh run watch`)
- Track the workflow status (success, failure, cancelled)
- Once completed, retrieve the workflow outputs and deployment URL
6. **Send system notification with results**
- On workflow start: notify that deployment has been triggered
- On workflow completion: notify with final status (success/failure), deployment URL if available, and any relevant outputs
- On failure: notify about the error with details
-17
View File
@@ -1,17 +0,0 @@
# Get Checks Status
## Overview
Fetch the status of the "Checks" workflow run (workflow file `.github/workflows/checks.yml`) for __current branch__.
## Steps
_Note_ in the command output, format all URLs as clickable Markdown links: `[Link Text](URL)`
1. **Fetch the status of the most recent workflow run**
- Use the GitHub API to get the workflow status for the *current branch*.
- If the workflow is pending, subscribe to its completion.
- If the workflow has failed, retrieve the list of all failed jobs and steps.
- If the workflow was never run for the current branch, report that and skip other steps.
2. **Report the status with a system notification**
- Upon workflow completion, notify with the final status (success or failure).
- In case of failure, notify about the error along with the list of failed jobs and steps.
-52
View File
@@ -1,52 +0,0 @@
# Prepare Release
## Overview
Prepare the next release of the application.
## Steps
1. **Get the next release tag name**
- Fetch the latest release from GitHub and retrieve its name.
- If not specified, calculate the next __minor__ version according to [semantic versioning](https://semver.org).
- If specified, calculate the next __major__ or __patch__ version.
2. **Update `./docs/ENVS.md` and `./docs/DEPRECATED_ENVS.md` files**
- In these files, update all placeholders containing "upcoming" text with the next release tag, adding a "+" at the end. Examples:
- "upcoming" -> "v1.2.3+"
- "<upcoming>" -> "v1.2.3+"
3. **Create release notes**
- Use `./RELEASE_NOTES.md` as a reference and this release notes [link](https://github.com/blockscout/frontend/releases/tag/v2.3.0) as an example.
- Get all commits between the head of the remote main branch and the latest release tag.
- Use the GitHub API to draft the next release notes using the main branch as a target. Parse the response to obtain the list of pull requests and new contributors.
- Copy `./RELEASE_NOTES.md` into a new file named `./RELEASE_NOTES_<release-tag>.md`.
- For every section (except "Changes in ENV variables") in the file, add the appropriate pull requests from previous steps using the pattern for each line: `- <pull-request-name> by <pull-request-author> in <link-to-pull-request>`. Example: "- API documentation page by @tom2drum in https://github.com/blockscout/frontend/pull/2725". Capitalize first letter in the PR name if needed.
- To determine the correct section in the release notes file, use the labels assigned to each pull request (which need to be fetched separately from the GitHub API alongside the pull request description, as the description will be used in the next step) and the table below. If a pull request belongs to several sections, mention it in each section. If a pull request lacks labels or its section cannot be determined, place it in the "Other Changes" section.
| Section | Labels |
| --------------------------- | ----------------------------------------------- |
| New Features | feature, enhancement, client feature |
| Bug Fixes | bug |
| Performance Improvements | performance |
| Dependencies updates | dependencies |
| Design updates | design |
- Compose the "Changes in ENV Variables" section following these rules:
- Find all pull requests tagged with "ENVs."
- Create a temporary file and paste the pull request numbers along with their descriptions, excluding the "Checklist for PR Author" section.
- Analyze the changes made to the ENV variables based on those descriptions. Feel free to rephrase sentences if necessary. If you cannot determine the correct changes or are unsure of their accuracy, use "Cannot find any changes in ENVs in PR description" as a placeholder in the next step.
- Compose the section according to the following template (note that changes are grouped by the related pull request number):
```
- <pull-request-number>:
- <change-1>
- <change-2>
```
Examples:
- #3005
- Added `NEXT_PUBLIC_AD_BANNER_ENABLE_SPECIFY` to enable the Specify ad provider for users with a connected wallet.
- Removed the `hype` option from the `NEXT_PUBLIC_AD_BANNER_PROVIDER` variable values.
- #2968
- Added `NEXT_PUBLIC_MEGA_ETH_SOCKET_URL_METRICS` to display information on the uptime dashboard page.
- Update the "Full list of the ENV variables" and "Full Changelog" with the correct version tags.
- Update the "New Contributors" section if necessary.
- Keep the "Compatibility" section unchanged.
- Remove all empty sections.
+2 -7
View File
@@ -1,8 +1,3 @@
{
"mcpServers": {
"chakra-ui": {
"command": "npx",
"args": ["-y", "@chakra-ui/react-mcp"]
}
}
}
"mcpServers": {}
}
+17
View File
@@ -0,0 +1,17 @@
---
name: check-github-cli
description: Ensure GitHub CLI (gh) is installed and authenticated before running gh commands; guide the user to configure it if not
---
# Check GitHub CLI Availability
Use this skill whenever a workflow or command requires the GitHub CLI (`gh`). Before running any `gh` commands:
1. **Check installation and auth**: Run `gh auth status`. If it reports "not logged in" or the command is not found:
- **If `gh` is not installed**: Ask the user to install it (e.g. `brew install gh` on macOS, or see [GitHub CLI](https://cli.github.com/)) and then authenticate.
- **If `gh` is installed but not configured**: Ask the user to configure it themselves. Provide these instructions to help them:
- Run `gh auth login` and follow the prompts (choose HTTPS or SSH, authenticate via browser or token).
- Ensure the account has the permissions needed for the operation (e.g. read access to the repository, or read/write if the task requires it).
- Do not attempt to authenticate on the user's behalf; only guide them with the commands and link to [GitHub CLI authentication docs](https://cli.github.com/manual/gh_auth_login).
2. **If `gh auth status` succeeds**: Proceed with the steps that require `gh`.
Other skills that depend on `gh` (e.g. get-checks-status) should instruct the agent to ensure GitHub CLI is ready first by following this skill.
@@ -0,0 +1,169 @@
---
name: create-issue-from-slack-thread
description: >-
Create a GitHub issue from a Slack thread conversation. Use when the user
wants to turn a Slack thread into a GitHub issue, create an issue from a Slack
conversation, or mentions creating issues from Slack links/URLs.
disable-model-invocation: true
---
# Create Issue from Slack Thread
Turn a Slack thread into a well-structured GitHub issue in a Blockscout repository.
## Prerequisites
### 1. GitHub CLI
This workflow uses `gh` to create issues and manage labels. **Follow the check-github-cli skill** first (ensure `gh auth status` succeeds; if not, guide the user to install/configure `gh` and do not proceed).
### 2. Slack MCP Plugin
This workflow uses the Slack MCP plugin (`plugin-slack-slack`) to read thread content. Before proceeding:
- Try calling the `slack_read_thread` MCP tool with a test request to verify connectivity.
- If the Slack MCP server is not available or returns an error, tell the user:
- The Slack plugin must be enabled in Cursor. Go to **Cursor Settings > MCP** and ensure the Slack server is connected and running.
- They may need to re-authenticate the Slack plugin if the session has expired.
- Do not proceed until both `gh` and the Slack plugin are confirmed working.
## Workflow
### Step 1: Parse the Slack Thread URL
The user provides a Slack thread URL. Extract `channel_id` and `message_ts` from it.
Slack thread URLs follow these patterns:
- `https://<workspace>.slack.com/archives/<channel_id>/p<timestamp_without_dot>`
- `https://app.slack.com/client/<workspace_id>/<channel_id>/thread/<channel_id>-<timestamp_without_dot>`
Parsing rules:
- **channel_id**: The segment starting with `C` (e.g., `C04XXXX5DAT`).
- **message_ts**: Take the `p`-prefixed number, remove the `p`, and insert a dot before the last 6 digits. Example: `p1709834567890123` becomes `1709834567.890123`.
If the URL cannot be parsed, ask the user for the `channel_id` and `message_ts` directly.
### Step 2: Read the Slack Thread
Use the `slack_read_thread` MCP tool:
```
Tool: slack_read_thread
Server: plugin-slack-slack
Arguments:
channel_id: "<extracted_channel_id>"
message_ts: "<extracted_message_ts>"
limit: 200
```
If the thread has more than 200 messages, use the `cursor` parameter to paginate and read the full conversation.
### Step 3: Summarize the Conversation
Analyze the full thread and produce a technical summary that captures:
- The core problem or request being discussed
- Relevant technical details (error messages, stack traces, affected components, versions)
- Steps to reproduce if applicable
- Any proposed solutions or workarounds mentioned
- Acceptance criteria or expected behavior if discussed
**Mandatory rules for the summary:**
- **Never** include a link to the original Slack thread
- **Never** include names of team members or attribute statements to specific people
- Write in neutral, third-person technical language
### Step 4: Determine the Target Repository
Ask the user which Blockscout repository the issue should be created in. To help them decide, fetch the list of public repositories:
```bash
gh repo list blockscout --source --no-archived --limit 100 --json name,description --jq '.[] | "\(.name): \(.description)"'
```
Present the most relevant repositories based on the conversation topic and ask the user to confirm the target repository. Always wait for explicit confirmation before proceeding.
### Step 5: Fetch Available Labels
Retrieve labels from the chosen repository:
```bash
gh label list --repo blockscout/<repo_name> --json name,description --limit 100
```
Based on the issue content, select labels that correspond to the problem described. **Do not add a label if none of the available labels match the issue topic.** It is acceptable to have zero labels.
### Step 6: Compose the Issue
Draft the issue with:
- **Title**: A clear, concise summary of the problem or request (imperative mood preferred, e.g., "Fix X" or "Add support for Y").
- **Description**: A well-structured body using this template:
```markdown
## Description
[Core problem or request in 2-3 sentences]
## Details
[Technical details, error messages, affected components]
## Steps to Reproduce
[If applicable — numbered steps]
## Expected Behavior
[What should happen instead, or acceptance criteria]
## Additional Context
[Any other relevant technical information from the discussion]
```
Omit any section that has no content rather than leaving it empty.
**Mandatory rules for the issue:**
- **Never** include a link to the original Slack thread
- **Never** include names of team members or attribute statements to specific people
### Step 7: User Confirmation
Before creating the issue, present the following to the user and ask for confirmation:
1. **Repository**: `blockscout/<repo_name>`
2. **Title**: the proposed title
3. **Description**: the full issue body
4. **Label(s)**: the selected labels (or "None" if no labels match)
Wait for the user to confirm or request changes. Apply any requested changes and re-confirm if needed.
### Step 8: Create the Issue
Once confirmed, create the issue:
```bash
gh issue create \
--repo blockscout/<repo_name> \
--title "<title>" \
--body "<body>"
```
If labels were selected, add them:
```bash
gh issue edit <issue_number> --repo blockscout/<repo_name> --add-label "<label1>" --add-label "<label2>"
```
Alternatively, pass labels at creation time if supported:
```bash
gh issue create \
--repo blockscout/<repo_name> \
--title "<title>" \
--body "<body>" \
--label "<label1>" --label "<label2>"
```
After creation, display a clickable link to the new issue.
+62
View File
@@ -0,0 +1,62 @@
---
name: create-pr
description: Create a well-structured pull request with proper description, labels, and reviewers
disable-model-invocation: true
---
# Create PR
## Prerequisites: GitHub CLI
This workflow uses `gh` to check for existing PRs, fetch issue details, and create the PR. **Follow the check-github-cli skill** first (ensure `gh auth status` succeeds; if not, guide the user to install/configure `gh` and do not proceed). The account needs read access to the repo and write access to create PRs and manage labels.
## Overview
Create a well-structured pull request with proper description, labels, and reviewers.
## Steps
_Note:_ In the command output, format all URLs as clickable Markdown links: `[Link Text](URL)`.
### 1. Check that a PR is not already open for this branch
- Get the current branch: `git branch --show-current`.
- List open PRs for that branch: `gh pr list --head <BRANCH> --state open`.
- If a PR exists, do **only** the PR summary (see step 3: write the description content as if for the PR, but do not create or update the PR). Skip steps 2, 3 (create/update), and 4. Tell the user the PR is already open and link to it.
### 2. Prepare the branch
- Ensure all changes are committed:
- `git status` to see uncommitted changes.
- If there are changes: `git add` (as appropriate), then `git commit -m "..."` with a clear message.
- Push the branch: `git push -u origin <BRANCH>` (or `git push` if upstream is already set).
- Verify the branch is up to date with main:
- `git fetch origin main` then compare: e.g. `git rev-list --left-right --count origin/main...HEAD` (expect `0 N` for “main has nothing we dont have”) or merge/rebase if the user wants: `git merge origin/main`.
- Resolve any merge conflicts before continuing.
### 3. Write the PR description
- Use the template from `./docs/PULL_REQUEST_TEMPLATE.md` as the base. Read it and fill in each section.
- **Issue number from branch name:** If the branch name matches the pattern `issue-\d+` (e.g. `issue-123`), extract the number (e.g. `git branch --show-current | grep -oE 'issue-[0-9]+' | grep -oE '[0-9]+'`), then:
- Fetch the issue: `gh issue view <ISSUE_NUMBER>`.
- At the very beginning of the **"Description and Related Issue(s)"** section, include: `Resolves #<ISSUE_NUMBER>`.
- **Summary of changes:** Summarize the changes clearly and concisely in no more than two paragraphs. Use bullet points if needed. Be precise; keep the description short.
- **Environment variable changes:** If any env vars were added, changed, or documented:
- Compare or read `./docs/ENVS.md` (and the validator/ENVS docs if relevant) to list what changed.
- Add a separate section listing each variable change and the **purpose** of each (why it was added/changed).
- **Bad:** "Added `NEXT_PUBLIC_VIEWS_TX_GROUPED_FEES` environment variable to the documentation."
- **Good:** "Added `NEXT_PUBLIC_VIEWS_TX_GROUPED_FEES` to group transaction fees into one section on the transaction page."
- **Good:** "Extended possible values for `NEXT_PUBLIC_VIEWS_TX_ADDITIONAL_FIELDS` with set_max_gas_limit to display the maximum gas price set by the transaction sender."
- **Good:** "Introduced a new option, `"fee reception"`, for the `NEXT_PUBLIC_NETWORK_VERIFICATION_TYPE` variable."
- **Checklist:** Keep the "Checklist for PR Author" section from the template and check the items that apply (e.g. tested locally, tests added, ENVS/docs/validator updated if env vars changed).
- When the description is ready, **ask the user for confirmation or changes** before creating the PR (step 4).
### 4. Create the PR and set labels
- Create the pull request with a descriptive title. Use draft mode if the user asked for it:
- `gh pr create --title "Your descriptive title" --body-file /path/to/body.md` (and add `--draft` if draft).
- Or paste the body inline if preferred; ensure the filled template is used.
- Add labels:
- If anything was added or changed in `./docs/ENVS.md`, add the **"ENVs"** label: `gh pr edit <PR_NUMBER> --add-label "ENVs"` (or add labels during `gh pr create` if your `gh` version supports it).
- If `package.json` has changed (check with `git diff origin/main -- package.json`), add the **"dependencies"** label.
- If the branch name contained an issue number (pattern `issue-\d+`), copy all labels from that issue onto the PR: get labels with `gh issue view <ISSUE_NUMBER> --json labels -q '.labels[].name'`, then add each: `gh pr edit <PR_NUMBER> --add-label "<LABEL>"`.
- Include a clickable link to the created PR in the command output (e.g. from `gh pr view --web` or the URL printed by `gh pr create`).
+59
View File
@@ -0,0 +1,59 @@
---
name: deploy-demo
description: Create a GitHub deployment for the current branch using the deploy-review workflow
disable-model-invocation: true
---
# Deploy demo
## Prerequisites: GitHub CLI
This workflow uses `gh` to trigger and monitor the deployment workflow. **Follow the check-github-cli skill** first (ensure `gh auth status` succeeds; if not, guide the user to install/configure `gh` and do not proceed). The account needs permission to trigger workflows and read the repository.
## Overview
Create a GitHub deployment for the current branch using `.github/workflows/deploy-review.yml` (workflow name: "Deploy review environment").
## Steps
_Note:_ In the command output, format all URLs as clickable Markdown links: `[Link Text](URL)`.
### 1. Ensure all changes are pushed to remote
- Check status: `git status`. If there are uncommitted changes, ask the user to commit and push, or run `git add` / `git commit` and then push.
- Push the current branch: `git push origin $(git branch --show-current)` (or `git push` if upstream is set). Abort if push fails.
### 2. Check for an already running deployment for the current branch
- Get current branch: `git branch --show-current`.
- List runs for the deploy-review workflow on this branch that are in progress or queued:
- `gh run list --workflow=deploy-review.yml --branch <BRANCH> --status in_progress`
- `gh run list --workflow=deploy-review.yml --branch <BRANCH> --status queued`
- If any run is returned, **abort the command** and tell the user a deployment is already running for this branch (include a link to the run).
### 3. Resolve the "envs_preset" workflow input (optional)
- **Get valid options from the workflow file (single source of truth):** Read `.github/workflows/deploy-review.yml` and extract the list of allowed values from `on.workflow_dispatch.inputs.envs_preset.options` (the YAML array under that key). Do not hardcode or copy the preset list into this skill — always read it from the file.
- Infer from the users prompt which preset they want. Examples:
- "deploy a demo for base" or "deploy with base preset" → preset `base`
- "spin up a demo using main preset" → preset `main`
- **If the user did not mention any preset:** skip passing `envs_preset` (the workflow uses its default).
- **Validate the chosen preset:** Check that the users chosen preset is one of the values in the options list you extracted from the workflow file. If it is not in that list, notify the user (you can show the valid options from the file) and **abort the command**.
### 4. Trigger the workflow and capture the run ID
- Run the workflow from the current branch (use the branch name from step 1 or 2):
- Without preset: `gh workflow run deploy-review.yml --ref <BRANCH>`
- With preset: `gh workflow run deploy-review.yml --ref <BRANCH> -f envs_preset=<PRESET>`
- The CLI does not print the new run ID. To get it: wait a few seconds, then list the latest run for this workflow and branch: `gh run list --workflow=deploy-review.yml --branch <BRANCH> --limit 1`. Use that runs ID for the next steps.
### 5. Monitor the workflow until it completes
- Watch the run: `gh run watch <RUN_ID>` (polls until completion).
- Track the outcome: success, failure, or cancelled (from the watch output or from `gh run view <RUN_ID>`).
- When completed, get outputs and deployment URL: `gh run view <RUN_ID>` and, if available, `gh run view <RUN_ID> --log` or job outputs. The deployment URL may appear in the workflow summary or in job outputs; extract it and include it in the notification.
### 6. Send system notifications with results
- **When the workflow is triggered:** Notify the user that the deployment has been started (include a link to the run).
- **When the workflow completes:** Notify with the final status (success, failure, or cancelled), the deployment URL if available, and any other relevant outputs.
- **On failure:** Notify with the error and details (e.g. failed job/step from `gh run view <RUN_ID>` or `gh run view <RUN_ID> --log-failed`).
+36
View File
@@ -0,0 +1,36 @@
---
name: get-checks-status
description: Fetch the status of the Checks workflow for the current branch and report with optional system notification
disable-model-invocation: true
---
# Get Checks Status
## Prerequisites: GitHub CLI
Before running any steps, ensure the GitHub CLI is available and authenticated. **Follow the check-github-cli skill** (ensure `gh auth status` succeeds; if not, guide the user to install/configure `gh` and do not proceed). For this workflow, the account needs read access to the repository.
## Overview
Fetch the status of the "Checks" workflow run (workflow file `.github/workflows/checks.yml`) for __current branch__.
## Steps
_Note_ in the command output, format all URLs as clickable Markdown links: `[Link Text](URL)`
1. **Determine the current branch**
- Run: `git branch --show-current` (or equivalent) to get the branch name. Use this in subsequent `gh` commands.
2. **Fetch the status of the most recent workflow run**
- List the latest run for the Checks workflow on the current branch:
- `gh run list --workflow=checks.yml --branch <BRANCH> --limit 1`
- If no runs are returned, report that the workflow was never run for the current branch and skip other steps.
- If a run exists, get its status and run ID, then:
- **If the workflow is pending (queued or in progress)**: Use `gh run watch <RUN_ID>` to subscribe to completion (or poll with `gh run view <RUN_ID>` until status is completed).
- **If the workflow has failed**: Retrieve failed jobs and steps with:
- `gh run view <RUN_ID>` for summary and job list.
- `gh run view <RUN_ID> --log-failed` for failed step logs (optional, for details).
- Format the run URL as a Markdown link, e.g. `gh run view <RUN_ID> --web` gives the URL; or use: `https://github.com/<OWNER>/<REPO>/actions/runs/<RUN_ID>`.
3. **Report the status with a system notification**
- Upon workflow completion, notify with the final status (success or failure).
- In case of failure, notify about the error along with the list of failed jobs and steps.
+73
View File
@@ -0,0 +1,73 @@
---
name: prepare-release
description: Prepare the next release of the application (tag, docs, release notes)
disable-model-invocation: true
---
# Prepare Release
## Prerequisites: GitHub CLI
This workflow uses `gh` to fetch releases, compare branches, and draft release notes via the GitHub API. **Follow the check-github-cli skill** first (ensure `gh auth status` succeeds; if not, guide the user to install/configure `gh` and do not proceed). The account needs read access to the repo and, if you publish or draft releases, appropriate write access.
## Overview
Prepare the next release of the application.
## Steps
### 1. Get the next release tag name
- Fetch the latest release from GitHub: `gh release list --limit 1` (or `gh release view` for the latest). Retrieve its tag name (e.g. `v1.2.3`).
- **If the user did not specify which version bump to use:** Compute the next **minor** version per [semantic versioning](https://semver.org) (e.g. `v1.2.3``v1.3.0`).
- **If the user specified major or patch:** Compute the next **major** (e.g. `v2.0.0`) or **patch** (e.g. `v1.2.4`) version accordingly.
- Use this tag (e.g. `v1.3.0`) as the release tag for all following steps.
### 2. Update `./docs/ENVS.md` and `./docs/DEPRECATED_ENVS.md`
- In both files, replace every placeholder that contains the text "upcoming" with the next release tag followed by a "+". Examples:
- `"upcoming"``"v1.3.0+"`
- `"<upcoming>"``"v1.3.0+"`
- You can use search-and-replace in the editor or a script (e.g. `sed -i '' 's/upcoming/v1.3.0+/g' ./docs/ENVS.md` and similarly for `DEPRECATED_ENVS.md`; adjust for `<upcoming>` if present). Ensure all such placeholders are updated.
### 3. Create release notes
Perform the following sub-steps **in order**.
- **Reference files:** Use `./RELEASE_NOTES.md` as the template and, for format inspiration, this [example release](https://github.com/blockscout/frontend/releases/tag/v2.3.0).
- **Get release notes draft:** Use the GitHub API to generate draft release notes with main as the target (e.g. `gh api repos/OWNER/REPO/releases/generate-notes -f tag_name=<next-tag> -f target_commitish=main -f previous_tag_name=<latest-release-tag>`). Parse the response to get the list of pull request **numbers** and new contributors. Keep this list; every PR in it must appear in the final notes.
- **Fetch and store PR data (labels and descriptions):** Before editing the release notes file, fetch labels and body for all PRs from the draft **once** and save them to a temporary file so later steps do not hit the GitHub API repeatedly. Use the script that rate-limits requests (authenticated API limit is 5000 requests/hour; the script adds a delay between calls).
- From the **repository root**, run: `node .cursor/skills/prepare-release/fetch-release-prs.js <pr-number-1> <pr-number-2> ... --out release-prs-data.json` with every PR number from the release notes draft. Example: `node .cursor/skills/prepare-release/fetch-release-prs.js 2725 2726 2727 --out release-prs-data.json`.
- The script writes JSON to `release-prs-data.json` in the repository root (format: `{ "prs": [ { "number", "title", "author", "url", "labels", "body" }, ... ] }`). Use this file as the **single source of truth** for labels and descriptions in the next two steps; do not call the GitHub API again when mapping sections or writing the ENV section.
- **Copy and fill the notes file:** Copy `./RELEASE_NOTES.md` to a new file `./RELEASE_NOTES_<release-tag>.md` (e.g. `RELEASE_NOTES_v1.3.0.md`).
- **Map PRs to sections:** For each section in the new file **except** "Changes in ENV variables", add the relevant pull requests. **Use only the data in `release-prs-data.json`** (labels, title, author, url) — do not call the GitHub API again. For each line use the format: `- <pull-request-title> by @<author> in <link-to-pull-request>`. Example: `- API documentation page by @tom2drum in https://github.com/blockscout/frontend/pull/2725`. Capitalize the first letter of the PR title if needed. Assign PRs to sections using each PRs **labels** from the stored file and this mapping:
| Section | Labels |
| ------------------------- | ------------------------------------------- |
| New Features | feature, enhancement, client feature |
| Bug Fixes | bug |
| Performance Improvements | performance |
| Dependencies updates | dependencies |
| Design updates | design |
If a PR has no matching labels, try to categorize it based on its description (the **body** field in the `release-prs-data.json` file). If the section remains unclear, categorize it as "Other Changes." Never exclude a PR from the notes. The list of PRs in the release notes must match exactly the list from "Get release notes draft." Always double-check this.
- **"Changes in ENV variables" section:**
- From `release-prs-data.json`, find all PRs whose **labels** include `"ENVs"` (or `ENVs`). Use their **body** field as the PR description.
- For each of those PRs, strip the "Checklist for PR Author" part from the body if present. Then, summarize the changes to the ENV variables and rephrase them if necessary. If you are unable to determine the changes or are unsure, use the placeholder: "Cannot find any changes in ENVs in PR description."
- Write the section in this form (grouped by PR number):
```
- <pull-request-number>:
- <change-1>
- <change-2>
```
- Examples:
- #3005
- Added `NEXT_PUBLIC_AD_BANNER_ENABLE_SPECIFY` to enable the Specify ad provider for users with a connected wallet.
- Removed the `hype` option from the `NEXT_PUBLIC_AD_BANNER_PROVIDER` variable values.
- #2968
- Added `NEXT_PUBLIC_MEGA_ETH_SOCKET_URL_METRICS` to display information on the uptime dashboard page.
- **Final edits in the release notes file:**
- Update "Full list of the ENV variables" and "Full Changelog" with the correct version tags/links.
- Update the "New Contributors" section if the "Get release notes draft" response included new contributors.
- Leave the "Compatibility" section content unchanged.
@@ -0,0 +1,101 @@
#!/usr/bin/env node
/* eslint-disable no-console */
/**
* Fetches labels and description (body) for a list of pull requests via the GitHub API,
* with rate limiting to avoid hitting API limits. Outputs JSON to a file for use when
* preparing release notes (mapping PRs to sections and building the ENV variables section).
*
* Prerequisites: GitHub CLI (gh) installed and authenticated.
*
* Usage:
* node fetch-release-prs.js <pr-number> [pr-number ...] [--out <path>]
* echo "2725 2726" | xargs node fetch-release-prs.js --out release-prs-data.json
*
* Output JSON shape (written to --out or stdout):
* { "prs": [ { "number", "title", "author", "url", "labels", "body" }, ... ] }
*/
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const DELAY_MS = 400;
function getRepo() {
try {
return execSync('gh repo view --json nameWithOwner -q .nameWithOwner', {
encoding: 'utf-8',
}).trim();
} catch {
return 'blockscout/frontend';
}
}
function fetchPr(ownerRepo, number) {
const [ owner, repo ] = ownerRepo.split('/');
const out = execSync(
`gh api repos/${ owner }/${ repo }/issues/${ number } --jq '{number, title, user: .user.login, labels: [.labels[].name], body}'`,
{ encoding: 'utf-8', maxBuffer: 2 * 1024 * 1024 },
);
const data = JSON.parse(out);
return {
number: data.number,
title: data.title,
author: data.user,
url: `https://github.com/${ ownerRepo }/pull/${ data.number }`,
labels: data.labels || [],
body: data.body || '',
};
}
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function main() {
const args = process.argv.slice(2);
let outPath = null;
const prNumbers = [];
for (let i = 0; i < args.length; i++) {
if (args[i] === '--out' && args[i + 1]) {
outPath = args[i + 1];
i += 1;
} else if (/^\d+$/.test(args[i])) {
prNumbers.push(Number(args[i], 10));
}
}
if (prNumbers.length === 0) {
console.error('Usage: node fetch-release-prs.js <pr-number> [pr-number ...] [--out <path>]');
process.exit(1);
}
const ownerRepo = getRepo();
const prs = [];
for (let i = 0; i < prNumbers.length; i++) {
const num = prNumbers[i];
try {
prs.push(fetchPr(ownerRepo, num));
if (i < prNumbers.length - 1) {
await sleep(DELAY_MS);
}
} catch (err) {
console.error(`Failed to fetch PR #${ num }:`, err.message);
process.exit(1);
}
}
const result = { prs };
const json = JSON.stringify(result, null, 2);
if (outPath) {
fs.writeFileSync(outPath, json, 'utf-8');
console.error(`Wrote ${ prs.length } PR(s) to ${ path.resolve(outPath) }`);
} else {
console.log(json);
}
}
main();
-1
View File
@@ -13,6 +13,5 @@ README.md
/playwright-report/
/blob-report/
/.vscode/
/playwright/
CHANGELOG.md
.env.local
+3 -6
View File
@@ -18,12 +18,9 @@ NEXT_PUBLIC_APP_PROTOCOL=https
NEXT_PUBLIC_IS_TESTNET=false
NEXT_PUBLIC_NETWORK_RPC_URL=https://api.lux.network/ext/bc/C/rpc
# Branding
NEXT_PUBLIC_NETWORK_LOGO=/logos/lux-logo-white.png
NEXT_PUBLIC_NETWORK_LOGO_DARK=/logos/lux-logo-white.png
NEXT_PUBLIC_NETWORK_ICON=/logos/lux-logo-white.png
NEXT_PUBLIC_NETWORK_ICON_DARK=/logos/lux-logo-white.png
NEXT_PUBLIC_OG_IMAGE_URL=/logos/lux-logo-white.png
# Branding — intentionally left unset for multi-tenant.
# Each chain uses text-based branding from chainRegistry.ts.
# Per-chain logos can be set via configmap env vars at runtime.
# Font Configuration (Geist from Google Fonts, registered as 'Geist' not 'Geist Sans')
NEXT_PUBLIC_FONT_FAMILY_HEADING={"name":"Geist","url":"https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&display=swap"}
+3
View File
@@ -0,0 +1,3 @@
node_modules
.git
.next
+76 -11
View File
@@ -24,8 +24,8 @@ env:
IMAGE_NAME: luxfi/explore
jobs:
build-and-deploy:
runs-on: lux-build
build:
runs-on: lux-build-linux-amd64
permissions:
contents: read
packages: write
@@ -71,20 +71,85 @@ jobs:
GIT_COMMIT_SHA=${{ github.sha }}
GIT_TAG=${{ github.ref_type == 'tag' && github.ref_name || '' }}
- name: Deploy to production
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
deploy:
needs: build
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
runs-on: lux-build-linux-amd64
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
with:
sparse-checkout: .github
- name: Fetch deploy credentials from KMS
id: kms
env:
DIGITALOCEAN_ACCESS_TOKEN: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
KMS_CLIENT_ID: ${{ secrets.KMS_CLIENT_ID }}
KMS_CLIENT_SECRET: ${{ secrets.KMS_CLIENT_SECRET }}
HANZO_API_KEY: ${{ secrets.HANZO_API_KEY }}
KMS_ENDPOINT: ${{ vars.KMS_ENDPOINT || 'https://kms.hanzo.ai' }}
run: |
# Install doctl + kubectl if not present
# Auth: Universal Auth (preferred) or legacy API key
if [ -n "${KMS_CLIENT_ID}" ] && [ -n "${KMS_CLIENT_SECRET}" ]; then
HANZO_API_KEY=$(curl -sf "${KMS_ENDPOINT}/api/v1/auth/universal-auth/login" \
-H "Content-Type: application/json" \
-d "{\"clientId\":\"${KMS_CLIENT_ID}\",\"clientSecret\":\"${KMS_CLIENT_SECRET}\"}" | jq -r '.accessToken')
fi
response=$(curl -sf "${KMS_ENDPOINT}/api/v3/secrets/raw?workspaceId=e1359bf4-31b4-4dfa-bb90-323e2c298ad8&secretPath=/deploy&environment=prod" \
-H "Authorization: Bearer ${HANZO_API_KEY}" 2>/dev/null || echo "")
if [ -n "$response" ]; then
token=$(echo "$response" | jq -r '.secrets[] | select(.secretKey=="DO_API_TOKEN") | .secretValue // empty')
fi
if [ -z "${token:-}" ]; then
echo "::warning::Deploy credentials not found. Image was pushed but deployment skipped."
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "::add-mask::${token}"
echo "token=${token}" >> "$GITHUB_OUTPUT"
- name: Deploy to production
if: steps.kms.outputs.skip != 'true'
env:
DO_TOKEN: ${{ steps.kms.outputs.token }}
run: |
INSTALL_DIR="$HOME/.local/bin"
mkdir -p "$INSTALL_DIR"
export PATH="$INSTALL_DIR:$PATH"
if ! command -v doctl &>/dev/null; then
curl -sL https://github.com/digitalocean/doctl/releases/latest/download/doctl-1.119.1-linux-amd64.tar.gz | tar xz -C /usr/local/bin 2>/dev/null || true
DOCTL_VERSION=$(curl -sI https://github.com/digitalocean/doctl/releases/latest | grep -i '^location:' | sed 's|.*/v||;s/\r//')
curl -sL "https://github.com/digitalocean/doctl/releases/download/v${DOCTL_VERSION}/doctl-${DOCTL_VERSION}-linux-amd64.tar.gz" | tar xz -C "$INSTALL_DIR"
fi
if ! command -v kubectl &>/dev/null; then
curl -sLO "https://dl.k8s.io/release/$(curl -sL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl && mv kubectl /usr/local/bin/kubectl
chmod +x kubectl && mv kubectl "$INSTALL_DIR/kubectl"
fi
doctl auth init -t "$DIGITALOCEAN_ACCESS_TOKEN"
doctl auth init -t "$DO_TOKEN"
doctl kubernetes cluster kubeconfig save lux-k8s
kubectl rollout restart deployment/explorer-frontend -n lux-explorer
kubectl rollout status deployment/explorer-frontend -n lux-explorer --timeout=300s
# Ensure namespaces exist
for ns in lux-mainnet lux-testnet lux-devnet; do
kubectl create namespace $ns 2>/dev/null || true
done
# Deploy shared services (stats) — mainnet only for now
kubectl apply -f deploy/k8s/stats.yaml -n lux-mainnet || true
kubectl rollout restart deployment/lux-stats -n lux-mainnet 2>/dev/null || true
# Deploy testnet & devnet frontends (creates if not exists)
kubectl apply -f deploy/k8s/frontend-testnet.yaml -n lux-testnet || true
kubectl apply -f deploy/k8s/frontend-devnet.yaml -n lux-devnet || true
# Mainnet frontends
for dep in lux-frontend-mainnet lux-frontend-zoo lux-frontend-hanzo lux-frontend-spc lux-frontend-pars; do
kubectl rollout restart deployment/$dep -n lux-mainnet || true
done
# Testnet & devnet frontends
kubectl rollout restart deployment/lux-frontend-testnet -n lux-testnet || true
kubectl rollout restart deployment/lux-frontend-devnet -n lux-devnet || true
# Wait for mainnet rollout
kubectl rollout status deployment/lux-frontend-mainnet -n lux-mainnet --timeout=300s
+2 -1
View File
@@ -23,11 +23,12 @@ on:
- filecoin
- immutable
- mega_eth
- multichain_dev
- multichain_prod
- neon_devnet
- numine
- optimism
- optimism_sepolia
- optimism_superchain
- polygon
- rootstock
- scroll_sepolia
+2 -1
View File
@@ -25,11 +25,12 @@ on:
- main
- mega_eth
- mekong
- multichain_dev
- multichain_prod
- neon_devnet
- numine
- optimism
- optimism_sepolia
- optimism_superchain
- polygon
- rari_testnet
- rootstock
@@ -223,7 +223,7 @@ jobs:
const issues = associatedPullRequests
.nodes
.filter(({ closingIssuesReferences: { nodes: issues } }) => !issues?.some(({ labels }) => labels?.nodes?.some(({ description }) => description.toLowerCase().startsWith('release'))))
.filter(({ closingIssuesReferences: { nodes: issues } }) => !issues?.some(({ labels }) => labels?.nodes?.some(({ description }) => description?.toLowerCase().startsWith('release'))))
.map(({ closingIssuesReferences: { nodes: issues } }) => issues.map(({ number }) => number))
.flat();
+13 -11
View File
@@ -15,18 +15,20 @@ jobs:
contents: read
pull-requests: write
# publish_image:
# image will be published in e2e-tests.yml workflow
# name: Publish Docker image
# uses: './.github/workflows/publish-image.yml'
# secrets: inherit
e2e_tests:
name: Run e2e tests
needs: checks
uses: "./.github/workflows/e2e-tests.yml"
publish_image:
name: Publish Docker image
uses: './.github/workflows/publish-image.yml'
secrets: inherit
permissions: write-all
with:
platforms: linux/amd64
# e2e_tests:
# decided to disable e2e temporarily
# name: Run e2e tests
# needs: checks
# uses: "./.github/workflows/e2e-tests.yml"
# secrets: inherit
# permissions: write-all
version:
name: Pre-release version info
+1 -5
View File
@@ -57,11 +57,7 @@ jobs:
- name: Set image name based on private flag
id: image-name
run: |
if [ "${{ inputs.private }}" = "true" ]; then
echo "image-name=ghcr.io/blockscout/frontend-private" >> $GITHUB_OUTPUT
else
echo "image-name=ghcr.io/blockscout/frontend" >> $GITHUB_OUTPUT
fi
echo "image-name=ghcr.io/luxfi/explore" >> $GITHUB_OUTPUT
# Will automatically make nice tags, see the table here https://github.com/docker/metadata-action#basic
- name: Docker meta
+1
View File
@@ -67,6 +67,7 @@ yarn-error.log*
/tools/preset-sync/index.js
/toolkit/package/dist
license.json
release-prs-data.json
AGENTS.md
CLAUDE.md
+2 -2
View File
@@ -354,12 +354,12 @@
"filecoin",
"mega_eth",
"mekong",
"multichain_dev",
"multichain_prod",
"neon_devnet",
"numine",
"optimism",
"optimism_interop_0",
"optimism_sepolia",
"optimism_superchain",
"polygon",
"rari_testnet",
"rootstock_testnet",
-102
View File
@@ -1,102 +0,0 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
```bash
# Development
yarn dev # Start dev server
yarn build # Production build (Next.js only)
yarn build:next # Full build with asset downloading and sprite building
# Linting
yarn lint:eslint # ESLint check
yarn lint:eslint:fix # ESLint auto-fix
yarn lint:tsc # TypeScript type check
yarn lint:cspell # Spell check
yarn lint:envs-validator:test # Validate environment variable schemas
# Testing
yarn test:vitest # Unit tests (Vitest, matches **/*.spec.ts(x))
yarn test:pw # Playwright component/E2E tests (matches *.pw.tsx)
yarn test:pw:docker # Playwright tests in Docker
# Assets
yarn svg:build-sprite # Rebuild SVG sprite
yarn chakra:typegen # Regenerate Chakra UI types
```
**Requirements:** Node >=22.14.0, npm >=10.9.0
## Architecture
**Stack:** Next.js 15 (Pages Router, not App Router), React 19, Chakra UI v3, React Query 5, Wagmi 2 / Viem 2, Valibot for schema validation, Vitest + Playwright for testing.
**Key directories:**
- `pages/` — Next.js page components (require default exports)
- `ui/` — React UI components organized by feature (~65 subdirectories)
- `lib/` — Business logic, API utilities, custom hooks, context providers
- `toolkit/` — Design system layer: `toolkit/chakra/` (custom Chakra components), `toolkit/theme/` (semantic color tokens), `toolkit/hooks/`
- `configs/app/` — Runtime app configuration (features, API endpoints, UI settings)
- `nextjs/` — Next.js config utilities: headers, rewrites, redirects, type-safe routes via `nextjs-routes`
- `mocks/` — Mock data for tests
- `deploy/tools/envs-validator/` — Environment variable validation schema and tests
**Data flow:** Pages use React Query for server state. Global UI state lives in React Context providers (`AppContextProvider`, `SettingsContextProvider`, etc.) initialized in `pages/_app.tsx`. WebSocket real-time data flows through `SocketProvider`.
**Routing:** Use `nextjs-routes` / `nextjs/routes` utilities for constructing links to application pages — never string concatenation. The full route list is in `nextjs/nextjs-routes.d.ts`.
## Design System Rules
These are enforced by ESLint and must be followed:
- **Always import from `toolkit/chakra/**`** before falling back to native Chakra UI. If a custom version exists in `toolkit/chakra/`, use it.
- **Never use hardcoded colors** (RGB, hex). Use semantic color tokens from `toolkit/theme/foundations/semanticTokens.ts` and `toolkit/theme/foundations/colors.ts` (e.g., `text.secondary`, `border.divider`, `icon.secondary`).
- **No custom `box-shadow`** — use design system shadow tokens.
- Don't override spacing on internal parts of compound components (e.g., don't add custom padding to `DialogHeader` inside a `Dialog`).
- Use `toolkit/chakra/link` instead of `next/link`.
- Use `lib/date/dayjs.ts` instead of importing `dayjs` directly.
- Date/time rendering must use the shared `Time` or `TimeWithTooltip` components.
## Global Type Declarations
- **Never use `(window as any)`** to access third-party globals. Instead, declare the property in `global.d.ts` inside the existing `declare global { interface Window { ... } }` block.
- Use `decs.d.ts` only for untyped third-party module declarations (`declare module 'foo'`).
## TypeScript Conventions
- Prefer `interface` over `type`. Use `interface extends` over `&` intersection (performance).
- No `enum` — use `as const` objects instead.
- Use top-level `import type { Foo }` not inline `import { type Foo }`.
- Default exports only when required by the framework (Next.js pages). All other exports are named.
- Declare return types on top-level module functions.
- `readonly` properties by default; omit only when genuinely mutable.
- Use `satisfies` for type validation instead of `as MyType[]` assertions.
- Outside generic functions, use `any` extremely sparingly; prefer `unknown` with proper narrowing.
- Extract magic numbers as `UPPER_SNAKE_CASE` constants above the component definition.
- Define empty array/object defaults as static constants outside components (not inline `?? []`).
- Wrap `.filter()`, `.map()`, `.reduce()` results in `useMemo` when passed as props or used as hook deps.
- Type parameters in generics are prefixed with `T` (e.g., `TKey`, `TValue`).
## Adding Environment Variables
When adding, renaming, or removing an environment variable, all of the following must be updated:
1. `docs/ENVS.md` — document name, type, whether required, default, and example
2. `configs/app/` — add to the appropriate section (`features/`, `ui.ts`, `api.ts`, etc.)
3. `deploy/tools/envs-validator/schema.ts` — add/update validation schema
4. `deploy/tools/envs-validator/test/.env.base` — add to test presets
5. `nextjs/csp/policies/` — update CSP if the variable references an external (non-asset) URL
6. `deploy/scripts/download_assets.sh` — add to `ASSETS_ENVS` if it's an asset URL
7. If it's a JSON config URL: add example to `deploy/tools/envs-validator/test/assets/configs/` and extend `envsWithJsonConfig` in `deploy/tools/envs-validator/index.ts`
## Testing
**Vitest** (unit): Files named `*.spec.ts` / `*.spec.tsx`. Run a single file with `yarn test:vitest path/to/file.spec.ts`.
**Playwright** (component/E2E): Files named `*.pw.tsx`. Three test projects run against each test: `default` (desktop Chrome 1200×750), `mobile` (iPhone 13 Pro), `dark-color-mode`. Tag tests with `@mobile` or `@dark-mode` to target specific projects; use `-@default` to exclude desktop.
- Use roles, test IDs, and text content as selectors — never CSS class selectors.
- Import mock values from existing files in `mocks/` rather than hardcoding them.
- Avoid the `testFn: TestFixture<...>` pattern unless sharing logic across multiple suites.
+1 -1
View File
@@ -1,4 +1,4 @@
FROM ghcr.io/blockscout/frontend:latest
FROM ghcr.io/luxfi/explore:latest
# LUX Network Branding
ENV NEXT_PUBLIC_NETWORK_NAME="LUX Network" \
+13
View File
@@ -0,0 +1,13 @@
FROM node:22-alpine
WORKDIR /app
COPY .next/standalone ./
COPY .next/static .next/static
COPY public public
COPY scripts/download-external-assets.sh scripts/
COPY scripts/validate-envs.sh scripts/
COPY configs/envs configs/envs
COPY entrypoint.sh .
RUN chmod +x entrypoint.sh scripts/*.sh
ENV PORT=3000 HOSTNAME=0.0.0.0
EXPOSE 3000
ENTRYPOINT ["./entrypoint.sh"]
+12
View File
@@ -0,0 +1,12 @@
steps:
- name: 'gcr.io/kaniko-project/executor:latest'
args:
- '--destination=us-docker.pkg.dev/$PROJECT_ID/backend/explore:white-label'
- '--cache=true'
- '--cache-ttl=168h'
- '--snapshotMode=redo'
- '--use-new-run'
options:
machineType: 'E2_HIGHCPU_32'
diskSizeGb: 100
timeout: '1800s'
+1 -1
View File
@@ -2,7 +2,7 @@ version: '3.8'
services:
frontend:
image: ghcr.io/blockscout/frontend:latest
image: ghcr.io/luxfi/explore:latest
container_name: lux-explorer-frontend
restart: unless-stopped
ports:
+42 -7
View File
@@ -25,7 +25,7 @@ services:
- explorer-network
backend:
image: blockscout/blockscout:latest
image: ghcr.io/luxfi/explorer:latest
container_name: lux-backend
restart: unless-stopped
depends_on:
@@ -48,6 +48,36 @@ services:
networks:
- explorer-network
stats:
image: ghcr.io/luxfi/explorer-stats:latest
container_name: lux-stats
restart: unless-stopped
depends_on:
- backend
- postgres
environment:
STATS__DB_URL: postgresql://blockscout:blockscout@postgres:5432/stats
STATS__BLOCKSCOUT_DB_URL: postgresql://blockscout:blockscout@postgres:5432/blockscout
STATS__CREATE_DATABASE: 'true'
STATS__RUN_MIGRATIONS: 'true'
STATS__SERVER__HTTP__ENABLED: 'true'
STATS__SERVER__HTTP__ADDR: 0.0.0.0:8050
STATS__BLOCKSCOUT_API_URL: http://backend:4000
STATS__FORCE_UPDATE_ON_START: 'true'
ports:
- "8050:8050"
networks:
- explorer-network
visualizer:
image: ghcr.io/luxfi/explorer-visualizer:latest
container_name: lux-visualizer
restart: unless-stopped
ports:
- "8051:8050"
networks:
- explorer-network
frontend:
build:
context: .
@@ -56,6 +86,7 @@ services:
restart: unless-stopped
depends_on:
- backend
- stats
environment:
# Network configuration
NEXT_PUBLIC_NETWORK_NAME: LUX Network
@@ -64,33 +95,37 @@ services:
NEXT_PUBLIC_NETWORK_CURRENCY_NAME: LUX
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL: LUX
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS: 18
# Branding
NEXT_PUBLIC_NETWORK_LOGO: https://docs.lux.network/img/lux-logo-white.png
NEXT_PUBLIC_NETWORK_LOGO_DARK: https://docs.lux.network/img/lux-logo-white.png
NEXT_PUBLIC_NETWORK_ICON: https://docs.lux.network/img/lux-logo-white.png
NEXT_PUBLIC_NETWORK_ICON_DARK: https://docs.lux.network/img/lux-logo-white.png
NEXT_PUBLIC_OG_IMAGE_URL: https://docs.lux.network/img/lux-logo-white.png
# Font configuration
NEXT_PUBLIC_FONT_FAMILY_HEADING: '{"name": "Inter", "url": "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"}'
NEXT_PUBLIC_FONT_FAMILY_BODY: '{"name": "Inter", "url": "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"}'
# Theme configuration
NEXT_PUBLIC_COLOR_THEME_DEFAULT: dark
NEXT_PUBLIC_HOMEPAGE_PLATE_BACKGROUND: black
NEXT_PUBLIC_HOMEPAGE_PLATE_TEXT_COLOR: white
# API configuration
NEXT_PUBLIC_API_HOST: localhost
NEXT_PUBLIC_API_PORT: 4000
NEXT_PUBLIC_API_PROTOCOL: http
NEXT_PUBLIC_API_BASE_PATH: /
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL: ws
# Stats & visualizer
NEXT_PUBLIC_STATS_API_HOST: http://localhost:8050
NEXT_PUBLIC_VISUALIZE_API_HOST: http://localhost:8051
# Network dropdown (all LUX ecosystem networks)
NEXT_PUBLIC_FEATURED_NETWORKS: /networks.json
# Other configurations
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED: 'true'
NEXT_PUBLIC_AUTH_URL: http://localhost:4000
+1 -1
View File
@@ -21,7 +21,7 @@ const app = Object.freeze({
isDev,
isReview,
isPw,
protocol: appSchema,
protocol: appSchema || 'https',
host: appHost,
port: appPort,
baseUrl,
+311 -42
View File
@@ -6,6 +6,24 @@ export interface ChainBranding {
/** Display name in the header (e.g. "Lux Network", "Zoo Chain") */
readonly brandName: string;
/** Organization name for copyright (e.g. "Lux Industries Inc.") */
readonly orgName: string;
/** Primary website URL */
readonly websiteUrl: string;
/** One-line description for footer */
readonly description: string;
/** GitHub org URL */
readonly githubUrl: string;
/** Twitter/X URL */
readonly twitterUrl: string;
/** Discord invite URL */
readonly discordUrl: string;
/** viewBox for the inline logo SVG */
readonly logoViewBox: string;
@@ -20,7 +38,7 @@ export interface ChainEntry {
readonly name: string;
readonly label: string;
readonly vm: string;
readonly network: 'mainnet' | 'testnet' | 'devnet';
readonly network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
readonly hostnames: ReadonlyArray<string>;
readonly explorerUrl: string;
readonly apiUrl: string;
@@ -30,7 +48,7 @@ export interface ChainEntry {
export interface NetworkEntry {
readonly name: string;
readonly label: string;
readonly network: 'mainnet' | 'testnet' | 'devnet';
readonly network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
readonly baseHostname: string;
readonly explorerUrl: string;
}
@@ -41,29 +59,82 @@ export interface NetworkEntry {
/** Lux — downward-pointing triangle (~/work/lux/logo/) */
const LUX_BRANDING: ChainBranding = {
brandName: 'Lux Network',
orgName: 'Lux Industries Inc.',
websiteUrl: 'https://lux.network',
description: 'High-performance blockchain for decentralized applications.',
githubUrl: 'https://github.com/luxfi',
twitterUrl: 'https://x.com/luxdefi',
discordUrl: 'https://discord.gg/luxnetwork',
logoViewBox: '0 0 100 100',
logoContent: '<path d="M50 85 L15 25 L85 25 Z" fill="currentColor"/>',
faviconContent: '<circle cx="256" cy="256" r="256"/><path fill="#fff" d="m256 410 179-308H77z"/>',
};
/** Zoo — three overlapping circles (~/work/zoo/logo/) */
/** Zoo — colorful interlocking circles from ~/work/zoo/logo/ */
const ZOO_BRANDING: ChainBranding = {
brandName: 'Zoo Chain',
logoViewBox: '0 0 64 64',
orgName: 'Zoo Labs Foundation',
websiteUrl: 'https://zoo.ngo',
description: 'Open AI research network — decentralized AI and science.',
githubUrl: 'https://github.com/zoolabs',
twitterUrl: 'https://x.com/zoolabs',
discordUrl: 'https://discord.gg/zoolabs',
logoViewBox: '0 0 1024 1024',
logoContent:
'<circle cx="32" cy="22" r="12" fill="#00A652"/>' +
'<circle cx="21" cy="40" r="12" fill="#ED1C24"/>' +
'<circle cx="43" cy="40" r="12" fill="#2E3192"/>',
'<defs>' +
'<clipPath id="zooClip"><circle cx="512" cy="511" r="270"/></clipPath>' +
'<clipPath id="zooGClip"><circle cx="513" cy="369" r="234"/></clipPath>' +
'<clipPath id="zooRClip"><circle cx="365" cy="595" r="234"/></clipPath>' +
'</defs>' +
'<g clip-path="url(#zooClip)">' +
'<circle cx="513" cy="369" r="234" fill="#00A652"/>' +
'<circle cx="365" cy="595" r="234" fill="#ED1C24"/>' +
'<circle cx="643" cy="595" r="234" fill="#2E3192"/>' +
'<g clip-path="url(#zooGClip)">' +
'<circle cx="365" cy="595" r="234" fill="#FCF006"/>' +
'<circle cx="643" cy="595" r="234" fill="#01ACF1"/>' +
'</g>' +
'<g clip-path="url(#zooRClip)">' +
'<circle cx="643" cy="595" r="234" fill="#EA018E"/>' +
'</g>' +
'<g clip-path="url(#zooGClip)">' +
'<g clip-path="url(#zooRClip)">' +
'<circle cx="643" cy="595" r="234" fill="#FFFFFF"/>' +
'</g></g></g>',
faviconContent:
'<rect width="512" height="512" rx="64" fill="#000"/>' +
'<circle cx="256" cy="176" r="96" fill="#00A652"/>' +
'<circle cx="168" cy="320" r="96" fill="#ED1C24"/>' +
'<circle cx="344" cy="320" r="96" fill="#2E3192"/>',
'<g transform="translate(0,-5) scale(0.5)">' +
'<defs>' +
'<clipPath id="zfClip"><circle cx="512" cy="511" r="270"/></clipPath>' +
'<clipPath id="zfG"><circle cx="513" cy="369" r="234"/></clipPath>' +
'<clipPath id="zfR"><circle cx="365" cy="595" r="234"/></clipPath>' +
'</defs>' +
'<g clip-path="url(#zfClip)">' +
'<circle cx="513" cy="369" r="234" fill="#00A652"/>' +
'<circle cx="365" cy="595" r="234" fill="#ED1C24"/>' +
'<circle cx="643" cy="595" r="234" fill="#2E3192"/>' +
'<g clip-path="url(#zfG)">' +
'<circle cx="365" cy="595" r="234" fill="#FCF006"/>' +
'<circle cx="643" cy="595" r="234" fill="#01ACF1"/>' +
'</g>' +
'<g clip-path="url(#zfR)">' +
'<circle cx="643" cy="595" r="234" fill="#EA018E"/>' +
'</g>' +
'<g clip-path="url(#zfG)">' +
'<g clip-path="url(#zfR)">' +
'<circle cx="643" cy="595" r="234" fill="#FFFFFF"/>' +
'</g></g></g></g>',
};
/** Hanzo — geometric H logo (~/work/hanzo/logo/) */
const HANZO_BRANDING: ChainBranding = {
brandName: 'Hanzo AI',
orgName: 'Hanzo Industries Inc.',
websiteUrl: 'https://hanzo.ai',
description: 'AI blockchain — decentralized compute and inference.',
githubUrl: 'https://github.com/hanzoai',
twitterUrl: 'https://x.com/hanaboratory',
discordUrl: 'https://discord.gg/hanzoai',
logoViewBox: '0 0 67 67',
logoContent:
'<path d="M22.21 67V44.64H0V67H22.21Z" fill="currentColor"/>' +
@@ -85,6 +156,12 @@ const HANZO_BRANDING: ChainBranding = {
/** SPC — unicorn */
const SPC_BRANDING: ChainBranding = {
brandName: 'SPC Chain',
orgName: 'Sparkle Pony Club',
websiteUrl: 'https://sparkleponyclub.com',
description: 'SPC chain.',
githubUrl: 'https://github.com/luxfi',
twitterUrl: 'https://x.com/luxdefi',
discordUrl: 'https://discord.gg/luxnetwork',
logoViewBox: '0 0 64 64',
logoContent:
'<text x="32" y="46" text-anchor="middle" font-size="42" fill="currentColor">&#x1F984;</text>',
@@ -93,28 +170,64 @@ const SPC_BRANDING: ChainBranding = {
'<text x="256" y="350" text-anchor="middle" font-size="320">&#x1F984;</text>',
};
/** Pars — 8-pointed star with gold/blue gradients (~/work/pars/logo/) */
const PARS_STAR_OUTER = 'M0-100 30-60 100-40 60 0 100 40 30 60 0 100-30 60-100 40-60 0-100-40-30-60Z';
const PARS_STAR_INNER = 'M0-65 20-39 65-26 39 0 65 26 20 39 0 65-20 39-65 26-39 0-65-26-20-39Z';
/** Pars — Persian 8-pointed star from ~/work/pars/logo/docs/assets/pars-logo-mono.svg */
const PARS_BRANDING: ChainBranding = {
brandName: 'Pars Network',
orgName: 'Parsis Foundation',
websiteUrl: 'https://pars.network',
description: 'Pars blockchain — financial infrastructure for the Persian-speaking world.',
githubUrl: 'https://github.com/luxfi',
twitterUrl: 'https://x.com/parsnetwork',
discordUrl: 'https://discord.gg/luxnetwork',
logoViewBox: '-120 -120 240 240',
logoContent:
`<path d="${ PARS_STAR_OUTER }" fill="none"` +
' stroke="currentColor" stroke-width="8"/>' +
`<path d="${ PARS_STAR_INNER }" fill="currentColor"/>` +
'<circle r="12" fill="currentColor"/>',
// Outer 8-pointed star
'<path d="M0,-100 L30,-60 L100,-40 L60,0 L100,40 L30,60 L0,100 L-30,60 L-100,40 L-60,0 L-100,-40 L-30,-60 Z"' +
' fill="none" stroke="currentColor" stroke-width="4" stroke-linejoin="round"/>' +
// Inner star
'<path d="M0,-70 L22,-42 L70,-28 L42,0 L70,28 L22,42 L0,70 L-22,42 L-70,28 L-42,0 L-70,-28 L-22,-42 Z"' +
' fill="currentColor" fill-opacity="0.15" stroke="currentColor" stroke-width="3" stroke-linejoin="round"/>' +
// Recursive inner star
'<path d="M0,-45 L14,-27 L45,-18 L27,0 L45,18 L14,27 L0,45 L-14,27 L-45,18 L-27,0 L-45,-18 L-14,-27 Z"' +
' fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round" opacity="0.6"/>' +
// Interlaced circles
'<circle r="55" fill="none" stroke="currentColor" stroke-width="1.5" opacity="0.4"/>' +
'<circle r="35" fill="none" stroke="currentColor" stroke-width="1.5" opacity="0.4"/>' +
// Center rosette
'<circle r="8" fill="currentColor"/>' +
'<path d="M0,-20 L6,-6 L20,0 L6,6 L0,20 L-6,6 L-20,0 L-6,-6 Z"' +
' fill="none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round" opacity="0.8"/>',
faviconContent:
'<rect width="512" height="512" rx="64" fill="#003355"/>' +
'<rect width="512" height="512" rx="64" fill="#000"/>' +
'<g transform="translate(256,256) scale(2)">' +
`<path d="${ PARS_STAR_OUTER }" fill="none"` +
' stroke="#f5d06f" stroke-width="8"/>' +
`<path d="${ PARS_STAR_INNER }"` +
' fill="#00abff" stroke="#f5d06f" stroke-width="6"/>' +
'<circle r="12" fill="#f5d06f"/></g>',
'<path d="M0,-100 L30,-60 L100,-40 L60,0 L100,40 L30,60 L0,100 L-30,60 L-100,40 L-60,0 L-100,-40 L-30,-60 Z"' +
' fill="none" stroke="#fff" stroke-width="4" stroke-linejoin="round"/>' +
'<path d="M0,-70 L22,-42 L70,-28 L42,0 L70,28 L22,42 L0,70 L-22,42 L-70,28 L-42,0 L-70,-28 L-22,-42 Z"' +
' fill="#fff" fill-opacity="0.15" stroke="#fff" stroke-width="3" stroke-linejoin="round"/>' +
'<path d="M0,-45 L14,-27 L45,-18 L27,0 L45,18 L14,27 L0,45 L-14,27 L-45,18 L-27,0 L-45,-18 L-14,-27 Z"' +
' fill="none" stroke="#fff" stroke-width="2" stroke-linejoin="round" opacity="0.6"/>' +
'<circle r="55" fill="none" stroke="#fff" stroke-width="1.5" opacity="0.4"/>' +
'<circle r="35" fill="none" stroke="#fff" stroke-width="1.5" opacity="0.4"/>' +
'<circle r="8" fill="#fff"/>' +
'<path d="M0,-20 L6,-6 L20,0 L6,6 L0,20 L-6,6 L-20,0 L-6,-6 Z"' +
' fill="none" stroke="#fff" stroke-width="1.5" stroke-linejoin="round" opacity="0.8"/>' +
'</g>',
};
/** Liquidity — wordmark "L" from ~/work/liquidity/brand/ */
const LIQUIDITY_BRANDING: ChainBranding = {
brandName: 'Liquidity Network',
orgName: 'Liquidity Inc.',
websiteUrl: 'https://',
description: 'Digital securities exchange — ATS, broker-dealer, transfer agent.',
githubUrl: 'https://github.com/',
twitterUrl: 'https://x.com/',
discordUrl: 'https://discord.gg/',
logoViewBox: '0 0 100 100',
logoContent: '<path d="M30 20 L30 80 L70 80 L70 65 L45 65 L45 20 Z" fill="currentColor"/>',
faviconContent:
'<rect width="512" height="512" rx="64" fill="#000"/>' +
'<path d="M155 100 L155 410 L360 410 L360 340 L230 340 L230 100 Z" fill="#fff"/>',
};
export const CHAINS: ReadonlyArray<ChainEntry> = [
@@ -123,7 +236,9 @@ export const CHAINS: ReadonlyArray<ChainEntry> = [
label: 'Contract Chain',
vm: 'EVM',
network: 'mainnet',
hostnames: [ 'explore.lux.network', 'localhost' ],
// explore.lux.build is a legacy alias — the runtime ingress 301-redirects
// it to explore.lux.network, so we only register the canonical host here.
hostnames: [ 'explore.lux.network', 'localhost', '127.0.0.1', '0.0.0.0' ],
explorerUrl: 'https://explore.lux.network',
apiUrl: 'https://api-explore.lux.network',
branding: LUX_BRANDING,
@@ -131,9 +246,9 @@ export const CHAINS: ReadonlyArray<ChainEntry> = [
{
name: 'Zoo',
label: 'Zoo Chain',
vm: 'Subnet EVM',
vm: 'L2',
network: 'mainnet',
hostnames: [ 'explore-zoo.lux.network' ],
hostnames: [ 'explore-zoo.lux.network', 'explore.zoo.network', 'explore.zoo.ngo' ],
explorerUrl: 'https://explore-zoo.lux.network',
apiUrl: 'https://api-explore-zoo.lux.network',
branding: ZOO_BRANDING,
@@ -141,9 +256,9 @@ export const CHAINS: ReadonlyArray<ChainEntry> = [
{
name: 'Hanzo',
label: 'Hanzo AI',
vm: 'Subnet EVM',
vm: 'L2',
network: 'mainnet',
hostnames: [ 'explore-hanzo.lux.network' ],
hostnames: [ 'explore-hanzo.lux.network', 'explore.hanzo.network', 'explore.hanzo.ai' ],
explorerUrl: 'https://explore-hanzo.lux.network',
apiUrl: 'https://api-explore-hanzo.lux.network',
branding: HANZO_BRANDING,
@@ -151,7 +266,7 @@ export const CHAINS: ReadonlyArray<ChainEntry> = [
{
name: 'SPC',
label: 'SPC Chain',
vm: 'Subnet EVM',
vm: 'L2',
network: 'mainnet',
hostnames: [ 'explore-spc.lux.network' ],
explorerUrl: 'https://explore-spc.lux.network',
@@ -161,35 +276,89 @@ export const CHAINS: ReadonlyArray<ChainEntry> = [
{
name: 'Pars',
label: 'Pars Network',
vm: 'Subnet EVM',
vm: 'L2',
network: 'mainnet',
hostnames: [ 'explore-pars.lux.network' ],
hostnames: [ 'explore-pars.lux.network', 'explore.pars.network' ],
explorerUrl: 'https://explore-pars.lux.network',
apiUrl: 'https://api-explore-pars.lux.network',
branding: PARS_BRANDING,
},
{
name: 'Liquidity',
label: 'Liquidity Network',
vm: '',
network: 'mainnet',
hostnames: [ 'explore.', 'explore.' ],
explorerUrl: 'https://explore.',
apiUrl: 'https://api-explore.',
branding: LIQUIDITY_BRANDING,
},
// Testnet chains
{
name: 'C-Chain',
label: 'Contract Chain',
vm: 'EVM',
network: 'testnet',
hostnames: [ 'explore.lux-test.network' ],
explorerUrl: 'https://explore.lux-test.network',
apiUrl: 'https://api-explore.lux-test.network',
hostnames: [ 'explore-test.lux.network', 'explore.lux-test.network' ],
explorerUrl: 'https://explore-test.lux.network',
apiUrl: 'https://api-explore-test.lux.network',
branding: LUX_BRANDING,
},
{
name: 'Liquidity',
label: 'Liquidity Network',
vm: '',
network: 'testnet',
hostnames: [ 'explore.test.' ],
explorerUrl: 'https://explore.test.',
apiUrl: 'https://api-explore.test.',
branding: LIQUIDITY_BRANDING,
},
// Devnet chains
{
name: 'C-Chain',
label: 'Contract Chain',
vm: 'EVM',
network: 'devnet',
hostnames: [ 'explore.lux-dev.network' ],
explorerUrl: 'https://explore.lux-dev.network',
apiUrl: 'https://api-explore.lux-dev.network',
hostnames: [ 'explore-dev.lux.network', 'explore.lux-dev.network' ],
explorerUrl: 'https://explore-dev.lux.network',
apiUrl: 'https://api-explore-dev.lux.network',
branding: LUX_BRANDING,
},
{
name: 'Liquidity',
label: 'Liquidity Network',
vm: '',
network: 'devnet',
hostnames: [ 'explore.dev.' ],
explorerUrl: 'https://explore.dev.',
apiUrl: 'https://api-explore.dev.',
branding: LIQUIDITY_BRANDING,
},
// Localnet — chainId 1337 (Lux) / 8675312 (Liquidity). Listing localhost /
// 127.0.0.1 / 0.0.0.0 here keeps isWhiteLabelMode() false in local dev so
// the chain + network selectors remain visible without env gymnastics.
{
name: 'C-Chain',
label: 'Contract Chain',
vm: 'EVM',
network: 'localnet',
hostnames: [ 'explore.localnet', 'explore-local.lux.network' ],
explorerUrl: 'http://localhost:3000',
apiUrl: 'http://localhost:4000',
branding: LUX_BRANDING,
},
{
name: 'Liquidity',
label: 'Liquidity Network',
vm: '',
network: 'localnet',
hostnames: [ 'explore.local.', 'explore.local.' ],
explorerUrl: 'http://explore.local.',
apiUrl: 'http://api-explore.local.',
branding: LIQUIDITY_BRANDING,
},
];
export const NETWORKS: ReadonlyArray<NetworkEntry> = [
@@ -214,27 +383,127 @@ export const NETWORKS: ReadonlyArray<NetworkEntry> = [
baseHostname: 'explore.lux-dev.network',
explorerUrl: 'https://explore.lux-dev.network',
},
{
name: 'Localnet',
label: 'Local development (chainId 1337)',
network: 'localnet',
baseHostname: 'localhost',
explorerUrl: 'http://localhost:3000',
},
];
import { getEnvValue } from 'configs/app/utils';
// ── White-label support ──
// When the hostname doesn't match any known chain, build branding from env vars.
// This allows a single Docker image to serve any EVM chain.
function buildWhiteLabelBranding(): ChainBranding {
return {
brandName: getEnvValue('NEXT_PUBLIC_NETWORK_NAME') || '▼ Explorer',
orgName: getEnvValue('NEXT_PUBLIC_NETWORK_ORG_NAME') || '',
websiteUrl: getEnvValue('NEXT_PUBLIC_NETWORK_WEBSITE_URL') || '',
description: getEnvValue('NEXT_PUBLIC_NETWORK_DESCRIPTION') || 'Blockchain explorer.',
githubUrl: getEnvValue('NEXT_PUBLIC_NETWORK_GITHUB_URL') || '',
twitterUrl: getEnvValue('NEXT_PUBLIC_NETWORK_TWITTER_URL') || '',
discordUrl: getEnvValue('NEXT_PUBLIC_NETWORK_DISCORD_URL') || '',
logoViewBox: '0 0 100 100',
logoContent: '<circle cx="50" cy="50" r="40" fill="currentColor"/>',
faviconContent: '<circle cx="256" cy="256" r="256"/>',
};
}
function buildWhiteLabelChain(hostname: string): ChainEntry {
const branding = buildWhiteLabelBranding();
const appHost = getEnvValue('NEXT_PUBLIC_APP_HOST') || hostname;
const apiHost = getEnvValue('NEXT_PUBLIC_API_HOST') || '';
const protocol = getEnvValue('NEXT_PUBLIC_APP_PROTOCOL') || 'https';
const apiProtocol = getEnvValue('NEXT_PUBLIC_API_PROTOCOL') || 'https';
return {
name: getEnvValue('NEXT_PUBLIC_NETWORK_SHORT_NAME') || branding.brandName,
label: branding.brandName,
vm: 'EVM',
network: (getEnvValue('NEXT_PUBLIC_IS_TESTNET') === 'true' ? 'testnet' : 'mainnet') as 'mainnet' | 'testnet' | 'devnet' | 'localnet',
hostnames: [ hostname ],
explorerUrl: `${ protocol }://${ appHost }`,
apiUrl: apiHost ? `${ apiProtocol }://${ apiHost }` : '',
branding,
};
}
function getHostname(): string {
// Client: trust the browser — this is the request origin.
if (typeof window !== 'undefined') {
return window.location.hostname;
}
// Server: prefer the per-request Host header captured in AsyncLocalStorage
// at the start of each SSR render (see pages/_document.tsx). This keeps the
// FE stateless — one docker image serves any hostname. Fall back to the
// build-time env only when called outside a request (static prerender,
// health checks, etc.).
try {
// Lazy require so browser bundles don't pick up the ALS module.
// eslint-disable-next-line @typescript-eslint/no-var-requires, global-require
const { getRequestHost } = require('lib/requestHost') as { getRequestHost: () => string };
const reqHost = getRequestHost();
if (reqHost) return reqHost;
} catch {
// Falls through to env fallback.
}
return getEnvValue('NEXT_PUBLIC_APP_HOST') || 'explore.lux.network';
}
export function isWhiteLabelMode(): boolean {
const hostname = getHostname();
return !CHAINS.some((c) => c.hostnames.includes(hostname));
}
export function isChainSelectorEnabled(): boolean {
const envVal = getEnvValue('NEXT_PUBLIC_CHAIN_SELECTOR_ENABLED');
if (envVal !== undefined && envVal !== '') {
return envVal === 'true';
}
// Disabled by default in white-label mode
return !isWhiteLabelMode();
}
export function isNetworkSelectorEnabled(): boolean {
const envVal = getEnvValue('NEXT_PUBLIC_NETWORK_SELECTOR_ENABLED');
if (envVal !== undefined && envVal !== '') {
return envVal === 'true';
}
// Disabled by default in white-label mode
return !isWhiteLabelMode();
}
export function getCurrentChain(): ChainEntry {
const hostname = getHostname();
return CHAINS.find((c) => c.hostnames.includes(hostname)) ?? CHAINS[0];
const found = CHAINS.find((c) => c.hostnames.includes(hostname));
if (found) {
return found;
}
// White-label mode: build from env vars
return buildWhiteLabelChain(hostname);
}
export function getCurrentNetwork(): NetworkEntry {
const chain = getCurrentChain();
if (isWhiteLabelMode()) {
// In white-label mode, return a single network entry from env vars
const branding = buildWhiteLabelBranding();
const appHost = getEnvValue('NEXT_PUBLIC_APP_HOST') || '';
const protocol = getEnvValue('NEXT_PUBLIC_APP_PROTOCOL') || 'https';
return {
name: chain.network === 'testnet' ? 'Testnet' : 'Mainnet',
label: branding.brandName,
network: chain.network,
baseHostname: appHost,
explorerUrl: appHost ? `${ protocol }://${ appHost }` : '',
};
}
return NETWORKS.find((n) => n.network === chain.network) ?? NETWORKS[0];
}
export function getChainsForNetwork(network: 'mainnet' | 'testnet' | 'devnet'): ReadonlyArray<ChainEntry> {
export function getChainsForNetwork(network: 'mainnet' | 'testnet' | 'devnet' | 'localnet'): ReadonlyArray<ChainEntry> {
return CHAINS.filter((c) => c.network === network);
}
+16
View File
@@ -7,6 +7,17 @@ import { getEnvValue } from '../utils';
const title = 'My account';
const apiKeysButton = (() => {
const value = getEnvValue('NEXT_PUBLIC_ACCOUNT_API_KEYS_BUTTON');
if (value === undefined || value === 'true') {
return true;
}
if (value === 'false') {
return false;
}
return value;
})();
const config: Feature<{
isEnabled: true;
authProvider: AuthProvider;
@@ -17,6 +28,7 @@ const config: Feature<{
serverUrl: string;
clientId: string;
};
apiKeysButton: boolean | string;
}> = (() => {
if (
@@ -36,6 +48,7 @@ const config: Feature<{
dynamic: {
environmentId: dynamicEnvironmentId,
},
apiKeysButton,
});
}
@@ -48,6 +61,7 @@ const config: Feature<{
serverUrl: oidcServerUrl,
clientId: oidcClientId,
},
apiKeysButton,
});
}
@@ -56,6 +70,7 @@ const config: Feature<{
title,
isEnabled: true,
authProvider: 'auth0',
apiKeysButton,
});
}
@@ -69,6 +84,7 @@ const config: Feature<{
serverUrl: oidcServerUrl,
clientId: oidcClientId,
},
apiKeysButton,
});
}
}
+19 -1
View File
@@ -5,6 +5,18 @@ import type { AdTextProviders } from 'types/client/adProviders';
import app from '../app';
import { getEnvValue } from '../utils';
const SEVIO_ZONE = '179b0a0e-19b0-4b2a-ad15-7446870bf189';
const SEVIO_INVENTORY_ID = '65597ae2-67b8-404b-ac28-43d5029389da';
const SEVIO_ACCOUNT_ID = 'e08c2e1e-2213-49d8-a397-c2e32094fba4';
const SEVIO_AD_TYPE = 'native';
interface SevioConfig {
readonly zone: string;
readonly inventoryId: string;
readonly accountId: string;
readonly adType: string;
}
const provider: AdTextProviders = (() => {
const envValue = getEnvValue('NEXT_PUBLIC_AD_TEXT_PROVIDER') as AdTextProviders;
// Lux fork: disable ads by default
@@ -13,12 +25,18 @@ const provider: AdTextProviders = (() => {
const title = 'Text ads';
const config: Feature<{ provider: AdTextProviders }> = (() => {
const config: Feature<{ provider: AdTextProviders; sevio: SevioConfig }> = (() => {
if (!app.isPrivateMode && provider !== 'none') {
return Object.freeze({
title,
isEnabled: true,
provider,
sevio: {
zone: SEVIO_ZONE,
inventoryId: SEVIO_INVENTORY_ID,
accountId: SEVIO_ACCOUNT_ID,
adType: SEVIO_AD_TYPE,
},
});
}
+2 -1
View File
@@ -15,7 +15,7 @@ const title = 'API documentation';
const config: Feature<{
tabs: Array<ApiDocsTabId>;
coreApiSwaggerUrl: string;
alertMessage: string | undefined;
}> = (() => {
if (tabs) {
return Object.freeze({
@@ -23,6 +23,7 @@ const config: Feature<{
isEnabled: true,
tabs,
coreApiSwaggerUrl: getEnvValue('NEXT_PUBLIC_API_SPEC_URL') || `https://raw.githubusercontent.com/luxfi/explorer-api-swagger/main/swagger.yaml`,
alertMessage: getEnvValue('NEXT_PUBLIC_API_DOCS_ALERT_MESSAGE'),
});
}
@@ -4,7 +4,7 @@ import app from '../app';
import chain from '../chain';
import { getEnvValue, parseEnvJson } from '../utils';
import accountFeature from './account';
import opSuperchain from './opSuperchain';
import multichain from './multichain';
const walletConnectProjectId = getEnvValue('NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID');
@@ -31,11 +31,11 @@ const config: Feature<FeaturePayload> = (() => {
chain.rpcUrls.length > 0,
);
const isOpSuperchain = opSuperchain.isEnabled;
const isMultichain = multichain.isEnabled;
if (
!app.isPrivateMode &&
(isSingleChain || isOpSuperchain)
(isSingleChain || isMultichain)
) {
if (accountFeature.isEnabled && accountFeature.authProvider === 'dynamic' && accountFeature.dynamic?.environmentId) {
return Object.freeze({
-25
View File
@@ -1,25 +0,0 @@
import type { Feature } from './types';
import app from '../app';
import { getEnvValue } from '../utils';
const clientKey = getEnvValue('NEXT_PUBLIC_GROWTH_BOOK_CLIENT_KEY');
const title = 'GrowthBook feature flagging and A/B testing';
const config: Feature<{ clientKey: string }> = (() => {
if (!app.isPrivateMode && clientKey) {
return Object.freeze({
title,
isEnabled: true,
clientKey,
});
}
return Object.freeze({
title,
isEnabled: false,
});
})();
export default config;
+1 -3
View File
@@ -22,23 +22,21 @@ export { default as flashblocks } from './flashblocks';
export { default as gasTracker } from './gasTracker';
export { default as getGasButton } from './getGasButton';
export { default as googleAnalytics } from './googleAnalytics';
export { default as growthBook } from './growthBook';
export { default as hotContracts } from './hotContracts';
export { default as marketplace } from './marketplace';
export { default as megaEth } from './megaEth';
export { default as metasuites } from './metasuites';
export { default as mixpanel } from './mixpanel';
export { default as mudFramework } from './mudFramework';
export { default as multichain } from './multichain';
export { default as multichainButton } from './multichainButton';
export { default as nameServices } from './nameServices';
export { default as opSuperchain } from './opSuperchain';
export { default as pools } from './pools';
export { default as publicTagsSubmission } from './publicTagsSubmission';
export { default as rewards } from './rewards';
export { default as rollbar } from './rollbar';
export { default as rollup } from './rollup';
export { default as safe } from './safe';
export { default as saveOnGas } from './saveOnGas';
export { default as sol2uml } from './sol2uml';
export { default as stats } from './stats';
export { default as suave } from './suave';
@@ -6,12 +6,7 @@ import { getEnvValue } from '../utils';
const isEnabled = getEnvValue('NEXT_PUBLIC_MULTICHAIN_ENABLED') === 'true';
const cluster = getEnvValue('NEXT_PUBLIC_MULTICHAIN_CLUSTER');
// The feature was initially implemented for OP Superchain interop cluster
// but later the project was abandoned by Optimism team.
// Now it serves mainly for demo purposes of multichain explorer possible functionalities.
// So for now I have kept all naming in the code as it was initially done
// and later it could be changed when specific multichain cluster will be implemented.
const title = 'OP Superchain interop explorer';
const title = 'Multichain explorer';
const config: Feature<{ cluster: string }> = (() => {
if (apis.multichainAggregator && apis.multichainStats && isEnabled && cluster) {
+1 -1
View File
@@ -10,7 +10,7 @@ const instance = (() => {
return envValue;
}
return app.host?.replace('.lux.network', '').replace('.blockscout.com', '').replace('.k8s-dev', '').replaceAll('-', '_');
return app.host?.replace('.lux.network', '').replace('.lux.network', '').replace('.k8s-dev', '').replaceAll('-', '_');
})();
const environment = getEnvValue('NEXT_PUBLIC_APP_ENV') || 'production';
const codeVersion = getEnvValue('NEXT_PUBLIC_GIT_TAG') || getEnvValue('NEXT_PUBLIC_GIT_COMMIT_SHA');
+4 -4
View File
@@ -15,15 +15,13 @@ const L2WithdrawalUrl = getEnvValue('NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL');
const parentChain: ParentChain | undefined = (() => {
const envValue = parseEnvJson<ParentChain>(getEnvValue('NEXT_PUBLIC_ROLLUP_PARENT_CHAIN'));
const baseUrl = stripTrailingSlash(getEnvValue('NEXT_PUBLIC_ROLLUP_L1_BASE_URL') || '');
if (!baseUrl && !envValue?.baseUrl) {
if (!envValue?.baseUrl) {
return;
}
return {
...envValue,
baseUrl: baseUrl || envValue?.baseUrl || '',
baseUrl: stripTrailingSlash(envValue.baseUrl),
};
})();
@@ -32,6 +30,7 @@ const title = 'Rollup (L2) chain';
const config: Feature<{
type: RollupType;
stageIndex: string | undefined;
layerNumber: number;
homepage: { showLatestBlocks: boolean };
outputRootsEnabled: boolean;
interopEnabled: boolean;
@@ -50,6 +49,7 @@ const config: Feature<{
isEnabled: true,
type,
stageIndex: getEnvValue('NEXT_PUBLIC_ROLLUP_STAGE_INDEX'),
layerNumber: Number(getEnvValue('NEXT_PUBLIC_ROLLUP_LAYER_NUMBER') || 2),
L2WithdrawalUrl: type === 'optimistic' ? L2WithdrawalUrl : undefined,
outputRootsEnabled: type === 'optimistic' && getEnvValue('NEXT_PUBLIC_ROLLUP_OUTPUT_ROOTS_ENABLED') === 'true',
interopEnabled: type === 'optimistic' && getEnvValue('NEXT_PUBLIC_INTEROP_ENABLED') === 'true',
-25
View File
@@ -1,25 +0,0 @@
import type { Feature } from './types';
import { getEnvValue } from '../utils';
import marketplace from './marketplace';
const title = 'Save on gas with GasHawk';
const config: Feature<{
apiUrlTemplate: string;
}> = (() => {
if (getEnvValue('NEXT_PUBLIC_SAVE_ON_GAS_ENABLED') === 'true' && marketplace.isEnabled) {
return Object.freeze({
title,
isEnabled: true,
apiUrlTemplate: 'https://core.gashawk.io/apiv2/stats/address/<address>/savingsPotential/0x1',
});
}
return Object.freeze({
title,
isEnabled: false,
});
})();
export default config;
+2 -2
View File
@@ -1,12 +1,12 @@
import type { Feature } from './types';
import apis from '../apis';
import opSuperchain from './opSuperchain';
import multichain from './multichain';
const title = 'Blockchain statistics';
const config: Feature<{}> = (() => {
if (apis.stats || opSuperchain.isEnabled) {
if (apis.stats || multichain.isEnabled) {
return Object.freeze({
title,
isEnabled: true,
+12
View File
@@ -1,7 +1,19 @@
import { getEnvValue } from 'configs/app/utils';
const TEST_TOKEN_ADDRESSES: ReadonlySet<string> = new Set([
// UsdCoin (USDC) — test/fake deployments
'0x3569c06a80c148d7b4b67f8a06125f6d59774243',
'0x8031e9b0d02a792cfefaa2bdca6e1289d385426f',
'0xa85eb8e163f4d70bfc43a4f3fcc9a8dfc42b1ae4',
// Tether (USDT) — test/fake deployments
'0x724f4ef0400386fc8c1011788af733bd367ac00f',
'0x79608e442d046ea6d3125931a33ce971ad99c6f9',
'0xdf1de693c31e2a5eb869c329529623556b20abf3',
]);
const config = Object.freeze({
hideScamTokensEnabled: getEnvValue('NEXT_PUBLIC_VIEWS_TOKEN_SCAM_TOGGLE_ENABLED') === 'true',
testTokenAddresses: TEST_TOKEN_ADDRESSES,
});
export default config;
+1 -3
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=arbitrum.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS=[{'text':'Swap','icon':'swap','url':'https://arbitrum.blockscout.com/essential-dapps/swap?utm_source=defi-dropdown&utm_medium=swap'},{'text':'Revoke','icon':'integration/partial','dappId':'revokescout'}, {'text': 'Multisend', 'icon': 'token', 'url': 'https://arbitrum.blockscout.com/essential-dapps/multisend?utm_source=defi-dropdown-multisend&utm_medium=multisend'}]
@@ -33,7 +32,7 @@ NEXT_PUBLIC_MAINTENANCE_ALERT_MESSAGE=<p>Launch your own fully functioning block
NEXT_PUBLIC_MARKETPLACE_BANNER_CONTENT_URL=https://gist.githubusercontent.com/0xdeval/1a7395339d20b603b9c1d0ee929f23dc/raw/55e2eebef3ba3ef064842d15555b59d5ba8cbcc7/badges-banner.html
NEXT_PUBLIC_MARKETPLACE_BANNER_LINK_URL=https://badges.blockscout.com/badges-list?utm_source=blockscout-explorer&utm_medium=marketplace-banner
NEXT_PUBLIC_MARKETPLACE_ENABLED=true
NEXT_PUBLIC_MARKETPLACE_ESSENTIAL_DAPPS_CONFIG={'swap': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '1923', '42793', '59144'], 'fee': '0.004', 'integrator': 'blockscout'}, 'multisend': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '59144', '7000'], 'posthogKey': 'phc_7O4WGsecqqDO1PeaKayHAxUWN1PjheOmQCiDxEMcmkx', 'posthogHost': 'https://us.i.posthog.com'}}
NEXT_PUBLIC_MARKETPLACE_ESSENTIAL_DAPPS_CONFIG={'swap': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '1923', '42793', '59144'], 'fee': '0.004', 'integrator': 'blockscout'}, 'multisend': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '59144', '7000'], 'insightsKey': 'phc_7O4WGsecqqDO1PeaKayHAxUWN1PjheOmQCiDxEMcmkx', 'insightsHost': 'https://insights.hanzo.ai'}}
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://airtable.com/appiy5yijZpMMSKjT/shr6uMGPKjj1DK7NL
NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM=https://airtable.com/appiy5yijZpMMSKjT/pag3t82DUCyhGRZZO/form
NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com
@@ -56,7 +55,6 @@ NEXT_PUBLIC_NETWORK_RPC_URL=https://arbitrum-one.publicnode.com
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/arbitrum-one.png
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com','currency':{'name':'Ether','symbol':'ETH','decimals':18},'isTestnet':false,'id':1,'name':'Ethereum Mainnet','rpcUrls':['https://eth.drpc.org']}
NEXT_PUBLIC_ROLLUP_STAGE_INDEX=1
NEXT_PUBLIC_ROLLUP_TYPE=arbitrum
+1 -2
View File
@@ -13,7 +13,6 @@ NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=ws
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=arbitrum-nova.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs']
@@ -32,8 +31,8 @@ NEXT_PUBLIC_NETWORK_RPC_URL=https://arbitrum.llamarpc.com
NEXT_PUBLIC_NETWORK_SHORT_NAME=Arbitrum Nova
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/arbitrum-nova.png
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com
NEXT_PUBLIC_ROLLUP_TYPE=arbitrum
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com'}
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=blockscout
NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED=true
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
-2
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=arbitrum-sepolia.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/arbitrum-sepolia.json
@@ -45,7 +44,6 @@ NEXT_PUBLIC_NETWORK_RPC_URL=https://sepolia-rollup.arbitrum.io/rpc
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/arbitrum-sepolia.png
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth-sepolia.blockscout.com
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth-sepolia.blockscout.com','currency':{'name':'Ether','symbol':'ETH','decimals':18},'isTestnet':true,'id':11155111,'name':'Sepolia','rpcUrls':['https://eth-sepolia.public.blastapi.io']}
NEXT_PUBLIC_ROLLUP_TYPE=arbitrum
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
+2 -3
View File
@@ -17,7 +17,6 @@ NEXT_PUBLIC_ADDRESS_USERNAME_TAG={'api_url_template': 'https://api.zora.co/disco
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=base.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS=[{'text':'Swap','icon':'swap','url':'https://base.blockscout.com/essential-dapps/swap?utm_source=defi-dropdown&utm_medium=swap'},{'text':'Revoke','icon':'integration/partial','dappId':'revokescout'}, {'text': 'Multisend', 'icon': 'token', 'url': 'https://base.blockscout.com/essential-dapps/multisend?utm_source=defi-dropdown-multisend&utm_medium=multisend'}]
@@ -41,7 +40,7 @@ NEXT_PUBLIC_MARKETPLACE_BANNER_CONTENT_URL=https://gist.githubusercontent.com/0x
NEXT_PUBLIC_MARKETPLACE_BANNER_LINK_URL=https://badges.blockscout.com/badges-list?utm_source=blockscout-explorer&utm_medium=marketplace-banner
NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-categories/default.json
NEXT_PUBLIC_MARKETPLACE_ENABLED=true
NEXT_PUBLIC_MARKETPLACE_ESSENTIAL_DAPPS_CONFIG={'swap': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '1923', '42793', '59144'], 'fee': '0.004', 'integrator': 'blockscout'}, 'multisend': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '59144', '7000'], 'posthogKey': 'phc_7O4WGsecqqDO1PeaKayHAxUWN1PjheOmQCiDxEMcmkx', 'posthogHost': 'https://us.i.posthog.com'}}
NEXT_PUBLIC_MARKETPLACE_ESSENTIAL_DAPPS_CONFIG={'swap': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '1923', '42793', '59144'], 'fee': '0.004', 'integrator': 'blockscout'}, 'multisend': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '59144', '7000'], 'insightsKey': 'phc_7O4WGsecqqDO1PeaKayHAxUWN1PjheOmQCiDxEMcmkx', 'insightsHost': 'https://insights.hanzo.ai'}}
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://airtable.com/appiy5yijZpMMSKjT/shr6uMGPKjj1DK7NL
NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM=https://airtable.com/appiy5yijZpMMSKjT/pag3t82DUCyhGRZZO/form
NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com
@@ -68,7 +67,7 @@ NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/base-mainnet.png
NEXT_PUBLIC_OTHER_LINKS=[{'url':'https://base.drpc.org?ref=559183','text':'Public RPC'}]
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com'}
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://bridge.base.org/withdraw
NEXT_PUBLIC_ROLLUP_STAGE_INDEX=1
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
-1
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=testnet.blackfortscan.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/blackfort-testnet.json
+2 -3
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=celo.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CELO_ENABLED=true
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
@@ -35,7 +34,7 @@ NEXT_PUBLIC_MARKETPLACE_BANNER_CONTENT_URL=https://gist.githubusercontent.com/0x
NEXT_PUBLIC_MARKETPLACE_BANNER_LINK_URL=https://badges.blockscout.com/badges-list?utm_source=blockscout-explorer&utm_medium=marketplace-banner
NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-categories/default.json
NEXT_PUBLIC_MARKETPLACE_ENABLED=true
NEXT_PUBLIC_MARKETPLACE_ESSENTIAL_DAPPS_CONFIG={'swap': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '1923', '42793', '59144'], 'fee': '0.004', 'integrator': 'blockscout'}, 'multisend': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '59144', '7000'], 'posthogKey': 'phc_7O4WGsecqqDO1PeaKayHAxUWN1PjheOmQCiDxEMcmkx', 'posthogHost': 'https://us.i.posthog.com'}}
NEXT_PUBLIC_MARKETPLACE_ESSENTIAL_DAPPS_CONFIG={'swap': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '1923', '42793', '59144'], 'fee': '0.004', 'integrator': 'blockscout'}, 'multisend': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '59144', '7000'], 'insightsKey': 'phc_7O4WGsecqqDO1PeaKayHAxUWN1PjheOmQCiDxEMcmkx', 'insightsHost': 'https://insights.hanzo.ai'}}
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://airtable.com/appiy5yijZpMMSKjT/shr6uMGPKjj1DK7NL
NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM=https://airtable.com/appiy5yijZpMMSKjT/pag3t82DUCyhGRZZO/form
NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com
@@ -56,7 +55,7 @@ NEXT_PUBLIC_NETWORK_SHORT_NAME=Mainnet
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/celo.png
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com'}
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://mondo.celo.org/bridge
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
-1
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=celo-sepolia.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CELO_ENABLED=true
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
+4 -4
View File
@@ -19,7 +19,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=eth.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_BEACON_CHAIN_VALIDATOR_URL_TEMPLATE=https://beaconcha.in/validator/{pk}
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
@@ -42,7 +41,7 @@ NEXT_PUBLIC_MARKETPLACE_BANNER_CONTENT_URL=https://gist.githubusercontent.com/ma
NEXT_PUBLIC_MARKETPLACE_BANNER_LINK_URL=https://eth.blockscout.com/apps/revokescout?chainId=1
NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-categories/default.json
NEXT_PUBLIC_MARKETPLACE_ENABLED=true
NEXT_PUBLIC_MARKETPLACE_ESSENTIAL_DAPPS_CONFIG={'swap': {'url': 'https://swapscout.vercel.app', 'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '1923', '42793', '59144'], 'fee': '0.004', 'integrator': 'blockscout'}, 'multisend': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '59144', '7000'], 'posthogKey': 'phc_7O4WGsecqqDO1PeaKayHAxUWN1PjheOmQCiDxEMcmkx', 'posthogHost': 'https://us.i.posthog.com'}, 'revoke': {'chains': ['1', '10', '30', '100', '122', '130', '324', '480', '8453', '13371', '42161', '42220', '57073', '534352', '1868', '7887', '1514', '245022934', '61', '148', '314', '137', '7000', '42793', '4326']}}
NEXT_PUBLIC_MARKETPLACE_ESSENTIAL_DAPPS_CONFIG={'swap': {'url': 'https://swapscout.vercel.app', 'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '1923', '42793', '59144'], 'fee': '0.004', 'integrator': 'blockscout'}, 'multisend': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '59144', '7000'], 'insightsKey': 'phc_7O4WGsecqqDO1PeaKayHAxUWN1PjheOmQCiDxEMcmkx', 'insightsHost': 'https://insights.hanzo.ai'}, 'revoke': {'chains': ['1', '10', '30', '100', '122', '130', '324', '480', '8453', '13371', '42161', '42220', '57073', '534352', '1868', '7887', '1514', '245022934', '61', '148', '314', '137', '7000', '42793', '4326']}}
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://airtable.com/appiy5yijZpMMSKjT/shr6uMGPKjj1DK7NL
NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM=https://airtable.com/appiy5yijZpMMSKjT/pag3t82DUCyhGRZZO/form
NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com
@@ -66,7 +65,6 @@ NEXT_PUBLIC_OTHER_LINKS=[{'url':'https://eth.drpc.org?ref=559183','text':'Public
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_REWARDS_SERVICE_API_HOST=https://merits.blockscout.com
NEXT_PUBLIC_SAFE_TX_SERVICE_URL=https://safe-transaction-mainnet.safe.global
NEXT_PUBLIC_SAVE_ON_GAS_ENABLED=true
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
NEXT_PUBLIC_STATS_API_HOST=https://eth.blockscout.com
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=blockscout
@@ -76,4 +74,6 @@ NEXT_PUBLIC_VIEWS_NFT_MARKETPLACES=[{'name':'OpenSea','collection_url':'https://
NEXT_PUBLIC_VIEWS_TOKEN_SCAM_TOGGLE_ENABLED=true
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
NEXT_PUBLIC_XSTAR_SCORE_URL=https://docs.xname.app/the-solution-adaptive-proof-of-humanity-on-blockchain/xhs-scoring-algorithm?utm_source=blockscout&utm_medium=address
NEXT_PUBLIC_API_KEYS_ALERT_MESSAGE='<strong>Chain-specific API keys are being deprecated.</strong> Please migrate to <a href="https://docs.blockscout.com/for-developers/api-keys/pro-api" target="_blank" rel="noopener noreferrer">Blockscout's PRO API</a> for new multichain access. Existing API keys will become invalid on 1st of Jan 2027'
NEXT_PUBLIC_API_KEYS_ALERT_MESSAGE='<strong>Chain-specific API keys are being deprecated.</strong> Please migrate to <a href="https://docs.blockscout.com/for-developers/api-keys/pro-api" target="_blank" rel="noopener noreferrer">Blockscout's PRO API</a> for new multichain access. Existing API keys will become invalid on 1st of Jan 2027'
NEXT_PUBLIC_API_DOCS_ALERT_MESSAGE='<strong>Blockscout Pro API is now available.</strong> Check out the <a href="https://dev.blockscout.com" target="_blank" rel="noopener noreferrer">Blockscout Pro API documentation</a> for new multichain access.'
NEXT_PUBLIC_ACCOUNT_API_KEYS_BUTTON=https://dev.blockscout.com
-1
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=eth-sepolia.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_DATA_AVAILABILITY_ENABLED=true
-1
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=filecoin.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS=[{'text':'Revoke','icon':'integration/partial','url':'https://revoke.blockscout.com/?utm_source=Blockscout&utm_medium=filecoin'}]
+1 -2
View File
@@ -18,7 +18,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=explorer.garnetchain.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/redstone.json
@@ -47,7 +46,7 @@ NEXT_PUBLIC_OG_DESCRIPTION=Redstone is the home for onchain games, worlds, and o
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/garnet.png
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth-holesky.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth-holesky.blockscout.com'}
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://garnet.qry.live/withdraw
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
-1
View File
@@ -18,7 +18,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=gnosis.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_BEACON_CHAIN_CURRENCY_SYMBOL=GNO
NEXT_PUBLIC_BRIDGED_TOKENS_BRIDGES=[{'type':'omni','title':'OmniBridge','short_title':'OMNI'},{'type':'amb','title':'Arbitrary Message Bridge','short_title':'AMB'}]
NEXT_PUBLIC_BRIDGED_TOKENS_CHAINS=[{'id':'1','title':'Ethereum','short_title':'ETH','base_url':'https://eth.blockscout.com/token/'},{'id':'56','title':'Binance Smart Chain','short_title':'BSC','base_url':'https://bscscan.com/token/'},{'id':'99','title':'POA','short_title':'POA','base_url':'https://blockscout.com/poa/core/token/'}]
-1
View File
@@ -18,7 +18,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=explorer.immutable.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS=[{'text':'Swap','icon':'swap','dappId':'swapscout'},{'text':'Revoke','icon':'integration/partial','dappId':'revokescout'}]
-2
View File
@@ -19,7 +19,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs-test.k8s-dev.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=eth-sepolia.k8s-dev.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_BEACON_CHAIN_VALIDATOR_URL_TEMPLATE=https://light-sepolia.beaconcha.in/validator/{pk}
NEXT_PUBLIC_CLUSTERS_API_HOST=https://api.clusters.xyz
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
@@ -73,7 +72,6 @@ NEXT_PUBLIC_OTHER_LINKS=[{'url':'https://sepolia.drpc.org?ref=559183','text':'Pu
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/sherblockHolmesBadge
NEXT_PUBLIC_REWARDS_SERVICE_API_HOST=https://points.k8s-dev.blockscout.com
NEXT_PUBLIC_SAFE_TX_SERVICE_URL=https://safe-transaction-sepolia.safe.global
NEXT_PUBLIC_SAVE_ON_GAS_ENABLED=true
NEXT_PUBLIC_SEO_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
NEXT_PUBLIC_STATS_API_HOST=https://eth-sepolia.k8s-dev.blockscout.com
+1 -2
View File
@@ -18,7 +18,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=megaeth.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_COLOR_THEME_DEFAULT=dark
NEXT_PUBLIC_COLOR_THEME_OVERRIDES={'bg':{'primary':{'_light':{'value':'rgba(250,249,249)'},'_dark':{'value':'rgba(25,25,26)'}}},'text':{'primary':{'_light':{'value':'rgba(25,25,26)'},'_dark':{'value':'rgba(236,232,232)'}},'secondary':{'_light':{'value':'rgba(25,25,26)'},'_dark':{'value':'rgba(223,217,217)'}}},'hover':{'_light':{'value':'rgba(245,175,148)'},'_dark':{'value':'rgba(114,215,159)'}},'selected':{'control':{'text':{'_light':{'value':'rgba(25,25,26)'},'_dark':{'value':'rgba(247,250,252)'}},'bg':{'_light':{'value':'rgba(236,232,232)'},'_dark':{'value':'rgba(255,255,255,0.06)'}}},'option':{'bg':{'_light':{'value':'rgba(84,75,75)'},'_dark':{'value':'rgba(66,96,82)'}}}},'icon':{'primary':{'_light':{'value':'rgba(25,25,26)'},'_dark':{'value':'rgba(223,217,217)'}},'secondary':{'_light':{'value':'rgba(176,176,176)'},'_dark':{'value':'rgba(105,103,103)'}}},'button':{'primary':{'_light':{'value':'rgba(25,25,26)'},'_dark':{'value':'rgba(105,103,103)'}}},'link':{'primary':{'_light':{'value':'rgba(25,25,26)'},'_dark':{'value':'rgba(109,208,169)'}}},'graph':{'line':{'_light':{'value':'rgba(105,103,103)'},'_dark':{'value':'rgba(109,208,169)'}},'gradient':{'start':{'_light':{'value':'rgba(105,103,103,0.3)'},'_dark':{'value':'rgba(109,208,169,0.3)'}},'stop':{'_light':{'value':'rgba(105,103,103,0)'},'_dark':{'value':'rgba(109,208,169,0)'}}}},'stats':{'bg':{'_light':{'value':'rgba(236,232,232)'},'_dark':{'value':'rgba(255,255,255,0.06)'}}},'topbar':{'bg':{'_light':{'value':'rgba(236,232,232)'},'_dark':{'value':'rgba(255,255,255,0.06)'}}},'navigation':{'text':{'selected':{'_light':{'value':'rgba(25,25,26)'},'_dark':{'value':'rgba(247,250,252)'}}},'bg':{'selected':{'_light':{'value':'rgba(236,232,232)'},'_dark':{'value':'rgba(255,255,255,0.06)'}}}},'tabs':{'text':{'primary':{'_light':{'value':'rgba(25,25,26)'},'_dark':{'value':'rgba(236,232,232)'}}}}}
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
@@ -50,7 +49,7 @@ NEXT_PUBLIC_NETWORK_RPC_URL=https://alpha.megaeth.com/rpc
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/mega-eth.png
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com'}
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://www.megaeth.com/
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
-1
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=mekong.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/sherblockHolmesBadge
NEXT_PUBLIC_HAS_BEACON_CHAIN=true
+30
View File
@@ -0,0 +1,30 @@
# Set of ENVs for OP Mainnet network explorer
# https://xxx.blockscout.com
# This is an auto-generated file. To update all values, run "yarn dev:preset:sync --name=multichain_dev"
# Local ENVs
NEXT_PUBLIC_APP_PROTOCOL=http
NEXT_PUBLIC_APP_HOST=localhost
NEXT_PUBLIC_APP_PORT=3000
NEXT_PUBLIC_APP_ENV=development
NEXT_PUBLIC_MULTICHAIN_ENABLED=true
NEXT_PUBLIC_MULTICHAIN_AGGREGATOR_API_HOST=https://multichain-aggregator.k8s-dev.blockscout.com
NEXT_PUBLIC_MULTICHAIN_CLUSTER=interop
NEXT_PUBLIC_MULTICHAIN_STATS_API_HOST=http://multichain-search-stats.k8s-dev.blockscout.com
SKIP_ENVS_VALIDATION=true
NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG=[{'name': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview?utm_source=blockscout&utm_medium=address', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'}]
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs','coin_price','market_cap']
NEXT_PUBLIC_HOMEPAGE_STATS=['total_txs','wallet_addresses']
NEXT_PUBLIC_API_DOCS_TABS=[]
NEXT_PUBLIC_NETWORK_NAME=Blockscout
NEXT_PUBLIC_GAS_TRACKER_ENABLED=false
NEXT_PUBLIC_HIDE_INDEXING_ALERT_BLOCKS=true
NEXT_PUBLIC_HIDE_INDEXING_ALERT_INT_TXS=true
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=false
NEXT_PUBLIC_IS_TESTNET=false
NEXT_PUBLIC_USE_NEXT_JS_PROXY=true
NEXT_PUBLIC_HAS_USER_OPS=true
NEXT_PUBLIC_ADVANCED_FILTER_ENABLED=false
+40
View File
@@ -0,0 +1,40 @@
# Set of ENVs for OP Mainnet network explorer
# https://xxx.blockscout.com
# This is an auto-generated file. To update all values, run "yarn dev:preset:sync --name=multichain_prod"
# Local ENVs
NEXT_PUBLIC_APP_PROTOCOL=http
NEXT_PUBLIC_APP_HOST=localhost
NEXT_PUBLIC_APP_PORT=3000
NEXT_PUBLIC_APP_ENV=development
NEXT_PUBLIC_NETWORK_ICON=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/multichain-light.svg
NEXT_PUBLIC_NETWORK_ICON_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/multichain-dark.svg
NEXT_PUBLIC_NETWORK_LOGO=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/multichain-light.svg
NEXT_PUBLIC_NETWORK_LOGO_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/multichain-dark.svg
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/multichain.png
FAVICON_MASTER_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/favicons/multichain.png
NEXT_PUBLIC_HOMEPAGE_HERO_BANNER_CONFIG={'background':['linear-gradient(89deg,rgba(83,83,211) 50.49%,rgba(155,155,255) 99.38%)'],'text_color':['rgba(225,225,255,1)'],'button':{'_default':{'background':['rgba(16,17,18,1)']},'_hover':{'background':['rgba(74,71,127,1)']}}}
NEXT_PUBLIC_COLOR_THEME_OVERRIDES={'bg':{'primary':{'_light':{'value':'rgba(255,255,255,1)'},'_dark':{'value':'rgba(35,43,55,1)'}}},'text':{'primary':{'_light':{'value':'rgba(16,17,18,0.8)'},'_dark':{'value':'rgba(255,255,255,0.8)'}},'secondary':{'_light':{'value':'rgba(113,128,150,1)'},'_dark':{'value':'rgba(160,174,192,1)'}}},'hover':{'_light':{'value':'rgba(155,155,255,1)'},'_dark':{'value':'rgba(155,155,255,1)'}},'selected':{'control':{'text':{'_light':{'value':'rgba(16,17,18,1)'},'_dark':{'value':'rgba(247,250,252,1)'}},'bg':{'_light':{'value':'rgba(16,17,18,0.04)'},'_dark':{'value':'rgba(247,250,252,0.06)'}}},'option':{'bg':{'_light':{'value':'rgba(83,83,211,1)'},'_dark':{'value':'rgba(114,114,233,1)'}}}},'icon':{'primary':{'_light':{'value':'rgba(113,128,150,1)'},'_dark':{'value':'rgba(160,174,192,1)'}},'secondary':{'_light':{'value':'rgba(160,174,192,1)'},'_dark':{'value':'rgba(113,128,150,1)'}}},'button':{'primary':{'_light':{'value':'rgba(83,83,211,1)'},'_dark':{'value':'rgba(114,114,233,1)'},'text':{'_light':{'value':'rgba(255,255,255,0.92)'},'_dark':{'value':'rgba(255,255,255,0.92)'}}}},'link':{'primary':{'_light':{'value':'rgba(83,83,211,1)'},'_dark':{'value':'rgba(114,114,233,1)'}}},'graph':{'line':{'_light':{'value':'rgba(94,87,112,1)'},'_dark':{'value':'rgba(194,190,208,1)'}},'gradient':{'start':{'_light':{'value':'rgba(94,87,112,0.3)'},'_dark':{'value':'rgba(194,190,208,0.3)'}},'stop':{'_light':{'value':'rgba(94,87,112,0)'},'_dark':{'value':'rgba(194,190,208,0)'}}}},'stats':{'bg':{'_light':{'value':'rgba(16,17,18,0.04)'},'_dark':{'value':'rgba(255,255,255,0.06)'}}},'topbar':{'bg':{'_light':{'value':'rgba(16,17,18,0.04)'},'_dark':{'value':'rgba(255,255,255,0.06)'}}},'navigation':{'text':{'selected':{'_light':{'value':'rgba(16,17,18,1)'},'_dark':{'value':'rgba(247,250,252,1)'}}},'bg':{'selected':{'_light':{'value':'rgba(16,17,18,0.04)'},'_dark':{'value':'rgba(255,255,255,0.06)'}}}},'tabs':{'text':{'primary':{'_light':{'value':'rgba(113,128,150,1)'},'_dark':{'value':'rgba(160,174,192,1)'}}}}}
NEXT_PUBLIC_MULTICHAIN_ENABLED=true
NEXT_PUBLIC_MULTICHAIN_AGGREGATOR_API_HOST=https://multichain-aggregator.services.blockscout.com
NEXT_PUBLIC_MULTICHAIN_CLUSTER=multichain
NEXT_PUBLIC_MULTICHAIN_STATS_API_HOST=https://multichain-stats.k8s-prod-3.blockscout.com
SKIP_ENVS_VALIDATION=true
NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG=[{'name': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview?utm_source=blockscout&utm_medium=address', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'}]
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs','coin_price','market_cap']
NEXT_PUBLIC_HOMEPAGE_STATS=['total_txs','wallet_addresses']
NEXT_PUBLIC_API_DOCS_TABS=[]
NEXT_PUBLIC_NETWORK_NAME=Blockscout
NEXT_PUBLIC_GAS_TRACKER_ENABLED=false
NEXT_PUBLIC_HIDE_INDEXING_ALERT_BLOCKS=true
NEXT_PUBLIC_HIDE_INDEXING_ALERT_INT_TXS=true
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=false
NEXT_PUBLIC_IS_TESTNET=false
NEXT_PUBLIC_USE_NEXT_JS_PROXY=true
NEXT_PUBLIC_HAS_USER_OPS=true
NEXT_PUBLIC_ADVANCED_FILTER_ENABLED=false
-1
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=neon-devnet.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/neon-devnet.json
-1
View File
@@ -19,7 +19,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=numine.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/sherblockHolmesBadge
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs']
+2 -3
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=explorer.optimism.io
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS=[{'text':'Swap','icon':'swap','url':'https://explorer.optimism.io/essential-dapps/swap?utm_source=defi-dropdown&utm_medium=swap'},{'text':'Revoke','icon':'integration/partial','dappId':'revokescout'}, {'text': 'Multisend', 'icon': 'token', 'url': 'https://explorer.optimism.io/essential-dapps/multisend?utm_source=defi-dropdown-multisend&utm_medium=multisend'}]
@@ -38,7 +37,7 @@ NEXT_PUBLIC_MARKETPLACE_BANNER_CONTENT_URL=https://gist.githubusercontent.com/0x
NEXT_PUBLIC_MARKETPLACE_BANNER_LINK_URL=https://badges.blockscout.com/badges-list?utm_source=blockscout-explorer&utm_medium=marketplace-banner
NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-categories/default.json
NEXT_PUBLIC_MARKETPLACE_ENABLED=true
NEXT_PUBLIC_MARKETPLACE_ESSENTIAL_DAPPS_CONFIG={'swap': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '1923', '42793', '59144'], 'fee': '0.004', 'integrator': 'blockscout'}, 'multisend': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '59144', '7000'], 'posthogKey': 'phc_7O4WGsecqqDO1PeaKayHAxUWN1PjheOmQCiDxEMcmkx', 'posthogHost': 'https://us.i.posthog.com'}}
NEXT_PUBLIC_MARKETPLACE_ESSENTIAL_DAPPS_CONFIG={'swap': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '1923', '42793', '59144'], 'fee': '0.004', 'integrator': 'blockscout'}, 'multisend': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '59144', '7000'], 'insightsKey': 'phc_7O4WGsecqqDO1PeaKayHAxUWN1PjheOmQCiDxEMcmkx', 'insightsHost': 'https://insights.hanzo.ai'}}
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://airtable.com/appiy5yijZpMMSKjT/shr6uMGPKjj1DK7NL
NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM=https://airtable.com/appiy5yijZpMMSKjT/pag3t82DUCyhGRZZO/form
NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com
@@ -64,7 +63,7 @@ NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/optimism-mainnet.png
NEXT_PUBLIC_OTHER_LINKS=[{'url':'https://optimism.drpc.org?ref=559183','text':'Public RPC'}]
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com'}
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://app.optimism.io/bridge/withdraw
NEXT_PUBLIC_ROLLUP_STAGE_INDEX=1
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
-54
View File
@@ -1,54 +0,0 @@
# Set of ENVs for OP Interop Alpha 0 network explorer
# https://optimism-interop-alpha-0.blockscout.com
# This is an auto-generated file. To update all values, run "yarn dev:preset:sync --name=optimism_interop_0"
# Local ENVs
NEXT_PUBLIC_APP_PROTOCOL=http
NEXT_PUBLIC_APP_HOST=localhost
NEXT_PUBLIC_APP_PORT=3000
NEXT_PUBLIC_APP_ENV=development
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=ws
# Instance ENVs
NEXT_PUBLIC_AD_BANNER_ENABLE_SPECIFY=true
NEXT_PUBLIC_AD_BANNER_PROVIDER=none
NEXT_PUBLIC_AD_TEXT_PROVIDER=none
NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS=['talentprotocol','drops','blockscoutbadges','gitpoap','efp','etherscore','webacy','humanpassport','trustblock','smartmuv','humanode','deepdao']
NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/widgets/config.json
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=optimism-interop-alpha-0.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_FAULT_PROOF_ENABLED=true
NEXT_PUBLIC_FOOTER_LINKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/footer-links/optimism.json
NEXT_PUBLIC_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/sherblockHolmesBadge
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs']
NEXT_PUBLIC_HOMEPAGE_HERO_BANNER_CONFIG={'background':['linear-gradient(90deg, rgb(232, 52, 53) 0%, rgb(139, 28, 232) 100%)'],'text_color':['rgb(255, 255, 255)']}
NEXT_PUBLIC_INTEROP_ENABLED=true
NEXT_PUBLIC_IS_TESTNET=true
NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com
NEXT_PUBLIC_MIXPANEL_CONFIG_OVERRIDES={"record_sessions_percent": 0.5,"record_heatmap_data": true}
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18
NEXT_PUBLIC_NETWORK_CURRENCY_NAME=Ether
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL=ETH
NEXT_PUBLIC_NETWORK_ICON=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/optimism.svg
NEXT_PUBLIC_NETWORK_ICON_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/optimism.svg
NEXT_PUBLIC_NETWORK_ID=420120000
NEXT_PUBLIC_NETWORK_LOGO=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/optimism.svg
NEXT_PUBLIC_NETWORK_LOGO_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/optimism.svg
NEXT_PUBLIC_NETWORK_NAME=OP Interop Alpha 0
NEXT_PUBLIC_NETWORK_RPC_URL=https://interop-alpha-0.optimism.io
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth-sepolia.blockscout.com/
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://bridge.interop-alpha-0.optimism.io
NEXT_PUBLIC_ROLLUP_OUTPUT_ROOTS_ENABLED=false
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
NEXT_PUBLIC_STATS_API_HOST=https://optimism-interop-alpha-0.blockscout.com
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=blockscout
NEXT_PUBLIC_VIEWS_TOKEN_SCAM_TOGGLE_ENABLED=true
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
NEXT_PUBLIC_WEB3_WALLETS=['token_pocket', 'metamask']
+1 -2
View File
@@ -18,7 +18,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=testnet-explorer.optimism.io
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_FAULT_PROOF_ENABLED=true
@@ -51,7 +50,7 @@ NEXT_PUBLIC_NETWORK_NAME=OP Sepolia
NEXT_PUBLIC_NETWORK_RPC_URL=https://sepolia.optimism.io
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth-sepolia.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth-sepolia.blockscout.com'}
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://app.optimism.io/bridge/withdraw
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
-39
View File
@@ -1,39 +0,0 @@
# Set of ENVs for OP Mainnet network explorer
# https://xxx.blockscout.com
# This is an auto-generated file. To update all values, run "yarn dev:preset:sync --name=optimism_superchain"
# Local ENVs
NEXT_PUBLIC_APP_PROTOCOL=http
NEXT_PUBLIC_APP_HOST=localhost
NEXT_PUBLIC_APP_PORT=3000
NEXT_PUBLIC_APP_ENV=development
NEXT_PUBLIC_MULTICHAIN_AGGREGATOR_API_HOST=https://multichain-aggregator.k8s-dev.blockscout.com
NEXT_PUBLIC_MULTICHAIN_STATS_API_HOST=http://multichain-search-stats.k8s-dev.blockscout.com
NEXT_PUBLIC_MULTICHAIN_ENABLED=true
NEXT_PUBLIC_MULTICHAIN_CLUSTER=interop
SKIP_ENVS_VALIDATION=false
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs','coin_price','market_cap']
NEXT_PUBLIC_HOMEPAGE_STATS=['total_txs','wallet_addresses']
NEXT_PUBLIC_API_DOCS_TABS=[]
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/optimism-mainnet.json
NEXT_PUBLIC_FOOTER_LINKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/footer-links/optimism.json
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs', 'coin_price', 'market_cap', 'secondary_coin_price']
NEXT_PUBLIC_HOMEPAGE_HERO_BANNER_CONFIG={'background':['linear-gradient(90deg, rgb(232, 52, 53) 0%, rgb(139, 28, 232) 100%)'],'text_color':['rgb(255, 255, 255)']}
NEXT_PUBLIC_NETWORK_ICON=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/optimism-superchain.svg
NEXT_PUBLIC_NETWORK_ICON_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/optimism-superchain.svg
NEXT_PUBLIC_NETWORK_LOGO=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/optimism-superchain.svg
NEXT_PUBLIC_NETWORK_LOGO_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/optimism-superchain-dark.svg
NEXT_PUBLIC_NETWORK_NAME=OP Superchain
NEXT_PUBLIC_NETWORK_SHORT_NAME=OP Superchain
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/optimism-mainnet.png
NEXT_PUBLIC_GAS_TRACKER_ENABLED=false
NEXT_PUBLIC_HIDE_INDEXING_ALERT_BLOCKS=true
NEXT_PUBLIC_HIDE_INDEXING_ALERT_INT_TXS=true
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=false
NEXT_PUBLIC_IS_TESTNET=true
NEXT_PUBLIC_USE_NEXT_JS_PROXY=true
NEXT_PUBLIC_HAS_USER_OPS=true
NEXT_PUBLIC_ADVANCED_FILTER_ENABLED=false
+1 -2
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=polygon.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS=[{'text':'Swap','icon':'swap','url':'https://polygon.blockscout.com/essential-dapps/swap?utm_source=defi-dropdown&utm_medium=swap'},{'text':'Revoke','icon':'integration/partial','dappId':'revokescout'}, {'text': 'Multisend', 'icon': 'token', 'url': 'https://polygon.blockscout.com/essential-dapps/multisend?utm_source=defi-dropdown-multisend&utm_medium=multisend'}]
@@ -33,7 +32,7 @@ NEXT_PUBLIC_MARKETPLACE_BANNER_CONTENT_URL=https://gist.githubusercontent.com/0x
NEXT_PUBLIC_MARKETPLACE_BANNER_LINK_URL=https://badges.blockscout.com/badges-list?utm_source=blockscout-explorer&utm_medium=marketplace-banner
NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-categories/default.json
NEXT_PUBLIC_MARKETPLACE_ENABLED=true
NEXT_PUBLIC_MARKETPLACE_ESSENTIAL_DAPPS_CONFIG={'swap': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '1923', '42793', '59144'], 'fee': '0.004', 'integrator': 'blockscout'}, 'multisend': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '59144', '7000'], 'posthogKey': 'phc_7O4WGsecqqDO1PeaKayHAxUWN1PjheOmQCiDxEMcmkx', 'posthogHost': 'https://us.i.posthog.com'}}
NEXT_PUBLIC_MARKETPLACE_ESSENTIAL_DAPPS_CONFIG={'swap': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '1923', '42793', '59144'], 'fee': '0.004', 'integrator': 'blockscout'}, 'multisend': {'chains': ['1', '10', '30', '100', '122', '130', '137', '324', '480', '1135', '1514', '1868', '8453', '13371', '42161', '42220', '57073', '534352', '11155111', '1313161554', '59144', '7000'], 'insightsKey': 'phc_7O4WGsecqqDO1PeaKayHAxUWN1PjheOmQCiDxEMcmkx', 'insightsHost': 'https://insights.hanzo.ai'}}
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://airtable.com/appiy5yijZpMMSKjT/shr6uMGPKjj1DK7NL
NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM=https://airtable.com/appiy5yijZpMMSKjT/pag3t82DUCyhGRZZO/form
NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com
+1 -2
View File
@@ -14,7 +14,6 @@ NEXT_PUBLIC_AD_BANNER_PROVIDER=slise
NEXT_PUBLIC_AD_TEXT_PROVIDER=coinzilla
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=rari-testnet.cloud.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_COLOR_THEME_DEFAULT=light
NEXT_PUBLIC_HAS_BEACON_CHAIN=true
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs']
@@ -31,7 +30,7 @@ NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=false
NEXT_PUBLIC_OTHER_LINKS=[]
NEXT_PUBLIC_ROLLUP_DA_CELESTIA_CELENIUM_URL=https://mocha-4.celenium.io/blob
NEXT_PUBLIC_ROLLUP_DA_CELESTIA_NAMESPACE=0x00000000000000000000000000000000000000ca1de12a9905be97beaf
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://arbitrum-sepolia.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://arbitrum-sepolia.blockscout.com'}
NEXT_PUBLIC_ROLLUP_TYPE=arbitrum
NEXT_PUBLIC_SEO_ENHANCED_DATA_ENABLED=false
NEXT_PUBLIC_VIEWS_ADDRESS_IDENTICON_TYPE=jazzicon
-1
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=rootstock-testnet.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/rsk-testnet.json
+1 -2
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=scroll-sepolia.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/scroll-testnet.json
@@ -40,7 +39,7 @@ NEXT_PUBLIC_NETWORK_RPC_URL=https://sepolia-rpc.scroll.io
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/scroll-testnet.png
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth-sepolia.blockscout.com
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth-sepolia.blockscout.com'}
NEXT_PUBLIC_ROLLUP_TYPE=scroll
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
NEXT_PUBLIC_STATS_API_HOST=https://scroll-sepolia.blockscout.com
+1 -2
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=www.shibariumscan.io
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_APP_INSTANCE=shibarium_mainnet
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
@@ -57,7 +56,7 @@ NEXT_PUBLIC_NETWORK_SHORT_NAME=Puppynet
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/shibarium-mainnet.png
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com'}
NEXT_PUBLIC_ROLLUP_TYPE=shibarium
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
NEXT_PUBLIC_STATS_API_HOST=https://www.shibariumscan.io
-1
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=explorer.testnet.stabilityprotocol.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/stability-testnet.json
-1
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=explorer.tac.build
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_FOOTER_LINKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/footer-links/tac.json
NEXT_PUBLIC_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/sherblockHolmesBadge
+2 -2
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=spb.explorer.tac.build
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_FOOTER_LINKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/footer-links/tac.json
NEXT_PUBLIC_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/sherblockHolmesBadge
@@ -41,7 +40,8 @@ NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-c
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
NEXT_PUBLIC_STATS_API_HOST=https://spb.explorer.tac.build
NEXT_PUBLIC_TAC_OPERATION_LIFECYCLE_API_HOST=https://tac-spb-operation-lifecycle.k8s.blockscout.com
# NEXT_PUBLIC_TAC_OPERATION_LIFECYCLE_API_HOST=https://tac-spb-operation-lifecycle.k8s.blockscout.com
NEXT_PUBLIC_TAC_OPERATION_LIFECYCLE_API_HOST=https://tac-spb-operation-lifecycle.k8s-dev.blockscout.com
NEXT_PUBLIC_TAC_TON_EXPLORER_URL=https://testnet.tonviewer.com
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=blockscout
NEXT_PUBLIC_VIEWS_TOKEN_SCAM_TOGGLE_ENABLED=true
-1
View File
@@ -18,7 +18,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=zetascan.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS=[{'text':'Revoke','icon':'integration/partial','dappId':'revokescout'}]
-1
View File
@@ -18,7 +18,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=testnet.zetascan.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/zetachain-athens-3.json
-1
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=zilliqa.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/zilliqa.json
+1 -2
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=polygon-cdk-stavanger.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/cdk-stavanger.json
@@ -40,7 +39,7 @@ NEXT_PUBLIC_NETWORK_NAME=Polygon CDK Stavanger
NEXT_PUBLIC_NETWORK_RPC_URL=https://sn2-stavanger-rpc.eu-north-2.gateway.fm
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth-sepolia.blockscout.com
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth-sepolia.blockscout.com'}
NEXT_PUBLIC_ROLLUP_TYPE=zkEvm
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
NEXT_PUBLIC_STATS_API_HOST=https://polygon-cdk-stavanger.blockscout.com
+1 -2
View File
@@ -16,7 +16,6 @@ NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.c
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=zksync.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS=[{'text':'Swap','icon':'swap','url':'https://zksync.blockscout.com/essential-dapps/swap?utm_source=defi-dropdown&utm_medium=swap'},{'text':'Revoke','icon':'integration/partial','dappId':'revokescout'}, {'text': 'Multisend', 'icon': 'token', 'url': 'https://zksync.blockscout.com/essential-dapps/multisend?utm_source=defi-dropdown-multisend&utm_medium=multisend'}]
NEXT_PUBLIC_DEX_POOLS_ENABLED=true
@@ -52,7 +51,7 @@ NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/zksync.png
NEXT_PUBLIC_OTHER_LINKS=[{'url':'https://zksync.drpc.org?ref=559183','text':'Public RPC'}]
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com'}
NEXT_PUBLIC_ROLLUP_TYPE=zkSync
NEXT_PUBLIC_SAFE_TX_SERVICE_URL=https://safe-transaction-zksync.safe.global
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
+1 -2
View File
@@ -19,7 +19,6 @@ NEXT_PUBLIC_ADDRESS_USERNAME_TAG={'api_url_template': 'https://api.zora.co/disco
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=explorer.zora.energy
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_DEX_POOLS_ENABLED=true
@@ -55,7 +54,7 @@ NEXT_PUBLIC_NETWORK_VERIFICATION_TYPE=validation
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/zora-mainnet.png
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com'}
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://bridge.zora.energy
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
+1 -1
View File
@@ -5,7 +5,7 @@ import * as multichainConfigNodejs from 'configs/multichain/config.nodejs';
import { isBrowser } from 'toolkit/utils/isBrowser';
const multichainConfig: () => MultichainConfig | undefined = () => {
if (!config.features.opSuperchain.isEnabled) {
if (!config.features.multichain.isEnabled) {
return;
}
+9 -3
View File
@@ -15,7 +15,8 @@
"public/static/capybara/index.js",
"ui/showcases/utils.ts",
"ui/tx/TxExternalTxs.pw.tsx",
"pnpm-lock.yaml"
"pnpm-lock.yaml",
".cspell-words.txt"
],
"enableGlobDot": true,
"ignoreRandomStrings": true,
@@ -25,7 +26,7 @@
"f410f[a-z2-7]{39}",
// Specify publisher key
"spk_\\w+",
// Posthog project key
// Insights project key
"phc_\\w+",
// GitHub account names
"@(\\w|-)+"
@@ -33,6 +34,7 @@
// words - list of words to be always considered correct
"words": [
"aatx",
"hanzoai",
"abfnrtv",
"abitype",
"AIVM",
@@ -88,6 +90,7 @@
"clstr",
"coinzilla",
"coinzillatag",
"commitish",
"Computor",
"contentscript",
"contractname",
@@ -195,7 +198,7 @@
"peekers",
"pino",
"pjpeg",
"posthog",
"insights",
"procs",
"PWDEBUG",
"pwstory",
@@ -224,6 +227,7 @@
"rollups",
"rubic",
"Sastana",
"",
"schnorr",
"screencasts",
"scure",
@@ -231,6 +235,8 @@
"SEMRESATTRS",
"Semrush",
"servedbyadbutler",
"sevio",
"sevioads",
"Shavuha",
"Shavukha",
"shibarium",
+109
View File
@@ -0,0 +1,109 @@
# Devnet frontend deployment
# Deploy: kubectl apply -f deploy/k8s/frontend-devnet.yaml -n lux-devnet
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: lux-frontend-devnet
labels:
app: lux-frontend-devnet
spec:
replicas: 1
selector:
matchLabels:
app: lux-frontend-devnet
template:
metadata:
labels:
app: lux-frontend-devnet
spec:
containers:
- name: frontend
image: ghcr.io/luxfi/explore:latest
ports:
- containerPort: 3000
env:
- name: NEXT_PUBLIC_NETWORK_NAME
value: "LUX Devnet"
- name: NEXT_PUBLIC_NETWORK_SHORT_NAME
value: "LUX"
- name: NEXT_PUBLIC_NETWORK_ID
value: "96367"
- name: NEXT_PUBLIC_NETWORK_CURRENCY_NAME
value: "LUX"
- name: NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL
value: "LUX"
- name: NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS
value: "18"
- name: NEXT_PUBLIC_API_HOST
value: "api-explore-devnet.lux.network"
- name: NEXT_PUBLIC_API_PROTOCOL
value: "https"
- name: NEXT_PUBLIC_API_BASE_PATH
value: "/"
- name: NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL
value: "wss"
- name: NEXT_PUBLIC_APP_HOST
value: "explore-devnet.lux.network"
- name: NEXT_PUBLIC_APP_PROTOCOL
value: "https"
- name: NEXT_PUBLIC_IS_TESTNET
value: "true"
- name: NEXT_PUBLIC_NETWORK_RPC_URL
value: "https://api.lux-dev.network/ext/bc/C/rpc"
- name: NEXT_PUBLIC_COLOR_THEME_DEFAULT
value: "dark"
- name: NEXT_PUBLIC_HOMEPAGE_CHARTS
value: '["daily_txs"]'
- name: NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED
value: "true"
- name: NEXT_PUBLIC_PROMOTE_BLOCKSCOUT_IN_TITLE
value: "false"
resources:
requests:
memory: 256Mi
cpu: 100m
limits:
memory: 512Mi
cpu: 500m
readinessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: lux-frontend-devnet
spec:
selector:
app: lux-frontend-devnet
ports:
- port: 3000
targetPort: 3000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: lux-frontend-devnet
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts:
- explore-devnet.lux.network
secretName: explore-devnet-lux-tls
rules:
- host: explore-devnet.lux.network
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: lux-frontend-devnet
port:
number: 3000
+109
View File
@@ -0,0 +1,109 @@
# Testnet frontend deployment
# Deploy: kubectl apply -f deploy/k8s/frontend-testnet.yaml -n lux-testnet
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: lux-frontend-testnet
labels:
app: lux-frontend-testnet
spec:
replicas: 1
selector:
matchLabels:
app: lux-frontend-testnet
template:
metadata:
labels:
app: lux-frontend-testnet
spec:
containers:
- name: frontend
image: ghcr.io/luxfi/explore:latest
ports:
- containerPort: 3000
env:
- name: NEXT_PUBLIC_NETWORK_NAME
value: "LUX Testnet"
- name: NEXT_PUBLIC_NETWORK_SHORT_NAME
value: "LUX"
- name: NEXT_PUBLIC_NETWORK_ID
value: "96368"
- name: NEXT_PUBLIC_NETWORK_CURRENCY_NAME
value: "LUX"
- name: NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL
value: "LUX"
- name: NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS
value: "18"
- name: NEXT_PUBLIC_API_HOST
value: "api-explore-testnet.lux.network"
- name: NEXT_PUBLIC_API_PROTOCOL
value: "https"
- name: NEXT_PUBLIC_API_BASE_PATH
value: "/"
- name: NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL
value: "wss"
- name: NEXT_PUBLIC_APP_HOST
value: "explore-testnet.lux.network"
- name: NEXT_PUBLIC_APP_PROTOCOL
value: "https"
- name: NEXT_PUBLIC_IS_TESTNET
value: "true"
- name: NEXT_PUBLIC_NETWORK_RPC_URL
value: "https://api.lux-test.network/ext/bc/C/rpc"
- name: NEXT_PUBLIC_COLOR_THEME_DEFAULT
value: "dark"
- name: NEXT_PUBLIC_HOMEPAGE_CHARTS
value: '["daily_txs"]'
- name: NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED
value: "true"
- name: NEXT_PUBLIC_PROMOTE_BLOCKSCOUT_IN_TITLE
value: "false"
resources:
requests:
memory: 256Mi
cpu: 100m
limits:
memory: 512Mi
cpu: 500m
readinessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: lux-frontend-testnet
spec:
selector:
app: lux-frontend-testnet
ports:
- port: 3000
targetPort: 3000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: lux-frontend-testnet
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts:
- explore-testnet.lux.network
secretName: explore-testnet-lux-tls
rules:
- host: explore-testnet.lux.network
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: lux-frontend-testnet
port:
number: 3000
+115
View File
@@ -0,0 +1,115 @@
# Stats microservice deployment for LUX Explorer
# Provides /api/v1/pages/main, /api/v1/counters, /api/v1/lines chart data
# Deploy: kubectl apply -f deploy/k8s/stats.yaml -n lux-mainnet
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: lux-stats
labels:
app: lux-stats
spec:
replicas: 1
selector:
matchLabels:
app: lux-stats
template:
metadata:
labels:
app: lux-stats
spec:
containers:
- name: stats
image: ghcr.io/luxfi/explorer-stats:latest
ports:
- containerPort: 8050
protocol: TCP
env:
- name: STATS__SERVER__HTTP__ENABLED
value: "true"
- name: STATS__SERVER__HTTP__ADDR
value: "0.0.0.0:8050"
- name: STATS__CREATE_DATABASE
value: "true"
- name: STATS__RUN_MIGRATIONS
value: "true"
- name: STATS__FORCE_UPDATE_ON_START
value: "true"
- name: STATS__DEFAULT_SCHEDULE
value: "0 0 1 * * * *"
- name: STATS__BLOCKSCOUT_API_URL
value: "http://lux-backend-mainnet:4000"
envFrom:
- secretRef:
name: lux-stats-secrets
resources:
requests:
memory: 256Mi
cpu: 100m
limits:
memory: 512Mi
cpu: 500m
readinessProbe:
httpGet:
path: /health
port: 8050
initialDelaySeconds: 10
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 8050
initialDelaySeconds: 30
periodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
name: lux-stats
labels:
app: lux-stats
spec:
selector:
app: lux-stats
ports:
- port: 8050
targetPort: 8050
protocol: TCP
---
# Secret template — apply with actual DB credentials before deploying
# kubectl create secret generic lux-stats-secrets -n lux-mainnet \
# --from-literal=STATS__DB_URL='postgresql://USER:PASS@HOST:5432/stats_luxnet' \
# --from-literal=STATS__BLOCKSCOUT_DB_URL='postgresql://USER:PASS@HOST:5432/explorer_luxnet'
apiVersion: v1
kind: Secret
metadata:
name: lux-stats-secrets
type: Opaque
stringData:
STATS__DB_URL: "postgresql://blockscout:CHANGE_ME@postgres:5432/stats_luxnet"
STATS__BLOCKSCOUT_DB_URL: "postgresql://blockscout:CHANGE_ME@postgres:5432/explorer_luxnet"
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: lux-stats-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts:
- api-explore.lux.network
secretName: api-explore-lux-tls
rules:
- host: api-explore.lux.network
http:
paths:
- path: /api/stats(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: lux-stats
port:
number: 8050
+3 -2
View File
@@ -27,8 +27,9 @@ for var in $(env | grep '^NEXT_PUBLIC_' | cut -d= -f1); do
# Get the value of the variable
value="${!var}"
# Replace double quotes with single quotes
value="${value//\"/\'}"
# Escape double quotes with backslash for valid JavaScript string
value="${value//\\/\\\\}"
value="${value//\"/\\\"}"
# Write the variable name and value to the output file
echo "${var}: \"${value}\"," >> "$output_file"
+1 -6
View File
@@ -152,12 +152,7 @@ function getEnvsPlaceholders(filePath: string): Promise<Array<string>> {
}
function printDeprecationWarning(envsMap: Record<string, string>) {
if (
envsMap.NEXT_PUBLIC_ROLLUP_L1_BASE_URL
) {
// eslint-disable-next-line max-len
console.warn('❗ The NEXT_PUBLIC_ROLLUP_L1_BASE_URL variables are now deprecated and will be removed in the next release. Please migrate to the NEXT_PUBLIC_ROLLUP_PARENT_CHAIN variable.');
}
}
function checkDeprecatedEnvs(envsMap: Record<string, string>) {
+2 -15
View File
@@ -13,7 +13,6 @@ import type { AddressProfileAPIConfig } from 'types/client/addressProfileAPIConf
import type { GasRefuelProviderConfig } from 'types/client/gasRefuelProviderConfig';
import { GAS_UNITS } from 'types/client/gasTracker';
import type { GasUnit } from 'types/client/gasTracker';
import type { MultichainProviderConfig } from 'types/client/multichainProviderConfig';
import { PROVIDERS as TX_INTERPRETATION_PROVIDERS } from 'types/client/txInterpretation';
import { VALIDATORS_CHAIN_TYPE } from 'types/client/validators';
import type { ValidatorsChainType } from 'types/client/validators';
@@ -30,14 +29,6 @@ import * as uiSchemas from './schemas/ui';
import * as featuresSchemas from './schemas/features';
import servicesSchema from './schemas/services';
const multichainProviderConfigSchema: yup.ObjectSchema<MultichainProviderConfig> = yup.object({
name: yup.string().required(),
url_template: yup.string().required(),
logo: yup.string().required(),
dapp_id: yup.string(),
promo: yup.boolean(),
});
const schema = yup
.object()
.noUnknown(true, (params) => {
@@ -79,11 +70,6 @@ const schema = yup
NEXT_PUBLIC_SAFE_TX_SERVICE_URL: yup.string().test(urlTest),
NEXT_PUBLIC_IS_SUAVE_CHAIN: yup.boolean(),
NEXT_PUBLIC_METASUITES_ENABLED: yup.boolean(),
NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG: yup
.array()
.transform(replaceQuotes)
.json()
.of(multichainProviderConfigSchema),
NEXT_PUBLIC_GAS_REFUEL_PROVIDER_CONFIG: yup
.mixed()
.test('shape', 'Invalid schema were provided for NEXT_PUBLIC_GAS_REFUEL_PROVIDER_CONFIG, it should have name and url template', (data) => {
@@ -113,7 +99,6 @@ const schema = yup
value => value === undefined,
),
}),
NEXT_PUBLIC_SAVE_ON_GAS_ENABLED: yup.boolean(),
NEXT_PUBLIC_ADDRESS_USERNAME_TAG: yup
.mixed()
.test('shape', 'Invalid schema were provided for NEXT_PUBLIC_ADDRESS_USERNAME_TAG, it should have api_url_template', (data) => {
@@ -150,6 +135,7 @@ const schema = yup
// Misc
NEXT_PUBLIC_USE_NEXT_JS_PROXY: yup.boolean(),
NEXT_PUBLIC_API_KEYS_ALERT_MESSAGE: yup.string(),
NEXT_PUBLIC_API_DOCS_ALERT_MESSAGE: yup.string(),
})
.concat(apisSchema)
.concat(chainSchema)
@@ -170,6 +156,7 @@ const schema = yup
.concat(featuresSchemas.highlightsConfigSchema)
.concat(featuresSchemas.marketplaceSchema)
.concat(featuresSchemas.megaEthSchema)
.concat(featuresSchemas.multichainButtonSchema)
.concat(featuresSchemas.nameServicesSchema)
.concat(featuresSchemas.rollupSchema)
.concat(featuresSchemas.tacSchema)
@@ -12,6 +12,7 @@ import * as uiSchemas from './schemas/ui';
import * as featuresSchemas from './schemas/features';
import servicesSchemas from './schemas/services';
import { replaceQuotes } from 'configs/app/utils';
import { IDENTICON_TYPES } from 'types/views/address';
const schema = yup
.object()
@@ -38,6 +39,10 @@ const schema = yup
NEXT_PUBLIC_NETWORK_SHORT_NAME: yup.string(),
NEXT_PUBLIC_IS_TESTNET: yup.boolean(),
// 3. UI views configuration
// Some settings that we actually support in multichain mode
NEXT_PUBLIC_VIEWS_ADDRESS_IDENTICON_TYPE: yup.string().oneOf(IDENTICON_TYPES),
// 5. Features configuration
// NOTE!: Not all features are supported in multichain mode, and some of them not relevant or enabled per chain basis
// Below listed supported features and the features that are enabled by default, so we have to turn them off
@@ -63,8 +68,9 @@ const schema = yup
.concat(uiSchemas.footerSchema)
.concat(uiSchemas.miscSchema)
.concat(featuresSchemas.adsSchema)
.concat(featuresSchemas.userOpsSchema)
.concat(featuresSchemas.defiDropdownSchema)
.concat(featuresSchemas.multichainButtonSchema)
.concat(featuresSchemas.userOpsSchema)
.concat(servicesSchemas);
export default schema;
@@ -1,16 +1,31 @@
import { AuthProvider } from 'types/client/account';
import * as yup from 'yup';
import { urlTest } from '../../utils';
export const accountSchema = yup
.object()
.shape({
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED: yup.boolean(),
NEXT_PUBLIC_ACCOUNT_API_KEYS_BUTTON: yup
.mixed()
.test('shape', 'Invalid schema were provided for NEXT_PUBLIC_ACCOUNT_API_KEYS_BUTTON, it should be either boolean or string', (data) => {
return yup.boolean().isValidSync(data) || yup.string().test(urlTest).isValidSync(data);
})
.when('NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED', {
is: (value: boolean) => value === true,
then: (schema) => schema,
otherwise: (schema) => schema.test(
'not-exist',
'NEXT_PUBLIC_ACCOUNT_API_KEYS_BUTTON can only be used if NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED is set to \'true\'',
value => value === undefined,
),
}),
NEXT_PUBLIC_ACCOUNT_AUTH_PROVIDER: yup
.string<AuthProvider>()
.when('NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED', {
is: (value: boolean) => value === true,
then: (schema) => schema.oneOf([ 'auth0', 'dynamic', 'oidc' ]),
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_ACCOUNT_AUTH_PROVIDER cannot not be used if NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED is not defined'),
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_ACCOUNT_AUTH_PROVIDER can only be used if NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED is set to \'true\''),
}),
NEXT_PUBLIC_ACCOUNT_DYNAMIC_ENVIRONMENT_ID: yup
.string()
@@ -1,4 +1,3 @@
import { urlTest } from "../../utils";
import * as yup from 'yup';
import { replaceQuotes } from 'configs/app/utils';
import type { ApiDocsTabId } from 'types/views/apiDocs';
@@ -11,7 +10,4 @@ export const apiDocsSchema = yup
.transform(replaceQuotes)
.json()
.of(yup.string<ApiDocsTabId>().oneOf(API_DOCS_TABS)),
NEXT_PUBLIC_API_SPEC_URL: yup
.string()
.test(urlTest),
});
@@ -9,6 +9,7 @@ export * from './defiDropdown';
export * from './highlights';
export * from './marketplace';
export * from './megaEth';
export * from './multichainButton';
export * from './nameServices';
export * from './rollup';
export * from './tac';
@@ -124,8 +124,8 @@ export const marketplaceSchema = yup
multisend: yup.lazy(value => value ?
yup.object<EssentialDappsConfig['multisend']>().shape({
chains: chainsSchema,
posthogKey: yup.string(),
posthogHost: yup.string().test(urlTest),
insightsKey: yup.string(),
insightsHost: yup.string().test(urlTest),
}) :
yup.object().nullable(),
),
@@ -0,0 +1,21 @@
import { replaceQuotes } from 'configs/app/utils';
import { MultichainProviderConfig } from 'types/client/multichainProviderConfig';
import * as yup from 'yup';
const multichainProviderConfigSchema: yup.ObjectSchema<MultichainProviderConfig> = yup.object({
name: yup.string().required(),
url_template: yup.string().required(),
logo: yup.string().required(),
dapp_id: yup.string(),
promo: yup.boolean(),
});
export const multichainButtonSchema = yup
.object()
.shape({
NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG: yup
.array()
.transform(replaceQuotes)
.json()
.of(multichainProviderConfigSchema)
});
@@ -12,46 +12,46 @@ const parentChainCurrencySchema = yup
decimals: yup.number().required(),
});
const parentChainSchema = yup
.object()
.transform(replaceQuotes)
.json()
.shape({
id: yup.number(),
name: yup.string(),
baseUrl: yup.string().test(urlTest).required(),
rpcUrls: yup.array().of(yup.string().test(urlTest)),
currency: yup
.mixed()
.test(
'shape',
(ctx) => {
try {
parentChainCurrencySchema.validateSync(ctx.originalValue);
throw new Error('Unknown validation error');
} catch (error: unknown) {
const message = getYupValidationErrorMessage(error);
return 'in \"currency\" property ' + (message ? `${ message }` : '');
}
},
(data) => {
const isUndefined = data === undefined;
return isUndefined || parentChainCurrencySchema.isValidSync(data);
},
),
isTestnet: yup.boolean(),
});
export const rollupSchema = yup
.object()
.shape({
NEXT_PUBLIC_ROLLUP_TYPE: yup.string().oneOf(ROLLUP_TYPES),
NEXT_PUBLIC_ROLLUP_L1_BASE_URL: yup
.string()
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN: yup
.object()
.when('NEXT_PUBLIC_ROLLUP_TYPE', {
is: (value: string) => value,
then: (schema) => schema.test(urlTest).required(),
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_ROLLUP_L1_BASE_URL cannot not be used if NEXT_PUBLIC_ROLLUP_TYPE is not defined'),
then: (schema) => {
return schema.transform(replaceQuotes).json().shape({
id: yup.number(),
name: yup.string(),
baseUrl: yup.string().test(urlTest).required(),
rpcUrls: yup.array().of(yup.string().test(urlTest)),
currency: yup
.mixed()
.test(
'shape',
(ctx) => {
try {
parentChainCurrencySchema.validateSync(ctx.originalValue);
throw new Error('Unknown validation error');
} catch (error: unknown) {
const message = getYupValidationErrorMessage(error);
return 'in \"currency\" property ' + (message ? `${ message }` : '');
}
},
(data) => {
const isUndefined = data === undefined;
return isUndefined || parentChainCurrencySchema.isValidSync(data);
},
),
isTestnet: yup.boolean(),
})
},
otherwise: (schema) => schema.test(
'not-exist',
'NEXT_PUBLIC_ROLLUP_PARENT_CHAIN cannot not be used if NEXT_PUBLIC_ROLLUP_TYPE is not defined',
value => value === undefined,
),
}),
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL: yup
.string()
@@ -113,34 +113,6 @@ export const rollupSchema = yup
value => value === undefined,
),
}),
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN: yup
.mixed()
.when('NEXT_PUBLIC_ROLLUP_TYPE', {
is: (value: string) => value,
then: (schema) => {
return schema.test(
'shape',
(ctx) => {
try {
parentChainSchema.validateSync(ctx.originalValue);
throw new Error('Unknown validation error');
} catch (error: unknown) {
const message = getYupValidationErrorMessage(error);
return 'Invalid schema were provided for NEXT_PUBLIC_ROLLUP_PARENT_CHAIN' + (message ? `: ${ message }` : '');
}
},
(data) => {
const isUndefined = data === undefined;
return isUndefined || parentChainSchema.isValidSync(data);
}
)
},
otherwise: (schema) => schema.test(
'not-exist',
'NEXT_PUBLIC_ROLLUP_PARENT_CHAIN cannot not be used if NEXT_PUBLIC_ROLLUP_TYPE is not defined',
value => value === undefined,
),
}),
NEXT_PUBLIC_ROLLUP_DA_CELESTIA_NAMESPACE: yup
.string()
.min(60)
@@ -169,4 +141,17 @@ export const rollupSchema = yup
value => value === undefined,
),
}),
NEXT_PUBLIC_ROLLUP_LAYER_NUMBER: yup.number()
.positive()
.integer()
.min(2)
.when('NEXT_PUBLIC_ROLLUP_TYPE', {
is: (value: string) => Boolean(value),
then: (schema) => schema,
otherwise: (schema) => schema.test(
'not-exist',
'NEXT_PUBLIC_ROLLUP_LAYER_NUMBER can only be used with NEXT_PUBLIC_ROLLUP_TYPE',
value => value === undefined,
),
}),
});
@@ -11,5 +11,6 @@ NEXT_PUBLIC_HAS_USER_OPS=true
NEXT_PUBLIC_USER_OPS_INDEXER_API_HOST=https://example.com
NEXT_PUBLIC_NAVIGATION_PROMO_BANNER_CONFIG={'img_url': {'small': 'https://example.com/promo-sm.png', 'large': 'https://example.com/promo-lg.png'}, 'link_url': 'https://example.com'}
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=true
NEXT_PUBLIC_ACCOUNT_API_KEYS_BUTTON=https://example.com
NEXT_PUBLIC_ACCOUNT_AUTH_PROVIDER=dynamic
NEXT_PUBLIC_ACCOUNT_DYNAMIC_ENVIRONMENT_ID=xxx
@@ -1,5 +1,4 @@
NEXT_PUBLIC_ROLLUP_TYPE=arbitrum
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://example.com
NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS=true
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://explorer.duckchain.io','currency':{'name':'Quack','symbol':'QUACK','decimals':18},'isTestnet':true,'id':42,'name':'DuckChain','rpcUrls':['https://rpc.duckchain.io']}
+1 -2
View File
@@ -1,5 +1,6 @@
NEXT_PUBLIC_ROLLBAR_CLIENT_TOKEN=https://rollbar.com
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=true
NEXT_PUBLIC_ACCOUNT_API_KEYS_BUTTON=false
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=xxx
NEXT_PUBLIC_WALLET_CONNECT_FEATURED_WALLET_IDS=['xxx']
NEXT_PUBLIC_RE_CAPTCHA_APP_SITE_KEY=xxx
@@ -11,7 +12,6 @@ NEXT_PUBLIC_AD_TEXT_PROVIDER=coinzilla
NEXT_PUBLIC_AD_BANNER_PROVIDER=slise
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://example.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_SPEC_URL=https://example.com
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=ws
NEXT_PUBLIC_APP_ENV=development
NEXT_PUBLIC_APP_PORT=3000
@@ -86,7 +86,6 @@ NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE=stability
NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS=[{'text':'Swap','icon':'swap','dappId':'uniswap'},{'text':'Payment link','icon':'payment_link','url':'https://example.com'}]
NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG=[{'name': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'}]
NEXT_PUBLIC_GAS_REFUEL_PROVIDER_CONFIG={'name': 'Need gas?', 'dapp_id': 'smol-refuel', 'url_template': 'https://smolrefuel.com/?outboundChain={chainId}&partner=blockscout&utm_source=blockscout&utm_medium=address&disableBridges=true', 'logo': 'https://blockscout-content.s3.amazonaws.com/smolrefuel-logo-action-button.png'}
NEXT_PUBLIC_SAVE_ON_GAS_ENABLED=true
NEXT_PUBLIC_REWARDS_SERVICE_API_HOST=https://example.com
NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS=['widget-1', 'widget-2']
NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://example.com

Some files were not shown because too many files have changed in this diff Show More