@trufnetwork/sdk-js 0.6.1 → 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.
@@ -1,4 +1,233 @@
1
1
  "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __esm = (fn, res) => function __init() {
5
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
+ };
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+
12
+ // src/util/orderbookHelpers.ts
13
+ var orderbookHelpers_exports = {};
14
+ __export(orderbookHelpers_exports, {
15
+ bytesToHex: () => bytesToHex,
16
+ dbBytesToUint8Array: () => dbBytesToUint8Array,
17
+ decodeMarketData: () => decodeMarketData,
18
+ encodeActionArgs: () => encodeActionArgs,
19
+ encodeEqualsActionArgs: () => encodeEqualsActionArgs,
20
+ encodeQueryComponents: () => encodeQueryComponents,
21
+ encodeRangeActionArgs: () => encodeRangeActionArgs,
22
+ hexToBytes: () => hexToBytes,
23
+ settledFilterToBoolean: () => settledFilterToBoolean,
24
+ stringToBytes32: () => stringToBytes32,
25
+ validateAmount: () => validateAmount,
26
+ validateBridge: () => validateBridge,
27
+ validateMaxSpread: () => validateMaxSpread,
28
+ validatePrice: () => validatePrice,
29
+ validateSettleTime: () => validateSettleTime
30
+ });
31
+ function decodeMarketData(encoded) {
32
+ const bytes = dbBytesToUint8Array(encoded);
33
+ const { dataProvider, streamId, actionId, args: argsBytes } = (0, import_AttestationEncoding.decodeQueryComponents)(bytes);
34
+ const args = (0, import_AttestationEncoding.decodeActionArgs)(argsBytes);
35
+ const market = {
36
+ dataProvider,
37
+ streamId,
38
+ actionId,
39
+ type: "unknown",
40
+ thresholds: []
41
+ };
42
+ switch (actionId) {
43
+ case "price_above_threshold":
44
+ market.type = "above";
45
+ if (args.length >= 4) {
46
+ market.thresholds.push(args[3].toString());
47
+ }
48
+ break;
49
+ case "price_below_threshold":
50
+ market.type = "below";
51
+ if (args.length >= 4) {
52
+ market.thresholds.push(args[3].toString());
53
+ }
54
+ break;
55
+ case "value_in_range":
56
+ market.type = "between";
57
+ if (args.length >= 5) {
58
+ market.thresholds.push(args[3].toString(), args[4].toString());
59
+ }
60
+ break;
61
+ case "value_equals":
62
+ market.type = "equals";
63
+ if (args.length >= 5) {
64
+ market.thresholds.push(args[3].toString(), args[4].toString());
65
+ }
66
+ break;
67
+ }
68
+ return market;
69
+ }
70
+ function encodeActionArgs(dataProvider, streamId, timestamp, threshold, frozenAt) {
71
+ return (0, import_AttestationEncoding.encodeActionArgs)(
72
+ [
73
+ dataProvider.toLowerCase(),
74
+ // TEXT: data provider address
75
+ streamId,
76
+ // TEXT: stream ID
77
+ timestamp,
78
+ // INT8: timestamp
79
+ threshold,
80
+ // NUMERIC: threshold - must specify type explicitly
81
+ frozenAt === 0 ? null : frozenAt
82
+ // INT8: frozen_at (null for latest)
83
+ ],
84
+ {
85
+ // Argument 3 (threshold) must be NUMERIC(36, 18) to match price_above_threshold action signature
86
+ 3: import_kwil_js.Utils.DataType.Numeric(36, 18)
87
+ }
88
+ );
89
+ }
90
+ function encodeRangeActionArgs(dataProvider, streamId, timestamp, minValue, maxValue, frozenAt) {
91
+ return (0, import_AttestationEncoding.encodeActionArgs)(
92
+ [
93
+ dataProvider.toLowerCase(),
94
+ streamId,
95
+ timestamp,
96
+ minValue,
97
+ maxValue,
98
+ frozenAt === 0 ? null : frozenAt
99
+ ],
100
+ {
101
+ // Arguments 3, 4 (minValue, maxValue) must be NUMERIC(36, 18)
102
+ 3: import_kwil_js.Utils.DataType.Numeric(36, 18),
103
+ 4: import_kwil_js.Utils.DataType.Numeric(36, 18)
104
+ }
105
+ );
106
+ }
107
+ function encodeEqualsActionArgs(dataProvider, streamId, timestamp, targetValue, tolerance, frozenAt) {
108
+ return (0, import_AttestationEncoding.encodeActionArgs)(
109
+ [
110
+ dataProvider.toLowerCase(),
111
+ streamId,
112
+ timestamp,
113
+ targetValue,
114
+ tolerance,
115
+ frozenAt === 0 ? null : frozenAt
116
+ ],
117
+ {
118
+ // Arguments 3, 4 (targetValue, tolerance) must be NUMERIC(36, 18)
119
+ 3: import_kwil_js.Utils.DataType.Numeric(36, 18),
120
+ 4: import_kwil_js.Utils.DataType.Numeric(36, 18)
121
+ }
122
+ );
123
+ }
124
+ function encodeQueryComponents(dataProvider, streamId, actionId, args) {
125
+ const abiCoder = import_ethers.ethers.AbiCoder.defaultAbiCoder();
126
+ const streamIdBytes = stringToBytes32(streamId);
127
+ const encoded = abiCoder.encode(
128
+ ["address", "bytes32", "string", "bytes"],
129
+ [dataProvider, streamIdBytes, actionId, args]
130
+ );
131
+ return import_ethers.ethers.getBytes(encoded);
132
+ }
133
+ function stringToBytes32(str) {
134
+ const bytes = import_ethers.ethers.toUtf8Bytes(str);
135
+ if (bytes.length > 32) {
136
+ throw new Error(`String too long for bytes32: ${str.length} characters`);
137
+ }
138
+ return import_ethers.ethers.zeroPadValue(bytes, 32);
139
+ }
140
+ function hexToBytes(hex) {
141
+ const cleanHex = hex.startsWith("0x") ? hex : "0x" + hex;
142
+ return import_ethers.ethers.getBytes(cleanHex);
143
+ }
144
+ function isBase64(str) {
145
+ const s = str.startsWith("0x") ? str.slice(2) : str;
146
+ return /[+/=]/.test(s) || !/^[0-9a-fA-F]*$/.test(s);
147
+ }
148
+ function base64ToBytes(b64) {
149
+ const cleanB64 = b64.startsWith("0x") ? b64.slice(2) : b64;
150
+ if (typeof Buffer !== "undefined") {
151
+ return new Uint8Array(Buffer.from(cleanB64, "base64"));
152
+ }
153
+ const binary = atob(cleanB64);
154
+ const bytes = new Uint8Array(binary.length);
155
+ for (let i = 0; i < binary.length; i++) {
156
+ bytes[i] = binary.charCodeAt(i);
157
+ }
158
+ return bytes;
159
+ }
160
+ function dbBytesToUint8Array(value) {
161
+ if (value instanceof Uint8Array) {
162
+ return value;
163
+ }
164
+ if (typeof value === "string") {
165
+ if (isBase64(value)) {
166
+ return base64ToBytes(value);
167
+ }
168
+ return hexToBytes(value);
169
+ }
170
+ throw new Error(`Unexpected bytes value type: ${typeof value}`);
171
+ }
172
+ function bytesToHex(bytes) {
173
+ return import_ethers.ethers.hexlify(bytes);
174
+ }
175
+ function validatePrice(price, operation) {
176
+ if (!Number.isInteger(price)) {
177
+ throw new Error(`${operation}: Price must be an integer`);
178
+ }
179
+ if (price < 1 || price > 99) {
180
+ throw new Error(`${operation}: Price must be between 1 and 99 cents`);
181
+ }
182
+ }
183
+ function validateAmount(amount, operation) {
184
+ if (!Number.isInteger(amount)) {
185
+ throw new Error(`${operation}: Amount must be an integer`);
186
+ }
187
+ if (amount <= 0) {
188
+ throw new Error(`${operation}: Amount must be positive`);
189
+ }
190
+ if (amount > 1e9) {
191
+ throw new Error(`${operation}: Amount exceeds maximum (1,000,000,000)`);
192
+ }
193
+ }
194
+ function validateBridge(bridge) {
195
+ const validBridges = ["hoodi_tt2", "sepolia_bridge", "ethereum_bridge"];
196
+ if (!validBridges.includes(bridge)) {
197
+ throw new Error(
198
+ `Invalid bridge: ${bridge}. Must be one of: ${validBridges.join(", ")}`
199
+ );
200
+ }
201
+ }
202
+ function validateMaxSpread(maxSpread) {
203
+ if (!Number.isInteger(maxSpread)) {
204
+ throw new Error("Max spread must be an integer");
205
+ }
206
+ if (maxSpread < 1 || maxSpread > 50) {
207
+ throw new Error("Max spread must be between 1 and 50 cents");
208
+ }
209
+ }
210
+ function validateSettleTime(settleTime) {
211
+ const now = Math.floor(Date.now() / 1e3);
212
+ if (settleTime <= now) {
213
+ throw new Error("Settle time must be in the future");
214
+ }
215
+ }
216
+ function settledFilterToBoolean(filter) {
217
+ if (filter === null || filter === void 0) {
218
+ return null;
219
+ }
220
+ return filter;
221
+ }
222
+ var import_ethers, import_kwil_js, import_AttestationEncoding;
223
+ var init_orderbookHelpers = __esm({
224
+ "src/util/orderbookHelpers.ts"() {
225
+ "use strict";
226
+ import_ethers = require("ethers");
227
+ import_kwil_js = require("@trufnetwork/kwil-js");
228
+ import_AttestationEncoding = require("./AttestationEncoding.cjs");
229
+ }
230
+ });
2
231
 
