@waterx/sdk 4.1.0 → 4.3.0

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 (66) hide show
  1. package/README.md +22 -17
  2. package/dist/cjs/src/account/config.d.ts +3 -2
  3. package/dist/cjs/src/generated/waterx_rule/waterx_rule.d.ts +7 -134
  4. package/dist/cjs/src/generated/waterx_rule/waterx_rule.js +8 -154
  5. package/dist/cjs/src/oracle/aggregate.d.ts +21 -21
  6. package/dist/cjs/src/oracle/aggregate.js +118 -69
  7. package/dist/cjs/src/oracle/config.d.ts +38 -72
  8. package/dist/cjs/src/oracle/config.js +0 -56
  9. package/dist/cjs/src/oracle/host.d.ts +24 -20
  10. package/dist/cjs/src/oracle/index.d.ts +5 -3
  11. package/dist/cjs/src/oracle/index.js +31 -8
  12. package/dist/cjs/src/oracle/price-update-rule.d.ts +13 -6
  13. package/dist/cjs/src/oracle/price-update-rule.js +3 -3
  14. package/dist/cjs/src/oracle/pyth.d.ts +44 -0
  15. package/dist/cjs/src/oracle/pyth.js +48 -6
  16. package/dist/cjs/src/oracle/read-plane.d.ts +70 -0
  17. package/dist/cjs/src/oracle/read-plane.js +78 -0
  18. package/dist/cjs/src/oracle/rule-registry.d.ts +6 -4
  19. package/dist/cjs/src/oracle/rule-registry.js +6 -4
  20. package/dist/cjs/src/oracle/rules/pyth-core-rule.js +4 -4
  21. package/dist/cjs/src/oracle/rules/pyth-lazer-rule.d.ts +21 -0
  22. package/dist/cjs/src/oracle/rules/pyth-lazer-rule.js +29 -4
  23. package/dist/cjs/src/oracle/rules/pyth-rule.js +5 -4
  24. package/dist/cjs/src/oracle/rules/waterx-rule.d.ts +42 -5
  25. package/dist/cjs/src/oracle/rules/waterx-rule.js +57 -17
  26. package/dist/cjs/src/perp/client.d.ts +40 -27
  27. package/dist/cjs/src/perp/client.js +28 -20
  28. package/dist/cjs/src/perp/config.d.ts +6 -6
  29. package/dist/cjs/src/perp/config.js +12 -12
  30. package/dist/cjs/src/perp/index.d.ts +3 -3
  31. package/dist/cjs/src/perp/index.js +7 -4
  32. package/dist/cjs/src/unified-client.d.ts +14 -9
  33. package/dist/cjs/src/unified-client.js +2 -2
  34. package/dist/src/account/config.d.ts +3 -2
  35. package/dist/src/generated/waterx_rule/waterx_rule.d.ts +7 -134
  36. package/dist/src/generated/waterx_rule/waterx_rule.js +7 -143
  37. package/dist/src/oracle/aggregate.d.ts +21 -21
  38. package/dist/src/oracle/aggregate.js +118 -69
  39. package/dist/src/oracle/config.d.ts +38 -72
  40. package/dist/src/oracle/config.js +1 -55
  41. package/dist/src/oracle/host.d.ts +24 -20
  42. package/dist/src/oracle/index.d.ts +5 -3
  43. package/dist/src/oracle/index.js +25 -10
  44. package/dist/src/oracle/price-update-rule.d.ts +13 -6
  45. package/dist/src/oracle/price-update-rule.js +3 -3
  46. package/dist/src/oracle/pyth.d.ts +44 -0
  47. package/dist/src/oracle/pyth.js +45 -5
  48. package/dist/src/oracle/read-plane.d.ts +70 -0
  49. package/dist/src/oracle/read-plane.js +74 -0
  50. package/dist/src/oracle/rule-registry.d.ts +6 -4
  51. package/dist/src/oracle/rule-registry.js +6 -4
  52. package/dist/src/oracle/rules/pyth-core-rule.js +5 -5
  53. package/dist/src/oracle/rules/pyth-lazer-rule.d.ts +21 -0
  54. package/dist/src/oracle/rules/pyth-lazer-rule.js +28 -3
  55. package/dist/src/oracle/rules/pyth-rule.js +5 -4
  56. package/dist/src/oracle/rules/waterx-rule.d.ts +42 -5
  57. package/dist/src/oracle/rules/waterx-rule.js +53 -14
  58. package/dist/src/perp/client.d.ts +40 -27
  59. package/dist/src/perp/client.js +29 -21
  60. package/dist/src/perp/config.d.ts +6 -6
  61. package/dist/src/perp/config.js +11 -9
  62. package/dist/src/perp/index.d.ts +3 -3
  63. package/dist/src/perp/index.js +2 -2
  64. package/dist/src/unified-client.d.ts +14 -9
  65. package/dist/src/unified-client.js +2 -2
  66. package/package.json +1 -1
@@ -4,7 +4,7 @@
4
4
  * `aggregateTicker` appends per waterx-routed ticker. Pulls one enclave-signed
5
5
  * batch envelope covering every requested ticker from the quote-center
6
6
  * (`GET /v1/quotes/update?symbols=…`, endpoint from `host.waterx` — the
7
- * `waterxEndpoint`/`waterxFetch` create options — else `WATERX_DEFAULTS`), then —
7
+ * `waterxEndpoint`/`waterxFetch` create options — else its own `WATERX_INFRA`), then —
8
8
  * unlike Pyth Lazer, whose verify is a single shared PTB step — verifies AND
9
9
  * feeds in ONE `waterx_rule::collect_batch_latest` call per collector (the Move
10
10
  * API bundles the two). So `buildUpdateCalls` emits nothing and the signed
@@ -13,12 +13,47 @@
13
13
  * `collect_batch_latest` is the dual-rule path: it feeds the item matching
14
14
  * `collector.symbol()` WITHOUT aggregating, so a waterx-routed ticker composes
15
15
  * onto the same collector as Pyth/Supra (compose-then-aggregate). On-chain a
16
- * freshness miss / replayed timestamp ABSTAINS (the other weighted rules
17
- * cover); a config/integrity mismatch or bad signature aborts.
16
+ * FRESHNESS miss ABSTAINS (the other weighted rules cover); a config/
17
+ * integrity mismatch, bad signature, future timestamp — or a REPLAYED signed
18
+ * timestamp — ABORTS (`EReplayedSignature`, audit F-014: a signed tuple is
19
+ * single-use per symbol, enforced by a per-symbol high-water mark BEFORE any
20
+ * weight arbitration). Consequence for concurrent builds: two PTBs carrying
21
+ * the same envelope for the same symbol cannot both land — the second aborts
22
+ * even if the rule is unweighted for that ticker. Never share one fetched
23
+ * envelope across builds that may execute concurrently for the same symbol.
18
24
  */
19
25
  import type { Transaction, TransactionArgument } from "@mysten/sui/transactions";
26
+ import type { Network } from "../../constants.ts";
20
27
  import type { OracleHost } from "../host.ts";
21
28
  import { type PriceUpdateRule, type RuleUpdateData } from "../price-update-rule.ts";
