pyth_publisher.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #!/usr/bin/env python3
  2. from pyth_utils import *
  3. from http.server import HTTPServer, BaseHTTPRequestHandler
  4. import json
  5. import random
  6. import sys
  7. import threading
  8. import time
  9. class PythAccEndpoint(BaseHTTPRequestHandler):
  10. """
  11. A dumb endpoint to respond with a JSON containing Pyth account addresses
  12. """
  13. def do_GET(self):
  14. print(f"Got path {self.path}")
  15. sys.stdout.flush()
  16. data = json.dumps(ACCOUNTS).encode("utf-8")
  17. print(f"Sending:\n{data}")
  18. self.send_response(200)
  19. self.send_header("Content-Type", "application/json")
  20. self.send_header("Content-Length", str(len(data)))
  21. self.end_headers()
  22. self.wfile.write(data)
  23. self.wfile.flush()
  24. ACCOUNTS = dict()
  25. def publisher_random_update(price_pubkey):
  26. """
  27. Update the specified price with random values
  28. """
  29. value = random.randrange(1024)
  30. confidence = 5
  31. pyth_run_or_die("upd_price_val", args=[
  32. price_pubkey, str(value), str(confidence), "trading"
  33. ])
  34. print(f"Price {price_pubkey} value updated to {str(value)}!")
  35. def accounts_endpoint():
  36. """
  37. Run a barebones HTTP server to share the dynamic Pyth
  38. mapping/product/price account addresses
  39. """
  40. server_address = ('', 4242)
  41. httpd = HTTPServer(server_address, PythAccEndpoint)
  42. httpd.serve_forever()
  43. # Fund the publisher
  44. sol_run_or_die("airdrop", [
  45. str(SOL_AIRDROP_AMT),
  46. "--keypair", PYTH_PUBLISHER_KEYPAIR,
  47. "--commitment", "finalized",
  48. ])
  49. # Create a mapping
  50. pyth_run_or_die("init_mapping")
  51. # Add a product
  52. prod_pubkey = pyth_run_or_die(
  53. "add_product", capture_output=True).stdout.strip()
  54. print(f"Added product {prod_pubkey}")
  55. # Add a price
  56. price_pubkey = pyth_run_or_die(
  57. "add_price",
  58. args=[prod_pubkey, "price"],
  59. confirm=False,
  60. capture_output=True
  61. ).stdout.strip()
  62. print(f"Added price {price_pubkey}")
  63. publisher_pubkey = sol_run_or_die("address", args=[
  64. "--keypair", PYTH_PUBLISHER_KEYPAIR
  65. ], capture_output=True).stdout.strip()
  66. # Become a publisher
  67. pyth_run_or_die(
  68. "add_publisher", args=[publisher_pubkey, price_pubkey],
  69. confirm=False,
  70. debug=True,
  71. capture_output=True)
  72. print(f"Added publisher {publisher_pubkey}")
  73. # Update the price as the newly added publisher
  74. publisher_random_update(price_pubkey)
  75. print(
  76. f"Mock updates ready to roll. Updating every {str(PYTH_PUBLISHER_INTERVAL)} seconds")
  77. # Spin off the readiness probe endpoint into a separate thread
  78. readiness_thread = threading.Thread(target=readiness, daemon=True)
  79. # Start an HTTP endpoint for looking up product/price address
  80. http_service = threading.Thread(target=accounts_endpoint, daemon=True)
  81. ACCOUNTS["product"] = prod_pubkey
  82. ACCOUNTS["price"] = price_pubkey
  83. readiness_thread.start()
  84. http_service.start()
  85. while True:
  86. publisher_random_update(price_pubkey)
  87. time.sleep(PYTH_PUBLISHER_INTERVAL)
  88. sys.stdout.flush()
  89. readiness_thread.join()
  90. http_service.join()