-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcli.ts
More file actions
122 lines (112 loc) · 3.31 KB
/
cli.ts
File metadata and controls
122 lines (112 loc) · 3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { Command } from "commander"
import { OpenSeaAPIError, OpenSeaClient } from "./client.js"
import {
accountsCommand,
collectionsCommand,
eventsCommand,
healthCommand,
listingsCommand,
nftsCommand,
offersCommand,
searchCommand,
swapsCommand,
tokensCommand,
} from "./commands/index.js"
import type { OutputFormat } from "./output.js"
import { parseIntOption } from "./parse.js"
const BANNER = `
____ _____
/ __ \\ / ____|
| | | |_ __ ___ _ _| (___ ___ __ _
| | | | '_ \\ / _ \\ '_ \\___ \\ / _ \\/ _\` |
| |__| | |_) | __/ | | |___) | __/ (_| |
\\____/| .__/ \\___|_| |_|____/ \\___|\\__,_|
| |
|_|
`
const program = new Command()
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")
function getClient(): OpenSeaClient {
const opts = program.opts<{
apiKey?: string
chain: string
baseUrl?: string
timeout: string
verbose?: boolean
}>()
const apiKey = opts.apiKey ?? process.env.OPENSEA_API_KEY
if (!apiKey) {
console.error(
"Error: API key required. Use --api-key or set OPENSEA_API_KEY environment variable.",
)
process.exit(2)
}
return new OpenSeaClient({
apiKey,
chain: opts.chain,
baseUrl: opts.baseUrl,
timeout: parseIntOption(opts.timeout, "--timeout"),
verbose: opts.verbose,
})
}
function getFormat(): OutputFormat {
const opts = program.opts<{ format: string }>()
if (opts.format === "table") return "table"
if (opts.format === "toon") return "toon"
return "json"
}
program.addCommand(collectionsCommand(getClient, getFormat))
program.addCommand(nftsCommand(getClient, getFormat))
program.addCommand(listingsCommand(getClient, getFormat))
program.addCommand(offersCommand(getClient, getFormat))
program.addCommand(eventsCommand(getClient, getFormat))
program.addCommand(accountsCommand(getClient, getFormat))
program.addCommand(tokensCommand(getClient, getFormat))
program.addCommand(searchCommand(getClient, getFormat))
program.addCommand(swapsCommand(getClient, getFormat))
program.addCommand(healthCommand(getClient, getFormat))
async function main() {
try {
await program.parseAsync(process.argv)
} catch (error) {
if (error instanceof OpenSeaAPIError) {
console.error(
JSON.stringify(
{
error: "API Error",
status: error.statusCode,
path: error.path,
message: error.responseBody,
},
null,
2,
),
)
process.exit(1)
}
const label =
error instanceof TypeError ? "Network Error" : (error as Error).name
console.error(
JSON.stringify(
{
error: label,
message: (error as Error).message,
},
null,
2,
),
)
process.exit(1)
}
}
main()