@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.
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
  /**