From 1a89df7e5aa2cdbedb0cab655c2a6d984ca3bd4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Thu, 7 Mar 2024 12:14:27 -0600 Subject: [PATCH] test: unify brc-20 parsing tests (#324) * test: unify brc-20 parsing tests * chore: remove unused import --- src/pg/brc20/brc20-pg-store.ts | 14 +-- src/pg/brc20/helpers.ts | 20 ++-- tests/brc-20/brc20.test.ts | 166 ++++++++++++++++++++++----------- 3 files changed, 122 insertions(+), 78 deletions(-) diff --git a/src/pg/brc20/brc20-pg-store.ts b/src/pg/brc20/brc20-pg-store.ts index e04a5734..fa3d6dab 100644 --- a/src/pg/brc20/brc20-pg-store.ts +++ b/src/pg/brc20/brc20-pg-store.ts @@ -1,6 +1,5 @@ import { BasePgStoreModule, logger } from '@hirosystems/api-toolkit'; import * as postgres from 'postgres'; -import { hexToBuffer } from '../../api/util/helpers'; import { DbInscriptionIndexPaging, InscriptionData, @@ -26,7 +25,7 @@ import { DbBrc20TokenWithSupply, DbBrc20TransferEvent, } from './types'; -import { Brc20Deploy, Brc20Mint, Brc20Transfer, brc20FromInscriptionContent } from './helpers'; +import { Brc20Deploy, Brc20Mint, Brc20Transfer, brc20FromInscription } from './helpers'; import { Brc20TokenOrderBy } from '../../api/schemas'; import { objRemoveUndefinedValues } from '../helpers'; @@ -46,16 +45,7 @@ export class Brc20PgStore extends BasePgStoreModule { const pointer = args.pointers[i]; if (parseInt(pointer.block_height) < BRC20_GENESIS_BLOCK) continue; if ('inscription' in reveal) { - if ( - reveal.inscription.classic_number < 0 || - reveal.inscription.number < 0 || - reveal.location.transfer_type != DbLocationTransferType.transferred || - !['text/plain', 'application/json'].includes(reveal.inscription.mime_type) - ) - continue; - const brc20 = brc20FromInscriptionContent( - hexToBuffer(reveal.inscription.content as string).toString('utf-8') - ); + const brc20 = brc20FromInscription(reveal); if (brc20) { switch (brc20.op) { case 'deploy': diff --git a/src/pg/brc20/helpers.ts b/src/pg/brc20/helpers.ts index 3b1f1958..854609df 100644 --- a/src/pg/brc20/helpers.ts +++ b/src/pg/brc20/helpers.ts @@ -2,7 +2,7 @@ import { Static, Type } from '@fastify/type-provider-typebox'; import { TypeCompiler } from '@sinclair/typebox/compiler'; import BigNumber from 'bignumber.js'; import { hexToBuffer } from '../../api/util/helpers'; -import { InscriptionData } from '../types'; +import { DbLocationTransferType, InscriptionRevealData } from '../types'; const Brc20TickerSchema = Type.String({ minLength: 1 }); const Brc20NumberSchema = Type.RegEx(/^((\d+)|(\d*\.?\d+))$/); @@ -50,18 +50,16 @@ const UINT64_MAX = BigNumber('18446744073709551615'); // 20 digits // Only compare against `UINT64_MAX` if the number is at least the same number of digits. const numExceedsMax = (num: string) => num.length >= 20 && UINT64_MAX.isLessThan(num); -// For testing only -export function brc20FromInscription(inscription: InscriptionData): Brc20 | undefined { - if (inscription.number < 0) return; - if (inscription.mime_type !== 'text/plain' && inscription.mime_type !== 'application/json') +export function brc20FromInscription(reveal: InscriptionRevealData): Brc20 | undefined { + if ( + reveal.inscription.classic_number < 0 || + reveal.inscription.number < 0 || + reveal.location.transfer_type != DbLocationTransferType.transferred || + !['text/plain', 'application/json'].includes(reveal.inscription.mime_type) + ) return; - const buf = hexToBuffer(inscription.content as string).toString('utf-8'); - return brc20FromInscriptionContent(buf); -} - -export function brc20FromInscriptionContent(content: string): Brc20 | undefined { try { - const json = JSON.parse(content); + const json = JSON.parse(hexToBuffer(reveal.inscription.content as string).toString('utf-8')); if (Brc20C.Check(json)) { // Check ticker byte length if (Buffer.from(json.tick).length !== 4) return; diff --git a/tests/brc-20/brc20.test.ts b/tests/brc-20/brc20.test.ts index 9f5a8608..efedf8c4 100644 --- a/tests/brc-20/brc20.test.ts +++ b/tests/brc-20/brc20.test.ts @@ -3,7 +3,7 @@ import { buildApiServer } from '../../src/api/init'; import { Brc20ActivityResponse, Brc20TokenResponse } from '../../src/api/schemas'; import { brc20FromInscription } from '../../src/pg/brc20/helpers'; import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store'; -import { InscriptionData } from '../../src/pg/types'; +import { DbLocationTransferType, InscriptionRevealData } from '../../src/pg/types'; import { TestChainhookPayloadBuilder, TestFastifyServer, @@ -86,26 +86,44 @@ describe('BRC-20', () => { }); describe('token standard validation', () => { - const testInsert = (json: any): InscriptionData => { + const testInsert = (json: any): InscriptionRevealData => { const content = Buffer.from(JSON.stringify(json), 'utf-8'); - const insert: InscriptionData = { - genesis_id: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dci0', - number: 0, - classic_number: 0, - mime_type: 'application/json', - content_type: 'application/json', - content_length: content.length, - content: `0x${content.toString('hex')}`, - fee: '200', - curse_type: null, - sat_ordinal: '2000000', - sat_rarity: 'common', - sat_coinbase_height: 110, - recursive: false, - metadata: null, - parent: null, + return { + inscription: { + genesis_id: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dci0', + number: 0, + classic_number: 0, + mime_type: 'application/json', + content_type: 'application/json', + content_length: content.length, + content: `0x${content.toString('hex')}`, + fee: '200', + curse_type: null, + sat_ordinal: '2000000', + sat_rarity: 'common', + sat_coinbase_height: 110, + recursive: false, + metadata: null, + parent: null, + }, + recursive_refs: [], + location: { + genesis_id: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dci0', + block_height: 830000, + block_hash: '00000000000000000002c5c0aba96f981642a6dca109e6b3564925c21a98aa3e', + tx_id: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dc', + tx_index: 0, + address: 'bc1pdjd6q33l0ca9nuudu2hr5qrs9u5dt6nl0z7fvu8kv4y8w4fzdpysc80028', + output: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dc:0', + offset: '0', + prev_output: null, + prev_offset: null, + value: '9999', + transfer_type: DbLocationTransferType.transferred, + block_transfer_index: null, + timestamp: 1091091019, + }, }; - return insert; }; test('ignores incorrect MIME type', () => { @@ -118,29 +136,48 @@ describe('BRC-20', () => { }), 'utf-8' ); - const insert: InscriptionData = { - genesis_id: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dci0', - number: 0, - classic_number: 0, - mime_type: 'foo/bar', - content_type: 'foo/bar;x=1', - content_length: content.length, - content: `0x${content.toString('hex')}`, - fee: '200', - curse_type: null, - sat_ordinal: '2000000', - sat_rarity: 'common', - sat_coinbase_height: 110, - recursive: false, - metadata: null, - parent: null, + const insert: InscriptionRevealData = { + inscription: { + genesis_id: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dci0', + number: 0, + classic_number: 0, + mime_type: 'foo/bar', + content_type: 'foo/bar;x=1', + content_length: content.length, + content: `0x${content.toString('hex')}`, + fee: '200', + curse_type: null, + sat_ordinal: '2000000', + sat_rarity: 'common', + sat_coinbase_height: 110, + recursive: false, + metadata: null, + parent: null, + }, + recursive_refs: [], + location: { + genesis_id: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dci0', + block_height: 830000, + block_hash: '00000000000000000002c5c0aba96f981642a6dca109e6b3564925c21a98aa3e', + tx_id: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dc', + tx_index: 0, + address: 'bc1pdjd6q33l0ca9nuudu2hr5qrs9u5dt6nl0z7fvu8kv4y8w4fzdpysc80028', + output: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dc:0', + offset: '0', + prev_output: null, + prev_offset: null, + value: '9999', + transfer_type: DbLocationTransferType.transferred, + block_transfer_index: null, + timestamp: 1091091019, + }, }; expect(brc20FromInscription(insert)).toBeUndefined(); - insert.content_type = 'application/json'; - insert.mime_type = 'application/json'; + insert.inscription.content_type = 'application/json'; + insert.inscription.mime_type = 'application/json'; expect(brc20FromInscription(insert)).not.toBeUndefined(); - insert.content_type = 'text/plain;charset=utf-8'; - insert.mime_type = 'text/plain'; + insert.inscription.content_type = 'text/plain;charset=utf-8'; + insert.inscription.mime_type = 'text/plain'; expect(brc20FromInscription(insert)).not.toBeUndefined(); }); @@ -149,22 +186,41 @@ describe('BRC-20', () => { '{"p": "brc-20", "op": "deploy", "tick": "PEPE", "max": "21000000"', 'utf-8' ); - const insert: InscriptionData = { - genesis_id: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dci0', - number: 0, - classic_number: 0, - mime_type: 'application/json', - content_type: 'application/json', - content_length: content.length, - content: `0x${content.toString('hex')}`, - fee: '200', - curse_type: null, - sat_ordinal: '2000000', - sat_rarity: 'common', - sat_coinbase_height: 110, - recursive: false, - metadata: null, - parent: null, + const insert: InscriptionRevealData = { + inscription: { + genesis_id: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dci0', + number: 0, + classic_number: 0, + mime_type: 'application/json', + content_type: 'application/json', + content_length: content.length, + content: `0x${content.toString('hex')}`, + fee: '200', + curse_type: null, + sat_ordinal: '2000000', + sat_rarity: 'common', + sat_coinbase_height: 110, + recursive: false, + metadata: null, + parent: null, + }, + recursive_refs: [], + location: { + genesis_id: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dci0', + block_height: 830000, + block_hash: '00000000000000000002c5c0aba96f981642a6dca109e6b3564925c21a98aa3e', + tx_id: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dc', + tx_index: 0, + address: 'bc1pdjd6q33l0ca9nuudu2hr5qrs9u5dt6nl0z7fvu8kv4y8w4fzdpysc80028', + output: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dc:0', + offset: '0', + prev_output: null, + prev_offset: null, + value: '9999', + transfer_type: DbLocationTransferType.transferred, + block_transfer_index: null, + timestamp: 1091091019, + }, }; expect(brc20FromInscription(insert)).toBeUndefined(); });