@waterx/sdk 4.3.3 → 5.0.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 (145) hide show
  1. package/.claude/skills/waterx-sdk-integration/SKILL.md +41 -35
  2. package/README.md +81 -77
  3. package/dist/cjs/src/account/config.d.ts +3 -5
  4. package/dist/cjs/src/account/funding/wormhole.d.ts +1 -2
  5. package/dist/cjs/src/account/funding/wormhole.js +1 -2
  6. package/dist/cjs/src/oracle/aggregate.d.ts +45 -61
  7. package/dist/cjs/src/oracle/aggregate.js +138 -138
  8. package/dist/cjs/src/oracle/config.d.ts +35 -49
  9. package/dist/cjs/src/oracle/config.js +1 -1
  10. package/dist/cjs/src/oracle/host.d.ts +14 -19
  11. package/dist/cjs/src/oracle/host.js +3 -3
  12. package/dist/cjs/src/oracle/index.d.ts +25 -16
  13. package/dist/cjs/src/oracle/index.js +79 -66
  14. package/dist/cjs/src/oracle/price-update-rule.d.ts +104 -66
  15. package/dist/cjs/src/oracle/price-update-rule.js +24 -16
  16. package/dist/cjs/src/oracle/pyth-pro-history.d.ts +36 -0
  17. package/dist/cjs/src/oracle/pyth-pro-history.js +41 -0
  18. package/dist/cjs/src/oracle/read-plane.d.ts +35 -53
  19. package/dist/cjs/src/oracle/read-plane.js +26 -48
  20. package/dist/cjs/src/oracle/read-prices.d.ts +105 -0
  21. package/dist/cjs/src/oracle/read-prices.js +162 -0
  22. package/dist/cjs/src/oracle/rule-registry.d.ts +12 -12
  23. package/dist/cjs/src/oracle/rule-registry.js +12 -14
  24. package/dist/cjs/src/oracle/rules/pyth-lazer-rule.d.ts +24 -3
  25. package/dist/cjs/src/oracle/rules/pyth-lazer-rule.js +40 -20
  26. package/dist/cjs/src/oracle/rules/waterx-rule.d.ts +137 -12
  27. package/dist/cjs/src/oracle/rules/waterx-rule.js +318 -55
  28. package/dist/cjs/src/oracle/schedule.d.ts +109 -0
  29. package/dist/cjs/src/oracle/schedule.js +991 -0
  30. package/dist/cjs/src/oracle/source-list.d.ts +31 -27
  31. package/dist/cjs/src/oracle/source-list.js +43 -45
  32. package/dist/cjs/src/oracle/symbol-catalog.d.ts +54 -0
  33. package/dist/cjs/src/oracle/symbol-catalog.js +69 -0
  34. package/dist/cjs/src/oracle/update-fetch.d.ts +11 -15
  35. package/dist/cjs/src/oracle/update-fetch.js +12 -19
  36. package/dist/cjs/src/oracle/validate.d.ts +105 -0
  37. package/dist/cjs/src/oracle/validate.js +185 -0
  38. package/dist/cjs/src/oracle/weight-coverage.d.ts +79 -0
  39. package/dist/cjs/src/oracle/weight-coverage.js +173 -0
  40. package/dist/cjs/src/perp/client.d.ts +35 -52
  41. package/dist/cjs/src/perp/client.js +44 -17
  42. package/dist/cjs/src/perp/config-view.d.ts +5 -14
  43. package/dist/cjs/src/perp/config-view.js +5 -16
  44. package/dist/cjs/src/perp/config.d.ts +3 -3
  45. package/dist/cjs/src/perp/config.js +11 -13
  46. package/dist/cjs/src/perp/index.d.ts +4 -6
  47. package/dist/cjs/src/perp/index.js +35 -18
  48. package/dist/cjs/src/perp/tx-builders/common.d.ts +86 -48
  49. package/dist/cjs/src/perp/tx-builders/common.js +115 -47
  50. package/dist/cjs/src/perp/tx-builders/wlp.d.ts +3 -14
  51. package/dist/cjs/src/perp/tx-builders/wlp.js +6 -35
  52. package/dist/cjs/src/perp/tx-builders.d.ts +6 -5
  53. package/dist/cjs/src/perp/tx-builders.js +16 -10
  54. package/dist/cjs/src/unified-client.d.ts +8 -34
  55. package/dist/cjs/src/unified-client.js +3 -4
  56. package/dist/cjs/src/utils/config.d.ts +0 -8
  57. package/dist/cjs/src/utils/config.js +5 -13
  58. package/dist/src/account/config.d.ts +3 -5
  59. package/dist/src/account/funding/wormhole.d.ts +1 -2
  60. package/dist/src/account/funding/wormhole.js +1 -2
  61. package/dist/src/oracle/aggregate.d.ts +45 -61
  62. package/dist/src/oracle/aggregate.js +138 -137
  63. package/dist/src/oracle/config.d.ts +35 -49
  64. package/dist/src/oracle/config.js +1 -1
  65. package/dist/src/oracle/host.d.ts +14 -19
  66. package/dist/src/oracle/host.js +3 -3
  67. package/dist/src/oracle/index.d.ts +25 -16
  68. package/dist/src/oracle/index.js +55 -50
  69. package/dist/src/oracle/price-update-rule.d.ts +104 -66
  70. package/dist/src/oracle/price-update-rule.js +23 -16
  71. package/dist/src/oracle/pyth-pro-history.d.ts +36 -0
  72. package/dist/src/oracle/pyth-pro-history.js +38 -0
  73. package/dist/src/oracle/read-plane.d.ts +35 -53
  74. package/dist/src/oracle/read-plane.js +25 -47
  75. package/dist/src/oracle/read-prices.d.ts +105 -0
  76. package/dist/src/oracle/read-prices.js +156 -0
  77. package/dist/src/oracle/rule-registry.d.ts +12 -12
  78. package/dist/src/oracle/rule-registry.js +12 -14
  79. package/dist/src/oracle/rules/pyth-lazer-rule.d.ts +24 -3
  80. package/dist/src/oracle/rules/pyth-lazer-rule.js +39 -20
  81. package/dist/src/oracle/rules/waterx-rule.d.ts +137 -12
  82. package/dist/src/oracle/rules/waterx-rule.js +314 -56
  83. package/dist/src/oracle/schedule.d.ts +109 -0
  84. package/dist/src/oracle/schedule.js +985 -0
  85. package/dist/src/oracle/source-list.d.ts +31 -27
  86. package/dist/src/oracle/source-list.js +42 -43
  87. package/dist/src/oracle/symbol-catalog.d.ts +54 -0
  88. package/dist/src/oracle/symbol-catalog.js +65 -0
  89. package/dist/src/oracle/update-fetch.d.ts +11 -15
  90. package/dist/src/oracle/update-fetch.js +12 -18
  91. package/dist/src/oracle/validate.d.ts +105 -0
  92. package/dist/src/oracle/validate.js +177 -0
  93. package/dist/src/oracle/weight-coverage.d.ts +79 -0
  94. package/dist/src/oracle/weight-coverage.js +166 -0
  95. package/dist/src/perp/client.d.ts +35 -52
  96. package/dist/src/perp/client.js +45 -18
  97. package/dist/src/perp/config-view.d.ts +5 -14
  98. package/dist/src/perp/config-view.js +5 -16
  99. package/dist/src/perp/config.d.ts +3 -3
  100. package/dist/src/perp/config.js +11 -13
  101. package/dist/src/perp/index.d.ts +4 -6
  102. package/dist/src/perp/index.js +11 -5
  103. package/dist/src/perp/tx-builders/common.d.ts +86 -48
  104. package/dist/src/perp/tx-builders/common.js +114 -48
  105. package/dist/src/perp/tx-builders/wlp.d.ts +3 -14
  106. package/dist/src/perp/tx-builders/wlp.js +6 -35
  107. package/dist/src/perp/tx-builders.d.ts +6 -5
  108. package/dist/src/perp/tx-builders.js +15 -6
  109. package/dist/src/unified-client.d.ts +8 -34
  110. package/dist/src/unified-client.js +3 -4
  111. package/dist/src/utils/config.d.ts +0 -8
  112. package/dist/src/utils/config.js +5 -12
  113. package/package.json +1 -1
  114. package/dist/cjs/src/generated/pyth_sponsor_rule/deps/sui/balance.d.ts +0 -12
  115. package/dist/cjs/src/generated/pyth_sponsor_rule/deps/sui/balance.js +0 -17
  116. package/dist/cjs/src/generated/pyth_sponsor_rule/pyth_sponsor_rule.d.ts +0 -68
  117. package/dist/cjs/src/generated/pyth_sponsor_rule/pyth_sponsor_rule.js +0 -113
  118. package/dist/cjs/src/generated/waterx_pyth_rule/deps/sui/vec_map.d.ts +0 -36
  119. package/dist/cjs/src/generated/waterx_pyth_rule/deps/sui/vec_map.js +0 -31
  120. package/dist/cjs/src/generated/waterx_pyth_rule/pyth_rule.d.ts +0 -192
  121. package/dist/cjs/src/generated/waterx_pyth_rule/pyth_rule.js +0 -214
  122. package/dist/cjs/src/oracle/pyth.d.ts +0 -227
  123. package/dist/cjs/src/oracle/pyth.js +0 -652
  124. package/dist/cjs/src/oracle/rules/pyth-core-rule.d.ts +0 -15
  125. package/dist/cjs/src/oracle/rules/pyth-core-rule.js +0 -100
  126. package/dist/cjs/src/oracle/rules/pyth-rule.d.ts +0 -11
  127. package/dist/cjs/src/oracle/rules/pyth-rule.js +0 -29
  128. package/dist/cjs/src/oracle/rules/sponsor.d.ts +0 -32
  129. package/dist/cjs/src/oracle/rules/sponsor.js +0 -56
  130. package/dist/src/generated/pyth_sponsor_rule/deps/sui/balance.d.ts +0 -12
  131. package/dist/src/generated/pyth_sponsor_rule/deps/sui/balance.js +0 -14
  132. package/dist/src/generated/pyth_sponsor_rule/pyth_sponsor_rule.d.ts +0 -68
  133. package/dist/src/generated/pyth_sponsor_rule/pyth_sponsor_rule.js +0 -73
  134. package/dist/src/generated/waterx_pyth_rule/deps/sui/vec_map.d.ts +0 -36
  135. package/dist/src/generated/waterx_pyth_rule/deps/sui/vec_map.js +0 -27
  136. package/dist/src/generated/waterx_pyth_rule/pyth_rule.d.ts +0 -192
  137. package/dist/src/generated/waterx_pyth_rule/pyth_rule.js +0 -170
  138. package/dist/src/oracle/pyth.d.ts +0 -227
  139. package/dist/src/oracle/pyth.js +0 -638
  140. package/dist/src/oracle/rules/pyth-core-rule.d.ts +0 -15
  141. package/dist/src/oracle/rules/pyth-core-rule.js +0 -97
  142. package/dist/src/oracle/rules/pyth-rule.d.ts +0 -11
  143. package/dist/src/oracle/rules/pyth-rule.js +0 -26
  144. package/dist/src/oracle/rules/sponsor.d.ts +0 -32
  145. package/dist/src/oracle/rules/sponsor.js +0 -52
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Oracle-layer config schema — the package entries + config slice the shared
3
- * oracle layer (Pyth source + oracle rules + aggregate) reads. This is shared
3
+ * oracle layer (oracle rules + aggregate) reads. This is shared
4
4
  * infra, **not** the perp line: `perp/config.ts` imports these and
