openbroker 1.0.72 → 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 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.72", "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)"}]}}
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)
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "openbroker",
3
3
  "name": "OpenBroker — Hyperliquid Trading",
4
- "version": "1.0.72",
4
+ "version": "1.0.73",
5
5
  "description": "Trade on Hyperliquid DEX with background position monitoring",
6
6
  "configSchema": {
7
7
  "type": "object",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openbroker",
3
- "version": "1.0.72",
3
+ "version": "1.0.73",
4
4
  "description": "Hyperliquid trading CLI - execute orders, manage positions, and run trading strategies",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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 accountMode = await client.getAccountMode();
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: client.address,
55
- signingWallet: client.walletAddress,
56
- walletType: client.isApiWallet ? 'api' : 'main',
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
- console.log('Wallet Configuration');
89
- console.log('--------------------');
90
- console.log(`Trading Account: ${client.address}`);
91
- console.log(`Signing Wallet: ${client.walletAddress}`);
92
- console.log(`Wallet Type: ${client.isApiWallet ? 'API Wallet' : 'Main Wallet'}`);
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
- // Check builder fee approval
103
- const builderApproval = await client.getMaxBuilderFee();
104
- console.log(`Builder Address: ${client.builderAddress}`);
105
- console.log(`Builder Fee: ${client.builderFeeBps} bps`);
106
- if (builderApproval) {
107
- console.log(`Builder Approved: ✅ Yes (max: ${builderApproval})`);
108
- } else {
109
- console.log(`Builder Approved: ❌ No`);
110
- console.log(`\n⚠️ Run: npx tsx scripts/setup/approve-builder.ts`);
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
- // Warn if API wallet setup looks misconfigured
114
- if (!client.isApiWallet && accountValue === 0 && positions.length === 0) {
115
- console.log('\n⚠️ No positions and $0 equity.');
116
- console.log(' If this account is traded via an API wallet, set HYPERLIQUID_ACCOUNT_ADDRESS');
117
- console.log(' in ~/.openbroker/.env to the master account address (the wallet that holds funds).');
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 {
@@ -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');
@@ -9,15 +9,17 @@ function printUsage() {
9
9
  Usage: openbroker fills [options]
10
10
 
11
11
  Options:
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
- --help, -h Show this help
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> Order ID (number) or client order ID (hex string) — required
13
- --help, -h Show this help
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`);
@@ -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
  }
@@ -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> Filter by coin symbol
34
- --balances Show your spot token balances
35
- --top <n> Show only top N markets by volume
36
- --verbose Show detailed output
37
- --help Show this help
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
- console.log(`Fetching spot balances for ${client.address}...\n`);
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.');