@imbingox/acex 0.1.0 → 0.2.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.
Files changed (85) hide show
  1. package/README.md +92 -285
  2. package/index.ts +1 -0
  3. package/package.json +40 -23
  4. package/src/adapters/binance/adapter.ts +80 -0
  5. package/src/adapters/binance/book-ticker.ts +123 -0
  6. package/src/adapters/binance/mark-price.ts +126 -0
  7. package/src/adapters/binance/market-catalog.ts +258 -0
  8. package/src/adapters/binance/private-adapter.ts +833 -0
  9. package/src/adapters/types.ts +219 -0
  10. package/src/client/context.ts +123 -0
  11. package/src/client/create-client.ts +6 -0
  12. package/src/client/private-subscription-coordinator.ts +512 -0
  13. package/src/client/runtime.ts +410 -0
  14. package/src/errors.ts +27 -0
  15. package/src/index.ts +5 -0
  16. package/src/internal/async-event-bus.ts +100 -0
  17. package/src/internal/filters.ts +117 -0
  18. package/src/internal/managed-websocket.ts +280 -0
  19. package/src/managers/account-manager.ts +609 -0
  20. package/src/managers/market-manager.ts +889 -0
  21. package/src/managers/order-manager.ts +685 -0
  22. package/src/types/account.ts +157 -0
  23. package/src/types/client.ts +79 -0
  24. package/src/types/index.ts +5 -0
  25. package/src/types/market.ts +150 -0
  26. package/src/types/order.ts +177 -0
  27. package/src/types/shared.ts +93 -0
  28. package/dist/adapters/binance/composite-adapter.d.ts +0 -116
  29. package/dist/adapters/binance/composite-adapter.js +0 -121
  30. package/dist/adapters/binance/market-types.d.ts +0 -63
  31. package/dist/adapters/binance/market-types.js +0 -1
  32. package/dist/adapters/binance/native-market-adapter.d.ts +0 -102
  33. package/dist/adapters/binance/native-market-adapter.js +0 -455
  34. package/dist/adapters/binance/normalizers.d.ts +0 -8
  35. package/dist/adapters/binance/normalizers.js +0 -123
  36. package/dist/adapters/binance/rest-client.d.ts +0 -17
  37. package/dist/adapters/binance/rest-client.js +0 -66
  38. package/dist/adapters/binance/symbol-router.d.ts +0 -9
  39. package/dist/adapters/binance/symbol-router.js +0 -174
  40. package/dist/adapters/binance/ws-client.d.ts +0 -24
  41. package/dist/adapters/binance/ws-client.js +0 -261
  42. package/dist/adapters/ccxt/aster-ccxt-adapter.d.ts +0 -157
  43. package/dist/adapters/ccxt/aster-ccxt-adapter.js +0 -272
  44. package/dist/adapters/ccxt/binance-usdm-ccxt-adapter.d.ts +0 -180
  45. package/dist/adapters/ccxt/binance-usdm-ccxt-adapter.js +0 -539
  46. package/dist/adapters/ccxt/binance-usdm-exchange.d.ts +0 -22
  47. package/dist/adapters/ccxt/binance-usdm-exchange.js +0 -23
  48. package/dist/adapters/fake/fake-aster-adapter.d.ts +0 -130
  49. package/dist/adapters/fake/fake-aster-adapter.js +0 -283
  50. package/dist/adapters/types.d.ts +0 -210
  51. package/dist/adapters/types.js +0 -1
  52. package/dist/core/client.d.ts +0 -50
  53. package/dist/core/client.js +0 -403
  54. package/dist/core/recovery.d.ts +0 -22
  55. package/dist/core/recovery.js +0 -18
  56. package/dist/core/runtime.d.ts +0 -26
  57. package/dist/core/runtime.js +0 -150
  58. package/dist/errors/acex-error.d.ts +0 -25
  59. package/dist/errors/acex-error.js +0 -54
  60. package/dist/index.d.ts +0 -6
  61. package/dist/index.js +0 -3
  62. package/dist/managers/account-manager.d.ts +0 -41
  63. package/dist/managers/account-manager.js +0 -80
  64. package/dist/managers/market-manager.d.ts +0 -16
  65. package/dist/managers/market-manager.js +0 -28
  66. package/dist/managers/order-manager.d.ts +0 -87
  67. package/dist/managers/order-manager.js +0 -122
  68. package/dist/runtime/async-queue.d.ts +0 -8
  69. package/dist/runtime/async-queue.js +0 -88
  70. package/dist/runtime/request-id.d.ts +0 -1
  71. package/dist/runtime/request-id.js +0 -5
  72. package/dist/runtime/ws-connection-supervisor.d.ts +0 -76
  73. package/dist/runtime/ws-connection-supervisor.js +0 -522
  74. package/dist/store/account-store.d.ts +0 -52
  75. package/dist/store/account-store.js +0 -18
  76. package/dist/store/health-store.d.ts +0 -16
  77. package/dist/store/health-store.js +0 -29
  78. package/dist/store/market-store.d.ts +0 -42
  79. package/dist/store/market-store.js +0 -51
  80. package/dist/store/order-store.d.ts +0 -38
  81. package/dist/store/order-store.js +0 -49
  82. package/dist/testing/create-fake-runtime.d.ts +0 -5
  83. package/dist/testing/create-fake-runtime.js +0 -7
  84. package/dist/types/public.d.ts +0 -5
  85. package/dist/types/public.js +0 -1
