Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🏠 add tokenID to balances for account: #167

Merged
merged 1 commit into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,20 @@ CREATE TABLE "Account" (
"publicKey" TEXT,
"name" TEXT,
"description" TEXT,

CONSTRAINT "Account_pkey" PRIMARY KEY ("address")
);

-- CreateTable
CREATE TABLE "TokenBalance" (
"id" SERIAL NOT NULL,
"tokenID" TEXT NOT NULL,
"totalBalance" BIGINT NOT NULL DEFAULT 0,
"availableBalance" BIGINT NOT NULL DEFAULT 0,
"lockedBalance" BIGINT NOT NULL DEFAULT 0,
"accountAddress" TEXT NOT NULL,

CONSTRAINT "Account_pkey" PRIMARY KEY ("address")
CONSTRAINT "TokenBalance_pkey" PRIMARY KEY ("id")
);

-- CreateTable
Expand Down Expand Up @@ -306,6 +315,9 @@ CREATE UNIQUE INDEX "Account_address_key" ON "Account"("address");
-- CreateIndex
CREATE UNIQUE INDEX "Account_publicKey_key" ON "Account"("publicKey");

-- CreateIndex
CREATE UNIQUE INDEX "TokenBalance_accountAddress_tokenID_key" ON "TokenBalance"("accountAddress", "tokenID");

-- CreateIndex
CREATE UNIQUE INDEX "App_chainID_key" ON "App"("chainID");

Expand Down Expand Up @@ -339,6 +351,9 @@ CREATE UNIQUE INDEX "Token_tokenID_key" ON "Token"("tokenID");
-- CreateIndex
CREATE UNIQUE INDEX "TokenLogo_tokenID_key" ON "TokenLogo"("tokenID");

-- AddForeignKey
ALTER TABLE "TokenBalance" ADD CONSTRAINT "TokenBalance_accountAddress_fkey" FOREIGN KEY ("accountAddress") REFERENCES "Account"("address") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "ServiceURL" ADD CONSTRAINT "ServiceURL_appChainID_fkey" FOREIGN KEY ("appChainID") REFERENCES "App"("chainID") ON DELETE RESTRICT ON UPDATE CASCADE;

Expand Down
16 changes: 13 additions & 3 deletions prisma/schema/account.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,22 @@ model Account {
publicKey String? @unique
name String?
description String?
totalBalance BigInt @default(0)
availableBalance BigInt @default(0)
lockedBalance BigInt @default(0)
validator Validator?
tokenBalances TokenBalance[]
block Block[]
stakes Stake[]
transactionSender Transaction[] @relation("sender")
transactionRecipient Transaction[] @relation("recipient")
}

