Skip to content

Commit

Permalink
feat: filter by block hash
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelcr committed Feb 17, 2023
1 parent 56389b5 commit ed73b78
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 9 deletions.
4 changes: 2 additions & 2 deletions migrations/1676395230930_inscriptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ export function up(pgm: MigrationBuilder): void {
notNull: true,
},
block_hash: {
type: 'text',
type: 'bytea',
notNull: true,
},
tx_id: {
type: 'text',
type: 'bytea',
notNull: true,
},
address: {
Expand Down
20 changes: 18 additions & 2 deletions src/api/routes/inscriptions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox';
import { Type } from '@sinclair/typebox';
import { TypeCompiler } from '@sinclair/typebox/compiler';
import { Value } from '@sinclair/typebox/value';
import { FastifyPluginCallback } from 'fastify';
import { Server } from 'http';
Expand All @@ -12,14 +13,19 @@ import {
NotFoundResponse,
OffsetParam,
PaginatedResponse,
BlockHashParam,
} from '../types';
import {
DEFAULT_API_LIMIT,
parseDbInscriptions,
parseDbInscription,
hexToBuffer,
normalizeHashString,
} from '../util/helpers';

const BlockHashParamCType = TypeCompiler.Compile(BlockHashParam);
const BlockHeightParamCType = TypeCompiler.Compile(BlockHeightParam);

export const InscriptionRoutes: FastifyPluginCallback<
Record<never, never>,
Server,
Expand All @@ -33,7 +39,7 @@ export const InscriptionRoutes: FastifyPluginCallback<
description: 'Retrieves inscriptions',
tags: ['Inscriptions'],
querystring: Type.Object({
block_height: Type.Optional(BlockHeightParam),
block: Type.Optional(Type.Union([BlockHashParam, BlockHeightParam])),
address: Type.Optional(BitcoinAddressParam),
offset: Type.Optional(OffsetParam),
limit: Type.Optional(LimitParam),
Expand All @@ -47,7 +53,17 @@ export const InscriptionRoutes: FastifyPluginCallback<
async (request, reply) => {
const limit = request.query.limit ?? DEFAULT_API_LIMIT;
const offset = request.query.offset ?? 0;
const inscriptions = await fastify.db.getInscriptions({ ...request.query, limit, offset });
const blockArg = BlockHashParamCType.Check(request.query.block)
? { block_hash: normalizeHashString(request.query.block) as string }
: BlockHeightParamCType.Check(request.query.block)
? { block_height: request.query.block }
: {};
const inscriptions = await fastify.db.getInscriptions({
...blockArg,
address: request.query.address,
limit,
offset,
});
await reply.send({
limit,
offset,
Expand Down
10 changes: 5 additions & 5 deletions src/api/types.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { Static, TSchema, Type } from '@sinclair/typebox';
import { SatoshiRarity } from './util/ordinal-satoshi';

const BitcoinAddressRegEx = /(bc1|[13])[a-zA-HJ-NP-Z0-9]{25,39}/;
export const BitcoinAddressParam = Type.RegEx(BitcoinAddressRegEx);
export const BitcoinAddressParam = Type.RegEx(/^(bc1|[13])[a-zA-HJ-NP-Z0-9]{25,39}$/);

const InscriptionIdRegEx = /[a-fA-F0-9]{64}i[0-9]+/;
export const InscriptionIdParam = Type.RegEx(InscriptionIdRegEx, {
export const InscriptionIdParam = Type.RegEx(/^[a-fA-F0-9]{64}i[0-9]+$/, {
description: 'Inscription ID',
examples: ['38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dci0'],
});

export const OrdinalParam = Type.Integer();

export const BlockHeightParam = Type.Integer();
export const BlockHeightParam = Type.RegEx(/^[0-9]+$/);

export const BlockHashParam = Type.RegEx(/^(0x)?[0]{8}[a-fA-F0-9]{56}$/);

export const OffsetParam = Type.Integer({ minimum: 0 });

Expand Down
22 changes: 22 additions & 0 deletions src/api/util/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,25 @@ export function hexToBuffer(hex: string): Buffer {
}
return Buffer.from(hex.substring(2), 'hex');
}

export const has0xPrefix = (id: string) => id.substr(0, 2).toLowerCase() === '0x';

/**
* Check if the input is a valid 32-byte hex string. If valid, returns a
* lowercase and 0x-prefixed hex string. If invalid, returns false.
*/
export function normalizeHashString(input: string): string | false {
if (typeof input !== 'string') {
return false;
}
let hashBuffer: Buffer | undefined;
if (input.length === 66 && has0xPrefix(input)) {
hashBuffer = Buffer.from(input.slice(2), 'hex');
} else if (input.length === 64) {
hashBuffer = Buffer.from(input, 'hex');
}
if (hashBuffer === undefined || hashBuffer.length !== 32) {
return false;
}
return `0x${hashBuffer.toString('hex')}`;
}
2 changes: 2 additions & 0 deletions src/pg/pg-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export class PgStore extends BasePgStore {

async getInscriptions(args: {
block_height?: number;
block_hash?: string;
address?: string;
limit: number;
offset: number;
Expand All @@ -80,6 +81,7 @@ export class PgStore extends BasePgStore {
FROM inscriptions
WHERE true
${args.block_height ? this.sql`AND block_height = ${args.block_height}` : this.sql``}
${args.block_hash ? this.sql`AND block_hash = ${args.block_hash}` : this.sql``}
${args.address ? this.sql`AND address = ${args.address}` : this.sql``}
ORDER BY block_height DESC
LIMIT ${args.limit}
Expand Down

0 comments on commit ed73b78

Please sign in to comment.