package/README.md CHANGED
@@ -1,25 +1,8 @@
1
- # acex
1
+ # @imbingox/acex
2
2
 
3
- `acex` 是一个面向 Bun 的交易 SDK
3
+ `acex` 是一个面向交易场景的 **状态型** 多交易所 SDK。调用方持有一个 `AcexClient`,通过统一的 `market` / `account` / `order` manager 读取最新快照、消费增量事件、执行下单撤单命令;SDK 内部负责本地缓存、ready barrier、websocket 生命周期和自动重连,调用方不需要自己处理。
4
4
 
5
- 当前 public `createClient()` 的可用范围是:
6
-
7
- - 只支持 `binance`
8
- - 只支持单账户
9
- - 默认走 `sandbox: true`
10
- - 当前官方验证环境是 Binance USD-M demo/testnet
11
-
12
- 当前 Binance 路径分为两层:
13
-
14
- - market 行情层已经走 native adapter,支持 `spot`、`USDⓈ-M perpetual`、`COIN-M perpetual`、`COIN-M delivery`
15
- - `subscribeFundingRate()` 只对 perpetual 市场可用
16
- - account / order 仍沿用当前 Binance USD-M private 路径
17
-
18
- 包名:
19
-
20
- ```bash
21
- @imbingox/acex
22
- ```
5
+ 当前 MVP 只落地 Binance(Spot + USDⓈ-M + COIN-M 行情,PAPI UM 私有链路)。
23
6
 
24
7
  ## 安装
25
8
 
@@ -27,333 +10,157 @@
27
10
  bun add @imbingox/acex
28
11
  ```
29
12
 
30
- ## 你会怎么用它
31
-
32
- 典型流程只有 5 步:
13
+ ## 快速上手
33
14
 
34
- 1. `createClient()` 创建客户端
35
- 2. `registerAccount()` 注册账户
36
- 3. `start()` 启动运行时
37
- 4. `subscribe...()` 建立你关心的数据订阅
38
- 5. 用 `get...()` 读取当前最新快照,或用下单 API 发命令
39
-
40
- ## 最小示例
41
-
42
- 下面这段就是当前推荐的接入方式:
15
+ ### 行情(无需凭证)
43
16
 
44
17
  ```ts
45
18
  import { createClient } from "@imbingox/acex";
46
19
 
