diff --git a/src/api/routes/inscriptions.ts b/src/api/routes/inscriptions.ts index c088b812..fc185a06 100644 --- a/src/api/routes/inscriptions.ts +++ b/src/api/routes/inscriptions.ts @@ -25,6 +25,7 @@ import { BlockHeightParam, TimestampParam, OrdinalParam, + InscriptionNumberParam, } from '../schemas'; import { handleChainTipCache, handleInscriptionCache } from '../util/cache'; import { @@ -75,6 +76,8 @@ const IndexRoutes: FastifyPluginCallback, Server, TypeBoxTy to_sat_ordinal: Type.Optional(OrdinalParam), from_sat_coinbase_height: Type.Optional(BlockHeightParam), to_sat_coinbase_height: Type.Optional(BlockHeightParam), + from_number: Type.Optional(InscriptionNumberParam), + to_number: Type.Optional(InscriptionNumberParam), output: Type.Optional(OutputParam), address: Type.Optional(AddressParam), mime_type: Type.Optional(MimeTypesParam), @@ -105,6 +108,8 @@ const IndexRoutes: FastifyPluginCallback, Server, TypeBoxTy to_genesis_timestamp: request.query.to_genesis_timestamp, from_sat_ordinal: bigIntParam(request.query.from_sat_ordinal), to_sat_ordinal: bigIntParam(request.query.to_sat_ordinal), + from_number: request.query.from_number, + to_number: request.query.to_number, output: request.query.output, address: request.query.address, mime_type: request.query.mime_type, diff --git a/src/pg/pg-store.ts b/src/pg/pg-store.ts index c9e0a5b4..3aab5bd7 100644 --- a/src/pg/pg-store.ts +++ b/src/pg/pg-store.ts @@ -165,6 +165,8 @@ export class PgStore extends BasePgStore { from_sat_coinbase_height?: number; to_sat_coinbase_height?: number; number?: number; + from_number?: number; + to_number?: number; address?: string; mime_type?: string[]; output?: string; @@ -252,6 +254,8 @@ export class PgStore extends BasePgStore { args.to_sat_ordinal ? this.sql`AND loc.sat_ordinal <= ${args.to_sat_ordinal}` : this.sql`` } ${args.number ? this.sql`AND i.number = ${args.number}` : this.sql``} + ${args.from_number ? this.sql`AND i.number >= ${args.from_number}` : this.sql``} + ${args.to_number ? this.sql`AND i.number <= ${args.to_number}` : this.sql``} ${args.address ? this.sql`AND loc.address = ${args.address}` : this.sql``} ${ args.mime_type?.length diff --git a/tests/inscriptions.test.ts b/tests/inscriptions.test.ts index fcd6dade..dd20fdae 100644 --- a/tests/inscriptions.test.ts +++ b/tests/inscriptions.test.ts @@ -704,6 +704,81 @@ describe('/inscriptions', () => { expect(responseJson3.results[0].sat_coinbase_height).toBe(650000); }); + test('index filtered by inscription number range', async () => { + await db.insertInscriptionGenesis({ + inscription: { + genesis_id: '9f4a9b73b0713c5da01c0a47f97c6c001af9028d6bdd9e264dfacbc4e6790201i0', + mime_type: 'text/plain', + content_type: 'text/plain;charset=utf-8', + content_length: 5, + number: 7, + content: '0x48656C6C6F', + fee: 705n, + }, + location: { + inscription_id: 0, + block_height: 778575, + block_hash: '00000000000000000002a90330a99f67e3f01eb2ce070b45930581e82fb7a91d', + tx_id: '9f4a9b73b0713c5da01c0a47f97c6c001af9028d6bdd9e264dfacbc4e6790201', + address: 'bc1pscktlmn99gyzlvymvrezh6vwd0l4kg06tg5rvssw0czg8873gz5sdkteqj', + output: '9f4a9b73b0713c5da01c0a47f97c6c001af9028d6bdd9e264dfacbc4e6790201:0', + offset: 0n, + value: 10000n, + timestamp: 1677731361, + sat_ordinal: 257418248345364n, + sat_rarity: 'common', + sat_coinbase_height: 650000, + genesis: true, + current: true, + }, + }); + await db.insertInscriptionGenesis({ + inscription: { + genesis_id: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dci0', + mime_type: 'image/png', + content_type: 'image/png', + content_length: 5, + number: 50, + content: '0x48656C6C6F', + fee: 2805n, + }, + location: { + inscription_id: 0, + block_height: 775617, + block_hash: '00000000000000000002a90330a99f67e3f01eb2ce070b45930581e82fb7a91d', + tx_id: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dc', + address: 'bc1p3cyx5e2hgh53w7kpxcvm8s4kkega9gv5wfw7c4qxsvxl0u8x834qf0u2td', + output: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dc:0', + offset: 0n, + value: 10000n, + timestamp: 1675312161, + sat_ordinal: 1000000000000n, + sat_rarity: 'epic', + sat_coinbase_height: 750000, + genesis: true, + current: true, + }, + }); + + const response2 = await fastify.inject({ + method: 'GET', + url: '/ordinals/v1/inscriptions?from_number=10', + }); + expect(response2.statusCode).toBe(200); + const responseJson2 = response2.json(); + expect(responseJson2.total).toBe(1); + expect(responseJson2.results[0].number).toBe(50); + + const response3 = await fastify.inject({ + method: 'GET', + url: '/ordinals/v1/inscriptions?to_number=10', + }); + expect(response3.statusCode).toBe(200); + const responseJson3 = response3.json(); + expect(responseJson3.total).toBe(1); + expect(responseJson3.results[0].number).toBe(7); + }); + test('index filtered by output', async () => { await db.insertInscriptionGenesis({ inscription: {