Skip to content

Commit 89ab2b3

Browse files
authored
Merge pull request #97 from api3dao/dcroote/94-lint
Fixes, lints, prettier, and upgrades
2 parents b18048b + 96904b8 commit 89ab2b3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+3315
-1385
lines changed

.eslintrc.json

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
11
{
2-
"extends": "next/core-web-vitals"
2+
"extends": [
3+
"plugin:@api3/eslint-plugin-commons/universal",
4+
"next/core-web-vitals"
5+
],
6+
"parserOptions": {
7+
"project": ["./tsconfig.json"]
8+
},
9+
"rules": {
10+
// Some of these can be removed with effort (not addressed by --fix)
11+
"@typescript-eslint/ban-ts-comment": "off",
12+
"@typescript-eslint/no-unsafe-function-type": "off",
13+
"@typescript-eslint/prefer-namespace-keyword": "off",
14+
"@typescript-eslint/prefer-nullish-coalescing": "off",
15+
"eqeqeq": "off",
16+
"functional/no-classes": "off",
17+
"import/no-default-export": "off",
18+
"no-console": "off",
19+
"prefer-named-capture-group": "off",
20+
"prefer-template": "off",
21+
"radix": "off",
22+
"unicorn/filename-case": "off",
23+
"unicorn/no-array-callback-reference": "off",
24+
"unicorn/no-array-push-push": "off",
25+
"unicorn/no-await-expression-member": "off",
26+
"unicorn/number-literal-case": "off",
27+
"unicorn/prefer-code-point": "off",
28+
"unicorn/prefer-string-slice": "off",
29+
"unicorn/prefer-switch": "off"
30+
}
331
}

.github/ISSUE_TEMPLATE/community-bug-bounty.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
---
22
name: Community bug bounty
33
about: Submissions for the community bug bounty
4-
title: ''
4+
title: ""
55
labels: cbb
6-
assignees: ''
7-
6+
assignees: ""
87
---
98

109
## Steps to reproduce

.github/workflows/docker-image.yml

Lines changed: 0 additions & 41 deletions
This file was deleted.

.github/workflows/main.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Continuous Build
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
9+
jobs:
10+
lint:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- name: Setup Node.js
15+
uses: actions/setup-node@v4
16+
with:
17+
node-version: "20"
18+
cache: "yarn"
19+
- name: Install dependencies
20+
run: yarn install --frozen-lockfile
21+
- name: Lint
22+
run: yarn lint
23+
24+
only_build:
25+
runs-on: ubuntu-latest
26+
if: github.ref != 'refs/heads/main'
27+
steps:
28+
- uses: actions/checkout@v4
29+
- name: Build the Docker image
30+
run: docker build . --file Dockerfile --tag api3tracker:latest
31+
32+
build_deploy:
33+
runs-on: ubuntu-latest
34+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
35+
env:
36+
SSH_HOST: ${{ secrets.SSH_HOST }}
37+
SSH_REMOTE_PATH: /home/ubuntu/src/github.com/api3dao/api3-tracker/terraform/workspaces/api3tracker-prod
38+
steps:
39+
- name: Install SSH Key
40+
uses: shimataro/ssh-key-action@v2
41+
with:
42+
key: ${{ secrets.SSH_PRIVATE_KEY }}
43+
known_hosts: /dev/null
44+
- uses: actions/checkout@v4
45+
- name: Build the Docker image
46+
run: docker build . --file Dockerfile --tag api3tracker:latest
47+
- name: Push main Docker image
48+
run: docker save api3tracker:latest | bzip2 | ssh -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/dev/null $SSH_HOST 'bunzip2 -d | docker load'
49+
- name: Apply Terraform plan
50+
run: |
51+
echo "::add-mask::$TF_VAR_API3TRACKER_ENDPOINT"
52+
echo "::add-mask::$TF_VAR_API3TRACKER_ARCHIVE_ENDPOINT"
53+
export REMOTE_CMD="cd $SSH_REMOTE_PATH && terraform init && terraform apply -auto-approve && docker system prune -af"
54+
ssh -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/dev/null $SSH_HOST bash -c '"'$REMOTE_CMD'"'

Dockerfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
FROM node:16.16-alpine3.15 AS dependencies
1+
FROM node:20.18-alpine3.19 AS dependencies
22
WORKDIR /app
33
COPY package.json yarn.lock ./
44
RUN yarn install --frozen-lockfile
55

6-
FROM node:16.16-alpine3.15 AS builder
6+
FROM node:20.18-alpine3.19 AS builder
77
WORKDIR /app
88
COPY . .
99
COPY --from=dependencies /app/node_modules ./node_modules
1010
RUN yarn prisma generate
1111
RUN yarn build
1212
RUN yarn next telemetry disable
1313

