1717_SUPPORTED_VERSIONS = set ((_VERSION_1 , _VERSION_2 ))
1818_ACCOUNT_HEADER_BYTES = 16 # magic + version + type + size, u32 * 4
1919_NULL_KEY_BYTES = b'\x00 ' * SolanaPublicKey .LENGTH
20+ MAX_SLOT_DIFFERENCE = 25
2021
2122
2223class PythAccountType (Enum ):
@@ -377,7 +378,7 @@ class PythPriceInfo:
377378 price (int): the price
378379 confidence_interval (int): the price confidence interval
379380 price_status (PythPriceStatus): the price status
380- slot (int): the slot time this price information was published
381+ pub_slot (int): the slot time this price information was published
381382 exponent (int): the power-of-10 order of the price
382383 """
383384
@@ -386,7 +387,7 @@ class PythPriceInfo:
386387 raw_price : int
387388 raw_confidence_interval : int
388389 price_status : PythPriceStatus
389- slot : int
390+ pub_slot : int
390391 exponent : int
391392
392393 price : float = field (init = False )
@@ -410,9 +411,9 @@ def deserialise(buffer: bytes, offset: int = 0, *, exponent: int) -> PythPriceIn
410411 slot (u64)
411412 """
412413 # _ is corporate_action
413- price , confidence_interval , price_status , _ , slot = struct .unpack_from (
414+ price , confidence_interval , price_status , _ , pub_slot = struct .unpack_from (
414415 "<qQIIQ" , buffer , offset )
415- return PythPriceInfo (price , confidence_interval , PythPriceStatus (price_status ), slot , exponent )
416+ return PythPriceInfo (price , confidence_interval , PythPriceStatus (price_status ), pub_slot , exponent )
416417
417418 def __str__ (self ) -> str :
418419 return f"PythPriceInfo status { self .price_status } price { self .price } "
@@ -507,7 +508,7 @@ class PythPriceAccount(PythAccount):
507508 aggregate_price_info (PythPriceInfo): the aggregate price information
508509 price_components (List[PythPriceComponent]): the price components that the
509510 aggregate price is composed of
510- slot (int): the slot time when this account was last updated
511+ slot (int): the slot time when this account was last fetched
511512 product (Optional[PythProductAccount]): the product this price is for, if loaded
512513 """
513514
@@ -528,13 +529,41 @@ def __init__(self, key: SolanaPublicKey, solana: SolanaClient, *, product: Optio
528529
529530 @property
530531 def aggregate_price (self ) -> Optional [float ]:
531- """the aggregate price"""
532- return self .aggregate_price_info and self .aggregate_price_info .price
532+ """
533+ The aggregate price. Returns None if price is not currently available.
534+ If you need the price value regardless of availability use `aggregate_price_info.price`
535+ """
536+ if self .aggregate_price_status == PythPriceStatus .TRADING :
537+ return self .aggregate_price_info .price
538+ else :
539+ return None
533540
534541 @property
535542 def aggregate_price_confidence_interval (self ) -> Optional [float ]:
536- """the aggregate price confidence interval"""
537- return self .aggregate_price_info and self .aggregate_price_info .confidence_interval
543+ """
544+ The aggregate price confidence interval. Returns None if price is not currently available.
545+ If you need the confidence value regardless of availability use `aggregate_price_info.confidence_interval`
546+ """
547+ if self .aggregate_price_status == PythPriceStatus .TRADING :
548+ return self .aggregate_price_info .confidence_interval
549+ else :
550+ return None
551+
552+ @property
553+ def aggregate_price_status (self ) -> Optional [PythPriceStatus ]:
554+ """The aggregate price status."""
555+ return self .get_aggregate_price_status_with_slot (self .slot )
556+
557+ def get_aggregate_price_status_with_slot (self , slot : int ) -> Optional [PythPriceStatus ]:
558+ """
559+ Gets the aggregate price status given a solana slot.
560+ You might consider using this function with the latest solana slot to make sure the price has not gone stale.
561+ """
562+ if self .aggregate_price_info .price_status == PythPriceStatus .TRADING and \
563+ slot - self .aggregate_price_info .pub_slot > MAX_SLOT_DIFFERENCE :
564+ return PythPriceStatus .UNKNOWN
565+
566+ return self .aggregate_price_info .price_status
538567
539568 def update_from (self , buffer : bytes , * , version : int , offset : int = 0 ) -> None :
540569 """
0 commit comments