Skip to content

Commit

Permalink
fix: use bignumber to handle FT supplies (#239)
Browse files Browse the repository at this point in the history
* fix: use bignumber to handle FT supplies

* fix: query supplies as string

* fix: tests
  • Loading branch information
rafaelcr authored Aug 22, 2024
1 parent 40e39cd commit 053d622
Show file tree
Hide file tree
Showing 10 changed files with 33 additions and 34 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"@sinclair/typebox": "^0.28.17",
"@stacks/transactions": "^6.1.0",
"@types/node": "^20.16.1",
"bignumber.js": "^9.1.2",
"env-schema": "^5.1.0",
"evt": "^1.11.2",
"fastify": "4.15.0",
Expand Down
4 changes: 2 additions & 2 deletions src/api/routes/ft.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const IndexRoutes: FastifyPluginCallback<Record<never, never>, Server, TypeBoxTy
name: t.name,
symbol: t.symbol,
decimals: t.decimals,
total_supply: t.total_supply?.toString(),
total_supply: t.total_supply,
token_uri: t.uri,
description: t.description,
tx_id: t.tx_id,
Expand Down Expand Up @@ -124,7 +124,7 @@ const ShowRoutes: FastifyPluginCallback<Record<never, never>, Server, TypeBoxTyp
name: metadataBundle?.token?.name ?? undefined,
symbol: metadataBundle?.token?.symbol ?? undefined,
decimals: metadataBundle?.token?.decimals ?? undefined,
total_supply: metadataBundle?.token?.total_supply?.toString() ?? undefined,
total_supply: metadataBundle?.token?.total_supply ?? undefined,
token_uri: metadataBundle?.token?.uri ?? undefined,
description: metadataBundle?.metadataLocale?.metadata?.description ?? undefined,
tx_id: contract.tx_id,
Expand Down
13 changes: 7 additions & 6 deletions src/pg/chainhook/block-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from '../../token-processor/util/sip-validation';
import { ClarityAbi } from '@stacks/transactions';
import { ClarityTypeID, decodeClarityValue } from 'stacks-encoding-native-js';
import BigNumber from 'bignumber.js';

export type CachedEvent<T> = {
event: T;
Expand All @@ -22,7 +23,7 @@ export type CachedEvent<T> = {
event_index?: number;
};

export type CachedFtSupplyDeltaMap = Map<string, bigint>;
export type CachedFtSupplyDeltaMap = Map<string, BigNumber>;

function contractPrincipalFromAssetIdentifier(asset_identifier: string): string {
return asset_identifier.split('::')[0];
Expand All @@ -39,7 +40,7 @@ export class BlockCache {
notifications: CachedEvent<TokenMetadataUpdateNotification>[] = [];
sftMints: CachedEvent<SftMintEvent>[] = [];
nftMints: CachedEvent<NftMintEvent>[] = [];
ftSupplyDelta: CachedFtSupplyDeltaMap = new Map<string, bigint>();
ftSupplyDelta: CachedFtSupplyDeltaMap = new Map<string, BigNumber>();

constructor(block: BlockIdentifier) {
this.block = block;
Expand Down Expand Up @@ -90,10 +91,10 @@ export class BlockCache {
case 'FTMintEvent':
case 'FTBurnEvent':
const principal = contractPrincipalFromAssetIdentifier(event.data.asset_identifier);
const previous = this.ftSupplyDelta.get(principal) ?? 0n;
let amount = BigInt(event.data.amount);
if (event.type === 'FTBurnEvent') amount *= -1n;
this.ftSupplyDelta.set(principal, previous + amount);
const previous = this.ftSupplyDelta.get(principal) ?? BigNumber(0);
let amount = BigNumber(event.data.amount);
if (event.type === 'FTBurnEvent') amount = amount.negated();
this.ftSupplyDelta.set(principal, previous.plus(amount));
break;
case 'NFTMintEvent':
const value = decodeClarityValue(event.data.raw_value);
Expand Down
5 changes: 3 additions & 2 deletions src/pg/chainhook/chainhook-pg-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
} from '../types';
import { BlockCache, CachedEvent } from './block-cache';
import { dbSipNumberToDbTokenType } from '../../token-processor/util/helpers';
import BigNumber from 'bignumber.js';

export class ChainhookPgStore extends BasePgStoreModule {
async processPayload(payload: StacksPayload): Promise<void> {
Expand Down Expand Up @@ -155,7 +156,7 @@ export class ChainhookPgStore extends BasePgStoreModule {
for (const mint of cache.nftMints) await this.rollBackNftMint(sql, mint, cache);
for (const mint of cache.sftMints) await this.rollBackSftMint(sql, mint, cache);
for (const [contract, delta] of cache.ftSupplyDelta)
await this.applyFtSupplyChange(sql, contract, delta * -1n, cache);
await this.applyFtSupplyChange(sql, contract, delta.negated(), cache);
}

private async applyNotification(
Expand Down Expand Up @@ -279,7 +280,7 @@ export class ChainhookPgStore extends BasePgStoreModule {
private async applyFtSupplyChange(
sql: PgSqlClient,
contract: string,
delta: bigint,
delta: BigNumber,
cache: BlockCache
): Promise<void> {
await sql`
Expand Down
6 changes: 1 addition & 5 deletions src/pg/pg-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,7 @@ export class PgStore extends BasePgStore {
if (result.count === 0) {
return undefined;
}
const token = result[0];
return {
...token,
total_supply: token.total_supply ? BigInt(token.total_supply.toString()) : undefined,
};
return result[0];
}

async getTokenMetadataBundle(args: {
Expand Down
15 changes: 7 additions & 8 deletions src/pg/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,13 @@ export type DbToken = {
smart_contract_id: number;
type: DbTokenType;
token_number: bigint;
uri?: string;
name?: string;
decimals?: number;
total_supply?: bigint;
symbol?: string;
uri: string | null;
name: string | null;
decimals: number | null;
total_supply: string | null;
symbol: string | null;
created_at: string;
updated_at?: string;
token_medatada_notification_id?: number;
updated_at: string | null;
};

export type DbJobInsert = {
Expand Down Expand Up @@ -254,7 +253,7 @@ export type DbFungibleTokenMetadataItem = {
name?: string;
symbol?: string;
decimals?: number;
total_supply?: bigint;
total_supply?: string;
uri?: string;
description?: string;
tx_id: string;
Expand Down
6 changes: 3 additions & 3 deletions tests/api/ft.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ describe('FT routes', () => {
description: 'Meme',
tx_id: '0xbdc41843d5e0cd4a70611f6badeb5c87b07b12309e77c4fbaf2334c7b4cee89b',
principal: 'SP22PCWZ9EJMHV4PHVS0C8H3B3E4Q079ZHY6CXDS1.meme-token',
total_supply: 200000n,
total_supply: '200000',
image: 'http://img.com/meme.jpg',
cached_image: 'http://img.com/meme.jpg',
uri: 'https://ipfs.io/abcd.json',
Expand All @@ -338,7 +338,7 @@ describe('FT routes', () => {
name: 'miamicoin',
symbol: 'MIA',
decimals: 6,
total_supply: 5586789829000000n,
total_supply: '5586789829000000',
uri: 'https://cdn.citycoins.co/metadata/miamicoin.json',
description: 'A CityCoin for Miami, ticker is MIA, Stack it to earn Stacks (STX)',
image: 'https://cdn.citycoins.co/logos/miamicoin.png',
Expand All @@ -350,7 +350,7 @@ describe('FT routes', () => {
name: 'STACKSWAP',
symbol: 'STSW',
decimals: 6,
total_supply: 1000000000000000n,
total_supply: '1000000000000000',
uri: 'https://app.stackswap.org/token/stsw.json',
description: 'StackSwap Project',
image: 'https://app.stackswap.org/icon/stsw.svg',
Expand Down
8 changes: 4 additions & 4 deletions tests/chainhook/ft-events.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('FT events', () => {
};
await db.updateProcessedTokenWithMetadata({ id: 1, values: tokenValues });
let token = await db.getToken({ id: 1 });
expect(token?.total_supply).toBe(10000n);
expect(token?.total_supply).toBe('10000');

await db.chainhook.processPayload(
new TestChainhookPayloadBuilder()
Expand All @@ -58,7 +58,7 @@ describe('FT events', () => {
);

token = await db.getToken({ id: 1 });
expect(token?.total_supply).toBe(12000n);
expect(token?.total_supply).toBe('12000');
});

test('FT mints do not enqueue refresh', async () => {
Expand Down Expand Up @@ -105,7 +105,7 @@ describe('FT events', () => {
};
await db.updateProcessedTokenWithMetadata({ id: 1, values: tokenValues });
let token = await db.getToken({ id: 1 });
expect(token?.total_supply).toBe(10000n);
expect(token?.total_supply).toBe('10000');

await db.chainhook.processPayload(
new TestChainhookPayloadBuilder()
Expand All @@ -125,7 +125,7 @@ describe('FT events', () => {
);

token = await db.getToken({ id: 1 });
expect(token?.total_supply).toBe(8000n);
expect(token?.total_supply).toBe('8000');
});

test('FT burns do not enqueue refresh', async () => {
Expand Down
8 changes: 4 additions & 4 deletions tests/token-queue/process-token-job.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ describe('ProcessTokenJob', () => {
expect(token?.name).toBe('FooToken');
expect(token?.symbol).toBe('FOO');
expect(token?.decimals).toBe(6);
expect(token?.total_supply).toBe(1997500000000n);
expect(token?.total_supply).toBe('1997500000000');
});

test('keeps contract FT info if metadata fetch fails', async () => {
Expand Down Expand Up @@ -176,7 +176,7 @@ describe('ProcessTokenJob', () => {
expect(token?.name).toBe('FooToken');
expect(token?.symbol).toBe('FOO');
expect(token?.decimals).toBe(6);
expect(token?.total_supply).toBe(1997500000000n);
expect(token?.total_supply).toBe('1997500000000');
const bundle = await db.getTokenMetadataBundle({
contractPrincipal: 'ABCD.test-ft',
tokenNumber: 1,
Expand Down Expand Up @@ -246,7 +246,7 @@ describe('ProcessTokenJob', () => {
expect(token?.name).toBe('FooToken');
expect(token?.symbol).toBe('FOO');
expect(token?.decimals).toBe(6);
expect(token?.total_supply).toBeUndefined();
expect(token?.total_supply).toBeNull();
});

test('accepts FTs with invalid image entries', async () => {
Expand Down Expand Up @@ -776,7 +776,7 @@ describe('ProcessTokenJob', () => {
expect(token).not.toBeUndefined();
expect(token?.uri).toBeNull();
expect(token?.decimals).toBe(6);
expect(token?.total_supply).toBe(200200200n);
expect(token?.total_supply).toBe('200200200');
});
});

Expand Down

0 comments on commit 053d622

Please sign in to comment.