chainbase-cli 0.1.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 +188 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +633 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# Chainbase CLI
|
|
2
|
+
|
|
3
|
+
A command-line interface for the [Chainbase Web3 API](https://docs.chainbase.com/api-reference/overview). Designed for both human use and AI agent automation — outputs JSON by default, with an optional `--pretty` flag for human-readable format.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g chainbase-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or run directly with npx:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx chainbase-cli --help
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Set your API key (get one at https://console.chainbase.com)
|
|
21
|
+
chainbase config set api-key YOUR_API_KEY
|
|
22
|
+
|
|
23
|
+
# Get latest Ethereum block number
|
|
24
|
+
chainbase block latest
|
|
25
|
+
|
|
26
|
+
# Get USDT price
|
|
27
|
+
chainbase token price 0xdac17f958d2ee523a2206206994597c13d831ec7
|
|
28
|
+
|
|
29
|
+
# Resolve ENS domain
|
|
30
|
+
chainbase domain ens-resolve vitalik.eth
|
|
31
|
+
|
|
32
|
+
# Query on BSC (chain ID 56)
|
|
33
|
+
chainbase token price 0x55d398326f99059fF775485246999027B3197955 --chain 56
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Global Options
|
|
37
|
+
|
|
38
|
+
| Option | Description | Default |
|
|
39
|
+
|--------|-------------|---------|
|
|
40
|
+
| `--chain <id>` | Chain ID | `1` (Ethereum) |
|
|
41
|
+
| `--pretty` | Human-readable output | `false` |
|
|
42
|
+
| `--page <n>` | Page number | `1` |
|
|
43
|
+
| `--limit <n>` | Results per page | `20` |
|
|
44
|
+
|
|
45
|
+
## Commands
|
|
46
|
+
|
|
47
|
+
### `config` — Configuration
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
chainbase config set api-key <key> # Set API key
|
|
51
|
+
chainbase config set default-chain 137 # Set default chain to Polygon
|
|
52
|
+
chainbase config get api-key # Get a config value
|
|
53
|
+
chainbase config list # List all config
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### `block` — Block Queries
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
chainbase block latest # Latest block number
|
|
60
|
+
chainbase block detail 20000000 # Block details by number
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### `tx` — Transaction Queries
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
chainbase tx detail <hash> # Transaction by hash
|
|
67
|
+
chainbase tx list <address> # Account transactions
|
|
68
|
+
chainbase tx list <address> --from-block 20000000 # With block range filter
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### `token` — Token Queries
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
chainbase token metadata <contract> # Token metadata
|
|
75
|
+
chainbase token price <contract> # Current price
|
|
76
|
+
chainbase token price-history <contract> --from <ts> --to <ts> # Price history
|
|
77
|
+
chainbase token holders <contract> # All holders
|
|
78
|
+
chainbase token top-holders <contract> # Top holders
|
|
79
|
+
chainbase token transfers --contract <addr> # Transfer history
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### `nft` — NFT Queries
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
chainbase nft metadata <contract> <token_id> # NFT metadata
|
|
86
|
+
chainbase nft collection <contract> # Collection info
|
|
87
|
+
chainbase nft collection-items <contract> # Items in collection
|
|
88
|
+
chainbase nft search "Bored Ape" # Search by name
|
|
89
|
+
chainbase nft owner <contract> <token_id> # Current owner
|
|
90
|
+
chainbase nft owners <contract> # All owners
|
|
91
|
+
chainbase nft owner-history <contract> <token_id> # Owner history
|
|
92
|
+
chainbase nft transfers --contract <addr> # Transfer history
|
|
93
|
+
chainbase nft floor-price <contract> # Floor price
|
|
94
|
+
chainbase nft price-history <contract> --from <ts> --to <ts> # Price history
|
|
95
|
+
chainbase nft trending # Trending collections
|
|
96
|
+
chainbase nft rarity <contract> # Rarity scores
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### `balance` — Balance & Portfolio
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
chainbase balance native <address> # Native token balance (ETH, BNB, etc.)
|
|
103
|
+
chainbase balance tokens <address> # ERC20 token balances
|
|
104
|
+
chainbase balance nfts <address> # NFTs owned
|
|
105
|
+
chainbase balance portfolios <address> # DeFi positions
|
|
106
|
+
chainbase balance portfolios <address> --chains 1,137 # Filter by chains
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### `domain` — ENS & Space ID
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
chainbase domain ens <address> # ENS domains held by address
|
|
113
|
+
chainbase domain ens-resolve vitalik.eth # Resolve ENS → address
|
|
114
|
+
chainbase domain ens-reverse <address> # Reverse resolve address → ENS
|
|
115
|
+
chainbase domain spaceid-resolve <domain> # Resolve Space ID (BSC)
|
|
116
|
+
chainbase domain spaceid-reverse <address> # Reverse resolve Space ID
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### `contract` — Smart Contract
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
chainbase contract call \
|
|
123
|
+
--address <contract> \
|
|
124
|
+
--function "balanceOf" \
|
|
125
|
+
--abi '[...]' \
|
|
126
|
+
--params '["0x..."]'
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### `sql` — SQL Queries
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
chainbase sql execute "SELECT number FROM ethereum.blocks LIMIT 5" # Execute async query
|
|
133
|
+
chainbase sql status <execution_id> # Check status
|
|
134
|
+
chainbase sql results <execution_id> # Get results
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Supported Chains
|
|
138
|
+
|
|
139
|
+
| Chain | ID | Chain | ID |
|
|
140
|
+
|-------|----|-------|----|
|
|
141
|
+
| Ethereum | `1` | Arbitrum | `42161` |
|
|
142
|
+
| BSC | `56` | Optimism | `10` |
|
|
143
|
+
| Polygon | `137` | Base | `8453` |
|
|
144
|
+
| Avalanche | `43114` | zkSync | `324` |
|
|
145
|
+
|
|
146
|
+
## Authentication
|
|
147
|
+
|
|
148
|
+
The API key can be configured in three ways (in priority order):
|
|
149
|
+
|
|
150
|
+
1. **Environment variable**: `CHAINBASE_API_KEY=xxx chainbase block latest`
|
|
151
|
+
2. **Config file**: `chainbase config set api-key xxx` (stored at `~/.chainbase/config.json`, mode 0600)
|
|
152
|
+
|
|
153
|
+
## For AI Agents
|
|
154
|
+
|
|
155
|
+
This CLI is designed to be controlled by AI agents. Key features:
|
|
156
|
+
|
|
157
|
+
- **JSON output by default** — machine-parseable, no colors or formatting
|
|
158
|
+
- **Consistent error format** — errors output as `{"error":"message"}` to stderr
|
|
159
|
+
- **Discoverable** — `chainbase --help` and `chainbase <command> --help` list all available commands
|
|
160
|
+
- **Predictable** — every command follows the same pattern: `chainbase <group> <action> [args] [options]`
|
|
161
|
+
|
|
162
|
+
Example agent usage:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
# Parse output directly
|
|
166
|
+
PRICE=$(chainbase token price 0xdac17f958d2ee523a2206206994597c13d831ec7 | jq '.data.price')
|
|
167
|
+
|
|
168
|
+
# Check if command succeeded
|
|
169
|
+
if chainbase balance native 0x... 2>/dev/null; then
|
|
170
|
+
echo "Success"
|
|
171
|
+
fi
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Development
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
git clone https://github.com/chainbase-labs/cli.git
|
|
178
|
+
cd cli
|
|
179
|
+
npm install
|
|
180
|
+
npm run build # Build
|
|
181
|
+
npm test # Run tests
|
|
182
|
+
npm run lint # Type-check
|
|
183
|
+
npm link # Install globally for local dev
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## License
|
|
187
|
+
|
|
188
|
+
ISC
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { Command as Command11 } from "commander";
|
|
5
|
+
|
|
6
|
+
// src/commands/config.ts
|
|
7
|
+
import { Command } from "commander";
|
|
8
|
+
|
|
9
|
+
// src/config.ts
|
|
10
|
+
import fs from "fs";
|
|
11
|
+
import path from "path";
|
|
12
|
+
import os from "os";
|
|
13
|
+
function getConfigDir() {
|
|
14
|
+
return process.env.CHAINBASE_CONFIG_DIR || path.join(os.homedir(), ".chainbase");
|
|
15
|
+
}
|
|
16
|
+
function getConfigPath() {
|
|
17
|
+
return path.join(getConfigDir(), "config.json");
|
|
18
|
+
}
|
|
19
|
+
function readConfigFile() {
|
|
20
|
+
const configPath = getConfigPath();
|
|
21
|
+
if (!fs.existsSync(configPath)) return {};
|
|
22
|
+
try {
|
|
23
|
+
return JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
24
|
+
} catch {
|
|
25
|
+
throw new Error(`Config file corrupted: ${configPath}
|
|
26
|
+
Delete it and re-configure: chainbase config set api-key <your-key>`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function writeConfigFile(config) {
|
|
30
|
+
const dir = getConfigDir();
|
|
31
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
32
|
+
fs.writeFileSync(getConfigPath(), JSON.stringify(config, null, 2), { mode: 384 });
|
|
33
|
+
}
|
|
34
|
+
function setConfig(key, value) {
|
|
35
|
+
const config = readConfigFile();
|
|
36
|
+
config[key] = value;
|
|
37
|
+
writeConfigFile(config);
|
|
38
|
+
}
|
|
39
|
+
function getConfig(key) {
|
|
40
|
+
const config = readConfigFile();
|
|
41
|
+
return config[key];
|
|
42
|
+
}
|
|
43
|
+
function listConfig() {
|
|
44
|
+
return readConfigFile();
|
|
45
|
+
}
|
|
46
|
+
function getApiKey() {
|
|
47
|
+
const envKey = process.env.CHAINBASE_API_KEY;
|
|
48
|
+
if (envKey) return envKey;
|
|
49
|
+
const fileKey = getConfig("api-key");
|
|
50
|
+
if (fileKey) return fileKey;
|
|
51
|
+
throw new Error("No API key configured. Run: chainbase config set api-key <your-key>");
|
|
52
|
+
}
|
|
53
|
+
function getDefaultChain() {
|
|
54
|
+
return getConfig("default-chain") || "1";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/output.ts
|
|
58
|
+
import chalk from "chalk";
|
|
59
|
+
function formatOutput(data, pretty) {
|
|
60
|
+
if (pretty) {
|
|
61
|
+
process.stdout.write(JSON.stringify(data, null, 2) + "\n");
|
|
62
|
+
} else {
|
|
63
|
+
process.stdout.write(JSON.stringify(data) + "\n");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function formatError(message, pretty) {
|
|
67
|
+
const error = { error: message };
|
|
68
|
+
if (pretty) {
|
|
69
|
+
process.stderr.write(chalk.red(`Error: ${message}`) + "\n");
|
|
70
|
+
} else {
|
|
71
|
+
process.stderr.write(JSON.stringify(error) + "\n");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// src/commands/config.ts
|
|
76
|
+
function createConfigCommand() {
|
|
77
|
+
const cmd = new Command("config").description("\u7BA1\u7406 CLI \u914D\u7F6E");
|
|
78
|
+
cmd.command("set <key> <value>").description("\u8BBE\u7F6E\u914D\u7F6E\u9879\uFF08api-key, default-chain\uFF09").action((key, value) => {
|
|
79
|
+
setConfig(key, value);
|
|
80
|
+
const pretty = cmd.parent?.opts().pretty ?? false;
|
|
81
|
+
formatOutput({ status: "ok", key, value: key === "api-key" ? "***" : value }, pretty);
|
|
82
|
+
});
|
|
83
|
+
cmd.command("get <key>").description("\u83B7\u53D6\u914D\u7F6E\u9879").action((key) => {
|
|
84
|
+
const pretty = cmd.parent?.opts().pretty ?? false;
|
|
85
|
+
let value = getConfig(key) ?? null;
|
|
86
|
+
if (key === "api-key" && value) value = "***" + value.slice(-4);
|
|
87
|
+
formatOutput({ key, value }, pretty);
|
|
88
|
+
});
|
|
89
|
+
cmd.command("list").description("\u5217\u51FA\u6240\u6709\u914D\u7F6E\u9879").action(() => {
|
|
90
|
+
const pretty = cmd.parent?.opts().pretty ?? false;
|
|
91
|
+
const config = listConfig();
|
|
92
|
+
const safe = { ...config };
|
|
93
|
+
if (safe["api-key"]) safe["api-key"] = "***" + safe["api-key"].slice(-4);
|
|
94
|
+
formatOutput(safe, pretty);
|
|
95
|
+
});
|
|
96
|
+
return cmd;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// src/commands/block.ts
|
|
100
|
+
import { Command as Command2 } from "commander";
|
|
101
|
+
|
|
102
|
+
// src/client.ts
|
|
103
|
+
import axios from "axios";
|
|
104
|
+
var WEB3_BASE = "https://api.chainbase.online";
|
|
105
|
+
var SQL_BASE = "https://api.chainbase.com/api/v1";
|
|
106
|
+
var ChainbaseClient = class {
|
|
107
|
+
constructor(apiKey) {
|
|
108
|
+
this.apiKey = apiKey;
|
|
109
|
+
}
|
|
110
|
+
getBaseUrl(path2) {
|
|
111
|
+
if (path2.startsWith("/query/") || path2.startsWith("/execution/")) {
|
|
112
|
+
return SQL_BASE;
|
|
113
|
+
}
|
|
114
|
+
return WEB3_BASE;
|
|
115
|
+
}
|
|
116
|
+
async get(path2, params) {
|
|
117
|
+
return this.request("GET", path2, { params });
|
|
118
|
+
}
|
|
119
|
+
async post(path2, data) {
|
|
120
|
+
return this.request("POST", path2, { data });
|
|
121
|
+
}
|
|
122
|
+
async request(method, path2, options) {
|
|
123
|
+
const baseUrl = this.getBaseUrl(path2);
|
|
124
|
+
const response = await axios.request({
|
|
125
|
+
method,
|
|
126
|
+
url: `${baseUrl}${path2}`,
|
|
127
|
+
headers: {
|
|
128
|
+
"x-api-key": this.apiKey,
|
|
129
|
+
"Content-Type": "application/json"
|
|
130
|
+
},
|
|
131
|
+
params: options.params,
|
|
132
|
+
data: options.data
|
|
133
|
+
});
|
|
134
|
+
const body = response.data;
|
|
135
|
+
if (body && typeof body === "object" && "code" in body && body.code !== 0) {
|
|
136
|
+
throw new Error(body.message || `API error code: ${body.code}`);
|
|
137
|
+
}
|
|
138
|
+
return body;
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
function createClient(opts) {
|
|
142
|
+
const apiKey = getApiKey();
|
|
143
|
+
const chainId = opts.chain || getDefaultChain();
|
|
144
|
+
return { client: new ChainbaseClient(apiKey), chainId };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// src/commands/block.ts
|
|
148
|
+
function createBlockCommand() {
|
|
149
|
+
const cmd = new Command2("block").description("\u533A\u5757\u67E5\u8BE2");
|
|
150
|
+
cmd.command("latest").description("\u83B7\u53D6\u6700\u65B0\u533A\u5757\u53F7").action(async () => {
|
|
151
|
+
const opts = cmd.parent.opts();
|
|
152
|
+
const { client, chainId } = createClient(opts);
|
|
153
|
+
const result = await client.get("/v1/block/number/latest", { chain_id: chainId });
|
|
154
|
+
formatOutput(result, opts.pretty);
|
|
155
|
+
});
|
|
156
|
+
cmd.command("detail <number>").description("\u6309\u533A\u5757\u53F7\u67E5\u8BE2\u533A\u5757\u8BE6\u60C5").action(async (number) => {
|
|
157
|
+
const opts = cmd.parent.opts();
|
|
158
|
+
const { client, chainId } = createClient(opts);
|
|
159
|
+
const result = await client.get("/v1/block/detail", { chain_id: chainId, number });
|
|
160
|
+
formatOutput(result, opts.pretty);
|
|
161
|
+
});
|
|
162
|
+
return cmd;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// src/commands/tx.ts
|
|
166
|
+
import { Command as Command3 } from "commander";
|
|
167
|
+
function createTxCommand() {
|
|
168
|
+
const cmd = new Command3("tx").description("\u4EA4\u6613\u67E5\u8BE2");
|
|
169
|
+
cmd.command("detail <hash>").description("\u6309\u54C8\u5E0C\u67E5\u8BE2\u4EA4\u6613\u8BE6\u60C5").action(async (hash) => {
|
|
170
|
+
const opts = cmd.parent.opts();
|
|
171
|
+
const { client, chainId } = createClient(opts);
|
|
172
|
+
const result = await client.get("/v1/tx/detail", { chain_id: chainId, hash });
|
|
173
|
+
formatOutput(result, opts.pretty);
|
|
174
|
+
});
|
|
175
|
+
cmd.command("list <address>").description("\u67E5\u8BE2\u8D26\u6237\u4EA4\u6613\u5217\u8868").option("--from-block <n>", "\u8D77\u59CB\u533A\u5757\u53F7").option("--to-block <n>", "\u7ED3\u675F\u533A\u5757\u53F7").option("--from-timestamp <n>", "\u8D77\u59CB\u65F6\u95F4\u6233").option("--end-timestamp <n>", "\u7ED3\u675F\u65F6\u95F4\u6233").option("--page <n>", "\u9875\u7801").option("--limit <n>", "\u6BCF\u9875\u6761\u6570").action(async (address, cmdOpts) => {
|
|
176
|
+
const opts = cmd.parent.opts();
|
|
177
|
+
const { client, chainId } = createClient(opts);
|
|
178
|
+
const params = {
|
|
179
|
+
chain_id: chainId,
|
|
180
|
+
address
|
|
181
|
+
};
|
|
182
|
+
if (cmdOpts.page) params.page = cmdOpts.page;
|
|
183
|
+
if (cmdOpts.limit) params.limit = cmdOpts.limit;
|
|
184
|
+
if (cmdOpts.fromBlock) params.from_block = cmdOpts.fromBlock;
|
|
185
|
+
if (cmdOpts.toBlock) params.to_block = cmdOpts.toBlock;
|
|
186
|
+
if (cmdOpts.fromTimestamp) params.from_timestamp = cmdOpts.fromTimestamp;
|
|
187
|
+
if (cmdOpts.endTimestamp) params.end_timestamp = cmdOpts.endTimestamp;
|
|
188
|
+
const result = await client.get("/v1/account/txs", params);
|
|
189
|
+
formatOutput(result, opts.pretty);
|
|
190
|
+
});
|
|
191
|
+
return cmd;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// src/commands/contract.ts
|
|
195
|
+
import { Command as Command4 } from "commander";
|
|
196
|
+
function createContractCommand() {
|
|
197
|
+
const cmd = new Command4("contract").description("\u667A\u80FD\u5408\u7EA6\u4EA4\u4E92");
|
|
198
|
+
cmd.command("call").description("\u8C03\u7528\u5408\u7EA6\u53EA\u8BFB\u51FD\u6570").requiredOption("--address <addr>", "\u5408\u7EA6\u5730\u5740").requiredOption("--function <name>", "\u51FD\u6570\u540D").requiredOption("--abi <json>", "\u5408\u7EA6 ABI\uFF08JSON \u5B57\u7B26\u4E32\uFF09").option("--params <json>", "\u51FD\u6570\u53C2\u6570\uFF08JSON \u6570\u7EC4\uFF09", "[]").option("--to-block <n>", "\u533A\u5757\u53F7").action(async (cmdOpts) => {
|
|
199
|
+
const opts = cmd.parent.opts();
|
|
200
|
+
const { client, chainId } = createClient(opts);
|
|
201
|
+
const body = {
|
|
202
|
+
chain_id: Number(chainId),
|
|
203
|
+
contract_address: cmdOpts.address,
|
|
204
|
+
function_name: cmdOpts.function,
|
|
205
|
+
abi: cmdOpts.abi,
|
|
206
|
+
params: (() => {
|
|
207
|
+
try {
|
|
208
|
+
return JSON.parse(cmdOpts.params);
|
|
209
|
+
} catch {
|
|
210
|
+
throw new Error(`--params \u683C\u5F0F\u9519\u8BEF\uFF0C\u8BF7\u63D0\u4F9B\u5408\u6CD5 JSON \u6570\u7EC4\uFF0C\u5982 '["0x..."]'`);
|
|
211
|
+
}
|
|
212
|
+
})(),
|
|
213
|
+
...cmdOpts.toBlock && { to_block: cmdOpts.toBlock }
|
|
214
|
+
};
|
|
215
|
+
const result = await client.post("/v1/contract/call", body);
|
|
216
|
+
formatOutput(result, opts.pretty);
|
|
217
|
+
});
|
|
218
|
+
return cmd;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// src/commands/address.ts
|
|
222
|
+
import { Command as Command5 } from "commander";
|
|
223
|
+
function createAddressCommand() {
|
|
224
|
+
const cmd = new Command5("address").description("\u5730\u5740\u67E5\u8BE2");
|
|
225
|
+
cmd.command("labels <address>").description("\u83B7\u53D6\u5730\u5740\u6807\u7B7E").action(async (address) => {
|
|
226
|
+
const opts = cmd.parent.opts();
|
|
227
|
+
const { client, chainId } = createClient(opts);
|
|
228
|
+
const result = await client.get("/v1/address/labels", { chain_id: chainId, address });
|
|
229
|
+
formatOutput(result, opts.pretty);
|
|
230
|
+
});
|
|
231
|
+
return cmd;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// src/commands/token.ts
|
|
235
|
+
import { Command as Command6 } from "commander";
|
|
236
|
+
function createTokenCommand() {
|
|
237
|
+
const cmd = new Command6("token").description("\u4EE3\u5E01\u67E5\u8BE2");
|
|
238
|
+
cmd.command("metadata <contract>").description("\u83B7\u53D6\u4EE3\u5E01\u5143\u6570\u636E").action(async (contract) => {
|
|
239
|
+
const opts = cmd.parent.opts();
|
|
240
|
+
const { client, chainId } = createClient(opts);
|
|
241
|
+
const result = await client.get("/v1/token/metadata", {
|
|
242
|
+
chain_id: chainId,
|
|
243
|
+
contract_address: contract
|
|
244
|
+
});
|
|
245
|
+
formatOutput(result, opts.pretty);
|
|
246
|
+
});
|
|
247
|
+
cmd.command("transfers").description("\u83B7\u53D6\u4EE3\u5E01\u8F6C\u8D26\u8BB0\u5F55").option("--contract <addr>", "\u5408\u7EA6\u5730\u5740").option("--address <addr>", "\u94B1\u5305\u5730\u5740").option("--from-block <n>", "\u8D77\u59CB\u533A\u5757\u53F7").option("--to-block <n>", "\u7ED3\u675F\u533A\u5757\u53F7").option("--from-timestamp <n>", "\u8D77\u59CB\u65F6\u95F4\u6233").option("--end-timestamp <n>", "\u7ED3\u675F\u65F6\u95F4\u6233").action(async (cmdOpts) => {
|
|
248
|
+
const opts = cmd.parent.opts();
|
|
249
|
+
const { client, chainId } = createClient(opts);
|
|
250
|
+
const params = {
|
|
251
|
+
chain_id: chainId
|
|
252
|
+
};
|
|
253
|
+
if (cmdOpts.contract) params.contract_address = cmdOpts.contract;
|
|
254
|
+
if (cmdOpts.address) params.address = cmdOpts.address;
|
|
255
|
+
if (cmdOpts.fromBlock) params.from_block = cmdOpts.fromBlock;
|
|
256
|
+
if (cmdOpts.toBlock) params.to_block = cmdOpts.toBlock;
|
|
257
|
+
if (cmdOpts.fromTimestamp) params.from_timestamp = cmdOpts.fromTimestamp;
|
|
258
|
+
if (cmdOpts.endTimestamp) params.end_timestamp = cmdOpts.endTimestamp;
|
|
259
|
+
if (opts.page) params.page = opts.page;
|
|
260
|
+
if (opts.limit) params.limit = opts.limit;
|
|
261
|
+
const result = await client.get("/v1/token/transfers", params);
|
|
262
|
+
formatOutput(result, opts.pretty);
|
|
263
|
+
});
|
|
264
|
+
cmd.command("holders <contract>").description("\u83B7\u53D6\u4EE3\u5E01\u6301\u6709\u8005\u5217\u8868").action(async (contract) => {
|
|
265
|
+
const opts = cmd.parent.opts();
|
|
266
|
+
const { client, chainId } = createClient(opts);
|
|
267
|
+
const params = {
|
|
268
|
+
chain_id: chainId,
|
|
269
|
+
contract_address: contract
|
|
270
|
+
};
|
|
271
|
+
if (opts.page) params.page = opts.page;
|
|
272
|
+
if (opts.limit) params.limit = opts.limit;
|
|
273
|
+
const result = await client.get("/v1/token/holders", params);
|
|
274
|
+
formatOutput(result, opts.pretty);
|
|
275
|
+
});
|
|
276
|
+
cmd.command("top-holders <contract>").description("\u83B7\u53D6\u4EE3\u5E01 Top \u6301\u6709\u8005").action(async (contract) => {
|
|
277
|
+
const opts = cmd.parent.opts();
|
|
278
|
+
const { client, chainId } = createClient(opts);
|
|
279
|
+
const params = {
|
|
280
|
+
chain_id: chainId,
|
|
281
|
+
contract_address: contract
|
|
282
|
+
};
|
|
283
|
+
if (opts.page) params.page = opts.page;
|
|
284
|
+
if (opts.limit) params.limit = opts.limit;
|
|
285
|
+
const result = await client.get("/v1/token/top-holders", params);
|
|
286
|
+
formatOutput(result, opts.pretty);
|
|
287
|
+
});
|
|
288
|
+
cmd.command("price <contract>").description("\u83B7\u53D6\u4EE3\u5E01\u4EF7\u683C").action(async (contract) => {
|
|
289
|
+
const opts = cmd.parent.opts();
|
|
290
|
+
const { client, chainId } = createClient(opts);
|
|
291
|
+
const result = await client.get("/v1/token/price", {
|
|
292
|
+
chain_id: chainId,
|
|
293
|
+
contract_address: contract
|
|
294
|
+
});
|
|
295
|
+
formatOutput(result, opts.pretty);
|
|
296
|
+
});
|
|
297
|
+
cmd.command("price-history <contract>").description("\u83B7\u53D6\u4EE3\u5E01\u5386\u53F2\u4EF7\u683C").requiredOption("--from <timestamp>", "\u8D77\u59CB\u65F6\u95F4\u6233").requiredOption("--to <timestamp>", "\u7ED3\u675F\u65F6\u95F4\u6233").action(async (contract, cmdOpts) => {
|
|
298
|
+
const opts = cmd.parent.opts();
|
|
299
|
+
const { client, chainId } = createClient(opts);
|
|
300
|
+
const result = await client.get("/v1/token/price/history", {
|
|
301
|
+
chain_id: chainId,
|
|
302
|
+
contract_address: contract,
|
|
303
|
+
from_timestamp: cmdOpts.from,
|
|
304
|
+
end_timestamp: cmdOpts.to
|
|
305
|
+
});
|
|
306
|
+
formatOutput(result, opts.pretty);
|
|
307
|
+
});
|
|
308
|
+
return cmd;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// src/commands/nft.ts
|
|
312
|
+
import { Command as Command7 } from "commander";
|
|
313
|
+
function createNftCommand() {
|
|
314
|
+
const cmd = new Command7("nft").description("NFT \u67E5\u8BE2");
|
|
315
|
+
cmd.command("metadata <contract> <token_id>").description("\u83B7\u53D6 NFT \u5143\u6570\u636E").action(async (contract, tokenId) => {
|
|
316
|
+
const opts = cmd.parent.opts();
|
|
317
|
+
const { client, chainId } = createClient(opts);
|
|
318
|
+
const result = await client.get("/v1/nft/metadata", {
|
|
319
|
+
chain_id: chainId,
|
|
320
|
+
contract_address: contract,
|
|
321
|
+
token_id: tokenId
|
|
322
|
+
});
|
|
323
|
+
formatOutput(result, opts.pretty);
|
|
324
|
+
});
|
|
325
|
+
cmd.command("collection <contract>").description("\u83B7\u53D6 NFT \u96C6\u5408\u4FE1\u606F").action(async (contract) => {
|
|
326
|
+
const opts = cmd.parent.opts();
|
|
327
|
+
const { client, chainId } = createClient(opts);
|
|
328
|
+
const result = await client.get("/v1/nft/collection", {
|
|
329
|
+
chain_id: chainId,
|
|
330
|
+
contract_address: contract
|
|
331
|
+
});
|
|
332
|
+
formatOutput(result, opts.pretty);
|
|
333
|
+
});
|
|
334
|
+
cmd.command("collection-items <contract>").description("\u83B7\u53D6 NFT \u96C6\u5408\u5185\u6240\u6709\u9879\u76EE").option("--page <n>", "\u9875\u7801").option("--limit <n>", "\u6BCF\u9875\u6761\u6570").action(async (contract, cmdOpts) => {
|
|
335
|
+
const opts = cmd.parent.opts();
|
|
336
|
+
const { client, chainId } = createClient(opts);
|
|
337
|
+
const params = {
|
|
338
|
+
chain_id: chainId,
|
|
339
|
+
contract_address: contract
|
|
340
|
+
};
|
|
341
|
+
if (cmdOpts.page) params.page = cmdOpts.page;
|
|
342
|
+
if (cmdOpts.limit) params.limit = cmdOpts.limit;
|
|
343
|
+
const result = await client.get("/v1/nft/collection/items", params);
|
|
344
|
+
formatOutput(result, opts.pretty);
|
|
345
|
+
});
|
|
346
|
+
cmd.command("search <name>").description("\u6309\u540D\u79F0\u641C\u7D22 NFT \u96C6\u5408").option("--contract <addr>", "\u5408\u7EA6\u5730\u5740").option("--page <n>", "\u9875\u7801").option("--limit <n>", "\u6BCF\u9875\u6761\u6570").action(async (name, cmdOpts) => {
|
|
347
|
+
const opts = cmd.parent.opts();
|
|
348
|
+
const { client, chainId } = createClient(opts);
|
|
349
|
+
const params = {
|
|
350
|
+
chain_id: chainId,
|
|
351
|
+
name
|
|
352
|
+
};
|
|
353
|
+
if (cmdOpts.contract) params.contract_address = cmdOpts.contract;
|
|
354
|
+
if (cmdOpts.page) params.page = cmdOpts.page;
|
|
355
|
+
if (cmdOpts.limit) params.limit = cmdOpts.limit;
|
|
356
|
+
const result = await client.get("/v1/nft/search", params);
|
|
357
|
+
formatOutput(result, opts.pretty);
|
|
358
|
+
});
|
|
359
|
+
cmd.command("transfers").description("\u83B7\u53D6 NFT \u8F6C\u8D26\u8BB0\u5F55").option("--contract <addr>", "\u5408\u7EA6\u5730\u5740").option("--token-id <id>", "Token ID").option("--address <addr>", "\u94B1\u5305\u5730\u5740").option("--from-block <n>", "\u8D77\u59CB\u533A\u5757\u53F7").option("--to-block <n>", "\u7ED3\u675F\u533A\u5757\u53F7").option("--from-timestamp <n>", "\u8D77\u59CB\u65F6\u95F4\u6233").option("--end-timestamp <n>", "\u7ED3\u675F\u65F6\u95F4\u6233").option("--page <n>", "\u9875\u7801").option("--limit <n>", "\u6BCF\u9875\u6761\u6570").action(async (cmdOpts) => {
|
|
360
|
+
const opts = cmd.parent.opts();
|
|
361
|
+
const { client, chainId } = createClient(opts);
|
|
362
|
+
const params = {
|
|
363
|
+
chain_id: chainId
|
|
364
|
+
};
|
|
365
|
+
if (cmdOpts.contract) params.contract_address = cmdOpts.contract;
|
|
366
|
+
if (cmdOpts.tokenId) params.token_id = cmdOpts.tokenId;
|
|
367
|
+
if (cmdOpts.address) params.address = cmdOpts.address;
|
|
368
|
+
if (cmdOpts.fromBlock) params.from_block = cmdOpts.fromBlock;
|
|
369
|
+
if (cmdOpts.toBlock) params.to_block = cmdOpts.toBlock;
|
|
370
|
+
if (cmdOpts.fromTimestamp) params.from_timestamp = cmdOpts.fromTimestamp;
|
|
371
|
+
if (cmdOpts.endTimestamp) params.end_timestamp = cmdOpts.endTimestamp;
|
|
372
|
+
if (cmdOpts.page) params.page = cmdOpts.page;
|
|
373
|
+
if (cmdOpts.limit) params.limit = cmdOpts.limit;
|
|
374
|
+
const result = await client.get("/v1/nft/transfers", params);
|
|
375
|
+
formatOutput(result, opts.pretty);
|
|
376
|
+
});
|
|
377
|
+
cmd.command("owner <contract> <token_id>").description("\u83B7\u53D6 NFT \u5F53\u524D\u6301\u6709\u8005").option("--to-block <n>", "\u533A\u5757\u53F7").action(async (contract, tokenId, cmdOpts) => {
|
|
378
|
+
const opts = cmd.parent.opts();
|
|
379
|
+
const { client, chainId } = createClient(opts);
|
|
380
|
+
const params = {
|
|
381
|
+
chain_id: chainId,
|
|
382
|
+
contract_address: contract,
|
|
383
|
+
token_id: tokenId
|
|
384
|
+
};
|
|
385
|
+
if (cmdOpts.toBlock) params.to_block = cmdOpts.toBlock;
|
|
386
|
+
const result = await client.get("/v1/nft/owner", params);
|
|
387
|
+
formatOutput(result, opts.pretty);
|
|
388
|
+
});
|
|
389
|
+
cmd.command("owners <contract>").description("\u83B7\u53D6 NFT \u96C6\u5408\u6240\u6709\u6301\u6709\u8005").option("--page <n>", "\u9875\u7801").option("--limit <n>", "\u6BCF\u9875\u6761\u6570").action(async (contract, cmdOpts) => {
|
|
390
|
+
const opts = cmd.parent.opts();
|
|
391
|
+
const { client, chainId } = createClient(opts);
|
|
392
|
+
const params = {
|
|
393
|
+
chain_id: chainId,
|
|
394
|
+
contract_address: contract
|
|
395
|
+
};
|
|
396
|
+
if (cmdOpts.page) params.page = cmdOpts.page;
|
|
397
|
+
if (cmdOpts.limit) params.limit = cmdOpts.limit;
|
|
398
|
+
const result = await client.get("/v1/nft/owners", params);
|
|
399
|
+
formatOutput(result, opts.pretty);
|
|
400
|
+
});
|
|
401
|
+
cmd.command("owner-history <contract> <token_id>").description("\u83B7\u53D6 NFT \u6301\u6709\u8005\u5386\u53F2").option("--from-block <n>", "\u8D77\u59CB\u533A\u5757\u53F7").option("--to-block <n>", "\u7ED3\u675F\u533A\u5757\u53F7").option("--from-timestamp <n>", "\u8D77\u59CB\u65F6\u95F4\u6233").option("--end-timestamp <n>", "\u7ED3\u675F\u65F6\u95F4\u6233").option("--page <n>", "\u9875\u7801").option("--limit <n>", "\u6BCF\u9875\u6761\u6570").action(async (contract, tokenId, cmdOpts) => {
|
|
402
|
+
const opts = cmd.parent.opts();
|
|
403
|
+
const { client, chainId } = createClient(opts);
|
|
404
|
+
const params = {
|
|
405
|
+
chain_id: chainId,
|
|
406
|
+
contract_address: contract,
|
|
407
|
+
token_id: tokenId
|
|
408
|
+
};
|
|
409
|
+
if (cmdOpts.fromBlock) params.from_block = cmdOpts.fromBlock;
|
|
410
|
+
if (cmdOpts.toBlock) params.to_block = cmdOpts.toBlock;
|
|
411
|
+
if (cmdOpts.fromTimestamp) params.from_timestamp = cmdOpts.fromTimestamp;
|
|
412
|
+
if (cmdOpts.endTimestamp) params.end_timestamp = cmdOpts.endTimestamp;
|
|
413
|
+
if (cmdOpts.page) params.page = cmdOpts.page;
|
|
414
|
+
if (cmdOpts.limit) params.limit = cmdOpts.limit;
|
|
415
|
+
const result = await client.get("/v1/nft/owner/history", params);
|
|
416
|
+
formatOutput(result, opts.pretty);
|
|
417
|
+
});
|
|
418
|
+
cmd.command("floor-price <contract>").description("\u83B7\u53D6 NFT \u5730\u677F\u4EF7").action(async (contract) => {
|
|
419
|
+
const opts = cmd.parent.opts();
|
|
420
|
+
const { client, chainId } = createClient(opts);
|
|
421
|
+
const result = await client.get("/v1/nft/floor_price", {
|
|
422
|
+
chain_id: chainId,
|
|
423
|
+
contract_address: contract
|
|
424
|
+
});
|
|
425
|
+
formatOutput(result, opts.pretty);
|
|
426
|
+
});
|
|
427
|
+
cmd.command("price-history <contract>").description("\u83B7\u53D6 NFT \u5386\u53F2\u5730\u677F\u4EF7").requiredOption("--from <timestamp>", "\u8D77\u59CB\u65F6\u95F4\u6233").requiredOption("--to <timestamp>", "\u7ED3\u675F\u65F6\u95F4\u6233").action(async (contract, cmdOpts) => {
|
|
428
|
+
const opts = cmd.parent.opts();
|
|
429
|
+
const { client, chainId } = createClient(opts);
|
|
430
|
+
const result = await client.get("/v1/nft/price/history", {
|
|
431
|
+
chain_id: chainId,
|
|
432
|
+
contract_address: contract,
|
|
433
|
+
from_timestamp: cmdOpts.from,
|
|
434
|
+
end_timestamp: cmdOpts.to
|
|
435
|
+
});
|
|
436
|
+
formatOutput(result, opts.pretty);
|
|
437
|
+
});
|
|
438
|
+
cmd.command("trending").description("\u83B7\u53D6\u70ED\u95E8 NFT \u96C6\u5408").option("--range <period>", "\u65F6\u95F4\u8303\u56F4", "7d").option("--exchange <name>", "\u4EA4\u6613\u6240\u540D\u79F0").option("--sort <order>", "\u6392\u5E8F\u65B9\u5F0F").option("--page <n>", "\u9875\u7801").option("--limit <n>", "\u6BCF\u9875\u6761\u6570").action(async (cmdOpts) => {
|
|
439
|
+
const opts = cmd.parent.opts();
|
|
440
|
+
const { client, chainId } = createClient(opts);
|
|
441
|
+
const params = {
|
|
442
|
+
chain_id: chainId,
|
|
443
|
+
range: cmdOpts.range
|
|
444
|
+
};
|
|
445
|
+
if (cmdOpts.exchange) params.exchange_name = cmdOpts.exchange;
|
|
446
|
+
if (cmdOpts.sort) params.sort = cmdOpts.sort;
|
|
447
|
+
if (cmdOpts.page) params.page = cmdOpts.page;
|
|
448
|
+
if (cmdOpts.limit) params.limit = cmdOpts.limit;
|
|
449
|
+
const result = await client.get("/v1/nft/collection/trending", params);
|
|
450
|
+
formatOutput(result, opts.pretty);
|
|
451
|
+
});
|
|
452
|
+
cmd.command("rarity <contract>").description("\u83B7\u53D6 NFT \u7A00\u6709\u5EA6").option("--token-id <id>", "Token ID").option("--rank-min <n>", "\u6700\u4F4E\u6392\u540D").option("--rank-max <n>", "\u6700\u9AD8\u6392\u540D").option("--page <n>", "\u9875\u7801").option("--limit <n>", "\u6BCF\u9875\u6761\u6570").action(async (contract, cmdOpts) => {
|
|
453
|
+
const opts = cmd.parent.opts();
|
|
454
|
+
const { client, chainId } = createClient(opts);
|
|
455
|
+
const params = {
|
|
456
|
+
chain_id: chainId,
|
|
457
|
+
contract_address: contract
|
|
458
|
+
};
|
|
459
|
+
if (cmdOpts.tokenId) params.token_id = cmdOpts.tokenId;
|
|
460
|
+
if (cmdOpts.rankMin) params.rank_min = cmdOpts.rankMin;
|
|
461
|
+
if (cmdOpts.rankMax) params.rank_max = cmdOpts.rankMax;
|
|
462
|
+
if (cmdOpts.page) params.page = cmdOpts.page;
|
|
463
|
+
if (cmdOpts.limit) params.limit = cmdOpts.limit;
|
|
464
|
+
const result = await client.get("/v1/nft/rarity", params);
|
|
465
|
+
formatOutput(result, opts.pretty);
|
|
466
|
+
});
|
|
467
|
+
return cmd;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// src/commands/balance.ts
|
|
471
|
+
import { Command as Command8 } from "commander";
|
|
472
|
+
function createBalanceCommand() {
|
|
473
|
+
const cmd = new Command8("balance").description("\u4F59\u989D\u4E0E\u8D26\u6237\u67E5\u8BE2");
|
|
474
|
+
cmd.command("native <address>").description("\u83B7\u53D6\u539F\u751F\u4EE3\u5E01\u4F59\u989D").option("--to-block <n>", "\u533A\u5757\u53F7").action(async (address, cmdOpts) => {
|
|
475
|
+
const opts = cmd.parent.opts();
|
|
476
|
+
const { client, chainId } = createClient(opts);
|
|
477
|
+
const params = {
|
|
478
|
+
chain_id: chainId,
|
|
479
|
+
address
|
|
480
|
+
};
|
|
481
|
+
if (cmdOpts.toBlock) params.to_block = cmdOpts.toBlock;
|
|
482
|
+
const result = await client.get("/v1/account/balance", params);
|
|
483
|
+
formatOutput(result, opts.pretty);
|
|
484
|
+
});
|
|
485
|
+
cmd.command("tokens <address>").description("\u83B7\u53D6 ERC20 \u4EE3\u5E01\u4F59\u989D").option("--contract <addr>", "\u6309\u5408\u7EA6\u5730\u5740\u7B5B\u9009").option("--page <n>", "\u9875\u7801").option("--limit <n>", "\u6BCF\u9875\u6761\u6570").action(async (address, cmdOpts) => {
|
|
486
|
+
const opts = cmd.parent.opts();
|
|
487
|
+
const { client, chainId } = createClient(opts);
|
|
488
|
+
const params = {
|
|
489
|
+
chain_id: chainId,
|
|
490
|
+
address
|
|
491
|
+
};
|
|
492
|
+
if (cmdOpts.contract) params.contract_address = cmdOpts.contract;
|
|
493
|
+
if (cmdOpts.page) params.page = cmdOpts.page;
|
|
494
|
+
if (cmdOpts.limit) params.limit = cmdOpts.limit;
|
|
495
|
+
const result = await client.get("/v1/account/tokens", params);
|
|
496
|
+
formatOutput(result, opts.pretty);
|
|
497
|
+
});
|
|
498
|
+
cmd.command("portfolios <address>").description("\u83B7\u53D6 DeFi \u7EC4\u5408\u6301\u4ED3").option("--chains <ids>", "\u94FE ID\uFF08\u9017\u53F7\u5206\u9694\uFF09").action(async (address, cmdOpts) => {
|
|
499
|
+
const opts = cmd.parent.opts();
|
|
500
|
+
const { client } = createClient(opts);
|
|
501
|
+
const params = {
|
|
502
|
+
address
|
|
503
|
+
};
|
|
504
|
+
if (cmdOpts.chains) params.chain_id = cmdOpts.chains.split(",");
|
|
505
|
+
const result = await client.get("/v1/account/portfolios", params);
|
|
506
|
+
formatOutput(result, opts.pretty);
|
|
507
|
+
});
|
|
508
|
+
cmd.command("nfts <address>").description("\u83B7\u53D6\u6301\u6709\u7684 NFT \u5217\u8868").option("--contract <addr>", "\u6309\u5408\u7EA6\u5730\u5740\u7B5B\u9009").option("--page <n>", "\u9875\u7801").option("--limit <n>", "\u6BCF\u9875\u6761\u6570").action(async (address, cmdOpts) => {
|
|
509
|
+
const opts = cmd.parent.opts();
|
|
510
|
+
const { client, chainId } = createClient(opts);
|
|
511
|
+
const params = {
|
|
512
|
+
chain_id: chainId,
|
|
513
|
+
address
|
|
514
|
+
};
|
|
515
|
+
if (cmdOpts.contract) params.contract_address = cmdOpts.contract;
|
|
516
|
+
if (cmdOpts.page) params.page = cmdOpts.page;
|
|
517
|
+
if (cmdOpts.limit) params.limit = cmdOpts.limit;
|
|
518
|
+
const result = await client.get("/v1/account/nfts", params);
|
|
519
|
+
formatOutput(result, opts.pretty);
|
|
520
|
+
});
|
|
521
|
+
return cmd;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// src/commands/domain.ts
|
|
525
|
+
import { Command as Command9 } from "commander";
|
|
526
|
+
function createDomainCommand() {
|
|
527
|
+
const cmd = new Command9("domain").description("\u57DF\u540D\u67E5\u8BE2");
|
|
528
|
+
cmd.command("ens <address>").description("\u83B7\u53D6\u5730\u5740\u6301\u6709\u7684 ENS \u57DF\u540D").option("--to-block <n>", "\u533A\u5757\u53F7").action(async (address, cmdOpts) => {
|
|
529
|
+
const opts = cmd.parent.opts();
|
|
530
|
+
const { client, chainId } = createClient(opts);
|
|
531
|
+
const params = {
|
|
532
|
+
chain_id: chainId,
|
|
533
|
+
address
|
|
534
|
+
};
|
|
535
|
+
if (cmdOpts.toBlock) params.to_block = cmdOpts.toBlock;
|
|
536
|
+
const result = await client.get("/v1/account/ens", params);
|
|
537
|
+
formatOutput(result, opts.pretty);
|
|
538
|
+
});
|
|
539
|
+
cmd.command("ens-resolve <domain>").description("\u89E3\u6790 ENS \u57DF\u540D").option("--to-block <n>", "\u533A\u5757\u53F7").action(async (domain, cmdOpts) => {
|
|
540
|
+
const opts = cmd.parent.opts();
|
|
541
|
+
const { client, chainId } = createClient(opts);
|
|
542
|
+
const params = {
|
|
543
|
+
chain_id: chainId,
|
|
544
|
+
domain
|
|
545
|
+
};
|
|
546
|
+
if (cmdOpts.toBlock) params.to_block = cmdOpts.toBlock;
|
|
547
|
+
const result = await client.get("/v1/ens/records", params);
|
|
548
|
+
formatOutput(result, opts.pretty);
|
|
549
|
+
});
|
|
550
|
+
cmd.command("ens-reverse <address>").description("\u53CD\u5411\u89E3\u6790\u5730\u5740\u5230 ENS \u57DF\u540D").option("--to-block <n>", "\u533A\u5757\u53F7").action(async (address, cmdOpts) => {
|
|
551
|
+
const opts = cmd.parent.opts();
|
|
552
|
+
const { client, chainId } = createClient(opts);
|
|
553
|
+
const params = {
|
|
554
|
+
chain_id: chainId,
|
|
555
|
+
address
|
|
556
|
+
};
|
|
557
|
+
if (cmdOpts.toBlock) params.to_block = cmdOpts.toBlock;
|
|
558
|
+
const result = await client.get("/v1/ens/reverse", params);
|
|
559
|
+
formatOutput(result, opts.pretty);
|
|
560
|
+
});
|
|
561
|
+
cmd.command("spaceid-resolve <domain>").description("\u89E3\u6790 Space ID \u57DF\u540D").option("--to-block <n>", "\u533A\u5757\u53F7").action(async (domain, cmdOpts) => {
|
|
562
|
+
const opts = cmd.parent.opts();
|
|
563
|
+
const { client, chainId } = createClient(opts);
|
|
564
|
+
const params = {
|
|
565
|
+
chain_id: chainId,
|
|
566
|
+
domain
|
|
567
|
+
};
|
|
568
|
+
if (cmdOpts.toBlock) params.to_block = cmdOpts.toBlock;
|
|
569
|
+
const result = await client.get("/v1/space-id/records", params);
|
|
570
|
+
formatOutput(result, opts.pretty);
|
|
571
|
+
});
|
|
572
|
+
cmd.command("spaceid-reverse <address>").description("\u53CD\u5411\u89E3\u6790\u5730\u5740\u5230 Space ID \u57DF\u540D").option("--to-block <n>", "\u533A\u5757\u53F7").action(async (address, cmdOpts) => {
|
|
573
|
+
const opts = cmd.parent.opts();
|
|
574
|
+
const { client, chainId } = createClient(opts);
|
|
575
|
+
const params = {
|
|
576
|
+
chain_id: chainId,
|
|
577
|
+
address
|
|
578
|
+
};
|
|
579
|
+
if (cmdOpts.toBlock) params.to_block = cmdOpts.toBlock;
|
|
580
|
+
const result = await client.get("/v1/space-id/reverse", params);
|
|
581
|
+
formatOutput(result, opts.pretty);
|
|
582
|
+
});
|
|
583
|
+
return cmd;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// src/commands/sql.ts
|
|
587
|
+
import { Command as Command10 } from "commander";
|
|
588
|
+
function createSqlCommand() {
|
|
589
|
+
const cmd = new Command10("sql").description("SQL \u67E5\u8BE2\u4E0E\u6267\u884C");
|
|
590
|
+
cmd.command("execute <sql>").description("\u5F02\u6B65\u6267\u884C SQL \u8BED\u53E5").action(async (sql) => {
|
|
591
|
+
const opts = cmd.parent.opts();
|
|
592
|
+
const { client } = createClient(opts);
|
|
593
|
+
const result = await client.post("/query/execute", { sql });
|
|
594
|
+
formatOutput(result, opts.pretty);
|
|
595
|
+
});
|
|
596
|
+
cmd.command("status <execution_id>").description("\u67E5\u8BE2\u6267\u884C\u72B6\u6001").action(async (executionId) => {
|
|
597
|
+
const opts = cmd.parent.opts();
|
|
598
|
+
const { client } = createClient(opts);
|
|
599
|
+
const result = await client.get(`/execution/${executionId}/status`, {});
|
|
600
|
+
formatOutput(result, opts.pretty);
|
|
601
|
+
});
|
|
602
|
+
cmd.command("results <execution_id>").description("\u83B7\u53D6\u6267\u884C\u7ED3\u679C").action(async (executionId) => {
|
|
603
|
+
const opts = cmd.parent.opts();
|
|
604
|
+
const { client } = createClient(opts);
|
|
605
|
+
const result = await client.get(`/execution/${executionId}/results`, {});
|
|
606
|
+
formatOutput(result, opts.pretty);
|
|
607
|
+
});
|
|
608
|
+
return cmd;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// src/index.ts
|
|
612
|
+
var program = new Command11();
|
|
613
|
+
program.name("chainbase").description("Chainbase Web3 API \u547D\u4EE4\u884C\u5DE5\u5177").version("0.1.0").option("--chain <id>", "\u94FE ID\uFF08\u9ED8\u8BA4\u4ECE\u914D\u7F6E\u8BFB\u53D6\uFF0C\u5426\u5219\u4E3A 1\uFF09").option("--pretty", "\u4EE5\u4EBA\u7C7B\u53EF\u8BFB\u683C\u5F0F\u8F93\u51FA", false).option("--page <n>", "\u9875\u7801", "1").option("--limit <n>", "\u6BCF\u9875\u6761\u6570", "20");
|
|
614
|
+
program.addCommand(createConfigCommand());
|
|
615
|
+
program.addCommand(createBlockCommand());
|
|
616
|
+
program.addCommand(createTxCommand());
|
|
617
|
+
program.addCommand(createContractCommand());
|
|
618
|
+
program.addCommand(createAddressCommand());
|
|
619
|
+
program.addCommand(createTokenCommand());
|
|
620
|
+
program.addCommand(createNftCommand());
|
|
621
|
+
program.addCommand(createBalanceCommand());
|
|
622
|
+
program.addCommand(createDomainCommand());
|
|
623
|
+
program.addCommand(createSqlCommand());
|
|
624
|
+
async function main() {
|
|
625
|
+
try {
|
|
626
|
+
await program.parseAsync();
|
|
627
|
+
} catch (err) {
|
|
628
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
629
|
+
formatError(message, program.opts().pretty);
|
|
630
|
+
process.exit(1);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "chainbase-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI for Chainbase Web3 API",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"chainbase": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsup src/index.ts --format esm --dts --clean",
|
|
11
|
+
"dev": "tsup src/index.ts --format esm --watch",
|
|
12
|
+
"test": "vitest run",
|
|
13
|
+
"test:watch": "vitest",
|
|
14
|
+
"lint": "tsc --noEmit"
|
|
15
|
+
},
|
|
16
|
+
"files": ["dist"],
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/chainbase-com/chainbase-cli.git"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [],
|
|
22
|
+
"author": "",
|
|
23
|
+
"license": "ISC",
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/chainbase-com/chainbase-cli/issues"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/chainbase-com/chainbase-cli#readme",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"axios": "^1.13.5",
|
|
30
|
+
"chalk": "^5.6.2",
|
|
31
|
+
"cli-table3": "^0.6.5",
|
|
32
|
+
"commander": "^14.0.3"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^25.3.0",
|
|
36
|
+
"tsup": "^8.5.1",
|
|
37
|
+
"typescript": "^5.9.3",
|
|
38
|
+
"vitest": "^4.0.18"
|
|
39
|
+
}
|
|
40
|
+
}
|