Skip to content

Commit

Permalink
Merge pull request #93 from zkLinkProtocol/feat-loadOtherPoints
Browse files Browse the repository at this point in the history
add supplement endpoint.
  • Loading branch information
zkcarter authored Jul 24, 2024
2 parents 978b9c9 + 0eb2f3c commit 3066311
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 12 deletions.
4 changes: 4 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ import { TxDataOfPointsRepository } from "./repositories/txDataOfPoints.reposito
import { ReferralService } from "./referral/referral.service";
import { ReferralRepository } from "./repositories/referral.repository";
import { SeasonTotalPointRepository } from "./repositories/seasonTotalPoint.repository";
import { SupplementPointRepository } from "./repositories/supplementPoint.repository";
import { supplementPoint } from "./entities/supplementPoint.entity";

@Module({
imports: [
Expand Down Expand Up @@ -105,6 +107,7 @@ import { SeasonTotalPointRepository } from "./repositories/seasonTotalPoint.repo
UserStaked,
UserWithdraw,
SeasonTotalPoint,
supplementPoint,
]),
TypeOrmModule.forFeature([Referral], "referral"),
MetricsModule,
Expand Down Expand Up @@ -161,6 +164,7 @@ import { SeasonTotalPointRepository } from "./repositories/seasonTotalPoint.repo
ReferralService,
ReferralRepository,
SeasonTotalPointRepository,
SupplementPointRepository,
],
})
export class AppModule {}
24 changes: 24 additions & 0 deletions src/entities/supplementPoint.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Entity, Column, PrimaryColumn, Index } from "typeorm";
import { BaseEntity } from "./base.entity";
import { hexTransformer } from "../transformers/hex.transformer";

export enum SupplementPointType {
DirectHold = "directHold",
}

@Entity({ name: "supplementPoint" })
@Index("idx_supplementPoint_1", ["address", "batchString", "type"])
export class supplementPoint extends BaseEntity {
@Column({ type: "bytea", transformer: hexTransformer })
public address: string;

@Column({ type: "varchar", length: 20 })
public batchString: string;

@Column("decimal")
public point: number;

// directHold
@PrimaryColumn({ type: "varchar", length: 20 })
public type: SupplementPointType;
}
34 changes: 34 additions & 0 deletions src/nova/nova.balance.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { ProjectService } from "src/common/service/project.service";
import { Worker } from "src/common/worker";
import waitFor from "src/utils/waitFor";
import s2_1Milestone from "../config/season2-1.milestone";
import { verifyMessage } from "ethers";
import { SupplementPointRepository } from "src/repositories/supplementPoint.repository";

