diff --git a/buildkite/src/Jobs/Release/LeaderboardArtifact.dhall b/buildkite/src/Jobs/Release/LeaderboardArtifact.dhall deleted file mode 100644 index 2482ee5b0d3..00000000000 --- a/buildkite/src/Jobs/Release/LeaderboardArtifact.dhall +++ /dev/null @@ -1,54 +0,0 @@ -let Cmd = ../../Lib/Cmds.dhall - -let S = ../../Lib/SelectFiles.dhall - -let Pipeline = ../../Pipeline/Dsl.dhall - -let PipelineTag = ../../Pipeline/Tag.dhall - -let JobSpec = ../../Pipeline/JobSpec.dhall - -let Command = ../../Command/Base.dhall - -let Size = ../../Command/Size.dhall - -let DockerImage = ../../Command/DockerImage.dhall - -let spec = - DockerImage.ReleaseSpec::{ - , service = "leaderboard" - , step_key = "leaderboard-docker-image" - } - -in Pipeline.build - Pipeline.Config::{ - , spec = JobSpec::{ - , dirtyWhen = - [ S.strictlyStart - (S.contains "buildkite/src/Jobs/Release/LeaderboardArtifact") - , S.strictlyStart (S.contains "frontend/leaderboard") - ] - , path = "Release" - , name = "LeaderboardArtifact" - , tags = - [ PipelineTag.Type.Long - , PipelineTag.Type.Release - , PipelineTag.Type.Stable - ] - } - , steps = - [ Command.build - Command.Config::{ - , commands = - [ Cmd.run - "echo export MINA_VERSION=\$(cat frontend/leaderboard/package.json | jq '.version') > LEADERBOARD_DEPLOY_ENV" - ] - , label = "Setup Leaderboard docker image deploy environment" - , key = "setup-deploy-env" - , target = Size.Small - , artifact_paths = - [ S.contains "frontend/leaderboard/package.json" ] - } - , DockerImage.generateStep spec - ] - } diff --git a/flake.nix b/flake.nix index 95152c68f25..c15c3b87951 100644 --- a/flake.nix +++ b/flake.nix @@ -323,7 +323,7 @@ granular = ocamlPackages.default; default = ocamlPackages.mina; inherit (pkgs) - libp2p_helper kimchi_bindings_stubs snarky_js leaderboard validation + libp2p_helper kimchi_bindings_stubs snarky_js validation trace-tool zkapp-cli; inherit (dockerImages) mina-image-slim mina-image-full mina-archive-image-full diff --git a/frontend/leaderboard/.gitignore b/frontend/leaderboard/.gitignore deleted file mode 100644 index 76eae69bb3a..00000000000 --- a/frontend/leaderboard/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.merlin -.next -lib/ -*.bs.js -.bsb.lock -yarn-error.log diff --git a/frontend/leaderboard/.npmignore b/frontend/leaderboard/.npmignore deleted file mode 100644 index 1b2beb9aa4c..00000000000 --- a/frontend/leaderboard/.npmignore +++ /dev/null @@ -1,6 +0,0 @@ -.merlin -.next -.bsb.lock -/src -/lib/bs -yarn-error.log diff --git a/frontend/leaderboard/Dockerfile b/frontend/leaderboard/Dockerfile deleted file mode 100644 index a18a6c8bb1d..00000000000 --- a/frontend/leaderboard/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM node:12.9.0-stretch-slim - -WORKDIR /code - -COPY package.json yarn.lock ./ - -RUN yarn && \ - yarn cache clean - -COPY bsconfig.json ./ -COPY ./src ./src - -RUN yarn build - -ENTRYPOINT ["bash", "-c"] -CMD ["node lib/js/src/Main.bs.js"] \ No newline at end of file diff --git a/frontend/leaderboard/README.md b/frontend/leaderboard/README.md deleted file mode 100644 index 282ac28793f..00000000000 --- a/frontend/leaderboard/README.md +++ /dev/null @@ -1,9 +0,0 @@ -## Leaderboard Project - -The Leaderboard project is designed to collect metrics on users who participate in various testnets and award points based on the challenges they complete. - -## Environment Variables - -`GOOGLE_APPLICATION_CREDENTIALS`: The Google credentials used to access the Leaderboard sheets -`SPREADSHEET_ID`: The Leaderboard Google Sheets ID. -`PGCONN`: The database URL that points to the archive node. diff --git a/frontend/leaderboard/bsconfig.json b/frontend/leaderboard/bsconfig.json deleted file mode 100644 index d4149e7c9a5..00000000000 --- a/frontend/leaderboard/bsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "leaderboard", - "sources": [ - { - "dir": "src", - "subdirs": true - } - ], - "bs-dependencies": ["bsc-stdlib-polyfill", "bs-fetch"], - "reason": { - "react-jsx": 3 - }, - "package-specs": { - "module": "commonjs" - }, - "suffix": ".bs.js", - "bsc-flags": ["-bs-super-errors", "-open BscStdlibPolyfill"], - "refmt": 3 -} diff --git a/frontend/leaderboard/helm/.helmignore b/frontend/leaderboard/helm/.helmignore deleted file mode 100644 index 50af0317254..00000000000 --- a/frontend/leaderboard/helm/.helmignore +++ /dev/null @@ -1,22 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ diff --git a/frontend/leaderboard/helm/CHANGELOG.md b/frontend/leaderboard/helm/CHANGELOG.md deleted file mode 100644 index 24e51c23129..00000000000 --- a/frontend/leaderboard/helm/CHANGELOG.md +++ /dev/null @@ -1,10 +0,0 @@ -0.1.10: ------- -- enable Artifacthub repository hosting *changes* annotations -- add CHANGELOG.md for chart version => changelog tracking -0.1.11: ------- -- removed duplicate instance of archive node that was used to support testworld network restart -0.1.12: ------- -- moved SPREADSHEET_ID env var to helm chart from Dockerfile diff --git a/frontend/leaderboard/helm/Chart.yaml b/frontend/leaderboard/helm/Chart.yaml deleted file mode 100644 index b80f9719d78..00000000000 --- a/frontend/leaderboard/helm/Chart.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: v2 -name: leaderboard -description: A Helm chart for Mina Protocol's Testnet leaderboard service -type: application -version: 0.1.10 -appVersion: 1.16.0 -annotations: - artifacthub.io/changes: | - - enable Artifacthub repository hosting *changes* annotations - - add CHANGELOG.md for chart version => changelog tracking -icon: https://storage.googleapis.com/coda-charts/Mina_Icon_Secondary_RGB_Black.png -keywords: -- coda protocol -- testnet -- leaderboard -- points -- mina -- testnet -home: https://minaprotocol.com/ -sources: -- https://github.com/MinaProtocol/mina/tree/develop/frontend/leaderboard/helm diff --git a/frontend/leaderboard/helm/Makefile b/frontend/leaderboard/helm/Makefile deleted file mode 120000 index 3256dff2eb8..00000000000 --- a/frontend/leaderboard/helm/Makefile +++ /dev/null @@ -1 +0,0 @@ -../../../helm/common/Makefile \ No newline at end of file diff --git a/frontend/leaderboard/helm/README.md b/frontend/leaderboard/helm/README.md deleted file mode 100644 index f5baf1485bb..00000000000 --- a/frontend/leaderboard/helm/README.md +++ /dev/null @@ -1,39 +0,0 @@ -## Introduction - -This chart bootstraps a Mina Protocol Testnet leaderboard service - -## Add Mina Helm chart repository: - - ```console - helm repo add mina https://coda-charts.storage.googleapis.com - helm repo update - ``` - -## Configuration - -The following table lists the configurable parameters of the `leaderboard` chart and its default values. - -### Required Settings - -Parameter | Description ---- | --- -`postgresql.postgresHost` | Mina protocol Postgres SQL archive host address -`postgresql.postgresPort` | Mina protocol Postgres SQL archive listening port -`volume.secretName` | Leaderboard credentials information | `none` - -### Optional Settings - -Parameter | Description | Default ---- | --- | --- -`leaderboard.name` | Mina protocol leaderboard service/cron job name | `leaderboard-cron` -`leaderboard.containerName` | name of container to provision for leaderboard job | `leaderboard` -`leaderboard.image` | Mina protocol leaderboard container image | `gcr.io/o1labs-192920/leaderboard` -`leaderboard.schedule` | frequency with which to execute leaderboard operations | `@hourly` -`postgresql.postgresqlUsername` | Mina protocol Postgres SQL archive username | `none` -`postgresql.postgresqlPassword` | Mina protocol Postgres SQL archive password | `none` - -## leaderboard launch examples - -```console -helm install leaderboard -``` diff --git a/frontend/leaderboard/helm/templates/leaderboard-cron-job.yaml b/frontend/leaderboard/helm/templates/leaderboard-cron-job.yaml deleted file mode 100644 index 724a3b79802..00000000000 --- a/frontend/leaderboard/helm/templates/leaderboard-cron-job.yaml +++ /dev/null @@ -1,29 +0,0 @@ -apiVersion: batch/v1 -kind: CronJob -metadata: - name: {{ .Values.leaderboard.name }} -spec: - schedule: "{{ .Values.leaderboard.schedule }}" - jobTemplate: - spec: - template: - spec: - restartPolicy: Never - volumes: - - name: {{ .Values.volume.name }} - secret: - secretName: {{ .Values.volume.secretName }} - containers: - - name: {{ .Values.leaderboard.containerName }} - image: {{ .Values.leaderboard.image }} - imagePullPolicy: Always - env: - - name: PGCONN - value: postgres://{{ .Values.postgresql.postgresqlUsername }}:{{ .Values.postgresql.postgresqlPassword }}@{{ .Values.postgresql.postgresHost }}:{{ .Values.postgresql.postgresPort }}/{{ .Values.postgresql.postgresDB }} - - name: SPREADSHEET_ID - value: {{ .Values.googleSheets.spreadsheetId }} - volumeMounts: - - name: {{ .Values.volume.name }} - mountPath: {{ .Values.volume.mountPath }} - subPath: {{ .Values.volume.subPath }} - readOnly: true \ No newline at end of file diff --git a/frontend/leaderboard/helm/values.yaml b/frontend/leaderboard/helm/values.yaml deleted file mode 100644 index f685fbcb406..00000000000 --- a/frontend/leaderboard/helm/values.yaml +++ /dev/null @@ -1,21 +0,0 @@ -leaderboard: - name: "leaderboard-cron" - containerName: "leaderboard" - image: "gcr.io/o1labs-192920/leaderboard" - schedule: "@hourly" - -volume: - name: "credentials" - secretName: "sheets-credentials" - mountPath: "/code/google_sheets_credentials.json" - subPath: "google_sheets_credentials.json" - -postgresql: - postgresqlPassword: "foobar" - postgresqlUsername: "postgres" - postgresHost: "postgresql" - postgresPort: "5432" - postgresDB: "archive" - -googleSheets: - spreadsheetId: "1Nq_Y76ALzSVJRhSFZZm4pfuGbPkZs2vTtCnVQ1ehujE" diff --git a/frontend/leaderboard/package.json b/frontend/leaderboard/package.json deleted file mode 100644 index 1e08542f5e0..00000000000 --- a/frontend/leaderboard/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "leaderboard", - "version": "1.0.0", - "scripts": { - "dev": "bsb -clean-world -make-world -w", - "build": "bsb -make-world", - "clean": "bsb -clean-world", - "reformat": "bsrefmt --in-place src/**/*.re", - "start": "node ./lib/js/src/Main.bs.js" - }, - "license": "ISC", - "dependencies": { - "@googleapis/sheets": "^0.3.0", - "bs-fetch": "^0.5.0", - "bsc-stdlib-polyfill": "Schmavery/bsc-stdlib-polyfill", - "isomorphic-unfetch": "^3.0.0", - "pg": "^8.3.0" - }, - "devDependencies": { - "bs-platform": "7.0.0-dev.1" - } -} diff --git a/frontend/leaderboard/src/Bindings.re b/frontend/leaderboard/src/Bindings.re deleted file mode 100644 index bceba0581b0..00000000000 --- a/frontend/leaderboard/src/Bindings.re +++ /dev/null @@ -1,80 +0,0 @@ -module Postgres = { - type pool; - type config = { - connectionString: string, - connectionTimeoutMillis: int, - }; - - type dbResult = {rows: array(Js.Json.t)}; - - [@bs.module "pg"] [@bs.new] external makePool: config => pool = "Pool"; - - [@bs.send] - external query: - (pool, string, (~error: Js.Nullable.t(string), ~res: dbResult) => unit) => - unit = - "query"; - - [@bs.send] external endPool: pool => unit = "end"; -}; - -module GoogleSheets = { - type client; - type sheets; - type token = Js.Json.t; - type cellData; - type sheetsUploadData = {values: array(array(string))}; - type sheetsData = {values: array(array(cellData))}; - type res = {data: sheetsData}; - - type authConfig = {scopes: array(string)}; - - type sheetsConfig = { - version: string, - auth: client, - }; - - type sheetsQuery = { - spreadsheetId: string, - range: string, - valueRenderOption: string, - }; - - type sheetsUpdate = { - spreadsheetId: string, - range: string, - valueInputOption: string, - resource: sheetsUploadData, - }; - - [@bs.scope ("auth")] [@bs.new] [@bs.module "@googleapis/sheets"] - external googleAuth: authConfig => client = "GoogleAuth"; - - [@bs.module "@googleapis/sheets"] - external sheets: sheetsConfig => sheets = ""; - - [@bs.send] - external getClient: - (client, (~error: Js.Nullable.t(string), ~token: token) => unit) => unit = - "getClient"; - - [@bs.scope ("spreadsheets", "values")] [@bs.send] - external get: - ( - sheets, - sheetsQuery, - (~error: Js.Nullable.t(string), ~res: res) => unit - ) => - unit = - "get"; - - [@bs.scope ("spreadsheets", "values")] [@bs.send] - external update: - ( - sheets, - sheetsUpdate, - (~error: Js.Nullable.t(string), ~res: res) => unit - ) => - unit = - "update"; -}; diff --git a/frontend/leaderboard/src/Challenges.re b/frontend/leaderboard/src/Challenges.re deleted file mode 100644 index 86c8d30ef50..00000000000 --- a/frontend/leaderboard/src/Challenges.re +++ /dev/null @@ -1,112 +0,0 @@ -/* - Challenges.re has the responsibilities of taking a Map of public keys to - metricRecords and compute a new Map that contains a public key to - points where points is a number value (either Int64 or int). - - Points are rewarded based on completing challenges that are previously defined - by O(1) community managers. The challenges that are supported are defined in - calculatePoints() - - The data visualized for a Map is as follows, where x is some number value: - - "public_key1": x - - All the challenges to be computed are specified in calculatePoints(). - calculatePoints() is invoked in Upload.re where the points are computed - and then uploaded to the Leaderboard Google Sheets. - */ - -module StringMap = Map.Make(String); - -let echoServiceChallenge = metricsMap => { - metricsMap - |> Points.addPointsToUsersWithAtleastN( - (metricRecord: Types.Metrics.t) => - metricRecord.transactionsReceivedByEcho, - 1, - 1000, - ); -}; - -let coinbaseReceiverChallenge = (points, metricsMap) => { - metricsMap - |> StringMap.fold( - (key, metric: Types.Metrics.t, map) => { - switch (metric.coinbaseReceiver) { - | Some(metricValue) => - metricValue ? StringMap.add(key, points, map) : map - | None => map - } - }, - StringMap.empty, - ); -}; - -let snarkFeeChallenge = metricsMap => { - Js.log("SNARK Fee Challenge"); - Points.applyTopNPoints( - [| - (0, 6500), // 1st place: 6500 pts - (1, 5000), // 2nd place: 5000 pts - (2, 4000), // 3rd place: 4000 pts - (51, 3500), // Top 50: 3500 pts. - (101, 3000), // Top 100: 3000 pts - (251, 2000), // Top 250: 2000 pts - (501, 1000), // Top 500: 1000 pts - (751, 750), // Top 750: 750 pts - (1001, 500) // Top 1000: 500 pts - |], - metricsMap, - (metricRecord: Types.Metrics.t) => metricRecord.snarkFeesCollected, - compare, - ); -}; - -let blocksChallenge = metricsMap => { - Js.log("Blocks Challenge"); - Points.applyTopNPoints( - [| - (0, 6500), // 1st place: 6500 pts - (1, 5000), // 2nd place: 5000 pts - (2, 4000), // 3rd place: 4000 pts - (51, 3500), // Top 50: 3500 pts. - (101, 3000), // Top 100: 3000 pts - (251, 2000), // Top 250: 2000 pts - (501, 1000), // Top 500: 1000 pts - (751, 750), // Top 750: 750 pts - (1001, 500) // Top 1000: 500 pts - |], - metricsMap, - (metricRecord: Types.Metrics.t) => metricRecord.blocksCreated, - compare, - ); -}; - -let sendMinaChallenge = metricsMap => { - Js.log("Send Mina Challenge"); - Points.applyTopNPoints( - [| - (0, 6500), // 1st place: 6500 pts - (1, 5000), // 2nd place: 5000 pts - (2, 4000), // 3rd place: 4000 pts - (51, 3500), // Top 50: 3500 pts. - (101, 3000), // Top 100: 3000 pts - (251, 2000), // Top 250: 2000 pts - (501, 1000), // Top 500: 1000 pts - (751, 750), // Top 750: 750 pts - (1001, 500) // Top 1000: 500 pts - |], - metricsMap, - (metricRecord: Types.Metrics.t) => metricRecord.transactionSent, - compare, - ); -}; - -let calculatePoints = (challengeName, metricsMap) => { - switch (String.lowercase_ascii(challengeName)) { - | "produce blocks on mina" => Some(blocksChallenge(metricsMap)) - | "produce & sell snarks" => Some(snarkFeeChallenge(metricsMap)) - | "send transactions" => Some(sendMinaChallenge(metricsMap)) - | _ => None - }; -}; diff --git a/frontend/leaderboard/src/Main.re b/frontend/leaderboard/src/Main.re deleted file mode 100644 index 1c94ae85c89..00000000000 --- a/frontend/leaderboard/src/Main.re +++ /dev/null @@ -1,55 +0,0 @@ -/* - Main.re is the entry point of the leaderboard project. - - Main.re has the responsibilities of being the driver to upload all necessary - information to the google sheets. - - Additionally, Main.re expects to have the spreadsheet id, and postgres - connection string available in the form of environment variables. */ - -let getEnvOrFail = name => - switch (Js.Dict.get(Node.Process.process##env, name)) { - | Some(value) => value - | None => failwith({j|Couldn't find env var: `$name`|j}) - }; - -/* The Google Sheets API expects the credentials to be a local file instead of a parameter - Thus, we set an environment variable indicating it's path. - */ -Node.Process.putEnvVar( - "GOOGLE_APPLICATION_CREDENTIALS", - "./google_sheets_credentials.json", -); - -let spreadsheetId = getEnvOrFail("SPREADSHEET_ID"); -let pgConnection = getEnvOrFail("PGCONN"); - -let main = () => { - open Js.Promise; - let pool = Postgres.createPool(pgConnection); - - Metrics.calculateMetricsAndUploadPoints(pool, spreadsheetId) - |> then_(_ => { - Postgres.makeQuery(pool, Postgres.getBlockHeight) - |> then_(blockHeight => { - switch (Postgres.getRow(blockHeight, "max", 0)) { - | Some(height) => - UploadLeaderboardData.uploadData(spreadsheetId, height) - | None => () - }; - resolve(); - }) - |> then_(_ => { - UploadLeaderboardData.uploadUserProfileData(spreadsheetId); - resolve(); - }) - |> then_(_ => { - Postgres.endPool(pool); - resolve(); - }) - |> ignore; - resolve(); - }); -}; - -main(); diff --git a/frontend/leaderboard/src/Metrics.re b/frontend/leaderboard/src/Metrics.re deleted file mode 100644 index 26fc91f9801..00000000000 --- a/frontend/leaderboard/src/Metrics.re +++ /dev/null @@ -1,251 +0,0 @@ -/* - Metrics.re has the responsibilities of making all the necessary queries to - the archive node to gather user metrics on testnet challenges and transforming - that data into a map of public_keys to metricRecord types. - - The data visualized for a Map is as follows, where x is some int value: - - "public_key1": { - blocksCreated: x, - transactionSent: x, - snarkFeesCollected: x, - highestSnarkFeeCollected: x, - transactionsReceivedByEcho: x, - coinbaseReceiver: x, - createAndSendToken: x, - } - - All the metrics to be computed are specified in calculateMetrics(). Each - metric to be computed is contained within it's own Map structure and is then - combined together with all other metric Maps. - */ - -module StringMap = Map.Make(String); - -let echoBotPublicKeys = [ - "B62qndJi5mnRoBZ8SAYDM1oR2SgAk5WpZC8hGpJUZ4e64kDHGbFMeLJ", -]; - -let excludePublicKeys = []; - -// Helper functions for gathering metrics -let printMap = map => { - map - |> StringMap.mapi((key, value) => { - Js.log(key); - Js.log(value); - }); -}; - -let convertDBRowsToMap = (a, f) => { - a - |> Array.fold_left( - (map, info) => {StringMap.add(info[0], f(info[1]), map)}, - StringMap.empty, - ); -}; - -let mergeMetricsMaps = (metricMap, oldMetricMap, f) => { - let oldMetricsMap = - StringMap.mapi( - (key, challengeMetric) => - if (StringMap.mem(key, metricMap)) { - f(StringMap.find(key, metricMap), challengeMetric); - } else { - challengeMetric; - }, - oldMetricMap, - ); - - StringMap.mapi( - (key, challengeMetric) => - if (StringMap.mem(key, oldMetricsMap)) { - StringMap.find(key, oldMetricsMap); - } else { - challengeMetric; - }, - metricMap, - ); -}; - -let mergeIntMap = (challenges, challengesOld) => { - let challengeMap = convertDBRowsToMap(challenges, int_of_string); - let challengeMapOld = convertDBRowsToMap(challengesOld, int_of_string); - mergeMetricsMaps(challengeMap, challengeMapOld, (a, b) => a + b); -}; - -let mergeInt64Map = (challenges, challengesOld) => { - let challengeMap = convertDBRowsToMap(challenges, Int64.of_string); - let challengeMapOld = convertDBRowsToMap(challengesOld, Int64.of_string); - mergeMetricsMaps(challengeMap, challengeMapOld, Int64.add); -}; - -/** - * Makes a query to the archive node for the specified challenge. - * Returns a 2d array where the first column is the public keys of - * users and the second column being the returned query data. - * - */ -let getPromisifiedChallenge = (users, pgPool, f, index, columnName) => { - Js.Promise.( - users - |> then_(users => { - users - |> Array.map(user => { - Postgres.makeQuery(pgPool, f(user)) - |> then_(row => { - ( - switch (Postgres.getRow(row, columnName, index)) { - | Some(dbResult) => Some([|user, dbResult|]) - | None => None - } - ) - |> resolve - }) - }) - |> resolve - }) - ); -}; - -let filterNonePromises = challenges => { - Js.Promise.( - challenges - |> then_(challenge => { - let result = - challenge - |> all - |> then_(rows => { - Array.fold_left( - (values, row) => { - switch (row) { - | Some(row) => Array.append(values, [|row|]) - | None => values - } - }, - [||], - rows, - ) - |> resolve - }); - resolve(result); - }) - ); -}; - -let calculateMetrics = - (users, blocksChallenge, snarkChallenge, transactionChallenge) => { - let usersMap = - Array.fold_left( - (map, user) => {StringMap.add(user, (), map)}, - StringMap.empty, - users, - ); - - let highestSnarkFeeCollected = StringMap.empty; - let transactionsReceivedByEcho = StringMap.empty; - let coinbaseReceiverChallenge = StringMap.empty; - - usersMap - |> StringMap.filter((key, _) => {!List.mem(key, excludePublicKeys)}) - |> StringMap.mapi((key, _) => - { - Types.Metrics.blocksCreated: StringMap.find_opt(key, blocksChallenge), - transactionSent: StringMap.find_opt(key, transactionChallenge), - snarkFeesCollected: StringMap.find_opt(key, snarkChallenge), - highestSnarkFeeCollected: - StringMap.find_opt(key, highestSnarkFeeCollected), - transactionsReceivedByEcho: - StringMap.find_opt(key, transactionsReceivedByEcho), - coinbaseReceiver: StringMap.find_opt(key, coinbaseReceiverChallenge), - } - ); -}; - -let calculateMetricsAndUploadPoints = (pgPool, spreadsheetId) => { - open Js.Promise; - let users = - Postgres.makeQuery(pgPool, Postgres.getUsers) - |> then_(userRows => { - userRows - |> Array.map(userRow => { - switch (Postgres.getColumn(userRow, "value")) { - | Some(pk) => pk - | None => "" - } - }) - |> resolve - }); - - let blocksChallenge = - getPromisifiedChallenge( - users, - pgPool, - Postgres.getBlocksChallenge, - 0, - "count", - ) - |> filterNonePromises; - - let snarkFeeChallenge = - getPromisifiedChallenge( - users, - pgPool, - Postgres.getSnarkFeeChallenge, - 0, - "sum", - ) - |> filterNonePromises; - - let transactionSentChallenge = - getPromisifiedChallenge( - users, - pgPool, - Postgres.getTransactionsSentChallenge, - 0, - "max", - ) - |> filterNonePromises; - - [|blocksChallenge, snarkFeeChallenge, transactionSentChallenge|] - |> all - |> then_(result => { - result - |> all - |> then_(result => { - users - |> then_(users => { - let blocksMetrics = result[0]; - let snarkFeeMetrics = result[1]; - let transactionMetrics = result[2]; - - let blocksChallenge = - convertDBRowsToMap(blocksMetrics, int_of_string); - let snarkFeeChallenge = - convertDBRowsToMap(snarkFeeMetrics, Int64.of_string); - let transactionChallenge = - convertDBRowsToMap(transactionMetrics, int_of_string); - - Js.log("Computing Metrics - In Progress"); - - let metrics = - calculateMetrics( - users, - blocksChallenge, - snarkFeeChallenge, - transactionChallenge, - ); - - Js.log("Computing Metrics - Done"); - - UploadLeaderboardPoints.uploadChallengePoints( - spreadsheetId, - metrics, - ); - resolve(); - }) - |> ignore; - resolve(); - }) - }); -}; diff --git a/frontend/leaderboard/src/Points.re b/frontend/leaderboard/src/Points.re deleted file mode 100644 index c16706b8f8d..00000000000 --- a/frontend/leaderboard/src/Points.re +++ /dev/null @@ -1,101 +0,0 @@ -module StringMap = Map.Make(String); - -let addPointsForExtra = (getMetricValue, threshold, points, metricsMap) => { - StringMap.fold( - (key, metric, map) => { - switch (getMetricValue(metric)) { - | Some(metricValue) => - metricValue > threshold - ? StringMap.add(key, points * (metricValue - threshold), map) : map - | None => map - } - }, - metricsMap, - StringMap.empty, - ); -}; - -let addPointsToUsersWithAtleastN = - (getMetricValue, threshold, points, metricsMap) => { - StringMap.fold( - (key, metric, map) => { - switch (getMetricValue(metric)) { - | Some(metricValue) => - metricValue >= threshold ? StringMap.add(key, points, map) : map - | None => map - } - }, - metricsMap, - StringMap.empty, - ); -}; - -let applyTopNPoints = - (threshholdPointsList, metricsMap, getMetricValue, compareFunc) => { - let metricsArray = Array.of_list(StringMap.bindings(metricsMap)); - let f = ((_, metricValue1), (_, metricValue2)) => { - compareFunc(getMetricValue(metricValue1), getMetricValue(metricValue2)); - }; - - Array.sort(f, metricsArray); - Belt.Array.reverseInPlace(metricsArray); - - metricsArray - |> Array.iteri((index, metric) => { - Js.log("index: " ++ string_of_int(index)); - Js.log("metric: "); - Js.log(metric); - Js.log("\n"); - }); - - let counter = ref(0); - let topNArrayWithPoints = - metricsArray - |> Array.mapi((i, (username, metric)) => { - metric - ->getMetricValue - ->Belt.Option.mapWithDefault((username, 0), challengeMetric => - if (counter^ >= Array.length(threshholdPointsList)) { - (username, 0); - } else { - let (place, points) = threshholdPointsList[counter^]; - if (i < Array.length(metricsArray) - 1) { - let (_, nextMetric) = metricsArray[i + 1]; - - nextMetric - ->getMetricValue - ->Belt.Option.mapWithDefault((), nextChallengeMetric => - if (challengeMetric !== nextChallengeMetric && i >= place) { - counter := counter^ + 1; - } - ); - }; - (username, points); - } - ) - }); - - Belt.Array.keep(topNArrayWithPoints, ((_, points)) => {points != 0}) - |> Array.fold_left( - (map, (userPublicKey, userPoints)) => { - StringMap.add(userPublicKey, userPoints, map) - }, - StringMap.empty, - ); -}; - -// Combines a list of maps of users to points and returns one map of users to points -let sumPointsMaps = maps => { - maps - |> List.fold_left( - StringMap.merge((_, value, secondValue) => { - switch (value, secondValue) { - | (Some(value), Some(secondValue)) => Some(value + secondValue) - | (Some(value), None) - | (None, Some(value)) => Some(value) - | (None, None) => None - } - }), - StringMap.empty, - ); -}; diff --git a/frontend/leaderboard/src/Postgres.re b/frontend/leaderboard/src/Postgres.re deleted file mode 100644 index 62d3904b710..00000000000 --- a/frontend/leaderboard/src/Postgres.re +++ /dev/null @@ -1,90 +0,0 @@ -open Bindings.Postgres; - -let getUsers = "SELECT * FROM public_keys"; - -let getBlocksChallenge = pk => { - {j| - SELECT COUNT(*) - FROM - (SELECT DISTINCT ON (global_slot) global_slot, state_hash - FROM blocks - INNER JOIN public_keys AS p ON creator_id=p.id - WHERE p.value = '$(pk)') AS blocksCreated - |j}; -}; - -let getTransactionsSentChallenge = pk => { - {j| - SELECT MAX(nonce) - FROM user_commands - INNER JOIN public_keys AS p ON source_id=p.id - WHERE status = 'applied' - AND type = 'payment' - AND p.value = '$(pk)' - |j}; -}; - -let getSnarkFeeChallenge = pk => { - {j| - SELECT SUM(fee) - FROM internal_commands as ic - INNER JOIN blocks_internal_commands as bic ON bic.internal_command_id=ic.id - INNER JOIN blocks as b ON b.id = bic.block_id - INNER JOIN public_keys as p ON p.id=ic.receiver_id - WHERE type = 'fee_transfer' - AND value = '$(pk)' - AND b.id NOT IN - ( - SELECT b.id - FROM internal_commands as ic - INNER JOIN blocks_internal_commands as bic ON bic.internal_command_id=ic.id - INNER JOIN blocks as b ON b.id = bic.block_id - INNER JOIN public_keys as p ON p.id=ic.receiver_id - WHERE type = 'coinbase' - AND value = '$(pk)' - ) - |j}; -}; - -let getBlockHeight = "SELECT MAX(height) FROM blocks"; - -let createPool = pgConn => { - makePool({connectionString: pgConn, connectionTimeoutMillis: 900000}); -}; - -let endPool = pool => { - endPool(pool); -}; - -let makeQuery = (pool, queryText) => { - Js.Promise.make((~resolve, ~reject) => { - query(pool, queryText, (~error, ~res) => { - switch (Js.Nullable.toOption(error)) { - | None => resolve(. res.rows) - | Some(error) => reject(. failwith(error)) - } - }) - }); -}; - -let getColumn = (cell, columnName) => { - Belt.Option.( - Js.Json.( - cell - ->decodeObject - ->flatMap(x => Js.Dict.get(x, columnName)) - ->flatMap(decodeString) - ) - ); -}; - -let getRow = (cell, columnName, index) => { - Belt.Option.( - Js.Json.( - cell[index] - ->decodeObject - ->flatMap(x => Js.Dict.get(x, columnName)) - ->flatMap(decodeString) - ) - ); -}; diff --git a/frontend/leaderboard/src/Sheets.re b/frontend/leaderboard/src/Sheets.re deleted file mode 100644 index 4e61baa6535..00000000000 --- a/frontend/leaderboard/src/Sheets.re +++ /dev/null @@ -1,153 +0,0 @@ -open Bindings.GoogleSheets; - -let createClient = () => { - googleAuth({scopes: [|"https://www.googleapis.com/auth/spreadsheets"|]}); -}; - -let getRange = (client, sheetsQuery, cb) => { - let sheets = sheets({version: "v4", auth: client}); - get(sheets, sheetsQuery, (~error, ~res) => { - switch (Js.Nullable.toOption(error)) { - | None => cb(Ok(res.data.values)) - | Some(error) => cb(Error(error)) - } - }); -}; - -let updateRange = (client, sheetsUpdate, cb) => { - let sheets = sheets({version: "v4", auth: client}); - - update(sheets, sheetsUpdate, (~error, ~res) => { - switch (Js.Nullable.toOption(error)) { - | None => cb(Ok(res.data.values)) - | Some(error) => cb(Error(error)) - } - }); -}; - -/* - Core is a module that provides some helpers to be used when interacting - with the Google Sheets API. - */ -module Core = { - module Sheets = { - type t = { - name: string, - range: string, - }; - - type sheets = - | Main - | AllTimeLeaderboard - | CurrentPhaseLeaderboard - | CurrentReleaseLeaderboard - | MemberProfileData - | Users - | Data; - - let getSheet = sheet => { - switch (sheet) { - | Main => {name: "main", range: "main!A5:AQ"} - | AllTimeLeaderboard => { - name: "All-Time Leaderboard", - range: "All-Time Leaderboard!C4:H", - } - | CurrentPhaseLeaderboard => { - name: "Phase 5 Testworld Leaderboard", - range: "Phase 5 Testworld Leaderboard!B4:E", - } - | CurrentReleaseLeaderboard => {name: "5.1", range: "5.1!A4:C"} - | MemberProfileData => { - name: "Member_Profile_Data", - range: "Member_Profile_Data!A2:Z", - } - | Users => {name: "Users", range: "Users!A2:B"} - | Data => {name: "Data", range: "Data!A1:D"} - }; - }; - }; - - let getColumnIndex = (columnToFind, data) => { - Belt.Array.getIndexBy(data, headerName => - switch (headerName) { - | Some(headerName) => - String.lowercase_ascii(headerName) - == String.lowercase_ascii(columnToFind) - | None => false - } - ); - }; - - let getCellType = v => - switch (Js.Types.classify(v)) { - | JSNumber(float) => `Float(float) - | JSString(string) => `String(string) - | _ => failwith("Sheets can only contain string or number") - }; - - /* - Googlesheets API returns a typed 2d array of the cell data. - The data being fetched will either be a number (for points) - or a string (for a formula). - */ - let decodeGoogleSheets = sheetsData => { - sheetsData->Belt.Array.keep(row => Array.length(row) > 0) - |> Array.map(row => { - Array.map( - cell => { - switch (getCellType(cell)) { - | `Float(float) => Some(Js.Float.toString(float)) - | `String(string) => Some(string) - | _ => None - } - }, - row, - ) - }); - }; - - let encodeGoogleSheets = sheetsData => { - sheetsData - |> Array.map(row => { - Array.map( - cell => { - switch (cell) { - | Some(cell) => cell - | None => "" - } - }, - row, - ) - }); - }; - - /* - Googlesheets API will truncate rows that have empty trailing cells. - Because of this, we make each row the same size from the fetched data. - */ - let normalizeGoogleSheets = sheetsData => { - // The first row is assumed to be the column titles of the sheet. - let headerLength = Array.length(sheetsData[0]); - sheetsData - |> Array.map(row => { - let rowLength = Array.length(row); - if (rowLength < headerLength) { - Array.append( - row, - ArrayLabels.make(headerLength - rowLength, None), - ); - } else { - row; - }; - }); - }; - - let initSheetsQuery = (spreadsheetId, range, valueRenderOption) => { - {spreadsheetId, range, valueRenderOption}; - }; - - let initSheetsUpdate = (spreadsheetId, range, valueInputOption, data) => { - let resource: sheetsUploadData = {values: data}; - {spreadsheetId, range, valueInputOption, resource}; - }; -}; diff --git a/frontend/leaderboard/src/Types.re b/frontend/leaderboard/src/Types.re deleted file mode 100644 index 60171ee1c89..00000000000 --- a/frontend/leaderboard/src/Types.re +++ /dev/null @@ -1,10 +0,0 @@ -module Metrics = { - type t = { - blocksCreated: option(int), - transactionSent: option(int), - snarkFeesCollected: option(int64), - highestSnarkFeeCollected: option(int64), - transactionsReceivedByEcho: option(int), - coinbaseReceiver: option(bool), - }; -}; diff --git a/frontend/leaderboard/src/UploadLeaderboardData.re b/frontend/leaderboard/src/UploadLeaderboardData.re deleted file mode 100644 index ba415ea531e..00000000000 --- a/frontend/leaderboard/src/UploadLeaderboardData.re +++ /dev/null @@ -1,227 +0,0 @@ -/* - UploadLeaderboardData.re has the responsibilities of uploading the - information needed for the Leaderboard webpage to a Google Sheets tab. - - This information is seperate from points as it's data that is only - useful for the Leaderboard webpage. - - */ - -module StringMap = Map.Make(String); -open Sheets; -open Sheets.Core; - -/* - Upload "Genesis Members", "Block Count", and "Participants" to the Data tab - */ -let uploadData = (spreadsheetId, totalBlocks) => { - let dataSheet = Sheets.getSheet(Sheets.Data); - let client = createClient(); - - getRange( - client, - initSheetsQuery( - spreadsheetId, - Sheets.getSheet(Sheets.AllTimeLeaderboard).range, - "FORMATTED_VALUE", - ), - result => { - switch (result) { - | Ok(sheetsData) => - let data = sheetsData |> decodeGoogleSheets; - - let columnHeaders = [| - "Genesis Members", - "Block Count", - "Participants", - "Last Updated", - |]; - - let statisticsData = [| - data->Belt.Array.keep(row => { - /* The 4th column indicates whether the user is a genesis member */ - switch (Belt.Array.get(row, 3)) { - | Some(genesisMember) => - String.length(Belt.Option.getExn(genesisMember)) == 0 - ? false : true - | None => false - } - }) - |> Array.length - |> string_of_int, - totalBlocks, - data |> Array.length |> string_of_int, - |]; - - updateRange( - client, - initSheetsUpdate( - spreadsheetId, - dataSheet.range, - "USER_ENTERED", - Array.append([|columnHeaders|], [|statisticsData|]), - ), - result => { - switch (result) { - | Ok(_) => Js.log({j|Uploaded to Data spreadsheet|j}) - | Error(error) => Js.log(error) - } - }); - | Error(error) => Js.log(error) - } - }); -}; - -/* - Takes a map of users and column values and adds the column value - to the user row that will be uploaded. If the value in the map was - */ - -let addPropertyToUserRow = (users, userColumnValueMap) => { - users - |> Array.map(userRow => { - let username = Belt.Option.getExn(userRow[0]); - if (StringMap.mem(username, userColumnValueMap)) { - let columnValue = StringMap.find(username, userColumnValueMap); - Belt.Array.concat(userRow, [|Some(columnValue)|]); - } else { - Belt.Array.concat(userRow, [|None|]); - }; - }); -}; - -/* - Iterates through all user rows and creates a map of usernames as keys - and column values as values. If the username or column value does not exist, - we don't do anything and move on. - */ -let createColumnUserMap = (columnValue, usernameColumn, userData) => { - userData - |> Array.fold_left( - (map, userRow) => { - switch ( - Belt.Array.get(userRow, usernameColumn), - Belt.Array.get(userRow, columnValue), - ) { - | (Some(username), Some(columnValue)) => - switch (username, columnValue) { - | (Some(username), Some(column)) => - StringMap.add(username, column, map) - | (_, _) => map - } - | (_, _) => map - } - }, - StringMap.empty, - ); -}; - -let addPropertyToUserRow = (columnValue, usernameColumn, pointsData, users) => { - pointsData - |> createColumnUserMap(columnValue, usernameColumn) - |> addPropertyToUserRow(users); -}; - -let getAllValidUsers = (usernameColumn, userData) => { - userData - |> Array.fold_left( - (a, row) => { - switch (Belt.Array.get(row, usernameColumn)) { - | Some(usernameOption) => - switch (usernameOption) { - | Some(username) => Array.append(a, [|[|Some(username)|]|]) - | None => a - } - | None => a - } - }, - [||], - ); -}; - -/* - Queries all rows in the `main` tab and aggregates data on each individual user row. - The information we are interested in gathering for a particular user is: - - username column - - all time points column - - phase points column - - release points column - - all time rank column - - phase rank column - - release rank column - - GFM badge column - - technical badge column - - mvp badge column - */ - -let computeMemberProfileData = mainData => { - let mainUserIndex = 2; /* usernames are located in the 3rd column */ - let allTimePoints = 20; /* all time points are located in the 21st column */ - let phasePoints = 17; /* all time points are located in the 17th column */ - let releasePoints = 40; /* all time points are located in the 41st column */ - - let allTimeRank = 19; /* all time points are located in the 20th column */ - let phaseRank = 16; /* all time points are located in the 17th column */ - let releaseRank = 41; /* all time points are located in the 42nd column */ - - let genesisBadge = 4; /* all time points are located in the 17th column */ - let technicalBadge = 5; /* all time points are located in the 17th column */ - let mvpBadge = 6; /* all time points are located in the 17th column */ - - /* compute users */ - getAllValidUsers(mainUserIndex, mainData) - /* compute all time points */ - |> addPropertyToUserRow(allTimePoints, mainUserIndex, mainData) - /* compute phase points */ - |> addPropertyToUserRow(phasePoints, mainUserIndex, mainData) - // /* compute release points */ - |> addPropertyToUserRow(releasePoints, mainUserIndex, mainData) - // /* compute all time rank */ - |> addPropertyToUserRow(allTimeRank, mainUserIndex, mainData) - /* compute phase rank */ - |> addPropertyToUserRow(phaseRank, mainUserIndex, mainData) - /* compute release rank */ - |> addPropertyToUserRow(releaseRank, mainUserIndex, mainData) - /* compute genesis member badge*/ - |> addPropertyToUserRow(genesisBadge, mainUserIndex, mainData) - /* compute technical MVP badge */ - |> addPropertyToUserRow(technicalBadge, mainUserIndex, mainData) - /* compute community MVP badge */ - |> addPropertyToUserRow(mvpBadge, mainUserIndex, mainData); -}; - -let uploadUserProfileData = spreadsheetId => { - let client = createClient(); - - /* Fetch main leaderboard data */ - getRange( - client, - initSheetsQuery( - spreadsheetId, - Sheets.getSheet(Sheets.Main).range, - "FORMATTED_VALUE", - ), - result => { - switch (result) { - | Ok(mainResult) => - let mainData = mainResult |> decodeGoogleSheets; - let data = computeMemberProfileData(mainData); - - updateRange( - client, - initSheetsUpdate( - spreadsheetId, - Sheets.getSheet(Sheets.MemberProfileData).range, - "USER_ENTERED", - encodeGoogleSheets(data), - ), - result => { - switch (result) { - | Ok(_) => Js.log({j|Uploaded member data|j}) - | Error(error) => Js.log(error) - } - }); - | Error(error) => Js.log(error) - } - }); -}; diff --git a/frontend/leaderboard/src/UploadLeaderboardPoints.re b/frontend/leaderboard/src/UploadLeaderboardPoints.re deleted file mode 100644 index 82491299861..00000000000 --- a/frontend/leaderboard/src/UploadLeaderboardPoints.re +++ /dev/null @@ -1,170 +0,0 @@ -/* - UploadLeaderboardPoints.re has the responsibilities of managing - calculation of points from challenges and uploading the corresponding - points to each user. - - The entry point to upload points is uploadChallengePoints(). The fetched - Google Sheets data is in a form of an array of rows. Each entry - in the array is another array that represents cell values for a particular user. - - The script first fetches from "Users!A2:B" to compute a mapping of usernames and - public keys. The username/pk mapping is then used to assign points to users for - completing challenges. Finally, the new points data is uploaded to the spreadsheet. - */ - -module StringMap = Map.Make(String); -open Sheets; -open Sheets.Core; - -let createPublickeyUsernameMap = sheetsData => { - sheetsData - |> Array.fold_left( - (map, user) => { - switch (user[0], user[1]) { - | (Some(publickey), Some(username)) => - StringMap.add(publickey, username, map) - | (_, _) => map - } - }, - StringMap.empty, - ); -}; - -let createUsernamePointsMap = (pointsMap, userMap) => { - StringMap.fold( - (username, pk, map) => { - StringMap.mem(pk, pointsMap) - ? StringMap.add(username, StringMap.find(pk, pointsMap), map) : map - }, - userMap, - StringMap.empty, - ); -}; - -let assignPointsToUsers = - (pointIndex, userNameIndex, usernamePointsMap, sheetsData) => { - /* Iterate through all the rows in the fetched Google Sheets data */ - Belt.Array.slice(sheetsData, ~offset=1, ~len=Array.length(sheetsData)) - |> Array.iter(row => { - let username = - switch (row[userNameIndex]) { - | Some(username) => username - | None => "" - }; - - if (StringMap.mem(username, usernamePointsMap)) { - /* Found a username, get the points to update */ - let pointsBinding = StringMap.find(username, usernamePointsMap); - /* Add points from challenge */ - row[pointIndex] = Some(string_of_int(pointsBinding)); - } else { - /* If username has no points for the challenge, wipe cell */ - row[pointIndex] = - None; - }; - }); -}; - -/* - Filter the collected metrics that don't have a corresponding user from the "Users" tab - */ -let filterMetricsBySheetsUsers = (metricsMap, userMap) => { - let userPublickeys = - StringMap.bindings(userMap) |> List.map(((_, publickey)) => publickey); - - metricsMap - |> StringMap.filter((publickey, _) => { - List.mem(publickey, userPublickeys) - }); -}; - -let updatePointsByChallenge = (metricsMap, userMap, sheetsData, usernameIndex) => { - let filteredMetrics = filterMetricsBySheetsUsers(metricsMap, userMap); - /* Loop through the first row which contains all challenge headers and calculate valid challenges */ - sheetsData[0] - |> Array.iteri((challengePointIndex, challengeTitle) => { - switch (challengeTitle) { - | Some(challengeTitle) => - switch (Challenges.calculatePoints(challengeTitle, filteredMetrics)) { - | Some(pointsMap) => - let usernamePointsMap = - createUsernamePointsMap(pointsMap, userMap); - - assignPointsToUsers( - challengePointIndex, - usernameIndex, - usernamePointsMap, - sheetsData, - ); - (); - | None => () - } - | None => () - } - }); -}; - -let updateUserPoints = (metricsMap, userMap, sheetsData) => { - switch (getColumnIndex("Name", sheetsData[0])) { - | Some(usernameIndex) => - updatePointsByChallenge(metricsMap, userMap, sheetsData, usernameIndex) - | None => () - }; -}; - -let updateChallengeSheet = (client, spreadsheetId, range, userMap, metricsMap) => { - getRange(client, initSheetsQuery(spreadsheetId, range, "FORMULA"), result => { - switch (result) { - /* leaderboardData is a 2d array that has usernames and points to be given for each column */ - | Ok(leaderboardData) => - let sheetsData = - leaderboardData |> decodeGoogleSheets |> normalizeGoogleSheets; - - updateUserPoints(metricsMap, userMap, sheetsData); - - updateRange( - client, - initSheetsUpdate( - spreadsheetId, - range, - "USER_ENTERED", - encodeGoogleSheets(sheetsData), - ), - result => { - switch (result) { - | Ok(_) => Js.log({j|Data uploaded points for $range|j}) - | Error(error) => Js.log(error) - } - }); - | Error(error) => Js.log(error) - } - }); -}; - -let uploadChallengePoints = (spreadsheetId, metricsMap) => { - let client = createClient(); - getRange( - client, - initSheetsQuery( - spreadsheetId, - Sheets.getSheet(Sheets.Users).range, - "FORMULA", - ), - result => { - switch (result) { - /* userData is a 2d array of usernames and public keys to represent each user */ - | Ok(userData) => - let userMap = - userData |> decodeGoogleSheets |> createPublickeyUsernameMap; - - updateChallengeSheet( - client, - spreadsheetId, - Sheets.getSheet(Sheets.CurrentReleaseLeaderboard).name ++ "!A4:V", - userMap, - metricsMap, - ); - | Error(error) => Js.log(error) - } - }); -}; diff --git a/frontend/leaderboard/yarn.lock b/frontend/leaderboard/yarn.lock deleted file mode 100644 index 9904bf64990..00000000000 --- a/frontend/leaderboard/yarn.lock +++ /dev/null @@ -1,443 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@googleapis/sheets@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@googleapis/sheets/-/sheets-0.3.0.tgz#1d96d8990a6c1a79f13ec3574a84fba07382910e" - integrity sha512-Axhbw2Hi3IAPyYGC4y8wmE/0aY0NVTieDDc+RMnx2/iSQ8laodWqAUDsUskTdEm4ZB2JD2Z+SU6o3IXktDaG4Q== - dependencies: - googleapis-common "^5.0.1" - -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -arrify@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" - integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== - -base64-js@^1.3.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bignumber.js@^9.0.0: - version "9.0.2" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.2.tgz#71c6c6bed38de64e24a65ebe16cfcf23ae693673" - integrity sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw== - -bs-fetch@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/bs-fetch/-/bs-fetch-0.5.2.tgz#a9f4582ddb1414d3467b900305c738813481988c" - integrity sha512-CYweTJcgLeLOqzR3vNsB+NmyEFhWThnPNdZmmF28nkFmo0CQEf+20eSHZJDO6EuAhhoRqJ0qp2VgxtH6zBB5xA== - -bs-platform@7.0.0-dev.1: - version "7.0.0-dev.1" - resolved "https://registry.yarnpkg.com/bs-platform/-/bs-platform-7.0.0-dev.1.tgz#e9f2b05c68b16e325fc9a284ca529bb84fd5509b" - integrity sha512-nXxk3oUBvp2o0D8Qc2JOKNeeYNg/wPVYj+eu4vPbWzR/dbhfc4bRG/QkU6z6DuV1aiDzGnKIBY06azYPuw4a+g== - -bsc-stdlib-polyfill@Schmavery/bsc-stdlib-polyfill: - version "0.0.1" - resolved "https://codeload.github.com/Schmavery/bsc-stdlib-polyfill/tar.gz/b6e9bde87e80363572aa969b7af9c02ccfabe9de" - integrity sha512-SJWVZeauxHIFeUag5+KI7zlybNW9+wOV/JJYcvZstwGa1J9EDq10EH8k+poI320P4MnVnzU2dsxHXDyuXC0VUA== - -buffer-equal-constant-time@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" - integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= - -buffer-writer@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04" - integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw== - -call-bind@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -debug@4: - version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== - dependencies: - ms "2.1.2" - -ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" - integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== - dependencies: - safe-buffer "^5.0.1" - -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - -extend@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -fast-text-encoding@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz#ec02ac8e01ab8a319af182dae2681213cfe9ce53" - integrity sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -gaxios@^4.0.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-4.3.2.tgz#845827c2dc25a0213c8ab4155c7a28910f5be83f" - integrity sha512-T+ap6GM6UZ0c4E6yb1y/hy2UB6hTrqhglp3XfmU9qbLCGRYhLVV5aRPpC4EmoG8N8zOnkYCgoBz+ScvGAARY6Q== - dependencies: - abort-controller "^3.0.0" - extend "^3.0.2" - https-proxy-agent "^5.0.0" - is-stream "^2.0.0" - node-fetch "^2.6.1" - -gcp-metadata@^4.2.0: - version "4.3.1" - resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-4.3.1.tgz#fb205fe6a90fef2fd9c85e6ba06e5559ee1eefa9" - integrity sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A== - dependencies: - gaxios "^4.0.0" - json-bigint "^1.0.0" - -get-intrinsic@^1.0.2: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -google-auth-library@^7.0.2: - version "7.10.4" - resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-7.10.4.tgz#95307b2e94d69edb587d8d2522cbef839da4ef11" - integrity sha512-DJ4VGaLwgPcMg8hMZFoQxjA0VeIy2A1RkJ6kUt5vXNfbVEma8WA9waUJ29cwpXjpFjpEAT2Uu6Y5loYbmInyFw== - dependencies: - arrify "^2.0.0" - base64-js "^1.3.0" - ecdsa-sig-formatter "^1.0.11" - fast-text-encoding "^1.0.0" - gaxios "^4.0.0" - gcp-metadata "^4.2.0" - gtoken "^5.0.4" - jws "^4.0.0" - lru-cache "^6.0.0" - -google-p12-pem@^3.0.3: - version "3.1.2" - resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-3.1.2.tgz#c3d61c2da8e10843ff830fdb0d2059046238c1d4" - integrity sha512-tjf3IQIt7tWCDsa0ofDQ1qqSCNzahXDxdAGJDbruWqu3eCg5CKLYKN+hi0s6lfvzYZ1GDVr+oDF9OOWlDSdf0A== - dependencies: - node-forge "^0.10.0" - -googleapis-common@^5.0.1: - version "5.0.5" - resolved "https://registry.yarnpkg.com/googleapis-common/-/googleapis-common-5.0.5.tgz#4c7160be1ed7e4cc8cdbcdb6eac8a4b3a61dd782" - integrity sha512-o2dgoW4x4fLIAN+IVAOccz3mEH8Lj1LP9c9BSSvkNJEn+U7UZh0WSr4fdH08x5VH7+sstIpd1lOYFZD0g7j4pw== - dependencies: - extend "^3.0.2" - gaxios "^4.0.0" - google-auth-library "^7.0.2" - qs "^6.7.0" - url-template "^2.0.8" - uuid "^8.0.0" - -gtoken@^5.0.4: - version "5.3.1" - resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-5.3.1.tgz#c1c2598a826f2b5df7c6bb53d7be6cf6d50c3c78" - integrity sha512-yqOREjzLHcbzz1UrQoxhBtpk8KjrVhuqPE7od1K2uhyxG2BHjKZetlbLw/SPZak/QqTIQW+addS+EcjqQsZbwQ== - dependencies: - gaxios "^4.0.0" - google-p12-pem "^3.0.3" - jws "^4.0.0" - -has-symbols@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" - integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -https-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== - dependencies: - agent-base "6" - debug "4" - -inherits@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -isomorphic-unfetch@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-3.0.0.tgz#de6d80abde487b17de2c400a7ef9e5ecc2efb362" - integrity sha512-V0tmJSYfkKokZ5mgl0cmfQMTb7MLHsBMngTkbLY0eXvKqiVRRoZP04Ly+KhKrJfKtzC9E6Pp15Jo+bwh7Vi2XQ== - dependencies: - node-fetch "^2.2.0" - unfetch "^4.0.0" - -json-bigint@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1" - integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ== - dependencies: - bignumber.js "^9.0.0" - -jwa@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc" - integrity sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA== - dependencies: - buffer-equal-constant-time "1.0.1" - ecdsa-sig-formatter "1.0.11" - safe-buffer "^5.0.1" - -jws@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4" - integrity sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg== - dependencies: - jwa "^2.0.0" - safe-buffer "^5.0.1" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -node-fetch@^2.2.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" - integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== - -node-fetch@^2.6.1: - version "2.6.6" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89" - integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA== - dependencies: - whatwg-url "^5.0.0" - -node-forge@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" - integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== - -object-inspect@^1.9.0: - version "1.11.1" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.1.tgz#d4bd7d7de54b9a75599f59a00bd698c1f1c6549b" - integrity sha512-If7BjFlpkzzBeV1cqgT3OSWT3azyoxDGajR+iGnFBfVV2EWyDyWaZZW2ERDjUaY2QM8i5jI3Sj7mhsM4DDAqWA== - -packet-reader@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74" - integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ== - -pg-connection-string@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34" - integrity sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ== - -pg-int8@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" - integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== - -pg-pool@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.4.1.tgz#0e71ce2c67b442a5e862a9c182172c37eda71e9c" - integrity sha512-TVHxR/gf3MeJRvchgNHxsYsTCHQ+4wm3VIHSS19z8NC0+gioEhq1okDY1sm/TYbfoP6JLFx01s0ShvZ3puP/iQ== - -pg-protocol@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.5.0.tgz#b5dd452257314565e2d54ab3c132adc46565a6a0" - integrity sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ== - -pg-types@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" - integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== - dependencies: - pg-int8 "1.0.1" - postgres-array "~2.0.0" - postgres-bytea "~1.0.0" - postgres-date "~1.0.4" - postgres-interval "^1.1.0" - -pg@^8.3.0: - version "8.7.1" - resolved "https://registry.yarnpkg.com/pg/-/pg-8.7.1.tgz#9ea9d1ec225980c36f94e181d009ab9f4ce4c471" - integrity sha512-7bdYcv7V6U3KAtWjpQJJBww0UEsWuh4yQ/EjNf2HeO/NnvKjpvhEIe/A/TleP6wtmSKnUnghs5A9jUoK6iDdkA== - dependencies: - buffer-writer "2.0.0" - packet-reader "1.0.0" - pg-connection-string "^2.5.0" - pg-pool "^3.4.1" - pg-protocol "^1.5.0" - pg-types "^2.1.0" - pgpass "1.x" - -pgpass@1.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.4.tgz#85eb93a83800b20f8057a2b029bf05abaf94ea9c" - integrity sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w== - dependencies: - split2 "^3.1.1" - -postgres-array@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" - integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== - -postgres-bytea@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" - integrity sha1-AntTPAqokOJtFy1Hz5zOzFIazTU= - -postgres-date@~1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" - integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== - -postgres-interval@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" - integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== - dependencies: - xtend "^4.0.0" - -qs@^6.7.0: - version "6.10.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.2.tgz#c1431bea37fc5b24c5bdbafa20f16bdf2a4b9ffe" - integrity sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw== - dependencies: - side-channel "^1.0.4" - -readable-stream@^3.0.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -safe-buffer@^5.0.1, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -split2@^3.1.1: - version "3.2.2" - resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" - integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg== - dependencies: - readable-stream "^3.0.0" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= - -unfetch@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.1.0.tgz#6ec2dd0de887e58a4dee83a050ded80ffc4137db" - integrity sha512-crP/n3eAPUJxZXM9T80/yv0YhkTEx2K1D3h7D1AJM6fzsWZrxdyRuLN0JH/dkZh1LNH8LxCnBzoPFCPbb2iGpg== - -url-template@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21" - integrity sha1-/FZaPMy/93MMd19WQflVV5FDnyE= - -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -uuid@^8.0.0: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -xtend@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/helm/leaderboard/.helmignore b/helm/leaderboard/.helmignore deleted file mode 100644 index 50af0317254..00000000000 --- a/helm/leaderboard/.helmignore +++ /dev/null @@ -1,22 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ diff --git a/helm/leaderboard/CHANGELOG.md b/helm/leaderboard/CHANGELOG.md deleted file mode 100644 index 2abfa0a3433..00000000000 --- a/helm/leaderboard/CHANGELOG.md +++ /dev/null @@ -1,3 +0,0 @@ -1.0.0: ------- -- initial chart version for simple ui, cron, and postgres deploys diff --git a/helm/leaderboard/Chart.lock b/helm/leaderboard/Chart.lock deleted file mode 100644 index a1f68710a8b..00000000000 --- a/helm/leaderboard/Chart.lock +++ /dev/null @@ -1,6 +0,0 @@ -dependencies: -- name: postgresql - repository: https://charts.bitnami.com/bitnami - version: '*' -digest: sha256:39d21fec4c1d45df8474190d3ac494d0e1c48694bfa9b23fb96bc1325da4e8fb -generated: "2021-04-20T02:18:31.7718805-04:00" diff --git a/helm/leaderboard/Chart.yaml b/helm/leaderboard/Chart.yaml deleted file mode 100644 index 9e7c912e29d..00000000000 --- a/helm/leaderboard/Chart.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: v2 -name: leaderboard -description: A Helm chart for Mina Foundation's block producer leaderboard -type: application -version: 1.0.0 -appVersion: 1.16.0 -annotations: - artifacthub.io/changes: | - - initial chart version for simple ui, cron, and postgres deploys -dependencies: - - name: postgresql - version: "*" - repository: "https://charts.bitnami.com/bitnami" - condition: leaderboard.enablePostgresDB -icon: https://storage.googleapis.com/coda-charts/Mina_Icon_Secondary_RGB_Black.png -keywords: -- postgres -- mina -- foundation -- leaderboard -home: https://minaprotocol.com/ -sources: -- https://github.com/MinaProtocol/mina/tree/compatible/helm/leaderboard diff --git a/helm/leaderboard/Makefile b/helm/leaderboard/Makefile deleted file mode 120000 index d981720c97c..00000000000 --- a/helm/leaderboard/Makefile +++ /dev/null @@ -1 +0,0 @@ -../common/Makefile \ No newline at end of file diff --git a/helm/leaderboard/charts/postgresql-10.9.4.tgz b/helm/leaderboard/charts/postgresql-10.9.4.tgz deleted file mode 100644 index bcc4511b042..00000000000 Binary files a/helm/leaderboard/charts/postgresql-10.9.4.tgz and /dev/null differ diff --git a/helm/leaderboard/templates/NOTES.txt b/helm/leaderboard/templates/NOTES.txt deleted file mode 100644 index 8b137891791..00000000000 --- a/helm/leaderboard/templates/NOTES.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/helm/leaderboard/templates/_helpers.tpl b/helm/leaderboard/templates/_helpers.tpl deleted file mode 100644 index d088e640f50..00000000000 --- a/helm/leaderboard/templates/_helpers.tpl +++ /dev/null @@ -1,79 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "leaderboard.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "leaderboard.fullname" -}} -{{- if .Values.fullnameOverride -}} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Release.Name .Values.nameOverride -}} -{{- printf "%s" $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "leaderboard.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Common labels -*/}} -{{- define "leaderboard.labels" -}} -helm.sh/chart: {{ include "leaderboard.chart" . }} -{{ include "leaderboard.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end -}} - -{{/* -Selector labels -*/}} -{{- define "leaderboard.selectorLabels" -}} -app.kubernetes.io/name: {{ include "leaderboard.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end -}} - -{{/* -Create the name of the service account to use -*/}} -{{- define "leaderboard.serviceAccountName" -}} -{{- if .Values.serviceAccount.create -}} - {{ default (include "leaderboard.fullname" .) .Values.serviceAccount.name }} -{{- else -}} - {{ default "default" .Values.serviceAccount.name }} -{{- end -}} -{{- end -}} - - -{{/* -NOTE: This utility template is needed until https://git.io/JvuGN is resolved. - -Call a template from the context of a subchart. - -Usage: - {{ include "call-nested" (list . "" "") }} -*/}} -{{- define "call-nested" }} -{{- $dot := index . 0 }} -{{- $subchart := index . 1 | splitList "." }} -{{- $template := index . 2 }} -{{- $values := $dot.Values }} -{{- range $subchart }} -{{- $values = index $values . }} -{{- end }} -{{- include $template (dict "Chart" (dict "Name" (last $subchart)) "Values" $values "Release" $dot.Release "Capabilities" $dot.Capabilities) }} -{{- end }} diff --git a/helm/leaderboard/templates/email-cron.yaml b/helm/leaderboard/templates/email-cron.yaml deleted file mode 100644 index d31c28254fd..00000000000 --- a/helm/leaderboard/templates/email-cron.yaml +++ /dev/null @@ -1,34 +0,0 @@ -apiVersion: batch/v1 -kind: CronJob -metadata: - name: "email-cron" -spec: - schedule: "0 0 */15 * *" - jobTemplate: - spec: - template: - spec: - restartPolicy: OnFailure - containers: - - name: cron - image: {{ .Values.cron.image }} - imagePullPolicy: Always - command: - - /usr/local/bin/python - - send_email.py - {{- if .Values.cron.secret }} - volumeMounts: - - name: cron-creds - mountPath: /opt/minanet/creds/ - volumes: - - name: cron-creds - secret: - secretName: {{ .Values.cron.secret }} - items: - - key: gcs-credential.json - path: gcs-credential.json - - key: config.py - path: config.py - - key: sendgrid.key - path: sendgrid.key - {{- end }} diff --git a/helm/leaderboard/templates/leaderboard-cron.yaml b/helm/leaderboard/templates/leaderboard-cron.yaml deleted file mode 100644 index 39421387f48..00000000000 --- a/helm/leaderboard/templates/leaderboard-cron.yaml +++ /dev/null @@ -1,31 +0,0 @@ -apiVersion: batch/v1 -kind: CronJob -metadata: - name: "leaderboard-cron" -spec: - schedule: "*/30 * * * *" - jobTemplate: - spec: - template: - spec: - restartPolicy: OnFailure - containers: - - name: cron - image: {{ .Values.cron.image }} - imagePullPolicy: Always - {{- if .Values.cron.secret }} - volumeMounts: - - name: cron-creds - mountPath: /opt/minanet/creds/ - volumes: - - name: cron-creds - secret: - secretName: {{ .Values.cron.secret }} - items: - - key: gcs-credential.json - path: gcs-credential.json - - key: sheets-credential.json - path: sheets-credential.json - - key: config.py - path: config.py - {{- end }} diff --git a/helm/leaderboard/templates/ui-loadbalancer.yaml b/helm/leaderboard/templates/ui-loadbalancer.yaml deleted file mode 100644 index 8f38c526c7e..00000000000 --- a/helm/leaderboard/templates/ui-loadbalancer.yaml +++ /dev/null @@ -1,18 +0,0 @@ ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "leaderboard.fullname" . }}-ui -spec: - type: LoadBalancer - # We want all pods to have their addresses published for the sake of the - # other testnet pods even before they're ready, since they - # have to be able to talk to each other in order to become ready. - publishNotReadyAddresses: true - selector: - app: {{ template "leaderboard.fullname" . }}-ui - ports: - - name: leaderboard-ui - port: {{ .Values.ui.port }} - targetPort: leaderboard-ui - protocol: TCP diff --git a/helm/leaderboard/templates/ui.yaml b/helm/leaderboard/templates/ui.yaml deleted file mode 100644 index 60ab4647582..00000000000 --- a/helm/leaderboard/templates/ui.yaml +++ /dev/null @@ -1,38 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "leaderboard.fullname" . }}-ui - labels: - app: {{ template "leaderboard.fullname" . }}-ui -spec: - replicas: 1 - selector: - matchLabels: - app: {{ template "leaderboard.fullname" . }}-ui - template: - metadata: - labels: - app: {{ template "leaderboard.fullname" . }}-ui - role: leaderboard - version: {{ trunc 6 (split ":" .Values.ui.image)._1 | trimSuffix "-" }} - spec: - containers: - - name: ui - image: {{ .Values.ui.image }} - imagePullPolicy: Always - ports: - - name: leaderboard-ui - protocol: TCP - containerPort: {{ .Values.ui.port }} - {{- if .Values.ui.secret }} - volumeMounts: - - name: php-creds - mountPath: /var/www/html/creds/ - volumes: - - name: php-creds - secret: - secretName: {{ .Values.ui.secret }} - items: - - key: connection.php - path: connection.php - {{- end }} diff --git a/helm/leaderboard/values.yaml b/helm/leaderboard/values.yaml deleted file mode 100644 index a537b90704b..00000000000 --- a/helm/leaderboard/values.yaml +++ /dev/null @@ -1,41 +0,0 @@ -ui: - image: gcr.io/mina-mainnet-303900/leaderboard-ui:v2 - port: 80 - secret: php-connection - -cron: - image: gcr.io/mina-mainnet-303900/leaderboard-bot:v2 - secret: leaderboard-cron-creds - -leaderboard: - enableLocalDaemon: true - enablePostgresDB: true - -fullnameOverride: "leaderboard" - -postgresql: - image: - pullPolicy: Always - registry: gcr.io - repository: mina-mainnet-303900/postgres - tag: v2 - postgresqlPassword: "some_password_here" - postgresqlUsername: "leaderboard" - postgresqlDatabase: "leaderboard" - #postgresqlDataDir: "/data/pgdata" - fullnameOverride: "pg" - persistence: - enabled: true - # mountPath: "/data/" - securityContext: - enabled: true - fsGroup: 70 - runAsUser: 70 - volumePermissions: - securityContext: - enabled: true - fsGroup: 70 - runAsUser: 70 - containerSecurityContext: - enabled: true - runAsUser: 70 diff --git a/scripts/release-docker.sh b/scripts/release-docker.sh index 70c0cb63409..94d853e7c29 100755 --- a/scripts/release-docker.sh +++ b/scripts/release-docker.sh @@ -10,8 +10,7 @@ set -x CLEAR='\033[0m' RED='\033[0;31m' # Array of valid service names - -VALID_SERVICES=('mina-archive' 'mina-daemon' 'mina-rosetta' 'mina-test-suite' 'mina-batch-txn' 'mina-zkapp-test-transaction' 'mina-toolchain' 'bot' 'leaderboard' 'itn-orchestrator') +VALID_SERVICES=('mina-archive' 'mina-daemon' 'mina-rosetta' 'mina-test-suite' 'mina-batch-txn' 'mina-zkapp-test-transaction' 'mina-toolchain' 'bot' 'itn-orchestrator') function usage() { if [[ -n "$1" ]]; then @@ -136,10 +135,6 @@ mina-rosetta) mina-zkapp-test-transaction) DOCKERFILE_PATH="dockerfiles/Dockerfile-zkapp-test-transaction" ;; -leaderboard) - DOCKERFILE_PATH="frontend/leaderboard/Dockerfile" - DOCKER_CONTEXT="frontend/leaderboard" - ;; itn-orchestrator) DOCKERFILE_PATH="dockerfiles/Dockerfile-itn-orchestrator" DOCKER_CONTEXT="src/app/itn_orchestrator"