@distilled.cloud/coinbase 0.25.2 → 0.26.1
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/lib/client.d.ts.map +1 -1
- package/lib/client.js +20 -11
- package/lib/client.js.map +1 -1
- package/package.json +2 -2
- package/src/client.ts +37 -15
package/lib/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAoCA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAY/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAsPnD;;;;GAIG;AACH,eAAO,MAAM,GAAG;;;CAqBd,CAAC"}
|
package/lib/client.js
CHANGED
|
@@ -30,15 +30,15 @@
|
|
|
30
30
|
*
|
|
31
31
|
* Errors are dispatched first by `errorType`, then by HTTP status code.
|
|
32
32
|
*/
|
|
33
|
+
import { makeAPI } from "@distilled.cloud/core/client";
|
|
34
|
+
import { parseRetryAfterForStatus } from "@distilled.cloud/core/retry-after";
|
|
33
35
|
import * as Effect from "effect/Effect";
|
|
34
36
|
import * as Redacted from "effect/Redacted";
|
|
35
37
|
import * as Schema from "effect/Schema";
|
|
36
38
|
import * as crypto from "node:crypto";
|
|
37
|
-
import { makeAPI } from "@distilled.cloud/core/client";
|
|
38
|
-
import { parseRetryAfterForStatus } from "@distilled.cloud/core/retry-after";
|
|
39
|
-
import { Retry } from "./retry.js";
|
|
40
|
-
import { HTTP_STATUS_MAP, COINBASE_HTTP_STATUS_MAP, ERROR_TYPE_MAP, STANDARD_ERROR_TYPE_MAP, UnknownCoinbaseError, CoinbaseParseError, } from "./errors.js";
|
|
41
39
|
import { Credentials } from "./credentials.js";
|
|
40
|
+
import { COINBASE_HTTP_STATUS_MAP, CoinbaseParseError, ERROR_TYPE_MAP, HTTP_STATUS_MAP, STANDARD_ERROR_TYPE_MAP, UnknownCoinbaseError, } from "./errors.js";
|
|
41
|
+
import { Retry } from "./retry.js";
|
|
42
42
|
// Re-export for convenience
|
|
43
43
|
export { UnknownCoinbaseError } from "./errors.js";
|
|
44
44
|
// ============================================================================
|
|
@@ -94,9 +94,9 @@ const resolveSigningKey = (apiKeySecret) => {
|
|
|
94
94
|
*
|
|
95
95
|
* The JWT includes:
|
|
96
96
|
* - header: { alg, kid, typ: "JWT", nonce }
|
|
97
|
-
* - payload: { sub, iss: "cdp",
|
|
97
|
+
* - payload: { sub, iss: "cdp", aud, nbf, exp, uri }
|
|
98
98
|
*/
|
|
99
|
-
const generateJwt = (apiKeyId, apiKeySecret) => {
|
|
99
|
+
const generateJwt = (apiKeyId, apiKeySecret, method, uri) => {
|
|
100
100
|
const { jwsAlg, key } = resolveSigningKey(apiKeySecret);
|
|
101
101
|
const now = Math.floor(Date.now() / 1000);
|
|
102
102
|
const header = {
|
|
@@ -108,9 +108,10 @@ const generateJwt = (apiKeyId, apiKeySecret) => {
|
|
|
108
108
|
const payload = {
|
|
109
109
|
sub: apiKeyId,
|
|
110
110
|
iss: "cdp",
|
|
111
|
-
|
|
111
|
+
aud: ["cdp_service"],
|
|
112
112
|
nbf: now,
|
|
113
113
|
exp: now + 120,
|
|
114
|
+
uri: `${method} ${uri}`,
|
|
114
115
|
};
|
|
115
116
|
const headerB64 = base64url(Buffer.from(JSON.stringify(header)));
|
|
116
117
|
const payloadB64 = base64url(Buffer.from(JSON.stringify(payload)));
|
|
@@ -182,6 +183,11 @@ const CoinbaseErrorResponse = Schema.Struct({
|
|
|
182
183
|
* 5. Falls back to UnknownCoinbaseError for unrecognized errors
|
|
183
184
|
*/
|
|
184
185
|
const matchError = (status, errorBody, _errors, headers) => {
|
|
186
|
+
if (errorBody &&
|
|
187
|
+
typeof errorBody === "object" &&
|
|
188
|
+
("isValid" in errorBody || "success" in errorBody)) {
|
|
189
|
+
return Effect.succeed(errorBody);
|
|
190
|
+
}
|
|
185
191
|
try {
|
|
186
192
|
const parsed = Schema.decodeUnknownSync(CoinbaseErrorResponse)(errorBody);
|
|
187
193
|
const errorProps = {
|
|
@@ -240,14 +246,17 @@ const matchError = (status, errorBody, _errors, headers) => {
|
|
|
240
246
|
export const API = makeAPI({
|
|
241
247
|
credentials: Credentials,
|
|
242
248
|
getBaseUrl: (creds) => creds.apiBaseUrl,
|
|
243
|
-
getAuthHeaders: (
|
|
244
|
-
|
|
245
|
-
const
|
|
249
|
+
getAuthHeaders: () => ({}),
|
|
250
|
+
getRequestHeaders: (_requestOptions, { method, parts, credentials }) => {
|
|
251
|
+
const c = credentials;
|
|
252
|
+
const baseUrl = new URL(c.apiBaseUrl);
|
|
253
|
+
const uri = `${baseUrl.host}${baseUrl.pathname}${parts.path}`;
|
|
254
|
+
const jwt = generateJwt(c.apiKeyId, Redacted.value(c.apiKeySecret), method, uri);
|
|
246
255
|
return {
|
|
247
256
|
Authorization: `Bearer ${jwt}`,
|
|
248
257
|
};
|
|
249
258
|
},
|
|
250
|
-
matchError,
|
|
259
|
+
matchError: matchError,
|
|
251
260
|
ParseError: CoinbaseParseError,
|
|
252
261
|
retry: Retry,
|
|
253
262
|
});
|
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@distilled.cloud/coinbase",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/alchemy-run/distilled",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"specs:update": "git -C specs/cdp-sdk fetch && git -C specs/cdp-sdk checkout main && git -C specs/cdp-sdk pull"
|
|
75
75
|
},
|
|
76
76
|
"dependencies": {
|
|
77
|
-
"@distilled.cloud/core": "0.
|
|
77
|
+
"@distilled.cloud/core": "0.26.1"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@types/bun": "^1.3.0",
|
package/src/client.ts
CHANGED
|
@@ -30,23 +30,23 @@
|
|
|
30
30
|
*
|
|
31
31
|
* Errors are dispatched first by `errorType`, then by HTTP status code.
|
|
32
32
|
*/
|
|
33
|
+
import { makeAPI } from "@distilled.cloud/core/client";
|
|
34
|
+
import { parseRetryAfterForStatus } from "@distilled.cloud/core/retry-after";
|
|
33
35
|
import * as Effect from "effect/Effect";
|
|
34
36
|
import * as Redacted from "effect/Redacted";
|
|
35
37
|
import * as Schema from "effect/Schema";
|
|
36
38
|
import * as crypto from "node:crypto";
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import { Retry } from "./retry.ts";
|
|
39
|
+
import type { Config } from "./credentials.ts";
|
|
40
|
+
import { Credentials } from "./credentials.ts";
|
|
40
41
|
import {
|
|
41
|
-
HTTP_STATUS_MAP,
|
|
42
42
|
COINBASE_HTTP_STATUS_MAP,
|
|
43
|
+
CoinbaseParseError,
|
|
43
44
|
ERROR_TYPE_MAP,
|
|
45
|
+
HTTP_STATUS_MAP,
|
|
44
46
|
STANDARD_ERROR_TYPE_MAP,
|
|
45
47
|
UnknownCoinbaseError,
|
|
46
|
-
CoinbaseParseError,
|
|
47
48
|
} from "./errors.ts";
|
|
48
|
-
import
|
|
49
|
-
import { Credentials } from "./credentials.ts";
|
|
49
|
+
import { Retry } from "./retry.ts";
|
|
50
50
|
|
|
51
51
|
// Re-export for convenience
|
|
52
52
|
export { UnknownCoinbaseError } from "./errors.ts";
|
|
@@ -115,9 +115,14 @@ const resolveSigningKey = (
|
|
|
115
115
|
*
|
|
116
116
|
* The JWT includes:
|
|
117
117
|
* - header: { alg, kid, typ: "JWT", nonce }
|
|
118
|
-
* - payload: { sub, iss: "cdp",
|
|
118
|
+
* - payload: { sub, iss: "cdp", aud, nbf, exp, uri }
|
|
119
119
|
*/
|
|
120
|
-
const generateJwt = (
|
|
120
|
+
const generateJwt = (
|
|
121
|
+
apiKeyId: string,
|
|
122
|
+
apiKeySecret: string,
|
|
123
|
+
method: string,
|
|
124
|
+
uri: string,
|
|
125
|
+
): string => {
|
|
121
126
|
const { jwsAlg, key } = resolveSigningKey(apiKeySecret);
|
|
122
127
|
|
|
123
128
|
const now = Math.floor(Date.now() / 1000);
|
|
@@ -130,9 +135,10 @@ const generateJwt = (apiKeyId: string, apiKeySecret: string): string => {
|
|
|
130
135
|
const payload = {
|
|
131
136
|
sub: apiKeyId,
|
|
132
137
|
iss: "cdp",
|
|
133
|
-
|
|
138
|
+
aud: ["cdp_service"],
|
|
134
139
|
nbf: now,
|
|
135
140
|
exp: now + 120,
|
|
141
|
+
uri: `${method} ${uri}`,
|
|
136
142
|
};
|
|
137
143
|
|
|
138
144
|
const headerB64 = base64url(Buffer.from(JSON.stringify(header)));
|
|
@@ -218,7 +224,15 @@ const matchError = (
|
|
|
218
224
|
errorBody: unknown,
|
|
219
225
|
_errors?: readonly unknown[],
|
|
220
226
|
headers?: Record<string, string | undefined>,
|
|
221
|
-
): Effect.Effect<
|
|
227
|
+
): Effect.Effect<unknown, unknown> => {
|
|
228
|
+
if (
|
|
229
|
+
errorBody &&
|
|
230
|
+
typeof errorBody === "object" &&
|
|
231
|
+
("isValid" in errorBody || "success" in errorBody)
|
|
232
|
+
) {
|
|
233
|
+
return Effect.succeed(errorBody);
|
|
234
|
+
}
|
|
235
|
+
|
|
222
236
|
try {
|
|
223
237
|
const parsed = Schema.decodeUnknownSync(CoinbaseErrorResponse)(errorBody);
|
|
224
238
|
const errorProps = {
|
|
@@ -289,14 +303,22 @@ const matchError = (
|
|
|
289
303
|
export const API = makeAPI<Credentials>({
|
|
290
304
|
credentials: Credentials as any,
|
|
291
305
|
getBaseUrl: (creds: any) => (creds as Config).apiBaseUrl,
|
|
292
|
-
getAuthHeaders: (
|
|
293
|
-
|
|
294
|
-
const
|
|
306
|
+
getAuthHeaders: () => ({}),
|
|
307
|
+
getRequestHeaders: (_requestOptions, { method, parts, credentials }) => {
|
|
308
|
+
const c = credentials as any;
|
|
309
|
+
const baseUrl = new URL(c.apiBaseUrl);
|
|
310
|
+
const uri = `${baseUrl.host}${baseUrl.pathname}${parts.path}`;
|
|
311
|
+
const jwt = generateJwt(
|
|
312
|
+
c.apiKeyId,
|
|
313
|
+
Redacted.value(c.apiKeySecret),
|
|
314
|
+
method,
|
|
315
|
+
uri,
|
|
316
|
+
);
|
|
295
317
|
return {
|
|
296
318
|
Authorization: `Bearer ${jwt}`,
|
|
297
319
|
};
|
|
298
320
|
},
|
|
299
|
-
matchError,
|
|
321
|
+
matchError: matchError as any,
|
|
300
322
|
ParseError: CoinbaseParseError as any,
|
|
301
323
|
retry: Retry as any,
|
|
302
324
|
});
|