3
232
  // src/util/orderbookHelpers.test.ts
4
233
  var import_vitest = require("vitest");
@@ -213,5 +442,97 @@ var TEST_DATA_PROVIDER = "0x4710a8d8f0d845da110086812a32de6d90d7ff5c";
213
442
  (0, import_vitest.expect)(result.length).toBeGreaterThan(0);
214
443
  });
215
444
  });
445
+ (0, import_vitest.describe)("decodeMarketData", () => {
446
+ const importHelper = async () => {
447
+ const { decodeMarketData: decodeMarketData2 } = await Promise.resolve().then(() => (init_orderbookHelpers(), orderbookHelpers_exports));
448
+ return { decodeMarketData: decodeMarketData2 };
449
+ };
450
+ (0, import_vitest.it)("should round-trip price_above_threshold", async () => {
451
+ const { decodeMarketData: decodeMarketData2 } = await importHelper();
452
+ const threshold = "100000.0";
453
+ const args = (0, import_orderbookHelpers.encodeActionArgs)(
454
+ TEST_DATA_PROVIDER,
455
+ TEST_STREAM_ID,
456
+ 17e8,
457
+ threshold,
458
+ 0
459
+ );
460
+ const encoded = (0, import_orderbookHelpers.encodeQueryComponents)(
461
+ TEST_DATA_PROVIDER,
462
+ TEST_STREAM_ID,
463
+ "price_above_threshold",
464
+ args
465
+ );
466
+ const decoded = decodeMarketData2(encoded);
467
+ (0, import_vitest.expect)(decoded.type).toBe("above");
468
+ (0, import_vitest.expect)(decoded.thresholds[0]).toBe(threshold);
469
+ (0, import_vitest.expect)(decoded.dataProvider).toBe(TEST_DATA_PROVIDER.toLowerCase());
470
+ (0, import_vitest.expect)(decoded.streamId).toBe(TEST_STREAM_ID);
471
+ });
472
+ (0, import_vitest.it)("should round-trip price_below_threshold", async () => {
473
+ const { decodeMarketData: decodeMarketData2 } = await importHelper();
474
+ const threshold = "4.5";
475
+ const args = (0, import_orderbookHelpers.encodeActionArgs)(
476
+ TEST_DATA_PROVIDER,
477
+ TEST_STREAM_ID,
478
+ 17e8,
479
+ threshold,
480
+ 0
481
+ );
482
+ const encoded = (0, import_orderbookHelpers.encodeQueryComponents)(
483
+ TEST_DATA_PROVIDER,
484
+ TEST_STREAM_ID,
485
+ "price_below_threshold",
486
+ args
487
+ );
488
+ const decoded = decodeMarketData2(encoded);
489
+ (0, import_vitest.expect)(decoded.type).toBe("below");
490
+ (0, import_vitest.expect)(decoded.thresholds[0]).toBe(threshold);
491
+ });
492
+ (0, import_vitest.it)("should round-trip value_in_range", async () => {
493
+ const { decodeMarketData: decodeMarketData2 } = await importHelper();
494
+ const min = "90000.0";
495
+ const max = "110000.0";
496
+ const args = (0, import_orderbookHelpers.encodeRangeActionArgs)(
497
+ TEST_DATA_PROVIDER,
498
+ TEST_STREAM_ID,
499
+ 17e8,
500
+ min,
501
+ max,
502
+ 0
503
+ );
504
+ const encoded = (0, import_orderbookHelpers.encodeQueryComponents)(
505
+ TEST_DATA_PROVIDER,
506
+ TEST_STREAM_ID,
507
+ "value_in_range",
508
+ args
509
+ );
510
+ const decoded = decodeMarketData2(encoded);
511
+ (0, import_vitest.expect)(decoded.type).toBe("between");
512
+ (0, import_vitest.expect)(decoded.thresholds).toEqual([min, max]);
513
+ });
514
+ (0, import_vitest.it)("should round-trip value_equals", async () => {
515
+ const { decodeMarketData: decodeMarketData2 } = await importHelper();
516
+ const target = "5.25";
517
+ const tolerance = "0.01";
518
+ const args = (0, import_orderbookHelpers.encodeEqualsActionArgs)(
519
+ TEST_DATA_PROVIDER,
520
+ TEST_STREAM_ID,
521
+ 17e8,
522
+ target,
523
+ tolerance,
524
+ 0
525
+ );
526
+ const encoded = (0, import_orderbookHelpers.encodeQueryComponents)(
527
+ TEST_DATA_PROVIDER,
528
+ TEST_STREAM_ID,
529
+ "value_equals",
530
+ args
531
+ );
532
+ const decoded = decodeMarketData2(encoded);
533
+ (0, import_vitest.expect)(decoded.type).toBe("equals");
534
+ (0, import_vitest.expect)(decoded.thresholds).toEqual([target, tolerance]);
535
+ });
536
+ });
216
537
  });
217
538
  //# sourceMappingURL=orderbookHelpers.test.cjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../src/util/orderbookHelpers.test.ts"],