29
+ /** The single signing intent the quote-center emits — exported so read-plane
30
+ * consumers can mirror the rule's own envelope intent check (a mispointed
31
+ * endpoint must be rejected by reads exactly as tx-builds reject it). */
32
+ export declare const BATCH_PRICE_INTENT = 1;
33
+ /**
34
+ * WaterX quote-center external infra — owned by THIS source, by network.
35
+ * Mirrors `PYTH_CORE_INFRA` (oracle/pyth.ts) and `LAZER_INFRA`
36
+ * (rules/pyth-lazer-rule.ts): per-network constants for infrastructure the
37
+ * source's operator runs, co-located with the only rule that reads them — no
38
+ * other oracle source ever touches a quote-center endpoint. Public read (no
39
+ * auth), so there is no api_key. `endpoint` has no trailing slash — the rule
40
+ * appends the path.
41
+ *
42
+ * These are the DEFAULTS behind the caller's `client.waterx` access slice
43
+ * (`waterxEndpoint` / `waterxFetch` create options) — the browser-CORS proxy
44
+ * hook, since this is the one source fetched from the page.
45
+ */
46
+ export declare const WATERX_INFRA: Record<Network, {
47
+ endpoint: string;
48
+ }>;
49
+ /**
50
+ * The waterx source's quote-center base for `network` — the ONE accessor
51
+ * consumers (BE/FE read planes) use when, and only when, their own
52
+ * `ORACLE_SOURCE` resolves to `'waterx_rule'`. Mirrors
53
+ * `pythCoreHermesEndpoint`. Under any other source the read endpoint is that
54
+ * source's own configuration — never this one.
55
+ */
56
+ export declare function waterxQuoteCenterEndpoint(network: Network): string;
22
57
  /**
23
58
  * One item inside a signed batch payload, mirroring the quote-center
24
59
  * `/v1/quotes/update` JSON 1:1 (snake_case). The u64 integer fields are the
@@ -82,8 +117,10 @@ export declare function waterxEnvelopeOf(data: RuleUpdateData): WaterxSignedEnve
82
117
  * per item, the exact shape the enclave signed) and contribute the price for
83
118
  * `collector.symbol()` to the collector. One collect call re-verifies the batch
84
119
  * signature and picks this collector's symbol out of the batch; on-chain it
85
- * abstains (records `none`) instead of aborting when the symbol is stale,
86
- * absent from the batch, or its timestamp was already accepted (replay).
120
+ * abstains (records `none`) when the symbol is stale or absent from the batch,
121
+ * but ABORTS `EReplayedSignature` when the symbol's signed timestamp was
122
+ * already accepted (per-symbol high-water mark, audit F-014) — see the module
123
+ * header for the concurrent-build consequence.
87
124
  */
88
125
  export declare function feedWaterxRule(tx: Transaction, host: OracleHost, collector: TransactionArgument, envelope: WaterxSignedEnvelope): void;
89
126
  export declare const WaterxRule: PriceUpdateRule;
@@ -5,7 +5,7 @@
5
5
  * `aggregateTicker` appends per waterx-routed ticker. Pulls one enclave-signed
6
6
  * batch envelope covering every requested ticker from the quote-center
7
7
  * (`GET /v1/quotes/update?symbols=…`, endpoint from `host.waterx` — the
8
- * `waterxEndpoint`/`waterxFetch` create options — else `WATERX_DEFAULTS`), then —
8
+ * `waterxEndpoint`/`waterxFetch` create options — else its own `WATERX_INFRA`), then —
9
9
  * unlike Pyth Lazer, whose verify is a single shared PTB step — verifies AND
10
10
  * feeds in ONE `waterx_rule::collect_batch_latest` call per collector (the Move
11
11
  * API bundles the two). So `buildUpdateCalls` emits nothing and the signed
@@ -14,21 +14,56 @@
14
14
  * `collect_batch_latest` is the dual-rule path: it feeds the item matching
15
15
  * `collector.symbol()` WITHOUT aggregating, so a waterx-routed ticker composes
16
16
  * onto the same collector as Pyth/Supra (compose-then-aggregate). On-chain a
17
- * freshness miss / replayed timestamp ABSTAINS (the other weighted rules
18
- * cover); a config/integrity mismatch or bad signature aborts.
17
+ * FRESHNESS miss ABSTAINS (the other weighted rules cover); a config/
18
+ * integrity mismatch, bad signature, future timestamp — or a REPLAYED signed
19
+ * timestamp — ABORTS (`EReplayedSignature`, audit F-014: a signed tuple is
20
+ * single-use per symbol, enforced by a per-symbol high-water mark BEFORE any
21
+ * weight arbitration). Consequence for concurrent builds: two PTBs carrying
22
+ * the same envelope for the same symbol cannot both land — the second aborts
23
+ * even if the rule is unweighted for that ticker. Never share one fetched
24
+ * envelope across builds that may execute concurrently for the same symbol.
19
25
  */
20
26
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.WaterxRule = void 0;
27
+ exports.WaterxRule = exports.WATERX_INFRA = exports.BATCH_PRICE_INTENT = void 0;
28
+ exports.waterxQuoteCenterEndpoint = waterxQuoteCenterEndpoint;
22
29
  exports.parseSignedEnvelope = parseSignedEnvelope;
23
30
  exports.waterxEnvelopeOf = waterxEnvelopeOf;
24
31
  exports.feedWaterxRule = feedWaterxRule;
25
32
  const bcs_1 = require("@mysten/bcs");
26
33
  const waterx_rule_ts_1 = require("../../generated/waterx_rule/waterx_rule.js");
27
- const config_ts_1 = require("../config.js");
28
34
  const price_update_rule_ts_1 = require("../price-update-rule.js");
29
35
  const update_fetch_ts_1 = require("../update-fetch.js");
30
- /** The single signing intent (`BATCH_PRICE_INTENT`) the quote-center emits. */
31
- const BATCH_PRICE_INTENT = 1;
36
+ /** The single signing intent the quote-center emits — exported so read-plane
37
+ * consumers can mirror the rule's own envelope intent check (a mispointed
38
+ * endpoint must be rejected by reads exactly as tx-builds reject it). */
39
+ exports.BATCH_PRICE_INTENT = 1;
40
+ /**
41
+ * WaterX quote-center external infra — owned by THIS source, by network.
42
+ * Mirrors `PYTH_CORE_INFRA` (oracle/pyth.ts) and `LAZER_INFRA`
43
+ * (rules/pyth-lazer-rule.ts): per-network constants for infrastructure the
44
+ * source's operator runs, co-located with the only rule that reads them — no
45
+ * other oracle source ever touches a quote-center endpoint. Public read (no
46
+ * auth), so there is no api_key. `endpoint` has no trailing slash — the rule
47
+ * appends the path.
48
+ *
49
+ * These are the DEFAULTS behind the caller's `client.waterx` access slice
50
+ * (`waterxEndpoint` / `waterxFetch` create options) — the browser-CORS proxy
51
+ * hook, since this is the one source fetched from the page.
52
+ */
53
+ exports.WATERX_INFRA = {
54
+ MAINNET: { endpoint: "https://quote-center.waterx.app" },
55
+ TESTNET: { endpoint: "https://quote-center-staging.waterx.app" },
56
+ };
57
+ /**
58
+ * The waterx source's quote-center base for `network` — the ONE accessor
59
+ * consumers (BE/FE read planes) use when, and only when, their own
60
+ * `ORACLE_SOURCE` resolves to `'waterx_rule'`. Mirrors
61
+ * `pythCoreHermesEndpoint`. Under any other source the read endpoint is that
62
+ * source's own configuration — never this one.
63
+ */
64
+ function waterxQuoteCenterEndpoint(network) {
65
+ return exports.WATERX_INFRA[network].endpoint;
66
+ }
32
67
  /**
33
68
  * Shape check ONLY — the `kind` discriminant is checked separately by the
34
69
  * caller before this runs (mirrors the other rules' guard split), so a
@@ -90,18 +125,21 @@ function requireWaterxPackage(host) {
90
125
  return entry;
91
126
  }
92
127
  /**
93
- * Resolve the quote-center infra for this host: the `waterxEndpoint` /
94
- * `waterxFetch` create options when the client carries them, else the network
95
- * default. The fetch policy falls back to the shared `pyth.fetch` policy so a
96
- * consumer that already tuned timeouts/retries once keeps them here.
128
+ * Resolve the quote-center infra for this host: each field independently from
129
+ * the caller's `client.waterx` access slice (`waterxEndpoint` / `waterxFetch`
130
+ * create options) when set, else this source's own `WATERX_INFRA` default /
131
+ * `fetchWithPolicy`'s built-ins. Deliberately NO fallback onto `pyth.fetch`
132
+ * or any other source's policy — sources stay fully independent.
97
133
  *
98
134
  * This is the seam a browser consumer needs: the envelope is fetched FROM THE
99
135
  * PAGE, so a front end whose origin the quote-center does not allow (CORS)
100
136
  * points `endpoint` at a same-origin proxy, or supplies its own `fetchImpl`.
101
137
  */
