Skip to content
This repository was archived by the owner on Mar 14, 2024. It is now read-only.

Commit

Permalink
add new optional metadata property to PriceFeed and test
Browse files Browse the repository at this point in the history
  • Loading branch information
cctdaniel committed Sep 6, 2022
1 parent 7fd8ae7 commit de9d497
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 12 deletions.
39 changes: 36 additions & 3 deletions src/__tests__/PriceFeed.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Price, PriceFeed, PriceStatus } from "../index";
import { Price, PriceFeed, PriceFeedMetadata, PriceStatus } from "../index";

beforeAll(() => {
jest.useFakeTimers();
Expand Down Expand Up @@ -42,8 +42,7 @@ test("Parsing Price Feed works as expected", () => {
new Price("1", 4, "10")
);
expect(priceFeed.getLatestAvailablePriceWithinDuration(5)).toBeUndefined();

expect(priceFeed.toJson()).toStrictEqual(data);
expect(priceFeed.toJson()).toEqual(data);
});

test("getCurrentPrice returns undefined if status is not Trading", () => {
Expand Down Expand Up @@ -99,3 +98,37 @@ test("getLatestAvailablePrice returns prevPrice when status is not Trading", ()
);
expect(priceFeed.getLatestAvailablePriceWithinDuration(10)).toBeUndefined();
});

test("getMetadata returns PriceFeedMetadata as expected", () => {
const data = {
conf: "1",
ema_conf: "2",
ema_price: "3",
expo: 4,
id: "abcdef0123456789",
max_num_publishers: 6,
metadata: new PriceFeedMetadata({
attestation_time: 7,
emitter_chain: 8,
sequence_number: 9,
}),
num_publishers: 10,
prev_conf: "11",
prev_price: "12",
prev_publish_time: 13,
price: "14",
product_id: "0123456789abcdef",
publish_time: 16,
status: PriceStatus.Unknown,
};

const priceFeed = PriceFeed.fromJson(data);

expect(priceFeed.getMetadata()).toStrictEqual(
new PriceFeedMetadata({
attestation_time: 7,
emitter_chain: 8,
sequence_number: 9,
})
);
});
60 changes: 57 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,36 @@ export enum PriceStatus {
Unknown = "Unknown",
}

/**
* Metadata about the price
*
* Represents metadata of a price feed.
*/
export class PriceFeedMetadata {
/**
* Attestation time of the price
*/
attestation_time: number;
/**
* Chain of the emitter
*/
emitter_chain: number;
/**
* Sequence number of the price
*/
sequence_number: number;

constructor(metadata: {
attestation_time: number;
emitter_chain: number;
sequence_number: number;
}) {
this.attestation_time = metadata.attestation_time;
this.emitter_chain = metadata.emitter_chain;
this.sequence_number = metadata.sequence_number;
}
}

/**
* Pyth Price Feed
*
Expand Down Expand Up @@ -84,6 +114,10 @@ export class PriceFeed {
* Maximum number of allowed publishers that can contribute to a price.
*/
maxNumPublishers: number;
/**
* Metadata about the price
*/
metadata?: PriceFeedMetadata;
/**
* Number of publishers that made up current aggregate.
*/
Expand Down Expand Up @@ -124,6 +158,7 @@ export class PriceFeed {
expo: number;
id: HexString;
maxNumPublishers: number;
metadata?: PriceFeedMetadata;
numPublishers: number;
prevConf: string;
prevPrice: string;
Expand All @@ -139,6 +174,7 @@ export class PriceFeed {
this.expo = rawValues.expo;
this.id = rawValues.id;
this.maxNumPublishers = rawValues.maxNumPublishers;
this.metadata = rawValues.metadata;
this.numPublishers = rawValues.numPublishers;
this.prevConf = rawValues.prevConf;
this.prevPrice = rawValues.prevPrice;
Expand All @@ -158,6 +194,7 @@ export class PriceFeed {
expo: jsonFeed.expo,
id: jsonFeed.id,
maxNumPublishers: jsonFeed.max_num_publishers,
metadata: jsonFeed.metadata,
numPublishers: jsonFeed.num_publishers,
prevConf: jsonFeed.prev_conf,
prevPrice: jsonFeed.prev_price,
Expand All @@ -177,6 +214,7 @@ export class PriceFeed {
expo: this.expo,
id: this.id,
max_num_publishers: this.maxNumPublishers,
metadata: this.metadata,
num_publishers: this.numPublishers,
prev_conf: this.prevConf,
prev_price: this.prevPrice,
Expand All @@ -186,6 +224,7 @@ export class PriceFeed {
publish_time: this.publishTime,
status: this.status,
};
// this is done to avoid sending undefined values to the server
return Convert.priceFeedToJson(jsonFeed);
}

Expand Down Expand Up @@ -259,18 +298,33 @@ export class PriceFeed {
* @returns a struct containing the latest available price, confidence interval and the exponent for
* both numbers, or `undefined` if no price update occurred within `duration` seconds of the current time.
*/
getLatestAvailablePriceWithinDuration(duration: DurationInSeconds): Price | undefined {
getLatestAvailablePriceWithinDuration(
duration: DurationInSeconds
): Price | undefined {
const [price, timestamp] = this.getLatestAvailablePriceUnchecked();

const currentTime: UnixTimestamp = Math.floor(Date.now() / 1000);

// This checks the absolute difference as a sanity check
// for the cases that the system time is behind or price
// feed timestamp happen to be in the future (a bug).
// feed timestamp happen to be in the future (a bug).
if (Math.abs(currentTime - timestamp) > duration) {
return undefined;
}

return price;
}

/**
* Get the price feed metadata.
*
* @returns a struct containing the attestation time, emitter chain, and the sequence number.
* Returns `undefined` if metadata is currently unavailable.
*/
getMetadata(): PriceFeedMetadata | undefined {
if (this.metadata === undefined) {
return undefined;
}
return new PriceFeedMetadata(this.metadata);
}
}
37 changes: 37 additions & 0 deletions src/schemas/PriceFeed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ export interface PriceFeed {
* Maximum number of allowed publishers that can contribute to a price.
*/
max_num_publishers: number;
/**
* Metadata about the price
*/
metadata?: PriceFeedMetadata;
/**
* Number of publishers that made up current aggregate.
*/
Expand Down Expand Up @@ -69,6 +73,26 @@ export interface PriceFeed {
status: PriceStatus;
}

/**
* Metadata about the price
*
* Represents metadata of a price feed.
*/
export interface PriceFeedMetadata {
/**
* Attestation time of the price
*/
attestation_time: number;
/**
* Chain of the emitter
*/
emitter_chain: number;
/**
* Sequence number of the price
*/
sequence_number: number;
}

/**
* Status of price (Trading is valid).
*
Expand Down Expand Up @@ -249,6 +273,11 @@ const typeMap: any = {
{ json: "expo", js: "expo", typ: 0 },
{ json: "id", js: "id", typ: "" },
{ json: "max_num_publishers", js: "max_num_publishers", typ: 0 },
{
json: "metadata",
js: "metadata",
typ: u(undefined, r("PriceFeedMetadata")),
},
{ json: "num_publishers", js: "num_publishers", typ: 0 },
{ json: "prev_conf", js: "prev_conf", typ: "" },
{ json: "prev_price", js: "prev_price", typ: "" },
Expand All @@ -260,5 +289,13 @@ const typeMap: any = {
],
"any"
),
PriceFeedMetadata: o(
[
{ json: "attestation_time", js: "attestation_time", typ: 0 },
{ json: "emitter_chain", js: "emitter_chain", typ: 0 },
{ json: "sequence_number", js: "sequence_number", typ: 0 },
],
"any"
),
PriceStatus: ["Auction", "Halted", "Trading", "Unknown"],
};
37 changes: 31 additions & 6 deletions src/schemas/price_feed.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@
"$ref": "#/definitions/PriceStatus"
}
]
},
"metadata": {
"description": "Metadata about the price",
"allOf": [
{
"$ref": "#/definitions/PriceFeedMetadata"
}
]
}
},
"definitions": {
Expand All @@ -103,12 +111,29 @@
"PriceStatus": {
"description": "Represents availability status of a price feed.",
"type": "string",
"enum": [
"Unknown",
"Trading",
"Halted",
"Auction"
]
"enum": ["Unknown", "Trading", "Halted", "Auction"]
},
"PriceFeedMetadata": {
"description": "Represents metadata of a price feed.",
"type": "object",
"required": ["attestation_time", "emitter_chain", "sequence_number"],
"properties": {
"attestation_time": {
"description": "Attestation time of the price",
"type": "integer",
"format": "int64"
},
"emitter_chain": {
"description": "Chain of the emitter",
"type": "integer",
"format": "int16"
},
"sequence_number": {
"description": "Sequence number of the price",
"type": "integer",
"format": "int64"
}
}
}
}
}

0 comments on commit de9d497

Please sign in to comment.