openbroker 1.0.71 → 1.0.73
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/SKILL.md +64 -6
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/scripts/info/account.ts +41 -27
- package/scripts/info/fees.ts +7 -1
- package/scripts/info/fills.ts +14 -5
- package/scripts/info/order-status.ts +7 -3
- package/scripts/info/orders.ts +15 -2
- package/scripts/info/positions.ts +11 -3
- package/scripts/info/spot.ts +12 -7
package/SKILL.md
CHANGED
|
@@ -4,7 +4,7 @@ description: Hyperliquid trading plugin with background position monitoring and
|
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: Requires Node.js 22+, network access to api.hyperliquid.xyz
|
|
6
6
|
homepage: https://www.npmjs.com/package/openbroker
|
|
7
|
-
metadata: {"author": "monemetrics", "version": "1.0.
|
|
7
|
+
metadata: {"author": "monemetrics", "version": "1.0.73", "openclaw": {"requires": {"bins": ["openbroker"], "env": ["HYPERLIQUID_PRIVATE_KEY"]}, "primaryEnv": "HYPERLIQUID_PRIVATE_KEY", "install": [{"id": "node", "kind": "node", "package": "openbroker", "bins": ["openbroker"], "label": "Install openbroker (npm)"}]}}
|
|
8
8
|
allowed-tools: ob_account ob_positions ob_funding ob_markets ob_search ob_spot ob_fills ob_orders ob_order_status ob_fees ob_candles ob_funding_history ob_trades ob_rate_limit ob_funding_scan ob_buy ob_sell ob_limit ob_trigger ob_tpsl ob_cancel ob_twap ob_twap_cancel ob_twap_status ob_bracket ob_chase ob_watcher_status ob_auto_run ob_auto_stop ob_auto_list Bash(openbroker:*)
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -127,8 +127,10 @@ HYPERLIQUID_NETWORK=mainnet
|
|
|
127
127
|
```bash
|
|
128
128
|
openbroker account # Balance, equity, margin
|
|
129
129
|
openbroker account --orders # Include open orders
|
|
130
|
+
openbroker account --address 0xabc... # Look up another account
|
|
130
131
|
openbroker positions # Open positions with PnL
|
|
131
132
|
openbroker positions --coin ETH # Specific coin
|
|
133
|
+
openbroker positions --address 0xabc... # Another account's positions
|
|
132
134
|
```
|
|
133
135
|
|
|
134
136
|
### Funding Rates
|
|
@@ -164,6 +166,7 @@ openbroker search --query ETH --type perp # ETH perps only
|
|
|
164
166
|
openbroker spot # Show all spot markets
|
|
165
167
|
openbroker spot --coin PURR # Show PURR market info
|
|
166
168
|
openbroker spot --balances # Show your spot balances
|
|
169
|
+
openbroker spot --balances --address 0xabc... # Another account's spot balances
|
|
167
170
|
openbroker spot --top 20 # Top 20 by volume
|
|
168
171
|
```
|
|
169
172
|
|
|
@@ -172,6 +175,7 @@ openbroker spot --top 20 # Top 20 by volume
|
|
|
172
175
|
openbroker fills # Recent fills
|
|
173
176
|
openbroker fills --coin ETH # ETH fills only
|
|
174
177
|
openbroker fills --coin BTC --side buy --top 50
|
|
178
|
+
openbroker fills --address 0xabc... # Another account's fills
|
|
175
179
|
```
|
|
176
180
|
|
|
177
181
|
### Order History
|
|
@@ -181,17 +185,20 @@ openbroker orders --open # Currently open orders only
|
|
|
181
185
|
openbroker orders --open --coin ETH # Open orders for a specific coin
|
|
182
186
|
openbroker orders --coin ETH --status filled
|
|
183
187
|
openbroker orders --top 50
|
|
188
|
+
openbroker orders --address 0xabc... --open # Another account's open orders
|
|
184
189
|
```
|
|
185
190
|
|
|
186
191
|
### Order Status
|
|
187
192
|
```bash
|
|
188
193
|
openbroker order-status --oid 123456789 # Check specific order
|
|
189
194
|
openbroker order-status --oid 0x1234... # By client order ID
|
|
195
|
+
openbroker order-status --oid 123456789 --address 0xabc... # On another account
|
|
190
196
|
```
|
|
191
197
|
|
|
192
198
|
### Fee Schedule
|
|
193
199
|
```bash
|
|
194
200
|
openbroker fees # Fee tier, rates, and volume
|
|
201
|
+
openbroker fees --address 0xabc... # Another account's fees
|
|
195
202
|
```
|
|
196
203
|
|
|
197
204
|
### Candle Data (OHLCV)
|
|
@@ -436,15 +443,66 @@ The plugin reads wallet credentials from `~/.openbroker/.env` (set up by `openbr
|
|
|
436
443
|
|
|
437
444
|
### Webhook setup for watcher alerts
|
|
438
445
|
|
|
439
|
-
For position alerts to
|
|
446
|
+
For the position watcher and automations to send alerts to the agent, you must enable webhooks in your OpenClaw gateway config and add a hook mapping. This is a manual configuration step — plugins cannot auto-configure gateway settings.
|
|
440
447
|
|
|
448
|
+
**1. Generate a hook token** — any secure random string:
|
|
449
|
+
```bash
|
|
450
|
+
openssl rand -hex 32
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
**2. Enable hooks and add a mapping** in your `openclaw.json` (or `openclaw.yaml`) deployment config:
|
|
454
|
+
```json
|
|
455
|
+
"hooks": {
|
|
456
|
+
"enabled": true,
|
|
457
|
+
"path": "/hooks",
|
|
458
|
+
"token": "<your-generated-token>",
|
|
459
|
+
"allowedAgentIds": ["hooks", "main", "openbroker"],
|
|
460
|
+
"mappings": [
|
|
461
|
+
{
|
|
462
|
+
"id": "main",
|
|
463
|
+
"match": {
|
|
464
|
+
"path": "openbroker"
|
|
465
|
+
},
|
|
466
|
+
"action": "agent",
|
|
467
|
+
"wakeMode": "now",
|
|
468
|
+
"name": "Openbroker",
|
|
469
|
+
"agentId": "main",
|
|
470
|
+
"deliver": true,
|
|
471
|
+
"channel": "last",
|
|
472
|
+
"model": "anthropic/claude-sonnet-4-6"
|
|
473
|
+
}
|
|
474
|
+
]
|
|
475
|
+
}
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
| Field | Description |
|
|
479
|
+
|-------|-------------|
|
|
480
|
+
| `token` | Shared secret — must match `hooksToken` in the plugin config |
|
|
481
|
+
| `allowedAgentIds` | Agent IDs allowed to receive webhook requests |
|
|
482
|
+
| `mappings[].match.path` | Matches the webhook path sent by the plugin (always `"openbroker"`) |
|
|
483
|
+
| `mappings[].wakeMode` | `"now"` triggers an immediate agent turn. `"next-heartbeat"` queues for the next scheduled heartbeat |
|
|
484
|
+
| `mappings[].deliver` | If `true`, the agent's response is delivered to the user via the configured channel |
|
|
485
|
+
| `mappings[].channel` | Delivery channel: `"last"` (most recent), `"slack"`, `"telegram"`, `"discord"`, `"whatsapp"`, etc. |
|
|
486
|
+
| `mappings[].model` | Model override for webhook-triggered turns. Optional — uses deployment default if omitted |
|
|
487
|
+
|
|
488
|
+
**3. Set the same token in your plugin config:**
|
|
441
489
|
```yaml
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
490
|
+
plugins:
|
|
491
|
+
entries:
|
|
492
|
+
openbroker:
|
|
493
|
+
enabled: true
|
|
494
|
+
config:
|
|
495
|
+
hooksToken: "<your-generated-token>" # Same token as hooks.token
|
|
496
|
+
watcher:
|
|
497
|
+
enabled: true
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
**4. Restart the gateway** and verify:
|
|
501
|
+
```bash
|
|
502
|
+
openclaw ob status
|
|
445
503
|
```
|
|
446
504
|
|
|
447
|
-
Without hooks, the watcher still
|
|
505
|
+
The watcher sends alerts to `POST /hooks/agent` with `Authorization: Bearer <token>`. The gateway matches the request against the mapping and triggers an agent turn. Without hooks enabled, the watcher still tracks state (accessible via `ob_watcher_status`), but it can't wake the agent.
|
|
448
506
|
|
|
449
507
|
### Using with or without the plugin
|
|
450
508
|
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
package/scripts/info/account.ts
CHANGED
|
@@ -7,16 +7,20 @@ import { formatUsd, formatPercent, parseArgs } from '../core/utils.js';
|
|
|
7
7
|
async function main() {
|
|
8
8
|
const args = parseArgs(process.argv.slice(2));
|
|
9
9
|
const jsonOutput = args.json as boolean;
|
|
10
|
+
const targetAddress = args.address as string | undefined;
|
|
10
11
|
const client = getClient();
|
|
11
12
|
|
|
12
13
|
if (args.verbose) {
|
|
13
14
|
client.verbose = true;
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
const
|
|
17
|
+
const lookupAddress = targetAddress?.toLowerCase() ?? client.address;
|
|
18
|
+
const isOtherAccount = !!targetAddress;
|
|
19
|
+
|
|
20
|
+
const accountMode = await client.getAccountMode(isOtherAccount ? lookupAddress : undefined);
|
|
17
21
|
|
|
18
22
|
try {
|
|
19
|
-
const state = await client.getUserStateAll();
|
|
23
|
+
const state = await client.getUserStateAll(isOtherAccount ? lookupAddress : undefined);
|
|
20
24
|
|
|
21
25
|
const margin = state.crossMarginSummary;
|
|
22
26
|
const accountValue = parseFloat(margin.accountValue);
|
|
@@ -51,9 +55,11 @@ async function main() {
|
|
|
51
55
|
// JSON output
|
|
52
56
|
if (jsonOutput) {
|
|
53
57
|
const result: Record<string, unknown> = {
|
|
54
|
-
address:
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
address: lookupAddress,
|
|
59
|
+
...(isOtherAccount ? {} : {
|
|
60
|
+
signingWallet: client.walletAddress,
|
|
61
|
+
walletType: client.isApiWallet ? 'api' : 'main',
|
|
62
|
+
}),
|
|
57
63
|
accountMode,
|
|
58
64
|
equity: accountValue,
|
|
59
65
|
totalNotional,
|
|
@@ -65,7 +71,7 @@ async function main() {
|
|
|
65
71
|
};
|
|
66
72
|
|
|
67
73
|
if (args.orders) {
|
|
68
|
-
const orders = await client.getOpenOrders();
|
|
74
|
+
const orders = await client.getOpenOrders(isOtherAccount ? lookupAddress : undefined);
|
|
69
75
|
result.openOrders = orders.map(o => ({
|
|
70
76
|
coin: o.coin,
|
|
71
77
|
oid: o.oid,
|
|
@@ -85,11 +91,17 @@ async function main() {
|
|
|
85
91
|
console.log('Open Broker - Account Info');
|
|
86
92
|
console.log('==========================\n');
|
|
87
93
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
94
|
+
if (isOtherAccount) {
|
|
95
|
+
console.log('Lookup Address');
|
|
96
|
+
console.log('--------------------');
|
|
97
|
+
console.log(`Address: ${lookupAddress}`);
|
|
98
|
+
} else {
|
|
99
|
+
console.log('Wallet Configuration');
|
|
100
|
+
console.log('--------------------');
|
|
101
|
+
console.log(`Trading Account: ${client.address}`);
|
|
102
|
+
console.log(`Signing Wallet: ${client.walletAddress}`);
|
|
103
|
+
console.log(`Wallet Type: ${client.isApiWallet ? 'API Wallet' : 'Main Wallet'}`);
|
|
104
|
+
}
|
|
93
105
|
|
|
94
106
|
const modeLabel: Record<string, string> = {
|
|
95
107
|
standard: 'Standard (separate balances per dex)',
|
|
@@ -99,22 +111,24 @@ async function main() {
|
|
|
99
111
|
};
|
|
100
112
|
console.log(`Account Mode: ${modeLabel[accountMode] ?? accountMode}`);
|
|
101
113
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
114
|
+
if (!isOtherAccount) {
|
|
115
|
+
// Check builder fee approval
|
|
116
|
+
const builderApproval = await client.getMaxBuilderFee();
|
|
117
|
+
console.log(`Builder Address: ${client.builderAddress}`);
|
|
118
|
+
console.log(`Builder Fee: ${client.builderFeeBps} bps`);
|
|
119
|
+
if (builderApproval) {
|
|
120
|
+
console.log(`Builder Approved: ✅ Yes (max: ${builderApproval})`);
|
|
121
|
+
} else {
|
|
122
|
+
console.log(`Builder Approved: ❌ No`);
|
|
123
|
+
console.log(`\n⚠️ Run: npx tsx scripts/setup/approve-builder.ts`);
|
|
124
|
+
}
|
|
112
125
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
126
|
+
// Warn if API wallet setup looks misconfigured
|
|
127
|
+
if (!client.isApiWallet && accountValue === 0 && positions.length === 0) {
|
|
128
|
+
console.log('\n⚠️ No positions and $0 equity.');
|
|
129
|
+
console.log(' If this account is traded via an API wallet, set HYPERLIQUID_ACCOUNT_ADDRESS');
|
|
130
|
+
console.log(' in ~/.openbroker/.env to the master account address (the wallet that holds funds).');
|
|
131
|
+
}
|
|
118
132
|
}
|
|
119
133
|
console.log('');
|
|
120
134
|
|
|
@@ -157,7 +171,7 @@ async function main() {
|
|
|
157
171
|
console.log('\nOpen Orders');
|
|
158
172
|
console.log('-----------');
|
|
159
173
|
|
|
160
|
-
const orders = await client.getOpenOrders();
|
|
174
|
+
const orders = await client.getOpenOrders(isOtherAccount ? lookupAddress : undefined);
|
|
161
175
|
if (orders.length === 0) {
|
|
162
176
|
console.log('No open orders');
|
|
163
177
|
} else {
|
package/scripts/info/fees.ts
CHANGED
|
@@ -24,13 +24,19 @@ async function main() {
|
|
|
24
24
|
process.exit(0);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
const targetAddress = args.address as string | undefined;
|
|
27
28
|
const client = getClient();
|
|
29
|
+
const lookupAddress = targetAddress?.toLowerCase();
|
|
28
30
|
|
|
29
31
|
console.log('Open Broker - Fee Schedule');
|
|
30
32
|
console.log('=========================\n');
|
|
31
33
|
|
|
34
|
+
if (targetAddress) {
|
|
35
|
+
console.log(`Lookup: ${lookupAddress}\n`);
|
|
36
|
+
}
|
|
37
|
+
|
|
32
38
|
try {
|
|
33
|
-
const fees = await client.getUserFees();
|
|
39
|
+
const fees = await client.getUserFees(lookupAddress);
|
|
34
40
|
|
|
35
41
|
// Fee rates
|
|
36
42
|
console.log('Fee Rates');
|
package/scripts/info/fills.ts
CHANGED
|
@@ -9,15 +9,17 @@ function printUsage() {
|
|
|
9
9
|
Usage: openbroker fills [options]
|
|
10
10
|
|
|
11
11
|
Options:
|
|
12
|
-
--coin <symbol>
|
|
13
|
-
--side <buy|sell>
|
|
14
|
-
--top <n>
|
|
15
|
-
--
|
|
12
|
+
--coin <symbol> Filter by coin (e.g. ETH, BTC)
|
|
13
|
+
--side <buy|sell> Filter by side
|
|
14
|
+
--top <n> Show last N fills (default: 20)
|
|
15
|
+
--address <0x...> Look up another account's fills
|
|
16
|
+
--help, -h Show this help
|
|
16
17
|
|
|
17
18
|
Examples:
|
|
18
19
|
openbroker fills
|
|
19
20
|
openbroker fills --coin ETH
|
|
20
21
|
openbroker fills --coin BTC --side buy --top 50
|
|
22
|
+
openbroker fills --address 0xabc... --coin ETH
|
|
21
23
|
`);
|
|
22
24
|
}
|
|
23
25
|
|
|
@@ -33,10 +35,13 @@ async function main() {
|
|
|
33
35
|
const filterSide = args.side as string | undefined;
|
|
34
36
|
const top = parseInt(args.top as string) || 20;
|
|
35
37
|
const jsonOutput = args.json as boolean;
|
|
38
|
+
const targetAddress = args.address as string | undefined;
|
|
36
39
|
const client = getClient();
|
|
37
40
|
|
|
41
|
+
const lookupAddress = targetAddress?.toLowerCase();
|
|
42
|
+
|
|
38
43
|
try {
|
|
39
|
-
let fills = await client.getUserFills();
|
|
44
|
+
let fills = await client.getUserFills(lookupAddress);
|
|
40
45
|
|
|
41
46
|
if (filterCoin) {
|
|
42
47
|
fills = fills.filter(f => f.coin === normalizeCoin(filterCoin));
|
|
@@ -66,6 +71,10 @@ async function main() {
|
|
|
66
71
|
console.log('Open Broker - Trade Fills');
|
|
67
72
|
console.log('========================\n');
|
|
68
73
|
|
|
74
|
+
if (targetAddress) {
|
|
75
|
+
console.log(`Lookup: ${lookupAddress}\n`);
|
|
76
|
+
}
|
|
77
|
+
|
|
69
78
|
if (fills.length === 0) {
|
|
70
79
|
console.log('No fills found');
|
|
71
80
|
return;
|
|
@@ -9,12 +9,14 @@ function printUsage() {
|
|
|
9
9
|
Usage: openbroker order-status --oid <order-id>
|
|
10
10
|
|
|
11
11
|
Options:
|
|
12
|
-
--oid <id>
|
|
13
|
-
--
|
|
12
|
+
--oid <id> Order ID (number) or client order ID (hex string) — required
|
|
13
|
+
--address <0x...> Look up order on another account
|
|
14
|
+
--help, -h Show this help
|
|
14
15
|
|
|
15
16
|
Examples:
|
|
16
17
|
openbroker order-status --oid 123456789
|
|
17
18
|
openbroker order-status --oid 0x1234abcd...
|
|
19
|
+
openbroker order-status --oid 123456789 --address 0xabc...
|
|
18
20
|
`);
|
|
19
21
|
}
|
|
20
22
|
|
|
@@ -34,13 +36,15 @@ async function main() {
|
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
const oid = oidArg.startsWith('0x') ? oidArg : parseInt(oidArg);
|
|
39
|
+
const targetAddress = args.address as string | undefined;
|
|
37
40
|
const client = getClient();
|
|
41
|
+
const lookupAddress = targetAddress?.toLowerCase();
|
|
38
42
|
|
|
39
43
|
console.log('Open Broker - Order Status');
|
|
40
44
|
console.log('=========================\n');
|
|
41
45
|
|
|
42
46
|
try {
|
|
43
|
-
const result = await client.getOrderStatus(oid);
|
|
47
|
+
const result = await client.getOrderStatus(oid, lookupAddress);
|
|
44
48
|
|
|
45
49
|
if (result.status === 'unknownOid') {
|
|
46
50
|
console.log(`Order ${oidArg} not found`);
|
package/scripts/info/orders.ts
CHANGED
|
@@ -13,6 +13,7 @@ Options:
|
|
|
13
13
|
--status <status> Filter by status (filled, canceled, open, triggered, rejected, etc.)
|
|
14
14
|
--open Show only currently open orders
|
|
15
15
|
--top <n> Show last N orders (default: 20)
|
|
16
|
+
--address <0x...> Look up another account's orders
|
|
16
17
|
--help, -h Show this help
|
|
17
18
|
|
|
18
19
|
Examples:
|
|
@@ -21,6 +22,7 @@ Examples:
|
|
|
21
22
|
openbroker orders --open --coin ETH
|
|
22
23
|
openbroker orders --coin ETH --status filled
|
|
23
24
|
openbroker orders --top 50
|
|
25
|
+
openbroker orders --address 0xabc... --open
|
|
24
26
|
`);
|
|
25
27
|
}
|
|
26
28
|
|
|
@@ -37,12 +39,15 @@ async function main() {
|
|
|
37
39
|
const openOnly = args.open as boolean;
|
|
38
40
|
const top = parseInt(args.top as string) || 20;
|
|
39
41
|
const jsonOutput = args.json as boolean;
|
|
42
|
+
const targetAddress = args.address as string | undefined;
|
|
40
43
|
const client = getClient();
|
|
41
44
|
|
|
45
|
+
const lookupAddress = targetAddress?.toLowerCase();
|
|
46
|
+
|
|
42
47
|
try {
|
|
43
48
|
if (openOnly) {
|
|
44
49
|
// Use the dedicated open orders endpoint
|
|
45
|
-
let openOrders = await client.getOpenOrders();
|
|
50
|
+
let openOrders = await client.getOpenOrders(lookupAddress);
|
|
46
51
|
|
|
47
52
|
if (filterCoin) {
|
|
48
53
|
openOrders = openOrders.filter(o => o.coin === normalizeCoin(filterCoin));
|
|
@@ -69,6 +74,10 @@ async function main() {
|
|
|
69
74
|
console.log('Open Broker - Open Orders');
|
|
70
75
|
console.log('=========================\n');
|
|
71
76
|
|
|
77
|
+
if (targetAddress) {
|
|
78
|
+
console.log(`Lookup: ${lookupAddress}\n`);
|
|
79
|
+
}
|
|
80
|
+
|
|
72
81
|
if (openOrders.length === 0) {
|
|
73
82
|
console.log('No open orders found');
|
|
74
83
|
return;
|
|
@@ -106,7 +115,7 @@ async function main() {
|
|
|
106
115
|
return;
|
|
107
116
|
}
|
|
108
117
|
|
|
109
|
-
let orders = await client.getHistoricalOrders();
|
|
118
|
+
let orders = await client.getHistoricalOrders(lookupAddress);
|
|
110
119
|
|
|
111
120
|
if (filterCoin) {
|
|
112
121
|
orders = orders.filter(o => o.order.coin === normalizeCoin(filterCoin));
|
|
@@ -137,6 +146,10 @@ async function main() {
|
|
|
137
146
|
console.log('Open Broker - Order History');
|
|
138
147
|
console.log('==========================\n');
|
|
139
148
|
|
|
149
|
+
if (targetAddress) {
|
|
150
|
+
console.log(`Lookup: ${lookupAddress}\n`);
|
|
151
|
+
}
|
|
152
|
+
|
|
140
153
|
if (orders.length === 0) {
|
|
141
154
|
console.log('No orders found');
|
|
142
155
|
return;
|
|
@@ -8,17 +8,21 @@ async function main() {
|
|
|
8
8
|
const args = parseArgs(process.argv.slice(2));
|
|
9
9
|
const filterCoin = args.coin as string | undefined;
|
|
10
10
|
const jsonOutput = args.json as boolean;
|
|
11
|
+
const targetAddress = args.address as string | undefined;
|
|
11
12
|
const client = getClient();
|
|
12
13
|
|
|
13
14
|
if (args.verbose) {
|
|
14
15
|
client.verbose = true;
|
|
15
16
|
}
|
|
16
17
|
|
|
18
|
+
const lookupAddress = targetAddress?.toLowerCase();
|
|
19
|
+
const isOtherAccount = !!targetAddress;
|
|
20
|
+
|
|
17
21
|
try {
|
|
18
22
|
const [state, mids, fundingHistory] = await Promise.all([
|
|
19
|
-
client.getUserStateAll(),
|
|
23
|
+
client.getUserStateAll(lookupAddress),
|
|
20
24
|
client.getAllMids(),
|
|
21
|
-
client.getUserFunding(),
|
|
25
|
+
client.getUserFunding(lookupAddress),
|
|
22
26
|
]);
|
|
23
27
|
|
|
24
28
|
const positions = state.assetPositions.filter(ap => {
|
|
@@ -69,9 +73,13 @@ async function main() {
|
|
|
69
73
|
console.log('Open Broker - Positions');
|
|
70
74
|
console.log('=======================\n');
|
|
71
75
|
|
|
76
|
+
if (isOtherAccount) {
|
|
77
|
+
console.log(`Lookup: ${lookupAddress}\n`);
|
|
78
|
+
}
|
|
79
|
+
|
|
72
80
|
if (positions.length === 0) {
|
|
73
81
|
console.log(filterCoin ? `No position in ${filterCoin}` : 'No open positions');
|
|
74
|
-
if (!filterCoin && !client.isApiWallet) {
|
|
82
|
+
if (!filterCoin && !isOtherAccount && !client.isApiWallet) {
|
|
75
83
|
console.log('\n⚠️ If this account is traded via an API wallet, set HYPERLIQUID_ACCOUNT_ADDRESS');
|
|
76
84
|
console.log(' in ~/.openbroker/.env to the master account address.');
|
|
77
85
|
}
|
package/scripts/info/spot.ts
CHANGED
|
@@ -8,6 +8,7 @@ interface Args {
|
|
|
8
8
|
balances?: boolean;
|
|
9
9
|
top?: number;
|
|
10
10
|
verbose?: boolean;
|
|
11
|
+
address?: string;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
function parseArgs(): Args {
|
|
@@ -21,6 +22,8 @@ function parseArgs(): Args {
|
|
|
21
22
|
args.balances = true;
|
|
22
23
|
} else if (arg === '--top' && process.argv[i + 1]) {
|
|
23
24
|
args.top = parseInt(process.argv[++i], 10);
|
|
25
|
+
} else if (arg === '--address' && process.argv[i + 1]) {
|
|
26
|
+
args.address = process.argv[++i].toLowerCase();
|
|
24
27
|
} else if (arg === '--verbose') {
|
|
25
28
|
args.verbose = true;
|
|
26
29
|
} else if (arg === '--help' || arg === '-h') {
|
|
@@ -30,11 +33,12 @@ Spot Markets - View Hyperliquid spot markets and balances
|
|
|
30
33
|
Usage: npx tsx scripts/info/spot.ts [options]
|
|
31
34
|
|
|
32
35
|
Options:
|
|
33
|
-
--coin <symbol>
|
|
34
|
-
--balances
|
|
35
|
-
--
|
|
36
|
-
--
|
|
37
|
-
--
|
|
36
|
+
--coin <symbol> Filter by coin symbol
|
|
37
|
+
--balances Show your spot token balances
|
|
38
|
+
--address <0x...> Look up another account's spot balances (with --balances)
|
|
39
|
+
--top <n> Show only top N markets by volume
|
|
40
|
+
--verbose Show detailed output
|
|
41
|
+
--help Show this help
|
|
38
42
|
|
|
39
43
|
Examples:
|
|
40
44
|
npx tsx scripts/info/spot.ts # Show all spot markets
|
|
@@ -80,9 +84,10 @@ async function main() {
|
|
|
80
84
|
|
|
81
85
|
// Show balances
|
|
82
86
|
if (args.balances) {
|
|
83
|
-
|
|
87
|
+
const lookupAddress = args.address ?? client.address;
|
|
88
|
+
console.log(`Fetching spot balances for ${lookupAddress}...\n`);
|
|
84
89
|
|
|
85
|
-
const balances = await client.getSpotBalances();
|
|
90
|
+
const balances = await client.getSpotBalances(args.address);
|
|
86
91
|
|
|
87
92
|
if (!balances.balances || balances.balances.length === 0) {
|
|
88
93
|
console.log('No spot token balances found.');
|