Skip to content

Commit

Permalink
add new latest_price_info endpoint (#264)
Browse files Browse the repository at this point in the history
* add new latest_price_info endpoint

* add verbose query param to latest_price_feeds

* add back logging statement for VAA

* trigger CI
  • Loading branch information
cctdaniel authored Sep 5, 2022
1 parent aa7be4d commit b846fc3
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 24 deletions.
1 change: 1 addition & 0 deletions third_party/pyth/price-service/src/__tests__/rest.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ function dummyPriceInfoPair(
attestationTime: 0,
seqNum,
vaaBytes: Buffer.from(vaa, "hex").toString("binary"),
emitterChainId: 0,
},
];
}
Expand Down
18 changes: 10 additions & 8 deletions third_party/pyth/price-service/src/listen.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
import {
ChainId,
hexToUint8Array,
uint8ArrayToHex,
uint8ArrayToHex
} from "@certusone/wormhole-sdk";

import {
createSpyRPCServiceClient,
subscribeSignedVAA,
subscribeSignedVAA
} from "@certusone/wormhole-spydk";

import { importCoreWasm } from "@certusone/wormhole-sdk/lib/cjs/solana/wasm";

import { envOrErr, sleep, TimestampInSec } from "./helpers";
import { PromClient } from "./promClient";
import {
getBatchSummary,
parseBatchPriceAttestation,
priceAttestationToPriceFeed,
priceAttestationToPriceFeed
} from "@certusone/p2w-sdk";
import { ClientReadableStream } from "@grpc/grpc-js";
import {
FilterEntry,
SubscribeSignedVAAResponse,
SubscribeSignedVAAResponse
} from "@certusone/wormhole-spydk/lib/cjs/proto/spy/v1/spy";
import { logger } from "./logging";
import { ClientReadableStream } from "@grpc/grpc-js";
import { HexString, PriceFeed } from "@pythnetwork/pyth-sdk-js";
import { sleep, TimestampInSec } from "./helpers";
import { logger } from "./logging";
import { PromClient } from "./promClient";

export type PriceInfo = {
vaaBytes: string;
seqNum: number;
attestationTime: TimestampInSec;
priceFeed: PriceFeed;
emitterChainId: number;
};

export interface PriceStore {
Expand Down Expand Up @@ -196,6 +197,7 @@ export class Listener implements PriceStore {
vaaBytes: vaaBytes,
attestationTime: priceAttestation.attestationTime,
priceFeed,
emitterChainId: parsedVAA.emitter_chain,
});

for (let callback of this.updateCallbacks) {
Expand Down
43 changes: 27 additions & 16 deletions third_party/pyth/price-service/src/rest.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import express, { Express } from "express";
import cors from "cors";
import express, { NextFunction, Request, Response } from "express";
import { Joi, schema, validate, ValidationError } from "express-validation";
import { Server } from "http";
import { StatusCodes } from "http-status-codes";
import morgan from "morgan";
import responseTime from "response-time";
import { Request, Response, NextFunction } from "express";
import { DurationInMs, DurationInSec } from "./helpers";
import { PriceStore } from "./listen";
import { logger } from "./logging";
import { PromClient } from "./promClient";
import { DurationInMs, DurationInSec } from "./helpers";
import { StatusCodes } from "http-status-codes";
import { validate, ValidationError, Joi, schema } from "express-validation";
import { Server } from "http";

const MORGAN_LOG_FORMAT =
':remote-addr - :remote-user ":method :url HTTP/:http-version"' +
Expand Down Expand Up @@ -135,13 +134,16 @@ export class RestAPI {
ids: Joi.array()
.items(Joi.string().regex(/^(0x)?[a-f0-9]{64}$/))
.required(),
verbose: Joi.boolean(),
}).required(),
};
app.get(
"/api/latest_price_feeds",
validate(latestPriceFeedsInputSchema),
(req: Request, res: Response) => {
let priceIds = req.query.ids as string[];
// verbose is optional, default to false
let verbose = req.query.verbose === "true";

let responseJson = [];

Expand All @@ -167,7 +169,18 @@ export class RestAPI {
freshness
);

responseJson.push(latestPriceInfo.priceFeed.toJson());
if (verbose) {
responseJson.push({
...latestPriceInfo.priceFeed.toJson(),
metadata: {
emitter_chain: latestPriceInfo.emitterChainId,
attestation_time: latestPriceInfo.attestationTime,
sequence_number: latestPriceInfo.seqNum,
},
});
} else {
responseJson.push(latestPriceInfo.priceFeed.toJson());
}
}

if (notFoundIds.length > 0) {
Expand All @@ -180,18 +193,16 @@ export class RestAPI {
endpoints.push(
"api/latest_price_feeds?ids[]=<price_feed_id>&ids[]=<price_feed_id_2>&.."
);

app.get(
"/api/price_feed_ids",
(req: Request, res: Response) => {
const availableIds = this.priceFeedVaaInfo.getPriceIds();
res.json([...availableIds]);
}
);
endpoints.push(
"api/price_feed_ids"
"api/latest_price_feeds?ids[]=<price_feed_id>&ids[]=<price_feed_id_2>&..&verbose=true"
);

app.get("/api/price_feed_ids", (req: Request, res: Response) => {
const availableIds = this.priceFeedVaaInfo.getPriceIds();
res.json([...availableIds]);
});
endpoints.push("api/price_feed_ids");

app.get("/ready", (_, res: Response) => {
if (this.isReady!()) {
res.sendStatus(StatusCodes.OK);
Expand Down

0 comments on commit b846fc3

Please sign in to comment.