interface ProjectPoints {
name: string;
Expand Down Expand Up @@ -54,6 +56,7 @@ export class NovaBalanceService extends Worker {
private readonly seasonTotalPointRepository: SeasonTotalPointRepository,
private readonly projectService: ProjectService,
private readonly balanceOfLp: BalanceOfLpRepository,
private readonly supplementPointRepository: SupplementPointRepository,
) {
super();
this.logger = new Logger(NovaBalanceService.name);
Expand Down Expand Up @@ -693,4 +696,35 @@ export class NovaBalanceService extends Worker {

return result;
}

async uploadOtherPoints(
data: { address: string; point: number }[],
signature,
batchString,
): Promise<boolean> {
const message = "supplementPoint";
const address = "0xfb5eb3d27128a9dde885304e2653c41396e36662";
const valid = await this.validatePrivatekey(address, message, signature);
if (!valid) {
return false;
}
await this.supplementPointRepository.addManyDirectPoint(data, batchString);
return true;
}

async validatePrivatekey(
address: string,
message: string,
signature: string,
): Promise<boolean> {
try {
const recoveredAddress = verifyMessage(message, signature);
return recoveredAddress.toLowerCase() === address.toLowerCase();
} catch (error) {
this.logger.log(
`validatePrivatekey: ${address} ${message} ${signature}, error: ${error.stack}`,
);
return false;
}
}
}
43 changes: 31 additions & 12 deletions src/nova/nova.controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { Controller, Get, Logger, Param, Query } from "@nestjs/common";
import {
Body,
Controller,
Get,
Logger,
Param,
Post,
Query,
} from "@nestjs/common";
import {
ApiBadRequestResponse,
ApiExcludeController,
Expand Down Expand Up @@ -672,17 +680,28 @@ export class NovaController {
data: result,
};
}
@Get("/zkl/list")
@ApiOperation({ summary: "Retrieve all users'total points and zkl amount." })
@ApiBadRequestResponse({
description: '{ "errno": 1, "errmsg": "Service exception" }',
})
@ApiNotFoundResponse({
description: '{ "errno": 1, "errmsg": "not found" }',
})
public async getZklsAmount(): Promise<ResponseDto<ZklDto[]>> {
const season = 2;
const result = await this.novaBalanceService.getAllPointsZkl(season);

@Post("/point/supplement")
public async uploadSupplementPoints(
@Query("signature") signature: string,
@Query("batchString") batchString: string,
@Body()
data: {
address: string;
point: number;
}[],
): Promise<ResponseDto<boolean>> {
let result = false;
try {
result = await this.novaBalanceService.uploadOtherPoints(
data,
signature,
batchString,
);
} catch (error) {
this.logger.error("Upload supplement points failed", error.stack);
result = false;
}
return {
errno: 0,
errmsg: "no error",
Expand Down
54 changes: 54 additions & 0 deletions src/repositories/base.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,58 @@ export abstract class BaseRepository<T> {
const transactionManager = this.unitOfWork.getTransactionManager();
return await transactionManager.find(this.entityTarget, options);
}

public async addManyIgnoreConflicts(records: Partial<T>[]): Promise<void> {
if (!records?.length) {
return;
}

const transactionManager = this.unitOfWork.getTransactionManager();

let recordsToInsert = [];
for (let i = 0; i < records.length; i++) {
recordsToInsert.push(records[i]);
if (recordsToInsert.length === BATCH_SIZE || i === records.length - 1) {
await transactionManager
.createQueryBuilder()
.insert()
.into(this.entityTarget)
.values(recordsToInsert)
.orIgnore()
.execute();

recordsToInsert = [];
}
}
}

public async addManyOrUpdate(
records: Partial<T>[],
updateColumns: string[],
conflictColumns: string[],
): Promise<void> {
if (!records?.length) {
return;
}

const transactionManager = this.unitOfWork.getTransactionManager();

let recordsToAddOrUpdate = [];
for (let i = 0; i < records.length; i++) {
recordsToAddOrUpdate.push(records[i]);
if (
recordsToAddOrUpdate.length === BATCH_SIZE ||
i === records.length - 1
) {
await transactionManager
.createQueryBuilder()
.insert()
.into(this.entityTarget)
.values(recordsToAddOrUpdate)
.orUpdate(updateColumns, conflictColumns)
.execute();
recordsToAddOrUpdate = [];
}
}
}
}
33 changes: 33 additions & 0 deletions src/repositories/supplementPoint.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Injectable } from "@nestjs/common";
import { UnitOfWork } from "../unitOfWork";
import { BaseRepository } from "./base.repository";
import {
SupplementPointType,
supplementPoint,
} from "../entities/supplementPoint.entity";

@Injectable()
export class SupplementPointRepository extends BaseRepository<supplementPoint> {
public constructor(unitOfWork: UnitOfWork) {
super(supplementPoint, unitOfWork);
}

async addManyDirectPoint(
points: { address: string; point: number }[],
batchString: string,
): Promise<void> {
const insertData = points.map((item) => {
return {
address: item.address,
point: item.point,
batchString: batchString,
type: SupplementPointType.DirectHold,
};
});
await this.addManyOrUpdate(
insertData,
["point"],
["address", "batchString", "type"],
);
}
}

0 comments on commit 3066311

Please sign in to comment.