@provex/utils 1.0.16 → 1.2.4

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 (149) hide show
  1. package/dist/chain.d.ts +446 -0
  2. package/dist/chain.js +98 -0
  3. package/dist/chain.test.js +112 -0
  4. package/dist/contracts.d.ts +206 -0
  5. package/dist/contracts.js +292 -0
  6. package/dist/contracts.test.js +243 -0
  7. package/dist/conversionRates.d.ts +215 -0
  8. package/dist/{src/conversionRates.js → conversionRates.js} +74 -4
  9. package/dist/conversionRates.test.js +473 -0
  10. package/dist/currencies.d.ts +248 -0
  11. package/dist/{src/currencies.js → currencies.js} +119 -38
  12. package/dist/currencies.test.js +343 -0
  13. package/dist/data/countries.json +1099 -0
  14. package/dist/deposit.d.ts +69 -0
  15. package/dist/deposit.js +52 -0
  16. package/dist/depositKeys.d.ts +154 -0
  17. package/dist/depositKeys.js +104 -0
  18. package/dist/depositKeys.test.d.ts +1 -0
  19. package/dist/depositKeys.test.js +231 -0
  20. package/dist/events.d.ts +41 -0
  21. package/dist/events.js +92 -0
  22. package/dist/events.test.d.ts +1 -0
  23. package/dist/events.test.js +111 -0
  24. package/dist/fees.d.ts +136 -0
  25. package/dist/fees.js +178 -0
  26. package/dist/fees.test.d.ts +1 -0
  27. package/dist/fees.test.js +165 -0
  28. package/dist/ids.d.ts +175 -0
  29. package/dist/ids.js +231 -0
  30. package/dist/ids.test.d.ts +1 -0
  31. package/dist/ids.test.js +607 -0
  32. package/dist/index.d.ts +45 -0
  33. package/dist/index.js +45 -0
  34. package/dist/input.d.ts +26 -0
  35. package/dist/{src/input.js → input.js} +23 -4
  36. package/dist/intent.d.ts +50 -0
  37. package/dist/intent.js +28 -0
  38. package/dist/intent.test.d.ts +1 -0
  39. package/dist/intent.test.js +119 -0
  40. package/dist/json.d.ts +55 -0
  41. package/dist/json.js +80 -0
  42. package/dist/participants.d.ts +22 -0
  43. package/dist/participants.js +28 -0
  44. package/dist/payment.d.ts +481 -0
  45. package/dist/payment.js +1149 -0
  46. package/dist/payment.test.d.ts +1 -0
  47. package/dist/payment.test.js +272 -0
  48. package/dist/peer-types.d.ts +327 -0
  49. package/dist/peer-types.js +169 -0
  50. package/dist/profit.d.ts +49 -0
  51. package/dist/profit.js +57 -0
  52. package/dist/profit.test.d.ts +1 -0
  53. package/dist/profit.test.js +315 -0
  54. package/dist/reputation.d.ts +125 -0
  55. package/dist/reputation.js +188 -0
  56. package/dist/reputation.test.d.ts +1 -0
  57. package/dist/reputation.test.js +156 -0
  58. package/dist/sort.d.ts +75 -0
  59. package/dist/sort.js +70 -0
  60. package/dist/sort.test.d.ts +1 -0
  61. package/dist/sort.test.js +216 -0
  62. package/dist/stateKey.d.ts +35 -0
  63. package/dist/stateKey.js +36 -0
  64. package/dist/stats.d.ts +61 -0
  65. package/dist/stats.js +53 -0
  66. package/dist/stats.test.d.ts +1 -0
  67. package/dist/stats.test.js +104 -0
  68. package/dist/time.d.ts +104 -0
  69. package/dist/time.js +162 -0
  70. package/dist/time.test.d.ts +1 -0
  71. package/dist/time.test.js +231 -0
  72. package/dist/tokens.d.ts +15502 -0
  73. package/dist/{src/tokens.js → tokens.js} +98 -17
  74. package/dist/tokens.test.d.ts +1 -0
  75. package/dist/tokens.test.js +193 -0
  76. package/dist/units.d.ts +200 -0
  77. package/dist/units.js +279 -0
  78. package/dist/units.test.d.ts +1 -0
  79. package/dist/units.test.js +327 -0
  80. package/package.json +119 -29
  81. package/dist/scripts/convert-svg.js +0 -17
  82. package/dist/src/chain.d.ts +0 -14
  83. package/dist/src/chain.js +0 -18
  84. package/dist/src/contracts.d.ts +0 -30
  85. package/dist/src/contracts.js +0 -64
  86. package/dist/src/conversionRates.d.ts +0 -124
  87. package/dist/src/currencies.d.ts +0 -144
  88. package/dist/src/data/countries.json +0 -1099
  89. package/dist/src/deposit.d.ts +0 -1
  90. package/dist/src/events.d.ts +0 -3
  91. package/dist/src/events.js +0 -16
  92. package/dist/src/ids.d.ts +0 -72
  93. package/dist/src/ids.js +0 -81
  94. package/dist/src/index.d.ts +0 -16
  95. package/dist/src/index.js +0 -16
  96. package/dist/src/input.d.ts +0 -7
  97. package/dist/src/intent.d.ts +0 -14
  98. package/dist/src/json.d.ts +0 -18
  99. package/dist/src/json.js +0 -44
  100. package/dist/src/participants.d.ts +0 -7
  101. package/dist/src/participants.js +0 -13
  102. package/dist/src/payment.d.ts +0 -164
  103. package/dist/src/payment.js +0 -439
  104. package/dist/src/profit.d.ts +0 -28
  105. package/dist/src/profit.js +0 -34
  106. package/dist/src/sort.d.ts +0 -36
  107. package/dist/src/sort.js +0 -39
  108. package/dist/src/stats.d.ts +0 -7
  109. package/dist/src/stats.js +0 -8
  110. package/dist/src/time.d.ts +0 -54
  111. package/dist/src/time.js +0 -106
  112. package/dist/src/tokens.d.ts +0 -3675
  113. package/dist/src/units.d.ts +0 -17
  114. package/dist/src/units.js +0 -79
  115. package/dist/src/zkp2p-types.d.ts +0 -48
  116. package/dist/tsconfig.tsbuildinfo +0 -1
  117. package/scripts/convert-svg.ts +0 -22
  118. package/src/chain.ts +0 -27
  119. package/src/contracts.ts +0 -89
  120. package/src/conversionRates.ts +0 -356
  121. package/src/currencies.ts +0 -286
  122. package/src/data/countries.json +0 -1099
  123. package/src/deposit.ts +0 -2
  124. package/src/events.ts +0 -21
  125. package/src/flags/eur.svg +0 -4
  126. package/src/flags/usd.svg +0 -25
  127. package/src/flags.ts +0 -4
  128. package/src/global.d.ts +0 -9
  129. package/src/ids.ts +0 -137
  130. package/src/index.ts +0 -16
  131. package/src/input.ts +0 -35
  132. package/src/intent.ts +0 -15
  133. package/src/json.ts +0 -42
  134. package/src/participants.ts +0 -14
  135. package/src/payment.ts +0 -573
  136. package/src/profit.ts +0 -55
  137. package/src/sort.ts +0 -49
  138. package/src/stats.ts +0 -10
  139. package/src/time.ts +0 -123
  140. package/src/tokens.ts +0 -159
  141. package/src/units.ts +0 -120
  142. package/src/zkp2p-types.ts +0 -55
  143. package/tsconfig.json +0 -18
  144. /package/dist/{scripts/convert-svg.d.ts → chain.test.d.ts} +0 -0
  145. /package/dist/{src/deposit.js → contracts.test.d.ts} +0 -0
  146. /package/dist/{src/intent.js → conversionRates.test.d.ts} +0 -0
  147. /package/dist/{src/zkp2p-types.js → currencies.test.d.ts} +0 -0
  148. /package/dist/{src/flags.d.ts → flags.d.ts} +0 -0
  149. /package/dist/{src/flags.js → flags.js} +0 -0
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @fileoverview Input manipulation utilities for numeric string handling.
3
+ *
4
+ * Provides utilities for incrementing/decrementing decimal values while
5
+ * preserving the user's intended precision (trailing zeros).
6
+ */
7
+ /**
8
+ * Adjust the lowest decimal place of a numeric string by +1 or -1.
9
+ * Preserves the original decimal precision (trailing zeros are maintained).
10
+ *
11
+ * Used for numeric input controls with up/down buttons that increment
12
+ * at the current decimal precision level.
13
+ *
14
+ * @param inputVal - The input value as a string (e.g., "1.50", "100", "0.001")
15
+ * @param direction - Direction to adjust: 1 (increment) or -1 (decrement)
16
+ * @returns The adjusted value with original precision preserved
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * adjustLowestDecimal("1.50", 1) // "1.51"
21
+ * adjustLowestDecimal("1.50", -1) // "1.49"
22
+ * adjustLowestDecimal("100", 1) // "101"
23
+ * adjustLowestDecimal("0.001", 1) // "0.002"
24
+ * ```
25
+ */
26
+ export declare const adjustLowestDecimal: (inputVal: string, direction: 1 | -1) => string;
@@ -1,8 +1,27 @@
1
1
  /**
2
- * Adjust the lowest decimal place directly on the string, preserving all trailing zeros
3
- * @param inputVal - The input value
4
- * @param direction - The direction to adjust the decimal place
5
- * @returns The adjusted value
2
+ * @fileoverview Input manipulation utilities for numeric string handling.
3
+ *
4
+ * Provides utilities for incrementing/decrementing decimal values while
5
+ * preserving the user's intended precision (trailing zeros).
6
+ */
7
+ /**
8
+ * Adjust the lowest decimal place of a numeric string by +1 or -1.
9
+ * Preserves the original decimal precision (trailing zeros are maintained).
10
+ *
11
+ * Used for numeric input controls with up/down buttons that increment
12
+ * at the current decimal precision level.
13
+ *
14
+ * @param inputVal - The input value as a string (e.g., "1.50", "100", "0.001")
15
+ * @param direction - Direction to adjust: 1 (increment) or -1 (decrement)
16
+ * @returns The adjusted value with original precision preserved
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * adjustLowestDecimal("1.50", 1) // "1.51"
21
+ * adjustLowestDecimal("1.50", -1) // "1.49"
22
+ * adjustLowestDecimal("100", 1) // "101"
23
+ * adjustLowestDecimal("0.001", 1) // "0.002"
24
+ * ```
6
25
  */
