@cubist-labs/cubesigner-sdk 0.4.241 → 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.
@@ -252,7 +252,7 @@ export class BaseClient extends EventEmitter<ClientEvents> {
252
252
  return status >= 500 && status < 600;
253
253
  },
254
254
  });
255
- // 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)
256
256
  return assertOk(resp);
257
257
  } catch (e) {
258
258
  if (e instanceof ErrResponse) {
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":
package/src/response.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { MfaVote, EnvInterface, MfaReceipts, MfaRequired } from ".";
2
2
  import { CubeSignerClient, isManyMfaReceipts } from ".";
3
3
  import { encodeToBase64Url } from "./util";
4
- import type { AcceptedResponse } from "./schema_types";
4
+ import type { AcceptedResponse, AcceptedValue, BinanceDryRun, SignDryRun } from "./schema_types";
5
5
 
6
6
  /**
7
7
  * Response type, which can be either a value of type {@link U}
@@ -29,46 +29,95 @@ export type MapFn<U, V> = (u: U) => V;
29
29
  * @returns Response whose value for status code 200 is mapped from U to V
30
30
  */
31
31
  export function mapResponse<U, V>(resp: Response<U>, mapFn: MapFn<U, V>): Response<V> {
32
- if ((resp as AcceptedResponse).accepted?.MfaRequired) {
32
+ if (asAccepted(resp) !== undefined) {
33
33
  return resp as AcceptedResponse;
34
34
  } else {
35
35
  return mapFn(resp as U);
36
36
  }
37
37
  }
38
38
 
39
+ /**
40
+ * @param resp The response to check
41
+ * @returns The {@link AcceptedValue} if the response status code is 202.
42
+ */
43
+ function asAccepted<U>(resp: Response<U>): AcceptedValue | undefined {
44
+ const acceptedResp = resp as AcceptedResponse;
45
+ return acceptedResp.error_code === "SignDryRun" || acceptedResp.error_code === "MfaRequired"
46
+ ? (acceptedResp.accepted ?? undefined)
47
+ : undefined;
48
+ }
49
+
39
50
  /**
40
51
  * A response of a CubeSigner request.
41
52
  */
42
53
  export class CubeSignerResponse<U> {
43
54
  readonly #env: EnvInterface;
44
55
  readonly #requestFn: RequestFn<U>;
45
- readonly #resp: U | AcceptedResponse;
56
+ readonly #resp: Response<U>;
57
+
58
+ /**
59
+ * @returns The {@link AcceptedValue} if the response status code is 202.
60
+ */
61
+ asAccepted(): AcceptedValue | undefined {
62
+ return asAccepted(this.#resp);
63
+ }
64
+
65
+ /**
66
+ * @returns The associated {@link MfaRequired} value, if the response status code is 202 and the response indicates that MFA is required.
67
+ */
68
+ asMfaRequired(): MfaRequired | undefined {
69
+ return this.asAccepted()?.MfaRequired ?? undefined;
70
+ }
71
+
46
72
  /**
47
- * Optional MFA id. Only set if there is an MFA request associated with the request
73
+ * @returns The associated {@link SignDryRun} value, if the response status code is 202 and the response is a dry run of a sign operation.
48
74
  */
49
- readonly #mfaRequired?: MfaRequired;
75
+ asSignDryRun(): SignDryRun | undefined {
76
+ return this.asAccepted()?.SignDryRun ?? undefined;
77
+ }
78
+
79
+ /**
80
+ * @returns The associated {@link BinanceDryRun} value, if the response status code is 202 and the response is a dry run of a sign operation.
81
+ */
82
+ asBinanceDryRun(): BinanceDryRun | undefined {
83
+ return this.asAccepted()?.BinanceDryRun ?? undefined;
84
+ }
85
+
86
+ /**
87
+ * @returns Whether this response is a "200 Success" (in which case it is safe to call {@link data})
88
+ */
89
+ isSuccess(): boolean {
90
+ return this.asAccepted() === undefined;
91
+ }
92
+
93
+ /**
94
+ * @returns The underlying {@link MfaRequired} response (if any).
95
+ */
96
+ private get mfaRequired() {
97
+ return this.asAccepted()?.MfaRequired;
98
+ }
50
99
 
51
100
  /** @returns The first MFA id associated with this request (if any) */
52
101
  mfaId(): string | undefined {
53
- return this.#mfaRequired?.id;
102
+ return this.mfaRequired?.id;
54
103
  }
55
104
 
56
105
  /** @returns The MFA ids associated with this request (if any) */
57
106
  mfaIds(): string[] {
58
- return this.#mfaRequired?.ids ?? [];
107
+ return this.mfaRequired?.ids ?? [];
59
108
  }
60
109
 
61
110
  /** @returns True if this request requires an MFA approval */
62
111
  requiresMfa(): boolean {
63
- return this.#mfaRequired !== undefined;
112
+ return this.mfaRequired !== undefined;
64
113
  }
65
114
 
66
115
  /**
67
116
  * @returns Session information to use for any MFA approval requests (if any was included in the response).
68
117
  */
69
118
  async mfaClient(): Promise<CubeSignerClient | undefined> {
70
- if (this.#mfaRequired === undefined) return;
71
- const session = (this.#resp as AcceptedResponse).accepted?.MfaRequired?.session ?? undefined;
119
+ if (this.mfaRequired === undefined) return;
120
+ const session = this.asMfaRequired()?.session ?? undefined;
72
121
  if (session === undefined) return;
73
122
 
74
123
  const env = this.#env;
@@ -76,7 +125,7 @@ export class CubeSignerResponse<U> {
76
125
  env: {
77
126
  "Dev-CubeSignerStack": env,
78
127
  },
79
- org_id: this.#mfaRequired.org_id,
128
+ org_id: this.mfaRequired.org_id,
80
129
  session_exp: session.expiration,
81
130
  session_info: session.session_info,
82
131
  token: session.token,
@@ -86,8 +135,10 @@ export class CubeSignerResponse<U> {
86
135
 
87
136
  /** @returns The response data, if no MFA is required */
88
137
  data(): U {
89
- if (this.requiresMfa()) {
90
- throw new Error("Cannot call `data()` while MFA is required");
138
+ if (!this.isSuccess()) {
139
+ throw new Error(
140
+ "Cannot call `data()` on a 202 Accepted response; use `asMfaRequired()` or `asSignDryRun()`",
141
+ );
91
142
  }
92
143
  return this.#resp as U;
93
144
  }
@@ -131,7 +182,7 @@ export class CubeSignerResponse<U> {
131
182
  return this;
132
183
  }
133
184
 
134
- const mfaOrgId = this.#mfaRequired!.org_id;
185
+ const mfaOrgId = this.mfaRequired!.org_id;
135
186
  const mfaApproval = await client.apiClient.mfaVoteTotp(mfaId, code, vote);
136
187
  const mfaConf = mfaApproval.receipt?.confirmation;
137
188
 
@@ -174,7 +225,7 @@ export class CubeSignerResponse<U> {
174
225
  return this;
175
226
  }
176
227
 
177
- const mfaOrgId = this.#mfaRequired!.org_id;
228
+ const mfaOrgId = this.mfaRequired!.org_id;
178
229
 
179
230
  const mfaApproval = await client.apiClient.mfaVoteCs(mfaId, mfaVote);
180
231
  const mfaConf = mfaApproval.receipt?.confirmation;
@@ -211,11 +262,10 @@ export class CubeSignerResponse<U> {
211
262
  * @param resp The response as returned by the OpenAPI client.
212
263
  * @internal
213
264
  */
214
- protected constructor(env: EnvInterface, requestFn: RequestFn<U>, resp: U | AcceptedResponse) {
265
+ protected constructor(env: EnvInterface, requestFn: RequestFn<U>, resp: Response<U>) {
215
266
  this.#env = env;
216
267
  this.#requestFn = requestFn;
217
268
  this.#resp = resp;
218
- this.#mfaRequired = (this.#resp as AcceptedResponse).accepted?.MfaRequired;
219
269
  }
220
270
 
221
271
  /**