@coinbase/cdp-api-client 0.0.91 → 0.0.93

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,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.91";
1
+ const o = "0.0.93";
2
2
  export {
3
3
  o as VERSION
4
4
  };
@@ -1,69 +1,89 @@
1
1
  import { Analytics as o } from "./index2.js";
2
2
  import "./index3.js";
3
- import h from "axios";
3
+ import l from "axios";
4
4
  import { ERROR_DOCS_PAGE_URL as c } from "./index9.js";
5
- import { UnknownApiError as v, HttpErrorType as u, isOpenAPIError as R, APIError as d, UnknownError as g } from "./index8.js";
6
- const l = () => typeof window < "u" && typeof document < "u";
7
- let n = h.create({
5
+ import { UnknownApiError as g, HttpErrorType as u, isOpenAPIError as R, APIError as d, UnknownError as y } from "./index8.js";
6
+ const w = () => typeof window < "u" && typeof document < "u";
7
+ let n = l.create({
8
8
  baseURL: "https://api.cdp.coinbase.com/platform"
9
9
  }), i = null;
10
- const x = (r) => {
11
- n = h.create({
10
+ const X = (r) => {
11
+ n = l.create({
12
12
  baseURL: r.basePath || "https://api.cdp.coinbase.com/platform",
13
13
  // Only enable cookies in browser environments where they're supported
14
- withCredentials: l()
15
- }), n.interceptors.request.use(async (t) => {
16
- const e = T(t), s = p(t);
17
- if (!i || f(s.pathname) || m(s.pathname) && !await i.isSignedIn() || !S(s.pathname))
18
- return t;
14
+ withCredentials: w()
15
+ }), n.interceptors.request.use(async (e) => {
16
+ const t = U(e), s = m(e);
17
+ if (!i || v(s.pathname) || A(s.pathname) && !await i.isSignedIn() || !$(s.pathname))
18
+ return e;
19
19
  const a = await i.getXWalletAuth({
20
- requestMethod: e,
20
+ requestMethod: t,
21
21
  requestHost: s.host,
22
22
  requestPath: s.pathname,
23
- requestData: t.data
23
+ requestData: e.data
24
24
  });
25
- return a && (t.headers["X-Wallet-Auth"] = a), t;
26
- }), n.interceptors.request.use(async (t) => {
27
- const e = p(t);
28
- if (!i || f(e.pathname) || m(e.pathname) && !await i.isSignedIn())
29
- return t;
25
+ return a && (e.headers["X-Wallet-Auth"] = a), e;
26
+ }), n.interceptors.request.use(async (e) => {
27
+ const t = m(e);
28
+ if (!i || v(t.pathname) || A(t.pathname) && !await i.isSignedIn())
29
+ return e;
30
30
  const s = await i.getToken();
31
- return s && s !== "" && (t.headers.Authorization = `Bearer ${s}`), t;
32
- }), l() || n.interceptors.request.use(async (t) => {
33
- let e = t.headers["User-Agent"];
34
- return e = e ? `${e} CDP/reactnative` : "CDP/reactnative", t.headers["User-Agent"] = e, t;
35
- }), r.refreshTokenStorage && _(r.refreshTokenStorage), r.debugging && (n.interceptors.request.use((t) => (console.log("Request:", t), t)), n.interceptors.response.use((t) => (console.log("Response:", t), t)));
36
- }, j = (r) => {
31
+ return s && s !== "" && (e.headers.Authorization = `Bearer ${s}`), e;
32
+ }), w() || n.interceptors.request.use(async (e) => {
33
+ let t = e.headers["User-Agent"];
34
+ return t = t ? `${t} CDP/reactnative` : "CDP/reactnative", e.headers["User-Agent"] = t, e;
35
+ }), r.refreshTokenStorage && _(r.refreshTokenStorage), r.generateAssertion && k(r.generateAssertion), r.debugging && (n.interceptors.request.use((e) => (console.log("Request:", e), e)), n.interceptors.response.use((e) => (console.log("Response:", e), e)));
36
+ }, O = (r) => {
37
37
  i = r;
38
- }, k = (r, t) => ({
38
+ }, k = (r) => {
39
+ n.interceptors.request.use(async (e) => {
40
+ const t = m(e);
41
+ if (!I(t.pathname))
42
+ return e;
43
+ try {
44
+ const s = t.pathname.match(/\/projects\/([^/]+)\//);
45
+ if (!s || !s[1])
46
+ return e;
47
+ const p = `/v2/embedded-wallet-api/projects/${s[1]}/attestation/challenge`, f = (await n.post(p)).data.challenge;
48
+ if (!f)
49
+ return console.warn("Failed to fetch assertion challenge"), e;
50
+ const h = await r(f);
51
+ return h.keyId ? (e.headers["X-App-Attestation-Assertion"] = h.assertion, e.headers["X-App-Attestation-Key-ID"] = h.keyId, e.headers["X-App-Attestation-Challenge"] = f) : e.headers["X-Integrity-Token"] = h.assertion, e;
52
+ } catch (s) {
53
+ throw new Error(
54
+ `App attestation required but assertion generation failed: ${s instanceof Error ? s.message : String(s)}`
55
+ );
56
+ }
57
+ });
58
+ }, E = (r, e) => ({
39
59
  ...r,
40
60
  headers: {
41
61
  ...r.headers || {},
42
- "X-Idempotency-Key": t
62
+ "X-Idempotency-Key": e
43
63
  }
44
- }), I = async (r, t) => {
45
- P(r), t && t !== "" && (r = k(r, t));
64
+ }), D = async (r, e) => {
65
+ S(r), e && e !== "" && (r = E(r, e));
46
66
  try {
47
67
  return (await n(r)).data;
48
- } catch (e) {
49
- if (h.isAxiosError(e) && !e.response)
50
- throw new v(
68
+ } catch (t) {
69
+ if (l.isAxiosError(t) && !t.response)
70
+ throw new g(
51
71
  u.unknown,
52
- e.cause instanceof Error ? e.cause.message : e.message,
53
- e.cause
72
+ t.cause instanceof Error ? t.cause.message : t.message,
73
+ t.cause
54
74
  );
55
- if (h.isAxiosError(e) && e.response) {
56
- if (R(e.response.data))
75
+ if (l.isAxiosError(t) && t.response) {
76
+ if (R(t.response.data))
57
77
  throw new d(
58
- e.response.status,
59
- e.response.data.errorType,
60
- e.response.data.errorMessage,
61
- e.response.data.correlationId,
62
- e.response.data.errorLink,
63
- e.cause
78
+ t.response.status,
79
+ t.response.data.errorType,
80
+ t.response.data.errorMessage,
81
+ t.response.data.correlationId,
82
+ t.response.data.errorLink,
83
+ t.cause
64
84
  );
65
85
  {
66
- const s = e.response.status;
86
+ const s = t.response.status;
67
87
  switch (s) {
68
88
  case 401:
69
89
  throw new d(
@@ -72,7 +92,7 @@ const x = (r) => {
72
92
  "Unauthorized.",
73
93
  void 0,
74
94
  `${c}#unauthorized`,
75
- e.cause
95
+ t.cause
76
96
  );
77
97
  case 404:
78
98
  throw new d(
@@ -81,7 +101,7 @@ const x = (r) => {
81
101
  "API not found.",
82
102
  void 0,
83
103
  `${c}#not_found`,
84
- e.cause
104
+ t.cause
85
105
  );
86
106
  case 502:
87
107
  throw new d(
@@ -90,7 +110,7 @@ const x = (r) => {
90
110
  "Bad gateway.",
91
111
  void 0,
92
112
  `${c}`,
93
- e.cause
113
+ t.cause
94
114
  );
95
115
  case 503:
96
116
  throw new d(
@@ -99,47 +119,47 @@ const x = (r) => {
99
119
  "Service unavailable. Please try again later.",
100
120
  void 0,
101
121
  `${c}`,
102
- e.cause
122
+ t.cause
103
123
  );
104
124
  default: {
105
125
  let a = "";
106
- if (e.response.data)
126
+ if (t.response.data)
107
127
  try {
108
- a = JSON.stringify(e.response.data);
128
+ a = JSON.stringify(t.response.data);
109
129
  } catch {
110
- a = String(e.response.data);
130
+ a = String(t.response.data);
111
131
  }
112
- const w = a ? `An unexpected error occurred: ${a}` : "An unexpected error occurred.";
132
+ const p = a ? `An unexpected error occurred: ${a}` : "An unexpected error occurred.";
113
133
  throw new d(
114
134
  s,
115
135
  u.unexpected_error,
116
- w,
136
+ p,
117
137
  void 0,
118
138
  `${c}`,
119
- e.cause
139
+ t.cause
120
140
  );
121
141
  }
122
142
  }
123
143
  }
124
144
  }
125
- throw new g(
145
+ throw new y(
126
146
  "Something went wrong. Please reach out at https://discord.com/channels/1220414409550336183/1271495764580896789 for help.",
127
- e instanceof Error ? e : void 0
147
+ t instanceof Error ? t : void 0
128
148
  );
129
149
  }
130
150
  }, _ = (r) => {
131
151
  n.interceptors.response.use(
132
- async (t) => {
152
+ async (e) => {
133
153
  try {
134
- if (E(t)) {
154
+ if (T(e)) {
135
155
  o.sendSessionRefreshEvent({
136
156
  name: "refresh_token_response"
137
157
  });
138
- const e = t.data?.refreshToken;
139
- e && (o.sendSessionRefreshEvent({
158
+ const t = e.data?.refreshToken;
159
+ t && (o.sendSessionRefreshEvent({
140
160
  name: "refresh_token_received"
141
161
  }), await Promise.race([
142
- r.setRefreshToken(e),
162
+ r.setRefreshToken(t),
143
163
  new Promise(
144
164
  (s, a) => setTimeout(() => a(new Error("setRefreshToken timed out after 5000ms")), 5e3)
145
165
  )
@@ -147,65 +167,71 @@ const x = (r) => {
147
167
  name: "refresh_token_stored"
148
168
  }));
149
169
  }
150
- } catch (e) {
151
- const s = e instanceof Error ? e.message : String(e);
170
+ } catch (t) {
171
+ const s = t instanceof Error ? t.message : String(t);
152
172
  o.sendSessionRefreshEvent({
153
173
  name: "refresh_token_store_failed",
154
174
  error_message: s
155
- }), console.warn("Failed to store refresh token:", e);
175
+ }), console.warn("Failed to store refresh token:", t);
156
176
  }
157
- return t;
177
+ return e;
158
178
  },
159
- (t) => Promise.reject(t)
160
- ), n.interceptors.request.use(async (t) => {
179
+ (e) => Promise.reject(e)
180
+ ), n.interceptors.request.use(async (e) => {
161
181
  try {
162
- if (A(t.url)) {
163
- const e = await r.getRefreshToken();
164
- e ? (o.sendSessionRefreshEvent({
182
+ if (b(e.url)) {
183
+ const t = await r.getRefreshToken();
184
+ t ? (o.sendSessionRefreshEvent({
165
185
  name: "refresh_token_retrieved"
166
- }), t.data = {
167
- ...t.data,
168
- refreshToken: e
186
+ }), e.data = {
187
+ ...e.data,
188
+ refreshToken: t
169
189
  }) : o.sendSessionRefreshEvent({
170
190
  name: "refresh_token_missing"
171
191
  });
172
192
  }
173
- y(t.url) && await r.removeRefreshToken();
174
- } catch (e) {
175
- const s = e instanceof Error ? e.message : String(e);
193
+ P(e.url) && await r.removeRefreshToken();
194
+ } catch (t) {
195
+ const s = t instanceof Error ? t.message : String(t);
176
196
  o.sendSessionRefreshEvent({
177
197
  name: "refresh_token_retrieve_failed",
178
198
  error_message: s
179
- }), console.warn("Failed to retrieve refresh token:", e);
199
+ }), console.warn("Failed to retrieve refresh token:", t);
180
200
  }
181
- return t;
201
+ return e;
182
202
  });
183
- }, y = (r) => r ? /^\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/logout$/.test(r) : !1, A = (r) => r ? /^\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(refresh|logout)$/.test(r) : !1, E = (r) => {
184
- const t = r.config.url;
185
- return t ? /^\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(verify\/(email|sms|oauth\/.*)|refresh)$/.test(
186
- t
203
+ }, P = (r) => r ? /^\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/logout$/.test(r) : !1, b = (r) => r ? /^\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(refresh|logout)$/.test(r) : !1, T = (r) => {
204
+ const e = r.config.url;
205
+ return e ? /^\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(verify\/(email|sms|oauth\/.*)|refresh)$/.test(
206
+ e
187
207
  ) : !1;
188
- }, P = (r) => {
208
+ }, S = (r) => {
189
209
  if (!n.getUri() || n.getUri() === "")
190
210
  throw new Error("CDP client URI not configured. Call configure() first.");
191
211
  if (!r.url || r.url === "")
192
212
  throw new Error("AxiosRequestConfig URL is empty. This should never happen.");
193
213
  if (!r.method || r.method === "")
194
214
  throw new Error("AxiosRequestConfig method is empty. This should never happen.");
195
- }, T = (r) => r.method?.toString().toUpperCase() || "GET", p = (r) => {
215
+ }, U = (r) => r.method?.toString().toUpperCase() || "GET", m = (r) => {
196
216
  if (!r.url)
197
217
  throw new Error("URL is required for authentication");
198
- const t = n.getUri() + r.url;
199
- return new URL(t);
200
- }, f = (r) => {
201
- const t = /^\/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$/;
202
- return t.test(r) || e.test(r) || s.test(r);
203
- }, S = (r) => !/^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/custom\/authenticate$/.test(r), m = (r) => {
204
- const t = /^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(init)$/, e = /^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/verify\//;
205
- return t.test(r) || e.test(r);
206
- };
218
+ const e = n.getUri() + r.url;
219
+ return new URL(e);
220
+ }, v = (r) => {
221
+ const e = /^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(refresh|logout)$/, t = /^\/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)$/;
222
+ return e.test(r) || t.test(r) || s.test(r) || a.test(r);
223
+ }, $ = (r) => !/^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/custom\/authenticate$/.test(r), A = (r) => {
224
+ const e = /^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(init)$/, t = /^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/verify\//;
225
+ return e.test(r) || t.test(r);
226
+ }, I = (r) => [
227
+ // Auth flows: prevent account takeover on mobile clients
228
+ /\/auth\/verify\//,
229
+ // VerifyEmailAuthentication, VerifySmsAuthentication, VerifyOAuthCode, VerifyOAuthEndUserIdentity
230
+ /\/auth\/refresh$/
231
+ // RefreshAccessToken
232
+ ].some((t) => t.test(r));
207
233
  export {
208
- I as cdpApiClient,
209
- x as configureCdpApiClient,
210
- j as setAuthManager
234
+ D as cdpApiClient,
235
+ X as configureCdpApiClient,
236
+ O as setAuthManager
211
237
  };
@@ -320,6 +320,10 @@ export declare type CdpOptions = {
320
320
  debugging?: boolean;
321
321
  basePath?: string;
322
322
  refreshTokenStorage?: RefreshTokenStorage;
323
+ generateAssertion?: (clientData: string) => Promise<{
324
+ assertion: string;
325
+ keyId?: string;
326
+ }>;
323
327
  };
324
328
 
325
329
  export declare interface CommonSwapResponse {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinbase/cdp-api-client",
3
- "version": "0.0.91",
3
+ "version": "0.0.93",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**",