From 6b3eb2805636dea57701f6a2d4d67067d09b858f Mon Sep 17 00:00:00 2001 From: Dawid Sowa Date: Tue, 7 May 2024 16:47:07 +0200 Subject: [PATCH] feat: add sessionId to CE transport --- .../modules/storage/local-storage.module.ts | 1 + .../connector-extension.module.ts | 49 ++++++++++++++++--- .../transport/connector-extension/subjects.ts | 5 +- .../modules/wallet-request/wallet-request.ts | 3 +- packages/dapp-toolkit/src/schemas/index.ts | 23 +++++++++ 5 files changed, 69 insertions(+), 12 deletions(-) diff --git a/packages/dapp-toolkit/src/modules/storage/local-storage.module.ts b/packages/dapp-toolkit/src/modules/storage/local-storage.module.ts index 2b1c77db..73063d08 100644 --- a/packages/dapp-toolkit/src/modules/storage/local-storage.module.ts +++ b/packages/dapp-toolkit/src/modules/storage/local-storage.module.ts @@ -9,6 +9,7 @@ type PartitionKey = | 'requests' | 'state' | 'connectButton' + | 'connectorExtension' type dAppDefinitionAddress = string export type StorageChange = { diff --git a/packages/dapp-toolkit/src/modules/wallet-request/transport/connector-extension/connector-extension.module.ts b/packages/dapp-toolkit/src/modules/wallet-request/transport/connector-extension/connector-extension.module.ts index 13095e0b..524fedfd 100644 --- a/packages/dapp-toolkit/src/modules/wallet-request/transport/connector-extension/connector-extension.module.ts +++ b/packages/dapp-toolkit/src/modules/wallet-request/transport/connector-extension/connector-extension.module.ts @@ -1,6 +1,6 @@ import { ConnectorExtensionSubjects } from './subjects' -import { Err, Result, ResultAsync, err, ok } from 'neverthrow' +import { Err, Result, ResultAsync, err, ok, okAsync } from 'neverthrow' import { Subject, Subscription, @@ -25,11 +25,13 @@ import { IncomingMessage, MessageLifeCycleExtensionStatusEvent, WalletInteraction, + WalletInteractionExtensionInteraction, WalletInteractionResponse, eventType, } from '../../../../schemas' -import { SdkError } from '../../../../error' import { RequestItemModule } from '../../request-items' +import { StorageModule } from '../../../storage' +import { SdkError } from '../../../../error' import { TransportProvider } from '../../../../_types' export type ConnectorExtensionModule = ReturnType< @@ -42,15 +44,19 @@ export const ConnectorExtensionModule = (input: { extensionDetectionTime?: number providers: { requestItemModule: RequestItemModule + storageModule: StorageModule<{ sessionId?: string }> } }) => { const logger = input?.logger?.getSubLogger({ name: 'ConnectorExtensionModule', }) + const subjects = input?.subjects ?? ConnectorExtensionSubjects() const subscription = new Subscription() const extensionDetectionTime = input?.extensionDetectionTime ?? 100 const requestItemModule = input.providers.requestItemModule + const storage = + input.providers.storageModule.getPartition('connectorExtension') subscription.add( subjects.incomingMessageSubject @@ -87,6 +93,29 @@ export const ConnectorExtensionModule = (input: { .subscribe(), ) + const wrapOutgoingInteraction = ( + interaction: WalletInteraction, + ): ResultAsync => { + return storage.getState().andThen((state) => { + const isAuthorizedRequest = + interaction.items.discriminator === 'authorizedRequest' + + const sessionId = isAuthorizedRequest + ? state?.sessionId || crypto.randomUUID() + : state?.sessionId + + const wrappedRequest = { + interactionId: interaction.interactionId, + interaction, + sessionId, + discriminator: 'walletInteraction' as const, + } + return isAuthorizedRequest + ? storage.setState({ sessionId }).map(() => wrappedRequest) + : okAsync(wrappedRequest) + }) + } + const handleIncomingMessage = (event: Event) => { const message = (event as CustomEvent).detail subjects.incomingMessageSubject.next(message) @@ -134,7 +163,7 @@ export const ConnectorExtensionModule = (input: { const sendCancelRequest = () => { subjects.outgoingMessageSubject.next({ interactionId: walletInteraction.interactionId, - items: { discriminator: 'cancelRequest' }, + discriminator: 'cancelInteraction', metadata: walletInteraction.metadata, }) @@ -200,9 +229,13 @@ export const ConnectorExtensionModule = (input: { filter((value): value is Err => !('eventType' in value)), ) - const sendWalletRequest$ = of(walletInteraction).pipe( - tap((message) => { - subjects.outgoingMessageSubject.next(message) + const sendWalletRequest$ = of( + wrapOutgoingInteraction(walletInteraction), + ).pipe( + tap((result) => { + result.map((message) => { + subjects.outgoingMessageSubject.next(message) + }) }), filter((_): _ is never => false), ) @@ -272,7 +305,9 @@ export const ConnectorExtensionModule = (input: { }), ) }, - disconnect: () => {}, + disconnect: () => { + storage.clear() + }, destroy: () => { subscription.unsubscribe() removeEventListener(eventType.incomingMessage, handleIncomingMessage) diff --git a/packages/dapp-toolkit/src/modules/wallet-request/transport/connector-extension/subjects.ts b/packages/dapp-toolkit/src/modules/wallet-request/transport/connector-extension/subjects.ts index d61ae20a..1ffeed32 100644 --- a/packages/dapp-toolkit/src/modules/wallet-request/transport/connector-extension/subjects.ts +++ b/packages/dapp-toolkit/src/modules/wallet-request/transport/connector-extension/subjects.ts @@ -3,7 +3,6 @@ import type { ExtensionInteraction, MessageLifeCycleEvent, MessageLifeCycleExtensionStatusEvent, - WalletInteraction, WalletInteractionResponse, } from '../../../../schemas' @@ -12,9 +11,7 @@ export type ConnectorExtensionSubjects = ReturnType< > export const ConnectorExtensionSubjects = () => ({ - outgoingMessageSubject: new Subject< - WalletInteraction | ExtensionInteraction - >(), + outgoingMessageSubject: new Subject(), incomingMessageSubject: new Subject< | MessageLifeCycleEvent | MessageLifeCycleExtensionStatusEvent diff --git a/packages/dapp-toolkit/src/modules/wallet-request/wallet-request.ts b/packages/dapp-toolkit/src/modules/wallet-request/wallet-request.ts index b236fd92..db8d4c9d 100644 --- a/packages/dapp-toolkit/src/modules/wallet-request/wallet-request.ts +++ b/packages/dapp-toolkit/src/modules/wallet-request/wallet-request.ts @@ -92,7 +92,7 @@ export const WalletRequestModule = (input: { const transports: TransportProvider[] = input.providers.transports ?? [ ConnectorExtensionModule({ logger, - providers: { requestItemModule }, + providers: { requestItemModule, storageModule }, }), ] @@ -581,6 +581,7 @@ export const WalletRequestModule = (input: { stateModule.reset() requestItemModule.clear() + transports.forEach((transport) => transport?.disconnect()) } const destroy = () => { diff --git a/packages/dapp-toolkit/src/schemas/index.ts b/packages/dapp-toolkit/src/schemas/index.ts index caf996d3..df2a5429 100644 --- a/packages/dapp-toolkit/src/schemas/index.ts +++ b/packages/dapp-toolkit/src/schemas/index.ts @@ -381,9 +381,32 @@ export type OpenPopupExtensionInteraction = Output< typeof OpenPopupExtensionInteraction > +export type WalletInteractionExtensionInteraction = Output< + typeof WalletInteractionExtensionInteraction +> + +export const WalletInteractionExtensionInteraction = object({ + interactionId: string(), + discriminator: literal('walletInteraction'), + interaction: WalletInteraction, + sessionId: optional(string()), +}) + +export type CancelInteractionExtensionInteraction = Output< + typeof CancelInteractionExtensionInteraction +> + +export const CancelInteractionExtensionInteraction = object({ + interactionId: string(), + discriminator: literal('cancelInteraction'), + metadata: Metadata, +}) + export const ExtensionInteraction = union([ StatusExtensionInteraction, OpenPopupExtensionInteraction, + WalletInteractionExtensionInteraction, + CancelInteractionExtensionInteraction, ]) export type ExtensionInteraction = Output