@coinbase/cdp-api-client 0.0.116 → 0.0.117

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.
@@ -1,4 +1,4 @@
1
- var r = { exports: {} };
1
+ var r = {};
2
2
  export {
3
- r as __module
3
+ r as __exports
4
4
  };
@@ -1,4 +1,4 @@
1
- var r = {};
1
+ var e = { exports: {} };
2
2
  export {
3
- r as __exports
3
+ e as __module
4
4
  };
@@ -1,4 +1,4 @@
1
- var e = { exports: {} };
1
+ var r = { exports: {} };
2
2
  export {
3
- e as __module
3
+ r as __module
4
4
  };
@@ -1,2 +1,2 @@
1
- import { __require as r } from "./index17.js";
1
+ import { __require as r } from "./index12.js";
2
2
  r();
@@ -1,4 +1,4 @@
1
- const o = "0.0.116";
1
+ const o = "0.0.117";
2
2
  export {
3
3
  o as VERSION
4
4
  };
@@ -1,93 +1,93 @@
1
1
  import { Analytics as o } from "./index2.js";
2
2
  import "./index3.js";
3
- import c from "axios";
4
- import { ERROR_DOCS_PAGE_URL as h } from "./index9.js";
5
- import { UnknownApiError as R, HttpErrorType as u, isOpenAPIError as A, APIError as d, UnknownError as k } from "./index7.js";
3
+ import h from "axios";
4
+ import { ERROR_DOCS_PAGE_URL as l } from "./index9.js";
5
+ import { UnknownApiError as k, HttpErrorType as u, isOpenAPIError as _, APIError as d, UnknownError as y } from "./index7.js";
6
6
  const w = () => typeof window < "u" && typeof document < "u";
