Compare commits

...

3 Commits

Author SHA1 Message Date
02235b12a9 Add lint and build gitea workflow 2025-12-23 18:17:03 +05:30
AdityaSalunkhe21
4e73b98a17 Add lint and build github workflow 2025-12-19 13:52:25 +05:30
AdityaSalunkhe21
47af6e0bcf Fix lint and type errors 2025-12-19 13:50:52 +05:30
10 changed files with 1870 additions and 55 deletions

3
.eslintignore Normal file
View File

@ -0,0 +1,3 @@
node_modules
dist
*.js

29
.eslintrc.json Normal file
View File

@ -0,0 +1,29 @@
{
"env": {
"es2021": true,
"node": true
},
"extends": [
"semistandard",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"indent": ["error", 2, { "SwitchCase": 1 }],
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/explicit-module-boundary-types": [
"warn",
{
"allowArgumentsExplicitlyTypedAsAny": true
}
]
},
"ignorePatterns": ["dist", "node_modules", "*.js"]
}

View File

@ -0,0 +1,42 @@
name: Lint and Build
on:
push:
branches:
- main
paths:
- 'src/**'
pull_request:
branches:
- main
paths:
- 'src/**'
jobs:
lint-and-build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Enable corepack and yarn
run: corepack enable
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Run lint
run: yarn lint
- name: Run build
run: yarn build

36
.github/workflows/lint-and-build.yml vendored Normal file
View File

@ -0,0 +1,36 @@
name: Lint and Build
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
lint-and-build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Run lint
run: yarn lint
- name: Run build
run: yarn build

View File