5
5
  * `WaterXPackages extends OraclePackages`; nothing here imports `perp/` or
6
6
  * `prediction/`. Snake_case mirrors the canonical `waterx-config` JSON 1:1.
@@ -12,35 +12,26 @@
12
12
  import type { BasePackageEntry } from "../account/config.ts";
13
13
  import type { BaseLineConfig } from "../base-client.ts";
14
14
  import type { FetchPolicy } from "./update-fetch.ts";
15
- export interface PythRulePackage extends BasePackageEntry {
16
- config: string;
17
- feeds: Record<string, {
18
- feed_id: string;
19
- price_info_object: string;
20
- }>;
21
- }
22
- export interface PythSponsorRulePackage extends BasePackageEntry {
23
- pyth_sponsor: string;
24
- }
25
15
  /**
26
16
  * `pyth_lazer_rule` deployment entry — present in the deployed testnet
27
17
  * `waterx-config` JSON. Read by `PythLazerRule` (`rules/pyth-lazer-rule.ts`):
28
18
  * `feeds` for ticker support + integer feed-id resolution, `state` for the
29
19
  * verify call, `published_at`/`config` for the per-ticker feed call.
30
20
  *
31
- * `enabled` mirrors the JSON field verbatim but MUST NOT be read for routing —
32
- * which rule prices a ticker is decided solely by the client's `oracleSource`
33
- * create option (see `OracleHost.oracleSources`), never by this flag or any
34
- * other config value.
21
+ * `enabled` switches the source off for this deployment: `deriveOracleSources`
22
+ * skips a block explicitly set to `false`. Absent means ON every live config
23
+ * omits it, and a published block with feeds is a wired source. Which rule
24
+ * prices a given TICKER is still decided by the feeds maps alone, never by a
25
+ * per-ticker flag.
35
26
  */