7
- let a = c.create({
7
+ let n = h.create({
8
8
  baseURL: "https://api.cdp.coinbase.com/platform"
9
9
  }), i = null;
10
- const O = (t) => {
11
- if (a = c.create({
10
+ const N = (t) => {
11
+ if (n = h.create({
12
12
  baseURL: t.basePath || "https://api.cdp.coinbase.com/platform",
13
13
  // Only enable cookies in browser environments where they're supported
14
14
  withCredentials: w()
15
- }), a.interceptors.request.use(async (r) => {
16
- const e = U(r), s = f(r);
17
- if (!i || v(s.pathname) || _(s.pathname) && !await i.isSignedIn() || !I(s.pathname))
15
+ }), n.interceptors.request.use(async (r) => {
16
+ const e = j(r), s = m(r);
17
+ if (!i || v(s.pathname) || A(s.pathname) && !await i.isSignedIn() || !C(s.pathname))
18
18
  return r;
19
- const n = await i.getXWalletAuth({
19
+ const a = await i.getXWalletAuth({
20
20
  requestMethod: e,
21
21
  requestHost: s.host,
22
22
  requestPath: s.pathname,
23
23
  requestData: r.data
24
24
  });
25
- return n && (r.headers["X-Wallet-Auth"] = n), r;
26
- }), a.interceptors.request.use(async (r) => {
27
- const e = f(r);
28
- if (!i || v(e.pathname) || _(e.pathname) && !await i.isSignedIn())
25
+ return a && (r.headers["X-Wallet-Auth"] = a), r;
26
+ }), n.interceptors.request.use(async (r) => {
27
+ const e = m(r);
28
+ if (!i || v(e.pathname) || A(e.pathname) && !await i.isSignedIn())
29
29
  return r;
30
30
  const s = await i.getToken();
31
31
  return s && s !== "" && (r.headers.Authorization = `Bearer ${s}`), r;
32
32
  }), !w()) {
33
33
  const r = t.platform ? `CDP/reactnative/${t.platform}` : "CDP/reactnative";
34
- a.interceptors.request.use(async (e) => {
34
+ n.interceptors.request.use(async (e) => {
35
35
  let s = e.headers["User-Agent"];
36
36
  return s = s ? `${s} ${r}` : r, e.headers["User-Agent"] = s, e;
37
37
  });
38
38
  }
39
- t.refreshTokenStorage && P(t.refreshTokenStorage), t.appAttestation && y(t.appAttestation, t.platform), t.debugging && (a.interceptors.request.use((r) => (console.log("Request:", r), r)), a.interceptors.response.use((r) => (console.log("Response:", r), r)));
40
- }, D = (t) => {
39
+ t.refreshTokenStorage && b(t.refreshTokenStorage, t.retryTokenReads ?? !1), t.appAttestation && g(t.appAttestation, t.platform), t.debugging && (n.interceptors.request.use((r) => (console.log("Request:", r), r)), n.interceptors.response.use((r) => (console.log("Response:", r), r)));
40
+ }, W = (t) => {
41
41
  i = t;
42
- }, y = (t, r) => {
43
- a.interceptors.request.use(async (e) => {
44
- const s = f(e);
45
- if (!q(s.pathname) || !t.isEnabled())
42
+ }, g = (t, r) => {
43
+ n.interceptors.request.use(async (e) => {
44
+ const s = m(e);
45
+ if (!M(s.pathname) || !t.isEnabled())
46
46
  return e;
47
47
  try {
48
48
  if (r === "ios") {
49
- const n = s.pathname.match(/\/projects\/([^/]+)\//);
50
- if (!n || !n[1])
49
+ const a = s.pathname.match(/\/projects\/([^/]+)\//);
50
+ if (!a || !a[1])
51
51
  return e;
52
- const g = `/v2/embedded-wallet-api/projects/${n[1]}/attestation/challenge`, l = (await a.post(g)).data.challenge;
53
- if (!l)
54
- return console.warn("Failed to fetch assertion challenge"), e;
55
- const p = await t.generateAssertion(l);
52
+ const E = `/v2/embedded-wallet-api/projects/${a[1]}/attestation/challenge`, p = (await n.post(E)).data.challenge;
56
53
  if (!p)
54
+ return console.warn("Failed to fetch assertion challenge"), e;
55
+ const f = await t.generateAssertion(p);
56
+ if (!f)
57
57
  return e;
58
- e.headers["X-App-Attestation-Assertion"] = p.assertion, e.headers["X-App-Attestation-Key-ID"] = p.keyId, e.headers["X-App-Attestation-Challenge"] = l;
58
+ e.headers["X-App-Attestation-Assertion"] = f.assertion, e.headers["X-App-Attestation-Key-ID"] = f.keyId, e.headers["X-App-Attestation-Challenge"] = p;
59
59
  } else {
60
- const n = await t.generateAssertion(JSON.stringify(e.data));
61
- if (!n)
60
+ const a = await t.generateAssertion(JSON.stringify(e.data));
61
+ if (!a)
62
62
  return e;
63
- e.headers["X-Integrity-Token"] = n.assertion, e.headers["X-Package-Name"] = t.appIdentifier;
63
+ e.headers["X-Integrity-Token"] = a.assertion, e.headers["X-Package-Name"] = t.appIdentifier;
64
64
  }
65
65
  return e;
66
- } catch (n) {
66
+ } catch (a) {
67
67
  throw new Error(
68
- `App attestation required but assertion generation failed: ${n instanceof Error ? n.message : String(n)}`
68
+ `App attestation required but assertion generation failed: ${a instanceof Error ? a.message : String(a)}`
69
69
  );
70
70
  }
71
71
  });
72
- }, E = (t, r) => ({
72
+ }, T = (t, r) => ({
73
73
  ...t,
74
74
  headers: {
75
75
  ...t.headers || {},
76
76
  "X-Idempotency-Key": r
77
77
  }
78
78
  }), z = async (t, r) => {
79
- $(t), r && r !== "" && (t = E(t, r));
79
+ q(t), r && r !== "" && (t = T(t, r));
80
80
  try {
81
- return (await a(t)).data;
81
+ return (await n(t)).data;
82
82
  } catch (e) {
83
- if (c.isAxiosError(e) && !e.response)
84
- throw new R(
83
+ if (h.isAxiosError(e) && !e.response)
84
+ throw new k(
85
85
  u.unknown,
86
86
  e.cause instanceof Error ? e.cause.message : e.message,
87
87
  e.cause
88
88
  );
89
- if (c.isAxiosError(e) && e.response) {
90
- if (A(e.response.data))
89
+ if (h.isAxiosError(e) && e.response) {
90
+ if (_(e.response.data))
91
91
  throw new d(
92
92
  e.response.status,
93
93
  e.response.data.errorType,
@@ -105,7 +105,7 @@ const O = (t) => {
105
105
  u.unauthorized,
106
106
  "Unauthorized.",
107
107
  void 0,
108
- `${h}#unauthorized`,
108
+ `${l}#unauthorized`,
109
109
  e.cause
110
110
  );
111
111
  case 404:
@@ -114,7 +114,7 @@ const O = (t) => {
114
114
  u.not_found,
115
115
  "API not found.",
116
116
  void 0,
117
- `${h}#not_found`,
117
+ `${l}#not_found`,
118
118
  e.cause
119
119
  );
120
120
  case 502:
@@ -123,7 +123,7 @@ const O = (t) => {
123
123
  u.bad_gateway,
124
124
  "Bad gateway.",
125
125
  void 0,
126
- `${h}`,
126
+ `${l}`,
127
127
  e.cause
128
128
  );
129
129
  case 503:
@@ -132,123 +132,122 @@ const O = (t) => {
132
132
  u.service_unavailable,
133
133
  "Service unavailable. Please try again later.",
134
134
  void 0,
135
- `${h}`,
135
+ `${l}`,
136
136
  e.cause
137
137
  );
138
138
  default: {
139
- let n = "";
139
+ let a = "";
140
140
  if (e.response.data)
141
141
  try {
142
- n = JSON.stringify(e.response.data);
142
+ a = JSON.stringify(e.response.data);
143
143
  } catch {
144
- n = String(e.response.data);
144
+ a = String(e.response.data);
145
145
  }
146
- const m = n ? `An unexpected error occurred: ${n}` : "An unexpected error occurred.";
146
+ const c = a ? `An unexpected error occurred: ${a}` : "An unexpected error occurred.";
147
147
  throw new d(
148
148
  s,
149
149
  u.unexpected_error,
150
- m,
150
+ c,
151
151
  void 0,
152
- `${h}`,
152
+ `${l}`,
153
153
  e.cause
154
154
  );
155
155
  }
156
156
  }
157
157
  }
158
158
  }
159
- throw new k("Something went wrong.", e instanceof Error ? e : void 0);
159
+ throw new y("Something went wrong.", e instanceof Error ? e : void 0);
160
+ }
161
+ }, R = 4, P = [25, 50, 100], S = async (t) => {
162
+ let r = null;
163
+ for (let e = 0; e < R; e++) {
164
+ if (r = await t.getRefreshToken(), r)
165
+ return { token: r, attempt: e };
166
+ const s = P[e];
167
+ s !== void 0 && await new Promise((a) => setTimeout(a, s));
160
168
  }
161
- }, P = (t) => {
162
- a.interceptors.response.use(
163
- async (r) => {
169
+ return { token: r, attempt: R - 1 };
170
+ }, b = (t, r) => {
171
+ n.interceptors.response.use(
172
+ async (e) => {
164
173
  try {
165
- if (b(r)) {
174
+ if (I(e)) {
166
175
  o.sendSessionRefreshEvent({
167
176
  name: "refresh_token_response"
168
177
  });
169
- const e = r.data?.refreshToken;
170
- e && (o.sendSessionRefreshEvent({
178
+ const s = e.data?.refreshToken;
179
+ s && (o.sendSessionRefreshEvent({
171
180
  name: "refresh_token_received"
172
181
  }), await Promise.race([
173
- t.setRefreshToken(e),
182
+ t.setRefreshToken(s),
174
183
  new Promise(
175
- (s, n) => setTimeout(() => n(new Error("setRefreshToken timed out after 5000ms")), 5e3)
184
+ (a, c) => setTimeout(() => c(new Error("setRefreshToken timed out after 5000ms")), 5e3)
176
185
  )
177
186
  ]), o.sendSessionRefreshEvent({
178
187
  name: "refresh_token_stored"
179
188
  }));
180
189
  }
181
- } catch (e) {
182
- const s = e instanceof Error ? e.message : String(e);
190
+ } catch (s) {
191
+ const a = s instanceof Error ? s.message : String(s);
183
192
  o.sendSessionRefreshEvent({
184
193
  name: "refresh_token_store_failed",
185
- error_message: s
186
- }), console.warn("Failed to store refresh token:", e);
194
+ error_message: a
195
+ }), console.warn("Failed to store refresh token:", s);
187
196
  }
188
- return r;
197
+ return e;
189
198
  },
190
- (r) => Promise.reject(r)
191
- ), a.interceptors.request.use(async (r) => {
199
+ (e) => Promise.reject(e)
200
+ ), n.interceptors.request.use(async (e) => {
192
201
  try {
193
- if (T(r.url)) {
194
- const e = await t.getRefreshToken();
195
- e || setTimeout(() => {
196
- t.getRefreshToken().then((s) => {
197
- s && o.sendSessionRefreshEvent({
198
- name: "refresh_token_received_after_missing"
199
- });
200
- }).catch((s) => {
201
- const n = s instanceof Error ? s.message : String(s);
202
- o.sendSessionRefreshEvent({
203
- name: "refresh_token_retrieve_failed_after_missing",
204
- error_message: n
205
- });
206
- });
207
- }, 10), e ? (o.sendSessionRefreshEvent({
208
- name: "refresh_token_retrieved"
209
- }), r.data = {
210
- ...r.data,
211
- refreshToken: e
202
+ if (U(e.url)) {
203
+ const { token: s, attempt: a } = r ? await S(t) : { token: await t.getRefreshToken(), attempt: 0 };
204
+ s ? (o.sendSessionRefreshEvent({
205
+ name: "refresh_token_retrieved",
206
+ attempt: a
207
+ }), e.data = {
208
+ ...e.data,
209
+ refreshToken: s
212
210
  }) : o.sendSessionRefreshEvent({
213
- name: "refresh_token_missing"
211
+ name: "refresh_token_missing",
212
+ attempt: a
214
213
  });
215
214
  }
216
- S(r.url) && (o.sendSessionRefreshEvent({
215
+ $(e.url) && (o.sendSessionRefreshEvent({
217
216
  name: "refresh_token_removing_token"
218
217
  }), await t.removeRefreshToken());
219
- } catch (e) {
220
- const s = e instanceof Error ? e.message : String(e);
218
+ } catch (s) {
219
+ const a = s instanceof Error ? s.message : String(s);
221
220
  o.sendSessionRefreshEvent({
222
221
  name: "refresh_token_retrieve_failed",
223
- error_message: s
224
- }), console.warn("Failed to retrieve refresh token:", e);
222
+ error_message: a
223
+ }), console.warn("Failed to retrieve refresh token:", s);
225
224
  }
226
- return r;
225
+ return e;
227
226
  });
228
- }, S = (t) => t ? /^\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/logout$/.test(t) : !1, T = (t) => t ? /^\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(refresh|logout)$/.test(t) : !1, b = (t) => {
227
+ }, $ = (t) => t ? /^\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/logout$/.test(t) : !1, U = (t) => t ? /^\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(refresh|logout)$/.test(t) : !1, I = (t) => {
229
228
  const r = t.config.url;
230
229
  return r ? /^\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(verify\/(email|sms|siwe|oauth\/.*)|refresh)$/.test(
231
230
  r
232
231
  ) : !1;
233
- }, $ = (t) => {
234
- if (!a.getUri() || a.getUri() === "")
232
+ }, q = (t) => {
233
+ if (!n.getUri() || n.getUri() === "")
235
234
  throw new Error("CDP client URI not configured. Call configure() first.");
236
235
  if (!t.url || t.url === "")
237
236
  throw new Error("AxiosRequestConfig URL is empty. This should never happen.");
238
237
  if (!t.method || t.method === "")
239
238
  throw new Error("AxiosRequestConfig method is empty. This should never happen.");
240
- }, U = (t) => t.method?.toString().toUpperCase() || "GET", f = (t) => {
239
+ }, j = (t) => t.method?.toString().toUpperCase() || "GET", m = (t) => {
241
240
  if (!t.url)
242
241
  throw new Error("URL is required for authentication");
243
- const r = a.getUri() + t.url;
242
+ const r = n.getUri() + t.url;
244
243
  return new URL(r);
245
244
  }, v = (t) => {
246
- const r = /^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(refresh|logout)$/, e = /^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(mfa)$/, s = /^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/config$/, n = /^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/attestation\/(challenge|register)$/;
247
- return r.test(t) || e.test(t) || s.test(t) || n.test(t);
248
- }, I = (t) => !/^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/custom\/authenticate$/.test(t), _ = (t) => {
245
+ const r = /^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(refresh|logout)$/, e = /^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(mfa)$/, s = /^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/config$/, a = /^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/attestation\/(challenge|register)$/;
246
+ return r.test(t) || e.test(t) || s.test(t) || a.test(t);
247
+ }, C = (t) => !/^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/custom\/authenticate$/.test(t), A = (t) => {
249
248
  const r = /^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(init)$/, e = /^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/verify\//;
250
249
  return r.test(t) || e.test(t);
251
- }, q = (t) => [
250
+ }, M = (t) => [
252
251
  // Auth flows: prevent account takeover on mobile clients
253
252
  /\/auth\/verify\//,
254
253
  // VerifyEmailAuthentication, VerifySmsAuthentication, VerifyOAuthCode, VerifyOAuthEndUserIdentity
@@ -257,6 +256,6 @@ const O = (t) => {
257
256
  ].some((e) => e.test(t));
258
257
  export {
259
258
  z as cdpApiClient,
260
- O as configureCdpApiClient,
261
- D as setAuthManager
259
+ N as configureCdpApiClient,
260
+ W as setAuthManager
262
261
  };
@@ -203,6 +203,13 @@ export declare type CdpOptions = {
203
203
  * relying on HTTP cookies.
204
204
  */
205
205
  refreshTokenStorage?: RefreshTokenStorage;
206
+ /**
207
+ * Whether to retry reading the refresh token when the initial read is empty.
208
+ * Enable on native platforms whose secure storage can transiently return empty
209
+ * on the first read after a cold start or app resume; leave off for web, where
210
+ * reads are synchronous and have no such race. Defaults to false.
211
+ */
212
+ retryTokenReads?: boolean;
206
213
  /**
207
214
  * Optional app attestation for native mobile platforms.
208
215
  * When provided, adds assertion headers to sensitive API calls to prove app integrity.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinbase/cdp-api-client",
3
- "version": "0.0.116",
3
+ "version": "0.0.117",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**",