@provex/utils 1.0.16 → 1.2.3

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 (122) hide show
  1. package/dist/src/chain.d.ts +436 -4
  2. package/dist/src/chain.js +80 -0
  3. package/dist/src/chain.test.d.ts +1 -0
  4. package/dist/src/chain.test.js +112 -0
  5. package/dist/src/contracts.d.ts +196 -20
  6. package/dist/src/contracts.js +245 -17
  7. package/dist/src/contracts.test.d.ts +1 -0
  8. package/dist/src/contracts.test.js +243 -0
  9. package/dist/src/conversionRates.d.ts +99 -8
  10. package/dist/src/conversionRates.js +74 -4
  11. package/dist/src/conversionRates.test.d.ts +1 -0
  12. package/dist/src/conversionRates.test.js +473 -0
  13. package/dist/src/currencies.d.ts +113 -9
  14. package/dist/src/currencies.js +119 -38
  15. package/dist/src/currencies.test.d.ts +1 -0
  16. package/dist/src/currencies.test.js +343 -0
  17. package/dist/src/data/countries.json +166 -166
  18. package/dist/src/deposit.d.ts +69 -1
  19. package/dist/src/deposit.js +52 -1
  20. package/dist/src/depositKeys.d.ts +154 -0
  21. package/dist/src/depositKeys.js +104 -0
  22. package/dist/src/depositKeys.test.d.ts +1 -0
  23. package/dist/src/depositKeys.test.js +231 -0
  24. package/dist/src/endpoints.d.ts +51 -0
  25. package/dist/src/endpoints.js +70 -0
  26. package/dist/src/endpoints.test.d.ts +1 -0
  27. package/dist/src/endpoints.test.js +54 -0
  28. package/dist/src/events.d.ts +40 -2
  29. package/dist/src/events.js +86 -10
  30. package/dist/src/events.test.d.ts +1 -0
  31. package/dist/src/events.test.js +111 -0
  32. package/dist/src/fees.d.ts +136 -0
  33. package/dist/src/fees.js +178 -0
  34. package/dist/src/fees.test.d.ts +1 -0
  35. package/dist/src/fees.test.js +165 -0
  36. package/dist/src/ids.d.ts +125 -22
  37. package/dist/src/ids.js +211 -61
  38. package/dist/src/ids.test.d.ts +1 -0
  39. package/dist/src/ids.test.js +607 -0
  40. package/dist/src/index.d.ts +30 -1
  41. package/dist/src/index.js +30 -1
  42. package/dist/src/input.d.ts +23 -4
  43. package/dist/src/input.js +23 -4
  44. package/dist/src/intent.d.ts +38 -2
  45. package/dist/src/intent.js +28 -1
  46. package/dist/src/intent.test.d.ts +1 -0
  47. package/dist/src/intent.test.js +119 -0
  48. package/dist/src/json.d.ts +38 -1
  49. package/dist/src/json.js +38 -2
  50. package/dist/src/normalization.d.ts +224 -0
  51. package/dist/src/normalization.js +119 -0
  52. package/dist/src/normalization.test.d.ts +1 -0
  53. package/dist/src/normalization.test.js +284 -0
  54. package/dist/src/participants.d.ts +19 -4
  55. package/dist/src/participants.js +19 -4
  56. package/dist/src/payment.d.ts +333 -16
  57. package/dist/src/payment.js +768 -58
  58. package/dist/src/payment.test.d.ts +1 -0
  59. package/dist/src/payment.test.js +272 -0
  60. package/dist/src/peer-types.d.ts +327 -0
  61. package/dist/src/peer-types.js +169 -0
  62. package/dist/src/profit.d.ts +26 -5
  63. package/dist/src/profit.js +31 -8
  64. package/dist/src/profit.test.d.ts +1 -0
  65. package/dist/src/profit.test.js +315 -0
  66. package/dist/src/reputation.d.ts +125 -0
  67. package/dist/src/reputation.js +188 -0
  68. package/dist/src/reputation.test.d.ts +1 -0
  69. package/dist/src/reputation.test.js +156 -0
  70. package/dist/src/sort.d.ts +49 -10
  71. package/dist/src/sort.js +40 -9
  72. package/dist/src/sort.test.d.ts +1 -0
  73. package/dist/src/sort.test.js +216 -0
  74. package/dist/src/stateKey.d.ts +35 -0
  75. package/dist/src/stateKey.js +36 -0
  76. package/dist/src/stats.d.ts +55 -1
  77. package/dist/src/stats.js +46 -1
  78. package/dist/src/stats.test.d.ts +1 -0
  79. package/dist/src/stats.test.js +104 -0
  80. package/dist/src/time.d.ts +59 -9
  81. package/dist/src/time.js +71 -15
  82. package/dist/src/time.test.d.ts +1 -0
  83. package/dist/src/time.test.js +231 -0
  84. package/dist/src/tokens.d.ts +11972 -145
  85. package/dist/src/tokens.js +98 -17
  86. package/dist/src/tokens.test.d.ts +1 -0
  87. package/dist/src/tokens.test.js +193 -0
  88. package/dist/src/units.d.ts +183 -0
  89. package/dist/src/units.js +206 -6
  90. package/dist/src/units.test.d.ts +1 -0
  91. package/dist/src/units.test.js +327 -0
  92. package/dist/src/zkp2p-types.d.ts +273 -4
  93. package/dist/src/zkp2p-types.js +169 -1
  94. package/dist/tsconfig.tsbuildinfo +1 -1
  95. package/package.json +116 -26
  96. package/scripts/convert-svg.ts +0 -22
  97. package/src/chain.ts +0 -27
  98. package/src/contracts.ts +0 -89
  99. package/src/conversionRates.ts +0 -356
  100. package/src/currencies.ts +0 -286
  101. package/src/data/countries.json +0 -1099
  102. package/src/deposit.ts +0 -2
  103. package/src/events.ts +0 -21
  104. package/src/flags/eur.svg +0 -4
  105. package/src/flags/usd.svg +0 -25
  106. package/src/flags.ts +0 -4
  107. package/src/global.d.ts +0 -9
  108. package/src/ids.ts +0 -137
  109. package/src/index.ts +0 -16
  110. package/src/input.ts +0 -35
  111. package/src/intent.ts +0 -15
  112. package/src/json.ts +0 -42
  113. package/src/participants.ts +0 -14
  114. package/src/payment.ts +0 -573
  115. package/src/profit.ts +0 -55
  116. package/src/sort.ts +0 -49
  117. package/src/stats.ts +0 -10
  118. package/src/time.ts +0 -123
  119. package/src/tokens.ts +0 -159
  120. package/src/units.ts +0 -120
  121. package/src/zkp2p-types.ts +0 -55
  122. package/tsconfig.json +0 -18
