From 4d2bd3481f93bbda5d3d63cb5f923dd8fe873a29 Mon Sep 17 00:00:00 2001 From: will pankiewicz Date: Tue, 5 Mar 2024 12:48:43 +0100 Subject: [PATCH] add tests, update swagger endpoints, use enums --- package.json | 4 +- packages/common/src/chaindata/queries/Era.ts | 5 +- packages/common/src/db/models.ts | 6 + packages/common/src/db/queries/Candidate.ts | 2 +- packages/common/src/db/queries/Era.ts | 52 +-- .../common/src/db/queries/ValidatorScore.ts | 2 +- packages/common/src/db/queries/Validators.ts | 5 +- .../src/nominator/NominatorChainInfo.ts | 24 +- packages/common/src/nominator/NominatorTx.ts | 20 +- .../src/nominator/__mocks__/nominator.ts | 4 + packages/common/src/nominator/nominator.ts | 84 ++--- packages/common/src/scorekeeper/Nominating.ts | 5 +- .../common/src/scorekeeper/NumNominations.ts | 5 +- packages/common/src/scorekeeper/Round.ts | 33 +- .../jobs/specificJobs/CancelJob.ts | 2 +- .../jobs/specificJobs/ConstraintsJob.ts | 2 +- .../jobs/specificJobs/EraPointsJob.ts | 2 +- .../jobs/specificJobs/ExecutionJob.ts | 14 +- .../jobs/specificJobs/MainScorekeeperJob.ts | 10 +- .../jobs/specificJobs/StaleNomination.ts | 2 +- .../common/src/scorekeeper/scorekeeper.ts | 5 +- packages/common/src/types.ts | 39 ++ packages/common/src/utils/Validators.ts | 2 +- .../test/db/queries/EraStats.unit.test.ts | 15 +- .../scorekeeper/NumNominations.int.test.ts | 15 +- .../common/test/utils/Validators.unit.test.ts | 101 ++++++ packages/core/package.json | 2 +- packages/gateway/src/routes/index.ts | 17 - packages/gateway/src/swagger.yml | 335 ++++++++++++------ packages/scorekeeper-status-ui/src/App.tsx | 5 +- .../scorekeeper-status-ui/src/EraStatsBar.tsx | 8 +- packages/worker/package.json | 2 +- yarn.lock | 335 +++++++++++------- 33 files changed, 758 insertions(+), 406 deletions(-) create mode 100644 packages/common/test/utils/Validators.unit.test.ts diff --git a/package.json b/package.json index ca5008c39..81e5edade 100644 --- a/package.json +++ b/package.json @@ -79,8 +79,8 @@ "typedoc-plugin-markdown": "^3.17.1" }, "dependencies": { - "@polkadot/api": "^10.11.2", - "@polkadot/rpc-provider": "^10.11.2", + "@polkadot/api": "^10.12.1", + "@polkadot/rpc-provider": "^10.12.1", "@types/ws": "^8.5.10", "axios": "^1.6.7", "chalk": "4.1.2", diff --git a/packages/common/src/chaindata/queries/Era.ts b/packages/common/src/chaindata/queries/Era.ts index b7940e980..fd6f4ef1c 100644 --- a/packages/common/src/chaindata/queries/Era.ts +++ b/packages/common/src/chaindata/queries/Era.ts @@ -208,13 +208,12 @@ export const findEraBlockHash = async ( return ["", "API at block hash is null"]; } - const testEra = await apiAt.query.staking.activeEra(); + const testEra = await apiAt.query.staking.currentEra(); if (testEra && testEra.isEmpty) { logger.info(`Test era is empty: ${JSON.stringify(testEra)}`); return ["", "Test era is none"]; } - const testEraJSON = testEra.toJSON() as { index: string; start: string }; - const testIndex = testEraJSON.index ? Number(testEraJSON.index) : 0; + const testIndex = testEra.unwrap().toNumber(); if (era == testIndex) { return [blockHash.toString(), null]; } diff --git a/packages/common/src/db/models.ts b/packages/common/src/db/models.ts index c1c384e68..2b263a2df 100644 --- a/packages/common/src/db/models.ts +++ b/packages/common/src/db/models.ts @@ -463,6 +463,12 @@ export const CandidateSchema = new Schema({ export const CandidateModel = mongoose.model("Candidate", CandidateSchema); +export interface Era { + lastNominatedEraIndex: string; + nextNomination: number; + when: number; +} + export const EraSchema = new Schema({ // The last era a nomination took place lastNominatedEraIndex: { type: String, default: "0" }, diff --git a/packages/common/src/db/queries/Candidate.ts b/packages/common/src/db/queries/Candidate.ts index d780b0bb8..ca3c930d1 100644 --- a/packages/common/src/db/queries/Candidate.ts +++ b/packages/common/src/db/queries/Candidate.ts @@ -334,7 +334,7 @@ export const getIdentityName = async ( .lean() .select({ name: 1 }); - return identity?.name; + return identity?.name || null; } }; diff --git a/packages/common/src/db/queries/Era.ts b/packages/common/src/db/queries/Era.ts index 9c4a61d91..fe455e94b 100644 --- a/packages/common/src/db/queries/Era.ts +++ b/packages/common/src/db/queries/Era.ts @@ -1,33 +1,39 @@ -import { EraModel } from "../models"; +import { Era, EraModel } from "../models"; +import logger from "../../logger"; export const setLastNominatedEraIndex = async ( index: number, ): Promise => { - const data = await EraModel.findOne({}).lean(); - if (!data) { - const eraIndex = new EraModel({ - lastNominatedEraIndex: index.toString(), - when: Date.now(), - }); - await eraIndex.save(); - return true; - } - - await EraModel.findOneAndUpdate( - { lastNominatedEraIndex: /.*/ }, - { - $set: { + try { + const data = await EraModel.findOne({}).lean(); + if (!data) { + const eraIndex = new EraModel({ lastNominatedEraIndex: index.toString(), when: Date.now(), - nextNomination: Date.now() + 86400000, + }); + await eraIndex.save(); + return true; + } + + await EraModel.findOneAndUpdate( + { lastNominatedEraIndex: /.*/ }, + { + $set: { + lastNominatedEraIndex: index.toString(), + when: Date.now(), + nextNomination: Date.now() + 86400000, + }, }, - }, - ).exec(); - return true; + ).exec(); + return true; + } catch (e) { + logger.error( + `Error setting last nominated era index: ${JSON.stringify(e)}`, + ); + return false; + } }; -export const getLastNominatedEraIndex = async (): Promise => { - return EraModel.findOne({ lastNominatedEraIndex: /[0-9]+/ }) - .lean() - .exec(); +export const getLastNominatedEraIndex = async (): Promise => { + return EraModel.findOne({ lastNominatedEraIndex: /[0-9]+/ }).lean(); }; diff --git a/packages/common/src/db/queries/ValidatorScore.ts b/packages/common/src/db/queries/ValidatorScore.ts index b0cdbeeed..383ae04c0 100644 --- a/packages/common/src/db/queries/ValidatorScore.ts +++ b/packages/common/src/db/queries/ValidatorScore.ts @@ -107,7 +107,7 @@ export const getValidatorScore = async ( export const getLatestValidatorScore = async ( address: string, -): Promise => { +): Promise => { return ValidatorScoreModel.findOne({ address: address }, { _id: 0, __v: 0 }) .sort({ session: -1 }) .limit(1) diff --git a/packages/common/src/db/queries/Validators.ts b/packages/common/src/db/queries/Validators.ts index 45b4d5090..856488963 100644 --- a/packages/common/src/db/queries/Validators.ts +++ b/packages/common/src/db/queries/Validators.ts @@ -44,10 +44,7 @@ export const getLatestValidatorSet = async (): Promise => { }; export const getAllValidatorSets = async (): Promise => { - return ValidatorSetModel.find({}) - .sort({ era: -1 }) - .lean() - .exec(); + return ValidatorSetModel.find({}).sort({ era: -1 }).lean(); }; export const validatorSetExistsForEra = async ( diff --git a/packages/common/src/nominator/NominatorChainInfo.ts b/packages/common/src/nominator/NominatorChainInfo.ts index ca7053bb6..26f1e8e14 100644 --- a/packages/common/src/nominator/NominatorChainInfo.ts +++ b/packages/common/src/nominator/NominatorChainInfo.ts @@ -1,13 +1,14 @@ import Nominator from "./nominator"; import { queries } from "../index"; import { NOMINATOR_SHOULD_NOMINATE_ERAS_THRESHOLD } from "../constants"; +import { NominatorState } from "../types"; // Query on-chain info for a nominator export const getNominatorChainInfo = async (nominator: Nominator) => { const stash = await nominator.stash(); const isBonded = await nominator.chaindata.isBonded(stash); const [bonded, err] = await nominator.chaindata.getDenomBondedAmount(stash); - const currentBlock = await nominator.chaindata.getLatestBlock(); + const currentBlock = (await nominator.chaindata.getLatestBlock()) || 0; const currentEra = (await nominator.chaindata.getCurrentEra()) || 0; const lastNominationEra = @@ -20,7 +21,8 @@ export const getNominatorChainInfo = async (nominator: Nominator) => { const kyc = await queries.isKYC(target); let name = await queries.getIdentityName(target); if (!name) { - name = (await nominator.chaindata.getFormattedIdentity(target))?.name; + name = + (await nominator.chaindata.getFormattedIdentity(target))?.name || ""; } const scoreResult = await queries.getLatestValidatorScore(target); @@ -28,8 +30,8 @@ export const getNominatorChainInfo = async (nominator: Nominator) => { return { stash: target, - name: name, - kyc: kyc, + name: name || "", + kyc: kyc || false, score: score, }; }), @@ -49,7 +51,7 @@ export const getNominatorChainInfo = async (nominator: Nominator) => { if (!name) { const formattedIdentity = await nominator.chaindata.getFormattedIdentity(target); - name = formattedIdentity?.name; + name = formattedIdentity?.name || ""; } const scoreResult = await queries.getLatestValidatorScore(target); @@ -58,8 +60,8 @@ export const getNominatorChainInfo = async (nominator: Nominator) => { return { stash: target, - name: name, - kyc: kyc, + name: name || "", + kyc: kyc || false, score: score, }; }), @@ -95,13 +97,13 @@ export const getNominatorChainInfo = async (nominator: Nominator) => { let state; if (shouldNominate) { - state = "Ready to Nominate"; + state = NominatorState.ReadyToNominate; } else if (namedProxyTargets.length > 0) { - state = "Awaiting Proxy Execution"; + state = NominatorState.AwaitingProxyExecution; } else if (lastNominationEra == 0) { - state = "Not Nominating"; + state = NominatorState.NotNominating; } else if (namedProxyTargets.length == 0 && lastNominationEra > 0) { - status = "Nominated"; + state = NominatorState.Nominated; } const stale = diff --git a/packages/common/src/nominator/NominatorTx.ts b/packages/common/src/nominator/NominatorTx.ts index 188cf24ea..7a1273c5a 100644 --- a/packages/common/src/nominator/NominatorTx.ts +++ b/packages/common/src/nominator/NominatorTx.ts @@ -2,9 +2,10 @@ import logger from "../logger"; import { blake2AsHex } from "@polkadot/util-crypto"; import { DelayedTx } from "../db"; import { ChainData, queries } from "../index"; -import Nominator, { nominatorLabel } from "./nominator"; import { ApiPromise } from "@polkadot/api"; import MatrixBot from "../matrix"; +import Nominator, { nominatorLabel } from "./nominator"; +import { NominatorState } from "../types"; // Sends a Proxy Delay Nominate Tx for a given nominator // TODO: unit tests @@ -21,7 +22,7 @@ export const sendProxyDelayTx = async ( nominatorLabel, ); await nominator.updateNominatorStatus({ - state: "Nominating", + state: NominatorState.Nominating, status: `[noninate] starting proxy delay tx`, updated: Date.now(), stale: false, @@ -57,7 +58,7 @@ export const sendProxyDelayTx = async ( }; await queries.addDelayedTx(delayedTx); await nominator.updateNominatorStatus({ - state: "Nominating", + state: NominatorState.Nominating, status: `[noninate] tx: ${JSON.stringify(delayedTx)}`, updated: Date.now(), stale: false, @@ -67,7 +68,7 @@ export const sendProxyDelayTx = async ( const didSend = await nominator.signAndSendTx(tx); await nominator.updateNominatorStatus({ - state: "Awaiting Proxy Execution", + state: NominatorState.AwaitingProxyExecution, status: `Announced Proxy Tx: ${didSend}`, nextTargets: targets, updated: Date.now(), @@ -147,17 +148,20 @@ export const sendProxyTx = async ( targets.map(async (val) => { const name = await queries.getIdentityName(val); const kyc = await queries.isKYC(val); + const scoreResult = await queries.getLatestValidatorScore(val); + const score = scoreResult && scoreResult.total ? scoreResult.total : 0; return { address: val, - name: name, - kyc: kyc, + name: name || "", + kyc: kyc || false, + score: score, }; }), ); - const currentEra = await chaindata.getCurrentEra(); + const currentEra = (await chaindata.getCurrentEra()) || 0; await nominator.updateNominatorStatus({ - state: "Awaiting Proxy Execution", + state: NominatorState.AwaitingProxyExecution, status: "Submitted Proxy Tx", currentTargets: namedTargets, updated: Date.now(), diff --git a/packages/common/src/nominator/__mocks__/nominator.ts b/packages/common/src/nominator/__mocks__/nominator.ts index a226b9e99..ed8e876b4 100644 --- a/packages/common/src/nominator/__mocks__/nominator.ts +++ b/packages/common/src/nominator/__mocks__/nominator.ts @@ -100,6 +100,10 @@ class NominatorMock { async sendStakingTx(tx: any, targets: string[]): Promise { return true; } + + async updateNominatorStatus(): Promise { + return true; + } } export default NominatorMock; diff --git a/packages/common/src/nominator/nominator.ts b/packages/common/src/nominator/nominator.ts index 665a0632a..9197440ac 100644 --- a/packages/common/src/nominator/nominator.ts +++ b/packages/common/src/nominator/nominator.ts @@ -8,45 +8,10 @@ import logger from "../logger"; import EventEmitter from "eventemitter3"; import { sendProxyDelayTx, sendProxyTx } from "./NominatorTx"; import { getNominatorChainInfo } from "./NominatorChainInfo"; +import { NominatorState, NominatorStatus } from "../types"; export const nominatorLabel = { label: "Nominator" }; -export interface NominatorStatus { - state?: - | "Nominated" - | "Ready to Nominate" - | "Nominating" - | "Awaiting Proxy Execution" - | "Not Nominating" - | "Stale"; - status?: string; - isBonded?: boolean; - bondedAddress?: string; - bondedAmount?: number; - stashAddress?: string; - proxyAddress?: string; - isProxy?: boolean; - proxyDelay?: number; - isNominating?: boolean; - lastNominationEra?: number; - lastNominationTime?: number; - currentTargets?: - | string[] - | { - stash?: string; - name?: string; - kyc?: boolean; - score?: string | number; - }[]; - nextTargets?: string[]; - proxyTxs?: any[]; - updated: number; - rewardDestination?: string; - stale?: boolean; - dryRun?: boolean; - shouldNominate?: boolean; -} - export default class Nominator extends EventEmitter { public currentlyNominating: Types.Stash[] = []; @@ -65,7 +30,7 @@ export default class Nominator extends EventEmitter { // The amount of blocks for a time delay proxy private _proxyDelay: number; - public lastEraNomination: number; + public lastEraNomination = 0; public _shouldNominate = false; @@ -153,7 +118,7 @@ export default class Nominator extends EventEmitter { const [bonded, err] = await this.chaindata.getDenomBondedAmount(stash); const proxyTxs = await queries.getAccountDelayedTx(this.bondedAddress); const lastNominationEra = - await this.chaindata.getNominatorLastNominationEra(stash); + (await this.chaindata.getNominatorLastNominationEra(stash)) || 0; this.lastEraNomination = lastNominationEra; const currentEra = (await this.chaindata.getCurrentEra()) || 0; @@ -165,7 +130,7 @@ export default class Nominator extends EventEmitter { return this._shouldNominate; } - public async init(): Promise { + public async init(): Promise { try { const nominatorInfo = await getNominatorChainInfo(this); const { @@ -294,7 +259,7 @@ export default class Nominator extends EventEmitter { if (this._dryRun) { logger.info(`DRY RUN ENABLED, SKIPPING TX`, nominatorLabel); await this.updateNominatorStatus({ - state: "Nominating", + state: NominatorState.Nominating, status: `[signAndSend] DRY RUN TX`, updated: Date.now(), stale: false, @@ -304,7 +269,7 @@ export default class Nominator extends EventEmitter { logger.info(`Sending tx: ${tx.method.toString()}`, nominatorLabel); await tx.signAndSend(this.signer); await this.updateNominatorStatus({ - state: "Nominated", + state: NominatorState.Nominated, status: `[signAndSend] signed and sent tx`, updated: Date.now(), stale: false, @@ -335,9 +300,9 @@ export default class Nominator extends EventEmitter { return false; } - const currentEra = await this.chaindata.getCurrentEra(); + const currentEra = (await this.chaindata.getCurrentEra()) || 0; const nominatorStatus: NominatorStatus = { - state: "Nominating", + state: NominatorState.Nominating, status: `[nominate] start`, updated: Date.now(), stale: false, @@ -356,7 +321,7 @@ export default class Nominator extends EventEmitter { logger.info(`nominator is bonded: ${isBonded}`, nominatorLabel); await this.updateNominatorStatus({ - state: "Nominating", + state: NominatorState.Nominating, status: `[nominate] bonded; ${isBonded}`, updated: Date.now(), stale: false, @@ -374,7 +339,7 @@ export default class Nominator extends EventEmitter { // Start an announcement for a delayed proxy tx if (this._isProxy && this._proxyDelay > 0) { await this.updateNominatorStatus({ - state: "Nominating", + state: NominatorState.Nominating, status: `[nominate] proxy ${this._isProxy}; delay ${this._proxyDelay}`, updated: Date.now(), stale: false, @@ -455,30 +420,30 @@ export default class Nominator extends EventEmitter { // If Dry Run is enabled in the config, nominations will be stubbed but not executed if (this._dryRun) { logger.info(`DRY RUN ENABLED, SKIPPING TX`, nominatorLabel); - const currentEra = await this.chaindata.getCurrentEra(); + const currentEra = (await this.chaindata.getCurrentEra()) || 0; const namedTargets = await Promise.all( targets.map(async (target) => { - const kyc = await queries.isKYC(target); - let name = await queries.getIdentityName(target); + const kyc = (await queries.isKYC(target)) || false; + let name = (await queries.getIdentityName(target)) || ""; // Fetch name using chaindata.getFormattedIdentity only if the name wasn't found initially if (!name) { const formattedIdentity = await this.chaindata.getFormattedIdentity(target); - name = formattedIdentity?.name; + name = formattedIdentity?.name || ""; } return { stash: target, - name, // shorthand for name: name - kyc, // shorthand for kyc: kyc + name: name || "", + kyc: kyc || false, score: 0, }; }), ); const nominatorStatus: NominatorStatus = { - state: "Nominating", + state: NominatorState.Nominating, status: `Dry Run: Nominated ${targets.length} validators`, updated: Date.now(), stale: false, @@ -620,27 +585,28 @@ export default class Nominator extends EventEmitter { break; } }); - const currentEra = await this.chaindata.getCurrentEra(); + const currentEra = (await this.chaindata.getCurrentEra()) || 0; const namedTargets = await Promise.all( targets.map(async (target) => { const kyc = await queries.isKYC(target); let name = await queries.getIdentityName(target); if (!name) { - name = (await this.chaindata.getFormattedIdentity(target))?.name; + name = + (await this.chaindata.getFormattedIdentity(target))?.name || ""; } const score = await queries.getLatestValidatorScore(target); return { stash: target, - name: name, - kyc: kyc, - score: score && score[0] && score[0].total ? score[0].total : 0, + name: name || "", + kyc: kyc || false, + score: score && score && score?.total ? score?.total : 0, }; }), ); const nominatorStatus: NominatorStatus = { - state: "Nominated", + state: NominatorState.Nominated, status: `Nominated ${targets.length} validators: ${didSend} ${finalizedBlockHash}`, updated: Date.now(), stale: false, @@ -651,7 +617,7 @@ export default class Nominator extends EventEmitter { return [didSend, finalizedBlockHash || null]; // Change to return undefined } catch (e) { logger.error(`Error sending tx: ${JSON.stringify(e)}`, nominatorLabel); - return [false, e]; + return [false, JSON.stringify(e)]; } }; } diff --git a/packages/common/src/scorekeeper/Nominating.ts b/packages/common/src/scorekeeper/Nominating.ts index 74febe5a4..4e793ef87 100644 --- a/packages/common/src/scorekeeper/Nominating.ts +++ b/packages/common/src/scorekeeper/Nominating.ts @@ -10,7 +10,8 @@ import { ChainData, queries, Util } from "../index"; import ApiHandler from "../ApiHandler/ApiHandler"; import MatrixBot from "../matrix"; import { ConfigSchema } from "../config"; -import Nominator, { NominatorStatus } from "../nominator/nominator"; +import Nominator from "../nominator/nominator"; +import { NominatorState, NominatorStatus } from "../types"; // Takes in a list of valid Candidates, and will nominate them based on the nominator groups export const doNominations = async ( @@ -59,7 +60,7 @@ export const doNominations = async ( } const nominatorStatus: NominatorStatus = { - state: "Nominating", + state: NominatorState.Nominating, status: `Nominating...`, updated: Date.now(), stale: false, diff --git a/packages/common/src/scorekeeper/NumNominations.ts b/packages/common/src/scorekeeper/NumNominations.ts index 4833b350b..53eaa3d2c 100644 --- a/packages/common/src/scorekeeper/NumNominations.ts +++ b/packages/common/src/scorekeeper/NumNominations.ts @@ -5,9 +5,10 @@ */ import { ApiPromise } from "@polkadot/api"; import { scorekeeperLabel } from "./scorekeeper"; -import Nominator, { NominatorStatus } from "../nominator/nominator"; +import Nominator from "../nominator/nominator"; import { Constants } from "../index"; import logger from "../logger"; +import { NominatorState, NominatorStatus } from "../types"; /** * Automatically determines the number of validators a nominator can nominate based on their available balance @@ -36,7 +37,7 @@ export const autoNumNominations = async ( nominator: Nominator, ): Promise => { const nominatorStatus: NominatorStatus = { - state: "Nominating", + state: NominatorState.Nominating, status: `Calculating how many validators to nominate...`, updated: Date.now(), stale: false, diff --git a/packages/common/src/scorekeeper/Round.ts b/packages/common/src/scorekeeper/Round.ts index e70d8e521..8507c87e5 100644 --- a/packages/common/src/scorekeeper/Round.ts +++ b/packages/common/src/scorekeeper/Round.ts @@ -11,9 +11,10 @@ import { OTV } from "../constraints/constraints"; import { ConfigSchema } from "../config"; import MatrixBot from "../matrix"; import ApiHandler from "../ApiHandler/ApiHandler"; -import Nominator, { NominatorStatus } from "../nominator/nominator"; +import Nominator from "../nominator/nominator"; import { jobStatusEmitter } from "../Events"; import { JobNames } from "./jobs/JobConfigs"; +import { NominatorState, NominatorStatus } from "../types"; /// Handles the beginning of a new round. // - Gets the current era @@ -34,16 +35,6 @@ export const startRound = async ( if (nominating) return []; nominating = true; - const shouldNominatePromises = nominatorGroups.map(async (nom) => { - return { - nominator: nom, - shouldNominate: await nom.shouldNominate(), - }; - }); - const resolvedNominators = await Promise.all(shouldNominatePromises); - const filteredNominators = resolvedNominators - .filter((nom) => nom.shouldNominate) - .map((nom) => nom.nominator); const now = new Date().getTime(); // The nominations sent now won't be active until the next era. @@ -58,9 +49,9 @@ export const startRound = async ( `New round is starting! Era ${newEra} will begin new nominations.`, ); - for (const nom of filteredNominators) { + for (const nom of nominatorGroups) { const nominatorStatus: NominatorStatus = { - state: "Nominating", + state: NominatorState.Nominating, status: `Round Started`, updated: Date.now(), stale: false, @@ -98,9 +89,9 @@ export const startRound = async ( `[${index}/${allCandidates.length}] checked ${candidate.name} ${isValid ? "Valid" : "Invalid"} [${index}/${allCandidates.length}]`, scorekeeperLabel, ); - for (const nom of filteredNominators) { + for (const nom of nominatorGroups) { const nominatorStatus: NominatorStatus = { - state: "Nominating", + state: NominatorState.Nominating, status: `[${index}/${allCandidates.length}] ${candidate.name} ${isValid ? "✅ " : "❌"}`, updated: Date.now(), stale: false, @@ -109,9 +100,9 @@ export const startRound = async ( } } - for (const nom of filteredNominators) { + for (const nom of nominatorGroups) { const nominatorStatus: NominatorStatus = { - state: "Nominating", + state: NominatorState.Nominating, status: `Scoring Candidates...`, updated: Date.now(), stale: false, @@ -129,7 +120,7 @@ export const startRound = async ( const scoredCandidate = { name: candidate.name, stash: candidate.stash, - total: score.total, + total: score?.total || 0, }; return scoredCandidate; }), @@ -146,7 +137,7 @@ export const startRound = async ( // TODO unit test that assets this value const numValidatorsNominated = await doNominations( sortedCandidates, - filteredNominators, + nominatorGroups, chaindata, handler, bot, @@ -160,9 +151,9 @@ export const startRound = async ( scorekeeperLabel, ); await queries.setLastNominatedEraIndex(newEra); - for (const nom of filteredNominators) { + for (const nom of nominatorGroups) { const nominatorStatus: NominatorStatus = { - state: "Nominated", + state: NominatorState.Nominated, status: `Nominated!`, updated: Date.now(), stale: false, diff --git a/packages/common/src/scorekeeper/jobs/specificJobs/CancelJob.ts b/packages/common/src/scorekeeper/jobs/specificJobs/CancelJob.ts index b901114a2..69b145873 100644 --- a/packages/common/src/scorekeeper/jobs/specificJobs/CancelJob.ts +++ b/packages/common/src/scorekeeper/jobs/specificJobs/CancelJob.ts @@ -20,7 +20,7 @@ export const cancelJob = async ( const latestBlock = await chaindata.getLatestBlock(); if (!latestBlock) { logger.error(`latest block is null`, cronLabel); - return; + return false; } const threshold = latestBlock - 1.2 * config?.proxy?.timeDelayBlocks; diff --git a/packages/common/src/scorekeeper/jobs/specificJobs/ConstraintsJob.ts b/packages/common/src/scorekeeper/jobs/specificJobs/ConstraintsJob.ts index ed81ec78b..520d5c5be 100644 --- a/packages/common/src/scorekeeper/jobs/specificJobs/ConstraintsJob.ts +++ b/packages/common/src/scorekeeper/jobs/specificJobs/ConstraintsJob.ts @@ -162,7 +162,7 @@ export const scoreJob = async ( name: JobNames.Score, progress, updated: Date.now(), - iteration: `[${score.toFixed(1)}] ${candidate.name}`, + iteration: `[${score?.toFixed(1)}] ${candidate.name}`, }); logger.info( diff --git a/packages/common/src/scorekeeper/jobs/specificJobs/EraPointsJob.ts b/packages/common/src/scorekeeper/jobs/specificJobs/EraPointsJob.ts index e6e0c4dc3..fffa5305a 100644 --- a/packages/common/src/scorekeeper/jobs/specificJobs/EraPointsJob.ts +++ b/packages/common/src/scorekeeper/jobs/specificJobs/EraPointsJob.ts @@ -22,7 +22,7 @@ export const individualEraPointsJob = async ( // If Era Points for the era exist, and are what the total should be, skip if (!!erapoints && erapoints.totalEraPoints >= 0 && erapoints.median) { - return; + return false; } else { const data = await chaindata.getTotalEraPoints(eraIndex); if ( diff --git a/packages/common/src/scorekeeper/jobs/specificJobs/ExecutionJob.ts b/packages/common/src/scorekeeper/jobs/specificJobs/ExecutionJob.ts index b00b9cee7..c6cb1bd3f 100644 --- a/packages/common/src/scorekeeper/jobs/specificJobs/ExecutionJob.ts +++ b/packages/common/src/scorekeeper/jobs/specificJobs/ExecutionJob.ts @@ -4,7 +4,7 @@ import { Constants, queries, Util } from "../../../index"; import { cronLabel } from "../cron/StartCronJobs"; import { jobStatusEmitter } from "../../../Events"; import { JobNames } from "../JobConfigs"; -import { NominatorStatus } from "../../../nominator/nominator"; +import { NominatorState, NominatorStatus } from "../../../types"; export class ExecutionJob extends Job { constructor(jobConfig: JobConfig, jobRunnerMetadata: JobRunnerMetadata) { @@ -28,19 +28,19 @@ export const executionJob = async ( const latestBlock = await chaindata.getLatestBlock(); if (!latestBlock) { logger.error(`latest block is null`, cronLabel); - return; + return false; } const api = handler.getApi(); if (!api) { logger.error(`api is null`, cronLabel); - return; + return false; } const era = await chaindata.getCurrentEra(); if (!era) { logger.error(`current era is null`, cronLabel); - return; + return false; } const allDelayed = await queries.getAllDelayedTxs(); @@ -129,7 +129,7 @@ export const executionJob = async ( if (shouldExecute) { await nominator.updateNominatorStatus({ - state: "Nominating", + state: NominatorState.Nominating, status: `Starting Delayed Execution for ${callHash} - ${dataNum}`, updated: Date.now(), stale: false, @@ -140,7 +140,7 @@ export const executionJob = async ( ); const nominatorStatus: NominatorStatus = { - state: "Nominating", + state: NominatorState.NotNominating, status: `${isDryRun ? "DRY RUN: " : ""} Executing Valid Proxy Tx: ${data.callHash}`, updated: Date.now(), stale: false, @@ -170,7 +170,7 @@ export const executionJob = async ( // `dryRun` is a special value for the returned block hash that is used to test the execution job without actually sending the transaction if (didSend || finalizedBlockHash == "dryRun") { const nominatorStatus: NominatorStatus = { - state: "Nominated", + state: NominatorState.Nominated, status: `Executed Proxy Tx: ${finalizedBlockHash == "dryRun" ? "" : didSend} ${finalizedBlockHash}`, updated: Date.now(), stale: false, diff --git a/packages/common/src/scorekeeper/jobs/specificJobs/MainScorekeeperJob.ts b/packages/common/src/scorekeeper/jobs/specificJobs/MainScorekeeperJob.ts index fbb19c956..67be1a52d 100644 --- a/packages/common/src/scorekeeper/jobs/specificJobs/MainScorekeeperJob.ts +++ b/packages/common/src/scorekeeper/jobs/specificJobs/MainScorekeeperJob.ts @@ -4,6 +4,7 @@ import { queries } from "../../../index"; import { startRound } from "../../Round"; import { jobStatusEmitter } from "../../../Events"; import { JobNames } from "../JobConfigs"; +import { NOMINATOR_SHOULD_NOMINATE_ERAS_THRESHOLD } from "../../../constants"; export class MainScorekeeperJob extends Job { constructor(jobConfig: JobConfig, jobRunnerMetadata: JobRunnerMetadata) { @@ -41,7 +42,8 @@ export const mainScorekeeperJob = async ( return; } - const { lastNominatedEraIndex } = await queries.getLastNominatedEraIndex(); + const lastNominatedEra = await queries.getLastNominatedEraIndex(); + const lastNominatedEraIndex = lastNominatedEra?.lastNominatedEraIndex || 0; const eraBuffer = config.global.networkPrefix == 0 ? 1 : 4; const isNominationRound = Number(lastNominatedEraIndex) <= activeEra - eraBuffer; @@ -55,8 +57,10 @@ export const mainScorekeeperJob = async ( const stash = await nom.stash(); if (!stash || stash === "0x") return false; const lastNominatedEra = - await chaindata.getNominatorLastNominationEra(stash); - return lastNominatedEra <= activeEra - 1; + (await chaindata.getNominatorLastNominationEra(stash)) || 0; + return ( + activeEra - lastNominatedEra >= NOMINATOR_SHOULD_NOMINATE_ERAS_THRESHOLD + ); }), ); diff --git a/packages/common/src/scorekeeper/jobs/specificJobs/StaleNomination.ts b/packages/common/src/scorekeeper/jobs/specificJobs/StaleNomination.ts index 444ecfb57..85f2651a5 100644 --- a/packages/common/src/scorekeeper/jobs/specificJobs/StaleNomination.ts +++ b/packages/common/src/scorekeeper/jobs/specificJobs/StaleNomination.ts @@ -38,7 +38,7 @@ export const staleNominationJob = async ( if (!stash || stash === "0x") continue; const lastNominatedEra = - await chaindata.getNominatorLastNominationEra(stash); + (await chaindata.getNominatorLastNominationEra(stash)) || 0; if (lastNominatedEra < Number(currentEra) - threshold) { const message = `Nominator ${stash} has a stale nomination. Last nomination was in era ${nom.getStatus()?.lastNominationEra} (it is now era ${currentEra})`; diff --git a/packages/common/src/scorekeeper/scorekeeper.ts b/packages/common/src/scorekeeper/scorekeeper.ts index c9e23c1a0..05ca7a017 100644 --- a/packages/common/src/scorekeeper/scorekeeper.ts +++ b/packages/common/src/scorekeeper/scorekeeper.ts @@ -9,7 +9,7 @@ import { Util, } from "../index"; -import Nominator, { NominatorStatus } from "../nominator/nominator"; +import Nominator from "../nominator/nominator"; import { registerAPIHandler, registerEventEmitterHandler, @@ -17,6 +17,7 @@ import { import { Job, JobRunnerMetadata, JobStatus } from "./jobs/JobsClass"; import { JobsRunnerFactory } from "./jobs/JobsRunnerFactory"; import { startRound } from "./Round"; +import { NominatorStatus } from "../types"; // import { monitorJob } from "./jobs"; export type NominatorGroup = Config.NominatorConfig[]; @@ -240,7 +241,7 @@ export default class ScoreKeeper { scorekeeperLabel, ); - const currentEra = await this.chaindata.getCurrentEra(); + const currentEra = (await this.chaindata.getCurrentEra()) || 0; this.currentEra = currentEra; // await setAllIdentities(this.chaindata, scorekeeperLabel); diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 7936559dd..6095a0aee 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -111,3 +111,42 @@ export interface TelemetryWsPayload extends Array { 6: any; // location 7: any; // startupTime } + +export enum NominatorState { + Nominated = "Nominated", + ReadyToNominate = "Ready to Nominate", + Nominating = "Nominating", + AwaitingProxyExecution = "Awaiting Proxy Execution", + NotNominating = "Not Nominating", + Stale = "Stale", +} + +export interface NominatorStatus { + state?: NominatorState; + status?: string; + isBonded?: boolean; + bondedAddress?: string; + bondedAmount?: number; + stashAddress?: string; + proxyAddress?: string; + isProxy?: boolean; + proxyDelay?: number; + isNominating?: boolean; + lastNominationEra?: number; + lastNominationTime?: number; + currentTargets?: + | string[] + | { + stash?: string; + name?: string; + kyc?: boolean; + score?: string | number; + }[]; + nextTargets?: string[]; + proxyTxs?: any[]; + updated: number; + rewardDestination?: string; + stale?: boolean; + dryRun?: boolean; + shouldNominate?: boolean; +} diff --git a/packages/common/src/utils/Validators.ts b/packages/common/src/utils/Validators.ts index d8e87f0b5..b296e6b59 100644 --- a/packages/common/src/utils/Validators.ts +++ b/packages/common/src/utils/Validators.ts @@ -1,4 +1,4 @@ -import { allCandidates, setRank } from "../db"; +import { allCandidates, setRank } from "../db/queries"; import { queries } from "../index"; // Sets all validators ranks diff --git a/packages/common/test/db/queries/EraStats.unit.test.ts b/packages/common/test/db/queries/EraStats.unit.test.ts index 72b8d62cd..c0ba80d47 100644 --- a/packages/common/test/db/queries/EraStats.unit.test.ts +++ b/packages/common/test/db/queries/EraStats.unit.test.ts @@ -10,13 +10,15 @@ describe("setEraStats", () => { const totalNodes = 10; const valid = 8; const active = 6; - await setEraStats(era, totalNodes, valid, active); + const kyc = 3; + await setEraStats(era, totalNodes, valid, active, kyc); const eraStats = await EraStatsModel.findOne({ era }).lean(); expect(eraStats).toBeDefined(); expect(eraStats?.totalNodes).toBe(totalNodes); expect(eraStats?.valid).toBe(valid); expect(eraStats?.active).toBe(active); + expect(eraStats?.kyc).toBe(kyc); }); it("should update existing era stats with different values", async () => { @@ -24,6 +26,7 @@ describe("setEraStats", () => { const initialTotalNodes = 5; const initialValid = 4; const initialActive = 3; + const kyc = 2; await new EraStatsModel({ era, totalNodes: initialTotalNodes, @@ -34,13 +37,14 @@ describe("setEraStats", () => { const updatedTotalNodes = 12; const updatedValid = 10; const updatedActive = 8; - await setEraStats(era, updatedTotalNodes, updatedValid, updatedActive); + await setEraStats(era, updatedTotalNodes, updatedValid, updatedActive, kyc); const eraStats = await EraStatsModel.findOne({ era }).lean(); expect(eraStats).toBeDefined(); expect(eraStats?.totalNodes).toBe(updatedTotalNodes); expect(eraStats?.valid).toBe(updatedValid); expect(eraStats?.active).toBe(updatedActive); + expect(eraStats?.kyc).toBe(kyc); }); it("should not update existing era stats if values are the same", async () => { @@ -48,10 +52,11 @@ describe("setEraStats", () => { const totalNodes = 20; const valid = 15; const active = 10; - await new EraStatsModel({ era, totalNodes, valid, active }).save(); + const kyc = 5; + await new EraStatsModel({ era, totalNodes, valid, active, kyc }).save(); // Call setEraStats with the same values - await setEraStats(era, totalNodes, valid, active); + await setEraStats(era, totalNodes, valid, active, kyc); const eraStats = await EraStatsModel.findOne({ era }).lean(); expect(eraStats).toBeDefined(); @@ -59,6 +64,7 @@ describe("setEraStats", () => { expect(eraStats?.totalNodes).toBe(totalNodes); expect(eraStats?.valid).toBe(valid); expect(eraStats?.active).toBe(active); + expect(eraStats?.kyc).toBe(kyc); }); }); @@ -70,6 +76,7 @@ describe("getLatestEraStats", () => { totalNodes: era * 2, valid: era * 1.5, active: era, + kyc: 1, })); await EraStatsModel.create(eraStatsData); diff --git a/packages/common/test/scorekeeper/NumNominations.int.test.ts b/packages/common/test/scorekeeper/NumNominations.int.test.ts index c43c7ff56..1a58ba2e7 100644 --- a/packages/common/test/scorekeeper/NumNominations.int.test.ts +++ b/packages/common/test/scorekeeper/NumNominations.int.test.ts @@ -2,6 +2,8 @@ import { ApiPromise, WsProvider } from "@polkadot/api"; import { autoNumNominations } from "../../src/scorekeeper/NumNominations"; import { KusamaEndpoints } from "../../src/constants"; +import Nominator from "../../src/nominator/nominator"; +import ApiHandler from "../../src/ApiHandler/ApiHandler"; describe("autoNumNominations Integration Test", () => { it("queries the real API and retrieves data", async () => { @@ -10,11 +12,18 @@ describe("autoNumNominations Integration Test", () => { }); await api.isReadyOrError; - const nom = { - stash: () => "EX9uchmfeSqKTM7cMMg8DkH49XV8i4R7a7rqCn8btpZBHDP", + const handler = new ApiHandler(KusamaEndpoints); + + const nominatorConfig = { + isProxy: false, + seed: "0x" + "00".repeat(32), + proxyDelay: 10800, + proxyFor: "EX9uchmfeSqKTM7cMMg8DkH49XV8i4R7a7rqCn8btpZBHDP", }; - const result = await autoNumNominations(api, nom as any); + const nominator = new Nominator(handler, nominatorConfig, 2, null); + + const result = await autoNumNominations(api, nominator); expect(result).toBeDefined(); diff --git a/packages/common/test/utils/Validators.unit.test.ts b/packages/common/test/utils/Validators.unit.test.ts new file mode 100644 index 000000000..9cb61e41b --- /dev/null +++ b/packages/common/test/utils/Validators.unit.test.ts @@ -0,0 +1,101 @@ +// import { setValidatorRanks } from "../../src/utils"; +import { addKusamaCandidates } from "../testUtils/candidate"; +import { Identity } from "../../src/types"; +import { + addCandidate, + getCandidate, + getIdentityValidatorActiveEras, + getValidatorActiveEras, + setCandidateIdentity, + setValidatorSet, +} from "../../src/db/queries"; +import { initTestServerBeforeAll } from "../testUtils/dbUtils"; +import { ValidatorSetModel } from "../../src/db"; +import { setValidatorRanks } from "../../src/utils/Validators"; + +initTestServerBeforeAll(); +describe("setValidatorRanks", () => { + it("should set ranks for all candidates", async () => { + await addKusamaCandidates(); + + await addCandidate( + 2398, + "Blockshard2", + "HkJjBkX8fPBFJvTtAbUDKWZSsMrNFuMc7TrT8BqVS5YhZXg", + "", + false, + "matrixhandle", + false, + ); + + const identity1: Identity = { + address: "Cp4U5UYg2FaVUpyEtQgfBm9aqge6EEPkJxEFVZFYy7L1AZF", + name: "Blockshard", + display: "Blockshard", + subIdentities: [ + { + name: "Blockshard2", + address: "HkJjBkX8fPBFJvTtAbUDKWZSsMrNFuMc7TrT8BqVS5YhZXg", + }, + ], + }; + const identity2: Identity = { + address: "D9rwRxuG8xm8TZf5tgkbPxhhTJK5frCJU9wvp59VRjcMkUf", + name: "🎠 Forbole GP01 🇭🇰", + display: "🎠 Forbole GP01 🇭🇰", + }; + const identity3: Identity = { + address: "J4hAvZoHCviZSoPHoSwLida8cEkZR1NXJcGrcfx9saHTk7D", + name: "Anonstake", + display: "Anonstake", + }; + const identity4: Identity = { + address: "EPhtbjecJ9P2SQEGEJ4XmFS4xN7JioBFarSrbqjhj8BuJ2v", + name: "Indigo One", + display: "Indigo One", + }; + const identity5: Identity = { + address: "HhcrzHdB5iBx823XNfBUukjj4TUGzS9oXS8brwLm4ovMuVp", + name: "KIRA Staking", + display: "KIRA Staking", + }; + await setCandidateIdentity(identity1?.address, identity1); + + await setValidatorSet(1, 1, [identity1?.address, identity2?.address]); + await setValidatorSet(5, 2, [identity1?.address, identity2?.address]); + await setValidatorSet(8, 3, [ + identity1?.address, + identity3?.address, + identity5?.address, + "HkJjBkX8fPBFJvTtAbUDKWZSsMrNFuMc7TrT8BqVS5YhZXg", + ]); + await setValidatorSet(16, 4, [ + identity1?.address, + identity3?.address, + identity4?.address, + "HkJjBkX8fPBFJvTtAbUDKWZSsMrNFuMc7TrT8BqVS5YhZXg", + identity5?.address, + ]); + await setValidatorSet(100, 5, [identity1?.address, identity4?.address]); + + const validatorSets = await ValidatorSetModel.find({}).exec(); + expect(validatorSets.length).toBe(5); + + const numEras = await getValidatorActiveEras(identity1?.address); + expect(numEras).toBe(5); + + const subNumEras = await getIdentityValidatorActiveEras( + "HkJjBkX8fPBFJvTtAbUDKWZSsMrNFuMc7TrT8BqVS5YhZXg", + ); + expect(subNumEras).toBe(5); + + await setValidatorRanks(); + const candidate = await getCandidate(identity1?.address); + expect(candidate?.rank).toBe(5); + + const secondNode = await getCandidate( + "HkJjBkX8fPBFJvTtAbUDKWZSsMrNFuMc7TrT8BqVS5YhZXg", + ); + expect(secondNode?.rank).toBe(5); + }, 10000); +}); diff --git a/packages/core/package.json b/packages/core/package.json index 3e1805b6f..ed17917ff 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -40,7 +40,7 @@ "@1kv/worker": "workspace:^", "@koa/router": "^12.0.1", "@octokit/rest": "^20.0.2", - "@polkadot/api": "^10.11.2", + "@polkadot/api": "^10.12.1", "@polkadot/keyring": "^12.6.2", "@types/cron": "^2.4.0", "@types/jest": "^29.5.12", diff --git a/packages/gateway/src/routes/index.ts b/packages/gateway/src/routes/index.ts index 382dd1f99..9f1a1492a 100644 --- a/packages/gateway/src/routes/index.ts +++ b/packages/gateway/src/routes/index.ts @@ -52,7 +52,6 @@ const API = { CurrentValidatorSet: "/validators/current", Validators: "/validators", Validator: "/validator/:address", - //TODO: add to swagger ValidatorsNumActiveEras: "/validators/activeeras/:address", ValidatorsBeefyStats: "/validators/beefy", ValidatorsBeefyDummy: "/validators/beefy/dummy", @@ -132,20 +131,4 @@ router.get(API.BlockIndex, Block.getBlockIndex); router.get(API.StatsTotalReqeusts, Stats.getTotalRequests); router.get(API.StatsEndpointCounts, Stats.getEndpointCounts); -// router.get("/stats/totalRequests", (ctx) => { -// ctx.body = { totalRequests: requestEmitter.listenerCount("requestReceived") }; -// }); -// -// // Endpoint to retrieve the count of requests per endpoint -// router.get("/stats/endpointCounts", (ctx) => { -// const endpointCounts = {}; -// -// // Iterate over all registered endpoints -// requestEmitter.eventNames().forEach((endpoint) => { -// endpointCounts[endpoint] = requestEmitter.listenerCount(endpoint); -// }); -// -// ctx.body = { endpointCounts }; -// }); - export default router; diff --git a/packages/gateway/src/swagger.yml b/packages/gateway/src/swagger.yml index a7d5d882b..e9993719a 100644 --- a/packages/gateway/src/swagger.yml +++ b/packages/gateway/src/swagger.yml @@ -32,6 +32,8 @@ tags: description: Querying score data paths: + + /candidate/{candidateStash}: get: tags: @@ -58,6 +60,33 @@ paths: description: Successful response with a list of candidates + /candidates/rank: + get: + tags: + - Candidates + summary: Retrieve a list of candidates ordered by rank + responses: + 200: + description: Successful response with a list of candidates + + /candidates/valid: + get: + tags: + - Candidates + summary: Retrieve a list of candidates that are valid + responses: + 200: + description: Successful response with a list of candidates + + /candidates/invalid: + get: + tags: + - Candidates + summary: Retrieve a list of candidates that are invalid + responses: + 200: + description: Successful response with a list of candidates + /rewards/validator/{stash}: get: tags: @@ -148,12 +177,7 @@ paths: responses: 200: description: Rewards. - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/Reward' + /rewards/nominator/{address}/total: get: @@ -171,13 +195,19 @@ paths: responses: '200': description: "Total rewards for the specified nominator." - content: - application/json: - schema: - $ref: '#/components/schemas/RewardTotal' '404': description: "Validator not found." + + /healthcheck: + get: + summary: "health check of the backend" + description: "Health check of the backend" + responses: + '200': + description: "health check of the backend" + + /nominators: get: summary: "Get All Nominators" @@ -207,6 +237,31 @@ paths: '404': description: "Nominator not found." + /nominator/{address}/{last}: + get: + summary: "Get Nominator by Address" + tags: + - Nominator + description: "Retrieve details of a specific nominator by address." + parameters: + - in: path + name: address + required: true + schema: + type: string + description: "The unique address of the nominator." + - in: path + name: last + required: true + schema: + type: string + description: "Number of eras to retrieve." + responses: + '200': + description: "Successful response with nominator details." + '404': + description: "Nominator not found." + /nominations: get: summary: "Get All Nominations" @@ -385,12 +440,12 @@ paths: '404': description: "Data not found." - /delegations/{address}: + + + /erapoints/{address}: get: - summary: "Delegation Data" - tags: - - Candidates - description: "Retrieve details of a specific validator's delegations'" + summary: "Era Points" + description: "Retrieve details of a specific validator's era points'" parameters: - in: path name: address @@ -404,100 +459,178 @@ paths: '404': description: "Data not found." - /opengov/votes/address/{address}: + /totalerapoints: get: - summary: "Open Gov Vote Data" - tags: - - Candidates - description: "Retrieve details of a specific validator's votes" + summary: "Total Era Points" + description: "Retrieves total era points" + responses: + '200': + description: "Successful response." + + /erastats: + get: + summary: "Era Stats" + description: "Retrieves era stats" + responses: + '200': + description: "Successful response." + + /scoremetadata: + get: + summary: "Score Metadata" + description: "Retrieves score metadata" + responses: + '200': + description: "Successful response." + + /scoremetadata/{session}: + get: + summary: "Score Metadata" + description: "Retrieve details of a score metadata for a session'" parameters: - in: path - name: address + name: session required: true schema: type: string - description: "The unique address of the validator." + description: "Session" + responses: + '200': + description: "Successful response." + '404': + description: "Data not found." + + /release: + get: + summary: "Latest Release" + description: "Retrieves latest tagged release" + responses: + '200': + description: "Successful response." + + /location/currentvalidatorset: + get: + summary: "location stats of the current validator set" + description: "location stats of the current validator set" + responses: + '200': + description: "Successful response." + + /locationstats: + get: + summary: "location stats" + description: "location stats" + responses: + '200': + description: "Successful response." + + /locationstats/valid: + get: + summary: "location stats of valid nodes" + description: "location stats of valid nodes" + responses: + '200': + description: "Successful response." + + /locationstats/{session}: + get: + summary: "location stats for a session" + description: "Retrieve details of location stats for a session'" + parameters: + - in: path + name: session + required: true + schema: + type: string + description: "Session" responses: '200': description: "Successful response." '404': description: "Data not found." -# -# -#components: -# schemas: -# Reward: -# type: object -# properties: -# role: -# type: string -# exposurePercentage: -# type: integer -# totalStake: -# type: integer -# commission: -# type: integer -# era: -# type: integer -# validator: -# type: string -# nominator: -# type: string -# rewardAmount: -# type: string -# rewardDestination: -# type: string -# erasMinStake: -# type: number -# format: float -# validatorStakeEfficiency: -# type: number -# format: float -# blockHash: -# type: string -# blockNumber: -# type: integer -# timestamp: -# type: integer -# date: -# type: string -# format: date -# chf: -# type: number -# format: float -# usd: -# type: number -# format: float -# eur: -# type: number -# format: float -# RewardTotal: -# type: object -# properties: -# validator: -# type: string -# example: "ESNMjpEWcenAbCqGEsHVdbbRai79VQYMmV1fNW1kRZogmzx" -# total: -# type: number -# format: float -# example: 0.879469625343 -# rewardCount: -# type: integer -# example: 1 -# RewardStats: -# type: object -# properties: -# total: -# type: number -# format: float -# example: 0.235934990397 -# rewardCount: -# type: integer -# example: 1 -# avgEfficiency: -# type: number -# format: float -# example: 84.46114961271203 -# avgStake: -# type: integer -# example: 7985 \ No newline at end of file + + /validators/current: + get: + summary: "Current Validator Set" + description: "Current Validator Set" + responses: + '200': + description: "Successful response." + + /validators: + get: + summary: "Validator Set Keys" + description: "Validator Set Keys" + responses: + '200': + description: "Successful response." + + /validators/beefy: + get: + summary: "Validator Set Beefy Keys" + description: "Validator Set Beefy Keys" + responses: + '200': + description: "Successful response." + + /validators/beefy/dummmy: + get: + summary: "Validator Set Beefy Dummy Keys" + description: "Validator Set Beefy Dummy Keys" + responses: + '200': + description: "Successful response." + + /validators/{address}: + get: + summary: "Validator Set Keys" + description: "Validator Set Keys" + parameters: + - in: path + name: address + required: true + schema: + type: string + description: "address" + responses: + '200': + description: "Successful response." + + /validators/activeeras/{address}: + get: + summary: "Number of active eras for an address" + description: "Number of active eras for an address" + parameters: + - in: path + name: address + required: true + schema: + type: string + description: "address" + responses: + '200': + description: "Successful response." + + /blockindex: + get: + summary: "The block index of the backend" + description: "block index of the backend" + responses: + '200': + description: "Successful response." + + /stats/totalReqeusts: + get: + summary: "The total number of api requests of the backend" + description: "The total number of api requests of the backend" + responses: + '200': + description: "Successful response." + + /stats/endpointCount: + get: + summary: "The total number of api requests of the backend for an endpoint" + description: "The total number of api requests of the backend for an endpoint" + responses: + '200': + description: "Successful response." \ No newline at end of file diff --git a/packages/scorekeeper-status-ui/src/App.tsx b/packages/scorekeeper-status-ui/src/App.tsx index 296ca65b9..8f2e1c56a 100644 --- a/packages/scorekeeper-status-ui/src/App.tsx +++ b/packages/scorekeeper-status-ui/src/App.tsx @@ -1,4 +1,5 @@ import React, { useCallback, useEffect, useState } from "react"; +import axios from "axios"; import { FiActivity, FiAlertTriangle, @@ -15,15 +16,13 @@ import { FiUserCheck, FiXCircle, } from "react-icons/fi"; - import { BeatLoader } from "react-spinners"; import { motion } from "framer-motion"; import "./App.css"; -import axios from "axios"; // Ensure the path to your CSS file is correct -import { debounce } from "lodash"; import HealthCheckBar from "./HealthCheckBar"; import { Identicon } from "@polkadot/react-identicon"; import EraStatsBar from "./EraStatsBar"; +import { debounce } from "lodash"; interface Job { name: string; diff --git a/packages/scorekeeper-status-ui/src/EraStatsBar.tsx b/packages/scorekeeper-status-ui/src/EraStatsBar.tsx index a8c7f60af..ff2f37f6e 100644 --- a/packages/scorekeeper-status-ui/src/EraStatsBar.tsx +++ b/packages/scorekeeper-status-ui/src/EraStatsBar.tsx @@ -23,10 +23,7 @@ const EraStatsBar = ({ currentEndpoint }) => { try { const eraStatsEndpoint = new URL("/erastats", currentEndpoint).href; const { data } = await axios.get(eraStatsEndpoint); - // console.log("Era Stats Data:", JSON.stringify(data)); setEraStats(data[0]); - console.log(`era stats`); - console.log(JSON.stringify(eraStats)); } catch (error) { console.error("Error fetching era stats data:", error); } @@ -36,6 +33,11 @@ const EraStatsBar = ({ currentEndpoint }) => { return () => clearInterval(interval); }, [currentEndpoint]); + useEffect(() => { + console.log(`era stats`); + console.log(JSON.stringify(eraStats)); + }, [eraStats]); + return (
diff --git a/packages/worker/package.json b/packages/worker/package.json index 2a48bbe66..d3ee1b416 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -29,7 +29,7 @@ }, "dependencies": { "@1kv/common": "workspace:^", - "@polkadot/api": "^10.11.2", + "@polkadot/api": "^10.12.1", "bullmq": "^5.1.5", "typescript": "^5.3.3" }, diff --git a/yarn.lock b/yarn.lock index 0fdea3918..8205f2b5a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,8 +9,8 @@ __metadata: version: 0.0.0-use.local resolution: "1k-validators-be@workspace:." dependencies: - "@polkadot/api": ^10.11.2 - "@polkadot/rpc-provider": ^10.11.2 + "@polkadot/api": ^10.12.1 + "@polkadot/rpc-provider": ^10.12.1 "@types/coingecko-api": ^1.0.13 "@types/eslint": ^8.44.7 "@types/jest": ^29.5.12 @@ -77,7 +77,7 @@ __metadata: "@ava/typescript": ^4.1.0 "@koa/router": ^12.0.1 "@octokit/rest": ^20.0.2 - "@polkadot/api": ^10.11.2 + "@polkadot/api": ^10.12.1 "@polkadot/keyring": ^12.6.2 "@types/cron": ^2.4.0 "@types/jest": ^29.5.12 @@ -196,7 +196,7 @@ __metadata: dependencies: "@1kv/common": "workspace:^" "@ava/typescript": ^4.1.0 - "@polkadot/api": ^10.11.2 + "@polkadot/api": ^10.12.1 "@typescript-eslint/eslint-plugin": ^5.59.9 "@typescript-eslint/parser": ^5.59.9 ava: ^6.1.1 @@ -1606,7 +1606,7 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:1.3.3, @noble/hashes@npm:^1.3.3": +"@noble/hashes@npm:1.3.3, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.3.3": version: 1.3.3 resolution: "@noble/hashes@npm:1.3.3" checksum: 8a6496d1c0c64797339bc694ad06cdfaa0f9e56cd0c3f68ae3666cfb153a791a55deb0af9c653c7ed2db64d537aa3e3054629740d2f2338bb1dcb7ab60cd205b @@ -1808,74 +1808,138 @@ __metadata: languageName: node linkType: hard -"@polkadot/api-augment@npm:10.11.2": - version: 10.11.2 - resolution: "@polkadot/api-augment@npm:10.11.2" +"@polkadot-api/client@npm:0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0": + version: 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + resolution: "@polkadot-api/client@npm:0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0" dependencies: - "@polkadot/api-base": 10.11.2 - "@polkadot/rpc-augment": 10.11.2 - "@polkadot/types": 10.11.2 - "@polkadot/types-augment": 10.11.2 - "@polkadot/types-codec": 10.11.2 + "@polkadot-api/metadata-builders": 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + "@polkadot-api/substrate-bindings": 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + "@polkadot-api/substrate-client": 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + "@polkadot-api/utils": 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + peerDependencies: + rxjs: ">=7.8.0" + checksum: 572a5538013131321722924a8ec4c4a3f18dfe76fc4897d77a65b2aa7e3162c5d11adab30111fd8489ab6952b7bd875f544e863b8cc0e54948233c6d736335e5 + languageName: node + linkType: hard + +"@polkadot-api/json-rpc-provider-proxy@npm:0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0": + version: 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + resolution: "@polkadot-api/json-rpc-provider-proxy@npm:0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0" + checksum: d30789f6171fce9887139b88e832d121489fbe1694aa6919fb1c4a37e6ac39ba1f8e19caa76c0007fd815820f1c1b1de6e12169c6b638c580eb74eb0137b4b34 + languageName: node + linkType: hard + +"@polkadot-api/json-rpc-provider@npm:0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0": + version: 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + resolution: "@polkadot-api/json-rpc-provider@npm:0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0" + checksum: fb028b1d16e2c39e5130f90e340691afcd1c45f08f39f56e3a46aa5a87f2bdfd2f71ad81f348d7fe78aceae483c50be4eb55e572f5fdf273beab5ac7b253a59c + languageName: node + linkType: hard + +"@polkadot-api/metadata-builders@npm:0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0": + version: 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + resolution: "@polkadot-api/metadata-builders@npm:0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0" + dependencies: + "@polkadot-api/substrate-bindings": 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + "@polkadot-api/utils": 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + checksum: 64705f32b9f7d43af759db28161e244f1ea45d5a4214a2a7592b1a4b3922378f1bfe50ad659defe93f23a63da306e50df9602a757656200cf1e50387b1a11842 + languageName: node + linkType: hard + +"@polkadot-api/substrate-bindings@npm:0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0": + version: 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + resolution: "@polkadot-api/substrate-bindings@npm:0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0" + dependencies: + "@noble/hashes": ^1.3.1 + "@polkadot-api/utils": 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + "@scure/base": ^1.1.1 + scale-ts: ^1.4.3 + checksum: c17caa73feaee67edff6e106453f4ef54fe2e14fc921e1fa5e1bd4e8e3f4af8e01802ce3959df072f5997d843c9ad4916b0b52103fdf58c7bf006911be326585 + languageName: node + linkType: hard + +"@polkadot-api/substrate-client@npm:0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0": + version: 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + resolution: "@polkadot-api/substrate-client@npm:0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0" + checksum: 655272b98490e084b948e2c798e0f7d4ba7d90d33b9f24b4d01dd2a5ef6e7e31bf523dd6de602354a3911e897c55bdc32dc24f3b504ce22f27a8e40063296bb4 + languageName: node + linkType: hard + +"@polkadot-api/utils@npm:0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0": + version: 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + resolution: "@polkadot-api/utils@npm:0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0" + checksum: 48ff709170ee7abad50f784f1123532b6b39725ab709da59fc9ddd859568753456b46c9c42d5aa56cad3d9fa0af27e46ed0650697df840f0ef2c023bd3a512f1 + languageName: node + linkType: hard + +"@polkadot/api-augment@npm:10.12.1": + version: 10.12.1 + resolution: "@polkadot/api-augment@npm:10.12.1" + dependencies: + "@polkadot/api-base": 10.12.1 + "@polkadot/rpc-augment": 10.12.1 + "@polkadot/types": 10.12.1 + "@polkadot/types-augment": 10.12.1 + "@polkadot/types-codec": 10.12.1 "@polkadot/util": ^12.6.2 tslib: ^2.6.2 - checksum: 04a59f84abdc242ba0111afc9a41cc84ab562c3fb653db545f9d3ceb081afac2bcee392f709d4742079e1d3d1297fd135eac8727565c237349bdb7aa389ba04b + checksum: 430f4eba309cc7d4d3508d1bc5d949d6312cb96739a93a257f490ff0261d20a4b61a894afcbb13661f4a5e40060f5080a3c710c619b98a0e39e249cdb668072e languageName: node linkType: hard -"@polkadot/api-base@npm:10.11.2": - version: 10.11.2 - resolution: "@polkadot/api-base@npm:10.11.2" +"@polkadot/api-base@npm:10.12.1": + version: 10.12.1 + resolution: "@polkadot/api-base@npm:10.12.1" dependencies: - "@polkadot/rpc-core": 10.11.2 - "@polkadot/types": 10.11.2 + "@polkadot/rpc-core": 10.12.1 + "@polkadot/types": 10.12.1 "@polkadot/util": ^12.6.2 rxjs: ^7.8.1 tslib: ^2.6.2 - checksum: 88f3aa2c61ebf0ac75451236767d3e873b1823a4e3bef96433e765899f9f030cdf5d059da0d1ec3e97effc6287974e48b8f60966f019ed8f62e19b35170a9721 + checksum: 9eb9ccdfae93e5bd333bb669dde00e2ed1242142d689f49ae56b501fbfcd5981018eec31e3d7539bc345ebaf856d0c57cc971a2e62f6f1f914ffe68b9eee4544 languageName: node linkType: hard -"@polkadot/api-derive@npm:10.11.2": - version: 10.11.2 - resolution: "@polkadot/api-derive@npm:10.11.2" +"@polkadot/api-derive@npm:10.12.1": + version: 10.12.1 + resolution: "@polkadot/api-derive@npm:10.12.1" dependencies: - "@polkadot/api": 10.11.2 - "@polkadot/api-augment": 10.11.2 - "@polkadot/api-base": 10.11.2 - "@polkadot/rpc-core": 10.11.2 - "@polkadot/types": 10.11.2 - "@polkadot/types-codec": 10.11.2 + "@polkadot/api": 10.12.1 + "@polkadot/api-augment": 10.12.1 + "@polkadot/api-base": 10.12.1 + "@polkadot/rpc-core": 10.12.1 + "@polkadot/types": 10.12.1 + "@polkadot/types-codec": 10.12.1 "@polkadot/util": ^12.6.2 "@polkadot/util-crypto": ^12.6.2 rxjs: ^7.8.1 tslib: ^2.6.2 - checksum: e89bcae6ac730fce72bb75f9b491400d561b0c61eb6f390d01e7c7060dd8fe24f893d7278f12e57200e485632f4a19f61af9b3dd5354bdfc07281bc9d2e85cb2 + checksum: fdd725f8b28b4f213e2b61ab6e99cddff26add60cd9a605ebf59b210c9f1a8b79879c169d13e9a0ff712cec9fd64281a235c704c08a3877b33b349a7b13c00c4 languageName: node linkType: hard -"@polkadot/api@npm:10.11.2, @polkadot/api@npm:^10.11.2": - version: 10.11.2 - resolution: "@polkadot/api@npm:10.11.2" +"@polkadot/api@npm:10.12.1, @polkadot/api@npm:^10.12.1": + version: 10.12.1 + resolution: "@polkadot/api@npm:10.12.1" dependencies: - "@polkadot/api-augment": 10.11.2 - "@polkadot/api-base": 10.11.2 - "@polkadot/api-derive": 10.11.2 + "@polkadot/api-augment": 10.12.1 + "@polkadot/api-base": 10.12.1 + "@polkadot/api-derive": 10.12.1 "@polkadot/keyring": ^12.6.2 - "@polkadot/rpc-augment": 10.11.2 - "@polkadot/rpc-core": 10.11.2 - "@polkadot/rpc-provider": 10.11.2 - "@polkadot/types": 10.11.2 - "@polkadot/types-augment": 10.11.2 - "@polkadot/types-codec": 10.11.2 - "@polkadot/types-create": 10.11.2 - "@polkadot/types-known": 10.11.2 + "@polkadot/rpc-augment": 10.12.1 + "@polkadot/rpc-core": 10.12.1 + "@polkadot/rpc-provider": 10.12.1 + "@polkadot/types": 10.12.1 + "@polkadot/types-augment": 10.12.1 + "@polkadot/types-codec": 10.12.1 + "@polkadot/types-create": 10.12.1 + "@polkadot/types-known": 10.12.1 "@polkadot/util": ^12.6.2 "@polkadot/util-crypto": ^12.6.2 eventemitter3: ^5.0.1 rxjs: ^7.8.1 tslib: ^2.6.2 - checksum: 4bb1c3ab28e7a96ea2c7a10f192ed679aff3c49e713164e69f163df7503686cb9fea7a20ab59b2dd6b85ed51e9c84df3efb346902dfd91b2f2e39aec0bdb351f + checksum: 25ef0b7ae5fbc740a9a0e4fd2536475ec473edfe29f94a97b5ea776c7d02b6a95a937564e7a171a459d678784818053a7444dff8302fafc594241f8db29ab440 languageName: node linkType: hard @@ -1929,128 +1993,128 @@ __metadata: languageName: node linkType: hard -"@polkadot/rpc-augment@npm:10.11.2": - version: 10.11.2 - resolution: "@polkadot/rpc-augment@npm:10.11.2" +"@polkadot/rpc-augment@npm:10.12.1": + version: 10.12.1 + resolution: "@polkadot/rpc-augment@npm:10.12.1" dependencies: - "@polkadot/rpc-core": 10.11.2 - "@polkadot/types": 10.11.2 - "@polkadot/types-codec": 10.11.2 + "@polkadot/rpc-core": 10.12.1 + "@polkadot/types": 10.12.1 + "@polkadot/types-codec": 10.12.1 "@polkadot/util": ^12.6.2 tslib: ^2.6.2 - checksum: 06daf8630fd2e73bb5d6692300e6e9d0b4ed9b4b0814174c5103e73ad59c79036657543ddf34a4da273e16e8dde6482dcc7c422850b3f21fb54a665565881d48 + checksum: 845ea139f6526de67de1afb7e0f4542e29b63af3efdc98934676031eb174b84e49a17a212f06441c400cd234453414f78fff2b8b0c0c5cd54d2364cf2fbb6010 languageName: node linkType: hard -"@polkadot/rpc-core@npm:10.11.2": - version: 10.11.2 - resolution: "@polkadot/rpc-core@npm:10.11.2" +"@polkadot/rpc-core@npm:10.12.1": + version: 10.12.1 + resolution: "@polkadot/rpc-core@npm:10.12.1" dependencies: - "@polkadot/rpc-augment": 10.11.2 - "@polkadot/rpc-provider": 10.11.2 - "@polkadot/types": 10.11.2 + "@polkadot/rpc-augment": 10.12.1 + "@polkadot/rpc-provider": 10.12.1 + "@polkadot/types": 10.12.1 "@polkadot/util": ^12.6.2 rxjs: ^7.8.1 tslib: ^2.6.2 - checksum: f1511fbebee55ea993d1cb113c2a163efd7fd4ae03829c91c8400ed1ba6fbd7d6e1aeebcbf9f9997b0c386fdeb7db62eab25ac3ce7ed0a7cea9691ff28488973 + checksum: d9f12597110e237fbb0f8f1c4c86cc8fcc598eddfd4ace0de00928fae446f3ddd8208183b462984738c149048cd51c9556c76d12568b27b77cc6ede4177db700 languageName: node linkType: hard -"@polkadot/rpc-provider@npm:10.11.2, @polkadot/rpc-provider@npm:^10.11.2": - version: 10.11.2 - resolution: "@polkadot/rpc-provider@npm:10.11.2" +"@polkadot/rpc-provider@npm:10.12.1, @polkadot/rpc-provider@npm:^10.12.1": + version: 10.12.1 + resolution: "@polkadot/rpc-provider@npm:10.12.1" dependencies: "@polkadot/keyring": ^12.6.2 - "@polkadot/types": 10.11.2 - "@polkadot/types-support": 10.11.2 + "@polkadot/types": 10.12.1 + "@polkadot/types-support": 10.12.1 "@polkadot/util": ^12.6.2 "@polkadot/util-crypto": ^12.6.2 "@polkadot/x-fetch": ^12.6.2 "@polkadot/x-global": ^12.6.2 "@polkadot/x-ws": ^12.6.2 - "@substrate/connect": 0.7.35 + "@substrate/connect": 0.8.7 eventemitter3: ^5.0.1 mock-socket: ^9.3.1 - nock: ^13.4.0 + nock: ^13.5.0 tslib: ^2.6.2 dependenciesMeta: "@substrate/connect": optional: true - checksum: a266ea4bf1fa4b2f3aaad005a04906bc2ffb6440b96b21789c41aad975311fe9a73f46e57a88c327130d69af06ad39d4e8826d70c5635966e55e2644a77ffa9a + checksum: 29246fa825be3f4f2eb34d63a1ef17ecda1b2e6423cfcb6c119ecbfdf15c18230d085fc111ff4739c07748cc3923a4829ec5deefaebb54b8b6a1252b80d5da39 languageName: node linkType: hard -"@polkadot/types-augment@npm:10.11.2": - version: 10.11.2 - resolution: "@polkadot/types-augment@npm:10.11.2" +"@polkadot/types-augment@npm:10.12.1": + version: 10.12.1 + resolution: "@polkadot/types-augment@npm:10.12.1" dependencies: - "@polkadot/types": 10.11.2 - "@polkadot/types-codec": 10.11.2 + "@polkadot/types": 10.12.1 + "@polkadot/types-codec": 10.12.1 "@polkadot/util": ^12.6.2 tslib: ^2.6.2 - checksum: 74d6efbac15dd20ce1f4c47adccdc1bf9cabed577c53ae964cf14ab943346c0fb4d0965e93b1276055f42f136d51de4bf10115ef79942bf12f8b309344e57fa4 + checksum: eec5f93331174a587dd804fe4f00b5409b7f775af3d8b8db3289d804d165a1a840311d44e54beaacf0b1ae323ac51905725aad32f9e48ff68a84a3afec03e726 languageName: node linkType: hard -"@polkadot/types-codec@npm:10.11.2": - version: 10.11.2 - resolution: "@polkadot/types-codec@npm:10.11.2" +"@polkadot/types-codec@npm:10.12.1": + version: 10.12.1 + resolution: "@polkadot/types-codec@npm:10.12.1" dependencies: "@polkadot/util": ^12.6.2 "@polkadot/x-bigint": ^12.6.2 tslib: ^2.6.2 - checksum: 154b3c89120b8095c82b55e89e0c0233b9f4e628017dfbbf0a9ca8383e6085bf93a3f91cd21264acdc9e996180e28d734c5f669a70524a3aa1399d0f5b8202d6 + checksum: 800f4172d0504d860e97f6894a8f43bde5ae20abe9f7b0a3a0e85cb8cfbeb80ce77fb381bda49d1defe30f4756939649b607dc4c3660e40c335e1b21651f28e5 languageName: node linkType: hard -"@polkadot/types-create@npm:10.11.2": - version: 10.11.2 - resolution: "@polkadot/types-create@npm:10.11.2" +"@polkadot/types-create@npm:10.12.1": + version: 10.12.1 + resolution: "@polkadot/types-create@npm:10.12.1" dependencies: - "@polkadot/types-codec": 10.11.2 + "@polkadot/types-codec": 10.12.1 "@polkadot/util": ^12.6.2 tslib: ^2.6.2 - checksum: 4fb124dbd3f42baaf99de68e6b26c4ce3d314ec92ba2c8a88eee72b9c3404bbe84d234e66048edbe26afb155338cdc81bf62a65c9e4dbdfe9c32e694de6f97b2 + checksum: ff051f75c5e692f89de4e7686311a66e7b889a398efefcd373a67a18796c06a80266eed55726a97850b1e4e430ca13004895394a8e368acbe5e030e55c20269f languageName: node linkType: hard -"@polkadot/types-known@npm:10.11.2": - version: 10.11.2 - resolution: "@polkadot/types-known@npm:10.11.2" +"@polkadot/types-known@npm:10.12.1": + version: 10.12.1 + resolution: "@polkadot/types-known@npm:10.12.1" dependencies: "@polkadot/networks": ^12.6.2 - "@polkadot/types": 10.11.2 - "@polkadot/types-codec": 10.11.2 - "@polkadot/types-create": 10.11.2 + "@polkadot/types": 10.12.1 + "@polkadot/types-codec": 10.12.1 + "@polkadot/types-create": 10.12.1 "@polkadot/util": ^12.6.2 tslib: ^2.6.2 - checksum: 198c92576fa85060bf571a56dcca3041ff749950645109d357ef77a619472096136a2fec2eaf3174742db9d20a181486c29bc23c4224c9968fc60a17b161408c + checksum: dbd4b4ac107908606d24fc5ec1a5be9cc1a972d1345b45908b310dae7fe09fc9f4f49c03edbec4694ed8b2de4c771f98ec228aa155a968b13e82513f33db9eeb languageName: node linkType: hard -"@polkadot/types-support@npm:10.11.2": - version: 10.11.2 - resolution: "@polkadot/types-support@npm:10.11.2" +"@polkadot/types-support@npm:10.12.1": + version: 10.12.1 + resolution: "@polkadot/types-support@npm:10.12.1" dependencies: "@polkadot/util": ^12.6.2 tslib: ^2.6.2 - checksum: 6283a5581876c7fba850add6612cd9285a876f506298581392a7db1f0f92357857da86aac031eef515e8d0ca725ec89259bef676b662616242cc5f5efc2527bc + checksum: a6eb886fb0e1c56f7c22e96a9255d6dac53fd4e30248c96950867a58854b542943b9143a69052b3b73a596ec2b2665b8857ed98267acf0e55fbeebb1670ca125 languageName: node linkType: hard -"@polkadot/types@npm:10.11.2": - version: 10.11.2 - resolution: "@polkadot/types@npm:10.11.2" +"@polkadot/types@npm:10.12.1": + version: 10.12.1 + resolution: "@polkadot/types@npm:10.12.1" dependencies: "@polkadot/keyring": ^12.6.2 - "@polkadot/types-augment": 10.11.2 - "@polkadot/types-codec": 10.11.2 - "@polkadot/types-create": 10.11.2 + "@polkadot/types-augment": 10.12.1 + "@polkadot/types-codec": 10.12.1 + "@polkadot/types-create": 10.12.1 "@polkadot/util": ^12.6.2 "@polkadot/util-crypto": ^12.6.2 rxjs: ^7.8.1 tslib: ^2.6.2 - checksum: 6e4873329bc8754d6ebdf1e4b20b1ced1edbda554a837c6d47dbc6f3abf8001e74884631bba3695cbd08b07e96ae784191a586d286d3bdfc5a985a0785595049 + checksum: 6184f50bef018b1fa11e3caaf851dc6fc7510c3dc56f81cfbde1b401f30ddd8ac73083770af41f3c8b3aa76beb4784d9ddb772460ab77c933628385090ab290c languageName: node linkType: hard @@ -2373,7 +2437,7 @@ __metadata: languageName: node linkType: hard -"@scure/base@npm:^1.1.5": +"@scure/base@npm:^1.1.1, @scure/base@npm:^1.1.5": version: 1.1.5 resolution: "@scure/base@npm:1.1.5" checksum: 9e9ee6088cb3aa0fb91f5a48497d26682c7829df3019b1251d088d166d7a8c0f941c68aaa8e7b96bbad20c71eb210397cb1099062cde3e29d4bad6b975c18519 @@ -2412,20 +2476,46 @@ __metadata: languageName: node linkType: hard -"@substrate/connect-extension-protocol@npm:^1.0.1": - version: 1.0.1 - resolution: "@substrate/connect-extension-protocol@npm:1.0.1" - checksum: 116dee587e81e832e14c25038bd849438c9493c6089aa6c1bf1760780d463880d44d362ed983d57ac3695368ac46f3c9df3dbaed92f36de89626c9735cecd1e4 +"@substrate/connect-extension-protocol@npm:^2.0.0": + version: 2.0.0 + resolution: "@substrate/connect-extension-protocol@npm:2.0.0" + checksum: a7c6ff3fefc0784f28b1d253514c1d2951684fe3d06392dfd70299fa2184fbe040d2bd6e0f113e30a1920920b649d43668aa4565847778ab3334c7e445e880cf + languageName: node + linkType: hard + +"@substrate/connect-known-chains@npm:^1.0.7": + version: 1.0.9 + resolution: "@substrate/connect-known-chains@npm:1.0.9" + checksum: 58a25df8dd8e7836e7ff932c3834e6cee67b820c0ee4832eb08d3ef25e6523c9560edd6ddecc96cb816fcbbb1ed01a3e0df50d1cf58a4bf9cc820180f21269e8 languageName: node linkType: hard -"@substrate/connect@npm:0.7.35": - version: 0.7.35 - resolution: "@substrate/connect@npm:0.7.35" +"@substrate/connect@npm:0.8.7": + version: 0.8.7 + resolution: "@substrate/connect@npm:0.8.7" dependencies: - "@substrate/connect-extension-protocol": ^1.0.1 - smoldot: 2.0.7 - checksum: 4f0cfb2b9521c5300cbcc0245e87b72484738e6cc8103ddf91e3516f627de546d0a152839824ac2716b8ea2f327f3eee0f74a9a07886ed4a091e3b7c1e989441 + "@substrate/connect-extension-protocol": ^2.0.0 + "@substrate/connect-known-chains": ^1.0.7 + "@substrate/light-client-extension-helpers": ^0.0.3 + smoldot: 2.0.21 + checksum: 8390d03f463690b63193363024c4c9edafebebe1722acd95d07a8177630d85039d7115cf1c502d1d8254adbea97e5b3cf49ec36841cebefeb0408201e39e8fc5 + languageName: node + linkType: hard + +"@substrate/light-client-extension-helpers@npm:^0.0.3": + version: 0.0.3 + resolution: "@substrate/light-client-extension-helpers@npm:0.0.3" + dependencies: + "@polkadot-api/client": 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + "@polkadot-api/json-rpc-provider": 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + "@polkadot-api/json-rpc-provider-proxy": 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + "@polkadot-api/substrate-client": 0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0 + "@substrate/connect-extension-protocol": ^2.0.0 + "@substrate/connect-known-chains": ^1.0.7 + rxjs: ^7.8.1 + peerDependencies: + smoldot: 2.x + checksum: a2e4a1df8f76c10c7ef3193cd4c7633beaea59e840afa71b74a5d90bdd8b335f1ec7b847b3c30e84be6e59bd25a8240549860d3016e3851a14aced45eac339a7 languageName: node linkType: hard @@ -9115,14 +9205,14 @@ __metadata: languageName: node linkType: hard -"nock@npm:^13.4.0": - version: 13.5.3 - resolution: "nock@npm:13.5.3" +"nock@npm:^13.5.0": + version: 13.5.4 + resolution: "nock@npm:13.5.4" dependencies: debug: ^4.1.0 json-stringify-safe: ^5.0.1 propagate: ^2.0.0 - checksum: f119e71d8e56a456a29bfa00a1d959387210fe8ada69443a7102fa9329a9c5fb2e0db149c4a00d304b11681127efd03fc0e6bc142a4ff609b1e153f70aa8712d + checksum: d31f924e34c87ae985edfb7b5a56e8a4dcfc3a072334ceb6d686326581f93090b3e23492663a64ce61b8df4f365b113231d926bc300bcfe9e5eb309c3e4b8628 languageName: node linkType: hard @@ -10464,6 +10554,13 @@ __metadata: languageName: node linkType: hard +"scale-ts@npm:^1.4.3": + version: 1.6.0 + resolution: "scale-ts@npm:1.6.0" + checksum: 2cd6d3e31ea78621fe2e068eedc3beb6a3cfc338c9033f04ec3e355b4b08e134febad655c54a80272a50737136a27436f9d14d6525b126e621a3b77524111056 + languageName: node + linkType: hard + "scheduler@npm:^0.23.0": version: 0.23.0 resolution: "scheduler@npm:0.23.0" @@ -10686,12 +10783,12 @@ __metadata: languageName: node linkType: hard -"smoldot@npm:2.0.7": - version: 2.0.7 - resolution: "smoldot@npm:2.0.7" +"smoldot@npm:2.0.21": + version: 2.0.21 + resolution: "smoldot@npm:2.0.21" dependencies: ws: ^8.8.1 - checksum: fc039bfa0560312ae09c2136dd506f2a1994ead804b7234b49b2ecfac2fd19d306973a0fcfb66019645a8cf9a1702c270bc544a622ae40b63cf14790ea3531e0 + checksum: 464f23dd20e8156ab63dfdccf719da9a9e245b4c1581844c3d76ab64384154f578261810d9f3d1957739577a1bccbf51b6a7467f7862f092c45b47f8e1e7b9a4 languageName: node linkType: hard