openbroker 1.3.1 → 1.4.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/CHANGELOG.md +12 -0
- package/SKILL.md +7 -4
- package/dist/auto/audit.d.ts +57 -0
- package/dist/auto/audit.d.ts.map +1 -0
- package/dist/auto/audit.js +407 -0
- package/dist/auto/cli.d.ts +2 -0
- package/dist/auto/cli.d.ts.map +1 -0
- package/dist/auto/cli.js +423 -0
- package/dist/auto/events.d.ts +11 -0
- package/dist/auto/events.d.ts.map +1 -0
- package/dist/auto/events.js +36 -0
- package/dist/auto/examples/dca.d.ts +4 -0
- package/dist/auto/examples/dca.d.ts.map +1 -0
- package/dist/auto/examples/dca.js +60 -0
- package/dist/auto/examples/funding-arb.d.ts +4 -0
- package/dist/auto/examples/funding-arb.d.ts.map +1 -0
- package/dist/auto/examples/funding-arb.js +81 -0
- package/dist/auto/examples/grid.d.ts +4 -0
- package/dist/auto/examples/grid.d.ts.map +1 -0
- package/dist/auto/examples/grid.js +114 -0
- package/dist/auto/examples/mm-maker.d.ts +4 -0
- package/dist/auto/examples/mm-maker.d.ts.map +1 -0
- package/dist/auto/examples/mm-maker.js +131 -0
- package/dist/auto/examples/mm-spread.d.ts +4 -0
- package/dist/auto/examples/mm-spread.d.ts.map +1 -0
- package/dist/auto/examples/mm-spread.js +119 -0
- package/dist/auto/examples/price-alert.d.ts +4 -0
- package/dist/auto/examples/price-alert.d.ts.map +1 -0
- package/dist/auto/examples/price-alert.js +85 -0
- package/dist/auto/keep-awake.d.ts +11 -0
- package/dist/auto/keep-awake.d.ts.map +1 -0
- package/dist/auto/keep-awake.js +70 -0
- package/dist/auto/loader.d.ts +22 -0
- package/dist/auto/loader.d.ts.map +1 -0
- package/dist/auto/loader.js +127 -0
- package/dist/auto/prune.d.ts +40 -0
- package/dist/auto/prune.d.ts.map +1 -0
- package/dist/auto/prune.js +204 -0
- package/dist/auto/registry.d.ts +24 -0
- package/dist/auto/registry.d.ts.map +1 -0
- package/dist/auto/registry.js +93 -0
- package/dist/auto/report.d.ts +3 -0
- package/dist/auto/report.d.ts.map +1 -0
- package/dist/auto/report.js +385 -0
- package/dist/auto/runtime.d.ts +33 -0
- package/dist/auto/runtime.d.ts.map +1 -0
- package/dist/auto/runtime.js +844 -0
- package/dist/auto/types.d.ts +236 -0
- package/dist/auto/types.d.ts.map +1 -0
- package/dist/auto/types.js +3 -0
- package/dist/core/client.d.ts +684 -0
- package/dist/core/client.d.ts.map +1 -0
- package/dist/core/client.js +2040 -0
- package/dist/core/config.d.ts +22 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +143 -0
- package/dist/core/types.d.ts +221 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/utils.d.ts +61 -0
- package/dist/core/utils.d.ts.map +1 -0
- package/dist/core/utils.js +142 -0
- package/dist/core/ws.d.ts +121 -0
- package/dist/core/ws.d.ts.map +1 -0
- package/dist/core/ws.js +222 -0
- package/dist/info/account.d.ts +3 -0
- package/dist/info/account.d.ts.map +1 -0
- package/dist/info/account.js +198 -0
- package/dist/info/all-markets.d.ts +3 -0
- package/dist/info/all-markets.d.ts.map +1 -0
- package/dist/info/all-markets.js +272 -0
- package/dist/info/candles.d.ts +3 -0
- package/dist/info/candles.d.ts.map +1 -0
- package/dist/info/candles.js +120 -0
- package/dist/info/fees.d.ts +3 -0
- package/dist/info/fees.d.ts.map +1 -0
- package/dist/info/fees.js +87 -0
- package/dist/info/fills.d.ts +3 -0
- package/dist/info/fills.d.ts.map +1 -0
- package/dist/info/fills.js +105 -0
- package/dist/info/funding-history.d.ts +3 -0
- package/dist/info/funding-history.d.ts.map +1 -0
- package/dist/info/funding-history.js +98 -0
- package/dist/info/funding-scan.d.ts +3 -0
- package/dist/info/funding-scan.d.ts.map +1 -0
- package/dist/info/funding-scan.js +178 -0
- package/dist/info/funding.d.ts +3 -0
- package/dist/info/funding.d.ts.map +1 -0
- package/dist/info/funding.js +158 -0
- package/dist/info/markets.d.ts +3 -0
- package/dist/info/markets.d.ts.map +1 -0
- package/dist/info/markets.js +178 -0
- package/dist/info/order-status.d.ts +3 -0
- package/dist/info/order-status.d.ts.map +1 -0
- package/dist/info/order-status.js +85 -0
- package/dist/info/orders.d.ts +3 -0
- package/dist/info/orders.d.ts.map +1 -0
- package/dist/info/orders.js +162 -0
- package/dist/info/outcomes.d.ts +3 -0
- package/dist/info/outcomes.d.ts.map +1 -0
- package/dist/info/outcomes.js +175 -0
- package/dist/info/positions.d.ts +3 -0
- package/dist/info/positions.d.ts.map +1 -0
- package/dist/info/positions.js +127 -0
- package/dist/info/rate-limit.d.ts +3 -0
- package/dist/info/rate-limit.d.ts.map +1 -0
- package/dist/info/rate-limit.js +58 -0
- package/dist/info/search-markets.d.ts +3 -0
- package/dist/info/search-markets.d.ts.map +1 -0
- package/dist/info/search-markets.js +296 -0
- package/dist/info/spot.d.ts +3 -0
- package/dist/info/spot.d.ts.map +1 -0
- package/dist/info/spot.js +192 -0
- package/dist/info/trades.d.ts +3 -0
- package/dist/info/trades.d.ts.map +1 -0
- package/dist/info/trades.js +97 -0
- package/dist/lib.d.ts +14 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +17 -0
- package/dist/operations/bracket.d.ts +28 -0
- package/dist/operations/bracket.d.ts.map +1 -0
- package/dist/operations/bracket.js +266 -0
- package/dist/operations/cancel.d.ts +3 -0
- package/dist/operations/cancel.d.ts.map +1 -0
- package/dist/operations/cancel.js +107 -0
- package/dist/operations/chase.d.ts +25 -0
- package/dist/operations/chase.d.ts.map +1 -0
- package/dist/operations/chase.js +215 -0
- package/dist/operations/limit-order.d.ts +3 -0
- package/dist/operations/limit-order.d.ts.map +1 -0
- package/dist/operations/limit-order.js +144 -0
- package/dist/operations/market-order.d.ts +3 -0
- package/dist/operations/market-order.d.ts.map +1 -0
- package/dist/operations/market-order.js +153 -0
- package/dist/operations/outcome-order.d.ts +3 -0
- package/dist/operations/outcome-order.d.ts.map +1 -0
- package/dist/operations/outcome-order.js +171 -0
- package/dist/operations/scale.d.ts +3 -0
- package/dist/operations/scale.d.ts.map +1 -0
- package/dist/operations/scale.js +212 -0
- package/dist/operations/set-tpsl.d.ts +3 -0
- package/dist/operations/set-tpsl.d.ts.map +1 -0
- package/dist/operations/set-tpsl.js +277 -0
- package/dist/operations/spot-order.d.ts +3 -0
- package/dist/operations/spot-order.d.ts.map +1 -0
- package/dist/operations/spot-order.js +173 -0
- package/dist/operations/trigger-order.d.ts +3 -0
- package/dist/operations/trigger-order.d.ts.map +1 -0
- package/dist/operations/trigger-order.js +177 -0
- package/dist/operations/twap-cancel.d.ts +3 -0
- package/dist/operations/twap-cancel.d.ts.map +1 -0
- package/dist/operations/twap-cancel.js +57 -0
- package/dist/operations/twap-status.d.ts +3 -0
- package/dist/operations/twap-status.d.ts.map +1 -0
- package/dist/operations/twap-status.js +81 -0
- package/dist/operations/twap.d.ts +3 -0
- package/dist/operations/twap.d.ts.map +1 -0
- package/dist/operations/twap.js +124 -0
- package/dist/setup/approve-builder.d.ts +3 -0
- package/dist/setup/approve-builder.d.ts.map +1 -0
- package/dist/setup/approve-builder.js +155 -0
- package/dist/setup/env.d.ts +4 -0
- package/dist/setup/env.d.ts.map +1 -0
- package/dist/setup/env.js +8 -0
- package/dist/setup/onboard.d.ts +10 -0
- package/dist/setup/onboard.d.ts.map +1 -0
- package/dist/setup/onboard.js +462 -0
- package/package.json +10 -4
- package/scripts/core/client.ts +13 -3
- package/scripts/info/all-markets.ts +18 -2
- package/scripts/info/search-markets.ts +18 -2
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
// Search Markets - Find specific assets across all providers (perps, HIP-3, spot, HIP-4)
|
|
3
|
+
import { getClient } from '../core/client.js';
|
|
4
|
+
function parseArgs() {
|
|
5
|
+
const args = { query: '', type: 'all' };
|
|
6
|
+
for (let i = 2; i < process.argv.length; i++) {
|
|
7
|
+
const arg = process.argv[i];
|
|
8
|
+
if (arg === '--query' && process.argv[i + 1]) {
|
|
9
|
+
args.query = process.argv[++i];
|
|
10
|
+
}
|
|
11
|
+
else if (arg === '--type' && process.argv[i + 1]) {
|
|
12
|
+
const val = process.argv[++i].toLowerCase();
|
|
13
|
+
if (['perp', 'spot', 'hip3', 'outcome', 'all'].includes(val)) {
|
|
14
|
+
args.type = val;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
else if (arg === '--verbose') {
|
|
18
|
+
args.verbose = true;
|
|
19
|
+
}
|
|
20
|
+
else if (arg === '--json') {
|
|
21
|
+
args.json = true;
|
|
22
|
+
}
|
|
23
|
+
else if (arg === '--help' || arg === '-h') {
|
|
24
|
+
console.log(`
|
|
25
|
+
Search Markets - Find assets across all Hyperliquid markets
|
|
26
|
+
|
|
27
|
+
Usage: npx tsx scripts/info/search-markets.ts --query <search> [options]
|
|
28
|
+
|
|
29
|
+
Options:
|
|
30
|
+
--query <search> Search term (required) - matches coin name
|
|
31
|
+
--type <type> Filter by market type: perp, spot, hip3, outcome, or all (default: all)
|
|
32
|
+
--json Output as JSON (machine-readable)
|
|
33
|
+
--verbose Show detailed output
|
|
34
|
+
--help Show this help
|
|
35
|
+
|
|
36
|
+
Examples:
|
|
37
|
+
npx tsx scripts/info/search-markets.ts --query GOLD # Find all GOLD markets
|
|
38
|
+
npx tsx scripts/info/search-markets.ts --query BTC # Find all BTC markets
|
|
39
|
+
npx tsx scripts/info/search-markets.ts --query ETH --type perp # ETH perps only
|
|
40
|
+
npx tsx scripts/info/search-markets.ts --query PURR --type spot # PURR spot only
|
|
41
|
+
npx tsx scripts/info/search-markets.ts --query BTC --type outcome # HIP-4 outcomes only
|
|
42
|
+
npx tsx scripts/info/search-markets.ts --query HYPE --json # JSON output
|
|
43
|
+
`);
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
else if (!args.query && !arg.startsWith('-')) {
|
|
47
|
+
// Allow query as positional arg
|
|
48
|
+
args.query = arg;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (!args.query) {
|
|
52
|
+
console.error('Error: --query is required');
|
|
53
|
+
console.log('Usage: npx tsx scripts/info/search-markets.ts --query <search>');
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
return args;
|
|
57
|
+
}
|
|
58
|
+
function formatVolume(vol) {
|
|
59
|
+
if (vol >= 1_000_000_000)
|
|
60
|
+
return `$${(vol / 1_000_000_000).toFixed(2)}B`;
|
|
61
|
+
if (vol >= 1_000_000)
|
|
62
|
+
return `$${(vol / 1_000_000).toFixed(2)}M`;
|
|
63
|
+
if (vol >= 1_000)
|
|
64
|
+
return `$${(vol / 1_000).toFixed(2)}K`;
|
|
65
|
+
return `$${vol.toFixed(2)}`;
|
|
66
|
+
}
|
|
67
|
+
function formatPrice(price) {
|
|
68
|
+
const p = typeof price === 'string' ? parseFloat(price) : price;
|
|
69
|
+
if (p >= 1000)
|
|
70
|
+
return p.toFixed(2);
|
|
71
|
+
if (p >= 1)
|
|
72
|
+
return p.toFixed(4);
|
|
73
|
+
if (p >= 0.01)
|
|
74
|
+
return p.toFixed(6);
|
|
75
|
+
return p.toFixed(8);
|
|
76
|
+
}
|
|
77
|
+
function formatFunding(rate) {
|
|
78
|
+
const r = parseFloat(rate);
|
|
79
|
+
const annualized = r * 24 * 365 * 100;
|
|
80
|
+
const sign = annualized >= 0 ? '+' : '';
|
|
81
|
+
return `${sign}${annualized.toFixed(2)}%`;
|
|
82
|
+
}
|
|
83
|
+
function handleMarketFetchError(kind, error, requestedType, verbose) {
|
|
84
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
85
|
+
if (requestedType === kind) {
|
|
86
|
+
throw new Error(`Failed to fetch ${kind} markets: ${message}`);
|
|
87
|
+
}
|
|
88
|
+
if (verbose) {
|
|
89
|
+
console.error(`Failed to fetch ${kind} markets:`, error);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async function main() {
|
|
93
|
+
const args = parseArgs();
|
|
94
|
+
const client = getClient();
|
|
95
|
+
client.verbose = args.verbose ?? false;
|
|
96
|
+
const query = args.query.toUpperCase();
|
|
97
|
+
if (!args.json) {
|
|
98
|
+
console.log(`Searching for "${query}" across all markets...\n`);
|
|
99
|
+
}
|
|
100
|
+
const results = [];
|
|
101
|
+
// Search main perps
|
|
102
|
+
if (args.type === 'all' || args.type === 'perp') {
|
|
103
|
+
const meta = await client.getMetaAndAssetCtxs();
|
|
104
|
+
for (let i = 0; i < meta.meta.universe.length; i++) {
|
|
105
|
+
const asset = meta.meta.universe[i];
|
|
106
|
+
const ctx = meta.assetCtxs[i];
|
|
107
|
+
if (asset.name.toUpperCase().includes(query)) {
|
|
108
|
+
results.push({
|
|
109
|
+
type: 'perp',
|
|
110
|
+
provider: 'Hyperliquid',
|
|
111
|
+
coin: asset.name,
|
|
112
|
+
assetId: i,
|
|
113
|
+
price: ctx.markPx,
|
|
114
|
+
volume24h: parseFloat(ctx.dayNtlVlm),
|
|
115
|
+
funding: ctx.funding,
|
|
116
|
+
maxLeverage: asset.maxLeverage,
|
|
117
|
+
openInterest: ctx.openInterest,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Search HIP-3 perps
|
|
123
|
+
if (args.type === 'all' || args.type === 'hip3') {
|
|
124
|
+
if (client.isTestnet) {
|
|
125
|
+
// On testnet, load specific dex if query is "dex:COIN" format
|
|
126
|
+
if (args.query.includes(':')) {
|
|
127
|
+
await client.loadSingleHip3Dex(args.query.split(':')[0]);
|
|
128
|
+
}
|
|
129
|
+
else if (!args.json) {
|
|
130
|
+
console.log(' (Testnet: HIP-3 dexes not auto-loaded. Use "dexName:COIN" to search a specific dex.)\n');
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
const allPerpMetas = await client.getAllPerpMetas();
|
|
135
|
+
// Skip index 0 (main dex), process HIP-3 dexs
|
|
136
|
+
for (let dexIdx = 1; dexIdx < allPerpMetas.length; dexIdx++) {
|
|
137
|
+
const dexData = allPerpMetas[dexIdx];
|
|
138
|
+
if (!dexData || !dexData.meta?.universe)
|
|
139
|
+
continue;
|
|
140
|
+
for (let i = 0; i < dexData.meta.universe.length; i++) {
|
|
141
|
+
const asset = dexData.meta.universe[i];
|
|
142
|
+
const ctx = dexData.assetCtxs[i];
|
|
143
|
+
if (!asset || !ctx)
|
|
144
|
+
continue;
|
|
145
|
+
if (asset.name.toUpperCase().includes(query)) {
|
|
146
|
+
let assetId = -1;
|
|
147
|
+
try {
|
|
148
|
+
assetId = client.getAssetIndex(asset.name);
|
|
149
|
+
}
|
|
150
|
+
catch { /* not registered */ }
|
|
151
|
+
results.push({
|
|
152
|
+
type: 'hip3',
|
|
153
|
+
provider: dexData.dexName || `HIP-3 DEX ${dexIdx}`,
|
|
154
|
+
coin: asset.name,
|
|
155
|
+
assetId,
|
|
156
|
+
price: ctx.markPx,
|
|
157
|
+
volume24h: parseFloat(ctx.dayNtlVlm || '0'),
|
|
158
|
+
funding: ctx.funding,
|
|
159
|
+
maxLeverage: asset.maxLeverage,
|
|
160
|
+
openInterest: ctx.openInterest,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
if (args.verbose)
|
|
168
|
+
console.error('Failed to fetch HIP-3 markets:', e);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// Search spot markets
|
|
172
|
+
if (args.type === 'all' || args.type === 'spot') {
|
|
173
|
+
try {
|
|
174
|
+
const spotData = await client.getSpotMetaAndAssetCtxs();
|
|
175
|
+
// Build token index → name lookup for matching by base token name
|
|
176
|
+
const tokenNameMap = new Map();
|
|
177
|
+
for (const token of spotData.meta.tokens) {
|
|
178
|
+
tokenNameMap.set(token.index, token.name);
|
|
179
|
+
}
|
|
180
|
+
// Build ctx map by coin name (contexts have a 'coin' field that matches pair.name).
|
|
181
|
+
// The contexts array can be longer than universe and is NOT aligned by index.
|
|
182
|
+
const ctxMap = new Map();
|
|
183
|
+
for (const ctx of spotData.assetCtxs) {
|
|
184
|
+
if (ctx.coin) {
|
|
185
|
+
ctxMap.set(ctx.coin, ctx);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
for (const pair of spotData.meta.universe) {
|
|
189
|
+
if (!pair)
|
|
190
|
+
continue;
|
|
191
|
+
const ctx = ctxMap.get(pair.name);
|
|
192
|
+
if (!ctx)
|
|
193
|
+
continue;
|
|
194
|
+
// Match against pair name, base token name, and quote token name
|
|
195
|
+
const baseTokenName = tokenNameMap.get(pair.tokens[0]) ?? '';
|
|
196
|
+
const quoteTokenName = tokenNameMap.get(pair.tokens[1]) ?? '';
|
|
197
|
+
const searchable = `${pair.name} ${baseTokenName} ${quoteTokenName}`.toUpperCase();
|
|
198
|
+
if (searchable.includes(query)) {
|
|
199
|
+
const displayName = baseTokenName && quoteTokenName
|
|
200
|
+
? `${baseTokenName}/${quoteTokenName}`
|
|
201
|
+
: pair.name;
|
|
202
|
+
results.push({
|
|
203
|
+
type: 'spot',
|
|
204
|
+
provider: 'Spot',
|
|
205
|
+
coin: displayName,
|
|
206
|
+
assetId: 10000 + pair.index,
|
|
207
|
+
price: ctx.markPx,
|
|
208
|
+
volume24h: parseFloat(ctx.dayNtlVlm || '0'),
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch (e) {
|
|
214
|
+
if (args.verbose)
|
|
215
|
+
console.error('Failed to fetch spot markets:', e);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Search HIP-4 outcome markets
|
|
219
|
+
if (args.type === 'all' || args.type === 'outcome') {
|
|
220
|
+
try {
|
|
221
|
+
const outcomes = await client.getOutcomeMarkets();
|
|
222
|
+
for (const market of outcomes) {
|
|
223
|
+
const parsed = Object.values(market.parsedDescription).join(' ');
|
|
224
|
+
const searchable = `${market.name} ${market.description} ${parsed}`.toUpperCase();
|
|
225
|
+
if (!searchable.includes(query))
|
|
226
|
+
continue;
|
|
227
|
+
for (const side of market.sides) {
|
|
228
|
+
results.push({
|
|
229
|
+
type: 'outcome',
|
|
230
|
+
provider: 'HIP-4',
|
|
231
|
+
coin: side.coin,
|
|
232
|
+
assetId: side.assetId,
|
|
233
|
+
price: side.midPx ?? side.markPx ?? '0',
|
|
234
|
+
volume24h: parseFloat(side.dayNtlVlm || '0'),
|
|
235
|
+
outcome: market.outcome,
|
|
236
|
+
outcomeSide: side.name,
|
|
237
|
+
outcomeName: market.name,
|
|
238
|
+
tokenName: side.tokenName,
|
|
239
|
+
parsedDescription: market.parsedDescription,
|
|
240
|
+
description: market.description,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch (e) {
|
|
246
|
+
handleMarketFetchError('outcome', e, args.type, args.verbose);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// Sort by volume
|
|
250
|
+
results.sort((a, b) => b.volume24h - a.volume24h);
|
|
251
|
+
if (args.json) {
|
|
252
|
+
console.log(JSON.stringify(results, null, 2));
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (results.length === 0) {
|
|
256
|
+
console.log(`No markets found matching "${query}"`);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
console.log(`Found ${results.length} market(s) matching "${query}":\n`);
|
|
260
|
+
console.log('Type Provider Coin AssetID Price 24h Volume Funding (Ann.) OI');
|
|
261
|
+
console.log('-'.repeat(112));
|
|
262
|
+
for (const m of results) {
|
|
263
|
+
const typeStr = m.type === 'hip3' ? 'HIP-3' : m.type === 'outcome' ? 'HIP-4' : m.type.charAt(0).toUpperCase() + m.type.slice(1);
|
|
264
|
+
const oi = m.openInterest ? formatVolume(parseFloat(m.openInterest)) : '-';
|
|
265
|
+
console.log(`${typeStr.padEnd(8)} ${m.provider.padEnd(16)} ${m.coin.padEnd(14)} ${String(m.assetId).padStart(7)} ${formatPrice(m.price).padStart(16)} ${formatVolume(m.volume24h).padStart(13)} ${(m.funding ? formatFunding(m.funding) : '-').padStart(14)} ${oi.padStart(10)}`);
|
|
266
|
+
if (m.type === 'outcome' && args.verbose) {
|
|
267
|
+
console.log(` Outcome ${m.outcome} ${m.outcomeSide}: ${m.description}`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// Show comparison if same asset on multiple providers
|
|
271
|
+
const coinGroups = new Map();
|
|
272
|
+
for (const r of results) {
|
|
273
|
+
// Extract base asset name (strip /USDC, -PERP, etc.)
|
|
274
|
+
const baseCoin = r.coin.replace(/[-\/].*/, '').toUpperCase();
|
|
275
|
+
if (!coinGroups.has(baseCoin)) {
|
|
276
|
+
coinGroups.set(baseCoin, []);
|
|
277
|
+
}
|
|
278
|
+
coinGroups.get(baseCoin).push(r);
|
|
279
|
+
}
|
|
280
|
+
// Show funding comparison for assets with multiple providers
|
|
281
|
+
for (const [coin, markets] of coinGroups) {
|
|
282
|
+
const perpsWithFunding = markets.filter((m) => m.funding && m.type !== 'spot');
|
|
283
|
+
if (perpsWithFunding.length > 1) {
|
|
284
|
+
console.log(`\n=== ${coin} Funding Comparison ===\n`);
|
|
285
|
+
console.log('Provider Coin AssetID Funding (Ann.) Price');
|
|
286
|
+
console.log('-'.repeat(78));
|
|
287
|
+
for (const m of perpsWithFunding.sort((a, b) => parseFloat(b.funding) - parseFloat(a.funding))) {
|
|
288
|
+
console.log(`${m.provider.padEnd(16)} ${m.coin.padEnd(14)} ${String(m.assetId).padStart(7)} ${formatFunding(m.funding).padStart(14)} ${formatPrice(m.price)}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
main().catch((e) => {
|
|
294
|
+
console.error('Error:', e.message);
|
|
295
|
+
process.exit(1);
|
|
296
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spot.d.ts","sourceRoot":"","sources":["../../scripts/info/spot.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
// Spot Markets - View spot markets and balances
|
|
3
|
+
import { getClient } from '../core/client.js';
|
|
4
|
+
function parseArgs() {
|
|
5
|
+
const args = {};
|
|
6
|
+
for (let i = 2; i < process.argv.length; i++) {
|
|
7
|
+
const arg = process.argv[i];
|
|
8
|
+
if (arg === '--coin' && process.argv[i + 1]) {
|
|
9
|
+
args.coin = process.argv[++i].toUpperCase();
|
|
10
|
+
}
|
|
11
|
+
else if (arg === '--balances') {
|
|
12
|
+
args.balances = true;
|
|
13
|
+
}
|
|
14
|
+
else if (arg === '--top' && process.argv[i + 1]) {
|
|
15
|
+
args.top = parseInt(process.argv[++i], 10);
|
|
16
|
+
}
|
|
17
|
+
else if (arg === '--address' && process.argv[i + 1]) {
|
|
18
|
+
args.address = process.argv[++i].toLowerCase();
|
|
19
|
+
}
|
|
20
|
+
else if (arg === '--verbose') {
|
|
21
|
+
args.verbose = true;
|
|
22
|
+
}
|
|
23
|
+
else if (arg === '--json') {
|
|
24
|
+
args.json = true;
|
|
25
|
+
}
|
|
26
|
+
else if (arg === '--help' || arg === '-h') {
|
|
27
|
+
console.log(`
|
|
28
|
+
Spot Markets - View Hyperliquid spot markets and balances
|
|
29
|
+
|
|
30
|
+
Usage: npx tsx scripts/info/spot.ts [options]
|
|
31
|
+
|
|
32
|
+
Options:
|
|
33
|
+
--coin <symbol> Filter by coin symbol
|
|
34
|
+
--balances Show your spot token balances
|
|
35
|
+
--address <0x...> Look up another account's spot balances (with --balances)
|
|
36
|
+
--top <n> Show only top N markets by volume
|
|
37
|
+
--json Output as JSON (machine-readable)
|
|
38
|
+
--verbose Show detailed output
|
|
39
|
+
--help Show this help
|
|
40
|
+
|
|
41
|
+
Examples:
|
|
42
|
+
npx tsx scripts/info/spot.ts # Show all spot markets
|
|
43
|
+
npx tsx scripts/info/spot.ts --coin PURR # Show PURR market info
|
|
44
|
+
npx tsx scripts/info/spot.ts --balances # Show your spot balances
|
|
45
|
+
npx tsx scripts/info/spot.ts --top 20 # Show top 20 by volume
|
|
46
|
+
`);
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return args;
|
|
51
|
+
}
|
|
52
|
+
function formatVolume(vol) {
|
|
53
|
+
if (vol >= 1_000_000_000)
|
|
54
|
+
return `$${(vol / 1_000_000_000).toFixed(2)}B`;
|
|
55
|
+
if (vol >= 1_000_000)
|
|
56
|
+
return `$${(vol / 1_000_000).toFixed(2)}M`;
|
|
57
|
+
if (vol >= 1_000)
|
|
58
|
+
return `$${(vol / 1_000).toFixed(2)}K`;
|
|
59
|
+
return `$${vol.toFixed(2)}`;
|
|
60
|
+
}
|
|
61
|
+
function formatPrice(price) {
|
|
62
|
+
const p = typeof price === 'string' ? parseFloat(price) : price;
|
|
63
|
+
if (p >= 1000)
|
|
64
|
+
return p.toFixed(2);
|
|
65
|
+
if (p >= 1)
|
|
66
|
+
return p.toFixed(4);
|
|
67
|
+
if (p >= 0.01)
|
|
68
|
+
return p.toFixed(6);
|
|
69
|
+
return p.toFixed(8);
|
|
70
|
+
}
|
|
71
|
+
function formatChange(current, prev) {
|
|
72
|
+
const c = parseFloat(current);
|
|
73
|
+
const p = parseFloat(prev);
|
|
74
|
+
if (p === 0)
|
|
75
|
+
return '-';
|
|
76
|
+
const change = ((c - p) / p) * 100;
|
|
77
|
+
const sign = change >= 0 ? '+' : '';
|
|
78
|
+
return `${sign}${change.toFixed(2)}%`;
|
|
79
|
+
}
|
|
80
|
+
async function main() {
|
|
81
|
+
const args = parseArgs();
|
|
82
|
+
const client = getClient();
|
|
83
|
+
client.verbose = args.verbose ?? false;
|
|
84
|
+
// Show balances
|
|
85
|
+
if (args.balances) {
|
|
86
|
+
const lookupAddress = args.address ?? client.address;
|
|
87
|
+
if (!args.json)
|
|
88
|
+
console.log(`Fetching spot balances for ${lookupAddress}...\n`);
|
|
89
|
+
const balances = await client.getSpotBalances(args.address);
|
|
90
|
+
if (args.json) {
|
|
91
|
+
console.log(JSON.stringify(balances.balances ?? [], null, 2));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (!balances.balances || balances.balances.length === 0) {
|
|
95
|
+
console.log('No spot token balances found.');
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
console.log('=== Spot Balances ===\n');
|
|
99
|
+
console.log('Token Total Hold Entry Value');
|
|
100
|
+
console.log('-'.repeat(70));
|
|
101
|
+
for (const b of balances.balances) {
|
|
102
|
+
const total = parseFloat(b.total);
|
|
103
|
+
const hold = parseFloat(b.hold);
|
|
104
|
+
const entry = parseFloat(b.entryNtl);
|
|
105
|
+
if (total === 0)
|
|
106
|
+
continue;
|
|
107
|
+
console.log(`${b.coin.padEnd(14)} ${total.toFixed(6).padStart(18)} ${hold.toFixed(6).padStart(18)} ${formatVolume(entry).padStart(15)}`);
|
|
108
|
+
}
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
// Show markets
|
|
112
|
+
if (!args.json)
|
|
113
|
+
console.log('Fetching spot market data...\n');
|
|
114
|
+
const spotData = await client.getSpotMetaAndAssetCtxs();
|
|
115
|
+
const markets = [];
|
|
116
|
+
// Build ctx map by coin name — the contexts array is NOT aligned with universe by index.
|
|
117
|
+
// Each context has a 'coin' field matching pair.name.
|
|
118
|
+
const ctxMap = new Map();
|
|
119
|
+
for (const ctx of spotData.assetCtxs) {
|
|
120
|
+
if (ctx.coin)
|
|
121
|
+
ctxMap.set(ctx.coin, ctx);
|
|
122
|
+
}
|
|
123
|
+
// Build token name map for filtering by base token name
|
|
124
|
+
const tokenNameMap = new Map();
|
|
125
|
+
for (const token of spotData.meta.tokens) {
|
|
126
|
+
tokenNameMap.set(token.index, token.name);
|
|
127
|
+
}
|
|
128
|
+
for (const pair of spotData.meta.universe) {
|
|
129
|
+
if (!pair)
|
|
130
|
+
continue;
|
|
131
|
+
const ctx = ctxMap.get(pair.name);
|
|
132
|
+
if (!ctx)
|
|
133
|
+
continue;
|
|
134
|
+
// Filter by coin — match pair name or base token name
|
|
135
|
+
if (args.coin) {
|
|
136
|
+
const baseTokenName = tokenNameMap.get(pair.tokens[0]) ?? '';
|
|
137
|
+
const searchable = `${pair.name} ${baseTokenName}`.toUpperCase();
|
|
138
|
+
if (!searchable.includes(args.coin))
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
markets.push({
|
|
142
|
+
name: pair.name,
|
|
143
|
+
index: pair.index,
|
|
144
|
+
assetId: 10000 + pair.index,
|
|
145
|
+
price: ctx.markPx,
|
|
146
|
+
volume24h: parseFloat(ctx.dayNtlVlm || '0'),
|
|
147
|
+
change24h: formatChange(ctx.markPx, ctx.prevDayPx),
|
|
148
|
+
tokens: pair.tokens,
|
|
149
|
+
base: tokenNameMap.get(pair.tokens[0]),
|
|
150
|
+
quote: tokenNameMap.get(pair.tokens[1]),
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// Sort by volume
|
|
154
|
+
markets.sort((a, b) => b.volume24h - a.volume24h);
|
|
155
|
+
// Apply top filter
|
|
156
|
+
const displayMarkets = args.top ? markets.slice(0, args.top) : markets;
|
|
157
|
+
if (args.json) {
|
|
158
|
+
console.log(JSON.stringify(displayMarkets, null, 2));
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (displayMarkets.length === 0) {
|
|
162
|
+
console.log(args.coin ? `No spot markets found for "${args.coin}"` : 'No spot markets found');
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
// Get token info for detailed display
|
|
166
|
+
const tokenMap = new Map();
|
|
167
|
+
for (const token of spotData.meta.tokens) {
|
|
168
|
+
tokenMap.set(token.index, { name: token.name, tokenId: token.tokenId });
|
|
169
|
+
}
|
|
170
|
+
console.log(`=== Spot Markets (${displayMarkets.length} total) ===\n`);
|
|
171
|
+
console.log('Pair AssetID Price 24h Volume 24h Change Base/Quote');
|
|
172
|
+
console.log('-'.repeat(92));
|
|
173
|
+
for (const m of displayMarkets) {
|
|
174
|
+
const baseToken = tokenMap.get(m.tokens[0]);
|
|
175
|
+
const quoteToken = tokenMap.get(m.tokens[1]);
|
|
176
|
+
const pairStr = `${baseToken?.name || '?'}/${quoteToken?.name || '?'}`;
|
|
177
|
+
console.log(`${m.name.padEnd(14)} ${String(m.assetId).padStart(7)} ${formatPrice(m.price).padStart(16)} ${formatVolume(m.volume24h).padStart(13)} ${m.change24h.padStart(11)} ${pairStr}`);
|
|
178
|
+
}
|
|
179
|
+
// Show tokens if verbose
|
|
180
|
+
if (args.verbose) {
|
|
181
|
+
console.log('\n=== Tokens ===\n');
|
|
182
|
+
console.log('Name Token ID Decimals');
|
|
183
|
+
console.log('-'.repeat(50));
|
|
184
|
+
for (const token of spotData.meta.tokens) {
|
|
185
|
+
console.log(`${token.name.padEnd(14)} ${token.tokenId.padEnd(16)} sz=${token.szDecimals}, wei=${token.weiDecimals}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
main().catch((e) => {
|
|
190
|
+
console.error('Error:', e.message);
|
|
191
|
+
process.exit(1);
|
|
192
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trades.d.ts","sourceRoot":"","sources":["../../scripts/info/trades.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env npx tsx
|
|
2
|
+
// View recent trades (tape) for an asset on Hyperliquid
|
|
3
|
+
import { getClient } from '../core/client.js';
|
|
4
|
+
import { formatUsd, parseArgs, normalizeCoin } from '../core/utils.js';
|
|
5
|
+
function printUsage() {
|
|
6
|
+
console.log(`
|
|
7
|
+
Usage: openbroker trades --coin <symbol> [options]
|
|
8
|
+
|
|
9
|
+
Options:
|
|
10
|
+
--coin <symbol> Asset symbol (required, e.g. ETH, BTC)
|
|
11
|
+
--top <n> Show last N trades (default: 30)
|
|
12
|
+
--json Output as JSON (machine-readable)
|
|
13
|
+
--help, -h Show this help
|
|
14
|
+
|
|
15
|
+
Examples:
|
|
16
|
+
openbroker trades --coin ETH
|
|
17
|
+
openbroker trades --coin BTC --top 50
|
|
18
|
+
`);
|
|
19
|
+
}
|
|
20
|
+
async function main() {
|
|
21
|
+
const args = parseArgs(process.argv.slice(2));
|
|
22
|
+
if (args.help || args.h) {
|
|
23
|
+
printUsage();
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
const coin = args.coin;
|
|
27
|
+
if (!coin) {
|
|
28
|
+
console.error('Error: --coin is required');
|
|
29
|
+
printUsage();
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
const top = parseInt(args.top) || 30;
|
|
33
|
+
const jsonOutput = args.json;
|
|
34
|
+
const client = getClient();
|
|
35
|
+
if (!jsonOutput) {
|
|
36
|
+
console.log(`Open Broker - ${normalizeCoin(coin)} Recent Trades`);
|
|
37
|
+
console.log('='.repeat(40) + '\n');
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
// Load metadata (needed for HIP-3 coin resolution)
|
|
41
|
+
await client.getMetaAndAssetCtxs();
|
|
42
|
+
if (client.isTestnet && coin.includes(':')) {
|
|
43
|
+
await client.loadSingleHip3Dex(coin.split(':')[0]);
|
|
44
|
+
}
|
|
45
|
+
let trades = await client.getRecentTrades(normalizeCoin(coin));
|
|
46
|
+
// Most recent first
|
|
47
|
+
trades.sort((a, b) => b.time - a.time);
|
|
48
|
+
trades = trades.slice(0, top);
|
|
49
|
+
if (jsonOutput) {
|
|
50
|
+
let assetId = -1;
|
|
51
|
+
try {
|
|
52
|
+
assetId = client.getAssetIndex(normalizeCoin(coin));
|
|
53
|
+
}
|
|
54
|
+
catch { /* noop */ }
|
|
55
|
+
console.log(JSON.stringify({ coin: normalizeCoin(coin), assetId, trades }, null, 2));
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (trades.length === 0) {
|
|
59
|
+
console.log('No recent trades found');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// Table header
|
|
63
|
+
console.log('Time'.padEnd(20) +
|
|
64
|
+
'Side'.padEnd(6) +
|
|
65
|
+
'Size'.padEnd(14) +
|
|
66
|
+
'Price');
|
|
67
|
+
console.log('─'.repeat(55));
|
|
68
|
+
let totalVol = 0;
|
|
69
|
+
let buyVol = 0;
|
|
70
|
+
let sellVol = 0;
|
|
71
|
+
for (const trade of trades) {
|
|
72
|
+
const time = new Date(trade.time).toLocaleString();
|
|
73
|
+
const side = trade.side === 'B' ? 'BUY' : 'SELL';
|
|
74
|
+
const notional = parseFloat(trade.px) * parseFloat(trade.sz);
|
|
75
|
+
totalVol += notional;
|
|
76
|
+
if (trade.side === 'B')
|
|
77
|
+
buyVol += notional;
|
|
78
|
+
else
|
|
79
|
+
sellVol += notional;
|
|
80
|
+
console.log(time.padEnd(20) +
|
|
81
|
+
side.padEnd(6) +
|
|
82
|
+
trade.sz.padEnd(14) +
|
|
83
|
+
formatUsd(parseFloat(trade.px)));
|
|
84
|
+
}
|
|
85
|
+
// Summary
|
|
86
|
+
console.log('─'.repeat(55));
|
|
87
|
+
console.log(`Trades: ${trades.length} | Volume: ${formatUsd(totalVol)}`);
|
|
88
|
+
const buyPct = totalVol > 0 ? (buyVol / totalVol * 100).toFixed(1) : '0';
|
|
89
|
+
const sellPct = totalVol > 0 ? (sellVol / totalVol * 100).toFixed(1) : '0';
|
|
90
|
+
console.log(`Buy: ${buyPct}% | Sell: ${sellPct}%`);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error('Error fetching trades:', error);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
main();
|
package/dist/lib.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { HyperliquidClient, getClient, } from './core/client.js';
|
|
2
|
+
export { loadConfig, isConfigured, getNetwork, isMainnet, ensureConfigDir, getConfigPath, GLOBAL_CONFIG_DIR, GLOBAL_ENV_PATH, OPEN_BROKER_BUILDER_ADDRESS, } from './core/config.js';
|
|
3
|
+
export { roundPrice, roundSize, sleep, normalizeCoin, formatUsd, formatPercent, annualizeFundingRate, parseArgs, getSlippagePrice, getTimestampMs, generateCloid, orderToWire, checkBuilderFeeApproval, } from './core/utils.js';
|
|
4
|
+
export type * from './core/types.js';
|
|
5
|
+
export { runBracket } from './operations/bracket.js';
|
|
6
|
+
export type { BracketOptions, BracketResult } from './operations/bracket.js';
|
|
7
|
+
export { runChase } from './operations/chase.js';
|
|
8
|
+
export type { ChaseOptions, ChaseResult } from './operations/chase.js';
|
|
9
|
+
export { startAutomation, getRunningAutomations, getAutomation, getRegisteredAutomations, } from './auto/runtime.js';
|
|
10
|
+
export type { RuntimeOptions } from './auto/runtime.js';
|
|
11
|
+
export { resolveScriptPath, resolveExamplePath, listAutomations, listExamples, loadExampleConfigs, ensureAutomationsDir, loadAutomation, } from './auto/loader.js';
|
|
12
|
+
export { registerAutomation, unregisterAutomation, cleanRegistry, getAutomationsToRestart, markAutomationError, } from './auto/registry.js';
|
|
13
|
+
export type * from './auto/types.js';
|
|
14
|
+
//# sourceMappingURL=lib.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../scripts/lib.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,iBAAiB,EACjB,SAAS,GACV,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,UAAU,EACV,YAAY,EACZ,UAAU,EACV,SAAS,EACT,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,UAAU,EACV,SAAS,EACT,KAAK,EACL,aAAa,EACb,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,WAAW,EACX,uBAAuB,GACxB,MAAM,iBAAiB,CAAC;AAEzB,mBAAmB,iBAAiB,CAAC;AAIrC,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE7E,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIvE,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,aAAa,EACb,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,GACf,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAE5B,mBAAmB,iBAAiB,CAAC"}
|
package/dist/lib.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Public library API for `openbroker`.
|
|
2
|
+
//
|
|
3
|
+
// External packages — notably `openbroker-plugin` — import from here to
|
|
4
|
+
// drive the CLI's functionality in-process (no `child_process` dispatch).
|
|
5
|
+
//
|
|
6
|
+
// Stability: every symbol re-exported here is a public API. Renames or
|
|
7
|
+
// removals are breaking changes and require a major version bump.
|
|
8
|
+
export { HyperliquidClient, getClient, } from './core/client.js';
|
|
9
|
+
export { loadConfig, isConfigured, getNetwork, isMainnet, ensureConfigDir, getConfigPath, GLOBAL_CONFIG_DIR, GLOBAL_ENV_PATH, OPEN_BROKER_BUILDER_ADDRESS, } from './core/config.js';
|
|
10
|
+
export { roundPrice, roundSize, sleep, normalizeCoin, formatUsd, formatPercent, annualizeFundingRate, parseArgs, getSlippagePrice, getTimestampMs, generateCloid, orderToWire, checkBuilderFeeApproval, } from './core/utils.js';
|
|
11
|
+
// ── Operations (in-process callable) ────────────────────────────────
|
|
12
|
+
export { runBracket } from './operations/bracket.js';
|
|
13
|
+
export { runChase } from './operations/chase.js';
|
|
14
|
+
// ── Automation runtime ──────────────────────────────────────────────
|
|
15
|
+
export { startAutomation, getRunningAutomations, getAutomation, getRegisteredAutomations, } from './auto/runtime.js';
|
|
16
|
+
export { resolveScriptPath, resolveExamplePath, listAutomations, listExamples, loadExampleConfigs, ensureAutomationsDir, loadAutomation, } from './auto/loader.js';
|
|
17
|
+
export { registerAutomation, unregisterAutomation, cleanRegistry, getAutomationsToRestart, markAutomationError, } from './auto/registry.js';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env npx tsx
|
|
2
|
+
export interface BracketOptions {
|
|
3
|
+
coin: string;
|
|
4
|
+
side: 'buy' | 'sell';
|
|
5
|
+
size: number;
|
|
6
|
+
tpPct: number;
|
|
7
|
+
slPct: number;
|
|
8
|
+
entryType?: 'market' | 'limit';
|
|
9
|
+
entryPrice?: number;
|
|
10
|
+
slippage?: number;
|
|
11
|
+
leverage?: number;
|
|
12
|
+
dryRun?: boolean;
|
|
13
|
+
verbose?: boolean;
|
|
14
|
+
/** Receives each output line. Defaults to console.log. */
|
|
15
|
+
output?: (line: string) => void;
|
|
16
|
+
}
|
|
17
|
+
export interface BracketResult {
|
|
18
|
+
status: 'dry' | 'limit_resting' | 'complete' | 'entry_failed' | 'partial';
|
|
19
|
+
entryPrice?: number;
|
|
20
|
+
tpPrice?: number;
|
|
21
|
+
slPrice?: number;
|
|
22
|
+
tpOid?: number | null;
|
|
23
|
+
slOid?: number | null;
|
|
24
|
+
entryOid?: number | null;
|
|
25
|
+
reason?: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function runBracket(opts: BracketOptions): Promise<BracketResult>;
|
|
28
|
+
//# sourceMappingURL=bracket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bracket.d.ts","sourceRoot":"","sources":["../../scripts/operations/bracket.ts"],"names":[],"mappings":";AA8CA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,KAAK,GAAG,eAAe,GAAG,UAAU,GAAG,cAAc,GAAG,SAAS,CAAC;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAsL7E"}
|