package/dist/src/ids.js CHANGED
@@ -1,81 +1,231 @@
1
- import { concatHex, keccak256, numberToHex, stringToHex } from "viem";
1
+ /**
2
+ * @fileoverview ID generation and parsing utilities for the indexer.
3
+ *
4
+ * The indexer uses composite IDs (orderIds) to uniquely identify and order
5
+ * events across multiple chains. Each ID type encodes different information:
6
+ *
7
+ * - **deposit**: [escrow (20)][localId (8)][chainId (4)] = 32 bytes
8
+ * - **block**: [timestamp (8)][chainId (4)] = 12 bytes
9
+ * - **transaction**: [timestamp (8)][txIndex (4)][chainId (4)] = 16 bytes
10
+ * - **log**: [timestamp (8)][txIndex (4)][logIndex (4)][chainId (4)] = 20 bytes
11
+ * - **order**: [timestamp (8)][txIndex (4)][eventType (1)][logIndex (4)][chainId (4)] = 21 bytes
12
+ * - **stat**: [timestamp (8)][hash (20)][chainId (4)] = 32 bytes
13
+ *
14
+ * @remarks
15
+ * The orderId structure ensures:
16
+ * - Global ordering across chains by timestamp
17
+ * - Deterministic ordering within same block
18
+ * - Parseability to extract original components
19
+ *
20
+ * @see {@link events} for event type definitions
21
+ * @see {@link depositKeys} for deposit compound keys
22
+ */
23
+ import { concatHex, keccak256, numberToHex, stringToHex, isHex } from "viem";
2
24
  import { eventOrderId } from "./events.js";
3
25
  import { interval } from "./time.js";
26
+ import { chainIds } from "./chain.js";
27
+ /**
28
+ * Generate a chain-specific hash by combining chainId and an existing hash.
29
+ * Creates a unique identifier that includes chain context.
30
+ */
4
31
  export const onChainHash = ({ chainId, hash }) => (keccak256(concatHex([
5
32
  numberToHex(chainId, { size: 8 }),
6
33
  hash,
7
34
  ])));