4
- "sourcesContent": ["import { describe, it, expect } from \"vitest\";\r\nimport {\r\n encodeActionArgs,\r\n encodeQueryComponents,\r\n encodeRangeActionArgs,\r\n encodeEqualsActionArgs,\r\n stringToBytes32,\r\n hexToBytes,\r\n bytesToHex,\r\n validatePrice,\r\n validateAmount,\r\n validateBridge,\r\n validateMaxSpread,\r\n validateSettleTime,\r\n settledFilterToBoolean,\r\n} from \"./orderbookHelpers\";\r\n\r\n// Valid 32-character stream ID for testing\r\nconst TEST_STREAM_ID = \"stbtc000000000000000000000000000\"; // exactly 32 chars\r\nconst TEST_DATA_PROVIDER = \"0x4710a8d8f0d845da110086812a32de6d90d7ff5c\";\r\n\r\ndescribe(\"orderbookHelpers\", () => {\r\n describe(\"stringToBytes32\", () => {\r\n it(\"should convert a short string to bytes32\", () => {\r\n const result = stringToBytes32(\"test\");\r\n expect(result).toMatch(/^0x/);\r\n expect(result.length).toBe(66); // 0x + 64 hex chars\r\n });\r\n\r\n it(\"should convert a 32-char string to bytes32\", () => {\r\n const str = \"abcdefghijklmnopqrstuvwxyz123456\";\r\n expect(str.length).toBe(32);\r\n const result = stringToBytes32(str);\r\n expect(result).toMatch(/^0x/);\r\n expect(result.length).toBe(66);\r\n });\r\n\r\n it(\"should throw for strings longer than 32 bytes\", () => {\r\n const longStr = \"a\".repeat(33);\r\n expect(() => stringToBytes32(longStr)).toThrow(\"String too long\");\r\n });\r\n });\r\n\r\n describe(\"hexToBytes\", () => {\r\n it(\"should convert hex string with 0x prefix\", () => {\r\n const result = hexToBytes(\"0x1234\");\r\n expect(result).toBeInstanceOf(Uint8Array);\r\n expect(result.length).toBe(2);\r\n expect(result[0]).toBe(0x12);\r\n expect(result[1]).toBe(0x34);\r\n });\r\n\r\n it(\"should convert hex string without 0x prefix\", () => {\r\n const result = hexToBytes(\"abcd\");\r\n expect(result).toBeInstanceOf(Uint8Array);\r\n expect(result.length).toBe(2);\r\n expect(result[0]).toBe(0xab);\r\n expect(result[1]).toBe(0xcd);\r\n });\r\n });\r\n\r\n describe(\"bytesToHex\", () => {\r\n it(\"should convert Uint8Array to hex string with 0x prefix\", () => {\r\n const bytes = new Uint8Array([0x12, 0x34, 0xab, 0xcd]);\r\n const result = bytesToHex(bytes);\r\n expect(result).toBe(\"0x1234abcd\");\r\n });\r\n\r\n it(\"should handle empty array\", () => {\r\n const bytes = new Uint8Array([]);\r\n const result = bytesToHex(bytes);\r\n expect(result).toBe(\"0x\");\r\n });\r\n });\r\n\r\n describe(\"validatePrice\", () => {\r\n it(\"should accept valid prices (1-99)\", () => {\r\n expect(() => validatePrice(1, \"test\")).not.toThrow();\r\n expect(() => validatePrice(50, \"test\")).not.toThrow();\r\n expect(() => validatePrice(99, \"test\")).not.toThrow();\r\n });\r\n\r\n it(\"should reject price 0\", () => {\r\n expect(() => validatePrice(0, \"test\")).toThrow(\"between 1 and 99\");\r\n });\r\n\r\n it(\"should reject price 100\", () => {\r\n expect(() => validatePrice(100, \"test\")).toThrow(\"between 1 and 99\");\r\n });\r\n\r\n it(\"should reject negative prices\", () => {\r\n expect(() => validatePrice(-1, \"test\")).toThrow(\"between 1 and 99\");\r\n });\r\n\r\n it(\"should reject non-integer prices\", () => {\r\n expect(() => validatePrice(50.5, \"test\")).toThrow(\"must be an integer\");\r\n });\r\n });\r\n\r\n describe(\"validateAmount\", () => {\r\n it(\"should accept valid amounts\", () => {\r\n expect(() => validateAmount(1, \"test\")).not.toThrow();\r\n expect(() => validateAmount(1000000, \"test\")).not.toThrow();\r\n });\r\n\r\n it(\"should reject zero amount\", () => {\r\n expect(() => validateAmount(0, \"test\")).toThrow(\"must be positive\");\r\n });\r\n\r\n it(\"should reject negative amounts\", () => {\r\n expect(() => validateAmount(-1, \"test\")).toThrow(\"must be positive\");\r\n });\r\n\r\n it(\"should reject amounts over 1 billion\", () => {\r\n expect(() => validateAmount(1_000_000_001, \"test\")).toThrow(\"exceeds maximum\");\r\n });\r\n\r\n it(\"should reject non-integer amounts\", () => {\r\n expect(() => validateAmount(10.5, \"test\")).toThrow(\"must be an integer\");\r\n });\r\n });\r\n\r\n describe(\"validateBridge\", () => {\r\n it(\"should accept valid bridges\", () => {\r\n expect(() => validateBridge(\"hoodi_tt2\")).not.toThrow();\r\n expect(() => validateBridge(\"sepolia_bridge\")).not.toThrow();\r\n expect(() => validateBridge(\"ethereum_bridge\")).not.toThrow();\r\n });\r\n\r\n it(\"should reject invalid bridges\", () => {\r\n expect(() => validateBridge(\"invalid\")).toThrow(\"Invalid bridge\");\r\n expect(() => validateBridge(\"\")).toThrow(\"Invalid bridge\");\r\n });\r\n });\r\n\r\n describe(\"validateMaxSpread\", () => {\r\n it(\"should accept valid spreads (1-50)\", () => {\r\n expect(() => validateMaxSpread(1)).not.toThrow();\r\n expect(() => validateMaxSpread(25)).not.toThrow();\r\n expect(() => validateMaxSpread(50)).not.toThrow();\r\n });\r\n\r\n it(\"should reject spread 0\", () => {\r\n expect(() => validateMaxSpread(0)).toThrow(\"between 1 and 50\");\r\n });\r\n\r\n it(\"should reject spread over 50\", () => {\r\n expect(() => validateMaxSpread(51)).toThrow(\"between 1 and 50\");\r\n });\r\n });\r\n\r\n describe(\"validateSettleTime\", () => {\r\n it(\"should accept future timestamps\", () => {\r\n const futureTime = Math.floor(Date.now() / 1000) + 3600;\r\n expect(() => validateSettleTime(futureTime)).not.toThrow();\r\n });\r\n\r\n it(\"should reject past timestamps\", () => {\r\n const pastTime = Math.floor(Date.now() / 1000) - 3600;\r\n expect(() => validateSettleTime(pastTime)).toThrow(\"must be in the future\");\r\n });\r\n\r\n it(\"should reject current timestamp\", () => {\r\n const now = Math.floor(Date.now() / 1000);\r\n expect(() => validateSettleTime(now)).toThrow(\"must be in the future\");\r\n });\r\n });\r\n\r\n describe(\"settledFilterToBoolean\", () => {\r\n it(\"should return null for null (all markets)\", () => {\r\n expect(settledFilterToBoolean(null)).toBe(null);\r\n });\r\n\r\n it(\"should return null for undefined (all markets)\", () => {\r\n expect(settledFilterToBoolean(undefined)).toBe(null);\r\n });\r\n\r\n it(\"should return true for true (unsettled)\", () => {\r\n expect(settledFilterToBoolean(true)).toBe(true);\r\n });\r\n\r\n it(\"should return false for false (settled)\", () => {\r\n expect(settledFilterToBoolean(false)).toBe(false);\r\n });\r\n });\r\n\r\n describe(\"encodeActionArgs\", () => {\r\n it(\"should encode action arguments\", () => {\r\n const result = encodeActionArgs(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n 1700000000,\r\n \"50000.00\",\r\n 1000\r\n );\r\n\r\n expect(result).toBeInstanceOf(Uint8Array);\r\n expect(result.length).toBeGreaterThan(0);\r\n });\r\n\r\n it(\"should produce consistent output for same input\", () => {\r\n const args = [\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n 1700000000,\r\n \"50000.00\",\r\n 1000,\r\n ] as const;\r\n\r\n const result1 = encodeActionArgs(...args);\r\n const result2 = encodeActionArgs(...args);\r\n\r\n expect(bytesToHex(result1)).toBe(bytesToHex(result2));\r\n });\r\n });\r\n\r\n describe(\"encodeQueryComponents\", () => {\r\n it(\"should encode query components\", () => {\r\n const args = encodeActionArgs(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n 1700000000,\r\n \"50000.00\",\r\n 1000\r\n );\r\n\r\n const result = encodeQueryComponents(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n \"price_above_threshold\",\r\n args\r\n );\r\n\r\n expect(result).toBeInstanceOf(Uint8Array);\r\n expect(result.length).toBeGreaterThan(args.length);\r\n });\r\n });\r\n\r\n describe(\"encodeRangeActionArgs\", () => {\r\n it(\"should encode range action arguments\", () => {\r\n const result = encodeRangeActionArgs(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n 1700000000,\r\n \"45000.00\",\r\n \"55000.00\",\r\n 1000\r\n );\r\n\r\n expect(result).toBeInstanceOf(Uint8Array);\r\n expect(result.length).toBeGreaterThan(0);\r\n });\r\n });\r\n\r\n describe(\"encodeEqualsActionArgs\", () => {\r\n it(\"should encode equals action arguments\", () => {\r\n const result = encodeEqualsActionArgs(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n 1700000000,\r\n \"50000.00\",\r\n \"100.00\",\r\n 1000\r\n );\r\n\r\n expect(result).toBeInstanceOf(Uint8Array);\r\n expect(result.length).toBeGreaterThan(0);\r\n });\r\n });\r\n});\r\n"],
5
- "mappings": "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",
6
- "names": []
3
+ "sources": ["../../../src/util/orderbookHelpers.ts", "../../../src/util/orderbookHelpers.test.ts"],
4
+ "sourcesContent": ["/**\r\n * Order Book Helper Utilities\r\n *\r\n * Provides encoding functions for query components and byte conversion utilities.\r\n */\r\n\r\nimport { ethers } from \"ethers\";\r\nimport { Utils } from \"@trufnetwork/kwil-js\";\r\nimport {\r\n encodeActionArgs as encodeActionArgsKwil,\r\n decodeActionArgs,\r\n decodeQueryComponents\r\n} from \"./AttestationEncoding\";\r\n\r\n/**\r\n * Structured content of a prediction market's query components\r\n */\r\nexport interface MarketData {\r\n dataProvider: string;\r\n streamId: string;\r\n actionId: string;\r\n type: \"above\" | \"below\" | \"between\" | \"equals\" | \"unknown\";\r\n thresholds: string[];\r\n}\r\n\r\n/**\r\n * Decodes ABI-encoded query_components into high-level MarketData.\r\n *\r\n * @param encoded - ABI-encoded bytes (from marketInfo.queryComponents)\r\n * @returns Object with decoded market details\r\n *\r\n * @example\r\n * ```typescript\r\n * const market = decodeMarketData(marketInfo.queryComponents);\r\n * console.log(`Market type: ${market.type}, Threshold: ${market.thresholds[0]}`);\r\n * ```\r\n */\r\nexport function decodeMarketData(encoded: string | Uint8Array): MarketData {\r\n const bytes = dbBytesToUint8Array(encoded);\r\n const { dataProvider, streamId, actionId, args: argsBytes } = decodeQueryComponents(bytes);\r\n const args = decodeActionArgs(argsBytes);\r\n\r\n const market: MarketData = {\r\n dataProvider,\r\n streamId,\r\n actionId,\r\n type: \"unknown\",\r\n thresholds: [],\r\n };\r\n\r\n // Map action_id to market type and thresholds\r\n // Based on 040-binary-attestation-actions.sql\r\n switch (actionId) {\r\n case \"price_above_threshold\":\r\n market.type = \"above\";\r\n if (args.length >= 4) {\r\n market.thresholds.push(args[3].toString());\r\n }\r\n break;\r\n case \"price_below_threshold\":\r\n market.type = \"below\";\r\n if (args.length >= 4) {\r\n market.thresholds.push(args[3].toString());\r\n }\r\n break;\r\n case \"value_in_range\":\r\n market.type = \"between\";\r\n if (args.length >= 5) {\r\n market.thresholds.push(args[3].toString(), args[4].toString());\r\n }\r\n break;\r\n case \"value_equals\":\r\n market.type = \"equals\";\r\n if (args.length >= 5) {\r\n market.thresholds.push(args[3].toString(), args[4].toString());\r\n }\r\n break;\r\n }\r\n\r\n return market;\r\n}\r\n\r\n/**\r\n * Encodes action arguments for order book queries using Kwil's native encoding.\r\n *\r\n * @param dataProvider - Data provider's Ethereum address\r\n * @param streamId - Stream ID (32 characters)\r\n * @param timestamp - Unix timestamp for price/value check\r\n * @param threshold - Threshold value (as decimal string, e.g., \"50000.00\")\r\n * @param frozenAt - Block height for data snapshot (0 for latest)\r\n * @returns Kwil-encoded bytes compatible with call_dispatch\r\n *\r\n * @example\r\n * ```typescript\r\n * const args = encodeActionArgs(\r\n * \"0x1234567890abcdef1234567890abcdef12345678\",\r\n * \"my_stream_id____________________\", // 32 chars\r\n * 1700000000,\r\n * \"50000.00\",\r\n * 0\r\n * );\r\n * ```\r\n */\r\nexport function encodeActionArgs(\r\n dataProvider: string,\r\n streamId: string,\r\n timestamp: number,\r\n threshold: string,\r\n frozenAt: number\r\n): Uint8Array {\r\n // Use Kwil's native encoding format which is compatible with call_dispatch\r\n // The price_above_threshold action expects: ($data_provider TEXT, $stream_id TEXT, $timestamp INT8, $threshold NUMERIC(36, 18), $frozen_at INT8)\r\n return encodeActionArgsKwil(\r\n [\r\n dataProvider.toLowerCase(), // TEXT: data provider address\r\n streamId, // TEXT: stream ID\r\n timestamp, // INT8: timestamp\r\n threshold, // NUMERIC: threshold - must specify type explicitly\r\n frozenAt === 0 ? null : frozenAt, // INT8: frozen_at (null for latest)\r\n ],\r\n {\r\n // Argument 3 (threshold) must be NUMERIC(36, 18) to match price_above_threshold action signature\r\n 3: Utils.DataType.Numeric(36, 18),\r\n }\r\n );\r\n}\r\n\r\n/**\r\n * Encodes action arguments for range-based markets using Kwil's native encoding.\r\n *\r\n * @param dataProvider - Data provider's Ethereum address\r\n * @param streamId - Stream ID\r\n * @param timestamp - Unix timestamp\r\n * @param minValue - Minimum value of range\r\n * @param maxValue - Maximum value of range\r\n * @param frozenAt - Block height (0 for latest)\r\n * @returns Kwil-encoded bytes compatible with call_dispatch\r\n */\r\nexport function encodeRangeActionArgs(\r\n dataProvider: string,\r\n streamId: string,\r\n timestamp: number,\r\n minValue: string,\r\n maxValue: string,\r\n frozenAt: number\r\n): Uint8Array {\r\n // value_in_range expects: ($data_provider TEXT, $stream_id TEXT, $timestamp INT8, $min_value NUMERIC, $max_value NUMERIC, $frozen_at INT8)\r\n return encodeActionArgsKwil(\r\n [\r\n dataProvider.toLowerCase(),\r\n streamId,\r\n timestamp,\r\n minValue,\r\n maxValue,\r\n frozenAt === 0 ? null : frozenAt,\r\n ],\r\n {\r\n // Arguments 3, 4 (minValue, maxValue) must be NUMERIC(36, 18)\r\n 3: Utils.DataType.Numeric(36, 18),\r\n 4: Utils.DataType.Numeric(36, 18),\r\n }\r\n );\r\n}\r\n\r\n/**\r\n * Encodes action arguments for value equals markets using Kwil's native encoding.\r\n *\r\n * @param dataProvider - Data provider's Ethereum address\r\n * @param streamId - Stream ID\r\n * @param timestamp - Unix timestamp\r\n * @param targetValue - Target value\r\n * @param tolerance - Acceptable tolerance\r\n * @param frozenAt - Block height (0 for latest)\r\n * @returns Kwil-encoded bytes compatible with call_dispatch\r\n */\r\nexport function encodeEqualsActionArgs(\r\n dataProvider: string,\r\n streamId: string,\r\n timestamp: number,\r\n targetValue: string,\r\n tolerance: string,\r\n frozenAt: number\r\n): Uint8Array {\r\n // value_equals expects: ($data_provider TEXT, $stream_id TEXT, $timestamp INT8, $target NUMERIC, $tolerance NUMERIC, $frozen_at INT8)\r\n return encodeActionArgsKwil(\r\n [\r\n dataProvider.toLowerCase(),\r\n streamId,\r\n timestamp,\r\n targetValue,\r\n tolerance,\r\n frozenAt === 0 ? null : frozenAt,\r\n ],\r\n {\r\n // Arguments 3, 4 (targetValue, tolerance) must be NUMERIC(36, 18)\r\n 3: Utils.DataType.Numeric(36, 18),\r\n 4: Utils.DataType.Numeric(36, 18),\r\n }\r\n );\r\n}\r\n\r\n/**\r\n * Encodes full query components for market creation.\r\n *\r\n * The query components are ABI-encoded as a tuple:\r\n * (address dataProvider, bytes32 streamId, string actionId, bytes args)\r\n *\r\n * @param dataProvider - Data provider's Ethereum address\r\n * @param streamId - Stream ID (will be padded to 32 bytes)\r\n * @param actionId - Action identifier (e.g., \"price_above_threshold\")\r\n * @param args - Pre-encoded action arguments from encodeActionArgs()\r\n * @returns ABI-encoded query components\r\n *\r\n * @example\r\n * ```typescript\r\n * const args = encodeActionArgs(...);\r\n * const queryComponents = encodeQueryComponents(\r\n * \"0x1234567890abcdef1234567890abcdef12345678\",\r\n * \"my_stream_id____________________\",\r\n * \"price_above_threshold\",\r\n * args\r\n * );\r\n * ```\r\n */\r\nexport function encodeQueryComponents(\r\n dataProvider: string,\r\n streamId: string,\r\n actionId: string,\r\n args: Uint8Array\r\n): Uint8Array {\r\n const abiCoder = ethers.AbiCoder.defaultAbiCoder();\r\n const streamIdBytes = stringToBytes32(streamId);\r\n\r\n const encoded = abiCoder.encode(\r\n [\"address\", \"bytes32\", \"string\", \"bytes\"],\r\n [dataProvider, streamIdBytes, actionId, args]\r\n );\r\n\r\n return ethers.getBytes(encoded);\r\n}\r\n\r\n/**\r\n * Converts a string to bytes32, padding with zeros if needed.\r\n *\r\n * @param str - String to convert (max 32 characters)\r\n * @returns bytes32 as hex string\r\n */\r\nexport function stringToBytes32(str: string): string {\r\n // Convert string to UTF-8 bytes\r\n const bytes = ethers.toUtf8Bytes(str);\r\n\r\n // Ensure it's not longer than 32 bytes\r\n if (bytes.length > 32) {\r\n throw new Error(`String too long for bytes32: ${str.length} characters`);\r\n }\r\n\r\n // Pad to 32 bytes\r\n return ethers.zeroPadValue(bytes, 32);\r\n}\r\n\r\n/**\r\n * Converts a hex string to Uint8Array.\r\n *\r\n * @param hex - Hex string (with or without 0x prefix)\r\n * @returns Uint8Array\r\n *\r\n * @example\r\n * ```typescript\r\n * const bytes = hexToBytes(\"0x1234abcd\");\r\n * const bytes2 = hexToBytes(\"1234abcd\");\r\n * ```\r\n */\r\nexport function hexToBytes(hex: string): Uint8Array {\r\n const cleanHex = hex.startsWith(\"0x\") ? hex : \"0x\" + hex;\r\n return ethers.getBytes(cleanHex);\r\n}\r\n\r\n/**\r\n * Checks if a string appears to be base64 encoded.\r\n *\r\n * @param str - String to check\r\n * @returns true if string appears to be base64\r\n */\r\nfunction isBase64(str: string): boolean {\r\n // Remove potential 0x prefix for checking\r\n const s = str.startsWith(\"0x\") ? str.slice(2) : str;\r\n // Base64 strings contain +, /, or = which are not valid hex\r\n return /[+/=]/.test(s) || !/^[0-9a-fA-F]*$/.test(s);\r\n}\r\n\r\n/**\r\n * Decodes a base64 string to Uint8Array.\r\n *\r\n * @param b64 - Base64 string (may have 0x prefix from kwil-js)\r\n * @returns Uint8Array\r\n */\r\nfunction base64ToBytes(b64: string): Uint8Array {\r\n // Remove potential 0x prefix that kwil-js might add\r\n const cleanB64 = b64.startsWith(\"0x\") ? b64.slice(2) : b64;\r\n\r\n // In Node.js, use Buffer\r\n if (typeof Buffer !== \"undefined\") {\r\n return new Uint8Array(Buffer.from(cleanB64, \"base64\"));\r\n }\r\n\r\n // In browser, use atob\r\n const binary = atob(cleanB64);\r\n const bytes = new Uint8Array(binary.length);\r\n for (let i = 0; i < binary.length; i++) {\r\n bytes[i] = binary.charCodeAt(i);\r\n }\r\n return bytes;\r\n}\r\n\r\n/**\r\n * Converts a database bytes value (hex or base64) to Uint8Array.\r\n * kwil-js may return BYTEA as hex or base64 depending on version/context.\r\n *\r\n * @param value - Hex string, base64 string, or Uint8Array\r\n * @returns Uint8Array\r\n */\r\nexport function dbBytesToUint8Array(\r\n value: string | Uint8Array\r\n): Uint8Array {\r\n if (value instanceof Uint8Array) {\r\n return value;\r\n }\r\n\r\n if (typeof value === \"string\") {\r\n if (isBase64(value)) {\r\n return base64ToBytes(value);\r\n }\r\n return hexToBytes(value);\r\n }\r\n\r\n throw new Error(`Unexpected bytes value type: ${typeof value}`);\r\n}\r\n\r\n/**\r\n * Converts a Uint8Array to hex string with 0x prefix.\r\n *\r\n * @param bytes - Uint8Array to convert\r\n * @returns Hex string with 0x prefix\r\n *\r\n * @example\r\n * ```typescript\r\n * const hex = bytesToHex(new Uint8Array([0x12, 0x34]));\r\n * // Returns \"0x1234\"\r\n * ```\r\n */\r\nexport function bytesToHex(bytes: Uint8Array): string {\r\n return ethers.hexlify(bytes);\r\n}\r\n\r\n/**\r\n * Validates a price value for order operations.\r\n *\r\n * @param price - Price to validate (1-99)\r\n * @param operation - Operation name for error message\r\n * @throws Error if price is invalid\r\n */\r\nexport function validatePrice(price: number, operation: string): void {\r\n if (!Number.isInteger(price)) {\r\n throw new Error(`${operation}: Price must be an integer`);\r\n }\r\n if (price < 1 || price > 99) {\r\n throw new Error(`${operation}: Price must be between 1 and 99 cents`);\r\n }\r\n}\r\n\r\n/**\r\n * Validates an amount value for order operations.\r\n *\r\n * @param amount - Amount to validate (must be positive)\r\n * @param operation - Operation name for error message\r\n * @throws Error if amount is invalid\r\n */\r\nexport function validateAmount(amount: number, operation: string): void {\r\n if (!Number.isInteger(amount)) {\r\n throw new Error(`${operation}: Amount must be an integer`);\r\n }\r\n if (amount <= 0) {\r\n throw new Error(`${operation}: Amount must be positive`);\r\n }\r\n if (amount > 1_000_000_000) {\r\n throw new Error(`${operation}: Amount exceeds maximum (1,000,000,000)`);\r\n }\r\n}\r\n\r\n/**\r\n * Validates a bridge identifier.\r\n *\r\n * @param bridge - Bridge identifier to validate\r\n * @throws Error if bridge is invalid\r\n */\r\nexport function validateBridge(bridge: string): void {\r\n const validBridges = [\"hoodi_tt2\", \"sepolia_bridge\", \"ethereum_bridge\"];\r\n if (!validBridges.includes(bridge)) {\r\n throw new Error(\r\n `Invalid bridge: ${bridge}. Must be one of: ${validBridges.join(\", \")}`\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Validates max spread for market creation.\r\n *\r\n * @param maxSpread - Max spread to validate (1-50)\r\n * @throws Error if maxSpread is invalid\r\n */\r\nexport function validateMaxSpread(maxSpread: number): void {\r\n if (!Number.isInteger(maxSpread)) {\r\n throw new Error(\"Max spread must be an integer\");\r\n }\r\n if (maxSpread < 1 || maxSpread > 50) {\r\n throw new Error(\"Max spread must be between 1 and 50 cents\");\r\n }\r\n}\r\n\r\n/**\r\n * Validates settle time for market creation.\r\n *\r\n * @param settleTime - Unix timestamp to validate (must be in future)\r\n * @throws Error if settleTime is invalid\r\n */\r\nexport function validateSettleTime(settleTime: number): void {\r\n const now = Math.floor(Date.now() / 1000);\r\n if (settleTime <= now) {\r\n throw new Error(\"Settle time must be in the future\");\r\n }\r\n}\r\n\r\n/**\r\n * Converts settled filter boolean to the value for Kuneiform.\r\n *\r\n * @param filter - Boolean filter (null/undefined=all, true=unsettled, false=settled)\r\n * @returns Boolean or null (null=all, true/false=filter by settled status)\r\n */\r\nexport function settledFilterToBoolean(\r\n filter: boolean | null | undefined\r\n): boolean | null {\r\n if (filter === null || filter === undefined) {\r\n return null; // All markets\r\n }\r\n return filter; // true=unsettled, false=settled\r\n}\r\n", "import { describe, it, expect } from \"vitest\";\r\nimport {\r\n encodeActionArgs,\r\n encodeQueryComponents,\r\n encodeRangeActionArgs,\r\n encodeEqualsActionArgs,\r\n stringToBytes32,\r\n hexToBytes,\r\n bytesToHex,\r\n validatePrice,\r\n validateAmount,\r\n validateBridge,\r\n validateMaxSpread,\r\n validateSettleTime,\r\n settledFilterToBoolean,\r\n} from \"./orderbookHelpers\";\r\n\r\n// Valid 32-character stream ID for testing\r\nconst TEST_STREAM_ID = \"stbtc000000000000000000000000000\"; // exactly 32 chars\r\nconst TEST_DATA_PROVIDER = \"0x4710a8d8f0d845da110086812a32de6d90d7ff5c\";\r\n\r\ndescribe(\"orderbookHelpers\", () => {\r\n describe(\"stringToBytes32\", () => {\r\n it(\"should convert a short string to bytes32\", () => {\r\n const result = stringToBytes32(\"test\");\r\n expect(result).toMatch(/^0x/);\r\n expect(result.length).toBe(66); // 0x + 64 hex chars\r\n });\r\n\r\n it(\"should convert a 32-char string to bytes32\", () => {\r\n const str = \"abcdefghijklmnopqrstuvwxyz123456\";\r\n expect(str.length).toBe(32);\r\n const result = stringToBytes32(str);\r\n expect(result).toMatch(/^0x/);\r\n expect(result.length).toBe(66);\r\n });\r\n\r\n it(\"should throw for strings longer than 32 bytes\", () => {\r\n const longStr = \"a\".repeat(33);\r\n expect(() => stringToBytes32(longStr)).toThrow(\"String too long\");\r\n });\r\n });\r\n\r\n describe(\"hexToBytes\", () => {\r\n it(\"should convert hex string with 0x prefix\", () => {\r\n const result = hexToBytes(\"0x1234\");\r\n expect(result).toBeInstanceOf(Uint8Array);\r\n expect(result.length).toBe(2);\r\n expect(result[0]).toBe(0x12);\r\n expect(result[1]).toBe(0x34);\r\n });\r\n\r\n it(\"should convert hex string without 0x prefix\", () => {\r\n const result = hexToBytes(\"abcd\");\r\n expect(result).toBeInstanceOf(Uint8Array);\r\n expect(result.length).toBe(2);\r\n expect(result[0]).toBe(0xab);\r\n expect(result[1]).toBe(0xcd);\r\n });\r\n });\r\n\r\n describe(\"bytesToHex\", () => {\r\n it(\"should convert Uint8Array to hex string with 0x prefix\", () => {\r\n const bytes = new Uint8Array([0x12, 0x34, 0xab, 0xcd]);\r\n const result = bytesToHex(bytes);\r\n expect(result).toBe(\"0x1234abcd\");\r\n });\r\n\r\n it(\"should handle empty array\", () => {\r\n const bytes = new Uint8Array([]);\r\n const result = bytesToHex(bytes);\r\n expect(result).toBe(\"0x\");\r\n });\r\n });\r\n\r\n describe(\"validatePrice\", () => {\r\n it(\"should accept valid prices (1-99)\", () => {\r\n expect(() => validatePrice(1, \"test\")).not.toThrow();\r\n expect(() => validatePrice(50, \"test\")).not.toThrow();\r\n expect(() => validatePrice(99, \"test\")).not.toThrow();\r\n });\r\n\r\n it(\"should reject price 0\", () => {\r\n expect(() => validatePrice(0, \"test\")).toThrow(\"between 1 and 99\");\r\n });\r\n\r\n it(\"should reject price 100\", () => {\r\n expect(() => validatePrice(100, \"test\")).toThrow(\"between 1 and 99\");\r\n });\r\n\r\n it(\"should reject negative prices\", () => {\r\n expect(() => validatePrice(-1, \"test\")).toThrow(\"between 1 and 99\");\r\n });\r\n\r\n it(\"should reject non-integer prices\", () => {\r\n expect(() => validatePrice(50.5, \"test\")).toThrow(\"must be an integer\");\r\n });\r\n });\r\n\r\n describe(\"validateAmount\", () => {\r\n it(\"should accept valid amounts\", () => {\r\n expect(() => validateAmount(1, \"test\")).not.toThrow();\r\n expect(() => validateAmount(1000000, \"test\")).not.toThrow();\r\n });\r\n\r\n it(\"should reject zero amount\", () => {\r\n expect(() => validateAmount(0, \"test\")).toThrow(\"must be positive\");\r\n });\r\n\r\n it(\"should reject negative amounts\", () => {\r\n expect(() => validateAmount(-1, \"test\")).toThrow(\"must be positive\");\r\n });\r\n\r\n it(\"should reject amounts over 1 billion\", () => {\r\n expect(() => validateAmount(1_000_000_001, \"test\")).toThrow(\"exceeds maximum\");\r\n });\r\n\r\n it(\"should reject non-integer amounts\", () => {\r\n expect(() => validateAmount(10.5, \"test\")).toThrow(\"must be an integer\");\r\n });\r\n });\r\n\r\n describe(\"validateBridge\", () => {\r\n it(\"should accept valid bridges\", () => {\r\n expect(() => validateBridge(\"hoodi_tt2\")).not.toThrow();\r\n expect(() => validateBridge(\"sepolia_bridge\")).not.toThrow();\r\n expect(() => validateBridge(\"ethereum_bridge\")).not.toThrow();\r\n });\r\n\r\n it(\"should reject invalid bridges\", () => {\r\n expect(() => validateBridge(\"invalid\")).toThrow(\"Invalid bridge\");\r\n expect(() => validateBridge(\"\")).toThrow(\"Invalid bridge\");\r\n });\r\n });\r\n\r\n describe(\"validateMaxSpread\", () => {\r\n it(\"should accept valid spreads (1-50)\", () => {\r\n expect(() => validateMaxSpread(1)).not.toThrow();\r\n expect(() => validateMaxSpread(25)).not.toThrow();\r\n expect(() => validateMaxSpread(50)).not.toThrow();\r\n });\r\n\r\n it(\"should reject spread 0\", () => {\r\n expect(() => validateMaxSpread(0)).toThrow(\"between 1 and 50\");\r\n });\r\n\r\n it(\"should reject spread over 50\", () => {\r\n expect(() => validateMaxSpread(51)).toThrow(\"between 1 and 50\");\r\n });\r\n });\r\n\r\n describe(\"validateSettleTime\", () => {\r\n it(\"should accept future timestamps\", () => {\r\n const futureTime = Math.floor(Date.now() / 1000) + 3600;\r\n expect(() => validateSettleTime(futureTime)).not.toThrow();\r\n });\r\n\r\n it(\"should reject past timestamps\", () => {\r\n const pastTime = Math.floor(Date.now() / 1000) - 3600;\r\n expect(() => validateSettleTime(pastTime)).toThrow(\"must be in the future\");\r\n });\r\n\r\n it(\"should reject current timestamp\", () => {\r\n const now = Math.floor(Date.now() / 1000);\r\n expect(() => validateSettleTime(now)).toThrow(\"must be in the future\");\r\n });\r\n });\r\n\r\n describe(\"settledFilterToBoolean\", () => {\r\n it(\"should return null for null (all markets)\", () => {\r\n expect(settledFilterToBoolean(null)).toBe(null);\r\n });\r\n\r\n it(\"should return null for undefined (all markets)\", () => {\r\n expect(settledFilterToBoolean(undefined)).toBe(null);\r\n });\r\n\r\n it(\"should return true for true (unsettled)\", () => {\r\n expect(settledFilterToBoolean(true)).toBe(true);\r\n });\r\n\r\n it(\"should return false for false (settled)\", () => {\r\n expect(settledFilterToBoolean(false)).toBe(false);\r\n });\r\n });\r\n\r\n describe(\"encodeActionArgs\", () => {\r\n it(\"should encode action arguments\", () => {\r\n const result = encodeActionArgs(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n 1700000000,\r\n \"50000.00\",\r\n 1000\r\n );\r\n\r\n expect(result).toBeInstanceOf(Uint8Array);\r\n expect(result.length).toBeGreaterThan(0);\r\n });\r\n\r\n it(\"should produce consistent output for same input\", () => {\r\n const args = [\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n 1700000000,\r\n \"50000.00\",\r\n 1000,\r\n ] as const;\r\n\r\n const result1 = encodeActionArgs(...args);\r\n const result2 = encodeActionArgs(...args);\r\n\r\n expect(bytesToHex(result1)).toBe(bytesToHex(result2));\r\n });\r\n });\r\n\r\n describe(\"encodeQueryComponents\", () => {\r\n it(\"should encode query components\", () => {\r\n const args = encodeActionArgs(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n 1700000000,\r\n \"50000.00\",\r\n 1000\r\n );\r\n\r\n const result = encodeQueryComponents(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n \"price_above_threshold\",\r\n args\r\n );\r\n\r\n expect(result).toBeInstanceOf(Uint8Array);\r\n expect(result.length).toBeGreaterThan(args.length);\r\n });\r\n });\r\n\r\n describe(\"encodeRangeActionArgs\", () => {\r\n it(\"should encode range action arguments\", () => {\r\n const result = encodeRangeActionArgs(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n 1700000000,\r\n \"45000.00\",\r\n \"55000.00\",\r\n 1000\r\n );\r\n\r\n expect(result).toBeInstanceOf(Uint8Array);\r\n expect(result.length).toBeGreaterThan(0);\r\n });\r\n });\r\n\r\n describe(\"encodeEqualsActionArgs\", () => {\r\n it(\"should encode equals action arguments\", () => {\r\n const result = encodeEqualsActionArgs(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n 1700000000,\r\n \"50000.00\",\r\n \"100.00\",\r\n 1000\r\n );\r\n\r\n expect(result).toBeInstanceOf(Uint8Array);\r\n expect(result.length).toBeGreaterThan(0);\r\n });\r\n });\r\n\r\n describe(\"decodeMarketData\", () => {\r\n const importHelper = async () => {\r\n const { decodeMarketData } = await import(\"./orderbookHelpers\");\r\n return { decodeMarketData };\r\n };\r\n\r\n it(\"should round-trip price_above_threshold\", async () => {\r\n const { decodeMarketData } = await importHelper();\r\n const threshold = \"100000.0\";\r\n const args = encodeActionArgs(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n 1700000000,\r\n threshold,\r\n 0\r\n );\r\n\r\n const encoded = encodeQueryComponents(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n \"price_above_threshold\",\r\n args\r\n );\r\n\r\n const decoded = decodeMarketData(encoded);\r\n expect(decoded.type).toBe(\"above\");\r\n expect(decoded.thresholds[0]).toBe(threshold);\r\n expect(decoded.dataProvider).toBe(TEST_DATA_PROVIDER.toLowerCase());\r\n expect(decoded.streamId).toBe(TEST_STREAM_ID);\r\n });\r\n\r\n it(\"should round-trip price_below_threshold\", async () => {\r\n const { decodeMarketData } = await importHelper();\r\n const threshold = \"4.5\";\r\n const args = encodeActionArgs(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n 1700000000,\r\n threshold,\r\n 0\r\n );\r\n \r\n const encoded = encodeQueryComponents(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n \"price_below_threshold\",\r\n args\r\n );\r\n \r\n const decoded = decodeMarketData(encoded);\r\n expect(decoded.type).toBe(\"below\");\r\n expect(decoded.thresholds[0]).toBe(threshold);\r\n });\r\n\r\n it(\"should round-trip value_in_range\", async () => {\r\n const { decodeMarketData } = await importHelper();\r\n const min = \"90000.0\";\r\n const max = \"110000.0\";\r\n const args = encodeRangeActionArgs(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n 1700000000,\r\n min,\r\n max,\r\n 0\r\n );\r\n \r\n const encoded = encodeQueryComponents(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n \"value_in_range\",\r\n args\r\n );\r\n \r\n const decoded = decodeMarketData(encoded);\r\n expect(decoded.type).toBe(\"between\");\r\n expect(decoded.thresholds).toEqual([min, max]);\r\n });\r\n\r\n it(\"should round-trip value_equals\", async () => {\r\n const { decodeMarketData } = await importHelper();\r\n const target = \"5.25\";\r\n const tolerance = \"0.01\";\r\n const args = encodeEqualsActionArgs(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n 1700000000,\r\n target,\r\n tolerance,\r\n 0\r\n );\r\n \r\n const encoded = encodeQueryComponents(\r\n TEST_DATA_PROVIDER,\r\n TEST_STREAM_ID,\r\n \"value_equals\",\r\n args\r\n );\r\n \r\n const decoded = decodeMarketData(encoded);\r\n expect(decoded.type).toBe(\"equals\");\r\n expect(decoded.thresholds).toEqual([target, tolerance]);\r\n });\r\n });\r\n});\r\n"],
5
+ "mappings": "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",
6
+ "names": ["encodeActionArgsKwil", "decodeMarketData"]
7
7
  }
