@yuants/vendor-hyperliquid 0.9.9 → 0.10.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/dist/api/client.js +36 -2
- package/dist/api/client.js.map +1 -1
- package/dist/api/private-api.js +52 -41
- package/dist/api/private-api.js.map +1 -1
- package/dist/api/public-api.js +22 -11
- package/dist/api/public-api.js.map +1 -1
- package/dist/api/rate-limit.js +205 -0
- package/dist/api/rate-limit.js.map +1 -0
- package/dist/api/rate-limit.test.js +129 -0
- package/dist/api/rate-limit.test.js.map +1 -0
- package/dist/api/sign.js.map +1 -1
- package/dist/api/types.js.map +1 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +1 -1
- package/dist/services/accounts/spot.js.map +1 -1
- package/dist/services/exchange.js.map +1 -1
- package/dist/services/markets/quote.js.map +1 -1
- package/dist/services/ohlc-service.js.map +1 -1
- package/dist/services/orders/cancelOrder.js.map +1 -1
- package/dist/services/orders/listOrders.js +2 -2
- package/dist/services/orders/listOrders.js.map +1 -1
- package/dist/services/orders/modifyOrder.js.map +1 -1
- package/dist/services/quotes.js.map +1 -1
- package/dist/services/utils.js.map +1 -1
- package/lib/api/client.d.ts +1 -1
- package/lib/api/client.d.ts.map +1 -1
- package/lib/api/client.js +35 -1
- package/lib/api/client.js.map +1 -1
- package/lib/api/private-api.d.ts +67 -3
- package/lib/api/private-api.d.ts.map +1 -1
- package/lib/api/private-api.js +59 -43
- package/lib/api/private-api.js.map +1 -1
- package/lib/api/public-api.d.ts +61 -11
- package/lib/api/public-api.d.ts.map +1 -1
- package/lib/api/public-api.js +33 -12
- package/lib/api/public-api.js.map +1 -1
- package/lib/api/rate-limit.d.ts +21 -0
- package/lib/api/rate-limit.d.ts.map +1 -0
- package/lib/api/rate-limit.js +214 -0
- package/lib/api/rate-limit.js.map +1 -0
- package/lib/api/rate-limit.test.d.ts +2 -0
- package/lib/api/rate-limit.test.d.ts.map +1 -0
- package/lib/api/rate-limit.test.js +131 -0
- package/lib/api/rate-limit.test.js.map +1 -0
- package/lib/api/sign.js +5 -6
- package/lib/api/sign.js.map +1 -1
- package/lib/api/types.d.ts.map +1 -1
- package/lib/api/types.js.map +1 -1
- package/lib/index.d.ts +0 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +0 -2
- package/lib/index.js.map +1 -1
- package/lib/services/accounts/perp.d.ts.map +1 -1
- package/lib/services/accounts/spot.d.ts.map +1 -1
- package/lib/services/accounts/spot.js.map +1 -1
- package/lib/services/exchange.js.map +1 -1
- package/lib/services/markets/product.d.ts.map +1 -1
- package/lib/services/markets/quote.js.map +1 -1
- package/lib/services/ohlc-service.js.map +1 -1
- package/lib/services/orders/cancelOrder.d.ts.map +1 -1
- package/lib/services/orders/cancelOrder.js.map +1 -1
- package/lib/services/orders/listOrders.d.ts.map +1 -1
- package/lib/services/orders/listOrders.js +2 -2
- package/lib/services/orders/listOrders.js.map +1 -1
- package/lib/services/orders/modifyOrder.d.ts.map +1 -1
- package/lib/services/orders/modifyOrder.js.map +1 -1
- package/lib/services/orders/submitOrder.d.ts.map +1 -1
- package/lib/services/quotes.js.map +1 -1
- package/lib/services/utils.d.ts +2 -2
- package/lib/services/utils.d.ts.map +1 -1
- package/lib/services/utils.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/package.json +48 -48
- package/temp/build/typescript/ts_HOjXkPSo.json +1 -0
- package/temp/package-deps.json +27 -27
- package/temp/test/jest/haste-map-1a3370ad4952cc1cbecf8fc42c6e9732-7b2990dcc44090c4eba2c52e971c544c-6a2a6e27ca3579da37751287ea19ab4c +0 -0
- package/temp/test/jest/perf-cache-1a3370ad4952cc1cbecf8fc42c6e9732-da39a3ee5e6b4b0d3255bfef95601890 +1 -0
- package/temp/vendor-hyperliquid.api.json +18 -2
- package/dist/services/markets/interest-rate.js +0 -60
- package/dist/services/markets/interest-rate.js.map +0 -1
- package/dist/services/markets/ohlc.js +0 -110
- package/dist/services/markets/ohlc.js.map +0 -1
- package/lib/services/markets/interest-rate.d.ts +0 -2
- package/lib/services/markets/interest-rate.d.ts.map +0 -1
- package/lib/services/markets/interest-rate.js +0 -62
- package/lib/services/markets/interest-rate.js.map +0 -1
- package/lib/services/markets/ohlc.d.ts +0 -2
- package/lib/services/markets/ohlc.d.ts.map +0 -1
- package/lib/services/markets/ohlc.js +0 -112
- package/lib/services/markets/ohlc.js.map +0 -1
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@yuants/utils");
|
|
4
|
+
const rate_limit_1 = require("./rate-limit");
|
|
5
|
+
describe('rate-limit', () => {
|
|
6
|
+
const bucketId = 'HYPERLIQUID_REST_IP_WEIGHT_1200_PER_MIN';
|
|
7
|
+
const readBucket = () => (0, utils_1.tokenBucket)(bucketId).read();
|
|
8
|
+
afterAll(() => {
|
|
9
|
+
const bucket = (0, utils_1.tokenBucket)(bucketId);
|
|
10
|
+
bucket[Symbol.dispose]();
|
|
11
|
+
});
|
|
12
|
+
it('parses rest request context', () => {
|
|
13
|
+
const infoCtx = (0, rate_limit_1.getRestRequestContext)('POST', 'info', { type: 'allMids' });
|
|
14
|
+
expect(infoCtx.kind).toBe('info');
|
|
15
|
+
expect(infoCtx.infoType).toBe('allMids');
|
|
16
|
+
const exchangeCtx = (0, rate_limit_1.getRestRequestContext)('POST', 'exchange', {
|
|
17
|
+
action: { type: 'order', orders: [{}, {}] },
|
|
18
|
+
});
|
|
19
|
+
expect(exchangeCtx.kind).toBe('exchange');
|
|
20
|
+
expect(exchangeCtx.exchangeActionType).toBe('order');
|
|
21
|
+
expect(exchangeCtx.exchangeBatchLength).toBe(2);
|
|
22
|
+
const explorerCtx = (0, rate_limit_1.getRestRequestContext)('GET', 'explorer/tx/0x', undefined);
|
|
23
|
+
expect(explorerCtx.kind).toBe('explorer');
|
|
24
|
+
});
|
|
25
|
+
it('calculates info base weight', () => {
|
|
26
|
+
const ctx = (0, rate_limit_1.getRestRequestContext)('POST', 'info', { type: 'allMids' });
|
|
27
|
+
expect((0, rate_limit_1.getRestBaseWeight)(ctx)).toBe(2);
|
|
28
|
+
});
|
|
29
|
+
it('defaults base weight for unknown info type', () => {
|
|
30
|
+
const ctx = (0, rate_limit_1.getRestRequestContext)('POST', 'info', { type: 'unknownType' });
|
|
31
|
+
expect((0, rate_limit_1.getRestBaseWeight)(ctx)).toBe(20);
|
|
32
|
+
});
|
|
33
|
+
it('assigns base weight for explorer and other requests', () => {
|
|
34
|
+
const explorerCtx = (0, rate_limit_1.getRestRequestContext)('GET', 'explorer/tx/0x', undefined);
|
|
35
|
+
expect((0, rate_limit_1.getRestBaseWeight)(explorerCtx)).toBe(40);
|
|
36
|
+
const otherCtx = (0, rate_limit_1.getRestRequestContext)('GET', 'status', undefined);
|
|
37
|
+
expect((0, rate_limit_1.getRestBaseWeight)(otherCtx)).toBe(20);
|
|
38
|
+
});
|
|
39
|
+
it('calculates exchange base weight across batch sizes', () => {
|
|
40
|
+
const cases = [
|
|
41
|
+
{ batchLength: 0, expected: 1 },
|
|
42
|
+
{ batchLength: 1, expected: 1 },
|
|
43
|
+
{ batchLength: 40, expected: 2 },
|
|
44
|
+
{ batchLength: 41, expected: 2 },
|
|
45
|
+
{ batchLength: 80, expected: 3 },
|
|
46
|
+
];
|
|
47
|
+
for (const { batchLength, expected } of cases) {
|
|
48
|
+
const ctx = (0, rate_limit_1.getRestRequestContext)('POST', 'exchange', {
|
|
49
|
+
action: { type: 'order', orders: new Array(batchLength).fill({}) },
|
|
50
|
+
});
|
|
51
|
+
expect((0, rate_limit_1.getRestBaseWeight)(ctx)).toBe(expected);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
it('estimates candleSnapshot extra weight with 5000 cap', () => {
|
|
55
|
+
const intervalMs = 60000;
|
|
56
|
+
const candles = 10000;
|
|
57
|
+
const ctx = (0, rate_limit_1.getRestRequestContext)('POST', 'info', {
|
|
58
|
+
type: 'candleSnapshot',
|
|
59
|
+
req: { interval: '1m', startTime: 0, endTime: candles * intervalMs },
|
|
60
|
+
});
|
|
61
|
+
expect((0, rate_limit_1.getRestEstimatedExtraWeight)(ctx)).toBe(Math.ceil(5000 / 60));
|
|
62
|
+
});
|
|
63
|
+
it('returns zero extra weight for invalid candleSnapshot inputs', () => {
|
|
64
|
+
const invalidIntervalCtx = (0, rate_limit_1.getRestRequestContext)('POST', 'info', {
|
|
65
|
+
type: 'candleSnapshot',
|
|
66
|
+
req: { interval: '2m', startTime: 0, endTime: 60000 },
|
|
67
|
+
});
|
|
68
|
+
expect((0, rate_limit_1.getRestEstimatedExtraWeight)(invalidIntervalCtx)).toBe(0);
|
|
69
|
+
const sameTimeCtx = (0, rate_limit_1.getRestRequestContext)('POST', 'info', {
|
|
70
|
+
type: 'candleSnapshot',
|
|
71
|
+
req: { interval: '1m', startTime: 0, endTime: 0 },
|
|
72
|
+
});
|
|
73
|
+
expect((0, rate_limit_1.getRestEstimatedExtraWeight)(sameTimeCtx)).toBe(0);
|
|
74
|
+
const missingReqCtx = (0, rate_limit_1.getRestRequestContext)('POST', 'info', { type: 'candleSnapshot' });
|
|
75
|
+
expect((0, rate_limit_1.getRestEstimatedExtraWeight)(missingReqCtx)).toBe(0);
|
|
76
|
+
});
|
|
77
|
+
it('consumes base and estimated weight before request', () => {
|
|
78
|
+
const ctx = (0, rate_limit_1.getRestRequestContext)('POST', 'info', {
|
|
79
|
+
type: 'candleSnapshot',
|
|
80
|
+
req: { interval: '1m', startTime: 0, endTime: 120 * 60000 },
|
|
81
|
+
});
|
|
82
|
+
const before = readBucket();
|
|
83
|
+
const { baseWeight, estimatedExtraWeight } = (0, rate_limit_1.beforeRestRequest)({ requestKey: 'test' }, ctx);
|
|
84
|
+
const after = readBucket();
|
|
85
|
+
expect(baseWeight).toBe(20);
|
|
86
|
+
expect(estimatedExtraWeight).toBe(2);
|
|
87
|
+
expect(after).toBe(before - baseWeight - estimatedExtraWeight);
|
|
88
|
+
});
|
|
89
|
+
it('throws on invalid or excessive weights before request', () => {
|
|
90
|
+
const invalidCtx = {
|
|
91
|
+
method: 'POST',
|
|
92
|
+
path: 'exchange',
|
|
93
|
+
kind: 'exchange',
|
|
94
|
+
exchangeBatchLength: Number.NaN,
|
|
95
|
+
};
|
|
96
|
+
expect(() => (0, rate_limit_1.beforeRestRequest)({ requestKey: 'test' }, invalidCtx)).toThrow(/HYPERLIQUID_REST_WEIGHT_INVALID/);
|
|
97
|
+
const maxWeight = 1200 * 10;
|
|
98
|
+
const excessiveCtx = {
|
|
99
|
+
method: 'POST',
|
|
100
|
+
path: 'exchange',
|
|
101
|
+
kind: 'exchange',
|
|
102
|
+
exchangeBatchLength: (maxWeight + 1) * 40,
|
|
103
|
+
};
|
|
104
|
+
expect(() => (0, rate_limit_1.beforeRestRequest)({ requestKey: 'test' }, excessiveCtx)).toThrow(/HYPERLIQUID_REST_WEIGHT_EXCESSIVE/);
|
|
105
|
+
});
|
|
106
|
+
it('applies extra weight based on response size', async () => {
|
|
107
|
+
const ctx = (0, rate_limit_1.getRestRequestContext)('POST', 'info', { type: 'userFills' });
|
|
108
|
+
const response = { fills: new Array(41).fill({}) };
|
|
109
|
+
const before = readBucket();
|
|
110
|
+
await (0, rate_limit_1.afterRestResponse)({ requestKey: 'test' }, ctx, response, 0);
|
|
111
|
+
const after = readBucket();
|
|
112
|
+
expect(before - after).toBe(Math.ceil(41 / 20));
|
|
113
|
+
});
|
|
114
|
+
it('applies delta extra weight for candleSnapshot responses', async () => {
|
|
115
|
+
const ctx = (0, rate_limit_1.getRestRequestContext)('POST', 'info', { type: 'candleSnapshot' });
|
|
116
|
+
const response = new Array(120).fill({});
|
|
117
|
+
const before = readBucket();
|
|
118
|
+
await (0, rate_limit_1.afterRestResponse)({ requestKey: 'test' }, ctx, response, 1);
|
|
119
|
+
const after = readBucket();
|
|
120
|
+
expect(before - after).toBe(1);
|
|
121
|
+
});
|
|
122
|
+
it('skips extra acquire when response weight is within estimate', async () => {
|
|
123
|
+
const ctx = (0, rate_limit_1.getRestRequestContext)('POST', 'info', { type: 'userFills' });
|
|
124
|
+
const response = { fills: [{}] };
|
|
125
|
+
const before = readBucket();
|
|
126
|
+
await (0, rate_limit_1.afterRestResponse)({ requestKey: 'test' }, ctx, response, 1);
|
|
127
|
+
const after = readBucket();
|
|
128
|
+
expect(after).toBe(before);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
//# sourceMappingURL=rate-limit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.test.js","sourceRoot":"","sources":["../../src/api/rate-limit.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { tokenBucket } from '@yuants/utils';\nimport {\n afterRestResponse,\n beforeRestRequest,\n getRestBaseWeight,\n getRestEstimatedExtraWeight,\n getRestRequestContext,\n} from './rate-limit';\n\ndescribe('rate-limit', () => {\n const bucketId = 'HYPERLIQUID_REST_IP_WEIGHT_1200_PER_MIN';\n const readBucket = () => tokenBucket(bucketId).read();\n\n afterAll(() => {\n const bucket = tokenBucket(bucketId);\n bucket[Symbol.dispose]();\n });\n\n it('parses rest request context', () => {\n const infoCtx = getRestRequestContext('POST', 'info', { type: 'allMids' });\n expect(infoCtx.kind).toBe('info');\n expect(infoCtx.infoType).toBe('allMids');\n\n const exchangeCtx = getRestRequestContext('POST', 'exchange', {\n action: { type: 'order', orders: [{}, {}] },\n });\n expect(exchangeCtx.kind).toBe('exchange');\n expect(exchangeCtx.exchangeActionType).toBe('order');\n expect(exchangeCtx.exchangeBatchLength).toBe(2);\n\n const explorerCtx = getRestRequestContext('GET', 'explorer/tx/0x', undefined);\n expect(explorerCtx.kind).toBe('explorer');\n });\n\n it('calculates info base weight', () => {\n const ctx = getRestRequestContext('POST', 'info', { type: 'allMids' });\n expect(getRestBaseWeight(ctx)).toBe(2);\n });\n\n it('defaults base weight for unknown info type', () => {\n const ctx = getRestRequestContext('POST', 'info', { type: 'unknownType' });\n expect(getRestBaseWeight(ctx)).toBe(20);\n });\n\n it('assigns base weight for explorer and other requests', () => {\n const explorerCtx = getRestRequestContext('GET', 'explorer/tx/0x', undefined);\n expect(getRestBaseWeight(explorerCtx)).toBe(40);\n\n const otherCtx = getRestRequestContext('GET', 'status', undefined);\n expect(getRestBaseWeight(otherCtx)).toBe(20);\n });\n\n it('calculates exchange base weight across batch sizes', () => {\n const cases = [\n { batchLength: 0, expected: 1 },\n { batchLength: 1, expected: 1 },\n { batchLength: 40, expected: 2 },\n { batchLength: 41, expected: 2 },\n { batchLength: 80, expected: 3 },\n ];\n\n for (const { batchLength, expected } of cases) {\n const ctx = getRestRequestContext('POST', 'exchange', {\n action: { type: 'order', orders: new Array(batchLength).fill({}) },\n });\n expect(getRestBaseWeight(ctx)).toBe(expected);\n }\n });\n\n it('estimates candleSnapshot extra weight with 5000 cap', () => {\n const intervalMs = 60_000;\n const candles = 10_000;\n const ctx = getRestRequestContext('POST', 'info', {\n type: 'candleSnapshot',\n req: { interval: '1m', startTime: 0, endTime: candles * intervalMs },\n });\n expect(getRestEstimatedExtraWeight(ctx)).toBe(Math.ceil(5000 / 60));\n });\n\n it('returns zero extra weight for invalid candleSnapshot inputs', () => {\n const invalidIntervalCtx = getRestRequestContext('POST', 'info', {\n type: 'candleSnapshot',\n req: { interval: '2m', startTime: 0, endTime: 60_000 },\n });\n expect(getRestEstimatedExtraWeight(invalidIntervalCtx)).toBe(0);\n\n const sameTimeCtx = getRestRequestContext('POST', 'info', {\n type: 'candleSnapshot',\n req: { interval: '1m', startTime: 0, endTime: 0 },\n });\n expect(getRestEstimatedExtraWeight(sameTimeCtx)).toBe(0);\n\n const missingReqCtx = getRestRequestContext('POST', 'info', { type: 'candleSnapshot' });\n expect(getRestEstimatedExtraWeight(missingReqCtx)).toBe(0);\n });\n\n it('consumes base and estimated weight before request', () => {\n const ctx = getRestRequestContext('POST', 'info', {\n type: 'candleSnapshot',\n req: { interval: '1m', startTime: 0, endTime: 120 * 60_000 },\n });\n const before = readBucket();\n const { baseWeight, estimatedExtraWeight } = beforeRestRequest({ requestKey: 'test' }, ctx);\n const after = readBucket();\n expect(baseWeight).toBe(20);\n expect(estimatedExtraWeight).toBe(2);\n expect(after).toBe(before - baseWeight - estimatedExtraWeight);\n });\n\n it('throws on invalid or excessive weights before request', () => {\n const invalidCtx = {\n method: 'POST',\n path: 'exchange',\n kind: 'exchange',\n exchangeBatchLength: Number.NaN,\n } as ReturnType<typeof getRestRequestContext>;\n expect(() => beforeRestRequest({ requestKey: 'test' }, invalidCtx)).toThrow(\n /HYPERLIQUID_REST_WEIGHT_INVALID/,\n );\n\n const maxWeight = 1200 * 10;\n const excessiveCtx = {\n method: 'POST',\n path: 'exchange',\n kind: 'exchange',\n exchangeBatchLength: (maxWeight + 1) * 40,\n } as ReturnType<typeof getRestRequestContext>;\n expect(() => beforeRestRequest({ requestKey: 'test' }, excessiveCtx)).toThrow(\n /HYPERLIQUID_REST_WEIGHT_EXCESSIVE/,\n );\n });\n\n it('applies extra weight based on response size', async () => {\n const ctx = getRestRequestContext('POST', 'info', { type: 'userFills' });\n const response = { fills: new Array(41).fill({}) };\n\n const before = readBucket();\n await afterRestResponse({ requestKey: 'test' }, ctx, response, 0);\n const after = readBucket();\n expect(before - after).toBe(Math.ceil(41 / 20));\n });\n\n it('applies delta extra weight for candleSnapshot responses', async () => {\n const ctx = getRestRequestContext('POST', 'info', { type: 'candleSnapshot' });\n const response = new Array(120).fill({});\n\n const before = readBucket();\n await afterRestResponse({ requestKey: 'test' }, ctx, response, 1);\n const after = readBucket();\n expect(before - after).toBe(1);\n });\n\n it('skips extra acquire when response weight is within estimate', async () => {\n const ctx = getRestRequestContext('POST', 'info', { type: 'userFills' });\n const response = { fills: [{}] };\n\n const before = readBucket();\n await afterRestResponse({ requestKey: 'test' }, ctx, response, 1);\n const after = readBucket();\n expect(after).toBe(before);\n });\n});\n"]}
|
package/lib/api/sign.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.signL1Action = signL1Action;
|
|
4
|
+
exports.actionHash = actionHash;
|
|
5
|
+
exports.addressToBytes = addressToBytes;
|
|
6
|
+
exports.constructPhantomAgent = constructPhantomAgent;
|
|
7
|
+
exports.l1Payload = l1Payload;
|
|
4
8
|
const msgpack_1 = require("@msgpack/msgpack");
|
|
5
9
|
const ethers_1 = require("ethers");
|
|
6
10
|
function addressToBytes(address) {
|
|
7
11
|
const cleanAddress = address.startsWith('0x') ? address.slice(2) : address;
|
|
8
12
|
return new Uint8Array(Buffer.from(cleanAddress, 'hex'));
|
|
9
13
|
}
|
|
10
|
-
exports.addressToBytes = addressToBytes;
|
|
11
14
|
function actionHash(action, vaultAddress, nonce, expiresAfter) {
|
|
12
15
|
let data = new Uint8Array((0, msgpack_1.encode)(action));
|
|
13
16
|
const nonceBytes = new Uint8Array(8);
|
|
@@ -30,7 +33,6 @@ function actionHash(action, vaultAddress, nonce, expiresAfter) {
|
|
|
30
33
|
}
|
|
31
34
|
return (0, ethers_1.keccak256)(data);
|
|
32
35
|
}
|
|
33
|
-
exports.actionHash = actionHash;
|
|
34
36
|
function concatUint8Arrays(...arrays) {
|
|
35
37
|
const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);
|
|
36
38
|
const result = new Uint8Array(totalLength);
|
|
@@ -47,7 +49,6 @@ function constructPhantomAgent(hash, isMainnet) {
|
|
|
47
49
|
connectionId: hash,
|
|
48
50
|
};
|
|
49
51
|
}
|
|
50
|
-
exports.constructPhantomAgent = constructPhantomAgent;
|
|
51
52
|
function l1Payload(phantomAgent) {
|
|
52
53
|
return {
|
|
53
54
|
domain: {
|
|
@@ -72,7 +73,6 @@ function l1Payload(phantomAgent) {
|
|
|
72
73
|
message: phantomAgent,
|
|
73
74
|
};
|
|
74
75
|
}
|
|
75
|
-
exports.l1Payload = l1Payload;
|
|
76
76
|
async function signInner(wallet, data) {
|
|
77
77
|
const signature = await wallet.signTypedData(data.domain, { Agent: data.types.Agent }, data.message);
|
|
78
78
|
const r = signature.slice(0, 66);
|
|
@@ -97,5 +97,4 @@ async function signL1Action(wallet, action, activePool, nonce, expiresAfter, isM
|
|
|
97
97
|
const data = l1Payload(phantomAgent);
|
|
98
98
|
return await signInner(wallet, data);
|
|
99
99
|
}
|
|
100
|
-
exports.signL1Action = signL1Action;
|
|
101
100
|
//# sourceMappingURL=sign.js.map
|
package/lib/api/sign.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sign.js","sourceRoot":"","sources":["../../src/api/sign.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sign.js","sourceRoot":"","sources":["../../src/api/sign.ts"],"names":[],"mappings":"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","sourcesContent":["import { encode } from '@msgpack/msgpack';\nimport { keccak256, Wallet } from 'ethers';\n\ninterface PhantomAgent {\n source: string;\n connectionId: string;\n}\n\ninterface L1Payload {\n domain: {\n chainId: number;\n name: string;\n verifyingContract: string;\n version: string;\n };\n types: {\n Agent: Array<{ name: string; type: string }>;\n EIP712Domain: Array<{ name: string; type: string }>;\n };\n primaryType: string;\n message: PhantomAgent;\n}\n\ninterface Signature {\n r: string;\n s: string;\n v: number;\n}\n\nfunction addressToBytes(address: string): Uint8Array {\n const cleanAddress = address.startsWith('0x') ? address.slice(2) : address;\n return new Uint8Array(Buffer.from(cleanAddress, 'hex'));\n}\n\nfunction actionHash(\n action: any,\n vaultAddress: string | null,\n nonce: number,\n expiresAfter: number | null,\n): string {\n let data: any = new Uint8Array(encode(action));\n\n const nonceBytes = new Uint8Array(8);\n const nonceView = new DataView(nonceBytes.buffer);\n nonceView.setBigUint64(0, BigInt(nonce), false); // false = big endian\n data = concatUint8Arrays(data, nonceBytes);\n\n if (vaultAddress == null) {\n data = concatUint8Arrays(data, new Uint8Array([0x00]));\n } else {\n data = concatUint8Arrays(data, new Uint8Array([0x01]));\n data = concatUint8Arrays(data, addressToBytes(vaultAddress));\n }\n if (expiresAfter != null) {\n data = concatUint8Arrays(data, new Uint8Array([0x00]));\n const expiresBytes = new Uint8Array(8);\n const expiresView = new DataView(expiresBytes.buffer);\n expiresView.setBigUint64(0, BigInt(expiresAfter), false); // false = big endian\n data = concatUint8Arrays(data, expiresBytes);\n }\n\n return keccak256(data);\n}\n\nfunction concatUint8Arrays(...arrays: Uint8Array[]): Uint8Array {\n const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n\n for (const arr of arrays) {\n result.set(arr, offset);\n offset += arr.length;\n }\n\n return result;\n}\n\nfunction constructPhantomAgent(hash: string, isMainnet: boolean): PhantomAgent {\n return {\n source: isMainnet ? 'a' : 'b',\n connectionId: hash,\n };\n}\n\nfunction l1Payload(phantomAgent: PhantomAgent): L1Payload {\n return {\n domain: {\n chainId: 1337,\n name: 'Exchange',\n verifyingContract: '0x0000000000000000000000000000000000000000',\n version: '1',\n },\n types: {\n Agent: [\n { name: 'source', type: 'string' },\n { name: 'connectionId', type: 'bytes32' },\n ],\n EIP712Domain: [\n { name: 'name', type: 'string' },\n { name: 'version', type: 'string' },\n { name: 'chainId', type: 'uint256' },\n { name: 'verifyingContract', type: 'address' },\n ],\n },\n primaryType: 'Agent',\n message: phantomAgent,\n };\n}\n\nasync function signInner(wallet: Wallet, data: L1Payload): Promise<Signature> {\n const signature = await wallet.signTypedData(data.domain, { Agent: data.types.Agent }, data.message);\n\n const r = signature.slice(0, 66);\n const s = '0x' + signature.slice(66, 130);\n const v = parseInt(signature.slice(130, 132), 16);\n\n return { r, s, v };\n}\n\n/**\n * 签署 L1 动作\n *\n * @param wallet - 以太坊钱包实例\n * @param action - 要签署的动作数据\n * @param activePool - 活跃池地址(可以为 null)\n * @param nonce - 随机数\n * @param expiresAfter - 过期时间(可以为 null)\n * @param isMainnet - 是否为主网\n * @returns 签名对象\n */\nexport async function signL1Action(\n wallet: Wallet,\n action: any,\n activePool: string | null,\n nonce: number,\n expiresAfter: number | null,\n isMainnet: boolean,\n): Promise<Signature> {\n const hash = actionHash(action, activePool, nonce, expiresAfter);\n const phantomAgent = constructPhantomAgent(hash, isMainnet);\n const data = l1Payload(phantomAgent);\n return await signInner(wallet, data);\n}\n\nexport { actionHash, addressToBytes, constructPhantomAgent, l1Payload };\n"]}
|
package/lib/api/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,YAAY,WAAW,KAAG,MACP,CAAC;AAEpD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,aAAa,MAAM,KAAG,WAGtD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,QAAO,WAMvC,CAAC"}
|
package/lib/api/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":";;;AAAA,mCAAgC;AAWhC;;GAEG;AACI,MAAM,eAAe,GAAG,CAAC,UAAuB,EAAU,EAAE,CACjE,eAAe,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;AADvC,QAAA,eAAe,mBACwB;AAEpD;;;;GAIG;AACI,MAAM,gBAAgB,GAAG,CAAC,WAAmB,EAAe,EAAE;IACnE,MAAM,MAAM,GAAG,IAAI,eAAM,CAAC,WAAW,CAAC,CAAC;IACvC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;AAClD,CAAC,CAAC;AAHW,QAAA,gBAAgB,oBAG3B;AAEF;;;GAGG;AACI,MAAM,oBAAoB,GAAG,GAAgB,EAAE;IACpD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IAC5C,IAAI,CAAC,WAAW,EAAE;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":";;;AAAA,mCAAgC;AAWhC;;GAEG;AACI,MAAM,eAAe,GAAG,CAAC,UAAuB,EAAU,EAAE,CACjE,eAAe,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;AADvC,QAAA,eAAe,mBACwB;AAEpD;;;;GAIG;AACI,MAAM,gBAAgB,GAAG,CAAC,WAAmB,EAAe,EAAE;IACnE,MAAM,MAAM,GAAG,IAAI,eAAM,CAAC,WAAW,CAAC,CAAC;IACvC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;AAClD,CAAC,CAAC;AAHW,QAAA,gBAAgB,oBAG3B;AAEF;;;GAGG;AACI,MAAM,oBAAoB,GAAG,GAAgB,EAAE;IACpD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IAC5C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,IAAA,wBAAgB,EAAC,WAAW,CAAC,CAAC;AACvC,CAAC,CAAC;AANW,QAAA,oBAAoB,wBAM/B","sourcesContent":["import { Wallet } from 'ethers';\n\n/**\n * Hyperliquid 凭证接口\n * 仅包含核心数据,行为方法通过辅助函数提供\n */\nexport interface ICredential {\n private_key: string;\n address: string;\n}\n\n/**\n * 获取凭证唯一标识\n */\nexport const getCredentialId = (credential: ICredential): string =>\n `HYPERLIQUID/${credential.address.toLowerCase()}`;\n\n/**\n * 创建凭证对象\n * @param private_key 私钥\n * @returns 凭证对象\n */\nexport const createCredential = (private_key: string): ICredential => {\n const wallet = new Wallet(private_key);\n return { private_key, address: wallet.address };\n};\n\n/**\n * 获取默认凭证(从环境变量)\n * @returns 默认凭证对象\n */\nexport const getDefaultCredential = (): ICredential => {\n const private_key = process.env.PRIVATE_KEY;\n if (!private_key) {\n throw new Error('Missing Hyperliquid credential: PRIVATE_KEY must be set');\n }\n return createCredential(private_key);\n};\n"]}
|
package/lib/index.d.ts
CHANGED
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAC7B,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAC7B,OAAO,4BAA4B,CAAC;AACpC,OAAO,0BAA0B,CAAC;AAClC,OAAO,mBAAmB,CAAC;AAC3B,OAAO,yBAAyB,CAAC;AACjC,OAAO,kCAAkC,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
require("./services/exchange");
|
|
4
|
-
require("./services/markets/interest-rate");
|
|
5
|
-
require("./services/markets/ohlc");
|
|
6
4
|
require("./services/markets/product");
|
|
7
5
|
require("./services/markets/quote");
|
|
8
6
|
require("./services/quotes");
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,+BAA6B;AAC7B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,+BAA6B;AAC7B,sCAAoC;AACpC,oCAAkC;AAClC,6BAA2B;AAC3B,mCAAiC;AACjC,4CAA0C","sourcesContent":["import './services/exchange';\nimport './services/markets/product';\nimport './services/markets/quote';\nimport './services/quotes';\nimport './services/ohlc-service';\nimport './services/interest-rate-service';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"perp.d.ts","sourceRoot":"","sources":["../../../src/services/accounts/perp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAoB,MAAM,sBAAsB,CAAC;AAGnE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"perp.d.ts","sourceRoot":"","sources":["../../../src/services/accounts/perp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAoB,MAAM,sBAAsB,CAAC;AAGnE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAAU,YAAY,WAAW,yBA2C7D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spot.d.ts","sourceRoot":"","sources":["../../../src/services/accounts/spot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAoB,MAAM,sBAAsB,CAAC;AAGnE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAkB9C;;GAEG;AACH,eAAO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"spot.d.ts","sourceRoot":"","sources":["../../../src/services/accounts/spot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAoB,MAAM,sBAAsB,CAAC;AAGnE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAkB9C;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAAU,YAAY,WAAW,yBA4B7D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spot.js","sourceRoot":"","sources":["../../../src/services/accounts/spot.ts"],"names":[],"mappings":";;;AAAA,yCAA4C;AAC5C,uDAAmE;AACnE,yCAAuD;AACvD,qDAAwE;AAExE,gDAAkD;AAElD,MAAM,mBAAmB,GAAG,IAAA,mBAAW,EACrC,KAAK,IAAI,EAAE;IACT,MAAM,QAAQ,GAAG,MAAM,IAAA,sBAAY,GAAE,CAAC;IACtC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;
|
|
1
|
+
{"version":3,"file":"spot.js","sourceRoot":"","sources":["../../../src/services/accounts/spot.ts"],"names":[],"mappings":";;;AAAA,yCAA4C;AAC5C,uDAAmE;AACnE,yCAAuD;AACvD,qDAAwE;AAExE,gDAAkD;AAElD,MAAM,mBAAmB,GAAG,IAAA,mBAAW,EACrC,KAAK,IAAI,EAAE;IACT,MAAM,QAAQ,GAAG,MAAM,IAAA,sBAAY,GAAE,CAAC;IACtC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnD,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;YACxB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,EACD,EAAE,MAAM,EAAE,QAAU,EAAE,CACvB,CAAC;AAEF;;GAEG;AACI,MAAM,gBAAgB,GAAG,KAAK,EAAE,UAAuB,EAAE,EAAE;IAChE,OAAO,CAAC,IAAI,CAAC,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,iCAAiC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;IAE5F,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,cAAc,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACzD,IAAA,iCAAoB,EAAC,EAAE,IAAI,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC;QAClD,IAAA,uBAAU,GAAE;QACZ,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;KAC9B,CAAC,CAAC;IACH,MAAM,sBAAsB,GAAG,cAAc,aAAd,cAAc,cAAd,cAAc,GAAI,IAAI,GAAG,EAAkB,CAAC;IAE3E,8DAA8D;IAC9D,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ;SAChC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;SAC9C,GAAG,CACF,CAAC,OAAO,EAAa,EAAE;;QACrB,OAAA,IAAA,+BAAgB,EAAC;YACf,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE;YAC9B,aAAa,EAAE,aAAa;YAC5B,UAAU,EACR,MAAA,sBAAsB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,mCACxC,IAAA,kBAAU,EAAC,aAAa,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,OAAO,CAAC;YAC3D,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;YAC7B,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;YACzD,cAAc,EAAE,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAG,OAAO,CAAC,IAAI,CAAC,mCAAI,CAAC,CAAC;SAChF,CAAC,CAAA;KAAA,CACL,CAAC;IAEJ,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AA5BW,QAAA,gBAAgB,oBA4B3B","sourcesContent":["import { createCache } from '@yuants/cache';\nimport { IPosition, makeSpotPosition } from '@yuants/data-account';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { getAllMids, getUserTokenBalances } from '../../api/public-api';\nimport { ICredential } from '../../api/types';\nimport { listProducts } from '../markets/product';\n\nconst spotProductMapCache = createCache(\n async () => {\n const products = await listProducts();\n const map = new Map<string, string>();\n for (const product of products) {\n const [, instType] = product.product_id.split('/');\n if (instType === 'SPOT') {\n map.set(product.base_currency, product.product_id);\n }\n }\n return map;\n },\n { expire: 86_400_000 },\n);\n\n/**\n * Get account info for spot account\n */\nexport const getSpotPositions = async (credential: ICredential) => {\n console.info(formatTime(Date.now()), `Getting spot account info for ${credential.address}`);\n\n const [balances, mids, spotProductMap] = await Promise.all([\n getUserTokenBalances({ user: credential.address }),\n getAllMids(),\n spotProductMapCache.query(''),\n ]);\n const resolvedSpotProductMap = spotProductMap ?? new Map<string, string>();\n\n // Map token balances to positions (using spot as \"positions\")\n const positions = balances.balances\n .filter((balance) => Number(balance.total) > 0)\n .map(\n (balance): IPosition =>\n makeSpotPosition({\n position_id: `${balance.coin}`,\n datasource_id: 'HYPERLIQUID',\n product_id:\n resolvedSpotProductMap.get(balance.coin) ??\n encodePath('HYPERLIQUID', 'SPOT', `${balance.coin}-USDC`),\n volume: Number(balance.total),\n free_volume: Number(balance.total) - Number(balance.hold),\n closable_price: balance.coin === 'USDC' ? 1 : Number(mids?.[balance.coin] ?? 0),\n }),\n );\n\n return positions;\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exchange.js","sourceRoot":"","sources":["../../src/services/exchange.ts"],"names":[],"mappings":";;AAEA,+CAA2D;AAC3D,+CAA4C;AAC5C,yCAAuD;AACvD,wCAA6F;AAC7F,+CAAiD;AACjD,0CAAmD;AACnD,0CAAmD;AACnD,sDAAyD;AACzD,oDAA4E;AAC5E,sDAAmD;AACnD,sDAAmD;AAEnD,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,wBAAwB,GAAG,CAAC,UAAmB,EAAE,EAAE;IACvD,IAAI,CAAC,UAAU,EAAE;
|
|
1
|
+
{"version":3,"file":"exchange.js","sourceRoot":"","sources":["../../src/services/exchange.ts"],"names":[],"mappings":"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","sourcesContent":["import { IPosition } from '@yuants/data-account';\nimport { IOrder } from '@yuants/data-order';\nimport { provideExchangeServices } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { decodePath, formatTime } from '@yuants/utils';\nimport { ICredential, getCredentialId as getCredentialIdFromCredential } from '../api/types';\nimport { listProducts } from './markets/product';\nimport { getPerpPositions } from './accounts/perp';\nimport { getSpotPositions } from './accounts/spot';\nimport { cancelOrderAction } from './orders/cancelOrder';\nimport { listOrdersByProductId, listPerpOrders } from './orders/listOrders';\nimport { modifyOrder } from './orders/modifyOrder';\nimport { submitOrder } from './orders/submitOrder';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst ensureHyperliquidProduct = (product_id?: string) => {\n if (!product_id) {\n throw new Error('product_id is required');\n }\n const [exchange, instType] = decodePath(product_id);\n if (exchange !== 'HYPERLIQUID') {\n throw new Error(`product_id must start with HYPERLIQUID, got ${product_id}`);\n }\n if (instType !== 'PERPETUAL') {\n throw new Error(`Hyperliquid only supports PERPETUAL orders for now: ${product_id}`);\n }\n};\n\nprovideExchangeServices<ICredential>(terminal, {\n name: 'HYPERLIQUID',\n credentialSchema: {\n type: 'object',\n required: ['private_key', 'address'],\n properties: {\n private_key: { type: 'string' },\n address: { type: 'string' },\n },\n },\n getCredentialId: async (credential) => getCredentialIdFromCredential(credential),\n listProducts,\n getPositions: async (credential: ICredential): Promise<IPosition[]> => {\n console.info(\n `[${formatTime(Date.now())}] Fetching positions for ${getCredentialIdFromCredential(credential)}`,\n );\n const [perpPositions, spotPositions] = await Promise.all([\n getPerpPositions(credential),\n getSpotPositions(credential),\n ]);\n return [...perpPositions, ...spotPositions];\n },\n getPositionsByProductId: async (credential: ICredential, product_id: string): Promise<IPosition[]> => {\n const [exchange, instType] = decodePath(product_id);\n if (exchange !== 'HYPERLIQUID') {\n throw new Error(`Invalid product_id for Hyperliquid: ${product_id}`);\n }\n if (instType === 'PERPETUAL') {\n const perpPositions = await getPerpPositions(credential);\n return perpPositions.filter((position) => position.product_id === product_id);\n }\n if (instType === 'PERPETUAL-ASSET') {\n const perpPositions = await getPerpPositions(credential);\n return perpPositions.filter((position) => position.product_id === product_id);\n }\n if (instType === 'SPOT') {\n const spotPositions = await getSpotPositions(credential);\n return spotPositions.filter((position) => position.product_id === product_id);\n }\n return [];\n },\n getOrders: async (credential: ICredential): Promise<IOrder[]> => {\n return listPerpOrders(credential);\n },\n getOrdersByProductId: async (credential: ICredential, product_id: string): Promise<IOrder[]> => {\n return listOrdersByProductId(credential, product_id);\n },\n submitOrder: async (credential: ICredential, order: IOrder): Promise<{ order_id: string }> => {\n ensureHyperliquidProduct(order.product_id);\n return submitOrder(credential, order);\n },\n modifyOrder: async (credential: ICredential, order: IOrder): Promise<void> => {\n ensureHyperliquidProduct(order.product_id);\n return modifyOrder(credential, order);\n },\n cancelOrder: async (credential: ICredential, order: IOrder): Promise<void> => {\n ensureHyperliquidProduct(order.product_id);\n return cancelOrderAction(credential, order);\n },\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"product.d.ts","sourceRoot":"","sources":["../../../src/services/markets/product.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAsD,MAAM,sBAAsB,CAAC;AAWpG,eAAO,MAAM,YAAY,QAAa,
|
|
1
|
+
{"version":3,"file":"product.d.ts","sourceRoot":"","sources":["../../../src/services/markets/product.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAsD,MAAM,sBAAsB,CAAC;AAWpG,eAAO,MAAM,YAAY,QAAa,OAAO,CAAC,QAAQ,EAAE,CA+CvD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quote.js","sourceRoot":"","sources":["../../../src/services/markets/quote.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"quote.js","sourceRoot":"","sources":["../../../src/services/markets/quote.ts"],"names":[],"mappings":"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","sourcesContent":["import { IQuote, setMetricsQuoteState } from '@yuants/data-quote';\nimport { GlobalPrometheusRegistry, Terminal } from '@yuants/protocol';\nimport { writeToSQL } from '@yuants/sql';\nimport { decodePath, encodePath } from '@yuants/utils';\nimport { defer, filter, map, mergeMap, repeat, retry, shareReplay, withLatestFrom } from 'rxjs';\nimport { getAllMids, getMetaAndAssetCtxs } from '../../api/public-api';\n\nconst terminal = Terminal.fromNodeEnv();\nconst ASSET_CTX_REFRESH_INTERVAL = Number(process.env.ASSET_CTX_REFRESH_INTERVAL ?? 5_000);\n\ntype HyperliquidAssetContext = Awaited<ReturnType<typeof getMetaAndAssetCtxs>>[1][number];\n\nconst assetCtxMap$ = defer(() => getMetaAndAssetCtxs()).pipe(\n map(([meta, assetCtxs]) => {\n const entries = meta?.universe?.map<[string, HyperliquidAssetContext | undefined]>((asset, index) => [\n asset.name,\n assetCtxs?.[index],\n ]);\n return new Map(entries?.filter(([, ctx]) => !!ctx) ?? []);\n }),\n repeat({ delay: ASSET_CTX_REFRESH_INTERVAL }),\n retry({ delay: 5000 }),\n shareReplay({ bufferSize: 1, refCount: true }),\n);\n\nconst quote$ = defer(() => getAllMids()).pipe(\n map((mids) => Object.entries(mids ?? {})),\n mergeMap((entries) => entries),\n withLatestFrom(assetCtxMap$),\n map(([entry, assetCtxMap]): Partial<IQuote> => {\n const [coin, price] = entry;\n const ctx = assetCtxMap.get(coin);\n return {\n datasource_id: 'HYPERLIQUID',\n product_id: encodePath('HYPERLIQUID', 'PERPETUAL', `${coin}-USD`),\n last_price: `${price}`,\n bid_price: `${price}`,\n ask_price: `${price}`,\n open_interest: `${ctx?.openInterest ?? 0}`,\n interest_rate_long: ctx?.funding ? `${-+ctx.funding}` : undefined,\n interest_rate_short: ctx?.funding,\n updated_at: new Date().toISOString(),\n };\n }),\n repeat({ delay: 1000 }),\n retry({ delay: 5000 }),\n shareReplay({ bufferSize: 1, refCount: true }),\n);\n\nconst shouldWriteQuoteToSQL = /^(1|true)$/i.test(process.env.WRITE_QUOTE_TO_SQL ?? '');\n\nif (shouldWriteQuoteToSQL) {\n quote$\n .pipe(\n setMetricsQuoteState(terminal.terminal_id),\n writeToSQL({\n terminal,\n tableName: 'quote',\n writeInterval: 1000,\n conflictKeys: ['datasource_id', 'product_id'],\n }),\n )\n .subscribe();\n}\n\nterminal.channel.publishChannel('quote', { pattern: '^HYPERLIQUID/' }, (channel_id) => {\n const [datasourceId] = decodePath(channel_id);\n if (datasourceId !== 'HYPERLIQUID') {\n throw new Error(`Invalid channel_id: ${channel_id}`);\n }\n return quote$.pipe(filter((quote) => quote.product_id === channel_id));\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ohlc-service.js","sourceRoot":"","sources":["../../src/services/ohlc-service.ts"],"names":[],"mappings":";;AACA,+CAAsD;AACtD,+CAA4C;AAC5C,yCAAgF;AAChF,kDAAsD;AAEtD,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,gCAAgC,GAA2B;IAC/D,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,KAAK;IACZ,KAAK,EAAE,KAAK;IACZ,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,KAAK;IACZ,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;CACV,CAAC;AAEF,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAE/B,MAAM,qBAAqB,GAAG,KAAK,EAAE,GAKpC,EAAoB,EAAE;IACrB,MAAM,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,GAAG,IAAA,kBAAU,EAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC1D,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1E,IAAI,UAAU,KAAK,WAAW,IAAI,UAAU,KAAK,MAAM,EAAE;
|
|
1
|
+
{"version":3,"file":"ohlc-service.js","sourceRoot":"","sources":["../../src/services/ohlc-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { IOHLC } from '@yuants/data-ohlc';\nimport { provideOHLCService } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { convertDurationToOffset, decodePath, formatTime } from '@yuants/utils';\nimport { getCandleSnapshot } from '../api/public-api';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst DURATION_TO_HYPERLIQUID_INTERVAL: Record<string, string> = {\n PT1M: '1m',\n PT3M: '3m',\n PT5M: '5m',\n PT15M: '15m',\n PT30M: '30m',\n PT1H: '1h',\n PT2H: '2h',\n PT4H: '4h',\n PT8H: '8h',\n PT12H: '12h',\n P1D: '1d',\n P3D: '3d',\n P1W: '1w',\n P1M: '1M',\n};\n\nconst DEFAULT_BAR_COUNT = 1000;\n\nconst fetchOHLCPageBackward = async (req: {\n product_id: string;\n duration: string;\n time: number;\n series_id: string;\n}): Promise<IOHLC[]> => {\n const [, marketType, symbol] = decodePath(req.product_id);\n if (!symbol) throw new Error(`Unsupported product_id: ${req.product_id}`);\n if (marketType !== 'PERPETUAL' && marketType !== 'SPOT') {\n throw new Error(`Unsupported product_id: ${req.product_id}`);\n }\n\n const coin = symbol.split('-')[0];\n if (!coin) throw new Error(`Invalid symbol: ${symbol}`);\n\n const interval = DURATION_TO_HYPERLIQUID_INTERVAL[req.duration];\n if (!interval) throw new Error(`Unsupported duration: ${req.duration}`);\n\n const periodMs = convertDurationToOffset(req.duration);\n const endTime = req.time;\n const startTime = Math.max(0, endTime - DEFAULT_BAR_COUNT * periodMs);\n\n const res = await getCandleSnapshot({\n req: { coin, interval, startTime, endTime },\n });\n\n return (res ?? [])\n .map((x): IOHLC => {\n const createdAtMs = x.t;\n return {\n series_id: req.series_id,\n datasource_id: 'HYPERLIQUID',\n product_id: req.product_id,\n duration: req.duration,\n created_at: formatTime(createdAtMs),\n closed_at: formatTime(createdAtMs + periodMs),\n open: x.o,\n high: x.h,\n low: x.l,\n close: x.c,\n volume: x.v,\n open_interest: '0',\n };\n })\n .filter((x) => Date.parse(x.created_at) < endTime);\n};\n\nprovideOHLCService(\n terminal,\n {\n product_id_prefix: 'HYPERLIQUID/PERPETUAL/',\n duration_list: Object.keys(DURATION_TO_HYPERLIQUID_INTERVAL),\n direction: 'backward',\n },\n fetchOHLCPageBackward,\n);\n\nprovideOHLCService(\n terminal,\n {\n product_id_prefix: 'HYPERLIQUID/SPOT/',\n duration_list: Object.keys(DURATION_TO_HYPERLIQUID_INTERVAL),\n direction: 'backward',\n },\n fetchOHLCPageBackward,\n);\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cancelOrder.d.ts","sourceRoot":"","sources":["../../../src/services/orders/cancelOrder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAI9C,eAAO,MAAM,iBAAiB,
|
|
1
|
+
{"version":3,"file":"cancelOrder.d.ts","sourceRoot":"","sources":["../../../src/services/orders/cancelOrder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAI9C,eAAO,MAAM,iBAAiB,GAAU,YAAY,WAAW,EAAE,OAAO,MAAM,kBA6B7E,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cancelOrder.js","sourceRoot":"","sources":["../../../src/services/orders/cancelOrder.ts"],"names":[],"mappings":";;;AAEA,oCAA4C;AAC5C,uDAAoD;AAE7C,MAAM,iBAAiB,GAAG,KAAK,EAAE,UAAuB,EAAE,KAAa,EAAE,EAAE;;IAChF,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;
|
|
1
|
+
{"version":3,"file":"cancelOrder.js","sourceRoot":"","sources":["../../../src/services/orders/cancelOrder.ts"],"names":[],"mappings":";;;AAEA,oCAA4C;AAC5C,uDAAoD;AAE7C,MAAM,iBAAiB,GAAG,KAAK,EAAE,UAAuB,EAAE,KAAa,EAAE,EAAE;;IAChF,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,qBAAqB,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE;QACpB,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACzC,IAAI,OAAO,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,CAAA,KAAK,QAAQ,EAAE,CAAC;oBACzC,OAAO,MAAM,CAAC,QAAQ,CAAC;gBACzB,CAAC;YACH,CAAC;YAAC,WAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC,EAAE,CAAC;IACL,MAAM,aAAa,GAAG,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,CAAC,MAAM,IAAA,wBAAgB,EAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;IACpF,MAAM,GAAG,GAAG,MAAM,IAAA,yBAAW,EAAC,UAAU,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC3F,MAAM,MAAM,GAAG,MAAA,MAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,QAAQ,0CAAE,IAAI,0CAAE,QAAQ,CAAC;IAC7C,MAAM,KAAK,GACT,CAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,MAAM,MAAK,IAAI;QAClB,CAAC,CAAC,WAAW;QACb,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,QAAQ;YACxD,CAAC,CAAC,MAAA,MAAM,CAAC,CAAC,CAAC,0CAAE,KAAK;YAClB,CAAC,CAAC,SAAS,CAAC;IAEhB,IAAI,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;AACpC,CAAC,CAAC;AA7BW,QAAA,iBAAiB,qBA6B5B","sourcesContent":["import { IOrder } from '@yuants/data-order';\nimport { ICredential } from '../../api/types';\nimport { resolveAssetInfo } from '../utils';\nimport { cancelOrder } from '../../api/private-api';\n\nexport const cancelOrderAction = async (credential: ICredential, order: IOrder) => {\n const orderId = Number(order.order_id);\n if (!Number.isFinite(orderId)) {\n throw new Error(`Invalid order_id: ${order.order_id}`);\n }\n const assetId = (() => {\n if (order.comment) {\n try {\n const parsed = JSON.parse(order.comment);\n if (typeof parsed?.asset_id === 'number') {\n return parsed.asset_id;\n }\n } catch {\n // ignore\n }\n }\n return undefined;\n })();\n const resolvedAsset = assetId ?? (await resolveAssetInfo(order.product_id)).assetId;\n const res = await cancelOrder(credential, { cancels: [{ a: resolvedAsset, o: orderId }] });\n const status = res?.response?.data?.statuses;\n const error =\n res?.status !== 'ok'\n ? 'API ERROR'\n : Array.isArray(status) && typeof status[0] !== 'string'\n ? status[0]?.error\n : undefined;\n\n if (error) throw new Error(error);\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listOrders.d.ts","sourceRoot":"","sources":["../../../src/services/orders/listOrders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAyC/D;;GAEG;AACH,eAAO,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"listOrders.d.ts","sourceRoot":"","sources":["../../../src/services/orders/listOrders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAyC/D;;GAEG;AACH,eAAO,MAAM,cAAc,GAAU,YAAY,WAAW,KAAG,OAAO,CAAC,MAAM,EAAE,CAc9E,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAChC,YAAY,WAAW,EACvB,YAAY,MAAM,KACjB,OAAO,CAAC,MAAM,EAAE,CAUlB,CAAC"}
|
|
@@ -27,12 +27,12 @@ const mapOrder = (order) => {
|
|
|
27
27
|
order_id: `${order.oid}`,
|
|
28
28
|
account_id: '',
|
|
29
29
|
product_id: (0, utils_1.encodePath)('HYPERLIQUID', 'PERPETUAL', `${(_a = order.coin) === null || _a === void 0 ? void 0 : _a.trim()}-USD`),
|
|
30
|
-
order_type: 'LIMIT',
|
|
30
|
+
order_type: 'LIMIT', // Hyperliquid primarily uses limit orders
|
|
31
31
|
order_direction: mapOrderDirection(order.side),
|
|
32
32
|
volume: Number.isFinite(volume) ? volume : 0,
|
|
33
33
|
price: Number.isFinite(price) && price > 0 ? price : undefined,
|
|
34
34
|
submit_at: Number((_b = order.timestamp) !== null && _b !== void 0 ? _b : Date.now()),
|
|
35
|
-
order_status: 'open',
|
|
35
|
+
order_status: 'open', // Since these are open orders
|
|
36
36
|
// Additional fields that might be useful
|
|
37
37
|
comment: order.coin ? JSON.stringify({ asset_id: order.coin }) : undefined,
|
|
38
38
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listOrders.js","sourceRoot":"","sources":["../../../src/services/orders/listOrders.ts"],"names":[],"mappings":";;;AACA,yCAAmE;AAEnE,qDAAyD;AAIzD;;GAEG;AACH,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAkB,EAAE;IACzD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACtC,IAAI,UAAU,KAAK,KAAK,IAAI,UAAU,KAAK,KAAK,EAAE;
|
|
1
|
+
{"version":3,"file":"listOrders.js","sourceRoot":"","sources":["../../../src/services/orders/listOrders.ts"],"names":[],"mappings":"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","sourcesContent":["import { IOrder } from '@yuants/data-order';\nimport { decodePath, encodePath, formatTime } from '@yuants/utils';\nimport { ICredential, getCredentialId } from '../../api/types';\nimport { getUserOpenOrders } from '../../api/public-api';\n\ntype OrderDirection = 'OPEN_LONG' | 'OPEN_SHORT' | 'CLOSE_LONG' | 'CLOSE_SHORT';\n\n/**\n * Map order direction based on side and reduce-only logic\n */\nconst mapOrderDirection = (side: string): OrderDirection => {\n const normalized = side.toUpperCase();\n if (normalized === 'BID' || normalized === 'BUY') {\n return 'OPEN_LONG';\n }\n if (normalized === 'ASK' || normalized === 'SELL') {\n return 'OPEN_SHORT';\n }\n return 'OPEN_LONG';\n};\n\n/**\n * Map Hyperliquid order to Yuan IOrder format\n */\nconst mapOrder = (order: any): IOrder => {\n const volume = Number(order.sz) || 0;\n const price = Number(order.limitPx) || 0;\n\n return {\n order_id: `${order.oid}`,\n account_id: '',\n product_id: encodePath('HYPERLIQUID', 'PERPETUAL', `${order.coin?.trim()}-USD`),\n order_type: 'LIMIT', // Hyperliquid primarily uses limit orders\n order_direction: mapOrderDirection(order.side),\n volume: Number.isFinite(volume) ? volume : 0,\n price: Number.isFinite(price) && price > 0 ? price : undefined,\n submit_at: Number(order.timestamp ?? Date.now()),\n order_status: 'open', // Since these are open orders\n // Additional fields that might be useful\n comment: order.coin ? JSON.stringify({ asset_id: order.coin }) : undefined,\n };\n};\n\n/**\n * List perpetual orders\n */\nexport const listPerpOrders = async (credential: ICredential): Promise<IOrder[]> => {\n console.info(`[${formatTime(Date.now())}] Listing perpetual orders for ${credential.address}`);\n\n try {\n const orders = await getUserOpenOrders({ user: credential.address });\n if (!orders || !Array.isArray(orders)) {\n return [];\n }\n return orders.map((order) => mapOrder(order));\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n console.error(`[${formatTime(Date.now())}] Failed to list perpetual orders: ${errorMessage}`);\n throw new Error(`Failed to list perpetual orders: ${errorMessage}`);\n }\n};\n\n/**\n * List orders by product_id\n */\nexport const listOrdersByProductId = async (\n credential: ICredential,\n product_id: string,\n): Promise<IOrder[]> => {\n const [exchange, instType] = decodePath(product_id);\n if (exchange !== 'HYPERLIQUID') {\n throw new Error(`Invalid product_id for Hyperliquid: ${product_id}`);\n }\n if (instType !== 'PERPETUAL') {\n return [];\n }\n const orders = await listPerpOrders(credential);\n return orders.filter((order) => order.product_id === product_id);\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modifyOrder.d.ts","sourceRoot":"","sources":["../../../src/services/orders/modifyOrder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAI9C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"modifyOrder.d.ts","sourceRoot":"","sources":["../../../src/services/orders/modifyOrder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAI9C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,GAAU,YAAY,WAAW,EAAE,OAAO,MAAM,KAAG,OAAO,CAAC,IAAI,CA0CtF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modifyOrder.js","sourceRoot":"","sources":["../../../src/services/orders/modifyOrder.ts"],"names":[],"mappings":";;;AACA,yCAA2C;AAE3C,uDAAsE;AACtE,oCAA6C;AAE7C;;;;;;;;;;GAUG;AACI,MAAM,WAAW,GAAG,KAAK,EAAE,UAAuB,EAAE,KAAa,EAAiB,EAAE;;IACzF,OAAO,CAAC,IAAI,CAAC,IAAI,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,qBAAqB,KAAK,CAAC,QAAQ,QAAQ,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IAEtG,IAAI;
|
|
1
|
+
{"version":3,"file":"modifyOrder.js","sourceRoot":"","sources":["../../../src/services/orders/modifyOrder.ts"],"names":[],"mappings":";;;AACA,yCAA2C;AAE3C,uDAAsE;AACtE,oCAA6C;AAE7C;;;;;;;;;;GAUG;AACI,MAAM,WAAW,GAAG,KAAK,EAAE,UAAuB,EAAE,KAAa,EAAiB,EAAE;;IACzF,OAAO,CAAC,IAAI,CAAC,IAAI,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,qBAAqB,KAAK,CAAC,QAAQ,QAAQ,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IAEtG,IAAI,CAAC;QACH,oBAAoB;QACpB,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,qBAAqB,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QACzD,CAAC;QAED,sDAAsD;QACtD,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,IAAA,yBAAiB,EAAC,KAAK,CAAC,CAAC;QAEvD,OAAO,CAAC,IAAI,CAAC,IAAI,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,qBAAqB,KAAK,CAAC,QAAQ,mBAAmB,EAAE;YAC7F,KAAK,EAAE,WAAW,CAAC,CAAC;YACpB,KAAK,EAAE,WAAW,CAAC,CAAC;YACpB,KAAK,EAAE,WAAW,CAAC,CAAC;YACpB,IAAI,EAAE,WAAW,CAAC,CAAC;YACnB,UAAU,EAAE,WAAW,CAAC,CAAC;YACzB,GAAG,EAAE,MAAA,WAAW,CAAC,CAAC,CAAC,KAAK,0CAAE,GAAG;SAC9B,CAAC,CAAC;QAEH,6CAA6C;QAC7C,MAAM,MAAM,GAAG,MAAM,IAAA,yBAAc,EAAC,UAAU,EAAE;YAC9C,GAAG,EAAE,OAAO;YACZ,KAAK,EAAE,WAAW;SACnB,CAAC,CAAC;QAEH,2CAA2C;QAC3C,MAAM,MAAM,GAAG,MAAA,MAAA,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,0CAAE,IAAI,0CAAE,QAAQ,0CAAG,CAAC,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,MAAK,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,EAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QAE/F,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,2BAA2B,KAAK,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,IAAI,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,WAAW,KAAK,CAAC,QAAQ,wBAAwB,CAAC,CAAC;IAC5F,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QAC9E,OAAO,CAAC,KAAK,CAAC,IAAI,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,4BAA4B,KAAK,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC,CAAC;QACvG,MAAM,IAAI,KAAK,CAAC,2BAA2B,YAAY,EAAE,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC,CAAC;AA1CW,QAAA,WAAW,eA0CtB","sourcesContent":["import { IOrder } from '@yuants/data-order';\nimport { formatTime } from '@yuants/utils';\nimport { ICredential } from '../../api/types';\nimport { modifyOrder as modifyOrderApi } from '../../api/private-api';\nimport { buildOrderPayload } from '../utils';\n\n/**\n * 修改订单 - 使用 Hyperliquid 原生 modify order API\n *\n * Hyperliquid supports native order modification through the modify action:\n * https://hyperliquid.gitbook.io/hyperliquid-docs/for-develope../../api/exchange-endpoint#modify-an-order\n *\n * This is more efficient than cancel + place new as it:\n * 1. Maintains order priority in the order book\n * 2. Reduces API calls from 2 to 1\n * 3. Prevents race conditions where the cancelled order might be filled before new order is placed\n */\nexport const modifyOrder = async (credential: ICredential, order: IOrder): Promise<void> => {\n console.info(`[${formatTime(Date.now())}] Modifying order ${order.order_id} for ${order.product_id}`);\n\n try {\n // Validate order_id\n const orderId = Number(order.order_id);\n if (!Number.isFinite(orderId)) {\n throw new Error(`Invalid order_id: ${order.order_id}`);\n }\n\n // Build the new order payload with updated parameters\n const { orderParams } = await buildOrderPayload(order);\n\n console.info(`[${formatTime(Date.now())}] Modifying order ${order.order_id} with new params:`, {\n asset: orderParams.a,\n isBuy: orderParams.b,\n price: orderParams.p,\n size: orderParams.s,\n reduceOnly: orderParams.r,\n tif: orderParams.t.limit?.tif,\n });\n\n // Call Hyperliquid's native modify order API\n const result = await modifyOrderApi(credential, {\n oid: orderId,\n order: orderParams,\n });\n\n // Check if the modification was successful\n const status = result?.response?.data?.statuses?.[0];\n const error = result?.status !== 'ok' ? 'API ERROR' : status?.error ? status.error : undefined;\n\n if (error) {\n throw new Error(`Failed to modify order: ${error}`);\n }\n\n console.info(`[${formatTime(Date.now())}] Order ${order.order_id} modified successfully`);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n console.error(`[${formatTime(Date.now())}] Failed to modify order ${order.order_id}: ${errorMessage}`);\n throw new Error(`Failed to modify order: ${errorMessage}`);\n }\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submitOrder.d.ts","sourceRoot":"","sources":["../../../src/services/orders/submitOrder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"submitOrder.d.ts","sourceRoot":"","sources":["../../../src/services/orders/submitOrder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C,eAAO,MAAM,WAAW,GAAU,YAAY,WAAW,EAAE,OAAO,MAAM,KAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAWtG,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quotes.js","sourceRoot":"","sources":["../../src/services/quotes.ts"],"names":[],"mappings":";;AAAA,+CAAuD;AACvD,+CAA4C;AAC5C,yCAA2C;AAC3C,kDAAoE;AAEpE,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,IAAA,8BAAmB,EACjB,QAAQ,EACR;IACE,iBAAiB,EAAE,wBAAwB;IAC3C,MAAM,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,WAAW,CAAC;CACjD,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;IACZ,MAAM,IAAI,GAAG,MAAM,IAAA,uBAAU,GAAE,CAAC;IAEhC,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE;QACtD,OAAO;YACL,UAAU,EAAE,IAAA,kBAAU,EAAC,aAAa,EAAE,WAAW,EAAE,GAAG,IAAI,MAAM,CAAC;YACjE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;YACtB,UAAU,EAAE,GAAG,KAAK,EAAE;YACtB,SAAS,EAAE,GAAG,KAAK,EAAE;YACrB,SAAS,EAAE,GAAG,KAAK,EAAE;SACtB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CACF,CAAC;AAEF,IAAA,8BAAmB,EACjB,QAAQ,EACR;IACE,iBAAiB,EAAE,wBAAwB;IAC3C,MAAM,EAAE,CAAC,eAAe,EAAE,oBAAoB,EAAE,qBAAqB,CAAC;CACvE,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;;IACZ,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,MAAM,IAAA,gCAAmB,GAAE,CAAC;IAEtD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAsC,CAAC;IAChE,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,0CAAE,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACvC,MAAM,GAAG,GAAG,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAG,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,IAAI,KAAI,GAAG,EAAE;
|
|
1
|
+
{"version":3,"file":"quotes.js","sourceRoot":"","sources":["../../src/services/quotes.ts"],"names":[],"mappings":";;AAAA,+CAAuD;AACvD,+CAA4C;AAC5C,yCAA2C;AAC3C,kDAAoE;AAEpE,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,IAAA,8BAAmB,EACjB,QAAQ,EACR;IACE,iBAAiB,EAAE,wBAAwB;IAC3C,MAAM,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,WAAW,CAAC;CACjD,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;IACZ,MAAM,IAAI,GAAG,MAAM,IAAA,uBAAU,GAAE,CAAC;IAEhC,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE;QACtD,OAAO;YACL,UAAU,EAAE,IAAA,kBAAU,EAAC,aAAa,EAAE,WAAW,EAAE,GAAG,IAAI,MAAM,CAAC;YACjE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;YACtB,UAAU,EAAE,GAAG,KAAK,EAAE;YACtB,SAAS,EAAE,GAAG,KAAK,EAAE;YACrB,SAAS,EAAE,GAAG,KAAK,EAAE;SACtB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CACF,CAAC;AAEF,IAAA,8BAAmB,EACjB,QAAQ,EACR;IACE,iBAAiB,EAAE,wBAAwB;IAC3C,MAAM,EAAE,CAAC,eAAe,EAAE,oBAAoB,EAAE,qBAAqB,CAAC;CACvE,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;;IACZ,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,MAAM,IAAA,gCAAmB,GAAE,CAAC;IAEtD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAsC,CAAC;IAChE,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,0CAAE,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACvC,MAAM,GAAG,GAAG,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAG,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,IAAI,KAAI,GAAG,EAAE,CAAC;YACvB,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACjC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE;;QAAC,OAAA,CAAC;YAC3D,UAAU,EAAE,IAAA,kBAAU,EAAC,aAAa,EAAE,WAAW,EAAE,GAAG,IAAI,MAAM,CAAC;YACjE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;YACtB,aAAa,EAAE,MAAA,GAAG,CAAC,YAAY,mCAAI,GAAG;YACtC,kBAAkB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG;YACjE,mBAAmB,EAAE,MAAA,GAAG,CAAC,OAAO,mCAAI,GAAG;SACxC,CAAC,CAAA;KAAA,CAAC,CAAC;AACN,CAAC,CACF,CAAC","sourcesContent":["import { provideQuoteService } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath } from '@yuants/utils';\nimport { getAllMids, getMetaAndAssetCtxs } from '../api/public-api';\n\nconst terminal = Terminal.fromNodeEnv();\n\nprovideQuoteService(\n terminal,\n {\n product_id_prefix: 'HYPERLIQUID/PERPETUAL/',\n fields: ['last_price', 'ask_price', 'bid_price'],\n },\n async (req) => {\n const mids = await getAllMids();\n\n return Object.entries(mids ?? {}).map(([coin, price]) => {\n return {\n product_id: encodePath('HYPERLIQUID', 'PERPETUAL', `${coin}-USD`),\n updated_at: Date.now(),\n last_price: `${price}`,\n bid_price: `${price}`,\n ask_price: `${price}`,\n };\n });\n },\n);\n\nprovideQuoteService(\n terminal,\n {\n product_id_prefix: 'HYPERLIQUID/PERPETUAL/',\n fields: ['open_interest', 'interest_rate_long', 'interest_rate_short'],\n },\n async (req) => {\n const [meta, assetCtxs] = await getMetaAndAssetCtxs();\n\n const coinToCtx = new Map<string, (typeof assetCtxs)[number]>();\n meta?.universe?.forEach((asset, index) => {\n const ctx = assetCtxs?.[index];\n if (asset?.name && ctx) {\n coinToCtx.set(asset.name, ctx);\n }\n });\n\n return Array.from(coinToCtx.entries()).map(([coin, ctx]) => ({\n product_id: encodePath('HYPERLIQUID', 'PERPETUAL', `${coin}-USD`),\n updated_at: Date.now(),\n open_interest: ctx.openInterest ?? '0',\n interest_rate_long: ctx.funding ? `${-Number(ctx.funding)}` : '0',\n interest_rate_short: ctx.funding ?? '0',\n }));\n },\n);\n"]}
|
package/lib/services/utils.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ declare const enum InstrumentType {
|
|
|
3
3
|
PERPETUAL = "PERPETUAL",
|
|
4
4
|
SPOT = "SPOT"
|
|
5
5
|
}
|
|
6
|
-
|
|
6
|
+
type AssetInfo = {
|
|
7
7
|
assetId: number;
|
|
8
8
|
szDecimals: number;
|
|
9
9
|
instType: InstrumentType;
|
|
@@ -14,7 +14,7 @@ export declare const parseProductPath: (product_id: string) => {
|
|
|
14
14
|
baseCurrency: string;
|
|
15
15
|
};
|
|
16
16
|
export declare const resolveAssetInfo: (product_id: string) => Promise<AssetInfo>;
|
|
17
|
-
export declare const roundPrice: (price: number, instType:
|
|
17
|
+
export declare const roundPrice: (price: number, instType: "PERPETUAL" | "SPOT", szDecimals: number) => string;
|
|
18
18
|
export declare const buildOrderPayload: (order: IOrder) => Promise<{
|
|
19
19
|
assetInfo: AssetInfo;
|
|
20
20
|
orderParams: {
|