diff --git a/packages/transport-http/src/subscribe/handlers/block-digests.ts b/packages/transport-http/src/subscribe/handlers/block-digests.ts new file mode 100644 index 000000000..e9481be62 --- /dev/null +++ b/packages/transport-http/src/subscribe/handlers/block-digests.ts @@ -0,0 +1,82 @@ +import {SdkTransport} from "@onflow/typedefs" +import {BlockArgsModel, createSubscriptionHandler} from "./types" + +type BlockDigestsArgs = + SdkTransport.SubscriptionArguments + +type BlockDigestsData = + SdkTransport.SubscriptionData + +type BlockDigestsDataDto = { + // TODO: We do not know the data model types yet + block_digest: { + id: string + height: number + timestamp: string + } +} + +type BlockDigestsArgsDto = BlockArgsModel + +export const blockDigestsHandler = createSubscriptionHandler<{ + Topic: SdkTransport.SubscriptionTopic.BLOCK_DIGESTS + Args: BlockDigestsArgs + Data: BlockDigestsData + ArgsDto: BlockDigestsArgsDto + DataDto: BlockDigestsDataDto +}>({ + topic: SdkTransport.SubscriptionTopic.BLOCK_DIGESTS, + createSubscriber: (initialArgs, onData, onError) => { + let resumeArgs: BlockDigestsArgs = { + ...initialArgs, + } + + return { + onData(data: BlockDigestsDataDto) { + // Parse the raw data + const parsedData: BlockDigestsData = { + blockDigest: { + id: data.block_digest.id, + height: data.block_digest.height, + timestamp: data.block_digest.timestamp, + }, + } + + // Update the resume args + resumeArgs = { + blockStatus: resumeArgs.blockStatus, + startBlockId: data.block_digest.id + 1, + } + + onData(parsedData) + }, + onError(error: Error) { + onError(error) + }, + argsToDto(args: BlockDigestsArgs) { + let encodedArgs: BlockDigestsArgsDto = { + block_status: args.blockStatus, + } + + if ("startBlockHeight" in args) { + return { + ...encodedArgs, + start_block_height: args.startBlockHeight, + } + } + + if ("startBlockId" in args) { + return { + ...encodedArgs, + start_block_id: args.startBlockId, + } + } + + return encodedArgs + }, + get connectionArgs() { + return resumeArgs + }, + } + }, +}) diff --git a/packages/transport-http/src/subscribe/handlers/blocks.ts b/packages/transport-http/src/subscribe/handlers/blocks.ts index 5ab96627c..ca9b405ec 100644 --- a/packages/transport-http/src/subscribe/handlers/blocks.ts +++ b/packages/transport-http/src/subscribe/handlers/blocks.ts @@ -1,5 +1,5 @@ import {SdkTransport} from "@onflow/typedefs" -import {createSubscriptionHandler} from "./types" +import {createSubscriptionHandler, BlockArgsModel} from "./types" type BlocksArgs = SdkTransport.SubscriptionArguments diff --git a/packages/transport-http/src/subscribe/handlers/types.ts b/packages/transport-http/src/subscribe/handlers/types.ts index 939b6c59f..098d67e8d 100644 --- a/packages/transport-http/src/subscribe/handlers/types.ts +++ b/packages/transport-http/src/subscribe/handlers/types.ts @@ -48,3 +48,13 @@ export function createSubscriptionHandler< >(handler: SubscriptionHandler): SubscriptionHandler { return handler } + +export type BlockArgsModel = + | { + block_status?: number + start_block_id?: string + } + | { + block_status?: number + start_block_height?: number + } diff --git a/packages/transport-http/src/subscribe/subscribe.ts b/packages/transport-http/src/subscribe/subscribe.ts index 3daf07823..cebf511bd 100644 --- a/packages/transport-http/src/subscribe/subscribe.ts +++ b/packages/transport-http/src/subscribe/subscribe.ts @@ -1,8 +1,9 @@ import {SdkTransport} from "@onflow/typedefs" import {SubscriptionManager} from "./subscription-manager" import {blocksHandler} from "./handlers/blocks" +import {blockDigestsHandler} from "./handlers/block-digests" -const SUBSCRIPTION_HANDLERS = [blocksHandler] +const SUBSCRIPTION_HANDLERS = [blocksHandler, blockDigestsHandler] // Map of SubscriptionManager instances by access node URL let subscriptionManagerMap: Map< diff --git a/packages/typedefs/src/index.ts b/packages/typedefs/src/index.ts index 4f92c10f9..8a6728d8e 100644 --- a/packages/typedefs/src/index.ts +++ b/packages/typedefs/src/index.ts @@ -120,6 +120,23 @@ export type BlockSeal = { */ executionReceiptId: string } +/** + * BlockDigest holds lightweight block information which includes only block id, block height and block timestamp. + */ +export type BlockDigest = { + /** + * - The id of the block + */ + id: string + /** + * - The height of the block + */ + height: number + /** + * - Timestamp of the block + */ + timestamp: string +} export type CompositeSignature = { /** * - A type identifier used internally by FCL diff --git a/packages/typedefs/src/sdk-transport/subscriptions.ts b/packages/typedefs/src/sdk-transport/subscriptions.ts index d80c6a367..b0ecf2f15 100644 --- a/packages/typedefs/src/sdk-transport/subscriptions.ts +++ b/packages/typedefs/src/sdk-transport/subscriptions.ts @@ -1,28 +1,38 @@ -import {Block} from ".." +import {Block, BlockDigest} from ".." -type SchemaItem = { - args: TArgs - data: TData +export type SubscriptionSchema = { + [SubscriptionTopic.BLOCKS]: SchemaItem< + BlockArgs, + { + block: Block + } + > + [SubscriptionTopic.BLOCK_DIGESTS]: SchemaItem< + BlockArgs, + { + blockDigest: BlockDigest + } + > } export enum SubscriptionTopic { BLOCKS = "blocks", + BLOCK_DIGESTS = "block_digests", } -export type SubscriptionSchema = { - [SubscriptionTopic.BLOCKS]: SchemaItem< - | { - blockStatus?: number - startBlockId?: string - } - | { - blockStatus?: number - startBlockHeight?: number - }, - { - block: Block +type BlockArgs = + | { + blockStatus?: number + startBlockId?: string } - > + | { + blockStatus?: number + startBlockHeight?: number + } + +type SchemaItem = { + args: TArgs + data: TData } export type SubscriptionArguments =