36
27
  export interface PythLazerRulePackage extends BasePackageEntry {
37
28
  config: string;
38
29
  state: string;
39
30
  enabled?: boolean;
40
- /** Oracle ticker → integer Pyth Lazer feed id (distinct id scheme from `pyth_rule`'s hex `feed_id`). */
31
+ /** Oracle ticker → integer Pyth Lazer feed id (distinct from the legacy Hermes hex id scheme). */
41
32
  feeds: Record<string, number>;
42
33
  }
43
- /** Per-ticker `constant_rule` feed entry (mirrors the `pyth_rule.feeds` shape). */
34
+ /** Per-ticker `constant_rule` feed entry (per-ticker map keyed by oracle ticker). */
44
35
  export interface ConstantFeedEntry {
45
36
  /**
46
37
  * Constant 1e9-scaled price (decimal string), mirroring the on-chain
@@ -54,13 +45,13 @@ export interface WaterxConstantRulePackage extends BasePackageEntry {
54
45
  /** Shared `constant_rule::Config` holding the per-ticker constant prices. */
55
46
  config: string;
56
47
  /**
57
- * Oracle ticker → constant feed entry, mirroring `pyth_rule.feeds`. A ticker
58
- * present here is fed via `constant_rule::feed` instead of (steady state) or
59
- * alongside (dual-feed) `pyth_rule::feed` (e.g. `USDCUSD → { price: "1000000000" }`).
48
+ * Oracle ticker → constant feed entry. A ticker present here is fed via
49
+ * `constant_rule::feed`, alone (constant-only) or alongside the live
50
+ * sources (e.g. `USDCUSD → { price: "1000000000" }`).
60
51
  */
61
52
  feeds?: Record<string, ConstantFeedEntry>;
62
53
  }