@ -9,7 +9,9 @@
"postbuild": "cp src/schema.graphql dist/schema.graphql",
"start": "node dist/index.js",
"dev": "ts-node src/index.ts",
"generate-participants": "node dist/participant-generator.js"
"generate-participants": "node dist/participant-generator.js",
"lint": "eslint --max-warnings=0 .",
"lint:fix": "eslint . --fix"
},
"dependencies": {
"apollo-server-express": "^3.12.1",
@ -23,6 +25,15 @@
"devDependencies": {
"@types/express": "^4.17.21",
"@types/node": "^20.14.10",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"eslint": "^8.57.0",
"eslint-config-semistandard": "^15.0.1",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-standard": "^5.0.0",
"ts-node": "^10.9.2",
"typescript": "^5.5.3"
}

View File

@ -26,14 +26,14 @@ interface BlockData {
}
interface PointLockedEvent {
__typename: "PointLockedEvent";
__typename: 'PointLockedEvent';
azimuth_id: string;
point: string;
lock_period: number;
}
interface LockdropClosedEvent {
__typename: "LockdropClosedEvent";
__typename: 'LockdropClosedEvent';
ok: boolean;
}
@ -48,7 +48,7 @@ interface GeneratedData {
};
}
function generateMockBlock(): BlockData {
function generateMockBlock (): BlockData {
const sixMonthsAgo = Math.floor(Date.now() / 1000) - (6 * 30 * 24 * 60 * 60);
const now = Math.floor(Date.now() / 1000);
@ -58,15 +58,15 @@ function generateMockBlock(): BlockData {
return {
hash: `0x${Math.random().toString(16).substr(2, 64)}`,
number: randomBlockNumber,
timestamp: randomTimestamp,
timestamp: randomTimestamp
};
}
function generateRandomLockPeriod(): number {
function generateRandomLockPeriod (): number {
return Math.floor(Math.random() * 5) + 1; // 1 to 5 years
}
export function generateDataFromParticipants(verifiedParticipantsPath: string): GeneratedData {
export function generateDataFromParticipants (verifiedParticipantsPath: string): GeneratedData {
const participantsData = JSON.parse(fs.readFileSync(verifiedParticipantsPath, 'utf8')) as VerifiedParticipant[];
const events: EventInRange[] = [];
@ -115,11 +115,11 @@ export function generateDataFromParticipants(verifiedParticipantsPath: string):
const event: EventInRange = {
block,
event: {
__typename: "PointLockedEvent",
__typename: 'PointLockedEvent',
azimuth_id: azimuthId,
point,
lock_period: lockPeriod,
},
lock_period: lockPeriod
}
};
events.push(event);
}
@ -130,19 +130,19 @@ export function generateDataFromParticipants(verifiedParticipantsPath: string):
events.push({
block: latestBlock,
event: {
__typename: "LockdropClosedEvent",
ok: true,
},
__typename: 'LockdropClosedEvent',
ok: true
}
});
}
return {
data: {
eventsInRange: events,
},
eventsInRange: events
}
};
}
export function saveGeneratedData(data: GeneratedData, outputPath: string): void {
export function saveGeneratedData (data: GeneratedData, outputPath: string): void {
fs.writeFileSync(outputPath, JSON.stringify(data, null, 2));
}

View File

@ -4,12 +4,12 @@ import { readFileSync } from 'fs';
import { join } from 'path';
import { resolvers } from './resolvers';
async function startServer() {
async function startServer () {
const typeDefs = readFileSync(join(__dirname, 'schema.graphql'), 'utf8');
const server = new ApolloServer({
typeDefs,
resolvers,
resolvers
});
await server.start();

View File

@ -10,7 +10,7 @@ const MAX_GALAXIES = 256;
const MAX_STARS = 65280;
// Generate real Cosmos address with zenith prefix using standard derivation
async function generateCosmosAddress(): Promise<{ address: string; privateKey: string }> {
async function generateCosmosAddress (): Promise<{ address: string; privateKey: string }> {
const privkeyBytes = Random.getBytes(32);
const keypair = await Secp256k1.makeKeypair(privkeyBytes);
const pubkey = Secp256k1.compressPubkey(keypair.pubkey);
@ -27,7 +27,7 @@ async function generateCosmosAddress(): Promise<{ address: string; privateKey: s
}
// Generate real Ethereum address
function generateEthereumAddress(): { address: string; privateKey: string } {
function generateEthereumAddress (): { address: string; privateKey: string } {
const wallet = Wallet.createRandom();
return {
address: wallet.address,
@ -36,7 +36,7 @@ function generateEthereumAddress(): { address: string; privateKey: string } {
}
// Generate Urbit point names using urbit-ob
function getUrbitPointName(id: number): string {
function getUrbitPointName (id: number): string {
return patp(id.toString());
}
@ -88,11 +88,11 @@ export class ParticipantGenerator {
private usedGalaxies: Set<number> = new Set();
private usedStars: Set<number> = new Set();
constructor(config: GeneratorConfig) {
constructor (config: GeneratorConfig) {
this.config = config;
}
private shuffleArray<T>(array: T[]): T[] {
private shuffleArray<T> (array: T[]): T[] {
const shuffled = [...array];
for (let i = shuffled.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
@ -101,19 +101,19 @@ export class ParticipantGenerator {
return shuffled;
}
private getAvailableGalaxies(): number[] {
private getAvailableGalaxies (): number[] {
const galaxies = Array.from({ length: MAX_GALAXIES }, (_, i) => i);
return this.shuffleArray(galaxies).slice(0, this.config.galaxyCount);
}
private getAvailableStars(): number[] {
private getAvailableStars (): number[] {
// Stars start from MAX_GALAXIES (after galaxies)
const stars = Array.from({ length: MAX_STARS }, (_, i) => i + MAX_GALAXIES);
return this.shuffleArray(stars).slice(0, this.config.starCount);
}
// Distribute all available galaxies among first participants (they become validators)
private distributeGalaxies(availableGalaxies: number[]): number[] {
private distributeGalaxies (availableGalaxies: number[]): number[] {
const galaxyAllocation: number[] = new Array(this.config.totalParticipants).fill(null);
// First galaxyCount participants get galaxies (and become validators)
@ -125,7 +125,7 @@ export class ParticipantGenerator {
}
// Distribute all available stars randomly among all participants (each gets at least 1)
private distributeStars(availableStars: number[]): number[][] {
private distributeStars (availableStars: number[]): number[][] {
const starAllocation: number[][] = Array.from({ length: this.config.totalParticipants }, () => []);
const shuffledStars = this.shuffleArray([...availableStars]);
@ -143,7 +143,7 @@ export class ParticipantGenerator {
return starAllocation;
}
async generate(): Promise<{ participants: VerifiedParticipant[]; accounts: GeneratedAccount[]; stats: GenerationStats }> {
async generate (): Promise<{ participants: VerifiedParticipant[]; accounts: GeneratedAccount[]; stats: GenerationStats }> {
const participants: VerifiedParticipant[] = [];
this.accounts = [];
this.usedGalaxies.clear();
@ -192,10 +192,10 @@ export class ParticipantGenerator {
attestation: {
payload: {
address: ethereumAccount.address,
msg: "Onboarding my Azimuth ID onto ZenithChain",
msg: 'Onboarding my Azimuth ID onto ZenithChain',
payload: {
address: cosmosAccount.address,
msg: "Onboarding my validator onto ZenithChain",
msg: 'Onboarding my validator onto ZenithChain',
owned_points: {
galaxy,
stars
@ -207,7 +207,7 @@ export class ParticipantGenerator {
`dummy_zenith_sig_${i}_${Math.random().toString(36).substring(2, 15)}`
]
},
role: isValidator ? "validator" : "delegator"
role: isValidator ? 'validator' : 'delegator'
};
participants.push(participant);
@ -233,7 +233,7 @@ export class ParticipantGenerator {
return { participants, accounts: this.accounts, stats };
}
saveToFiles(outputDir: string, participants: VerifiedParticipant[], accounts: GeneratedAccount[], stats: GenerationStats): void {
saveToFiles (outputDir: string, participants: VerifiedParticipant[], accounts: GeneratedAccount[], stats: GenerationStats): void {
// Ensure output directory exists
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
@ -257,7 +257,7 @@ export class ParticipantGenerator {
}
// Validation function
function validateConfig(config: GeneratorConfig): void {
function validateConfig (config: GeneratorConfig): void {
const errors: string[] = [];
if (config.totalParticipants <= 0) {
@ -297,7 +297,7 @@ function validateConfig(config: GeneratorConfig): void {
}
// CLI interface
function parseArgs(): GeneratorConfig {
function parseArgs (): GeneratorConfig {
const args = process.argv.slice(2);
const config: GeneratorConfig = {
totalParticipants: 400,
@ -374,10 +374,10 @@ if (require.main === module) {
if (fs.existsSync(statsPath)) existingFiles.push('point-allocation-stats.json');
if (existingFiles.length > 0) {
console.warn(`\nWARNING: The following files will be overwritten:`);
console.warn('\nWARNING: The following files will be overwritten:');
existingFiles.forEach(file => console.warn(` - ${path.join(config.outputDir, file)}`));
console.warn(` This will replace all existing generated participant data.`);
console.warn(` Press Ctrl+C to cancel or any key to continue...`);
console.warn(' This will replace all existing generated participant data.');
console.warn(' Press Ctrl+C to cancel or any key to continue...');
// Wait for user input
process.stdin.setRawMode(true);
@ -398,7 +398,7 @@ if (require.main === module) {
startGeneration();
}
function startGeneration() {
function startGeneration () {
console.log('\nStarting generation...\n');
const generator = new ParticipantGenerator(config);

View File

@ -3,7 +3,7 @@ import * as path from 'path';
import { generateDataFromParticipants, saveGeneratedData } from './data-generator';
function loadOrGenerateData() {
function loadOrGenerateData (): any {
const outputDir = process.env.GENERATED_WATCHER_EVENTS_OUTPUT_PATH || path.join(process.cwd(), 'generated');
// Ensure output directory exists
@ -14,7 +14,7 @@ function loadOrGenerateData() {
const dataPath = path.join(outputDir, 'watcher-events.json');
const verifiedParticipantsPath = process.env.VERIFIED_PARTICIPANTS_PATH;
// Fallback to existing data
// Fallback to existing data
if (fs.existsSync(dataPath)) {
console.log('Using existing watcher-events.json...');
return JSON.parse(fs.readFileSync(dataPath, 'utf8'));
@ -39,7 +39,7 @@ const data = loadOrGenerateData();
export const resolvers = {
Query: {
eventsInRange: (_: any, args: { fromBlockNumber: number; toBlockNumber: number; name?: string }) => {
eventsInRange: (_: any, args: { fromBlockNumber: number; toBlockNumber: number; name?: string }): any[] => {
const events = data.data.eventsInRange;
return events.filter((event: any) => {

1722
yarn.lock

File diff suppressed because it is too large Load Diff