Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# You should copy this file to .env.mainnet or .env.testnet and fill in the values.
# then run the proper script `pnpm run dev` (testnet) o `pnpm run dev:mainnet` (mainnet)
# Copy this file to .env.mainnet or .env.testnet and fill in the values.
# Then run: pnpm run dev (testnet) or pnpm run dev:mainnet (mainnet)

NUXT_HUB_PROJECT_KEY=
NUXT_PUBLIC_NIMIQ_NETWORK=test-albatross
ALBATROSS_RPC_NODE_URL=
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
NUXT_PUBLIC_NIMIQ_NETWORK: ${{ vars.NUXT_PUBLIC_NIMIQ_NETWORK }}

- name: Validate JSON files
run: pnpm run validate:json-files github
run: pnpm run validate:json-files

- name: Test
run: pnpm run test
Expand Down
86 changes: 0 additions & 86 deletions .github/workflows/nuxt-hub.yml

This file was deleted.

99 changes: 0 additions & 99 deletions .github/workflows/sync.yaml

This file was deleted.

28 changes: 18 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</p>

<p align="center">
<a href="https://github.com/nimiq/validators-api/actions/workflows/sync.yml" target="_blank"><img src="https://github.com/nimiq/validators-api/actions/workflows/sync.yml/badge.svg" /></a>
<a href="https://github.com/nimiq/validators-api/actions/workflows/ci.yml" target="_blank"><img src="https://github.com/nimiq/validators-api/actions/workflows/ci.yml/badge.svg" /></a>
</p>

<h2 align="center">Dashboards</h2>
Expand Down Expand Up @@ -203,17 +203,25 @@ The system automatically detects the environment and only sends notifications in

## Deployment

The deployment is handled by the [`NuxtHub Action`](./.github/workflows/nuxt-hub.yml).
Deployed via Wrangler CLI with `wrangler.json` config:

There are 4 different environments:
```bash
pnpm build && npx wrangler --cwd .output deploy [-e env]
```

Where `env`: `preview`, `testnet`, or `testnet-preview` (omit for mainnet production).

**Required secrets:** `ALBATROSS_RPC_NODE_URL`, `NUXT_SLACK_WEBHOOK_URL`

**Environments** (configured in `wrangler.json`):