14-
FROM node:16.16-alpine3.15
14+
FROM node:20.18-alpine3.19
1515
WORKDIR /app
1616
ENV NODE_ENV=production
1717

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@ The services are:
2020
```
2121

2222
Containers:
23+
2324
- api3tracker: The FE and BE-service
2425
- postgres: The database the FE and BE rely on
2526
- traefik: A load balancer that encrypts HTTP responses (using the CF origin server key pair)
2627
- postgres-exporter: a service that exports the database as a backup on an interval
2728

2829
Host services:
2930
The host OS also runs some cron services, these are:
31+
3032
```bash
3133
*/10 * * * * root cd /home/ubuntu/src/github.com/api3dao/api3-tracker/terraform/workspaces/api3tracker-prod && ./bin/job_logs_download.sh >> /var/log/api3-logs-download.log 2>&1
3234
15,45 * * * * root cd /home/ubuntu/src/github.com/api3dao/api3-tracker/terraform/workspaces/api3tracker-prod && ./bin/job_supply_download.sh >> /var/log/api3-supply-download.log 2>&1
@@ -37,36 +39,45 @@ The host OS also runs some cron services, these are:
3739
```
3840

3941
## Local developement using Docker
42+
4043
Developers can run some or all services locally using Docker Swarm, or even bare-bones, without containerisation.
4144

4245
One combination is running just postgres locally using Docker, eg:
46+
4347
```bash
4448
docker run --rm -ti -p 5432:5432 postgres:15
4549
```
50+
4651
and then running the FE and BE services directly (refer to Cron jobs below and `yarn next dev` in `package.json`).
4752

4853
Alternatively, one can run services using Docker Swarm, but this lacks hot-reloading.
4954

5055
### Local development using Docker Swarm
56+
5157
If you haven't already enabled Swarm mode on your Docker instance, do so now (only has to be done once):
58+
5259
```bash
5360
docker swarm init
5461
```
62+
5563
The result of the above command can be ignored.
5664

5765
Build the FE/BE image:
66+
5867
```bash
5968
docker build -t api3dao/api3-tracker:latest .
6069
```
6170

6271
Run the stack:
72+
6373
```bash
6474
docker stack deploy -c dev-tools/docker-compose.yml tracker-stack
6575
```
6676

6777
If all goes well the application will be served at http://localhost:3000
6878

6979
Some commands for visualising the services:
80+
7081
```bash
7182
docker ps # all docker containers
7283
docker service ls # all swarm services
@@ -75,11 +86,13 @@ docker stack rm tracker-stack # tear down the stack
7586
```
7687

7788
Initialise the DB:
89+
7890
```bash
7991
DATABASE_URL="postgres://postgres:[email protected]:5432/postgres?sslmode=disable" yarn prisma migrate deploy
8092
```
8193

8294
Cron jobs (unwrapped versions of cronjobs):
95+
8396
```bash
8497
DATABASE_URL="postgres://postgres:[email protected]:5432/postgres?sslmode=disable" TS_NODE_PROJECT=./tsconfig.cli.json yarn ts-node cli.ts logs download
8598
DATABASE_URL="postgres://postgres:[email protected]:5432/postgres?sslmode=disable" TS_NODE_PROJECT=./tsconfig.cli.json yarn ts-node cli.ts supply download

cli.ts

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import yargs from "yargs/yargs";
21
import { hideBin } from "yargs/helpers";
2+
import yargs from "yargs/yargs";
3+
4+
import { ENS } from "./services/ens";
35
import { EthereumPrice } from "./services/price";
6+
import { Shares } from "./services/shares";
7+
import { Supply } from "./services/supply";
48
import { Events } from "./services/sync";
59
import { Treasuries } from "./services/treasuries";
6-
import { Supply } from "./services/supply";
7-
import { Shares } from "./services/shares";
8-
import { ENS } from "./services/ens";
910

