Skip to content

Commit

Permalink
feat(op): add monetization client
Browse files Browse the repository at this point in the history
  • Loading branch information
raducristianpopa committed Jan 12, 2024
1 parent 2e00b5f commit d0becc8
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 10 deletions.
84 changes: 83 additions & 1 deletion packages/open-payments/src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
WalletAddressRoutes
} from './wallet-address'
import { createAxiosInstance } from './requests'
import { AxiosInstance } from 'axios'
import { AxiosInstance, InternalAxiosRequestConfig } from 'axios'
import { createGrantRoutes, GrantRoutes } from './grant'
import {
createOutgoingPaymentRoutes,
Expand Down Expand Up @@ -152,6 +152,41 @@ const createUnauthenticatedDeps = async ({
}
}

const createMonetizationClientDeps = async ({
useHttp = false,
...args
}: CreateMonetizationClientDeps) => {
const logger = args?.logger ?? createLogger({ name: 'Open Payments Client' })
if (args.logLevel) {
logger.level = args.logLevel
}

const axiosInstance = createAxiosInstance({
requestTimeoutMs:
args?.requestTimeoutMs ?? config.DEFAULT_REQUEST_TIMEOUT_MS,
requestInterceptor: args.requestInterceptor
})

const walletAddressServerOpenApi = await createOpenAPI(
path.resolve(__dirname, '../openapi/wallet-address-server.yaml')
)
const resourceServerOpenApi = await createOpenAPI(
path.resolve(__dirname, '../openapi/resource-server.yaml')
)
const authServerOpenApi = await createOpenAPI(
path.resolve(__dirname, '../openapi/auth-server.yaml')
)

return {
axiosInstance,
walletAddressServerOpenApi,
resourceServerOpenApi,
authServerOpenApi,
logger,
useHttp
}
}

const createAuthenticatedClientDeps = async ({
useHttp = false,
...args
Expand Down Expand Up @@ -249,6 +284,14 @@ export interface CreateAuthenticatedClientArgs
walletAddressUrl: string
}

export interface CreateMonetizationClientDeps
extends CreateUnauthenticatedClientArgs {
walletAddressUrl: string
requestInterceptor: (
value: InternalAxiosRequestConfig
) => InternalAxiosRequestConfig | Promise<InternalAxiosRequestConfig>
}

export interface AuthenticatedClient
extends Omit<UnauthenticatedClient, 'incomingPayment'> {
incomingPayment: IncomingPaymentRoutes
Expand Down Expand Up @@ -296,3 +339,42 @@ export const createAuthenticatedClient = async (
})
}
}

export const createMonetizationClient = async (
args: CreateMonetizationClientDeps
): Promise<AuthenticatedClient> => {
const {
resourceServerOpenApi,
authServerOpenApi,
walletAddressServerOpenApi,
...baseDeps
} = await createMonetizationClientDeps(args)

return {
incomingPayment: createIncomingPaymentRoutes({
...baseDeps,
openApi: resourceServerOpenApi
}),
outgoingPayment: createOutgoingPaymentRoutes({
...baseDeps,
openApi: resourceServerOpenApi
}),
walletAddress: createWalletAddressRoutes({
...baseDeps,
openApi: walletAddressServerOpenApi
}),
grant: createGrantRoutes({
...baseDeps,
openApi: authServerOpenApi,
client: args.walletAddressUrl
}),
token: createTokenRoutes({
...baseDeps,
openApi: authServerOpenApi
}),
quote: createQuoteRoutes({
...baseDeps,
openApi: resourceServerOpenApi
})
}
}
53 changes: 44 additions & 9 deletions packages/open-payments/src/client/requests.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import axios, {
AxiosInstance,
AxiosInterceptorOptions,
InternalAxiosRequestConfig,
isAxiosError
} from 'axios'
Expand Down Expand Up @@ -158,11 +159,38 @@ const checkUrlProtocol = (deps: BaseDeps, url: string): string => {
return requestUrl.href
}

export const createAxiosInstance = (args: {
export type InterceptorFn = (
config: InternalAxiosRequestConfig
) => InternalAxiosRequestConfig | Promise<InternalAxiosRequestConfig>

interface BaseAxiosInstanceArgs {
requestTimeoutMs: number
}

interface CreateBaseAxiosInstanceArgs extends BaseAxiosInstanceArgs {
privateKey?: KeyObject
keyId?: string
}): AxiosInstance => {
}

interface CreateMonetizationAxiosInstanceArgs extends BaseAxiosInstanceArgs {
requestInterceptor: InterceptorFn
}

const isMonetizationArgs = (
args: any
): args is CreateMonetizationAxiosInstanceArgs => {
return typeof args.requestInterceptor === 'function'
}

export function createAxiosInstance(
args: CreateBaseAxiosInstanceArgs
): AxiosInstance
export function createAxiosInstance(
args: CreateMonetizationAxiosInstanceArgs
): AxiosInstance
export function createAxiosInstance(
args: any
): AxiosInstance {
const axiosInstance = axios.create({
headers: {
common: {
Expand All @@ -173,7 +201,19 @@ export const createAxiosInstance = (args: {
timeout: args.requestTimeoutMs
})

if (args.privateKey !== undefined && args.keyId !== undefined) {
const interceptorOptions: AxiosInterceptorOptions = {
runWhen: (config: InternalAxiosRequestConfig) =>
config.method?.toLowerCase() === 'post' ||
!!(config.headers && config.headers['Authorization'])
}

if (isMonetizationArgs(args)) {
axiosInstance.interceptors.request.use(
args.requestInterceptor,
undefined,
interceptorOptions
)
} else if (args.privateKey !== undefined && args.keyId !== undefined) {
const privateKey = args.privateKey
const keyId = args.keyId
axiosInstance.interceptors.request.use(
Expand Down Expand Up @@ -204,13 +244,8 @@ export const createAxiosInstance = (args: {
return config
},
undefined,
{
runWhen: (config: InternalAxiosRequestConfig) =>
config.method?.toLowerCase() === 'post' ||
!!(config.headers && config.headers['Authorization'])
}
interceptorOptions
)
}

return axiosInstance
}

0 comments on commit d0becc8

Please sign in to comment.