Skip to content

Commit fdd1e54

Browse files
Add register-api key call when making an api key in app (#13772)
1 parent 879837d commit fdd1e54

7 files changed

Lines changed: 224 additions & 42 deletions

File tree

.changeset/great-lemons-draw.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@audius/sdk": minor
3+
---
4+
5+
Add register dev app key endpoint

packages/sdk/src/sdk/api/developer-apps/DeveloperAppsApi.ts

Lines changed: 13 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,22 @@ export class DeveloperAppsApi extends GeneratedDeveloperAppsApi {
9696
? (privateKey as string).slice(2).toLowerCase()
9797
: (privateKey as string).toLowerCase()
9898

99-
// Create api_access_key for the relay-created app (user from auth headers; indexer may lag, so retry)
100-
const bearerToken = await this.createAccessKeyWithRetry({
99+
await this.registerDeveloperAppAPIKey({
101100
address,
102-
userId: userId.toString()
101+
userId: userId.toString(),
102+
metadata: { apiSecret }
103103
})
104104

105+
const path = `/developer-apps/${encodeURIComponent(address)}/access-keys`
106+
const res = await this.request({
107+
path,
108+
method: 'POST',
109+
headers: {},
110+
query: { user_id: userId.toString() }
111+
})
112+
const json = (await res.json()) as { api_access_key: string }
113+
const bearerToken = json.api_access_key ?? ''
114+
105115
return {
106116
...response,
107117
apiKey,
@@ -111,45 +121,6 @@ export class DeveloperAppsApi extends GeneratedDeveloperAppsApi {
111121
}
112122
}
113123

114-
/**
115-
* Call POST /developer-apps/{address}/access-keys to create the first api_access_key
116-
* for a relay-created app. User is identified from request auth headers. Retries on 404
117-
* while indexer processes the CreateDeveloperApp tx.
118-
*/
119-
private async createAccessKeyWithRetry(params: {
120-
address: string
121-
userId: string
122-
}): Promise<string> {
123-
const { address, userId } = params
124-
const maxAttempts = 5
125-
const delayMs = 2000
126-
127-
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
128-
try {
129-
const path = `/developer-apps/${encodeURIComponent(address)}/access-keys`
130-
const res = await this.request({
131-
path,
132-
method: 'POST',
133-
headers: {},
134-
query: { user_id: userId }
135-
})
136-
const json = (await res.json()) as { api_access_key: string }
137-
return json.api_access_key ?? ''
138-
} catch (e: unknown) {
139-
const status =
140-
e && typeof e === 'object' && 'response' in e
141-
? (e as { response?: { status?: number } }).response?.status
142-
: undefined
143-
if (status === 404 && attempt < maxAttempts) {
144-
await new Promise((resolve) => setTimeout(resolve, delayMs))
145-
continue
146-
}
147-
throw e
148-
}
149-
}
150-
return ''
151-
}
152-
153124
/**
154125
* Get developer apps with api_access_keys (bearer tokens).
155126
* Uses include=metrics to fetch bearer tokens from the API.

packages/sdk/src/sdk/api/generated/default/.openapi-generator/FILES

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ models/ReceiveTipNotification.ts
250250
models/ReceiveTipNotificationAction.ts
251251
models/ReceiveTipNotificationActionData.ts
252252
models/RedeemAmountResponse.ts
253+
models/RegisterApiKeyRequestBody.ts
254+
models/RegisterApiKeyResponse.ts
253255
models/Related.ts
254256
models/RelatedArtistResponse.ts
255257
models/Remix.ts

packages/sdk/src/sdk/api/generated/default/apis/DeveloperAppsApi.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import type {
2323
DeactivateAccessKeyResponse,
2424
DeveloperAppResponse,
2525
DeveloperAppsResponse,
26+
RegisterApiKeyRequestBody,
27+
RegisterApiKeyResponse,
2628
UpdateDeveloperAppRequestBody,
2729
WriteResponse,
2830
} from '../models';
@@ -41,6 +43,10 @@ import {
4143
DeveloperAppResponseToJSON,
4244
DeveloperAppsResponseFromJSON,
4345
DeveloperAppsResponseToJSON,
46+
RegisterApiKeyRequestBodyFromJSON,
47+
RegisterApiKeyRequestBodyToJSON,
48+
RegisterApiKeyResponseFromJSON,
49+
RegisterApiKeyResponseToJSON,
4450
UpdateDeveloperAppRequestBodyFromJSON,
4551
UpdateDeveloperAppRequestBodyToJSON,
4652
WriteResponseFromJSON,
@@ -77,6 +83,12 @@ export interface GetDeveloperAppsRequest {
7783
include?: GetDeveloperAppsIncludeEnum;
7884
}
7985

86+
export interface RegisterDeveloperAppAPIKeyRequest {
87+
userId: string;
88+
address: string;
89+
metadata: RegisterApiKeyRequestBody;
90+
}
91+
8092
export interface UpdateDeveloperAppRequest {
8193
userId: string;
8294
address: string;
@@ -320,6 +332,63 @@ export class DeveloperAppsApi extends runtime.BaseAPI {
320332
return await response.value();
321333
}
322334

335+
/**
336+
* @hidden
337+
* Register api_key and api_secret in api_keys table for developer apps created via entity manager transactions. Use when the client sends raw ManageEntity tx instead of POST /developer-apps. Inserts with rps=10, rpm=500000. Requires the app to exist in developer_apps and belong to the authenticated user.
338+
*/
339+
async registerDeveloperAppAPIKeyRaw(params: RegisterDeveloperAppAPIKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<RegisterApiKeyResponse>> {
340+
if (params.userId === null || params.userId === undefined) {
341+
throw new runtime.RequiredError('userId','Required parameter params.userId was null or undefined when calling registerDeveloperAppAPIKey.');
342+
}
343+
344+
if (params.address === null || params.address === undefined) {
345+
throw new runtime.RequiredError('address','Required parameter params.address was null or undefined when calling registerDeveloperAppAPIKey.');
346+
}
347+
348+
if (params.metadata === null || params.metadata === undefined) {
349+
throw new runtime.RequiredError('metadata','Required parameter params.metadata was null or undefined when calling registerDeveloperAppAPIKey.');
350+
}
351+
352+
const queryParameters: any = {};
353+
354+
if (params.userId !== undefined) {
355+
queryParameters['user_id'] = params.userId;
356+
}
357+
358+
const headerParameters: runtime.HTTPHeaders = {};
359+
360+
headerParameters['Content-Type'] = 'application/json';
361+
362+
if (this.configuration && (this.configuration.username !== undefined || this.configuration.password !== undefined)) {
363+
headerParameters["Authorization"] = "Basic " + btoa(this.configuration.username + ":" + this.configuration.password);
364+
}
365+
if (this.configuration && this.configuration.accessToken) {
366+
const token = this.configuration.accessToken;
367+
const tokenString = await token("BearerAuth", []);
368+
369+
if (tokenString) {
370+
headerParameters["Authorization"] = `Bearer ${tokenString}`;
371+
}
372+
}
373+
const response = await this.request({
374+
path: `/developer-apps/{address}/register-api-key`.replace(`{${"address"}}`, encodeURIComponent(String(params.address))),
375+
method: 'POST',
376+
headers: headerParameters,
377+
query: queryParameters,
378+
body: RegisterApiKeyRequestBodyToJSON(params.metadata),
379+
}, initOverrides);
380+
381+
return new runtime.JSONApiResponse(response, (jsonValue) => RegisterApiKeyResponseFromJSON(jsonValue));
382+
}
383+
384+
/**
385+
* Register api_key and api_secret in api_keys table for developer apps created via entity manager transactions. Use when the client sends raw ManageEntity tx instead of POST /developer-apps. Inserts with rps=10, rpm=500000. Requires the app to exist in developer_apps and belong to the authenticated user.
386+
*/
387+
async registerDeveloperAppAPIKey(params: RegisterDeveloperAppAPIKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<RegisterApiKeyResponse> {
388+
const response = await this.registerDeveloperAppAPIKeyRaw(params, initOverrides);
389+
return await response.value();
390+
}
391+
323392
/**
324393
* @hidden
325394
* Updates a developer app. Indexer validates grants.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/* tslint:disable */
2+
/* eslint-disable */
3+
// @ts-nocheck
4+
/**
5+
* API
6+
* Audius V1 API
7+
*
8+
* The version of the OpenAPI document: 1.0
9+
*
10+
*
11+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
12+
* https://openapi-generator.tech
13+
* Do not edit the class manually.
14+
*/
15+
16+
import { exists, mapValues } from '../runtime';
17+
/**
18+
*
19+
* @export
20+
* @interface RegisterApiKeyRequestBody
21+
*/
22+
export interface RegisterApiKeyRequestBody {
23+
/**
24+
* The API secret (private key hex) for the developer app
25+
* @type {string}
26+
* @memberof RegisterApiKeyRequestBody
27+
*/
28+
apiSecret: string;
29+
}
30+
31+
/**
32+
* Check if a given object implements the RegisterApiKeyRequestBody interface.
33+
*/
34+
export function instanceOfRegisterApiKeyRequestBody(value: object): value is RegisterApiKeyRequestBody {
35+
let isInstance = true;
36+
isInstance = isInstance && "apiSecret" in value && value["apiSecret"] !== undefined;
37+
38+
return isInstance;
39+
}
40+
41+
export function RegisterApiKeyRequestBodyFromJSON(json: any): RegisterApiKeyRequestBody {
42+
return RegisterApiKeyRequestBodyFromJSONTyped(json, false);
43+
}
44+
45+
export function RegisterApiKeyRequestBodyFromJSONTyped(json: any, ignoreDiscriminator: boolean): RegisterApiKeyRequestBody {
46+
if ((json === undefined) || (json === null)) {
47+
return json;
48+
}
49+
return {
50+
51+
'apiSecret': json['api_secret'],
52+
};
53+
}
54+
55+
export function RegisterApiKeyRequestBodyToJSON(value?: RegisterApiKeyRequestBody | null): any {
56+
if (value === undefined) {
57+
return undefined;
58+
}
59+
if (value === null) {
60+
return null;
61+
}
62+
return {
63+
64+
'api_secret': value.apiSecret,
65+
};
66+
}
67+
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/* tslint:disable */
2+
/* eslint-disable */
3+
// @ts-nocheck
4+
/**
5+
* API
6+
* Audius V1 API
7+
*
8+
* The version of the OpenAPI document: 1.0
9+
*
10+
*
11+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
12+
* https://openapi-generator.tech
13+
* Do not edit the class manually.
14+
*/
15+
16+
import { exists, mapValues } from '../runtime';
17+
/**
18+
*
19+
* @export
20+
* @interface RegisterApiKeyResponse
21+
*/
22+
export interface RegisterApiKeyResponse {
23+
/**
24+
* Whether the registration was successful
25+
* @type {boolean}
26+
* @memberof RegisterApiKeyResponse
27+
*/
28+
success?: boolean;
29+
}
30+
31+
/**
32+
* Check if a given object implements the RegisterApiKeyResponse interface.
33+
*/
34+
export function instanceOfRegisterApiKeyResponse(value: object): value is RegisterApiKeyResponse {
35+
let isInstance = true;
36+
37+
return isInstance;
38+
}
39+
40+
export function RegisterApiKeyResponseFromJSON(json: any): RegisterApiKeyResponse {
41+
return RegisterApiKeyResponseFromJSONTyped(json, false);
42+
}
43+
44+
export function RegisterApiKeyResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): RegisterApiKeyResponse {
45+
if ((json === undefined) || (json === null)) {
46+
return json;
47+
}
48+
return {
49+
50+
'success': !exists(json, 'success') ? undefined : json['success'],
51+
};
52+
}
53+
54+
export function RegisterApiKeyResponseToJSON(value?: RegisterApiKeyResponse | null): any {
55+
if (value === undefined) {
56+
return undefined;
57+
}
58+
if (value === null) {
59+
return null;
60+
}
61+
return {
62+
63+
'success': value.success,
64+
};
65+
}
66+

packages/sdk/src/sdk/api/generated/default/models/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ export * from './ReceiveTipNotification';
229229
export * from './ReceiveTipNotificationAction';
230230
export * from './ReceiveTipNotificationActionData';
231231
export * from './RedeemAmountResponse';
232+
export * from './RegisterApiKeyRequestBody';
233+
export * from './RegisterApiKeyResponse';
232234
export * from './Related';
233235
export * from './RelatedArtistResponse';
234236
export * from './Remix';

0 commit comments

Comments
 (0)