8
35
  export const onChainAddress = ({ chainId, address }) => (onChainHash({ chainId, hash: address }));
36
+ /**
37
+ * ID generator functions for various entity types.
38
+ * Each function creates a unique, deterministic identifier.
39
+ */
9
40
  export const ids = {
41
+ /** Block ID: keccak256(chainId || blockHash) */
10
42
  block: onChainHash,
43
+ /** Transaction ID: keccak256(chainId || txHash) */
11
44
  transaction: onChainHash,
12
- participant: onChainAddress,
45
+ /** Provider hash ID: keccak256(chainId || providerHash) */
13
46
  providerHash: onChainHash,
47
+ /** Verifier ID: keccak256(chainId || verifierAddress) */
14
48
  verifier: onChainAddress,
15
- depositVerifierAdded: ({ depositId, verifier }) => {
16
- return keccak256(concatHex([depositId, verifier]));
17
- },
18
- depositCurrencyAdded: ({ depositId, currency, verifier }) => {
19
- return keccak256(concatHex([
20
- ids.depositVerifierAdded({ verifier, depositId }),
21
- currency,
22
- ]));
23
- },
24
- depositConversionRateUpdated: ({ currency, verifier, depositId, changeId }) => {
25
- return concatHex([
26
- ids.depositCurrencyAdded({ currency, verifier, depositId }),
27
- numberToHex(changeId, { size: 4 }),
28
- ]);
29
- },
30
49
  };
31
50
  const hourFactor = BigInt(interval.hour) / BigInt(interval.second);
32
51
  const dayFactor = BigInt(interval.day) / BigInt(interval.second);
33
52
  const monthFactor = BigInt(interval.month) / BigInt(interval.second);
