@wahoopredict/trading-sdk 0.0.1
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 +21 -0
- package/README.md +309 -0
- package/dist/cjs/client.js +129 -0
- package/dist/cjs/client.spec.js +153 -0
- package/dist/cjs/index.js +72 -0
- package/dist/cjs/schema.d.js +4 -0
- package/dist/esm/client.js +59 -0
- package/dist/esm/client.spec.js +108 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/schema.d.js +433 -0
- package/dist/types/client.d.ts +48 -0
- package/dist/types/client.d.ts.map +1 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/index.d.ts.map +1 -0
- package/package.json +66 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 WahooPredict
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# WahooPredict Trading SDK
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for the WahooPredict trading API. Built on [openapi-fetch](https://github.com/drwpow/openapi-typescript/tree/main/packages/openapi-fetch) for type-safe API calls.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @wahoopredict/trading-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { createWahooClient } from "@wahoopredict/trading-sdk";
|
|
15
|
+
|
|
16
|
+
const client = createWahooClient({
|
|
17
|
+
apiKey: "your-api-key",
|
|
18
|
+
secretKey: "your-secret-key",
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Get your balance
|
|
22
|
+
const { data, error } = await client.GET("/user/profile", {
|
|
23
|
+
params: { query: { fields: ["balance", "totalBalance"] } },
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
if (error) {
|
|
27
|
+
console.error("Error:", error);
|
|
28
|
+
} else {
|
|
29
|
+
console.log("Balance:", data.user?.balance);
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Authentication
|
|
34
|
+
|
|
35
|
+
The SDK uses HMAC-SHA256 signature-based authentication. You need an API key and secret key from WahooPredict.
|
|
36
|
+
|
|
37
|
+
The authentication headers are automatically added to every request:
|
|
38
|
+
|
|
39
|
+
- `X-API-KEY` - Your API key
|
|
40
|
+
- `X-TIMESTAMP` - Current Unix timestamp (seconds)
|
|
41
|
+
- `X-SIGNATURE` - HMAC-SHA256 signature of `apiKey + timestamp + requestBody`
|
|
42
|
+
|
|
43
|
+
## API Reference
|
|
44
|
+
|
|
45
|
+
### Market Data
|
|
46
|
+
|
|
47
|
+
#### Get Events List
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
const { data, error } = await client.POST("/event/events-list", {
|
|
51
|
+
body: {
|
|
52
|
+
page: 1,
|
|
53
|
+
limit: 20,
|
|
54
|
+
filter: {
|
|
55
|
+
status: ["LIVE"],
|
|
56
|
+
search: "bitcoin",
|
|
57
|
+
},
|
|
58
|
+
sort: {
|
|
59
|
+
sortBy: "volume",
|
|
60
|
+
sortOrder: "desc",
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Access events
|
|
66
|
+
data?.data.forEach((event) => {
|
|
67
|
+
console.log(event.title, event.status);
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### Get Event Details
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
const { data, error } = await client.GET("/event/event-details/{eventId}", {
|
|
75
|
+
params: {
|
|
76
|
+
path: { eventId: "cmkhbgto400rl01uqr9gn3mna" },
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// data is the Event object directly
|
|
81
|
+
console.log(data?.title);
|
|
82
|
+
console.log(data?.outcomes); // Array of possible outcomes
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### Get Order Book
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
const { data, error } = await client.GET("/event/orderbook", {
|
|
89
|
+
params: {
|
|
90
|
+
query: { outcomeOptionId: "cmkhbgw8f00t001uqprn3a2pk" },
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
console.log("Bids:", data?.bids);
|
|
95
|
+
console.log("Asks:", data?.asks);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Trading
|
|
99
|
+
|
|
100
|
+
#### Test Order (Simulate)
|
|
101
|
+
|
|
102
|
+
Before placing an order, you can test it to see the potential return:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
const { data, error } = await client.POST("/event/test-order", {
|
|
106
|
+
body: {
|
|
107
|
+
eventId: "cmkhbgto400rl01uqr9gn3mna",
|
|
108
|
+
outcomeOptionId: "cmkhbgw8f00t001uqprn3a2pk",
|
|
109
|
+
side: "BUY",
|
|
110
|
+
type: "MARKET",
|
|
111
|
+
amount: "10.00",
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
if (data) {
|
|
116
|
+
console.log("Potential return:", data.potentialReturn);
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
#### Place Market Order
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
const { data, error } = await client.POST("/event/place-order", {
|
|
124
|
+
body: {
|
|
125
|
+
eventId: "cmkhbgto400rl01uqr9gn3mna",
|
|
126
|
+
outcomeOptionId: "cmkhbgw8f00t001uqprn3a2pk",
|
|
127
|
+
side: "BUY",
|
|
128
|
+
type: "MARKET",
|
|
129
|
+
amount: "10.00", // Amount to spend (for BUY)
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
if (data) {
|
|
134
|
+
console.log("Order placed! New balance:", data.newBalance);
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
#### Place Limit Order
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
const { data, error } = await client.POST("/event/place-order", {
|
|
142
|
+
body: {
|
|
143
|
+
eventId: "cmkhbgto400rl01uqr9gn3mna",
|
|
144
|
+
outcomeOptionId: "cmkhbgw8f00t001uqprn3a2pk",
|
|
145
|
+
side: "BUY",
|
|
146
|
+
type: "LIMIT",
|
|
147
|
+
size: "100", // Number of shares
|
|
148
|
+
price: "0.45", // Price per share
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
#### Cancel Order
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
const { data, error } = await client.DELETE("/event/cancel-order", {
|
|
157
|
+
params: {
|
|
158
|
+
query: { orderId: "order-id-here" },
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
if (data) {
|
|
163
|
+
console.log("Order cancelled! New balance:", data.newBalance);
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Positions & Orders
|
|
168
|
+
|
|
169
|
+
#### Get Your Orders
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
const { data, error } = await client.POST("/event/orders", {
|
|
173
|
+
body: {
|
|
174
|
+
page: 1,
|
|
175
|
+
limit: 20,
|
|
176
|
+
filter: {
|
|
177
|
+
isOpen: true, // Only open orders
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
data?.data.forEach((order) => {
|
|
183
|
+
console.log(`${order.side} ${order.size} @ ${order.price} - ${order.status}`);
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
#### Get Your Positions
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
const { data, error } = await client.POST("/event/positions", {
|
|
191
|
+
body: {
|
|
192
|
+
page: 1,
|
|
193
|
+
limit: 20,
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
data?.data.forEach((position) => {
|
|
198
|
+
console.log(
|
|
199
|
+
`Position: ${position.part} shares, avg price: ${position.avgPrice}`,
|
|
200
|
+
);
|
|
201
|
+
});
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
#### Collect Position (After Event Resolution)
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
const { data, error } = await client.POST("/event/collect-position", {
|
|
208
|
+
body: {
|
|
209
|
+
positionId: "position-id-here",
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
if (data) {
|
|
214
|
+
console.log("Position collected! New balance:", data.newBalance);
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### User Profile
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
const { data, error } = await client.GET("/user/profile", {
|
|
222
|
+
params: {
|
|
223
|
+
query: {
|
|
224
|
+
fields: ["id", "username", "balance", "totalBalance", "bonusBalance"],
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
console.log("User:", data?.user?.username);
|
|
230
|
+
console.log("Balance:", data?.user?.balance);
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Error Handling
|
|
234
|
+
|
|
235
|
+
The SDK returns errors in a consistent format:
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
const { data, error } = await client.POST("/event/place-order", {
|
|
239
|
+
body: {
|
|
240
|
+
/* ... */
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
if (error) {
|
|
245
|
+
// error has type-safe structure based on the endpoint
|
|
246
|
+
console.error("Error:", error.message);
|
|
247
|
+
console.error("Error type:", error.error);
|
|
248
|
+
|
|
249
|
+
// Handle specific error types
|
|
250
|
+
if (error.error === "BetsClosed") {
|
|
251
|
+
console.log("Trading is closed for this outcome");
|
|
252
|
+
} else if (error.error === "InsufficientBalance") {
|
|
253
|
+
console.log("Not enough balance");
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Common error types:
|
|
259
|
+
|
|
260
|
+
- `BetsClosed` - Trading is closed for this outcome
|
|
261
|
+
- `EmptyOrderBook` - No liquidity for market orders
|
|
262
|
+
- `InternalRestriction` - Order restrictions apply
|
|
263
|
+
- `InsufficientBalance` - Not enough balance
|
|
264
|
+
- `EventNotFound` - Event doesn't exist
|
|
265
|
+
- `NotFound` - Resource not found
|
|
266
|
+
|
|
267
|
+
## TypeScript Support
|
|
268
|
+
|
|
269
|
+
The SDK provides full TypeScript support with auto-generated types from the OpenAPI specification:
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
import type { paths, components } from "@wahoopredict/trading-sdk";
|
|
273
|
+
|
|
274
|
+
// Use component types
|
|
275
|
+
type Event = components["schemas"]["Event"];
|
|
276
|
+
type Order = components["schemas"]["Order"];
|
|
277
|
+
type Position = components["schemas"]["Position"];
|
|
278
|
+
|
|
279
|
+
// Use path types for custom implementations
|
|
280
|
+
type PlaceOrderBody =
|
|
281
|
+
paths["/event/place-order"]["post"]["requestBody"]["content"]["application/json"];
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Configuration
|
|
285
|
+
|
|
286
|
+
### Custom Base URL
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
const client = createWahooClient({
|
|
290
|
+
apiKey: "your-api-key",
|
|
291
|
+
secretKey: "your-secret-key",
|
|
292
|
+
baseUrl: "https://staging-api.wahoopredict.com/oapi/v2", // Optional
|
|
293
|
+
});
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Environment Variables
|
|
297
|
+
|
|
298
|
+
We recommend storing credentials in environment variables:
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
const client = createWahooClient({
|
|
302
|
+
apiKey: process.env.WAHOO_API_KEY!,
|
|
303
|
+
secretKey: process.env.WAHOO_SECRET_KEY!,
|
|
304
|
+
});
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## License
|
|
308
|
+
|
|
309
|
+
MIT
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get DEFAULT_BASE_URL () {
|
|
13
|
+
return DEFAULT_BASE_URL;
|
|
14
|
+
},
|
|
15
|
+
get createAuthMiddleware () {
|
|
16
|
+
return createAuthMiddleware;
|
|
17
|
+
},
|
|
18
|
+
get /**
|
|
19
|
+
* Creates a type-safe WahooPredict API client
|
|
20
|
+
*
|
|
21
|
+
* @param config - Configuration options including API credentials
|
|
22
|
+
* @returns A configured openapi-fetch client with authentication
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* import { createWahooClient } from '@wahoopredict/trading-sdk';
|
|
27
|
+
*
|
|
28
|
+
* const client = createWahooClient({
|
|
29
|
+
* apiKey: 'your-api-key',
|
|
30
|
+
* secretKey: 'your-secret-key',
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* // Get user profile
|
|
34
|
+
* const { data, error } = await client.GET('/user/profile', {
|
|
35
|
+
* params: { query: { fields: ['balance'] } },
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/ default () {
|
|
39
|
+
return createWahooClient;
|
|
40
|
+
},
|
|
41
|
+
get generateSignature () {
|
|
42
|
+
return generateSignature;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
const _openapifetch = /*#__PURE__*/ _interop_require_default(require("openapi-fetch"));
|
|
46
|
+
const _nodecrypto = /*#__PURE__*/ _interop_require_wildcard(require("node:crypto"));
|
|
47
|
+
function _interop_require_default(obj) {
|
|
48
|
+
return obj && obj.__esModule ? obj : {
|
|
49
|
+
default: obj
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
53
|
+
if (typeof WeakMap !== "function") return null;
|
|
54
|
+
var cacheBabelInterop = new WeakMap();
|
|
55
|
+
var cacheNodeInterop = new WeakMap();
|
|
56
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
57
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
58
|
+
})(nodeInterop);
|
|
59
|
+
}
|
|
60
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
61
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
62
|
+
return obj;
|
|
63
|
+
}
|
|
64
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
65
|
+
return {
|
|
66
|
+
default: obj
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
70
|
+
if (cache && cache.has(obj)) {
|
|
71
|
+
return cache.get(obj);
|
|
72
|
+
}
|
|
73
|
+
var newObj = {
|
|
74
|
+
__proto__: null
|
|
75
|
+
};
|
|
76
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
77
|
+
for(var key in obj){
|
|
78
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
79
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
80
|
+
if (desc && (desc.get || desc.set)) {
|
|
81
|
+
Object.defineProperty(newObj, key, desc);
|
|
82
|
+
} else {
|
|
83
|
+
newObj[key] = obj[key];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
newObj.default = obj;
|
|
88
|
+
if (cache) {
|
|
89
|
+
cache.set(obj, newObj);
|
|
90
|
+
}
|
|
91
|
+
return newObj;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Default base URL for the WahooPredict API
|
|
95
|
+
*/ const DEFAULT_BASE_URL = "https://api.wahoopredict.com/oapi/v2";
|
|
96
|
+
/**
|
|
97
|
+
* Configuration options for the WahooPredict client
|
|
98
|
+
*/ /** Your API key from WahooPredict */ /** Your secret key for signing requests */ /** Optional custom base URL (defaults to production API) */ /**
|
|
99
|
+
* Generates HMAC-SHA256 signature for API authentication
|
|
100
|
+
*/ function generateSignature(apiKey, secretKey, timestamp, requestBody) {
|
|
101
|
+
const dataToSign = `${apiKey}${timestamp}${requestBody}`;
|
|
102
|
+
return _nodecrypto.createHmac("sha256", secretKey).update(dataToSign).digest("hex");
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Creates an authentication middleware for the WahooPredict API
|
|
106
|
+
*/ function createAuthMiddleware(apiKey, secretKey) {
|
|
107
|
+
return {
|
|
108
|
+
async onRequest ({ request }) {
|
|
109
|
+
const timestamp = Math.round(Date.now() / 1000);
|
|
110
|
+
const urlParts = request.url.split("?");
|
|
111
|
+
const rawQuery = urlParts.length > 1 ? urlParts[1] : "";
|
|
112
|
+
const rawBody = await request.clone().text();
|
|
113
|
+
const requestBody = rawQuery && rawBody ? `${rawQuery}${rawBody}` : rawQuery || rawBody;
|
|
114
|
+
const signature = generateSignature(apiKey, secretKey, timestamp, requestBody);
|
|
115
|
+
request.headers.set("X-API-KEY", apiKey);
|
|
116
|
+
request.headers.set("X-TIMESTAMP", timestamp.toString());
|
|
117
|
+
request.headers.set("X-SIGNATURE", signature);
|
|
118
|
+
return request;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function createWahooClient(config) {
|
|
123
|
+
const { apiKey, secretKey, baseUrl = DEFAULT_BASE_URL } = config;
|
|
124
|
+
const client = (0, _openapifetch.default)({
|
|
125
|
+
baseUrl
|
|
126
|
+
});
|
|
127
|
+
client.use(createAuthMiddleware(apiKey, secretKey));
|
|
128
|
+
return client;
|
|
129
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
const _globals = require("@jest/globals");
|
|
6
|
+
const _client = /*#__PURE__*/ _interop_require_wildcard(require("./client.js"));
|
|
7
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
8
|
+
if (typeof WeakMap !== "function") return null;
|
|
9
|
+
var cacheBabelInterop = new WeakMap();
|
|
10
|
+
var cacheNodeInterop = new WeakMap();
|
|
11
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
12
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
13
|
+
})(nodeInterop);
|
|
14
|
+
}
|
|
15
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
16
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
17
|
+
return obj;
|
|
18
|
+
}
|
|
19
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
20
|
+
return {
|
|
21
|
+
default: obj
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
25
|
+
if (cache && cache.has(obj)) {
|
|
26
|
+
return cache.get(obj);
|
|
27
|
+
}
|
|
28
|
+
var newObj = {
|
|
29
|
+
__proto__: null
|
|
30
|
+
};
|
|
31
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
32
|
+
for(var key in obj){
|
|
33
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
34
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
35
|
+
if (desc && (desc.get || desc.set)) {
|
|
36
|
+
Object.defineProperty(newObj, key, desc);
|
|
37
|
+
} else {
|
|
38
|
+
newObj[key] = obj[key];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
newObj.default = obj;
|
|
43
|
+
if (cache) {
|
|
44
|
+
cache.set(obj, newObj);
|
|
45
|
+
}
|
|
46
|
+
return newObj;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Creates mock middleware callback params for testing
|
|
50
|
+
*/ function createMockMiddlewareParams(request, schemaPath) {
|
|
51
|
+
return {
|
|
52
|
+
request,
|
|
53
|
+
params: {},
|
|
54
|
+
schemaPath,
|
|
55
|
+
id: "test-request-id",
|
|
56
|
+
options: {
|
|
57
|
+
baseUrl: "https://api.wahoopredict.com/oapi/v2",
|
|
58
|
+
parseAs: "json",
|
|
59
|
+
querySerializer: (query)=>new URLSearchParams(query).toString(),
|
|
60
|
+
bodySerializer: (body)=>JSON.stringify(body),
|
|
61
|
+
fetch: globalThis.fetch
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
(0, _globals.describe)("generateSignature", ()=>{
|
|
66
|
+
(0, _globals.it)("should generate consistent HMAC-SHA256 signature", ()=>{
|
|
67
|
+
const apiKey = "test-api-key";
|
|
68
|
+
const secretKey = "test-secret-key";
|
|
69
|
+
const timestamp = 1704067200;
|
|
70
|
+
// 2024-01-01 00:00:00 UTC
|
|
71
|
+
const requestBody = '{"test":"data"}';
|
|
72
|
+
const signature = (0, _client.generateSignature)(apiKey, secretKey, timestamp, requestBody);
|
|
73
|
+
// Signature should be a hex string of 64 characters (256 bits = 32 bytes = 64 hex chars)
|
|
74
|
+
(0, _globals.expect)(signature).toMatch(/^[a-f0-9]{64}$/);
|
|
75
|
+
// Same inputs should produce same output
|
|
76
|
+
const signature2 = (0, _client.generateSignature)(apiKey, secretKey, timestamp, requestBody);
|
|
77
|
+
(0, _globals.expect)(signature).toBe(signature2);
|
|
78
|
+
});
|
|
79
|
+
(0, _globals.it)("should produce different signatures for different inputs", ()=>{
|
|
80
|
+
const apiKey = "test-api-key";
|
|
81
|
+
const secretKey = "test-secret-key";
|
|
82
|
+
const timestamp = 1704067200;
|
|
83
|
+
const sig1 = (0, _client.generateSignature)(apiKey, secretKey, timestamp, '{"a":"1"}');
|
|
84
|
+
const sig2 = (0, _client.generateSignature)(apiKey, secretKey, timestamp, '{"a":"2"}');
|
|
85
|
+
(0, _globals.expect)(sig1).not.toBe(sig2);
|
|
86
|
+
});
|
|
87
|
+
(0, _globals.it)("should handle empty request body", ()=>{
|
|
88
|
+
const apiKey = "test-api-key";
|
|
89
|
+
const secretKey = "test-secret-key";
|
|
90
|
+
const timestamp = 1704067200;
|
|
91
|
+
const signature = (0, _client.generateSignature)(apiKey, secretKey, timestamp, "");
|
|
92
|
+
(0, _globals.expect)(signature).toMatch(/^[a-f0-9]{64}$/);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
(0, _globals.describe)("createAuthMiddleware", ()=>{
|
|
96
|
+
(0, _globals.it)("should create middleware that adds auth headers", async ()=>{
|
|
97
|
+
const apiKey = "test-api-key";
|
|
98
|
+
const secretKey = "test-secret-key";
|
|
99
|
+
const middleware = (0, _client.createAuthMiddleware)(apiKey, secretKey);
|
|
100
|
+
// Create a mock request
|
|
101
|
+
const mockRequest = new Request("https://api.wahoopredict.com/oapi/v2/user/profile", {
|
|
102
|
+
method: "GET"
|
|
103
|
+
});
|
|
104
|
+
const result = await middleware.onRequest(createMockMiddlewareParams(mockRequest, "/user/profile"));
|
|
105
|
+
(0, _globals.expect)(result).toBeInstanceOf(Request);
|
|
106
|
+
const resultRequest = result;
|
|
107
|
+
(0, _globals.expect)(resultRequest.headers.get("X-API-KEY")).toBe(apiKey);
|
|
108
|
+
(0, _globals.expect)(resultRequest.headers.get("X-TIMESTAMP")).toMatch(/^\d+$/);
|
|
109
|
+
(0, _globals.expect)(resultRequest.headers.get("X-SIGNATURE")).toMatch(/^[a-f0-9]{64}$/);
|
|
110
|
+
});
|
|
111
|
+
(0, _globals.it)("should include request body in signature calculation", async ()=>{
|
|
112
|
+
const apiKey = "test-api-key";
|
|
113
|
+
const secretKey = "test-secret-key";
|
|
114
|
+
const middleware = (0, _client.createAuthMiddleware)(apiKey, secretKey);
|
|
115
|
+
const body = JSON.stringify({
|
|
116
|
+
eventId: "test-event"
|
|
117
|
+
});
|
|
118
|
+
const mockRequest = new Request("https://api.wahoopredict.com/oapi/v2/event/place-order", {
|
|
119
|
+
method: "POST",
|
|
120
|
+
body,
|
|
121
|
+
headers: {
|
|
122
|
+
"Content-Type": "application/json"
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
const result = await middleware.onRequest(createMockMiddlewareParams(mockRequest, "/event/place-order"));
|
|
126
|
+
const resultRequest = result;
|
|
127
|
+
(0, _globals.expect)(resultRequest.headers.get("X-SIGNATURE")).toMatch(/^[a-f0-9]{64}$/);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
(0, _globals.describe)("createWahooClient", ()=>{
|
|
131
|
+
(0, _globals.it)("should create client with default base URL", ()=>{
|
|
132
|
+
const client = (0, _client.default)({
|
|
133
|
+
apiKey: "test-api-key",
|
|
134
|
+
secretKey: "test-secret-key"
|
|
135
|
+
});
|
|
136
|
+
(0, _globals.expect)(client).toBeDefined();
|
|
137
|
+
(0, _globals.expect)(client.GET).toBeDefined();
|
|
138
|
+
(0, _globals.expect)(client.POST).toBeDefined();
|
|
139
|
+
(0, _globals.expect)(client.DELETE).toBeDefined();
|
|
140
|
+
});
|
|
141
|
+
(0, _globals.it)("should create client with custom base URL", ()=>{
|
|
142
|
+
const customUrl = "https://custom.api.com/v2";
|
|
143
|
+
const client = (0, _client.default)({
|
|
144
|
+
apiKey: "test-api-key",
|
|
145
|
+
secretKey: "test-secret-key",
|
|
146
|
+
baseUrl: customUrl
|
|
147
|
+
});
|
|
148
|
+
(0, _globals.expect)(client).toBeDefined();
|
|
149
|
+
});
|
|
150
|
+
(0, _globals.it)("should export DEFAULT_BASE_URL", ()=>{
|
|
151
|
+
(0, _globals.expect)(_client.DEFAULT_BASE_URL).toBe("https://api.wahoopredict.com/oapi/v2");
|
|
152
|
+
});
|
|
153
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get DEFAULT_BASE_URL () {
|
|
13
|
+
return _client.DEFAULT_BASE_URL;
|
|
14
|
+
},
|
|
15
|
+
get createAuthMiddleware () {
|
|
16
|
+
return _client.createAuthMiddleware;
|
|
17
|
+
},
|
|
18
|
+
get /**
|
|
19
|
+
* WahooPredict Trading SDK
|
|
20
|
+
*
|
|
21
|
+
* TypeScript SDK for the WahooPredict trading API.
|
|
22
|
+
* Built on top of openapi-fetch for type-safe API calls.
|
|
23
|
+
*/ createWahooClient () {
|
|
24
|
+
return _client.default;
|
|
25
|
+
},
|
|
26
|
+
get generateSignature () {
|
|
27
|
+
return _client.generateSignature;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
const _client = /*#__PURE__*/ _interop_require_wildcard(require("./client.js" // Re-export useful types from openapi-fetch
|
|
31
|
+
));
|
|
32
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
33
|
+
if (typeof WeakMap !== "function") return null;
|
|
34
|
+
var cacheBabelInterop = new WeakMap();
|
|
35
|
+
var cacheNodeInterop = new WeakMap();
|
|
36
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
37
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
38
|
+
})(nodeInterop);
|
|
39
|
+
}
|
|
40
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
41
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
42
|
+
return obj;
|
|
43
|
+
}
|
|
44
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
45
|
+
return {
|
|
46
|
+
default: obj
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
50
|
+
if (cache && cache.has(obj)) {
|
|
51
|
+
return cache.get(obj);
|
|
52
|
+
}
|
|
53
|
+
var newObj = {
|
|
54
|
+
__proto__: null
|
|
55
|
+
};
|
|
56
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
57
|
+
for(var key in obj){
|
|
58
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
59
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
60
|
+
if (desc && (desc.get || desc.set)) {
|
|
61
|
+
Object.defineProperty(newObj, key, desc);
|
|
62
|
+
} else {
|
|
63
|
+
newObj[key] = obj[key];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
newObj.default = obj;
|
|
68
|
+
if (cache) {
|
|
69
|
+
cache.set(obj, newObj);
|
|
70
|
+
}
|
|
71
|
+
return newObj;
|
|
72
|
+
}
|