@waterx/sdk 3.1.0 → 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 +53 -7
- 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 +15 -20
- package/dist/cjs/src/perp/config.js +86 -30
- package/dist/cjs/src/perp/index.d.ts +4 -3
- package/dist/cjs/src/perp/index.js +8 -4
- 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/prediction/config.d.ts +5 -15
- package/dist/cjs/src/prediction/config.js +4 -12
- package/dist/cjs/src/prediction/fetch.d.ts +6 -1
- package/dist/cjs/src/prediction/fetch.js +64 -0
- package/dist/cjs/src/prediction/index.d.ts +2 -2
- package/dist/cjs/src/prediction/index.js +7 -4
- package/dist/cjs/src/prediction/types.d.ts +19 -0
- package/dist/cjs/src/unified-client.d.ts +26 -4
- package/dist/cjs/src/unified-client.js +4 -2
- 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 +15 -20
- package/dist/src/perp/config.js +85 -29
- 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/prediction/config.d.ts +5 -15
- package/dist/src/prediction/config.js +4 -11
- package/dist/src/prediction/fetch.d.ts +6 -1
- package/dist/src/prediction/fetch.js +60 -0
- package/dist/src/prediction/index.d.ts +2 -2
- package/dist/src/prediction/index.js +2 -2
- package/dist/src/prediction/types.d.ts +19 -0
- package/dist/src/unified-client.d.ts +26 -4
- package/dist/src/unified-client.js +4 -2
- package/package.json +1 -1
|
@@ -12,8 +12,8 @@ import type { AccountPackages, BasePackageEntry, WormholeInfraConfig } from "../
|
|
|
12
12
|
import type { OraclePackages, PythInfraConfig } from "../oracle/config.ts";
|
|
13
13
|
import type { Network } from "./constants.ts";
|
|
14
14
|
export type { AccountConfig, AccountPackages, BasePackageEntry, NativeCustodyAsset, NativeCustodyPackage, TrustedEmitterRow, WaterxCreditPackage, WaterxReferralPackage, WithdrawalQueuePackage, WormholeBridgePackage, WormholeInfraConfig, WxaAccountPackage, } from "../account/config.ts";
|
|
15
|
-
export type { ConstantFeedEntry, OracleConfig, OraclePackages, PythInfraConfig, PythRulePackage, PythSponsorRulePackage, SupraFeedEntry, SupraRulePackage, WaterxConstantRulePackage, WaterxOraclePackage, } from "../oracle/config.ts";
|
|
16
|
-
export { PYTH_DEFAULTS } from "../oracle/config.ts";
|
|
15
|
+
export type { ConstantFeedEntry, OracleConfig, OraclePackages, PythGeneration, PythInfraConfig, PythLazerRulePackage, PythRulePackage, PythSponsorRulePackage, SupraFeedEntry, SupraRulePackage, WaterxConstantRulePackage, WaterxOraclePackage, } from "../oracle/config.ts";
|
|
16
|
+
export { PYTH_DEFAULTS, PYTH_PRO_DEFAULTS } from "../oracle/config.ts";
|
|
17
17
|
export interface WaterxPerpMarketEntry {
|
|
18
18
|
market: string;
|
|
19
19
|
config: string;
|
|
@@ -95,32 +95,27 @@ export interface WaterXConfig {
|
|
|
95
95
|
}
|
|
96
96
|
export interface LoadConfigOptions {
|
|
97
97
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
98
|
+
* Canonical `waterx-config` JSON URL to fetch, **as-is** (no `<network>.json`
|
|
99
|
+
* / git ref appended). Required — {@link loadConfig} reads the URL only from
|
|
100
|
+
* this option (there is no env-var fallback and no built-in default) and
|
|
101
|
+
* throws when it is unset. Point it at a staging deployment or local mirror
|
|
102
|
+
* as needed.
|
|
101
103
|
*/
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Pin the canonical config to a specific git ref — a commit SHA, branch,
|
|
105
|
-
* or tag — instead of the default `main` branch. Resolves to
|
|
106
|
-
* `https://raw.githubusercontent.com/WaterXProtocol/waterx-config/<ref>/<network>.json`.
|
|
107
|
-
* Ignored when {@link configUrl} is set.
|
|
108
|
-
*/
|
|
109
|
-
configRef?: string;
|
|
104
|
+
waterxConfigUrl?: string;
|
|
110
105
|
/**
|
|
111
106
|
* Reuse a previously-fetched config from the in-memory cache (keyed by
|
|
112
|
-
* the effective URL). Default: false (always fetch fresh).
|
|
107
|
+
* network + the effective URL). Default: false (always fetch fresh).
|
|
113
108
|
*/
|
|
114
109
|
cache?: boolean;
|
|
115
110
|
/** Optional fetch implementation (for tests or environments without global `fetch`). */
|
|
116
111
|
fetchImpl?: typeof fetch;
|
|
117
|
-
/**
|
|
112
|
+
/**
|
|
113
|
+
* Optional PER-ATTEMPT timeout in ms. Default 10_000. {@link loadConfig}
|
|
114
|
+
* retries a transient failure (network error / 429 / 5xx) via
|
|
115
|
+
* `fetchWithPolicy` (2 retries, exponential backoff) before falling back to
|
|
116
|
+
* the last successfully-validated config for this network+URL, if one exists.
|
|
117
|
+
*/
|
|
118
118
|
timeoutMs?: number;
|
|
119
119
|
}
|
|
120
|
-
/**
|
|
121
|
-
* Build the canonical config URL for `network`, optionally pinned to a
|
|
122
|
-
* specific git `ref` (commit SHA, branch, or tag). Defaults to `main`.
|
|
123
|
-
*/
|
|
124
|
-
export declare function defaultConfigUrl(network: Network, ref?: string): string;
|
|
125
120
|
export declare function clearConfigCache(): void;
|
|
126
121
|
export declare function loadConfig(network: Network, opts?: LoadConfigOptions): Promise<WaterXConfig>;
|
|
@@ -10,12 +10,13 @@
|
|
|
10
10
|
* below, keyed by network.
|
|
11
11
|
*/
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.WORMHOLE_DEFAULTS = exports.PYTH_DEFAULTS = void 0;
|
|
14
|
-
exports.defaultConfigUrl = defaultConfigUrl;
|
|
13
|
+
exports.WORMHOLE_DEFAULTS = exports.PYTH_PRO_DEFAULTS = exports.PYTH_DEFAULTS = void 0;
|
|
15
14
|
exports.clearConfigCache = clearConfigCache;
|
|
16
15
|
exports.loadConfig = loadConfig;
|
|
16
|
+
const update_fetch_ts_1 = require("../oracle/update-fetch.js");
|
|
17
17
|
var config_ts_1 = require("../oracle/config.js");
|
|
18
18
|
Object.defineProperty(exports, "PYTH_DEFAULTS", { enumerable: true, get: function () { return config_ts_1.PYTH_DEFAULTS; } });
|
|
19
|
+
Object.defineProperty(exports, "PYTH_PRO_DEFAULTS", { enumerable: true, get: function () { return config_ts_1.PYTH_PRO_DEFAULTS; } });
|
|
19
20
|
// ============================================================================
|
|
20
21
|
// Wormhole / Hermes — external chain infra, defaults by network
|
|
21
22
|
// ============================================================================
|
|
@@ -40,45 +41,97 @@ exports.WORMHOLE_DEFAULTS = {
|
|
|
40
41
|
wormholescan_api: "https://api.testnet.wormholescan.io/api/v1",
|
|
41
42
|
},
|
|
42
43
|
};
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
44
|
+
// Last successfully-validated config per `${network}:${url}` — the ONE module
|
|
45
|
+
// map, written UNCONDITIONALLY on every successful load regardless of
|
|
46
|
+
// `opts.cache`. It serves two roles at once: the resilience fallback for a
|
|
47
|
+
// refresh failure (see `loadConfig` below) AND the opt-in fast-path read
|
|
48
|
+
// `opts.cache: true` gates at the top of `loadConfig`. `opts.cache` therefore
|
|
49
|
+
// only gates whether a call *reads* this map early (skipping the fetch
|
|
50
|
+
// entirely) — it never gates whether a call *writes* it; every successful
|
|
51
|
+
// load writes here. The network prefix keeps one network's snapshot from ever
|
|
52
|
+
// satisfying another's request (see the cache-key note in `loadConfig`).
|
|
53
|
+
//
|
|
54
|
+
// Deliberate (benign) semantic refinement from the prior two-map design: a
|
|
55
|
+
// `cache: true` call can now hit an entry that was populated by an earlier
|
|
56
|
+
// `cache: false` call for the SAME network+url. That's fine — it's still that
|
|
57
|
+
// key's latest successfully-validated fetch, strictly FRESHER than any
|
|
58
|
+
// fallback read would have been, so a `cache: true` caller never observes
|
|
59
|
+
// staler data than before; it can only observe MORE-recent data sooner.
|
|
60
|
+
const configCache = new Map();
|
|
54
61
|
function clearConfigCache() {
|
|
55
|
-
|
|
62
|
+
configCache.clear();
|
|
56
63
|
}
|
|
57
64
|
async function loadConfig(network, opts = {}) {
|
|
58
|
-
const url = opts.
|
|
59
|
-
if (
|
|
60
|
-
|
|
65
|
+
const url = opts.waterxConfigUrl;
|
|
66
|
+
if (!url) {
|
|
67
|
+
throw new Error("loadConfig: no config URL — pass opts.waterxConfigUrl");
|
|
68
|
+
}
|
|
69
|
+
// Key by network AND url, never url alone: the same url can legitimately be
|
|
70
|
+
// requested for two networks (and `validateConfig` enforces network/url
|
|
71
|
+
// coherence on the success path), so a url-only key would let a testnet
|
|
72
|
+
// snapshot satisfy a mainnet request — both on this fast-path read and on
|
|
73
|
+
// the resilience fallback below — handing back wrong-CHAIN object ids to
|
|
74
|
+
// build transactions against. A wrong-network request simply misses here
|
|
75
|
+
// and fetches fresh.
|
|
76
|
+
const cacheKey = `${network}:${url}`;
|
|
77
|
+
if (opts.cache && configCache.has(cacheKey)) {
|
|
78
|
+
return configCache.get(cacheKey);
|
|
61
79
|
}
|
|
62
80
|
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
63
81
|
if (!fetchImpl) {
|
|
64
82
|
throw new Error("loadConfig: no global `fetch` available; pass opts.fetchImpl");
|
|
65
83
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
84
|
+
// Same resilience policy as the oracle money-path fetches (see
|
|
85
|
+
// `fetchWithPolicy`): bounded retry with backoff instead of one bare
|
|
86
|
+
// attempt. A refresh failure (network exhaustion, a non-ok response, OR a
|
|
87
|
+
// 200 response that fails to parse/validate — see below) falls back to the
|
|
88
|
+
// last successfully-validated config for this network+URL when one exists — a
|
|
89
|
+
// config-endpoint blip must not crash a long-running process that already
|
|
90
|
+
// has a working deployment snapshot. First load (nothing cached yet) has
|
|
91
|
+
// no fallback and still throws. Intentionally no log line on the fallback
|
|
92
|
+
// path — the SDK never logs (see every other oracle error in this
|
|
93
|
+
// codebase); a caller that cares can tell it got a stale snapshot by
|
|
94
|
+
// re-deriving staleness itself if it needs to.
|
|
95
|
+
//
|
|
96
|
+
// Deliberate limitation (not fixed here — a follow-up): this treats EVERY
|
|
97
|
+
// failure mode identically, including a DETERMINISTIC one (404/403 — the
|
|
98
|
+
// URL moved, or access was revoked) once a `configCache` snapshot exists.
|
|
99
|
+
// Unlike a transient blip, a deterministic failure will never self-heal on
|
|
100
|
+
// the next retry, so a long-running process with a stale snapshot will
|
|
101
|
+
// keep serving it FOREVER and silently mask what is actually a permanent
|
|
102
|
+
// deployment problem. Disambiguating "blip" from "moved/revoked" (e.g. via
|
|
103
|
+
// a max-staleness budget, or treating non-retryable 4xx specially) is
|
|
104
|
+
// intentionally deferred rather than folded into this change.
|
|
105
|
+
//
|
|
106
|
+
// fetch → ok-check → parse → validate all run in ONE try, so any failure
|
|
107
|
+
// along that chain (network exhaustion, a non-ok response, malformed JSON,
|
|
108
|
+
// or a `validateConfig` rejection) lands in the same catch and takes the
|
|
109
|
+
// same single last-known-good lookup below.
|
|
110
|
+
let raw;
|
|
69
111
|
try {
|
|
70
|
-
response = await
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
112
|
+
const response = await (0, update_fetch_ts_1.fetchWithPolicy)(url, {}, { timeoutMs: opts.timeoutMs ?? 10_000, retries: 2, fetchImpl });
|
|
113
|
+
if (!response.ok) {
|
|
114
|
+
throw new Error(`loadConfig: HTTP ${response.status} fetching ${url}`);
|
|
115
|
+
}
|
|
116
|
+
raw = (await response.json());
|
|
117
|
+
validateConfig(raw, network, url);
|
|
74
118
|
}
|
|
75
|
-
|
|
76
|
-
|
|
119
|
+
catch (err) {
|
|
120
|
+
const stale = configCache.get(cacheKey);
|
|
121
|
+
if (stale)
|
|
122
|
+
return stale;
|
|
123
|
+
// Reformat a status-carrying FetchPolicyError (retries exhausted on a
|
|
124
|
+
// retryable status) into this function's own message shape, mirroring
|
|
125
|
+
// the non-retried `!response.ok` throw above. A network-level
|
|
126
|
+
// exhaustion (no status), a `!response.ok` throw, or a JSON parse /
|
|
127
|
+
// `validateConfig` failure has no domain-specific reframing to add —
|
|
128
|
+
// propagate that error's own message as-is.
|
|
129
|
+
if (err instanceof update_fetch_ts_1.FetchPolicyError && err.status !== undefined) {
|
|
130
|
+
throw new Error(`loadConfig: HTTP ${err.status} fetching ${url} (retries exhausted after ${err.attempts} attempts)`, { cause: err });
|
|
131
|
+
}
|
|
132
|
+
throw err;
|
|
77
133
|
}
|
|
78
|
-
|
|
79
|
-
validateConfig(raw, network, url);
|
|
80
|
-
if (opts.cache)
|
|
81
|
-
cache.set(url, raw);
|
|
134
|
+
configCache.set(cacheKey, raw);
|
|
82
135
|
return raw;
|
|
83
136
|
}
|
|
84
137
|
function validateConfig(cfg, expected, url) {
|
|
@@ -96,6 +149,9 @@ function validateConfig(cfg, expected, url) {
|
|
|
96
149
|
};
|
|
97
150
|
// Validate by deployment kind. A perp config must carry the perp set; a
|
|
98
151
|
// credit config the credit set. `waterx_account` is common to both.
|
|
152
|
+
// `pyth_lazer_rule` is intentionally NOT required (and never will be by
|
|
153
|
+
// presence alone) — it's an optional/experimental package selected only via
|
|
154
|
+
// a client's `oracleSource` option, never by its presence in the config.
|
|
99
155
|
const isPerp = "waterx_perp" in cfg.packages;
|
|
100
156
|
const isCredit = "waterx_credit" in cfg.packages || "wormhole_bridge" in cfg.packages;
|
|
101
157
|
const required = isPerp
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { PerpClient } from "./client.ts";
|
|
2
2
|
export type { CreateClientOptions } from "./client.ts";
|
|
3
|
-
export { PYTH_DEFAULTS, WORMHOLE_DEFAULTS, clearConfigCache,
|
|
4
|
-
export type { BasePackageEntry, ConstantFeedEntry, WaterxReferralPackage, LoadConfigOptions, NativeCustodyAsset, NativeCustodyPackage, PythInfraConfig, PythRulePackage, PythSponsorRulePackage, SupraFeedEntry, SupraRulePackage, TestnetFaucetPackage, TrustedEmitterRow, WaterXConfig, WaterXPackages, WaterxCreditPackage, WaterxOraclePackage, WaterxPerpMarketEntry, WaterxPerpPackage, WaterxStakingPackage, WithdrawalQueuePackage, WlpPackage, WormholeBridgePackage, WormholeInfraConfig, WxaAccountPackage, } from "./config.ts";
|
|
3
|
+
export { PYTH_DEFAULTS, PYTH_PRO_DEFAULTS, WORMHOLE_DEFAULTS, clearConfigCache, loadConfig, } from "./config.ts";
|
|
4
|
+
export type { BasePackageEntry, ConstantFeedEntry, WaterxReferralPackage, LoadConfigOptions, NativeCustodyAsset, NativeCustodyPackage, PythGeneration, PythInfraConfig, PythLazerRulePackage, PythRulePackage, PythSponsorRulePackage, SupraFeedEntry, SupraRulePackage, TestnetFaucetPackage, TrustedEmitterRow, WaterXConfig, WaterXPackages, WaterxCreditPackage, WaterxOraclePackage, WaterxPerpMarketEntry, WaterxPerpPackage, WaterxStakingPackage, WithdrawalQueuePackage, WlpPackage, WormholeBridgePackage, WormholeInfraConfig, WxaAccountPackage, } from "./config.ts";
|
|
5
5
|
export { ACTION_ADD_PRE_ORDER, ACTION_CANCEL_ORDER, ACTION_CANCEL_PRE_ORDER, ACTION_CLOSE_POSITION, ACTION_DECREASE_POSITION, ACTION_DEPOSIT_COLLATERAL, ACTION_INCREASE_POSITION, ACTION_LIQUIDATE, ACTION_OPEN_POSITION, ACTION_PLACE_ORDER, ACTION_UPDATE_ORDER, ACTION_WITHDRAW_COLLATERAL, BPS_SCALE, CRYPTO_FEE_RATE, DOUBLE_SCALE, DRY_RUN_SENDER, FLOAT_SCALE, MAINTENANCE_MARGIN_RATE, ORDER_LIMIT_BUY, ORDER_LIMIT_SELL, ORDER_STOP_BUY, ORDER_STOP_SELL, ORDER_TAG_WILDCARD, PERM_ALL, PERM_ALL_TRADING, PERM_CANCEL_ORDER, PERM_CLOSE_POSITION, PERM_DECREASE_POSITION, PERM_DEPOSIT_COLLATERAL, PERM_INCREASE_POSITION, PERM_MINT_WLP, PERM_OPEN_POSITION, PERM_PLACE_ORDER, PERM_REDEEM_WLP, PERM_WITHDRAW_COLLATERAL, STAKING_PERM_DEPOSIT_STAKE, STAKING_PERM_REDEEM_STAKE, STAKING_PERM_CLAIM_REWARD, STAKING_PERM_ALL, STOCK_FEE_RATE, MS_PER_YEAR, SUI_DECIMALS, WLP_DECIMALS, COLLATERAL_DECIMALS, TOKEN_DECIMALS, } from "./constants.ts";
|
|
6
6
|
export type { Network } from "./constants.ts";
|
|
7
7
|
export { getMarketTickers, getCollateralAssets } from "../utils/config.ts";
|
|
@@ -9,7 +9,8 @@ export { annualizedApyFromRatio, annualizeFundingRate, calcBorrowRate, calcBorro
|
|
|
9
9
|
export * from "./user/index.ts";
|
|
10
10
|
export * from "./tx-builders.ts";
|
|
11
11
|
export * from "./fetch.ts";
|
|
12
|
-
export { PythCache, aggregateTicker, aggregateTickerWithConstant, aggregateTickerWithPyth, buildPythPriceUpdateCalls, fetchPriceFeedsUpdateData, refreshOraclePrices, updatePythPrices, } from "../oracle/index.ts";
|
|
12
|
+
export { FetchPolicyError, LazerApiKeyMissingError, OracleFeeSourceUnavailableError, OracleSourceNotImplementedError, PythCache, aggregateTicker, aggregateTickerWithConstant, aggregateTickerWithPyth, buildPythPriceUpdateCalls, fetchPriceFeedsUpdateData, refreshOraclePrices, updatePythPrices, } from "../oracle/index.ts";
|
|
13
|
+
export type { FetchPolicy, OracleFeeSource, OracleSource, UpdateDataProvider, } from "../oracle/index.ts";
|
|
13
14
|
export { fetchDepositVaa, fetchVaa, listBridgeWithdrawalVaas, listVaasByEmitter, padEvmEmitter, toWormholescanEmitter, vaaBase64ToBytes, vaaBase64ToHex, vaaBytesToBase64, waitForVaa, } from "../account/funding/wormhole.ts";
|
|
14
15
|
export type { VaaListItem, VaaResponse, WormholescanOptions } from "../account/funding/wormhole.ts";
|
|
15
16
|
export { AccountData as AccountDataBcs, GlobalConfigData as GlobalConfigDataBcs, MarketData as MarketDataBcs, OrderData as OrderDataBcs, PoolData as PoolDataBcs, PositionData as PositionDataBcs, RedeemRequestData as RedeemRequestDataBcs, TokenPoolData as TokenPoolDataBcs, } from "../generated/waterx_perp_view/view.ts";
|
|
@@ -36,17 +36,17 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
36
36
|
};
|
|
37
37
|
})();
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.COLLATERAL_DECIMALS = exports.WLP_DECIMALS = exports.SUI_DECIMALS = exports.MS_PER_YEAR = exports.STOCK_FEE_RATE = exports.STAKING_PERM_ALL = exports.STAKING_PERM_CLAIM_REWARD = exports.STAKING_PERM_REDEEM_STAKE = exports.STAKING_PERM_DEPOSIT_STAKE = exports.PERM_WITHDRAW_COLLATERAL = exports.PERM_REDEEM_WLP = exports.PERM_PLACE_ORDER = exports.PERM_OPEN_POSITION = exports.PERM_MINT_WLP = exports.PERM_INCREASE_POSITION = exports.PERM_DEPOSIT_COLLATERAL = exports.PERM_DECREASE_POSITION = exports.PERM_CLOSE_POSITION = exports.PERM_CANCEL_ORDER = exports.PERM_ALL_TRADING = exports.PERM_ALL = exports.ORDER_TAG_WILDCARD = exports.ORDER_STOP_SELL = exports.ORDER_STOP_BUY = exports.ORDER_LIMIT_SELL = exports.ORDER_LIMIT_BUY = exports.MAINTENANCE_MARGIN_RATE = exports.FLOAT_SCALE = exports.DRY_RUN_SENDER = exports.DOUBLE_SCALE = exports.CRYPTO_FEE_RATE = exports.BPS_SCALE = exports.ACTION_WITHDRAW_COLLATERAL = exports.ACTION_UPDATE_ORDER = exports.ACTION_PLACE_ORDER = exports.ACTION_OPEN_POSITION = exports.ACTION_LIQUIDATE = exports.ACTION_INCREASE_POSITION = exports.ACTION_DEPOSIT_COLLATERAL = exports.ACTION_DECREASE_POSITION = exports.ACTION_CLOSE_POSITION = exports.ACTION_CANCEL_PRE_ORDER = exports.ACTION_CANCEL_ORDER = exports.ACTION_ADD_PRE_ORDER = exports.loadConfig = exports.
|
|
40
|
-
exports.
|
|
41
|
-
exports.withdrawalQueueCalls = exports.nativeCustodyCalls = exports.referralCalls = exports.pythSponsorRuleCalls = exports.pythRuleCalls = exports.oracleCalls = exports.stakingCalls = exports.wxaAccountCalls = exports.viewCalls = exports.lpPoolCalls = exports.tradingCalls = exports.MarketConfigBcs = exports.MarketBcs = exports.OrderBcs = exports.PositionBcs = exports.TokenPoolDataBcs = exports.RedeemRequestDataBcs = exports.PositionDataBcs = void 0;
|
|
39
|
+
exports.COLLATERAL_DECIMALS = exports.WLP_DECIMALS = exports.SUI_DECIMALS = exports.MS_PER_YEAR = exports.STOCK_FEE_RATE = exports.STAKING_PERM_ALL = exports.STAKING_PERM_CLAIM_REWARD = exports.STAKING_PERM_REDEEM_STAKE = exports.STAKING_PERM_DEPOSIT_STAKE = exports.PERM_WITHDRAW_COLLATERAL = exports.PERM_REDEEM_WLP = exports.PERM_PLACE_ORDER = exports.PERM_OPEN_POSITION = exports.PERM_MINT_WLP = exports.PERM_INCREASE_POSITION = exports.PERM_DEPOSIT_COLLATERAL = exports.PERM_DECREASE_POSITION = exports.PERM_CLOSE_POSITION = exports.PERM_CANCEL_ORDER = exports.PERM_ALL_TRADING = exports.PERM_ALL = exports.ORDER_TAG_WILDCARD = exports.ORDER_STOP_SELL = exports.ORDER_STOP_BUY = exports.ORDER_LIMIT_SELL = exports.ORDER_LIMIT_BUY = exports.MAINTENANCE_MARGIN_RATE = exports.FLOAT_SCALE = exports.DRY_RUN_SENDER = exports.DOUBLE_SCALE = exports.CRYPTO_FEE_RATE = exports.BPS_SCALE = exports.ACTION_WITHDRAW_COLLATERAL = exports.ACTION_UPDATE_ORDER = exports.ACTION_PLACE_ORDER = exports.ACTION_OPEN_POSITION = exports.ACTION_LIQUIDATE = exports.ACTION_INCREASE_POSITION = exports.ACTION_DEPOSIT_COLLATERAL = exports.ACTION_DECREASE_POSITION = exports.ACTION_CLOSE_POSITION = exports.ACTION_CANCEL_PRE_ORDER = exports.ACTION_CANCEL_ORDER = exports.ACTION_ADD_PRE_ORDER = exports.loadConfig = exports.clearConfigCache = exports.WORMHOLE_DEFAULTS = exports.PYTH_PRO_DEFAULTS = exports.PYTH_DEFAULTS = exports.PerpClient = void 0;
|
|
40
|
+
exports.AccountDataBcs = exports.waitForVaa = exports.vaaBytesToBase64 = exports.vaaBase64ToHex = exports.vaaBase64ToBytes = exports.toWormholescanEmitter = exports.padEvmEmitter = exports.listVaasByEmitter = exports.listBridgeWithdrawalVaas = exports.fetchVaa = exports.fetchDepositVaa = exports.updatePythPrices = exports.refreshOraclePrices = exports.fetchPriceFeedsUpdateData = exports.buildPythPriceUpdateCalls = exports.aggregateTickerWithPyth = exports.aggregateTickerWithConstant = exports.aggregateTicker = exports.PythCache = exports.OracleSourceNotImplementedError = exports.OracleFeeSourceUnavailableError = exports.LazerApiKeyMissingError = exports.FetchPolicyError = exports.rawPrice = exports.decodeFundingIndexDelta = exports.calcWlpRedeemOut = exports.calcWlpPrice = exports.calcWlpMintOut = exports.calcWlpIncentiveApy = exports.calcUnrealizedPnl = exports.calcTotalTradingFeeRate = exports.calcTokenUtilizationBps = exports.calcPositionBorrowFee = exports.calcNotional = exports.calcMaxReducibleCollateralUsd = exports.calcLeverage = exports.calcImpactFeeRate = exports.calcFundingRate = exports.calcFundingFeeUsd = exports.calcFee = exports.calcEstLiqPrice = exports.calcEffectiveCollateralUsd = exports.calcDynamicFeeBps = exports.calcBorrowRateAccrual = exports.calcBorrowRate = exports.annualizeFundingRate = exports.annualizedApyFromRatio = exports.getCollateralAssets = exports.getMarketTickers = exports.TOKEN_DECIMALS = void 0;
|
|
41
|
+
exports.withdrawalQueueCalls = exports.nativeCustodyCalls = exports.referralCalls = exports.pythSponsorRuleCalls = exports.pythRuleCalls = exports.oracleCalls = exports.stakingCalls = exports.wxaAccountCalls = exports.viewCalls = exports.lpPoolCalls = exports.tradingCalls = exports.MarketConfigBcs = exports.MarketBcs = exports.OrderBcs = exports.PositionBcs = exports.TokenPoolDataBcs = exports.RedeemRequestDataBcs = exports.PositionDataBcs = exports.PoolDataBcs = exports.OrderDataBcs = exports.MarketDataBcs = exports.GlobalConfigDataBcs = void 0;
|
|
42
42
|
// ======== Core ========
|
|
43
43
|
var client_ts_1 = require("./client.js");
|
|
44
44
|
Object.defineProperty(exports, "PerpClient", { enumerable: true, get: function () { return client_ts_1.PerpClient; } });
|
|
45
45
|
var config_ts_1 = require("./config.js");
|
|
46
46
|
Object.defineProperty(exports, "PYTH_DEFAULTS", { enumerable: true, get: function () { return config_ts_1.PYTH_DEFAULTS; } });
|
|
47
|
+
Object.defineProperty(exports, "PYTH_PRO_DEFAULTS", { enumerable: true, get: function () { return config_ts_1.PYTH_PRO_DEFAULTS; } });
|
|
47
48
|
Object.defineProperty(exports, "WORMHOLE_DEFAULTS", { enumerable: true, get: function () { return config_ts_1.WORMHOLE_DEFAULTS; } });
|
|
48
49
|
Object.defineProperty(exports, "clearConfigCache", { enumerable: true, get: function () { return config_ts_1.clearConfigCache; } });
|
|
49
|
-
Object.defineProperty(exports, "defaultConfigUrl", { enumerable: true, get: function () { return config_ts_1.defaultConfigUrl; } });
|
|
50
50
|
Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return config_ts_1.loadConfig; } });
|
|
51
51
|
// ======== Constants & enums ========
|
|
52
52
|
var constants_ts_1 = require("./constants.js");
|
|
@@ -132,6 +132,10 @@ __exportStar(require("./tx-builders.js"), exports);
|
|
|
132
132
|
__exportStar(require("./fetch.js"), exports);
|
|
133
133
|
// ======== Oracle utilities (Pyth source + rule aggregation) ========
|
|
134
134
|
var index_ts_1 = require("../oracle/index.js");
|
|
135
|
+
Object.defineProperty(exports, "FetchPolicyError", { enumerable: true, get: function () { return index_ts_1.FetchPolicyError; } });
|
|
136
|
+
Object.defineProperty(exports, "LazerApiKeyMissingError", { enumerable: true, get: function () { return index_ts_1.LazerApiKeyMissingError; } });
|
|
137
|
+
Object.defineProperty(exports, "OracleFeeSourceUnavailableError", { enumerable: true, get: function () { return index_ts_1.OracleFeeSourceUnavailableError; } });
|
|
138
|
+
Object.defineProperty(exports, "OracleSourceNotImplementedError", { enumerable: true, get: function () { return index_ts_1.OracleSourceNotImplementedError; } });
|
|
135
139
|
Object.defineProperty(exports, "PythCache", { enumerable: true, get: function () { return index_ts_1.PythCache; } });
|
|
136
140
|
Object.defineProperty(exports, "aggregateTicker", { enumerable: true, get: function () { return index_ts_1.aggregateTicker; } });
|
|
137
141
|
Object.defineProperty(exports, "aggregateTickerWithConstant", { enumerable: true, get: function () { return index_ts_1.aggregateTickerWithConstant; } });
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* and the request+execute envelope (optional Pyth-sponsor flow + pre-sweep).
|
|
5
5
|
*/
|
|
6
6
|
import { Transaction, type TransactionArgument } from "@mysten/sui/transactions";
|
|
7
|
-
import { PythCache } from "../../oracle/index.ts";
|
|
7
|
+
import { PythCache, type OracleFeeSource, type UpdateDataProvider } from "../../oracle/index.ts";
|
|
8
8
|
import type { PerpClient } from "../client.ts";
|
|
9
9
|
export interface CommonBuildOpts {
|
|
10
10
|
/** Append to an existing PTB instead of creating a new one. */
|
|
@@ -14,16 +14,31 @@ export interface CommonBuildOpts {
|
|
|
14
14
|
/** Share a `PythCache` across builders to avoid redundant pyth_state reads. */
|
|
15
15
|
pythCache?: PythCache;
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
17
|
+
* @deprecated No longer a fee-source decision. `wrapRequestAndExecute` now
|
|
18
|
+
* opens (and reimburses) the `pyth_sponsor_rule` Fund purely from config
|
|
19
|
+
* presence — whenever `client.config.packages.pyth_sponsor_rule` is
|
|
20
|
+
* deployed, the fund is ALWAYS opened, regardless of this flag (see
|
|
21
|
+
* `OracleFeeSourceUnavailable` in `oracle/pyth.ts`). This closes the gap
|
|
22
|
+
* where a market whose checklist required `PythSponsorRule`, or a caller
|
|
23
|
+
* that mis-set this flag, silently drew from `tx.gas` and failed
|
|
24
|
+
* ON-CHAIN instead of at build time. Use `allowGasFee` for the
|
|
25
|
+
* non-sponsored case instead. Kept accepted (as a no-op) only so existing
|
|
26
|
+
* callers keep compiling; will be removed in a future major version.
|
|
25
27
|
*/
|
|
26
28
|
useSponsor?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Explicit opt-in to draw the Pyth update fee from `tx.gas` when this
|
|
31
|
+
* client's config has no `pyth_sponsor_rule` deployed. Ignored whenever a
|
|
32
|
+
* sponsor fund IS available — the sponsor pool always wins over `tx.gas`
|
|
33
|
+
* when one can be opened (see `useSponsor`'s deprecation note above).
|
|
34
|
+
* Required for flows with no `TradingRequest` to reimburse a sponsor fund
|
|
35
|
+
* against (e.g. `buildMintWlpTx` — see its doc comment). Building an
|
|
36
|
+
* oracle refresh with neither a sponsor fund nor this flag throws
|
|
37
|
+
* `OracleFeeSourceUnavailable` instead of silently drawing from `tx.gas`
|
|
38
|
+
* (Enoki-sponsored transactions reject any `tx.gas` draw). Default:
|
|
39
|
+
* `false`.
|
|
40
|
+
*/
|
|
41
|
+
allowGasFee?: boolean;
|
|
27
42
|
/**
|
|
28
43
|
* Pre-sweep parked backing assets (USDC, USDsui, …) at the wxa account's
|
|
29
44
|
* address into USD credit, plus any CREDIT coins/funds at the address into
|
|
@@ -42,6 +57,15 @@ export interface CommonBuildOpts {
|
|
|
42
57
|
* {@link buildConsolidateToUsdTx} separately.
|
|
43
58
|
*/
|
|
44
59
|
consolidateToUsd?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* BE prefetch-cache seam for the oracle update-data fetch — forwarded
|
|
62
|
+
* verbatim into `refreshOraclePrices`'s `updateDataProvider` opt (see
|
|
63
|
+
* `UpdateDataProvider` in `oracle/price-update-rule.ts`). Default: none
|
|
64
|
+
* (always a live fetch). A caller-supplied provider that misses or throws
|
|
65
|
+
* still falls back to a live fetch — this option can only make a refresh
|
|
66
|
+
* faster, never break it.
|
|
67
|
+
*/
|
|
68
|
+
updateDataProvider?: UpdateDataProvider;
|
|
45
69
|
}
|
|
46
70
|
interface RequestParams {
|
|
47
71
|
ticker: string;
|
|
@@ -57,20 +81,33 @@ export declare function newTx(opts?: CommonBuildOpts): Transaction;
|
|
|
57
81
|
*/
|
|
58
82
|
export declare function refreshWlpPoolOracles(tx: Transaction, client: PerpClient, extraTickers: string[], opts: {
|
|
59
83
|
cache?: PythCache;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
packageId: string;
|
|
63
|
-
};
|
|
84
|
+
/** Forwarded to `refreshOraclePrices` — already resolved by the caller (see `OracleFeeSource`). */
|
|
85
|
+
feeSource?: OracleFeeSource;
|
|
64
86
|
lpType?: string;
|
|
87
|
+
updateDataProvider?: UpdateDataProvider;
|
|
65
88
|
}): Promise<void>;
|
|
66
89
|
/**
|
|
67
|
-
* Build the *Request + execute envelope with
|
|
90
|
+
* Build the *Request + execute envelope with the config-driven Pyth sponsor flow:
|
|
68
91
|
*
|
|
92
|
+
* [maybeConsolidate(tx)]
|
|
69
93
|
* [fund = sponsor.request()]
|
|
70
|
-
* refreshOraclePrices(...,
|
|
94
|
+
* refreshOraclePrices(..., feeSource?)
|
|
71
95
|
* req = buildRequest()
|
|
72
96
|
* [sponsor.reimburse(fund, req)]
|
|
73
97
|
* trading::execute(req)
|
|
98
|
+
*
|
|
99
|
+
* Accepted ordering caveat: `maybeConsolidate` runs FIRST and can itself
|
|
100
|
+
* append PTB commands (the consolidation sweep) before the fee-source check
|
|
101
|
+
* inside `refreshOraclePrices` ever runs — so an `OracleFeeSourceUnavailable`
|
|
102
|
+
* throw here is NOT the "zero commands appended" guarantee
|
|
103
|
+
* `refreshOraclePrices` gives its own callers (see its docblock in
|
|
104
|
+
* `aggregate.ts`); `tx` can already carry the sweep. This is the same
|
|
105
|
+
* discard-tx-on-throw contract every `build*Tx` composer already has for
|
|
106
|
+
* mid-build on-chain-read failures — not a new hole. It matters only for a
|
|
107
|
+
* caller that passed in their OWN `opts.tx` (reusing one `Transaction`
|
|
108
|
+
* across builder calls, e.g. to compose several actions in one PTB); such a
|
|
109
|
+
* caller must discard the whole `tx` on any throw from this function, not
|
|
110
|
+
* just retry the failed step.
|
|
74
111
|
*/
|
|
75
112
|
export declare function wrapRequestAndExecute(client: PerpClient, tx: Transaction, req: RequestParams & {
|
|
76
113
|
accountId: string;
|
|
@@ -29,32 +29,65 @@ async function refreshWlpPoolOracles(tx, client, extraTickers, opts) {
|
|
|
29
29
|
const oracleTickers = Array.from(new Set([...extraTickers, ...poolTickers]));
|
|
30
30
|
await (0, index_ts_1.refreshOraclePrices)(tx, client, oracleTickers, {
|
|
31
31
|
cache: opts.cache,
|
|
32
|
-
|
|
32
|
+
feeSource: opts.feeSource,
|
|
33
|
+
updateDataProvider: opts.updateDataProvider,
|
|
33
34
|
});
|
|
34
35
|
for (const tokenType of Object.values(client.config.packages.wlp.pool_tokens)) {
|
|
35
36
|
(0, wlp_ts_1.updateTokenValue)(client, tx, { tokenType, lpType: opts.lpType });
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
39
|
/**
|
|
39
|
-
* Build the *Request + execute envelope with
|
|
40
|
+
* Build the *Request + execute envelope with the config-driven Pyth sponsor flow:
|
|
40
41
|
*
|
|
42
|
+
* [maybeConsolidate(tx)]
|
|
41
43
|
* [fund = sponsor.request()]
|
|
42
|
-
* refreshOraclePrices(...,
|
|
44
|
+
* refreshOraclePrices(..., feeSource?)
|
|
43
45
|
* req = buildRequest()
|
|
44
46
|
* [sponsor.reimburse(fund, req)]
|
|
45
47
|
* trading::execute(req)
|
|
48
|
+
*
|
|
49
|
+
* Accepted ordering caveat: `maybeConsolidate` runs FIRST and can itself
|
|
50
|
+
* append PTB commands (the consolidation sweep) before the fee-source check
|
|
51
|
+
* inside `refreshOraclePrices` ever runs — so an `OracleFeeSourceUnavailable`
|
|
52
|
+
* throw here is NOT the "zero commands appended" guarantee
|
|
53
|
+
* `refreshOraclePrices` gives its own callers (see its docblock in
|
|
54
|
+
* `aggregate.ts`); `tx` can already carry the sweep. This is the same
|
|
55
|
+
* discard-tx-on-throw contract every `build*Tx` composer already has for
|
|
56
|
+
* mid-build on-chain-read failures — not a new hole. It matters only for a
|
|
57
|
+
* caller that passed in their OWN `opts.tx` (reusing one `Transaction`
|
|
58
|
+
* across builder calls, e.g. to compose several actions in one PTB); such a
|
|
59
|
+
* caller must discard the whole `tx` on any throw from this function, not
|
|
60
|
+
* just retry the failed step.
|
|
46
61
|
*/
|
|
47
62
|
async function wrapRequestAndExecute(client, tx, req, collateralTicker, opts, buildRequest) {
|
|
48
63
|
await maybeConsolidate(client, tx, req.accountId, opts);
|
|
49
|
-
|
|
64
|
+
// Fee source + witness attachment is config-driven, not a caller flag: the
|
|
65
|
+
// sponsor fund is opened (and later reimbursed) whenever this client's
|
|
66
|
+
// config has `pyth_sponsor_rule` deployed — regardless of the deprecated
|
|
67
|
+
// `useSponsor` flag (see its JSDoc). `allowGasFee` is the only caller lever
|
|
68
|
+
// left, and it only matters when config has NO sponsor rule to open (see
|
|
69
|
+
// `OracleFeeSourceUnavailable` in `oracle/pyth.ts`).
|
|
70
|
+
//
|
|
71
|
+
// `feeSource` is resolved HERE, once, from that same decision — sponsor
|
|
72
|
+
// beats gas structurally because this is the only branch that ever sees
|
|
73
|
+
// both candidates; everything downstream (`refreshWlpPoolOracles` →
|
|
74
|
+
// `refreshOraclePrices` → `BuildUpdateOpts` → `PythCoreRule` →
|
|
75
|
+
// `buildPythPriceUpdateCalls`) just carries the single resolved value.
|
|
50
76
|
let sponsorFund;
|
|
51
|
-
if (
|
|
77
|
+
if (client.config.packages.pyth_sponsor_rule) {
|
|
52
78
|
sponsorFund = (0, index_ts_1.openPythSponsorFund)(tx, client);
|
|
79
|
+
}
|
|
80
|
+
const feeSource = sponsorFund
|
|
81
|
+
? { kind: "sponsor", ...sponsorFund }
|
|
82
|
+
: opts?.allowGasFee
|
|
83
|
+
? { kind: "gas" }
|
|
84
|
+
: undefined;
|
|
53
85
|
if (!opts?.skipOraclePriceRefresh) {
|
|
54
86
|
await refreshWlpPoolOracles(tx, client, [req.ticker, collateralTicker], {
|
|
55
87
|
cache: opts?.pythCache,
|
|
56
|
-
|
|
88
|
+
feeSource,
|
|
57
89
|
lpType: req.lpType,
|
|
90
|
+
updateDataProvider: opts?.updateDataProvider,
|
|
58
91
|
});
|
|
59
92
|
}
|
|
60
93
|
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 {
|
|
@@ -18,17 +18,29 @@ const common_ts_1 = require("./common.js");
|
|
|
18
18
|
* `last_price_refresh_timestamp` so `assert_prices_fresh` inside
|
|
19
19
|
* `mint_wlp` passes.
|
|
20
20
|
*
|
|
21
|
-
*
|
|
21
|
+
* Never uses the pyth_sponsor flow — `mint_wlp` produces no
|
|
22
22
|
* `TradingRequest`, so there's nothing for the sponsor to attach its
|
|
23
|
-
* witness to
|
|
23
|
+
* witness to, and `pyth_sponsor_rule::reimburse` cannot consume a Fund
|
|
24
|
+
* without one. So when `skipOraclePriceRefresh` is `false` (the refresh
|
|
25
|
+
* actually runs), the caller MUST pass `allowGasFee: true` — the Pyth
|
|
26
|
+
* update fee is drawn from `tx.gas`, which Enoki-sponsored transactions
|
|
27
|
+
* reject; a sponsored caller should keep `skipOraclePriceRefresh: true`
|
|
28
|
+
* instead and rely on freshness from other trade traffic (see
|
|
29
|
+
* `OracleFeeSourceUnavailable` in `oracle/pyth.ts`).
|
|
24
30
|
*/
|
|
25
31
|
async function buildMintWlpTx(client, params) {
|
|
26
32
|
const tx = (0, common_ts_1.newTx)(params);
|
|
27
33
|
await (0, common_ts_1.maybeConsolidate)(client, tx, params.accountId, params);
|
|
34
|
+
// `mint_wlp` has no sponsor flow to resolve against (see the doc comment
|
|
35
|
+
// above) — the only candidate source at this edge is the caller's
|
|
36
|
+
// ergonomic `allowGasFee` opt-in.
|
|
37
|
+
const feeSource = params.allowGasFee ? { kind: "gas" } : undefined;
|
|
28
38
|
if (!params.skipOraclePriceRefresh) {
|
|
29
39
|
await (0, common_ts_1.refreshWlpPoolOracles)(tx, client, [params.depositTicker], {
|
|
30
40
|
cache: params.pythCache,
|
|
31
41
|
lpType: params.lpType,
|
|
42
|
+
feeSource,
|
|
43
|
+
updateDataProvider: params.updateDataProvider,
|
|
32
44
|
});
|
|
33
45
|
}
|
|
34
46
|
(0, wlp_ts_1.mintWlp)(client, tx, params);
|
|
@@ -46,10 +58,16 @@ async function buildMintWlpTx(client, params) {
|
|
|
46
58
|
async function buildMintAndStakeWlpTx(client, params) {
|
|
47
59
|
const tx = (0, common_ts_1.newTx)(params);
|
|
48
60
|
await (0, common_ts_1.maybeConsolidate)(client, tx, params.accountId, params);
|
|
61
|
+
// `mint_wlp` has no sponsor flow to resolve against (see `buildMintWlpTx`'s
|
|
62
|
+
// doc comment) — the only candidate source at this edge is the caller's
|
|
63
|
+
// ergonomic `allowGasFee` opt-in.
|
|
64
|
+
const feeSource = params.allowGasFee ? { kind: "gas" } : undefined;
|
|
49
65
|
if (!params.skipOraclePriceRefresh) {
|
|
50
66
|
await (0, common_ts_1.refreshWlpPoolOracles)(tx, client, [params.depositTicker], {
|
|
51
67
|
cache: params.pythCache,
|
|
52
68
|
lpType: params.lpType,
|
|
69
|
+
feeSource,
|
|
70
|
+
updateDataProvider: params.updateDataProvider,
|
|
53
71
|
});
|
|
54
72
|
}
|
|
55
73
|
const stakeAlias = params.stakeAlias ?? "WLP";
|
|
@@ -71,16 +89,24 @@ async function buildMintAndStakeWlpTx(client, params) {
|
|
|
71
89
|
* Refreshes every WLP pool-token oracle by default — `request_redeem` runs
|
|
72
90
|
* `assert_prices_fresh` internally, so a stale oracle would abort the PTB.
|
|
73
91
|
* Pass `skipOraclePriceRefresh: true` only when the caller is composing this
|
|
74
|
-
* into a larger PTB that already pre-pumps prices.
|
|
92
|
+
* into a larger PTB that already pre-pumps prices. Like `buildMintWlpTx`,
|
|
93
|
+
* `request_redeem` produces no `TradingRequest`, so a non-skipped refresh
|
|
94
|
+
* requires `allowGasFee: true` (see `buildMintWlpTx`'s doc comment).
|
|
75
95
|
*/
|
|
76
96
|
async function buildUnstakeAndRequestRedeemWlpTx(client, params) {
|
|
77
97
|
const tx = (0, common_ts_1.newTx)(params);
|
|
78
98
|
const stakeAlias = params.stakeAlias ?? "WLP";
|
|
79
99
|
await (0, common_ts_1.maybeConsolidate)(client, tx, params.accountId, params);
|
|
100
|
+
// `request_redeem` has no sponsor flow to resolve against (see
|
|
101
|
+
// `buildMintWlpTx`'s doc comment) — the only candidate source at this edge
|
|
102
|
+
// is the caller's ergonomic `allowGasFee` opt-in.
|
|
103
|
+
const feeSource = params.allowGasFee ? { kind: "gas" } : undefined;
|
|
80
104
|
if (!params.skipOraclePriceRefresh) {
|
|
81
105
|
await (0, common_ts_1.refreshWlpPoolOracles)(tx, client, [], {
|
|
82
106
|
cache: params.pythCache,
|
|
83
107
|
lpType: params.lpType,
|
|
108
|
+
feeSource,
|
|
109
|
+
updateDataProvider: params.updateDataProvider,
|
|
84
110
|
});
|
|
85
111
|
}
|
|
86
112
|
(0, staking_ts_1.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*)
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Each `build*Tx` composer creates (or appends to) a `Transaction`, refreshes
|
|
6
6
|
* the on-chain `Oracle` via Pyth, optionally pre-sweeps parked balances
|
|
7
|
-
* (`consolidateToUsd`), wires the `pyth_sponsor_rule` flow when
|
|
8
|
-
* calls the matching `*_request` + `execute`. Implementations are
|
|
9
|
-
* domain under `tx-builders/`:
|
|
7
|
+
* (`consolidateToUsd`), wires the `pyth_sponsor_rule` flow when deployed in
|
|
8
|
+
* config, and calls the matching `*_request` + `execute`. Implementations are
|
|
9
|
+
* split by domain under `tx-builders/`:
|
|
10
10
|
*
|
|
11
11
|
* common.ts CommonBuildOpts + request/execute envelope + oracle refresh
|
|
12
12
|
* consolidate.ts parked-balance → wxUSD pre-sweep (appendConsolidate*)
|
|
@@ -47,17 +47,12 @@ export interface WaterxPredictionConfig {
|
|
|
47
47
|
}
|
|
48
48
|
export interface LoadConfigOptions {
|
|
49
49
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
50
|
+
* Canonical `waterx-config` JSON URL to fetch, **as-is** (no `<network>.json`
|
|
51
|
+
* / git ref appended). Required — {@link loadConfig} reads the URL only from
|
|
52
|
+
* this option (there is no env-var fallback and no built-in default) and
|
|
53
|
+
* throws when it is unset.
|
|
52
54
|
*/
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Pin the canonical config to a specific git ref — a commit SHA, branch, or
|
|
56
|
-
* tag — instead of the default `main` branch. Resolves to
|
|
57
|
-
* `https://raw.githubusercontent.com/WaterXProtocol/waterx-config/<ref>/<network>.json`.
|
|
58
|
-
* Ignored when {@link configUrl} is set.
|
|
59
|
-
*/
|
|
60
|
-
configRef?: string;
|
|
55
|
+
waterxConfigUrl?: string;
|
|
61
56
|
/** Reuse a previously fetched config in memory. Default: false. */
|
|
62
57
|
cache?: boolean;
|
|
63
58
|
/** Optional fetch implementation for tests or runtimes without global fetch. */
|
|
@@ -65,10 +60,5 @@ export interface LoadConfigOptions {
|
|
|
65
60
|
/** Request timeout in ms. Default: 10_000. */
|
|
66
61
|
timeoutMs?: number;
|
|
67
62
|
}
|
|
68
|
-
/**
|
|
69
|
-
* Build the canonical config URL for `network`, optionally pinned to a
|
|
70
|
-
* specific git `ref` (commit SHA, branch, or tag). Defaults to `main`.
|
|
71
|
-
*/
|
|
72
|
-
export declare function defaultConfigUrl(network: Network, ref?: string): string;
|
|
73
63
|
export declare function clearConfigCache(): void;
|
|
74
64
|
export declare function loadConfig(network: Network, opts?: LoadConfigOptions): Promise<WaterxPredictionConfig>;
|