47
- async function main() {
48
- const client = createClient({
49
- sandbox: true,
50
- });
51
-
52
- await client.registerAccount({
53
- accountId: "main-binance",
54
- exchange: "binance",
55
- credentials: {
56
- apiKey: process.env.BINANCE_API_KEY!,
57
- secret: process.env.BINANCE_API_SECRET!,
58
- },
59
- });
60
-
61
- await client.start();
62
-
63
- await client.market.subscribeL1Book({
64
- exchange: "binance",
65
- symbol: "BTC/USDT",
66
- });
67
-
68
- await client.market.subscribeL1Book({
69
- exchange: "binance",
70
- symbol: "BTC/USDT:USDT",
71
- });
72
-
73
- await client.market.subscribeFundingRate({
74
- exchange: "binance",
75
- symbol: "BTC/USDT:USDT",
76
- });
77
-
78
- await client.account.subscribeAccount({
79
- accountId: "main-binance",
80
- });
81
-
82
- await client.order.subscribeOrders({
83
- accountId: "main-binance",
84
- });
85
-
86
- const book = client.market.getL1Book({
87
- exchange: "binance",
88
- symbol: "BTC/USDT:USDT",
89
- });
90
-
91
- const account = client.account.getAccountSnapshot("main-binance");
92
- const orderStatus = client.order.getOrderStatus("main-binance");
93
-
94
- console.log({
95
- status: client.getStatus(),
96
- health: client.getHealth(),
97
- book,
98
- account,
99
- orderStatus,
100
- });
101
-
102
- await client.stop();
103
- }
104
-
105
- void main();
106
- ```
107
-
108
- ## 运行顺序说明
109
-
110
- ### 1. 创建客户端
111
-
112
- ```ts
113
- const client = createClient({
114
- sandbox: true,
115
- });
116
- ```
117
-
118
- 当前只支持一个选项:
119
-
120
- - `sandbox`
121
-
122
- 说明:
123
-
124
- - `sandbox` 默认就是 `true`
125
- - 对当前实现来说,`sandbox: true` 对应 Binance USD-M demo/testnet 路径
126
-
127
- ### 2. 注册账户
128
-
129
- ```ts
130
- await client.registerAccount({
131
- accountId: "main-binance",
132
- exchange: "binance",
133
- credentials: {
134
- apiKey: process.env.BINANCE_API_KEY!,
135
- secret: process.env.BINANCE_API_SECRET!,
136
- },
137
- });
138
- ```
139
-
140
- 当前约束:
141
-
142
- - `accountId` 不能为空
143
- - `exchange` 只能是 `binance`
144
- - `apiKey` 和 `secret` 不能为空
145
- - 一个 `client` 现在只能注册一个账户
146
-
147
- ### 3. 启动运行时
148
-
149
- ```ts
20
+ const client = createClient();
150
21
  await client.start();
151
- ```
152
-
153
- `start()` 之后,SDK 才会真正建立底层 runtime。
154
22
 
155
- 如果你在 `start()` 之前调用:
156
-
157
- - `subscribeL1Book()`
158
- - `subscribeAccount()`
159
- - `subscribeOrders()`
160
- - 下单相关 API
161
-
162
- 会直接抛错。
163
-
164
- ### 4. 订阅你要的数据
165
-
166
- 行情:
167
-
168
- ```ts
169
23
  await client.market.subscribeL1Book({
170
24
  exchange: "binance",
171
- symbol: "BTC/USDT",
25
+ symbol: "BTC/USDT:USDT",
172
26
  });
173
27
 