53
+ /**
54
+ * Chunk a hex string into parts of specified byte sizes
55
+ * @param input - The hex string to chunk (with 0x prefix)
56
+ * @param byteSizes - Array of byte sizes for each chunk
57
+ * @returns Array of hex strings, one for each chunk
58
+ */
59
+ export function chunkHex(input, byteSizes) {
60
+ const expectedBytes = byteSizes.reduce((a, b) => a + b, 0);
61
+ if (!isHex(input, { strict: true })) {
62
+ throw new Error(`Invalid hex input: ${input}`);
63
+ }
64
+ const hex = input.slice(2).toLowerCase();
65
+ const expectedHexLen = expectedBytes * 2;
66
+ if (hex.length !== expectedHexLen) {
67
+ throw new Error(`Hex length ${hex.length / 2} bytes does not match expected ${expectedHexLen / 2} bytes`);
68
+ }
69
+ const out = [];
70
+ let offset = 0;
71
+ for (const size of byteSizes) {
72
+ const chars = size * 2;
73
+ const part = "0x" + hex.slice(offset, offset + chars);
74
+ out.push(part);
75
+ offset += chars;
76
+ }
77
+ return out;
78
+ }
79
+ /**
80
+ * Type guard to check if a number is a valid ChainId
81
+ */
82
+ function isChainId(value) {
83
+ return chainIds.includes(value);
84
+ }
85
+ /**
86
+ * OrderId serialization and parsing utilities.
87
+ *
88
+ * Each orderId type has a `serialize` method to create the ID from components,
89
+ * and a `parse` method to extract components from an existing ID.
90
+ *
91
+ * @example
92
+ * ```ts
93
+ * // Create a deposit orderId
94
+ * const id = orderId.deposit.serialize({ chainId: 8453n, escrow, depositId: 42n })
95
+ *
96
+ * // Parse it back
97
+ * const { chainId, escrow, depositId } = orderId.deposit.parse(id)
98
+ * ```
99
+ */
34
100
  export const orderId = {
35
- deposit: ({ chainId, depositId }) => concatHex([
36
- numberToHex(depositId, { size: 8 }),
37
- numberToHex(chainId, { size: 4 }),
38
- ]),
39
- block: ({ timestamp, chainId }) => concatHex([
40
- numberToHex(timestamp, { size: 8 }),
41
- numberToHex(chainId, { size: 4 }),
42
- ]),
43
- transaction: ({ timestamp, chainId, transactionIndex }) => concatHex([
44
- numberToHex(timestamp, { size: 8 }),
45
- numberToHex(transactionIndex, { size: 4 }),
46
- numberToHex(chainId, { size: 4 }),
47
- ]),
48
- log: ({ timestamp, chainId, transactionIndex, logIndex }) => concatHex([
49
- numberToHex(timestamp, { size: 8 }),
50
- numberToHex(transactionIndex, { size: 4 }),
51
- numberToHex(logIndex, { size: 4 }),
52
- numberToHex(chainId, { size: 4 }),
53
- ]),
54
- order: ({ timestamp, chainId, transactionIndex, logIndex, name }) => concatHex([
55
- numberToHex(timestamp, { size: 8 }),
56
- numberToHex(transactionIndex, { size: 4 }),
57
- numberToHex(eventOrderId.get(name), { size: 1 }),
58
- numberToHex(logIndex, { size: 4 }),
59
- numberToHex(chainId, { size: 4 }),
60
- ]),
61
- stat: ({ timestamp, type, action, currency, verifier, token, chainId }) => {
62
- const hour = (timestamp / hourFactor) * hourFactor;
63
- const day = (timestamp / dayFactor) * dayFactor;
64
- const month = (timestamp / monthFactor) * monthFactor;
65
- let time = timestamp;
66
- if (type === "hour") {
67
- time = hour;
68
- }
69
- if (type === "day") {
70
- time = day;
71
- }
72
- if (type === "month") {
73
- time = month;
74
- }
75
- return concatHex([
76
- numberToHex(time, { size: 8 }),
77
- `0x${keccak256(concatHex([stringToHex(type), stringToHex(action), token, currency ?? '0x', verifier])).slice(26)}`,
101
+ /**
102
+ * Deposit orderId: uniquely identifies a deposit across all chains and escrows.
103
+ * Format: [escrow (20)][localId (8)][chainId (4)] = 32 bytes
104
+ */
105
+ deposit: {
106
+ serialize: ({ chainId, escrow, depositId }) => concatHex([
107
+ escrow,
108
+ numberToHex(depositId, { size: 8 }),
109
+ numberToHex(chainId, { size: 4 }),
110
+ ]),
111
+ parse: (id) => {
112
+ const [escrow, depositIdHex, chainIdHex] = chunkHex(id, [20, 8, 4]);
113
+ const depositId = BigInt(depositIdHex);
114
+ const chainIdNum = Number(BigInt(chainIdHex));
115
+ if (!isChainId(chainIdNum)) {
116
+ throw new Error(`Unknown chainId parsed from deposit id: ${chainIdNum}`);
117
+ }
118
+ return { escrow, depositId, chainId: chainIdNum };
119
+ },
120
+ },
121
+ block: {
122
+ serialize: ({ timestamp, chainId }) => concatHex([
123
+ numberToHex(timestamp, { size: 8 }),
124
+ numberToHex(chainId, { size: 4 }),
125
+ ]),
126
+ parse: (id) => {
127
+ const [timestampHex, chainIdHex] = chunkHex(id, [8, 4]);
128
+ const timestamp = BigInt(timestampHex);
129
+ const chainIdNum = Number(BigInt(chainIdHex));
130
+ if (!isChainId(chainIdNum)) {
131
+ throw new Error(`Unknown chainId parsed from block id: ${chainIdNum}`);
132
+ }
133
+ return { timestamp, chainId: chainIdNum };
134
+ },
135
+ },
136
+ transaction: {
137
+ serialize: ({ timestamp, chainId, transactionIndex }) => concatHex([
138
+ numberToHex(timestamp, { size: 8 }),
139
+ numberToHex(transactionIndex, { size: 4 }),
140
+ numberToHex(chainId, { size: 4 }),
141
+ ]),
142
+ parse: (id) => {
143
+ const [timestampHex, txIndexHex, chainIdHex] = chunkHex(id, [8, 4, 4]);
144
+ const timestamp = BigInt(timestampHex);
145
+ const transactionIndex = Number(BigInt(txIndexHex));
146
+ const chainIdNum = Number(BigInt(chainIdHex));
147
+ if (!isChainId(chainIdNum)) {
148
+ throw new Error(`Unknown chainId parsed from transaction id: ${chainIdNum}`);
149
+ }
150
+ return { timestamp, transactionIndex, chainId: chainIdNum };
151
+ },
152
+ },
153
+ log: {
154
+ serialize: ({ timestamp, chainId, transactionIndex, logIndex }) => concatHex([
155
+ numberToHex(timestamp, { size: 8 }),
156
+ numberToHex(transactionIndex, { size: 4 }),
157
+ numberToHex(logIndex, { size: 4 }),
78
158
  numberToHex(chainId, { size: 4 }),
79
- ]);
159
+ ]),
160
+ parse: (id) => {
161
+ const [timestampHex, txIndexHex, logIndexHex, chainIdHex] = chunkHex(id, [8, 4, 4, 4]);
162
+ const timestamp = BigInt(timestampHex);
163
+ const transactionIndex = Number(BigInt(txIndexHex));
164
+ const logIndex = Number(BigInt(logIndexHex));
165
+ const chainIdNum = Number(BigInt(chainIdHex));
166
+ if (!isChainId(chainIdNum)) {
167
+ throw new Error(`Unknown chainId parsed from log id: ${chainIdNum}`);
168
+ }
169
+ return { timestamp, transactionIndex, logIndex, chainId: chainIdNum };
170
+ },
171
+ },
172
+ order: {
173
+ serialize: ({ timestamp, chainId, transactionIndex, logIndex, name }) => concatHex([
174
+ numberToHex(timestamp, { size: 8 }),
175
+ numberToHex(transactionIndex, { size: 4 }),
176
+ numberToHex(eventOrderId.get(name), { size: 1 }),
177
+ numberToHex(logIndex, { size: 4 }),
178
+ numberToHex(chainId, { size: 4 }),
179
+ ]),
180
+ parse: (id) => {
181
+ const [timestampHex, txIndexHex, typeHex, logIndexHex, chainIdHex] = chunkHex(id, [8, 4, 1, 4, 4]);
182
+ const timestamp = BigInt(timestampHex);
183
+ const transactionIndex = Number(BigInt(txIndexHex));
184
+ const eventTypeId = Number(BigInt(typeHex));
185
+ const logIndex = Number(BigInt(logIndexHex));
186
+ const chainIdNum = Number(BigInt(chainIdHex));
187
+ if (!isChainId(chainIdNum)) {
188
+ throw new Error(`Unknown chainId parsed from order id: ${chainIdNum}`);
189
+ }
190
+ const typeEntries = Array.from(eventOrderId.entries());
191
+ const name = typeEntries.find(([, v]) => v === eventTypeId)?.[0];
192
+ return { timestamp, transactionIndex, eventTypeId, name, logIndex, chainId: chainIdNum };
193
+ },
194
+ },
195
+ stat: {
196
+ serialize: ({ timestamp, type, event, currency, verifier, token, chainId, version }) => {
197
+ const hour = (timestamp / hourFactor) * hourFactor;
198
+ const day = (timestamp / dayFactor) * dayFactor;
199
+ const month = (timestamp / monthFactor) * monthFactor;
200
+ let time = timestamp;
201
+ if (type === "hour") {
202
+ time = hour;
203
+ }
204
+ if (type === "day") {
205
+ time = day;
206
+ }
207
+ if (type === "month") {
208
+ time = month;
209
+ }
210
+ return concatHex([
211
+ numberToHex(time, { size: 8 }),
212
+ `0x${keccak256(concatHex([stringToHex(type), stringToHex(event), token, currency ?? '0x', verifier, stringToHex(version)])).slice(26)}`,
213
+ numberToHex(chainId, { size: 4 }),
214
+ ]);
215
+ },
216
+ /**
217
+ * Parse a stat orderId to extract timestamp and chainId.
218
+ * Note: The hash component cannot be reversed to get type/event/currency/verifier/token.
219
+ * Format: [timestamp (8)][hash (20)][chainId (4)] = 32 bytes
220
+ */
221
+ parse: (id) => {
222
+ const [timestampHex, , chainIdHex] = chunkHex(id, [8, 20, 4]);
223
+ const timestamp = BigInt(timestampHex);
224
+ const chainIdNum = Number(BigInt(chainIdHex));
225
+ if (!isChainId(chainIdNum)) {
226
+ throw new Error(`Unknown chainId parsed from stat id: ${chainIdNum}`);
227
+ }
228
+ return { timestamp, chainId: chainIdNum };
229
+ },
80
230
  },
81
231
  };
@@ -0,0 +1 @@
1
+ export {};