@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.
- package/.claude/skills/waterx-sdk-integration/SKILL.md +225 -0
- package/README.md +216 -45
- package/SKILLS.md +34 -0
- package/dist/cjs/src/account/config.d.ts +3 -5
- package/dist/cjs/src/account/funding/wormhole.d.ts +1 -2
- package/dist/cjs/src/account/funding/wormhole.js +1 -2
- package/dist/cjs/src/generated/waterx_rule/waterx_rule.d.ts +140 -7
- package/dist/cjs/src/generated/waterx_rule/waterx_rule.js +163 -8
- package/dist/cjs/src/oracle/aggregate.d.ts +49 -62
- package/dist/cjs/src/oracle/aggregate.js +208 -164
- package/dist/cjs/src/oracle/config.d.ts +38 -51
- package/dist/cjs/src/oracle/config.js +1 -1
- package/dist/cjs/src/oracle/host.d.ts +14 -19
- package/dist/cjs/src/oracle/host.js +3 -3
- package/dist/cjs/src/oracle/index.d.ts +25 -16
- package/dist/cjs/src/oracle/index.js +87 -69
- package/dist/cjs/src/oracle/price-update-rule.d.ts +104 -66
- package/dist/cjs/src/oracle/price-update-rule.js +24 -16
- package/dist/cjs/src/oracle/pyth-pro-history.d.ts +36 -0
- package/dist/cjs/src/oracle/pyth-pro-history.js +41 -0
- package/dist/cjs/src/oracle/read-plane.d.ts +35 -53
- package/dist/cjs/src/oracle/read-plane.js +26 -48
- package/dist/cjs/src/oracle/read-prices.d.ts +105 -0
- package/dist/cjs/src/oracle/read-prices.js +162 -0
- package/dist/cjs/src/oracle/rule-registry.d.ts +12 -12
- package/dist/cjs/src/oracle/rule-registry.js +12 -14
- package/dist/cjs/src/oracle/rules/pyth-lazer-rule.d.ts +24 -3
- package/dist/cjs/src/oracle/rules/pyth-lazer-rule.js +40 -20
- package/dist/cjs/src/oracle/rules/waterx-rule.d.ts +271 -57
- package/dist/cjs/src/oracle/rules/waterx-rule.js +743 -144
- package/dist/cjs/src/oracle/schedule.d.ts +109 -0
- package/dist/cjs/src/oracle/schedule.js +991 -0
- package/dist/cjs/src/oracle/source-list.d.ts +31 -27
- package/dist/cjs/src/oracle/source-list.js +43 -45
- package/dist/cjs/src/oracle/symbol-catalog.d.ts +54 -0
- package/dist/cjs/src/oracle/symbol-catalog.js +69 -0
- package/dist/cjs/src/oracle/update-fetch.d.ts +11 -15
- package/dist/cjs/src/oracle/update-fetch.js +12 -19
- package/dist/cjs/src/oracle/validate.d.ts +105 -0
- package/dist/cjs/src/oracle/validate.js +185 -0
- package/dist/cjs/src/oracle/weight-coverage.d.ts +79 -0
- package/dist/cjs/src/oracle/weight-coverage.js +173 -0
- package/dist/cjs/src/perp/client.d.ts +40 -55
- package/dist/cjs/src/perp/client.js +44 -17
- package/dist/cjs/src/perp/config-view.d.ts +5 -14
- package/dist/cjs/src/perp/config-view.js +5 -16
- package/dist/cjs/src/perp/config.d.ts +3 -3
- package/dist/cjs/src/perp/config.js +11 -13
- package/dist/cjs/src/perp/index.d.ts +4 -6
- package/dist/cjs/src/perp/index.js +43 -18
- package/dist/cjs/src/perp/tx-builders/common.d.ts +86 -48
- package/dist/cjs/src/perp/tx-builders/common.js +115 -47
- package/dist/cjs/src/perp/tx-builders/wlp.d.ts +3 -14
- package/dist/cjs/src/perp/tx-builders/wlp.js +6 -35
- package/dist/cjs/src/perp/tx-builders.d.ts +6 -5
- package/dist/cjs/src/perp/tx-builders.js +16 -10
- package/dist/cjs/src/unified-client.d.ts +9 -35
- package/dist/cjs/src/unified-client.js +3 -4
- package/dist/cjs/src/utils/config.d.ts +0 -8
- package/dist/cjs/src/utils/config.js +5 -13
- package/dist/src/account/config.d.ts +3 -5
- package/dist/src/account/funding/wormhole.d.ts +1 -2
- package/dist/src/account/funding/wormhole.js +1 -2
- package/dist/src/generated/waterx_rule/waterx_rule.d.ts +140 -7
- package/dist/src/generated/waterx_rule/waterx_rule.js +151 -7
- package/dist/src/oracle/aggregate.d.ts +49 -62
- package/dist/src/oracle/aggregate.js +209 -164
- package/dist/src/oracle/config.d.ts +38 -51
- package/dist/src/oracle/config.js +1 -1
- package/dist/src/oracle/host.d.ts +14 -19
- package/dist/src/oracle/host.js +3 -3
- package/dist/src/oracle/index.d.ts +25 -16
- package/dist/src/oracle/index.js +61 -54
- package/dist/src/oracle/price-update-rule.d.ts +104 -66
- package/dist/src/oracle/price-update-rule.js +23 -16
- package/dist/src/oracle/pyth-pro-history.d.ts +36 -0
- package/dist/src/oracle/pyth-pro-history.js +38 -0
- package/dist/src/oracle/read-plane.d.ts +35 -53
- package/dist/src/oracle/read-plane.js +25 -47
- package/dist/src/oracle/read-prices.d.ts +105 -0
- package/dist/src/oracle/read-prices.js +156 -0
- package/dist/src/oracle/rule-registry.d.ts +12 -12
- package/dist/src/oracle/rule-registry.js +12 -14
- package/dist/src/oracle/rules/pyth-lazer-rule.d.ts +24 -3
- package/dist/src/oracle/rules/pyth-lazer-rule.js +39 -20
- package/dist/src/oracle/rules/waterx-rule.d.ts +271 -57
- package/dist/src/oracle/rules/waterx-rule.js +735 -144
- package/dist/src/oracle/schedule.d.ts +109 -0
- package/dist/src/oracle/schedule.js +985 -0
- package/dist/src/oracle/source-list.d.ts +31 -27
- package/dist/src/oracle/source-list.js +42 -43
- package/dist/src/oracle/symbol-catalog.d.ts +54 -0
- package/dist/src/oracle/symbol-catalog.js +65 -0
- package/dist/src/oracle/update-fetch.d.ts +11 -15
- package/dist/src/oracle/update-fetch.js +12 -18
- package/dist/src/oracle/validate.d.ts +105 -0
- package/dist/src/oracle/validate.js +177 -0
- package/dist/src/oracle/weight-coverage.d.ts +79 -0
- package/dist/src/oracle/weight-coverage.js +166 -0
- package/dist/src/perp/client.d.ts +40 -55
- package/dist/src/perp/client.js +45 -18
- package/dist/src/perp/config-view.d.ts +5 -14
- package/dist/src/perp/config-view.js +5 -16
- package/dist/src/perp/config.d.ts +3 -3
- package/dist/src/perp/config.js +11 -13
- package/dist/src/perp/index.d.ts +4 -6
- package/dist/src/perp/index.js +17 -5
- package/dist/src/perp/tx-builders/common.d.ts +86 -48
- package/dist/src/perp/tx-builders/common.js +114 -48
- package/dist/src/perp/tx-builders/wlp.d.ts +3 -14
- package/dist/src/perp/tx-builders/wlp.js +6 -35
- package/dist/src/perp/tx-builders.d.ts +6 -5
- package/dist/src/perp/tx-builders.js +15 -6
- package/dist/src/unified-client.d.ts +9 -35
- package/dist/src/unified-client.js +3 -4
- package/dist/src/utils/config.d.ts +0 -8
- package/dist/src/utils/config.js +5 -12
- package/package.json +8 -2
- package/dist/cjs/src/generated/pyth_sponsor_rule/deps/sui/balance.d.ts +0 -12
- package/dist/cjs/src/generated/pyth_sponsor_rule/deps/sui/balance.js +0 -17
- package/dist/cjs/src/generated/pyth_sponsor_rule/pyth_sponsor_rule.d.ts +0 -68
- package/dist/cjs/src/generated/pyth_sponsor_rule/pyth_sponsor_rule.js +0 -113
- package/dist/cjs/src/generated/waterx_pyth_rule/deps/sui/vec_map.d.ts +0 -36
- package/dist/cjs/src/generated/waterx_pyth_rule/deps/sui/vec_map.js +0 -31
- package/dist/cjs/src/generated/waterx_pyth_rule/pyth_rule.d.ts +0 -192
- package/dist/cjs/src/generated/waterx_pyth_rule/pyth_rule.js +0 -214
- package/dist/cjs/src/oracle/pyth.d.ts +0 -227
- package/dist/cjs/src/oracle/pyth.js +0 -652
- package/dist/cjs/src/oracle/rules/pyth-core-rule.d.ts +0 -15
- package/dist/cjs/src/oracle/rules/pyth-core-rule.js +0 -100
- package/dist/cjs/src/oracle/rules/pyth-rule.d.ts +0 -11
- package/dist/cjs/src/oracle/rules/pyth-rule.js +0 -29
- package/dist/cjs/src/oracle/rules/sponsor.d.ts +0 -32
- package/dist/cjs/src/oracle/rules/sponsor.js +0 -56
- package/dist/src/generated/pyth_sponsor_rule/deps/sui/balance.d.ts +0 -12
- package/dist/src/generated/pyth_sponsor_rule/deps/sui/balance.js +0 -14
- package/dist/src/generated/pyth_sponsor_rule/pyth_sponsor_rule.d.ts +0 -68
- package/dist/src/generated/pyth_sponsor_rule/pyth_sponsor_rule.js +0 -73
- package/dist/src/generated/waterx_pyth_rule/deps/sui/vec_map.d.ts +0 -36
- package/dist/src/generated/waterx_pyth_rule/deps/sui/vec_map.js +0 -27
- package/dist/src/generated/waterx_pyth_rule/pyth_rule.d.ts +0 -192
- package/dist/src/generated/waterx_pyth_rule/pyth_rule.js +0 -170
- package/dist/src/oracle/pyth.d.ts +0 -227
- package/dist/src/oracle/pyth.js +0 -638
- package/dist/src/oracle/rules/pyth-core-rule.d.ts +0 -15
- package/dist/src/oracle/rules/pyth-core-rule.js +0 -97
- package/dist/src/oracle/rules/pyth-rule.d.ts +0 -11
- package/dist/src/oracle/rules/pyth-rule.js +0 -26
- package/dist/src/oracle/rules/sponsor.d.ts +0 -32
- 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)
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
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
|
|
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)
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
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
|
|
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
|
-
* (
|
|
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
|
|
28
|
-
import { type
|
|
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
|
-
* - **
|
|
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" (
|
|
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
|
-
*
|
|
64
|
-
*
|
|
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
|
|
66
|
+
export declare function aggregateTickerWithConstant(tx: Transaction, host: OracleHost, args: {
|
|
67
67
|
ticker: string;
|
|
68
|
-
priceInfoObjectId: string;
|
|
69
68
|
}): void;
|
|
70
69
|
/**
|
|
71
|
-
* {@link
|
|
72
|
-
* the price comes from the on-chain `constant_rule::Config`).
|
|
70
|
+
* What {@link refreshOraclePrices} actually put on chain.
|
|
73
71
|
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
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
|
|
81
|
-
|
|
82
|
-
|
|
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 (
|
|
86
|
-
*
|
|
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
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
* moveCalls.
|
|
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
|
|
115
|
-
*
|
|
116
|
-
* on
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
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<
|
|
143
|
+
}): Promise<OracleRefreshSummary>;
|