102
138
  function resolveWaterxInfra(host) {
103
- const infra = host.waterx ?? config_ts_1.WATERX_DEFAULTS[host.network];
104
- return { endpoint: infra.endpoint, fetch: infra.fetch ?? host.pyth.fetch };
139
+ return {
140
+ endpoint: host.waterx?.endpoint ?? exports.WATERX_INFRA[host.network].endpoint,
141
+ fetch: host.waterx?.fetch,
142
+ };
105
143
  }
106
144
  /**
107
145
  * Pull one enclave-signed batch envelope covering `symbols` from the
@@ -136,8 +174,8 @@ async function fetchWaterxSignedUpdate(endpoint, symbols, fetchOpts) {
136
174
  // Parse from raw text (not res.json()) so the u64 fields are decoded exact as
137
175
  // bigint — see parseSignedEnvelope. Malformed-shape check lives there.
138
176
  const envelope = parseSignedEnvelope(await res.text());
139
- if (envelope.intent !== BATCH_PRICE_INTENT) {
140
- throw new Error(`WaterX quote-center returned intent ${envelope.intent}, expected BATCH_PRICE_INTENT ${BATCH_PRICE_INTENT}`);
177
+ if (envelope.intent !== exports.BATCH_PRICE_INTENT) {
178
+ throw new Error(`WaterX quote-center returned intent ${envelope.intent}, expected BATCH_PRICE_INTENT ${exports.BATCH_PRICE_INTENT}`);
141
179
  }
142
180
  return envelope;
143
181
  }
@@ -157,8 +195,10 @@ function decodeSig(hex) {
157
195
  * per item, the exact shape the enclave signed) and contribute the price for
158
196
  * `collector.symbol()` to the collector. One collect call re-verifies the batch
159
197
  * signature and picks this collector's symbol out of the batch; on-chain it
160
- * abstains (records `none`) instead of aborting when the symbol is stale,
161
- * absent from the batch, or its timestamp was already accepted (replay).
198
+ * abstains (records `none`) when the symbol is stale or absent from the batch,
199
+ * but ABORTS `EReplayedSignature` when the symbol's signed timestamp was
200
+ * already accepted (per-symbol high-water mark, audit F-014) — see the module
201
+ * header for the concurrent-build consequence.
162
202
  */
