@marinade.finance/scoring 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/dist/computing/cluster.d.ts +10 -0
  2. package/dist/computing/cluster.js +95 -0
  3. package/dist/computing/cluster.js.map +1 -0
  4. package/dist/computing/eligibility.d.ts +19 -0
  5. package/dist/computing/eligibility.js +163 -0
  6. package/dist/computing/eligibility.js.map +1 -0
  7. package/dist/computing/score.d.ts +20 -0
  8. package/dist/computing/score.js +174 -0
  9. package/dist/computing/score.js.map +1 -0
  10. package/dist/computing/stake.d.ts +26 -0
  11. package/dist/computing/stake.js +197 -0
  12. package/dist/computing/stake.js.map +1 -0
  13. package/dist/computing/validators.d.ts +16 -0
  14. package/dist/computing/validators.js +123 -0
  15. package/dist/computing/validators.js.map +1 -0
  16. package/dist/constants/marinade.json +38 -0
  17. package/dist/dto/bonds.dto.d.ts +12 -0
  18. package/dist/dto/bonds.dto.js +3 -0
  19. package/dist/dto/bonds.dto.js.map +1 -0
  20. package/dist/dto/cluster.dto.d.ts +12 -0
  21. package/dist/dto/cluster.dto.js +3 -0
  22. package/dist/dto/cluster.dto.js.map +1 -0
  23. package/{src/dto/eligibility.dto.ts → dist/dto/eligibility.dto.d.ts} +15 -20
  24. package/dist/dto/eligibility.dto.js +3 -0
  25. package/dist/dto/eligibility.dto.js.map +1 -0
  26. package/dist/dto/jito.dto.d.ts +9 -0
  27. package/dist/dto/jito.dto.js +10 -0
  28. package/dist/dto/jito.dto.js.map +1 -0
  29. package/dist/dto/marinade.dto.d.ts +18 -0
  30. package/dist/dto/marinade.dto.js +3 -0
  31. package/dist/dto/marinade.dto.js.map +1 -0
  32. package/dist/dto/rewards.dto.d.ts +17 -0
  33. package/dist/dto/rewards.dto.js +18 -0
  34. package/dist/dto/rewards.dto.js.map +1 -0
  35. package/dist/dto/scoring.dto.d.ts +101 -0
  36. package/dist/dto/scoring.dto.js +3 -0
  37. package/dist/dto/scoring.dto.js.map +1 -0
  38. package/dist/dto/snapshots.dto.d.ts +15 -0
  39. package/dist/dto/snapshots.dto.js +13 -0
  40. package/dist/dto/snapshots.dto.js.map +1 -0
  41. package/dist/dto/stakes.dto.d.ts +30 -0
  42. package/dist/dto/stakes.dto.js +3 -0
  43. package/dist/dto/stakes.dto.js.map +1 -0
  44. package/dist/dto/validators.dto.d.ts +110 -0
  45. package/dist/dto/validators.dto.js +19 -0
  46. package/dist/dto/validators.dto.js.map +1 -0
  47. package/dist/errors/fetching.d.ts +22 -0
  48. package/dist/errors/fetching.js +30 -0
  49. package/dist/errors/fetching.js.map +1 -0
  50. package/dist/index.d.ts +24 -0
  51. package/dist/index.js +41 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/interfaces/data-provider.interface.d.ts +16 -0
  54. package/dist/interfaces/data-provider.interface.js +3 -0
  55. package/dist/interfaces/data-provider.interface.js.map +1 -0
  56. package/dist/logging/logger.d.ts +3 -0
  57. package/dist/logging/logger.js +72 -0
  58. package/dist/logging/logger.js.map +1 -0
  59. package/dist/providers/api-data.provider.d.ts +30 -0
  60. package/dist/providers/api-data.provider.js +227 -0
  61. package/dist/providers/api-data.provider.js.map +1 -0
  62. package/dist/providers/file-data.provider.d.ts +29 -0
  63. package/dist/providers/file-data.provider.js +96 -0
  64. package/dist/providers/file-data.provider.js.map +1 -0
  65. package/dist/tsconfig.tsbuildinfo +1 -0
  66. package/dist/utils/csv.d.ts +2 -0
  67. package/dist/utils/csv.js +53 -0
  68. package/dist/utils/csv.js.map +1 -0
  69. package/dist/utils/maths.d.ts +8 -0
  70. package/dist/utils/maths.js +56 -0
  71. package/dist/utils/maths.js.map +1 -0
  72. package/dist/utils/solana.d.ts +1 -0
  73. package/dist/utils/solana.js +9 -0
  74. package/dist/utils/solana.js.map +1 -0
  75. package/dist/utils/zip.d.ts +2 -0
  76. package/dist/utils/zip.js +15 -0
  77. package/dist/utils/zip.js.map +1 -0
  78. package/package.json +14 -16
  79. package/src/cluster/cluster.module.ts +0 -8
  80. package/src/cluster/cluster.service.ts +0 -108
  81. package/src/config/config.module.ts +0 -8
  82. package/src/config/config.service.ts +0 -136
  83. package/src/constants/marinade.json +0 -38
  84. package/src/dto/bonds.dto.ts +0 -14
  85. package/src/dto/cluster.dto.ts +0 -13
  86. package/src/dto/jito.dto.ts +0 -10
  87. package/src/dto/marinade.dto.ts +0 -18
  88. package/src/dto/rewards.dto.ts +0 -21
  89. package/src/dto/scoring.dto.ts +0 -109
  90. package/src/dto/snapshots.dto.ts +0 -19
  91. package/src/dto/stakes.dto.ts +0 -35
  92. package/src/dto/validators.dto.ts +0 -146
  93. package/src/eligibility/eligibility.module.ts +0 -11
  94. package/src/eligibility/eligibility.service.ts +0 -183
  95. package/src/errors/fetching.ts +0 -25
  96. package/src/interfaces/data-provider.interface.ts +0 -17
  97. package/src/providers/api-data.provider.ts +0 -261
  98. package/src/providers/file-data.provider.ts +0 -125
  99. package/src/scoring/scoring.module.ts +0 -11
  100. package/src/scoring/scoring.service.ts +0 -184
  101. package/src/stake/stake.module.ts +0 -10
  102. package/src/stake/stake.service.ts +0 -242
  103. package/src/utils/csv.ts +0 -30
  104. package/src/utils/maths.ts +0 -75
  105. package/src/utils/solana.ts +0 -9
  106. package/src/utils/zip.ts +0 -12
  107. package/src/validators/validators.module.ts +0 -48
  108. package/src/validators/validators.service.ts +0 -177
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mathUtilityFunctions = exports.piecewise = exports.stdDev = exports.mean = exports.sum = void 0;
4
+ function sum(amounts) {
5
+ if (!Array.isArray(amounts) || amounts.some(amount => typeof amount !== 'number')) {
6
+ throw new TypeError('Input must be an array of numbers');
7
+ }
8
+ return amounts.reduce((acc, amount) => acc + amount, 0);
9
+ }
10
+ exports.sum = sum;
11
+ function mean(data) {
12
+ if (data.length === 0) {
13
+ throw new Error('Cannot calculate mean for empty data');
14
+ }
15
+ return sum(data) / data.length;
16
+ }
17
+ exports.mean = mean;
18
+ function stdDev(data) {
19
+ if (data.length === 0) {
20
+ throw new Error('Cannot calculate std. dev. for empty data');
21
+ }
22
+ const dataMean = mean(data);
23
+ return Math.sqrt(data.reduce((sum, value) => sum + Math.pow(value - dataMean, 2), 0) / data.length);
24
+ }
25
+ exports.stdDev = stdDev;
26
+ function piecewise(...args) {
27
+ if (args.length === 0) {
28
+ throw new Error('At least one argument must be provided!');
29
+ }
30
+ for (let conditionIndex = 0, valueIndex = 1; valueIndex < args.length; conditionIndex += 2, valueIndex += 2) {
31
+ const condition = args[conditionIndex];
32
+ const value = args[valueIndex];
33
+ if (typeof condition !== 'boolean') {
34
+ throw new Error(`Argument at position ${conditionIndex} must be a boolean!`);
35
+ }
36
+ if (condition) {
37
+ if (value === undefined) {
38
+ throw new Error(`Expected a value corresponding to the condition at position ${conditionIndex}, but got undefined.`);
39
+ }
40
+ return value;
41
+ }
42
+ }
43
+ const defaultValue = args[args.length - 1];
44
+ if (defaultValue === undefined) {
45
+ throw new Error('Unexpected error: Default value is undefined.');
46
+ }
47
+ return defaultValue;
48
+ }
49
+ exports.piecewise = piecewise;
50
+ function mathUtilityFunctions() {
51
+ return {
52
+ piecewise
53
+ };
54
+ }
55
+ exports.mathUtilityFunctions = mathUtilityFunctions;
56
+ //# sourceMappingURL=maths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maths.js","sourceRoot":"","sources":["../../src/utils/maths.ts"],"names":[],"mappings":";;;AAOA,SAAgB,GAAG,CAAE,OAAiB;IACpC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,EAAE;QACjF,MAAM,IAAI,SAAS,CAAC,mCAAmC,CAAC,CAAC;KAC1D;IACD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;AAC1D,CAAC;AALD,kBAKC;AAOD,SAAgB,IAAI,CAAE,IAAc;IAClC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;QACrB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;KACzD;IAED,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;AACjC,CAAC;AAND,oBAMC;AAQD,SAAgB,MAAM,CAAE,IAAc;IACpC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;QACrB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;KAC9D;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;AACtG,CAAC;AAPD,wBAOC;AAED,SAAgB,SAAS,CAAE,GAAG,IAAa;IACzC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;QACrB,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;KAC5D;IAED,KAAK,IAAI,cAAc,GAAG,CAAC,EAAE,UAAU,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,cAAc,IAAI,CAAC,EAAE,UAAU,IAAI,CAAC,EAAE;QAC3G,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QAE/B,IAAI,OAAO,SAAS,KAAK,SAAS,EAAE;YAClC,MAAM,IAAI,KAAK,CAAC,wBAAwB,cAAc,qBAAqB,CAAC,CAAC;SAC9E;QAED,IAAI,SAAS,EAAE;YACb,IAAI,KAAK,KAAK,SAAS,EAAE;gBACvB,MAAM,IAAI,KAAK,CAAC,+DAA+D,cAAc,sBAAsB,CAAC,CAAC;aACtH;YACD,OAAO,KAAK,CAAC;SACd;KACF;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3C,IAAI,YAAY,KAAK,SAAS,EAAE;QAC9B,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;KAClE;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AA1BD,8BA0BC;AAED,SAAgB,oBAAoB;IAClC,OAAO;QACL,SAAS;KACV,CAAC;AACJ,CAAC;AAJD,oDAIC"}
@@ -0,0 +1 @@
1
+ export declare function lamportsToSol(lamports: string): string;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.lamportsToSol = void 0;
4
+ function lamportsToSol(lamports) {
5
+ const paddedLamports = lamports.padStart(10, '0');
6
+ return paddedLamports.replace(/(.{9})$/, '.$1');
7
+ }
8
+ exports.lamportsToSol = lamportsToSol;
9
+ //# sourceMappingURL=solana.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solana.js","sourceRoot":"","sources":["../../src/utils/solana.ts"],"names":[],"mappings":";;;AAKA,SAAgB,aAAa,CAAE,QAAgB;IAC7C,MAAM,cAAc,GAAG,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAClD,OAAO,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AAClD,CAAC;AAHD,sCAGC"}
@@ -0,0 +1,2 @@
1
+ export declare function zip<T1, T2, T3>(...iterables: [Iterable<T1>, Iterable<T2>, Iterable<T3>]): Generator<[T1, T2, T3]>;
2
+ export declare function zip<T1, T2>(...iterables: [Iterable<T1>, Iterable<T2>]): Generator<[T1, T2]>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.zip = void 0;
4
+ function* zip(...iterables) {
5
+ const iterators = iterables.map((iterable) => iterable[Symbol.iterator]());
6
+ while (true) {
7
+ const results = iterators.map((iter) => iter.next());
8
+ if (results.some((result) => result.done)) {
9
+ return;
10
+ }
11
+ yield results.map((result) => result.value);
12
+ }
13
+ }
14
+ exports.zip = zip;
15
+ //# sourceMappingURL=zip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zip.js","sourceRoot":"","sources":["../../src/utils/zip.ts"],"names":[],"mappings":";;;AAEA,QAAe,CAAC,CAAC,GAAG,CAAU,GAAG,SAA8B;IAC7D,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC3E,OAAO,IAAI,EAAE;QACX,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACrD,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;YACzC,OAAO;SACR;QACD,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;KAC7C;AACH,CAAC;AATD,kBASC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marinade.finance/scoring",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Delegation Strategy Scoring",
5
5
  "repository": {
6
6
  "type": "git",
@@ -9,17 +9,12 @@
9
9
  "publishConfig": {
10
10
  "access": "public"
11
11
  },
12
-
13
12
  "files": [
14
- "src",
13
+ "dist",
15
14
  "generated",
16
15
  "README.md"
17
16
  ],
18
- "main": "index.js",
19
- "scripts": {
20
- "build": "nest build",
21
- "test": "echo \"Error: no test specified\" && exit 1"
22
- },
17
+ "main": "dist/index.js",
23
18
  "keywords": [
24
19
  "solana",
25
20
  "marinade.finance",
@@ -29,16 +24,19 @@
29
24
  "author": "Marinade Finance",
30
25
  "license": "ISC",
31
26
  "dependencies": {
32
- "@nestjs/cli": "^10.3.2",
33
- "@nestjs/common": "^10.3.3",
34
- "axios": "^1.6.7",
35
- "class-transformer": "^0.5.1",
36
- "class-validator": "^0.14.1",
27
+ "axios": "^1.6.8",
37
28
  "decimal.js": "^10.4.3",
38
29
  "expr-eval": "^2.0.2",
39
- "nestjs": "^0.0.1"
30
+ "log4js": "^6.9.1"
40
31
  },
41
32
  "devDependencies": {
42
- "@types/node": "^20.11.19"
33
+ "@types/jest": "29.5.0",
34
+ "@types/node": "^20.12.7",
35
+ "jest": "29.5.0",
36
+ "ts-jest": "29.0.5"
37
+ },
38
+ "scripts": {
39
+ "build": "tsc",
40
+ "test": "jest"
43
41
  }
44
- }
42
+ }
@@ -1,8 +0,0 @@
1
- import { Module } from '@nestjs/common';
2
- import { ClusterService } from './cluster.service';
3
-
4
- @Module({
5
- providers: [ClusterService],
6
- exports: [ClusterService],
7
- })
8
- export class ClusterModule {}
@@ -1,108 +0,0 @@
1
- import { BlockProductionResult, ClusterInfo } from '../dto/cluster.dto';
2
- import { ValidatorDto } from '../dto/validators.dto';
3
- import { mean, stdDev } from '../utils/maths';
4
- import Decimal from 'decimal.js';
5
-
6
- export class ClusterService {
7
- computeBlockProduction (validators: ValidatorDto[], startEpoch: number, endEpoch: number): BlockProductionResult {
8
- const blockProductions: number[] = [];
9
-
10
- for (const validator of validators) {
11
- let leaderSlots = 0;
12
- let blocksProduced = 0;
13
-
14
- for (let epoch = startEpoch; epoch <= endEpoch; epoch++) {
15
- if (!validator.epochStats) {
16
- continue;
17
- }
18
- const epochStat = validator.epochStats[epoch];
19
- if (epochStat) {
20
- leaderSlots += epochStat.leader_slots;
21
- blocksProduced += epochStat.blocks_produced;
22
- }
23
- }
24
-
25
- if (leaderSlots) {
26
- blockProductions.push(blocksProduced / leaderSlots);
27
- }
28
- }
29
-
30
- return {
31
- mean: mean(blockProductions),
32
- stdDev: stdDev(blockProductions),
33
- };
34
- }
35
-
36
- computeTargetCreditsByEpoch (validators: ValidatorDto[]): Map<number, number> {
37
- const sumOfWeightedCreditsPerEpoch = new Map<number, Decimal>();
38
- const sumOfWeightsPerEpoch = new Map<number, Decimal>();
39
-
40
- validators.forEach(validator => {
41
- validator.epoch_stats.forEach(epochStat => {
42
- if (epochStat.epoch_end_at) {
43
- const activatedStakeDecimal = new Decimal(epochStat.activated_stake);
44
- const stakeInLamports = activatedStakeDecimal.dividedBy(1e9);
45
-
46
- const prevSumOfWeightedCredits = sumOfWeightedCreditsPerEpoch.get(epochStat.epoch) || new Decimal(0);
47
- sumOfWeightedCreditsPerEpoch.set(epochStat.epoch, prevSumOfWeightedCredits.plus(new Decimal(epochStat.credits).times(stakeInLamports)));
48
-
49
- const prevSumOfWeightsPerEpoch = sumOfWeightsPerEpoch.get(epochStat.epoch) || new Decimal(0);
50
- sumOfWeightsPerEpoch.set(epochStat.epoch, prevSumOfWeightsPerEpoch.plus(stakeInLamports));
51
- }
52
- });
53
- });
54
-
55
- const result = new Map<number, number>();
56
- sumOfWeightsPerEpoch.forEach((sumOfWeights, epoch) => {
57
- const weightedCredits = sumOfWeightedCreditsPerEpoch.get(epoch) || new Decimal(0);
58
- result.set(epoch, weightedCredits.dividedBy(sumOfWeights).toDecimalPlaces(0, Decimal.ROUND_HALF_UP).toNumber());
59
- });
60
-
61
- return result;
62
- }
63
-
64
- computeConcentrations (validators: ValidatorDto[], epoch: number): { city: Map<string, number>, country: Map<string, number>, aso: Map<string, number> } {
65
- let total = 0;
66
- const city = new Map<string, number>();
67
- const country = new Map<string, number>();
68
- const aso = new Map<string, number>();
69
-
70
- for (const validator of validators) {
71
- const lastEpochStats = validator.epoch_stats[0];
72
- if (lastEpochStats?.epoch === epoch) {
73
- const cityKey = validator.dc_full_city ?? '???';
74
- const countryKey = validator.dc_country ?? '???';
75
- const asoKey = validator.dc_aso ?? '???';
76
-
77
- const stake = Number(validator.activated_stake) / 1e9;
78
-
79
- city.set(cityKey, (city.get(cityKey) ?? 0) + stake);
80
- country.set(countryKey, (country.get(countryKey) ?? 0) + stake);
81
- aso.set(asoKey, (aso.get(asoKey) ?? 0) + stake);
82
-
83
- total += stake;
84
- }
85
- }
86
-
87
- if (total > 0) {
88
- for (const map of [city, country, aso]) {
89
- for (const [key, value] of map) {
90
- map.set(key, value / total);
91
- }
92
- }
93
- }
94
-
95
- return { city, country, aso };
96
- }
97
-
98
- computeClusterInfo (validators: ValidatorDto[], basicEligibilityEpochs: number, lastEpoch: number): ClusterInfo {
99
- const { mean: meanBlockProduction, stdDev: stdDevBlockProduction } = this.computeBlockProduction(validators, lastEpoch - basicEligibilityEpochs, lastEpoch - 1);
100
-
101
- return {
102
- targetCreditsByEpoch: this.computeTargetCreditsByEpoch(validators),
103
- ...this.computeConcentrations(validators, lastEpoch),
104
- meanBlockProductionOverBasicEligibilityPeriod: meanBlockProduction,
105
- stdDevBlockProductionOverBasicEligibilityPeriod: stdDevBlockProduction,
106
- };
107
- }
108
- }
@@ -1,8 +0,0 @@
1
- import { Module } from '@nestjs/common';
2
- import { ConfigService } from './config.service';
3
-
4
- @Module({
5
- providers: [ConfigService],
6
- exports: [ConfigService],
7
- })
8
- export class ConfigModule {}
@@ -1,136 +0,0 @@
1
- import * as dotenv from 'dotenv';
2
- import { Injectable } from '@nestjs/common';
3
- import { Logger } from '../../../../src/logger';
4
- import { ScoringConfig } from '../dto/scoring.dto';
5
- import { readFileSync } from 'fs';
6
- import * as defaultScoringConfig from '../constants/marinade.json';
7
-
8
- dotenv.config();
9
-
10
- @Injectable()
11
- export class ConfigService {
12
- private readonly logger = new Logger();
13
- readonly scoringConfig: ScoringConfig;
14
- private getEnvVar (key: string): string {
15
- const val = process.env[key];
16
- if (!val) {
17
- this.logger.error(`Missing environment variable: ${key}`);
18
- throw new Error(`Missing environment variable: ${key}`);
19
- }
20
- return val;
21
- }
22
-
23
- getScoringConfig (): ScoringConfig {
24
- const scoringConfigPath = process.env['SCORING_CONFIG_PATH'];
25
-
26
- if (!scoringConfigPath) {
27
- return {
28
- DS_PUBKEY: defaultScoringConfig.DS_PUBKEY,
29
- REWARDS_PAST_EPOCHS: defaultScoringConfig.REWARDS_PAST_EPOCHS,
30
- CAP_FROM_BOND: defaultScoringConfig.CAP_FROM_BOND,
31
- formulaStakeBlockSize: defaultScoringConfig.formulaStakeBlockSize,
32
- formulaStakeBlocksFromScore: defaultScoringConfig.formulaStakeBlocksFromScore,
33
- formulaVoteCredits: defaultScoringConfig.formulaVoteCredits,
34
- formulaBlockProduction: defaultScoringConfig.formulaBlockProduction,
35
- formulaInflationCommission: defaultScoringConfig.formulaInflationCommission,
36
- formulaMEVCommission: defaultScoringConfig.formulaMEVCommission,
37
- formulaStakeConcentrationCountry: defaultScoringConfig.formulaStakeConcentrationCountry,
38
- formulaStakeConcentrationCity: defaultScoringConfig.formulaStakeConcentrationCity,
39
- formulaStakeConcentrationASO: defaultScoringConfig.formulaStakeConcentrationASO,
40
- formulaStakeConcentrationNode: defaultScoringConfig.formulaStakeConcentrationNode,
41
- weightTargetSumOfRewards: defaultScoringConfig.weightTargetSumOfRewards,
42
- weightMevHeuristic: defaultScoringConfig.weightMevHeuristic,
43
- weightVoteCredits: defaultScoringConfig.weightVoteCredits,
44
- weightBlockProduction: defaultScoringConfig.weightBlockProduction,
45
- weightInflationCommission: defaultScoringConfig.weightInflationCommission,
46
- weightMEVCommission: defaultScoringConfig.weightMEVCommission,
47
- weightStakeConcentrationCountry: defaultScoringConfig.weightStakeConcentrationCountry,
48
- weightStakeConcentrationCity: defaultScoringConfig.weightStakeConcentrationCity,
49
- weightStakeConcentrationASO: defaultScoringConfig.weightStakeConcentrationASO,
50
- weightStakeConcentrationNode: defaultScoringConfig.weightStakeConcentrationNode,
51
- basicEligibilityEpochs: defaultScoringConfig.basicEligibilityEpochs,
52
- bonusEligibilityExtraEpochs: defaultScoringConfig.bonusEligibilityExtraEpochs,
53
- maxCommission: defaultScoringConfig.maxCommission,
54
- voteCreditsWarning: defaultScoringConfig.voteCreditsWarning,
55
- voteCreditsLow: defaultScoringConfig.voteCreditsLow,
56
- minExternalStake: defaultScoringConfig.minExternalStake,
57
- minScore: defaultScoringConfig.minScore,
58
- maxStakeShare: defaultScoringConfig.maxStakeShare,
59
- maxWarnings: defaultScoringConfig.maxWarnings,
60
- mSolControl: defaultScoringConfig.mSolControl,
61
- veMndeControl: defaultScoringConfig.veMndeControl,
62
- stakeBlocksFromBonus: defaultScoringConfig.stakeBlocksFromBonus,
63
- concentrationParams: defaultScoringConfig.concentrationParams,
64
- };
65
- } else {
66
- const scoringConfigData = readFileSync(scoringConfigPath, 'utf8');
67
- return JSON.parse(scoringConfigData) as ScoringConfig;
68
- }
69
- }
70
-
71
- getDataProviderMode (): string {
72
- return this.getEnvVar('DATA_PROVIDER_MODE');
73
- }
74
-
75
- getMarinadeTvlURL (): string {
76
- return this.getEnvVar('MARINADE_TVL_URL');
77
- }
78
-
79
- getValidatorsURL (): string {
80
- return this.getEnvVar('VALIDATORS_URL');
81
- }
82
-
83
- getBlacklistURL (): string {
84
- return this.getEnvVar('BLACKLIST_URL');
85
- }
86
-
87
- getBondsURL (): string {
88
- return this.getEnvVar('BONDS_URL');
89
- }
90
-
91
- getVemndeVotesURL (): string {
92
- return this.getEnvVar('VEMNDE_VOTES_URL');
93
- }
94
-
95
- getMsolVotesURL (): string {
96
- return this.getEnvVar('MSOL_VOTES_URL');
97
- }
98
-
99
- getRewardsURL (): string {
100
- return this.getEnvVar('REWARDS_URL');
101
- }
102
- getJitoMevURL (): string {
103
- return this.getEnvVar('JITO_MEV_URL');
104
- }
105
- getValidatorsPath (): string {
106
- return this.getEnvVar('VALIDATORS_PATH');
107
- }
108
-
109
- getBlacklistPath (): string {
110
- return this.getEnvVar('BLACKLIST_PATH');
111
- }
112
-
113
- getVemndeVotesPath (): string {
114
- return this.getEnvVar('VEMNDE_VOTES_PATH');
115
- }
116
-
117
- getMsolVotesPath (): string {
118
- return this.getEnvVar('MSOL_VOTES_PATH');
119
- }
120
-
121
- getRewardsPath (): string {
122
- return this.getEnvVar('REWARDS_PATH');
123
- }
124
-
125
- getJitoMevPath (): string {
126
- return this.getEnvVar('JITO_MEV_PATH');
127
- }
128
-
129
- getBondsPath (): string {
130
- return this.getEnvVar('JITO_MEV_PATH');
131
- }
132
-
133
- getMarinadeTvlPath (): string {
134
- return this.getEnvVar('MARINADE_TVL_PATH');
135
- }
136
- }
@@ -1,38 +0,0 @@
1
- {
2
- "DS_PUBKEY": "MarinadeA1gorithmicDe1egationStrategy111111",
3
- "REWARDS_PAST_EPOCHS": 14,
4
- "CAP_FROM_BOND": 1000000000,
5
- "formulaStakeBlockSize": "tvl / ((6000000 / 30000) * 1.5 ^ (log(tvl / 6000000) / log(2)))",
6
- "formulaStakeBlocksFromScore": "1 + ((max(0.94, score) - 0.94) / (1 - 0.94)) ^ 10",
7
- "formulaVoteCredits": "min(credits_pct_mean ^ 10, 1)",
8
- "formulaBlockProduction": "piecewise((bp_mean - bp_cluster_mean) / bp_cluster_std_dev < -1, bp_mean / (bp_cluster_mean - bp_cluster_std_dev), 1)",
9
- "formulaInflationCommission": "piecewise(commission_inflation_max <= 10, (100 - commission_inflation_max) / 100, 0)",
10
- "formulaMEVCommission": "(100 - commission_mev) / 100",
11
- "formulaStakeConcentrationCountry": "piecewise(country_stake_concentration_last < 1/3, (1 - (3 * country_stake_concentration_last)) ^ (1/3), 0)",
12
- "formulaStakeConcentrationCity": "piecewise(city_stake_concentration_last < 1/3, (1 - (3 * city_stake_concentration_last)) ^ (1/3), 0)",
13
- "formulaStakeConcentrationASO": "piecewise(aso_stake_concentration_last < 1/3, (1 - (3 * aso_stake_concentration_last)) ^ (1/3), 0)",
14
- "formulaStakeConcentrationNode": "piecewise(node_stake_last < 100000, 1, node_stake_last < 4000000, 1 - (node_stake_last - 100000) / (4000000 - 100000), 0)",
15
- "weightTargetSumOfRewards": 5,
16
- "weightMevHeuristic": 0.1,
17
- "weightVoteCredits": 10,
18
- "weightBlockProduction": 5,
19
- "weightInflationCommission": 4.9,
20
- "weightMEVCommission": 0.1,
21
- "weightStakeConcentrationCountry": 2,
22
- "weightStakeConcentrationCity": 3,
23
- "weightStakeConcentrationASO": 4,
24
- "weightStakeConcentrationNode": 2,
25
- "basicEligibilityEpochs": 14,
26
- "bonusEligibilityExtraEpochs": 0,
27
- "maxCommission": 7,
28
- "voteCreditsWarning": 0,
29
- "voteCreditsLow": 80,
30
- "minExternalStake": 0,
31
- "minScore": 0.8,
32
- "maxStakeShare": 0.8,
33
- "maxWarnings": 1,
34
- "mSolControl": 0.2,
35
- "veMndeControl": 0.2,
36
- "stakeBlocksFromBonus": 0,
37
- "concentrationParams": [4, 5, 6, 7]
38
- }
@@ -1,14 +0,0 @@
1
- export type BondDto = {
2
- pubkey: string;
3
- vote_account: string;
4
- authority: string;
5
- cpmpe: number;
6
- updated_at: string;
7
- epoch: number;
8
- }
9
-
10
- export type BondsDto = {
11
- bonds: BondDto[];
12
- }
13
-
14
- export type Bonds = Record<string, number>;
@@ -1,13 +0,0 @@
1
- export type ClusterInfo = {
2
- city: Map<string, number>,
3
- country: Map<string, number>,
4
- aso: Map<string, number>,
5
- targetCreditsByEpoch: Map<number, number>,
6
- meanBlockProductionOverBasicEligibilityPeriod: number,
7
- stdDevBlockProductionOverBasicEligibilityPeriod: number,
8
- }
9
-
10
- export type BlockProductionResult = {
11
- mean: number;
12
- stdDev: number;
13
- }
@@ -1,10 +0,0 @@
1
- export class JitoValidatorDto {
2
- vote_account: string;
3
- mev_commission_bps: number;
4
- running_jito: boolean;
5
- active_stake: number;
6
- }
7
-
8
- export class JitoValidatorsResponseDto {
9
- validators: JitoValidatorDto[];
10
- }
@@ -1,18 +0,0 @@
1
- export type TvlStats = {
2
- staked_sol: number;
3
- staked_usd: number;
4
- msol_directed_stake_sol: number;
5
- msol_directed_stake_msol: number;
6
- liquidity_sol: number;
7
- liquidity_usd: number;
8
- total_sol: number;
9
- total_usd: number;
10
- self_staked_sol: number;
11
- self_staked_usd: number;
12
- standard_staked_sol: number;
13
- standard_staked_usd: number;
14
- total_virtual_staked_sol: number;
15
- total_virtual_staked_usd: number;
16
- marinade_native_stake_sol: number;
17
- marinade_native_stake_usd: number;
18
- }
@@ -1,21 +0,0 @@
1
- export class RewardPairDto {
2
- epoch: number;
3
- amount: number;
4
-
5
- constructor (pair: [number, number]) {
6
- this.epoch = pair[0];
7
- this.amount = pair[1];
8
- }
9
- }
10
-
11
- export class RewardsResponseDto {
12
- rewards_mev: RewardPairDto[];
13
- rewards_inflation_est: RewardPairDto[];
14
-
15
- constructor (data: { rewards_mev: [number, number][], rewards_inflation_est: [number, number][] }) {
16
- this.rewards_mev = data.rewards_mev.map(pair => new RewardPairDto(pair));
17
- this.rewards_inflation_est = data.rewards_inflation_est.map(pair => new RewardPairDto(pair));
18
- }
19
- }
20
-
21
- export type Rewards = { inflation: number, mev: number }
@@ -1,109 +0,0 @@
1
- import { ClusterInfo } from './cluster.dto';
2
- import { AggregatedValidator } from './validators.dto';
3
-
4
- export type ScoreDto = {
5
- score: number,
6
- concentrationScore: number,
7
- scores: number[]
8
- values: number[]
9
- scoreErrors: boolean[]
10
- tooltips: string[]
11
- }
12
-
13
- export type Score = {
14
- vote_account: string,
15
- score: string,
16
- score_credits: string,
17
- score_block_production: string,
18
- score_inflation_commission: string,
19
- score_mev_commission: string,
20
- score_country_concentration: string,
21
- score_city_concentration: string,
22
- score_aso_concentration: string,
23
- score_node_concentration: string,
24
- ui_hints: string,
25
- eligible_stake_algo: number;
26
- eligible_bonus: number;
27
- in_algo_stake_set: number;
28
- msol_votes: string;
29
- vemnde_votes: string;
30
- blacklisted: number,
31
- rank: number,
32
- version: string,
33
- max_commission: number,
34
- marinade_stake: string,
35
- target_stake_vemnde: string,
36
- target_stake_msol: string,
37
- target_stake_algo: string,
38
- target_stake: string,
39
- }
40
-
41
- export type ScoreConfig = {
42
- epochs: number,
43
- concentrationParams: number[]
44
- }
45
-
46
- export type ScoringConfig = {
47
- DS_PUBKEY: string;
48
- REWARDS_PAST_EPOCHS: number;
49
- CAP_FROM_BOND: number;
50
- formulaStakeBlockSize: string;
51
- formulaStakeBlocksFromScore: string;
52
- formulaVoteCredits: string;
53
- formulaBlockProduction: string;
54
- formulaInflationCommission: string;
55
- formulaMEVCommission: string;
56
- formulaStakeConcentrationCountry: string;
57
- formulaStakeConcentrationCity: string;
58
- formulaStakeConcentrationASO: string;
59
- formulaStakeConcentrationNode: string;
60
- weightTargetSumOfRewards: number;
61
- weightMevHeuristic: number;
62
- weightVoteCredits: number;
63
- weightBlockProduction: number;
64
- weightInflationCommission: number;
65
- weightMEVCommission: number;
66
- weightStakeConcentrationCountry: number;
67
- weightStakeConcentrationCity: number;
68
- weightStakeConcentrationASO: number;
69
- weightStakeConcentrationNode: number;
70
- basicEligibilityEpochs: number;
71
- bonusEligibilityExtraEpochs: number;
72
- maxCommission: number;
73
- voteCreditsWarning: number;
74
- voteCreditsLow: number;
75
- minExternalStake: number;
76
- minScore: number;
77
- maxStakeShare: number;
78
- maxWarnings: number;
79
- mSolControl: number;
80
- veMndeControl: number;
81
- stakeBlocksFromBonus: number;
82
- concentrationParams: number[];
83
- };
84
-
85
- export type Variables = {
86
- bp_cluster_mean: number;
87
- bp_cluster_std_dev: number;
88
- credits_pct_mean: number;
89
- bp_mean: number;
90
- commission_inflation_max: number;
91
- commission_mev: number;
92
- country_stake_concentration_last: number;
93
- city_stake_concentration_last: number;
94
- aso_stake_concentration_last: number;
95
- node_stake_last: number;
96
- };
97
-
98
- export type Scores = Record<string, ScoreDto>
99
- export type ScoreTooltipBuilder = (validator: AggregatedValidator, clusterInfo: ClusterInfo) => string
100
-
101
- export type UnstakeHint = {
102
- vote_account: string;
103
- marinade_stake: string;
104
- hints: string[];
105
- };
106
-
107
- export type UnstakeHints = {
108
- unstake_hints: UnstakeHint[];
109
- };
@@ -1,19 +0,0 @@
1
- export class RecordDto {
2
- amount: string | null;
3
- tokenOwner: string;
4
- validatorVoteAccount: string;
5
- }
6
-
7
- export class veMNDESnapshotDto {
8
- voteRecordsCreatedAt: string;
9
- records: RecordDto[];
10
- }
11
-
12
- export class mSolSnapshotDto {
13
- mSolSnapshotCreatedAt: string;
14
- voteRecordsCreatedAt: string;
15
- records: RecordDto[];
16
- }
17
-
18
- export type Votes = Record<string, number>
19
-