@vesper85/strategy-sdk 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/LICENSE +22 -0
- package/README.md +448 -0
- package/dist/clients/hyperliquid-client.d.ts +68 -0
- package/dist/clients/polymarket-client.d.ts +157 -0
- package/dist/context/osiris-context.d.ts +14 -0
- package/dist/engine/event-runner.d.ts +129 -0
- package/dist/engine/strategy-runner.d.ts +65 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +2195 -0
- package/dist/signer/index.d.ts +54 -0
- package/dist/signer/osiris-signer.d.ts +29 -0
- package/dist/signer/privatekey-signer.d.ts +41 -0
- package/dist/signer/types.d.ts +62 -0
- package/dist/state/memory-state.d.ts +17 -0
- package/dist/state/redis-state.d.ts +20 -0
- package/dist/types/event-types.d.ts +102 -0
- package/dist/types/osiris.d.ts +414 -0
- package/dist/types/strategy.d.ts +35 -0
- package/dist/utils/logger.d.ts +15 -0
- package/package.json +76 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Osiris AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
# @osiris-ai/strategy-sdk
|
|
2
|
+
|
|
3
|
+
SDK for writing and running trading strategies with Polymarket and Hyperliquid integrations.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **TypeScript-first**: Full type safety with IntelliSense support
|
|
8
|
+
- **Market Integrations**: Polymarket and Hyperliquid APIs
|
|
9
|
+
- **Technical Analysis**: Built-in technical indicators (RSI, MACD, Bollinger Bands, etc.)
|
|
10
|
+
- **State Management**: In-memory or Redis-backed persistent state
|
|
11
|
+
- **Dual Execution Modes**: Tick-based (polling) or Event-based (real-time WebSocket)
|
|
12
|
+
- **Flexible Logging**: Use built-in console logger or provide your own
|
|
13
|
+
- **Transaction Signing**: Support for both Osiris Hub signing and private key signing (EVM & Solana)
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @osiris-ai/strategy-sdk
|
|
19
|
+
# or
|
|
20
|
+
pnpm add @osiris-ai/strategy-sdk
|
|
21
|
+
# or
|
|
22
|
+
yarn add @osiris-ai/strategy-sdk
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
### 1. Create a Strategy (Tick-Based)
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import type { OsirisContext, CodeStrategy } from '@osiris-ai/strategy-sdk';
|
|
31
|
+
|
|
32
|
+
export default class MyStrategy implements CodeStrategy {
|
|
33
|
+
async shouldTrigger(osiris: OsirisContext): Promise<boolean> {
|
|
34
|
+
// Return true when you want to execute the strategy
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async onTrigger(osiris: OsirisContext): Promise<void> {
|
|
39
|
+
// Your trading logic here
|
|
40
|
+
if (osiris.hyperliquid) {
|
|
41
|
+
const price = await osiris.hyperliquid.getPrice('BTC');
|
|
42
|
+
osiris.log(`Current BTC price: ${price}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 2. Run the Strategy
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import {
|
|
52
|
+
createOsirisContext,
|
|
53
|
+
createConsoleLogger,
|
|
54
|
+
runStrategy,
|
|
55
|
+
PrivateKeySigner,
|
|
56
|
+
} from '@osiris-ai/strategy-sdk';
|
|
57
|
+
import MyStrategy from './my-strategy';
|
|
58
|
+
|
|
59
|
+
async function main() {
|
|
60
|
+
const logger = createConsoleLogger();
|
|
61
|
+
|
|
62
|
+
// Create signer
|
|
63
|
+
const signer = new PrivateKeySigner({
|
|
64
|
+
privateKey: process.env.PRIVATE_KEY!,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Create context
|
|
68
|
+
const context = createOsirisContext({
|
|
69
|
+
strategyId: 'my-strategy',
|
|
70
|
+
market: 'hyperliquid', // or 'polymarket'
|
|
71
|
+
userAddress: signer.getAddress()!,
|
|
72
|
+
signer,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Create strategy instance
|
|
76
|
+
const strategy = new MyStrategy();
|
|
77
|
+
|
|
78
|
+
// Run strategy once
|
|
79
|
+
await runStrategy(strategy, { logger }, context);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
main();
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Execution Modes
|
|
86
|
+
|
|
87
|
+
The SDK supports two mutually exclusive execution modes:
|
|
88
|
+
|
|
89
|
+
### Tick-Based Execution (Polling)
|
|
90
|
+
|
|
91
|
+
Runs your strategy at fixed intervals. Best for strategies that check conditions periodically.
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
interface CodeStrategy {
|
|
95
|
+
shouldTrigger(osiris: OsirisContext): Promise<boolean>;
|
|
96
|
+
onTrigger(osiris: OsirisContext): Promise<void>;
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { createStrategyEngine } from '@osiris-ai/strategy-sdk';
|
|
102
|
+
|
|
103
|
+
const engine = createStrategyEngine(strategy, {
|
|
104
|
+
logger,
|
|
105
|
+
strategyId: 'my-strategy', // Optional, for logging
|
|
106
|
+
tickIntervalMs: 60000, // Run every 60 seconds
|
|
107
|
+
}, context);
|
|
108
|
+
|
|
109
|
+
engine.start();
|
|
110
|
+
// engine.stop();
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Event-Based Execution (Real-time WebSocket)
|
|
114
|
+
|
|
115
|
+
Reacts to real-time events from your WebSocket server. Best for reactive strategies (price alerts, arbitrage, etc.)
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
interface CodeStrategy {
|
|
119
|
+
subscriptions: EventSubscription[];
|
|
120
|
+
onEvent(event: StrategyEvent, osiris: OsirisContext): Promise<void>;
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import { createEventRunner, type EventSubscription, type StrategyEvent } from '@osiris-ai/strategy-sdk';
|
|
126
|
+
|
|
127
|
+
class PriceAlertStrategy implements CodeStrategy {
|
|
128
|
+
subscriptions: EventSubscription[] = [
|
|
129
|
+
{
|
|
130
|
+
type: 'price',
|
|
131
|
+
market: 'BTC-USD',
|
|
132
|
+
conditions: { priceChangePercent: 5 }
|
|
133
|
+
}
|
|
134
|
+
];
|
|
135
|
+
|
|
136
|
+
async onEvent(event: StrategyEvent, osiris: OsirisContext): Promise<void> {
|
|
137
|
+
osiris.log(`Price changed: ${event.data.changePercent}%`);
|
|
138
|
+
// React to price change...
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const runner = createEventRunner(strategy, {
|
|
143
|
+
logger,
|
|
144
|
+
eventSourceUrl: 'wss://your-event-server.com/ws',
|
|
145
|
+
strategyId: 'price-alert', // Optional
|
|
146
|
+
}, context);
|
|
147
|
+
|
|
148
|
+
runner.start();
|
|
149
|
+
// runner.stop();
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### Event Types
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
type EventType = 'price' | 'orderbook' | 'time' | 'trade' | 'fill' | 'liquidation' | 'custom';
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
#### Event Subscriptions
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
interface EventSubscription {
|
|
162
|
+
type: EventType;
|
|
163
|
+
market?: string;
|
|
164
|
+
conditions?: {
|
|
165
|
+
priceAbove?: number;
|
|
166
|
+
priceBelow?: number;
|
|
167
|
+
priceChangePercent?: number;
|
|
168
|
+
spreadAbove?: number;
|
|
169
|
+
volumeAbove?: number;
|
|
170
|
+
cron?: string;
|
|
171
|
+
interval?: number;
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## API Reference
|
|
177
|
+
|
|
178
|
+
### Types
|
|
179
|
+
|
|
180
|
+
#### `CodeStrategy`
|
|
181
|
+
|
|
182
|
+
Interface that all strategies must implement (choose one execution mode):
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
interface CodeStrategy {
|
|
186
|
+
// Tick-based (optional if using event-based)
|
|
187
|
+
shouldTrigger?(osiris: OsirisContext): Promise<boolean>;
|
|
188
|
+
onTrigger?(osiris: OsirisContext): Promise<void>;
|
|
189
|
+
|
|
190
|
+
// Event-based (optional if using tick-based)
|
|
191
|
+
subscriptions?: EventSubscription[];
|
|
192
|
+
onEvent?(event: StrategyEvent, osiris: OsirisContext): Promise<void>;
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### `OsirisContext`
|
|
197
|
+
|
|
198
|
+
The context object passed to your strategy methods:
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
interface OsirisContext {
|
|
202
|
+
polymarket?: PolymarketAPI; // Available when market='polymarket'
|
|
203
|
+
hyperliquid?: HyperliquidAPI; // Available when market='hyperliquid'
|
|
204
|
+
ta: TechnicalAnalysisAPI; // Technical analysis functions
|
|
205
|
+
state: OsirisState; // State management
|
|
206
|
+
signer: SignerAPI; // Transaction signer
|
|
207
|
+
log: (message: string, meta?: any) => void; // Logging function
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### State Management
|
|
212
|
+
|
|
213
|
+
#### In Strategy
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
// Get state
|
|
217
|
+
const value = await osiris.state.get('myKey');
|
|
218
|
+
|
|
219
|
+
// Set state
|
|
220
|
+
await osiris.state.set('myKey', { count: 42 });
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
#### Redis State (for production)
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
import { RedisStateManager } from '@osiris-ai/strategy-sdk';
|
|
227
|
+
|
|
228
|
+
const stateManager = new RedisStateManager(
|
|
229
|
+
'redis://localhost:6379',
|
|
230
|
+
'strategy-id',
|
|
231
|
+
logger
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
await stateManager.connect();
|
|
235
|
+
// ... use stateManager
|
|
236
|
+
await stateManager.disconnect();
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Market APIs
|
|
240
|
+
|
|
241
|
+
#### Polymarket Trading
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
if (osiris.polymarket) {
|
|
245
|
+
// Initialize trading client (required before trading)
|
|
246
|
+
await osiris.polymarket.initializeTradingClient();
|
|
247
|
+
|
|
248
|
+
// ============================================
|
|
249
|
+
// Convenience Trading Methods (Recommended)
|
|
250
|
+
// ============================================
|
|
251
|
+
|
|
252
|
+
// Limit orders
|
|
253
|
+
await osiris.polymarket.buyLimit(tokenId, 0.65, 100); // Buy 100 shares @ $0.65
|
|
254
|
+
await osiris.polymarket.sellLimit(tokenId, 0.70, 50); // Sell 50 shares @ $0.70
|
|
255
|
+
|
|
256
|
+
// Market orders (execute immediately)
|
|
257
|
+
await osiris.polymarket.buyMarket(tokenId, 100); // Buy $100 worth
|
|
258
|
+
await osiris.polymarket.sellMarket(tokenId, 50); // Sell 50 shares
|
|
259
|
+
|
|
260
|
+
// ============================================
|
|
261
|
+
// Full Order Methods (More control)
|
|
262
|
+
// ============================================
|
|
263
|
+
|
|
264
|
+
await osiris.polymarket.createLimitOrder({
|
|
265
|
+
tokenId: '0x...',
|
|
266
|
+
price: 0.65,
|
|
267
|
+
size: 100,
|
|
268
|
+
side: 'BUY',
|
|
269
|
+
feeRateBps: '0',
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
await osiris.polymarket.createMarketOrder({
|
|
273
|
+
tokenId: '0x...',
|
|
274
|
+
amount: 100,
|
|
275
|
+
side: 'BUY',
|
|
276
|
+
slippageTolerance: 0.05,
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
// Order management
|
|
280
|
+
const orders = await osiris.polymarket.getOpenOrders();
|
|
281
|
+
await osiris.polymarket.cancelOrder(orderId);
|
|
282
|
+
await osiris.polymarket.cancelAllOrders();
|
|
283
|
+
|
|
284
|
+
// Market data
|
|
285
|
+
const market = await osiris.polymarket.getMarket('market-slug');
|
|
286
|
+
const markets = await osiris.polymarket.getMarkets({ active: true, limit: 50 });
|
|
287
|
+
const orderBook = await osiris.polymarket.getOrderBook(tokenId);
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
#### Hyperliquid Trading
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
if (osiris.hyperliquid) {
|
|
295
|
+
// Get price
|
|
296
|
+
const price = await osiris.hyperliquid.getPrice('BTC');
|
|
297
|
+
|
|
298
|
+
// Get position
|
|
299
|
+
const position = await osiris.hyperliquid.getPosition('BTC');
|
|
300
|
+
|
|
301
|
+
// Get all positions
|
|
302
|
+
const positions = await osiris.hyperliquid.getPositions();
|
|
303
|
+
|
|
304
|
+
// Get candle data
|
|
305
|
+
const candles = await osiris.hyperliquid.getCandleSnapshot(
|
|
306
|
+
'BTC', '1d', startTime, endTime
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
// Execute trades
|
|
310
|
+
await osiris.hyperliquid.buy('BTC', 0.1);
|
|
311
|
+
await osiris.hyperliquid.sell('BTC', 0.1);
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Technical Analysis
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
// Calculate RSI
|
|
319
|
+
const rsi = osiris.ta.calculate('rsi_14', ohlcvData, { period: 14 });
|
|
320
|
+
|
|
321
|
+
// Calculate MACD (returns [MACD, signal, histogram])
|
|
322
|
+
const macd = osiris.ta.calculate('macd_12_26_9', ohlcvData, {
|
|
323
|
+
fastPeriod: 12,
|
|
324
|
+
slowPeriod: 26,
|
|
325
|
+
signalPeriod: 9
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// Get specific component from multi-value indicator
|
|
329
|
+
const macdSignal = osiris.ta.calculate('macd_12_26_9', ohlcvData, {
|
|
330
|
+
component: 'signal'
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
// Available indicators:
|
|
334
|
+
// Single-value: rsi, sma, ema, atr, adx, obv, cci, mfi, vwap, williams_r, roc, psar, wma
|
|
335
|
+
// Multi-value: macd, bollinger_bands, stochastic, stochastic_rsi, keltner_channels
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Signing Transactions
|
|
339
|
+
|
|
340
|
+
#### Using Private Key Signer
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
import { PrivateKeySigner, createOsirisContext } from '@osiris-ai/strategy-sdk';
|
|
344
|
+
|
|
345
|
+
const signer = new PrivateKeySigner({
|
|
346
|
+
privateKey: process.env.PRIVATE_KEY!,
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
const address = signer.getAddress();
|
|
350
|
+
|
|
351
|
+
const context = createOsirisContext({
|
|
352
|
+
strategyId: 'my-strategy',
|
|
353
|
+
market: 'polymarket',
|
|
354
|
+
userAddress: address!,
|
|
355
|
+
signer,
|
|
356
|
+
});
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
#### Using Osiris Hub Signer
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
362
|
+
import { OsirisSigner, createOsirisContext } from '@osiris-ai/strategy-sdk';
|
|
363
|
+
|
|
364
|
+
const signer = new OsirisSigner({
|
|
365
|
+
hubBaseUrl: 'https://api.osirislabs.xyz/v1',
|
|
366
|
+
accessToken: process.env.OSIRIS_ACCESS_TOKEN!,
|
|
367
|
+
connectionId: process.env.WALLET_CONNECTION_ID!,
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
const context = createOsirisContext({
|
|
371
|
+
strategyId: 'my-strategy',
|
|
372
|
+
market: 'polymarket',
|
|
373
|
+
userAddress: '0x...',
|
|
374
|
+
signer,
|
|
375
|
+
polymarketOptions: {
|
|
376
|
+
useMcpForOrders: true,
|
|
377
|
+
mcpUrl: 'https://gateway.backend.osirislabs.xyz/@osiris/polymarket/mcp',
|
|
378
|
+
mcpAccessToken: process.env.MCP_ACCESS_TOKEN!,
|
|
379
|
+
},
|
|
380
|
+
});
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### Logging
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
import { createConsoleLogger } from '@osiris-ai/strategy-sdk';
|
|
387
|
+
|
|
388
|
+
const logger = createConsoleLogger();
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
## Examples
|
|
392
|
+
|
|
393
|
+
See the `examples/` directory:
|
|
394
|
+
|
|
395
|
+
- `example-rsi.ts` - RSI-based trading strategy (tick-based)
|
|
396
|
+
- `example-polymarket.ts` - Polymarket arbitrage strategy (tick-based)
|
|
397
|
+
- `example-event-strategy.ts` - Price alert strategy (event-based)
|
|
398
|
+
- `example-usage.ts` - Complete usage examples
|
|
399
|
+
- `example-signer.ts` - Signer usage examples
|
|
400
|
+
|
|
401
|
+
## Strategy Patterns
|
|
402
|
+
|
|
403
|
+
### Tick-Based Strategy Pattern
|
|
404
|
+
|
|
405
|
+
```typescript
|
|
406
|
+
class MyTickStrategy implements CodeStrategy {
|
|
407
|
+
async shouldTrigger(osiris: OsirisContext): Promise<boolean> {
|
|
408
|
+
// Called every tick - return true to execute
|
|
409
|
+
return true;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
async onTrigger(osiris: OsirisContext): Promise<void> {
|
|
413
|
+
// Your trading logic
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Event-Based Strategy Pattern
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
class MyEventStrategy implements CodeStrategy {
|
|
422
|
+
subscriptions: EventSubscription[] = [
|
|
423
|
+
{ type: 'price', market: 'BTC-USD', conditions: { priceChangePercent: 5 } }
|
|
424
|
+
];
|
|
425
|
+
|
|
426
|
+
async onEvent(event: StrategyEvent, osiris: OsirisContext): Promise<void> {
|
|
427
|
+
// Triggered by real-time events
|
|
428
|
+
osiris.log(`Event: ${event.type} - ${JSON.stringify(event.data)}`);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
## Best Practices
|
|
434
|
+
|
|
435
|
+
1. **State Management**: Use `osiris.state` for persistent data that should survive restarts
|
|
436
|
+
2. **Error Handling**: Always wrap API calls in try-catch blocks
|
|
437
|
+
3. **Rate Limiting**: Be mindful of API rate limits when making frequent calls
|
|
438
|
+
4. **Testing**: Use `MemoryStateManager` for testing, `RedisStateManager` for production
|
|
439
|
+
5. **Logging**: Use `osiris.log()` for strategy-specific logs
|
|
440
|
+
6. **Execution Mode**: Choose tick-based for polling, event-based for real-time reactions
|
|
441
|
+
|
|
442
|
+
## TypeScript Support
|
|
443
|
+
|
|
444
|
+
The SDK is written in TypeScript and provides full type definitions. All types are exported.
|
|
445
|
+
|
|
446
|
+
## License
|
|
447
|
+
|
|
448
|
+
MIT
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type ClearinghouseState, type SpotMeta, type SpotClearinghouseState, type SpotMetaAndAssetCtxs, type Meta, type MetaAndAssetCtxs, type UserFunding, type UserNonFundingLedgerUpdates, type FundingHistory, type PredictedFundings, type PerpsAtOpenInterestCap, type PerpDexLimits, type AllMids, type UserOpenOrders, type FrontendOpenOrders, type UserFills, type UserRateLimit, type OrderStatus, type L2Book, type CandleSnapshot, type HistoricalOrder, type TwapSliceFill, type SubAccount, type VaultDetails, type VaultEquity, type UserRole, type Delegation, type DelegatorSummary, type DelegatorHistoryEntry, type DelegatorReward, type ValidatorSummary, type VaultSummary, type UserFees, type PortfolioPeriods, type PreTransferCheck, type Referral, type ExtraAgent, type LegalCheck, type TwapHistory, type MultiSigSigners, type BuilderFeeApproval, type UserOrderHistory } from "hyperliquid";
|
|
2
|
+
import type { HyperliquidAPI } from "../types/osiris";
|
|
3
|
+
import type { Logger } from "../utils/logger";
|
|
4
|
+
export declare class HyperliquidClient implements HyperliquidAPI {
|
|
5
|
+
private logger;
|
|
6
|
+
private client;
|
|
7
|
+
private userAddress;
|
|
8
|
+
constructor(logger: Logger, userAddress?: string);
|
|
9
|
+
getPrice(ticker: string): Promise<number>;
|
|
10
|
+
getIndicator(ticker: string, indicator: string, params?: any): Promise<number>;
|
|
11
|
+
getSpotMeta(): Promise<SpotMeta>;
|
|
12
|
+
getSpotClearinghouseState(user: string): Promise<SpotClearinghouseState>;
|
|
13
|
+
getSpotMetaAndAssetCtxs(): Promise<SpotMetaAndAssetCtxs>;
|
|
14
|
+
getTokenDetails(tokenId: string): Promise<any>;
|
|
15
|
+
getSpotDeployState(user: string): Promise<any>;
|
|
16
|
+
getMeta(): Promise<Meta>;
|
|
17
|
+
getMetaAndAssetCtxs(): Promise<MetaAndAssetCtxs>;
|
|
18
|
+
getClearinghouseState(user: string): Promise<ClearinghouseState>;
|
|
19
|
+
getUserFunding(user: string, startTime: number, endTime?: number): Promise<UserFunding>;
|
|
20
|
+
getUserNonFundingLedgerUpdates(user: string, startTime: number, endTime?: number): Promise<UserNonFundingLedgerUpdates>;
|
|
21
|
+
getFundingHistory(coin: string, startTime: number, endTime?: number): Promise<FundingHistory>;
|
|
22
|
+
getPredictedFundings(): Promise<PredictedFundings>;
|
|
23
|
+
getPerpsAtOpenInterestCap(): Promise<PerpsAtOpenInterestCap>;
|
|
24
|
+
getPerpDexLimits(dex: string): Promise<PerpDexLimits>;
|
|
25
|
+
getAssetIndex(assetName: string): Promise<number | undefined>;
|
|
26
|
+
getInternalName(exchangeName: string): Promise<string | undefined>;
|
|
27
|
+
getAllAssets(): Promise<{
|
|
28
|
+
perp: string[];
|
|
29
|
+
spot: string[];
|
|
30
|
+
}>;
|
|
31
|
+
getAllMids(): Promise<AllMids>;
|
|
32
|
+
getUserOpenOrders(user: string): Promise<UserOpenOrders>;
|
|
33
|
+
getFrontendOpenOrders(user: string): Promise<FrontendOpenOrders>;
|
|
34
|
+
getUserFills(user: string): Promise<UserFills>;
|
|
35
|
+
getUserFillsByTime(user: string, startTime: number, endTime: number): Promise<UserFills>;
|
|
36
|
+
getUserRateLimit(user: string): Promise<UserRateLimit>;
|
|
37
|
+
getOrderStatus(user: string, oid: number | string): Promise<OrderStatus>;
|
|
38
|
+
getL2Book(coin: string): Promise<L2Book>;
|
|
39
|
+
getCandleSnapshot(coin: string, interval: string, startTime: number, endTime: number): Promise<CandleSnapshot>;
|
|
40
|
+
getMaxBuilderFee(user: string, builder: string): Promise<number>;
|
|
41
|
+
getHistoricalOrders(user: string): Promise<HistoricalOrder[]>;
|
|
42
|
+
getUserTwapSliceFills(user: string): Promise<TwapSliceFill[]>;
|
|
43
|
+
getSubAccounts(user: string): Promise<SubAccount[]>;
|
|
44
|
+
getVaultDetails(vaultAddress: string, user?: string): Promise<VaultDetails>;
|
|
45
|
+
getUserVaultEquities(user: string): Promise<VaultEquity[]>;
|
|
46
|
+
getUserRole(user: string): Promise<UserRole>;
|
|
47
|
+
getDelegations(user: string): Promise<Delegation[]>;
|
|
48
|
+
getDelegatorSummary(user: string): Promise<DelegatorSummary>;
|
|
49
|
+
getDelegatorHistory(user: string): Promise<DelegatorHistoryEntry[]>;
|
|
50
|
+
getDelegatorRewards(user: string): Promise<DelegatorReward[]>;
|
|
51
|
+
validatorSummaries(): Promise<ValidatorSummary[]>;
|
|
52
|
+
vaultSummaries(): Promise<VaultSummary[]>;
|
|
53
|
+
userFees(user: string): Promise<UserFees>;
|
|
54
|
+
portfolio(user: string): Promise<PortfolioPeriods>;
|
|
55
|
+
preTransferCheck(user: string, source: string): Promise<PreTransferCheck>;
|
|
56
|
+
referral(user: string): Promise<Referral>;
|
|
57
|
+
extraAgents(user: string): Promise<ExtraAgent[]>;
|
|
58
|
+
isVip(user: string): Promise<boolean>;
|
|
59
|
+
legalCheck(user: string): Promise<LegalCheck>;
|
|
60
|
+
userTwapSliceFillsByTime(user: string, startTime: number, endTime?: number): Promise<TwapSliceFill[]>;
|
|
61
|
+
twapHistory(user: string): Promise<TwapHistory[]>;
|
|
62
|
+
userToMultiSigSigners(user: string): Promise<MultiSigSigners | null>;
|
|
63
|
+
getBuilderFeeApproval(user: string, builderAddress: string): Promise<BuilderFeeApproval>;
|
|
64
|
+
getUserOrderHistory(user: string, startTime: number, endTime?: number): Promise<UserOrderHistory>;
|
|
65
|
+
getPosition(ticker: string): Promise<ClearinghouseState['assetPositions'][0] | null>;
|
|
66
|
+
getPositions(): Promise<ClearinghouseState['assetPositions']>;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=hyperliquid-client.d.ts.map
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { type GammaMarket, type Event as GammaEvent, type Tag, type Team, type Sport, type Series, type Comment as GammaComment, type SearchResults, type PaginatedResponse, type MarketFilters, type EventFilters, type EventPaginationFilters, type PaginationParams, type SearchParams } from "polymarket-gamma";
|
|
2
|
+
import type { PolymarketAPI, PolymarketClientOptions, PolymarketLimitOrderParams, PolymarketMarketOrderParams, PolymarketOrderResponse, PolymarketOpenOrder, PolymarketCancelResponse, PolymarketOrderBook, PolymarketApprovalResult, SignerAPI } from "../types/osiris";
|
|
3
|
+
import type { Logger } from "../utils/logger";
|
|
4
|
+
export declare class PolymarketClient implements PolymarketAPI {
|
|
5
|
+
private logger;
|
|
6
|
+
private signer;
|
|
7
|
+
private gammaClient;
|
|
8
|
+
private clobClient;
|
|
9
|
+
private wallet;
|
|
10
|
+
private provider;
|
|
11
|
+
private options;
|
|
12
|
+
private tradingInitialized;
|
|
13
|
+
private mcpInstance;
|
|
14
|
+
private isOsirisSigner;
|
|
15
|
+
private userAddress;
|
|
16
|
+
constructor(logger: Logger, signer: SignerAPI, userAddress: string, options?: PolymarketClientOptions);
|
|
17
|
+
initializeTradingClient(): Promise<void>;
|
|
18
|
+
isTradingClientInitialized(): boolean;
|
|
19
|
+
private getPrivateKeyFromSigner;
|
|
20
|
+
private ensureTradingClient;
|
|
21
|
+
private ensureMcpInstance;
|
|
22
|
+
/**
|
|
23
|
+
* Call an MCP tool with retry logic
|
|
24
|
+
*/
|
|
25
|
+
private callMCPTool;
|
|
26
|
+
/**
|
|
27
|
+
* Execute a tool on an MCP client instance
|
|
28
|
+
*/
|
|
29
|
+
private executeMCPTool;
|
|
30
|
+
/**
|
|
31
|
+
* Extract content from MCP tool response (ported from sozu-tg-bot)
|
|
32
|
+
*/
|
|
33
|
+
private extractMCPContent;
|
|
34
|
+
/**
|
|
35
|
+
* Extract order details from MCP response (ported from sozu-tg-bot)
|
|
36
|
+
*/
|
|
37
|
+
private extractOrderDetails;
|
|
38
|
+
/**
|
|
39
|
+
* Detect errors in MCP tool response (ported from sozu-tg-bot)
|
|
40
|
+
*/
|
|
41
|
+
private detectMCPError;
|
|
42
|
+
private ensureWallet;
|
|
43
|
+
getUsdcAllowance(): Promise<bigint>;
|
|
44
|
+
approveUsdc(amount?: bigint): Promise<string>;
|
|
45
|
+
isCtfApprovedForAll(): Promise<boolean>;
|
|
46
|
+
approveCtf(): Promise<string>;
|
|
47
|
+
setupApprovals(options?: {
|
|
48
|
+
usdcAmount?: bigint;
|
|
49
|
+
}): Promise<PolymarketApprovalResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Check token allowance via MCP tools
|
|
52
|
+
* @param tokenType - "USDC" for buy orders, "CONDITIONAL_TOKEN" for sell orders
|
|
53
|
+
* @returns true if sufficient allowance exists
|
|
54
|
+
*/
|
|
55
|
+
private checkAllowanceViaMCP;
|
|
56
|
+
/**
|
|
57
|
+
* Approve tokens via MCP tools
|
|
58
|
+
* @param tokenType - "USDC" for buy orders, "CONDITIONAL_TOKEN" for sell orders
|
|
59
|
+
* @returns true if approval was successful
|
|
60
|
+
*/
|
|
61
|
+
private approveTokensViaMCP;
|
|
62
|
+
/**
|
|
63
|
+
* Ensure token approval via MCP before placing orders
|
|
64
|
+
* @param side - Order side (BUY or SELL)
|
|
65
|
+
* @returns true if approval is ready
|
|
66
|
+
*/
|
|
67
|
+
private ensureTokenApprovalViaMCP;
|
|
68
|
+
/**
|
|
69
|
+
* Setup approvals via MCP tools (for OsirisSigner mode)
|
|
70
|
+
*/
|
|
71
|
+
private setupApprovalsViaMCP;
|
|
72
|
+
createLimitOrder(params: PolymarketLimitOrderParams): Promise<PolymarketOrderResponse>;
|
|
73
|
+
/**
|
|
74
|
+
* Create limit order via MCP tools (for OsirisSigner)
|
|
75
|
+
*/
|
|
76
|
+
private createLimitOrderViaMCP;
|
|
77
|
+
createMarketOrder(params: PolymarketMarketOrderParams): Promise<PolymarketOrderResponse>;
|
|
78
|
+
/**
|
|
79
|
+
* Create market order via MCP tools (for OsirisSigner)
|
|
80
|
+
*/
|
|
81
|
+
private createMarketOrderViaMCP;
|
|
82
|
+
getOpenOrders(): Promise<PolymarketOpenOrder[]>;
|
|
83
|
+
cancelOrder(orderId: string): Promise<PolymarketCancelResponse>;
|
|
84
|
+
cancelOrders(orderIds: string[]): Promise<PolymarketCancelResponse>;
|
|
85
|
+
cancelAllOrders(): Promise<PolymarketCancelResponse>;
|
|
86
|
+
getOrderBook(tokenId: string): Promise<PolymarketOrderBook>;
|
|
87
|
+
private ensureApprovals;
|
|
88
|
+
buy(tokenId: string, size: number): Promise<void>;
|
|
89
|
+
sell(tokenId: string, size: number): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Place a limit buy order
|
|
92
|
+
*/
|
|
93
|
+
buyLimit(tokenId: string, price: number, size: number): Promise<PolymarketOrderResponse>;
|
|
94
|
+
/**
|
|
95
|
+
* Place a limit sell order
|
|
96
|
+
*/
|
|
97
|
+
sellLimit(tokenId: string, price: number, size: number): Promise<PolymarketOrderResponse>;
|
|
98
|
+
/**
|
|
99
|
+
* Place a market buy order
|
|
100
|
+
*/
|
|
101
|
+
buyMarket(tokenId: string, amount: number, slippage?: number): Promise<PolymarketOrderResponse>;
|
|
102
|
+
/**
|
|
103
|
+
* Place a market sell order
|
|
104
|
+
*/
|
|
105
|
+
sellMarket(tokenId: string, size: number, slippage?: number): Promise<PolymarketOrderResponse>;
|
|
106
|
+
getPrice(ticker: string): Promise<number>;
|
|
107
|
+
getIndicator(ticker: string, indicator: string, params?: any): Promise<number>;
|
|
108
|
+
search(params: SearchParams): Promise<SearchResults>;
|
|
109
|
+
getMarket(idOrSlug: string): Promise<GammaMarket>;
|
|
110
|
+
/**
|
|
111
|
+
* Get markets from Polymarket Gamma API with full filter support
|
|
112
|
+
* https://docs.polymarket.com/api-reference/markets/list-markets
|
|
113
|
+
*/
|
|
114
|
+
getMarkets(filters?: MarketFilters & {
|
|
115
|
+
end_date_min?: string;
|
|
116
|
+
end_date_max?: string;
|
|
117
|
+
start_date_min?: string;
|
|
118
|
+
start_date_max?: string;
|
|
119
|
+
liquidity_num_min?: number;
|
|
120
|
+
liquidity_num_max?: number;
|
|
121
|
+
volume_num_min?: number;
|
|
122
|
+
volume_num_max?: number;
|
|
123
|
+
limit?: number;
|
|
124
|
+
offset?: number;
|
|
125
|
+
order?: string;
|
|
126
|
+
ascending?: boolean;
|
|
127
|
+
closed?: boolean;
|
|
128
|
+
}): Promise<GammaMarket[]>;
|
|
129
|
+
getMarketTags(marketId: string): Promise<Tag[]>;
|
|
130
|
+
getEvent(idOrSlug: string): Promise<GammaEvent>;
|
|
131
|
+
getEvents(filters?: EventFilters): Promise<GammaEvent[]>;
|
|
132
|
+
getEventTags(eventId: string): Promise<Tag[]>;
|
|
133
|
+
getEventsPaginated(filters?: EventPaginationFilters): Promise<PaginatedResponse<GammaEvent>>;
|
|
134
|
+
getTags(params?: PaginationParams): Promise<Tag[]>;
|
|
135
|
+
getTag(idOrSlug: string): Promise<Tag>;
|
|
136
|
+
getRelatedTags(idOrSlug: string): Promise<Tag[]>;
|
|
137
|
+
getRelatedTagsTags(idOrSlug: string): Promise<Tag[]>;
|
|
138
|
+
getTeams(params?: PaginationParams): Promise<Team[]>;
|
|
139
|
+
getSports(params?: PaginationParams): Promise<Sport[]>;
|
|
140
|
+
getSeries(params?: PaginationParams): Promise<Series[]>;
|
|
141
|
+
getSeriesById(seriesId: string): Promise<Series>;
|
|
142
|
+
getComments(params?: PaginationParams): Promise<GammaComment[]>;
|
|
143
|
+
getComment(commentId: string): Promise<GammaComment>;
|
|
144
|
+
getCommentsByUser(userAddress: string, params?: PaginationParams): Promise<GammaComment[]>;
|
|
145
|
+
private readonly DATA_API_BASE;
|
|
146
|
+
private fetchData;
|
|
147
|
+
getPositions(user: string, params?: any): Promise<any[]>;
|
|
148
|
+
getTrades(user: string, params?: any): Promise<any[]>;
|
|
149
|
+
getActivity(user: string, params?: any): Promise<any[]>;
|
|
150
|
+
getTopHolders(marketId: string): Promise<any[]>;
|
|
151
|
+
getPortfolioValue(user: string): Promise<number>;
|
|
152
|
+
getClosedPositions(user: string, params?: any): Promise<any[]>;
|
|
153
|
+
getTradedMarketsCount(user: string): Promise<number>;
|
|
154
|
+
getOpenInterest(marketId: string): Promise<number>;
|
|
155
|
+
getPosition(ticker: string): Promise<any | null>;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=polymarket-client.d.ts.map
|