@opensea/cli 0.2.1 → 0.4.0
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/README.md +91 -227
- package/dist/cli.js +386 -39
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +13 -8
- package/dist/index.js +367 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -6,16 +6,21 @@ import { Command as Command10 } from "commander";
|
|
|
6
6
|
// src/client.ts
|
|
7
7
|
var DEFAULT_BASE_URL = "https://api.opensea.io";
|
|
8
8
|
var DEFAULT_GRAPHQL_URL = "https://gql.opensea.io/graphql";
|
|
9
|
+
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
9
10
|
var OpenSeaClient = class {
|
|
10
11
|
apiKey;
|
|
11
12
|
baseUrl;
|
|
12
13
|
graphqlUrl;
|
|
13
14
|
defaultChain;
|
|
15
|
+
timeoutMs;
|
|
16
|
+
verbose;
|
|
14
17
|
constructor(config) {
|
|
15
18
|
this.apiKey = config.apiKey;
|
|
16
19
|
this.baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
|
|
17
20
|
this.graphqlUrl = config.graphqlUrl ?? DEFAULT_GRAPHQL_URL;
|
|
18
21
|
this.defaultChain = config.chain ?? "ethereum";
|
|
22
|
+
this.timeoutMs = config.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
23
|
+
this.verbose = config.verbose ?? false;
|
|
19
24
|
}
|
|
20
25
|
async get(path, params) {
|
|
21
26
|
const url = new URL(`${this.baseUrl}${path}`);
|
|
@@ -26,35 +31,64 @@ var OpenSeaClient = class {
|
|
|
26
31
|
}
|
|
27
32
|
}
|
|
28
33
|
}
|
|
34
|
+
if (this.verbose) {
|
|
35
|
+
console.error(`[verbose] GET ${url.toString()}`);
|
|
36
|
+
}
|
|
29
37
|
const response = await fetch(url.toString(), {
|
|
30
38
|
method: "GET",
|
|
31
39
|
headers: {
|
|
32
40
|
Accept: "application/json",
|
|
33
41
|
"x-api-key": this.apiKey
|
|
34
|
-
}
|
|
42
|
+
},
|
|
43
|
+
signal: AbortSignal.timeout(this.timeoutMs)
|
|
35
44
|
});
|
|
45
|
+
if (this.verbose) {
|
|
46
|
+
console.error(`[verbose] ${response.status} ${response.statusText}`);
|
|
47
|
+
}
|
|
36
48
|
if (!response.ok) {
|
|
37
49
|
const body = await response.text();
|
|
38
50
|
throw new OpenSeaAPIError(response.status, body, path);
|
|
39
51
|
}
|
|
40
52
|
return response.json();
|
|
41
53
|
}
|
|
42
|
-
async post(path) {
|
|
54
|
+
async post(path, body, params) {
|
|
43
55
|
const url = new URL(`${this.baseUrl}${path}`);
|
|
56
|
+
if (params) {
|
|
57
|
+
for (const [key, value] of Object.entries(params)) {
|
|
58
|
+
if (value !== void 0 && value !== null) {
|
|
59
|
+
url.searchParams.set(key, String(value));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const headers = {
|
|
64
|
+
Accept: "application/json",
|
|
65
|
+
"x-api-key": this.apiKey
|
|
66
|
+
};
|
|
67
|
+
if (body) {
|
|
68
|
+
headers["Content-Type"] = "application/json";
|
|
69
|
+
}
|
|
70
|
+
if (this.verbose) {
|
|
71
|
+
console.error(`[verbose] POST ${url.toString()}`);
|
|
72
|
+
}
|
|
44
73
|
const response = await fetch(url.toString(), {
|
|
45
74
|
method: "POST",
|
|
46
|
-
headers
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
75
|
+
headers,
|
|
76
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
77
|
+
signal: AbortSignal.timeout(this.timeoutMs)
|
|
50
78
|
});
|
|
79
|
+
if (this.verbose) {
|
|
80
|
+
console.error(`[verbose] ${response.status} ${response.statusText}`);
|
|
81
|
+
}
|
|
51
82
|
if (!response.ok) {
|
|
52
|
-
const
|
|
53
|
-
throw new OpenSeaAPIError(response.status,
|
|
83
|
+
const text = await response.text();
|
|
84
|
+
throw new OpenSeaAPIError(response.status, text, path);
|
|
54
85
|
}
|
|
55
86
|
return response.json();
|
|
56
87
|
}
|
|
57
88
|
async graphql(query, variables) {
|
|
89
|
+
if (this.verbose) {
|
|
90
|
+
console.error(`[verbose] POST ${this.graphqlUrl}`);
|
|
91
|
+
}
|
|
58
92
|
const response = await fetch(this.graphqlUrl, {
|
|
59
93
|
method: "POST",
|
|
60
94
|
headers: {
|
|
@@ -62,8 +96,12 @@ var OpenSeaClient = class {
|
|
|
62
96
|
Accept: "application/json",
|
|
63
97
|
"x-api-key": this.apiKey
|
|
64
98
|
},
|
|
65
|
-
body: JSON.stringify({ query, variables })
|
|
99
|
+
body: JSON.stringify({ query, variables }),
|
|
100
|
+
signal: AbortSignal.timeout(this.timeoutMs)
|
|
66
101
|
});
|
|
102
|
+
if (this.verbose) {
|
|
103
|
+
console.error(`[verbose] ${response.status} ${response.statusText}`);
|
|
104
|
+
}
|
|
67
105
|
if (!response.ok) {
|
|
68
106
|
const body = await response.text();
|
|
69
107
|
throw new OpenSeaAPIError(response.status, body, "graphql");
|
|
@@ -98,11 +136,284 @@ var OpenSeaAPIError = class extends Error {
|
|
|
98
136
|
// src/commands/accounts.ts
|
|
99
137
|
import { Command } from "commander";
|
|
100
138
|
|
|
139
|
+
// src/toon.ts
|
|
140
|
+
var INDENT = " ";
|
|
141
|
+
var NUMERIC_RE = /^-?\d+(?:\.\d+)?(?:e[+-]?\d+)?$/i;
|
|
142
|
+
var LEADING_ZERO_RE = /^0\d+$/;
|
|
143
|
+
var UNQUOTED_KEY_RE = /^[A-Za-z_][A-Za-z0-9_.]*$/;
|
|
144
|
+
function escapeString(s) {
|
|
145
|
+
return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
|
|
146
|
+
}
|
|
147
|
+
function needsQuoting(value, delimiter) {
|
|
148
|
+
if (value === "") return true;
|
|
149
|
+
if (value !== value.trim()) return true;
|
|
150
|
+
if (value === "true" || value === "false" || value === "null") return true;
|
|
151
|
+
if (NUMERIC_RE.test(value) || LEADING_ZERO_RE.test(value)) return true;
|
|
152
|
+
if (/[:"\\[\]{}]/.test(value)) return true;
|
|
153
|
+
if (/[\n\r\t]/.test(value)) return true;
|
|
154
|
+
if (value.includes(delimiter)) return true;
|
|
155
|
+
if (value.startsWith("-")) return true;
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
function encodeKey(key) {
|
|
159
|
+
if (UNQUOTED_KEY_RE.test(key)) return key;
|
|
160
|
+
return `"${escapeString(key)}"`;
|
|
161
|
+
}
|
|
162
|
+
function encodePrimitive(value, delimiter) {
|
|
163
|
+
if (value === null) return "null";
|
|
164
|
+
if (value === void 0) return "null";
|
|
165
|
+
if (typeof value === "boolean") return String(value);
|
|
166
|
+
if (typeof value === "number") return String(value);
|
|
167
|
+
if (typeof value === "string") {
|
|
168
|
+
if (needsQuoting(value, delimiter)) {
|
|
169
|
+
return `"${escapeString(value)}"`;
|
|
170
|
+
}
|
|
171
|
+
return value;
|
|
172
|
+
}
|
|
173
|
+
return `"${escapeString(String(value))}"`;
|
|
174
|
+
}
|
|
175
|
+
function isPrimitive(value) {
|
|
176
|
+
return value === null || value === void 0 || typeof value === "boolean" || typeof value === "number" || typeof value === "string";
|
|
177
|
+
}
|
|
178
|
+
function isTabular(arr) {
|
|
179
|
+
if (arr.length === 0) return false;
|
|
180
|
+
const first = arr[0];
|
|
181
|
+
if (first === null || typeof first !== "object" || Array.isArray(first))
|
|
182
|
+
return false;
|
|
183
|
+
const keys = Object.keys(first).sort();
|
|
184
|
+
for (const item of arr) {
|
|
185
|
+
if (item === null || typeof item !== "object" || Array.isArray(item))
|
|
186
|
+
return false;
|
|
187
|
+
const itemKeys = Object.keys(item).sort();
|
|
188
|
+
if (itemKeys.length !== keys.length) return false;
|
|
189
|
+
for (let i = 0; i < keys.length; i++) {
|
|
190
|
+
if (itemKeys[i] !== keys[i]) return false;
|
|
191
|
+
}
|
|
192
|
+
for (const k of keys) {
|
|
193
|
+
if (!isPrimitive(item[k])) return false;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
function isPrimitiveArray(arr) {
|
|
199
|
+
return arr.every(isPrimitive);
|
|
200
|
+
}
|
|
201
|
+
function encodeValue(value, depth, delimiter) {
|
|
202
|
+
if (isPrimitive(value)) {
|
|
203
|
+
return encodePrimitive(value, delimiter);
|
|
204
|
+
}
|
|
205
|
+
if (Array.isArray(value)) {
|
|
206
|
+
return encodeArray(value, depth, delimiter);
|
|
207
|
+
}
|
|
208
|
+
if (typeof value === "object" && value !== null) {
|
|
209
|
+
return encodeObject(value, depth, delimiter);
|
|
210
|
+
}
|
|
211
|
+
return encodePrimitive(value, delimiter);
|
|
212
|
+
}
|
|
213
|
+
function encodeObject(obj, depth, delimiter) {
|
|
214
|
+
const entries = Object.entries(obj);
|
|
215
|
+
if (entries.length === 0) return "";
|
|
216
|
+
const lines = [];
|
|
217
|
+
const prefix = INDENT.repeat(depth);
|
|
218
|
+
for (const [key, value] of entries) {
|
|
219
|
+
const encodedKey = encodeKey(key);
|
|
220
|
+
if (isPrimitive(value)) {
|
|
221
|
+
lines.push(`${prefix}${encodedKey}: ${encodePrimitive(value, delimiter)}`);
|
|
222
|
+
} else if (Array.isArray(value)) {
|
|
223
|
+
lines.push(encodeArrayField(encodedKey, value, depth, delimiter));
|
|
224
|
+
} else if (typeof value === "object" && value !== null) {
|
|
225
|
+
const nested = value;
|
|
226
|
+
if (Object.keys(nested).length === 0) {
|
|
227
|
+
lines.push(`${prefix}${encodedKey}:`);
|
|
228
|
+
} else {
|
|
229
|
+
lines.push(`${prefix}${encodedKey}:`);
|
|
230
|
+
lines.push(encodeObject(nested, depth + 1, delimiter));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return lines.join("\n");
|
|
235
|
+
}
|
|
236
|
+
function encodeArrayField(encodedKey, arr, depth, delimiter) {
|
|
237
|
+
const prefix = INDENT.repeat(depth);
|
|
238
|
+
if (arr.length === 0) {
|
|
239
|
+
return `${prefix}${encodedKey}[0]:`;
|
|
240
|
+
}
|
|
241
|
+
if (isPrimitiveArray(arr)) {
|
|
242
|
+
const values = arr.map((v) => encodePrimitive(v, delimiter)).join(delimiter);
|
|
243
|
+
return `${prefix}${encodedKey}[${arr.length}]: ${values}`;
|
|
244
|
+
}
|
|
245
|
+
if (isTabular(arr)) {
|
|
246
|
+
const firstObj = arr[0];
|
|
247
|
+
const fields = Object.keys(firstObj);
|
|
248
|
+
const fieldHeader = fields.map(encodeKey).join(delimiter);
|
|
249
|
+
const lines = [];
|
|
250
|
+
lines.push(`${prefix}${encodedKey}[${arr.length}]{${fieldHeader}}:`);
|
|
251
|
+
const rowPrefix = INDENT.repeat(depth + 1);
|
|
252
|
+
for (const item of arr) {
|
|
253
|
+
const obj = item;
|
|
254
|
+
const row = fields.map((f) => encodePrimitive(obj[f], delimiter)).join(delimiter);
|
|
255
|
+
lines.push(`${rowPrefix}${row}`);
|
|
256
|
+
}
|
|
257
|
+
return lines.join("\n");
|
|
258
|
+
}
|
|
259
|
+
return encodeExpandedList(encodedKey, arr, depth, delimiter);
|
|
260
|
+
}
|
|
261
|
+
function encodeExpandedList(encodedKey, arr, depth, delimiter) {
|
|
262
|
+
const prefix = INDENT.repeat(depth);
|
|
263
|
+
const itemPrefix = INDENT.repeat(depth + 1);
|
|
264
|
+
const lines = [];
|
|
265
|
+
lines.push(`${prefix}${encodedKey}[${arr.length}]:`);
|
|
266
|
+
for (const item of arr) {
|
|
267
|
+
if (isPrimitive(item)) {
|
|
268
|
+
lines.push(`${itemPrefix}- ${encodePrimitive(item, delimiter)}`);
|
|
269
|
+
} else if (Array.isArray(item)) {
|
|
270
|
+
if (isPrimitiveArray(item)) {
|
|
271
|
+
const values = item.map((v) => encodePrimitive(v, delimiter)).join(delimiter);
|
|
272
|
+
lines.push(`${itemPrefix}- [${item.length}]: ${values}`);
|
|
273
|
+
} else {
|
|
274
|
+
lines.push(`${itemPrefix}- [${item.length}]:`);
|
|
275
|
+
for (const inner of item) {
|
|
276
|
+
lines.push(encodeValue(inner, depth + 2, delimiter));
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
} else if (typeof item === "object" && item !== null) {
|
|
280
|
+
const obj = item;
|
|
281
|
+
const entries = Object.entries(obj);
|
|
282
|
+
if (entries.length === 0) {
|
|
283
|
+
lines.push(`${itemPrefix}-`);
|
|
284
|
+
} else {
|
|
285
|
+
const [firstKey, firstValue] = entries[0];
|
|
286
|
+
const ek = encodeKey(firstKey);
|
|
287
|
+
if (Array.isArray(firstValue)) {
|
|
288
|
+
const arrayLine = encodeArrayField(ek, firstValue, 0, delimiter);
|
|
289
|
+
lines.push(`${itemPrefix}- ${arrayLine.trimStart()}`);
|
|
290
|
+
} else if (isPrimitive(firstValue)) {
|
|
291
|
+
lines.push(
|
|
292
|
+
`${itemPrefix}- ${ek}: ${encodePrimitive(firstValue, delimiter)}`
|
|
293
|
+
);
|
|
294
|
+
} else {
|
|
295
|
+
lines.push(`${itemPrefix}- ${ek}:`);
|
|
296
|
+
lines.push(
|
|
297
|
+
encodeObject(
|
|
298
|
+
firstValue,
|
|
299
|
+
depth + 2,
|
|
300
|
+
delimiter
|
|
301
|
+
)
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
for (let i = 1; i < entries.length; i++) {
|
|
305
|
+
const [k, v] = entries[i];
|
|
306
|
+
const encodedK = encodeKey(k);
|
|
307
|
+
if (isPrimitive(v)) {
|
|
308
|
+
lines.push(
|
|
309
|
+
`${INDENT.repeat(depth + 2)}${encodedK}: ${encodePrimitive(v, delimiter)}`
|
|
310
|
+
);
|
|
311
|
+
} else if (Array.isArray(v)) {
|
|
312
|
+
lines.push(encodeArrayField(encodedK, v, depth + 2, delimiter));
|
|
313
|
+
} else if (typeof v === "object" && v !== null) {
|
|
314
|
+
lines.push(`${INDENT.repeat(depth + 2)}${encodedK}:`);
|
|
315
|
+
lines.push(
|
|
316
|
+
encodeObject(v, depth + 3, delimiter)
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return lines.join("\n");
|
|
324
|
+
}
|
|
325
|
+
function encodeArray(arr, depth, delimiter) {
|
|
326
|
+
const prefix = INDENT.repeat(depth);
|
|
327
|
+
if (arr.length === 0) {
|
|
328
|
+
return `${prefix}[0]:`;
|
|
329
|
+
}
|
|
330
|
+
if (isPrimitiveArray(arr)) {
|
|
331
|
+
const values = arr.map((v) => encodePrimitive(v, delimiter)).join(delimiter);
|
|
332
|
+
return `${prefix}[${arr.length}]: ${values}`;
|
|
333
|
+
}
|
|
334
|
+
if (isTabular(arr)) {
|
|
335
|
+
const firstObj = arr[0];
|
|
336
|
+
const fields = Object.keys(firstObj);
|
|
337
|
+
const fieldHeader = fields.map(encodeKey).join(delimiter);
|
|
338
|
+
const lines2 = [];
|
|
339
|
+
lines2.push(`${prefix}[${arr.length}]{${fieldHeader}}:`);
|
|
340
|
+
const rowPrefix = INDENT.repeat(depth + 1);
|
|
341
|
+
for (const item of arr) {
|
|
342
|
+
const obj = item;
|
|
343
|
+
const row = fields.map((f) => encodePrimitive(obj[f], delimiter)).join(delimiter);
|
|
344
|
+
lines2.push(`${rowPrefix}${row}`);
|
|
345
|
+
}
|
|
346
|
+
return lines2.join("\n");
|
|
347
|
+
}
|
|
348
|
+
const lines = [];
|
|
349
|
+
lines.push(`${prefix}[${arr.length}]:`);
|
|
350
|
+
const itemPrefix = INDENT.repeat(depth + 1);
|
|
351
|
+
for (const item of arr) {
|
|
352
|
+
if (isPrimitive(item)) {
|
|
353
|
+
lines.push(`${itemPrefix}- ${encodePrimitive(item, delimiter)}`);
|
|
354
|
+
} else if (Array.isArray(item)) {
|
|
355
|
+
if (isPrimitiveArray(item)) {
|
|
356
|
+
const values = item.map((v) => encodePrimitive(v, delimiter)).join(delimiter);
|
|
357
|
+
lines.push(`${itemPrefix}- [${item.length}]: ${values}`);
|
|
358
|
+
} else {
|
|
359
|
+
lines.push(`${itemPrefix}- [${item.length}]:`);
|
|
360
|
+
}
|
|
361
|
+
} else if (typeof item === "object" && item !== null) {
|
|
362
|
+
const obj = item;
|
|
363
|
+
const entries = Object.entries(obj);
|
|
364
|
+
if (entries.length > 0) {
|
|
365
|
+
const [firstKey, firstValue] = entries[0];
|
|
366
|
+
const ek = encodeKey(firstKey);
|
|
367
|
+
if (isPrimitive(firstValue)) {
|
|
368
|
+
lines.push(
|
|
369
|
+
`${itemPrefix}- ${ek}: ${encodePrimitive(firstValue, delimiter)}`
|
|
370
|
+
);
|
|
371
|
+
} else {
|
|
372
|
+
lines.push(`${itemPrefix}- ${ek}:`);
|
|
373
|
+
lines.push(encodeValue(firstValue, depth + 2, delimiter));
|
|
374
|
+
}
|
|
375
|
+
for (let i = 1; i < entries.length; i++) {
|
|
376
|
+
const [k, v] = entries[i];
|
|
377
|
+
const encodedK = encodeKey(k);
|
|
378
|
+
if (isPrimitive(v)) {
|
|
379
|
+
lines.push(
|
|
380
|
+
`${INDENT.repeat(depth + 2)}${encodedK}: ${encodePrimitive(v, delimiter)}`
|
|
381
|
+
);
|
|
382
|
+
} else if (Array.isArray(v)) {
|
|
383
|
+
lines.push(encodeArrayField(encodedK, v, depth + 2, delimiter));
|
|
384
|
+
} else if (typeof v === "object" && v !== null) {
|
|
385
|
+
lines.push(`${INDENT.repeat(depth + 2)}${encodedK}:`);
|
|
386
|
+
lines.push(
|
|
387
|
+
encodeObject(v, depth + 3, delimiter)
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return lines.join("\n");
|
|
395
|
+
}
|
|
396
|
+
function formatToon(data) {
|
|
397
|
+
if (isPrimitive(data)) {
|
|
398
|
+
return encodePrimitive(data, ",");
|
|
399
|
+
}
|
|
400
|
+
if (Array.isArray(data)) {
|
|
401
|
+
return encodeArray(data, 0, ",");
|
|
402
|
+
}
|
|
403
|
+
if (typeof data === "object" && data !== null) {
|
|
404
|
+
return encodeObject(data, 0, ",");
|
|
405
|
+
}
|
|
406
|
+
return String(data);
|
|
407
|
+
}
|
|
408
|
+
|
|
101
409
|
// src/output.ts
|
|
102
410
|
function formatOutput(data, format) {
|
|
103
411
|
if (format === "table") {
|
|
104
412
|
return formatTable(data);
|
|
105
413
|
}
|
|
414
|
+
if (format === "toon") {
|
|
415
|
+
return formatToon(data);
|
|
416
|
+
}
|
|
106
417
|
return JSON.stringify(data, null, 2);
|
|
107
418
|
}
|
|
108
419
|
function formatTable(data) {
|
|
@@ -130,6 +441,7 @@ function formatTable(data) {
|
|
|
130
441
|
}
|
|
131
442
|
if (data && typeof data === "object") {
|
|
132
443
|
const entries = Object.entries(data);
|
|
444
|
+
if (entries.length === 0) return "(empty)";
|
|
133
445
|
const maxKeyLength = Math.max(...entries.map(([k]) => k.length));
|
|
134
446
|
return entries.map(([key, value]) => {
|
|
135
447
|
const displayValue = typeof value === "object" && value !== null ? JSON.stringify(value) : String(value ?? "");
|
|
@@ -152,6 +464,24 @@ function accountsCommand(getClient2, getFormat2) {
|
|
|
152
464
|
|
|
153
465
|
// src/commands/collections.ts
|
|
154
466
|
import { Command as Command2 } from "commander";
|
|
467
|
+
|
|
468
|
+
// src/parse.ts
|
|
469
|
+
function parseIntOption(value, name) {
|
|
470
|
+
const parsed = Number.parseInt(value, 10);
|
|
471
|
+
if (Number.isNaN(parsed)) {
|
|
472
|
+
throw new Error(`Invalid value for ${name}: "${value}" is not an integer`);
|
|
473
|
+
}
|
|
474
|
+
return parsed;
|
|
475
|
+
}
|
|
476
|
+
function parseFloatOption(value, name) {
|
|
477
|
+
const parsed = Number.parseFloat(value);
|
|
478
|
+
if (Number.isNaN(parsed)) {
|
|
479
|
+
throw new Error(`Invalid value for ${name}: "${value}" is not a number`);
|
|
480
|
+
}
|
|
481
|
+
return parsed;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// src/commands/collections.ts
|
|
155
485
|
function collectionsCommand(getClient2, getFormat2) {
|
|
156
486
|
const cmd = new Command2("collections").description(
|
|
157
487
|
"Manage and query NFT collections"
|
|
@@ -172,7 +502,7 @@ function collectionsCommand(getClient2, getFormat2) {
|
|
|
172
502
|
order_by: options.orderBy,
|
|
173
503
|
creator_username: options.creator,
|
|
174
504
|
include_hidden: options.includeHidden,
|
|
175
|
-
limit:
|
|
505
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
176
506
|
next: options.next
|
|
177
507
|
});
|
|
178
508
|
console.log(formatOutput(result, getFormat2()));
|
|
@@ -207,10 +537,10 @@ function eventsCommand(getClient2, getFormat2) {
|
|
|
207
537
|
const client = getClient2();
|
|
208
538
|
const result = await client.get("/api/v2/events", {
|
|
209
539
|
event_type: options.eventType,
|
|
210
|
-
after: options.after ?
|
|
211
|
-
before: options.before ?
|
|
540
|
+
after: options.after ? parseIntOption(options.after, "--after") : void 0,
|
|
541
|
+
before: options.before ? parseIntOption(options.before, "--before") : void 0,
|
|
212
542
|
chain: options.chain,
|
|
213
|
-
limit:
|
|
543
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
214
544
|
next: options.next
|
|
215
545
|
});
|
|
216
546
|
console.log(formatOutput(result, getFormat2()));
|
|
@@ -222,7 +552,7 @@ function eventsCommand(getClient2, getFormat2) {
|
|
|
222
552
|
const result = await client.get(`/api/v2/events/accounts/${address}`, {
|
|
223
553
|
event_type: options.eventType,
|
|
224
554
|
chain: options.chain,
|
|
225
|
-
limit:
|
|
555
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
226
556
|
next: options.next
|
|
227
557
|
});
|
|
228
558
|
console.log(formatOutput(result, getFormat2()));
|
|
@@ -233,7 +563,7 @@ function eventsCommand(getClient2, getFormat2) {
|
|
|
233
563
|
const client = getClient2();
|
|
234
564
|
const result = await client.get(`/api/v2/events/collection/${slug}`, {
|
|
235
565
|
event_type: options.eventType,
|
|
236
|
-
limit:
|
|
566
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
237
567
|
next: options.next
|
|
238
568
|
});
|
|
239
569
|
console.log(formatOutput(result, getFormat2()));
|
|
@@ -246,7 +576,7 @@ function eventsCommand(getClient2, getFormat2) {
|
|
|
246
576
|
`/api/v2/events/chain/${chain}/contract/${contract}/nfts/${tokenId}`,
|
|
247
577
|
{
|
|
248
578
|
event_type: options.eventType,
|
|
249
|
-
limit:
|
|
579
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
250
580
|
next: options.next
|
|
251
581
|
}
|
|
252
582
|
);
|
|
@@ -264,7 +594,7 @@ function listingsCommand(getClient2, getFormat2) {
|
|
|
264
594
|
async (collection, options) => {
|
|
265
595
|
const client = getClient2();
|
|
266
596
|
const result = await client.get(`/api/v2/listings/collection/${collection}/all`, {
|
|
267
|
-
limit:
|
|
597
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
268
598
|
next: options.next
|
|
269
599
|
});
|
|
270
600
|
console.log(formatOutput(result, getFormat2()));
|
|
@@ -274,7 +604,7 @@ function listingsCommand(getClient2, getFormat2) {
|
|
|
274
604
|
async (collection, options) => {
|
|
275
605
|
const client = getClient2();
|
|
276
606
|
const result = await client.get(`/api/v2/listings/collection/${collection}/best`, {
|
|
277
|
-
limit:
|
|
607
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
278
608
|
next: options.next
|
|
279
609
|
});
|
|
280
610
|
console.log(formatOutput(result, getFormat2()));
|
|
@@ -306,7 +636,7 @@ function nftsCommand(getClient2, getFormat2) {
|
|
|
306
636
|
const result = await client.get(
|
|
307
637
|
`/api/v2/collection/${slug}/nfts`,
|
|
308
638
|
{
|
|
309
|
-
limit:
|
|
639
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
310
640
|
next: options.next
|
|
311
641
|
}
|
|
312
642
|
);
|
|
@@ -318,7 +648,7 @@ function nftsCommand(getClient2, getFormat2) {
|
|
|
318
648
|
const result = await client.get(
|
|
319
649
|
`/api/v2/chain/${chain}/contract/${contract}/nfts`,
|
|
320
650
|
{
|
|
321
|
-
limit:
|
|
651
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
322
652
|
next: options.next
|
|
323
653
|
}
|
|
324
654
|
);
|
|
@@ -331,7 +661,7 @@ function nftsCommand(getClient2, getFormat2) {
|
|
|
331
661
|
const result = await client.get(
|
|
332
662
|
`/api/v2/chain/${chain}/account/${address}/nfts`,
|
|
333
663
|
{
|
|
334
|
-
limit:
|
|
664
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
335
665
|
next: options.next
|
|
336
666
|
}
|
|
337
667
|
);
|
|
@@ -368,7 +698,7 @@ function offersCommand(getClient2, getFormat2) {
|
|
|
368
698
|
async (collection, options) => {
|
|
369
699
|
const client = getClient2();
|
|
370
700
|
const result = await client.get(`/api/v2/offers/collection/${collection}/all`, {
|
|
371
|
-
limit:
|
|
701
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
372
702
|
next: options.next
|
|
373
703
|
});
|
|
374
704
|
console.log(formatOutput(result, getFormat2()));
|
|
@@ -378,7 +708,7 @@ function offersCommand(getClient2, getFormat2) {
|
|
|
378
708
|
async (collection, options) => {
|
|
379
709
|
const client = getClient2();
|
|
380
710
|
const result = await client.get(`/api/v2/offers/collection/${collection}`, {
|
|
381
|
-
limit:
|
|
711
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
382
712
|
next: options.next
|
|
383
713
|
});
|
|
384
714
|
console.log(formatOutput(result, getFormat2()));
|
|
@@ -397,7 +727,7 @@ function offersCommand(getClient2, getFormat2) {
|
|
|
397
727
|
const result = await client.get(`/api/v2/offers/collection/${collection}/traits`, {
|
|
398
728
|
type: options.type,
|
|
399
729
|
value: options.value,
|
|
400
|
-
limit:
|
|
730
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
401
731
|
next: options.next
|
|
402
732
|
});
|
|
403
733
|
console.log(formatOutput(result, getFormat2()));
|
|
@@ -512,7 +842,7 @@ function searchCommand(getClient2, getFormat2) {
|
|
|
512
842
|
const client = getClient2();
|
|
513
843
|
const result = await client.graphql(SEARCH_COLLECTIONS_QUERY, {
|
|
514
844
|
query,
|
|
515
|
-
limit:
|
|
845
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
516
846
|
chains: options.chains?.split(",")
|
|
517
847
|
});
|
|
518
848
|
console.log(formatOutput(result.collectionsByQuery, getFormat2()));
|
|
@@ -524,7 +854,7 @@ function searchCommand(getClient2, getFormat2) {
|
|
|
524
854
|
const result = await client.graphql(SEARCH_NFTS_QUERY, {
|
|
525
855
|
query,
|
|
526
856
|
collectionSlug: options.collection,
|
|
527
|
-
limit:
|
|
857
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
528
858
|
chains: options.chains?.split(",")
|
|
529
859
|
});
|
|
530
860
|
console.log(formatOutput(result.itemsByQuery, getFormat2()));
|
|
@@ -535,7 +865,7 @@ function searchCommand(getClient2, getFormat2) {
|
|
|
535
865
|
const client = getClient2();
|
|
536
866
|
const result = await client.graphql(SEARCH_TOKENS_QUERY, {
|
|
537
867
|
query,
|
|
538
|
-
limit:
|
|
868
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
539
869
|
chain: options.chain
|
|
540
870
|
});
|
|
541
871
|
console.log(formatOutput(result.currenciesByQuery, getFormat2()));
|
|
@@ -545,7 +875,7 @@ function searchCommand(getClient2, getFormat2) {
|
|
|
545
875
|
const client = getClient2();
|
|
546
876
|
const result = await client.graphql(SEARCH_ACCOUNTS_QUERY, {
|
|
547
877
|
query,
|
|
548
|
-
limit:
|
|
878
|
+
limit: parseIntOption(options.limit, "--limit")
|
|
549
879
|
});
|
|
550
880
|
console.log(formatOutput(result.accountsByQuery, getFormat2()));
|
|
551
881
|
});
|
|
@@ -584,7 +914,7 @@ function swapsCommand(getClient2, getFormat2) {
|
|
|
584
914
|
to_address: options.toAddress,
|
|
585
915
|
quantity: options.quantity,
|
|
586
916
|
address: options.address,
|
|
587
|
-
slippage: options.slippage ?
|
|
917
|
+
slippage: options.slippage ? parseFloatOption(options.slippage, "--slippage") : void 0,
|
|
588
918
|
recipient: options.recipient
|
|
589
919
|
}
|
|
590
920
|
);
|
|
@@ -600,29 +930,31 @@ function tokensCommand(getClient2, getFormat2) {
|
|
|
600
930
|
const cmd = new Command9("tokens").description(
|
|
601
931
|
"Query trending tokens, top tokens, and token details"
|
|
602
932
|
);
|
|
603
|
-
cmd.command("trending").description("Get trending tokens based on OpenSea's trending score").option("--chains <chains>", "Comma-separated list of chains to filter by").option("--limit <limit>", "Number of results (max 100)", "20").option("--
|
|
933
|
+
cmd.command("trending").description("Get trending tokens based on OpenSea's trending score").option("--chains <chains>", "Comma-separated list of chains to filter by").option("--limit <limit>", "Number of results (max 100)", "20").option("--next <cursor>", "Pagination cursor").action(
|
|
604
934
|
async (options) => {
|
|
605
935
|
const client = getClient2();
|
|
606
936
|
const result = await client.get(
|
|
607
937
|
"/api/v2/tokens/trending",
|
|
608
938
|
{
|
|
609
939
|
chains: options.chains,
|
|
610
|
-
limit:
|
|
611
|
-
cursor
|
|
940
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
941
|
+
// Tokens API uses "cursor" instead of "next" as the query param
|
|
942
|
+
cursor: options.next
|
|
612
943
|
}
|
|
613
944
|
);
|
|
614
945
|
console.log(formatOutput(result, getFormat2()));
|
|
615
946
|
}
|
|
616
947
|
);
|
|
617
|
-
cmd.command("top").description("Get top tokens ranked by 24-hour trading volume").option("--chains <chains>", "Comma-separated list of chains to filter by").option("--limit <limit>", "Number of results (max 100)", "20").option("--
|
|
948
|
+
cmd.command("top").description("Get top tokens ranked by 24-hour trading volume").option("--chains <chains>", "Comma-separated list of chains to filter by").option("--limit <limit>", "Number of results (max 100)", "20").option("--next <cursor>", "Pagination cursor").action(
|
|
618
949
|
async (options) => {
|
|
619
950
|
const client = getClient2();
|
|
620
951
|
const result = await client.get(
|
|
621
952
|
"/api/v2/tokens/top",
|
|
622
953
|
{
|
|
623
954
|
chains: options.chains,
|
|
624
|
-
limit:
|
|
625
|
-
cursor
|
|
955
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
956
|
+
// Tokens API uses "cursor" instead of "next" as the query param
|
|
957
|
+
cursor: options.next
|
|
626
958
|
}
|
|
627
959
|
);
|
|
628
960
|
console.log(formatOutput(result, getFormat2()));
|
|
@@ -650,7 +982,7 @@ var BANNER = `
|
|
|
650
982
|
|_|
|
|
651
983
|
`;
|
|
652
984
|
var program = new Command10();
|
|
653
|
-
program.name("opensea").description("OpenSea CLI - Query the OpenSea API from the command line").version(process.env.npm_package_version ?? "0.0.0").addHelpText("before", BANNER).option("--api-key <key>", "OpenSea API key (or set OPENSEA_API_KEY env var)").option("--chain <chain>", "Default chain", "ethereum").option("--format <format>", "Output format (json or
|
|
985
|
+
program.name("opensea").description("OpenSea CLI - Query the OpenSea API from the command line").version(process.env.npm_package_version ?? "0.0.0").addHelpText("before", BANNER).option("--api-key <key>", "OpenSea API key (or set OPENSEA_API_KEY env var)").option("--chain <chain>", "Default chain", "ethereum").option("--format <format>", "Output format (json, table, or toon)", "json").option("--base-url <url>", "API base URL").option("--timeout <ms>", "Request timeout in milliseconds", "30000").option("--verbose", "Log request and response info to stderr");
|
|
654
986
|
function getClient() {
|
|
655
987
|
const opts = program.opts();
|
|
656
988
|
const apiKey = opts.apiKey ?? process.env.OPENSEA_API_KEY;
|
|
@@ -663,12 +995,16 @@ function getClient() {
|
|
|
663
995
|
return new OpenSeaClient({
|
|
664
996
|
apiKey,
|
|
665
997
|
chain: opts.chain,
|
|
666
|
-
baseUrl: opts.baseUrl
|
|
998
|
+
baseUrl: opts.baseUrl,
|
|
999
|
+
timeout: parseIntOption(opts.timeout, "--timeout"),
|
|
1000
|
+
verbose: opts.verbose
|
|
667
1001
|
});
|
|
668
1002
|
}
|
|
669
1003
|
function getFormat() {
|
|
670
1004
|
const opts = program.opts();
|
|
671
|
-
|
|
1005
|
+
if (opts.format === "table") return "table";
|
|
1006
|
+
if (opts.format === "toon") return "toon";
|
|
1007
|
+
return "json";
|
|
672
1008
|
}
|
|
673
1009
|
program.addCommand(collectionsCommand(getClient, getFormat));
|
|
674
1010
|
program.addCommand(nftsCommand(getClient, getFormat));
|
|
@@ -698,7 +1034,18 @@ async function main() {
|
|
|
698
1034
|
);
|
|
699
1035
|
process.exit(1);
|
|
700
1036
|
}
|
|
701
|
-
|
|
1037
|
+
const label = error instanceof TypeError ? "Network Error" : error.name;
|
|
1038
|
+
console.error(
|
|
1039
|
+
JSON.stringify(
|
|
1040
|
+
{
|
|
1041
|
+
error: label,
|
|
1042
|
+
message: error.message
|
|
1043
|
+
},
|
|
1044
|
+
null,
|
|
1045
|
+
2
|
|
1046
|
+
)
|
|
1047
|
+
);
|
|
1048
|
+
process.exit(1);
|
|
702
1049
|
}
|
|
703
1050
|
}
|
|
704
1051
|
main();
|