@trufnetwork/sdk-js 0.6.0 → 0.6.2
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/cjs/client/client.cjs +19 -0
- package/dist/cjs/client/client.cjs.map +2 -2
- package/dist/cjs/contracts-api/action.cjs +22 -0
- package/dist/cjs/contracts-api/action.cjs.map +2 -2
- package/dist/cjs/contracts-api/action.test.cjs +63 -0
- package/dist/cjs/contracts-api/action.test.cjs.map +7 -0
- package/dist/cjs/types/bridge.cjs.map +1 -1
- package/dist/cjs/util/AttestationEncoding.cjs +84 -0
- package/dist/cjs/util/AttestationEncoding.cjs.map +2 -2
- package/dist/cjs/util/orderbookHelpers.cjs +40 -0
- package/dist/cjs/util/orderbookHelpers.cjs.map +2 -2
- package/dist/cjs/util/orderbookHelpers.test.cjs +321 -0
- package/dist/cjs/util/orderbookHelpers.test.cjs.map +4 -4
- package/dist/esm/client/client.mjs +19 -0
- package/dist/esm/client/client.mjs.map +2 -2
- package/dist/esm/contracts-api/action.mjs +22 -0
- package/dist/esm/contracts-api/action.mjs.map +2 -2
- package/dist/esm/contracts-api/action.test.mjs +61 -0
- package/dist/esm/contracts-api/action.test.mjs.map +7 -0
- package/dist/esm/util/AttestationEncoding.mjs +84 -0
- package/dist/esm/util/AttestationEncoding.mjs.map +2 -2
- package/dist/esm/util/orderbookHelpers.mjs +45 -1
- package/dist/esm/util/orderbookHelpers.mjs.map +2 -2
- package/dist/esm/util/orderbookHelpers.test.mjs +383 -58
- package/dist/esm/util/orderbookHelpers.test.mjs.map +4 -4
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/client/client.d.ts +17 -1
- package/dist/types/client/client.d.ts.map +1 -1
- package/dist/types/contracts-api/action.d.ts +11 -1
- package/dist/types/contracts-api/action.d.ts.map +1 -1
- package/dist/types/contracts-api/action.test.d.ts +2 -0
- package/dist/types/contracts-api/action.test.d.ts.map +1 -0
- package/dist/types/types/bridge.d.ts +45 -0
- package/dist/types/types/bridge.d.ts.map +1 -1
- package/dist/types/util/AttestationEncoding.d.ts +21 -0
- package/dist/types/util/AttestationEncoding.d.ts.map +1 -1
- package/dist/types/util/orderbookHelpers.d.ts +23 -0
- package/dist/types/util/orderbookHelpers.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,51 +1,284 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __esm = (fn, res) => function __init() {
|
|
4
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
|
+
};
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// src/util/orderbookHelpers.ts
|
|
12
|
+
var orderbookHelpers_exports = {};
|
|
13
|
+
__export(orderbookHelpers_exports, {
|
|
14
|
+
bytesToHex: () => bytesToHex,
|
|
15
|
+
dbBytesToUint8Array: () => dbBytesToUint8Array,
|
|
16
|
+
decodeMarketData: () => decodeMarketData,
|
|
17
|
+
encodeActionArgs: () => encodeActionArgs,
|
|
18
|
+
encodeEqualsActionArgs: () => encodeEqualsActionArgs,
|
|
19
|
+
encodeQueryComponents: () => encodeQueryComponents,
|
|
20
|
+
encodeRangeActionArgs: () => encodeRangeActionArgs,
|
|
21
|
+
hexToBytes: () => hexToBytes,
|
|
22
|
+
settledFilterToBoolean: () => settledFilterToBoolean,
|
|
23
|
+
stringToBytes32: () => stringToBytes32,
|
|
24
|
+
validateAmount: () => validateAmount,
|
|
25
|
+
validateBridge: () => validateBridge,
|
|
26
|
+
validateMaxSpread: () => validateMaxSpread,
|
|
27
|
+
validatePrice: () => validatePrice,
|
|
28
|
+
validateSettleTime: () => validateSettleTime
|
|
29
|
+
});
|
|
30
|
+
import { ethers } from "ethers";
|
|
31
|
+
import { Utils } from "@trufnetwork/kwil-js";
|
|
32
|
+
import {
|
|
33
|
+
encodeActionArgs as encodeActionArgsKwil,
|
|
34
|
+
decodeActionArgs,
|
|
35
|
+
decodeQueryComponents
|
|
36
|
+
} from "./AttestationEncoding.mjs";
|
|
37
|
+
function decodeMarketData(encoded) {
|
|
38
|
+
const bytes = dbBytesToUint8Array(encoded);
|
|
39
|
+
const { dataProvider, streamId, actionId, args: argsBytes } = decodeQueryComponents(bytes);
|
|
40
|
+
const args = decodeActionArgs(argsBytes);
|
|
41
|
+
const market = {
|
|
42
|
+
dataProvider,
|
|
43
|
+
streamId,
|
|
44
|
+
actionId,
|
|
45
|
+
type: "unknown",
|
|
46
|
+
thresholds: []
|
|
47
|
+
};
|
|
48
|
+
switch (actionId) {
|
|
49
|
+
case "price_above_threshold":
|
|
50
|
+
market.type = "above";
|
|
51
|
+
if (args.length >= 4) {
|
|
52
|
+
market.thresholds.push(args[3].toString());
|
|
53
|
+
}
|
|
54
|
+
break;
|
|
55
|
+
case "price_below_threshold":
|
|
56
|
+
market.type = "below";
|
|
57
|
+
if (args.length >= 4) {
|
|
58
|
+
market.thresholds.push(args[3].toString());
|
|
59
|
+
}
|
|
60
|
+
break;
|
|
61
|
+
case "value_in_range":
|
|
62
|
+
market.type = "between";
|
|
63
|
+
if (args.length >= 5) {
|
|
64
|
+
market.thresholds.push(args[3].toString(), args[4].toString());
|
|
65
|
+
}
|
|
66
|
+
break;
|
|
67
|
+
case "value_equals":
|
|
68
|
+
market.type = "equals";
|
|
69
|
+
if (args.length >= 5) {
|
|
70
|
+
market.thresholds.push(args[3].toString(), args[4].toString());
|
|
71
|
+
}
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
return market;
|
|
75
|
+
}
|
|
76
|
+
function encodeActionArgs(dataProvider, streamId, timestamp, threshold, frozenAt) {
|
|
77
|
+
return encodeActionArgsKwil(
|
|
78
|
+
[
|
|
79
|
+
dataProvider.toLowerCase(),
|
|
80
|
+
// TEXT: data provider address
|
|
81
|
+
streamId,
|
|
82
|
+
// TEXT: stream ID
|
|
83
|
+
timestamp,
|
|
84
|
+
// INT8: timestamp
|
|
85
|
+
threshold,
|
|
86
|
+
// NUMERIC: threshold - must specify type explicitly
|
|
87
|
+
frozenAt === 0 ? null : frozenAt
|
|
88
|
+
// INT8: frozen_at (null for latest)
|
|
89
|
+
],
|
|
90
|
+
{
|
|
91
|
+
// Argument 3 (threshold) must be NUMERIC(36, 18) to match price_above_threshold action signature
|
|
92
|
+
3: Utils.DataType.Numeric(36, 18)
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
function encodeRangeActionArgs(dataProvider, streamId, timestamp, minValue, maxValue, frozenAt) {
|
|
97
|
+
return encodeActionArgsKwil(
|
|
98
|
+
[
|
|
99
|
+
dataProvider.toLowerCase(),
|
|
100
|
+
streamId,
|
|
101
|
+
timestamp,
|
|
102
|
+
minValue,
|
|
103
|
+
maxValue,
|
|
104
|
+
frozenAt === 0 ? null : frozenAt
|
|
105
|
+
],
|
|
106
|
+
{
|
|
107
|
+
// Arguments 3, 4 (minValue, maxValue) must be NUMERIC(36, 18)
|
|
108
|
+
3: Utils.DataType.Numeric(36, 18),
|
|
109
|
+
4: Utils.DataType.Numeric(36, 18)
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
function encodeEqualsActionArgs(dataProvider, streamId, timestamp, targetValue, tolerance, frozenAt) {
|
|
114
|
+
return encodeActionArgsKwil(
|
|
115
|
+
[
|
|
116
|
+
dataProvider.toLowerCase(),
|
|
117
|
+
streamId,
|
|
118
|
+
timestamp,
|
|
119
|
+
targetValue,
|
|
120
|
+
tolerance,
|
|
121
|
+
frozenAt === 0 ? null : frozenAt
|
|
122
|
+
],
|
|
123
|
+
{
|
|
124
|
+
// Arguments 3, 4 (targetValue, tolerance) must be NUMERIC(36, 18)
|
|
125
|
+
3: Utils.DataType.Numeric(36, 18),
|
|
126
|
+
4: Utils.DataType.Numeric(36, 18)
|
|
127
|
+
}
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
function encodeQueryComponents(dataProvider, streamId, actionId, args) {
|
|
131
|
+
const abiCoder = ethers.AbiCoder.defaultAbiCoder();
|
|
132
|
+
const streamIdBytes = stringToBytes32(streamId);
|
|
133
|
+
const encoded = abiCoder.encode(
|
|
134
|
+
["address", "bytes32", "string", "bytes"],
|
|
135
|
+
[dataProvider, streamIdBytes, actionId, args]
|
|
136
|
+
);
|
|
137
|
+
return ethers.getBytes(encoded);
|
|
138
|
+
}
|
|
139
|
+
function stringToBytes32(str) {
|
|
140
|
+
const bytes = ethers.toUtf8Bytes(str);
|
|
141
|
+
if (bytes.length > 32) {
|
|
142
|
+
throw new Error(`String too long for bytes32: ${str.length} characters`);
|
|
143
|
+
}
|
|
144
|
+
return ethers.zeroPadValue(bytes, 32);
|
|
145
|
+
}
|
|
146
|
+
function hexToBytes(hex) {
|
|
147
|
+
const cleanHex = hex.startsWith("0x") ? hex : "0x" + hex;
|
|
148
|
+
return ethers.getBytes(cleanHex);
|
|
149
|
+
}
|
|
150
|
+
function isBase64(str) {
|
|
151
|
+
const s = str.startsWith("0x") ? str.slice(2) : str;
|
|
152
|
+
return /[+/=]/.test(s) || !/^[0-9a-fA-F]*$/.test(s);
|
|
153
|
+
}
|
|
154
|
+
function base64ToBytes(b64) {
|
|
155
|
+
const cleanB64 = b64.startsWith("0x") ? b64.slice(2) : b64;
|
|
156
|
+
if (typeof Buffer !== "undefined") {
|
|
157
|
+
return new Uint8Array(Buffer.from(cleanB64, "base64"));
|
|
158
|
+
}
|
|
159
|
+
const binary = atob(cleanB64);
|
|
160
|
+
const bytes = new Uint8Array(binary.length);
|
|
161
|
+
for (let i = 0; i < binary.length; i++) {
|
|
162
|
+
bytes[i] = binary.charCodeAt(i);
|
|
163
|
+
}
|
|
164
|
+
return bytes;
|
|
165
|
+
}
|
|
166
|
+
function dbBytesToUint8Array(value) {
|
|
167
|
+
if (value instanceof Uint8Array) {
|
|
168
|
+
return value;
|
|
169
|
+
}
|
|
170
|
+
if (typeof value === "string") {
|
|
171
|
+
if (isBase64(value)) {
|
|
172
|
+
return base64ToBytes(value);
|
|
173
|
+
}
|
|
174
|
+
return hexToBytes(value);
|
|
175
|
+
}
|
|
176
|
+
throw new Error(`Unexpected bytes value type: ${typeof value}`);
|
|
177
|
+
}
|
|
178
|
+
function bytesToHex(bytes) {
|
|
179
|
+
return ethers.hexlify(bytes);
|
|
180
|
+
}
|
|
181
|
+
function validatePrice(price, operation) {
|
|
182
|
+
if (!Number.isInteger(price)) {
|
|
183
|
+
throw new Error(`${operation}: Price must be an integer`);
|
|
184
|
+
}
|
|
185
|
+
if (price < 1 || price > 99) {
|
|
186
|
+
throw new Error(`${operation}: Price must be between 1 and 99 cents`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function validateAmount(amount, operation) {
|
|
190
|
+
if (!Number.isInteger(amount)) {
|
|
191
|
+
throw new Error(`${operation}: Amount must be an integer`);
|
|
192
|
+
}
|
|
193
|
+
if (amount <= 0) {
|
|
194
|
+
throw new Error(`${operation}: Amount must be positive`);
|
|
195
|
+
}
|
|
196
|
+
if (amount > 1e9) {
|
|
197
|
+
throw new Error(`${operation}: Amount exceeds maximum (1,000,000,000)`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
function validateBridge(bridge) {
|
|
201
|
+
const validBridges = ["hoodi_tt2", "sepolia_bridge", "ethereum_bridge"];
|
|
202
|
+
if (!validBridges.includes(bridge)) {
|
|
203
|
+
throw new Error(
|
|
204
|
+
`Invalid bridge: ${bridge}. Must be one of: ${validBridges.join(", ")}`
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
function validateMaxSpread(maxSpread) {
|
|
209
|
+
if (!Number.isInteger(maxSpread)) {
|
|
210
|
+
throw new Error("Max spread must be an integer");
|
|
211
|
+
}
|
|
212
|
+
if (maxSpread < 1 || maxSpread > 50) {
|
|
213
|
+
throw new Error("Max spread must be between 1 and 50 cents");
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
function validateSettleTime(settleTime) {
|
|
217
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
218
|
+
if (settleTime <= now) {
|
|
219
|
+
throw new Error("Settle time must be in the future");
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function settledFilterToBoolean(filter) {
|
|
223
|
+
if (filter === null || filter === void 0) {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
return filter;
|
|
227
|
+
}
|
|
228
|
+
var init_orderbookHelpers = __esm({
|
|
229
|
+
"src/util/orderbookHelpers.ts"() {
|
|
230
|
+
"use strict";
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
|
|
1
234
|
// src/util/orderbookHelpers.test.ts
|
|
2
235
|
import { describe, it, expect } from "vitest";
|
|
3
236
|
import {
|
|
4
|
-
encodeActionArgs,
|
|
5
|
-
encodeQueryComponents,
|
|
6
|
-
encodeRangeActionArgs,
|
|
7
|
-
encodeEqualsActionArgs,
|
|
8
|
-
stringToBytes32,
|
|
9
|
-
hexToBytes,
|
|
10
|
-
bytesToHex,
|
|
11
|
-
validatePrice,
|
|
12
|
-
validateAmount,
|
|
13
|
-
validateBridge,
|
|
14
|
-
validateMaxSpread,
|
|
15
|
-
validateSettleTime,
|
|
16
|
-
settledFilterToBoolean
|
|
237
|
+
encodeActionArgs as encodeActionArgs2,
|
|
238
|
+
encodeQueryComponents as encodeQueryComponents2,
|
|
239
|
+
encodeRangeActionArgs as encodeRangeActionArgs2,
|
|
240
|
+
encodeEqualsActionArgs as encodeEqualsActionArgs2,
|
|
241
|
+
stringToBytes32 as stringToBytes322,
|
|
242
|
+
hexToBytes as hexToBytes2,
|
|
243
|
+
bytesToHex as bytesToHex2,
|
|
244
|
+
validatePrice as validatePrice2,
|
|
245
|
+
validateAmount as validateAmount2,
|
|
246
|
+
validateBridge as validateBridge2,
|
|
247
|
+
validateMaxSpread as validateMaxSpread2,
|
|
248
|
+
validateSettleTime as validateSettleTime2,
|
|
249
|
+
settledFilterToBoolean as settledFilterToBoolean2
|
|
17
250
|
} from "./orderbookHelpers.mjs";
|
|
18
251
|
var TEST_STREAM_ID = "stbtc000000000000000000000000000";
|
|
19
252
|
var TEST_DATA_PROVIDER = "0x4710a8d8f0d845da110086812a32de6d90d7ff5c";
|
|
20
253
|
describe("orderbookHelpers", () => {
|
|
21
254
|
describe("stringToBytes32", () => {
|
|
22
255
|
it("should convert a short string to bytes32", () => {
|
|
23
|
-
const result =
|
|
256
|
+
const result = stringToBytes322("test");
|
|
24
257
|
expect(result).toMatch(/^0x/);
|
|
25
258
|
expect(result.length).toBe(66);
|
|
26
259
|
});
|
|
27
260
|
it("should convert a 32-char string to bytes32", () => {
|
|
28
261
|
const str = "abcdefghijklmnopqrstuvwxyz123456";
|
|
29
262
|
expect(str.length).toBe(32);
|
|
30
|
-
const result =
|
|
263
|
+
const result = stringToBytes322(str);
|
|
31
264
|
expect(result).toMatch(/^0x/);
|
|
32
265
|
expect(result.length).toBe(66);
|
|
33
266
|
});
|
|
34
267
|
it("should throw for strings longer than 32 bytes", () => {
|
|
35
268
|
const longStr = "a".repeat(33);
|
|
36
|
-
expect(() =>
|
|
269
|
+
expect(() => stringToBytes322(longStr)).toThrow("String too long");
|
|
37
270
|
});
|
|
38
271
|
});
|
|
39
272
|
describe("hexToBytes", () => {
|
|
40
273
|
it("should convert hex string with 0x prefix", () => {
|
|
41
|
-
const result =
|
|
274
|
+
const result = hexToBytes2("0x1234");
|
|
42
275
|
expect(result).toBeInstanceOf(Uint8Array);
|
|
43
276
|
expect(result.length).toBe(2);
|
|
44
277
|
expect(result[0]).toBe(18);
|
|
45
278
|
expect(result[1]).toBe(52);
|
|
46
279
|
});
|
|
47
280
|
it("should convert hex string without 0x prefix", () => {
|
|
48
|
-
const result =
|
|
281
|
+
const result = hexToBytes2("abcd");
|
|
49
282
|
expect(result).toBeInstanceOf(Uint8Array);
|
|
50
283
|
expect(result.length).toBe(2);
|
|
51
284
|
expect(result[0]).toBe(171);
|
|
@@ -55,107 +288,107 @@ describe("orderbookHelpers", () => {
|
|
|
55
288
|
describe("bytesToHex", () => {
|
|
56
289
|
it("should convert Uint8Array to hex string with 0x prefix", () => {
|
|
57
290
|
const bytes = new Uint8Array([18, 52, 171, 205]);
|
|
58
|
-
const result =
|
|
291
|
+
const result = bytesToHex2(bytes);
|
|
59
292
|
expect(result).toBe("0x1234abcd");
|
|
60
293
|
});
|
|
61
294
|
it("should handle empty array", () => {
|
|
62
295
|
const bytes = new Uint8Array([]);
|
|
63
|
-
const result =
|
|
296
|
+
const result = bytesToHex2(bytes);
|
|
64
297
|
expect(result).toBe("0x");
|
|
65
298
|
});
|
|
66
299
|
});
|
|
67
300
|
describe("validatePrice", () => {
|
|
68
301
|
it("should accept valid prices (1-99)", () => {
|
|
69
|
-
expect(() =>
|
|
70
|
-
expect(() =>
|
|
71
|
-
expect(() =>
|
|
302
|
+
expect(() => validatePrice2(1, "test")).not.toThrow();
|
|
303
|
+
expect(() => validatePrice2(50, "test")).not.toThrow();
|
|
304
|
+
expect(() => validatePrice2(99, "test")).not.toThrow();
|
|
72
305
|
});
|
|
73
306
|
it("should reject price 0", () => {
|
|
74
|
-
expect(() =>
|
|
307
|
+
expect(() => validatePrice2(0, "test")).toThrow("between 1 and 99");
|
|
75
308
|
});
|
|
76
309
|
it("should reject price 100", () => {
|
|
77
|
-
expect(() =>
|
|
310
|
+
expect(() => validatePrice2(100, "test")).toThrow("between 1 and 99");
|
|
78
311
|
});
|
|
79
312
|
it("should reject negative prices", () => {
|
|
80
|
-
expect(() =>
|
|
313
|
+
expect(() => validatePrice2(-1, "test")).toThrow("between 1 and 99");
|
|
81
314
|
});
|
|
82
315
|
it("should reject non-integer prices", () => {
|
|
83
|
-
expect(() =>
|
|
316
|
+
expect(() => validatePrice2(50.5, "test")).toThrow("must be an integer");
|
|
84
317
|
});
|
|
85
318
|
});
|
|
86
319
|
describe("validateAmount", () => {
|
|
87
320
|
it("should accept valid amounts", () => {
|
|
88
|
-
expect(() =>
|
|
89
|
-
expect(() =>
|
|
321
|
+
expect(() => validateAmount2(1, "test")).not.toThrow();
|
|
322
|
+
expect(() => validateAmount2(1e6, "test")).not.toThrow();
|
|
90
323
|
});
|
|
91
324
|
it("should reject zero amount", () => {
|
|
92
|
-
expect(() =>
|
|
325
|
+
expect(() => validateAmount2(0, "test")).toThrow("must be positive");
|
|
93
326
|
});
|
|
94
327
|
it("should reject negative amounts", () => {
|
|
95
|
-
expect(() =>
|
|
328
|
+
expect(() => validateAmount2(-1, "test")).toThrow("must be positive");
|
|
96
329
|
});
|
|
97
330
|
it("should reject amounts over 1 billion", () => {
|
|
98
|
-
expect(() =>
|
|
331
|
+
expect(() => validateAmount2(1000000001, "test")).toThrow("exceeds maximum");
|
|
99
332
|
});
|
|
100
333
|
it("should reject non-integer amounts", () => {
|
|
101
|
-
expect(() =>
|
|
334
|
+
expect(() => validateAmount2(10.5, "test")).toThrow("must be an integer");
|
|
102
335
|
});
|
|
103
336
|
});
|
|
104
337
|
describe("validateBridge", () => {
|
|
105
338
|
it("should accept valid bridges", () => {
|
|
106
|
-
expect(() =>
|
|
107
|
-
expect(() =>
|
|
108
|
-
expect(() =>
|
|
339
|
+
expect(() => validateBridge2("hoodi_tt2")).not.toThrow();
|
|
340
|
+
expect(() => validateBridge2("sepolia_bridge")).not.toThrow();
|
|
341
|
+
expect(() => validateBridge2("ethereum_bridge")).not.toThrow();
|
|
109
342
|
});
|
|
110
343
|
it("should reject invalid bridges", () => {
|
|
111
|
-
expect(() =>
|
|
112
|
-
expect(() =>
|
|
344
|
+
expect(() => validateBridge2("invalid")).toThrow("Invalid bridge");
|
|
345
|
+
expect(() => validateBridge2("")).toThrow("Invalid bridge");
|
|
113
346
|
});
|
|
114
347
|
});
|
|
115
348
|
describe("validateMaxSpread", () => {
|
|
116
349
|
it("should accept valid spreads (1-50)", () => {
|
|
117
|
-
expect(() =>
|
|
118
|
-
expect(() =>
|
|
119
|
-
expect(() =>
|
|
350
|
+
expect(() => validateMaxSpread2(1)).not.toThrow();
|
|
351
|
+
expect(() => validateMaxSpread2(25)).not.toThrow();
|
|
352
|
+
expect(() => validateMaxSpread2(50)).not.toThrow();
|
|
120
353
|
});
|
|
121
354
|
it("should reject spread 0", () => {
|
|
122
|
-
expect(() =>
|
|
355
|
+
expect(() => validateMaxSpread2(0)).toThrow("between 1 and 50");
|
|
123
356
|
});
|
|
124
357
|
it("should reject spread over 50", () => {
|
|
125
|
-
expect(() =>
|
|
358
|
+
expect(() => validateMaxSpread2(51)).toThrow("between 1 and 50");
|
|
126
359
|
});
|
|
127
360
|
});
|
|
128
361
|
describe("validateSettleTime", () => {
|
|
129
362
|
it("should accept future timestamps", () => {
|
|
130
363
|
const futureTime = Math.floor(Date.now() / 1e3) + 3600;
|
|
131
|
-
expect(() =>
|
|
364
|
+
expect(() => validateSettleTime2(futureTime)).not.toThrow();
|
|
132
365
|
});
|
|
133
366
|
it("should reject past timestamps", () => {
|
|
134
367
|
const pastTime = Math.floor(Date.now() / 1e3) - 3600;
|
|
135
|
-
expect(() =>
|
|
368
|
+
expect(() => validateSettleTime2(pastTime)).toThrow("must be in the future");
|
|
136
369
|
});
|
|
137
370
|
it("should reject current timestamp", () => {
|
|
138
371
|
const now = Math.floor(Date.now() / 1e3);
|
|
139
|
-
expect(() =>
|
|
372
|
+
expect(() => validateSettleTime2(now)).toThrow("must be in the future");
|
|
140
373
|
});
|
|
141
374
|
});
|
|
142
375
|
describe("settledFilterToBoolean", () => {
|
|
143
376
|
it("should return null for null (all markets)", () => {
|
|
144
|
-
expect(
|
|
377
|
+
expect(settledFilterToBoolean2(null)).toBe(null);
|
|
145
378
|
});
|
|
146
379
|
it("should return null for undefined (all markets)", () => {
|
|
147
|
-
expect(
|
|
380
|
+
expect(settledFilterToBoolean2(void 0)).toBe(null);
|
|
148
381
|
});
|
|
149
382
|
it("should return true for true (unsettled)", () => {
|
|
150
|
-
expect(
|
|
383
|
+
expect(settledFilterToBoolean2(true)).toBe(true);
|
|
151
384
|
});
|
|
152
385
|
it("should return false for false (settled)", () => {
|
|
153
|
-
expect(
|
|
386
|
+
expect(settledFilterToBoolean2(false)).toBe(false);
|
|
154
387
|
});
|
|
155
388
|
});
|
|
156
389
|
describe("encodeActionArgs", () => {
|
|
157
390
|
it("should encode action arguments", () => {
|
|
158
|
-
const result =
|
|
391
|
+
const result = encodeActionArgs2(
|
|
159
392
|
TEST_DATA_PROVIDER,
|
|
160
393
|
TEST_STREAM_ID,
|
|
161
394
|
17e8,
|
|
@@ -173,21 +406,21 @@ describe("orderbookHelpers", () => {
|
|
|
173
406
|
"50000.00",
|
|
174
407
|
1e3
|
|
175
408
|
];
|
|
176
|
-
const result1 =
|
|
177
|
-
const result2 =
|
|
178
|
-
expect(
|
|
409
|
+
const result1 = encodeActionArgs2(...args);
|
|
410
|
+
const result2 = encodeActionArgs2(...args);
|
|
411
|
+
expect(bytesToHex2(result1)).toBe(bytesToHex2(result2));
|
|
179
412
|
});
|
|
180
413
|
});
|
|
181
414
|
describe("encodeQueryComponents", () => {
|
|
182
415
|
it("should encode query components", () => {
|
|
183
|
-
const args =
|
|
416
|
+
const args = encodeActionArgs2(
|
|
184
417
|
TEST_DATA_PROVIDER,
|
|
185
418
|
TEST_STREAM_ID,
|
|
186
419
|
17e8,
|
|
187
420
|
"50000.00",
|
|
188
421
|
1e3
|
|
189
422
|
);
|
|
190
|
-
const result =
|
|
423
|
+
const result = encodeQueryComponents2(
|
|
191
424
|
TEST_DATA_PROVIDER,
|
|
192
425
|
TEST_STREAM_ID,
|
|
193
426
|
"price_above_threshold",
|
|
@@ -199,7 +432,7 @@ describe("orderbookHelpers", () => {
|
|
|
199
432
|
});
|
|
200
433
|
describe("encodeRangeActionArgs", () => {
|
|
201
434
|
it("should encode range action arguments", () => {
|
|
202
|
-
const result =
|
|
435
|
+
const result = encodeRangeActionArgs2(
|
|
203
436
|
TEST_DATA_PROVIDER,
|
|
204
437
|
TEST_STREAM_ID,
|
|
205
438
|
17e8,
|
|
@@ -213,7 +446,7 @@ describe("orderbookHelpers", () => {
|
|
|
213
446
|
});
|
|
214
447
|
describe("encodeEqualsActionArgs", () => {
|
|
215
448
|
it("should encode equals action arguments", () => {
|
|
216
|
-
const result =
|
|
449
|
+
const result = encodeEqualsActionArgs2(
|
|
217
450
|
TEST_DATA_PROVIDER,
|
|
218
451
|
TEST_STREAM_ID,
|
|
219
452
|
17e8,
|
|
@@ -225,5 +458,97 @@ describe("orderbookHelpers", () => {
|
|
|
225
458
|
expect(result.length).toBeGreaterThan(0);
|
|
226
459
|
});
|
|
227
460
|
});
|
|
461
|
+
describe("decodeMarketData", () => {
|
|
462
|
+
const importHelper = async () => {
|
|
463
|
+
const { decodeMarketData: decodeMarketData2 } = await Promise.resolve().then(() => (init_orderbookHelpers(), orderbookHelpers_exports));
|
|
464
|
+
return { decodeMarketData: decodeMarketData2 };
|
|
465
|
+
};
|
|
466
|
+
it("should round-trip price_above_threshold", async () => {
|
|
467
|
+
const { decodeMarketData: decodeMarketData2 } = await importHelper();
|
|
468
|
+
const threshold = "100000.0";
|
|
469
|
+
const args = encodeActionArgs2(
|
|
470
|
+
TEST_DATA_PROVIDER,
|
|
471
|
+
TEST_STREAM_ID,
|
|
472
|
+
17e8,
|
|
473
|
+
threshold,
|
|
474
|
+
0
|
|
475
|
+
);
|
|
476
|
+
const encoded = encodeQueryComponents2(
|
|
477
|
+
TEST_DATA_PROVIDER,
|
|
478
|
+
TEST_STREAM_ID,
|
|
479
|
+
"price_above_threshold",
|
|
480
|
+
args
|
|
481
|
+
);
|
|
482
|
+
const decoded = decodeMarketData2(encoded);
|
|
483
|
+
expect(decoded.type).toBe("above");
|
|
484
|
+
expect(decoded.thresholds[0]).toBe(threshold);
|
|
485
|
+
expect(decoded.dataProvider).toBe(TEST_DATA_PROVIDER.toLowerCase());
|
|
486
|
+
expect(decoded.streamId).toBe(TEST_STREAM_ID);
|
|
487
|
+
});
|
|
488
|
+
it("should round-trip price_below_threshold", async () => {
|
|
489
|
+
const { decodeMarketData: decodeMarketData2 } = await importHelper();
|
|
490
|
+
const threshold = "4.5";
|
|
491
|
+
const args = encodeActionArgs2(
|
|
492
|
+
TEST_DATA_PROVIDER,
|
|
493
|
+
TEST_STREAM_ID,
|
|
494
|
+
17e8,
|
|
495
|
+
threshold,
|
|
496
|
+
0
|
|
497
|
+
);
|
|
498
|
+
const encoded = encodeQueryComponents2(
|
|
499
|
+
TEST_DATA_PROVIDER,
|
|
500
|
+
TEST_STREAM_ID,
|
|
501
|
+
"price_below_threshold",
|
|
502
|
+
args
|
|
503
|
+
);
|
|
504
|
+
const decoded = decodeMarketData2(encoded);
|
|
505
|
+
expect(decoded.type).toBe("below");
|
|
506
|
+
expect(decoded.thresholds[0]).toBe(threshold);
|
|
507
|
+
});
|
|
508
|
+
it("should round-trip value_in_range", async () => {
|
|
509
|
+
const { decodeMarketData: decodeMarketData2 } = await importHelper();
|
|
510
|
+
const min = "90000.0";
|
|
511
|
+
const max = "110000.0";
|
|
512
|
+
const args = encodeRangeActionArgs2(
|
|
513
|
+
TEST_DATA_PROVIDER,
|
|
514
|
+
TEST_STREAM_ID,
|
|
515
|
+
17e8,
|
|
516
|
+
min,
|
|
517
|
+
max,
|
|
518
|
+
0
|
|
519
|
+
);
|
|
520
|
+
const encoded = encodeQueryComponents2(
|
|
521
|
+
TEST_DATA_PROVIDER,
|
|
522
|
+
TEST_STREAM_ID,
|
|
523
|
+
"value_in_range",
|
|
524
|
+
args
|
|
525
|
+
);
|
|
526
|
+
const decoded = decodeMarketData2(encoded);
|
|
527
|
+
expect(decoded.type).toBe("between");
|
|
528
|
+
expect(decoded.thresholds).toEqual([min, max]);
|
|
529
|
+
});
|
|
530
|
+
it("should round-trip value_equals", async () => {
|
|
531
|
+
const { decodeMarketData: decodeMarketData2 } = await importHelper();
|
|
532
|
+
const target = "5.25";
|
|
533
|
+
const tolerance = "0.01";
|
|
534
|
+
const args = encodeEqualsActionArgs2(
|
|
535
|
+
TEST_DATA_PROVIDER,
|
|
536
|
+
TEST_STREAM_ID,
|
|
537
|
+
17e8,
|
|
538
|
+
target,
|
|
539
|
+
tolerance,
|
|
540
|
+
0
|
|
541
|
+
);
|
|
542
|
+
const encoded = encodeQueryComponents2(
|
|
543
|
+
TEST_DATA_PROVIDER,
|
|
544
|
+
TEST_STREAM_ID,
|
|
545
|
+
"value_equals",
|
|
546
|
+
args
|
|
547
|
+
);
|
|
548
|
+
const decoded = decodeMarketData2(encoded);
|
|
549
|
+
expect(decoded.type).toBe("equals");
|
|
550
|
+
expect(decoded.thresholds).toEqual([target, tolerance]);
|
|
551
|
+
});
|
|
552
|
+
});
|
|
228
553
|
});
|
|
229
554
|
//# sourceMappingURL=orderbookHelpers.test.mjs.map
|