@provex/utils 1.9.2-rc.20260722211737.69a2b06 → 1.9.2-rc.20260723040940.52bdacc
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/transports.d.ts +24 -3
- package/dist/transports.js +25 -4
- package/dist/transports.test.js +25 -5
- package/package.json +1 -1
package/dist/transports.d.ts
CHANGED
|
@@ -16,15 +16,36 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { type Transport } from 'viem';
|
|
18
18
|
import { type ChainId } from './chain.js';
|
|
19
|
+
/**
|
|
20
|
+
* valve.city PulseChain endpoint — one URL fronting a load-balanced node pool.
|
|
21
|
+
*
|
|
22
|
+
* `vk_demo` is the PUBLIC, RATE-LIMITED demo key. It is the right default for
|
|
23
|
+
* local development and for anyone building against this package without
|
|
24
|
+
* credentials, but a keyed endpoint (`https://one.valve.city/rpc/<key>/evm/369`)
|
|
25
|
+
* belongs in front of production traffic — a shared demo key is a shared rate
|
|
26
|
+
* limit. Override per-deployment via the `VITE_RPC_URLS_369` env (caller
|
|
27
|
+
* overrides are tried ahead of this list) rather than editing this constant.
|
|
28
|
+
*
|
|
29
|
+
* Kept in sync with `DEFAULT_MSGBOARD_ENDPOINT` in @provex/onramp, which points
|
|
30
|
+
* at the same host: one keyed valve.city endpoint serves both `msgboard_*` and
|
|
31
|
+
* `eth_*` methods.
|
|
32
|
+
*/
|
|
33
|
+
export declare const VALVE_CITY_PULSECHAIN_RPC = "https://one.valve.city/rpc/vk_demo/evm/369";
|
|
19
34
|
/**
|
|
20
35
|
* Provex-curated fallback RPC URLs per chain, applied after caller overrides
|
|
21
36
|
* but before the viem chain default.
|
|
22
37
|
*
|
|
23
38
|
* @remarks
|
|
24
|
-
* - Pulsechain (369):
|
|
25
|
-
*
|
|
39
|
+
* - Pulsechain (369): valve.city is listed first — it load balances across a
|
|
40
|
+
* pool of PulseChain nodes behind one endpoint, so it absorbs a single node
|
|
41
|
+
* going slow or stale without the client noticing. g4mm4 is retained behind
|
|
42
|
+
* it as an independent operator: valve.city's internal balancing cannot help
|
|
43
|
+
* if the endpoint ITSELF is unreachable, so a second operator is what makes
|
|
44
|
+
* this list a real fallback rather than one host with extra steps.
|
|
45
|
+
* Order is a hint, not a guarantee — {@link createChainTransport} ranks by
|
|
46
|
+
* measured latency, so the fastest healthy endpoint serves traffic either way.
|
|
26
47
|
* - Base (8453): no built-in fallback — Base's default endpoint is reliable
|
|
27
|
-
* and
|
|
48
|
+
* and neither operator runs a Base RPC.
|
|
28
49
|
*/
|
|
29
50
|
export declare const FALLBACK_RPC_URLS: Partial<Record<ChainId, readonly string[]>>;
|
|
30
51
|
/**
|
package/dist/transports.js
CHANGED
|
@@ -16,6 +16,21 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { fallback, http } from 'viem';
|
|
18
18
|
import { chainIdToChain } from './chain.js';
|
|
19
|
+
/**
|
|
20
|
+
* valve.city PulseChain endpoint — one URL fronting a load-balanced node pool.
|
|
21
|
+
*
|
|
22
|
+
* `vk_demo` is the PUBLIC, RATE-LIMITED demo key. It is the right default for
|
|
23
|
+
* local development and for anyone building against this package without
|
|
24
|
+
* credentials, but a keyed endpoint (`https://one.valve.city/rpc/<key>/evm/369`)
|
|
25
|
+
* belongs in front of production traffic — a shared demo key is a shared rate
|
|
26
|
+
* limit. Override per-deployment via the `VITE_RPC_URLS_369` env (caller
|
|
27
|
+
* overrides are tried ahead of this list) rather than editing this constant.
|
|
28
|
+
*
|
|
29
|
+
* Kept in sync with `DEFAULT_MSGBOARD_ENDPOINT` in @provex/onramp, which points
|
|
30
|
+
* at the same host: one keyed valve.city endpoint serves both `msgboard_*` and
|
|
31
|
+
* `eth_*` methods.
|
|
32
|
+
*/
|
|
33
|
+
export const VALVE_CITY_PULSECHAIN_RPC = 'https://one.valve.city/rpc/vk_demo/evm/369';
|
|
19
34
|
// Per-method call counter. Enabled at runtime by setting window.__RPC_DEBUG = true
|
|
20
35
|
// in the browser console (works in pre-built dist — no Vite env injection needed).
|
|
21
36
|
const _rpcCounts = {};
|
|
@@ -36,13 +51,19 @@ const _rpcLog = (method) => {
|
|
|
36
51
|
* but before the viem chain default.
|
|
37
52
|
*
|
|
38
53
|
* @remarks
|
|
39
|
-
* - Pulsechain (369):
|
|
40
|
-
*
|
|
54
|
+
* - Pulsechain (369): valve.city is listed first — it load balances across a
|
|
55
|
+
* pool of PulseChain nodes behind one endpoint, so it absorbs a single node
|
|
56
|
+
* going slow or stale without the client noticing. g4mm4 is retained behind
|
|
57
|
+
* it as an independent operator: valve.city's internal balancing cannot help
|
|
58
|
+
* if the endpoint ITSELF is unreachable, so a second operator is what makes
|
|
59
|
+
* this list a real fallback rather than one host with extra steps.
|
|
60
|
+
* Order is a hint, not a guarantee — {@link createChainTransport} ranks by
|
|
61
|
+
* measured latency, so the fastest healthy endpoint serves traffic either way.
|
|
41
62
|
* - Base (8453): no built-in fallback — Base's default endpoint is reliable
|
|
42
|
-
* and
|
|
63
|
+
* and neither operator runs a Base RPC.
|
|
43
64
|
*/
|
|
44
65
|
export const FALLBACK_RPC_URLS = {
|
|
45
|
-
369: ['https://rpc-pulsechain.g4mm4.io'],
|
|
66
|
+
369: [VALVE_CITY_PULSECHAIN_RPC, 'https://rpc-pulsechain.g4mm4.io'],
|
|
46
67
|
8453: [],
|
|
47
68
|
};
|
|
48
69
|
/**
|
package/dist/transports.test.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, it } from 'node:test';
|
|
2
2
|
import assert from 'node:assert/strict';
|
|
3
3
|
import { base, pulsechain } from 'viem/chains';
|
|
4
|
-
import { createChainTransport, parseRpcUrlList, resolveChainRpcUrls, FALLBACK_RPC_URLS, } from './transports.js';
|
|
4
|
+
import { createChainTransport, parseRpcUrlList, resolveChainRpcUrls, FALLBACK_RPC_URLS, VALVE_CITY_PULSECHAIN_RPC, } from './transports.js';
|
|
5
5
|
/**
|
|
6
6
|
* Read the ordered list of RPC URLs a built transport will actually dial.
|
|
7
7
|
*
|
|
@@ -19,10 +19,26 @@ const dialledUrls = (transport) => {
|
|
|
19
19
|
};
|
|
20
20
|
describe('transports', () => {
|
|
21
21
|
describe('FALLBACK_RPC_URLS', () => {
|
|
22
|
-
it('lists g4mm4 for PulseChain (369)', () => {
|
|
23
|
-
|
|
22
|
+
it('lists valve.city ahead of g4mm4 for PulseChain (369)', () => {
|
|
23
|
+
// valve.city load balances across a node pool, so it leads. g4mm4 stays
|
|
24
|
+
// behind it as an INDEPENDENT operator: valve.city's internal balancing
|
|
25
|
+
// cannot save us if that endpoint itself is down, which is the only
|
|
26
|
+
// failure a fallback list exists to survive.
|
|
27
|
+
assert.deepEqual(FALLBACK_RPC_URLS[369], [
|
|
28
|
+
VALVE_CITY_PULSECHAIN_RPC,
|
|
29
|
+
'https://rpc-pulsechain.g4mm4.io',
|
|
30
|
+
]);
|
|
31
|
+
});
|
|
32
|
+
it('keeps two independent operators for PulseChain', () => {
|
|
33
|
+
// Guard against someone "simplifying" the list down to a single host.
|
|
34
|
+
// One entry means fallback() short-circuits to a bare transport and a
|
|
35
|
+
// single operator outage takes the app down.
|
|
36
|
+
const urls = FALLBACK_RPC_URLS[369] ?? [];
|
|
37
|
+
assert.ok(urls.length >= 2, 'PulseChain must keep a second, independent RPC operator');
|
|
38
|
+
const hosts = new Set(urls.map((u) => new URL(u).host));
|
|
39
|
+
assert.equal(hosts.size, urls.length, 'fallback URLs must not share a host');
|
|
24
40
|
});
|
|
25
|
-
it('has an empty list for Base (8453) —
|
|
41
|
+
it('has an empty list for Base (8453) — neither operator runs a Base RPC', () => {
|
|
26
42
|
assert.deepEqual(FALLBACK_RPC_URLS[8453], []);
|
|
27
43
|
});
|
|
28
44
|
});
|
|
@@ -47,9 +63,10 @@ describe('transports', () => {
|
|
|
47
63
|
});
|
|
48
64
|
});
|
|
49
65
|
describe('resolveChainRpcUrls', () => {
|
|
50
|
-
it('returns g4mm4 then chain default for PulseChain', () => {
|
|
66
|
+
it('returns valve.city, then g4mm4, then chain default for PulseChain', () => {
|
|
51
67
|
const urls = resolveChainRpcUrls(369);
|
|
52
68
|
assert.deepEqual(urls, [
|
|
69
|
+
VALVE_CITY_PULSECHAIN_RPC,
|
|
53
70
|
'https://rpc-pulsechain.g4mm4.io',
|
|
54
71
|
pulsechain.rpcUrls.default.http[0],
|
|
55
72
|
]);
|
|
@@ -61,9 +78,12 @@ describe('transports', () => {
|
|
|
61
78
|
it('places caller-supplied userUrls ahead of curated fallbacks and the default', () => {
|
|
62
79
|
const userUrls = ['https://my-private-rpc.example', 'https://another.example'];
|
|
63
80
|
const urls = resolveChainRpcUrls(369, { userUrls });
|
|
81
|
+
// A deployment-supplied keyed endpoint MUST outrank the shared vk_demo
|
|
82
|
+
// default — this is how production escapes the demo key's rate limit.
|
|
64
83
|
assert.deepEqual(urls, [
|
|
65
84
|
'https://my-private-rpc.example',
|
|
66
85
|
'https://another.example',
|
|
86
|
+
VALVE_CITY_PULSECHAIN_RPC,
|
|
67
87
|
'https://rpc-pulsechain.g4mm4.io',
|
|
68
88
|
pulsechain.rpcUrls.default.http[0],
|
|
69
89
|
]);
|