7
26
  export const adjustLowestDecimal = (inputVal, direction) => {
8
27
  let [whole, decimal = ''] = inputVal.split('.');
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @fileoverview Intent data structures and validation utilities.
3
+ *
4
+ * An intent represents a buyer's commitment to purchase tokens from a deposit
5
+ * at a specific price. The intent lifecycle:
6
+ *
7
+ * 1. **Signal**: Buyer calls signalIntent() on Orchestrator, funds are soft-locked
8
+ * 2. **Lock**: For V3, explicit lock period with expiry time
9
+ * 3. **Verify**: Buyer proves off-chain payment via zkTLS attestation
10
+ * 4. **Fulfill**: Verifier releases escrowed funds to buyer
11
+ *
12
+ * @remarks
13
+ * V2 and V3 intents have different field structures:
14
+ * - V2: Uses paymentVerifier (address) to identify payment method
15
+ * - V3: Uses paymentMethod (bytes32 hash) and includes escrow address
16
+ *
17
+ * @see {@link peer-types} for attestation types
18
+ * @see {@link payment} for payment method definitions
19
+ */
20
+ import type { Hex } from "viem";
21
+ /**
22
+ * Structure representing an on-chain intent.
23
+ *
24
+ * V2 intents use `paymentVerifier` (address, 20 bytes).
25
+ * V3 intents use `paymentMethod` (bytes32, 32 bytes) and include `escrow`.
26
+ *
27
+ * When working with this interface:
28
+ * - Check `paymentMethod` first (V3), fall back to `paymentVerifier` (V2)
29
+ * - Use `escrow` only when available (V3)
30
+ */
31
+ export interface IntentStruct {
32
+ owner: Hex;
33
+ to: Hex;
34
+ depositId: bigint;
35
+ amount: bigint;
36
+ timestamp: bigint;
37
+ fiatCurrency: Hex;
38
+ conversionRate: bigint;
39
+ /** V2 only: Payment verifier contract address (20 bytes) */
40
+ paymentVerifier?: Hex;
41
+ /** V3 only: Payment method ID hash (32 bytes) */
42
+ paymentMethod?: Hex;
43
+ /** V3 only: Escrow contract address */
44
+ escrow?: Hex;
45
+ }
46
+ /**
47
+ * Check if an intent is empty (not found on-chain).
48
+ * V3 Orchestrator returns zero-filled struct when intent doesn't exist.
49
+ */
50
+ export declare function isEmptyIntent(intent: IntentStruct | null): boolean;
package/dist/intent.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @fileoverview Intent data structures and validation utilities.
3
+ *
4
+ * An intent represents a buyer's commitment to purchase tokens from a deposit
5
+ * at a specific price. The intent lifecycle:
6
+ *
7
+ * 1. **Signal**: Buyer calls signalIntent() on Orchestrator, funds are soft-locked
8
+ * 2. **Lock**: For V3, explicit lock period with expiry time
9
+ * 3. **Verify**: Buyer proves off-chain payment via zkTLS attestation
10
+ * 4. **Fulfill**: Verifier releases escrowed funds to buyer
11
+ *
12
+ * @remarks
13
+ * V2 and V3 intents have different field structures:
14
+ * - V2: Uses paymentVerifier (address) to identify payment method
15
+ * - V3: Uses paymentMethod (bytes32 hash) and includes escrow address
16
+ *
17
+ * @see {@link peer-types} for attestation types
18
+ * @see {@link payment} for payment method definitions
19
+ */
20
+ /**
21
+ * Check if an intent is empty (not found on-chain).
22
+ * V3 Orchestrator returns zero-filled struct when intent doesn't exist.
23
+ */
24
+ export function isEmptyIntent(intent) {
25
+ if (!intent)
26
+ return true;
27
+ return intent.amount === 0n && intent.timestamp === 0n && intent.depositId === 0n;
28
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,119 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { isEmptyIntent } from './intent.js';
4
+ import { zeroAddress } from 'viem';
5
+ /**
6
+ * Tests for IntentStruct and isEmptyIntent utility
7
+ *
8
+ * V2 intents use paymentVerifier (address, 20 bytes)
9
+ * V3 intents use paymentMethod (bytes32, 32 bytes) and include escrow
10
+ */
11
+ // Sample V3 intent (all fields populated)
12
+ const mockV3Intent = {
13
+ owner: '0x1234567890123456789012345678901234567890',
14
+ to: '0xabcdefabcdefabcdefabcdefabcdefabcdefabcd',
15
+ escrow: '0x2f121CDDCA6d652f35e8B3E560f9760898888888',
16
+ depositId: 42n,
17
+ amount: 100000000n, // 100 USDC
18
+ timestamp: 1737123456n,
19
+ paymentMethod: '0x1234567890123456789012345678901234567890123456789012345678901234',
20
+ fiatCurrency: '0x0000000000000000000000000000000000000000000000000000000000555344', // USD
21
+ conversionRate: 1000000000000000000n, // 1.0
22
+ };
23
+ // Sample V2 intent (no escrow, uses paymentVerifier)
24
+ const mockV2Intent = {
25
+ owner: '0x1234567890123456789012345678901234567890',
26
+ to: '0xabcdefabcdefabcdefabcdefabcdefabcdefabcd',
27
+ depositId: 42n,
28
+ amount: 100000000n,
29
+ timestamp: 1737123456n,
30
+ paymentVerifier: '0x9a733B55a875D0DB4915c6B36350b24F8AB99dF5', // venmo verifier
31
+ fiatCurrency: '0x0000000000000000000000000000000000000000000000000000000000555344',
32
+ conversionRate: 1000000000000000000n,
33
+ };
34
+ // Empty intent (what V3 Orchestrator returns when intent not found)
35
+ const emptyIntent = {
36
+ owner: zeroAddress,
37
+ to: zeroAddress,
38
+ escrow: zeroAddress,
39
+ depositId: 0n,
40
+ amount: 0n,
41
+ timestamp: 0n,
42
+ paymentMethod: '0x0000000000000000000000000000000000000000000000000000000000000000',
43
+ fiatCurrency: '0x0000000000000000000000000000000000000000000000000000000000000000',
44
+ conversionRate: 0n,
45
+ };
46
+ describe('IntentStruct type', () => {
47
+ describe('V3 intent structure', () => {
48
+ it('has escrow field for V3', () => {
49
+ assert.ok(mockV3Intent.escrow !== undefined, 'escrow should be defined');
50
+ assert.equal(mockV3Intent.escrow, '0x2f121CDDCA6d652f35e8B3E560f9760898888888');
51
+ });
52
+ it('has paymentMethod field (bytes32) for V3', () => {
53
+ assert.ok(mockV3Intent.paymentMethod !== undefined, 'paymentMethod should be defined');
54
+ assert.equal(mockV3Intent.paymentMethod?.length, 66, '0x + 64 hex chars');
55
+ });
56
+ it('does not require paymentVerifier for V3', () => {
57
+ assert.equal(mockV3Intent.paymentVerifier, undefined);
58
+ });
59
+ });
60
+ describe('V2 intent structure', () => {
61
+ it('has paymentVerifier field (address) for V2', () => {
62
+ assert.ok(mockV2Intent.paymentVerifier !== undefined, 'paymentVerifier should be defined');
63
+ assert.equal(mockV2Intent.paymentVerifier?.length, 42, '0x + 40 hex chars');
64
+ });
65
+ it('does not require escrow for V2', () => {
66
+ assert.equal(mockV2Intent.escrow, undefined);
67
+ });
68
+ it('does not require paymentMethod for V2', () => {
69
+ assert.equal(mockV2Intent.paymentMethod, undefined);
70
+ });
71
+ });
72
+ describe('backwards compatibility', () => {
73
+ it('common fields are present in both V2 and V3', () => {
74
+ const commonFields = ['owner', 'to', 'depositId', 'amount', 'timestamp', 'fiatCurrency', 'conversionRate'];
75
+ for (const field of commonFields) {
76
+ assert.ok(field in mockV3Intent, `V3 intent should have ${field}`);
77
+ assert.ok(field in mockV2Intent, `V2 intent should have ${field}`);
78
+ }
79
+ });
80
+ });
81
+ });
82
+ describe('isEmptyIntent', () => {
83
+ it('returns true for null', () => {
84
+ assert.equal(isEmptyIntent(null), true);
85
+ });
86
+ it('returns true for empty intent (all zeros)', () => {
87
+ assert.equal(isEmptyIntent(emptyIntent), true);
88
+ });
89
+ it('returns false when only amount is 0 (other fields non-zero)', () => {
90
+ const intentWithZeroAmount = { ...mockV3Intent, amount: 0n };
91
+ assert.equal(isEmptyIntent(intentWithZeroAmount), false);
92
+ });
93
+ it('returns false when only timestamp is 0 (other fields non-zero)', () => {
94
+ const intentWithZeroTimestamp = { ...mockV3Intent, timestamp: 0n };
95
+ assert.equal(isEmptyIntent(intentWithZeroTimestamp), false);
96
+ });
97
+ it('returns false when only depositId is 0 (other fields non-zero)', () => {
98
+ const intentWithZeroDepositId = { ...mockV3Intent, depositId: 0n };
99
+ assert.equal(isEmptyIntent(intentWithZeroDepositId), false);
100
+ });
101
+ it('returns false for valid V3 intent', () => {
102
+ assert.equal(isEmptyIntent(mockV3Intent), false);
103
+ });
104
+ it('returns false for valid V2 intent', () => {
105
+ assert.equal(isEmptyIntent(mockV2Intent), false);
106
+ });
107
+ });
108
+ describe('payment identifier handling', () => {
109
+ it('can extract payment identifier from V3 intent', () => {
110
+ const paymentIdentifier = mockV3Intent.paymentMethod ?? mockV3Intent.paymentVerifier ?? '0x';
111
+ assert.equal(paymentIdentifier, mockV3Intent.paymentMethod);
112
+ assert.equal(paymentIdentifier.length, 66, 'bytes32');
113
+ });
114
+ it('can extract payment identifier from V2 intent', () => {
115
+ const paymentIdentifier = mockV2Intent.paymentMethod ?? mockV2Intent.paymentVerifier ?? '0x';
116
+ assert.equal(paymentIdentifier, mockV2Intent.paymentVerifier);
117
+ assert.equal(paymentIdentifier.length, 42, 'address');
118
+ });
119
+ });
package/dist/json.d.ts ADDED
@@ -0,0 +1,55 @@
1
+ /**
2
+ * @fileoverview JSON utilities for handling bigint serialization.
3
+ *
4
+ * Standard JSON.stringify cannot handle bigint values. This module provides
5
+ * a serializer that converts bigints to strings, and utilities for
6
+ * converting string fields back to bigints after parsing.
7
+ */
8
+ /**
9
+ * JSON serializer with bigint support.
10
+ * Converts bigints to strings during stringify, allowing JSON.parse to read them later.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const obj = { amount: 100_000000n, name: 'test' }
15
+ * const json = jsonSerializer.stringify(obj)
16
+ * // '{"amount":"100000000","name":"test"}'
17
+ *
18
+ * const parsed = jsonSerializer.parse(json)
19
+ * // { amount: "100000000", name: "test" } (amount is still a string!)
20
+ *
21
+ * // Use mapBigIntFields to convert back to bigint
22
+ * const restored = mapBigIntFields(parsed, ['amount'])
23
+ * // { amount: 100000000n, name: 'test' }
24
+ * ```
25
+ */
26
+ export declare const jsonSerializer: {
27
+ /**
28
+ * Parse a JSON string
29
+ * @param str - The JSON string to parse
30
+ * @returns The parsed object
31
+ */
32
+ parse: (text: string, reviver?: (this: any, key: string, value: any) => any) => any;
33
+ /**
34
+ * Stringify an object
35
+ * @param obj - The object to stringify
36
+ * @returns The stringified object
37
+ */
38
+ stringify: (obj: unknown) => string;
39
+ };
40
+ /**
41
+ * Recursively convert specified string fields to BigInt in an object or array.
42
+ * Used after JSON.parse to restore bigint values that were serialized as strings.
43
+ *
44
+ * @param obj - The object or array to process
45
+ * @param fields - Array of field names that should be converted to BigInt
46
+ * @returns The object with specified fields converted to BigInt
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * const data = { amount: "100", nested: { value: "50" }, name: "test" }
51
+ * const result = mapBigIntFields(data, ['amount', 'value'])
52
+ * // { amount: 100n, nested: { value: 50n }, name: "test" }
53
+ * ```
54
+ */
55
+ export declare function mapBigIntFields<T>(obj: T, fields: string[]): T;
package/dist/json.js ADDED
@@ -0,0 +1,80 @@
1
+ /**
2
+ * @fileoverview JSON utilities for handling bigint serialization.
3
+ *
4
+ * Standard JSON.stringify cannot handle bigint values. This module provides
5
+ * a serializer that converts bigints to strings, and utilities for
6
+ * converting string fields back to bigints after parsing.
7
+ */
8
+ /**
9
+ * JSON serializer with bigint support.
10
+ * Converts bigints to strings during stringify, allowing JSON.parse to read them later.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const obj = { amount: 100_000000n, name: 'test' }
15
+ * const json = jsonSerializer.stringify(obj)
16
+ * // '{"amount":"100000000","name":"test"}'
17
+ *
18
+ * const parsed = jsonSerializer.parse(json)
19
+ * // { amount: "100000000", name: "test" } (amount is still a string!)
20
+ *
21
+ * // Use mapBigIntFields to convert back to bigint
22
+ * const restored = mapBigIntFields(parsed, ['amount'])
23
+ * // { amount: 100000000n, name: 'test' }
24
+ * ```
25
+ */
26
+ export const jsonSerializer = {
27
+ /**
28
+ * Parse a JSON string
29
+ * @param str - The JSON string to parse
30
+ * @returns The parsed object
31
+ */
32
+ parse: JSON.parse,
33
+ /**
34
+ * Stringify an object
35
+ * @param obj - The object to stringify
36
+ * @returns The stringified object
37
+ */
38
+ stringify: (obj) => JSON.stringify(obj, (_key, value) => {
39
+ if (typeof value === 'bigint') {
40
+ return value.toString();
41
+ }
42
+ return value;
43
+ })
44
+ };
45
+ /**
46
+ * Recursively convert specified string fields to BigInt in an object or array.
47
+ * Used after JSON.parse to restore bigint values that were serialized as strings.
48
+ *
49
+ * @param obj - The object or array to process
50
+ * @param fields - Array of field names that should be converted to BigInt
51
+ * @returns The object with specified fields converted to BigInt
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * const data = { amount: "100", nested: { value: "50" }, name: "test" }
56
+ * const result = mapBigIntFields(data, ['amount', 'value'])
57
+ * // { amount: 100n, nested: { value: 50n }, name: "test" }
58
+ * ```
59
+ */
60
+ export function mapBigIntFields(obj, fields) {
61
+ if (Array.isArray(obj)) {
62
+ return obj.map(item => mapBigIntFields(item, fields));
63
+ }
64
+ if (obj && typeof obj === 'object') {
65
+ const result = {};
66
+ for (const [key, value] of Object.entries(obj)) {
67
+ if (fields.includes(key) && typeof value === 'string' && value.match(/^-?\d+$/)) {
68
+ result[key] = BigInt(value);
69
+ }
70
+ else if (Array.isArray(value) || (value && typeof value === 'object')) {
71
+ result[key] = mapBigIntFields(value, fields);
72
+ }
73
+ else {
74
+ result[key] = value;
75
+ }
76
+ }
77
+ return result;
78
+ }
79
+ return obj;
80
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @fileoverview Participant identification utilities for the indexer.
3
+ *
4
+ * Participants (depositors and payers) are identified by a combination of
5
+ * their chain ID and address, hashed to create a unique cross-chain identifier.
6
+ */
7
+ /**
8
+ * Generate a unique participant ID from chain ID and address.
9
+ * Uses keccak256(chainId || address) to create a deterministic identifier
10
+ * that is unique across all chains.
11
+ *
12
+ * @param chainId - The chain ID (number or bigint)
13
+ * @param address - The participant's wallet address
14
+ * @returns A 32-byte hex string representing the participant ID
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * const id = generateParticipantId(8453, '0xabc123...')
19
+ * // '0x...' (keccak256 hash)
20
+ * ```
21
+ */
22
+ export declare function generateParticipantId(chainId: number | bigint, address: string): string;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @fileoverview Participant identification utilities for the indexer.
3
+ *
4
+ * Participants (depositors and payers) are identified by a combination of
5
+ * their chain ID and address, hashed to create a unique cross-chain identifier.
6
+ */
7
+ import { concatHex, keccak256, numberToHex } from 'viem';
8
+ /**
9
+ * Generate a unique participant ID from chain ID and address.
10
+ * Uses keccak256(chainId || address) to create a deterministic identifier
11
+ * that is unique across all chains.
12
+ *
13
+ * @param chainId - The chain ID (number or bigint)
14
+ * @param address - The participant's wallet address
15
+ * @returns A 32-byte hex string representing the participant ID
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * const id = generateParticipantId(8453, '0xabc123...')
20
+ * // '0x...' (keccak256 hash)
21
+ * ```
22
+ */
23
+ export function generateParticipantId(chainId, address) {
24
+ return keccak256(concatHex([
25
+ numberToHex(chainId, { size: 8 }),
26
+ address
27
+ ]));
28
+ }