Skip to content

Commit

Permalink
feat: add request interceptor
Browse files Browse the repository at this point in the history
  • Loading branch information
xstelea committed Sep 26, 2023
1 parent 77bb2e1 commit 2b331e8
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 45 deletions.
3 changes: 2 additions & 1 deletion examples/rdt/rdt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
DataRequestBuilder,
DataRequestStateClient,
RadixDappToolkit,
RadixDappToolkitOptions,
} from '../../src'
import { appLogger } from '../logger/state'
import {
Expand Down Expand Up @@ -98,7 +99,7 @@ const options = {
dataRequestStateClient,
},
useCache: false,
}
} satisfies RadixDappToolkitOptions

setTimeout(() => {
appLogger.debug('RDT initialized with', options)
Expand Down
37 changes: 34 additions & 3 deletions src/_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,26 @@ export type ExplorerConfig = {
accountsPath: string
}

type WalletDataRequest = Parameters<WalletSdk['request']>[0]

export type WalletRequest =
| { type: 'sendTransaction'; payload: SendTransactionInput }
| { type: 'dataRequest'; payload: WalletDataRequest }

export type RequestInterceptor = <T extends WalletRequest>(
input: T
) => Promise<T['payload']>

export type OptionalRadixDappToolkitOptions = {
logger: AppLogger
onDisconnect: () => void

explorer: ExplorerConfig
gatewayBaseUrl: string
applicationName: string
applicationVersion: string
useCache: boolean
providers: Partial<Providers>
requestInterceptor: RequestInterceptor
}

export type RadixDappToolkitOptions = {
Expand All @@ -106,6 +116,7 @@ export type SendTransactionResult = ResultAsync<
},
{
error: string
jsError?: unknown
message?: string
transactionIntentHash?: string
status?: TransactionStatus
Expand All @@ -132,14 +143,20 @@ export type ButtonApi = {
status$: Observable<RadixButtonStatus>
}

export type WalletDataRequestError = {
error: string
message?: string
jsError?: unknown
}

export type WalletDataRequestResult = ResultAsync<
WalletData,
{ error: string; message?: string }
WalletDataRequestError
>

export type AwaitedWalletDataRequestResult = Result<
WalletData,
{ error: string; message?: string }
WalletDataRequestError
>

export type WalletApi = {
Expand Down Expand Up @@ -179,3 +196,17 @@ export type WalletDataState = {
proofs: SignedChallenge[]
persona?: Persona
}

export type RequestInterceptorFactoryOutput = ReturnType<
typeof requestInterceptorFactory
>
export const requestInterceptorFactory =
(requestInterceptor: RequestInterceptor) =>
<T extends WalletRequest>(walletRequest: T) =>
ResultAsync.fromPromise(
requestInterceptor<T>(walletRequest),
(jsError) => ({
error: 'requestInterceptorError',
jsError,
})
)
92 changes: 52 additions & 40 deletions src/data-request/data-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { DataRequestStateClient } from './data-request-state'
import { WalletData } from '../state/types'
import {
AwaitedWalletDataRequestResult,
RequestInterceptorFactoryOutput,
WalletDataRequestResult,
} from '../_types'

Expand All @@ -25,12 +26,14 @@ export const DataRequestClient = ({
walletClient,
useCache,
dataRequestStateClient,
requestInterceptor,
}: {
stateClient: StateClient
requestItemClient: RequestItemClient
walletClient: WalletClient
dataRequestStateClient: DataRequestStateClient
useCache: boolean
requestInterceptor: RequestInterceptorFactoryOutput
}) => {
let challengeGenerator:
| (() => ResultAsync<string, { error: string; message: string }>)
Expand Down Expand Up @@ -121,50 +124,59 @@ export const DataRequestClient = ({
!stateClient.getState().walletData.persona &&
walletDataRequest.discriminator === 'authorizedRequest'

const { id } = requestItemClient.add(
isLoginRequest ? 'loginRequest' : 'dataRequest'
)
return walletClient
.request(walletDataRequest, id)
.mapErr(
({ error, message }): { error: string; message?: string } => ({
error: error,
message: message,
})
)
.andThen(transformWalletResponseToRdtWalletData)
.andThen((response) => {
if (dataRequestControl)
return dataRequestControl(response)
.map(() => {
requestItemClient.updateStatus({ id, status: 'success' })
return response
return requestInterceptor({
type: 'dataRequest',
payload: walletDataRequest,
})
.map((walletDataRequest) => {
const { id } = requestItemClient.add(
isLoginRequest ? 'loginRequest' : 'dataRequest'
)
return { walletDataRequest, id }
})
.andThen(({ walletDataRequest, id }) =>
walletClient
.request(walletDataRequest, id)
.mapErr(
({ error, message }): { error: string; message?: string } => ({
error: error,
message: message,
})
.mapErr((error) => {
requestItemClient.updateStatus({
id,
status: 'fail',
error: error.error,
)
.andThen(transformWalletResponseToRdtWalletData)
.andThen((response) => {
if (dataRequestControl)
return dataRequestControl(response)
.map(() => {
requestItemClient.updateStatus({ id, status: 'success' })
return response
})
.mapErr((error) => {
requestItemClient.updateStatus({
id,
status: 'fail',
error: error.error,
})
return error
})

requestItemClient.updateStatus({ id, status: 'success' })
return ok(response)
})
.map((walletData) => {
if (!oneTime)
stateClient.setState({
loggedInTimestamp: Date.now().toString(),
walletData,
sharedData: transformWalletRequestToSharedData(
walletDataRequest,
stateClient.getState().sharedData
),
})
return error
})

requestItemClient.updateStatus({ id, status: 'success' })
return ok(response)
})
.map((walletData) => {
if (!oneTime)
stateClient.setState({
loggedInTimestamp: Date.now().toString(),
walletData,
sharedData: transformWalletRequestToSharedData(
walletDataRequest,
stateClient.getState().sharedData
),
return walletData
})

return walletData
})
)
})

const setState = (...items: DataRequestBuilderItem[]) => {
Expand Down
15 changes: 14 additions & 1 deletion src/radix-dapp-toolkit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ import {
ButtonApi,
GatewayApi,
RadixDappToolkitOptions,
SendTransactionInput,
WalletApi,
WalletRequest,
requestInterceptorFactory,
RequestInterceptor,
} from './_types'
import { mergeMap, withLatestFrom } from 'rxjs/operators'
import { WalletData } from './state/types'
Expand All @@ -55,6 +59,8 @@ export const RadixDappToolkit = (
applicationName,
applicationVersion,
useCache = true,
requestInterceptor = (async ({ payload }: WalletRequest) =>
payload) as RequestInterceptor,
} = options || {}

const storageKey = `rdt:${dAppDefinitionAddress}:${networkId}`
Expand Down Expand Up @@ -119,6 +125,8 @@ export const RadixDappToolkit = (
const dataRequestStateClient =
providers?.dataRequestStateClient ?? DataRequestStateClient({})

const withInterceptor = requestInterceptorFactory(requestInterceptor)

const dataRequestClient =
providers?.dataRequestClient ??
DataRequestClient({
Expand All @@ -127,6 +135,7 @@ export const RadixDappToolkit = (
walletClient,
useCache,
dataRequestStateClient,
requestInterceptor: withInterceptor,
})

const disconnect = () => {
Expand Down Expand Up @@ -327,7 +336,11 @@ export const RadixDappToolkit = (
dataRequestClient.provideConnectResponseCallback,
updateSharedData: () => dataRequestClient.updateSharedData(),
sendOneTimeRequest: dataRequestClient.sendOneTimeRequest,
sendTransaction: walletClient.sendTransaction,
sendTransaction: (input: SendTransactionInput) =>
withInterceptor({
type: 'sendTransaction',
payload: input,
}).andThen(walletClient.sendTransaction),
walletData$: stateClient.walletData$,
getWalletData: () => stateClient.getWalletData(),
}
Expand Down

0 comments on commit 2b331e8

Please sign in to comment.