@waterx/sdk 3.1.1 → 4.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/README.md +36 -0
- package/dist/cjs/src/oracle/aggregate.d.ts +98 -17
- package/dist/cjs/src/oracle/aggregate.js +191 -21
- package/dist/cjs/src/oracle/config.d.ts +103 -0
- package/dist/cjs/src/oracle/config.js +64 -1
- package/dist/cjs/src/oracle/host.d.ts +13 -0
- package/dist/cjs/src/oracle/index.d.ts +19 -5
- package/dist/cjs/src/oracle/index.js +40 -6
- package/dist/cjs/src/oracle/price-update-rule.d.ts +180 -0
- package/dist/cjs/src/oracle/price-update-rule.js +56 -0
- package/dist/cjs/src/oracle/pyth.d.ts +80 -11
- package/dist/cjs/src/oracle/pyth.js +84 -17
- package/dist/cjs/src/oracle/rule-registry.d.ts +37 -0
- package/dist/cjs/src/oracle/rule-registry.js +61 -0
- package/dist/cjs/src/oracle/rules/pyth-core-rule.d.ts +15 -0
- package/dist/cjs/src/oracle/rules/pyth-core-rule.js +84 -0
- package/dist/cjs/src/oracle/rules/pyth-lazer-rule.d.ts +41 -0
- package/dist/cjs/src/oracle/rules/pyth-lazer-rule.js +194 -0
- package/dist/cjs/src/oracle/rules/sponsor.d.ts +11 -7
- package/dist/cjs/src/oracle/rules/sponsor.js +11 -7
- package/dist/cjs/src/oracle/update-fetch.d.ts +85 -0
- package/dist/cjs/src/oracle/update-fetch.js +228 -0
- package/dist/cjs/src/perp/client.d.ts +22 -1
- package/dist/cjs/src/perp/client.js +11 -2
- package/dist/cjs/src/perp/config.d.ts +9 -4
- package/dist/cjs/src/perp/config.js +82 -18
- package/dist/cjs/src/perp/index.d.ts +4 -3
- package/dist/cjs/src/perp/index.js +8 -3
- package/dist/cjs/src/perp/tx-builders/common.d.ts +52 -15
- package/dist/cjs/src/perp/tx-builders/common.js +39 -6
- package/dist/cjs/src/perp/tx-builders/wlp.d.ts +11 -3
- package/dist/cjs/src/perp/tx-builders/wlp.js +29 -3
- package/dist/cjs/src/perp/tx-builders.d.ts +3 -3
- package/dist/cjs/src/perp/tx-builders.js +3 -3
- package/dist/cjs/src/unified-client.d.ts +17 -0
- package/dist/cjs/src/unified-client.js +2 -0
- package/dist/src/oracle/aggregate.d.ts +98 -17
- package/dist/src/oracle/aggregate.js +192 -22
- package/dist/src/oracle/config.d.ts +103 -0
- package/dist/src/oracle/config.js +63 -0
- package/dist/src/oracle/host.d.ts +13 -0
- package/dist/src/oracle/index.d.ts +19 -5
- package/dist/src/oracle/index.js +34 -6
- package/dist/src/oracle/price-update-rule.d.ts +180 -0
- package/dist/src/oracle/price-update-rule.js +53 -0
- package/dist/src/oracle/pyth.d.ts +80 -11
- package/dist/src/oracle/pyth.js +82 -16
- package/dist/src/oracle/rule-registry.d.ts +37 -0
- package/dist/src/oracle/rule-registry.js +56 -0
- package/dist/src/oracle/rules/pyth-core-rule.d.ts +15 -0
- package/dist/src/oracle/rules/pyth-core-rule.js +81 -0
- package/dist/src/oracle/rules/pyth-lazer-rule.d.ts +41 -0
- package/dist/src/oracle/rules/pyth-lazer-rule.js +189 -0
- package/dist/src/oracle/rules/sponsor.d.ts +11 -7
- package/dist/src/oracle/rules/sponsor.js +11 -7
- package/dist/src/oracle/update-fetch.d.ts +85 -0
- package/dist/src/oracle/update-fetch.js +223 -0
- package/dist/src/perp/client.d.ts +22 -1
- package/dist/src/perp/client.js +12 -3
- package/dist/src/perp/config.d.ts +9 -4
- package/dist/src/perp/config.js +81 -18
- package/dist/src/perp/index.d.ts +4 -3
- package/dist/src/perp/index.js +2 -2
- package/dist/src/perp/tx-builders/common.d.ts +52 -15
- package/dist/src/perp/tx-builders/common.js +39 -6
- package/dist/src/perp/tx-builders/wlp.d.ts +11 -3
- package/dist/src/perp/tx-builders/wlp.js +29 -3
- package/dist/src/perp/tx-builders.d.ts +3 -3
- package/dist/src/perp/tx-builders.js +3 -3
- package/dist/src/unified-client.d.ts +17 -0
- package/dist/src/unified-client.js +2 -0
- package/package.json +1 -1
|
@@ -23,32 +23,65 @@ export async function refreshWlpPoolOracles(tx, client, extraTickers, opts) {
|
|
|
23
23
|
const oracleTickers = Array.from(new Set([...extraTickers, ...poolTickers]));
|
|
24
24
|
await refreshOraclePrices(tx, client, oracleTickers, {
|
|
25
25
|
cache: opts.cache,
|
|
26
|
-
|
|
26
|
+
feeSource: opts.feeSource,
|
|
27
|
+
updateDataProvider: opts.updateDataProvider,
|
|
27
28
|
});
|
|
28
29
|
for (const tokenType of Object.values(client.config.packages.wlp.pool_tokens)) {
|
|
29
30
|
updateTokenValue(client, tx, { tokenType, lpType: opts.lpType });
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
33
|
-
* Build the *Request + execute envelope with
|
|
34
|
+
* Build the *Request + execute envelope with the config-driven Pyth sponsor flow:
|
|
34
35
|
*
|
|
36
|
+
* [maybeConsolidate(tx)]
|
|
35
37
|
* [fund = sponsor.request()]
|
|
36
|
-
* refreshOraclePrices(...,
|
|
38
|
+
* refreshOraclePrices(..., feeSource?)
|
|
37
39
|
* req = buildRequest()
|
|
38
40
|
* [sponsor.reimburse(fund, req)]
|
|
39
41
|
* trading::execute(req)
|
|
42
|
+
*
|
|
43
|
+
* Accepted ordering caveat: `maybeConsolidate` runs FIRST and can itself
|
|
44
|
+
* append PTB commands (the consolidation sweep) before the fee-source check
|
|
45
|
+
* inside `refreshOraclePrices` ever runs — so an `OracleFeeSourceUnavailable`
|
|
46
|
+
* throw here is NOT the "zero commands appended" guarantee
|
|
47
|
+
* `refreshOraclePrices` gives its own callers (see its docblock in
|
|
48
|
+
* `aggregate.ts`); `tx` can already carry the sweep. This is the same
|
|
49
|
+
* discard-tx-on-throw contract every `build*Tx` composer already has for
|
|
50
|
+
* mid-build on-chain-read failures — not a new hole. It matters only for a
|
|
51
|
+
* caller that passed in their OWN `opts.tx` (reusing one `Transaction`
|
|
52
|
+
* across builder calls, e.g. to compose several actions in one PTB); such a
|
|
53
|
+
* caller must discard the whole `tx` on any throw from this function, not
|
|
54
|
+
* just retry the failed step.
|
|
40
55
|
*/
|
|
41
56
|
export async function wrapRequestAndExecute(client, tx, req, collateralTicker, opts, buildRequest) {
|
|
42
57
|
await maybeConsolidate(client, tx, req.accountId, opts);
|
|
43
|
-
|
|
58
|
+
// Fee source + witness attachment is config-driven, not a caller flag: the
|
|
59
|
+
// sponsor fund is opened (and later reimbursed) whenever this client's
|
|
60
|
+
// config has `pyth_sponsor_rule` deployed — regardless of the deprecated
|
|
61
|
+
// `useSponsor` flag (see its JSDoc). `allowGasFee` is the only caller lever
|
|
62
|
+
// left, and it only matters when config has NO sponsor rule to open (see
|
|
63
|
+
// `OracleFeeSourceUnavailable` in `oracle/pyth.ts`).
|
|
64
|
+
//
|
|
65
|
+
// `feeSource` is resolved HERE, once, from that same decision — sponsor
|
|
66
|
+
// beats gas structurally because this is the only branch that ever sees
|
|
67
|
+
// both candidates; everything downstream (`refreshWlpPoolOracles` →
|
|
68
|
+
// `refreshOraclePrices` → `BuildUpdateOpts` → `PythCoreRule` →
|
|
69
|
+
// `buildPythPriceUpdateCalls`) just carries the single resolved value.
|
|
44
70
|
let sponsorFund;
|
|
45
|
-
if (
|
|
71
|
+
if (client.config.packages.pyth_sponsor_rule) {
|
|
46
72
|
sponsorFund = openPythSponsorFund(tx, client);
|
|
73
|
+
}
|
|
74
|
+
const feeSource = sponsorFund
|
|
75
|
+
? { kind: "sponsor", ...sponsorFund }
|
|
76
|
+
: opts?.allowGasFee
|
|
77
|
+
? { kind: "gas" }
|
|
78
|
+
: undefined;
|
|
47
79
|
if (!opts?.skipOraclePriceRefresh) {
|
|
48
80
|
await refreshWlpPoolOracles(tx, client, [req.ticker, collateralTicker], {
|
|
49
81
|
cache: opts?.pythCache,
|
|
50
|
-
|
|
82
|
+
feeSource,
|
|
51
83
|
lpType: req.lpType,
|
|
84
|
+
updateDataProvider: opts?.updateDataProvider,
|
|
52
85
|
});
|
|
53
86
|
}
|
|
54
87
|
const tradingReq = buildRequest(sponsorFund);
|
|
@@ -17,9 +17,15 @@ export interface BuildMintWlpParams extends MintWlpParams, CommonBuildOpts {
|
|
|
17
17
|
* `last_price_refresh_timestamp` so `assert_prices_fresh` inside
|
|
18
18
|
* `mint_wlp` passes.
|
|
19
19
|
*
|
|
20
|
-
*
|
|
20
|
+
* Never uses the pyth_sponsor flow — `mint_wlp` produces no
|
|
21
21
|
* `TradingRequest`, so there's nothing for the sponsor to attach its
|
|
22
|
-
* witness to
|
|
22
|
+
* witness to, and `pyth_sponsor_rule::reimburse` cannot consume a Fund
|
|
23
|
+
* without one. So when `skipOraclePriceRefresh` is `false` (the refresh
|
|
24
|
+
* actually runs), the caller MUST pass `allowGasFee: true` — the Pyth
|
|
25
|
+
* update fee is drawn from `tx.gas`, which Enoki-sponsored transactions
|
|
26
|
+
* reject; a sponsored caller should keep `skipOraclePriceRefresh: true`
|
|
27
|
+
* instead and rely on freshness from other trade traffic (see
|
|
28
|
+
* `OracleFeeSourceUnavailable` in `oracle/pyth.ts`).
|
|
23
29
|
*/
|
|
24
30
|
export declare function buildMintWlpTx(client: PerpClient, params: BuildMintWlpParams): Promise<Transaction>;
|
|
25
31
|
export interface BuildMintAndStakeWlpParams extends BuildMintWlpParams {
|
|
@@ -62,7 +68,9 @@ export interface BuildUnstakeAndRequestRedeemWlpParams extends Omit<RequestRedee
|
|
|
62
68
|
* Refreshes every WLP pool-token oracle by default — `request_redeem` runs
|
|
63
69
|
* `assert_prices_fresh` internally, so a stale oracle would abort the PTB.
|
|
64
70
|
* Pass `skipOraclePriceRefresh: true` only when the caller is composing this
|
|
65
|
-
* into a larger PTB that already pre-pumps prices.
|
|
71
|
+
* into a larger PTB that already pre-pumps prices. Like `buildMintWlpTx`,
|
|
72
|
+
* `request_redeem` produces no `TradingRequest`, so a non-skipped refresh
|
|
73
|
+
* requires `allowGasFee: true` (see `buildMintWlpTx`'s doc comment).
|
|
66
74
|
*/
|
|
67
75
|
export declare function buildUnstakeAndRequestRedeemWlpTx(client: PerpClient, params: BuildUnstakeAndRequestRedeemWlpParams): Promise<Transaction>;
|
|
68
76
|
export interface BuildCancelRedeemAndStakeWlpParams extends CancelRedeemWlpParams, CommonBuildOpts {
|
|
@@ -12,17 +12,29 @@ import { maybeConsolidate, newTx, refreshWlpPoolOracles } from "./common.js";
|
|
|
12
12
|
* `last_price_refresh_timestamp` so `assert_prices_fresh` inside
|
|
13
13
|
* `mint_wlp` passes.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
15
|
+
* Never uses the pyth_sponsor flow — `mint_wlp` produces no
|
|
16
16
|
* `TradingRequest`, so there's nothing for the sponsor to attach its
|
|
17
|
-
* witness to
|
|
17
|
+
* witness to, and `pyth_sponsor_rule::reimburse` cannot consume a Fund
|
|
18
|
+
* without one. So when `skipOraclePriceRefresh` is `false` (the refresh
|
|
19
|
+
* actually runs), the caller MUST pass `allowGasFee: true` — the Pyth
|
|
20
|
+
* update fee is drawn from `tx.gas`, which Enoki-sponsored transactions
|
|
21
|
+
* reject; a sponsored caller should keep `skipOraclePriceRefresh: true`
|
|
22
|
+
* instead and rely on freshness from other trade traffic (see
|
|
23
|
+
* `OracleFeeSourceUnavailable` in `oracle/pyth.ts`).
|
|
18
24
|
*/
|
|
19
25
|
export async function buildMintWlpTx(client, params) {
|
|
20
26
|
const tx = newTx(params);
|
|
21
27
|
await maybeConsolidate(client, tx, params.accountId, params);
|
|
28
|
+
// `mint_wlp` has no sponsor flow to resolve against (see the doc comment
|
|
29
|
+
// above) — the only candidate source at this edge is the caller's
|
|
30
|
+
// ergonomic `allowGasFee` opt-in.
|
|
31
|
+
const feeSource = params.allowGasFee ? { kind: "gas" } : undefined;
|
|
22
32
|
if (!params.skipOraclePriceRefresh) {
|
|
23
33
|
await refreshWlpPoolOracles(tx, client, [params.depositTicker], {
|
|
24
34
|
cache: params.pythCache,
|
|
25
35
|
lpType: params.lpType,
|
|
36
|
+
feeSource,
|
|
37
|
+
updateDataProvider: params.updateDataProvider,
|
|
26
38
|
});
|
|
27
39
|
}
|
|
28
40
|
mintWlp(client, tx, params);
|
|
@@ -40,10 +52,16 @@ export async function buildMintWlpTx(client, params) {
|
|
|
40
52
|
export async function buildMintAndStakeWlpTx(client, params) {
|
|
41
53
|
const tx = newTx(params);
|
|
42
54
|
await maybeConsolidate(client, tx, params.accountId, params);
|
|
55
|
+
// `mint_wlp` has no sponsor flow to resolve against (see `buildMintWlpTx`'s
|
|
56
|
+
// doc comment) — the only candidate source at this edge is the caller's
|
|
57
|
+
// ergonomic `allowGasFee` opt-in.
|
|
58
|
+
const feeSource = params.allowGasFee ? { kind: "gas" } : undefined;
|
|
43
59
|
if (!params.skipOraclePriceRefresh) {
|
|
44
60
|
await refreshWlpPoolOracles(tx, client, [params.depositTicker], {
|
|
45
61
|
cache: params.pythCache,
|
|
46
62
|
lpType: params.lpType,
|
|
63
|
+
feeSource,
|
|
64
|
+
updateDataProvider: params.updateDataProvider,
|
|
47
65
|
});
|
|
48
66
|
}
|
|
49
67
|
const stakeAlias = params.stakeAlias ?? "WLP";
|
|
@@ -65,16 +83,24 @@ export async function buildMintAndStakeWlpTx(client, params) {
|
|
|
65
83
|
* Refreshes every WLP pool-token oracle by default — `request_redeem` runs
|
|
66
84
|
* `assert_prices_fresh` internally, so a stale oracle would abort the PTB.
|
|
67
85
|
* Pass `skipOraclePriceRefresh: true` only when the caller is composing this
|
|
68
|
-
* into a larger PTB that already pre-pumps prices.
|
|
86
|
+
* into a larger PTB that already pre-pumps prices. Like `buildMintWlpTx`,
|
|
87
|
+
* `request_redeem` produces no `TradingRequest`, so a non-skipped refresh
|
|
88
|
+
* requires `allowGasFee: true` (see `buildMintWlpTx`'s doc comment).
|
|
69
89
|
*/
|
|
70
90
|
export async function buildUnstakeAndRequestRedeemWlpTx(client, params) {
|
|
71
91
|
const tx = newTx(params);
|
|
72
92
|
const stakeAlias = params.stakeAlias ?? "WLP";
|
|
73
93
|
await maybeConsolidate(client, tx, params.accountId, params);
|
|
94
|
+
// `request_redeem` has no sponsor flow to resolve against (see
|
|
95
|
+
// `buildMintWlpTx`'s doc comment) — the only candidate source at this edge
|
|
96
|
+
// is the caller's ergonomic `allowGasFee` opt-in.
|
|
97
|
+
const feeSource = params.allowGasFee ? { kind: "gas" } : undefined;
|
|
74
98
|
if (!params.skipOraclePriceRefresh) {
|
|
75
99
|
await refreshWlpPoolOracles(tx, client, [], {
|
|
76
100
|
cache: params.pythCache,
|
|
77
101
|
lpType: params.lpType,
|
|
102
|
+
feeSource,
|
|
103
|
+
updateDataProvider: params.updateDataProvider,
|
|
78
104
|
});
|
|
79
105
|
}
|
|
80
106
|
unstake(client, tx, {
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Each `build*Tx` composer creates (or appends to) a `Transaction`, refreshes
|
|
5
5
|
* the on-chain `Oracle` via Pyth, optionally pre-sweeps parked balances
|
|
6
|
-
* (`consolidateToUsd`), wires the `pyth_sponsor_rule` flow when
|
|
7
|
-
* calls the matching `*_request` + `execute`. Implementations are
|
|
8
|
-
* domain under `tx-builders/`:
|
|
6
|
+
* (`consolidateToUsd`), wires the `pyth_sponsor_rule` flow when deployed in
|
|
7
|
+
* config, and calls the matching `*_request` + `execute`. Implementations are
|
|
8
|
+
* split by domain under `tx-builders/`:
|
|
9
9
|
*
|
|
10
10
|
* common.ts CommonBuildOpts + request/execute envelope + oracle refresh
|
|
11
11
|
* consolidate.ts parked-balance → wxUSD pre-sweep (appendConsolidate*)
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Each `build*Tx` composer creates (or appends to) a `Transaction`, refreshes
|
|
5
5
|
* the on-chain `Oracle` via Pyth, optionally pre-sweeps parked balances
|
|
6
|
-
* (`consolidateToUsd`), wires the `pyth_sponsor_rule` flow when
|
|
7
|
-
* calls the matching `*_request` + `execute`. Implementations are
|
|
8
|
-
* domain under `tx-builders/`:
|
|
6
|
+
* (`consolidateToUsd`), wires the `pyth_sponsor_rule` flow when deployed in
|
|
7
|
+
* config, and calls the matching `*_request` + `execute`. Implementations are
|
|
8
|
+
* split by domain under `tx-builders/`:
|
|
9
9
|
*
|
|
10
10
|
* common.ts CommonBuildOpts + request/execute envelope + oracle refresh
|
|
11
11
|
* consolidate.ts parked-balance → wxUSD pre-sweep (appendConsolidate*)
|
|
@@ -32,6 +32,8 @@ import { Transaction } from "@mysten/sui/transactions";
|
|
|
32
32
|
import * as accountOps from "./account/index.ts";
|
|
33
33
|
import * as perpReferral from "./account/referral.ts";
|
|
34
34
|
import type { Network } from "./constants.ts";
|
|
35
|
+
import type { PythGeneration } from "./oracle/config.ts";
|
|
36
|
+
import type { OracleSource } from "./oracle/price-update-rule.ts";
|
|
35
37
|
import { PerpClient, type CreateClientOptions as PerpCreateOptions } from "./perp/client.ts";
|
|
36
38
|
import * as perpFetch from "./perp/fetch.ts";
|
|
37
39
|
import * as perpTx from "./perp/tx-builders.ts";
|
|
@@ -363,6 +365,21 @@ export interface ClientCreateOptions {
|
|
|
363
365
|
waterxConfigUrl?: string;
|
|
364
366
|
/** Memoize the fetched config JSON. */
|
|
365
367
|
cache?: boolean;
|
|
368
|
+
/**
|
|
369
|
+
* Selects which `PriceUpdateRule` the perp line's `refreshOraclePrices` uses
|
|
370
|
+
* for the on-chain price-update leg (see `OracleHost.oracleSource`).
|
|
371
|
+
* Default: `'pyth_rule'`. Perp-line only. The SDK never reads `process.env`
|
|
372
|
+
* — pass this from your own env var (e.g. `ORACLE_SOURCE`).
|
|
373
|
+
*/
|
|
374
|
+
oracleSource?: OracleSource;
|
|
375
|
+
/**
|
|
376
|
+
* Selects which Pyth Core contract generation feeds the perp line's
|
|
377
|
+
* `client.perp.pyth` when the config JSON has no explicit `pyth` override:
|
|
378
|
+
* `'core'` (default) or `'pro'` (post-2026-08-18 Pro-compatible contracts +
|
|
379
|
+
* Hermes-compatible endpoint; pair with `pyth.api_key`). Perp-line only.
|
|
380
|
+
* See `PythGeneration` / `PYTH_PRO_DEFAULTS`.
|
|
381
|
+
*/
|
|
382
|
+
pythGeneration?: PythGeneration;
|
|
366
383
|
/** Perp-line overrides (network, grpcUrl, waterxConfigUrl, cache, …). */
|
|
367
384
|
perp?: PerpLineOptions;
|
|
368
385
|
/** Prediction-line overrides (network, grpcUrl, waterxConfigUrl, cache, settlement, …). */
|
|
@@ -168,6 +168,8 @@ export class WaterXClient {
|
|
|
168
168
|
grpcUrl: opts.grpcUrl,
|
|
169
169
|
waterxConfigUrl: opts.waterxConfigUrl,
|
|
170
170
|
cache: opts.cache,
|
|
171
|
+
oracleSource: opts.oracleSource,
|
|
172
|
+
pythGeneration: opts.pythGeneration,
|
|
171
173
|
...perpRest,
|
|
172
174
|
});
|
|
173
175
|
const predictClient = await PredictClient.create(resolvedPredictNetwork, {
|