Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/relay-rate-limit-auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@audius/sdk': patch
---

Add Authorization header and API identification to relay calls to support proper rate limiting
18 changes: 15 additions & 3 deletions packages/sdk/src/sdk/createSdkWithServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,20 @@ export const createSdkWithServices = (config: SdkConfig) => {
let apiKey = 'apiKey' in config ? config.apiKey : undefined
const appName = 'appName' in config ? config.appName : undefined
const apiSecret = 'apiSecret' in config ? config.apiSecret : undefined
const bearerToken = 'bearerToken' in config ? config.bearerToken : undefined

// Default apiKey to derived key from apiSecret if not provided
if (apiSecret && !apiKey) {
apiKey = privateKeyToAccount(ensureHex(apiSecret)).address
}

// Initialize services
const services = initializeServices({ config, apiKey, apiSecret })
const services = initializeServices({
config,
apiKey,
apiSecret,
bearerToken
})

// Warn if using private key in the browser
if (apiSecret && isBrowser) {
Expand Down Expand Up @@ -145,11 +151,13 @@ export const createSdkWithServices = (config: SdkConfig) => {
const initializeServices = ({
config,
apiKey,
apiSecret
apiSecret,
bearerToken
}: {
config: SdkConfig
apiKey?: string
apiSecret?: string
bearerToken?: string
}) => {
const servicesConfig =
config.environment === 'development' ? developmentConfig : productionConfig
Expand Down Expand Up @@ -179,7 +187,11 @@ const initializeServices = ({
new EntityManagerClient({
...getDefaultEntityManagerConfig(servicesConfig),
audiusWalletClient,
logger
logger,
apiKey,
apiSecret,
bearerToken,
appName: 'appName' in config ? config.appName : undefined
})

const storage =
Expand Down
31 changes: 27 additions & 4 deletions packages/sdk/src/sdk/services/EntityManager/EntityManagerClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ export class EntityManagerClient implements EntityManagerService {
private readonly chainId: number
private readonly contractAddress: string
private readonly endpoint: string
private readonly apiKey?: string
private readonly apiSecret?: string
private readonly bearerToken?: string
private readonly appName?: string

constructor(config_: EntityManagerConfig) {
const config = mergeConfigWithDefaults(
Expand All @@ -51,6 +55,10 @@ export class EntityManagerClient implements EntityManagerService {
this.contractAddress = config.contractAddress
this.logger = config.logger.createPrefixedLogger('[entity-manager]')
this.endpoint = config.endpoint
this.apiKey = config.apiKey
this.apiSecret = config.apiSecret
this.bearerToken = config.bearerToken
this.appName = config.appName
}

/**
Expand Down Expand Up @@ -87,13 +95,28 @@ export class EntityManagerClient implements EntityManagerService {
const [senderAddress] = await this.audiusWalletClient.getAddresses()
const signature = await this.audiusWalletClient.signTypedData(typedData)

const url = `${this.endpoint}/relay`
const params = new URLSearchParams()
if (this.apiKey) params.set('api_key', this.apiKey)
if (this.appName) params.set('app_name', this.appName)
const qs = params.toString()
const url = `${this.endpoint}/relay${qs ? `?${qs}` : ''}`
this.logger.info(`Making relay request to ${url}`)

const headers = new Headers({
'Content-Type': 'application/json'
})

// Add auth header for API identification and rate limiting
if (this.bearerToken) {
headers.set('Authorization', `Bearer ${this.bearerToken}`)
} else if (this.apiKey && this.apiSecret) {
const credentials = btoa(`${this.apiKey}:${this.apiSecret}`)
headers.set('Authorization', `Basic ${credentials}`)
}

const response = await fetch(url, {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/json'
}),
headers,
body: JSON.stringify({
contractAddress: this.contractAddress,
contractRegistryKey: 'EntityManager',
Expand Down
8 changes: 8 additions & 0 deletions packages/sdk/src/sdk/services/EntityManager/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ export type EntityManagerConfigInternal = {
* The endpoint to use for relays
*/
endpoint: string
/** API key for relay calls */
apiKey?: string
/** API secret for relay calls */
apiSecret?: string
/** Bearer token for relay calls */
bearerToken?: string
/** App name for relay calls */
appName?: string
}
export type EntityManagerConfig = Partial<EntityManagerConfigInternal> & {
audiusWalletClient: AudiusWalletClient
Expand Down
Loading