@outcome.xyz/hip4 1.0.0-beta
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 +101 -0
- package/README.md +224 -0
- package/dist/index-ubGjjLVg.d.cts +799 -0
- package/dist/index-ubGjjLVg.d.ts +799 -0
- package/dist/index.cjs +4244 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1058 -0
- package/dist/index.d.ts +1058 -0
- package/dist/index.js +4169 -0
- package/dist/index.js.map +1 -0
- package/dist/types.cjs +4 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +82 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
Business Source License 1.1
|
|
2
|
+
|
|
3
|
+
License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
|
|
4
|
+
"Business Source License" is a trademark of MariaDB Corporation Ab.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Parameters
|
|
9
|
+
|
|
10
|
+
Licensor: Outcome Labs
|
|
11
|
+
|
|
12
|
+
Licensed Work: @outcome.xyz/hip4 v1.0.0-beta (all prior and subsequent versions included)
|
|
13
|
+
The Licensed Work is (c) 2026 Outcome Labs.
|
|
14
|
+
|
|
15
|
+
Additional Use Grant: You may make use of the Licensed Work, provided that
|
|
16
|
+
you may not use the Licensed Work for a Production Use.
|
|
17
|
+
|
|
18
|
+
A "Production Use" is any use of the Licensed Work that
|
|
19
|
+
makes the Licensed Work available to third parties as
|
|
20
|
+
part of a commercial or non-commercial product,
|
|
21
|
+
service, or application, including but not limited to:
|
|
22
|
+
(a) incorporating the Licensed Work into a product or
|
|
23
|
+
service that is offered to third parties;
|
|
24
|
+
(b) using the Licensed Work to operate a service
|
|
25
|
+
accessible by third parties;
|
|
26
|
+
(c) distributing the Licensed Work or derivative works
|
|
27
|
+
to third parties.
|
|
28
|
+
|
|
29
|
+
For purposes of clarity, the following are permitted
|
|
30
|
+
under this license without a separate commercial
|
|
31
|
+
agreement:
|
|
32
|
+
(i) internal evaluation and testing;
|
|
33
|
+
(ii) non-production development and prototyping;
|
|
34
|
+
(iii) academic and educational use;
|
|
35
|
+
(iv) personal, non-commercial projects that are not
|
|
36
|
+
offered as a service to third parties.
|
|
37
|
+
|
|
38
|
+
Any Production Use requires a separate commercial
|
|
39
|
+
license from the Licensor. Contact: support@outcomelabs.xyz
|
|
40
|
+
|
|
41
|
+
A standing perpetual exception to the foregoing
|
|
42
|
+
restriction, granted to the Outcome project, its
|
|
43
|
+
operating entity Outcome Labs, and the Outcome
|
|
44
|
+
open source community, is set out in the file
|
|
45
|
+
LICENSE.OUTCOME-EXCEPTION distributed alongside
|
|
46
|
+
this License. That exception forms part of the
|
|
47
|
+
Licensor's grants under this License.
|
|
48
|
+
|
|
49
|
+
Change Date: May 19, 2028
|
|
50
|
+
|
|
51
|
+
Change License: MIT License
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
Terms
|
|
56
|
+
|
|
57
|
+
The Licensor hereby grants you the right to copy, modify, create derivative
|
|
58
|
+
works, redistribute, and make non-production use of the Licensed Work. The
|
|
59
|
+
Licensor may make an Additional Use Grant, above, permitting limited
|
|
60
|
+
production use.
|
|
61
|
+
|
|
62
|
+
Effective on the Change Date, or the fourth anniversary of the first publicly
|
|
63
|
+
available distribution of a specific version of the Licensed Work under this
|
|
64
|
+
License, whichever comes first, the Licensor hereby grants you rights under
|
|
65
|
+
the terms of the Change License, and the rights granted in the paragraph
|
|
66
|
+
above terminate.
|
|
67
|
+
|
|
68
|
+
If your use of the Licensed Work does not comply with the requirements
|
|
69
|
+
currently in effect as described in this License, you must purchase a
|
|
70
|
+
commercial license from the Licensor, its affiliated entities, or authorized
|
|
71
|
+
resellers, or you must refrain from using the Licensed Work.
|
|
72
|
+
|
|
73
|
+
All copies of the original and modified Licensed Work, and derivative works
|
|
74
|
+
of the Licensed Work, are subject to this License. This License applies
|
|
75
|
+
separately for each version of the Licensed Work and the Change Date may vary
|
|
76
|
+
for each version of the Licensed Work released by Licensor.
|
|
77
|
+
|
|
78
|
+
You must conspicuously display this License on each original or modified copy
|
|
79
|
+
of the Licensed Work. If you receive the Licensed Work in original or
|
|
80
|
+
modified form from a third party, the terms and conditions set forth in this
|
|
81
|
+
License apply to your use of that work.
|
|
82
|
+
|
|
83
|
+
Any use of the Licensed Work in violation of this License will automatically
|
|
84
|
+
terminate your rights under this License for the current and all other
|
|
85
|
+
versions of the Licensed Work.
|
|
86
|
+
|
|
87
|
+
This License does not grant you any right in any trademark or logo of
|
|
88
|
+
Licensor or its affiliates (provided that you may use a trademark or logo
|
|
89
|
+
of Licensor as expressly required by this License).
|
|
90
|
+
|
|
91
|
+
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED
|
|
92
|
+
ON AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND
|
|
93
|
+
CONDITIONS, EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES
|
|
94
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT,
|
|
95
|
+
AND TITLE.
|
|
96
|
+
|
|
97
|
+
IN NO EVENT WILL LICENSOR BE LIABLE FOR ANY DAMAGES, WHETHER DIRECT,
|
|
98
|
+
INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR
|
|
99
|
+
IN CONNECTION WITH THIS LICENSE OR THE USE OR INABILITY TO USE THE
|
|
100
|
+
LICENSED WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF
|
|
101
|
+
SUCH DAMAGES.
|
package/README.md
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="./assets/outcome-icon-light.svg" alt="@outcome.xyz/hip4" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">@outcome.xyz/hip4</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/@outcome.xyz/hip4"><img src="https://img.shields.io/npm/v/@outcome.xyz/hip4.svg" alt="npm version" /></a>
|
|
9
|
+
<img src="https://img.shields.io/badge/dependencies-0-brightgreen" alt="zero dependencies" />
|
|
10
|
+
<img src="https://img.shields.io/npm/l/@outcome.xyz/hip4" alt="license" />
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
TypeScript SDK for Hyperliquid HIP-4 prediction markets. Zero runtime dependencies.
|
|
16
|
+
|
|
17
|
+
## Built for developers
|
|
18
|
+
|
|
19
|
+
The SDK is structured around a single adapter with typed sub-modules for each domain - events, market data, account state, trading, wallet, and auth. Everything returns typed responses, WebSocket subscriptions return unsubscribe functions, and all signing (L1 agent + EIP-712) is handled internally with no external crypto dependencies.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pnpm add @outcome.xyz/hip4
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { createHIP4Adapter } from "@outcome.xyz/hip4";
|
|
27
|
+
|
|
28
|
+
const hip4 = createHIP4Adapter({ testnet: true });
|
|
29
|
+
await hip4.initialize();
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Examples
|
|
33
|
+
|
|
34
|
+
- [`auth-eoa.ts`](examples/auth-eoa.ts) - Agent key approval and auth setup
|
|
35
|
+
- [`get-all-markets.ts`](examples/get-all-markets.ts) - Fetch all markets grouped by type
|
|
36
|
+
- [`get-multi-outcome.ts`](examples/get-multi-outcome.ts) - Multi-outcome markets with live prices
|
|
37
|
+
- [`get-recurring-markets.ts`](examples/get-recurring-markets.ts) - Recurring markets with expiry countdowns
|
|
38
|
+
- [`place-limit-order.ts`](examples/place-limit-order.ts) - Limit order with price validation
|
|
39
|
+
- [`place-market-order.ts`](examples/place-market-order.ts) - Market order with FrontendMarket TIF
|
|
40
|
+
- [`stream-prices.ts`](examples/stream-prices.ts) - Stream live prices via WebSocket
|
|
41
|
+
- [`usdh-ramp.ts`](examples/usdh-ramp.ts) - End-to-end USDH on/off-ramp via Coinbase + Across
|
|
42
|
+
|
|
43
|
+
## API
|
|
44
|
+
|
|
45
|
+
### `hip4.events`
|
|
46
|
+
|
|
47
|
+
| Method | Description |
|
|
48
|
+
| -------------------------------- | ------------------------------------------------------------------------ |
|
|
49
|
+
| `fetchEvents(params?)` | List events. Filters: `category`, `active`, `limit`, `offset`, `query` |
|
|
50
|
+
| `fetchEvent(eventId)` | Single event by ID |
|
|
51
|
+
| `fetchCategories()` | Available categories |
|
|
52
|
+
| `fetchMarkets(params?)` | Typed HIP-4 markets with optional grouping by type or question |
|
|
53
|
+
| `fetchSettledOutcome(outcomeId)` | Settlement details for a resolved outcome. Returns `null` if not settled |
|
|
54
|
+
|
|
55
|
+
### `hip4.marketData`
|
|
56
|
+
|
|
57
|
+
| Method | Description |
|
|
58
|
+
| ------------------------------------------------- | --------------------------------------------- |
|
|
59
|
+
| `fetchOrderBook(marketId, sideIndex?)` | L2 snapshot |
|
|
60
|
+
| `fetchPrice(marketId)` | Both sides, 5s cache |
|
|
61
|
+
| `fetchTrades(marketId, limit?)` | Recent trades |
|
|
62
|
+
| `fetchCandles(marketId, interval?, start?, end?)` | OHLCV candles |
|
|
63
|
+
| `subscribeOrderBook(marketId, cb)` | Real-time L2 book |
|
|
64
|
+
| `subscribePrice(marketId, cb)` | Real-time prices |
|
|
65
|
+
| `subscribeTrades(marketId, cb)` | Real-time trades |
|
|
66
|
+
| `subscribeAllMids(cb)` | All mid-prices across every market |
|
|
67
|
+
| `subscribeActiveAssetCtx(coin, cb)` | Per-spot-coin context (vol, OI, mark) |
|
|
68
|
+
| `subscribeSpotAssetCtxs(cb)` | Bulk spot-asset context updates |
|
|
69
|
+
| `subscribePerpAssetCtx(coin, cb)` | Per-perp-coin context (mark, oracle, funding) |
|
|
70
|
+
|
|
71
|
+
### `hip4.account`
|
|
72
|
+
|
|
73
|
+
| Method | Description |
|
|
74
|
+
| --------------------------------- | ------------------------------------------ |
|
|
75
|
+
| `fetchPositions(address)` | Outcome positions with resolved side names |
|
|
76
|
+
| `fetchActivity(address)` | Fills, last 30 days |
|
|
77
|
+
| `fetchBalance(address)` | Spot balances |
|
|
78
|
+
| `fetchOpenOrders(address)` | Resting orders |
|
|
79
|
+
| `subscribePositions(address, cb)` | Polling at 10s |
|
|
80
|
+
|
|
81
|
+
### `hip4.trading`
|
|
82
|
+
|
|
83
|
+
| Method | Description |
|
|
84
|
+
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
85
|
+
| `placeOrder(params)` | Place market or limit order. Returns `{ success, orderId?, error? }` |
|
|
86
|
+
| `placeOrders(params[])` | Batch place orders in a single signed request |
|
|
87
|
+
| `modifyOrder(params)` | Modify a resting order (price and/or size); preserves queue priority on size-only edits |
|
|
88
|
+
| `cancelOrder(params[])` | Cancel one or more resting orders. Returns `HLCancelResponse` |
|
|
89
|
+
| `scheduleCancel(time)` | Dead-man's switch - registers a future timestamp at which HL cancels every open order from this agent. Pass `null` to clear |
|
|
90
|
+
| `splitOutcome(params)` | Split X quote tokens into X Yes + X No shares of one outcome |
|
|
91
|
+
| `mergeOutcome(params)` | Merge X paired Yes+No shares back into X quote tokens |
|
|
92
|
+
| `mergeQuestion(params)` | Merge X Yes shares from every outcome of a question into X quote tokens |
|
|
93
|
+
| `negateOutcome(params)` | Convert X No shares of one outcome into X Yes shares of every other outcome in the question |
|
|
94
|
+
|
|
95
|
+
### `hip4.wallet`
|
|
96
|
+
|
|
97
|
+
| Method | Signing | Description |
|
|
98
|
+
| ----------------------------------- | -------- | ------------------------------- |
|
|
99
|
+
| `setSigner(signer)` | - | Set user wallet for EIP-712 ops |
|
|
100
|
+
| `buyUsdh(amount)` | L1 agent | Buy USDH on spot |
|
|
101
|
+
| `sellUsdh(amount)` | L1 agent | Sell USDH on spot |
|
|
102
|
+
| `transferToSpot(amount)` | EIP-712 | Perp -> Spot |
|
|
103
|
+
| `transferToPerps(amount)` | EIP-712 | Spot -> Perp |
|
|
104
|
+
| `withdraw({ destination, amount })` | EIP-712 | Withdraw to external address |
|
|
105
|
+
| `usdSend({ destination, amount })` | EIP-712 | Send to another HL address |
|
|
106
|
+
|
|
107
|
+
### `hip4.auth`
|
|
108
|
+
|
|
109
|
+
| Method | Description |
|
|
110
|
+
| --------------------------------- | --------------------------------------------------- |
|
|
111
|
+
| `initAuth(walletAddress, signer)` | Accepts viem `PrivateKeyAccount` or ethers `Signer` |
|
|
112
|
+
| `getAuthStatus()` | `"disconnected" \| "pending_approval" \| "ready"` |
|
|
113
|
+
| `clearAuth()` | Reset auth state |
|
|
114
|
+
|
|
115
|
+
## Market Types
|
|
116
|
+
|
|
117
|
+
`fetchMarkets()` classifies every HIP-4 outcome into one of four types:
|
|
118
|
+
|
|
119
|
+
| Type | Description | Parsed Fields |
|
|
120
|
+
| ---------------- | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
|
|
121
|
+
| `defaultBinary` | Recurring price markets (BTC > $67250 1d) | `underlying`, `targetPrice`, `expiry`, `period` |
|
|
122
|
+
| `labelledBinary` | Standalone binary with custom sides (Hypurr vs Usain Bolt) | Custom side labels |
|
|
123
|
+
| `multiOutcome` | Grouped under a question, with fallback | `questionId`, `questionName`, `isFallback` |
|
|
124
|
+
| `priceBucket` | Recurring multi-bucket price markets (per-bucket Yes/No) | `underlying`, `expiry`, `priceThresholds`, `period`, `bucketIndex`, `lowerBound`, `upperBound` |
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
// Filter by type
|
|
128
|
+
const binaries = await hip4.events.fetchMarkets({ type: "defaultBinary" });
|
|
129
|
+
|
|
130
|
+
// Group by type
|
|
131
|
+
const grouped = await hip4.events.fetchMarkets({ groupBy: "type" });
|
|
132
|
+
|
|
133
|
+
// Group multi-outcome by question
|
|
134
|
+
const byQuestion = await hip4.events.fetchMarkets({ groupBy: "question" });
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Configuration
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
const hip4 = createHIP4Adapter({
|
|
141
|
+
testnet: true,
|
|
142
|
+
// Builder fee - collected on every order placed by this adapter
|
|
143
|
+
builderAddress: "0xYourBuilderAddress",
|
|
144
|
+
builderFee: 100, // 0.1% (tenths of a basis point, 0–1000)
|
|
145
|
+
logger: (level, msg, data) => console.log(level, msg, data),
|
|
146
|
+
});
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Per-order builder address/fee can also be passed on `placeOrder` to override the adapter-level config.
|
|
150
|
+
|
|
151
|
+
## Streams
|
|
152
|
+
|
|
153
|
+
Drop-in price feeds backed by HL's WebSocket. Each takes a callback and returns an unsubscribe function. The snapshot includes the rolling candle history plus the current mid.
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
import { createPriceFeed, createPerpPriceFeed } from "@outcome.xyz/hip4";
|
|
157
|
+
|
|
158
|
+
// HIP-4 outcome side (uses sideIndex 0 by default)
|
|
159
|
+
const unsub = createPriceFeed(
|
|
160
|
+
hip4.marketData,
|
|
161
|
+
"1758",
|
|
162
|
+
(snapshot) => console.log(snapshot.currentMid, snapshot.candles),
|
|
163
|
+
{ interval: "1h" },
|
|
164
|
+
);
|
|
165
|
+
unsub();
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
| Helper | Use |
|
|
169
|
+
| ---------------------------------------------------------- | ------------------------------------------------------------------ |
|
|
170
|
+
| `createPriceFeed(marketData, marketId, onSnapshot, opts?)` | Live mid + tick-aggregated candle history for a HIP-4 outcome side |
|
|
171
|
+
| `createPerpPriceFeed(client, coin, onSnapshot, opts?)` | Same shape for an HL perp coin |
|
|
172
|
+
| `processTick`, `candleBoundaryMs`, `intervalToMs` | Lower-level candle utilities |
|
|
173
|
+
|
|
174
|
+
## USDH on/off-ramp (mainnet)
|
|
175
|
+
|
|
176
|
+
Built-in fiat ↔ USDH ramp via Coinbase + Across. Buy: fiat → Coinbase onramp → USDC (Arbitrum) → Across counterfactual → USDH (HyperCore). Sell: USDH (HyperEVM) → Across swap → USDC (Arbitrum) → Coinbase offramp → fiat. See [`examples/usdh-ramp.ts`](examples/usdh-ramp.ts) for the full flow.
|
|
177
|
+
|
|
178
|
+
## Orderbook utilities
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
import {
|
|
182
|
+
computeTradeCost,
|
|
183
|
+
computeEstimatedCost,
|
|
184
|
+
computePotentialReturn,
|
|
185
|
+
} from "@outcome.xyz/hip4";
|
|
186
|
+
|
|
187
|
+
const cost = computeTradeCost({
|
|
188
|
+
tokenAmount: 100,
|
|
189
|
+
orderType: "limit",
|
|
190
|
+
limitPriceCents: 55, // 0.55 in cents
|
|
191
|
+
});
|
|
192
|
+
// → { estimatedCost, potentialReturn, displayShares }
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Signing
|
|
196
|
+
|
|
197
|
+
Both Hyperliquid signing flows are implemented from scratch.
|
|
198
|
+
|
|
199
|
+
**L1 agent signing** (orders, cancels, USDH spot):
|
|
200
|
+
|
|
201
|
+
1. Sort action keys in canonical order
|
|
202
|
+
2. MessagePack encode
|
|
203
|
+
3. Append nonce as BE u64
|
|
204
|
+
4. Append vault marker byte
|
|
205
|
+
5. Keccak-256 hash -> `connectionId`
|
|
206
|
+
6. EIP-712 sign with `Agent` type on chainId `1337`
|
|
207
|
+
|
|
208
|
+
**User-signed EIP-712** (transfers, withdrawals, sends):
|
|
209
|
+
|
|
210
|
+
- Domain: `HyperliquidSignTransaction`, `signatureChainId: 0x66eee`
|
|
211
|
+
- Message filtered to EIP-712 type keys only
|
|
212
|
+
- Requires user wallet, agent keys rejected
|
|
213
|
+
|
|
214
|
+
## Acknowledgements
|
|
215
|
+
|
|
216
|
+
Signing implementation inspired by [@nktkas/hyperliquid](https://github.com/nktkas/hyperliquid).
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
BUSL-1.1
|
|
221
|
+
|
|
222
|
+
## Builders
|
|
223
|
+
|
|
224
|
+
Dennis Furrer
|