@oddmaki-protocol/sdk 0.3.1 → 0.4.1
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/dist/index.d.mts +111 -2
- package/dist/index.d.ts +111 -2
- package/dist/index.js +169 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +169 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -5045,6 +5045,11 @@ var PriceMarketFacet_default = [
|
|
|
5045
5045
|
name: "strikePrice",
|
|
5046
5046
|
type: "int64",
|
|
5047
5047
|
internalType: "int64"
|
|
5048
|
+
},
|
|
5049
|
+
{
|
|
5050
|
+
name: "openPriceTime",
|
|
5051
|
+
type: "uint256",
|
|
5052
|
+
internalType: "uint256"
|
|
5048
5053
|
}
|
|
5049
5054
|
],
|
|
5050
5055
|
stateMutability: "view"
|
|
@@ -5190,6 +5195,32 @@ var PythResolutionFacet_default = [
|
|
|
5190
5195
|
outputs: [],
|
|
5191
5196
|
stateMutability: "nonpayable"
|
|
5192
5197
|
},
|
|
5198
|
+
{
|
|
5199
|
+
type: "function",
|
|
5200
|
+
name: "setOpenMaxStaleness",
|
|
5201
|
+
inputs: [
|
|
5202
|
+
{
|
|
5203
|
+
name: "openMaxStaleness",
|
|
5204
|
+
type: "uint256",
|
|
5205
|
+
internalType: "uint256"
|
|
5206
|
+
}
|
|
5207
|
+
],
|
|
5208
|
+
outputs: [],
|
|
5209
|
+
stateMutability: "nonpayable"
|
|
5210
|
+
},
|
|
5211
|
+
{
|
|
5212
|
+
type: "function",
|
|
5213
|
+
name: "getOpenMaxStaleness",
|
|
5214
|
+
inputs: [],
|
|
5215
|
+
outputs: [
|
|
5216
|
+
{
|
|
5217
|
+
name: "",
|
|
5218
|
+
type: "uint256",
|
|
5219
|
+
internalType: "uint256"
|
|
5220
|
+
}
|
|
5221
|
+
],
|
|
5222
|
+
stateMutability: "view"
|
|
5223
|
+
},
|
|
5193
5224
|
{
|
|
5194
5225
|
type: "event",
|
|
5195
5226
|
name: "MarketCreated",
|
|
@@ -5412,6 +5443,19 @@ var PythResolutionFacet_default = [
|
|
|
5412
5443
|
],
|
|
5413
5444
|
anonymous: false
|
|
5414
5445
|
},
|
|
5446
|
+
{
|
|
5447
|
+
type: "event",
|
|
5448
|
+
name: "OpenMaxStalenessUpdated",
|
|
5449
|
+
inputs: [
|
|
5450
|
+
{
|
|
5451
|
+
name: "openMaxStaleness",
|
|
5452
|
+
type: "uint256",
|
|
5453
|
+
indexed: false,
|
|
5454
|
+
internalType: "uint256"
|
|
5455
|
+
}
|
|
5456
|
+
],
|
|
5457
|
+
anonymous: false
|
|
5458
|
+
},
|
|
5415
5459
|
{
|
|
5416
5460
|
type: "event",
|
|
5417
5461
|
name: "WrappedCollateralRegistered",
|
|
@@ -7842,6 +7886,25 @@ var TradeModule = class extends BaseModule {
|
|
|
7842
7886
|
});
|
|
7843
7887
|
return wallet.writeContract(request);
|
|
7844
7888
|
}
|
|
7889
|
+
/**
|
|
7890
|
+
* Cancel all remaining orders on a resolved market in a single transaction.
|
|
7891
|
+
* Regular cancelOrder / batchCancelOrders revert once the market is no longer
|
|
7892
|
+
* active, so this is the only way to clear stale orders post-resolution.
|
|
7893
|
+
* @param marketId - The resolved market
|
|
7894
|
+
* @param orderIds - Order IDs to cancel (must belong to caller)
|
|
7895
|
+
*/
|
|
7896
|
+
async cancelOrdersOnResolvedMarket(marketId, orderIds) {
|
|
7897
|
+
const wallet = this.walletClient;
|
|
7898
|
+
const [account] = await wallet.getAddresses();
|
|
7899
|
+
const { request } = await this.publicClient.simulateContract({
|
|
7900
|
+
address: this.config.diamondAddress,
|
|
7901
|
+
abi: LimitOrdersFacet_default,
|
|
7902
|
+
functionName: "cancelOrdersOnResolvedMarket",
|
|
7903
|
+
args: [marketId, orderIds],
|
|
7904
|
+
account
|
|
7905
|
+
});
|
|
7906
|
+
return wallet.writeContract(request);
|
|
7907
|
+
}
|
|
7845
7908
|
/**
|
|
7846
7909
|
* Execute a market order (FOK or FAK)
|
|
7847
7910
|
*
|
|
@@ -10463,6 +10526,8 @@ var FeedProvider = /* @__PURE__ */ ((FeedProvider2) => {
|
|
|
10463
10526
|
FeedProvider2[FeedProvider2["CHAINLINK"] = 1] = "CHAINLINK";
|
|
10464
10527
|
return FeedProvider2;
|
|
10465
10528
|
})(FeedProvider || {});
|
|
10529
|
+
var DEFAULT_FRESH_MAX_AGE_SECONDS = 120;
|
|
10530
|
+
var DEFAULT_FRESH_MAX_ATTEMPTS = 3;
|
|
10466
10531
|
var PriceMarketModule = class extends BaseModule {
|
|
10467
10532
|
/**
|
|
10468
10533
|
* Create a Pyth-powered price market
|
|
@@ -10606,7 +10671,8 @@ var PriceMarketModule = class extends BaseModule {
|
|
|
10606
10671
|
finalPrice: BigInt(result[5]),
|
|
10607
10672
|
resolutionWindow: BigInt(result[6]),
|
|
10608
10673
|
resolved: result[7],
|
|
10609
|
-
strikePrice: BigInt(result[8])
|
|
10674
|
+
strikePrice: BigInt(result[8]),
|
|
10675
|
+
openPriceTime: BigInt(result[9])
|
|
10610
10676
|
};
|
|
10611
10677
|
}
|
|
10612
10678
|
/**
|
|
@@ -10619,6 +10685,51 @@ var PriceMarketModule = class extends BaseModule {
|
|
|
10619
10685
|
functionName: "getPythContract"
|
|
10620
10686
|
});
|
|
10621
10687
|
}
|
|
10688
|
+
/**
|
|
10689
|
+
* Set the Pyth oracle contract address. Diamond owner only.
|
|
10690
|
+
*/
|
|
10691
|
+
async setPythContract(pythContract) {
|
|
10692
|
+
const wallet = this.walletClient;
|
|
10693
|
+
const [account] = await wallet.getAddresses();
|
|
10694
|
+
const { request } = await this.publicClient.simulateContract({
|
|
10695
|
+
address: this.config.diamondAddress,
|
|
10696
|
+
abi: PythResolutionFacet_default,
|
|
10697
|
+
functionName: "setPythContract",
|
|
10698
|
+
args: [pythContract],
|
|
10699
|
+
account
|
|
10700
|
+
});
|
|
10701
|
+
return wallet.writeContract(request);
|
|
10702
|
+
}
|
|
10703
|
+
/**
|
|
10704
|
+
* Get the effective opening-price staleness window in seconds.
|
|
10705
|
+
*
|
|
10706
|
+
* A submitted VAA's `publishTime` must fall within
|
|
10707
|
+
* `[block.timestamp - openMaxStaleness, block.timestamp + OPEN_FUTURE_SKEW]`
|
|
10708
|
+
* at `createPriceMarketPyth` time. Defaults to 300s when unset on-chain.
|
|
10709
|
+
*/
|
|
10710
|
+
async getOpenMaxStaleness() {
|
|
10711
|
+
return await this.publicClient.readContract({
|
|
10712
|
+
address: this.config.diamondAddress,
|
|
10713
|
+
abi: PythResolutionFacet_default,
|
|
10714
|
+
functionName: "getOpenMaxStaleness"
|
|
10715
|
+
});
|
|
10716
|
+
}
|
|
10717
|
+
/**
|
|
10718
|
+
* Set the opening-price staleness window (seconds). Diamond owner only.
|
|
10719
|
+
* Pass 0 to fall back to the built-in default.
|
|
10720
|
+
*/
|
|
10721
|
+
async setOpenMaxStaleness(openMaxStaleness) {
|
|
10722
|
+
const wallet = this.walletClient;
|
|
10723
|
+
const [account] = await wallet.getAddresses();
|
|
10724
|
+
const { request } = await this.publicClient.simulateContract({
|
|
10725
|
+
address: this.config.diamondAddress,
|
|
10726
|
+
abi: PythResolutionFacet_default,
|
|
10727
|
+
functionName: "setOpenMaxStaleness",
|
|
10728
|
+
args: [openMaxStaleness],
|
|
10729
|
+
account
|
|
10730
|
+
});
|
|
10731
|
+
return wallet.writeContract(request);
|
|
10732
|
+
}
|
|
10622
10733
|
// ---- Private helpers ----
|
|
10623
10734
|
/**
|
|
10624
10735
|
* Shared pre-flight checks: creation fee allowance, ancillary data, tags
|
|
@@ -10671,20 +10782,73 @@ var PriceMarketModule = class extends BaseModule {
|
|
|
10671
10782
|
return stringToHex(data);
|
|
10672
10783
|
}
|
|
10673
10784
|
/**
|
|
10674
|
-
* Fetch latest Pyth price update
|
|
10785
|
+
* Fetch latest Pyth price update from Hermes — bytes plus the VAA's publishTime.
|
|
10786
|
+
*
|
|
10787
|
+
* Use this (or {@link fetchFreshPythUpdate}) instead of re-rolling Hermes
|
|
10788
|
+
* calls when building `createPriceMarketPyth` transactions. The on-chain
|
|
10789
|
+
* staleness window defaults to 300s — if the user takes longer than that
|
|
10790
|
+
* to sign, the VAA will be rejected.
|
|
10675
10791
|
*/
|
|
10676
|
-
async
|
|
10792
|
+
async fetchPythLatestUpdate(feedId) {
|
|
10677
10793
|
const url = `${PYTH_HERMES_BASE}/v2/updates/price/latest?ids[]=${feedId}`;
|
|
10678
10794
|
const response = await fetch(url);
|
|
10679
10795
|
if (!response.ok) {
|
|
10680
|
-
throw new Error(
|
|
10796
|
+
throw new Error(
|
|
10797
|
+
`Pyth Hermes API error: ${response.status} ${response.statusText}`
|
|
10798
|
+
);
|
|
10681
10799
|
}
|
|
10682
10800
|
const data = await response.json();
|
|
10683
10801
|
const updateData = data.binary?.data;
|
|
10684
10802
|
if (!updateData || updateData.length === 0) {
|
|
10685
10803
|
throw new Error("No price update data returned from Pyth Hermes");
|
|
10686
10804
|
}
|
|
10687
|
-
|
|
10805
|
+
const parsed = data.parsed?.[0];
|
|
10806
|
+
const publishTimeRaw = parsed?.price?.publish_time;
|
|
10807
|
+
if (typeof publishTimeRaw !== "number") {
|
|
10808
|
+
throw new Error("Pyth Hermes response missing parsed.price.publish_time");
|
|
10809
|
+
}
|
|
10810
|
+
return {
|
|
10811
|
+
updateData: updateData.map((d) => `0x${d}`),
|
|
10812
|
+
publishTime: BigInt(publishTimeRaw),
|
|
10813
|
+
fetchedAt: BigInt(Math.floor(Date.now() / 1e3))
|
|
10814
|
+
};
|
|
10815
|
+
}
|
|
10816
|
+
/**
|
|
10817
|
+
* Return a Pyth update that is fresh enough to pass the on-chain staleness check.
|
|
10818
|
+
*
|
|
10819
|
+
* If `cached` is provided and still within `maxAgeSeconds`, it is returned as-is.
|
|
10820
|
+
* Otherwise Hermes is re-queried; if the newly fetched VAA is also older than
|
|
10821
|
+
* `maxAgeSeconds` (e.g. feed is quiet), it retries up to `maxAttempts`.
|
|
10822
|
+
*
|
|
10823
|
+
* Defaults: `maxAgeSeconds = 120` (leaves ~180s headroom under the 300s default
|
|
10824
|
+
* on-chain window), `maxAttempts = 3`.
|
|
10825
|
+
*/
|
|
10826
|
+
async fetchFreshPythUpdate(feedId, options = {}) {
|
|
10827
|
+
const maxAgeSeconds = options.maxAgeSeconds ?? DEFAULT_FRESH_MAX_AGE_SECONDS;
|
|
10828
|
+
const maxAttempts = options.maxAttempts ?? DEFAULT_FRESH_MAX_ATTEMPTS;
|
|
10829
|
+
const isFresh = (u) => {
|
|
10830
|
+
const now = BigInt(Math.floor(Date.now() / 1e3));
|
|
10831
|
+
return now - u.publishTime <= BigInt(maxAgeSeconds);
|
|
10832
|
+
};
|
|
10833
|
+
if (options.cached && isFresh(options.cached)) {
|
|
10834
|
+
return options.cached;
|
|
10835
|
+
}
|
|
10836
|
+
let latest;
|
|
10837
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
10838
|
+
latest = await this.fetchPythLatestUpdate(feedId);
|
|
10839
|
+
if (isFresh(latest)) return latest;
|
|
10840
|
+
}
|
|
10841
|
+
if (!latest) {
|
|
10842
|
+
throw new Error("Failed to fetch any Pyth update from Hermes");
|
|
10843
|
+
}
|
|
10844
|
+
return latest;
|
|
10845
|
+
}
|
|
10846
|
+
/**
|
|
10847
|
+
* Fetch latest Pyth price update data from Hermes API (raw bytes only).
|
|
10848
|
+
*/
|
|
10849
|
+
async fetchPythUpdateData(feedId) {
|
|
10850
|
+
const { updateData } = await this.fetchPythLatestUpdate(feedId);
|
|
10851
|
+
return updateData;
|
|
10688
10852
|
}
|
|
10689
10853
|
/**
|
|
10690
10854
|
* Fetch historical Pyth price update data at a specific timestamp
|