@waterx/sdk 4.3.2 → 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 (150) hide show
  1. package/.claude/skills/waterx-sdk-integration/SKILL.md +225 -0
  2. package/README.md +216 -45
  3. package/SKILLS.md +34 -0
  4. package/dist/cjs/src/account/config.d.ts +3 -5
  5. package/dist/cjs/src/account/funding/wormhole.d.ts +1 -2
  6. package/dist/cjs/src/account/funding/wormhole.js +1 -2
  7. package/dist/cjs/src/generated/waterx_rule/waterx_rule.d.ts +140 -7
  8. package/dist/cjs/src/generated/waterx_rule/waterx_rule.js +163 -8
  9. package/dist/cjs/src/oracle/aggregate.d.ts +49 -62
  10. package/dist/cjs/src/oracle/aggregate.js +208 -164
  11. package/dist/cjs/src/oracle/config.d.ts +38 -51
  12. package/dist/cjs/src/oracle/config.js +1 -1
  13. package/dist/cjs/src/oracle/host.d.ts +14 -19
  14. package/dist/cjs/src/oracle/host.js +3 -3
  15. package/dist/cjs/src/oracle/index.d.ts +25 -16
  16. package/dist/cjs/src/oracle/index.js +87 -69
  17. package/dist/cjs/src/oracle/price-update-rule.d.ts +104 -66
  18. package/dist/cjs/src/oracle/price-update-rule.js +24 -16
  19. package/dist/cjs/src/oracle/pyth-pro-history.d.ts +36 -0
  20. package/dist/cjs/src/oracle/pyth-pro-history.js +41 -0
  21. package/dist/cjs/src/oracle/read-plane.d.ts +35 -53
  22. package/dist/cjs/src/oracle/read-plane.js +26 -48
  23. package/dist/cjs/src/oracle/read-prices.d.ts +105 -0
  24. package/dist/cjs/src/oracle/read-prices.js +162 -0
  25. package/dist/cjs/src/oracle/rule-registry.d.ts +12 -12
  26. package/dist/cjs/src/oracle/rule-registry.js +12 -14
  27. package/dist/cjs/src/oracle/rules/pyth-lazer-rule.d.ts +24 -3
  28. package/dist/cjs/src/oracle/rules/pyth-lazer-rule.js +40 -20
  29. package/dist/cjs/src/oracle/rules/waterx-rule.d.ts +271 -57
  30. package/dist/cjs/src/oracle/rules/waterx-rule.js +743 -144
  31. package/dist/cjs/src/oracle/schedule.d.ts +109 -0
  32. package/dist/cjs/src/oracle/schedule.js +991 -0
  33. package/dist/cjs/src/oracle/source-list.d.ts +31 -27
  34. package/dist/cjs/src/oracle/source-list.js +43 -45
  35. package/dist/cjs/src/oracle/symbol-catalog.d.ts +54 -0
  36. package/dist/cjs/src/oracle/symbol-catalog.js +69 -0
  37. package/dist/cjs/src/oracle/update-fetch.d.ts +11 -15
  38. package/dist/cjs/src/oracle/update-fetch.js +12 -19
  39. package/dist/cjs/src/oracle/validate.d.ts +105 -0
  40. package/dist/cjs/src/oracle/validate.js +185 -0
  41. package/dist/cjs/src/oracle/weight-coverage.d.ts +79 -0
  42. package/dist/cjs/src/oracle/weight-coverage.js +173 -0
  43. package/dist/cjs/src/perp/client.d.ts +40 -55
  44. package/dist/cjs/src/perp/client.js +44 -17
  45. package/dist/cjs/src/perp/config-view.d.ts +5 -14
  46. package/dist/cjs/src/perp/config-view.js +5 -16
  47. package/dist/cjs/src/perp/config.d.ts +3 -3
  48. package/dist/cjs/src/perp/config.js +11 -13
  49. package/dist/cjs/src/perp/index.d.ts +4 -6
  50. package/dist/cjs/src/perp/index.js +43 -18
  51. package/dist/cjs/src/perp/tx-builders/common.d.ts +86 -48
  52. package/dist/cjs/src/perp/tx-builders/common.js +115 -47
  53. package/dist/cjs/src/perp/tx-builders/wlp.d.ts +3 -14
  54. package/dist/cjs/src/perp/tx-builders/wlp.js +6 -35
  55. package/dist/cjs/src/perp/tx-builders.d.ts +6 -5
  56. package/dist/cjs/src/perp/tx-builders.js +16 -10
  57. package/dist/cjs/src/unified-client.d.ts +9 -35
  58. package/dist/cjs/src/unified-client.js +3 -4
  59. package/dist/cjs/src/utils/config.d.ts +0 -8
  60. package/dist/cjs/src/utils/config.js +5 -13
  61. package/dist/src/account/config.d.ts +3 -5
  62. package/dist/src/account/funding/wormhole.d.ts +1 -2
  63. package/dist/src/account/funding/wormhole.js +1 -2
  64. package/dist/src/generated/waterx_rule/waterx_rule.d.ts +140 -7
  65. package/dist/src/generated/waterx_rule/waterx_rule.js +151 -7
  66. package/dist/src/oracle/aggregate.d.ts +49 -62
  67. package/dist/src/oracle/aggregate.js +209 -164
  68. package/dist/src/oracle/config.d.ts +38 -51
  69. package/dist/src/oracle/config.js +1 -1
  70. package/dist/src/oracle/host.d.ts +14 -19
  71. package/dist/src/oracle/host.js +3 -3
  72. package/dist/src/oracle/index.d.ts +25 -16
  73. package/dist/src/oracle/index.js +61 -54
  74. package/dist/src/oracle/price-update-rule.d.ts +104 -66
  75. package/dist/src/oracle/price-update-rule.js +23 -16
  76. package/dist/src/oracle/pyth-pro-history.d.ts +36 -0
  77. package/dist/src/oracle/pyth-pro-history.js +38 -0
  78. package/dist/src/oracle/read-plane.d.ts +35 -53
  79. package/dist/src/oracle/read-plane.js +25 -47
  80. package/dist/src/oracle/read-prices.d.ts +105 -0
  81. package/dist/src/oracle/read-prices.js +156 -0
  82. package/dist/src/oracle/rule-registry.d.ts +12 -12
  83. package/dist/src/oracle/rule-registry.js +12 -14
  84. package/dist/src/oracle/rules/pyth-lazer-rule.d.ts +24 -3
  85. package/dist/src/oracle/rules/pyth-lazer-rule.js +39 -20
  86. package/dist/src/oracle/rules/waterx-rule.d.ts +271 -57
  87. package/dist/src/oracle/rules/waterx-rule.js +735 -144
  88. package/dist/src/oracle/schedule.d.ts +109 -0
  89. package/dist/src/oracle/schedule.js +985 -0
  90. package/dist/src/oracle/source-list.d.ts +31 -27
  91. package/dist/src/oracle/source-list.js +42 -43
  92. package/dist/src/oracle/symbol-catalog.d.ts +54 -0
  93. package/dist/src/oracle/symbol-catalog.js +65 -0
  94. package/dist/src/oracle/update-fetch.d.ts +11 -15
  95. package/dist/src/oracle/update-fetch.js +12 -18
  96. package/dist/src/oracle/validate.d.ts +105 -0
  97. package/dist/src/oracle/validate.js +177 -0
  98. package/dist/src/oracle/weight-coverage.d.ts +79 -0
  99. package/dist/src/oracle/weight-coverage.js +166 -0
  100. package/dist/src/perp/client.d.ts +40 -55
  101. package/dist/src/perp/client.js +45 -18
  102. package/dist/src/perp/config-view.d.ts +5 -14
  103. package/dist/src/perp/config-view.js +5 -16
  104. package/dist/src/perp/config.d.ts +3 -3
  105. package/dist/src/perp/config.js +11 -13
  106. package/dist/src/perp/index.d.ts +4 -6
  107. package/dist/src/perp/index.js +17 -5
  108. package/dist/src/perp/tx-builders/common.d.ts +86 -48
  109. package/dist/src/perp/tx-builders/common.js +114 -48
  110. package/dist/src/perp/tx-builders/wlp.d.ts +3 -14
  111. package/dist/src/perp/tx-builders/wlp.js +6 -35
  112. package/dist/src/perp/tx-builders.d.ts +6 -5
  113. package/dist/src/perp/tx-builders.js +15 -6
  114. package/dist/src/unified-client.d.ts +9 -35
  115. package/dist/src/unified-client.js +3 -4
  116. package/dist/src/utils/config.d.ts +0 -8
  117. package/dist/src/utils/config.js +5 -12
  118. package/package.json +8 -2
  119. package/dist/cjs/src/generated/pyth_sponsor_rule/deps/sui/balance.d.ts +0 -12
  120. package/dist/cjs/src/generated/pyth_sponsor_rule/deps/sui/balance.js +0 -17
  121. package/dist/cjs/src/generated/pyth_sponsor_rule/pyth_sponsor_rule.d.ts +0 -68
  122. package/dist/cjs/src/generated/pyth_sponsor_rule/pyth_sponsor_rule.js +0 -113
  123. package/dist/cjs/src/generated/waterx_pyth_rule/deps/sui/vec_map.d.ts +0 -36
  124. package/dist/cjs/src/generated/waterx_pyth_rule/deps/sui/vec_map.js +0 -31
  125. package/dist/cjs/src/generated/waterx_pyth_rule/pyth_rule.d.ts +0 -192
  126. package/dist/cjs/src/generated/waterx_pyth_rule/pyth_rule.js +0 -214
  127. package/dist/cjs/src/oracle/pyth.d.ts +0 -227
  128. package/dist/cjs/src/oracle/pyth.js +0 -652
  129. package/dist/cjs/src/oracle/rules/pyth-core-rule.d.ts +0 -15
  130. package/dist/cjs/src/oracle/rules/pyth-core-rule.js +0 -100
  131. package/dist/cjs/src/oracle/rules/pyth-rule.d.ts +0 -11
  132. package/dist/cjs/src/oracle/rules/pyth-rule.js +0 -29
  133. package/dist/cjs/src/oracle/rules/sponsor.d.ts +0 -32
  134. package/dist/cjs/src/oracle/rules/sponsor.js +0 -56
  135. package/dist/src/generated/pyth_sponsor_rule/deps/sui/balance.d.ts +0 -12
  136. package/dist/src/generated/pyth_sponsor_rule/deps/sui/balance.js +0 -14
  137. package/dist/src/generated/pyth_sponsor_rule/pyth_sponsor_rule.d.ts +0 -68
  138. package/dist/src/generated/pyth_sponsor_rule/pyth_sponsor_rule.js +0 -73
  139. package/dist/src/generated/waterx_pyth_rule/deps/sui/vec_map.d.ts +0 -36
  140. package/dist/src/generated/waterx_pyth_rule/deps/sui/vec_map.js +0 -27
  141. package/dist/src/generated/waterx_pyth_rule/pyth_rule.d.ts +0 -192
  142. package/dist/src/generated/waterx_pyth_rule/pyth_rule.js +0 -170
  143. package/dist/src/oracle/pyth.d.ts +0 -227
  144. package/dist/src/oracle/pyth.js +0 -638
  145. package/dist/src/oracle/rules/pyth-core-rule.d.ts +0 -15
  146. package/dist/src/oracle/rules/pyth-core-rule.js +0 -97
  147. package/dist/src/oracle/rules/pyth-rule.d.ts +0 -11
  148. package/dist/src/oracle/rules/pyth-rule.js +0 -26
  149. package/dist/src/oracle/rules/sponsor.d.ts +0 -32
  150. package/dist/src/oracle/rules/sponsor.js +0 -52