174
- await client.market.subscribeL1Book({
28
+ const book = client.market.getL1Book({
175
29
  exchange: "binance",
176
30
  symbol: "BTC/USDT:USDT",
177
31
  });
32
+ console.log(`bid=${book?.bidPrice.toFixed()} ask=${book?.askPrice.toFixed()}`);
33
+ console.log(`book freshness=${book?.status.freshness}`);
178
34
 
179
35
  await client.market.subscribeFundingRate({
180
36
  exchange: "binance",
181
37
  symbol: "BTC/USDT:USDT",
182
38
  });
183
- ```
184
-
185
- 账户基线:
186
-
187
- ```ts
188
- await client.account.subscribeAccount({
189
- accountId: "main-binance",
190
- });
191
- ```
192
-
193
- 订单基线:
194
-
195
- ```ts
196
- await client.order.subscribeOrders({
197
- accountId: "main-binance",
198
- });
199
- ```
200
-
201
- 建议:
202
-
203
- - 要读余额/仓位前,先做 `subscribeAccount()`
204
- - 要读 open orders / order status 前,先做 `subscribeOrders()`
205
39
 
206
- ### 5. 读取最新快照
207
-
208
- 行情快照:
209
-
210
- ```ts
211
- const book = client.market.getL1Book({
40
+ const funding = client.market.getFundingRate({
212
41
  exchange: "binance",
213
42
  symbol: "BTC/USDT:USDT",
214
43
  });
215
- ```
44
+ console.log(`funding=${funding?.fundingRate.toFixed()}`);
216
45
 
217
- 账户快照:
46
+ for await (const event of client.market.events.l1BookUpdates({
47
+ exchange: "binance",
48
+ symbol: "BTC/USDT:USDT",
49
+ })) {
50
+ console.log(event.snapshot.bidPrice.toFixed());
51
+ break;
52
+ }
218
53
 
219
- ```ts
220
- const account = client.account.getAccountSnapshot("main-binance");
221
- const balances = client.account.getBalances("main-binance");
222
- const positions = client.account.getPositions("main-binance");
223
- const risk = client.account.getRiskSnapshot("main-binance");
54
+ await client.stop();
224
55
  ```
225
56
 
226
- 订单投影:
57
+ ### 账户与订单
227
58
 
228
59
  ```ts
229
- const openOrders = client.order.getOpenOrders("main-binance");
230
- const orderStatus = client.order.getOrderStatus("main-binance");
231
- ```
60
+ const client = createClient();
61
+ await client.start();
232
62
 
233
- ## 下单相关 API
63
+ await client.registerAccount({
64
+ accountId: "main-binance",
65
+ exchange: "binance",
66
+ credentials: {
67
+ apiKey: process.env.BINANCE_PAPI_API_KEY,
68
+ secret: process.env.BINANCE_PAPI_SECRET,
69
+ },
70
+ });
234
71
 
235
- 当前 public API 已暴露这些命令:
72
+ await client.account.subscribeAccount({ accountId: "main-binance" });
73
+ await client.order.subscribeOrders({ accountId: "main-binance" });
236
74
 
237
- ```ts
238
- await client.order.placeOrder({
75
+ const created = await client.order.createOrder({
239
76
  accountId: "main-binance",
240
- exchange: "binance",
241
77
  symbol: "BTC/USDT:USDT",
242
78
  side: "buy",
79
+ type: "limit",
80
+ price: "71830.6",
243
81
  amount: "0.001",
244
- clientOrderId: "demo-open-1",
245
- type: "market",
246
82
  });
247
- ```
248
83
 
249
- ```ts
250
84
  await client.order.cancelOrder({
251
85
  accountId: "main-binance",
252
- exchange: "binance",
253
- clientOrderId: "demo-open-1",
86
+ symbol: "BTC/USDT:USDT",
87
+ orderId: created.orderId,
254
88
  });
255
- ```
256
89
 
257
- ```ts
258
- await client.order.amendOrder({
259
- accountId: "main-binance",
260
- exchange: "binance",
261
- clientOrderId: "demo-open-1",
262
- newPrice: "65000",
263
- });
90
+ await client.stop();
264
91
  ```
265
92
 
266
- ```ts
267
- await client.order.cancelAllOrders({
268
- accountId: "main-binance",
269
- exchange: "binance",
270
- });
271
- ```
272
-
273
- 读取单个订单:
274
-
275
- ```ts
276
- const order = client.order.getOrder({
277
- accountId: "main-binance",
278
- exchange: "binance",
279
- clientOrderId: "demo-open-1",
280
- });
281
- ```
93
+ 价格、数量等输出字段统一是 `BigNumber`;`createOrder()` 的 `price` / `amount` 输入仍接受 decimal string。详见手册 [§3 核心概念](./docs/api.md#3-核心概念)。
282
94
 
283
- ## 健康状态和错误流
95
+ ## 核心能力
284
96
 
285
- 客户端状态:
97
+ | 能力 | 概述 | 详细文档 |
98
+ |---|---|---|
99
+ | **Market** | Market catalog、L1 Book / Funding Rate 订阅、增量事件、订阅状态与自动重连 | [docs/api.md §5](./docs/api.md#5-marketmanager) |
100
+ | **Account** | 账户快照、余额、持仓、风险投影与事件流 | [docs/api.md §6](./docs/api.md#6-accountmanager) |
101
+ | **Order** | open orders 投影、订单事件流,`createOrder` / `cancelOrder` / `cancelAllOrders` 第一版命令 | [docs/api.md §7](./docs/api.md#7-ordermanager) |
102
+ | **健康与错误** | `getHealth()`、`events.health()`、`events.errors()` | [docs/api.md §8](./docs/api.md#8-健康与错误事件) |
286
103
 
287
- ```ts
288
- const status = client.getStatus();
289
- const health = client.getHealth();
290
- ```
104
+ 完整手册(接口签名、数据类型、错误码):[docs/api.md](./docs/api.md)。
291
105
 
292
- 监听 health:
106
+ ## 当前限制
293
107
 
294
- ```ts
295
- for await (const event of client.watchHealth()) {
296
- console.log("health", event);
297
- }
298
- ```
108
+ - 运行时只支持 `binance`;`okx` / `bybit` / `gate` 仅类型定义
109
+ - 私有链路仅 Binance PAPI UM(统一账户 / Portfolio Margin)
110
+ - Funding Rate 仅支持 Binance 永续合约,来自 mark price websocket;不支持现货和交割合约
111
+ - `createOrder()` 只支持 `limit` / `market`;条件单、改单、账户级全撤不支持
112
+ - 双向持仓账户下单时必须显式传 `positionSide`
113
+ - `CreateClientOptions` 中 `sandbox` / `logger` / `logLevel` 是预留位
299
114
 
300
- 监听内部错误:
115
+ ## 仓库内开发
301
116
 
302
- ```ts
303
- for await (const event of client.watchErrors()) {
304
- console.error("internal error", event);
305
- }
117
+ ```bash
118
+ bun install
119
+ bun run lint
120
+ bun run type-check
121
+ bun run test
306
122
  ```
307
123
 
308
- ## 当前最值得记住的限制
124
+ ### 真实环境 smoke / soak 脚本
309
125
 
310
- - 这是 `Bun-only` SDK
311
- - 当前 public 入口只接通了 `binance`
312
- - 当前 public 入口只支持单账户
313
- - 默认就是 `sandbox: true`
314
- - symbol 使用 CCXT unified symbol,例如 `BTC/USDT:USDT`
315
- - `createClient()` 适合直接接入;仓库里的 verification script 主要用于内部验收
126
+ 不进默认 `bun run test`,单独执行:
316
127
 
317
- ## 当前已验证的路径
128
+ ```bash
129
+ bun run test:live:market:smoke
130
+ bun run test:live:market:soak
131
+ bun run test:live:account:smoke
132
+ bun run test:live:account:soak
133
+ bun run test:live:order:smoke
134
+ bun run test:live:order:soak
135
+ ```
318
136
 
319
- 截至 `2026-03-31`,Binance USD-M demo/testnet 已验证:
137
+ 约定:
320
138
 
321
- - `subscribeL1Book`
322
- - `fetchAccountBaseline`
323
- - `fetchOpenOrdersBaseline`
324
- - market `placeOrder`
325
- - reduce-only market `placeOrder`
326
- - public WS
327
- - private WS
328
- - REST baseline
139
+ - `smoke` 默认跑 10 秒,做连通性检查,不主动断线
140
+ - `soak` 默认跑 60 秒,并做一次主动断线重连验证
329
141
 
330
- 这意味着:
142
+ 覆盖内容:
331
143
 
332
- - README 里的最小接入流程是当前实现重点保障的使用方式
333
- - `amendOrder` `cancelAllOrders` 已有 API,但不属于首轮官方实盘验收重点
144
+ - `market`:`loadMarkets()`、`subscribeL1Book()`、`subscribeFundingRate()`、`getL1Book()` / `getFundingRate()`、对应事件流和可选断线重连(`--disconnect-target funding` 可单独验证资金费率重连)
145
+ - `account`:Binance PAPI UM 账户 bootstrap、余额/仓位/风险投影、private stream 更新和可选重连
146
+ - `order`:open orders bootstrap、`subscribeOrders()`、订单事件投影和可选重连
334
147
 
335
- ## 本地开发
148
+ ### 发布流程
336
149
 
337
- 安装依赖:
150
+ 仓库使用 **Changesets + GitHub Actions + npm Trusted Publishing**:
338
151
 
339
- ```bash
340
- bun install
341
- ```
152
+ 1. 开发 PR 时,如果改动影响用户,执行 `bun run changeset`
153
+ 2. 按提示选择 `patch` / `minor` / `major`,写一段对外 release note
154
+ 3. PR merge 到 `main` 后,[release.yml](./.github/workflows/release.yml) 会:
155
+ - 安装依赖
156
+ - 跑 `bun run lint` / `bun run type-check` / `bun run test`
157
+ - 若有未消费的 changeset,创建或更新 release PR
158
+ 4. merge release PR 后,同一 workflow 自动发布到 npm
342
159
 
343
- 常用命令:
160
+ 当前仓库处于 Changesets 的 `beta` prerelease 模式,自动发布默认走 npm `beta` dist-tag。
344
161
 
345
- ```bash
346
- bun run typecheck
347
- bun test
348
- bun run lint
349
- ```
350
-
351
- ## 仓库里的验证脚本
352
-
353
- 如果你想直接验证 Binance demo/testnet 路径,可以跑:
354
-
355
- ```bash
356
- bun run scripts/verify-binance-usdm-testnet.ts
357
- ```
162
+ npm 侧配置 Trusted Publisher 要求:
358
163
 
359
- 这个脚本更偏“仓库验收”,不是普通业务接入时必须使用的入口。
164
+ - workflow 文件名是 `release.yml`
165
+ - `package.json.repository.url` 直接写仓库地址,例如 `https://github.com/imbingox/acex`
166
+ - npm 包 settings 绑定 GitHub Actions trusted publisher,不使用长期 `NPM_TOKEN`
package/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./src/index.ts";
package/package.json CHANGED
@@ -1,34 +1,51 @@
1
1
  {
2
2
  "name": "@imbingox/acex",
3
- "version": "0.1.0",
4
- "private": false,
3
+ "version": "0.2.0",
4
+ "description": "Multi-exchange trading SDK for market data, account, and order management",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/imbingox/acex.git"
8
+ },
9
+ "module": "index.ts",
5
10
  "type": "module",
6
- "packageManager": "bun@1.2.8",
11
+ "exports": {
12
+ ".": "./index.ts"
13
+ },
7
14
  "publishConfig": {
8
15
  "access": "public"
9
16
  },
10
- "files": ["dist"],
11
- "main": "./dist/index.js",
12
- "types": "./dist/index.d.ts",
13
- "exports": {
14
- ".": {
15
- "types": "./dist/index.d.ts",
16
- "import": "./dist/index.js"
17
- }
18
- },
17
+ "files": [
18
+ "index.ts",
19
+ "src/"
20
+ ],
19
21
  "scripts": {
20
- "build": "tsc -p tsconfig.json",
21
- "typecheck": "tsc -p tsconfig.typecheck.json --noEmit",
22
- "test": "bun test",
23
- "lint": "biome check package.json tsconfig.json src tests",
24
- "format": "biome format --write ."
25
- },
26
- "dependencies": {
27
- "ccxt": "^4.5.45"
22
+ "changeset": "changeset",
23
+ "changeset:pre:enter:beta": "changeset pre enter beta && if [ -f .changeset/pre.json ]; then biome check --write .changeset/pre.json; fi",
24
+ "changeset:pre:exit": "changeset pre exit && if [ -f .changeset/pre.json ]; then biome check --write .changeset/pre.json; fi",
25
+ "lint": "biome check .",
26
+ "lint:fix": "biome check --write .",
27
+ "release": "changeset publish",
28
+ "type-check": "tsc --noEmit",
29
+ "test": "bun test --max-concurrency=1",
30
+ "test:live:account": "bun run scripts/live-account-smoke.ts",
31
+ "test:live:account:smoke": "bun run scripts/live-account-smoke.ts --duration 10",
32
+ "test:live:account:soak": "bun run scripts/live-account-smoke.ts --duration 60 --disconnect-after 5",
33
+ "test:live:market": "bun run scripts/live-market-smoke.ts",
34
+ "test:live:market:smoke": "bun run scripts/live-market-smoke.ts --duration 10",
35
+ "test:live:market:soak": "bun run scripts/live-market-smoke.ts --duration 60 --disconnect-after 5 --disconnect-target perp",
36
+ "test:live:order": "bun run scripts/live-order-smoke.ts",
37
+ "test:live:order:smoke": "bun run scripts/live-order-smoke.ts --duration 10",
38
+ "test:live:order:soak": "bun run scripts/live-order-smoke.ts --duration 60 --disconnect-after 5",
39
+ "version-packages": "changeset version && files=\"package.json\"; if [ -f .changeset/pre.json ]; then files=\"$files .changeset/pre.json\"; fi; if [ -f CHANGELOG.md ]; then files=\"$files CHANGELOG.md\"; fi; biome check --write $files"
28
40
  },
29
41
  "devDependencies": {
30
- "@biomejs/biome": "^1.9.4",
31
- "typescript": "^5.8.2",
32
- "bun-types": "^1.3.11"
42
+ "@biomejs/biome": "^2.4.10",
43
+ "@changesets/cli": "^2.31.0",
44
+ "@types/bun": "latest",
45
+ "typescript": "^6.0.2"
46
+ },
47
+ "dependencies": {
48
+ "@mindfoldhq/trellis": "^0.4.0",
49
+ "bignumber.js": "^11.0.0"
33
50
  }
34
51
  }
@@ -0,0 +1,80 @@
1
+ import type { MarketDefinition } from "../../types/index.ts";
2
+ import type {
3
+ FundingRateStreamCallbacks,
4
+ FundingRateStreamOptions,
5
+ L1BookStreamCallbacks,
6
+ L1BookStreamOptions,
7
+ MarketAdapter,
8
+ StreamHandle,
9
+ } from "../types.ts";
10
+ import { subscribeBinanceBookTicker } from "./book-ticker.ts";
11
+ import { subscribeBinanceMarkPrice } from "./mark-price.ts";
12
+ import {
13
+ type BinanceMarketDefinition,
14
+ loadBinanceMarkets,
15
+ } from "./market-catalog.ts";
16
+
17
+ export class BinanceMarketAdapter implements MarketAdapter {
18
+ readonly exchange = "binance" as const;
19
+
20
+ private readonly definitions = new Map<string, BinanceMarketDefinition>();
21
+
22
+ async loadMarkets(): Promise<MarketDefinition[]> {
23
+ const markets = await loadBinanceMarkets();
24
+ this.definitions.clear();
25
+
26
+ for (const market of markets) {
27
+ this.definitions.set(market.symbol, market);
28
+ }
29
+
30
+ return markets;
31
+ }
32
+
33
+ createL1BookStream(
34
+ market: MarketDefinition,
35
+ callbacks: L1BookStreamCallbacks,
36
+ options: L1BookStreamOptions,
37
+ ): StreamHandle {
38
+ const binanceMarket = this.definitions.get(market.symbol);
39
+ if (!binanceMarket) {
40
+ throw new Error(`Unknown Binance market: ${market.symbol}`);
41
+ }
42
+
43
+ return subscribeBinanceBookTicker(
44
+ binanceMarket,
45
+ {
46
+ onBookTicker(update) {
47
+ callbacks.onUpdate(update);
48
+ },
49
+ onFreshnessChange: callbacks.onFreshnessChange,
50
+ onDisconnected: callbacks.onDisconnected,
51
+ onError: callbacks.onError,
52
+ },
53
+ options,
54
+ );
55
+ }
56
+
57
+ createFundingRateStream(
58
+ market: MarketDefinition,
59
+ callbacks: FundingRateStreamCallbacks,
60
+ options: FundingRateStreamOptions,
61
+ ): StreamHandle {
62
+ const binanceMarket = this.definitions.get(market.symbol);
63
+ if (!binanceMarket) {
64
+ throw new Error(`Unknown Binance market: ${market.symbol}`);
65
+ }
66
+
67
+ return subscribeBinanceMarkPrice(
68
+ binanceMarket,
69
+ {
70
+ onFundingRate(update) {
71
+ callbacks.onUpdate(update);
72
+ },
73
+ onFreshnessChange: callbacks.onFreshnessChange,
74
+ onDisconnected: callbacks.onDisconnected,
75
+ onError: callbacks.onError,
76
+ },
77
+ options,
78
+ );
79
+ }
80
+ }