diff --git a/lib/IO/schemas.ts b/lib/IO/schemas.ts index 903572b..1f416dd 100644 --- a/lib/IO/schemas.ts +++ b/lib/IO/schemas.ts @@ -318,16 +318,35 @@ export const WalletInteractionResponse = union([ WalletInteractionFailureResponse, ]) +export const ExtensionInteraction = object({ + interactionId: string(), + discriminator: literal('extensionStatus'), +}) + +export type ExtensionInteraction = z.infer + export const messageLifeCycleEventType = { + extensionStatus: 'extensionStatus', receivedByExtension: 'receivedByExtension', receivedByWallet: 'receivedByWallet', requestCancelSuccess: 'requestCancelSuccess', requestCancelFail: 'requestCancelFail', } as const -export type MessageLifeCycleEvent = z.infer +export const MessageLifeCycleExtensionStatusEvent = object({ + eventType: literal(messageLifeCycleEventType.extensionStatus), + interactionId: string(), + isWalletLinked: boolean(), + isExtensionAvailable: boolean(), +}) + +export type MessageLifeCycleExtensionStatusEvent = z.infer< + typeof MessageLifeCycleExtensionStatusEvent +> + export const MessageLifeCycleEvent = object({ eventType: union([ + literal(messageLifeCycleEventType.extensionStatus), literal(messageLifeCycleEventType.receivedByExtension), literal(messageLifeCycleEventType.receivedByWallet), literal(messageLifeCycleEventType.requestCancelSuccess), @@ -336,6 +355,8 @@ export const MessageLifeCycleEvent = object({ interactionId: string(), }) +export type MessageLifeCycleEvent = z.infer + export type IncomingMessage = z.infer const IncomingMessage = union([ MessageLifeCycleEvent, diff --git a/lib/connector-extension/connector-extension-client.ts b/lib/connector-extension/connector-extension-client.ts index d1891b3..dceb753 100644 --- a/lib/connector-extension/connector-extension-client.ts +++ b/lib/connector-extension/connector-extension-client.ts @@ -3,6 +3,7 @@ import { AppLogger } from '../helpers/logger' import { CallbackFns, IncomingMessage, + MessageLifeCycleExtensionStatusEvent, WalletInteraction, WalletInteractionSuccessResponse, eventType, @@ -18,7 +19,9 @@ import { map, merge, of, + race, share, + switchMap, takeUntil, tap, timer, @@ -191,11 +194,44 @@ export const ConnectorExtensionClient = ( ) } + const extensionStatusEvent$ = subjects.messageLifeCycleEventSubject.pipe( + filter( + (event): event is MessageLifeCycleExtensionStatusEvent => + event.eventType === 'extensionStatus' + ) + ) + return { send: sendWalletInteraction, destroy: () => { subscription.unsubscribe() removeEventListener(eventType.incomingMessage, handleIncomingMessage) }, + extensionStatus$: of(true).pipe( + tap(() => { + subjects.outgoingMessageSubject.next({ + interactionId: crypto.randomUUID(), + discriminator: 'extensionStatus', + }) + }), + switchMap(() => + race( + extensionStatusEvent$, + merge( + extensionStatusEvent$, + timer(config.extensionDetectionTime).pipe( + map( + () => + ({ + eventType: 'extensionStatus', + isWalletLinked: false, + isExtensionAvailable: false, + } as MessageLifeCycleExtensionStatusEvent) + ) + ) + ) + ) + ) + ), } } diff --git a/lib/connector-extension/subjects.ts b/lib/connector-extension/subjects.ts index 894ba06..26b236c 100644 --- a/lib/connector-extension/subjects.ts +++ b/lib/connector-extension/subjects.ts @@ -1,6 +1,8 @@ import { Subject } from 'rxjs' import { + ExtensionInteraction, MessageLifeCycleEvent, + MessageLifeCycleExtensionStatusEvent, WalletInteraction, WalletInteractionResponse, } from '../IO/schemas' @@ -8,9 +10,13 @@ import { export type Subjects = ReturnType export const Subjects = () => ({ - outgoingMessageSubject: new Subject(), + outgoingMessageSubject: new Subject< + WalletInteraction | ExtensionInteraction + >(), incomingMessageSubject: new Subject< - MessageLifeCycleEvent | WalletInteractionResponse + | MessageLifeCycleEvent + | MessageLifeCycleExtensionStatusEvent + | WalletInteractionResponse >(), responseSubject: new Subject(), messageLifeCycleEventSubject: new Subject(), diff --git a/lib/create-methods.ts b/lib/create-methods.ts index 4eade39..0400768 100644 --- a/lib/create-methods.ts +++ b/lib/create-methods.ts @@ -51,5 +51,6 @@ export const createMethods = ( return { request, sendTransaction, + extensionStatus$: connectorExtensionClient.extensionStatus$, } }