diff --git a/package.json b/package.json index 4699e1f07..5b6087857 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "./packages/*" ], "scripts": { - "build": "lerna run build", + "build": "lerna run build --stream", "start": "npm run build && lerna run start --parallel", "test": "jest", "release": "npm run build && npm run changeset publish", diff --git a/packages/transport-http/src/subscribe/handlers/account-statuses.ts b/packages/transport-http/src/subscribe/handlers/account-statuses.ts new file mode 100644 index 000000000..74f8763af --- /dev/null +++ b/packages/transport-http/src/subscribe/handlers/account-statuses.ts @@ -0,0 +1,104 @@ +import {SdkTransport} from "@onflow/typedefs" +import {createSubscriptionHandler} from "./types" +import {EventsArgsDto} from "./events" + +type AccountStatusesArgs = + SdkTransport.SubscriptionArguments + +type AccountStatusesData = + SdkTransport.SubscriptionData + +type AccountStatusesArgsDto = EventsArgsDto + +type AccountStatusesDataDto = { + // TODO: We do not know the data model types yet + account_status: { + block_id: string + height: number + account_events: { + block_id: string + block_height: number + block_timestamp: string + type: string + transaction_id: string + transaction_index: number + event_index: number + payload: string + }[] + } +} + +export const accountStatusesHandler = createSubscriptionHandler<{ + Topic: SdkTransport.SubscriptionTopic.ACCOUNT_STATUSES + Args: SdkTransport.SubscriptionArguments + Data: SdkTransport.SubscriptionData + ArgsDto: AccountStatusesArgsDto + DataDto: AccountStatusesDataDto +}>({ + topic: SdkTransport.SubscriptionTopic.ACCOUNT_STATUSES, + createSubscriber: (initialArgs, onData, onError) => { + let resumeArgs: AccountStatusesArgs = { + ...initialArgs, + } + + return { + onData(data: AccountStatusesDataDto) { + // Parse the raw data + const parsedData: AccountStatusesData = { + accountStatus: { + blockId: data.account_status.block_id, + height: data.account_status.height, + accountEvents: data.account_status.account_events.map(event => ({ + blockId: event.block_id, + blockHeight: event.block_height, + blockTimestamp: event.block_timestamp, + type: event.type, + transactionId: event.transaction_id, + transactionIndex: event.transaction_index, + eventIndex: event.event_index, + payload: event.payload, + })), + }, + } + + // Update the resume args + resumeArgs = { + ...resumeArgs, + startBlockHeight: data.account_status.height + 1, + startBlockId: undefined, + } + + onData(parsedData) + }, + onError(error: Error) { + onError(error) + }, + argsToDto(args: AccountStatusesArgs) { + let encodedArgs: AccountStatusesArgsDto = { + event_types: args.filter?.eventTypes, + addresses: args.filter?.addresses, + contracts: args.filter?.contracts, + } + + 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/subscribe.ts b/packages/transport-http/src/subscribe/subscribe.ts index 18265e894..cd12d6548 100644 --- a/packages/transport-http/src/subscribe/subscribe.ts +++ b/packages/transport-http/src/subscribe/subscribe.ts @@ -3,11 +3,13 @@ import {SubscriptionManager} from "./subscription-manager" import {blocksHandler} from "./handlers/blocks" import {blockDigestsHandler} from "./handlers/block-digests" import {eventsHandler} from "./handlers/events" +import {accountStatusesHandler} from "./handlers/account-statuses" const SUBSCRIPTION_HANDLERS = [ blocksHandler, blockDigestsHandler, eventsHandler, + accountStatusesHandler, ] // Map of SubscriptionManager instances by access node URL diff --git a/packages/typedefs/src/index.ts b/packages/typedefs/src/index.ts index 8a6728d8e..d2b8f4a59 100644 --- a/packages/typedefs/src/index.ts +++ b/packages/typedefs/src/index.ts @@ -437,6 +437,7 @@ export type NodeVersionInfo = { */ nodeRootBlockHeight: number } + export interface StreamConnection { on( channel: C, diff --git a/packages/typedefs/src/sdk-transport/subscriptions.ts b/packages/typedefs/src/sdk-transport/subscriptions.ts index 2530c30ba..a7a1ac455 100644 --- a/packages/typedefs/src/sdk-transport/subscriptions.ts +++ b/packages/typedefs/src/sdk-transport/subscriptions.ts @@ -13,6 +13,29 @@ export type SubscriptionSchema = { blockDigest: BlockDigest } > + [SubscriptionTopic.ACCOUNT_STATUSES]: SchemaItem< + ( + | { + startBlockId: string + } + | { + startBlockHeight: number + } + | {} + ) & { + filter: EventFilter + }, + { + // TODO: We do not know the data model types yet + accountStatus: { + blockId: string + height: number + accountEvents: (Omit & { + payload: string + })[] + } + } + > [SubscriptionTopic.EVENTS]: SchemaItem< // TODO: We do not know the data model types yet ( @@ -37,6 +60,7 @@ export type SubscriptionSchema = { export enum SubscriptionTopic { BLOCKS = "blocks", BLOCK_DIGESTS = "block_digests", + ACCOUNT_STATUSES = "account_statuses", EVENTS = "events", }