Skip to content

Commit

Permalink
feat: add sessionId to CE transport
Browse files Browse the repository at this point in the history
  • Loading branch information
dawidsowardx committed May 8, 2024
1 parent 6a1d2f4 commit 4419424
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type PartitionKey =
| 'requests'
| 'state'
| 'connectButton'
| 'connectorExtension'
type dAppDefinitionAddress = string

export type StorageChange<T> = {
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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<
Expand All @@ -42,15 +44,20 @@ export const ConnectorExtensionModule = (input: {
extensionDetectionTime?: number
providers: {
requestItemModule: RequestItemModule
storageModule: StorageModule<{ sessionId?: string }>
}
}) => {
let isExtensionHandlingSessions = false
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
Expand Down Expand Up @@ -87,6 +94,35 @@ export const ConnectorExtensionModule = (input: {
.subscribe(),
)

const wrapOutgoingInteraction = (
interaction: WalletInteraction,
): ResultAsync<
WalletInteractionExtensionInteraction | WalletInteraction,
Error
> => {
if (!isExtensionHandlingSessions) {
return okAsync(interaction)
}
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<IncomingMessage>).detail
subjects.incomingMessageSubject.next(message)
Expand Down Expand Up @@ -134,8 +170,10 @@ export const ConnectorExtensionModule = (input: {
const sendCancelRequest = () => {
subjects.outgoingMessageSubject.next({
interactionId: walletInteraction.interactionId,
items: { discriminator: 'cancelRequest' },
metadata: walletInteraction.metadata,
...(isExtensionHandlingSessions
? { discriminator: 'cancelInteraction' }
: { items: { discriminator: 'cancelRequest' } }),
})

setTimeout(() => {
Expand Down Expand Up @@ -200,9 +238,13 @@ export const ConnectorExtensionModule = (input: {
filter((value): value is Err<never, SdkError> => !('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),
)
Expand Down Expand Up @@ -246,12 +288,16 @@ export const ConnectorExtensionModule = (input: {
eventType: 'extensionStatus',
isWalletLinked: false,
isExtensionAvailable: false,
canHandleSessions: false,
}) as MessageLifeCycleExtensionStatusEvent,
),
),
),
),
),
tap((event) => {
isExtensionHandlingSessions = event.canHandleSessions || false
}),
shareReplay(1),
)

Expand All @@ -272,7 +318,9 @@ export const ConnectorExtensionModule = (input: {
}),
)
},
disconnect: () => {},
disconnect: () => {
storage.clear()
},
destroy: () => {
subscription.unsubscribe()
removeEventListener(eventType.incomingMessage, handleIncomingMessage)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export const WalletRequestModule = (input: {
const transports: TransportProvider[] = input.providers.transports ?? [
ConnectorExtensionModule({
logger,
providers: { requestItemModule },
providers: { requestItemModule, storageModule },
}),
]

Expand Down Expand Up @@ -581,6 +581,7 @@ export const WalletRequestModule = (input: {

stateModule.reset()
requestItemModule.clear()
transports.forEach((transport) => transport?.disconnect())
}

const destroy = () => {
Expand Down
24 changes: 24 additions & 0 deletions packages/dapp-toolkit/src/schemas/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<typeof ExtensionInteraction>
Expand All @@ -401,6 +424,7 @@ export const MessageLifeCycleExtensionStatusEvent = object({
interactionId: string(),
isWalletLinked: boolean(),
isExtensionAvailable: boolean(),
canHandleSessions: optional(boolean()),
})

export type MessageLifeCycleExtensionStatusEvent = Output<
Expand Down

0 comments on commit 4419424

Please sign in to comment.