| Nuxt Hub Env | GitHub Env | Dashboard URL | Trigger |
| ------------ | -------------------- | ------------------------------------------------------------------------------ | ----------------------------- |
| `production` | `production-mainnet` | [Validators API Mainnet](https://validators-api-mainnet.pages.dev) | Push to `main` branch |
| `production` | `production-testnet` | [Validators API Testnet](https://validators-api-testnet.pages.dev) | Push to `main` branch |
| `preview` | `preview-mainnet` | [Validators API Mainnet Preview](https://dev.validators-api-mainnet.pages.dev) | Push any commit to any branch |
| `preview` | `preview-testnet` | [Validators API Testnet Preview](https://dev.validators-api-testnet.pages.dev) | Push any commit to any branch |
| Environment | Dashboard URL | Trigger |
| ----------------- | ------------------------------------------------------------------------------ | ------------------ |
| `production` | [Validators API Mainnet](https://validators-api-mainnet.pages.dev) | Push to `main` |
| `preview` | [Validators API Mainnet Preview](https://dev.validators-api-mainnet.pages.dev) | Push to any branch |
| `testnet` | [Validators API Testnet](https://validators-api-testnet.pages.dev) | Push to `main` |
| `testnet-preview` | [Validators API Testnet Preview](https://dev.validators-api-testnet.pages.dev) | Push to any branch |

Each Nuxt Hub environment has its own database, so effectively we have 4 different databases and there are 4 tasks in the [`sync.yml`](./.github/workflows/sync.yml) workflow that are responsible for syncing the data from the Nimiq network to the database.
Each environment has its own D1 database, KV cache, and R2 blob. Sync runs hourly via Cloudflare cron triggers (see `server/tasks/sync/`).

**Write operations to `main` are restricted**, only via PR.
56 changes: 5 additions & 51 deletions app/app.vue
Original file line number Diff line number Diff line change
@@ -1,32 +1,6 @@
<script setup lang="ts">
const { data: status, status: statusRequest, refresh: refreshStatus, error } = await useFetch('/api/v1/status', { server: true, lazy: false })

const debouncedRefresh = useDebounceFn(() => {
refreshStatus()
refreshNuxtData(['/api/v1/validators', '/api/v1/supply', '/api/v1/status'])
}, 300)

const { status: statusSync, data: dataSync, error: syncError, close: closeSync, open: syncData } = useEventSource('/api/v1/sync/sse', [], { immediate: false })

// Check for sync success message and refresh document
watch(() => dataSync.value, (newData) => {
if (newData) {
try {
const parsedData = JSON.parse(newData)
if (parsedData.kind === 'success' && parsedData.message === 'Sync process completed') {
debouncedRefresh()
closeSync()
}
}
catch (e) {
console.error('Failed to parse sync data:', e)
}
}
}, { immediate: true })

// Also maintain the original watch for general updates
watch(() => [dataSync, syncError], debouncedRefresh)

const colorMode = useColorMode()
const toggleDark = () => colorMode.value = colorMode.value === 'light' ? 'dark' : 'light'

Expand Down Expand Up @@ -110,7 +84,7 @@ const currentEnvItem = { branch: gitBranch, network: nimiqNetwork, link: environ
<button i-nimiq:moon @click="() => toggleDark()" />
</header>
<main flex-1>
<div v-if="(!isSynced || error || syncError) && $route.path === '/'" bg="red/8" outline="1.5 ~ red-600" rounded-12 f-p-md text="14 red-1100" nq-prose-compact children:max-w-none f-mb-lg>
<div v-if="(!isSynced || error) && $route.path === '/'" bg="red/8" outline="1.5 ~ red-600" rounded-12 f-p-md text="14 red-1100" nq-prose-compact children:max-w-none f-mb-lg>
<h1 flex="~ items-center gap-12" text-red-1100 f-text-lg>
<div i-nimiq:alert op-70 text-0.9em m-0 />
<template v-if="!isActivitySync">
Expand All @@ -124,7 +98,7 @@ const currentEnvItem = { branch: gitBranch, network: nimiqNetwork, link: environ
The database is not fully synchronized with the blockchain. The API may not return the most recent data.
</p>

<pre v-if="syncError || error" bg="red/6" text="f-2xs red-1100" outline="red/30" w-inherit>{{ JSON.stringify(syncError || error, null, 2) }}</pre>
<pre v-if="error" bg="red/6" text="f-2xs red-1100" outline="red/30" w-inherit>{{ JSON.stringify(error, null, 2) }}</pre>

<template v-if="status">
<h2 f-mt-md text-red-1100 f-text-md flex="~ items-center gap-12">
Expand All @@ -149,29 +123,9 @@ const currentEnvItem = { branch: gitBranch, network: nimiqNetwork, link: environ

<hr f-my-sm border-red-600>

<div flex="~ items-baseline gap-8" mx-0 f-mt-md>
<button
mx-0 nq-pill nq-pill-red outline="~ 1.5 offset--1.5 red-1100/40"
:disabled="statusSync === 'OPEN'"
@click="() => syncData()"
>
<div :class="statusSync === 'OPEN' ? 'i-nimiq:spinner' : 'i-nimiq:restore'" mr-6 />
<span>
{{ statusSync === 'OPEN' ? 'Syncing...' : 'Sync now' }}
</span>
</button>

<button v-if="statusSync === 'OPEN'" mx-0 nq-pill-tertiary @click="() => closeSync()">
<div i-nimiq:cross mr-6 scale-70 />
Cancel
</button>

<div flex-1 flex="~ items-center justify-end">
<code w-max mr-0>SSE: {{ statusSync }}</code>
</div>
</div>

<pre v-if="dataSync" bg="red/6" lh-none text="f-2xs red-1100" outline="red/30" w-inherit max-h-80vh of-auto>{{ dataSync }}</pre>
<p f-mt-md text="f-sm red-1100/80">
<strong>Note:</strong> Data synchronization is handled automatically by scheduled tasks that run hourly. Please wait for the next sync cycle or contact an administrator if the issue persists.
</p>
</div>

<NuxtPage />
Expand Down
6 changes: 6 additions & 0 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,14 @@ export default defineNuxtConfig({
},

nitro: {
preset: 'cloudflare_module',
experimental: {
openAPI: true,
tasks: true,
},
scheduledTasks: {
// Hourly sync: fetch missing epochs and update validator snapshots
'0 * * * *': ['sync:epochs', 'sync:snapshot'],
},
openAPI: {
meta: { title: name, description, version },
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"dev:packages": "nr -C packages -r dev",
"build": "nr -r build && nuxt build",
"generate": "nuxt generate",
"preview": "npx nuxthub preview",
"preview": "npx wrangler --cwd .output dev",
"postinstall": "nuxt prepare",
"prepublishOnly": "nr build",
"typecheck": "nuxt typecheck && nr -r typecheck",
Expand Down
Binary file added public/assets/fonts/firacode-030c1602.woff2
Binary file not shown.
Binary file added public/assets/fonts/firacode-300fab9e.woff2
Binary file not shown.
Binary file added public/assets/fonts/firacode-50d475f6.woff2
Binary file not shown.
Binary file added public/assets/fonts/firacode-6175507f.woff2
Binary file not shown.
Binary file added public/assets/fonts/firacode-7d2b4d2e.woff2
Binary file not shown.
Binary file added public/assets/fonts/firacode-b029b37d.woff2
Binary file not shown.
Binary file added public/assets/fonts/firacode-f5905b7f.woff2
Binary file not shown.
Binary file added public/assets/fonts/mulish-294ced17.woff2
Binary file not shown.
Binary file added public/assets/fonts/mulish-4eb440e1.woff2
Binary file not shown.
Binary file added public/assets/fonts/mulish-78a2d471.woff2
Binary file not shown.
Binary file added public/assets/fonts/mulish-c1a61bc6.woff2
Binary file not shown.
Binary file added public/assets/fonts/mulish-e64de9e7.woff2
Binary file not shown.
33 changes: 0 additions & 33 deletions server/api/[version]/rpc-proxy.post.ts

This file was deleted.

Loading