@stryke-xyz/premarket-sdk 1.0.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.
Files changed (189) hide show
  1. package/dist/abi/AggregationRouterV6.abi.json +1186 -0
  2. package/dist/abi/NativeOrderFactory.abi.json +291 -0
  3. package/dist/abi/NativeOrderImpl.abi.json +381 -0
  4. package/dist/abi/limitOrderProtocol.json +63 -0
  5. package/dist/address.d.ts +13 -0
  6. package/dist/address.js +32 -0
  7. package/dist/api/filler.d.ts +109 -0
  8. package/dist/api/filler.js +289 -0
  9. package/dist/api/index.d.ts +3 -0
  10. package/dist/api/index.js +3 -0
  11. package/dist/api/order-helper.d.ts +59 -0
  12. package/dist/api/order-helper.js +112 -0
  13. package/dist/api/orderbook-api.d.ts +36 -0
  14. package/dist/api/orderbook-api.js +69 -0
  15. package/dist/bps.d.ts +35 -0
  16. package/dist/bps.js +52 -0
  17. package/dist/config/chains.d.ts +50 -0
  18. package/dist/config/chains.js +21 -0
  19. package/dist/config/index.d.ts +25 -0
  20. package/dist/config/index.js +103 -0
  21. package/dist/config/markets.d.ts +53 -0
  22. package/dist/config/markets.js +125 -0
  23. package/dist/constants.d.ts +4 -0
  24. package/dist/constants.js +30 -0
  25. package/dist/index.d.ts +19 -0
  26. package/dist/index.js +21 -0
  27. package/dist/limit-order/amounts.d.ts +14 -0
  28. package/dist/limit-order/amounts.js +19 -0
  29. package/dist/limit-order/eip712/domain.d.ts +10 -0
  30. package/dist/limit-order/eip712/domain.js +18 -0
  31. package/dist/limit-order/eip712/eip712.types.d.ts +23 -0
  32. package/dist/limit-order/eip712/eip712.types.js +1 -0
  33. package/dist/limit-order/eip712/index.d.ts +3 -0
  34. package/dist/limit-order/eip712/index.js +3 -0
  35. package/dist/limit-order/eip712/order-typed-data-builder.d.ts +6 -0
  36. package/dist/limit-order/eip712/order-typed-data-builder.js +25 -0
  37. package/dist/limit-order/extensions/extension-builder.d.ts +35 -0
  38. package/dist/limit-order/extensions/extension-builder.js +83 -0
  39. package/dist/limit-order/extensions/extension.d.ts +45 -0
  40. package/dist/limit-order/extensions/extension.js +108 -0
  41. package/dist/limit-order/extensions/extension.spec.d.ts +1 -0
  42. package/dist/limit-order/extensions/extension.spec.js +17 -0
  43. package/dist/limit-order/extensions/fee-taker/errors.d.ts +2 -0
  44. package/dist/limit-order/extensions/fee-taker/errors.js +2 -0
  45. package/dist/limit-order/extensions/fee-taker/fee-calculator.d.ts +40 -0
  46. package/dist/limit-order/extensions/fee-taker/fee-calculator.js +83 -0
  47. package/dist/limit-order/extensions/fee-taker/fee-calculator.spec.d.ts +1 -0
  48. package/dist/limit-order/extensions/fee-taker/fee-calculator.spec.js +14 -0
  49. package/dist/limit-order/extensions/fee-taker/fee-taker.extension.d.ts +130 -0
  50. package/dist/limit-order/extensions/fee-taker/fee-taker.extension.js +249 -0
  51. package/dist/limit-order/extensions/fee-taker/fee-taker.extension.spec.d.ts +1 -0
  52. package/dist/limit-order/extensions/fee-taker/fee-taker.extension.spec.js +72 -0
  53. package/dist/limit-order/extensions/fee-taker/fees.d.ts +19 -0
  54. package/dist/limit-order/extensions/fee-taker/fees.js +36 -0
  55. package/dist/limit-order/extensions/fee-taker/index.d.ts +7 -0
  56. package/dist/limit-order/extensions/fee-taker/index.js +7 -0
  57. package/dist/limit-order/extensions/fee-taker/integrator-fee.d.ts +13 -0
  58. package/dist/limit-order/extensions/fee-taker/integrator-fee.js +28 -0
  59. package/dist/limit-order/extensions/fee-taker/resolver-fee.d.ts +19 -0
  60. package/dist/limit-order/extensions/fee-taker/resolver-fee.js +28 -0
  61. package/dist/limit-order/extensions/fee-taker/types.d.ts +4 -0
  62. package/dist/limit-order/extensions/fee-taker/types.js +1 -0
  63. package/dist/limit-order/extensions/fee-taker/whitelist-half-address.d.ts +18 -0
  64. package/dist/limit-order/extensions/fee-taker/whitelist-half-address.js +26 -0
  65. package/dist/limit-order/extensions/index.d.ts +3 -0
  66. package/dist/limit-order/extensions/index.js +3 -0
  67. package/dist/limit-order/index.d.ts +10 -0
  68. package/dist/limit-order/index.js +10 -0
  69. package/dist/limit-order/interaction.d.ts +16 -0
  70. package/dist/limit-order/interaction.js +25 -0
  71. package/dist/limit-order/interaction.spec.d.ts +1 -0
  72. package/dist/limit-order/interaction.spec.js +8 -0
  73. package/dist/limit-order/limit-order-with-fee.d.ts +59 -0
  74. package/dist/limit-order/limit-order-with-fee.js +94 -0
  75. package/dist/limit-order/limit-order-with-fee.spec.d.ts +1 -0
  76. package/dist/limit-order/limit-order-with-fee.spec.js +31 -0
  77. package/dist/limit-order/limit-order.d.ts +63 -0
  78. package/dist/limit-order/limit-order.js +211 -0
  79. package/dist/limit-order/limit-order.spec.d.ts +1 -0
  80. package/dist/limit-order/limit-order.spec.js +103 -0
  81. package/dist/limit-order/maker-traits.d.ts +200 -0
  82. package/dist/limit-order/maker-traits.js +309 -0
  83. package/dist/limit-order/maker-traits.spec.d.ts +1 -0
  84. package/dist/limit-order/maker-traits.spec.js +102 -0
  85. package/dist/limit-order/source-track.d.ts +1 -0
  86. package/dist/limit-order/source-track.js +22 -0
  87. package/dist/limit-order/taker-traits.d.ts +141 -0
  88. package/dist/limit-order/taker-traits.js +207 -0
  89. package/dist/limit-order/types.d.ts +24 -0
  90. package/dist/limit-order/types.js +1 -0
  91. package/dist/limit-order/verification.d.ts +16 -0
  92. package/dist/limit-order/verification.js +108 -0
  93. package/dist/limit-order-contract/index.d.ts +4 -0
  94. package/dist/limit-order-contract/index.js +4 -0
  95. package/dist/limit-order-contract/limit-order-contract.d.ts +34 -0
  96. package/dist/limit-order-contract/limit-order-contract.js +79 -0
  97. package/dist/limit-order-contract/native-order-factory.d.ts +10 -0
  98. package/dist/limit-order-contract/native-order-factory.js +22 -0
  99. package/dist/limit-order-contract/native-order-impl.d.ts +10 -0
  100. package/dist/limit-order-contract/native-order-impl.js +24 -0
  101. package/dist/limit-order-contract/proxy-factory.d.ts +20 -0
  102. package/dist/limit-order-contract/proxy-factory.js +32 -0
  103. package/dist/limit-order-contract/proxy-factory.spec.d.ts +1 -0
  104. package/dist/limit-order-contract/proxy-factory.spec.js +16 -0
  105. package/dist/limit-order-contract/types.d.ts +6 -0
  106. package/dist/limit-order-contract/types.js +1 -0
  107. package/dist/ponder/client/index.d.ts +23 -0
  108. package/dist/ponder/client/index.js +44 -0
  109. package/dist/ponder/client/queries/markets.d.ts +30 -0
  110. package/dist/ponder/client/queries/markets.js +200 -0
  111. package/dist/ponder/client/queries/positions.d.ts +13 -0
  112. package/dist/ponder/client/queries/positions.js +406 -0
  113. package/dist/ponder/client/types/history.d.ts +94 -0
  114. package/dist/ponder/client/types/history.js +1 -0
  115. package/dist/ponder/client/types/index.d.ts +5 -0
  116. package/dist/ponder/client/types/index.js +5 -0
  117. package/dist/ponder/client/types/market.d.ts +45 -0
  118. package/dist/ponder/client/types/market.js +1 -0
  119. package/dist/ponder/client/types/position.d.ts +32 -0
  120. package/dist/ponder/client/types/position.js +1 -0
  121. package/dist/ponder/client/types/serializers.d.ts +57 -0
  122. package/dist/ponder/client/types/serializers.js +248 -0
  123. package/dist/ponder/client/types/user.d.ts +5 -0
  124. package/dist/ponder/client/types/user.js +1 -0
  125. package/dist/ponder/client/utils.d.ts +1 -0
  126. package/dist/ponder/client/utils.js +32 -0
  127. package/dist/ponder/generated/index.d.ts +18 -0
  128. package/dist/ponder/generated/index.js +20 -0
  129. package/dist/ponder/generated/runtime/batcher.d.ts +105 -0
  130. package/dist/ponder/generated/runtime/batcher.js +188 -0
  131. package/dist/ponder/generated/runtime/createClient.d.ts +17 -0
  132. package/dist/ponder/generated/runtime/createClient.js +24 -0
  133. package/dist/ponder/generated/runtime/error.d.ts +18 -0
  134. package/dist/ponder/generated/runtime/error.js +15 -0
  135. package/dist/ponder/generated/runtime/fetcher.d.ts +10 -0
  136. package/dist/ponder/generated/runtime/fetcher.js +67 -0
  137. package/dist/ponder/generated/runtime/generateGraphqlOperation.d.ts +30 -0
  138. package/dist/ponder/generated/runtime/generateGraphqlOperation.js +128 -0
  139. package/dist/ponder/generated/runtime/index.d.ts +11 -0
  140. package/dist/ponder/generated/runtime/index.js +10 -0
  141. package/dist/ponder/generated/runtime/linkTypeMap.d.ts +9 -0
  142. package/dist/ponder/generated/runtime/linkTypeMap.js +83 -0
  143. package/dist/ponder/generated/runtime/typeSelection.d.ts +28 -0
  144. package/dist/ponder/generated/runtime/typeSelection.js +3 -0
  145. package/dist/ponder/generated/runtime/types.d.ts +55 -0
  146. package/dist/ponder/generated/runtime/types.js +2 -0
  147. package/dist/ponder/generated/schema.d.ts +3026 -0
  148. package/dist/ponder/generated/schema.js +222 -0
  149. package/dist/ponder/generated/types.d.ts +2393 -0
  150. package/dist/ponder/generated/types.js +6915 -0
  151. package/dist/ponder/index.d.ts +2 -0
  152. package/dist/ponder/index.js +2 -0
  153. package/dist/ponder/types.d.ts +3 -0
  154. package/dist/ponder/types.js +1 -0
  155. package/dist/rfq-order/index.d.ts +1 -0
  156. package/dist/rfq-order/index.js +1 -0
  157. package/dist/rfq-order/rfq-order.d.ts +21 -0
  158. package/dist/rfq-order/rfq-order.js +22 -0
  159. package/dist/rfq-order/rfq-order.spec.d.ts +1 -0
  160. package/dist/rfq-order/rfq-order.spec.js +27 -0
  161. package/dist/shared/index.d.ts +2 -0
  162. package/dist/shared/index.js +2 -0
  163. package/dist/shared/types.d.ts +79 -0
  164. package/dist/shared/types.js +12 -0
  165. package/dist/shared/utils.d.ts +7 -0
  166. package/dist/shared/utils.js +19 -0
  167. package/dist/sync/clients/balance-client.d.ts +41 -0
  168. package/dist/sync/clients/balance-client.js +139 -0
  169. package/dist/sync/clients/base-client.d.ts +47 -0
  170. package/dist/sync/clients/base-client.js +154 -0
  171. package/dist/sync/clients/order-client.d.ts +18 -0
  172. package/dist/sync/clients/order-client.js +151 -0
  173. package/dist/sync/index.d.ts +5 -0
  174. package/dist/sync/index.js +3 -0
  175. package/dist/sync/redis-ws-client.d.ts +18 -0
  176. package/dist/sync/redis-ws-client.js +88 -0
  177. package/dist/sync/types.d.ts +20 -0
  178. package/dist/sync/types.js +1 -0
  179. package/dist/utils/mul-div.d.ts +5 -0
  180. package/dist/utils/mul-div.js +13 -0
  181. package/dist/utils/orderUtils.d.ts +19 -0
  182. package/dist/utils/orderUtils.js +51 -0
  183. package/dist/utils/rand-bigint.d.ts +1 -0
  184. package/dist/utils/rand-bigint.js +13 -0
  185. package/dist/utils/rand-bigint.spec.d.ts +1 -0
  186. package/dist/utils/rand-bigint.spec.js +11 -0
  187. package/dist/validations.d.ts +1 -0
  188. package/dist/validations.js +3 -0
  189. package/package.json +60 -0
