wormhole/backend/fetcher/PythPriceFetcher.ts

60 lines
1.7 KiB
TypeScript

/**
* Pricecaster Service.
*
* Fetcher backend component.
*
* (c) 2021 Randlabs, Inc.
*/
import { IPriceFetcher } from './IPriceFetcher'
import { IStrategy } from '../strategy/strategy'
import { getPythProgramKeyForCluster, PriceData, Product, PythConnection } from '@pythnetwork/client'
import { Cluster, clusterApiUrl, Connection } from '@solana/web3.js'
import { PriceTicker } from '../common/priceTicker'
export class PythPriceFetcher implements IPriceFetcher {
private strategy: IStrategy
private symbol: string
private pythConnection: PythConnection
constructor (symbol: string, strategy: IStrategy, solanaClusterName: string) {
const SOLANA_CLUSTER_NAME: Cluster = solanaClusterName as Cluster
const connection = new Connection(clusterApiUrl(SOLANA_CLUSTER_NAME))
const pythPublicKey = getPythProgramKeyForCluster(SOLANA_CLUSTER_NAME)
this.pythConnection = new PythConnection(connection, pythPublicKey)
this.strategy = strategy
this.symbol = symbol
}
async start () {
await this.pythConnection.start()
this.pythConnection.onPriceChange((product: Product, price: PriceData) => {
if (product.symbol === this.symbol) {
this.onPriceChange(price)
}
})
}
stop (): void {
this.pythConnection.stop()
}
setStrategy (s: IStrategy) {
this.strategy = s
}
hasData (): boolean {
return this.strategy.bufferCount() > 0
}
queryTicker (): PriceTicker | undefined {
return this.strategy.getPrice()
}
private onPriceChange (price: PriceData) {
const pt: PriceTicker = new PriceTicker(price.priceComponent,
price.confidenceComponent, price.exponent, price.publishSlot)
this.strategy.put(pt)
}
}