@opensea/cli 0.3.0 → 0.4.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/README.md CHANGED
@@ -89,7 +89,7 @@ opensea --format table collections stats mfers
89
89
  | `swaps` | Get swap quotes for token trading |
90
90
  | `accounts` | Get account details |
91
91
 
92
- Global options: `--api-key`, `--chain` (default: ethereum), `--format` (json/table), `--base-url`
92
+ Global options: `--api-key`, `--chain` (default: ethereum), `--format` (json/table/toon), `--base-url`
93
93
 
94
94
  Full command reference with all options and flags: [docs/cli-reference.md](docs/cli-reference.md)
95
95
 
@@ -137,6 +137,33 @@ Table - human-readable output:
137
137
  opensea --format table collections list --limit 5
138
138
  ```
139
139
 
140
+ TOON - [Token-Oriented Object Notation](https://github.com/toon-format/toon), a compact format that uses ~40% fewer tokens than JSON. Ideal for piping output into LLM / AI agent context windows:
141
+
142
+ ```bash
143
+ opensea --format toon tokens trending --limit 5
144
+ ```
145
+
146
+ Example TOON output for a list of tokens:
147
+
148
+ ```
149
+ tokens[3]{name,symbol,chain,market_cap,price_usd}:
150
+ Ethereum,ETH,ethereum,250000000000,2100.50
151
+ Bitcoin,BTC,bitcoin,900000000000,48000.00
152
+ Solana,SOL,solana,30000000000,95.25
153
+ next: abc123
154
+ ```
155
+
156
+ TOON collapses uniform arrays of objects into CSV-like tables with a single header row, while nested objects use YAML-like indentation. The encoder follows the [TOON v3.0 spec](https://github.com/toon-format/spec/blob/main/SPEC.md) and is implemented without external dependencies.
157
+
158
+ TOON is also available programmatically via the SDK:
159
+
160
+ ```typescript
161
+ import { formatToon } from "@opensea/cli"
162
+
163
+ const data = await client.tokens.trending({ limit: 5 })
164
+ console.log(formatToon(data))
165
+ ```
166
+
140
167
  ## Exit Codes
141
168
 
142
169
  - `0` - Success
package/dist/cli.js CHANGED
@@ -5,19 +5,16 @@ import { Command as Command10 } from "commander";
5
5
 
6
6
  // src/client.ts
7
7
  var DEFAULT_BASE_URL = "https://api.opensea.io";
8
- var DEFAULT_GRAPHQL_URL = "https://gql.opensea.io/graphql";
9
8
  var DEFAULT_TIMEOUT_MS = 3e4;
10
9
  var OpenSeaClient = class {
11
10
  apiKey;
12
11
  baseUrl;
13
- graphqlUrl;
14
12
  defaultChain;
15
13
  timeoutMs;
16
14
  verbose;
17
15
  constructor(config) {
18
16
  this.apiKey = config.apiKey;
19
17
  this.baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
20
- this.graphqlUrl = config.graphqlUrl ?? DEFAULT_GRAPHQL_URL;
21
18
  this.defaultChain = config.chain ?? "ethereum";
22
19
  this.timeoutMs = config.timeout ?? DEFAULT_TIMEOUT_MS;
23
20
  this.verbose = config.verbose ?? false;
@@ -85,40 +82,6 @@ var OpenSeaClient = class {
85
82
  }
86
83
  return response.json();
87
84
  }
88
- async graphql(query, variables) {
89
- if (this.verbose) {
90
- console.error(`[verbose] POST ${this.graphqlUrl}`);
91
- }
92
- const response = await fetch(this.graphqlUrl, {
93
- method: "POST",
94
- headers: {
95
- "Content-Type": "application/json",
96
- Accept: "application/json",
97
- "x-api-key": this.apiKey
98
- },
99
- body: JSON.stringify({ query, variables }),
100
- signal: AbortSignal.timeout(this.timeoutMs)
101
- });
102
- if (this.verbose) {
103
- console.error(`[verbose] ${response.status} ${response.statusText}`);
104
- }
105
- if (!response.ok) {
106
- const body = await response.text();
107
- throw new OpenSeaAPIError(response.status, body, "graphql");
108
- }
109
- const json = await response.json();
110
- if (json.errors?.length) {
111
- throw new OpenSeaAPIError(
112
- 400,
113
- json.errors.map((e) => e.message).join("; "),
114
- "graphql"
115
- );
116
- }
117
- if (!json.data) {
118
- throw new OpenSeaAPIError(500, "GraphQL response missing data", "graphql");
119
- }
120
- return json.data;
121
- }
122
85
  getDefaultChain() {
123
86
  return this.defaultChain;
124
87
  }
@@ -136,11 +99,284 @@ var OpenSeaAPIError = class extends Error {
136
99
  // src/commands/accounts.ts
137
100
  import { Command } from "commander";
138
101
 
102
+ // src/toon.ts
103
+ var INDENT = " ";
104
+ var NUMERIC_RE = /^-?\d+(?:\.\d+)?(?:e[+-]?\d+)?$/i;
105
+ var LEADING_ZERO_RE = /^0\d+$/;
106
+ var UNQUOTED_KEY_RE = /^[A-Za-z_][A-Za-z0-9_.]*$/;
107
+ function escapeString(s) {
108
+ return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
109
+ }
110
+ function needsQuoting(value, delimiter) {
111
+ if (value === "") return true;
112
+ if (value !== value.trim()) return true;
113
+ if (value === "true" || value === "false" || value === "null") return true;
114
+ if (NUMERIC_RE.test(value) || LEADING_ZERO_RE.test(value)) return true;
115
+ if (/[:"\\[\]{}]/.test(value)) return true;
116
+ if (/[\n\r\t]/.test(value)) return true;
117
+ if (value.includes(delimiter)) return true;
118
+ if (value.startsWith("-")) return true;
119
+ return false;
120
+ }
121
+ function encodeKey(key) {
122
+ if (UNQUOTED_KEY_RE.test(key)) return key;
123
+ return `"${escapeString(key)}"`;
124
+ }
125
+ function encodePrimitive(value, delimiter) {
126
+ if (value === null) return "null";
127
+ if (value === void 0) return "null";
128
+ if (typeof value === "boolean") return String(value);
129
+ if (typeof value === "number") return String(value);
130
+ if (typeof value === "string") {
131
+ if (needsQuoting(value, delimiter)) {
132
+ return `"${escapeString(value)}"`;
133
+ }
134
+ return value;
135
+ }
136
+ return `"${escapeString(String(value))}"`;
137
+ }
138
+ function isPrimitive(value) {
139
+ return value === null || value === void 0 || typeof value === "boolean" || typeof value === "number" || typeof value === "string";
140
+ }
141
+ function isTabular(arr) {
142
+ if (arr.length === 0) return false;
143
+ const first = arr[0];
144
+ if (first === null || typeof first !== "object" || Array.isArray(first))
145
+ return false;
146
+ const keys = Object.keys(first).sort();
147
+ for (const item of arr) {
148
+ if (item === null || typeof item !== "object" || Array.isArray(item))
149
+ return false;
150
+ const itemKeys = Object.keys(item).sort();
151
+ if (itemKeys.length !== keys.length) return false;
152
+ for (let i = 0; i < keys.length; i++) {
153
+ if (itemKeys[i] !== keys[i]) return false;
154
+ }
155
+ for (const k of keys) {
156
+ if (!isPrimitive(item[k])) return false;
157
+ }
158
+ }
159
+ return true;
160
+ }
161
+ function isPrimitiveArray(arr) {
162
+ return arr.every(isPrimitive);
163
+ }
164
+ function encodeValue(value, depth, delimiter) {
165
+ if (isPrimitive(value)) {
166
+ return encodePrimitive(value, delimiter);
167
+ }
168
+ if (Array.isArray(value)) {
169
+ return encodeArray(value, depth, delimiter);
170
+ }
171
+ if (typeof value === "object" && value !== null) {
172
+ return encodeObject(value, depth, delimiter);
173
+ }
174
+ return encodePrimitive(value, delimiter);
175
+ }
176
+ function encodeObject(obj, depth, delimiter) {
177
+ const entries = Object.entries(obj);
178
+ if (entries.length === 0) return "";
179
+ const lines = [];
180
+ const prefix = INDENT.repeat(depth);
181
+ for (const [key, value] of entries) {
182
+ const encodedKey = encodeKey(key);
183
+ if (isPrimitive(value)) {
184
+ lines.push(`${prefix}${encodedKey}: ${encodePrimitive(value, delimiter)}`);
185
+ } else if (Array.isArray(value)) {
186
+ lines.push(encodeArrayField(encodedKey, value, depth, delimiter));
187
+ } else if (typeof value === "object" && value !== null) {
188
+ const nested = value;
189
+ if (Object.keys(nested).length === 0) {
190
+ lines.push(`${prefix}${encodedKey}:`);
191
+ } else {
192
+ lines.push(`${prefix}${encodedKey}:`);
193
+ lines.push(encodeObject(nested, depth + 1, delimiter));
194
+ }
195
+ }
196
+ }
197
+ return lines.join("\n");
198
+ }
199
+ function encodeArrayField(encodedKey, arr, depth, delimiter) {
200
+ const prefix = INDENT.repeat(depth);
201
+ if (arr.length === 0) {
202
+ return `${prefix}${encodedKey}[0]:`;
203
+ }
204
+ if (isPrimitiveArray(arr)) {
205
+ const values = arr.map((v) => encodePrimitive(v, delimiter)).join(delimiter);
206
+ return `${prefix}${encodedKey}[${arr.length}]: ${values}`;
207
+ }
208
+ if (isTabular(arr)) {
209
+ const firstObj = arr[0];
210
+ const fields = Object.keys(firstObj);
211
+ const fieldHeader = fields.map(encodeKey).join(delimiter);
212
+ const lines = [];
213
+ lines.push(`${prefix}${encodedKey}[${arr.length}]{${fieldHeader}}:`);
214
+ const rowPrefix = INDENT.repeat(depth + 1);
215
+ for (const item of arr) {
216
+ const obj = item;
217
+ const row = fields.map((f) => encodePrimitive(obj[f], delimiter)).join(delimiter);
218
+ lines.push(`${rowPrefix}${row}`);
219
+ }
220
+ return lines.join("\n");
221
+ }
222
+ return encodeExpandedList(encodedKey, arr, depth, delimiter);
223
+ }
224
+ function encodeExpandedList(encodedKey, arr, depth, delimiter) {
225
+ const prefix = INDENT.repeat(depth);
226
+ const itemPrefix = INDENT.repeat(depth + 1);
227
+ const lines = [];
228
+ lines.push(`${prefix}${encodedKey}[${arr.length}]:`);
229
+ for (const item of arr) {
230
+ if (isPrimitive(item)) {
231
+ lines.push(`${itemPrefix}- ${encodePrimitive(item, delimiter)}`);
232
+ } else if (Array.isArray(item)) {
233
+ if (isPrimitiveArray(item)) {
234
+ const values = item.map((v) => encodePrimitive(v, delimiter)).join(delimiter);
235
+ lines.push(`${itemPrefix}- [${item.length}]: ${values}`);
236
+ } else {
237
+ lines.push(`${itemPrefix}- [${item.length}]:`);
238
+ for (const inner of item) {
239
+ lines.push(encodeValue(inner, depth + 2, delimiter));
240
+ }
241
+ }
242
+ } else if (typeof item === "object" && item !== null) {
243
+ const obj = item;
244
+ const entries = Object.entries(obj);
245
+ if (entries.length === 0) {
246
+ lines.push(`${itemPrefix}-`);
247
+ } else {
248
+ const [firstKey, firstValue] = entries[0];
249
+ const ek = encodeKey(firstKey);
250
+ if (Array.isArray(firstValue)) {
251
+ const arrayLine = encodeArrayField(ek, firstValue, 0, delimiter);
252
+ lines.push(`${itemPrefix}- ${arrayLine.trimStart()}`);
253
+ } else if (isPrimitive(firstValue)) {
254
+ lines.push(
255
+ `${itemPrefix}- ${ek}: ${encodePrimitive(firstValue, delimiter)}`
256
+ );
257
+ } else {
258
+ lines.push(`${itemPrefix}- ${ek}:`);
259
+ lines.push(
260
+ encodeObject(
261
+ firstValue,
262
+ depth + 2,
263
+ delimiter
264
+ )
265
+ );
266
+ }
267
+ for (let i = 1; i < entries.length; i++) {
268
+ const [k, v] = entries[i];
269
+ const encodedK = encodeKey(k);
270
+ if (isPrimitive(v)) {
271
+ lines.push(
272
+ `${INDENT.repeat(depth + 2)}${encodedK}: ${encodePrimitive(v, delimiter)}`
273
+ );
274
+ } else if (Array.isArray(v)) {
275
+ lines.push(encodeArrayField(encodedK, v, depth + 2, delimiter));
276
+ } else if (typeof v === "object" && v !== null) {
277
+ lines.push(`${INDENT.repeat(depth + 2)}${encodedK}:`);
278
+ lines.push(
279
+ encodeObject(v, depth + 3, delimiter)
280
+ );
281
+ }
282
+ }
283
+ }
284
+ }
285
+ }
286
+ return lines.join("\n");
287
+ }
288
+ function encodeArray(arr, depth, delimiter) {
289
+ const prefix = INDENT.repeat(depth);
290
+ if (arr.length === 0) {
291
+ return `${prefix}[0]:`;
292
+ }
293
+ if (isPrimitiveArray(arr)) {
294
+ const values = arr.map((v) => encodePrimitive(v, delimiter)).join(delimiter);
295
+ return `${prefix}[${arr.length}]: ${values}`;
296
+ }
297
+ if (isTabular(arr)) {
298
+ const firstObj = arr[0];
299
+ const fields = Object.keys(firstObj);
300
+ const fieldHeader = fields.map(encodeKey).join(delimiter);
301
+ const lines2 = [];
302
+ lines2.push(`${prefix}[${arr.length}]{${fieldHeader}}:`);
303
+ const rowPrefix = INDENT.repeat(depth + 1);
304
+ for (const item of arr) {
305
+ const obj = item;
306
+ const row = fields.map((f) => encodePrimitive(obj[f], delimiter)).join(delimiter);
307
+ lines2.push(`${rowPrefix}${row}`);
308
+ }
309
+ return lines2.join("\n");
310
+ }
311
+ const lines = [];
312
+ lines.push(`${prefix}[${arr.length}]:`);
313
+ const itemPrefix = INDENT.repeat(depth + 1);
314
+ for (const item of arr) {
315
+ if (isPrimitive(item)) {
316
+ lines.push(`${itemPrefix}- ${encodePrimitive(item, delimiter)}`);
317
+ } else if (Array.isArray(item)) {
318
+ if (isPrimitiveArray(item)) {
319
+ const values = item.map((v) => encodePrimitive(v, delimiter)).join(delimiter);
320
+ lines.push(`${itemPrefix}- [${item.length}]: ${values}`);
321
+ } else {
322
+ lines.push(`${itemPrefix}- [${item.length}]:`);
323
+ }
324
+ } else if (typeof item === "object" && item !== null) {
325
+ const obj = item;
326
+ const entries = Object.entries(obj);
327
+ if (entries.length > 0) {
328
+ const [firstKey, firstValue] = entries[0];
329
+ const ek = encodeKey(firstKey);
330
+ if (isPrimitive(firstValue)) {
331
+ lines.push(
332
+ `${itemPrefix}- ${ek}: ${encodePrimitive(firstValue, delimiter)}`
333
+ );
334
+ } else {
335
+ lines.push(`${itemPrefix}- ${ek}:`);
336
+ lines.push(encodeValue(firstValue, depth + 2, delimiter));
337
+ }
338
+ for (let i = 1; i < entries.length; i++) {
339
+ const [k, v] = entries[i];
340
+ const encodedK = encodeKey(k);
341
+ if (isPrimitive(v)) {
342
+ lines.push(
343
+ `${INDENT.repeat(depth + 2)}${encodedK}: ${encodePrimitive(v, delimiter)}`
344
+ );
345
+ } else if (Array.isArray(v)) {
346
+ lines.push(encodeArrayField(encodedK, v, depth + 2, delimiter));
347
+ } else if (typeof v === "object" && v !== null) {
348
+ lines.push(`${INDENT.repeat(depth + 2)}${encodedK}:`);
349
+ lines.push(
350
+ encodeObject(v, depth + 3, delimiter)
351
+ );
352
+ }
353
+ }
354
+ }
355
+ }
356
+ }
357
+ return lines.join("\n");
358
+ }
359
+ function formatToon(data) {
360
+ if (isPrimitive(data)) {
361
+ return encodePrimitive(data, ",");
362
+ }
363
+ if (Array.isArray(data)) {
364
+ return encodeArray(data, 0, ",");
365
+ }
366
+ if (typeof data === "object" && data !== null) {
367
+ return encodeObject(data, 0, ",");
368
+ }
369
+ return String(data);
370
+ }
371
+
139
372
  // src/output.ts
140
373
  function formatOutput(data, format) {
141
374
  if (format === "table") {
142
375
  return formatTable(data);
143
376
  }
377
+ if (format === "toon") {
378
+ return formatToon(data);
379
+ }
144
380
  return JSON.stringify(data, null, 2);
145
381
  }
146
382
  function formatTable(data) {
@@ -465,147 +701,30 @@ function offersCommand(getClient2, getFormat2) {
465
701
 
466
702
  // src/commands/search.ts
467
703
  import { Command as Command7 } from "commander";
468
-
469
- // src/queries.ts
470
- var SEARCH_COLLECTIONS_QUERY = `
471
- query SearchCollections($query: String!, $limit: Int, $chains: [ChainIdentifier!]) {
472
- collectionsByQuery(query: $query, limit: $limit, chains: $chains) {
473
- slug
474
- name
475
- description
476
- imageUrl
477
- chain {
478
- identifier
479
- name
480
- }
481
- stats {
482
- totalSupply
483
- ownerCount
484
- volume {
485
- usd
486
- }
487
- sales
488
- }
489
- floorPrice {
490
- pricePerItem {
491
- usd
492
- native {
493
- unit
494
- symbol
495
- }
496
- }
497
- }
498
- }
499
- }`;
500
- var SEARCH_NFTS_QUERY = `
501
- query SearchItems($query: String!, $collectionSlug: String, $limit: Int, $chains: [ChainIdentifier!]) {
502
- itemsByQuery(query: $query, collectionSlug: $collectionSlug, limit: $limit, chains: $chains) {
503
- tokenId
504
- name
505
- description
506
- imageUrl
507
- contractAddress
508
- collection {
509
- slug
510
- name
511
- }
512
- chain {
513
- identifier
514
- name
515
- }
516
- bestListing {
517
- pricePerItem {
518
- usd
519
- native {
520
- unit
521
- symbol
522
- }
523
- }
524
- }
525
- owner {
526
- address
527
- displayName
528
- }
529
- }
530
- }`;
531
- var SEARCH_TOKENS_QUERY = `
532
- query SearchCurrencies($query: String!, $limit: Int, $chain: ChainIdentifier) {
533
- currenciesByQuery(query: $query, limit: $limit, chain: $chain, allowlistOnly: false) {
534
- name
535
- symbol
536
- imageUrl
537
- usdPrice
538
- contractAddress
539
- chain {
540
- identifier
541
- name
542
- }
543
- stats {
544
- marketCapUsd
545
- oneDay {
546
- priceChange
547
- volume
548
- }
549
- }
550
- }
551
- }`;
552
- var SEARCH_ACCOUNTS_QUERY = `
553
- query SearchAccounts($query: String!, $limit: Int) {
554
- accountsByQuery(query: $query, limit: $limit) {
555
- address
556
- username
557
- imageUrl
558
- isVerified
559
- }
560
- }`;
561
-
562
- // src/commands/search.ts
563
704
  function searchCommand(getClient2, getFormat2) {
564
- const cmd = new Command7("search").description(
565
- "Search for collections, NFTs, tokens, and accounts"
566
- );
567
- 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(
568
- async (query, options) => {
569
- const client = getClient2();
570
- const result = await client.graphql(SEARCH_COLLECTIONS_QUERY, {
571
- query,
572
- limit: parseIntOption(options.limit, "--limit"),
573
- chains: options.chains?.split(",")
574
- });
575
- console.log(formatOutput(result.collectionsByQuery, getFormat2()));
576
- }
577
- );
578
- 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(
705
+ const cmd = new Command7("search").description("Search across collections, tokens, NFTs, and accounts").argument("<query>", "Search query").option(
706
+ "--types <types>",
707
+ "Filter by type (comma-separated: collection,nft,token,account)"
708
+ ).option("--chains <chains>", "Filter by chains (comma-separated)").option("--limit <limit>", "Number of results", "20").action(
579
709
  async (query, options) => {
580
710
  const client = getClient2();
581
- const result = await client.graphql(SEARCH_NFTS_QUERY, {
711
+ const params = {
582
712
  query,
583
- collectionSlug: options.collection,
584
- limit: parseIntOption(options.limit, "--limit"),
585
- chains: options.chains?.split(",")
586
- });
587
- console.log(formatOutput(result.itemsByQuery, getFormat2()));
588
- }
589
- );
590
- 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(
591
- async (query, options) => {
592
- const client = getClient2();
593
- const result = await client.graphql(SEARCH_TOKENS_QUERY, {
594
- query,
595
- limit: parseIntOption(options.limit, "--limit"),
596
- chain: options.chain
597
- });
598
- console.log(formatOutput(result.currenciesByQuery, getFormat2()));
713
+ limit: parseIntOption(options.limit, "--limit")
714
+ };
715
+ if (options.types) {
716
+ params.asset_types = options.types;
717
+ }
718
+ if (options.chains) {
719
+ params.chains = options.chains;
720
+ }
721
+ const result = await client.get(
722
+ "/api/v2/search",
723
+ params
724
+ );
725
+ console.log(formatOutput(result, getFormat2()));
599
726
  }
600
727
  );
601
- 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) => {
602
- const client = getClient2();
603
- const result = await client.graphql(SEARCH_ACCOUNTS_QUERY, {
604
- query,
605
- limit: parseIntOption(options.limit, "--limit")
606
- });
607
- console.log(formatOutput(result.accountsByQuery, getFormat2()));
608
- });
609
728
  return cmd;
610
729
  }
611
730
 
@@ -709,7 +828,7 @@ var BANNER = `
709
828
  |_|
710
829
  `;
711
830
  var program = new Command10();
712
- 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").option("--timeout <ms>", "Request timeout in milliseconds", "30000").option("--verbose", "Log request and response info to stderr");
831
+ 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");
713
832
  function getClient() {
714
833
  const opts = program.opts();
715
834
  const apiKey = opts.apiKey ?? process.env.OPENSEA_API_KEY;
@@ -729,7 +848,9 @@ function getClient() {
729
848
  }
730
849
  function getFormat() {
731
850
  const opts = program.opts();
732
- return opts.format === "table" ? "table" : "json";
851
+ if (opts.format === "table") return "table";
852
+ if (opts.format === "toon") return "toon";
853
+ return "json";
733
854
  }
734
855
  program.addCommand(collectionsCommand(getClient, getFormat));
735
856
  program.addCommand(nftsCommand(getClient, getFormat));