163
203
  function feedWaterxRule(tx, host, collector, envelope) {
164
204
  const wr = requireWaterxPackage(host);
@@ -13,35 +13,48 @@
13
13
  import { BaseLineClient } from "../base-client.ts";
14
14
  import type { OracleSource } from "../oracle/price-update-rule.ts";
15
15
  import type { FetchPolicy } from "../oracle/update-fetch.ts";
16
- import { type LoadConfigOptions, type PythFetchPolicy, type PythInfraConfig, type WaterXConfig, type WaterxInfraConfig, type WormholeInfraConfig } from "./config.ts";
16
+ import { type LoadConfigOptions, type PythAccessConfig, type PythFetchPolicy, type WaterxAccessConfig, type WaterXConfig, type WormholeInfraConfig } from "./config.ts";
17
17
  import type { Network } from "./constants.ts";
18
18
  export interface CreateClientOptions extends LoadConfigOptions {
19
19
  grpcUrl?: string;
20
20
  /**
21
- * Which oracle price-update source drives `refreshOraclePrices`. Each source
22
- * is self-contained (own infra + config) with NO cross-source fallback:
21
+ * Which oracle price-update source drives `refreshOraclePrices`. REQUIRED
22
+ * there is NO default source: every deployment names its source explicitly
23
+ * (wire it from your own env var, e.g. `ORACLE_SOURCE`). Each source is
24
+ * self-contained (own infra, own endpoints, own config) with NO cross-source
25
+ * fallback:
23
26
  *
24
- * - `'pyth_rule'` (default) — Pyth Core `pyth_rule` updates (Hermes VAA +
25
- * per-feed update fees), Core state + keyless Core Hermes.
27
+ * - `'pyth_rule'` — Pyth Core `pyth_rule` updates (Hermes VAA + per-feed
28
+ * update fees); Core state + Hermes endpoint live in the source's own
29
+ * `PYTH_CORE_INFRA` table.
26
30
  * - `'pyth_lazer_rule'` — Pyth Lazer signed updates (ONE `leEcdsa` verify
27
31
  * per PTB, no per-feed fees); needs `packages.pyth_lazer_rule` with feeds
28
- * and a `pythApiKey` (Lazer is auth-first).
32
+ * and a `pythApiKey` (Lazer is auth-first); Lazer infra lives in the
33
+ * source's own `LAZER_INFRA` table.
29
34
  * - `'waterx_rule'` — the first-party WaterX quote-center (Nautilus-TEE,
30
35
  * ed25519-signed batches): ONE envelope covering the build's tickers,
31
36
  * verified AND fed by a single `collect_batch_latest` per collector. No
32
37
  * credential and no per-update fee; needs `packages.waterx_rule` with
33
- * feeds. Endpoint/transport via {@link CreateClientOptions.waterxEndpoint}
34
- * / {@link CreateClientOptions.waterxFetch} — the browser-CORS proxy hook,
38
+ * feeds. Quote-center infra lives in the source's own `WATERX_INFRA`
39
+ * table; endpoint/transport overridable via
40
+ * {@link CreateClientOptions.waterxEndpoint} /
41
+ * {@link CreateClientOptions.waterxFetch} — the browser-CORS proxy hook,
35
42
  * since this is the one source fetched from the page.
36
43
  *
37
44
  * The name is source-neutral on purpose — a source need not be Pyth (as
38
45
  * `'waterx_rule'` shows). Selecting a source whose feed for a requested
39
46
  * ticker is absent is NOT an error at client creation: it fails at tx-build
40
- * time for exactly those tickers (see `refreshOraclePrices`). The Pyth Core
41
- * infra is fixed per network by `PYTH_DEFAULTS` and is not
42
- * deployment-overridable.
47
+ * time for exactly those tickers (see `refreshOraclePrices`).
48
+ *
49
+ * Accepts a SINGLE source or a LIST. A list means every listed source's
50
+ * data is fetched and fed in one build — required whenever the on-chain
51
+ * weight tables have more than one rule weighted (e.g. a Core→Pro or
52
+ * Pro+Waterx coexistence window): the chain drops unweighted contributions
53
+ * (harmless) but aborts on a starved weighted rule, so the list must stay a
54
+ * SUPERSET of every ticker's weighted set. Order is meaningful to consumers
55
+ * (read-plane priority), not to the on-chain build.
43
56
  */
44
- oracleSource?: OracleSource;
57
+ oracleSource: OracleSource | OracleSource[];
45
58
  /**
46
59
  * Pyth Lazer access token (`Authorization: Bearer …`). Required under
47
60
  * `oracleSource: 'pyth_lazer_rule'` (Lazer is auth-first) and unused by
@@ -57,7 +70,7 @@ export interface CreateClientOptions extends LoadConfigOptions {
57
70
  pythFetch?: PythFetchPolicy;
58
71
  /**
59
72
  * Quote-center base URL for `oracleSource: 'waterx_rule'` — overrides the
60
- * per-network {@link WATERX_DEFAULTS} host.
73
+ * source's own per-network `WATERX_INFRA` default.
61
74
  *
62
75
  * This is the one source a BROWSER fetches itself (the signed envelope is
63
76
  * pulled from the page), so it is bound by the quote-center deployment's CORS
@@ -73,28 +86,28 @@ export interface CreateClientOptions extends LoadConfigOptions {
73
86
  waterxEndpoint?: string;
74
87
  /**
75
88
  * Retry/timeout policy — and `fetchImpl` — for the quote-center fetch (see
76
- * `fetchWithPolicy`). Optional: falls back to `pythFetch`, then to the
77
- * built-in defaults. Supply `fetchImpl` to route the request through your own
89
+ * `fetchWithPolicy`). Optional: falls back to the built-in defaults — never
90
+ * to `pythFetch` (sources stay independent). Supply `fetchImpl` to route the request through your own
78
91
  * transport (a proxying `fetch` wrapper, a non-global `fetch`, a test double).
79
92
  */
80
93
  waterxFetch?: FetchPolicy;
81
94
  }
82
95
  export declare class PerpClient extends BaseLineClient<WaterXConfig> {
83
- /** Pyth Core infra (fixed per network) plus the caller-supplied credential/policy. */
84
- pyth: PythInfraConfig;
96
+ /** Caller-supplied Pyth credential + fetch policy — NO infra; each source owns its own tables. */
97
+ pyth: PythAccessConfig;
85
98
  /**
86
- * WaterX quote-center infra for `oracleSource: 'waterx_rule'` — the network
87
- * default, overridden by the `waterxEndpoint` / `waterxFetch` create options
88
- * (a same-origin proxy or a custom `fetchImpl` for browser consumers).
99
+ * Caller-supplied quote-center overrides for `oracleSource: 'waterx_rule'`
100
+ * (`waterxEndpoint` / `waterxFetch` create options) — access-only, mirroring
101
+ * `pyth` above; unset fields resolve against the rule's own `WATERX_INFRA`.
89
102
  */
90
- waterx: WaterxInfraConfig;
103
+ waterx: WaterxAccessConfig;
91
104
  /** Wormhole infra for the credit bridge (network defaults unless overridden). */
92
105
  wormhole: WormholeInfraConfig;
93
- /** Selected oracle price-update source (`oracleSource` create option; default `'pyth_rule'`). */
94
- readonly oracleSource: OracleSource;
106
+ /** The fed set: `oracleSource` create option normalized to a non-empty, deduped list. */
107
+ readonly oracleSources: readonly OracleSource[];
95
108
  /** Canonical-schema lookups (delegated to below); no transport. */
96
109
  private readonly view;
97
- constructor(network: Network, config: WaterXConfig, opts?: CreateClientOptions);
110
+ constructor(network: Network, config: WaterXConfig, opts: CreateClientOptions);
98
111
  /**
99
112
  * Async factory: fetches the deployment config for `network` and returns
100
113
  * a ready-to-use client. Pass `opts.cache=true` to memoize the JSON.
@@ -103,9 +116,9 @@ export declare class PerpClient extends BaseLineClient<WaterXConfig> {
103
116
  * not an error at init — it surfaces at tx-build time for the specific
104
117
  * tickers that source can't serve (see `refreshOraclePrices`).
105
118
  */
106
- static create(network: Network, opts?: CreateClientOptions): Promise<PerpClient>;
107
- static mainnet(opts?: CreateClientOptions): Promise<PerpClient>;
108
- static testnet(opts?: CreateClientOptions): Promise<PerpClient>;
119
+ static create(network: Network, opts: CreateClientOptions): Promise<PerpClient>;
120
+ static mainnet(opts: CreateClientOptions): Promise<PerpClient>;
121
+ static testnet(opts: CreateClientOptions): Promise<PerpClient>;
109
122
  /** @see PerpConfigView.getMarket */
110
123
  getMarket(ticker: string): import("./config.ts").WaterxPerpMarketEntry;
111
124
  /** @see PerpConfigView.getAggregator */
@@ -17,41 +17,49 @@ const base_client_ts_1 = require("../base-client.js");
17
17
  const config_view_ts_1 = require("./config-view.js");
18
18
  const config_ts_1 = require("./config.js");
19
19
  class PerpClient extends base_client_ts_1.BaseLineClient {
20
- /** Pyth Core infra (fixed per network) plus the caller-supplied credential/policy. */
20
+ /** Caller-supplied Pyth credential + fetch policy — NO infra; each source owns its own tables. */
21
21
  pyth;
22
22
  /**
23
- * WaterX quote-center infra for `oracleSource: 'waterx_rule'` — the network
24
- * default, overridden by the `waterxEndpoint` / `waterxFetch` create options
25
- * (a same-origin proxy or a custom `fetchImpl` for browser consumers).
23
+ * Caller-supplied quote-center overrides for `oracleSource: 'waterx_rule'`
24
+ * (`waterxEndpoint` / `waterxFetch` create options) — access-only, mirroring
25
+ * `pyth` above; unset fields resolve against the rule's own `WATERX_INFRA`.
26
26
  */
27
27
  waterx;
28
28
  /** Wormhole infra for the credit bridge (network defaults unless overridden). */
29
29
  wormhole;
30
- /** Selected oracle price-update source (`oracleSource` create option; default `'pyth_rule'`). */
31
- oracleSource;
30
+ /** The fed set: `oracleSource` create option normalized to a non-empty, deduped list. */
31
+ oracleSources;
32
32
  /** Canonical-schema lookups (delegated to below); no transport. */
33
33
  view;
34
- constructor(network, config, opts = {}) {
34
+ constructor(network, config, opts) {
35
35
  super(network, config, opts);
36
- // Pyth Core infra is fixed per network NOT deployment-overridable and
37
- // NOT source-dependent (the pyth_lazer_rule source reads only api_key/fetch
38
- // from here). The api_key + fetch policy are caller-supplied at init: a
39
- // secret has no place in the canonical waterx-config JSON.
36
+ // Access-only slice: the api_key + fetch policy are caller-supplied at
37
+ // init (a secret has no place in the canonical waterx-config JSON). All
38
+ // endpoint/object-id infra is per-source, owned by the rule modules
39
+ // nothing infra-shaped lives on the client.
40
40
  this.pyth = {
41
- ...config_ts_1.PYTH_DEFAULTS[network],
42
41
  ...(opts.pythApiKey !== undefined ? { api_key: opts.pythApiKey } : {}),
43
42
  ...(opts.pythFetch !== undefined ? { fetch: opts.pythFetch } : {}),
44
43
  };
45
44
  this.wormhole = config.wormhole ?? config_ts_1.WORMHOLE_DEFAULTS[network];
46
- // Quote-center infra: network default, each field independently overridable
47
- // — a browser blocked by the quote-center's CORS allowlist swaps `endpoint`
48
- // for a same-origin proxy without touching anything else.
45
+ // Quote-center access slice: overrides only a browser blocked by the
46
+ // quote-center's CORS allowlist swaps `endpoint` for a same-origin proxy;
47
+ // unset fields resolve inside the rule against WATERX_INFRA[network].
49
48
  this.waterx = {
50
- ...config_ts_1.WATERX_DEFAULTS[network],
51
49
  ...(opts.waterxEndpoint !== undefined ? { endpoint: opts.waterxEndpoint } : {}),
52
50
  ...(opts.waterxFetch !== undefined ? { fetch: opts.waterxFetch } : {}),
53
51
  };
54
- this.oracleSource = opts.oracleSource ?? "pyth_rule";
52
+ // Normalize single-or-list to a deduped, order-preserving list. An empty
53
+ // list — or a nullish/empty entry, the shape an untyped caller produces
54
+ // by omitting the REQUIRED option — is a caller bug, not "no oracle":
55
+ // fail construction loudly instead of booting green and surfacing as
56
+ // `OracleSourceNotImplemented: undefined` at the first tx-build.
57
+ const sources = Array.isArray(opts.oracleSource) ? opts.oracleSource : [opts.oracleSource];
58
+ this.oracleSources = [...new Set(sources)];
59
+ if (this.oracleSources.length === 0 ||
60
+ this.oracleSources.some((source) => typeof source !== "string" || source.length === 0)) {
61
+ throw new Error(`oracleSource is REQUIRED and must name at least one source (got ${JSON.stringify(sources)})`);
62
+ }
55
63
  this.view = new config_view_ts_1.PerpConfigView(() => this.config, () => this.wormhole);
56
64
  }
57
65
  /**
@@ -62,14 +70,14 @@ class PerpClient extends base_client_ts_1.BaseLineClient {
62
70
  * not an error at init — it surfaces at tx-build time for the specific
63
71
  * tickers that source can't serve (see `refreshOraclePrices`).
64
72
  */
65
- static async create(network, opts = {}) {
73
+ static async create(network, opts) {
66
74
  const config = await (0, config_ts_1.loadConfig)(network, opts);
67
75
  return new PerpClient(network, config, opts);
68
76
  }
69
- static mainnet(opts = {}) {
77
+ static mainnet(opts) {
70
78
  return PerpClient.create("MAINNET", opts);
71
79
  }
72
- static testnet(opts = {}) {
80
+ static testnet(opts) {
73
81
  return PerpClient.create("TESTNET", opts);
74
82
  }
75
83
  // ========================================================
@@ -3,17 +3,17 @@
3
3
  * `waterx-config` repo (default: GitHub raw).
4
4
  *
5
5
  * The schema mirrors the canonical JSON layout one-to-one (each package
6
- * groups its own object IDs + per-ticker maps). External chain infra
7
- * (Pyth state, Wormhole state/core, Hermes & Wormholescan endpoints) is
8
- * **not** in the JSON — it lives in `PYTH_DEFAULTS` / `WORMHOLE_DEFAULTS`
9
- * below, keyed by network.
6
+ * groups its own object IDs + per-ticker maps). External chain infra is
7
+ * **not** in the JSON each oracle source owns its own per-network table
8
+ * (`PYTH_CORE_INFRA` in `oracle/pyth.ts`, `LAZER_INFRA` in
9
+ * `oracle/rules/pyth-lazer-rule.ts`); Wormhole bridge infra lives in
10
+ * `WORMHOLE_DEFAULTS` below.
10
11
  */
11
12
  import type { AccountPackages, BasePackageEntry, WormholeInfraConfig } from "../account/config.ts";
12
13
  import type { OraclePackages } from "../oracle/config.ts";
13
14
  import type { Network } from "./constants.ts";
14
15
  export type { AccountConfig, AccountPackages, BasePackageEntry, NativeCustodyAsset, NativeCustodyPackage, WaterxCreditPackage, WaterxReferralPackage, WithdrawalQueuePackage, WormholeBridgePackage, WormholeInfraConfig, WxaAccountPackage, } from "../account/config.ts";
15
- export type { ConstantFeedEntry, OracleConfig, OraclePackages, PythFetchPolicy, PythInfraConfig, PythLazerRulePackage, PythRulePackage, PythSponsorRulePackage, SupraFeedEntry, SupraRulePackage, WaterxConstantRulePackage, WaterxInfraConfig, WaterxOraclePackage, WaterxRulePackage, } from "../oracle/config.ts";
16
- export { PYTH_DEFAULTS, WATERX_DEFAULTS } from "../oracle/config.ts";
16
+ export type { ConstantFeedEntry, OracleConfig, OraclePackages, PythAccessConfig, PythFetchPolicy, PythLazerRulePackage, PythRulePackage, PythSponsorRulePackage, SupraFeedEntry, SupraRulePackage, WaterxConstantRulePackage, WaterxAccessConfig, WaterxOraclePackage, WaterxRulePackage, } from "../oracle/config.ts";
17
17
  export interface WaterxPerpMarketEntry {
18
18
  market: string;
19
19
  config: string;
@@ -4,29 +4,29 @@
4
4
  * `waterx-config` repo (default: GitHub raw).
5
5
  *
6
6
  * The schema mirrors the canonical JSON layout one-to-one (each package
7
- * groups its own object IDs + per-ticker maps). External chain infra
8
- * (Pyth state, Wormhole state/core, Hermes & Wormholescan endpoints) is
9
- * **not** in the JSON — it lives in `PYTH_DEFAULTS` / `WORMHOLE_DEFAULTS`
10
- * below, keyed by network.
7
+ * groups its own object IDs + per-ticker maps). External chain infra is
8
+ * **not** in the JSON each oracle source owns its own per-network table
9
+ * (`PYTH_CORE_INFRA` in `oracle/pyth.ts`, `LAZER_INFRA` in
10
+ * `oracle/rules/pyth-lazer-rule.ts`); Wormhole bridge infra lives in
11
+ * `WORMHOLE_DEFAULTS` below.
11
12
  */
12
13
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.WORMHOLE_DEFAULTS = exports.WATERX_DEFAULTS = exports.PYTH_DEFAULTS = void 0;
14
+ exports.WORMHOLE_DEFAULTS = void 0;
14
15
  exports.clearConfigCache = clearConfigCache;
15
16
  exports.loadConfig = loadConfig;
16
17
  const update_fetch_ts_1 = require("../oracle/update-fetch.js");
17
- var config_ts_1 = require("../oracle/config.js");
18
- Object.defineProperty(exports, "PYTH_DEFAULTS", { enumerable: true, get: function () { return config_ts_1.PYTH_DEFAULTS; } });
19
- Object.defineProperty(exports, "WATERX_DEFAULTS", { enumerable: true, get: function () { return config_ts_1.WATERX_DEFAULTS; } });
20
18
  // ============================================================================
21
- // Wormhole / Hermes — external chain infra, defaults by network
19
+ // Wormhole — external chain infra, defaults by network
22
20
  // ============================================================================
23
21
  //
24
- // `PythInfraConfig` + `PYTH_DEFAULTS` live in `oracle/config.ts` (shared infra)
25
- // and are re-exported at the top of this file.
22
+ // Oracle-source infra lives with each source (`PYTH_CORE_INFRA` in
23
+ // `oracle/pyth.ts`, `LAZER_INFRA` in `oracle/rules/pyth-lazer-rule.ts`);
24
+ // `client.pyth` is the caller-supplied access slice only (`PythAccessConfig`,
25
+ // re-exported at the top of this file).
26
26
  // `WormholeInfraConfig` is defined in `account/config.ts` (funding base) and
27
27
  // re-exported at the top of this file. `state_id` is the same shared Sui
28
28
  // Wormhole `State` object Pyth uses (kept in sync with
29
- // `PYTH_DEFAULTS[*].wormhole_state_id`).
29
+ // `PYTH_CORE_INFRA[*].wormhole_state_id`).
30
30
  exports.WORMHOLE_DEFAULTS = {
31
31
  MAINNET: {
32
32
  state_id: "0xaeab97f96cf9877fee2883315d459552b2b921edc16d7ceac6eab944dd88919c",
@@ -1,7 +1,7 @@
1
1
  export { PerpClient } from "./client.ts";
2
2
  export type { CreateClientOptions } from "./client.ts";
3
- export { PYTH_DEFAULTS, WORMHOLE_DEFAULTS, clearConfigCache, loadConfig } from "./config.ts";
4
- export type { BasePackageEntry, ConstantFeedEntry, WaterxReferralPackage, LoadConfigOptions, NativeCustodyAsset, NativeCustodyPackage, PythFetchPolicy, PythInfraConfig, PythLazerRulePackage, PythRulePackage, PythSponsorRulePackage, SupraFeedEntry, SupraRulePackage, TestnetFaucetPackage, WaterXConfig, WaterXPackages, WaterxCreditPackage, WaterxOraclePackage, WaterxPerpMarketEntry, WaterxPerpPackage, WaterxStakingPackage, WithdrawalQueuePackage, WlpPackage, WormholeBridgePackage, WormholeInfraConfig, WxaAccountPackage, } from "./config.ts";
3
+ export { WORMHOLE_DEFAULTS, clearConfigCache, loadConfig } from "./config.ts";
4
+ export type { BasePackageEntry, ConstantFeedEntry, WaterxReferralPackage, LoadConfigOptions, NativeCustodyAsset, NativeCustodyPackage, PythAccessConfig, PythFetchPolicy, PythLazerRulePackage, PythRulePackage, PythSponsorRulePackage, SupraFeedEntry, SupraRulePackage, TestnetFaucetPackage, WaterXConfig, WaterXPackages, WaterxCreditPackage, WaterxOraclePackage, WaterxPerpMarketEntry, WaterxPerpPackage, WaterxStakingPackage, WithdrawalQueuePackage, WlpPackage, WormholeBridgePackage, WormholeInfraConfig, WxaAccountPackage, } from "./config.ts";
5
5
  export { ACTION_ADD_PRE_ORDER, ACTION_CANCEL_ORDER, ACTION_CANCEL_PRE_ORDER, ACTION_CLOSE_POSITION, ACTION_DECREASE_POSITION, ACTION_DEPOSIT_COLLATERAL, ACTION_INCREASE_POSITION, ACTION_LIQUIDATE, ACTION_OPEN_POSITION, ACTION_PLACE_ORDER, ACTION_UPDATE_ORDER, ACTION_WITHDRAW_COLLATERAL, BPS_SCALE, DOUBLE_SCALE, DRY_RUN_SENDER, FLOAT_SCALE, ORDER_LIMIT_BUY, ORDER_LIMIT_SELL, ORDER_STOP_BUY, ORDER_STOP_SELL, ORDER_TAG_WILDCARD, PERM_ALL, PERM_ALL_TRADING, PERM_CANCEL_ORDER, PERM_CLOSE_POSITION, PERM_DECREASE_POSITION, PERM_DEPOSIT_COLLATERAL, PERM_INCREASE_POSITION, PERM_MINT_WLP, PERM_OPEN_POSITION, PERM_PLACE_ORDER, PERM_REDEEM_WLP, PERM_WITHDRAW_COLLATERAL, STAKING_PERM_DEPOSIT_STAKE, STAKING_PERM_REDEEM_STAKE, STAKING_PERM_CLAIM_REWARD, STAKING_PERM_ALL, MS_PER_MINUTE, MS_PER_HOUR, MS_PER_YEAR, SUI_DECIMALS, WLP_DECIMALS, COLLATERAL_DECIMALS, TOKEN_DECIMALS, } from "./constants.ts";
6
6
  export type { Network } from "./constants.ts";
7
7
  export { getMarketTickers, getCollateralAssets } from "../utils/config.ts";
@@ -13,7 +13,7 @@ export type { EstLiqPriceViewOpts } from "./liq-view.ts";
13
13
  export * from "./user/index.ts";
14
14
  export * from "./tx-builders.ts";
15
15
  export * from "./fetch.ts";
16
- export { FetchPolicyError, LazerApiKeyMissingError, OracleFeeSourceUnavailableError, OracleSourceNotImplementedError, PythCache, aggregateTicker, aggregateTickerWithConstant, aggregateTickerWithPyth, buildPythPriceUpdateCalls, fetchPriceFeedsUpdateData, refreshOraclePrices, updatePythPrices, } from "../oracle/index.ts";
16
+ export { FetchPolicyError, LazerApiKeyMissingError, OracleFeeSourceUnavailableError, OracleSourceNotImplementedError, PythCache, aggregateTicker, aggregateTickerWithConstant, aggregateTickerWithPyth, buildPythPriceUpdateCalls, fetchPriceFeedsUpdateData, pythCoreHermesEndpoint, pythProHermesEndpoint, resolveHermesReadEndpoint, waterxQuoteCenterEndpoint, refreshOraclePrices, updatePythPrices, } from "../oracle/index.ts";
17
17
  export type { FetchPolicy, OracleFeeSource, OracleSource, UpdateDataProvider, } from "../oracle/index.ts";
18
18
  export { fetchDepositVaa, fetchVaa, listBridgeWithdrawalVaas, listVaasByEmitter, padEvmEmitter, toWormholescanEmitter, vaaBase64ToBytes, vaaBase64ToHex, vaaBytesToBase64, waitForVaa, } from "../account/funding/wormhole.ts";
19
19
  export type { VaaListItem, VaaResponse, WormholescanOptions } from "../account/funding/wormhole.ts";
@@ -36,14 +36,13 @@ var __importStar = (this && this.__importStar) || (function () {
36
36
  };
37
37
  })();
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.getMarketTickers = exports.TOKEN_DECIMALS = exports.COLLATERAL_DECIMALS = exports.WLP_DECIMALS = exports.SUI_DECIMALS = exports.MS_PER_YEAR = exports.MS_PER_HOUR = exports.MS_PER_MINUTE = exports.STAKING_PERM_ALL = exports.STAKING_PERM_CLAIM_REWARD = exports.STAKING_PERM_REDEEM_STAKE = exports.STAKING_PERM_DEPOSIT_STAKE = exports.PERM_WITHDRAW_COLLATERAL = exports.PERM_REDEEM_WLP = exports.PERM_PLACE_ORDER = exports.PERM_OPEN_POSITION = exports.PERM_MINT_WLP = exports.PERM_INCREASE_POSITION = exports.PERM_DEPOSIT_COLLATERAL = exports.PERM_DECREASE_POSITION = exports.PERM_CLOSE_POSITION = exports.PERM_CANCEL_ORDER = exports.PERM_ALL_TRADING = exports.PERM_ALL = exports.ORDER_TAG_WILDCARD = exports.ORDER_STOP_SELL = exports.ORDER_STOP_BUY = exports.ORDER_LIMIT_SELL = exports.ORDER_LIMIT_BUY = exports.FLOAT_SCALE = exports.DRY_RUN_SENDER = exports.DOUBLE_SCALE = exports.BPS_SCALE = exports.ACTION_WITHDRAW_COLLATERAL = exports.ACTION_UPDATE_ORDER = exports.ACTION_PLACE_ORDER = exports.ACTION_OPEN_POSITION = exports.ACTION_LIQUIDATE = exports.ACTION_INCREASE_POSITION = exports.ACTION_DEPOSIT_COLLATERAL = exports.ACTION_DECREASE_POSITION = exports.ACTION_CLOSE_POSITION = exports.ACTION_CANCEL_PRE_ORDER = exports.ACTION_CANCEL_ORDER = exports.ACTION_ADD_PRE_ORDER = exports.loadConfig = exports.clearConfigCache = exports.WORMHOLE_DEFAULTS = exports.PYTH_DEFAULTS = exports.PerpClient = void 0;
40
- exports.vaaBase64ToHex = exports.vaaBase64ToBytes = exports.toWormholescanEmitter = exports.padEvmEmitter = exports.listVaasByEmitter = exports.listBridgeWithdrawalVaas = exports.fetchVaa = exports.fetchDepositVaa = exports.updatePythPrices = exports.refreshOraclePrices = exports.fetchPriceFeedsUpdateData = exports.buildPythPriceUpdateCalls = exports.aggregateTickerWithPyth = exports.aggregateTickerWithConstant = exports.aggregateTicker = exports.PythCache = exports.OracleSourceNotImplementedError = exports.OracleFeeSourceUnavailableError = exports.LazerApiKeyMissingError = exports.FetchPolicyError = exports.calcEstLiqPriceRawFromView = exports.formatFundingInterval = exports.rawPrice = exports.decodeFundingIndexDelta = exports.calcWlpRedeemOut = exports.calcWlpPrice = exports.calcWlpMintOut = exports.calcWlpIncentiveApy = exports.calcViewEstLiqFeesUsd = exports.calcUnrealizedPnl = exports.calcTotalTradingFeeRate = exports.calcTokenUtilizationBps = exports.calcRealLiqNetCostUsd = exports.calcPositionBorrowFee = exports.calcNotional = exports.calcMaxReducibleCollateralUsd = exports.calcLeverage = exports.calcImpactFeeRate = exports.calcFundingRate = exports.calcFundingFeeUsd = exports.calcFee = exports.calcEstLiqPriceRaw = exports.calcEstLiqPrice = exports.calcEffectiveCollateralUsd = exports.calcDynamicFeeBps = exports.calcBorrowRateAccrual = exports.calcBorrowRate = exports.annualizeFundingRate = exports.annualizedApyFromRatio = exports.getCollateralAssets = void 0;
41
- exports.withdrawalQueueCalls = exports.nativeCustodyCalls = exports.referralCalls = exports.pythSponsorRuleCalls = exports.pythRuleCalls = exports.oracleCalls = exports.stakingCalls = exports.wxaAccountCalls = exports.viewCalls = exports.lpPoolCalls = exports.tradingCalls = exports.MarketConfigBcs = exports.MarketBcs = exports.OrderBcs = exports.PositionBcs = exports.TokenPoolDataBcs = exports.RedeemRequestDataBcs = exports.PositionDataBcs = exports.PoolDataBcs = exports.OrderDataBcs = exports.MarketDataBcs = exports.GlobalConfigDataBcs = exports.AccountDataBcs = exports.waitForVaa = exports.vaaBytesToBase64 = void 0;
39
+ exports.getCollateralAssets = exports.getMarketTickers = exports.TOKEN_DECIMALS = exports.COLLATERAL_DECIMALS = exports.WLP_DECIMALS = exports.SUI_DECIMALS = exports.MS_PER_YEAR = exports.MS_PER_HOUR = exports.MS_PER_MINUTE = exports.STAKING_PERM_ALL = exports.STAKING_PERM_CLAIM_REWARD = exports.STAKING_PERM_REDEEM_STAKE = exports.STAKING_PERM_DEPOSIT_STAKE = exports.PERM_WITHDRAW_COLLATERAL = exports.PERM_REDEEM_WLP = exports.PERM_PLACE_ORDER = exports.PERM_OPEN_POSITION = exports.PERM_MINT_WLP = exports.PERM_INCREASE_POSITION = exports.PERM_DEPOSIT_COLLATERAL = exports.PERM_DECREASE_POSITION = exports.PERM_CLOSE_POSITION = exports.PERM_CANCEL_ORDER = exports.PERM_ALL_TRADING = exports.PERM_ALL = exports.ORDER_TAG_WILDCARD = exports.ORDER_STOP_SELL = exports.ORDER_STOP_BUY = exports.ORDER_LIMIT_SELL = exports.ORDER_LIMIT_BUY = exports.FLOAT_SCALE = exports.DRY_RUN_SENDER = exports.DOUBLE_SCALE = exports.BPS_SCALE = exports.ACTION_WITHDRAW_COLLATERAL = exports.ACTION_UPDATE_ORDER = exports.ACTION_PLACE_ORDER = exports.ACTION_OPEN_POSITION = exports.ACTION_LIQUIDATE = exports.ACTION_INCREASE_POSITION = exports.ACTION_DEPOSIT_COLLATERAL = exports.ACTION_DECREASE_POSITION = exports.ACTION_CLOSE_POSITION = exports.ACTION_CANCEL_PRE_ORDER = exports.ACTION_CANCEL_ORDER = exports.ACTION_ADD_PRE_ORDER = exports.loadConfig = exports.clearConfigCache = exports.WORMHOLE_DEFAULTS = exports.PerpClient = void 0;
40
+ exports.padEvmEmitter = exports.listVaasByEmitter = exports.listBridgeWithdrawalVaas = exports.fetchVaa = exports.fetchDepositVaa = exports.updatePythPrices = exports.refreshOraclePrices = exports.waterxQuoteCenterEndpoint = exports.resolveHermesReadEndpoint = exports.pythProHermesEndpoint = exports.pythCoreHermesEndpoint = exports.fetchPriceFeedsUpdateData = exports.buildPythPriceUpdateCalls = exports.aggregateTickerWithPyth = exports.aggregateTickerWithConstant = exports.aggregateTicker = exports.PythCache = exports.OracleSourceNotImplementedError = exports.OracleFeeSourceUnavailableError = exports.LazerApiKeyMissingError = exports.FetchPolicyError = exports.calcEstLiqPriceRawFromView = exports.formatFundingInterval = exports.rawPrice = exports.decodeFundingIndexDelta = exports.calcWlpRedeemOut = exports.calcWlpPrice = exports.calcWlpMintOut = exports.calcWlpIncentiveApy = exports.calcViewEstLiqFeesUsd = exports.calcUnrealizedPnl = exports.calcTotalTradingFeeRate = exports.calcTokenUtilizationBps = exports.calcRealLiqNetCostUsd = exports.calcPositionBorrowFee = exports.calcNotional = exports.calcMaxReducibleCollateralUsd = exports.calcLeverage = exports.calcImpactFeeRate = exports.calcFundingRate = exports.calcFundingFeeUsd = exports.calcFee = exports.calcEstLiqPriceRaw = exports.calcEstLiqPrice = exports.calcEffectiveCollateralUsd = exports.calcDynamicFeeBps = exports.calcBorrowRateAccrual = exports.calcBorrowRate = exports.annualizeFundingRate = exports.annualizedApyFromRatio = void 0;
41
+ exports.withdrawalQueueCalls = exports.nativeCustodyCalls = exports.referralCalls = exports.pythSponsorRuleCalls = exports.pythRuleCalls = exports.oracleCalls = exports.stakingCalls = exports.wxaAccountCalls = exports.viewCalls = exports.lpPoolCalls = exports.tradingCalls = exports.MarketConfigBcs = exports.MarketBcs = exports.OrderBcs = exports.PositionBcs = exports.TokenPoolDataBcs = exports.RedeemRequestDataBcs = exports.PositionDataBcs = exports.PoolDataBcs = exports.OrderDataBcs = exports.MarketDataBcs = exports.GlobalConfigDataBcs = exports.AccountDataBcs = exports.waitForVaa = exports.vaaBytesToBase64 = exports.vaaBase64ToHex = exports.vaaBase64ToBytes = exports.toWormholescanEmitter = void 0;
42
42
  // ======== Core ========
43
43
  var client_ts_1 = require("./client.js");
44
44
  Object.defineProperty(exports, "PerpClient", { enumerable: true, get: function () { return client_ts_1.PerpClient; } });
45
45
  var config_ts_1 = require("./config.js");
46
- Object.defineProperty(exports, "PYTH_DEFAULTS", { enumerable: true, get: function () { return config_ts_1.PYTH_DEFAULTS; } });
47
46
  Object.defineProperty(exports, "WORMHOLE_DEFAULTS", { enumerable: true, get: function () { return config_ts_1.WORMHOLE_DEFAULTS; } });
48
47
  Object.defineProperty(exports, "clearConfigCache", { enumerable: true, get: function () { return config_ts_1.clearConfigCache; } });
49
48
  Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return config_ts_1.loadConfig; } });
@@ -147,6 +146,10 @@ Object.defineProperty(exports, "aggregateTickerWithConstant", { enumerable: true
147
146
  Object.defineProperty(exports, "aggregateTickerWithPyth", { enumerable: true, get: function () { return index_ts_1.aggregateTickerWithPyth; } });
148
147
  Object.defineProperty(exports, "buildPythPriceUpdateCalls", { enumerable: true, get: function () { return index_ts_1.buildPythPriceUpdateCalls; } });
149
148
  Object.defineProperty(exports, "fetchPriceFeedsUpdateData", { enumerable: true, get: function () { return index_ts_1.fetchPriceFeedsUpdateData; } });
149
+ Object.defineProperty(exports, "pythCoreHermesEndpoint", { enumerable: true, get: function () { return index_ts_1.pythCoreHermesEndpoint; } });
150
+ Object.defineProperty(exports, "pythProHermesEndpoint", { enumerable: true, get: function () { return index_ts_1.pythProHermesEndpoint; } });
151
+ Object.defineProperty(exports, "resolveHermesReadEndpoint", { enumerable: true, get: function () { return index_ts_1.resolveHermesReadEndpoint; } });
152
+ Object.defineProperty(exports, "waterxQuoteCenterEndpoint", { enumerable: true, get: function () { return index_ts_1.waterxQuoteCenterEndpoint; } });
150
153
  Object.defineProperty(exports, "refreshOraclePrices", { enumerable: true, get: function () { return index_ts_1.refreshOraclePrices; } });
151
154
  Object.defineProperty(exports, "updatePythPrices", { enumerable: true, get: function () { return index_ts_1.updatePythPrices; } });
152
155
  // ======== Wormhole / Wormholescan utilities (credit bridge) ========
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Exposes three namespaces over the two product-line sub-clients:
5
5
  *
6
- * const client = await WaterXClient.create({ network: "TESTNET" });
6
+ * const client = await WaterXClient.create({ network: "TESTNET", oracleSource: "pyth_rule" });
7
7
  * client.account.createAccount(tx, { alias }); // -> shared waterx_account + funding
8
8
  * client.perp.placeOrderRequest(tx, params); // -> perp builder
9
9
  * client.predict.placeOrder(tx, params); // -> prediction builder
@@ -370,20 +370,25 @@ export interface ClientCreateOptions {
370
370
  /**
371
371
  * The perp line's oracle price-update source (perp-line only — the
372
372
  * prediction line has no oracle leg), forwarded to `PerpClient.create`.
373
+ * REQUIRED — there is NO default source: every deployment names its source
374
+ * explicitly (wire it from your own env var, e.g. `ORACLE_SOURCE`).
373
375
  * Source-neutral by design: a source need not be Pyth (see `'waterx_rule'`).
374
376
  *
375
- * - `'pyth_rule'` (default) — Pyth Core updates on Core infra.
377
+ * - `'pyth_rule'` — Pyth Core updates; infra in the source's own
378
+ * `PYTH_CORE_INFRA` table.
376
379
  * - `'pyth_lazer_rule'` — Pyth Lazer signed updates (pair with `pythApiKey`
377
- * and a config carrying `packages.pyth_lazer_rule`).
380
+ * and a config carrying `packages.pyth_lazer_rule`); infra in the
381
+ * source's own `LAZER_INFRA` table.
378
382
  * - `'waterx_rule'` — the first-party WaterX quote-center (Nautilus-TEE,
379
- * ed25519 signed batches; no credential, no per-update fee). Pair with
380
- * `waterxEndpoint` / `waterxFetch` when the browser needs a proxy.
383
+ * ed25519 signed batches; no credential, no per-update fee); infra in the
384
+ * source's own `WATERX_INFRA` table. Pair with `waterxEndpoint` /
385
+ * `waterxFetch` when the browser needs a proxy.
381
386
  *
382
387
  * Each source is self-contained with no cross-source fallback; selecting a
383
388
  * source whose feed for a ticker is absent fails at tx-build (not at init).
384
389
  * See perp `CreateClientOptions.oracleSource` for the full note.
385
390
  */
386
- oracleSource?: OracleSource;
391
+ oracleSource: OracleSource | OracleSource[];
387
392
  /**
388
393
  * Pyth Lazer access token, forwarded to the perp line. Required under
389
394
  * `oracleSource: 'pyth_lazer_rule'`, unused by `'pyth_rule'`. A SECRET —
@@ -395,7 +400,7 @@ export interface ClientCreateOptions {
395
400
  pythFetch?: PythFetchPolicy;
396
401
  /**
397
402
  * Quote-center base URL for `oracleSource: 'waterx_rule'`, forwarded to the
398
- * perp line — overrides the per-network `WATERX_DEFAULTS` host.
403
+ * perp line — overrides the source's own per-network `WATERX_INFRA` default.
399
404
  *
400
405
  * `waterx_rule` is the one source a BROWSER fetches itself, so it is bound by
401
406
  * the quote-center deployment's CORS allowlist: a front end whose origin is
@@ -406,7 +411,7 @@ export interface ClientCreateOptions {
406
411
  waterxEndpoint?: string;
407
412
  /**
408
413
  * Retry/timeout policy — and `fetchImpl` — for the perp line's quote-center
409
- * fetch. Falls back to `pythFetch`, then to the built-in defaults.
414
+ * fetch. Falls back to the built-in defaults — never to `pythFetch`.
410
415
  */
411
416
  waterxFetch?: FetchPolicy;
412
417
  /** Perp-line overrides (network, grpcUrl, waterxConfigUrl, cache, …). */
@@ -448,6 +453,6 @@ export declare class WaterXClient {
448
453
  * `waterx-config` JSON) and returns a ready client. Each line can target a
449
454
  * different network via `opts.perp.network` / `opts.predict.network`.
450
455
  */
451
- static create(opts?: ClientCreateOptions): Promise<WaterXClient>;
456
+ static create(opts: ClientCreateOptions): Promise<WaterXClient>;
452
457
  }
453
458
  export {};