@rabby-wallet/hyperliquid-sdk 1.1.1 → 1.1.2-beta.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/README.md +139 -139
- package/dist/client/exchange-client.d.ts +10 -1
- package/dist/client/exchange-client.js +49 -0
- package/dist/client/info-client.d.ts +26 -1
- package/dist/client/info-client.js +69 -0
- package/dist/client/websocket-client.d.ts +49 -6
- package/dist/client/websocket-client.js +170 -60
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/types/constants.d.ts +24 -1
- package/dist/types/constants.js +26 -1
- package/dist/types/index.d.ts +118 -0
- package/dist/types/index.js +1 -0
- package/package.json +38 -37
package/README.md
CHANGED
|
@@ -1,140 +1,140 @@
|
|
|
1
|
-
# Hyperliquid Perpetuals SDK
|
|
2
|
-
|
|
3
|
-
一个简化的 Hyperliquid 永续合约交易 SDK,专为前端应用设计。
|
|
4
|
-
|
|
5
|
-
## 特性
|
|
6
|
-
|
|
7
|
-
- ✅ 仅核心API:最重要的交易与查询能力
|
|
8
|
-
- ✅ 永续合约专用:不包含现货功能
|
|
9
|
-
- ✅ TypeScript:完善的类型定义
|
|
10
|
-
- ✅ WebSocket:实时数据订阅
|
|
11
|
-
- ✅ 前端友好:基于 fetch API 的轻量实现
|
|
12
|
-
|
|
13
|
-
## 安装
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
yarn add @debank/hyperliquid-perp-sdk
|
|
17
|
-
# or
|
|
18
|
-
npm i @debank/hyperliquid-perp-sdk
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## 快速开始
|
|
22
|
-
|
|
23
|
-
### 仅查询(无需私钥)
|
|
24
|
-
```ts
|
|
25
|
-
import { HyperliquidSDK } from '@debank/hyperliquid-perp-sdk';
|
|
26
|
-
|
|
27
|
-
const sdk = new HyperliquidSDK({
|
|
28
|
-
masterAddress: '0xYourEOA',
|
|
29
|
-
isTestnet: true,
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
// 获取所有中间价
|
|
33
|
-
const prices = await sdk.info.getAllMids();
|
|
34
|
-
|
|
35
|
-
// 获取市场元数据与资产上下文
|
|
36
|
-
const canUseCache = true; //默认使用缓存,多次请求并发去重 ,需要刷新传false
|
|
37
|
-
const [meta, assetCtxs] = await sdk.info.metaAndAssetCtxs(canUseCache);
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// 获取账户综合状态
|
|
41
|
-
const account = await sdk.info.getClearingHouseState();
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### 交易(需要提供代理私钥、公钥、名称)
|
|
45
|
-
```ts
|
|
46
|
-
const sdk = new HyperliquidSDK({
|
|
47
|
-
masterAddress: '0xYourEOA',
|
|
48
|
-
agentPrivateKey: '0xYourAgentPrivKey',
|
|
49
|
-
agentPublicKey: '0xYourAgentPubKey',
|
|
50
|
-
agentName: 'MyAgent',
|
|
51
|
-
isTestnet: true,
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
// 限价下单
|
|
55
|
-
await sdk.exchange!.placeOrder({
|
|
56
|
-
coin: 'BTC',
|
|
57
|
-
isBuy: true,
|
|
58
|
-
sz: '0.1',
|
|
59
|
-
limitPx: '45000',
|
|
60
|
-
orderType: { limit: { tif: 'Gtc' } },
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
// 批量下单
|
|
64
|
-
await sdk.exchange!.multiOrder({
|
|
65
|
-
orders: [
|
|
66
|
-
{ coin: 'ETH', isBuy: true, sz: '1', limitPx: '3000', orderType: { limit: { tif: 'Ioc' } } },
|
|
67
|
-
{ coin: 'SOL', isBuy: false, sz: '10', limitPx: '150', orderType: { limit: { tif: 'Ioc' } } },
|
|
68
|
-
],
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
// 市价开仓(带可选的 TP/SL 触发单)
|
|
72
|
-
await sdk.exchange!.marketOrderOpen({
|
|
73
|
-
coin: 'BTC',
|
|
74
|
-
isBuy: true,
|
|
75
|
-
size: '0.05',
|
|
76
|
-
midPx: '45200',
|
|
77
|
-
tpTriggerPx: '47000',
|
|
78
|
-
slTriggerPx: '44000',
|
|
79
|
-
// slippage 默认 0.08
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
// 市价平仓
|
|
83
|
-
await sdk.exchange!.marketOrderClose({
|
|
84
|
-
coin: 'BTC',
|
|
85
|
-
isBuy: false,
|
|
86
|
-
size: '0.05',
|
|
87
|
-
midPx: '45000',
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// 绑定 TP/SL 到已有持仓(按位置绑定)
|
|
91
|
-
await sdk.exchange!.bindTpslByOrderId({
|
|
92
|
-
coin: 'BTC',
|
|
93
|
-
isBuy: true, // 持仓方向
|
|
94
|
-
tpTriggerPx: '47000',
|
|
95
|
-
slTriggerPx: '44000',
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
// 更新杠杆
|
|
99
|
-
await sdk.exchange!.updateLeverage({
|
|
100
|
-
coin: 'BTC',
|
|
101
|
-
leverage: 5,
|
|
102
|
-
isCross: true,
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
// 撤单(可批量)
|
|
106
|
-
await sdk.exchange!.cancelOrder([
|
|
107
|
-
{ coin: 'BTC', oid: 12345 },
|
|
108
|
-
{ coin: 'ETH', oid: 67890 },
|
|
109
|
-
]);
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### 授权持久化代理(主钱包签名)
|
|
113
|
-
```ts
|
|
114
|
-
// 准备主钱包签名的 EIP-712 数据(Approve Agent)
|
|
115
|
-
const approve = sdk.exchange!.prepareApproveAgent();
|
|
116
|
-
// 业务方使用主钱包签名(示例)
|
|
117
|
-
const signature = await mainWallet.signTypedData(approve.domain, approve.types, approve.message);
|
|
118
|
-
// 发送请求
|
|
119
|
-
await sdk.exchange!.sendApproveAgent({ action: approve.message, nonce: approve.nonce, signature });
|
|
120
|
-
|
|
121
|
-
// 准备并签名 Builder 费用
|
|
122
|
-
const builderFee = sdk.exchange!.prepareApproveBuilderFee({ builder: '0xBuilder', maxFee: '0.1%' });
|
|
123
|
-
const sig2 = await mainWallet.signTypedData(builderFee.domain, builderFee.types, builderFee.message);
|
|
124
|
-
await sdk.exchange!.sendApproveBuilderFee({ action: builderFee.message, nonce: builderFee.nonce, signature: sig2 });
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### WebSocket 实时数据
|
|
128
|
-
```ts
|
|
129
|
-
await sdk.connectWebSocket();
|
|
130
|
-
|
|
131
|
-
// 订阅价格
|
|
132
|
-
sdk.ws.subscribeToAllMids((prices) => {
|
|
133
|
-
console.log('价格更新:', prices);
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
// 订阅用户综合数据
|
|
137
|
-
sdk.ws.subscribeToWebData2('0xYourEOA', (webData2) => {
|
|
138
|
-
console.log('用户数据:', webData2);
|
|
139
|
-
});
|
|
1
|
+
# Hyperliquid Perpetuals SDK
|
|
2
|
+
|
|
3
|
+
一个简化的 Hyperliquid 永续合约交易 SDK,专为前端应用设计。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- ✅ 仅核心API:最重要的交易与查询能力
|
|
8
|
+
- ✅ 永续合约专用:不包含现货功能
|
|
9
|
+
- ✅ TypeScript:完善的类型定义
|
|
10
|
+
- ✅ WebSocket:实时数据订阅
|
|
11
|
+
- ✅ 前端友好:基于 fetch API 的轻量实现
|
|
12
|
+
|
|
13
|
+
## 安装
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
yarn add @debank/hyperliquid-perp-sdk
|
|
17
|
+
# or
|
|
18
|
+
npm i @debank/hyperliquid-perp-sdk
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 快速开始
|
|
22
|
+
|
|
23
|
+
### 仅查询(无需私钥)
|
|
24
|
+
```ts
|
|
25
|
+
import { HyperliquidSDK } from '@debank/hyperliquid-perp-sdk';
|
|
26
|
+
|
|
27
|
+
const sdk = new HyperliquidSDK({
|
|
28
|
+
masterAddress: '0xYourEOA',
|
|
29
|
+
isTestnet: true,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// 获取所有中间价
|
|
33
|
+
const prices = await sdk.info.getAllMids();
|
|
34
|
+
|
|
35
|
+
// 获取市场元数据与资产上下文
|
|
36
|
+
const canUseCache = true; //默认使用缓存,多次请求并发去重 ,需要刷新传false
|
|
37
|
+
const [meta, assetCtxs] = await sdk.info.metaAndAssetCtxs(canUseCache);
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
// 获取账户综合状态
|
|
41
|
+
const account = await sdk.info.getClearingHouseState();
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 交易(需要提供代理私钥、公钥、名称)
|
|
45
|
+
```ts
|
|
46
|
+
const sdk = new HyperliquidSDK({
|
|
47
|
+
masterAddress: '0xYourEOA',
|
|
48
|
+
agentPrivateKey: '0xYourAgentPrivKey',
|
|
49
|
+
agentPublicKey: '0xYourAgentPubKey',
|
|
50
|
+
agentName: 'MyAgent',
|
|
51
|
+
isTestnet: true,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// 限价下单
|
|
55
|
+
await sdk.exchange!.placeOrder({
|
|
56
|
+
coin: 'BTC',
|
|
57
|
+
isBuy: true,
|
|
58
|
+
sz: '0.1',
|
|
59
|
+
limitPx: '45000',
|
|
60
|
+
orderType: { limit: { tif: 'Gtc' } },
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// 批量下单
|
|
64
|
+
await sdk.exchange!.multiOrder({
|
|
65
|
+
orders: [
|
|
66
|
+
{ coin: 'ETH', isBuy: true, sz: '1', limitPx: '3000', orderType: { limit: { tif: 'Ioc' } } },
|
|
67
|
+
{ coin: 'SOL', isBuy: false, sz: '10', limitPx: '150', orderType: { limit: { tif: 'Ioc' } } },
|
|
68
|
+
],
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// 市价开仓(带可选的 TP/SL 触发单)
|
|
72
|
+
await sdk.exchange!.marketOrderOpen({
|
|
73
|
+
coin: 'BTC',
|
|
74
|
+
isBuy: true,
|
|
75
|
+
size: '0.05',
|
|
76
|
+
midPx: '45200',
|
|
77
|
+
tpTriggerPx: '47000',
|
|
78
|
+
slTriggerPx: '44000',
|
|
79
|
+
// slippage 默认 0.08
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// 市价平仓
|
|
83
|
+
await sdk.exchange!.marketOrderClose({
|
|
84
|
+
coin: 'BTC',
|
|
85
|
+
isBuy: false,
|
|
86
|
+
size: '0.05',
|
|
87
|
+
midPx: '45000',
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// 绑定 TP/SL 到已有持仓(按位置绑定)
|
|
91
|
+
await sdk.exchange!.bindTpslByOrderId({
|
|
92
|
+
coin: 'BTC',
|
|
93
|
+
isBuy: true, // 持仓方向
|
|
94
|
+
tpTriggerPx: '47000',
|
|
95
|
+
slTriggerPx: '44000',
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// 更新杠杆
|
|
99
|
+
await sdk.exchange!.updateLeverage({
|
|
100
|
+
coin: 'BTC',
|
|
101
|
+
leverage: 5,
|
|
102
|
+
isCross: true,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// 撤单(可批量)
|
|
106
|
+
await sdk.exchange!.cancelOrder([
|
|
107
|
+
{ coin: 'BTC', oid: 12345 },
|
|
108
|
+
{ coin: 'ETH', oid: 67890 },
|
|
109
|
+
]);
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 授权持久化代理(主钱包签名)
|
|
113
|
+
```ts
|
|
114
|
+
// 准备主钱包签名的 EIP-712 数据(Approve Agent)
|
|
115
|
+
const approve = sdk.exchange!.prepareApproveAgent();
|
|
116
|
+
// 业务方使用主钱包签名(示例)
|
|
117
|
+
const signature = await mainWallet.signTypedData(approve.domain, approve.types, approve.message);
|
|
118
|
+
// 发送请求
|
|
119
|
+
await sdk.exchange!.sendApproveAgent({ action: approve.message, nonce: approve.nonce, signature });
|
|
120
|
+
|
|
121
|
+
// 准备并签名 Builder 费用
|
|
122
|
+
const builderFee = sdk.exchange!.prepareApproveBuilderFee({ builder: '0xBuilder', maxFee: '0.1%' });
|
|
123
|
+
const sig2 = await mainWallet.signTypedData(builderFee.domain, builderFee.types, builderFee.message);
|
|
124
|
+
await sdk.exchange!.sendApproveBuilderFee({ action: builderFee.message, nonce: builderFee.nonce, signature: sig2 });
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### WebSocket 实时数据
|
|
128
|
+
```ts
|
|
129
|
+
await sdk.connectWebSocket();
|
|
130
|
+
|
|
131
|
+
// 订阅价格
|
|
132
|
+
sdk.ws.subscribeToAllMids((prices) => {
|
|
133
|
+
console.log('价格更新:', prices);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// 订阅用户综合数据
|
|
137
|
+
sdk.ws.subscribeToWebData2('0xYourEOA', (webData2) => {
|
|
138
|
+
console.log('用户数据:', webData2);
|
|
139
|
+
});
|
|
140
140
|
```
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ExchangeType } from '../types/constants';
|
|
2
|
-
import type { OrderResponse, CancelResponse, ExchangeClientConfig, PlaceOrderParams, MultiOrderParams, CancelOrderParams, ModifyOrderParams, WithdrawParams, ApproveBuilderFeeParams, PrepareApproveBuilderFeeResult, SendApproveParams, MarketOrderParams, UpdateLeverageParams, BindTpslByOrderIdParams, UpdateIsolatedMarginParams } from '../types';
|
|
2
|
+
import type { OrderResponse, CancelResponse, ExchangeClientConfig, PlaceOrderParams, MultiOrderParams, CancelOrderParams, ModifyOrderParams, WithdrawParams, ApproveBuilderFeeParams, PrepareApproveBuilderFeeResult, SendApproveParams, MarketOrderParams, UpdateLeverageParams, BindTpslByOrderIdParams, UpdateIsolatedMarginParams, TwapOrderParams, TwapCancelParams, TwapOrderResponse } from '../types';
|
|
3
3
|
/**
|
|
4
4
|
* Client for executing trades on Hyperliquid (perpetuals only)
|
|
5
5
|
* Only includes essential trading APIs as specified
|
|
@@ -125,4 +125,13 @@ export declare class ExchangeClient {
|
|
|
125
125
|
*/
|
|
126
126
|
prepareWithdraw(params: WithdrawParams): PrepareApproveBuilderFeeResult;
|
|
127
127
|
sendWithdraw(params: SendApproveParams): Promise<any>;
|
|
128
|
+
/**
|
|
129
|
+
* Place a TWAP order
|
|
130
|
+
* TWAP orders split a large order into smaller slices over time
|
|
131
|
+
*/
|
|
132
|
+
placeTwapOrder(params: TwapOrderParams): Promise<TwapOrderResponse>;
|
|
133
|
+
/**
|
|
134
|
+
* Cancel a TWAP order
|
|
135
|
+
*/
|
|
136
|
+
cancelTwapOrder(params: TwapCancelParams): Promise<any>;
|
|
128
137
|
}
|
|
@@ -653,5 +653,54 @@ class ExchangeClient {
|
|
|
653
653
|
signature: splitSignature,
|
|
654
654
|
});
|
|
655
655
|
}
|
|
656
|
+
/**
|
|
657
|
+
* Place a TWAP order
|
|
658
|
+
* TWAP orders split a large order into smaller slices over time
|
|
659
|
+
*/
|
|
660
|
+
placeTwapOrder(params) {
|
|
661
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
662
|
+
const nonce = Date.now();
|
|
663
|
+
const action = {
|
|
664
|
+
type: constants_1.ExchangeType.TWAP_ORDER,
|
|
665
|
+
a: yield this.symbolConversion.getAssetIndex(params.coin),
|
|
666
|
+
b: params.isBuy,
|
|
667
|
+
s: (0, number_1.removeTrailingZeros)(params.sz),
|
|
668
|
+
r: params.reduceOnly || false,
|
|
669
|
+
m: params.durationMillis,
|
|
670
|
+
t: params.randomizeDelay || false,
|
|
671
|
+
};
|
|
672
|
+
if (params.builder) {
|
|
673
|
+
action.builder = {
|
|
674
|
+
b: params.builder.address,
|
|
675
|
+
f: params.builder.fee,
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
const signature = (0, signer_1.signL1AgentAction)(this.getAgentPrivateKey(), action, this.isTestnet, nonce);
|
|
679
|
+
return this.httpClient.exchange({
|
|
680
|
+
action,
|
|
681
|
+
nonce,
|
|
682
|
+
signature,
|
|
683
|
+
});
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Cancel a TWAP order
|
|
688
|
+
*/
|
|
689
|
+
cancelTwapOrder(params) {
|
|
690
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
691
|
+
const nonce = Date.now();
|
|
692
|
+
const action = {
|
|
693
|
+
type: constants_1.ExchangeType.TWAP_CANCEL,
|
|
694
|
+
a: yield this.symbolConversion.getAssetIndex(params.coin),
|
|
695
|
+
t: params.twapId,
|
|
696
|
+
};
|
|
697
|
+
const signature = (0, signer_1.signL1AgentAction)(this.getAgentPrivateKey(), action, this.isTestnet, nonce);
|
|
698
|
+
return this.httpClient.exchange({
|
|
699
|
+
action,
|
|
700
|
+
nonce,
|
|
701
|
+
signature,
|
|
702
|
+
});
|
|
703
|
+
});
|
|
704
|
+
}
|
|
656
705
|
}
|
|
657
706
|
exports.ExchangeClient = ExchangeClient;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Meta, AssetCtx, ClearinghouseState, UserFills, CandleSnapshot, AllMids, ExtraAgent, OpenOrder, FeeResponse, UserNonFundingLedgerUpdates, UserHistoricalOrders, ReferralResponse } from '../types';
|
|
1
|
+
import type { Meta, AssetCtx, ClearinghouseState, UserFills, CandleSnapshot, AllMids, ExtraAgent, OpenOrder, FeeResponse, UserNonFundingLedgerUpdates, UserHistoricalOrders, ReferralResponse, L2BookSnapshot, UserTwapSliceFill, FundingHistoryItem, UserFunding } from '../types';
|
|
2
2
|
export interface InfoClientConfig {
|
|
3
3
|
isTestnet?: boolean;
|
|
4
4
|
timeout?: number;
|
|
@@ -61,4 +61,29 @@ export declare class InfoClient {
|
|
|
61
61
|
* Get user's approved persistent agents
|
|
62
62
|
*/
|
|
63
63
|
extraAgents(address?: string): Promise<ExtraAgent[]>;
|
|
64
|
+
/**
|
|
65
|
+
* get L2 order book for a specific coin
|
|
66
|
+
* nSigFigs: Optional field to aggregate levels to nSigFigs significant figures. Valid values are 2, 3, 4, 5, and null, which means full precision
|
|
67
|
+
* mantissa: Optional field to aggregate levels. This field is only allowed if nSigFigs is 5. Accepts values of 1(null), 2 or 5.
|
|
68
|
+
* total six level
|
|
69
|
+
* nSigFig: 5 default
|
|
70
|
+
* nSigFig: 5 mantissa: 2
|
|
71
|
+
* nSigFig: 5 mantissa: 5
|
|
72
|
+
* nSigFig: 4
|
|
73
|
+
* nSigFig: 3
|
|
74
|
+
* nSigFig: 2
|
|
75
|
+
*/
|
|
76
|
+
getL2Book(coin: string, nSigFigs?: number, mantissa?: number): Promise<L2BookSnapshot>;
|
|
77
|
+
/**
|
|
78
|
+
* Get user's TWAP slice fills
|
|
79
|
+
*/
|
|
80
|
+
getUserTwapSliceFills(address?: string, startTime?: number, endTime?: number): Promise<UserTwapSliceFill[]>;
|
|
81
|
+
/**
|
|
82
|
+
* Get funding history for a specific coin
|
|
83
|
+
*/
|
|
84
|
+
getFundingHistory(coin: string, startTime: number, endTime?: number): Promise<FundingHistoryItem[]>;
|
|
85
|
+
/**
|
|
86
|
+
* Get user funding
|
|
87
|
+
*/
|
|
88
|
+
getUserFunding(address?: string): Promise<UserFunding[]>;
|
|
64
89
|
}
|
|
@@ -244,5 +244,74 @@ class InfoClient {
|
|
|
244
244
|
});
|
|
245
245
|
});
|
|
246
246
|
}
|
|
247
|
+
/**
|
|
248
|
+
* get L2 order book for a specific coin
|
|
249
|
+
* nSigFigs: Optional field to aggregate levels to nSigFigs significant figures. Valid values are 2, 3, 4, 5, and null, which means full precision
|
|
250
|
+
* mantissa: Optional field to aggregate levels. This field is only allowed if nSigFigs is 5. Accepts values of 1(null), 2 or 5.
|
|
251
|
+
* total six level
|
|
252
|
+
* nSigFig: 5 default
|
|
253
|
+
* nSigFig: 5 mantissa: 2
|
|
254
|
+
* nSigFig: 5 mantissa: 5
|
|
255
|
+
* nSigFig: 4
|
|
256
|
+
* nSigFig: 3
|
|
257
|
+
* nSigFig: 2
|
|
258
|
+
*/
|
|
259
|
+
getL2Book(coin, nSigFigs, mantissa) {
|
|
260
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
261
|
+
return this.httpClient.info({
|
|
262
|
+
type: constants_1.InfoType.L2_BOOK,
|
|
263
|
+
coin,
|
|
264
|
+
nSigFigs,
|
|
265
|
+
// Optional field to aggregate levels to nSigFigs significant figures. Valid values are 2, 3, 4, 5, and null, which means full precision
|
|
266
|
+
mantissa,
|
|
267
|
+
// Optional field to aggregate levels. This field is only allowed if nSigFigs is 5. Accepts values of 1, 2 or 5.
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Get user's TWAP slice fills
|
|
273
|
+
*/
|
|
274
|
+
getUserTwapSliceFills(address, startTime, endTime) {
|
|
275
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
276
|
+
const user = address || this.masterAddress;
|
|
277
|
+
if (!user) {
|
|
278
|
+
throw new Error('user address is empty');
|
|
279
|
+
}
|
|
280
|
+
return this.httpClient.info({
|
|
281
|
+
type: constants_1.InfoType.USER_TWAP_SLICE_FILLS,
|
|
282
|
+
user,
|
|
283
|
+
startTime: startTime || 0,
|
|
284
|
+
endTime,
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Get funding history for a specific coin
|
|
290
|
+
*/
|
|
291
|
+
getFundingHistory(coin, startTime, endTime) {
|
|
292
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
293
|
+
return this.httpClient.info({
|
|
294
|
+
type: constants_1.InfoType.FUNDING_HISTORY,
|
|
295
|
+
coin,
|
|
296
|
+
startTime,
|
|
297
|
+
endTime,
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Get user funding
|
|
303
|
+
*/
|
|
304
|
+
getUserFunding(address) {
|
|
305
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
306
|
+
const user = address || this.masterAddress;
|
|
307
|
+
if (!user) {
|
|
308
|
+
throw new Error('user address is empty');
|
|
309
|
+
}
|
|
310
|
+
return this.httpClient.info({
|
|
311
|
+
type: constants_1.InfoType.USER_FUNDING,
|
|
312
|
+
user,
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
}
|
|
247
316
|
}
|
|
248
317
|
exports.InfoClient = InfoClient;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { L2Book, Candle, WsOrder, WebData2, WsActiveAssetCtx, WsUserFills, WsClearinghouseState, Notification, WsTwapStates, WsOpenOrders, WsUserTwapSliceFills, WsUserTwapHistory, wsUserNonFundingLedgerUpdates, WsAllMids, WsTrade } from '../types';
|
|
2
2
|
export interface WebSocketClientConfig {
|
|
3
3
|
masterAddress?: string;
|
|
4
4
|
isTestnet?: boolean;
|
|
@@ -17,7 +17,8 @@ export declare class WebSocketClient {
|
|
|
17
17
|
private ws;
|
|
18
18
|
private readonly url;
|
|
19
19
|
private readonly config;
|
|
20
|
-
private
|
|
20
|
+
private typeSubscriptions;
|
|
21
|
+
private userSubscriptions;
|
|
21
22
|
private activeSubscriptions;
|
|
22
23
|
private reconnectAttempts;
|
|
23
24
|
private isConnecting;
|
|
@@ -44,6 +45,11 @@ export declare class WebSocketClient {
|
|
|
44
45
|
*/
|
|
45
46
|
disconnect(): void;
|
|
46
47
|
private getSubscriptionKey;
|
|
48
|
+
/**
|
|
49
|
+
* Dispatch message to matching subscriptions
|
|
50
|
+
* Uses direct lookup instead of iteration for better performance
|
|
51
|
+
*/
|
|
52
|
+
private dispatchMessage;
|
|
47
53
|
/**
|
|
48
54
|
* Subscribe to a channel
|
|
49
55
|
*/
|
|
@@ -51,11 +57,24 @@ export declare class WebSocketClient {
|
|
|
51
57
|
/**
|
|
52
58
|
* Subscribe to all mid prices
|
|
53
59
|
*/
|
|
54
|
-
subscribeToAllMids(callback: SubscriptionCallback<
|
|
60
|
+
subscribeToAllMids(callback: SubscriptionCallback<WsAllMids>): Subscription;
|
|
55
61
|
/**
|
|
56
62
|
* Subscribe to L2 order book for a specific coin
|
|
57
|
-
|
|
58
|
-
|
|
63
|
+
* nSigFigs: Optional field to aggregate levels to nSigFigs significant figures. Valid values are 2, 3, 4, 5, and null, which means full precision
|
|
64
|
+
* mantissa: Optional field to aggregate levels. This field is only allowed if nSigFigs is 5. Accepts values of 1, 2 or 5.
|
|
65
|
+
* total six level
|
|
66
|
+
* nSigFig: 5 default
|
|
67
|
+
* nSigFig: 5 mantissa: 2
|
|
68
|
+
* nSigFig: 5 mantissa: 5
|
|
69
|
+
* nSigFig: 4
|
|
70
|
+
* nSigFig: 3
|
|
71
|
+
* nSigFig: 2
|
|
72
|
+
*/
|
|
73
|
+
subscribeToL2Book({ coin, nSigFigs, mantissa, }: {
|
|
74
|
+
coin: string;
|
|
75
|
+
nSigFigs?: number;
|
|
76
|
+
mantissa?: number;
|
|
77
|
+
}, callback: SubscriptionCallback<L2Book>): Subscription;
|
|
59
78
|
/**
|
|
60
79
|
* Subscribe to active asset ctx
|
|
61
80
|
*/
|
|
@@ -63,7 +82,7 @@ export declare class WebSocketClient {
|
|
|
63
82
|
/**
|
|
64
83
|
* Subscribe to trades for a specific coin
|
|
65
84
|
*/
|
|
66
|
-
subscribeToTrades(coin: string, callback: SubscriptionCallback<
|
|
85
|
+
subscribeToTrades(coin: string, callback: SubscriptionCallback<WsTrade[]>): Subscription;
|
|
67
86
|
/**
|
|
68
87
|
* Subscribe to candlestick data
|
|
69
88
|
*/
|
|
@@ -108,4 +127,28 @@ export declare class WebSocketClient {
|
|
|
108
127
|
* @param state 'active' | 'background' | 'inactive'
|
|
109
128
|
*/
|
|
110
129
|
handleAppStateChange(state: string): void;
|
|
130
|
+
/**
|
|
131
|
+
* Subscribe to notification messages
|
|
132
|
+
*/
|
|
133
|
+
subscribeToNotification(callback: SubscriptionCallback<Notification>): Subscription;
|
|
134
|
+
/**
|
|
135
|
+
* Subscribe to TWAP order states
|
|
136
|
+
*/
|
|
137
|
+
subscribeToTwapStates(callback: SubscriptionCallback<WsTwapStates>): Subscription;
|
|
138
|
+
/**
|
|
139
|
+
* Subscribe to open orders
|
|
140
|
+
*/
|
|
141
|
+
subscribeToOpenOrders(callback: SubscriptionCallback<WsOpenOrders>): Subscription;
|
|
142
|
+
/**
|
|
143
|
+
* Subscribe to user non-funding ledger updates (deposits/withdrawals)
|
|
144
|
+
*/
|
|
145
|
+
subscribeToUserNonFundingLedgerUpdates(callback: SubscriptionCallback<wsUserNonFundingLedgerUpdates>): Subscription;
|
|
146
|
+
/**
|
|
147
|
+
* Subscribe to user TWAP slice fills
|
|
148
|
+
*/
|
|
149
|
+
subscribeToUserTwapSliceFills(callback: SubscriptionCallback<WsUserTwapSliceFills>): Subscription;
|
|
150
|
+
/**
|
|
151
|
+
* Subscribe to user TWAP history
|
|
152
|
+
*/
|
|
153
|
+
subscribeToUserTwapHistory(callback: SubscriptionCallback<WsUserTwapHistory>): Subscription;
|
|
111
154
|
}
|
|
@@ -17,7 +17,10 @@ const constants_1 = require("../types/constants");
|
|
|
17
17
|
class WebSocketClient {
|
|
18
18
|
constructor(config) {
|
|
19
19
|
this.ws = null;
|
|
20
|
-
|
|
20
|
+
// Map<type, callback[]> for most subscription types
|
|
21
|
+
this.typeSubscriptions = new Map();
|
|
22
|
+
// Map<type:user, callback[]> for clearinghouseState (multi-account support)
|
|
23
|
+
this.userSubscriptions = new Map();
|
|
21
24
|
this.activeSubscriptions = new Map();
|
|
22
25
|
this.reconnectAttempts = 0;
|
|
23
26
|
this.isConnecting = false;
|
|
@@ -78,7 +81,24 @@ class WebSocketClient {
|
|
|
78
81
|
var _a;
|
|
79
82
|
if (((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN) {
|
|
80
83
|
const subKey = this.getSubscriptionKey(message.subscription);
|
|
81
|
-
|
|
84
|
+
const type = message.subscription.type;
|
|
85
|
+
const user = message.subscription.user;
|
|
86
|
+
// Register callback in appropriate map
|
|
87
|
+
if (type === constants_1.WsSubscriptionType.CLEARINGHOUSE_STATE && user) {
|
|
88
|
+
const userKey = `${type}:${user.toLowerCase()}`;
|
|
89
|
+
const callbacks = this.userSubscriptions.get(userKey) || [];
|
|
90
|
+
if (!callbacks.includes(callback)) {
|
|
91
|
+
callbacks.push(callback);
|
|
92
|
+
this.userSubscriptions.set(userKey, callbacks);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
const callbacks = this.typeSubscriptions.get(type) || [];
|
|
97
|
+
if (!callbacks.includes(callback)) {
|
|
98
|
+
callbacks.push(callback);
|
|
99
|
+
this.typeSubscriptions.set(type, callbacks);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
82
102
|
this.activeSubscriptions.set(subKey, { message, callback });
|
|
83
103
|
this.ws.send(JSON.stringify(Object.assign(Object.assign({}, message), { method: 'subscribe' })));
|
|
84
104
|
}
|
|
@@ -88,50 +108,15 @@ class WebSocketClient {
|
|
|
88
108
|
resolve();
|
|
89
109
|
};
|
|
90
110
|
this.ws.onmessage = (event) => {
|
|
91
|
-
var _a;
|
|
92
111
|
try {
|
|
93
112
|
const data = JSON.parse(event.data);
|
|
94
113
|
// Handle pong response
|
|
95
114
|
if (data.channel === 'pong') {
|
|
96
|
-
// console.log('Received pong from server'); // 可以注释掉以减少日志输出
|
|
97
115
|
return;
|
|
98
116
|
}
|
|
99
117
|
const type = data.channel;
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
for (const { message, callback } of this.activeSubscriptions.values()) {
|
|
103
|
-
const subParams = message.subscription;
|
|
104
|
-
if (subParams.type === type) {
|
|
105
|
-
let isMatch = true;
|
|
106
|
-
// Filter based on subscription parameters
|
|
107
|
-
if (type === 'l2Book' && data.data.coin !== subParams.coin)
|
|
108
|
-
isMatch = false;
|
|
109
|
-
if (type === 'trades' && ((_a = data.data[0]) === null || _a === void 0 ? void 0 : _a.coin) !== subParams.coin)
|
|
110
|
-
isMatch = false;
|
|
111
|
-
if (type === 'candle' && (data.data.s !== subParams.coin || data.data.i !== subParams.interval))
|
|
112
|
-
isMatch = false;
|
|
113
|
-
if (type === 'activeAssetCtx' && data.data.coin !== subParams.coin)
|
|
114
|
-
isMatch = false;
|
|
115
|
-
// For user-specific data
|
|
116
|
-
if (subParams.user) {
|
|
117
|
-
// If response data contains user, verify it matches
|
|
118
|
-
if (data.data && data.data.user && data.data.user.toLowerCase() !== subParams.user.toLowerCase()) {
|
|
119
|
-
isMatch = false;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
if (isMatch) {
|
|
123
|
-
callback(data.data);
|
|
124
|
-
hasDispatched = true;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
// Fallback to simple type map if no active subscription matched (backward compatibility or if activeSubscriptions missing)
|
|
129
|
-
if (!hasDispatched) {
|
|
130
|
-
const callback = this.subscriptions.get(type);
|
|
131
|
-
if (callback) {
|
|
132
|
-
callback(data.data);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
118
|
+
// Dispatch message to matching subscriptions
|
|
119
|
+
this.dispatchMessage(type, data.data);
|
|
135
120
|
}
|
|
136
121
|
catch (error) {
|
|
137
122
|
console.error('Error parsing WebSocket message:', error);
|
|
@@ -207,7 +192,8 @@ class WebSocketClient {
|
|
|
207
192
|
this.ws.close();
|
|
208
193
|
this.ws = null;
|
|
209
194
|
}
|
|
210
|
-
this.
|
|
195
|
+
this.typeSubscriptions.clear();
|
|
196
|
+
this.userSubscriptions.clear();
|
|
211
197
|
this.activeSubscriptions.clear();
|
|
212
198
|
this.pendingSubscriptions = [];
|
|
213
199
|
this.reconnectAttempts = 0; // 重置重连计数
|
|
@@ -215,6 +201,26 @@ class WebSocketClient {
|
|
|
215
201
|
getSubscriptionKey(subscription) {
|
|
216
202
|
return JSON.stringify(subscription);
|
|
217
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* Dispatch message to matching subscriptions
|
|
206
|
+
* Uses direct lookup instead of iteration for better performance
|
|
207
|
+
*/
|
|
208
|
+
dispatchMessage(type, data) {
|
|
209
|
+
// Special handling for clearinghouseState: dispatch by type:user
|
|
210
|
+
if (type === constants_1.WsSubscriptionType.CLEARINGHOUSE_STATE && data.user) {
|
|
211
|
+
const userKey = `${type}:${data.user.toLowerCase()}`;
|
|
212
|
+
const callbacks = this.userSubscriptions.get(userKey);
|
|
213
|
+
if (callbacks && callbacks.length > 0) {
|
|
214
|
+
callbacks.forEach(callback => callback(data));
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// For all other types: direct lookup by type
|
|
219
|
+
const callbacks = this.typeSubscriptions.get(type);
|
|
220
|
+
if (callbacks && callbacks.length > 0) {
|
|
221
|
+
callbacks.forEach(callback => callback(data));
|
|
222
|
+
}
|
|
223
|
+
}
|
|
218
224
|
/**
|
|
219
225
|
* Subscribe to a channel
|
|
220
226
|
*/
|
|
@@ -223,8 +229,22 @@ class WebSocketClient {
|
|
|
223
229
|
const subscriptionData = { message, callback };
|
|
224
230
|
const subKey = this.getSubscriptionKey(message.subscription);
|
|
225
231
|
const type = message.subscription.type;
|
|
232
|
+
const user = message.subscription.user;
|
|
233
|
+
// Register callback in appropriate map
|
|
234
|
+
if (type === constants_1.WsSubscriptionType.CLEARINGHOUSE_STATE && user) {
|
|
235
|
+
// Multi-account support: store by type:user
|
|
236
|
+
const userKey = `${type}:${user.toLowerCase()}`;
|
|
237
|
+
const callbacks = this.userSubscriptions.get(userKey) || [];
|
|
238
|
+
callbacks.push(callback);
|
|
239
|
+
this.userSubscriptions.set(userKey, callbacks);
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
// Normal subscriptions: store by type
|
|
243
|
+
const callbacks = this.typeSubscriptions.get(type) || [];
|
|
244
|
+
callbacks.push(callback);
|
|
245
|
+
this.typeSubscriptions.set(type, callbacks);
|
|
246
|
+
}
|
|
226
247
|
if (((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN) {
|
|
227
|
-
this.subscriptions.set(type, callback);
|
|
228
248
|
this.activeSubscriptions.set(subKey, subscriptionData);
|
|
229
249
|
this.ws.send(JSON.stringify(Object.assign(Object.assign({}, message), { method: 'subscribe' })));
|
|
230
250
|
}
|
|
@@ -240,16 +260,31 @@ class WebSocketClient {
|
|
|
240
260
|
unsubscribe: () => {
|
|
241
261
|
var _a;
|
|
242
262
|
this.activeSubscriptions.delete(subKey);
|
|
243
|
-
//
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
263
|
+
// Remove callback from appropriate map
|
|
264
|
+
if (type === constants_1.WsSubscriptionType.CLEARINGHOUSE_STATE && user) {
|
|
265
|
+
const userKey = `${type}:${user.toLowerCase()}`;
|
|
266
|
+
const callbacks = this.userSubscriptions.get(userKey);
|
|
267
|
+
if (callbacks) {
|
|
268
|
+
const filtered = callbacks.filter(cb => cb !== callback);
|
|
269
|
+
if (filtered.length > 0) {
|
|
270
|
+
this.userSubscriptions.set(userKey, filtered);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
this.userSubscriptions.delete(userKey);
|
|
274
|
+
}
|
|
249
275
|
}
|
|
250
276
|
}
|
|
251
|
-
|
|
252
|
-
this.
|
|
277
|
+
else {
|
|
278
|
+
const callbacks = this.typeSubscriptions.get(type);
|
|
279
|
+
if (callbacks) {
|
|
280
|
+
const filtered = callbacks.filter(cb => cb !== callback);
|
|
281
|
+
if (filtered.length > 0) {
|
|
282
|
+
this.typeSubscriptions.set(type, filtered);
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
this.typeSubscriptions.delete(type);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
253
288
|
}
|
|
254
289
|
if (((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN) {
|
|
255
290
|
this.ws.send(JSON.stringify(Object.assign(Object.assign({}, message), { method: 'unsubscribe' })));
|
|
@@ -264,15 +299,24 @@ class WebSocketClient {
|
|
|
264
299
|
*/
|
|
265
300
|
subscribeToAllMids(callback) {
|
|
266
301
|
return this.subscribe({
|
|
267
|
-
subscription: { type:
|
|
302
|
+
subscription: { type: constants_1.WsSubscriptionType.ALL_MIDS },
|
|
268
303
|
}, callback);
|
|
269
304
|
}
|
|
270
305
|
/**
|
|
271
306
|
* Subscribe to L2 order book for a specific coin
|
|
307
|
+
* nSigFigs: Optional field to aggregate levels to nSigFigs significant figures. Valid values are 2, 3, 4, 5, and null, which means full precision
|
|
308
|
+
* mantissa: Optional field to aggregate levels. This field is only allowed if nSigFigs is 5. Accepts values of 1, 2 or 5.
|
|
309
|
+
* total six level
|
|
310
|
+
* nSigFig: 5 default
|
|
311
|
+
* nSigFig: 5 mantissa: 2
|
|
312
|
+
* nSigFig: 5 mantissa: 5
|
|
313
|
+
* nSigFig: 4
|
|
314
|
+
* nSigFig: 3
|
|
315
|
+
* nSigFig: 2
|
|
272
316
|
*/
|
|
273
|
-
subscribeToL2Book(coin, callback) {
|
|
317
|
+
subscribeToL2Book({ coin, nSigFigs, mantissa, }, callback) {
|
|
274
318
|
return this.subscribe({
|
|
275
|
-
subscription: { type:
|
|
319
|
+
subscription: { type: constants_1.WsSubscriptionType.L2_BOOK, coin, nSigFigs: nSigFigs !== null && nSigFigs !== void 0 ? nSigFigs : null, mantissa: mantissa !== null && mantissa !== void 0 ? mantissa : null },
|
|
276
320
|
}, callback);
|
|
277
321
|
}
|
|
278
322
|
/**
|
|
@@ -280,7 +324,7 @@ class WebSocketClient {
|
|
|
280
324
|
*/
|
|
281
325
|
subscribeToActiveAssetCtx(coin, callback) {
|
|
282
326
|
return this.subscribe({
|
|
283
|
-
subscription: { type:
|
|
327
|
+
subscription: { type: constants_1.WsSubscriptionType.ACTIVE_ASSET_CTX, coin },
|
|
284
328
|
}, callback);
|
|
285
329
|
}
|
|
286
330
|
/**
|
|
@@ -288,7 +332,7 @@ class WebSocketClient {
|
|
|
288
332
|
*/
|
|
289
333
|
subscribeToTrades(coin, callback) {
|
|
290
334
|
return this.subscribe({
|
|
291
|
-
subscription: { type:
|
|
335
|
+
subscription: { type: constants_1.WsSubscriptionType.TRADES, coin },
|
|
292
336
|
}, callback);
|
|
293
337
|
}
|
|
294
338
|
/**
|
|
@@ -296,7 +340,7 @@ class WebSocketClient {
|
|
|
296
340
|
*/
|
|
297
341
|
subscribeToCandles(coin, interval, callback) {
|
|
298
342
|
return this.subscribe({
|
|
299
|
-
subscription: { type:
|
|
343
|
+
subscription: { type: constants_1.WsSubscriptionType.CANDLE, coin, interval },
|
|
300
344
|
}, callback);
|
|
301
345
|
}
|
|
302
346
|
/**
|
|
@@ -307,7 +351,7 @@ class WebSocketClient {
|
|
|
307
351
|
throw new Error('masterAddress is empty');
|
|
308
352
|
}
|
|
309
353
|
return this.subscribe({
|
|
310
|
-
subscription: { type:
|
|
354
|
+
subscription: { type: constants_1.WsSubscriptionType.USER_FILLS, user: this.config.masterAddress, aggregateByTime: true },
|
|
311
355
|
}, callback);
|
|
312
356
|
}
|
|
313
357
|
/**
|
|
@@ -318,7 +362,7 @@ class WebSocketClient {
|
|
|
318
362
|
throw new Error('masterAddress is empty');
|
|
319
363
|
}
|
|
320
364
|
return this.subscribe({
|
|
321
|
-
subscription: { type:
|
|
365
|
+
subscription: { type: constants_1.WsSubscriptionType.ORDER_UPDATES, user: this.config.masterAddress },
|
|
322
366
|
}, callback);
|
|
323
367
|
}
|
|
324
368
|
/**
|
|
@@ -329,7 +373,7 @@ class WebSocketClient {
|
|
|
329
373
|
throw new Error('masterAddress is empty');
|
|
330
374
|
}
|
|
331
375
|
return this.subscribe({
|
|
332
|
-
subscription: { type:
|
|
376
|
+
subscription: { type: constants_1.WsSubscriptionType.USER_FUNDINGS, user: this.config.masterAddress },
|
|
333
377
|
}, callback);
|
|
334
378
|
}
|
|
335
379
|
/**
|
|
@@ -341,7 +385,7 @@ class WebSocketClient {
|
|
|
341
385
|
throw new Error('masterAddress is empty');
|
|
342
386
|
}
|
|
343
387
|
return this.subscribe({
|
|
344
|
-
subscription: { type:
|
|
388
|
+
subscription: { type: constants_1.WsSubscriptionType.WEB_DATA2, user: this.config.masterAddress },
|
|
345
389
|
}, callback);
|
|
346
390
|
}
|
|
347
391
|
subscribeToClearinghouseState(user, callback) {
|
|
@@ -350,7 +394,7 @@ class WebSocketClient {
|
|
|
350
394
|
throw new Error('user address is empty');
|
|
351
395
|
}
|
|
352
396
|
const subscriptions = users.map(u => this.subscribe({
|
|
353
|
-
subscription: { type:
|
|
397
|
+
subscription: { type: constants_1.WsSubscriptionType.CLEARINGHOUSE_STATE, user: u || this.config.masterAddress },
|
|
354
398
|
}, callback));
|
|
355
399
|
return {
|
|
356
400
|
unsubscribe: () => {
|
|
@@ -412,5 +456,71 @@ class WebSocketClient {
|
|
|
412
456
|
}
|
|
413
457
|
}
|
|
414
458
|
}
|
|
459
|
+
/**
|
|
460
|
+
* Subscribe to notification messages
|
|
461
|
+
*/
|
|
462
|
+
subscribeToNotification(callback) {
|
|
463
|
+
if (!this.config.masterAddress) {
|
|
464
|
+
throw new Error('masterAddress is empty');
|
|
465
|
+
}
|
|
466
|
+
return this.subscribe({
|
|
467
|
+
subscription: { type: constants_1.WsSubscriptionType.NOTIFICATION, user: this.config.masterAddress },
|
|
468
|
+
}, callback);
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Subscribe to TWAP order states
|
|
472
|
+
*/
|
|
473
|
+
subscribeToTwapStates(callback) {
|
|
474
|
+
if (!this.config.masterAddress) {
|
|
475
|
+
throw new Error('masterAddress is empty');
|
|
476
|
+
}
|
|
477
|
+
return this.subscribe({
|
|
478
|
+
subscription: { type: constants_1.WsSubscriptionType.TWAP_STATES, user: this.config.masterAddress },
|
|
479
|
+
}, callback);
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Subscribe to open orders
|
|
483
|
+
*/
|
|
484
|
+
subscribeToOpenOrders(callback) {
|
|
485
|
+
if (!this.config.masterAddress) {
|
|
486
|
+
throw new Error('masterAddress is empty');
|
|
487
|
+
}
|
|
488
|
+
return this.subscribe({
|
|
489
|
+
subscription: { type: constants_1.WsSubscriptionType.OPEN_ORDERS, user: this.config.masterAddress },
|
|
490
|
+
}, callback);
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Subscribe to user non-funding ledger updates (deposits/withdrawals)
|
|
494
|
+
*/
|
|
495
|
+
subscribeToUserNonFundingLedgerUpdates(callback) {
|
|
496
|
+
if (!this.config.masterAddress) {
|
|
497
|
+
throw new Error('masterAddress is empty');
|
|
498
|
+
}
|
|
499
|
+
return this.subscribe({
|
|
500
|
+
subscription: { type: constants_1.WsSubscriptionType.USER_NON_FUNDING_LEDGER_UPDATES, user: this.config.masterAddress },
|
|
501
|
+
}, callback);
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Subscribe to user TWAP slice fills
|
|
505
|
+
*/
|
|
506
|
+
subscribeToUserTwapSliceFills(callback) {
|
|
507
|
+
if (!this.config.masterAddress) {
|
|
508
|
+
throw new Error('masterAddress is empty');
|
|
509
|
+
}
|
|
510
|
+
return this.subscribe({
|
|
511
|
+
subscription: { type: constants_1.WsSubscriptionType.USER_TWAP_SLICE_FILLS, user: this.config.masterAddress },
|
|
512
|
+
}, callback);
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Subscribe to user TWAP history
|
|
516
|
+
*/
|
|
517
|
+
subscribeToUserTwapHistory(callback) {
|
|
518
|
+
if (!this.config.masterAddress) {
|
|
519
|
+
throw new Error('masterAddress is empty');
|
|
520
|
+
}
|
|
521
|
+
return this.subscribe({
|
|
522
|
+
subscription: { type: constants_1.WsSubscriptionType.USER_TWAP_HISTORY, user: this.config.masterAddress },
|
|
523
|
+
}, callback);
|
|
524
|
+
}
|
|
415
525
|
}
|
|
416
526
|
exports.WebSocketClient = WebSocketClient;
|
package/dist/index.d.ts
CHANGED
|
@@ -6,4 +6,4 @@ export { HttpClient, HttpClientConfig } from './client/http-client';
|
|
|
6
6
|
export * from './types';
|
|
7
7
|
export * from './types/constants';
|
|
8
8
|
export { BASE_URLS, WSS_URLS, ENDPOINTS } from './types/constants';
|
|
9
|
-
export { InfoType, ExchangeType, OrderType, TimeInForce } from './types/constants';
|
|
9
|
+
export { InfoType, ExchangeType, OrderType, TimeInForce, WsSubscriptionType } from './types/constants';
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.TimeInForce = exports.OrderType = exports.ExchangeType = exports.InfoType = exports.ENDPOINTS = exports.WSS_URLS = exports.BASE_URLS = exports.HttpClient = exports.WebSocketClient = exports.ExchangeClient = exports.InfoClient = exports.HyperliquidSDK = void 0;
|
|
17
|
+
exports.WsSubscriptionType = exports.TimeInForce = exports.OrderType = exports.ExchangeType = exports.InfoType = exports.ENDPOINTS = exports.WSS_URLS = exports.BASE_URLS = exports.HttpClient = exports.WebSocketClient = exports.ExchangeClient = exports.InfoClient = exports.HyperliquidSDK = void 0;
|
|
18
18
|
// Main SDK
|
|
19
19
|
var hyperliquid_sdk_1 = require("./hyperliquid-sdk");
|
|
20
20
|
Object.defineProperty(exports, "HyperliquidSDK", { enumerable: true, get: function () { return hyperliquid_sdk_1.HyperliquidSDK; } });
|
|
@@ -40,3 +40,4 @@ Object.defineProperty(exports, "InfoType", { enumerable: true, get: function ()
|
|
|
40
40
|
Object.defineProperty(exports, "ExchangeType", { enumerable: true, get: function () { return constants_2.ExchangeType; } });
|
|
41
41
|
Object.defineProperty(exports, "OrderType", { enumerable: true, get: function () { return constants_2.OrderType; } });
|
|
42
42
|
Object.defineProperty(exports, "TimeInForce", { enumerable: true, get: function () { return constants_2.TimeInForce; } });
|
|
43
|
+
Object.defineProperty(exports, "WsSubscriptionType", { enumerable: true, get: function () { return constants_2.WsSubscriptionType; } });
|
|
@@ -23,17 +23,22 @@ export declare enum ExchangeType {
|
|
|
23
23
|
APPROVE_AGENT = "approveAgent",
|
|
24
24
|
APPROVE_BUILDER_FEE = "approveBuilderFee",
|
|
25
25
|
SUB_ACCOUNT_TRANSFER = "subAccountTransfer",
|
|
26
|
-
SET_REFERRER = "setReferrer"
|
|
26
|
+
SET_REFERRER = "setReferrer",
|
|
27
|
+
TWAP_ORDER = "twapOrder",
|
|
28
|
+
TWAP_CANCEL = "twapCancel"
|
|
27
29
|
}
|
|
28
30
|
export declare enum InfoType {
|
|
29
31
|
ALL_MIDS = "allMids",
|
|
32
|
+
NOTIFICATION = "notification",
|
|
30
33
|
USER_NON_FUNDING_LEDGER_UPDATES = "userNonFundingLedgerUpdates",
|
|
31
34
|
USER_HISTORICAL_ORDERS = "historicalOrders",
|
|
32
35
|
USER_OPEN_ORDERS = "openOrders",
|
|
33
36
|
USER_FILLS = "userFills",
|
|
34
37
|
USER_FILLS_BY_TIME = "userFillsByTime",
|
|
38
|
+
USER_TWAP_SLICE_FILLS = "userTwapSliceFills",
|
|
35
39
|
ORDER_STATUS = "orderStatus",
|
|
36
40
|
L2_BOOK = "l2Book",
|
|
41
|
+
TRADES = "trades",
|
|
37
42
|
CANDLES_SNAPSHOT = "candleSnapshot",
|
|
38
43
|
META_AND_ASSET_CTXS = "metaAndAssetCtxs",
|
|
39
44
|
USER_FUNDING = "userFunding",
|
|
@@ -68,3 +73,21 @@ export declare const CHAIN_IDS: {
|
|
|
68
73
|
readonly HYPERLIQUID_MAINNET: 1337;
|
|
69
74
|
};
|
|
70
75
|
export declare const SLIPPAGE = 0.08;
|
|
76
|
+
export declare enum WsSubscriptionType {
|
|
77
|
+
ALL_MIDS = "allMids",
|
|
78
|
+
L2_BOOK = "l2Book",
|
|
79
|
+
TRADES = "trades",
|
|
80
|
+
CANDLE = "candle",
|
|
81
|
+
ACTIVE_ASSET_CTX = "activeAssetCtx",
|
|
82
|
+
USER_FILLS = "userFills",
|
|
83
|
+
ORDER_UPDATES = "orderUpdates",
|
|
84
|
+
USER_FUNDINGS = "userFundings",
|
|
85
|
+
WEB_DATA2 = "webData2",
|
|
86
|
+
CLEARINGHOUSE_STATE = "clearinghouseState",
|
|
87
|
+
NOTIFICATION = "notification",
|
|
88
|
+
TWAP_STATES = "twapStates",
|
|
89
|
+
OPEN_ORDERS = "openOrders",
|
|
90
|
+
USER_NON_FUNDING_LEDGER_UPDATES = "userNonFundingLedgerUpdates",
|
|
91
|
+
USER_TWAP_SLICE_FILLS = "userTwapSliceFills",
|
|
92
|
+
USER_TWAP_HISTORY = "userTwapHistory"
|
|
93
|
+
}
|
package/dist/types/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SLIPPAGE = exports.CHAIN_IDS = exports.TimeInForce = exports.OrderType = exports.InfoType = exports.ExchangeType = exports.ENDPOINTS = exports.WSS_URLS = exports.BASE_URLS = void 0;
|
|
3
|
+
exports.WsSubscriptionType = exports.SLIPPAGE = exports.CHAIN_IDS = exports.TimeInForce = exports.OrderType = exports.InfoType = exports.ExchangeType = exports.ENDPOINTS = exports.WSS_URLS = exports.BASE_URLS = void 0;
|
|
4
4
|
// API endpoints
|
|
5
5
|
exports.BASE_URLS = {
|
|
6
6
|
PRODUCTION: 'https://api.hyperliquid.xyz',
|
|
@@ -30,18 +30,23 @@ var ExchangeType;
|
|
|
30
30
|
ExchangeType["APPROVE_BUILDER_FEE"] = "approveBuilderFee";
|
|
31
31
|
ExchangeType["SUB_ACCOUNT_TRANSFER"] = "subAccountTransfer";
|
|
32
32
|
ExchangeType["SET_REFERRER"] = "setReferrer";
|
|
33
|
+
ExchangeType["TWAP_ORDER"] = "twapOrder";
|
|
34
|
+
ExchangeType["TWAP_CANCEL"] = "twapCancel";
|
|
33
35
|
})(ExchangeType || (exports.ExchangeType = ExchangeType = {}));
|
|
34
36
|
// Info types for API requests (perpetuals only)
|
|
35
37
|
var InfoType;
|
|
36
38
|
(function (InfoType) {
|
|
37
39
|
InfoType["ALL_MIDS"] = "allMids";
|
|
40
|
+
InfoType["NOTIFICATION"] = "notification";
|
|
38
41
|
InfoType["USER_NON_FUNDING_LEDGER_UPDATES"] = "userNonFundingLedgerUpdates";
|
|
39
42
|
InfoType["USER_HISTORICAL_ORDERS"] = "historicalOrders";
|
|
40
43
|
InfoType["USER_OPEN_ORDERS"] = "openOrders";
|
|
41
44
|
InfoType["USER_FILLS"] = "userFills";
|
|
42
45
|
InfoType["USER_FILLS_BY_TIME"] = "userFillsByTime";
|
|
46
|
+
InfoType["USER_TWAP_SLICE_FILLS"] = "userTwapSliceFills";
|
|
43
47
|
InfoType["ORDER_STATUS"] = "orderStatus";
|
|
44
48
|
InfoType["L2_BOOK"] = "l2Book";
|
|
49
|
+
InfoType["TRADES"] = "trades";
|
|
45
50
|
InfoType["CANDLES_SNAPSHOT"] = "candleSnapshot";
|
|
46
51
|
InfoType["META_AND_ASSET_CTXS"] = "metaAndAssetCtxs";
|
|
47
52
|
InfoType["USER_FUNDING"] = "userFunding";
|
|
@@ -81,3 +86,23 @@ exports.CHAIN_IDS = {
|
|
|
81
86
|
HYPERLIQUID_MAINNET: 1337,
|
|
82
87
|
};
|
|
83
88
|
exports.SLIPPAGE = 0.08;
|
|
89
|
+
// WebSocket subscription types
|
|
90
|
+
var WsSubscriptionType;
|
|
91
|
+
(function (WsSubscriptionType) {
|
|
92
|
+
WsSubscriptionType["ALL_MIDS"] = "allMids";
|
|
93
|
+
WsSubscriptionType["L2_BOOK"] = "l2Book";
|
|
94
|
+
WsSubscriptionType["TRADES"] = "trades";
|
|
95
|
+
WsSubscriptionType["CANDLE"] = "candle";
|
|
96
|
+
WsSubscriptionType["ACTIVE_ASSET_CTX"] = "activeAssetCtx";
|
|
97
|
+
WsSubscriptionType["USER_FILLS"] = "userFills";
|
|
98
|
+
WsSubscriptionType["ORDER_UPDATES"] = "orderUpdates";
|
|
99
|
+
WsSubscriptionType["USER_FUNDINGS"] = "userFundings";
|
|
100
|
+
WsSubscriptionType["WEB_DATA2"] = "webData2";
|
|
101
|
+
WsSubscriptionType["CLEARINGHOUSE_STATE"] = "clearinghouseState";
|
|
102
|
+
WsSubscriptionType["NOTIFICATION"] = "notification";
|
|
103
|
+
WsSubscriptionType["TWAP_STATES"] = "twapStates";
|
|
104
|
+
WsSubscriptionType["OPEN_ORDERS"] = "openOrders";
|
|
105
|
+
WsSubscriptionType["USER_NON_FUNDING_LEDGER_UPDATES"] = "userNonFundingLedgerUpdates";
|
|
106
|
+
WsSubscriptionType["USER_TWAP_SLICE_FILLS"] = "userTwapSliceFills";
|
|
107
|
+
WsSubscriptionType["USER_TWAP_HISTORY"] = "userTwapHistory";
|
|
108
|
+
})(WsSubscriptionType || (exports.WsSubscriptionType = WsSubscriptionType = {}));
|
package/dist/types/index.d.ts
CHANGED
|
@@ -154,6 +154,11 @@ export interface UserFill {
|
|
|
154
154
|
export type UserFills = {
|
|
155
155
|
[asset: string]: UserFill[];
|
|
156
156
|
};
|
|
157
|
+
export type wsUserNonFundingLedgerUpdates = {
|
|
158
|
+
user: string;
|
|
159
|
+
isSnapshot: boolean;
|
|
160
|
+
nonFundingLedgerUpdates: UserNonFundingLedgerUpdates[];
|
|
161
|
+
};
|
|
157
162
|
export type UserNonFundingLedgerUpdates = {
|
|
158
163
|
time: number;
|
|
159
164
|
hash: string;
|
|
@@ -281,6 +286,9 @@ export interface AssetCtx {
|
|
|
281
286
|
export interface AllMids {
|
|
282
287
|
[coin: string]: string;
|
|
283
288
|
}
|
|
289
|
+
export interface WsAllMids {
|
|
290
|
+
mids: AllMids;
|
|
291
|
+
}
|
|
284
292
|
export interface L2Book {
|
|
285
293
|
coin: string;
|
|
286
294
|
levels: [WsLevel[], WsLevel[]];
|
|
@@ -298,6 +306,15 @@ export interface WsActiveAssetCtx {
|
|
|
298
306
|
oraclePx: string;
|
|
299
307
|
};
|
|
300
308
|
}
|
|
309
|
+
export interface WsTrade {
|
|
310
|
+
coin: string;
|
|
311
|
+
hash: string;
|
|
312
|
+
px: string;
|
|
313
|
+
sz: string;
|
|
314
|
+
side: Side;
|
|
315
|
+
tid: number;
|
|
316
|
+
time: number;
|
|
317
|
+
}
|
|
301
318
|
export interface Candle {
|
|
302
319
|
t: number;
|
|
303
320
|
T: number;
|
|
@@ -467,3 +484,104 @@ export interface ReferralResponse {
|
|
|
467
484
|
};
|
|
468
485
|
rewardHistory: any[];
|
|
469
486
|
}
|
|
487
|
+
export interface TwapOrderParams {
|
|
488
|
+
coin: string;
|
|
489
|
+
isBuy: boolean;
|
|
490
|
+
sz: string;
|
|
491
|
+
reduceOnly?: boolean;
|
|
492
|
+
durationMillis: number;
|
|
493
|
+
randomizeDelay?: boolean;
|
|
494
|
+
builder?: {
|
|
495
|
+
address: string;
|
|
496
|
+
fee: number;
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
export interface TwapCancelParams {
|
|
500
|
+
coin: string;
|
|
501
|
+
twapId: number;
|
|
502
|
+
}
|
|
503
|
+
export interface TwapOrderResponse {
|
|
504
|
+
status: 'ok';
|
|
505
|
+
response: {
|
|
506
|
+
type: 'twapOrder';
|
|
507
|
+
data: {
|
|
508
|
+
twapId: number;
|
|
509
|
+
};
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
export interface TwapState {
|
|
513
|
+
twapId: number;
|
|
514
|
+
coin: string;
|
|
515
|
+
isBuy: boolean;
|
|
516
|
+
sz: string;
|
|
517
|
+
reduceOnly: boolean;
|
|
518
|
+
totalSz: string;
|
|
519
|
+
executedSz: string;
|
|
520
|
+
remainingSz: string;
|
|
521
|
+
startTime: number;
|
|
522
|
+
endTime: number;
|
|
523
|
+
status: 'active' | 'completed' | 'cancelled';
|
|
524
|
+
}
|
|
525
|
+
export interface WsTwapStates {
|
|
526
|
+
dex: string;
|
|
527
|
+
user: string;
|
|
528
|
+
states?: TwapState[];
|
|
529
|
+
}
|
|
530
|
+
export interface WsOpenOrders {
|
|
531
|
+
user: string;
|
|
532
|
+
orders?: OpenOrder[];
|
|
533
|
+
}
|
|
534
|
+
export interface WsUserTwapSliceFills {
|
|
535
|
+
user: string;
|
|
536
|
+
fills?: UserTwapSliceFill[];
|
|
537
|
+
}
|
|
538
|
+
export interface WsUserTwapHistory {
|
|
539
|
+
user: string;
|
|
540
|
+
history?: UserTwapHistory[];
|
|
541
|
+
}
|
|
542
|
+
export interface UserTwapSliceFill {
|
|
543
|
+
coin: string;
|
|
544
|
+
px: string;
|
|
545
|
+
sz: string;
|
|
546
|
+
side: Side;
|
|
547
|
+
time: number;
|
|
548
|
+
hash: string;
|
|
549
|
+
oid: number;
|
|
550
|
+
crossed: boolean;
|
|
551
|
+
fee: string;
|
|
552
|
+
tid: number;
|
|
553
|
+
twapId: number;
|
|
554
|
+
}
|
|
555
|
+
export interface UserTwapHistory {
|
|
556
|
+
twapId: number;
|
|
557
|
+
user: string;
|
|
558
|
+
coin: string;
|
|
559
|
+
side: Side;
|
|
560
|
+
sz: string;
|
|
561
|
+
totalFilled: string;
|
|
562
|
+
avgFillPx: string;
|
|
563
|
+
startTime: number;
|
|
564
|
+
endTime: number;
|
|
565
|
+
status: string;
|
|
566
|
+
}
|
|
567
|
+
export interface L2BookSnapshot {
|
|
568
|
+
coin: string;
|
|
569
|
+
levels: [WsLevel[], WsLevel[]];
|
|
570
|
+
time: number;
|
|
571
|
+
}
|
|
572
|
+
export interface FundingHistoryItem {
|
|
573
|
+
coin: string;
|
|
574
|
+
fundingRate: string;
|
|
575
|
+
premium: string;
|
|
576
|
+
time: number;
|
|
577
|
+
}
|
|
578
|
+
export interface UserFunding {
|
|
579
|
+
time: number;
|
|
580
|
+
coin: string;
|
|
581
|
+
usdc: string;
|
|
582
|
+
szi: string;
|
|
583
|
+
fundingRate: string;
|
|
584
|
+
}
|
|
585
|
+
export interface Notification {
|
|
586
|
+
notification: string;
|
|
587
|
+
}
|
package/dist/types/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@rabby-wallet/hyperliquid-sdk",
|
|
3
|
-
"version": "1.1.1",
|
|
4
|
-
"description": "Simplified Hyperliquid Perpetuals Trading SDK for Frontend Applications",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
7
|
-
"files": [
|
|
8
|
-
"dist"
|
|
9
|
-
],
|
|
10
|
-
"publishConfig": {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
"@
|
|
23
|
-
"@
|
|
24
|
-
"@
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@rabby-wallet/hyperliquid-sdk",
|
|
3
|
+
"version": "1.1.2-beta.1",
|
|
4
|
+
"description": "Simplified Hyperliquid Perpetuals Trading SDK for Frontend Applications",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "rimraf dist && tsc",
|
|
16
|
+
"preversion": "npm run build",
|
|
17
|
+
"prepublishOnly": "npm run build"
|
|
18
|
+
},
|
|
19
|
+
"author": "",
|
|
20
|
+
"license": "UNLICENSED",
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@ethereumjs/util": "9.0.0",
|
|
23
|
+
"@metamask/eth-sig-util": "5.1.0",
|
|
24
|
+
"@msgpack/msgpack": "3.1.2",
|
|
25
|
+
"@noble/hashes": "1.8.0",
|
|
26
|
+
"ethereum-cryptography": "2.2.1"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/node": "24.3.1",
|
|
30
|
+
"prettier": "2.7.1",
|
|
31
|
+
"rimraf": "6.0.0",
|
|
32
|
+
"typescript": "5.9.2"
|
|
33
|
+
},
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=16.0.0"
|
|
36
|
+
},
|
|
37
|
+
"packageManager": "yarn@1.22.22"
|
|
38
|
+
}
|