@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.
- package/dist/src/chain.d.ts +436 -4
- package/dist/src/chain.js +80 -0
- package/dist/src/chain.test.d.ts +1 -0
- package/dist/src/chain.test.js +112 -0
- package/dist/src/contracts.d.ts +196 -20
- package/dist/src/contracts.js +245 -17
- package/dist/src/contracts.test.d.ts +1 -0
- package/dist/src/contracts.test.js +243 -0
- package/dist/src/conversionRates.d.ts +99 -8
- package/dist/src/conversionRates.js +74 -4
- package/dist/src/conversionRates.test.d.ts +1 -0
- package/dist/src/conversionRates.test.js +473 -0
- package/dist/src/currencies.d.ts +113 -9
- package/dist/src/currencies.js +119 -38
- package/dist/src/currencies.test.d.ts +1 -0
- package/dist/src/currencies.test.js +343 -0
- package/dist/src/data/countries.json +166 -166
- package/dist/src/deposit.d.ts +69 -1
- package/dist/src/deposit.js +52 -1
- package/dist/src/depositKeys.d.ts +154 -0
- package/dist/src/depositKeys.js +104 -0
- package/dist/src/depositKeys.test.d.ts +1 -0
- package/dist/src/depositKeys.test.js +231 -0
- package/dist/src/endpoints.d.ts +51 -0
- package/dist/src/endpoints.js +70 -0
- package/dist/src/endpoints.test.d.ts +1 -0
- package/dist/src/endpoints.test.js +54 -0
- package/dist/src/events.d.ts +40 -2
- package/dist/src/events.js +86 -10
- package/dist/src/events.test.d.ts +1 -0
- package/dist/src/events.test.js +111 -0
- package/dist/src/fees.d.ts +136 -0
- package/dist/src/fees.js +178 -0
- package/dist/src/fees.test.d.ts +1 -0
- package/dist/src/fees.test.js +165 -0
- package/dist/src/ids.d.ts +125 -22
- package/dist/src/ids.js +211 -61
- package/dist/src/ids.test.d.ts +1 -0
- package/dist/src/ids.test.js +607 -0
- package/dist/src/index.d.ts +30 -1
- package/dist/src/index.js +30 -1
- package/dist/src/input.d.ts +23 -4
- package/dist/src/input.js +23 -4
- package/dist/src/intent.d.ts +38 -2
- package/dist/src/intent.js +28 -1
- package/dist/src/intent.test.d.ts +1 -0
- package/dist/src/intent.test.js +119 -0
- package/dist/src/json.d.ts +38 -1
- package/dist/src/json.js +38 -2
- package/dist/src/normalization.d.ts +224 -0
- package/dist/src/normalization.js +119 -0
- package/dist/src/normalization.test.d.ts +1 -0
- package/dist/src/normalization.test.js +284 -0
- package/dist/src/participants.d.ts +19 -4
- package/dist/src/participants.js +19 -4
- package/dist/src/payment.d.ts +333 -16
- package/dist/src/payment.js +768 -58
- package/dist/src/payment.test.d.ts +1 -0
- package/dist/src/payment.test.js +272 -0
- package/dist/src/peer-types.d.ts +327 -0
- package/dist/src/peer-types.js +169 -0
- package/dist/src/profit.d.ts +26 -5
- package/dist/src/profit.js +31 -8
- package/dist/src/profit.test.d.ts +1 -0
- package/dist/src/profit.test.js +315 -0
- package/dist/src/reputation.d.ts +125 -0
- package/dist/src/reputation.js +188 -0
- package/dist/src/reputation.test.d.ts +1 -0
- package/dist/src/reputation.test.js +156 -0
- package/dist/src/sort.d.ts +49 -10
- package/dist/src/sort.js +40 -9
- package/dist/src/sort.test.d.ts +1 -0
- package/dist/src/sort.test.js +216 -0
- package/dist/src/stateKey.d.ts +35 -0
- package/dist/src/stateKey.js +36 -0
- package/dist/src/stats.d.ts +55 -1
- package/dist/src/stats.js +46 -1
- package/dist/src/stats.test.d.ts +1 -0
- package/dist/src/stats.test.js +104 -0
- package/dist/src/time.d.ts +59 -9
- package/dist/src/time.js +71 -15
- package/dist/src/time.test.d.ts +1 -0
- package/dist/src/time.test.js +231 -0
- package/dist/src/tokens.d.ts +11972 -145
- package/dist/src/tokens.js +98 -17
- package/dist/src/tokens.test.d.ts +1 -0
- package/dist/src/tokens.test.js +193 -0
- package/dist/src/units.d.ts +183 -0
- package/dist/src/units.js +206 -6
- package/dist/src/units.test.d.ts +1 -0
- package/dist/src/units.test.js +327 -0
- package/dist/src/zkp2p-types.d.ts +273 -4
- package/dist/src/zkp2p-types.js +169 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +116 -26
- package/scripts/convert-svg.ts +0 -22
- package/src/chain.ts +0 -27
- package/src/contracts.ts +0 -89
- package/src/conversionRates.ts +0 -356
- package/src/currencies.ts +0 -286
- package/src/data/countries.json +0 -1099
- package/src/deposit.ts +0 -2
- package/src/events.ts +0 -21
- package/src/flags/eur.svg +0 -4
- package/src/flags/usd.svg +0 -25
- package/src/flags.ts +0 -4
- package/src/global.d.ts +0 -9
- package/src/ids.ts +0 -137
- package/src/index.ts +0 -16
- package/src/input.ts +0 -35
- package/src/intent.ts +0 -15
- package/src/json.ts +0 -42
- package/src/participants.ts +0 -14
- package/src/payment.ts +0 -573
- package/src/profit.ts +0 -55
- package/src/sort.ts +0 -49
- package/src/stats.ts +0 -10
- package/src/time.ts +0 -123
- package/src/tokens.ts +0 -159
- package/src/units.ts +0 -120
- package/src/zkp2p-types.ts +0 -55
- package/tsconfig.json +0 -18
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service endpoint URLs for the Provex platform.
|
|
3
|
+
*
|
|
4
|
+
* Each URL resolves at module load time using this priority:
|
|
5
|
+
* 1. Vite env (`import.meta.env.VITE_<NAME>`)
|
|
6
|
+
* 2. Node env (`process.env.<NAME>` or `process.env.VITE_<NAME>`)
|
|
7
|
+
* 3. Hardcoded production default
|
|
8
|
+
*
|
|
9
|
+
* Override any URL by setting the corresponding environment variable
|
|
10
|
+
* before the module is imported.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* // In .env or shell
|
|
14
|
+
* VITE_SPONSOR_SERVER_URL=http://localhost:3001
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Read an environment variable from either Vite or Node runtime.
|
|
18
|
+
*
|
|
19
|
+
* Checks `import.meta.env.VITE_<name>` first (browser / Vite dev server),
|
|
20
|
+
* then falls back to `process.env.<name>` and `process.env.VITE_<name>`
|
|
21
|
+
* (Node / scripts).
|
|
22
|
+
*
|
|
23
|
+
* @param name - The bare variable name without the `VITE_` prefix.
|
|
24
|
+
* @returns The value if found, otherwise `undefined`.
|
|
25
|
+
*/
|
|
26
|
+
function readEnv(name) {
|
|
27
|
+
const viteVal = typeof import.meta !== 'undefined'
|
|
28
|
+
? import.meta.env?.[`VITE_${name}`]
|
|
29
|
+
: undefined;
|
|
30
|
+
const nodeVal = typeof process !== 'undefined'
|
|
31
|
+
? (process.env?.[name] ?? process.env?.[`VITE_${name}`])
|
|
32
|
+
: undefined;
|
|
33
|
+
return viteVal ?? nodeVal ?? undefined;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Base URL for the gas-sponsorship relay server.
|
|
37
|
+
*
|
|
38
|
+
* The sponsor server wraps user operations in a sponsored transaction
|
|
39
|
+
* so end-users never need native gas tokens.
|
|
40
|
+
*
|
|
41
|
+
* @defaultValue `https://sponsor.provex.xyz`
|
|
42
|
+
*/
|
|
43
|
+
export const SPONSOR_SERVER_URL = readEnv('SPONSOR_SERVER_URL') ?? 'https://sponsor.provex.xyz';
|
|
44
|
+
/**
|
|
45
|
+
* WebSocket URL for the Reclaim Protocol attestor node.
|
|
46
|
+
*
|
|
47
|
+
* Used during the ZK proof generation flow to obtain a TLS attestation
|
|
48
|
+
* of payment-provider API responses.
|
|
49
|
+
*
|
|
50
|
+
* @defaultValue `wss://attestor.reclaimprotocol.org/ws`
|
|
51
|
+
*/
|
|
52
|
+
export const ATTESTOR_WS_URL = readEnv('ATTESTOR_WS_URL') ?? 'wss://attestor.reclaimprotocol.org/ws';
|
|
53
|
+
/**
|
|
54
|
+
* GraphQL endpoint for the Provex indexer.
|
|
55
|
+
*
|
|
56
|
+
* Serves deposit listings, intent history, and on-chain event data
|
|
57
|
+
* consumed by the UI and analytics dashboard.
|
|
58
|
+
*
|
|
59
|
+
* @defaultValue `https://indexer.provex.xyz/graphql`
|
|
60
|
+
*/
|
|
61
|
+
export const INDEXER_GRAPHQL_URL = readEnv('INDEXER_GRAPHQL_URL') ?? 'https://indexer.provex.xyz/graphql';
|
|
62
|
+
/**
|
|
63
|
+
* Base URL for the attestation verification service.
|
|
64
|
+
*
|
|
65
|
+
* Validates TLS attestations produced by the attestor before they
|
|
66
|
+
* are submitted on-chain as proof of payment.
|
|
67
|
+
*
|
|
68
|
+
* @defaultValue `https://attestation.provex.xyz`
|
|
69
|
+
*/
|
|
70
|
+
export const ATTESTATION_SERVICE_URL = readEnv('ATTESTATION_SERVICE_URL') ?? 'https://attestation.provex.xyz';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { describe, it } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { SPONSOR_SERVER_URL, ATTESTOR_WS_URL, INDEXER_GRAPHQL_URL, ATTESTATION_SERVICE_URL, } from './endpoints.js';
|
|
4
|
+
describe('endpoints', () => {
|
|
5
|
+
const endpoints = [
|
|
6
|
+
{ name: 'SPONSOR_SERVER_URL', value: SPONSOR_SERVER_URL },
|
|
7
|
+
{ name: 'ATTESTOR_WS_URL', value: ATTESTOR_WS_URL },
|
|
8
|
+
{ name: 'INDEXER_GRAPHQL_URL', value: INDEXER_GRAPHQL_URL },
|
|
9
|
+
{ name: 'ATTESTATION_SERVICE_URL', value: ATTESTATION_SERVICE_URL },
|
|
10
|
+
];
|
|
11
|
+
for (const { name, value } of endpoints) {
|
|
12
|
+
describe(name, () => {
|
|
13
|
+
it('should be a non-empty string', () => {
|
|
14
|
+
assert.ok(typeof value === 'string', `${name} should be a string`);
|
|
15
|
+
assert.ok(value.length > 0, `${name} should not be empty`);
|
|
16
|
+
});
|
|
17
|
+
it('should start with https:// or wss://', () => {
|
|
18
|
+
assert.ok(value.startsWith('https://') || value.startsWith('wss://'), `${name} should start with https:// or wss://, got: ${value}`);
|
|
19
|
+
});
|
|
20
|
+
it('should not have a trailing slash', () => {
|
|
21
|
+
assert.ok(!value.endsWith('/'), `${name} should not end with a trailing slash, got: ${value}`);
|
|
22
|
+
});
|
|
23
|
+
it('should not contain whitespace', () => {
|
|
24
|
+
assert.equal(value, value.trim(), `${name} should not have leading/trailing whitespace`);
|
|
25
|
+
assert.ok(!/\s/.test(value), `${name} should not contain whitespace`);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
describe('default values', () => {
|
|
30
|
+
it('SPONSOR_SERVER_URL defaults to production', () => {
|
|
31
|
+
assert.equal(SPONSOR_SERVER_URL, 'https://sponsor.provex.xyz');
|
|
32
|
+
});
|
|
33
|
+
it('ATTESTOR_WS_URL defaults to Reclaim attestor', () => {
|
|
34
|
+
assert.equal(ATTESTOR_WS_URL, 'wss://attestor.reclaimprotocol.org/ws');
|
|
35
|
+
});
|
|
36
|
+
it('INDEXER_GRAPHQL_URL defaults to production GraphQL', () => {
|
|
37
|
+
assert.equal(INDEXER_GRAPHQL_URL, 'https://indexer.provex.xyz/graphql');
|
|
38
|
+
});
|
|
39
|
+
it('ATTESTATION_SERVICE_URL defaults to production', () => {
|
|
40
|
+
assert.equal(ATTESTATION_SERVICE_URL, 'https://attestation.provex.xyz');
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe('protocol expectations', () => {
|
|
44
|
+
it('ATTESTOR_WS_URL uses wss:// protocol', () => {
|
|
45
|
+
assert.ok(ATTESTOR_WS_URL.startsWith('wss://'), 'WebSocket URL should use wss://');
|
|
46
|
+
});
|
|
47
|
+
it('HTTPS endpoints use https:// protocol', () => {
|
|
48
|
+
const httpsEndpoints = [SPONSOR_SERVER_URL, INDEXER_GRAPHQL_URL, ATTESTATION_SERVICE_URL];
|
|
49
|
+
for (const url of httpsEndpoints) {
|
|
50
|
+
assert.ok(url.startsWith('https://'), `Expected https://, got: ${url}`);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
});
|
package/dist/src/events.d.ts
CHANGED
|
@@ -1,3 +1,41 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Event type definitions for the Provex indexer.
|
|
3
|
+
*
|
|
4
|
+
* This module defines all blockchain event types in their display order.
|
|
5
|
+
* The order determines how events are sorted in the UI when viewing
|
|
6
|
+
* deposit history - deposit creation events come first, followed by
|
|
7
|
+
* intent events, then close/withdrawal events.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* The eventOrderId map assigns each event a numeric ID used in orderId
|
|
11
|
+
* serialization for consistent cross-chain ordering.
|
|
12
|
+
*
|
|
13
|
+
* @see {@link ids} for orderId serialization
|
|
14
|
+
* @see {@link indexer} for event handlers
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Ordered list of all event types supported by the indexer.
|
|
18
|
+
* The order determines the display sort priority in the UI.
|
|
19
|
+
*
|
|
20
|
+
* Event categories:
|
|
21
|
+
* 1. Deposit open events (creation, configuration)
|
|
22
|
+
* 2. Intent lifecycle events (signal, lock, verify, fulfill)
|
|
23
|
+
* 3. Deposit close events (withdrawal, close)
|
|
24
|
+
* 4. Protocol configuration events (dust, fees, registries)
|
|
25
|
+
*/
|
|
26
|
+
export declare const eventOrder: readonly ["deposit_received", "deposit_payment_method_added", "deposit_payment_method_active_updated", "deposit_currency_added", "deposit_delegate_set", "deposit_delegate_removed", "deposit_conversion_rate_updated", "deposit_accepting_intents_updated", "deposit_intent_amount_range_updated", "deposit_funds_added", "intent_signaled", "funds_locked", "payment_verified", "funds_unlocked_and_transferred", "intent_fulfilled", "intent_pruned", "funds_unlocked", "intent_expiry_extended", "funds_removed", "deposit_withdrawn", "deposit_closed", "dust_collected", "dust_recipient_updated", "dust_threshold_updated", "deposit_retain_on_empty_updated", "payment_method_currency_added", "payment_method_currency_removed", "payment_method_added", "payment_method_removed", "allow_multiple_intents_updated", "escrow_registry_updated", "post_intent_hook_registry_updated", "protocol_fee_recipient_updated", "protocol_fee_updated", "relayer_registry_updated", "unpaused", "paused", "intent_expiration_period_updated", "max_intents_per_deposit_updated", "min_deposit_amount_set", "orchestrator_updated", "ownership_transferred", "payment_verifier_registry_updated", "provider_hash_added", "provider_hash_removed"];
|
|
27
|
+
/**
|
|
28
|
+
* Union type of all valid event type names.
|
|
29
|
+
* Use this when filtering or handling specific event types.
|
|
30
|
+
*/
|
|
2
31
|
export type EventType = (typeof eventOrder)[number];
|
|
3
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Map from event type name to its numeric order ID.
|
|
34
|
+
* Used in orderId serialization to maintain consistent ordering.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* const id = eventOrderId.get('intent_signaled') // 9
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare const eventOrderId: Map<"paused" | "deposit_received" | "deposit_payment_method_added" | "deposit_payment_method_active_updated" | "deposit_currency_added" | "deposit_delegate_set" | "deposit_delegate_removed" | "deposit_conversion_rate_updated" | "deposit_accepting_intents_updated" | "deposit_intent_amount_range_updated" | "deposit_funds_added" | "intent_signaled" | "funds_locked" | "payment_verified" | "funds_unlocked_and_transferred" | "intent_fulfilled" | "intent_pruned" | "funds_unlocked" | "intent_expiry_extended" | "funds_removed" | "deposit_withdrawn" | "deposit_closed" | "dust_collected" | "dust_recipient_updated" | "dust_threshold_updated" | "deposit_retain_on_empty_updated" | "payment_method_currency_added" | "payment_method_currency_removed" | "payment_method_added" | "payment_method_removed" | "allow_multiple_intents_updated" | "escrow_registry_updated" | "post_intent_hook_registry_updated" | "protocol_fee_recipient_updated" | "protocol_fee_updated" | "relayer_registry_updated" | "unpaused" | "intent_expiration_period_updated" | "max_intents_per_deposit_updated" | "min_deposit_amount_set" | "orchestrator_updated" | "ownership_transferred" | "payment_verifier_registry_updated" | "provider_hash_added" | "provider_hash_removed", number>;
|
package/dist/src/events.js
CHANGED
|
@@ -1,16 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Event type definitions for the Provex indexer.
|
|
3
|
+
*
|
|
4
|
+
* This module defines all blockchain event types in their display order.
|
|
5
|
+
* The order determines how events are sorted in the UI when viewing
|
|
6
|
+
* deposit history - deposit creation events come first, followed by
|
|
7
|
+
* intent events, then close/withdrawal events.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* The eventOrderId map assigns each event a numeric ID used in orderId
|
|
11
|
+
* serialization for consistent cross-chain ordering.
|
|
12
|
+
*
|
|
13
|
+
* @see {@link ids} for orderId serialization
|
|
14
|
+
* @see {@link indexer} for event handlers
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Ordered list of all event types supported by the indexer.
|
|
18
|
+
* The order determines the display sort priority in the UI.
|
|
19
|
+
*
|
|
20
|
+
* Event categories:
|
|
21
|
+
* 1. Deposit open events (creation, configuration)
|
|
22
|
+
* 2. Intent lifecycle events (signal, lock, verify, fulfill)
|
|
23
|
+
* 3. Deposit close events (withdrawal, close)
|
|
24
|
+
* 4. Protocol configuration events (dust, fees, registries)
|
|
25
|
+
*/
|
|
1
26
|
export const eventOrder = [
|
|
2
27
|
// deposit open events
|
|
3
|
-
'
|
|
4
|
-
'
|
|
5
|
-
'
|
|
6
|
-
|
|
7
|
-
'
|
|
28
|
+
'deposit_received',
|
|
29
|
+
'deposit_payment_method_added',
|
|
30
|
+
'deposit_payment_method_active_updated',
|
|
31
|
+
'deposit_currency_added',
|
|
32
|
+
'deposit_delegate_set',
|
|
33
|
+
'deposit_delegate_removed',
|
|
34
|
+
// configuration events (these happen before funds_added in deposit creation)
|
|
35
|
+
'deposit_conversion_rate_updated',
|
|
36
|
+
'deposit_accepting_intents_updated',
|
|
37
|
+
'deposit_intent_amount_range_updated',
|
|
38
|
+
// funds added comes after configuration so it appears first in UI (newest-first)
|
|
39
|
+
'deposit_funds_added',
|
|
8
40
|
// intent events
|
|
9
|
-
'
|
|
10
|
-
'
|
|
11
|
-
'
|
|
41
|
+
'intent_signaled',
|
|
42
|
+
'funds_locked',
|
|
43
|
+
'payment_verified',
|
|
44
|
+
'funds_unlocked_and_transferred',
|
|
45
|
+
'intent_fulfilled',
|
|
46
|
+
'intent_pruned',
|
|
47
|
+
'funds_unlocked',
|
|
48
|
+
'intent_expiry_extended',
|
|
12
49
|
// deposit close events
|
|
13
|
-
'
|
|
14
|
-
'
|
|
50
|
+
'funds_removed', // synthetic UI event for partial withdrawal (remaining > 0)
|
|
51
|
+
'deposit_withdrawn', // full withdrawal that closes the deposit (remaining = 0)
|
|
52
|
+
'deposit_closed',
|
|
53
|
+
// dust events
|
|
54
|
+
'dust_collected',
|
|
55
|
+
'dust_recipient_updated',
|
|
56
|
+
'dust_threshold_updated',
|
|
57
|
+
// deposit config events
|
|
58
|
+
'deposit_retain_on_empty_updated',
|
|
59
|
+
'payment_method_currency_added',
|
|
60
|
+
'payment_method_currency_removed',
|
|
61
|
+
// registry events
|
|
62
|
+
'payment_method_added',
|
|
63
|
+
'payment_method_removed',
|
|
64
|
+
'allow_multiple_intents_updated',
|
|
65
|
+
'escrow_registry_updated',
|
|
66
|
+
'post_intent_hook_registry_updated',
|
|
67
|
+
'protocol_fee_recipient_updated',
|
|
68
|
+
'protocol_fee_updated',
|
|
69
|
+
'relayer_registry_updated',
|
|
70
|
+
'unpaused',
|
|
71
|
+
'paused',
|
|
72
|
+
// V3 global config events
|
|
73
|
+
'intent_expiration_period_updated',
|
|
74
|
+
'max_intents_per_deposit_updated',
|
|
75
|
+
'min_deposit_amount_set',
|
|
76
|
+
'orchestrator_updated',
|
|
77
|
+
'ownership_transferred',
|
|
78
|
+
'payment_verifier_registry_updated',
|
|
79
|
+
// V2 verifier events
|
|
80
|
+
'provider_hash_added',
|
|
81
|
+
'provider_hash_removed',
|
|
15
82
|
];
|
|
83
|
+
/**
|
|
84
|
+
* Map from event type name to its numeric order ID.
|
|
85
|
+
* Used in orderId serialization to maintain consistent ordering.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```ts
|
|
89
|
+
* const id = eventOrderId.get('intent_signaled') // 9
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
16
92
|
export const eventOrderId = new Map(eventOrder.map((event, index) => [event, index]));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { describe, it } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { eventOrder, eventOrderId } from './events.js';
|
|
4
|
+
describe('events', () => {
|
|
5
|
+
describe('eventOrder', () => {
|
|
6
|
+
it('is a non-empty array', () => {
|
|
7
|
+
assert.ok(Array.isArray(eventOrder));
|
|
8
|
+
assert.ok(eventOrder.length > 0);
|
|
9
|
+
});
|
|
10
|
+
it('contains deposit lifecycle events', () => {
|
|
11
|
+
assert.ok(eventOrder.includes('deposit_received'));
|
|
12
|
+
assert.ok(eventOrder.includes('deposit_withdrawn'));
|
|
13
|
+
assert.ok(eventOrder.includes('deposit_closed'));
|
|
14
|
+
});
|
|
15
|
+
it('contains intent lifecycle events', () => {
|
|
16
|
+
assert.ok(eventOrder.includes('intent_signaled'));
|
|
17
|
+
assert.ok(eventOrder.includes('intent_fulfilled'));
|
|
18
|
+
assert.ok(eventOrder.includes('intent_pruned'));
|
|
19
|
+
});
|
|
20
|
+
it('contains V3-specific events', () => {
|
|
21
|
+
assert.ok(eventOrder.includes('funds_locked'));
|
|
22
|
+
assert.ok(eventOrder.includes('funds_unlocked'));
|
|
23
|
+
assert.ok(eventOrder.includes('funds_unlocked_and_transferred'));
|
|
24
|
+
assert.ok(eventOrder.includes('payment_verified'));
|
|
25
|
+
assert.ok(eventOrder.includes('intent_expiry_extended'));
|
|
26
|
+
assert.ok(eventOrder.includes('deposit_payment_method_active_updated'));
|
|
27
|
+
});
|
|
28
|
+
it('contains V3 global config events', () => {
|
|
29
|
+
assert.ok(eventOrder.includes('intent_expiration_period_updated'));
|
|
30
|
+
assert.ok(eventOrder.includes('max_intents_per_deposit_updated'));
|
|
31
|
+
assert.ok(eventOrder.includes('min_deposit_amount_set'));
|
|
32
|
+
assert.ok(eventOrder.includes('orchestrator_updated'));
|
|
33
|
+
assert.ok(eventOrder.includes('payment_verifier_registry_updated'));
|
|
34
|
+
});
|
|
35
|
+
it('has no duplicate events', () => {
|
|
36
|
+
const uniqueEvents = new Set(eventOrder);
|
|
37
|
+
assert.strictEqual(uniqueEvents.size, eventOrder.length);
|
|
38
|
+
});
|
|
39
|
+
it('orders deposit events before intent events', () => {
|
|
40
|
+
const depositReceivedIdx = eventOrder.indexOf('deposit_received');
|
|
41
|
+
const intentSignaledIdx = eventOrder.indexOf('intent_signaled');
|
|
42
|
+
assert.ok(depositReceivedIdx < intentSignaledIdx);
|
|
43
|
+
});
|
|
44
|
+
it('orders intent_signaled before intent_fulfilled', () => {
|
|
45
|
+
const signaledIdx = eventOrder.indexOf('intent_signaled');
|
|
46
|
+
const fulfilledIdx = eventOrder.indexOf('intent_fulfilled');
|
|
47
|
+
assert.ok(signaledIdx < fulfilledIdx);
|
|
48
|
+
});
|
|
49
|
+
it('orders funds_locked before funds_unlocked', () => {
|
|
50
|
+
const lockedIdx = eventOrder.indexOf('funds_locked');
|
|
51
|
+
const unlockedIdx = eventOrder.indexOf('funds_unlocked');
|
|
52
|
+
assert.ok(lockedIdx < unlockedIdx);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
describe('eventOrderId', () => {
|
|
56
|
+
it('is a Map', () => {
|
|
57
|
+
assert.ok(eventOrderId instanceof Map);
|
|
58
|
+
});
|
|
59
|
+
it('has same size as eventOrder', () => {
|
|
60
|
+
assert.strictEqual(eventOrderId.size, eventOrder.length);
|
|
61
|
+
});
|
|
62
|
+
it('maps each event to its index', () => {
|
|
63
|
+
for (let i = 0; i < eventOrder.length; i++) {
|
|
64
|
+
const event = eventOrder[i];
|
|
65
|
+
assert.strictEqual(eventOrderId.get(event), i);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
it('returns correct index for deposit_received', () => {
|
|
69
|
+
const idx = eventOrderId.get('deposit_received');
|
|
70
|
+
assert.strictEqual(idx, 0);
|
|
71
|
+
});
|
|
72
|
+
it('returns correct index for intent_signaled', () => {
|
|
73
|
+
const idx = eventOrderId.get('intent_signaled');
|
|
74
|
+
assert.strictEqual(idx, eventOrder.indexOf('intent_signaled'));
|
|
75
|
+
});
|
|
76
|
+
it('returns undefined for invalid event', () => {
|
|
77
|
+
// @ts-expect-error - Testing runtime behavior with invalid event
|
|
78
|
+
const idx = eventOrderId.get('invalid_event');
|
|
79
|
+
assert.strictEqual(idx, undefined);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe('EventType', () => {
|
|
83
|
+
it('type-checks valid events', () => {
|
|
84
|
+
// These should compile without error
|
|
85
|
+
const event1 = 'deposit_received';
|
|
86
|
+
const event2 = 'intent_signaled';
|
|
87
|
+
const event3 = 'funds_locked';
|
|
88
|
+
assert.ok(event1);
|
|
89
|
+
assert.ok(event2);
|
|
90
|
+
assert.ok(event3);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
describe('event ordering consistency', () => {
|
|
94
|
+
it('maintains consistent ordering for UI display', () => {
|
|
95
|
+
// Events in same transaction should sort consistently
|
|
96
|
+
// Lower index = appears first in time-ordered list (oldest first)
|
|
97
|
+
// Higher index = appears later
|
|
98
|
+
// Deposit setup should come before funds added
|
|
99
|
+
const depositReceivedIdx = eventOrderId.get('deposit_received');
|
|
100
|
+
const fundsAddedIdx = eventOrderId.get('deposit_funds_added');
|
|
101
|
+
assert.ok(depositReceivedIdx < fundsAddedIdx);
|
|
102
|
+
// Intent signaled should come before payment verified
|
|
103
|
+
const intentSignaledIdx = eventOrderId.get('intent_signaled');
|
|
104
|
+
const paymentVerifiedIdx = eventOrderId.get('payment_verified');
|
|
105
|
+
assert.ok(intentSignaledIdx < paymentVerifiedIdx);
|
|
106
|
+
// Payment verified should come before intent fulfilled
|
|
107
|
+
const intentFulfilledIdx = eventOrderId.get('intent_fulfilled');
|
|
108
|
+
assert.ok(paymentVerifiedIdx < intentFulfilledIdx);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
});
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fee calculation utilities for Provex protocol.
|
|
3
|
+
*
|
|
4
|
+
* Fee Precision Formats:
|
|
5
|
+
* - Basis points (bps): 10000 = 100%, 100 = 1%, 1 = 0.01%
|
|
6
|
+
* - 18 decimals: 1e18 = 100% (like Solidity's ether units)
|
|
7
|
+
*
|
|
8
|
+
* The protocol uses basis points for most fee calculations.
|
|
9
|
+
* Some contracts (Pulsechain V3) use 18-decimal precision which must
|
|
10
|
+
* be normalized to basis points before use.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* // Calculate 2% fee on 100 USDC
|
|
14
|
+
* const fee = calculateFeeAmount({ amount: 100_000000n, feeBps: 200n })
|
|
15
|
+
* // fee = 2_000000n (2 USDC)
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Maximum basis points value representing 100%.
|
|
19
|
+
* Used as the denominator in fee calculations.
|
|
20
|
+
*/
|
|
21
|
+
export declare const BPS_DENOMINATOR = 10000n;
|
|
22
|
+
/**
|
|
23
|
+
* 18-decimal representation of 100%.
|
|
24
|
+
* Used to detect and normalize 18-decimal fee values.
|
|
25
|
+
*/
|
|
26
|
+
export declare const EIGHTEEN_DECIMAL_100_PERCENT: bigint;
|
|
27
|
+
/**
|
|
28
|
+
* Precision format for fee values.
|
|
29
|
+
* - 'bps': Basis points (10000 = 100%)
|
|
30
|
+
* - '18decimals': 18-decimal precision (1e18 = 100%)
|
|
31
|
+
*/
|
|
32
|
+
export type FeePrecision = 'bps' | '18decimals';
|
|
33
|
+
/**
|
|
34
|
+
* Result of fee precision detection.
|
|
35
|
+
*/
|
|
36
|
+
export interface FeeInfo {
|
|
37
|
+
/** Human-readable percentage string (e.g., "2%", "0.50%") */
|
|
38
|
+
percentage: string;
|
|
39
|
+
/** Detected precision format */
|
|
40
|
+
precision: FeePrecision;
|
|
41
|
+
/** Fee value normalized to basis points */
|
|
42
|
+
normalizedBps: bigint;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Calculate the fee amount for a given transaction.
|
|
46
|
+
*
|
|
47
|
+
* @param params.amount - Transaction amount in smallest unit (e.g., 6 decimals for USDC)
|
|
48
|
+
* @param params.feeBps - Fee in basis points (200 = 2%)
|
|
49
|
+
* @returns Fee amount in the same units as the input amount
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* // 2% fee on 100 USDC (6 decimals)
|
|
53
|
+
* calculateFeeAmount({ amount: 100_000000n, feeBps: 200n })
|
|
54
|
+
* // Returns: 2_000000n (2 USDC)
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* // 0.5% fee on 1000 USDC
|
|
58
|
+
* calculateFeeAmount({ amount: 1000_000000n, feeBps: 50n })
|
|
59
|
+
* // Returns: 5_000000n (5 USDC)
|
|
60
|
+
*/
|
|
61
|
+
export declare function calculateFeeAmount(params: {
|
|
62
|
+
amount: bigint;
|
|
63
|
+
feeBps: bigint;
|
|
64
|
+
}): bigint;
|
|
65
|
+
/**
|
|
66
|
+
* Calculate the net amount after deducting fees.
|
|
67
|
+
*
|
|
68
|
+
* @param params.grossAmount - Original amount before fees
|
|
69
|
+
* @param params.feeBps - Fee in basis points (200 = 2%)
|
|
70
|
+
* @returns Amount remaining after fee deduction
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* // Net amount after 2% fee on 100 USDC
|
|
74
|
+
* calculateNetAmount({ grossAmount: 100_000000n, feeBps: 200n })
|
|
75
|
+
* // Returns: 98_000000n (98 USDC)
|
|
76
|
+
*/
|
|
77
|
+
export declare function calculateNetAmount(params: {
|
|
78
|
+
grossAmount: bigint;
|
|
79
|
+
feeBps: bigint;
|
|
80
|
+
}): bigint;
|
|
81
|
+
/**
|
|
82
|
+
* Format a basis points value as a human-readable percentage string.
|
|
83
|
+
*
|
|
84
|
+
* @param feeBps - Fee in basis points
|
|
85
|
+
* @returns Formatted percentage string (e.g., "2%", "0.50%")
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* formatFeeBps(200n) // "2%"
|
|
89
|
+
* formatFeeBps(50n) // "0.50%"
|
|
90
|
+
* formatFeeBps(0n) // "0%"
|
|
91
|
+
* formatFeeBps(10000n) // "100%"
|
|
92
|
+
* formatFeeBps(1n) // "0.01%"
|
|
93
|
+
*/
|
|
94
|
+
export declare function formatFeeBps(feeBps: bigint): string;
|
|
95
|
+
/**
|
|
96
|
+
* Detect the precision of a raw fee value and normalize to basis points.
|
|
97
|
+
*
|
|
98
|
+
* Contracts may use different precisions:
|
|
99
|
+
* - Basis points: 10000 = 100% (most common)
|
|
100
|
+
* - 18 decimals: 1e18 = 100% (like ether, used by some V3 contracts)
|
|
101
|
+
*
|
|
102
|
+
* Heuristic: If value > 1,000,000, assume 18-decimal precision.
|
|
103
|
+
*
|
|
104
|
+
* @param rawFee - Raw fee value from contract
|
|
105
|
+
* @returns Normalized fee information with bps value and detected precision
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* // Basis points input
|
|
109
|
+
* normalizeFeePrecision(200n)
|
|
110
|
+
* // Returns: { percentage: "2%", precision: "bps", normalizedBps: 200n }
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* // 18-decimal input (2%)
|
|
114
|
+
* normalizeFeePrecision(20000000000000000n)
|
|
115
|
+
* // Returns: { percentage: "2%", precision: "18decimals", normalizedBps: 200n }
|
|
116
|
+
*/
|
|
117
|
+
export declare function normalizeFeePrecision(rawFee: bigint): FeeInfo;
|
|
118
|
+
/**
|
|
119
|
+
* Calculate total fees from multiple fee sources.
|
|
120
|
+
*
|
|
121
|
+
* @param fees - Array of fee amounts (all in same precision)
|
|
122
|
+
* @returns Total fee amount
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* // Protocol fee + referrer fee
|
|
126
|
+
* calculateTotalFees([2_000000n, 500000n])
|
|
127
|
+
* // Returns: 2_500000n
|
|
128
|
+
*/
|
|
129
|
+
export declare function calculateTotalFees(fees: bigint[]): bigint;
|
|
130
|
+
/**
|
|
131
|
+
* Check if a fee value represents a zero/no fee.
|
|
132
|
+
*
|
|
133
|
+
* @param feeBps - Fee in basis points
|
|
134
|
+
* @returns true if fee is zero
|
|
135
|
+
*/
|
|
136
|
+
export declare function isZeroFee(feeBps: bigint): boolean;
|