63
- /** Per-ticker `supra_rule` feed entry (mirrors the `pyth_rule.feeds` shape). */
54
+ /** Per-ticker `supra_rule` feed entry (per-ticker map keyed by oracle ticker). */
64
55
  export interface SupraFeedEntry {
65
56
  /** Supra pair id (mirrors the on-chain `Config`; informational off-chain). */
66
57
  pair_id: number;
@@ -84,8 +75,8 @@ export interface SupraRulePackage extends BasePackageEntry {
84
75
  }
85
76
  /**
86
77
  * Per-ticker `waterx_rule` feed entry. Keyed in `feeds` by the oracle **ticker**
87
- * (e.g. `"SUIUSD"`, the same key `pyth_rule.feeds` uses), so
88
- * `Object.keys(feeds)` is the SDK's supported-ticker set. The fields are
78
+ * (e.g. `"SUIUSD"`), so `Object.keys(feeds)` is the SDK's supported-ticker
79
+ * set. The fields are
89
80
  * informational off-chain — the SDK keys routing/support off the entry's
90
81
  * presence and pushes the enclave-signed price verbatim, never re-deriving it.
91
82
  */
@@ -103,8 +94,8 @@ export interface WaterxRuleFeedEntry {
103
94
  * `rules/waterx-rule.ts`), not this JSON.
104
95
  *
105
96
  * `enabled` mirrors the JSON field verbatim but MUST NOT be read for routing —
106
- * which rule prices a ticker is decided solely by the client's `oracleSource`
107
- * create option (see `OracleHost.oracleSources`), mirroring `pyth_lazer_rule`.
97
+ * which rule prices a ticker is decided solely by the client's derived fed set
98
+ * (see `OracleHost.oracleSources`), mirroring `pyth_lazer_rule`.
108
99
  */
109
100
  export interface WaterxRulePackage extends BasePackageEntry {
110
101
  /** Shared `waterx_rule::Config` (per-symbol on-chain feed_config). */
@@ -128,23 +119,21 @@ export interface WaterxOraclePackage extends BasePackageEntry {
128
119
  * structurally an oracle config.
129
120
  */
130
121
  export interface OraclePackages {
131
- pyth_rule: PythRulePackage;
132
- pyth_sponsor_rule?: PythSponsorRulePackage;
133
122
  /** See {@link PythLazerRulePackage} — typed only, not read for routing. */
134
123
  pyth_lazer_rule?: PythLazerRulePackage;
135
124
  constant_rule?: WaterxConstantRulePackage;
136
125
  supra_rule?: SupraRulePackage;
137
- /** See {@link WaterxRulePackage} — read by `WaterxRule` when `oracleSource` selects it. */
126
+ /** See {@link WaterxRulePackage} — read by `WaterxRule` when the config wires it. */
138
127
  waterx_rule?: WaterxRulePackage;
139
128
  waterx_oracle: WaterxOraclePackage;
140
129
  }
141
130
  /**
142
131
  * The caller-tunable subset of `fetchWithPolicy`'s policy exposed on the
143
132
  * `pythFetch` create option and `client.pyth.fetch` — the retry/timeout budget
144
- * for the off-chain Hermes (`fetchPriceFeedsUpdateData`) and Lazer
145
- * (`PythLazerRule`) update fetches. Deliberately narrower than the internal
146
- * `FetchPolicy` (no `retryDelayMs` / `apiKey` / `fetchImpl`). Both fetches fall
147
- * back to `fetchWithPolicy`'s defaults (15s timeout, 2 retries) when unset.
133
+ * for the off-chain Lazer (`PythLazerRule`) update fetch and the Lazer read
134
+ * executor (`readLazerPrices`). Deliberately narrower than the internal
135
+ * `FetchPolicy` (no `retryDelayMs` / `apiKey` / `fetchImpl`). Falls back to
136
+ * `fetchWithPolicy`'s defaults (15s timeout, 2 retries) when unset.
148
137
  */
149
138
  export type PythFetchPolicy = {
150
139
  timeoutMs?: number;
@@ -152,10 +141,9 @@ export type PythFetchPolicy = {
152
141
  };
153
142
  /**
154
143
  * `client.pyth` — ONLY the caller-supplied Pyth credential + fetch policy,
155
- * shared by the Pyth-family rules (`pyth_rule`, `pyth_lazer_rule`). It carries
156
- * NO endpoints and NO on-chain object ids: every oracle source owns its own
157
- * infra, co-located with its rule (`PYTH_CORE_INFRA` in `oracle/pyth.ts`;
158
- * the Lazer constants inside `rules/pyth-lazer-rule.ts`). A non-Pyth source
144
+ * read by `PythLazerRule`. It carries NO endpoints and NO on-chain object
145
+ * ids: every oracle source owns its own infra, co-located with its rule (the
146
+ * Lazer constants inside `rules/pyth-lazer-rule.ts`). A non-Pyth source
159
147
  * never reads this slice.
160
148
  * Nothing here is sourced from the canonical `waterx-config` JSON — a Bearer
161
149
  * secret has no place in a public CDN document.
@@ -164,22 +152,20 @@ export interface PythAccessConfig {
164
152
  /**
165
153
  * Pyth access token (`Authorization: Bearer …`). Required by
166
154
  * `PythLazerRule`'s signed-update fetch — Lazer is auth-first, so there is
167
- * no keyless default; absent when a lazer-routed fetch runs →
168
- * `LazerApiKeyMissing` is thrown at fetch time. Supplied via the
169
- * `pythApiKey` create option (the SDK never reads `process.env` or the
170
- * config JSON). As of the Pyth Pro migration (post-2026-08-18, per
171
- * https://docs.pyth.network/price-feeds/core/upgrade) this is ALSO required
172
- * for `pyth_rule`'s Hermes fetch (`fetchPriceFeedsUpdateData`) — see
173
- * `fetch` below.
155
+ * no keyless default; absent when a lazer-routed build runs →
156
+ * `LazerApiKeyMissing` is thrown by `refreshOraclePrices`'s credential
157
+ * pre-check (before any fetch) or by the rule's own fetch. Supplied via
158
+ * the `pythApiKey` create option (the SDK never reads `process.env` or the
159
+ * config JSON). The same key authenticates the Pyth Pro read/history
160
+ * surfaces (`readLazerPrices`, `fetchPythProHistory`).
174
161
  */
175
162
  api_key?: string;
176
163
  /**
177
- * Retry/timeout policy for the Hermes (`fetchPriceFeedsUpdateData`) and
178
- * Lazer (`PythLazerRule`) off-chain update fetches see `fetchWithPolicy`
179
- * (`./update-fetch.ts`) for the full policy (backoff, which statuses retry,
180
- * Bearer attachment). Supplied via the `pythFetch` create option. Optional:
181
- * both fetches default to `fetchWithPolicy`'s built-in defaults (15s
182
- * timeout, 2 retries) when unset.
164
+ * Retry/timeout policy for the Lazer (`PythLazerRule`) off-chain update
165
+ * fetch — see `fetchWithPolicy` (`./update-fetch.ts`) for the full policy
166
+ * (backoff, which statuses retry, Bearer attachment). Supplied via the
167
+ * `pythFetch` create option. Optional: defaults to `fetchWithPolicy`'s
168
+ * built-in defaults (15s timeout, 2 retries) when unset.
183
169
  */
184
170
  fetch?: PythFetchPolicy;
185
171
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Oracle-layer config schema — the package entries + config slice the shared
3
- * oracle layer (Pyth source + oracle rules + aggregate) reads. This is shared
3
+ * oracle layer (oracle rules + aggregate) reads. This is shared
4
4
  * infra, **not** the perp line: `perp/config.ts` imports these and
5
5
  * `WaterXPackages extends OraclePackages`; nothing here imports `perp/` or
6
6
  * `prediction/`. Snake_case mirrors the canonical `waterx-config` JSON 1:1.
@@ -3,16 +3,16 @@
3
3
  *
4
4
  * The oracle/refresh code used to take a concrete `PerpClient`, which fused the
5
5
  * shared oracle layer to the perp line. It only ever needs config-schema
6
- * lookups, the Pyth infra block, and a gRPC client — so it depends on this
7
- * structural interface instead. `PerpClient` satisfies it without any `implements`
8
- * clause, and a future `PredictClient` (or a test double) can too.
6
+ * lookups, the caller-supplied access slices, and a gRPC client — so it depends
7
+ * on this structural interface instead. `PerpClient` satisfies it without any
8
+ * `implements` clause, and a future `PredictClient` (or a test double) can too.
9
9
  */
10
10
  import type { SuiGrpcClient } from "@mysten/sui/grpc";
11
11
  import type { Network } from "../constants.ts";
12
12
  import type { OracleConfig, PythAccessConfig, WaterxAccessConfig } from "./config.ts";
13
13
  import type { OracleSource } from "./price-update-rule.ts";
14
14
  export interface OracleHost {
15
- /** Sui network this client targets — each rule keys its OWN infra table by it (`PYTH_CORE_INFRA`, `LAZER_INFRA`). */
15
+ /** Sui network this client targets — each rule keys its OWN infra table by it (`LAZER_INFRA`, `WATERX_INFRA`). */
16
16
  readonly network: Network;
17
17
  /** Oracle slice of the canonical `waterx-config` JSON (rule packages + per-ticker feeds). */
18
18
  readonly config: OracleConfig;
@@ -29,19 +29,19 @@ export interface OracleHost {
29
29
  * by the quote-center's CORS allowlist.
30
30
  */
31
31
  readonly waterx?: WaterxAccessConfig;
32
- /** gRPC client for the on-chain reads the Pyth update path needs. */
32
+ /** gRPC client for any on-chain reads an update path needs. */
33
33
  readonly grpcClient: SuiGrpcClient;
34
34
  /**
35
- * The FED SET for `refreshOraclePrices`'s update legs the REQUIRED
36
- * `oracleSource` create option normalized to a non-empty, deduped list.
37
- * Every listed source's data is fetched and fed in one build; the chain's
35
+ * The FED SET for `refreshOraclePrices`'s update legs, derived from the
36
+ * deployment config (`deriveOracleSources`) never a create option and
37
+ * never an env var.
38
+ *
39
+ * Every derived source's data is fetched and fed in one build; the chain's
38
40
  * per-ticker weight tables decide which contributions count (feeding an
39
- * unweighted rule is dropped on-chain; starving a weighted one aborts), so
40
- * during weight migrations the list stays a SUPERSET of every ticker's
41
- * weighted set. Routing is driven by this value ALONE: never by a config
42
- * JSON `enabled` flag and never by `process.env` — the SDK never reads it;
43
- * consumers (BE/FE) wire this option from their own env var
44
- * (`ORACLE_SOURCE`, comma-separated).
41
+ * unweighted rule is dropped on-chain; starving a weighted one aborts).
42
+ * Deriving the maximal wired set is therefore the fail-safe direction, and
43
+ * it keeps the fed set a SUPERSET of every ticker's weighted set through a
44
+ * weight migration for free.
45
45
  */
46
46
  readonly oracleSources: readonly OracleSource[];
47
47
  /** True when `ticker` is priced by `constant_rule`. */
@@ -52,9 +52,4 @@ export interface OracleHost {
52
52
  config: string;
53
53
  oracle_holder: string;
54
54
  } | undefined;
55
- /** The `pyth_rule.feeds` entry for `ticker` (`{ feed_id, price_info_object }`); throws if absent. */
56
- getPythFeed(ticker: string): {
57
- feed_id: string;
58
- price_info_object: string;
59
- };
60
55
  }
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * The oracle/refresh code used to take a concrete `PerpClient`, which fused the
5
5
  * shared oracle layer to the perp line. It only ever needs config-schema
6
- * lookups, the Pyth infra block, and a gRPC client — so it depends on this
7
- * structural interface instead. `PerpClient` satisfies it without any `implements`
8
- * clause, and a future `PredictClient` (or a test double) can too.
6
+ * lookups, the caller-supplied access slices, and a gRPC client — so it depends
7
+ * on this structural interface instead. `PerpClient` satisfies it without any
8
+ * `implements` clause, and a future `PredictClient` (or a test double) can too.
9
9
  */
10
10
  export {};
@@ -5,32 +5,41 @@
5
5
  * - `host.ts` — `OracleHost`, the narrow client slice this module reads.
6
6
  * - `update-fetch.ts` — `fetchWithPolicy`, the shared retry/timeout/Bearer resilience
7
7
  * wrapper every off-chain oracle (and config) fetch goes through.
8
- * - `pyth.ts` — Pyth as a price source: Hermes REST + on-chain update PTB.
9
8
  * - `price-update-rule.ts`— `PriceUpdateRule`, the fetch/build strategy port a rule
10
9
  * implements; `rule-registry.ts` + `aggregate.ts` wire
11
10
  * routing across rules.
12
- * - `rules/*` — one file per oracle rule (pyth / supra / constant / sponsor).
11
+ * - `rules/*` — one file per oracle rule (lazer / waterx / supra / constant).
13
12
  * - `aggregate.ts` — the orchestrator that feeds rules into a collector + aggregates.
14
- *
15
- * `pyth.ts` deliberately imports NO rule package — Pyth-the-source and the
16
- * rules that consume it are separate concerns.
13
+ * - `read-plane.ts` / `read-prices.ts` — per-source READ plans + their executors.
14
+ * - `validate.ts` consumers' boot-time coverage/credential asserts.
15
+ * - `schedule.ts` / `symbol-catalog.ts` / `pyth-pro-history.ts` market hours
16
+ * (parser + status walker), the Pyth Pro symbol catalog,
17
+ * and Pro chart history.
17
18
  */
18
19
  export type { OracleHost } from "./host.ts";
19
20
  export { FetchPolicyError, fetchWithPolicy, joinEndpointPath } from "./update-fetch.ts";
20
21
  export type { FetchPolicy } from "./update-fetch.ts";
21
- export { PythCache, fetchPriceFeedsUpdateData, endpointSupportedFeedIds, probeMissingFeeds, buildPythPriceUpdateCalls, pythCoreHermesEndpoint, pythProHermesEndpoint, PYTH_PRO_HERMES_ENDPOINT, updatePythPrices, HermesEndpointRejectedAllFeedsError, MISSING_FEED_MEMO_TTL_MS, OracleFeeSourceUnavailableError, } from "./pyth.ts";
22
- export type { OracleFeeSource } from "./pyth.ts";
23
- export type { PriceUpdateRule, PriceUpdateRuleKind, RuleUpdateData, RuleUpdateHandle, BuildUpdateOpts, OracleSource, UpdateDataProvider, } from "./price-update-rule.ts";
22
+ export type { PriceUpdateRule, PriceUpdateRuleKind, RuleUpdateData, RuleUpdateHandle, OracleCredentialRequirement, OracleCredentials, OracleSource, UpdateDataProvider, } from "./price-update-rule.ts";
23
+ export { oracleCredentialsFromHost } from "./price-update-rule.ts";
24
24
  export { ORACLE_SOURCES } from "./price-update-rule.ts";
25
- export { isOracleSource, parseOracleSourceList } from "./source-list.ts";
26
- export { resolveOracleReadPlan, resolveHermesReadEndpoint } from "./read-plane.ts";
25
+ export { deriveOracleSources } from "./source-list.ts";
26
+ export { resolveOracleReadPlan, readPlanTickers } from "./read-plane.ts";
27
27
  export type { OracleReadPlan } from "./read-plane.ts";
28
- export { PythCoreRule } from "./rules/pyth-core-rule.ts";
29
- export type { PythCoreUpdatePayload } from "./rules/pyth-core-rule.ts";
28
+ export { LazerNotEntitledError, readLazerPrices, readQuoteCenterPrices } from "./read-prices.ts";
29
+ export type { OraclePriceEntry } from "./read-prices.ts";
30
+ export { OracleTickerUnservedError, assertOracleWriteCoverage, missingOracleCredentials, partitionServableTickers, servableTickers, } from "./validate.ts";
31
+ export type { OracleCredentialKind } from "./validate.ts";
32
+ export { assertOracleWeightCoverage, readOracleWeightCoverage, OracleWeightCoverageError, OracleWeightUnreadableError, } from "./weight-coverage.ts";
33
+ export type { TickerWeightCoverage } from "./weight-coverage.ts";
30
34
  export { PythLazerRule, LazerApiKeyMissingError } from "./rules/pyth-lazer-rule.ts";
31
35
  export type { PythLazerUpdatePayload } from "./rules/pyth-lazer-rule.ts";
32
- export { WaterxRule, parseSignedEnvelope, parseSignedLeaves, BATCH_PRICE_INTENT, MERKLE_ROOT_INTENT, WATERX_INFRA, waterxQuoteCenterEndpoint, waterxLeavesOf, waterxEnvelopeOf, } from "./rules/waterx-rule.ts";
33
- export type { WaterxUpdatePayload, WaterxLeafPayload, WaterxEnvelopePayload, WaterxSignedEnvelope, WaterxSignedLeaf, WaterxBatchItem, } from "./rules/waterx-rule.ts";
36
+ export { WaterxRule, parseSignedEnvelope, parseSignedLeaves, BATCH_PRICE_INTENT, MERKLE_ROOT_INTENT, WATERX_INFRA, waterxQuoteCenterEndpoint, fetchWaterxSignedUpdate, fetchWaterxSignedLeaves, fetchWaterxUpdateData, pullWaterxQuotes, WATERX_MAX_PRICE_AGE_MS, isFreshWaterxEntry, waterxLeavesOf, waterxEnvelopeOf, } from "./rules/waterx-rule.ts";
37
+ export type { WaterxUpdatePayload, WaterxLeafPayload, WaterxEnvelopePayload, WaterxSignedEnvelope, WaterxSignedLeaf, WaterxBatchItem, LeafPull, } from "./rules/waterx-rule.ts";
34
38
  export { OracleSourceNotImplementedError, resolveOracleRule } from "./rule-registry.ts";
35
- export { aggregateTicker, aggregateTickerWithPyth, aggregateTickerWithConstant, refreshOraclePrices, } from "./aggregate.ts";
36
- export { openPythSponsorFund, reimbursePythSponsor } from "./rules/sponsor.ts";
39
+ export { aggregateTicker, aggregateTickerWithConstant, refreshOraclePrices } from "./aggregate.ts";
40
+ export type { OracleRefreshSummary } from "./aggregate.ts";
41
+ export { PythScheduleParseError, parsePythSchedule, getMarketStatus } from "./schedule.ts";
42
+ export type { HolidayDate, MarketStatusResult, ParsedPythSchedule, TradingHours, TradingSession, } from "./schedule.ts";
43
+ export { fetchPythSymbolCatalog } from "./symbol-catalog.ts";
44
+ export type { PythSymbolRecord } from "./symbol-catalog.ts";
45
+ export { fetchPythProHistory } from "./pyth-pro-history.ts";
@@ -5,77 +5,82 @@
5
5
  * - `host.ts` — `OracleHost`, the narrow client slice this module reads.
6
6
  * - `update-fetch.ts` — `fetchWithPolicy`, the shared retry/timeout/Bearer resilience
7
7
  * wrapper every off-chain oracle (and config) fetch goes through.
8
- * - `pyth.ts` — Pyth as a price source: Hermes REST + on-chain update PTB.
9
8
  * - `price-update-rule.ts`— `PriceUpdateRule`, the fetch/build strategy port a rule
10
9
  * implements; `rule-registry.ts` + `aggregate.ts` wire
11
10
  * routing across rules.
12
- * - `rules/*` — one file per oracle rule (pyth / supra / constant / sponsor).
11
+ * - `rules/*` — one file per oracle rule (lazer / waterx / supra / constant).
13
12
  * - `aggregate.ts` — the orchestrator that feeds rules into a collector + aggregates.
14
- *
15
- * `pyth.ts` deliberately imports NO rule package — Pyth-the-source and the
16
- * rules that consume it are separate concerns.
13
+ * - `read-plane.ts` / `read-prices.ts` — per-source READ plans + their executors.
14
+ * - `validate.ts` consumers' boot-time coverage/credential asserts.
15
+ * - `schedule.ts` / `symbol-catalog.ts` / `pyth-pro-history.ts` market hours
16
+ * (parser + status walker), the Pyth Pro symbol catalog,
17
+ * and Pro chart history.
17
18
  */
18
19
  // Shared fetch resilience wrapper — `FetchPolicyError` is re-exported (not
19
20
  // just the type) so a consumer (e.g. a BE prefetch cache) can `instanceof`
20
- // it off the failure `fetchPriceFeedsUpdateData` / `PythLazerRule` /
21
- // `loadConfig` surface, without a deep import of `./update-fetch.ts`.
22
- // `fetchWithPolicy` + `joinEndpointPath` are exported for consumers that hit
23
- // Hermes-compatible endpoints THEMSELVES (e.g. the BE's parsed latest-price
24
- // bootstrap and Pyth schedule readers): one shared Bearer/timeout/retry
25
- // policy and one base-path-safe URL join, instead of each caller re-rolling
26
- // them (the hand-rolled copies were how the Pro `/hermes` base path got
27
- // dropped and the Bearer went missing on sibling fetches).
21
+ // it off a failed rule fetch / `loadConfig` surface, without a deep import
22
+ // of `./update-fetch.ts`. `fetchWithPolicy` + `joinEndpointPath` are exported
23
+ // for consumers that hit oracle-adjacent endpoints THEMSELVES: one shared
24
+ // Bearer/timeout/retry policy and one base-path-safe URL join, instead of
25
+ // each caller re-rolling them (the hand-rolled copies were how base paths
26
+ // got dropped and Bearers went missing on sibling fetches).
28
27
  export { FetchPolicyError, fetchWithPolicy, joinEndpointPath } from "./update-fetch.js";
29
- // Pyth source `OracleFeeSourceUnavailableError` and
30
- // `HermesEndpointRejectedAllFeedsError` are re-exported (not just the types)
31
- // for the same `instanceof` reason as `FetchPolicyError` above: a consumer of
32
- // `buildPythPriceUpdateCalls` / `updatePythPrices` / `refreshOraclePrices` can
33
- // branch on the fee-source failure directly, and a consumer of
34
- // `fetchPriceFeedsUpdateData` / `probeMissingFeeds` can tell a misconfigured
35
- // or unentitled endpoint apart from feeds that endpoint genuinely lacks.
36
- export { PythCache, fetchPriceFeedsUpdateData, endpointSupportedFeedIds, probeMissingFeeds, buildPythPriceUpdateCalls,
37
- // The pyth read-plane endpoint accessors — Core (keyless, per network) and
38
- // Pro (the documented fixed base; auth via the caller's Bearer key). There
39
- // is no client-level endpoint field: consumers pick via
40
- // `resolveHermesReadEndpoint` (pyth_rule listed → Core, else override ??
41
- // Pro) — never a hand-rolled branch, never a cross-source fallback.
42
- pythCoreHermesEndpoint, pythProHermesEndpoint, PYTH_PRO_HERMES_ENDPOINT, updatePythPrices, HermesEndpointRejectedAllFeedsError, MISSING_FEED_MEMO_TTL_MS, OracleFeeSourceUnavailableError, } from "./pyth.js";
43
- // Canonical OracleSource value list + THE env-string parser consumers fold
44
- // onto — semantics and rationale in `source-list.ts`'s header.
28
+ export { oracleCredentialsFromHost } from "./price-update-rule.js";
29
+ // Canonical OracleSource value list + THE fed-set derivation (config in,
30
+ // sources out) semantics and rationale in `source-list.ts`'s header. There
31
+ // is no `oracleSource` option and no `ORACLE_SOURCE` env var to parse.
45
32
  export { ORACLE_SOURCES } from "./price-update-rule.js";
46
- export { isOracleSource, parseOracleSourceList } from "./source-list.js";
33
+ export { deriveOracleSources } from "./source-list.js";
47
34
  // Per-source READ-plane resolution — which tickers a source can price
48
- // off-chain and with which ids (`resolveOracleReadPlan`), and which
49
- // Hermes-compatible base the hermes plans execute against
50
- // (`resolveHermesReadEndpoint`: pyth_rule listed Core, else override ??
51
- // the documented Pyth Pro base). The one place the "lazer reads through
52
- // `pyth_rule.feeds` hex ids" invariant lives; consumers resolve through
53
- // this instead of hardcoding namespace sharing or endpoint branching.
54
- export { resolveOracleReadPlan, resolveHermesReadEndpoint } from "./read-plane.js";
55
- // Pyth Core rule (PriceUpdateRule wrapper over the Pyth source above)
56
- export { PythCoreRule } from "./rules/pyth-core-rule.js";
35
+ // off-chain and with which ids (`resolveOracleReadPlan`; every source reads
36
+ // its OWN feeds namespace, so write set == read set), plus the executors that
37
+ // run a plan (`readLazerPrices` / `readQuoteCenterPrices`) and decode each
38
+ // source's wire scaling in ONE place. `LazerNotEntitledError` is re-exported
39
+ // (not just the type) for the same `instanceof` reason as `FetchPolicyError`
40
+ // above: a consumer drops unentitled feeds and retries.
41
+ export { resolveOracleReadPlan, readPlanTickers } from "./read-plane.js";
42
+ export { LazerNotEntitledError, readLazerPrices, readQuoteCenterPrices } from "./read-prices.js";
43
+ // Boot-time deployment asserts consumers fold onto (`OracleTickerUnservedError`
44
+ // is `instanceof`-able, same rationale as above — and is the SAME type the
45
+ // per-build composers raise). Deliberately NOT called at client creation —
46
+ // see `validate.ts`'s header.
47
+ export { OracleTickerUnservedError, assertOracleWriteCoverage, missingOracleCredentials, partitionServableTickers, servableTickers, } from "./validate.js";
48
+ // The ON-CHAIN half of the same question. `validate.ts` reasons from config
49
+ // alone (necessary, not sufficient); this reads the aggregator weights, which
50
+ // is the only way to catch a ticker that is servable by config yet weighted to
51
+ // a rule the fed set cannot supply — the shape that aborts a WHOLE PTB.
52
+ export { assertOracleWeightCoverage, readOracleWeightCoverage, OracleWeightCoverageError, OracleWeightUnreadableError, } from "./weight-coverage.js";
57
53
  // Pyth Lazer rule (signed-update generation; `feedLazerRule` stays internal to `aggregate.ts`)
58
54
  // `LazerApiKeyMissingError` is re-exported (not just the type) for the same
59
- // `instanceof` reason as `OracleFeeSourceUnavailableError` above.
55
+ // `instanceof` reason as `FetchPolicyError` above.
60
56
  export { PythLazerRule, LazerApiKeyMissingError } from "./rules/pyth-lazer-rule.js";
61
57
  // `WATERX_INFRA` / `waterxQuoteCenterEndpoint` are the source's own infra table +
62
- // read-plane accessor (mirrors `pythCoreHermesEndpoint`).
58
+ // read-plane accessor.
63
59
  // WaterX quote-center rule (first-party ed25519 signed prices; the `feedWaterxRule*`
64
60
  // legs stay internal to `aggregate.ts`). Both wire shapes are exported because a
65
61
  // BE prefetch cache holds whichever one its quote-center serves: per-symbol
66
- // Merkle leaves (default) or one indivisible batch envelope (fallback).
67
- export { WaterxRule, parseSignedEnvelope, parseSignedLeaves, BATCH_PRICE_INTENT, MERKLE_ROOT_INTENT, WATERX_INFRA, waterxQuoteCenterEndpoint,
62
+ // Merkle leaves (default) or one indivisible batch envelope (fallback). The
63
+ // WL-2345 seams: the raw fetchers (`fetchWaterxSignedUpdate` /
64
+ // `fetchWaterxSignedLeaves`), the coverage-policy fetch
65
+ // (`fetchWaterxUpdateData`), and the freshness contract
66
+ // (`WATERX_MAX_PRICE_AGE_MS` / `isFreshWaterxEntry`).
67
+ export { WaterxRule, parseSignedEnvelope, parseSignedLeaves, BATCH_PRICE_INTENT, MERKLE_ROOT_INTENT, WATERX_INFRA, waterxQuoteCenterEndpoint, fetchWaterxSignedUpdate, fetchWaterxSignedLeaves, fetchWaterxUpdateData, pullWaterxQuotes, WATERX_MAX_PRICE_AGE_MS, isFreshWaterxEntry,
68
68
  // Rule-owned payload accessors (kind-check + unwrap in one place) — never
69
69
  // hand-cast the payload shape, and never assume which variant it is.
70
70
  waterxLeavesOf, waterxEnvelopeOf, } from "./rules/waterx-rule.js";
71
71
  // `resolveOracleRule` is the ONE source→rule registry — exported so external
72
72
  // consumers (e.g. a BE prefetch cache that keys per source and needs each
73
- // source's `supportedTickers`/`fetchUpdateData`) resolve through it instead of
74
- // hand-mirroring the map and drifting. `OracleSourceNotImplementedError` is
75
- // its `instanceof`-able failure (same reason as `OracleFeeSourceUnavailableError`
76
- // above).
73
+ // source's `supportedTickers`/`fetchUpdateData`/`updateIdentityBySymbol`)
74
+ // resolve through it instead of hand-mirroring the map and drifting.
75
+ // `OracleSourceNotImplementedError` is its `instanceof`-able failure (same
76
+ // reason as `FetchPolicyError` above).
77
77
  export { OracleSourceNotImplementedError, resolveOracleRule } from "./rule-registry.js";
78
78
  // Aggregation orchestrator
79
- export { aggregateTicker, aggregateTickerWithPyth, aggregateTickerWithConstant, refreshOraclePrices, } from "./aggregate.js";
80
- // Sponsor rule (fund open / reimburse + witness attach)
81
- export { openPythSponsorFund, reimbursePythSponsor } from "./rules/sponsor.js";
79
+ export { aggregateTicker, aggregateTickerWithConstant, refreshOraclePrices } from "./aggregate.js";
80
+ // Market hours: the Pyth schedule-grammar parser + the pure market-status
81
+ // walker (the one cross-repo implementation — see `schedule.ts`'s header).
82
+ export { PythScheduleParseError, parsePythSchedule, getMarketStatus } from "./schedule.js";
83
+ // Pyth Pro symbol catalog (keyless; schedule strings + hex↔integer id map)
84
+ // and Bearer-keyed chart history.
85
+ export { fetchPythSymbolCatalog } from "./symbol-catalog.js";
86
+ export { fetchPythProHistory } from "./pyth-pro-history.js";