@cubist-labs/cubesigner-sdk 0.4.239 → 0.4.244

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -69,6 +69,7 @@ import type {
69
69
  ListBucketsResponse,
70
70
  UpdateBucketRequest,
71
71
  PolicyInfo,
72
+ JsonRpcRequest,
72
73
  } from "../schema_types";
73
74
  import { encodeToBase64 } from "../util";
74
75
  import { auditLogEntrySchema } from "../audit_log";
@@ -160,13 +161,19 @@ import {
160
161
  type BucketInfo,
161
162
  } from "../index";
162
163
  import { assertOk, op, type Op, type Operation, apiFetch } from "../fetch";
163
- import { BaseClient, type ClientConfig, signerSessionFromSessionInfo } from "./base_client";
164
+ import {
165
+ authHeader,
166
+ BaseClient,
167
+ type ClientConfig,
168
+ signerSessionFromSessionInfo,
169
+ } from "./base_client";
164
170
  import { retryOn5XX } from "../retry";
165
171
  import { PasskeyLoginChallenge } from "../passkey";
166
172
 
167
173
  // these types are used in doc comments only
168
174
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
169
175
  import type { RoleAttestationClaims, KeyAttestationClaims } from "../schema_types";
176
+ import { mergeHeaders } from "openapi-fetch";
170
177
 
171
178
  /**
172
179
  * String returned by API when a user does not have an email address (for backwards compatibility)
@@ -217,10 +224,7 @@ export class ApiClient extends BaseClient {
217
224
  return new ApiClient(this.sessionMeta, this.sessionManager, this.orgId, {
218
225
  ...this.config,
219
226
  ...cfg,
220
- headers: {
221
- ...(this.config.headers ?? {}),
222
- ...(cfg.headers ?? {}),
223
- },
227
+ headers: mergeHeaders(this.config.headers, cfg.headers),
224
228
  });
225
229
  }
226
230
 
@@ -258,12 +262,14 @@ export class ApiClient extends BaseClient {
258
262
  * @param env The environment to use
259
263
  * @param orgId The org to login to
260
264
  * @param email The email to send the signature to
265
+ * @param headers Optional headers to set
261
266
  * @returns The partial OIDC token that must be combined with the signature in the email
262
267
  */
263
268
  static async initEmailOtpAuth(
264
269
  env: EnvInterface,
265
270
  orgId: string,
266
271
  email: string,
272
+ headers?: HeadersInit,
267
273
  ): Promise<EmailOtpResponse> {
268
274
  const o = op("/v0/org/{org_id}/oidc/email-otp", "post");
269
275
 
@@ -272,6 +278,7 @@ export class ApiClient extends BaseClient {
272
278
  baseUrl: env.SignerApiRoot,
273
279
  params: { path: { org_id: orgId } },
274
280
  body: { email },
281
+ headers,
275
282
  }),
276
283
  ).then(assertOk);
277
284
  }