@@ -28,6 +28,60 @@ function encodeActionArgs(args, types) {
28
28
  }
29
29
  return buffer;
30
30
  }
31
+ function decodeActionArgs(data) {
32
+ if (data.length < 4) {
33
+ throw new Error("Data too short for arg count");
34
+ }
35
+ let offset = 0;
36
+ const argCount = readUint32LE(data, offset);
37
+ offset += 4;
38
+ const args = [];
39
+ for (let i = 0; i < argCount; i++) {
40
+ if (offset + 4 > data.length) {
41
+ throw new Error(`Data too short for arg ${i} length`);
42
+ }
43
+ const argLen = readUint32LE(data, offset);
44
+ offset += 4;
45
+ if (offset + argLen > data.length) {
46
+ throw new Error(`Data too short for arg ${i} bytes`);
47
+ }
48
+ const argBytes = data.slice(offset, offset + argLen);
49
+ const { value: decodedArg } = decodeEncodedValue(argBytes, 0);
50
+ args.push(decodedValueToJS(decodedArg));
51
+ offset += argLen;
52
+ }
53
+ return args;
54
+ }
55
+ function decodeQueryComponents(encoded) {
56
+ const abiCoder = AbiCoder.defaultAbiCoder();
57
+ const decoded = abiCoder.decode(
58
+ ["address", "bytes32", "string", "bytes"],
59
+ encoded
60
+ );
61
+ const streamIdBytes = hexToBytes(decoded[1]);
62
+ let lastNonZero = -1;
63
+ for (let i = 31; i >= 0; i--) {
64
+ if (streamIdBytes[i] !== 0) {
65
+ lastNonZero = i;
66
+ break;
67
+ }
68
+ }
69
+ const streamId = new TextDecoder().decode(streamIdBytes.slice(0, lastNonZero + 1));
70
+ return {
71
+ dataProvider: decoded[0].toLowerCase(),
72
+ streamId,
73
+ actionId: decoded[2],
74
+ args: hexToBytes(decoded[3])
75
+ };
76
+ }
77
+ function hexToBytes(hex) {
78
+ const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
79
+ const bytes = new Uint8Array(cleanHex.length / 2);
80
+ for (let i = 0; i < cleanHex.length; i += 2) {
81
+ bytes[i / 2] = parseInt(cleanHex.slice(i, i + 2), 16);
82
+ }
83
+ return bytes;
84
+ }
31
85
  function writeUint32LE(buffer, value, offset) {
32
86
  buffer[offset] = value & 255;
33
87
  buffer[offset + 1] = value >> 8 & 255;
@@ -407,6 +461,34 @@ if (import.meta.vitest) {
407
461
  expect(encoded.length).toBeGreaterThan(4);
408
462
  });
