@waterx/sdk 4.0.0 → 4.1.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.
- package/README.md +52 -37
- package/dist/cjs/src/account/account.js +2 -1
- package/dist/cjs/src/account/config.d.ts +0 -16
- package/dist/cjs/src/account/funding/balance.d.ts +25 -2
- package/dist/cjs/src/account/funding/balance.js +36 -24
- package/dist/cjs/src/account/funding/credit.js +6 -10
- package/dist/cjs/src/constants.d.ts +15 -1
- package/dist/cjs/src/constants.js +18 -4
- package/dist/cjs/src/generated/waterx_rule/deps/bucket_v2_framework/float.d.ts +8 -0
- package/dist/cjs/src/generated/waterx_rule/deps/bucket_v2_framework/float.js +13 -0
- package/dist/cjs/src/generated/waterx_rule/deps/sui/vec_map.d.ts +36 -0
- package/dist/cjs/src/generated/waterx_rule/deps/sui/vec_map.js +31 -0
- package/dist/cjs/src/generated/waterx_rule/waterx_rule.d.ts +940 -0
- package/dist/cjs/src/generated/waterx_rule/waterx_rule.js +1092 -0
- package/dist/cjs/src/oracle/aggregate.d.ts +21 -21
- package/dist/cjs/src/oracle/aggregate.js +84 -71
- package/dist/cjs/src/oracle/config.d.ts +107 -52
- package/dist/cjs/src/oracle/config.js +15 -35
- package/dist/cjs/src/oracle/host.d.ts +13 -2
- package/dist/cjs/src/oracle/index.d.ts +4 -2
- package/dist/cjs/src/oracle/index.js +25 -6
- package/dist/cjs/src/oracle/price-update-rule.d.ts +3 -4
- package/dist/cjs/src/oracle/pyth.d.ts +68 -6
- package/dist/cjs/src/oracle/pyth.js +338 -22
- package/dist/cjs/src/oracle/rule-registry.d.ts +11 -6
- package/dist/cjs/src/oracle/rule-registry.js +13 -6
- package/dist/cjs/src/oracle/rules/pyth-core-rule.js +17 -2
- package/dist/cjs/src/oracle/rules/pyth-lazer-rule.d.ts +6 -6
- package/dist/cjs/src/oracle/rules/pyth-lazer-rule.js +25 -22
- package/dist/cjs/src/oracle/rules/pyth-rule.js +5 -0
- package/dist/cjs/src/oracle/rules/waterx-rule.d.ts +89 -0
- package/dist/cjs/src/oracle/rules/waterx-rule.js +272 -0
- package/dist/cjs/src/oracle/update-fetch.d.ts +32 -2
- package/dist/cjs/src/oracle/update-fetch.js +60 -3
- package/dist/cjs/src/perp/client.d.ts +71 -19
- package/dist/cjs/src/perp/client.js +30 -10
- package/dist/cjs/src/perp/config.d.ts +4 -7
- package/dist/cjs/src/perp/config.js +9 -12
- package/dist/cjs/src/perp/constants.d.ts +0 -6
- package/dist/cjs/src/perp/constants.js +11 -9
- package/dist/cjs/src/perp/fetch/account.js +3 -0
- package/dist/cjs/src/perp/fetch/bridge.js +2 -1
- package/dist/cjs/src/perp/fetch/market.js +2 -1
- package/dist/cjs/src/perp/fetch/positions.d.ts +16 -10
- package/dist/cjs/src/perp/fetch/positions.js +23 -20
- package/dist/cjs/src/perp/index.d.ts +8 -4
- package/dist/cjs/src/perp/index.js +12 -7
- package/dist/cjs/src/perp/liq-view.d.ts +64 -0
- package/dist/cjs/src/perp/liq-view.js +74 -0
- package/dist/cjs/src/perp/user/order.d.ts +13 -0
- package/dist/cjs/src/perp/user/order.js +30 -16
- package/dist/cjs/src/perp/user/staking.js +3 -2
- package/dist/cjs/src/perp/user/trading.js +25 -24
- package/dist/cjs/src/perp/user/wlp.js +6 -5
- package/dist/cjs/src/prediction/utils.d.ts +11 -2
- package/dist/cjs/src/prediction/utils.js +22 -22
- package/dist/cjs/src/unified-client.d.ts +49 -20
- package/dist/cjs/src/unified-client.js +4 -1
- package/dist/cjs/src/utils/format.d.ts +14 -0
- package/dist/cjs/src/utils/format.js +24 -0
- package/dist/cjs/src/utils/math.d.ts +304 -12
- package/dist/cjs/src/utils/math.js +397 -17
- package/dist/cjs/src/utils/validate.d.ts +69 -0
- package/dist/cjs/src/utils/validate.js +183 -0
- package/dist/src/account/account.js +2 -1
- package/dist/src/account/config.d.ts +0 -16
- package/dist/src/account/funding/balance.d.ts +25 -2
- package/dist/src/account/funding/balance.js +36 -24
- package/dist/src/account/funding/credit.js +6 -10
- package/dist/src/constants.d.ts +15 -1
- package/dist/src/constants.js +17 -3
- package/dist/src/generated/waterx_rule/deps/bucket_v2_framework/float.d.ts +8 -0
- package/dist/src/generated/waterx_rule/deps/bucket_v2_framework/float.js +10 -0
- package/dist/src/generated/waterx_rule/deps/sui/vec_map.d.ts +36 -0
- package/dist/src/generated/waterx_rule/deps/sui/vec_map.js +27 -0
- package/dist/src/generated/waterx_rule/waterx_rule.d.ts +940 -0
- package/dist/src/generated/waterx_rule/waterx_rule.js +991 -0
- package/dist/src/oracle/aggregate.d.ts +21 -21
- package/dist/src/oracle/aggregate.js +84 -71
- package/dist/src/oracle/config.d.ts +107 -52
- package/dist/src/oracle/config.js +14 -34
- package/dist/src/oracle/host.d.ts +13 -2
- package/dist/src/oracle/index.d.ts +4 -2
- package/dist/src/oracle/index.js +18 -7
- package/dist/src/oracle/price-update-rule.d.ts +3 -4
- package/dist/src/oracle/pyth.d.ts +68 -6
- package/dist/src/oracle/pyth.js +334 -22
- package/dist/src/oracle/rule-registry.d.ts +11 -6
- package/dist/src/oracle/rule-registry.js +13 -6
- package/dist/src/oracle/rules/pyth-core-rule.js +18 -3
- package/dist/src/oracle/rules/pyth-lazer-rule.d.ts +6 -6
- package/dist/src/oracle/rules/pyth-lazer-rule.js +26 -23
- package/dist/src/oracle/rules/pyth-rule.js +5 -0
- package/dist/src/oracle/rules/waterx-rule.d.ts +89 -0
- package/dist/src/oracle/rules/waterx-rule.js +266 -0
- package/dist/src/oracle/update-fetch.d.ts +32 -2
- package/dist/src/oracle/update-fetch.js +57 -3
- package/dist/src/perp/client.d.ts +71 -19
- package/dist/src/perp/client.js +31 -11
- package/dist/src/perp/config.d.ts +4 -7
- package/dist/src/perp/config.js +9 -12
- package/dist/src/perp/constants.d.ts +0 -6
- package/dist/src/perp/constants.js +10 -8
- package/dist/src/perp/fetch/account.js +3 -0
- package/dist/src/perp/fetch/bridge.js +2 -1
- package/dist/src/perp/fetch/market.js +2 -1
- package/dist/src/perp/fetch/positions.d.ts +16 -10
- package/dist/src/perp/fetch/positions.js +28 -20
- package/dist/src/perp/index.d.ts +8 -4
- package/dist/src/perp/index.js +5 -3
- package/dist/src/perp/liq-view.d.ts +64 -0
- package/dist/src/perp/liq-view.js +71 -0
- package/dist/src/perp/user/order.d.ts +13 -0
- package/dist/src/perp/user/order.js +30 -16
- package/dist/src/perp/user/staking.js +3 -2
- package/dist/src/perp/user/trading.js +25 -24
- package/dist/src/perp/user/wlp.js +6 -5
- package/dist/src/prediction/utils.d.ts +11 -2
- package/dist/src/prediction/utils.js +22 -22
- package/dist/src/unified-client.d.ts +49 -20
- package/dist/src/unified-client.js +4 -1
- package/dist/src/utils/format.d.ts +14 -0
- package/dist/src/utils/format.js +21 -0
- package/dist/src/utils/math.d.ts +304 -12
- package/dist/src/utils/math.js +394 -17
- package/dist/src/utils/validate.d.ts +69 -0
- package/dist/src/utils/validate.js +167 -0
- package/package.json +4 -1
|
@@ -25,6 +25,7 @@ import type { Transaction, TransactionArgument } from "@mysten/sui/transactions"
|
|
|
25
25
|
import type { OracleHost } from "./host.ts";
|
|
26
26
|
import type { OracleSource, PriceUpdateRule, UpdateDataProvider } from "./price-update-rule.ts";
|
|
27
27
|
import { type OracleFeeSource, type PythCache } from "./pyth.ts";
|
|
28
|
+
import { type WaterxSignedEnvelope } from "./rules/waterx-rule.ts";
|
|
28
29
|
/**
|
|
29
30
|
* Aggregate one ticker's price into the shared `Oracle`: build a collector, feed
|
|
30
31
|
* every rule the ticker is configured for, then `aggregate`.
|
|
@@ -54,6 +55,7 @@ export declare function aggregateTicker(tx: Transaction, host: OracleHost, args:
|
|
|
54
55
|
ticker: string;
|
|
55
56
|
priceInfoObjectId?: string;
|
|
56
57
|
lazerUpdate?: TransactionArgument;
|
|
58
|
+
waterxEnvelope?: WaterxSignedEnvelope;
|
|
57
59
|
}): void;
|
|
58
60
|
/**
|
|
59
61
|
* Thin wrapper over {@link aggregateTicker} for a Pyth-fed ticker. Kept for
|
|
@@ -83,28 +85,26 @@ export declare function aggregateTickerWithConstant(tx: Transaction, host: Oracl
|
|
|
83
85
|
* enabled, Constant when it's a constant ticker).
|
|
84
86
|
*
|
|
85
87
|
* Before that, the on-chain price *update* leg is routed by `host.oracleSource`
|
|
86
|
-
* (see `rule-registry.ts`): the selected
|
|
87
|
-
* `supportedTickers(host)
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
* it
|
|
88
|
+
* (see `rule-registry.ts`): the ONE selected source serves every ticker in its
|
|
89
|
+
* `supportedTickers(host)`. There is **no cross-source fallback** — a requested
|
|
90
|
+
* ticker the selected source does not serve, and that is not a constant-only
|
|
91
|
+
* ticker (which needs no price-update leg), fails the build immediately with a
|
|
92
|
+
* clear error naming the ticker and source. That is the deliberate "fail the
|
|
93
|
+
* tx-build, don't silently reroute" contract: a wrong-but-present feed id is
|
|
94
|
+
* NOT validated here (it surfaces on-chain at dry-run); a MISSING feed for the
|
|
95
|
+
* selected source is caught here. When the selected source's feed exists but is
|
|
96
|
+
* wrong, this function does nothing special — the on-chain aggregate aborts at
|
|
97
|
+
* dry-run, which is correct.
|
|
93
98
|
*
|
|
94
|
-
*
|
|
95
|
-
* per-rule PTB atomicity
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* fee-free Lazer group ordered ahead of a Pyth Core fallback group). Only once
|
|
104
|
-
* that check passes do all groups' off-chain fetches run concurrently
|
|
105
|
-
* (`Promise.all`) and complete before any PTB mutation; on-chain reads inside
|
|
106
|
-
* `buildUpdateCalls` can still fail mid-append for other reasons — callers
|
|
107
|
-
* discard the tx on any throw.
|
|
99
|
+
* The selected source's fetch + build runs against its own infra, guaranteeing
|
|
100
|
+
* per-rule PTB atomicity. A fee-source pre-check runs first (the source's
|
|
101
|
+
* `requiresFeeSource`) BEFORE any off-chain fetch or PTB mutation — so a
|
|
102
|
+
* fee-charging source with no `opts.feeSource` throws
|
|
103
|
+
* `OracleFeeSourceUnavailable` with zero wasted network calls and zero stray
|
|
104
|
+
* moveCalls. Only once that check passes does the off-chain fetch run and
|
|
105
|
+
* complete before any PTB mutation; on-chain reads inside `buildUpdateCalls`
|
|
106
|
+
* can still fail mid-append for other reasons — callers discard the tx on any
|
|
107
|
+
* throw.
|
|
108
108
|
*
|
|
109
109
|
* **Collector-feed leg is rule-aware:** a lazer-served group's
|
|
110
110
|
* `buildUpdateCalls` returns the verified `Update` PTB value
|
|
@@ -34,6 +34,7 @@ const constant_rule_ts_1 = require("./rules/constant-rule.js");
|
|
|
34
34
|
const pyth_lazer_rule_ts_1 = require("./rules/pyth-lazer-rule.js");
|
|
35
35
|
const pyth_rule_ts_1 = require("./rules/pyth-rule.js");
|
|
36
36
|
const supra_rule_ts_1 = require("./rules/supra-rule.js");
|
|
37
|
+
const waterx_rule_ts_1 = require("./rules/waterx-rule.js");
|
|
37
38
|
/**
|
|
38
39
|
* Resolve one group's off-chain update payload for {@link refreshOraclePrices}:
|
|
39
40
|
* try `provider.get(source, tickers)` first (when a provider is configured),
|
|
@@ -116,6 +117,14 @@ function aggregateTicker(tx, host, args) {
|
|
|
116
117
|
(0, pyth_lazer_rule_ts_1.feedLazerRule)(tx, host, collector, args.lazerUpdate);
|
|
117
118
|
fed = true;
|
|
118
119
|
}
|
|
120
|
+
if (args.waterxEnvelope !== undefined) {
|
|
121
|
+
// waterx_rule::collect_batch_latest verifies the batch signature and feeds
|
|
122
|
+
// this collector's symbol from the batch. If the ticker's aggregator does
|
|
123
|
+
// not (yet) weight `WaterxRule`, the contribution is silently dropped
|
|
124
|
+
// on-chain — feeding ahead of the weight migration is harmless.
|
|
125
|
+
(0, waterx_rule_ts_1.feedWaterxRule)(tx, host, collector, args.waterxEnvelope);
|
|
126
|
+
fed = true;
|
|
127
|
+
}
|
|
119
128
|
if (fed) {
|
|
120
129
|
// Supra rides on the same collector when enabled (abstains on-chain otherwise).
|
|
121
130
|
(0, supra_rule_ts_1.maybeFeedSupra)(tx, host, collector);
|
|
@@ -165,28 +174,26 @@ function aggregateTickerWithConstant(tx, host, args) {
|
|
|
165
174
|
* enabled, Constant when it's a constant ticker).
|
|
166
175
|
*
|
|
167
176
|
* Before that, the on-chain price *update* leg is routed by `host.oracleSource`
|
|
168
|
-
* (see `rule-registry.ts`): the selected
|
|
169
|
-
* `supportedTickers(host)
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
* it
|
|
177
|
+
* (see `rule-registry.ts`): the ONE selected source serves every ticker in its
|
|
178
|
+
* `supportedTickers(host)`. There is **no cross-source fallback** — a requested
|
|
179
|
+
* ticker the selected source does not serve, and that is not a constant-only
|
|
180
|
+
* ticker (which needs no price-update leg), fails the build immediately with a
|
|
181
|
+
* clear error naming the ticker and source. That is the deliberate "fail the
|
|
182
|
+
* tx-build, don't silently reroute" contract: a wrong-but-present feed id is
|
|
183
|
+
* NOT validated here (it surfaces on-chain at dry-run); a MISSING feed for the
|
|
184
|
+
* selected source is caught here. When the selected source's feed exists but is
|
|
185
|
+
* wrong, this function does nothing special — the on-chain aggregate aborts at
|
|
186
|
+
* dry-run, which is correct.
|
|
175
187
|
*
|
|
176
|
-
*
|
|
177
|
-
* per-rule PTB atomicity
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
* fee-free Lazer group ordered ahead of a Pyth Core fallback group). Only once
|
|
186
|
-
* that check passes do all groups' off-chain fetches run concurrently
|
|
187
|
-
* (`Promise.all`) and complete before any PTB mutation; on-chain reads inside
|
|
188
|
-
* `buildUpdateCalls` can still fail mid-append for other reasons — callers
|
|
189
|
-
* discard the tx on any throw.
|
|
188
|
+
* The selected source's fetch + build runs against its own infra, guaranteeing
|
|
189
|
+
* per-rule PTB atomicity. A fee-source pre-check runs first (the source's
|
|
190
|
+
* `requiresFeeSource`) BEFORE any off-chain fetch or PTB mutation — so a
|
|
191
|
+
* fee-charging source with no `opts.feeSource` throws
|
|
192
|
+
* `OracleFeeSourceUnavailable` with zero wasted network calls and zero stray
|
|
193
|
+
* moveCalls. Only once that check passes does the off-chain fetch run and
|
|
194
|
+
* complete before any PTB mutation; on-chain reads inside `buildUpdateCalls`
|
|
195
|
+
* can still fail mid-append for other reasons — callers discard the tx on any
|
|
196
|
+
* throw.
|
|
190
197
|
*
|
|
191
198
|
* **Collector-feed leg is rule-aware:** a lazer-served group's
|
|
192
199
|
* `buildUpdateCalls` returns the verified `Update` PTB value
|
|
@@ -213,69 +220,74 @@ async function refreshOraclePrices(tx, host, tickers, opts = {}) {
|
|
|
213
220
|
const pythTickers = tickers.filter((t) => host.config.packages.pyth_rule?.feeds?.[t] !== undefined);
|
|
214
221
|
const priceInfoByTicker = new Map();
|
|
215
222
|
pythTickers.forEach((t) => priceInfoByTicker.set(t, host.getPythFeed(t).price_info_object));
|
|
216
|
-
//
|
|
217
|
-
//
|
|
218
|
-
//
|
|
219
|
-
//
|
|
220
|
-
// below has an OracleSource to key on without a cast.
|
|
223
|
+
// ONE source, no fallback. The selected source serves the tickers in its
|
|
224
|
+
// `supportedTickers(host)`; `source` is tracked alongside the group (rather
|
|
225
|
+
// than read back off `rule.kind`, typed as the broader PriceUpdateRuleKind)
|
|
226
|
+
// so the provider lookup below has an OracleSource to key on without a cast.
|
|
221
227
|
const selectedRule = (0, rule_registry_ts_1.resolveOracleRule)(host.oracleSource, opts.ruleOverrides);
|
|
222
228
|
const selectedSupported = new Set(selectedRule.supportedTickers(host));
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
229
|
+
// Fail the tx-build (NOT client init, NOT a silent reroute) when the selected
|
|
230
|
+
// source has no feed for a requested ticker that actually needs a price
|
|
231
|
+
// update. Only a CONSTANT-ONLY ticker is exempt — priced entirely by
|
|
232
|
+
// `constant_rule`, it needs no update leg from any source. A DUAL-FEED ticker
|
|
233
|
+
// (constant AND pyth) still needs its Pyth leg refreshed, so `isConstantTicker`
|
|
234
|
+
// alone must NOT exempt it: under a source that can't serve it, with no
|
|
235
|
+
// fallback, feeding an unrefreshed Pyth leg would price it stale (or abort on a
|
|
236
|
+
// missing weighted source). `priceInfoByTicker.has(t)` ⇔ the ticker has a
|
|
237
|
+
// `pyth_rule.feeds` entry, so `constant && !hasPyth` is exactly constant-only.
|
|
238
|
+
// This catches a MISSING feed; a present-but-WRONG feed id is deliberately not
|
|
239
|
+
// validated here (it aborts on-chain at dry-run).
|
|
240
|
+
const isConstantOnly = (t) => host.isConstantTicker(t) && !priceInfoByTicker.has(t);
|
|
241
|
+
const unservable = tickers.filter((t) => !selectedSupported.has(t) && !isConstantOnly(t));
|
|
242
|
+
if (unservable.length > 0) {
|
|
243
|
+
throw new Error(`oracleSource '${host.oracleSource}' has no feed configured for ticker(s): ` +
|
|
244
|
+
`${unservable.join(", ")}. Sources are self-contained with no fallback — add ` +
|
|
245
|
+
`${host.oracleSource} feeds for them, or select a source that serves them.`);
|
|
227
246
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
// Fee-source pre-check, hoisted ABOVE both the off-chain fetch below AND
|
|
237
|
-
// the per-group build loop further down. The condition only consults
|
|
238
|
-
// `group.rule.requiresFeeSource` — known the moment `groups` is built,
|
|
239
|
-
// before any fetch or PTB mutation — so this throws with ZERO wasted
|
|
240
|
-
// network calls and zero PTB commands. A per-call guard inside
|
|
241
|
-
// `buildPythPriceUpdateCalls` alone would not be early enough: in a mixed
|
|
242
|
-
// shape (e.g. a lazer-selected `oracleSource` with a `pyth_rule` fallback
|
|
243
|
-
// group for tickers Lazer doesn't cover), the build loop runs each
|
|
244
|
-
// group's `buildUpdateCalls` in sequence — a fee-free group ordered ahead
|
|
245
|
-
// of a fee-charging one would already have appended its verify/feed
|
|
246
|
-
// moveCalls to the shared `tx` by the time the fee-charging group's own
|
|
247
|
-
// guard fired, breaking the "throw before any PTB mutation" guarantee.
|
|
248
|
-
// Checking every group's `requiresFeeSource` up front — before ANY group
|
|
249
|
-
// fetches or builds — closes that gap, and (unlike a referential check
|
|
250
|
-
// against a specific rule instance) keeps protecting a future
|
|
251
|
-
// fee-charging rule or a test double standing in for one.
|
|
252
|
-
if (!opts.feeSource && groups.some((group) => group.rule.requiresFeeSource)) {
|
|
247
|
+
const selectedGroup = tickers.filter((t) => selectedSupported.has(t));
|
|
248
|
+
// Fee-source pre-check, hoisted ABOVE the off-chain fetch and PTB build below.
|
|
249
|
+
// It consults only `rule.requiresFeeSource` — known before any fetch or PTB
|
|
250
|
+
// mutation — so a fee-charging source with no `feeSource` throws with ZERO
|
|
251
|
+
// wasted network calls and zero PTB commands, rather than waiting for
|
|
252
|
+
// `buildPythPriceUpdateCalls`'s own per-call guard to fire after the off-chain
|
|
253
|
+
// fetch already ran.
|
|
254
|
+
if (selectedGroup.length > 0 && !opts.feeSource && selectedRule.requiresFeeSource) {
|
|
253
255
|
throw new pyth_ts_1.OracleFeeSourceUnavailableError();
|
|
254
256
|
}
|
|
255
|
-
//
|
|
256
|
-
//
|
|
257
|
-
//
|
|
258
|
-
//
|
|
259
|
-
const groupsWithData = await Promise.all(groups.map(async (group) => ({
|
|
260
|
-
rule: group.rule,
|
|
261
|
-
tickers: group.tickers,
|
|
262
|
-
data: await resolveGroupUpdateData(host, group, opts.updateDataProvider),
|
|
263
|
-
})));
|
|
264
|
-
// Verified-`Update` handle per lazer-served ticker (one shared PTB value per
|
|
265
|
-
// group) — consumed by the collector-feed leg below.
|
|
257
|
+
// Resolve + build the selected source's update leg. The off-chain fetch
|
|
258
|
+
// settles before the first PTB mutation, so a fetch failure never strands
|
|
259
|
+
// moveCalls in a caller-owned tx. Map each lazer-served ticker to the one
|
|
260
|
+
// verified `Update` PTB value for the collector-feed leg below.
|
|
266
261
|
const lazerUpdateByTicker = new Map();
|
|
267
|
-
|
|
268
|
-
|
|
262
|
+
// Signed batch envelope per waterx-served ticker. Unlike Lazer's shared PTB
|
|
263
|
+
// handle, waterx's verify+feed is bundled into `collect_batch_latest` in the
|
|
264
|
+
// per-ticker feed leg, so its `buildUpdateCalls` emits nothing and the
|
|
265
|
+
// envelope is carried straight from the group's fetched data.
|
|
266
|
+
const waterxEnvelopeByTicker = new Map();
|
|
267
|
+
if (selectedGroup.length > 0) {
|
|
268
|
+
const group = { source: host.oracleSource, rule: selectedRule, tickers: selectedGroup };
|
|
269
|
+
const data = await resolveGroupUpdateData(host, group, opts.updateDataProvider);
|
|
270
|
+
const handle = (await selectedRule.buildUpdateCalls(tx, host, data, {
|
|
269
271
|
cache: opts.cache,
|
|
270
272
|
feeSource: opts.feeSource,
|
|
271
273
|
})) ?? undefined;
|
|
272
274
|
// Route by the handle's kind discriminant — the one site the tag exists to
|
|
273
|
-
// protect: a future non-lazer handle
|
|
274
|
-
//
|
|
275
|
+
// protect: a future non-lazer handle must never be silently fed into
|
|
276
|
+
// pyth_lazer_rule::feed.
|
|
275
277
|
if (handle?.kind === "pyth_lazer_rule") {
|
|
276
|
-
for (const ticker of
|
|
278
|
+
for (const ticker of selectedGroup)
|
|
277
279
|
lazerUpdateByTicker.set(ticker, handle.update);
|
|
278
280
|
}
|
|
281
|
+
// waterx_rule emits no shared handle (verify+feed is bundled into the
|
|
282
|
+
// per-ticker `collect_batch_latest`), so the envelope is carried straight
|
|
283
|
+
// from this group's fetched data to the feed leg below.
|
|
284
|
+
if (selectedRule.kind === "waterx_rule") {
|
|
285
|
+
const envelope = (0, waterx_rule_ts_1.waterxEnvelopeOf)(data);
|
|
286
|
+
if (envelope) {
|
|
287
|
+
for (const ticker of selectedGroup)
|
|
288
|
+
waterxEnvelopeByTicker.set(ticker, envelope);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
279
291
|
}
|
|
280
292
|
// Aggregate each ticker, feeding whichever rules it is configured for.
|
|
281
293
|
for (const ticker of tickers) {
|
|
@@ -283,6 +295,7 @@ async function refreshOraclePrices(tx, host, tickers, opts = {}) {
|
|
|
283
295
|
ticker,
|
|
284
296
|
priceInfoObjectId: priceInfoByTicker.get(ticker),
|
|
285
297
|
lazerUpdate: lazerUpdateByTicker.get(ticker),
|
|
298
|
+
waterxEnvelope: waterxEnvelopeByTicker.get(ticker),
|
|
286
299
|
});
|
|
287
300
|
}
|
|
288
301
|
}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import type { BasePackageEntry } from "../account/config.ts";
|
|
13
13
|
import type { BaseLineConfig } from "../base-client.ts";
|
|
14
14
|
import type { Network } from "../constants.ts";
|
|
15
|
+
import type { FetchPolicy } from "./update-fetch.ts";
|
|
15
16
|
export interface PythRulePackage extends BasePackageEntry {
|
|
16
17
|
config: string;
|
|
17
18
|
feeds: Record<string, {
|
|
@@ -82,6 +83,39 @@ export interface SupraRulePackage extends BasePackageEntry {
|
|
|
82
83
|
*/
|
|
83
84
|
enabled?: boolean;
|
|
84
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Per-ticker `waterx_rule` feed entry. Keyed in `feeds` by the oracle **ticker**
|
|
88
|
+
* (e.g. `"SUIUSD"`, the same key `pyth_rule.feeds` uses), so
|
|
89
|
+
* `Object.keys(feeds)` is the SDK's supported-ticker set. The fields are
|
|
90
|
+
* informational off-chain — the SDK keys routing/support off the entry's
|
|
91
|
+
* presence and pushes the enclave-signed price verbatim, never re-deriving it.
|
|
92
|
+
*/
|
|
93
|
+
export interface WaterxRuleFeedEntry {
|
|
94
|
+
/** Exchange ticker the quote-center aggregates from (e.g. `"SUIUSDT"`). */
|
|
95
|
+
ticker?: string;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* `waterx_rule` deployment entry — the first-party Nautilus-TEE oracle rule.
|
|
99
|
+
* Read by `WaterxRule` (`rules/waterx-rule.ts`): `feeds` for ticker support,
|
|
100
|
+
* `config`/`enclave_config`/`enclave` for the `collect_batch_latest` call,
|
|
101
|
+
* `published_at` for the package address. The off-chain signed price is pulled
|
|
102
|
+
* from the quote-center (endpoint from {@link WATERX_DEFAULTS}), not this JSON.
|
|
103
|
+
*
|
|
104
|
+
* `enabled` mirrors the JSON field verbatim but MUST NOT be read for routing —
|
|
105
|
+
* which rule prices a ticker is decided solely by the client's `oracleSource`
|
|
106
|
+
* create option (see `OracleHost.oracleSource`), mirroring `pyth_lazer_rule`.
|
|
107
|
+
*/
|
|
108
|
+
export interface WaterxRulePackage extends BasePackageEntry {
|
|
109
|
+
/** Shared `waterx_rule::Config` (per-symbol on-chain feed_config). */
|
|
110
|
+
config: string;
|
|
111
|
+
/** Shared `EnclaveConfig<WATERX_RULE>` the on-chain signature verify runs against. */
|
|
112
|
+
enclave_config: string;
|
|
113
|
+
/** Shared `Enclave<WATERX_RULE>` holding the registered TEE signing pubkey. */
|
|
114
|
+
enclave: string;
|
|
115
|
+
enabled?: boolean;
|
|
116
|
+
/** Oracle ticker → feed entry; presence marks the ticker as waterx-served. */
|
|
117
|
+
feeds: Record<string, WaterxRuleFeedEntry>;
|
|
118
|
+
}
|
|
85
119
|
export interface WaterxOraclePackage extends BasePackageEntry {
|
|
86
120
|
listing_cap: string;
|
|
87
121
|
oracle: string;
|
|
@@ -99,8 +133,33 @@ export interface OraclePackages {
|
|
|
99
133
|
pyth_lazer_rule?: PythLazerRulePackage;
|
|
100
134
|
constant_rule?: WaterxConstantRulePackage;
|
|
101
135
|
supra_rule?: SupraRulePackage;
|
|
136
|
+
/** See {@link WaterxRulePackage} — read by `WaterxRule` when `oracleSource` selects it. */
|
|
137
|
+
waterx_rule?: WaterxRulePackage;
|
|
102
138
|
waterx_oracle: WaterxOraclePackage;
|
|
103
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Resolved Pyth Core infra as it lives on `client.pyth` — NOT a config-JSON
|
|
142
|
+
* shape. `state_id` / `wormhole_state_id` / `hermes_endpoint` come verbatim
|
|
143
|
+
* from the fixed per-network constant ({@link PYTH_DEFAULTS}); `api_key` /
|
|
144
|
+
* `fetch` are layered on from the caller's `pythApiKey` / `pythFetch` create
|
|
145
|
+
* options. None of it is sourced from the canonical `waterx-config` JSON — the
|
|
146
|
+
* SDK never reads a `pyth` block there (a Bearer secret has no place in a
|
|
147
|
+
* public CDN document). The infra is the same for every `oracleSource`; the
|
|
148
|
+
* `pyth_lazer_rule` source reads only the `api_key` / `fetch` from here and
|
|
149
|
+
* gets its on-chain infra from {@link LAZER_DEFAULTS} + config instead.
|
|
150
|
+
*/
|
|
151
|
+
/**
|
|
152
|
+
* The caller-tunable subset of `fetchWithPolicy`'s policy exposed on the
|
|
153
|
+
* `pythFetch` create option and `client.pyth.fetch` — the retry/timeout budget
|
|
154
|
+
* for the off-chain Hermes (`fetchPriceFeedsUpdateData`) and Lazer
|
|
155
|
+
* (`PythLazerRule`) update fetches. Deliberately narrower than the internal
|
|
156
|
+
* `FetchPolicy` (no `retryDelayMs` / `apiKey` / `fetchImpl`). Both fetches fall
|
|
157
|
+
* back to `fetchWithPolicy`'s defaults (15s timeout, 2 retries) when unset.
|
|
158
|
+
*/
|
|
159
|
+
export type PythFetchPolicy = {
|
|
160
|
+
timeoutMs?: number;
|
|
161
|
+
retries?: number;
|
|
162
|
+
};
|
|
104
163
|
export interface PythInfraConfig {
|
|
105
164
|
state_id: string;
|
|
106
165
|
wormhole_state_id: string;
|
|
@@ -109,8 +168,8 @@ export interface PythInfraConfig {
|
|
|
109
168
|
* Pyth Pro / Lazer access token (`Authorization: Bearer …`) for
|
|
110
169
|
* `PythLazerRule`'s signed-update fetch — Lazer is auth-first, so there is
|
|
111
170
|
* no keyless default. Optional: Pyth-Core-only deployments never need it.
|
|
112
|
-
*
|
|
113
|
-
*
|
|
171
|
+
* Supplied via the `pythApiKey` create option (the SDK never reads
|
|
172
|
+
* `process.env` or the config JSON). Absent when a lazer-routed fetch runs →
|
|
114
173
|
* `LazerApiKeyMissing` is thrown at fetch time. As of the Pyth Pro
|
|
115
174
|
* migration (post-2026-08-18, per
|
|
116
175
|
* https://docs.pyth.network/price-feeds/core/upgrade) this is ALSO required
|
|
@@ -119,57 +178,16 @@ export interface PythInfraConfig {
|
|
|
119
178
|
*/
|
|
120
179
|
api_key?: string;
|
|
121
180
|
/**
|
|
122
|
-
* Retry/timeout policy
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
* to `fetchWithPolicy`'s built-in defaults (15s
|
|
127
|
-
* unset.
|
|
181
|
+
* Retry/timeout policy for the Hermes (`fetchPriceFeedsUpdateData`) and
|
|
182
|
+
* Lazer (`PythLazerRule`) off-chain update fetches — see `fetchWithPolicy`
|
|
183
|
+
* (`./update-fetch.ts`) for the full policy (backoff, which statuses retry,
|
|
184
|
+
* Bearer attachment). Supplied via the `pythFetch` create option. Optional:
|
|
185
|
+
* both fetches default to `fetchWithPolicy`'s built-in defaults (15s
|
|
186
|
+
* timeout, 2 retries) when unset.
|
|
128
187
|
*/
|
|
129
|
-
fetch?:
|
|
130
|
-
timeoutMs?: number;
|
|
131
|
-
retries?: number;
|
|
132
|
-
};
|
|
188
|
+
fetch?: PythFetchPolicy;
|
|
133
189
|
}
|
|
134
190
|
export declare const PYTH_DEFAULTS: Record<Network, PythInfraConfig>;
|
|
135
|
-
/**
|
|
136
|
-
* Which Pyth Core contract generation feeds `host.pyth` when the config JSON
|
|
137
|
-
* carries no explicit `pyth` override:
|
|
138
|
-
*
|
|
139
|
-
* - `'core'` (default) — the original contracts + keyless Hermes
|
|
140
|
-
* ({@link PYTH_DEFAULTS}).
|
|
141
|
-
* - `'pro'` — the Pro-compatible upgraded contracts + the Hermes-compatible
|
|
142
|
-
* endpoint ({@link PYTH_PRO_DEFAULTS}); pair with `pyth.api_key` after the
|
|
143
|
-
* 2026-08-18 cutover.
|
|
144
|
-
*
|
|
145
|
-
* Resolved once at client creation from the `pythGeneration` create option.
|
|
146
|
-
* Orthogonal to `oracleSource` — this flips the Pyth-Core *infra* (state ids
|
|
147
|
-
* + endpoint), not which `PriceUpdateRule` routes tickers.
|
|
148
|
-
*/
|
|
149
|
-
export type PythGeneration = "core" | "pro";
|
|
150
|
-
/**
|
|
151
|
-
* Pyth **Pro-generation** Core-compatible infra — the post-2026-08-18
|
|
152
|
-
* contracts (cutover date per
|
|
153
|
-
* https://docs.pyth.network/price-feeds/core/upgrade) from Pyth's Core-Upgrade
|
|
154
|
-
* docs
|
|
155
|
-
* (https://docs.pyth.network/price-feeds/core/upgrade/contracts, Sui section;
|
|
156
|
-
* package revs `sui-pro-compatible-contract-mainnet` /
|
|
157
|
-
* `sui-pro-compatible-contract-testnet`). Selected via the client's
|
|
158
|
-
* `pythGeneration: 'pro'` create option; `config.pyth` still overrides
|
|
159
|
-
* wholesale (see `PerpClient`). All four state ids were verified on-chain
|
|
160
|
-
* (shared `state::State` objects under the docs' upgraded package ids).
|
|
161
|
-
*
|
|
162
|
-
* Kept as a second flat map beside {@link PYTH_DEFAULTS} rather than a nested
|
|
163
|
-
* `PYTH_INFRA[network][generation]` — `PYTH_DEFAULTS` is a published export
|
|
164
|
-
* with external consumers, so the smallest honest surface is an additive
|
|
165
|
-
* sibling (same deferral note as {@link LAZER_DEFAULTS}).
|
|
166
|
-
*
|
|
167
|
-
* The Hermes-compatible endpoint (`pyth.dourolabs.app/hermes`) serves the
|
|
168
|
-
* same REST surface as `hermes.pyth.network` but requires `pyth.api_key`
|
|
169
|
-
* (`Authorization: Bearer …`) after the cutover — see
|
|
170
|
-
* {@link PythInfraConfig.api_key}.
|
|
171
|
-
*/
|
|
172
|
-
export declare const PYTH_PRO_DEFAULTS: Record<Network, PythInfraConfig>;
|
|
173
191
|
/**
|
|
174
192
|
* Pyth Lazer (Pyth Pro) external infra the `PythLazerRule` needs, by network.
|
|
175
193
|
* Mirrors {@link PYTH_DEFAULTS}: per-network constants for infrastructure Pyth
|
|
@@ -190,6 +208,45 @@ export declare const LAZER_DEFAULTS: Record<Network, {
|
|
|
190
208
|
endpoint: string;
|
|
191
209
|
verifier_package: string;
|
|
192
210
|
}>;
|
|
211
|
+
/**
|
|
212
|
+
* Resolved WaterX quote-center infra for `WaterxRule` — the network default
|
|
213
|
+
* from {@link WATERX_DEFAULTS}, with both fields overridable at client init
|
|
214
|
+
* (`waterxEndpoint` / `waterxFetch`).
|
|
215
|
+
*
|
|
216
|
+
* The override exists because this is the one oracle source a BROWSER fetches
|
|
217
|
+
* itself: the rule pulls the signed envelope from the page, so it is subject to
|
|
218
|
+
* the quote-center deployment's CORS allowlist. A front end whose origin is not
|
|
219
|
+
* on that list — or one that must route egress through its own backend — points
|
|
220
|
+
* `endpoint` at a same-origin proxy (or supplies `fetch.fetchImpl`) instead of
|
|
221
|
+
* being locked to the hardcoded host.
|
|
222
|
+
*/
|
|
223
|
+
export interface WaterxInfraConfig {
|
|
224
|
+
/**
|
|
225
|
+
* Quote-center base URL. A base PATH is preserved — the rule appends via
|
|
226
|
+
* `joinEndpointPath`, so `https://app.example/api/quote-center` resolves to
|
|
227
|
+
* `…/api/quote-center/v1/quotes/update` and a proxy route is not rewritten
|
|
228
|
+
* away. A trailing slash is trimmed.
|
|
229
|
+
*/
|
|
230
|
+
endpoint: string;
|
|
231
|
+
/**
|
|
232
|
+
* Retry/timeout policy (and `fetchImpl`) for the quote-center fetch — see
|
|
233
|
+
* `fetchWithPolicy` (`./update-fetch.ts`). Supplied via the `waterxFetch`
|
|
234
|
+
* create option. When unset the rule falls back to the shared `pyth.fetch`
|
|
235
|
+
* policy, then to `fetchWithPolicy`'s defaults (15s timeout, 2 retries).
|
|
236
|
+
*/
|
|
237
|
+
fetch?: FetchPolicy;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* WaterX quote-center base URL by network — the first-party TEE-signed price
|
|
241
|
+
* hub `WaterxRule` pulls from (`GET /v1/quotes/update?symbols=…`). Mirrors
|
|
242
|
+
* {@link LAZER_DEFAULTS}: infra WaterX operates, not part of the `waterx-config`
|
|
243
|
+
* JSON. Public read (no auth), so there is no api_key. `endpoint` has no
|
|
244
|
+
* trailing slash — the rule appends the path.
|
|
245
|
+
*
|
|
246
|
+
* These are DEFAULTS, not a hard pin: a consumer overrides them per client via
|
|
247
|
+
* `waterxEndpoint` / `waterxFetch` (resolved onto `client.waterx`).
|
|
248
|
+
*/
|
|
249
|
+
export declare const WATERX_DEFAULTS: Record<Network, WaterxInfraConfig>;
|
|
193
250
|
/**
|
|
194
251
|
* The narrow config shape the oracle/refresh code needs. `WaterXConfig`
|
|
195
252
|
* (the perp line's full config) is assignable to this, so `PerpClient` satisfies
|
|
@@ -197,6 +254,4 @@ export declare const LAZER_DEFAULTS: Record<Network, {
|
|
|
197
254
|
*/
|
|
198
255
|
export interface OracleConfig extends BaseLineConfig {
|
|
199
256
|
packages: OraclePackages;
|
|
200
|
-
/** Pyth infra override (defaults from {@link PYTH_DEFAULTS}). */
|
|
201
|
-
pyth?: PythInfraConfig;
|
|
202
257
|
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* mirrors the earlier account-config hoist.
|
|
12
12
|
*/
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.
|
|
14
|
+
exports.WATERX_DEFAULTS = exports.LAZER_DEFAULTS = exports.PYTH_DEFAULTS = void 0;
|
|
15
15
|
exports.PYTH_DEFAULTS = {
|
|
16
16
|
MAINNET: {
|
|
17
17
|
state_id: "0x1f9310238ee9298fb703c3419030b35b22bb1cc37113e3bb5007c99aec79e5b8",
|
|
@@ -24,40 +24,6 @@ exports.PYTH_DEFAULTS = {
|
|
|
24
24
|
hermes_endpoint: "https://hermes-beta.pyth.network",
|
|
25
25
|
},
|
|
26
26
|
};
|
|
27
|
-
/**
|
|
28
|
-
* Pyth **Pro-generation** Core-compatible infra — the post-2026-08-18
|
|
29
|
-
* contracts (cutover date per
|
|
30
|
-
* https://docs.pyth.network/price-feeds/core/upgrade) from Pyth's Core-Upgrade
|
|
31
|
-
* docs
|
|
32
|
-
* (https://docs.pyth.network/price-feeds/core/upgrade/contracts, Sui section;
|
|
33
|
-
* package revs `sui-pro-compatible-contract-mainnet` /
|
|
34
|
-
* `sui-pro-compatible-contract-testnet`). Selected via the client's
|
|
35
|
-
* `pythGeneration: 'pro'` create option; `config.pyth` still overrides
|
|
36
|
-
* wholesale (see `PerpClient`). All four state ids were verified on-chain
|
|
37
|
-
* (shared `state::State` objects under the docs' upgraded package ids).
|
|
38
|
-
*
|
|
39
|
-
* Kept as a second flat map beside {@link PYTH_DEFAULTS} rather than a nested
|
|
40
|
-
* `PYTH_INFRA[network][generation]` — `PYTH_DEFAULTS` is a published export
|
|
41
|
-
* with external consumers, so the smallest honest surface is an additive
|
|
42
|
-
* sibling (same deferral note as {@link LAZER_DEFAULTS}).
|
|
43
|
-
*
|
|
44
|
-
* The Hermes-compatible endpoint (`pyth.dourolabs.app/hermes`) serves the
|
|
45
|
-
* same REST surface as `hermes.pyth.network` but requires `pyth.api_key`
|
|
46
|
-
* (`Authorization: Bearer …`) after the cutover — see
|
|
47
|
-
* {@link PythInfraConfig.api_key}.
|
|
48
|
-
*/
|
|
49
|
-
exports.PYTH_PRO_DEFAULTS = {
|
|
50
|
-
MAINNET: {
|
|
51
|
-
state_id: "0x03719fae774ddab3cfcaa53bbc046f0cbe21410019b6280811bf3f9f4b05839d",
|
|
52
|
-
wormhole_state_id: "0xdbca52b9fb4f712e25f61f974586d93ac541bcf8389564f0323bb07215168b5c",
|
|
53
|
-
hermes_endpoint: "https://pyth.dourolabs.app/hermes",
|
|
54
|
-
},
|
|
55
|
-
TESTNET: {
|
|
56
|
-
state_id: "0x3c48fe392912de6c18087a2b3f5fdbfbfdb4598e180947feff1f12f8e9ea073e",
|
|
57
|
-
wormhole_state_id: "0x750da8e6d16b6a363a39fe2eaa8295ac224a1e6fce4e47b58845e2e8746164f0",
|
|
58
|
-
hermes_endpoint: "https://pyth.dourolabs.app/hermes",
|
|
59
|
-
},
|
|
60
|
-
};
|
|
61
27
|
// ============================================================================
|
|
62
28
|
// Pyth Lazer — external infra, defaults by network
|
|
63
29
|
// ============================================================================
|
|
@@ -87,3 +53,17 @@ exports.LAZER_DEFAULTS = {
|
|
|
87
53
|
verifier_package: "0xf5bd2141967507050a91b58de3d95e77c432cd90d1799ee46effc27430a68c21",
|
|
88
54
|
},
|
|
89
55
|
};
|
|
56
|
+
/**
|
|
57
|
+
* WaterX quote-center base URL by network — the first-party TEE-signed price
|
|
58
|
+
* hub `WaterxRule` pulls from (`GET /v1/quotes/update?symbols=…`). Mirrors
|
|
59
|
+
* {@link LAZER_DEFAULTS}: infra WaterX operates, not part of the `waterx-config`
|
|
60
|
+
* JSON. Public read (no auth), so there is no api_key. `endpoint` has no
|
|
61
|
+
* trailing slash — the rule appends the path.
|
|
62
|
+
*
|
|
63
|
+
* These are DEFAULTS, not a hard pin: a consumer overrides them per client via
|
|
64
|
+
* `waterxEndpoint` / `waterxFetch` (resolved onto `client.waterx`).
|
|
65
|
+
*/
|
|
66
|
+
exports.WATERX_DEFAULTS = {
|
|
67
|
+
MAINNET: { endpoint: "https://quote-center.waterx.app" },
|
|
68
|
+
TESTNET: { endpoint: "https://quote-center-staging.waterx.app" },
|
|
69
|
+
};
|
|
@@ -9,15 +9,26 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { SuiGrpcClient } from "@mysten/sui/grpc";
|
|
11
11
|
import type { Network } from "../constants.ts";
|
|
12
|
-
import type { OracleConfig, PythInfraConfig } from "./config.ts";
|
|
12
|
+
import type { OracleConfig, PythInfraConfig, WaterxInfraConfig } from "./config.ts";
|
|
13
13
|
import type { OracleSource } from "./price-update-rule.ts";
|
|
14
14
|
export interface OracleHost {
|
|
15
15
|
/** Sui network this client targets — selects per-network external-infra defaults (e.g. `LAZER_DEFAULTS`). */
|
|
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;
|
|
19
|
-
/** External Pyth/Wormhole/Hermes infra (network
|
|
19
|
+
/** External Pyth/Wormhole/Hermes infra — fixed per `(network, generation)`; api_key/fetch layered from create options. */
|
|
20
20
|
readonly pyth: PythInfraConfig;
|
|
21
|
+
/**
|
|
22
|
+
* WaterX quote-center infra for `WaterxRule` — endpoint + fetch policy,
|
|
23
|
+
* resolved from the `waterxEndpoint` / `waterxFetch` create options.
|
|
24
|
+
*
|
|
25
|
+
* OPTIONAL so an existing host stays a valid `OracleHost`: when absent the
|
|
26
|
+
* rule falls back to `WATERX_DEFAULTS[network]`. This is the hook a browser
|
|
27
|
+
* consumer uses to route the quote-center fetch through a same-origin proxy
|
|
28
|
+
* (`endpoint`) or its own transport (`fetch.fetchImpl`) — that request is
|
|
29
|
+
* made from the page, so it is bound by the quote-center's CORS allowlist.
|
|
30
|
+
*/
|
|
31
|
+
readonly waterx?: WaterxInfraConfig;
|
|
21
32
|
/** gRPC client for the on-chain reads the Pyth update path needs. */
|
|
22
33
|
readonly grpcClient: SuiGrpcClient;
|
|
23
34
|
/**
|
|
@@ -16,15 +16,17 @@
|
|
|
16
16
|
* rules that consume it are separate concerns.
|
|
17
17
|
*/
|
|
18
18
|
export type { OracleHost } from "./host.ts";
|
|
19
|
-
export { FetchPolicyError } from "./update-fetch.ts";
|
|
19
|
+
export { FetchPolicyError, fetchWithPolicy, joinEndpointPath } from "./update-fetch.ts";
|
|
20
20
|
export type { FetchPolicy } from "./update-fetch.ts";
|
|
21
|
-
export { PythCache, fetchPriceFeedsUpdateData, buildPythPriceUpdateCalls, updatePythPrices, OracleFeeSourceUnavailableError, } from "./pyth.ts";
|
|
21
|
+
export { PythCache, fetchPriceFeedsUpdateData, endpointSupportedFeedIds, probeMissingFeeds, buildPythPriceUpdateCalls, updatePythPrices, HermesEndpointRejectedAllFeedsError, MISSING_FEED_MEMO_TTL_MS, OracleFeeSourceUnavailableError, } from "./pyth.ts";
|
|
22
22
|
export type { OracleFeeSource } from "./pyth.ts";
|
|
23
23
|
export type { PriceUpdateRule, PriceUpdateRuleKind, RuleUpdateData, RuleUpdateHandle, BuildUpdateOpts, OracleSource, UpdateDataProvider, } from "./price-update-rule.ts";
|
|
24
24
|
export { PythCoreRule } from "./rules/pyth-core-rule.ts";
|
|
25
25
|
export type { PythCoreUpdatePayload } from "./rules/pyth-core-rule.ts";
|
|
26
26
|
export { PythLazerRule, LazerApiKeyMissingError } from "./rules/pyth-lazer-rule.ts";
|
|
27
27
|
export type { PythLazerUpdatePayload } from "./rules/pyth-lazer-rule.ts";
|
|
28
|
+
export { WaterxRule, parseSignedEnvelope } from "./rules/waterx-rule.ts";
|
|
29
|
+
export type { WaterxUpdatePayload, WaterxSignedEnvelope, WaterxBatchItem, } from "./rules/waterx-rule.ts";
|
|
28
30
|
export { OracleSourceNotImplementedError } from "./rule-registry.ts";
|
|
29
31
|
export { aggregateTicker, aggregateTickerWithPyth, aggregateTickerWithConstant, refreshOraclePrices, } from "./aggregate.ts";
|
|
30
32
|
export { openPythSponsorFund, reimbursePythSponsor } from "./rules/sponsor.ts";
|