@@ -0,0 +1,151 @@
1
+ import { OrderStatus } from "../../shared/types.js";
2
+ import { BaseSyncClient } from "./base-client.js";
3
+ export class OrderbookSyncClient extends BaseSyncClient {
4
+ constructor(config) {
5
+ // Build full config with channel
6
+ const fullConfig = {
7
+ ...config,
8
+ channel: `orderbook:market:${config.marketId}`,
9
+ };
10
+ super(fullConfig);
11
+ this.expireCheckInterval = null;
12
+ }
13
+ async connect() {
14
+ await super.connect();
15
+ this.startExpireCheck();
16
+ }
17
+ async fetchSnapshot() {
18
+ try {
19
+ if (!this.config.snapshotUrl) {
20
+ return;
21
+ }
22
+ const url = `${this.config.snapshotUrl}/api/orders?marketId=${this.config.marketId}&status=ACTIVE`;
23
+ const response = await fetch(url);
24
+ if (!response.ok) {
25
+ throw new Error(`Snapshot fetch failed: ${response.status} ${response.statusText}`);
26
+ }
27
+ const data = (await response.json());
28
+ if (data.success && data.data) {
29
+ const orders = data.data.orders || data.data;
30
+ const snapshotSeq = data.data.seq || data.seq || 0;
31
+ this.dataMap.clear();
32
+ orders.forEach((order) => {
33
+ this.dataMap.set(order.orderHash, order);
34
+ });
35
+ this.lastSeq = snapshotSeq;
36
+ this.notifySnapshotListeners(orders);
37
+ }
38
+ }
39
+ catch (error) {
40
+ console.error("Error fetching snapshot:", error);
41
+ }
42
+ }
43
+ applyMessage(message) {
44
+ const change = message.change;
45
+ switch (change.type) {
46
+ case "INSERT":
47
+ if (change.order) {
48
+ this.dataMap.set(change.orderHash, change.order);
49
+ }
50
+ break;
51
+ case "UPDATE":
52
+ if (change.order) {
53
+ // Only keep the order if it's still ACTIVE, otherwise remove it
54
+ // (CANCELLED and FILLED orders should not be in the orderbook)
55
+ if (change.order.status === OrderStatus.ACTIVE) {
56
+ this.dataMap.set(change.orderHash, change.order);
57
+ }
58
+ else {
59
+ this.dataMap.delete(change.orderHash);
60
+ }
61
+ }
62
+ break;
63
+ case "DELETE":
64
+ this.dataMap.delete(change.orderHash);
65
+ break;
66
+ }
67
+ this.changeListeners.forEach((listener) => {
68
+ try {
69
+ listener(change);
70
+ }
71
+ catch (error) {
72
+ console.error("Error in change listener:", error);
73
+ }
74
+ });
75
+ }
76
+ async recoverGap(fromSeq, toSeq) {
77
+ if (!this.config.gapRecoveryUrl) {
78
+ return [];
79
+ }
80
+ const gapSize = toSeq - fromSeq + 1;
81
+ if (gapSize > 1000) {
82
+ await this.fullResync();
83
+ return [];
84
+ }
85
+ this.setStatus("recovering");
86
+ try {
87
+ const url = `${this.config.gapRecoveryUrl}/api/sync/messages?marketId=${this.config.marketId}&fromSeq=${fromSeq}&toSeq=${toSeq}`;
88
+ const response = await fetch(url);
89
+ const data = (await response.json());
90
+ if (data.success && data.data) {
91
+ const messages = data.data;
92
+ messages.sort((a, b) => a.seq - b.seq);
93
+ this.setStatus("synced");
94
+ return messages;
95
+ }
96
+ this.setStatus("synced");
97
+ return [];
98
+ }
99
+ catch (error) {
100
+ await this.fullResync();
101
+ return [];
102
+ }
103
+ }
104
+ getOrders() {
105
+ return Array.from(this.dataMap.values());
106
+ }
107
+ getOrder(orderHash) {
108
+ return this.dataMap.get(orderHash);
109
+ }
110
+ startExpireCheck() {
111
+ // Clear any existing interval
112
+ if (this.expireCheckInterval) {
113
+ clearInterval(this.expireCheckInterval);
114
+ }
115
+ // Check for expired orders every 1 second
116
+ this.expireCheckInterval = setInterval(() => {
117
+ const now = Math.floor(Date.now() / 1000);
118
+ const expiredOrders = [];
119
+ for (const [orderHash, order] of this.dataMap.entries()) {
120
+ // Check if order has expired
121
+ if (order.expiresAt && order.expiresAt < now) {
122
+ expiredOrders.push(orderHash);
123
+ }
124
+ }
125
+ // Remove expired orders and notify listeners
126
+ for (const orderHash of expiredOrders) {
127
+ this.dataMap.delete(orderHash);
128
+ const change = {
129
+ type: "DELETE",
130
+ orderHash,
131
+ };
132
+ this.changeListeners.forEach((listener) => {
133
+ try {
134
+ listener(change);
135
+ }
136
+ catch (error) {
137
+ console.error("Error in change listener:", error);
138
+ }
139
+ });
140
+ }
141
+ }, 1000);
142
+ }
143
+ async disconnect() {
144
+ // Clear expire check interval
145
+ if (this.expireCheckInterval) {
146
+ clearInterval(this.expireCheckInterval);
147
+ this.expireCheckInterval = null;
148
+ }
149
+ await super.disconnect();
150
+ }
151
+ }
@@ -0,0 +1,5 @@
1
+ export { BaseSyncClient } from "./clients/base-client.js";
2
+ export { OrderbookSyncClient } from "./clients/order-client.js";
3
+ export { BalanceSyncClient } from "./clients/balance-client.js";
4
+ export type { OrderChange, SequencedMessage, SyncClientConfig, SyncStatus, } from "./types.js";
5
+ export type { BalanceData, BalanceUpdateMessage, BalanceSyncClientConfig, } from "./clients/balance-client.js";
@@ -0,0 +1,3 @@
1
+ export { BaseSyncClient } from "./clients/base-client.js";
2
+ export { OrderbookSyncClient } from "./clients/order-client.js";
3
+ export { BalanceSyncClient } from "./clients/balance-client.js";
@@ -0,0 +1,18 @@
1
+ type Handler<T = any> = (data: T) => void;
2
+ export declare class RedisWsClient {
3
+ private url;
4
+ private ws;
5
+ private handlers;
6
+ private heartbeat?;
7
+ constructor(url: string);
8
+ private connect;
9
+ private reconnect;
10
+ private startHeartbeat;
11
+ private stopHeartbeat;
12
+ subscribe<T>(channel: string, handler: Handler<T>): void;
13
+ unsubscribe(channel: string, handler?: Handler): void;
14
+ private subscribeInternal;
15
+ private unsubscribeInternal;
16
+ close(): void;
17
+ }
18
+ export {};
@@ -0,0 +1,88 @@
1
+ export class RedisWsClient {
2
+ constructor(url) {
3
+ this.url = url;
4
+ this.handlers = new Map();
5
+ this.connect();
6
+ }
7
+ connect() {
8
+ this.ws = new WebSocket(this.url);
9
+ this.ws.onopen = () => {
10
+ this.startHeartbeat();
11
+ // Re-subscribe to all channels after reconnection
12
+ for (const channel of this.handlers.keys()) {
13
+ this.subscribeInternal(channel);
14
+ }
15
+ };
16
+ this.ws.onmessage = (event) => {
17
+ const message = event.data;
18
+ // Redis messages come directly as strings from the bridge
19
+ // Since we subscribe to one channel per client instance in practice,
20
+ // we can call all handlers
21
+ for (const handlers of this.handlers.values()) {
22
+ handlers.forEach((fn) => fn(message));
23
+ }
24
+ };
25
+ this.ws.onclose = () => this.reconnect();
26
+ this.ws.onerror = () => this.ws.close();
27
+ }
28
+ reconnect() {
29
+ this.stopHeartbeat();
30
+ setTimeout(() => this.connect(), 1000);
31
+ }
32
+ startHeartbeat() {
33
+ this.heartbeat = setInterval(() => {
34
+ if (this.ws.readyState === WebSocket.OPEN) {
35
+ this.ws.send(JSON.stringify({ type: "ping" }));
36
+ }
37
+ }, 20000);
38
+ }
39
+ stopHeartbeat() {
40
+ if (this.heartbeat)
41
+ clearInterval(this.heartbeat);
42
+ }
43
+ subscribe(channel, handler) {
44
+ if (!this.handlers.has(channel)) {
45
+ this.handlers.set(channel, new Set());
46
+ this.subscribeInternal(channel);
47
+ }
48
+ this.handlers.get(channel).add(handler);
49
+ }
50
+ unsubscribe(channel, handler) {
51
+ const handlers = this.handlers.get(channel);
52
+ if (!handlers)
53
+ return;
54
+ if (handler) {
55
+ handlers.delete(handler);
56
+ if (handlers.size === 0) {
57
+ this.handlers.delete(channel);
58
+ this.unsubscribeInternal(channel);
59
+ }
60
+ }
61
+ else {
62
+ this.handlers.delete(channel);
63
+ this.unsubscribeInternal(channel);
64
+ }
65
+ }
66
+ subscribeInternal(channel) {
67
+ if (this.ws.readyState === WebSocket.OPEN) {
68
+ this.ws.send(JSON.stringify({
69
+ type: "subscribe",
70
+ channel,
71
+ }));
72
+ }
73
+ }
74
+ unsubscribeInternal(channel) {
75
+ if (this.ws.readyState === WebSocket.OPEN) {
76
+ this.ws.send(JSON.stringify({
77
+ type: "unsubscribe",
78
+ channel,
79
+ }));
80
+ }
81
+ }
82
+ close() {
83
+ this.stopHeartbeat();
84
+ if (this.ws) {
85
+ this.ws.close();
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,20 @@
1
+ import type { StoredOrder } from "../shared/types.js";
2
+ export type SyncStatus = "connecting" | "syncing" | "synced" | "recovering" | "disconnected" | "error";
3
+ export interface OrderChange {
4
+ type: "INSERT" | "UPDATE" | "DELETE";
5
+ orderHash: string;
6
+ order?: StoredOrder;
7
+ }
8
+ export interface SequencedMessage {
9
+ seq: number;
10
+ marketId: string;
11
+ change: OrderChange;
12
+ timestamp: number;
13
+ }
14
+ export interface SyncClientConfig {
15
+ redisUrl: string;
16
+ gapRecoveryUrl?: string;
17
+ marketId: string;
18
+ snapshotUrl?: string;
19
+ channel?: string;
20
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ export declare enum Rounding {
2
+ Ceil = 0,
3
+ Floor = 1
4
+ }
5
+ export declare function mulDiv(a: bigint, b: bigint, x: bigint, rounding?: Rounding): bigint;
@@ -0,0 +1,13 @@
1
+ export var Rounding;
2
+ (function (Rounding) {
3
+ Rounding[Rounding["Ceil"] = 0] = "Ceil";
4
+ Rounding[Rounding["Floor"] = 1] = "Floor";
5
+ })(Rounding || (Rounding = {}));
6
+ // todo: move to more appropriate place
7
+ export function mulDiv(a, b, x, rounding = Rounding.Floor) {
8
+ const res = (a * b) / x;
9
+ if (rounding === Rounding.Ceil && (a * b) % x > 0) {
10
+ return res + 1n;
11
+ }
12
+ return res;
13
+ }
@@ -0,0 +1,19 @@
1
+ import { type Hex } from "viem";
2
+ import { LimitOrder } from "../limit-order";
3
+ import type { OrderSignature } from "../shared/types.js";
4
+ /**
5
+ * Build makerAssetSuffix for ERC6909 extension
6
+ */
7
+ export declare function buildMakerAssetSuffix(tokenAddress: string, tokenId: Hex): string;
8
+ /**
9
+ * Decode asset suffix (makerAssetSuffix or takerAssetSuffix) to extract token address and tokenId
10
+ * Format: 0x + [32 bytes padded token address] + [32 bytes tokenId] + [32 bytes offset] + [32 bytes length]
11
+ */
12
+ export declare function decodeAssetSuffix(suffix: string): {
13
+ token: `0x${string}`;
14
+ tokenId: bigint;
15
+ } | null;
16
+ /**
17
+ * Verify order signature and recover signer address
18
+ */
19
+ export declare function verifyOrderSignature(limitOrder: LimitOrder, signature: OrderSignature, chainId: number): Promise<string>;
@@ -0,0 +1,51 @@
1
+ import { pad, toHex, recoverAddress, concat } from "viem";
2
+ /**
3
+ * Build makerAssetSuffix for ERC6909 extension
4
+ */
5
+ export function buildMakerAssetSuffix(tokenAddress, tokenId) {
6
+ const tokenPadded = pad(tokenAddress, { size: 32 }).slice(2);
7
+ const tokenIdPadded = pad(tokenId, { size: 32 }).slice(2);
8
+ const offsetPadded = pad(toHex(192), { size: 32 }).slice(2);
9
+ const lengthPadded = pad(toHex(0), { size: 32 }).slice(2);
10
+ return "0x" + tokenPadded + tokenIdPadded + offsetPadded + lengthPadded;
11
+ }
12
+ /**
13
+ * Decode asset suffix (makerAssetSuffix or takerAssetSuffix) to extract token address and tokenId
14
+ * Format: 0x + [32 bytes padded token address] + [32 bytes tokenId] + [32 bytes offset] + [32 bytes length]
15
+ */
16
+ export function decodeAssetSuffix(suffix) {
17
+ if (suffix === "0x" || suffix.length < 130)
18
+ return null;
19
+ const data = suffix.slice(2); // Remove 0x prefix
20
+ if (data.length < 128)
21
+ return null; // Need at least 64 bytes (128 hex chars) for address + tokenId
22
+ // Token address is in the last 20 bytes (40 hex chars) of the first 32-byte chunk
23
+ // Bytes 0-31: padded address (address is in bytes 12-31, hex chars 24-64)
24
+ const tokenAddressHex = ("0x" + data.slice(24, 64));
25
+ // TokenId is in the second 32-byte chunk
26
+ // Bytes 32-63: tokenId (hex chars 64-128)
27
+ const tokenIdHex = "0x" + data.slice(64, 128);
28
+ const tokenId = BigInt(tokenIdHex);
29
+ return {
30
+ token: tokenAddressHex,
31
+ tokenId,
32
+ };
33
+ }
34
+ /**
35
+ * Verify order signature and recover signer address
36
+ */
37
+ export async function verifyOrderSignature(limitOrder, signature, chainId) {
38
+ const orderHash = limitOrder.getOrderHash(chainId);
39
+ // Extract v from vs
40
+ const vsBigInt = BigInt(signature.vs);
41
+ const v = vsBigInt >> BigInt(255) === BigInt(1) ? 28 : 27;
42
+ const sMask = (BigInt(1) << BigInt(255)) - BigInt(1);
43
+ const s = pad(toHex(vsBigInt & sMask), { size: 32 });
44
+ // Reconstruct full signature
45
+ const fullSignature = concat([signature.r, s, toHex(v)]);
46
+ const recoveredAddress = await recoverAddress({
47
+ hash: orderHash,
48
+ signature: fullSignature,
49
+ });
50
+ return recoveredAddress.toLowerCase();
51
+ }
@@ -0,0 +1 @@
1
+ export declare function randBigInt(max: number | bigint): bigint;
@@ -0,0 +1,13 @@
1
+ import { randomBytes } from 'ethers';
2
+ export function randBigInt(max) {
3
+ let bytesCount = 0;
4
+ max = BigInt(max) + 1n;
5
+ let rest = max;
6
+ while (rest) {
7
+ rest = rest >> 8n;
8
+ bytesCount += 1;
9
+ }
10
+ const bytes = randomBytes(bytesCount);
11
+ const val = bytes.reduce((acc, val, i) => acc + (BigInt(val) << BigInt(i * 8)), 0n);
12
+ return val % max;
13
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ import { randBigInt } from './rand-bigint.js';
2
+ describe('randBigint', () => {
3
+ it('should generate rand bigint in correct interval', () => {
4
+ expect(randBigInt(1)).toBeGreaterThanOrEqual(0n);
5
+ expect(randBigInt(1)).toBeLessThanOrEqual(1n);
6
+ expect(randBigInt(10n)).toBeGreaterThanOrEqual(0);
7
+ expect(randBigInt(10n)).toBeLessThanOrEqual(10n);
8
+ expect(randBigInt(2n << 96n)).toBeGreaterThanOrEqual(0);
9
+ expect(randBigInt(2n << 96n)).toBeLessThanOrEqual(2n << 96n);
10
+ });
11
+ });
@@ -0,0 +1 @@
1
+ export declare function isInt(val: number): boolean;
@@ -0,0 +1,3 @@
1
+ export function isInt(val) {
2
+ return Math.floor(val) === val;
3
+ }
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@stryke-xyz/premarket-sdk",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "test": "bun test",
21
+ "test:e2e": "bun test test/e2e/index.test.ts",
22
+ "ponder:codegen": "genql --schema ./src/ponder/schema.graphql --output ./src/ponder/generated",
23
+ "fill-orderbook": "bun run scripts/fill-orderbook.ts"
24
+ },
25
+ "dependencies": {
26
+ "@1inch/byte-utils": "3.0.0",
27
+ "ethers": "6.13.5"
28
+ },
29
+ "devDependencies": {
30
+ "@1inch/eslint-config": "3.0.7",
31
+ "@1inch/tsconfig": "^1.0.9",
32
+ "@swc/cli": "0.7.7",
33
+ "@swc/core": "^1.13.3",
34
+ "@swc/jest": "^0.2.39",
35
+ "@types/jest": "^30.0.0",
36
+ "@types/node": "^22.17.0",
37
+ "@typescript-eslint/eslint-plugin": "~8.20.0",
38
+ "@typescript-eslint/parser": "~8.20.0",
39
+ "axios": "^1.12.0",
40
+ "eslint": "^9.32.0",
41
+ "eslint-config-prettier": "~10.1.8",
42
+ "eslint-config-standard": "^17.1.0",
43
+ "eslint-import-resolver-typescript": "3.7.0",
44
+ "eslint-plugin-import": "~2.31.0",
45
+ "eslint-plugin-n": "^17.21.3",
46
+ "eslint-plugin-prettier": "^5.5.4",
47
+ "eslint-plugin-promise": "^7.2.1",
48
+ "eslint-plugin-unused-imports": "^4.1.4",
49
+ "generate-changelog": "1.8.0",
50
+ "jest": "^30.0.5",
51
+ "prettier": "^3.6.2",
52
+ "testcontainers": "^11.5.1",
53
+ "tsdoc-markdown": "^1.4.1",
54
+ "tslib": "2.8.1",
55
+ "typescript": "5.8.3",
56
+ "bun-types": "^1.0.0",
57
+ "@genql/cli": "^3.0.0",
58
+ "viem": "^2.7.0"
59
+ }
60
+ }