opensea-cli 0.1.6 → 0.2.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/dist/cli.js DELETED
@@ -1,705 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/cli.ts
4
- import { Command as Command10 } from "commander";
5
-
6
- // src/client.ts
7
- var DEFAULT_BASE_URL = "https://api.opensea.io";
8
- var DEFAULT_GRAPHQL_URL = "https://gql.opensea.io/graphql";
9
- var OpenSeaClient = class {
10
- apiKey;
11
- baseUrl;
12
- graphqlUrl;
13
- defaultChain;
14
- constructor(config) {
15
- this.apiKey = config.apiKey;
16
- this.baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
17
- this.graphqlUrl = config.graphqlUrl ?? DEFAULT_GRAPHQL_URL;
18
- this.defaultChain = config.chain ?? "ethereum";
19
- }
20
- async get(path, params) {
21
- const url = new URL(`${this.baseUrl}${path}`);
22
- if (params) {
23
- for (const [key, value] of Object.entries(params)) {
24
- if (value !== void 0 && value !== null) {
25
- url.searchParams.set(key, String(value));
26
- }
27
- }
28
- }
29
- const response = await fetch(url.toString(), {
30
- method: "GET",
31
- headers: {
32
- Accept: "application/json",
33
- "x-api-key": this.apiKey
34
- }
35
- });
36
- if (!response.ok) {
37
- const body = await response.text();
38
- throw new OpenSeaAPIError(response.status, body, path);
39
- }
40
- return response.json();
41
- }
42
- async post(path) {
43
- const url = new URL(`${this.baseUrl}${path}`);
44
- const response = await fetch(url.toString(), {
45
- method: "POST",
46
- headers: {
47
- Accept: "application/json",
48
- "x-api-key": this.apiKey
49
- }
50
- });
51
- if (!response.ok) {
52
- const body = await response.text();
53
- throw new OpenSeaAPIError(response.status, body, path);
54
- }
55
- return response.json();
56
- }
57
- async graphql(query, variables) {
58
- const response = await fetch(this.graphqlUrl, {
59
- method: "POST",
60
- headers: {
61
- "Content-Type": "application/json",
62
- Accept: "application/json",
63
- "x-api-key": this.apiKey
64
- },
65
- body: JSON.stringify({ query, variables })
66
- });
67
- if (!response.ok) {
68
- const body = await response.text();
69
- throw new OpenSeaAPIError(response.status, body, "graphql");
70
- }
71
- const json = await response.json();
72
- if (json.errors?.length) {
73
- throw new OpenSeaAPIError(
74
- 400,
75
- json.errors.map((e) => e.message).join("; "),
76
- "graphql"
77
- );
78
- }
79
- if (!json.data) {
80
- throw new OpenSeaAPIError(500, "GraphQL response missing data", "graphql");
81
- }
82
- return json.data;
83
- }
84
- getDefaultChain() {
85
- return this.defaultChain;
86
- }
87
- };
88
- var OpenSeaAPIError = class extends Error {
89
- constructor(statusCode, responseBody, path) {
90
- super(`OpenSea API error ${statusCode} on ${path}: ${responseBody}`);
91
- this.statusCode = statusCode;
92
- this.responseBody = responseBody;
93
- this.path = path;
94
- this.name = "OpenSeaAPIError";
95
- }
96
- };
97
-
98
- // src/commands/accounts.ts
99
- import { Command } from "commander";
100
-
101
- // src/output.ts
102
- function formatOutput(data, format) {
103
- if (format === "table") {
104
- return formatTable(data);
105
- }
106
- return JSON.stringify(data, null, 2);
107
- }
108
- function formatTable(data) {
109
- if (Array.isArray(data)) {
110
- if (data.length === 0) return "(empty)";
111
- const keys = Object.keys(data[0]);
112
- const widths = keys.map(
113
- (key) => Math.max(
114
- key.length,
115
- ...data.map((row) => {
116
- const val = row[key];
117
- return String(val ?? "").length;
118
- })
119
- )
120
- );
121
- const header = keys.map((key, i) => key.padEnd(widths[i])).join(" ");
122
- const separator = widths.map((w) => "-".repeat(w)).join(" ");
123
- const rows = data.map(
124
- (row) => keys.map((key, i) => {
125
- const val = row[key];
126
- return String(val ?? "").padEnd(widths[i]);
127
- }).join(" ")
128
- );
129
- return [header, separator, ...rows].join("\n");
130
- }
131
- if (data && typeof data === "object") {
132
- const entries = Object.entries(data);
133
- const maxKeyLength = Math.max(...entries.map(([k]) => k.length));
134
- return entries.map(([key, value]) => {
135
- const displayValue = typeof value === "object" && value !== null ? JSON.stringify(value) : String(value ?? "");
136
- return `${key.padEnd(maxKeyLength)} ${displayValue}`;
137
- }).join("\n");
138
- }
139
- return String(data);
140
- }
141
-
142
- // src/commands/accounts.ts
143
- function accountsCommand(getClient2, getFormat2) {
144
- const cmd = new Command("accounts").description("Query accounts");
145
- cmd.command("get").description("Get an account by address").argument("<address>", "Wallet address").action(async (address) => {
146
- const client = getClient2();
147
- const result = await client.get(`/api/v2/accounts/${address}`);
148
- console.log(formatOutput(result, getFormat2()));
149
- });
150
- return cmd;
151
- }
152
-
153
- // src/commands/collections.ts
154
- import { Command as Command2 } from "commander";
155
- function collectionsCommand(getClient2, getFormat2) {
156
- const cmd = new Command2("collections").description(
157
- "Manage and query NFT collections"
158
- );
159
- cmd.command("get").description("Get a single collection by slug").argument("<slug>", "Collection slug").action(async (slug) => {
160
- const client = getClient2();
161
- const result = await client.get(`/api/v2/collections/${slug}`);
162
- console.log(formatOutput(result, getFormat2()));
163
- });
164
- cmd.command("list").description("List collections").option("--chain <chain>", "Filter by chain").option(
165
- "--order-by <orderBy>",
166
- "Order by field (created_date, one_day_change, seven_day_volume, seven_day_change, num_owners, market_cap)"
167
- ).option("--creator <username>", "Filter by creator username").option("--include-hidden", "Include hidden collections").option("--limit <limit>", "Number of results", "20").option("--next <cursor>", "Pagination cursor").action(
168
- async (options) => {
169
- const client = getClient2();
170
- const result = await client.get("/api/v2/collections", {
171
- chain: options.chain,
172
- order_by: options.orderBy,
173
- creator_username: options.creator,
174
- include_hidden: options.includeHidden,
175
- limit: Number.parseInt(options.limit, 10),
176
- next: options.next
177
- });
178
- console.log(formatOutput(result, getFormat2()));
179
- }
180
- );
181
- cmd.command("stats").description("Get collection stats").argument("<slug>", "Collection slug").action(async (slug) => {
182
- const client = getClient2();
183
- const result = await client.get(
184
- `/api/v2/collections/${slug}/stats`
185
- );
186
- console.log(formatOutput(result, getFormat2()));
187
- });
188
- cmd.command("traits").description("Get collection traits").argument("<slug>", "Collection slug").action(async (slug) => {
189
- const client = getClient2();
190
- const result = await client.get(
191
- `/api/v2/traits/${slug}`
192
- );
193
- console.log(formatOutput(result, getFormat2()));
194
- });
195
- return cmd;
196
- }
197
-
198
- // src/commands/events.ts
199
- import { Command as Command3 } from "commander";
200
- function eventsCommand(getClient2, getFormat2) {
201
- const cmd = new Command3("events").description("Query marketplace events");
202
- cmd.command("list").description("List events").option(
203
- "--event-type <type>",
204
- "Event type (sale, transfer, mint, listing, offer, trait_offer, collection_offer)"
205
- ).option("--after <timestamp>", "Filter events after this Unix timestamp").option("--before <timestamp>", "Filter events before this Unix timestamp").option("--chain <chain>", "Filter by chain").option("--limit <limit>", "Number of results", "20").option("--next <cursor>", "Pagination cursor").action(
206
- async (options) => {
207
- const client = getClient2();
208
- const result = await client.get("/api/v2/events", {
209
- event_type: options.eventType,
210
- after: options.after ? Number.parseInt(options.after, 10) : void 0,
211
- before: options.before ? Number.parseInt(options.before, 10) : void 0,
212
- chain: options.chain,
213
- limit: Number.parseInt(options.limit, 10),
214
- next: options.next
215
- });
216
- console.log(formatOutput(result, getFormat2()));
217
- }
218
- );
219
- cmd.command("by-account").description("Get events for an account").argument("<address>", "Account address").option("--event-type <type>", "Event type").option("--chain <chain>", "Filter by chain").option("--limit <limit>", "Number of results", "20").option("--next <cursor>", "Pagination cursor").action(
220
- async (address, options) => {
221
- const client = getClient2();
222
- const result = await client.get(`/api/v2/events/accounts/${address}`, {
223
- event_type: options.eventType,
224
- chain: options.chain,
225
- limit: Number.parseInt(options.limit, 10),
226
- next: options.next
227
- });
228
- console.log(formatOutput(result, getFormat2()));
229
- }
230
- );
231
- cmd.command("by-collection").description("Get events for a collection").argument("<slug>", "Collection slug").option("--event-type <type>", "Event type").option("--limit <limit>", "Number of results", "20").option("--next <cursor>", "Pagination cursor").action(
232
- async (slug, options) => {
233
- const client = getClient2();
234
- const result = await client.get(`/api/v2/events/collection/${slug}`, {
235
- event_type: options.eventType,
236
- limit: Number.parseInt(options.limit, 10),
237
- next: options.next
238
- });
239
- console.log(formatOutput(result, getFormat2()));
240
- }
241
- );
242
- cmd.command("by-nft").description("Get events for a specific NFT").argument("<chain>", "Chain").argument("<contract>", "Contract address").argument("<token-id>", "Token ID").option("--event-type <type>", "Event type").option("--limit <limit>", "Number of results", "20").option("--next <cursor>", "Pagination cursor").action(
243
- async (chain, contract, tokenId, options) => {
244
- const client = getClient2();
245
- const result = await client.get(
246
- `/api/v2/events/chain/${chain}/contract/${contract}/nfts/${tokenId}`,
247
- {
248
- event_type: options.eventType,
249
- limit: Number.parseInt(options.limit, 10),
250
- next: options.next
251
- }
252
- );
253
- console.log(formatOutput(result, getFormat2()));
254
- }
255
- );
256
- return cmd;
257
- }
258
-
259
- // src/commands/listings.ts
260
- import { Command as Command4 } from "commander";
261
- function listingsCommand(getClient2, getFormat2) {
262
- const cmd = new Command4("listings").description("Query NFT listings");
263
- cmd.command("all").description("Get all listings for a collection").argument("<collection>", "Collection slug").option("--limit <limit>", "Number of results", "20").option("--next <cursor>", "Pagination cursor").action(
264
- async (collection, options) => {
265
- const client = getClient2();
266
- const result = await client.get(`/api/v2/listings/collection/${collection}/all`, {
267
- limit: Number.parseInt(options.limit, 10),
268
- next: options.next
269
- });
270
- console.log(formatOutput(result, getFormat2()));
271
- }
272
- );
273
- cmd.command("best").description("Get best listings for a collection").argument("<collection>", "Collection slug").option("--limit <limit>", "Number of results", "20").option("--next <cursor>", "Pagination cursor").action(
274
- async (collection, options) => {
275
- const client = getClient2();
276
- const result = await client.get(`/api/v2/listings/collection/${collection}/best`, {
277
- limit: Number.parseInt(options.limit, 10),
278
- next: options.next
279
- });
280
- console.log(formatOutput(result, getFormat2()));
281
- }
282
- );
283
- cmd.command("best-for-nft").description("Get best listing for a specific NFT").argument("<collection>", "Collection slug").argument("<token-id>", "Token ID").action(async (collection, tokenId) => {
284
- const client = getClient2();
285
- const result = await client.get(
286
- `/api/v2/listings/collection/${collection}/nfts/${tokenId}/best`
287
- );
288
- console.log(formatOutput(result, getFormat2()));
289
- });
290
- return cmd;
291
- }
292
-
293
- // src/commands/nfts.ts
294
- import { Command as Command5 } from "commander";
295
- function nftsCommand(getClient2, getFormat2) {
296
- const cmd = new Command5("nfts").description("Query NFTs");
297
- cmd.command("get").description("Get a single NFT").argument("<chain>", "Chain (e.g. ethereum, base)").argument("<contract>", "Contract address").argument("<token-id>", "Token ID").action(async (chain, contract, tokenId) => {
298
- const client = getClient2();
299
- const result = await client.get(
300
- `/api/v2/chain/${chain}/contract/${contract}/nfts/${tokenId}`
301
- );
302
- console.log(formatOutput(result, getFormat2()));
303
- });
304
- cmd.command("list-by-collection").description("List NFTs in a collection").argument("<slug>", "Collection slug").option("--limit <limit>", "Number of results", "20").option("--next <cursor>", "Pagination cursor").action(async (slug, options) => {
305
- const client = getClient2();
306
- const result = await client.get(
307
- `/api/v2/collection/${slug}/nfts`,
308
- {
309
- limit: Number.parseInt(options.limit, 10),
310
- next: options.next
311
- }
312
- );
313
- console.log(formatOutput(result, getFormat2()));
314
- });
315
- cmd.command("list-by-contract").description("List NFTs by contract address").argument("<chain>", "Chain").argument("<contract>", "Contract address").option("--limit <limit>", "Number of results", "20").option("--next <cursor>", "Pagination cursor").action(
316
- async (chain, contract, options) => {
317
- const client = getClient2();
318
- const result = await client.get(
319
- `/api/v2/chain/${chain}/contract/${contract}/nfts`,
320
- {
321
- limit: Number.parseInt(options.limit, 10),
322
- next: options.next
323
- }
324
- );
325
- console.log(formatOutput(result, getFormat2()));
326
- }
327
- );
328
- cmd.command("list-by-account").description("List NFTs owned by an account").argument("<chain>", "Chain").argument("<address>", "Account address").option("--limit <limit>", "Number of results", "20").option("--next <cursor>", "Pagination cursor").action(
329
- async (chain, address, options) => {
330
- const client = getClient2();
331
- const result = await client.get(
332
- `/api/v2/chain/${chain}/account/${address}/nfts`,
333
- {
334
- limit: Number.parseInt(options.limit, 10),
335
- next: options.next
336
- }
337
- );
338
- console.log(formatOutput(result, getFormat2()));
339
- }
340
- );
341
- cmd.command("refresh").description("Refresh NFT metadata").argument("<chain>", "Chain").argument("<contract>", "Contract address").argument("<token-id>", "Token ID").action(async (chain, contract, tokenId) => {
342
- const client = getClient2();
343
- await client.post(
344
- `/api/v2/chain/${chain}/contract/${contract}/nfts/${tokenId}/refresh`
345
- );
346
- console.log(
347
- formatOutput(
348
- { status: "ok", message: "Metadata refresh requested" },
349
- getFormat2()
350
- )
351
- );
352
- });
353
- cmd.command("contract").description("Get contract details").argument("<chain>", "Chain").argument("<address>", "Contract address").action(async (chain, address) => {
354
- const client = getClient2();
355
- const result = await client.get(
356
- `/api/v2/chain/${chain}/contract/${address}`
357
- );
358
- console.log(formatOutput(result, getFormat2()));
359
- });
360
- return cmd;
361
- }
362
-
363
- // src/commands/offers.ts
364
- import { Command as Command6 } from "commander";
365
- function offersCommand(getClient2, getFormat2) {
366
- const cmd = new Command6("offers").description("Query NFT offers");
367
- cmd.command("all").description("Get all offers for a collection").argument("<collection>", "Collection slug").option("--limit <limit>", "Number of results", "20").option("--next <cursor>", "Pagination cursor").action(
368
- async (collection, options) => {
369
- const client = getClient2();
370
- const result = await client.get(`/api/v2/offers/collection/${collection}/all`, {
371
- limit: Number.parseInt(options.limit, 10),
372
- next: options.next
373
- });
374
- console.log(formatOutput(result, getFormat2()));
375
- }
376
- );
377
- cmd.command("collection").description("Get collection offers").argument("<collection>", "Collection slug").option("--limit <limit>", "Number of results", "20").option("--next <cursor>", "Pagination cursor").action(
378
- async (collection, options) => {
379
- const client = getClient2();
380
- const result = await client.get(`/api/v2/offers/collection/${collection}`, {
381
- limit: Number.parseInt(options.limit, 10),
382
- next: options.next
383
- });
384
- console.log(formatOutput(result, getFormat2()));
385
- }
386
- );
387
- cmd.command("best-for-nft").description("Get best offer for a specific NFT").argument("<collection>", "Collection slug").argument("<token-id>", "Token ID").action(async (collection, tokenId) => {
388
- const client = getClient2();
389
- const result = await client.get(
390
- `/api/v2/offers/collection/${collection}/nfts/${tokenId}/best`
391
- );
392
- console.log(formatOutput(result, getFormat2()));
393
- });
394
- cmd.command("traits").description("Get trait offers for a collection").argument("<collection>", "Collection slug").requiredOption("--type <type>", "Trait type (required)").requiredOption("--value <value>", "Trait value (required)").option("--limit <limit>", "Number of results", "20").option("--next <cursor>", "Pagination cursor").action(
395
- async (collection, options) => {
396
- const client = getClient2();
397
- const result = await client.get(`/api/v2/offers/collection/${collection}/traits`, {
398
- type: options.type,
399
- value: options.value,
400
- limit: Number.parseInt(options.limit, 10),
401
- next: options.next
402
- });
403
- console.log(formatOutput(result, getFormat2()));
404
- }
405
- );
406
- return cmd;
407
- }
408
-
409
- // src/commands/search.ts
410
- import { Command as Command7 } from "commander";
411
-
412
- // src/queries.ts
413
- var SEARCH_COLLECTIONS_QUERY = `
414
- query SearchCollections($query: String!, $limit: Int, $chains: [ChainIdentifier!]) {
415
- collectionsByQuery(query: $query, limit: $limit, chains: $chains) {
416
- slug
417
- name
418
- description
419
- imageUrl
420
- chain {
421
- identifier
422
- name
423
- }
424
- stats {
425
- totalSupply
426
- ownerCount
427
- volume {
428
- usd
429
- }
430
- sales
431
- }
432
- floorPrice {
433
- pricePerItem {
434
- usd
435
- native {
436
- unit
437
- symbol
438
- }
439
- }
440
- }
441
- }
442
- }`;
443
- var SEARCH_NFTS_QUERY = `
444
- query SearchItems($query: String!, $collectionSlug: String, $limit: Int, $chains: [ChainIdentifier!]) {
445
- itemsByQuery(query: $query, collectionSlug: $collectionSlug, limit: $limit, chains: $chains) {
446
- tokenId
447
- name
448
- description
449
- imageUrl
450
- contractAddress
451
- collection {
452
- slug
453
- name
454
- }
455
- chain {
456
- identifier
457
- name
458
- }
459
- bestListing {
460
- pricePerItem {
461
- usd
462
- native {
463
- unit
464
- symbol
465
- }
466
- }
467
- }
468
- owner {
469
- address
470
- displayName
471
- }
472
- }
473
- }`;
474
- var SEARCH_TOKENS_QUERY = `
475
- query SearchCurrencies($query: String!, $limit: Int, $chain: ChainIdentifier) {
476
- currenciesByQuery(query: $query, limit: $limit, chain: $chain, allowlistOnly: false) {
477
- name
478
- symbol
479
- imageUrl
480
- usdPrice
481
- contractAddress
482
- chain {
483
- identifier
484
- name
485
- }
486
- stats {
487
- marketCapUsd
488
- oneDay {
489
- priceChange
490
- volume
491
- }
492
- }
493
- }
494
- }`;
495
- var SEARCH_ACCOUNTS_QUERY = `
496
- query SearchAccounts($query: String!, $limit: Int) {
497
- accountsByQuery(query: $query, limit: $limit) {
498
- address
499
- username
500
- imageUrl
501
- isVerified
502
- }
503
- }`;
504
-
505
- // src/commands/search.ts
506
- function searchCommand(getClient2, getFormat2) {
507
- const cmd = new Command7("search").description(
508
- "Search for collections, NFTs, tokens, and accounts"
509
- );
510
- cmd.command("collections").description("Search collections by name or slug").argument("<query>", "Search query").option("--chains <chains>", "Filter by chains (comma-separated)").option("--limit <limit>", "Number of results", "10").action(
511
- async (query, options) => {
512
- const client = getClient2();
513
- const result = await client.graphql(SEARCH_COLLECTIONS_QUERY, {
514
- query,
515
- limit: Number.parseInt(options.limit, 10),
516
- chains: options.chains?.split(",")
517
- });
518
- console.log(formatOutput(result.collectionsByQuery, getFormat2()));
519
- }
520
- );
521
- cmd.command("nfts").description("Search NFTs by name").argument("<query>", "Search query").option("--collection <slug>", "Filter by collection slug").option("--chains <chains>", "Filter by chains (comma-separated)").option("--limit <limit>", "Number of results", "10").action(
522
- async (query, options) => {
523
- const client = getClient2();
524
- const result = await client.graphql(SEARCH_NFTS_QUERY, {
525
- query,
526
- collectionSlug: options.collection,
527
- limit: Number.parseInt(options.limit, 10),
528
- chains: options.chains?.split(",")
529
- });
530
- console.log(formatOutput(result.itemsByQuery, getFormat2()));
531
- }
532
- );
533
- cmd.command("tokens").description("Search tokens/currencies by name or symbol").argument("<query>", "Search query").option("--chain <chain>", "Filter by chain").option("--limit <limit>", "Number of results", "10").action(
534
- async (query, options) => {
535
- const client = getClient2();
536
- const result = await client.graphql(SEARCH_TOKENS_QUERY, {
537
- query,
538
- limit: Number.parseInt(options.limit, 10),
539
- chain: options.chain
540
- });
541
- console.log(formatOutput(result.currenciesByQuery, getFormat2()));
542
- }
543
- );
544
- cmd.command("accounts").description("Search accounts by username or address").argument("<query>", "Search query").option("--limit <limit>", "Number of results", "10").action(async (query, options) => {
545
- const client = getClient2();
546
- const result = await client.graphql(SEARCH_ACCOUNTS_QUERY, {
547
- query,
548
- limit: Number.parseInt(options.limit, 10)
549
- });
550
- console.log(formatOutput(result.accountsByQuery, getFormat2()));
551
- });
552
- return cmd;
553
- }
554
-
555
- // src/commands/swaps.ts
556
- import { Command as Command8 } from "commander";
557
- function swapsCommand(getClient2, getFormat2) {
558
- const cmd = new Command8("swaps").description(
559
- "Get swap quotes for token trading"
560
- );
561
- cmd.command("quote").description(
562
- "Get a quote for swapping tokens, including price details and executable transaction data"
563
- ).requiredOption("--from-chain <chain>", "Chain of the token to swap from").requiredOption(
564
- "--from-address <address>",
565
- "Contract address of the token to swap from"
566
- ).requiredOption("--to-chain <chain>", "Chain of the token to swap to").requiredOption(
567
- "--to-address <address>",
568
- "Contract address of the token to swap to"
569
- ).requiredOption("--quantity <quantity>", "Amount to swap (in token units)").requiredOption("--address <address>", "Wallet address executing the swap").option(
570
- "--slippage <slippage>",
571
- "Slippage tolerance (0.0 to 0.5, default: 0.01)"
572
- ).option(
573
- "--recipient <recipient>",
574
- "Recipient address (defaults to sender address)"
575
- ).action(
576
- async (options) => {
577
- const client = getClient2();
578
- const result = await client.get(
579
- "/api/v2/swap/quote",
580
- {
581
- from_chain: options.fromChain,
582
- from_address: options.fromAddress,
583
- to_chain: options.toChain,
584
- to_address: options.toAddress,
585
- quantity: options.quantity,
586
- address: options.address,
587
- slippage: options.slippage ? Number.parseFloat(options.slippage) : void 0,
588
- recipient: options.recipient
589
- }
590
- );
591
- console.log(formatOutput(result, getFormat2()));
592
- }
593
- );
594
- return cmd;
595
- }
596
-
597
- // src/commands/tokens.ts
598
- import { Command as Command9 } from "commander";
599
- function tokensCommand(getClient2, getFormat2) {
600
- const cmd = new Command9("tokens").description(
601
- "Query trending tokens, top tokens, and token details"
602
- );
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("--cursor <cursor>", "Pagination cursor").action(
604
- async (options) => {
605
- const client = getClient2();
606
- const result = await client.get(
607
- "/api/v2/tokens/trending",
608
- {
609
- chains: options.chains,
610
- limit: Number.parseInt(options.limit, 10),
611
- cursor: options.cursor
612
- }
613
- );
614
- console.log(formatOutput(result, getFormat2()));
615
- }
616
- );
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("--cursor <cursor>", "Pagination cursor").action(
618
- async (options) => {
619
- const client = getClient2();
620
- const result = await client.get(
621
- "/api/v2/tokens/top",
622
- {
623
- chains: options.chains,
624
- limit: Number.parseInt(options.limit, 10),
625
- cursor: options.cursor
626
- }
627
- );
628
- console.log(formatOutput(result, getFormat2()));
629
- }
630
- );
631
- cmd.command("get").description("Get detailed information about a specific token").argument("<chain>", "Blockchain chain").argument("<address>", "Token contract address").action(async (chain, address) => {
632
- const client = getClient2();
633
- const result = await client.get(
634
- `/api/v2/chain/${chain}/token/${address}`
635
- );
636
- console.log(formatOutput(result, getFormat2()));
637
- });
638
- return cmd;
639
- }
640
-
641
- // src/cli.ts
642
- var BANNER = `
643
- ____ _____
644
- / __ \\ / ____|
645
- | | | |_ __ ___ _ _| (___ ___ __ _
646
- | | | | '_ \\ / _ \\ '_ \\___ \\ / _ \\/ _\` |
647
- | |__| | |_) | __/ | | |___) | __/ (_| |
648
- \\____/| .__/ \\___|_| |_|____/ \\___|\\__,_|
649
- | |
650
- |_|
651
- `;
652
- 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 table)", "json").option("--base-url <url>", "API base URL");
654
- function getClient() {
655
- const opts = program.opts();
656
- const apiKey = opts.apiKey ?? process.env.OPENSEA_API_KEY;
657
- if (!apiKey) {
658
- console.error(
659
- "Error: API key required. Use --api-key or set OPENSEA_API_KEY environment variable."
660
- );
661
- process.exit(2);
662
- }
663
- return new OpenSeaClient({
664
- apiKey,
665
- chain: opts.chain,
666
- baseUrl: opts.baseUrl
667
- });
668
- }
669
- function getFormat() {
670
- const opts = program.opts();
671
- return opts.format === "table" ? "table" : "json";
672
- }
673
- program.addCommand(collectionsCommand(getClient, getFormat));
674
- program.addCommand(nftsCommand(getClient, getFormat));
675
- program.addCommand(listingsCommand(getClient, getFormat));
676
- program.addCommand(offersCommand(getClient, getFormat));
677
- program.addCommand(eventsCommand(getClient, getFormat));
678
- program.addCommand(accountsCommand(getClient, getFormat));
679
- program.addCommand(tokensCommand(getClient, getFormat));
680
- program.addCommand(searchCommand(getClient, getFormat));
681
- program.addCommand(swapsCommand(getClient, getFormat));
682
- async function main() {
683
- try {
684
- await program.parseAsync(process.argv);
685
- } catch (error) {
686
- if (error instanceof OpenSeaAPIError) {
687
- console.error(
688
- JSON.stringify(
689
- {
690
- error: "API Error",
691
- status: error.statusCode,
692
- path: error.path,
693
- message: error.responseBody
694
- },
695
- null,
696
- 2
697
- )
698
- );
699
- process.exit(1);
700
- }
701
- throw error;
702
- }
703
- }
704
- main();
705
- //# sourceMappingURL=cli.js.map