model TokenBalance {
id Int @id @default(autoincrement())
tokenID String
totalBalance BigInt @default(0)
availableBalance BigInt @default(0)
lockedBalance BigInt @default(0)
accountAddress String
account Account @relation(fields: [accountAddress], references: [address])

@@unique([accountAddress, tokenID])
}
37 changes: 25 additions & 12 deletions src/modules/account/account.controller.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Controller, Get, Query, UsePipes, ValidationPipe } from '@nestjs/common';
import { ApiResponse, ApiTags } from '@nestjs/swagger';
import { PrismaService } from '../prisma/prisma.service';
import { getAccountsRes } from './dto/get-accounts-res.dto';
import { getAccountsRes, GetAccountsResDto } from './dto/get-accounts-res.dto';
import { GatewayResponse } from 'src/utils/controller-helpers';
import { GetAccountsDto } from './dto/get-accounts.dto';
import { Prisma } from '@prisma/client';
Expand All @@ -15,9 +15,8 @@ export class AccountController {
@Get()
@UsePipes(new ValidationPipe({ transform: true, whitelist: true, forbidNonWhitelisted: true }))
@ApiResponse(getAccountsRes)
async getAccounts(@Query() query: GetAccountsDto): Promise<GatewayResponse<any[]>> {
const { address, name, publicKey, offset, sort, limit } = query;
const [field, direction] = sort.split(':');
async getAccounts(@Query() query: GetAccountsDto): Promise<GetAccountsResDto> {
const { address, name, publicKey, offset, limit } = query;
const take = Math.min(limit, MAX_ACCOUNTS_TO_FETCH);

const where: Prisma.AccountWhereInput = {
Expand All @@ -29,20 +28,34 @@ export class AccountController {
const accounts = await this.prisma.account.findMany({
where,
take,
orderBy: {
[field]: direction,
include: {
tokenBalances: true,
},
skip: offset,
});

const total = await this.prisma.account.count({ where });

const response = accounts.map((account) => ({
...account,
availableBalance: account.availableBalance.toString(),
lockedBalance: account.lockedBalance.toString(),
totalBalance: account.totalBalance.toString(),
}));
// ? can this be done in a better way?
const response = accounts.map((account) => {
const tokenBalances = account.tokenBalances.reduce((acc, balance) => {
const tokenID = balance.tokenID;
if (!acc[tokenID]) {
acc[tokenID] = [];
}
acc[tokenID].push({
availableBalance: balance.availableBalance.toString(),
lockedBalance: balance.lockedBalance.toString(),
totalBalance: balance.totalBalance.toString(),
});
return acc;
}, {});

return {
...account,
tokenBalances,
};
});

return new GatewayResponse(response, { count: accounts.length, offset, total });
}
Expand Down
10 changes: 7 additions & 3 deletions src/modules/account/dto/get-accounts-res.dto.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { ApiResponseOptions } from '@nestjs/swagger';

class TokenBalance {
availableBalance: string;
lockedBalance: string;
totalBalance: string;
}
export class GetAccountsData {
address: string;
publicKey: string;
name: string;
nonce: string;
totalBalance: string;
availableBalance: string;
lockedBalance: string;
description?: string;
tokenBalances: Record<string, TokenBalance[]>;
}

export class GetAccountMeta {
Expand Down
10 changes: 0 additions & 10 deletions src/modules/account/dto/get-accounts.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,6 @@ export class GetAccountsDto {
@IsOptional()
publicKey?: string;

/**
* Sort accounts.
*/
@IsString()
@IsEnum(AccountSortTypes, {
message:
'sort must be one of the following values: ' + Object.values(AccountSortTypes).join(', '),
})
sort?: AccountSortTypes = AccountSortTypes.TOTAL_BALANCE_DESC;

/**
* Limit the number of accounts fetched.
*/
Expand Down
19 changes: 16 additions & 3 deletions src/modules/indexer/event/commands/update-account.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export class UpdateAccountHandler implements ICommandHandler<UpdateAccountComman

async execute(command: UpdateAccountCommand): Promise<void> {
const { address, tokenID } = command;
console.log({ address });

const accountInfo = await this.nodeApi.invokeApi<TokenBalance>(NodeApi.TOKEN_GET_BALANCE, {
address,
Expand All @@ -40,9 +41,21 @@ export class UpdateAccountHandler implements ICommandHandler<UpdateAccountComman
const availableBalance = BigInt(accountInfo.availableBalance);
const totalBalance = lockedBalance + availableBalance;

await this.prisma.account.update({
where: { address },
data: {
await this.prisma.tokenBalance.upsert({
where: {
accountAddress_tokenID: {
accountAddress: address,
tokenID: tokenID,
},
},
update: {
availableBalance: availableBalance,
lockedBalance: lockedBalance,
totalBalance: totalBalance,
},
create: {
accountAddress: address,
tokenID: tokenID,
availableBalance: availableBalance,
lockedBalance: lockedBalance,
totalBalance: totalBalance,
Expand Down
1 change: 1 addition & 0 deletions src/modules/prisma/prisma.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export class PrismaService extends PrismaClient implements OnModuleInit {
await this.nextBlockToSync.deleteMany({});
await this.stake.deleteMany({});
await this.validator.deleteMany({});
await this.tokenBalance.deleteMany({});
await this.account.deleteMany({});
await this.cachedSchemas.deleteMany({});
await this.serviceURL.deleteMany({});
Expand Down
Loading