@coinbase/cdp-api-client 0.0.116 → 0.0.118
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/dist/esm/index10.js +1 -1
- package/dist/esm/index12.js +7 -38
- package/dist/esm/index14.js +358 -67
- package/dist/esm/index15.js +852 -34
- package/dist/esm/index16.js +38 -14
- package/dist/esm/index17.js +2 -8
- package/dist/esm/index18.js +70 -2
- package/dist/esm/index19.js +29 -355
- package/dist/esm/index20.js +14 -852
- package/dist/esm/index3.js +1 -1
- package/dist/esm/index4.js +1 -1
- package/dist/esm/index6.js +149 -124
- package/dist/types/index.d.ts +20 -0
- package/package.json +1 -1
package/dist/esm/index3.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { __require as r } from "./
|
|
1
|
+
import { __require as r } from "./index12.js";
|
|
2
2
|
r();
|
package/dist/esm/index4.js
CHANGED
package/dist/esm/index6.js
CHANGED
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
import { Analytics as
|
|
1
|
+
import { Analytics as i } from "./index2.js";
|
|
2
2
|
import "./index3.js";
|
|
3
|
-
import
|
|
3
|
+
import p from "axios";
|
|
4
4
|
import { ERROR_DOCS_PAGE_URL as h } from "./index9.js";
|
|
5
|
-
import { UnknownApiError as
|
|
6
|
-
const
|
|
7
|
-
let
|
|
5
|
+
import { UnknownApiError as g, HttpErrorType as d, isOpenAPIError as y, APIError as l, UnknownError as T } from "./index7.js";
|
|
6
|
+
const v = () => typeof window < "u" && typeof document < "u";
|
|
7
|
+
let n = p.create({
|
|
8
8
|
baseURL: "https://api.cdp.coinbase.com/platform"
|
|
9
|
-
}),
|
|
10
|
-
const
|
|
11
|
-
if (
|
|
9
|
+
}), c = null;
|
|
10
|
+
const N = (t) => {
|
|
11
|
+
if (n = p.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
|
-
withCredentials:
|
|
15
|
-
}),
|
|
16
|
-
const e =
|
|
17
|
-
if (!
|
|
14
|
+
withCredentials: v()
|
|
15
|
+
}), n.interceptors.request.use(async (r) => {
|
|
16
|
+
const e = C(r), s = w(r);
|
|
17
|
+
if (!c || _(s.pathname) || A(s.pathname) && !await c.isSignedIn() || !O(s.pathname))
|
|
18
18
|
return r;
|
|
19
|
-
const
|
|
19
|
+
const a = await c.getXWalletAuth({
|
|
20
20
|
requestMethod: e,
|
|
21
21
|
requestHost: s.host,
|
|
22
22
|
requestPath: s.pathname,
|
|
23
23
|
requestData: r.data
|
|
24
24
|
});
|
|
25
|
-
return
|
|
26
|
-
}),
|
|
27
|
-
const e =
|
|
28
|
-
if (!
|
|
25
|
+
return a && (r.headers["X-Wallet-Auth"] = a), r;
|
|
26
|
+
}), n.interceptors.request.use(async (r) => {
|
|
27
|
+
const e = w(r);
|
|
28
|
+
if (!c || _(e.pathname) || A(e.pathname) && !await c.isSignedIn())
|
|
29
29
|
return r;
|
|
30
|
-
const s = await
|
|
30
|
+
const s = await c.getToken();
|
|
31
31
|
return s && s !== "" && (r.headers.Authorization = `Bearer ${s}`), r;
|
|
32
|
-
}), !
|
|
32
|
+
}), !v()) {
|
|
33
33
|
const r = t.platform ? `CDP/reactnative/${t.platform}` : "CDP/reactnative";
|
|
34
|
-
|
|
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 &&
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
const s =
|
|
45
|
-
if (!
|
|
39
|
+
t.refreshTokenStorage && U(t.refreshTokenStorage, t.retryTokenReads ?? !1), t.appAttestation && P(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
|
+
}, z = (t) => {
|
|
41
|
+
c = t;
|
|
42
|
+
}, P = (t, r) => {
|
|
43
|
+
n.interceptors.request.use(async (e) => {
|
|
44
|
+
const s = w(e);
|
|
45
|
+
if (!x(s.pathname) || !t.isEnabled())
|
|
46
46
|
return e;
|
|
47
47
|
try {
|
|
48
48
|
if (r === "ios") {
|
|
49
|
-
const
|
|
50
|
-
if (!
|
|
49
|
+
const a = s.pathname.match(/\/projects\/([^/]+)\//);
|
|
50
|
+
if (!a || !a[1])
|
|
51
51
|
return e;
|
|
52
|
-
const
|
|
53
|
-
if (!
|
|
52
|
+
const u = `/v2/embedded-wallet-api/projects/${a[1]}/attestation/challenge`, m = (await n.post(u)).data.challenge;
|
|
53
|
+
if (!m)
|
|
54
54
|
return console.warn("Failed to fetch assertion challenge"), e;
|
|
55
|
-
const
|
|
56
|
-
if (!
|
|
55
|
+
const f = await t.generateAssertion(m);
|
|
56
|
+
if (!f)
|
|
57
57
|
return e;
|
|
58
|
-
e.headers["X-App-Attestation-Assertion"] =
|
|
58
|
+
e.headers["X-App-Attestation-Assertion"] = f.assertion, e.headers["X-App-Attestation-Key-ID"] = f.keyId, e.headers["X-App-Attestation-Challenge"] = m;
|
|
59
59
|
} else {
|
|
60
|
-
const
|
|
61
|
-
if (!
|
|
60
|
+
const a = await t.generateAssertion(JSON.stringify(e.data));
|
|
61
|
+
if (!a)
|
|
62
62
|
return e;
|
|
63
|
-
e.headers["X-Integrity-Token"] =
|
|
63
|
+
e.headers["X-Integrity-Token"] = a.assertion, e.headers["X-Package-Name"] = t.appIdentifier;
|
|
64
64
|
}
|
|
65
65
|
return e;
|
|
66
|
-
} catch (
|
|
66
|
+
} catch (a) {
|
|
67
67
|
throw new Error(
|
|
68
|
-
`App attestation required but assertion generation failed: ${
|
|
68
|
+
`App attestation required but assertion generation failed: ${a instanceof Error ? a.message : String(a)}`
|
|
69
69
|
);
|
|
70
70
|
}
|
|
71
71
|
});
|
|
72
|
-
},
|
|
72
|
+
}, S = (t, r) => ({
|
|
73
73
|
...t,
|
|
74
74
|
headers: {
|
|
75
75
|
...t.headers || {},
|
|
76
76
|
"X-Idempotency-Key": r
|
|
77
77
|
}
|
|
78
|
-
}),
|
|
79
|
-
|
|
78
|
+
}), H = async (t, r) => {
|
|
79
|
+
j(t), r && r !== "" && (t = S(t, r));
|
|
80
80
|
try {
|
|
81
|
-
return (await
|
|
81
|
+
return (await n(t)).data;
|
|
82
82
|
} catch (e) {
|
|
83
|
-
if (
|
|
84
|
-
throw new
|
|
85
|
-
|
|
83
|
+
if (p.isAxiosError(e) && !e.response)
|
|
84
|
+
throw new g(
|
|
85
|
+
d.unknown,
|
|
86
86
|
e.cause instanceof Error ? e.cause.message : e.message,
|
|
87
87
|
e.cause
|
|
88
88
|
);
|
|
89
|
-
if (
|
|
90
|
-
if (
|
|
91
|
-
throw new
|
|
89
|
+
if (p.isAxiosError(e) && e.response) {
|
|
90
|
+
if (y(e.response.data))
|
|
91
|
+
throw new l(
|
|
92
92
|
e.response.status,
|
|
93
93
|
e.response.data.errorType,
|
|
94
94
|
e.response.data.errorMessage,
|
|
@@ -100,54 +100,54 @@ const O = (t) => {
|
|
|
100
100
|
const s = e.response.status;
|
|
101
101
|
switch (s) {
|
|
102
102
|
case 401:
|
|
103
|
-
throw new
|
|
103
|
+
throw new l(
|
|
104
104
|
s,
|
|
105
|
-
|
|
105
|
+
d.unauthorized,
|
|
106
106
|
"Unauthorized.",
|
|
107
107
|
void 0,
|
|
108
108
|
`${h}#unauthorized`,
|
|
109
109
|
e.cause
|
|
110
110
|
);
|
|
111
111
|
case 404:
|
|
112
|
-
throw new
|
|
112
|
+
throw new l(
|
|
113
113
|
s,
|
|
114
|
-
|
|
114
|
+
d.not_found,
|
|
115
115
|
"API not found.",
|
|
116
116
|
void 0,
|
|
117
117
|
`${h}#not_found`,
|
|
118
118
|
e.cause
|
|
119
119
|
);
|
|
120
120
|
case 502:
|
|
121
|
-
throw new
|
|
121
|
+
throw new l(
|
|
122
122
|
s,
|
|
123
|
-
|
|
123
|
+
d.bad_gateway,
|
|
124
124
|
"Bad gateway.",
|
|
125
125
|
void 0,
|
|
126
126
|
`${h}`,
|
|
127
127
|
e.cause
|
|
128
128
|
);
|
|
129
129
|
case 503:
|
|
130
|
-
throw new
|
|
130
|
+
throw new l(
|
|
131
131
|
s,
|
|
132
|
-
|
|
132
|
+
d.service_unavailable,
|
|
133
133
|
"Service unavailable. Please try again later.",
|
|
134
134
|
void 0,
|
|
135
135
|
`${h}`,
|
|
136
136
|
e.cause
|
|
137
137
|
);
|
|
138
138
|
default: {
|
|
139
|
-
let
|
|
139
|
+
let a = "";
|
|
140
140
|
if (e.response.data)
|
|
141
141
|
try {
|
|
142
|
-
|
|
142
|
+
a = JSON.stringify(e.response.data);
|
|
143
143
|
} catch {
|
|
144
|
-
|
|
144
|
+
a = String(e.response.data);
|
|
145
145
|
}
|
|
146
|
-
const
|
|
147
|
-
throw new
|
|
146
|
+
const o = a ? `An unexpected error occurred: ${a}` : "An unexpected error occurred.";
|
|
147
|
+
throw new l(
|
|
148
148
|
s,
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
d.unexpected_error,
|
|
150
|
+
o,
|
|
151
151
|
void 0,
|
|
152
152
|
`${h}`,
|
|
153
153
|
e.cause
|
|
@@ -156,99 +156,124 @@ const O = (t) => {
|
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
|
-
throw new
|
|
159
|
+
throw new T("Something went wrong.", e instanceof Error ? e : void 0);
|
|
160
160
|
}
|
|
161
|
-
},
|
|
162
|
-
|
|
163
|
-
|
|
161
|
+
}, k = 4, b = [25, 50, 100], E = async (t) => {
|
|
162
|
+
if (t.getRefreshTokenWithOutcome) {
|
|
163
|
+
const { token: r, outcome: e, errorMessage: s } = await t.getRefreshTokenWithOutcome();
|
|
164
|
+
return { token: r, outcome: e, errorMessage: s };
|
|
165
|
+
}
|
|
166
|
+
return { token: await t.getRefreshToken() };
|
|
167
|
+
}, $ = async (t) => {
|
|
168
|
+
let r = null, e, s;
|
|
169
|
+
for (let a = 0; a < k; a++) {
|
|
170
|
+
const o = await E(t);
|
|
171
|
+
if (r = o.token, e = o.outcome, s = o.errorMessage, r)
|
|
172
|
+
return {
|
|
173
|
+
token: r,
|
|
174
|
+
attempt: a,
|
|
175
|
+
outcome: e,
|
|
176
|
+
errorMessage: s
|
|
177
|
+
};
|
|
178
|
+
const u = b[a];
|
|
179
|
+
u !== void 0 && await new Promise((R) => setTimeout(R, u));
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
token: r,
|
|
183
|
+
attempt: k - 1,
|
|
184
|
+
outcome: e,
|
|
185
|
+
errorMessage: s
|
|
186
|
+
};
|
|
187
|
+
}, U = (t, r) => {
|
|
188
|
+
n.interceptors.response.use(
|
|
189
|
+
async (e) => {
|
|
164
190
|
try {
|
|
165
|
-
if (
|
|
166
|
-
|
|
191
|
+
if (q(e)) {
|
|
192
|
+
i.sendSessionRefreshEvent({
|
|
167
193
|
name: "refresh_token_response"
|
|
168
194
|
});
|
|
169
|
-
const
|
|
170
|
-
|
|
195
|
+
const s = e.data?.refreshToken;
|
|
196
|
+
s && (i.sendSessionRefreshEvent({
|
|
171
197
|
name: "refresh_token_received"
|
|
172
198
|
}), await Promise.race([
|
|
173
|
-
t.setRefreshToken(
|
|
199
|
+
t.setRefreshToken(s),
|
|
174
200
|
new Promise(
|
|
175
|
-
(
|
|
201
|
+
(a, o) => setTimeout(() => o(new Error("setRefreshToken timed out after 5000ms")), 5e3)
|
|
176
202
|
)
|
|
177
|
-
]),
|
|
203
|
+
]), i.sendSessionRefreshEvent({
|
|
178
204
|
name: "refresh_token_stored"
|
|
179
205
|
}));
|
|
180
206
|
}
|
|
181
|
-
} catch (
|
|
182
|
-
const
|
|
183
|
-
|
|
207
|
+
} catch (s) {
|
|
208
|
+
const a = s instanceof Error ? s.message : String(s);
|
|
209
|
+
i.sendSessionRefreshEvent({
|
|
184
210
|
name: "refresh_token_store_failed",
|
|
185
|
-
error_message:
|
|
186
|
-
}), console.warn("Failed to store refresh token:",
|
|
211
|
+
error_message: a
|
|
212
|
+
}), console.warn("Failed to store refresh token:", s);
|
|
187
213
|
}
|
|
188
|
-
return
|
|
214
|
+
return e;
|
|
189
215
|
},
|
|
190
|
-
(
|
|
191
|
-
),
|
|
216
|
+
(e) => Promise.reject(e)
|
|
217
|
+
), n.interceptors.request.use(async (e) => {
|
|
192
218
|
try {
|
|
193
|
-
if (
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
name: "refresh_token_missing"
|
|
219
|
+
if (M(e.url)) {
|
|
220
|
+
const {
|
|
221
|
+
token: s,
|
|
222
|
+
attempt: a,
|
|
223
|
+
outcome: o,
|
|
224
|
+
errorMessage: u
|
|
225
|
+
} = r ? await $(t) : { ...await E(t), attempt: 0 };
|
|
226
|
+
s ? (i.sendSessionRefreshEvent({
|
|
227
|
+
name: "refresh_token_retrieved",
|
|
228
|
+
attempt: a,
|
|
229
|
+
read_outcome: o,
|
|
230
|
+
error_message: u
|
|
231
|
+
}), e.data = {
|
|
232
|
+
...e.data,
|
|
233
|
+
refreshToken: s
|
|
234
|
+
}) : i.sendSessionRefreshEvent({
|
|
235
|
+
name: "refresh_token_missing",
|
|
236
|
+
attempt: a,
|
|
237
|
+
read_outcome: o,
|
|
238
|
+
error_message: u
|
|
214
239
|
});
|
|
215
240
|
}
|
|
216
|
-
|
|
241
|
+
I(e.url) && (i.sendSessionRefreshEvent({
|
|
217
242
|
name: "refresh_token_removing_token"
|
|
218
243
|
}), await t.removeRefreshToken());
|
|
219
|
-
} catch (
|
|
220
|
-
const
|
|
221
|
-
|
|
244
|
+
} catch (s) {
|
|
245
|
+
const a = s instanceof Error ? s.message : String(s);
|
|
246
|
+
i.sendSessionRefreshEvent({
|
|
222
247
|
name: "refresh_token_retrieve_failed",
|
|
223
|
-
error_message:
|
|
224
|
-
}), console.warn("Failed to retrieve refresh token:",
|
|
248
|
+
error_message: a
|
|
249
|
+
}), console.warn("Failed to retrieve refresh token:", s);
|
|
225
250
|
}
|
|
226
|
-
return
|
|
251
|
+
return e;
|
|
227
252
|
});
|
|
228
|
-
},
|
|
253
|
+
}, I = (t) => t ? /^\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/logout$/.test(t) : !1, M = (t) => t ? /^\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(refresh|logout)$/.test(t) : !1, q = (t) => {
|
|
229
254
|
const r = t.config.url;
|
|
230
255
|
return r ? /^\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(verify\/(email|sms|siwe|oauth\/.*)|refresh)$/.test(
|
|
231
256
|
r
|
|
232
257
|
) : !1;
|
|
233
|
-
},
|
|
234
|
-
if (!
|
|
258
|
+
}, j = (t) => {
|
|
259
|
+
if (!n.getUri() || n.getUri() === "")
|
|
235
260
|
throw new Error("CDP client URI not configured. Call configure() first.");
|
|
236
261
|
if (!t.url || t.url === "")
|
|
237
262
|
throw new Error("AxiosRequestConfig URL is empty. This should never happen.");
|
|
238
263
|
if (!t.method || t.method === "")
|
|
239
264
|
throw new Error("AxiosRequestConfig method is empty. This should never happen.");
|
|
240
|
-
},
|
|
265
|
+
}, C = (t) => t.method?.toString().toUpperCase() || "GET", w = (t) => {
|
|
241
266
|
if (!t.url)
|
|
242
267
|
throw new Error("URL is required for authentication");
|
|
243
|
-
const r =
|
|
268
|
+
const r = n.getUri() + t.url;
|
|
244
269
|
return new URL(r);
|
|
245
|
-
},
|
|
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$/,
|
|
247
|
-
return r.test(t) || e.test(t) || s.test(t) ||
|
|
248
|
-
},
|
|
270
|
+
}, _ = (t) => {
|
|
271
|
+
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)$/;
|
|
272
|
+
return r.test(t) || e.test(t) || s.test(t) || a.test(t);
|
|
273
|
+
}, O = (t) => !/^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/custom\/authenticate$/.test(t), A = (t) => {
|
|
249
274
|
const r = /^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/(init)$/, e = /^\/platform\/v2\/embedded-wallet-api\/projects\/[^/]+\/auth\/verify\//;
|
|
250
275
|
return r.test(t) || e.test(t);
|
|
251
|
-
},
|
|
276
|
+
}, x = (t) => [
|
|
252
277
|
// Auth flows: prevent account takeover on mobile clients
|
|
253
278
|
/\/auth\/verify\//,
|
|
254
279
|
// VerifyEmailAuthentication, VerifySmsAuthentication, VerifyOAuthCode, VerifyOAuthEndUserIdentity
|
|
@@ -256,7 +281,7 @@ const O = (t) => {
|
|
|
256
281
|
// RefreshAccessToken
|
|
257
282
|
].some((e) => e.test(t));
|
|
258
283
|
export {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
284
|
+
H as cdpApiClient,
|
|
285
|
+
N as configureCdpApiClient,
|
|
286
|
+
z as setAuthManager
|
|
262
287
|
};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -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.
|
|
@@ -2533,6 +2540,19 @@ export declare type RefreshAccessTokenResult = NonNullable<Awaited<ReturnType<ty
|
|
|
2533
2540
|
export declare interface RefreshTokenStorage {
|
|
2534
2541
|
/** Retrieves the stored refresh token. */
|
|
2535
2542
|
getRefreshToken(): Promise<string | null>;
|
|
2543
|
+
/**
|
|
2544
|
+
* Retrieves the stored refresh token with read outcome metadata.
|
|
2545
|
+
*
|
|
2546
|
+
* @returns Promise that resolves to the stored token and read outcome.
|
|
2547
|
+
*/
|
|
2548
|
+
getRefreshTokenWithOutcome?(): Promise<{
|
|
2549
|
+
/** The stored refresh token, or null if not found or on error. */
|
|
2550
|
+
token: string | null;
|
|
2551
|
+
/** The outcome of the read: found, not found, or error. */
|
|
2552
|
+
outcome: "found" | "not_found" | "error";
|
|
2553
|
+
/** The error message when the read failed. */
|
|
2554
|
+
errorMessage?: string;
|
|
2555
|
+
}>;
|
|
2536
2556
|
/** Stores a refresh token securely. */
|
|
2537
2557
|
setRefreshToken(token: string): Promise<void>;
|
|
2538
2558
|
/** Removes the stored refresh token. */
|