@@ -70,6 +70,11 @@ export declare const BatchPricePayload: MoveStruct<{
70
70
  length: number;
71
71
  }, string>;
72
72
  }, "@waterx/rule::waterx_rule::BatchPricePayload">;
73
+ export declare const MerkleRoot: MoveStruct<{
74
+ root: import("@mysten/sui/bcs").BcsType<number[], Iterable<number> & {
75
+ length: number;
76
+ }, string>;
77
+ }, "@waterx/rule::waterx_rule::MerkleRoot">;
73
78
  export declare const FeedConfig: MoveStruct<{
74
79
  ticker: import("@mysten/sui/bcs").BcsType<string, string, "string">;
75
80
  sources: import("@mysten/sui/bcs").BcsType<string[], Iterable<string | number | bigint> & {
@@ -214,17 +219,82 @@ export interface CollectBatchLatestOptions {
214
219
  * and so aborts on any stale item, this path runs alongside Pyth/Supra. To let
215
220
  * those cover a lagging TEE — the blast-radius bound in the GCP ADR — a
216
221
  * _freshness_ miss ABSTAINS (records `none`, which `aggregator::remove_outliers`
217
- * drops before the `weight_threshold` fail-closed check). A _config/integrity_
218
- * mismatch (source / ticker / method / confidence / deviation) still ABORTS: an
219
- * enclave whose signed payload disagrees with the on-chain feed config is a red
220
- * flag, not a liveness blip. Bad signature, malformed batch, a future timestamp,
221
- * and replay always abort.
222
+ * drops before the `weight_threshold` fail-closed check), and so does a _replayed_
223
+ * signed timestamp (the chain already accepted that snapshot the on-chain price
224
+ * is at least as fresh, and two concurrent keeper PTBs sharing one envelope must
225
+ * not kill each other). A _config/integrity_ mismatch (source / ticker / method /
226
+ * confidence / deviation) still ABORTS: an enclave whose signed payload disagrees
227
+ * with the on-chain feed config is a red flag, not a liveness blip. Bad signature,
228
+ * malformed batch, and a future timestamp always abort.
222
229
  *
223
230
  * Every gate is identical to `feed_batch_item_latest`; only the abort-vs-abstain
224
- * disposition of the two freshness gates differs, and the sink is the caller's
225
- * collector rather than a fresh single-rule one.
231
+ * disposition of the freshness + replay gates differs, and the sink is the
232
+ * caller's collector rather than a fresh single-rule one.
226
233
  */
227
234
  export declare function collectBatchLatest(options: CollectBatchLatestOptions): (tx: Transaction) => import("@mysten/sui/transactions").TransactionResult;
235
+ export interface FeedSingleWithProofArguments {
236
+ oracleObj: RawTransactionArgument<string>;
237
+ config: RawTransactionArgument<string>;
238
+ enclaveConfig: RawTransactionArgument<string>;
239
+ enclave: RawTransactionArgument<string>;
240
+ timestampMs: RawTransactionArgument<number | bigint>;
241
+ item: TransactionArgument;
242
+ proof: RawTransactionArgument<Array<Array<number>>>;
243
+ sig: RawTransactionArgument<Array<number>>;
244
+ }
245
+ export interface FeedSingleWithProofOptions {
246
+ package?: string;
247
+ arguments: FeedSingleWithProofArguments | [
248
+ oracleObj: RawTransactionArgument<string>,
249
+ config: RawTransactionArgument<string>,
250
+ enclaveConfig: RawTransactionArgument<string>,
251
+ enclave: RawTransactionArgument<string>,
252
+ timestampMs: RawTransactionArgument<number | bigint>,
253
+ item: TransactionArgument,
254
+ proof: RawTransactionArgument<Array<Array<number>>>,
255
+ sig: RawTransactionArgument<Array<number>>
256
+ ];
257
+ }
258
+ /**
259
+ * Streaming per-symbol sibling of `feed_batch_latest`. Verifies ONE enclave
260
+ * signature over a Merkle `root`, checks `item` is a leaf of that root via
261
+ * `proof`, then runs the identical per-item gates + `oracle::aggregate`. Use for a
262
+ * WaterxRule-only aggregator; for a Pyth-coexisting aggregator use
263
+ * `collect_single_with_proof`.
264
+ */
265
+ export declare function feedSingleWithProof(options: FeedSingleWithProofOptions): (tx: Transaction) => import("@mysten/sui/transactions").TransactionResult;
266
+ export interface CollectSingleWithProofArguments {
267
+ collector: TransactionArgument;
268
+ config: RawTransactionArgument<string>;
269
+ enclaveConfig: RawTransactionArgument<string>;
270
+ enclave: RawTransactionArgument<string>;
271
+ timestampMs: RawTransactionArgument<number | bigint>;
272
+ item: TransactionArgument;
273
+ proof: RawTransactionArgument<Array<Array<number>>>;
274
+ sig: RawTransactionArgument<Array<number>>;
275
+ }
276
+ export interface CollectSingleWithProofOptions {
277
+ package?: string;
278
+ arguments: CollectSingleWithProofArguments | [
279
+ collector: TransactionArgument,
280
+ config: RawTransactionArgument<string>,
281
+ enclaveConfig: RawTransactionArgument<string>,
282
+ enclave: RawTransactionArgument<string>,
283
+ timestampMs: RawTransactionArgument<number | bigint>,
284
+ item: TransactionArgument,
285
+ proof: RawTransactionArgument<Array<Array<number>>>,
286
+ sig: RawTransactionArgument<Array<number>>
287
+ ];
288
+ }
289
+ /**
290
+ * Collect-only sibling of `feed_single_with_proof` for the dual-rule latest path
291
+ * (WaterX alongside Pyth on one aggregator), mirroring `collect_batch_latest`:
292
+ * verifies root + proof, feeds the leaf into the caller's `PriceCollector` WITHOUT
293
+ * calling `oracle::aggregate`. Abort vs abstain matches `collect_batch_latest`
294
+ * exactly — a config/integrity mismatch aborts, a freshness miss abstains so Pyth
295
+ * can cover a lagging TEE.
296
+ */
297
+ export declare function collectSingleWithProof(options: CollectSingleWithProofOptions): (tx: Transaction) => import("@mysten/sui/transactions").TransactionResult;
228
298
  export interface QuoteForTimestampArguments {
229
299
  config: RawTransactionArgument<string>;
230
300
  enclaveConfig: RawTransactionArgument<string>;
@@ -421,6 +491,27 @@ export interface BatchPriceIntentOptions {
421
491
  ];
422
492
  }
423
493
  export declare function batchPriceIntent(options?: BatchPriceIntentOptions): (tx: Transaction) => import("@mysten/sui/transactions").TransactionResult;
494
+ export interface MerkleRootIntentOptions {
495
+ package?: string;
496
+ arguments?: [
497
+ ];
498
+ }
499
+ export declare function merkleRootIntent(options?: MerkleRootIntentOptions): (tx: Transaction) => import("@mysten/sui/transactions").TransactionResult;
500
+ export interface LeafHashOfArguments {
501
+ item: TransactionArgument;
502
+ }
503
+ export interface LeafHashOfOptions {
504
+ package?: string;
505
+ arguments: LeafHashOfArguments | [
506
+ item: TransactionArgument
507
+ ];
508
+ }
509
+ /**
510
+ * The keccak256 leaf hash for `item` — `keccak256(0x00 || BCS(item))`. Exposed so
511
+ * the off-chain builder / SDK can be pinned against the on-chain encoding in a
512
+ * cross-implementation golden test.
513
+ */
514
+ export declare function leafHashOf(options: LeafHashOfOptions): (tx: Transaction) => import("@mysten/sui/transactions").TransactionResult;
424
515
  export interface MaxBatchSizeOptions {
425
516
  package?: string;
426
517
  arguments?: [
@@ -717,6 +808,48 @@ export interface SourceGataUsdtPerpWsOptions {
717
808
  ];
718
809
  }
719
810
  export declare function sourceGataUsdtPerpWs(options?: SourceGataUsdtPerpWsOptions): (tx: Transaction) => import("@mysten/sui/transactions").TransactionResult;
811
+ export interface SourceBybitSpotWsOptions {
812
+ package?: string;
813
+ arguments?: [
814
+ ];
815
+ }
816
+ export declare function sourceBybitSpotWs(options?: SourceBybitSpotWsOptions): (tx: Transaction) => import("@mysten/sui/transactions").TransactionResult;
817
+ export interface SourceXstockEquityRestOptions {
818
+ package?: string;
819
+ arguments?: [
820
+ ];
821
+ }
822
+ export declare function sourceXstockEquityRest(options?: SourceXstockEquityRestOptions): (tx: Transaction) => import("@mysten/sui/transactions").TransactionResult;
823
+ export interface SourceOkxSpotWsOptions {
824
+ package?: string;
825
+ arguments?: [
826
+ ];
827
+ }
828
+ export declare function sourceOkxSpotWs(options?: SourceOkxSpotWsOptions): (tx: Transaction) => import("@mysten/sui/transactions").TransactionResult;
829
+ export interface SourceHyperliquidPerpWsOptions {
830
+ package?: string;
831
+ arguments?: [
832
+ ];
833
+ }
834
+ export declare function sourceHyperliquidPerpWs(options?: SourceHyperliquidPerpWsOptions): (tx: Transaction) => import("@mysten/sui/transactions").TransactionResult;
835
+ export interface SourceGateioSpotWsOptions {
836
+ package?: string;
837
+ arguments?: [
838
+ ];
839
+ }
840
+ export declare function sourceGateioSpotWs(options?: SourceGateioSpotWsOptions): (tx: Transaction) => import("@mysten/sui/transactions").TransactionResult;
841
+ export interface SourceKrakenSpotWsOptions {
842
+ package?: string;
843
+ arguments?: [
844
+ ];
845
+ }
846
+ export declare function sourceKrakenSpotWs(options?: SourceKrakenSpotWsOptions): (tx: Transaction) => import("@mysten/sui/transactions").TransactionResult;
847
+ export interface SourcePythLazerWsOptions {
848
+ package?: string;
849
+ arguments?: [
850
+ ];
851
+ }
852
+ export declare function sourcePythLazerWs(options?: SourcePythLazerWsOptions): (tx: Transaction) => import("@mysten/sui/transactions").TransactionResult;
720
853
  export interface MethodDirectOptions {
721
854
  package?: string;
722
855
  arguments?: [
@@ -41,6 +41,9 @@ export const BatchPriceItem = new MoveStruct({ name: `${$moduleName}::BatchPrice
41
41
  export const BatchPricePayload = new MoveStruct({ name: `${$moduleName}::BatchPricePayload`, fields: {
42
42
  items: bcs.vector(BatchPriceItem)
43
43
  } });
44
+ export const MerkleRoot = new MoveStruct({ name: `${$moduleName}::MerkleRoot`, fields: {
45
+ root: bcs.vector(bcs.u8())
46
+ } });
44
47
  export const FeedConfig = new MoveStruct({ name: `${$moduleName}::FeedConfig`, fields: {
45
48
  ticker: bcs.string(),
46
49
  sources: bcs.vector(bcs.u64()),
@@ -126,15 +129,17 @@ export function feedBatchLatest(options) {
126
129
  * and so aborts on any stale item, this path runs alongside Pyth/Supra. To let
127
130
  * those cover a lagging TEE — the blast-radius bound in the GCP ADR — a
128
131
  * _freshness_ miss ABSTAINS (records `none`, which `aggregator::remove_outliers`
129
- * drops before the `weight_threshold` fail-closed check). A _config/integrity_
130
- * mismatch (source / ticker / method / confidence / deviation) still ABORTS: an
131
- * enclave whose signed payload disagrees with the on-chain feed config is a red
132
- * flag, not a liveness blip. Bad signature, malformed batch, a future timestamp,
133
- * and replay always abort.
132
+ * drops before the `weight_threshold` fail-closed check), and so does a _replayed_
133
+ * signed timestamp (the chain already accepted that snapshot the on-chain price
134
+ * is at least as fresh, and two concurrent keeper PTBs sharing one envelope must
135
+ * not kill each other). A _config/integrity_ mismatch (source / ticker / method /
136
+ * confidence / deviation) still ABORTS: an enclave whose signed payload disagrees
137
+ * with the on-chain feed config is a red flag, not a liveness blip. Bad signature,
138
+ * malformed batch, and a future timestamp always abort.
134
139
  *
135
140
  * Every gate is identical to `feed_batch_item_latest`; only the abort-vs-abstain
136
- * disposition of the two freshness gates differs, and the sink is the caller's
137
- * collector rather than a fresh single-rule one.
141
+ * disposition of the freshness + replay gates differs, and the sink is the
142
+ * caller's collector rather than a fresh single-rule one.
138
143
  */
139
144
  export function collectBatchLatest(options) {
140
145
  const packageAddress = options.package ?? '@waterx/rule';
@@ -156,6 +161,63 @@ export function collectBatchLatest(options) {
156
161
  arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
157
162
  });
158
163
  }
164
+ /**
165
+ * Streaming per-symbol sibling of `feed_batch_latest`. Verifies ONE enclave
166
+ * signature over a Merkle `root`, checks `item` is a leaf of that root via
167
+ * `proof`, then runs the identical per-item gates + `oracle::aggregate`. Use for a
168
+ * WaterxRule-only aggregator; for a Pyth-coexisting aggregator use
169
+ * `collect_single_with_proof`.
170
+ */
171
+ export function feedSingleWithProof(options) {
172
+ const packageAddress = options.package ?? '@waterx/rule';
173
+ const argumentsTypes = [
174
+ null,
175
+ null,
176
+ '0x2::clock::Clock',
177
+ null,
178
+ null,
179
+ 'u64',
180
+ null,
181
+ 'vector<vector<u8>>',
182
+ 'vector<u8>'
183
+ ];
184
+ const parameterNames = ["oracleObj", "config", "enclaveConfig", "enclave", "timestampMs", "item", "proof", "sig"];
185
+ return (tx) => tx.moveCall({
186
+ package: packageAddress,
187
+ module: 'waterx_rule',
188
+ function: 'feed_single_with_proof',
189
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
190
+ });
191
+ }
192
+ /**
193
+ * Collect-only sibling of `feed_single_with_proof` for the dual-rule latest path
194
+ * (WaterX alongside Pyth on one aggregator), mirroring `collect_batch_latest`:
195
+ * verifies root + proof, feeds the leaf into the caller's `PriceCollector` WITHOUT
196
+ * calling `oracle::aggregate`. Abort vs abstain matches `collect_batch_latest`
197
+ * exactly — a config/integrity mismatch aborts, a freshness miss abstains so Pyth
198
+ * can cover a lagging TEE.
199
+ */
200
+ export function collectSingleWithProof(options) {
201
+ const packageAddress = options.package ?? '@waterx/rule';
202
+ const argumentsTypes = [
203
+ null,
204
+ null,
205
+ '0x2::clock::Clock',
206
+ null,
207
+ null,
208
+ 'u64',
209
+ null,
210
+ 'vector<vector<u8>>',
211
+ 'vector<u8>'
212
+ ];
213
+ const parameterNames = ["collector", "config", "enclaveConfig", "enclave", "timestampMs", "item", "proof", "sig"];
214
+ return (tx) => tx.moveCall({
215
+ package: packageAddress,
216
+ module: 'waterx_rule',
217
+ function: 'collect_single_with_proof',
218
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
219
+ });
220
+ }
159
221
  /**
160
222
  * Verifies a historical quote without touching `waterx_oracle`.
161
223
  *
@@ -347,6 +409,32 @@ export function batchPriceIntent(options = {}) {
347
409
  function: 'batch_price_intent',
348
410
  });
349
411
  }
412
+ export function merkleRootIntent(options = {}) {
413
+ const packageAddress = options.package ?? '@waterx/rule';
414
+ return (tx) => tx.moveCall({
415
+ package: packageAddress,
416
+ module: 'waterx_rule',
417
+ function: 'merkle_root_intent',
418
+ });
419
+ }
420
+ /**
421
+ * The keccak256 leaf hash for `item` — `keccak256(0x00 || BCS(item))`. Exposed so
422
+ * the off-chain builder / SDK can be pinned against the on-chain encoding in a
423
+ * cross-implementation golden test.
424
+ */
425
+ export function leafHashOf(options) {
426
+ const packageAddress = options.package ?? '@waterx/rule';
427
+ const argumentsTypes = [
428
+ null
429
+ ];
430
+ const parameterNames = ["item"];
431
+ return (tx) => tx.moveCall({
432
+ package: packageAddress,
433
+ module: 'waterx_rule',
434
+ function: 'leaf_hash_of',
435
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
436
+ });
437
+ }
350
438
  export function maxBatchSize(options = {}) {
351
439
  const packageAddress = options.package ?? '@waterx/rule';
352
440
  return (tx) => tx.moveCall({
@@ -733,6 +821,62 @@ export function sourceGataUsdtPerpWs(options = {}) {
733
821
  function: 'source_gata_usdt_perp_ws',
734
822
  });
735
823
  }
824
+ export function sourceBybitSpotWs(options = {}) {
825
+ const packageAddress = options.package ?? '@waterx/rule';
826
+ return (tx) => tx.moveCall({
827
+ package: packageAddress,
828
+ module: 'waterx_rule',
829
+ function: 'source_bybit_spot_ws',
830
+ });
831
+ }
832
+ export function sourceXstockEquityRest(options = {}) {
833
+ const packageAddress = options.package ?? '@waterx/rule';
834
+ return (tx) => tx.moveCall({
835
+ package: packageAddress,
836
+ module: 'waterx_rule',
837
+ function: 'source_xstock_equity_rest',
838
+ });
839
+ }
840
+ export function sourceOkxSpotWs(options = {}) {
841
+ const packageAddress = options.package ?? '@waterx/rule';
842
+ return (tx) => tx.moveCall({
843
+ package: packageAddress,
844
+ module: 'waterx_rule',
845
+ function: 'source_okx_spot_ws',
846
+ });
847
+ }
848
+ export function sourceHyperliquidPerpWs(options = {}) {
849
+ const packageAddress = options.package ?? '@waterx/rule';
850
+ return (tx) => tx.moveCall({
851
+ package: packageAddress,
852
+ module: 'waterx_rule',
853
+ function: 'source_hyperliquid_perp_ws',
854
+ });
855
+ }
856
+ export function sourceGateioSpotWs(options = {}) {
857
+ const packageAddress = options.package ?? '@waterx/rule';
858
+ return (tx) => tx.moveCall({
859
+ package: packageAddress,
860
+ module: 'waterx_rule',
861
+ function: 'source_gateio_spot_ws',
862
+ });
863
+ }
864
+ export function sourceKrakenSpotWs(options = {}) {
865
+ const packageAddress = options.package ?? '@waterx/rule';
866
+ return (tx) => tx.moveCall({
867
+ package: packageAddress,
868
+ module: 'waterx_rule',
869
+ function: 'source_kraken_spot_ws',
870
+ });
871
+ }
872
+ export function sourcePythLazerWs(options = {}) {
873
+ const packageAddress = options.package ?? '@waterx/rule';
874
+ return (tx) => tx.moveCall({
875
+ package: packageAddress,
876
+ module: 'waterx_rule',
877
+ function: 'source_pyth_lazer_ws',
878
+ });
879
+ }
736
880
  export function methodDirect(options = {}) {
737
881
  const packageAddress = options.package ?? '@waterx/rule';
738
882
  return (tx) => tx.moveCall({
@@ -2,12 +2,12 @@
2
2
  * Oracle aggregation — the orchestrator that composes rules into the shared
3
3
  * `Oracle`. This is the ONE file that knows about every rule: it builds a
4
4
  * `PriceCollector`, feeds whichever rules a ticker is configured for
5
- * (Pyth / Lazer / Supra / Constant), then `aggregate`s.
5
+ * (Lazer / Waterx / Supra / Constant), then `aggregate`s.
6
6
  *
7
7
  * Per ticker:
8
8
  * collector = oracle::new_collector(ticker)
9
- * [pyth_rule::feed] when the ticker has a pyth_rule.feeds entry
10
9
  * [pyth_lazer_rule::feed] when the update leg produced a verified lazer Update
10
+ * [waterx_rule::collect_*] when the update leg fetched signed waterx data
11
11
  * [supra_rule::feed] when supra is enabled + wired
12
12
  * [constant_rule::feed] when the ticker is a constant ticker
13
13
  * oracle::aggregate(oracle, collector)
@@ -24,67 +24,68 @@
24
24
  */
25
25
  import type { Transaction, TransactionArgument } from "@mysten/sui/transactions";
26
26
  import type { OracleHost } from "./host.ts";
27
- import type { OracleSource, PriceUpdateRule, UpdateDataProvider } from "./price-update-rule.ts";
28
- import { type OracleFeeSource, type PythCache } from "./pyth.ts";
29
- import { type WaterxSignedEnvelope } from "./rules/waterx-rule.ts";
27
+ import { type OracleSource, type PriceUpdateRule, type UpdateDataProvider } from "./price-update-rule.ts";
28
+ import { type WaterxSignedEnvelope, type WaterxSignedLeaf } from "./rules/waterx-rule.ts";
30
29
  /**
31
30
  * Aggregate one ticker's price into the shared `Oracle`: build a collector, feed
32
31
  * every rule the ticker is configured for, then `aggregate`.
33
32
  *
34
- * - **Pyth** — fed when `priceInfoObjectId` is supplied (i.e. the ticker has a
35
- * `pyth_rule.feeds` entry). When this PTB's update leg refreshed the
36
- * `PriceInfoObject` it contributes a fresh price; when it did not (a
37
- * lazer-routed ticker), the on-chain rule only READS the object and abstains
38
- * if it is stale — it never aborts — so the call stays mandatory while
39
- * `pyth_rule` remains in the ticker's on-chain weighted set
40
- * (`EMissingPriceSource` requires every weighted rule to appear).
41
33
  * - **Lazer** — fed when `lazerUpdate` is supplied: the verified update this
42
34
  * PTB's lazer update leg produced with the network's verify entry
43
35
  * (`update_v2::Update` on mainnet, `update::Update` on testnet — see
44
36
  * `PythLazerRule.buildUpdateCalls`). If the ticker's aggregator does
45
37
  * not (yet) weight `PythLazerRule`, the contribution is silently dropped
46
38
  * on-chain — feeding ahead of the weight migration is harmless.
47
- * - **Supra** — fed alongside Pyth/Lazer when supra is enabled + wired
39
+ * - **Waterx** — fed when `waterxLeaf` (default shape) or `waterxEnvelope`
40
+ * (fallback shape) is supplied; verify AND feed are bundled into the one
41
+ * collect call per collector.
42
+ * - **Supra** — fed alongside the sources when supra is enabled + wired
48
43
  * (abstains on-chain for symbols it has no pair for).
49
44
  * - **Constant** — fed when the ticker is a constant ticker
50
45
  * ({@link OracleHost.isConstantTicker}).
51
46
  *
52
- * "Dual-feed" (Pyth + Constant, or Pyth + Lazer) and "constant-only" are not
47
+ * "Dual-feed" (Lazer + Constant, or Lazer + Waterx) and "constant-only" are not
53
48
  * special cases — they fall out of which rules the ticker is in. Throws if no
54
49
  * rule applies.
55
50
  */
56
51
  export declare function aggregateTicker(tx: Transaction, host: OracleHost, args: {
57
52
  ticker: string;
58
- priceInfoObjectId?: string;
59
53
  lazerUpdate?: TransactionArgument;
54
+ /** This ticker's signed Merkle leaf — the default waterx shape. */
55
+ waterxLeaf?: WaterxSignedLeaf;
56
+ /** Batch envelope covering this ticker — the fallback waterx shape. */
60
57
  waterxEnvelope?: WaterxSignedEnvelope;
61
58
  }): void;
62
59
  /**
63
- * Thin wrapper over {@link aggregateTicker} for a Pyth-fed ticker. Kept for
64
- * back-compat (e.g. WLP mint builds). Caller must run the Pyth update first.
60
+ * {@link aggregateTicker} for a **constant-only** ticker (no source update
61
+ * needed the price comes from the on-chain `constant_rule::Config`). Kept as
62
+ * a named entry so constant-only call sites (e.g. WLP builders refreshing the
63
+ * USDCUSD pool token) read as what they are; it adds nothing over
64
+ * `aggregateTicker(tx, host, { ticker })`.
65
65
  */
66
- export declare function aggregateTickerWithPyth(tx: Transaction, host: OracleHost, args: {
66
+ export declare function aggregateTickerWithConstant(tx: Transaction, host: OracleHost, args: {
67
67
  ticker: string;
68
- priceInfoObjectId: string;
69
68
  }): void;
70
69
  /**
71
- * {@link aggregateTicker} for a **constant-only** ticker (no Pyth update needed —
72
- * the price comes from the on-chain `constant_rule::Config`).
70
+ * What {@link refreshOraclePrices} actually put on chain.
73
71
  *
74
- * Throws if the ticker ALSO has a `pyth_rule.feeds` entry (a dual-feed transition
75
- * ticker): feeding only the constant leg would leave the still-weighted Pyth rule
76
- * absent from the collector and abort `aggregate` with `EMissingPriceSource`. Such
77
- * tickers must go through {@link aggregateTicker} with a `priceInfoObjectId` (or
78
- * {@link refreshOraclePrices}), which feeds both.
72
+ * `skipped` holds the requested tickers NO listed source can price (and that
73
+ * `constant_rule` does not pin). They got no collector and no aggregate, so
74
+ * their on-chain price is whatever a previous transaction left — which is why
75
+ * every caller whose ACTION depends on a ticker must check this rather than
76
+ * assume the refresh covered its whole request.
79
77
  */
80
- export declare function aggregateTickerWithConstant(tx: Transaction, host: OracleHost, args: {
81
- ticker: string;
82
- }): void;
78
+ export interface OracleRefreshSummary {
79
+ /** Tickers aggregated in this PTB — includes constant-pinned ones. */
80
+ refreshed: string[];
81
+ /** Requested tickers no listed source serves. */
82
+ skipped: string[];
83
+ }
83
84
  /**
84
85
  * Refresh multiple tickers in one PTB. For each ticker {@link aggregateTicker}
85
- * feeds whichever rules it is configured for (Pyth if it has a `pyth_rule.feeds`
86
- * entry, Lazer if the lazer update leg served it — see below — Supra when
87
- * enabled, Constant when it's a constant ticker).
86
+ * feeds whichever rules it is configured for (Lazer if the lazer update leg
87
+ * served it, Waterx if the waterx leg fetched signed data for it — see below —
88
+ * Supra when enabled, Constant when it's a constant ticker).
88
89
  *
89
90
  * Before that, the on-chain price *update* leg is routed by the
90
91
  * `host.oracleSources` fed set (see `rule-registry.ts`): EVERY listed source
@@ -98,11 +99,15 @@ export declare function aggregateTickerWithConstant(tx: Transaction, host: Oracl
98
99
  * source's feeds is caught here.
99
100
  *
100
101
  * Each source's fetch + build runs against its own infra, guaranteeing
101
- * per-rule PTB atomicity. A fee-source pre-check runs first (any listed
102
- * source's `requiresFeeSource`) BEFORE any off-chain fetch or PTB mutation
103
- * so a fee-charging source with no `opts.feeSource` throws
104
- * `OracleFeeSourceUnavailable` with zero wasted network calls and zero stray
105
- * moveCalls. Only once that check passes do the off-chain fetches run — in
102
+ * per-rule PTB atomicity. A credential pre-check runs early: any group that
103
+ * still needs to fetch, whose rule declares a `credential` the host does not
104
+ * carry while `host.pyth.api_key` is unset, throws `LazerApiKeyMissing`
105
+ * BEFORE any ORACLE fetch or PTB mutation — zero wasted oracle calls, zero
106
+ * stray moveCalls. (With an `updateDataProvider` configured, its per-source
107
+ * lookups run first so the check can be scoped to the groups the cache did
108
+ * NOT serve; a consumer-implemented provider may do I/O of its own, so the
109
+ * guarantee is about oracle fetches, not about every possible round trip.)
110
+ * Only once that check passes do the off-chain fetches run — in
106
111
  * parallel across sources — and ALL settle before the first PTB mutation;
107
112
  * on-chain reads inside `buildUpdateCalls` can still fail mid-append for
108
113
  * other reasons — callers discard the tx on any throw.
@@ -111,32 +116,14 @@ export declare function aggregateTickerWithConstant(tx: Transaction, host: Oracl
111
116
  * `buildUpdateCalls` returns the verified `Update` PTB value
112
117
  * ({@link RuleUpdateHandle}), and every ticker in that group is aggregated
113
118
  * with `lazerUpdate` set so {@link aggregateTicker} appends
114
- * `pyth_lazer_rule::feed` against it. A lazer-routed ticker that still has a
115
- * `pyth_rule.feeds` entry ALSO keeps its `pyth_rule::feed` leg required
116
- * on-chain while `pyth_rule` stays in the ticker's weighted set
117
- * (`aggregator::remove_outliers` aborts `EMissingPriceSource` unless every
118
- * weighted rule appears in the collector; an abstention counts as
119
- * appearing), and safe: `pyth_rule::feed` only READS the `PriceInfoObject`
120
- * this PTB never refreshed and abstains when it is stale rather than
121
- * aborting. Conversely, a lazer feed call on an aggregator that does not
122
- * (yet) weight `PythLazerRule` is silently dropped on-chain — so
123
- * lazer-routing a ticker ahead of its on-chain weight migration prices it
124
- * from the remaining weighted rules instead of failing.
119
+ * `pyth_lazer_rule::feed` against it. A waterx-served group's signed data is
120
+ * carried straight from its fetched payload to the per-ticker collect call.
121
+ * A feed call on an aggregator that does not (yet) weight that rule is
122
+ * silently dropped on-chain so routing a ticker ahead of its on-chain
123
+ * weight migration prices it from the remaining weighted rules instead of
124
+ * failing.
125
125
  */
126
126
  export declare function refreshOraclePrices(tx: Transaction, host: OracleHost, tickers: string[], opts?: {
127
- cache?: PythCache;
128
- /**
129
- * The single resolved fee source for the Pyth update fee, forwarded
130
- * verbatim to each group's `PriceUpdateRule.buildUpdateCalls` as
131
- * `BuildUpdateOpts.feeSource`. Already-resolved by the caller (see
132
- * {@link OracleFeeSource}'s own doc for where/how) — this function makes
133
- * no sponsor-vs-gas decision itself, it only checks whether a source was
134
- * resolved at all. Ignored by rules with no update fee (e.g.
135
- * `pyth_lazer_rule`). Building with `feeSource` unset throws
136
- * `OracleFeeSourceUnavailable` (see `oracle/pyth.ts`) instead of
137
- * silently drawing from `tx.gas`.
138
- */
139
- feeSource?: OracleFeeSource;
140
127
  /**
141
128
  * @internal Test-only: layer fake `PriceUpdateRule`s on top of the
142
129
  * production registry (see `rule-registry.ts`'s `resolveOracleRule`).
@@ -153,4 +140,4 @@ export declare function refreshOraclePrices(tx: Transaction, host: OracleHost, t
153
140
  * payload) throws instead, since that is a caller bug, not a cache miss.
154
141
  */
155
142
  updateDataProvider?: UpdateDataProvider;
156
- }): Promise<void>;
143
+ }): Promise<OracleRefreshSummary>;