From dfc48021acbbd19baea6e658064ff713fcab8b6a Mon Sep 17 00:00:00 2001 From: Hermi Date: Wed, 16 Jul 2025 00:34:54 +0800 Subject: [PATCH] feat: enhance Block type and update SyncClient methods to include nativeBytes --- src/cardano.ts | 26 ++++++++++++++++++++------ src/index.ts | 1 + test/index.test.mts | 24 +++++++++++++++++------- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/cardano.ts b/src/cardano.ts index fa02ed8..4025660 100644 --- a/src/cardano.ts +++ b/src/cardano.ts @@ -34,6 +34,10 @@ export type TxEvent = GenericTxEvent; export type MempoolEvent = GenericTxInMempoolEvent; export type TxHash = Uint8Array; export type TxCbor = Uint8Array; +export type Block = { + parsedBlock: cardano.Block; + nativeBytes: Uint8Array; +}; function toMempoolEvent(txInMempool: submit.TxInMempool): MempoolEvent { return { @@ -60,6 +64,16 @@ function anyChainToBlock(msg: sync.AnyChainBlock) { return msg.chain.case == "cardano" ? msg.chain.value : null; } +function anyChainToBlockWithBytes(msg: sync.AnyChainBlock): Block | null { + if (msg.chain.case == "cardano") { + return { + parsedBlock: msg.chain.value, + nativeBytes: msg.nativeBytes + }; + } + return null; +} + function pointToBlockRef(p: ChainPoint) { return new sync.BlockRef({ index: BigInt(p.slot), @@ -146,13 +160,13 @@ export class SyncClient { return blockRefToPoint(res.tip!); } - async fetchBlock(p: ChainPoint): Promise { + async fetchBlock(p: ChainPoint): Promise { const req = pointToBlockRef(p); const res = await this.inner.fetchBlock({ ref: [req] }); - return anyChainToBlock(res.block[0])!; + return anyChainToBlockWithBytes(res.block[0])!; } - async fetchHistory(p: ChainPoint | undefined, maxItems = 1): Promise { + async fetchHistory(p: ChainPoint | undefined, maxItems = 1): Promise { const req = new sync.DumpHistoryRequest({ startToken: p ? new sync.BlockRef({ index: BigInt(p.slot), @@ -167,9 +181,9 @@ export class SyncClient { throw new Error("No block history found for the provided ChainPoint."); } - const block = anyChainToBlock(res.block[0]); - - return block!; + return res.block + .map(anyChainToBlockWithBytes) + .filter((block): block is Block => block !== null); } } diff --git a/src/index.ts b/src/index.ts index ab62f88..35167f7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,6 +4,7 @@ export { SubmitClient as CardanoSubmitClient, WatchClient as CardanoWatchClient, ChainPoint as CardanoChainPoint, + Block as CardanoBlock, Utxo as CardanoUtxo, TipEvent as CardanoTipEvent, TxEvent as CardanoTxEvent, diff --git a/test/index.test.mts b/test/index.test.mts index 017a37c..caf2def 100644 --- a/test/index.test.mts +++ b/test/index.test.mts @@ -429,14 +429,17 @@ describe("SyncClient", () => { expect(tip.hash.length).toBeGreaterThan(0); }); test("fetchBlock", async () => { - const block = await syncClient.fetchBlock({ + const blockWithBytes = await syncClient.fetchBlock({ slot: 85213090, hash: 'e50842b1cc3ac813cb88d1533c3dea0f92e0ea945f53487c1d960c2210d0c3ba', }); + expect(blockWithBytes.nativeBytes).toBeInstanceOf(Uint8Array); + expect(blockWithBytes.nativeBytes.length).toBeGreaterThan(0); + expect({ - body: block.body?.toJson(), - header: block.header?.toJson() + body: blockWithBytes.parsedBlock.body?.toJson(), + header: blockWithBytes.parsedBlock.header?.toJson() }).toEqual({ body: {}, header: { @@ -447,14 +450,21 @@ describe("SyncClient", () => { }); }); test("fetchHistory", async () => { - const block = await syncClient.fetchHistory({ + const blocks = await syncClient.fetchHistory({ slot: 85213090, hash: 'e50842b1cc3ac813cb88d1533c3dea0f92e0ea945f53487c1d960c2210d0c3ba', - }); + }, 1); + + expect(Array.isArray(blocks)).toBe(true); + expect(blocks.length).toBe(1); + + const firstBlock = blocks[0]; + expect(firstBlock.nativeBytes).toBeInstanceOf(Uint8Array); + expect(firstBlock.nativeBytes.length).toBeGreaterThan(0); expect({ - body: block.body?.toJson(), - header: block.header?.toJson() + body: firstBlock.parsedBlock.body?.toJson(), + header: firstBlock.parsedBlock.header?.toJson() }).toEqual({ body: {}, header: {