@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.
@@ -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): g4mm4 operates a public PulseChain RPC that is more
25
- * reliable from browsers than the official `rpc.pulsechain.com`.
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 g4mm4 does not operate a Base RPC.
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
  /**
@@ -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): g4mm4 operates a public PulseChain RPC that is more
40
- * reliable from browsers than the official `rpc.pulsechain.com`.
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 g4mm4 does not operate a Base RPC.
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
  /**
@@ -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
- assert.deepEqual(FALLBACK_RPC_URLS[369], ['https://rpc-pulsechain.g4mm4.io']);
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) — g4mm4 does not run a Base RPC', () => {
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
  ]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@provex/utils",
3
- "version": "1.9.2-rc.20260722211737.69a2b06",
3
+ "version": "1.9.2-rc.20260723040940.52bdacc",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",