@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.
- package/README.md +92 -285
- package/index.ts +1 -0
- package/package.json +40 -23
- package/src/adapters/binance/adapter.ts +80 -0
- package/src/adapters/binance/book-ticker.ts +123 -0
- package/src/adapters/binance/mark-price.ts +126 -0
- package/src/adapters/binance/market-catalog.ts +258 -0
- package/src/adapters/binance/private-adapter.ts +833 -0
- package/src/adapters/types.ts +219 -0
- package/src/client/context.ts +123 -0
- package/src/client/create-client.ts +6 -0
- package/src/client/private-subscription-coordinator.ts +512 -0
- package/src/client/runtime.ts +410 -0
- package/src/errors.ts +27 -0
- package/src/index.ts +5 -0
- package/src/internal/async-event-bus.ts +100 -0
- package/src/internal/filters.ts +117 -0
- package/src/internal/managed-websocket.ts +280 -0
- package/src/managers/account-manager.ts +609 -0
- package/src/managers/market-manager.ts +889 -0
- package/src/managers/order-manager.ts +685 -0
- package/src/types/account.ts +157 -0
- package/src/types/client.ts +79 -0
- package/src/types/index.ts +5 -0
- package/src/types/market.ts +150 -0
- package/src/types/order.ts +177 -0
- package/src/types/shared.ts +93 -0
- package/dist/adapters/binance/composite-adapter.d.ts +0 -116
- package/dist/adapters/binance/composite-adapter.js +0 -121
- package/dist/adapters/binance/market-types.d.ts +0 -63
- package/dist/adapters/binance/market-types.js +0 -1
- package/dist/adapters/binance/native-market-adapter.d.ts +0 -102
- package/dist/adapters/binance/native-market-adapter.js +0 -455
- package/dist/adapters/binance/normalizers.d.ts +0 -8
- package/dist/adapters/binance/normalizers.js +0 -123
- package/dist/adapters/binance/rest-client.d.ts +0 -17
- package/dist/adapters/binance/rest-client.js +0 -66
- package/dist/adapters/binance/symbol-router.d.ts +0 -9
- package/dist/adapters/binance/symbol-router.js +0 -174
- package/dist/adapters/binance/ws-client.d.ts +0 -24
- package/dist/adapters/binance/ws-client.js +0 -261
- package/dist/adapters/ccxt/aster-ccxt-adapter.d.ts +0 -157
- package/dist/adapters/ccxt/aster-ccxt-adapter.js +0 -272
- package/dist/adapters/ccxt/binance-usdm-ccxt-adapter.d.ts +0 -180
- package/dist/adapters/ccxt/binance-usdm-ccxt-adapter.js +0 -539
- package/dist/adapters/ccxt/binance-usdm-exchange.d.ts +0 -22
- package/dist/adapters/ccxt/binance-usdm-exchange.js +0 -23
- package/dist/adapters/fake/fake-aster-adapter.d.ts +0 -130
- package/dist/adapters/fake/fake-aster-adapter.js +0 -283
- package/dist/adapters/types.d.ts +0 -210
- package/dist/adapters/types.js +0 -1
- package/dist/core/client.d.ts +0 -50
- package/dist/core/client.js +0 -403
- package/dist/core/recovery.d.ts +0 -22
- package/dist/core/recovery.js +0 -18
- package/dist/core/runtime.d.ts +0 -26
- package/dist/core/runtime.js +0 -150
- package/dist/errors/acex-error.d.ts +0 -25
- package/dist/errors/acex-error.js +0 -54
- package/dist/index.d.ts +0 -6
- package/dist/index.js +0 -3
- package/dist/managers/account-manager.d.ts +0 -41
- package/dist/managers/account-manager.js +0 -80
- package/dist/managers/market-manager.d.ts +0 -16
- package/dist/managers/market-manager.js +0 -28
- package/dist/managers/order-manager.d.ts +0 -87
- package/dist/managers/order-manager.js +0 -122
- package/dist/runtime/async-queue.d.ts +0 -8
- package/dist/runtime/async-queue.js +0 -88
- package/dist/runtime/request-id.d.ts +0 -1
- package/dist/runtime/request-id.js +0 -5
- package/dist/runtime/ws-connection-supervisor.d.ts +0 -76
- package/dist/runtime/ws-connection-supervisor.js +0 -522
- package/dist/store/account-store.d.ts +0 -52
- package/dist/store/account-store.js +0 -18
- package/dist/store/health-store.d.ts +0 -16
- package/dist/store/health-store.js +0 -29
- package/dist/store/market-store.d.ts +0 -42
- package/dist/store/market-store.js +0 -51
- package/dist/store/order-store.d.ts +0 -38
- package/dist/store/order-store.js +0 -49
- package/dist/testing/create-fake-runtime.d.ts +0 -5
- package/dist/testing/create-fake-runtime.js +0 -7
- package/dist/types/public.d.ts +0 -5
- package/dist/types/public.js +0 -1
package/README.md
CHANGED
|
@@ -1,25 +1,8 @@
|
|
|
1
|
-
# acex
|
|
1
|
+
# @imbingox/acex
|
|
2
2
|
|
|
3
|
-
`acex`
|
|
3
|
+
`acex` 是一个面向交易场景的 **状态型** 多交易所 SDK。调用方持有一个 `AcexClient`,通过统一的 `market` / `account` / `order` manager 读取最新快照、消费增量事件、执行下单撤单命令;SDK 内部负责本地缓存、ready barrier、websocket 生命周期和自动重连,调用方不需要自己处理。
|
|
4
4
|
|
|
5
|
-
当前
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
230
|
-
|
|
231
|
-
```
|
|
60
|
+
const client = createClient();
|
|
61
|
+
await client.start();
|
|
232
62
|
|
|
233
|
-
|
|
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
|
-
|
|
72
|
+
await client.account.subscribeAccount({ accountId: "main-binance" });
|
|
73
|
+
await client.order.subscribeOrders({ accountId: "main-binance" });
|
|
236
74
|
|
|
237
|
-
|
|
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
|
-
|
|
253
|
-
|
|
86
|
+
symbol: "BTC/USDT:USDT",
|
|
87
|
+
orderId: created.orderId,
|
|
254
88
|
});
|
|
255
|
-
```
|
|
256
89
|
|
|
257
|
-
|
|
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
|
-
|
|
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
|
-
|
|
288
|
-
const status = client.getStatus();
|
|
289
|
-
const health = client.getHealth();
|
|
290
|
-
```
|
|
104
|
+
完整手册(接口签名、数据类型、错误码):[docs/api.md](./docs/api.md)。
|
|
291
105
|
|
|
292
|
-
|
|
106
|
+
## 当前限制
|
|
293
107
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
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
|
-
```
|
|
303
|
-
|
|
304
|
-
|
|
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
|
-
|
|
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
|
-
|
|
137
|
+
约定:
|
|
320
138
|
|
|
321
|
-
- `
|
|
322
|
-
- `
|
|
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
|
-
-
|
|
333
|
-
- `
|
|
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
|
-
|
|
340
|
-
|
|
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
|
-
|
|
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.
|
|
4
|
-
"
|
|
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
|
-
"
|
|
11
|
+
"exports": {
|
|
12
|
+
".": "./index.ts"
|
|
13
|
+
},
|
|
7
14
|
"publishConfig": {
|
|
8
15
|
"access": "public"
|
|
9
16
|
},
|
|
10
|
-
"files": [
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"lint": "biome check
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
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": "^
|
|
31
|
-
"
|
|
32
|
-
"bun
|
|
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
|
+
}
|