@@ -2901,6 +2908,33 @@ export class ApiClient extends BaseClient {
2901
2908
 
2902
2909
  // #endregion
2903
2910
 
2911
+ // #region RPC
2912
+
2913
+ /**
2914
+ * Send a JSON RPC request to the high-level API endpoint.
2915
+ *
2916
+ * @param body JSON RPC request body
2917
+ * @param mfaReceipt Optional MFA receipts
2918
+ * @returns Corresponding response
2919
+ */
2920
+ async rpc(
2921
+ body: JsonRpcRequest,
2922
+ mfaReceipt?: MfaReceipts,
2923
+ ): Promise<CubeSignerResponse<schemas["JsonRpcResponse"]>> {
2924
+ const o = op("/v0/org/{org_id}/rpc", "post");
2925
+ const reqFn = (headers?: HeadersInit) =>
2926
+ this.exec(o, {
2927
+ headers,
2928
+ body: {
2929
+ jsonrpc: "2.0",
2930
+ ...body,
2931
+ },
2932
+ });
2933
+ return await CubeSignerResponse.create(this.env, reqFn, mfaReceipt);
2934
+ }
2935
+
2936
+ // #endregion
2937
+
2904
2938
  /**
2905
2939
  * Returns public org information.
2906
2940
  *
@@ -2934,14 +2968,16 @@ export class ApiClient extends BaseClient {
2934
2968
  *
2935
2969
  * @param env The environment to use
2936
2970
  * @param email The user's email
2971
+ * @param headers Optional headers to set
2937
2972
  * @returns Empty response
2938
2973
  */
2939
- static async emailMyOrgs(env: EnvInterface, email: string) {
2974
+ static async emailMyOrgs(env: EnvInterface, email: string, headers?: HeadersInit) {
2940
2975
  const o = op("/v0/email/orgs", "get");
2941
2976
  return await retryOn5XX(() =>
2942
2977
  o({
2943
2978
  baseUrl: env.SignerApiRoot,
2944
2979
  params: { query: { email } },
2980
+ headers,
2945
2981
  }),
2946
2982
  ).then(assertOk);
2947
2983
  }
@@ -2956,6 +2992,7 @@ export class ApiClient extends BaseClient {
2956
2992
  * @param lifetimes Lifetimes of the new session.
2957
2993
  * @param mfaReceipt Optional MFA receipt(s)
2958
2994
  * @param purpose Optional session description.
2995
+ * @param headers Additional headers to set
2959
2996
  * @returns The session data.
2960
2997
  */
2961
2998
  static async oidcSessionCreate(
@@ -2966,18 +3003,16 @@ export class ApiClient extends BaseClient {
2966
3003
  lifetimes?: RatchetConfig,
2967
3004
  mfaReceipt?: MfaReceipts,
2968
3005
  purpose?: string,
3006
+ headers?: HeadersInit,
2969
3007
  ): Promise<CubeSignerResponse<SessionData>> {
2970
3008
  const o = op("/v0/org/{org_id}/oidc", "post");
2971
3009
 
2972
- const loginFn = async (headers?: HeadersInit) => {
3010
+ const loginFn = async (mfaHeaders?: HeadersInit) => {
2973
3011
  const data = await retryOn5XX(() =>
2974
3012
  o({
2975
3013
  baseUrl: env.SignerApiRoot,
2976
3014
  params: { path: { org_id: orgId } },
2977
- headers: {
2978
- ...headers,
2979
- Authorization: token,
2980
- },
3015
+ headers: mergeHeaders(headers, mfaHeaders, authHeader(token)),
2981
3016
  body: {
2982
3017
  scopes,
2983
3018
  purpose,
@@ -3013,12 +3048,14 @@ export class ApiClient extends BaseClient {
3013
3048
  * @param env The environment to use
3014
3049
  * @param orgId The org to login to
3015
3050
  * @param body The request body
3051
+ * @param headers Optional headers to set
3016
3052
  * @returns The challenge that needs to be answered via {@link siweLoginComplete}
3017
3053
  */
3018
3054
  static async siweLoginInit(
3019
3055
  env: EnvInterface,
3020
3056
  orgId: string,
3021
3057
  body: schemas["SiweInitRequest"],
3058
+ headers?: HeadersInit,
3022
3059
  ): Promise<schemas["SiweInitResponse"]> {
3023
3060
  const o = op("/v0/org/{org_id}/oidc/siwe", "post");
3024
3061
  return await retryOn5XX(() =>
@@ -3026,6 +3063,7 @@ export class ApiClient extends BaseClient {
3026
3063
  baseUrl: env.SignerApiRoot,
3027
3064
  params: { path: { org_id: orgId } },
3028
3065
  body,
3066
+ headers,
3029
3067
  }),
3030
3068
  ).then(assertOk);
3031
3069
  }
@@ -3040,12 +3078,14 @@ export class ApiClient extends BaseClient {
3040
3078
  * @param env The environment to use
3041
3079
  * @param orgId The org to login to
3042
3080
  * @param body The request body
3081
+ * @param headers Optional headers to set
3043
3082
  * @returns An OIDC token which can be used to log in via OIDC (see {@link oidcSessionCreate})
3044
3083
  */
3045
3084
  static async siweLoginComplete(
3046
3085
  env: EnvInterface,
3047
3086
  orgId: string,
3048
3087
  body: schemas["SiweCompleteRequest"],
3088
+ headers?: HeadersInit,
3049
3089
  ): Promise<schemas["SiweCompleteResponse"]> {
3050
3090
  const o = op("/v0/org/{org_id}/oidc/siwe", "patch");
3051
3091
  return await retryOn5XX(() =>
@@ -3053,6 +3093,7 @@ export class ApiClient extends BaseClient {
3053
3093
  baseUrl: env.SignerApiRoot,
3054
3094
  params: { path: { org_id: orgId } },
3055
3095
  body,
3096
+ headers,
3056
3097
  }),
3057
3098
  ).then(assertOk);
3058
3099
  }
@@ -3062,17 +3103,20 @@ export class ApiClient extends BaseClient {
3062
3103
  *
3063
3104
  * @param env The environment to log into
3064
3105
  * @param body The login request
3106
+ * @param headers Optional headers to set
3065
3107
  * @returns The challenge that must be answered (see {@link passkeyLoginComplete}) to log in.
3066
3108
  */
3067
3109
  static async passkeyLoginInit(
3068
3110
  env: EnvInterface,
3069
3111
  body: LoginRequest,
3112
+ headers?: HeadersInit,
3070
3113
  ): Promise<PasskeyLoginChallenge> {
3071
3114
  const o = op("/v0/passkey", "post");
3072
3115
  const resp = await retryOn5XX(() =>
3073
3116
  o({
3074
3117
  baseUrl: env.SignerApiRoot,
3075
3118
  body,
3119
+ headers,
3076
3120
  }),
3077
3121
  ).then(assertOk);
3078
3122
  return new PasskeyLoginChallenge(env, resp, body.purpose);
@@ -3084,18 +3128,21 @@ export class ApiClient extends BaseClient {
3084
3128
  * @param env The environment to log into
3085
3129
  * @param body The request body
3086
3130
  * @param purpose Optional descriptive session purpose
3131
+ * @param headers Optional headers to set
3087
3132
  * @returns The session data
3088
3133
  */
3089
3134
  static async passkeyLoginComplete(
3090
3135
  env: EnvInterface,
3091
3136
  body: PasskeyAssertAnswer,
3092
3137
  purpose?: string | null,
3138
+ headers?: HeadersInit,
3093
3139
  ): Promise<SessionData> {
3094
3140
  const o = op("/v0/passkey", "patch");
3095
3141
  const resp = await retryOn5XX(() =>
3096
3142
  o({
3097
3143
  baseUrl: env.SignerApiRoot,
3098
3144
  body,
3145
+ headers,
3099
3146
  }),
3100
3147
  ).then(assertOk);
3101
3148
  return {
@@ -3117,11 +3164,13 @@ export class ApiClient extends BaseClient {
3117
3164
  * @param env The environment to log into
3118
3165
  * @param orgId The id of the organization
3119
3166
  * @param body The request body
3167
+ * @param headers Optional headers to set
3120
3168
  */
3121
3169
  static async idpAcceptInvite(
3122
3170
  env: EnvInterface,
3123
3171
  orgId: string,
3124
3172
  body: InvitationAcceptRequest,
3173
+ headers?: HeadersInit,
3125
3174
  ): Promise<void> {
3126
3175
  const o = op("/v0/org/{org_id}/invitation/accept", "post");
3127
3176
  await retryOn5XX(() =>
@@ -3129,6 +3178,7 @@ export class ApiClient extends BaseClient {
3129
3178
  baseUrl: env.SignerApiRoot,
3130
3179
  params: { path: { org_id: orgId } },
3131
3180
  body,
3181
+ headers,
3132
3182
  }),
3133
3183
  ).then(assertOk);
3134
3184
  }
@@ -3139,6 +3189,7 @@ export class ApiClient extends BaseClient {
3139
3189
  * @param env The environment to log into
3140
3190
  * @param orgId The id of the organization
3141
3191
  * @param body The request body
3192
+ * @param headers Optional headers to set
3142
3193
  * @returns Returns an OIDC token which can be used
3143
3194
  * to log in via OIDC (see {@link oidcSessionCreate}).
3144
3195
  */
@@ -3146,6 +3197,7 @@ export class ApiClient extends BaseClient {
3146
3197
  env: EnvInterface,
3147
3198
  orgId: string,
3148
3199
  body: AuthenticationRequest,
3200
+ headers?: HeadersInit,
3149
3201
  ): Promise<AuthenticationResponse> {
3150
3202
  const o = op("/v0/org/{org_id}/idp/authenticate", "post");
3151
3203
  return retryOn5XX(() =>
@@ -3153,6 +3205,7 @@ export class ApiClient extends BaseClient {
3153
3205
  baseUrl: env.SignerApiRoot,
3154
3206
  params: { path: { org_id: orgId } },
3155
3207
  body,
3208
+ headers,
3156
3209
  }),
3157
3210
  ).then(assertOk);
3158
3211
  }
@@ -3163,12 +3216,14 @@ export class ApiClient extends BaseClient {
3163
3216
  * @param env The environment to log into
3164
3217
  * @param orgId The id of the organization
3165
3218
  * @param body The request body
3219
+ * @param headers Optional headers to set
3166
3220
  * @returns Returns the partial token (`${header}.${claims}.`) while the signature is sent via email.
3167
3221
  */
3168
3222
  static async idpPasswordResetRequest(
3169
3223
  env: EnvInterface,
3170
3224
  orgId: string,
3171
3225
  body: PasswordResetRequest,
3226
+ headers?: HeadersInit,
3172
3227
  ): Promise<EmailOtpResponse> {
3173
3228
  const o = op("/v0/org/{org_id}/idp/password_reset", "post");
3174
3229
  return retryOn5XX(() =>
@@ -3176,6 +3231,7 @@ export class ApiClient extends BaseClient {
3176
3231
  baseUrl: env.SignerApiRoot,
3177
3232
  params: { path: { org_id: orgId } },
3178
3233
  body,
3234
+ headers,
3179
3235
  }),
3180
3236
  ).then(assertOk);
3181
3237
  }
@@ -3188,6 +3244,7 @@ export class ApiClient extends BaseClient {
3188
3244
  * @param partialToken The partial token returned by {@link passwordResetRequest}
3189
3245
  * @param signature The one-time code (signature in this case) sent via email
3190
3246
  * @param newPassword The new password
3247
+ * @param headers Optional headers to set
3191
3248
  */
3192
3249
  static async idpPasswordResetConfirm(
3193
3250
  env: EnvInterface,
@@ -3195,6 +3252,7 @@ export class ApiClient extends BaseClient {
3195
3252
  partialToken: string,
3196
3253
  signature: string,
3197
3254
  newPassword: string,
3255
+ headers?: HeadersInit,
3198
3256
  ): Promise<void> {
3199
3257
  const o = op("/v0/org/{org_id}/idp/password_reset", "patch");
3200
3258
  await retryOn5XX(() =>
@@ -3205,6 +3263,7 @@ export class ApiClient extends BaseClient {
3205
3263
  token: `${partialToken}${signature}`,
3206
3264
  new_password: newPassword,
3207
3265
  },
3266
+ headers,
3208
3267
  }),
3209
3268
  ).then(assertOk);
3210
3269
  }
@@ -3215,21 +3274,21 @@ export class ApiClient extends BaseClient {
3215
3274
  * @param env The environment to log into
3216
3275
  * @param orgId The org id in which to generate proof
3217
3276
  * @param token The oidc token
3277
+ * @param headers Optional headers to set
3218
3278
  * @returns Proof of authentication
3219
3279
  */
3220
3280
  static async identityProveOidc(
3221
3281
  env: EnvInterface,
3222
3282
  orgId: string,
3223
3283
  token: string,
3284
+ headers?: HeadersInit,
3224
3285
  ): Promise<IdentityProof> {
3225
3286
  const o = op("/v0/org/{org_id}/identity/prove/oidc", "post");
3226
3287
  return retryOn5XX(() =>
3227
3288
  o({
3228
3289
  baseUrl: env.SignerApiRoot,
3229
3290
  params: { path: { org_id: orgId } },
3230
- headers: {
3231
- Authorization: token,
3232
- },
3291
+ headers: mergeHeaders(headers, authHeader(token)),
3233
3292
  }),
3234
3293
  ).then(assertOk);
3235
3294
  }
@@ -3239,16 +3298,19 @@ export class ApiClient extends BaseClient {
3239
3298
  *
3240
3299
  * @param env The environment to log into
3241
3300
  * @param token The oidc token identifying the user
3301
+ * @param headers Optional headers to set
3242
3302
  * @returns The organization the user belongs to
3243
3303
  */
3244
- static async userOrgs(env: EnvInterface, token: string): Promise<UserOrgsResponse> {
3304
+ static async userOrgs(
3305
+ env: EnvInterface,
3306
+ token: string,
3307
+ headers?: HeadersInit,
3308
+ ): Promise<UserOrgsResponse> {
3245
3309
  const o = op("/v0/user/orgs", "get");
3246
3310
  return retryOn5XX(() =>
3247
3311
  o({
3248
3312
  baseUrl: env.SignerApiRoot,
3249
- headers: {
3250
- Authorization: token,
3251
- },
3313
+ headers: mergeHeaders(headers, authHeader(token)),
3252
3314
  }),
3253
3315
  ).then(assertOk);
3254
3316
  }
@@ -9,6 +9,7 @@ import type { SessionData, SessionManager, SessionMetadata } from "./session";
9
9
  import { MemorySessionManager, metadata, parseBase64SessionData } from "./session";
10
10
  import type { NewSessionResponse, ErrorResponse } from "../schema_types";
11
11
  import type { EnvInterface } from "../env";
12
+ import { mergeHeaders } from "openapi-fetch";
12
13
 
13
14
  /** CubeSigner SDK package name */
14
15
  export const NAME: string = pkg.name;
@@ -163,14 +164,16 @@ export class BaseClient extends EventEmitter<ClientEvents> {
163
164
  // If we have an activeSession, let it dictate the baseUrl. Otherwise fall back to the one set at construction
164
165
  baseUrl,
165
166
  ...opts,
166
- headers: {
167
- "User-Agent": browserUserAgent ?? `${NAME}@${VERSION}`,
168
- "X-Cubist-Ts-Sdk": `${NAME}@${VERSION}`,
169
- Origin: this.config.origin,
170
- Authorization: token,
171
- ...(this.config.headers ?? {}),
172
- ...opts.headers,
173
- },
167
+ headers: mergeHeaders(
168
+ {
169
+ "User-Agent": browserUserAgent ?? `${NAME}@${VERSION}`,
170
+ "X-Cubist-Ts-Sdk": `${NAME}@${VERSION}`,
171
+ Origin: this.config.origin,
172
+ },
173
+ authHeader(token),
174
+ this.config.headers,
175
+ opts.headers,
176
+ ),
174
177
  params: {
175
178
  ...opts.params,
176
179
  path: {
@@ -249,7 +252,7 @@ export class BaseClient extends EventEmitter<ClientEvents> {
249
252
  return status >= 500 && status < 600;
250
253
  },
251
254
  });
252
- // Once we have a non-5XX response, we will assertOk (either throwing or yielding the reponse)
255
+ // Once we have a non-5XX response, we will assertOk (either throwing or yielding the response)
253
256
  return assertOk(resp);
254
257
  } catch (e) {
255
258
  if (e instanceof ErrResponse) {
@@ -308,3 +311,13 @@ export type OmitAutoParams<O> = DeepOmit<
308
311
  params: { path: { org_id: string } };
309
312
  }
310
313
  > & { params?: { path?: Record<string, unknown> } };
314
+
315
+ /**
316
+ * Creates {@link HeadersInit} containing a single "Authorization" header with a given value.
317
+ *
318
+ * @param token The "Authorization" header value
319
+ * @returns A {@link HeadersInit} object containing a single "Authorization" header with a given value.
320
+ */
321
+ export function authHeader(token: string): HeadersInit {
322
+ return { Authorization: token };
323
+ }
package/src/client.ts CHANGED
@@ -1,19 +1,11 @@
1
1
  import { ApiClient } from "./client/api_client";
2
- import type { IdentityProof, RatchetConfig, EmailOtpResponse } from "./schema_types";
2
+ import type { EmailOtpResponse, IdentityProof, RatchetConfig } from "./schema_types";
3
3
 
4
4
  // used in doc comments
5
5
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
6
6
  import { AddFidoChallenge, TotpChallenge } from "./mfa";
7
7
  import { Org } from "./org";
8
- import type {
9
- CubeSignerResponse,
10
- EnvInterface,
11
- MfaReceipts,
12
- Scope,
13
- SessionData,
14
- SessionInfo,
15
- SessionManager,
16
- } from ".";
8
+ import type { MfaReceipts, SessionData, SessionInfo, SessionManager } from ".";
17
9
  import { Key } from ".";
18
10
 
19
11
  /** Options for logging in with OIDC token */
@@ -122,71 +114,45 @@ export class CubeSignerClient {
122
114
  }
123
115
 
124
116
  /**
125
- * Exchange an OIDC token for a CubeSigner session token.
126
- *
127
- * @param env The environment to log into
128
- * @param orgId The org to log into.
129
- * @param token The OIDC token to exchange
130
- * @param scopes The scopes for the new session
131
- * @param lifetimes Lifetimes of the new session.
132
- * @param mfaReceipt Optional MFA receipt(s)
133
- * @param purpose Optional session description.
134
- * @returns The session data.
117
+ * Create a new OIDC-backed session.
118
+ *
119
+ * Same as {@link ApiClient.oidcSessionCreate}, see its documentation for more details.
120
+ *
121
+ * @param args Request arguments
122
+ * @returns The new session data
135
123
  */
136
124
  static async createOidcSession(
137
- env: EnvInterface,
138
- orgId: string,
139
- token: string,
140
- scopes: Array<Scope>,
141
- lifetimes?: RatchetConfig,
142
- mfaReceipt?: MfaReceipts,
143
- purpose?: string,
144
- ): Promise<CubeSignerResponse<SessionData>> {
145
- return await ApiClient.oidcSessionCreate(
146
- env,
147
- orgId,
148
- token,
149
- scopes,
150
- lifetimes,
151
- mfaReceipt,
152
- purpose,
153
- );
125
+ ...args: Parameters<typeof ApiClient.oidcSessionCreate>
126
+ ): Promise<Awaited<ReturnType<typeof ApiClient.oidcSessionCreate>>> {
127
+ return await ApiClient.oidcSessionCreate(...args);
154
128
  }
155
129
 
156
130
  /**
157
- * Exchange an OIDC token for a proof of authentication.
131
+ * Prove an OIDC identity.
132
+ *
133
+ * Same as {@link ApiClient.identityProveOidc}, see its documentation for more details.
158
134
  *
159
- * @param env The environment to log into
160
- * @param orgId The org id in which to generate proof
161
- * @param token The oidc token
135
+ * @param args Request arguments
162
136
  * @returns Proof of authentication
163
137
  */
164
138
  static async proveOidcIdentity(
165
- env: EnvInterface,
166
- orgId: string,
167
- token: string,
139
+ ...args: Parameters<typeof ApiClient.identityProveOidc>
168
140
  ): Promise<IdentityProof> {
169
- return await ApiClient.identityProveOidc(env, orgId, token);
141
+ return await ApiClient.identityProveOidc(...args);
170
142
  }
171
143
 
172
144
  /**
173
- * Initiates login via Email OTP.
174
- * Returns an unsigned OIDC token and sends an email to the user containing the signature of that token.
175
- * The OIDC token can be reconstructed by appending the signature to the partial token like so:
145
+ * Initialize email OTP authentication.
176
146
  *
177
- * token = partial_token + signature
147
+ * Same as {@link ApiClient.initEmailOtpAuth}, see its documentation for more details.
178
148
  *
179
- * @param env The environment to use
180
- * @param orgId The org to login to
181
- * @param email The email to send the signature to
182
- * @returns The partial OIDC token that must be combined with the signature in the email
149
+ * @param args Request arguments
150
+ * @returns The partial OIDC token that must be combined with the signature in the email
183
151
  */
184
152
  static async initEmailOtpAuth(
185
- env: EnvInterface,
186
- orgId: string,
187
- email: string,
153
+ ...args: Parameters<typeof ApiClient.initEmailOtpAuth>
188
154
  ): Promise<EmailOtpResponse> {
189
- return await ApiClient.initEmailOtpAuth(env, orgId, email);
155
+ return await ApiClient.initEmailOtpAuth(...args);
190
156
  }
191
157
 
192
158
  /**
package/src/fetch.ts CHANGED
@@ -181,7 +181,7 @@ export type FetchResponseSuccessData<T> = Required<FetchResponse<T>>["data"];
181
181
  export function assertOk<T>(resp: FetchResponse<T>): FetchResponseSuccessData<T> {
182
182
  if (!resp.response.ok) {
183
183
  const errResp = resp.error as unknown as ErrorResponse | undefined;
184
- const error = new ErrResponse({
184
+ throw new ErrResponse({
185
185
  requestId: errResp?.request_id,
186
186
  message: errResp?.message,
187
187
  statusText: resp.response?.statusText,
@@ -189,7 +189,6 @@ export function assertOk<T>(resp: FetchResponse<T>): FetchResponseSuccessData<T>
189
189
  url: resp.response?.url,
190
190
  errorCode: errResp?.error_code,
191
191
  });
192
- throw error;
193
192
  }
194
193
  return resp.data!;
195
194
  }
package/src/key.ts CHANGED
@@ -29,6 +29,7 @@ import type {
29
29
  DiffieHellmanResponse,
30
30
  KeyInfoJwt,
31
31
  KeyAttestationQuery,
32
+ BinanceApiProperties,
32
33
  } from "./schema_types";
33
34
  import type {
34
35
  ApiClient,
@@ -99,6 +100,7 @@ export enum Ed25519 {
99
100
  Stellar = "Ed25519StellarAddr",
100
101
  Substrate = "Ed25519SubstrateAddr",
101
102
  Tendermint = "Ed25519TendermintAddr",
103
+ BinanceApi = "Ed25519BinanceApi",
102
104
  Ton = "Ed25519TonAddr",
103
105
  Xrp = "Ed25519XrpAddr",
104
106
  }
@@ -125,6 +127,9 @@ export type BabyJubjub = typeof BabyJubjub;
125
127
  /** Key type */
126
128
  export type KeyType = Secp256k1 | Bls | Ed25519 | Mnemonic | Stark | P256 | BabyJubjub;
127
129
 
130
+ /** The type representing all different kinds of key properties. */
131
+ export type KeyPropertiesPatch = { kind: "BinanceApi" } & BinanceApiProperties;
132
+
128
133
  /**
129
134
  * A representation of a signing key.
130
135
  */
@@ -265,6 +270,23 @@ export class Key {
265
270
  return await this.update({ metadata }, mfaReceipt);
266
271
  }
267
272
 
273
+ /**
274
+ * Set key properties. Each field in the provided patch is independent: missing
275
+ * means leave alone, `null` clears, a value sets. Sending `null` for the whole
276
+ * field clears all properties on the key.
277
+ *
278
+ * @param patch Type-specific properties
279
+ * @param mfaReceipt Optional MFA receipt(s)
280
+ * @throws if MFA is required and no receipts are provided
281
+ * @returns The updated key info
282
+ */
283
+ async setProperties(
284
+ patch: KeyPropertiesPatch | null,
285
+ mfaReceipt?: MfaReceipts,
286
+ ): Promise<KeyInfo> {
287
+ return await this.update({ properties: patch }, mfaReceipt);
288
+ }
289
+
268
290
  /**
269
291
  * Retrieves the existing metadata, asserts that it is an object (throws if it is not),
270
292
  * then sets the value of the {@link name} property in that object to {@link value},
@@ -820,6 +842,8 @@ export function fromSchemaKeyType(ty: SchemaKeyType): KeyType {
820
842
  return Ed25519.Tendermint;
821
843
  case "Ed25519TonAddr":
822
844
  return Ed25519.Ton;
845
+ case "Ed25519BinanceApi":
846
+ return Ed25519.BinanceApi;
823
847
  case "Stark":
824
848
  return Stark;
825
849
  case "Mnemonic":