1011
yargs(hideBin(process.argv))
1112
.env("API3TRACKER")
@@ -26,13 +27,13 @@ yargs(hideBin(process.argv))
2627
});
2728
},
2829
handler: async ({ endpoint, sub }) => {
29-
if (sub == "reset") {
30+
if (sub === "reset") {
3031
await ENS.resetAll();
3132
console.log("ENS cache was deleted");
32-
} else if (sub == "import") {
33+
} else if (sub === "import") {
3334
const total = await ENS.importLocal("./.cache");
3435
console.log(`saved ${total} new ENS records`);
35-
} else if (sub == "download") {
36+
} else if (sub === "download") {
3637
const total = await ENS.download(endpoint);
3738
console.log(`saved ${total} new ENS records`);
3839
} else {
@@ -52,7 +53,8 @@ yargs(hideBin(process.argv))
5253
describe: `logs subcommand - reset or download new`,
5354
})
5455
.option("coingecko_host", {
55-
default: process.env.API3TRACKER_COINGECKO_HOST || "api.coingecko.com",
56+
default:
57+
process.env.API3TRACKER_COINGECKO_HOST || "api.coingecko.com",
5658
type: "string",
5759
description: "Host to use for CoinGecko API",
5860
})
@@ -62,11 +64,12 @@ yargs(hideBin(process.argv))
6264
description: "API KEY to be used for CoinGecko-compatible API",
6365
});
6466
},
67+
// eslint-disable-next-line camelcase
6568
handler: async ({ endpoint, sub, coingecko_host, coingecko_api_key }) => {
66-
if (sub == "reset") {
69+
if (sub === "reset") {
6770
await Events.resetAll();
6871
console.log("events were deleted");
69-
} else if (sub == "download") {
72+
} else if (sub === "download") {
7073
const priceReader = EthereumPrice(coingecko_host, coingecko_api_key);
7174
const total = await Events.download(endpoint, priceReader);
7275
console.log(`downloaded ${total} new events`);
@@ -103,21 +106,21 @@ yargs(hideBin(process.argv))
103106
});
104107
},
105108
handler: async ({ endpoint, sub, member, tag, rpsLimit }) => {
106-
if (sub == "reset") {
109+
if (sub === "reset") {
107110
await Shares.resetAll();
108111
console.log("shares cache records were deleted");
109-
} else if (sub == "votings") {
110-
const total = await Shares.downloadVotings(endpoint);
112+
} else if (sub === "votings") {
113+
const total = await Shares.downloadVotings();
111114
console.log(`updated ${total} new records`);
112-
} else if (sub == "totals") {
115+
} else if (sub === "totals") {
113116
await Shares.recalculateTotals();
114-
} else if (sub == "download") {
115-
if (!tag) {
116-
const total = await Shares.download(endpoint, member, rpsLimit);
117-
console.log(`downloaded ${total} new records`);
118-
} else {
117+
} else if (sub === "download") {
118+
if (tag) {
119119
const total = await Shares.downloadMembers(endpoint, tag, rpsLimit);
120120
console.log(`scanned ${total} members`);
121+
} else {
122+
const total = await Shares.download(endpoint, member, rpsLimit);
123+
console.log(`downloaded ${total} new records`);
121124
}
122125
} else {
123126
console.error("ERROR: Unknown sub-command");
@@ -176,10 +179,10 @@ yargs(hideBin(process.argv))
176179
stopBlock,
177180
useArchive,
178181
}) => {
179-
if (sub == "reset") {
182+
if (sub === "reset") {
180183
await Events.resetState();
181184
console.log("Events state was reset");
182-
} else if (sub == "next") {
185+
} else if (sub === "next") {
183186
const verbose = {
184187
blocks: verboseBlocks || false,
185188
epochs: verboseEpochs || false,
@@ -194,10 +197,10 @@ yargs(hideBin(process.argv))
194197
endpoint,
195198
verbose,
196199
termination,
197-
useArchive
200+
useArchive,
198201
);
199202
console.log(`${blocks} blocks were processed`);
200-
} else if (sub == "update") {
203+
} else if (sub === "update") {
201204
const verbose = {
202205
blocks: verboseBlocks || false,
203206
epochs: verboseEpochs || false,
@@ -212,7 +215,7 @@ yargs(hideBin(process.argv))
212215
endpoint,
213216
verbose,
214217
termination,
215-
useArchive
218+
useArchive,
216219
);
217220
console.log(`${blocks} blocks were processed`);
218221
} else {
@@ -232,10 +235,10 @@ yargs(hideBin(process.argv))
232235
});
233236
},
234237
handler: async ({ endpoint, sub }) => {
235-
if (sub == "reset") {
238+
if (sub === "reset") {
236239
await Supply.resetAll();
237240
console.log("Supply history was reset");
238-
} else if (sub == "download") {
241+
} else if (sub === "download") {
239242
await Supply.download(endpoint);
240243
console.log("Supply history was updated");
241244
} else {
@@ -255,10 +258,10 @@ yargs(hideBin(process.argv))
255258
});
256259
},
257260
handler: async ({ endpoint, sub }) => {
258-
if (sub == "reset") {
261+
if (sub === "reset") {
259262
await Treasuries.resetAll();
260263
console.log("Treasuries state was reset");
261-
} else if (sub == "download") {
264+
} else if (sub === "download") {
262265
const total = await Treasuries.download(endpoint);
263266
console.log(`downloaded state of ${total} balances`);
264267
} else {

components/ContractsList.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import React from "react";
2-
import { IContract } from "../services/types";
2+
3+
import { type IContract } from "../services/types";
4+
35
import { BorderedPanel } from "./BorderedPanel";
46
import { Address } from "./Ethscan";
57

0 commit comments

Comments
 (0)