409
463
  });
464
+ describe("decodeActionArgs", () => {
465
+ it("should decode empty args", () => {
466
+ const original = [];
467
+ const encoded = encodeActionArgs(original);
468
+ const decoded = decodeActionArgs(encoded);
469
+ expect(decoded).toEqual(original);
470
+ });
471
+ it("should decode single string arg", () => {
472
+ const original = ["hello"];
473
+ const encoded = encodeActionArgs(original);
474
+ const decoded = decodeActionArgs(encoded);
475
+ expect(decoded).toEqual(original);
476
+ });
477
+ it("should decode single number arg", () => {
478
+ const original = [42];
479
+ const encoded = encodeActionArgs(original);
480
+ const decoded = decodeActionArgs(encoded);
481
+ expect(Number(decoded[0])).toBe(42);
482
+ });
483
+ it("should decode multiple args of different types", () => {
484
+ const original = ["hello", 42, true];
485
+ const encoded = encodeActionArgs(original);
486
+ const decoded = decodeActionArgs(encoded);
487
+ expect(decoded[0]).toBe("hello");
488
+ expect(Number(decoded[1])).toBe(42);
489
+ expect(decoded[2]).toBe(true);
490
+ });
491
+ });
410
492
  describe("writeUint32LE and readUint32LE", () => {
411
493
  it("should round-trip uint32 values", () => {
412
494
  const buffer = new Uint8Array(4);
@@ -464,8 +546,10 @@ if (import.meta.vitest) {
464
546
  }
465
547
  export {
466
548
  decodeABIDatapoints,
549
+ decodeActionArgs,
467
550
  decodeCanonicalQueryResult,
468
551
  decodeEncodedValue,
552
+ decodeQueryComponents,
469
553
  decodedValueToJS,
470
554
  encodeActionArgs,
471
555
  parseAttestationPayload,