diff --git a/examples/grpc_client.py b/examples/grpc_client.py new file mode 100644 index 00000000..9c02dbf2 --- /dev/null +++ b/examples/grpc_client.py @@ -0,0 +1,90 @@ +import asyncio +import os + +from anchorpy.provider import Provider, Wallet +from dotenv import load_dotenv +from solana.rpc.async_api import AsyncClient +from solana.rpc.commitment import Commitment +from solders.keypair import Keypair + +from driftpy.drift_client import AccountSubscriptionConfig, DriftClient +from driftpy.types import GrpcConfig + +load_dotenv() + +RED = "\033[91m" +GREEN = "\033[92m" +RESET = "\033[0m" + +CLEAR_SCREEN = "\033c" + + +async def watch_drift_markets(): + rpc_fqdn = os.environ.get("RPC_FQDN") + x_token = os.environ.get("X_TOKEN") + private_key = os.environ.get("PRIVATE_KEY") + rpc_url = os.environ.get("RPC_TRITON") + + if not (rpc_fqdn and x_token and private_key and rpc_url): + raise ValueError("RPC_FQDN, X_TOKEN, PRIVATE_KEY, and RPC_TRITON must be set") + + wallet = Wallet(Keypair.from_base58_string(private_key)) + connection = AsyncClient(rpc_url) + provider = Provider(connection, wallet) + + drift_client = DriftClient( + provider.connection, + provider.wallet, + "mainnet", + account_subscription=AccountSubscriptionConfig( + "grpc", + grpc_config=GrpcConfig( + endpoint=rpc_fqdn, + token=x_token, + commitment=Commitment("confirmed"), + ), + ), + ) + + await drift_client.subscribe() + print("Subscribed via gRPC. Listening for market updates...") + + previous_prices = {} + + while True: + print(CLEAR_SCREEN, end="") + + perp_markets = drift_client.get_perp_market_accounts() + + if not perp_markets: + print(f"{RED}No perp markets found (yet){RESET}") + else: + print("Drift Perp Markets (gRPC subscription)\n") + perp_markets.sort(key=lambda x: x.market_index) + for market in perp_markets[:20]: + market_index = market.market_index + last_price = market.amm.historical_oracle_data.last_oracle_price / 1e6 + + if market_index in previous_prices: + old_price = previous_prices[market_index] + if last_price > old_price: + color = GREEN + elif last_price < old_price: + color = RED + else: + color = RESET + else: + color = RESET + + print( + f"Market Index: {market_index} | " + f"Price: {color}${last_price:.4f}{RESET}" + ) + + previous_prices[market_index] = last_price + + await asyncio.sleep(1) + + +if __name__ == "__main__": + asyncio.run(watch_drift_markets()) diff --git a/poetry.lock b/poetry.lock index 80684716..a3ae958f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -258,13 +258,13 @@ graphql = ["graphql-core (>=3.0.0)"] [[package]] name = "async-timeout" -version = "4.0.2" +version = "4.0.3" description = "Timeout context manager for asyncio programs" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, - {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, + {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, + {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, ] [[package]] @@ -535,13 +535,13 @@ unicode-backport = ["unicodedata2"] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -587,20 +587,20 @@ construct = "2.10.68" [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dnspython" @@ -763,61 +763,70 @@ dev = ["flake8", "markdown", "twine", "wheel"] [[package]] name = "grpcio" -version = "1.65.1" +version = "1.68.1" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.8" files = [ - {file = "grpcio-1.65.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:3dc5f928815b8972fb83b78d8db5039559f39e004ec93ebac316403fe031a062"}, - {file = "grpcio-1.65.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:8333ca46053c35484c9f2f7e8d8ec98c1383a8675a449163cea31a2076d93de8"}, - {file = "grpcio-1.65.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:7af64838b6e615fff0ec711960ed9b6ee83086edfa8c32670eafb736f169d719"}, - {file = "grpcio-1.65.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbb64b4166362d9326f7efbf75b1c72106c1aa87f13a8c8b56a1224fac152f5c"}, - {file = "grpcio-1.65.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8422dc13ad93ec8caa2612b5032a2b9cd6421c13ed87f54db4a3a2c93afaf77"}, - {file = "grpcio-1.65.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4effc0562b6c65d4add6a873ca132e46ba5e5a46f07c93502c37a9ae7f043857"}, - {file = "grpcio-1.65.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a6c71575a2fedf259724981fd73a18906513d2f306169c46262a5bae956e6364"}, - {file = "grpcio-1.65.1-cp310-cp310-win32.whl", hash = "sha256:34966cf526ef0ea616e008d40d989463e3db157abb213b2f20c6ce0ae7928875"}, - {file = "grpcio-1.65.1-cp310-cp310-win_amd64.whl", hash = "sha256:ca931de5dd6d9eb94ff19a2c9434b23923bce6f767179fef04dfa991f282eaad"}, - {file = "grpcio-1.65.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:bbb46330cc643ecf10bd9bd4ca8e7419a14b6b9dedd05f671c90fb2c813c6037"}, - {file = "grpcio-1.65.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d827a6fb9215b961eb73459ad7977edb9e748b23e3407d21c845d1d8ef6597e5"}, - {file = "grpcio-1.65.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:6e71aed8835f8d9fbcb84babc93a9da95955d1685021cceb7089f4f1e717d719"}, - {file = "grpcio-1.65.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a1c84560b3b2d34695c9ba53ab0264e2802721c530678a8f0a227951f453462"}, - {file = "grpcio-1.65.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27adee2338d697e71143ed147fe286c05810965d5d30ec14dd09c22479bfe48a"}, - {file = "grpcio-1.65.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f62652ddcadc75d0e7aa629e96bb61658f85a993e748333715b4ab667192e4e8"}, - {file = "grpcio-1.65.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:71a05fd814700dd9cb7d9a507f2f6a1ef85866733ccaf557eedacec32d65e4c2"}, - {file = "grpcio-1.65.1-cp311-cp311-win32.whl", hash = "sha256:b590f1ad056294dfaeac0b7e1b71d3d5ace638d8dd1f1147ce4bd13458783ba8"}, - {file = "grpcio-1.65.1-cp311-cp311-win_amd64.whl", hash = "sha256:12e9bdf3b5fd48e5fbe5b3da382ad8f97c08b47969f3cca81dd9b36b86ed39e2"}, - {file = "grpcio-1.65.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:54cb822e177374b318b233e54b6856c692c24cdbd5a3ba5335f18a47396bac8f"}, - {file = "grpcio-1.65.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:aaf3c54419a28d45bd1681372029f40e5bfb58e5265e3882eaf21e4a5f81a119"}, - {file = "grpcio-1.65.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:557de35bdfbe8bafea0a003dbd0f4da6d89223ac6c4c7549d78e20f92ead95d9"}, - {file = "grpcio-1.65.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8bfd95ef3b097f0cc86ade54eafefa1c8ed623aa01a26fbbdcd1a3650494dd11"}, - {file = "grpcio-1.65.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e6a8f3d6c41e6b642870afe6cafbaf7b61c57317f9ec66d0efdaf19db992b90"}, - {file = "grpcio-1.65.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1faaf7355ceed07ceaef0b9dcefa4c98daf1dd8840ed75c2de128c3f4a4d859d"}, - {file = "grpcio-1.65.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:60f1f38eed830488ad2a1b11579ef0f345ff16fffdad1d24d9fbc97ba31804ff"}, - {file = "grpcio-1.65.1-cp312-cp312-win32.whl", hash = "sha256:e75acfa52daf5ea0712e8aa82f0003bba964de7ae22c26d208cbd7bc08500177"}, - {file = "grpcio-1.65.1-cp312-cp312-win_amd64.whl", hash = "sha256:ff5a84907e51924973aa05ed8759210d8cdae7ffcf9e44fd17646cf4a902df59"}, - {file = "grpcio-1.65.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:1fbd6331f18c3acd7e09d17fd840c096f56eaf0ef830fbd50af45ae9dc8dfd83"}, - {file = "grpcio-1.65.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:de5b6be29116e094c5ef9d9e4252e7eb143e3d5f6bd6d50a78075553ab4930b0"}, - {file = "grpcio-1.65.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:e4a3cdba62b2d6aeae6027ae65f350de6dc082b72e6215eccf82628e79efe9ba"}, - {file = "grpcio-1.65.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:941c4869aa229d88706b78187d60d66aca77fe5c32518b79e3c3e03fc26109a2"}, - {file = "grpcio-1.65.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f40cebe5edb518d78b8131e87cb83b3ee688984de38a232024b9b44e74ee53d3"}, - {file = "grpcio-1.65.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2ca684ba331fb249d8a1ce88db5394e70dbcd96e58d8c4b7e0d7b141a453dce9"}, - {file = "grpcio-1.65.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8558f0083ddaf5de64a59c790bffd7568e353914c0c551eae2955f54ee4b857f"}, - {file = "grpcio-1.65.1-cp38-cp38-win32.whl", hash = "sha256:8d8143a3e3966f85dce6c5cc45387ec36552174ba5712c5dc6fcc0898fb324c0"}, - {file = "grpcio-1.65.1-cp38-cp38-win_amd64.whl", hash = "sha256:76e81a86424d6ca1ce7c16b15bdd6a964a42b40544bf796a48da241fdaf61153"}, - {file = "grpcio-1.65.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:cb5175f45c980ff418998723ea1b3869cce3766d2ab4e4916fbd3cedbc9d0ed3"}, - {file = "grpcio-1.65.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b12c1aa7b95abe73b3e04e052c8b362655b41c7798da69f1eaf8d186c7d204df"}, - {file = "grpcio-1.65.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:3019fb50128b21a5e018d89569ffaaaa361680e1346c2f261bb84a91082eb3d3"}, - {file = "grpcio-1.65.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ae15275ed98ea267f64ee9ddedf8ecd5306a5b5bb87972a48bfe24af24153e8"}, - {file = "grpcio-1.65.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f096ffb881f37e8d4f958b63c74bfc400c7cebd7a944b027357cd2fb8d91a57"}, - {file = "grpcio-1.65.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2f56b5a68fdcf17a0a1d524bf177218c3c69b3947cb239ea222c6f1867c3ab68"}, - {file = "grpcio-1.65.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:941596d419b9736ab548aa0feb5bbba922f98872668847bf0720b42d1d227b9e"}, - {file = "grpcio-1.65.1-cp39-cp39-win32.whl", hash = "sha256:5fd7337a823b890215f07d429f4f193d24b80d62a5485cf88ee06648591a0c57"}, - {file = "grpcio-1.65.1-cp39-cp39-win_amd64.whl", hash = "sha256:1bceeec568372cbebf554eae1b436b06c2ff24cfaf04afade729fb9035408c6c"}, - {file = "grpcio-1.65.1.tar.gz", hash = "sha256:3c492301988cd720cd145d84e17318d45af342e29ef93141228f9cd73222368b"}, + {file = "grpcio-1.68.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:d35740e3f45f60f3c37b1e6f2f4702c23867b9ce21c6410254c9c682237da68d"}, + {file = "grpcio-1.68.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:d99abcd61760ebb34bdff37e5a3ba333c5cc09feda8c1ad42547bea0416ada78"}, + {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:f8261fa2a5f679abeb2a0a93ad056d765cdca1c47745eda3f2d87f874ff4b8c9"}, + {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0feb02205a27caca128627bd1df4ee7212db051019a9afa76f4bb6a1a80ca95e"}, + {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:919d7f18f63bcad3a0f81146188e90274fde800a94e35d42ffe9eadf6a9a6330"}, + {file = "grpcio-1.68.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:963cc8d7d79b12c56008aabd8b457f400952dbea8997dd185f155e2f228db079"}, + {file = "grpcio-1.68.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ccf2ebd2de2d6661e2520dae293298a3803a98ebfc099275f113ce1f6c2a80f1"}, + {file = "grpcio-1.68.1-cp310-cp310-win32.whl", hash = "sha256:2cc1fd04af8399971bcd4f43bd98c22d01029ea2e56e69c34daf2bf8470e47f5"}, + {file = "grpcio-1.68.1-cp310-cp310-win_amd64.whl", hash = "sha256:ee2e743e51cb964b4975de572aa8fb95b633f496f9fcb5e257893df3be854746"}, + {file = "grpcio-1.68.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:55857c71641064f01ff0541a1776bfe04a59db5558e82897d35a7793e525774c"}, + {file = "grpcio-1.68.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4b177f5547f1b995826ef529d2eef89cca2f830dd8b2c99ffd5fde4da734ba73"}, + {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:3522c77d7e6606d6665ec8d50e867f13f946a4e00c7df46768f1c85089eae515"}, + {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d1fae6bbf0816415b81db1e82fb3bf56f7857273c84dcbe68cbe046e58e1ccd"}, + {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:298ee7f80e26f9483f0b6f94cc0a046caf54400a11b644713bb5b3d8eb387600"}, + {file = "grpcio-1.68.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cbb5780e2e740b6b4f2d208e90453591036ff80c02cc605fea1af8e6fc6b1bbe"}, + {file = "grpcio-1.68.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ddda1aa22495d8acd9dfbafff2866438d12faec4d024ebc2e656784d96328ad0"}, + {file = "grpcio-1.68.1-cp311-cp311-win32.whl", hash = "sha256:b33bd114fa5a83f03ec6b7b262ef9f5cac549d4126f1dc702078767b10c46ed9"}, + {file = "grpcio-1.68.1-cp311-cp311-win_amd64.whl", hash = "sha256:7f20ebec257af55694d8f993e162ddf0d36bd82d4e57f74b31c67b3c6d63d8b2"}, + {file = "grpcio-1.68.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:8829924fffb25386995a31998ccbbeaa7367223e647e0122043dfc485a87c666"}, + {file = "grpcio-1.68.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3aed6544e4d523cd6b3119b0916cef3d15ef2da51e088211e4d1eb91a6c7f4f1"}, + {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:4efac5481c696d5cb124ff1c119a78bddbfdd13fc499e3bc0ca81e95fc573684"}, + {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ab2d912ca39c51f46baf2a0d92aa265aa96b2443266fc50d234fa88bf877d8e"}, + {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c87ce2a97434dffe7327a4071839ab8e8bffd0054cc74cbe971fba98aedd60"}, + {file = "grpcio-1.68.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e4842e4872ae4ae0f5497bf60a0498fa778c192cc7a9e87877abd2814aca9475"}, + {file = "grpcio-1.68.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:255b1635b0ed81e9f91da4fcc8d43b7ea5520090b9a9ad9340d147066d1d3613"}, + {file = "grpcio-1.68.1-cp312-cp312-win32.whl", hash = "sha256:7dfc914cc31c906297b30463dde0b9be48e36939575eaf2a0a22a8096e69afe5"}, + {file = "grpcio-1.68.1-cp312-cp312-win_amd64.whl", hash = "sha256:a0c8ddabef9c8f41617f213e527254c41e8b96ea9d387c632af878d05db9229c"}, + {file = "grpcio-1.68.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:a47faedc9ea2e7a3b6569795c040aae5895a19dde0c728a48d3c5d7995fda385"}, + {file = "grpcio-1.68.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:390eee4225a661c5cd133c09f5da1ee3c84498dc265fd292a6912b65c421c78c"}, + {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:66a24f3d45c33550703f0abb8b656515b0ab777970fa275693a2f6dc8e35f1c1"}, + {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c08079b4934b0bf0a8847f42c197b1d12cba6495a3d43febd7e99ecd1cdc8d54"}, + {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8720c25cd9ac25dd04ee02b69256d0ce35bf8a0f29e20577427355272230965a"}, + {file = "grpcio-1.68.1-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:04cfd68bf4f38f5bb959ee2361a7546916bd9a50f78617a346b3aeb2b42e2161"}, + {file = "grpcio-1.68.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c28848761a6520c5c6071d2904a18d339a796ebe6b800adc8b3f474c5ce3c3ad"}, + {file = "grpcio-1.68.1-cp313-cp313-win32.whl", hash = "sha256:77d65165fc35cff6e954e7fd4229e05ec76102d4406d4576528d3a3635fc6172"}, + {file = "grpcio-1.68.1-cp313-cp313-win_amd64.whl", hash = "sha256:a8040f85dcb9830d8bbb033ae66d272614cec6faceee88d37a88a9bd1a7a704e"}, + {file = "grpcio-1.68.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:eeb38ff04ab6e5756a2aef6ad8d94e89bb4a51ef96e20f45c44ba190fa0bcaad"}, + {file = "grpcio-1.68.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8a3869a6661ec8f81d93f4597da50336718bde9eb13267a699ac7e0a1d6d0bea"}, + {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:2c4cec6177bf325eb6faa6bd834d2ff6aa8bb3b29012cceb4937b86f8b74323c"}, + {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12941d533f3cd45d46f202e3667be8ebf6bcb3573629c7ec12c3e211d99cfccf"}, + {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80af6f1e69c5e68a2be529990684abdd31ed6622e988bf18850075c81bb1ad6e"}, + {file = "grpcio-1.68.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e8dbe3e00771bfe3d04feed8210fc6617006d06d9a2679b74605b9fed3e8362c"}, + {file = "grpcio-1.68.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:83bbf5807dc3ee94ce1de2dfe8a356e1d74101e4b9d7aa8c720cc4818a34aded"}, + {file = "grpcio-1.68.1-cp38-cp38-win32.whl", hash = "sha256:8cb620037a2fd9eeee97b4531880e439ebfcd6d7d78f2e7dcc3726428ab5ef63"}, + {file = "grpcio-1.68.1-cp38-cp38-win_amd64.whl", hash = "sha256:52fbf85aa71263380d330f4fce9f013c0798242e31ede05fcee7fbe40ccfc20d"}, + {file = "grpcio-1.68.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:cb400138e73969eb5e0535d1d06cae6a6f7a15f2cc74add320e2130b8179211a"}, + {file = "grpcio-1.68.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a1b988b40f2fd9de5c820f3a701a43339d8dcf2cb2f1ca137e2c02671cc83ac1"}, + {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:96f473cdacfdd506008a5d7579c9f6a7ff245a9ade92c3c0265eb76cc591914f"}, + {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:37ea3be171f3cf3e7b7e412a98b77685eba9d4fd67421f4a34686a63a65d99f9"}, + {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ceb56c4285754e33bb3c2fa777d055e96e6932351a3082ce3559be47f8024f0"}, + {file = "grpcio-1.68.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:dffd29a2961f3263a16d73945b57cd44a8fd0b235740cb14056f0612329b345e"}, + {file = "grpcio-1.68.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:025f790c056815b3bf53da850dd70ebb849fd755a4b1ac822cb65cd631e37d43"}, + {file = "grpcio-1.68.1-cp39-cp39-win32.whl", hash = "sha256:1098f03dedc3b9810810568060dea4ac0822b4062f537b0f53aa015269be0a76"}, + {file = "grpcio-1.68.1-cp39-cp39-win_amd64.whl", hash = "sha256:334ab917792904245a028f10e803fcd5b6f36a7b2173a820c0b5b076555825e1"}, + {file = "grpcio-1.68.1.tar.gz", hash = "sha256:44a8502dd5de653ae6a73e2de50a401d84184f0331d0ac3daeb044e66d5c5054"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.65.1)"] +protobuf = ["grpcio-tools (>=1.68.1)"] [[package]] name = "h11" @@ -898,13 +907,13 @@ files = [ [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -913,23 +922,6 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] -[[package]] -name = "jito-searcher-client" -version = "0.1.4" -description = "Jito Labs Python Searcher Client" -optional = false -python-versions = "<4.0,>=3.10" -files = [ - {file = "jito_searcher_client-0.1.4-py3-none-any.whl", hash = "sha256:51e65778f5519dcdbd9066b9f81130e840e25f63f65176d964efdeae813dd406"}, - {file = "jito_searcher_client-0.1.4.tar.gz", hash = "sha256:498d29aeaa1f520218f5e3859b03a8a0048e96566c13dfa545dbaeb36b57c5fa"}, -] - -[package.dependencies] -click = ">=8.1.3,<9.0.0" -grpcio = ">=1.62.1,<2.0.0" -protobuf = ">=4.25.3,<5.0.0" -solana = "0.34.0" - [[package]] name = "jsonalias" version = "0.1.1" @@ -1010,13 +1002,13 @@ dev = ["Sphinx (>=4.1.1)", "black (>=19.10b0)", "colorama (>=0.3.4)", "docutils [[package]] name = "markdown" -version = "3.6" +version = "3.7" description = "Python implementation of John Gruber's Markdown." optional = false python-versions = ">=3.8" files = [ - {file = "Markdown-3.6-py3-none-any.whl", hash = "sha256:48f276f4d8cfb8ce6527c8f79e2ee29708508bf4d40aa410fbc3b4ee832c850f"}, - {file = "Markdown-3.6.tar.gz", hash = "sha256:ed4f41f6daecbeeb96e576ce414c41d2d876daa9a16cb35fa8ed8c2ddfad0224"}, + {file = "Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803"}, + {file = "markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2"}, ] [package.extras] @@ -1025,71 +1017,72 @@ testing = ["coverage", "pyyaml"] [[package]] name = "markupsafe" -version = "2.1.5" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] @@ -1116,13 +1109,13 @@ files = [ [[package]] name = "mkdocs" -version = "1.6.0" +version = "1.6.1" description = "Project documentation with Markdown." optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs-1.6.0-py3-none-any.whl", hash = "sha256:1eb5cb7676b7d89323e62b56235010216319217d4af5ddc543a91beb8d125ea7"}, - {file = "mkdocs-1.6.0.tar.gz", hash = "sha256:a73f735824ef83a4f3bcb7a231dcab23f5a838f88b7efc54a0eef5fbdbc3c512"}, + {file = "mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e"}, + {file = "mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2"}, ] [package.dependencies] @@ -1146,13 +1139,13 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp [[package]] name = "mkdocs-autorefs" -version = "1.0.1" +version = "1.2.0" description = "Automatically link across pages in MkDocs." optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_autorefs-1.0.1-py3-none-any.whl", hash = "sha256:aacdfae1ab197780fb7a2dac92ad8a3d8f7ca8049a9cbe56a4218cd52e8da570"}, - {file = "mkdocs_autorefs-1.0.1.tar.gz", hash = "sha256:f684edf847eced40b570b57846b15f0bf57fb93ac2c510450775dcf16accb971"}, + {file = "mkdocs_autorefs-1.2.0-py3-none-any.whl", hash = "sha256:d588754ae89bd0ced0c70c06f58566a4ee43471eeeee5202427da7de9ef85a2f"}, + {file = "mkdocs_autorefs-1.2.0.tar.gz", hash = "sha256:a86b93abff653521bda71cf3fc5596342b7a23982093915cb74273f67522190f"}, ] [package.dependencies] @@ -1323,47 +1316,53 @@ files = [ [[package]] name = "mypy" -version = "1.11.0" +version = "1.14.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3824187c99b893f90c845bab405a585d1ced4ff55421fdf5c84cb7710995229"}, - {file = "mypy-1.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:96f8dbc2c85046c81bcddc246232d500ad729cb720da4e20fce3b542cab91287"}, - {file = "mypy-1.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a5d8d8dd8613a3e2be3eae829ee891b6b2de6302f24766ff06cb2875f5be9c6"}, - {file = "mypy-1.11.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:72596a79bbfb195fd41405cffa18210af3811beb91ff946dbcb7368240eed6be"}, - {file = "mypy-1.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:35ce88b8ed3a759634cb4eb646d002c4cef0a38f20565ee82b5023558eb90c00"}, - {file = "mypy-1.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:98790025861cb2c3db8c2f5ad10fc8c336ed2a55f4daf1b8b3f877826b6ff2eb"}, - {file = "mypy-1.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:25bcfa75b9b5a5f8d67147a54ea97ed63a653995a82798221cca2a315c0238c1"}, - {file = "mypy-1.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bea2a0e71c2a375c9fa0ede3d98324214d67b3cbbfcbd55ac8f750f85a414e3"}, - {file = "mypy-1.11.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d2b3d36baac48e40e3064d2901f2fbd2a2d6880ec6ce6358825c85031d7c0d4d"}, - {file = "mypy-1.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:d8e2e43977f0e09f149ea69fd0556623919f816764e26d74da0c8a7b48f3e18a"}, - {file = "mypy-1.11.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1d44c1e44a8be986b54b09f15f2c1a66368eb43861b4e82573026e04c48a9e20"}, - {file = "mypy-1.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cea3d0fb69637944dd321f41bc896e11d0fb0b0aa531d887a6da70f6e7473aba"}, - {file = "mypy-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a83ec98ae12d51c252be61521aa5731f5512231d0b738b4cb2498344f0b840cd"}, - {file = "mypy-1.11.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c7b73a856522417beb78e0fb6d33ef89474e7a622db2653bc1285af36e2e3e3d"}, - {file = "mypy-1.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:f2268d9fcd9686b61ab64f077be7ffbc6fbcdfb4103e5dd0cc5eaab53a8886c2"}, - {file = "mypy-1.11.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:940bfff7283c267ae6522ef926a7887305945f716a7704d3344d6d07f02df850"}, - {file = "mypy-1.11.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:14f9294528b5f5cf96c721f231c9f5b2733164e02c1c018ed1a0eff8a18005ac"}, - {file = "mypy-1.11.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7b54c27783991399046837df5c7c9d325d921394757d09dbcbf96aee4649fe9"}, - {file = "mypy-1.11.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:65f190a6349dec29c8d1a1cd4aa71284177aee5949e0502e6379b42873eddbe7"}, - {file = "mypy-1.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:dbe286303241fea8c2ea5466f6e0e6a046a135a7e7609167b07fd4e7baf151bf"}, - {file = "mypy-1.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:104e9c1620c2675420abd1f6c44bab7dd33cc85aea751c985006e83dcd001095"}, - {file = "mypy-1.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f006e955718ecd8d159cee9932b64fba8f86ee6f7728ca3ac66c3a54b0062abe"}, - {file = "mypy-1.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:becc9111ca572b04e7e77131bc708480cc88a911adf3d0239f974c034b78085c"}, - {file = "mypy-1.11.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6801319fe76c3f3a3833f2b5af7bd2c17bb93c00026a2a1b924e6762f5b19e13"}, - {file = "mypy-1.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:c1a184c64521dc549324ec6ef7cbaa6b351912be9cb5edb803c2808a0d7e85ac"}, - {file = "mypy-1.11.0-py3-none-any.whl", hash = "sha256:56913ec8c7638b0091ef4da6fcc9136896914a9d60d54670a75880c3e5b99ace"}, - {file = "mypy-1.11.0.tar.gz", hash = "sha256:93743608c7348772fdc717af4aeee1997293a1ad04bc0ea6efa15bf65385c538"}, + {file = "mypy-1.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e971c1c667007f9f2b397ffa80fa8e1e0adccff336e5e77e74cb5f22868bee87"}, + {file = "mypy-1.14.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e86aaeaa3221a278c66d3d673b297232947d873773d61ca3ee0e28b2ff027179"}, + {file = "mypy-1.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1628c5c3ce823d296e41e2984ff88c5861499041cb416a8809615d0c1f41740e"}, + {file = "mypy-1.14.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7fadb29b77fc14a0dd81304ed73c828c3e5cde0016c7e668a86a3e0dfc9f3af3"}, + {file = "mypy-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:3fa76988dc760da377c1e5069200a50d9eaaccf34f4ea18428a3337034ab5a44"}, + {file = "mypy-1.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6e73c8a154eed31db3445fe28f63ad2d97b674b911c00191416cf7f6459fd49a"}, + {file = "mypy-1.14.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:273e70fcb2e38c5405a188425aa60b984ffdcef65d6c746ea5813024b68c73dc"}, + {file = "mypy-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1daca283d732943731a6a9f20fdbcaa927f160bc51602b1d4ef880a6fb252015"}, + {file = "mypy-1.14.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7e68047bedb04c1c25bba9901ea46ff60d5eaac2d71b1f2161f33107e2b368eb"}, + {file = "mypy-1.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:7a52f26b9c9b1664a60d87675f3bae00b5c7f2806e0c2800545a32c325920bcc"}, + {file = "mypy-1.14.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d5326ab70a6db8e856d59ad4cb72741124950cbbf32e7b70e30166ba7bbf61dd"}, + {file = "mypy-1.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bf4ec4980bec1e0e24e5075f449d014011527ae0055884c7e3abc6a99cd2c7f1"}, + {file = "mypy-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:390dfb898239c25289495500f12fa73aa7f24a4c6d90ccdc165762462b998d63"}, + {file = "mypy-1.14.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7e026d55ddcd76e29e87865c08cbe2d0104e2b3153a523c529de584759379d3d"}, + {file = "mypy-1.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:585ed36031d0b3ee362e5107ef449a8b5dfd4e9c90ccbe36414ee405ee6b32ba"}, + {file = "mypy-1.14.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9f6f4c0b27401d14c483c622bc5105eff3911634d576bbdf6695b9a7c1ba741"}, + {file = "mypy-1.14.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56b2280cedcb312c7a79f5001ae5325582d0d339bce684e4a529069d0e7ca1e7"}, + {file = "mypy-1.14.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:342de51c48bab326bfc77ce056ba08c076d82ce4f5a86621f972ed39970f94d8"}, + {file = "mypy-1.14.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:00df23b42e533e02a6f0055e54de9a6ed491cd8b7ea738647364fd3a39ea7efc"}, + {file = "mypy-1.14.0-cp313-cp313-win_amd64.whl", hash = "sha256:e8c8387e5d9dff80e7daf961df357c80e694e942d9755f3ad77d69b0957b8e3f"}, + {file = "mypy-1.14.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b16738b1d80ec4334654e89e798eb705ac0c36c8a5c4798496cd3623aa02286"}, + {file = "mypy-1.14.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:10065fcebb7c66df04b05fc799a854b1ae24d9963c8bb27e9064a9bdb43aa8ad"}, + {file = "mypy-1.14.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fbb7d683fa6bdecaa106e8368aa973ecc0ddb79a9eaeb4b821591ecd07e9e03c"}, + {file = "mypy-1.14.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3498cb55448dc5533e438cd13d6ddd28654559c8c4d1fd4b5ca57a31b81bac01"}, + {file = "mypy-1.14.0-cp38-cp38-win_amd64.whl", hash = "sha256:c7b243408ea43755f3a21a0a08e5c5ae30eddb4c58a80f415ca6b118816e60aa"}, + {file = "mypy-1.14.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:14117b9da3305b39860d0aa34b8f1ff74d209a368829a584eb77524389a9c13e"}, + {file = "mypy-1.14.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:af98c5a958f9c37404bd4eef2f920b94874507e146ed6ee559f185b8809c44cc"}, + {file = "mypy-1.14.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0b343a1d3989547024377c2ba0dca9c74a2428ad6ed24283c213af8dbb0710b"}, + {file = "mypy-1.14.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cdb5563c1726c85fb201be383168f8c866032db95e1095600806625b3a648cb7"}, + {file = "mypy-1.14.0-cp39-cp39-win_amd64.whl", hash = "sha256:74e925649c1ee0a79aa7448baf2668d81cc287dc5782cff6a04ee93f40fb8d3f"}, + {file = "mypy-1.14.0-py3-none-any.whl", hash = "sha256:2238d7f93fc4027ed1efc944507683df3ba406445a2b6c96e79666a045aadfab"}, + {file = "mypy-1.14.0.tar.gz", hash = "sha256:822dbd184d4a9804df5a7d5335a68cf7662930e70b8c1bc976645d1509f9a9d6"}, ] [package.dependencies] -mypy-extensions = ">=1.0.0" +mypy_extensions = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = ">=4.6.0" +typing_extensions = ">=4.6.0" [package.extras] dmypy = ["psutil (>=4.0)"] +faster-cache = ["orjson"] install-types = ["pip"] mypyc = ["setuptools (>=50)"] reports = ["lxml"] @@ -1462,19 +1461,19 @@ files = [ [[package]] name = "platformdirs" -version = "4.2.2" +version = "4.3.6" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, - {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] [[package]] name = "pluggy" @@ -1493,22 +1492,22 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "protobuf" -version = "4.25.4" +version = "5.29.2" description = "" optional = false python-versions = ">=3.8" files = [ - {file = "protobuf-4.25.4-cp310-abi3-win32.whl", hash = "sha256:db9fd45183e1a67722cafa5c1da3e85c6492a5383f127c86c4c4aa4845867dc4"}, - {file = "protobuf-4.25.4-cp310-abi3-win_amd64.whl", hash = "sha256:ba3d8504116a921af46499471c63a85260c1a5fc23333154a427a310e015d26d"}, - {file = "protobuf-4.25.4-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:eecd41bfc0e4b1bd3fa7909ed93dd14dd5567b98c941d6c1ad08fdcab3d6884b"}, - {file = "protobuf-4.25.4-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:4c8a70fdcb995dcf6c8966cfa3a29101916f7225e9afe3ced4395359955d3835"}, - {file = "protobuf-4.25.4-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:3319e073562e2515c6ddc643eb92ce20809f5d8f10fead3332f71c63be6a7040"}, - {file = "protobuf-4.25.4-cp38-cp38-win32.whl", hash = "sha256:7e372cbbda66a63ebca18f8ffaa6948455dfecc4e9c1029312f6c2edcd86c4e1"}, - {file = "protobuf-4.25.4-cp38-cp38-win_amd64.whl", hash = "sha256:051e97ce9fa6067a4546e75cb14f90cf0232dcb3e3d508c448b8d0e4265b61c1"}, - {file = "protobuf-4.25.4-cp39-cp39-win32.whl", hash = "sha256:90bf6fd378494eb698805bbbe7afe6c5d12c8e17fca817a646cd6a1818c696ca"}, - {file = "protobuf-4.25.4-cp39-cp39-win_amd64.whl", hash = "sha256:ac79a48d6b99dfed2729ccccee547b34a1d3d63289c71cef056653a846a2240f"}, - {file = "protobuf-4.25.4-py3-none-any.whl", hash = "sha256:bfbebc1c8e4793cfd58589acfb8a1026be0003e852b9da7db5a4285bde996978"}, - {file = "protobuf-4.25.4.tar.gz", hash = "sha256:0dc4a62cc4052a036ee2204d26fe4d835c62827c855c8a03f29fe6da146b380d"}, + {file = "protobuf-5.29.2-cp310-abi3-win32.whl", hash = "sha256:c12ba8249f5624300cf51c3d0bfe5be71a60c63e4dcf51ffe9a68771d958c851"}, + {file = "protobuf-5.29.2-cp310-abi3-win_amd64.whl", hash = "sha256:842de6d9241134a973aab719ab42b008a18a90f9f07f06ba480df268f86432f9"}, + {file = "protobuf-5.29.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a0c53d78383c851bfa97eb42e3703aefdc96d2036a41482ffd55dc5f529466eb"}, + {file = "protobuf-5.29.2-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:494229ecd8c9009dd71eda5fd57528395d1eacdf307dbece6c12ad0dd09e912e"}, + {file = "protobuf-5.29.2-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:b6b0d416bbbb9d4fbf9d0561dbfc4e324fd522f61f7af0fe0f282ab67b22477e"}, + {file = "protobuf-5.29.2-cp38-cp38-win32.whl", hash = "sha256:e621a98c0201a7c8afe89d9646859859be97cb22b8bf1d8eacfd90d5bda2eb19"}, + {file = "protobuf-5.29.2-cp38-cp38-win_amd64.whl", hash = "sha256:13d6d617a2a9e0e82a88113d7191a1baa1e42c2cc6f5f1398d3b054c8e7e714a"}, + {file = "protobuf-5.29.2-cp39-cp39-win32.whl", hash = "sha256:36000f97ea1e76e8398a3f02936aac2a5d2b111aae9920ec1b769fc4a222c4d9"}, + {file = "protobuf-5.29.2-cp39-cp39-win_amd64.whl", hash = "sha256:2d2e674c58a06311c8e99e74be43e7f3a8d1e2b2fdf845eaa347fbd866f23355"}, + {file = "protobuf-5.29.2-py3-none-any.whl", hash = "sha256:fde4554c0e578a5a0bcc9a276339594848d1e89f9ea47b4427c80e5d72f90181"}, + {file = "protobuf-5.29.2.tar.gz", hash = "sha256:b2cc8e8bb7c9326996f0e160137b0861f1a82162502658df2951209d0cb0309e"}, ] [[package]] @@ -1689,13 +1688,13 @@ files = [ [[package]] name = "pymdown-extensions" -version = "10.8.1" +version = "10.13" description = "Extension pack for Python Markdown." optional = false python-versions = ">=3.8" files = [ - {file = "pymdown_extensions-10.8.1-py3-none-any.whl", hash = "sha256:f938326115884f48c6059c67377c46cf631c733ef3629b6eed1349989d1b30cb"}, - {file = "pymdown_extensions-10.8.1.tar.gz", hash = "sha256:3ab1db5c9e21728dabf75192d71471f8e50f216627e9a1fa9535ecb0231b9940"}, + {file = "pymdown_extensions-10.13-py3-none-any.whl", hash = "sha256:80bc33d715eec68e683e04298946d47d78c7739e79d808203df278ee8ef89428"}, + {file = "pymdown_extensions-10.13.tar.gz", hash = "sha256:e0b351494dc0d8d14a1f52b39b1499a00ef1566b4ba23dc74f1eba75c736f5dd"}, ] [package.dependencies] @@ -1829,15 +1828,29 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "python-dotenv" +version = "1.0.1" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, + {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + [[package]] name = "pytkdocs" -version = "0.16.1" +version = "0.16.2" description = "Load Python objects documentation." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pytkdocs-0.16.1-py3-none-any.whl", hash = "sha256:a8c3f46ecef0b92864cc598e9101e9c4cf832ebbf228f50c84aa5dd850aac379"}, - {file = "pytkdocs-0.16.1.tar.gz", hash = "sha256:e2ccf6dfe9dbbceb09818673f040f1a7c32ed0bffb2d709b06be6453c4026045"}, + {file = "pytkdocs-0.16.2-py3-none-any.whl", hash = "sha256:36450316d004f6399402d044f122f28f88ff4a069899d10de3d28ad6b4ba5799"}, + {file = "pytkdocs-0.16.2.tar.gz", hash = "sha256:e75538a34932996b8803fbad4e4f6851fc0e9fd9aea86fc6602d6582c12098f3"}, ] [package.extras] @@ -1845,62 +1858,64 @@ numpy-style = ["docstring_parser (>=0.7)"] [[package]] name = "pyyaml" -version = "6.0.1" +version = "6.0.2" description = "YAML parser and emitter for Python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] [[package]] @@ -1955,15 +1970,42 @@ idna = {version = "*", optional = true, markers = "extra == \"idna2008\""} [package.extras] idna2008 = ["idna"] +[[package]] +name = "ruff" +version = "0.8.4" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.8.4-py3-none-linux_armv6l.whl", hash = "sha256:58072f0c06080276804c6a4e21a9045a706584a958e644353603d36ca1eb8a60"}, + {file = "ruff-0.8.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ffb60904651c00a1e0b8df594591770018a0f04587f7deeb3838344fe3adabac"}, + {file = "ruff-0.8.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6ddf5d654ac0d44389f6bf05cee4caeefc3132a64b58ea46738111d687352296"}, + {file = "ruff-0.8.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e248b1f0fa2749edd3350a2a342b67b43a2627434c059a063418e3d375cfe643"}, + {file = "ruff-0.8.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf197b98ed86e417412ee3b6c893f44c8864f816451441483253d5ff22c0e81e"}, + {file = "ruff-0.8.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c41319b85faa3aadd4d30cb1cffdd9ac6b89704ff79f7664b853785b48eccdf3"}, + {file = "ruff-0.8.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9f8402b7c4f96463f135e936d9ab77b65711fcd5d72e5d67597b543bbb43cf3f"}, + {file = "ruff-0.8.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4e56b3baa9c23d324ead112a4fdf20db9a3f8f29eeabff1355114dd96014604"}, + {file = "ruff-0.8.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:736272574e97157f7edbbb43b1d046125fce9e7d8d583d5d65d0c9bf2c15addf"}, + {file = "ruff-0.8.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5fe710ab6061592521f902fca7ebcb9fabd27bc7c57c764298b1c1f15fff720"}, + {file = "ruff-0.8.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:13e9ec6d6b55f6da412d59953d65d66e760d583dd3c1c72bf1f26435b5bfdbae"}, + {file = "ruff-0.8.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:97d9aefef725348ad77d6db98b726cfdb075a40b936c7984088804dfd38268a7"}, + {file = "ruff-0.8.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ab78e33325a6f5374e04c2ab924a3367d69a0da36f8c9cb6b894a62017506111"}, + {file = "ruff-0.8.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:8ef06f66f4a05c3ddbc9121a8b0cecccd92c5bf3dd43b5472ffe40b8ca10f0f8"}, + {file = "ruff-0.8.4-py3-none-win32.whl", hash = "sha256:552fb6d861320958ca5e15f28b20a3d071aa83b93caee33a87b471f99a6c0835"}, + {file = "ruff-0.8.4-py3-none-win_amd64.whl", hash = "sha256:f21a1143776f8656d7f364bd264a9d60f01b7f52243fbe90e7670c0dfe0cf65d"}, + {file = "ruff-0.8.4-py3-none-win_arm64.whl", hash = "sha256:9183dd615d8df50defa8b1d9a074053891ba39025cf5ae88e8bcb52edcc4bf08"}, + {file = "ruff-0.8.4.tar.gz", hash = "sha256:0d5f89f254836799af1615798caa5f80b7f935d7a670fad66c5007928e57ace8"}, +] + [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -2129,43 +2171,41 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "watchdog" -version = "4.0.1" +version = "6.0.0" description = "Filesystem events monitoring" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "watchdog-4.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:da2dfdaa8006eb6a71051795856bedd97e5b03e57da96f98e375682c48850645"}, - {file = "watchdog-4.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e93f451f2dfa433d97765ca2634628b789b49ba8b504fdde5837cdcf25fdb53b"}, - {file = "watchdog-4.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ef0107bbb6a55f5be727cfc2ef945d5676b97bffb8425650dadbb184be9f9a2b"}, - {file = "watchdog-4.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:17e32f147d8bf9657e0922c0940bcde863b894cd871dbb694beb6704cfbd2fb5"}, - {file = "watchdog-4.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:03e70d2df2258fb6cb0e95bbdbe06c16e608af94a3ffbd2b90c3f1e83eb10767"}, - {file = "watchdog-4.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:123587af84260c991dc5f62a6e7ef3d1c57dfddc99faacee508c71d287248459"}, - {file = "watchdog-4.0.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:093b23e6906a8b97051191a4a0c73a77ecc958121d42346274c6af6520dec175"}, - {file = "watchdog-4.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:611be3904f9843f0529c35a3ff3fd617449463cb4b73b1633950b3d97fa4bfb7"}, - {file = "watchdog-4.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:62c613ad689ddcb11707f030e722fa929f322ef7e4f18f5335d2b73c61a85c28"}, - {file = "watchdog-4.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:d4925e4bf7b9bddd1c3de13c9b8a2cdb89a468f640e66fbfabaf735bd85b3e35"}, - {file = "watchdog-4.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cad0bbd66cd59fc474b4a4376bc5ac3fc698723510cbb64091c2a793b18654db"}, - {file = "watchdog-4.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a3c2c317a8fb53e5b3d25790553796105501a235343f5d2bf23bb8649c2c8709"}, - {file = "watchdog-4.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c9904904b6564d4ee8a1ed820db76185a3c96e05560c776c79a6ce5ab71888ba"}, - {file = "watchdog-4.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:667f3c579e813fcbad1b784db7a1aaa96524bed53437e119f6a2f5de4db04235"}, - {file = "watchdog-4.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d10a681c9a1d5a77e75c48a3b8e1a9f2ae2928eda463e8d33660437705659682"}, - {file = "watchdog-4.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0144c0ea9997b92615af1d94afc0c217e07ce2c14912c7b1a5731776329fcfc7"}, - {file = "watchdog-4.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:998d2be6976a0ee3a81fb8e2777900c28641fb5bfbd0c84717d89bca0addcdc5"}, - {file = "watchdog-4.0.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e7921319fe4430b11278d924ef66d4daa469fafb1da679a2e48c935fa27af193"}, - {file = "watchdog-4.0.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:f0de0f284248ab40188f23380b03b59126d1479cd59940f2a34f8852db710625"}, - {file = "watchdog-4.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bca36be5707e81b9e6ce3208d92d95540d4ca244c006b61511753583c81c70dd"}, - {file = "watchdog-4.0.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ab998f567ebdf6b1da7dc1e5accfaa7c6992244629c0fdaef062f43249bd8dee"}, - {file = "watchdog-4.0.1-py3-none-manylinux2014_aarch64.whl", hash = "sha256:dddba7ca1c807045323b6af4ff80f5ddc4d654c8bce8317dde1bd96b128ed253"}, - {file = "watchdog-4.0.1-py3-none-manylinux2014_armv7l.whl", hash = "sha256:4513ec234c68b14d4161440e07f995f231be21a09329051e67a2118a7a612d2d"}, - {file = "watchdog-4.0.1-py3-none-manylinux2014_i686.whl", hash = "sha256:4107ac5ab936a63952dea2a46a734a23230aa2f6f9db1291bf171dac3ebd53c6"}, - {file = "watchdog-4.0.1-py3-none-manylinux2014_ppc64.whl", hash = "sha256:6e8c70d2cd745daec2a08734d9f63092b793ad97612470a0ee4cbb8f5f705c57"}, - {file = "watchdog-4.0.1-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:f27279d060e2ab24c0aa98363ff906d2386aa6c4dc2f1a374655d4e02a6c5e5e"}, - {file = "watchdog-4.0.1-py3-none-manylinux2014_s390x.whl", hash = "sha256:f8affdf3c0f0466e69f5b3917cdd042f89c8c63aebdb9f7c078996f607cdb0f5"}, - {file = "watchdog-4.0.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:ac7041b385f04c047fcc2951dc001671dee1b7e0615cde772e84b01fbf68ee84"}, - {file = "watchdog-4.0.1-py3-none-win32.whl", hash = "sha256:206afc3d964f9a233e6ad34618ec60b9837d0582b500b63687e34011e15bb429"}, - {file = "watchdog-4.0.1-py3-none-win_amd64.whl", hash = "sha256:7577b3c43e5909623149f76b099ac49a1a01ca4e167d1785c76eb52fa585745a"}, - {file = "watchdog-4.0.1-py3-none-win_ia64.whl", hash = "sha256:d7b9f5f3299e8dd230880b6c55504a1f69cf1e4316275d1b215ebdd8187ec88d"}, - {file = "watchdog-4.0.1.tar.gz", hash = "sha256:eebaacf674fa25511e8867028d281e602ee6500045b57f43b08778082f7f8b44"}, + {file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26"}, + {file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112"}, + {file = "watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3"}, + {file = "watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c"}, + {file = "watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2"}, + {file = "watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c"}, + {file = "watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948"}, + {file = "watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860"}, + {file = "watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0"}, + {file = "watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c"}, + {file = "watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134"}, + {file = "watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b"}, + {file = "watchdog-6.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e6f0e77c9417e7cd62af82529b10563db3423625c5fce018430b249bf977f9e8"}, + {file = "watchdog-6.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:90c8e78f3b94014f7aaae121e6b909674df5b46ec24d6bebc45c44c56729af2a"}, + {file = "watchdog-6.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e7631a77ffb1f7d2eefa4445ebbee491c720a5661ddf6df3498ebecae5ed375c"}, + {file = "watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881"}, + {file = "watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11"}, + {file = "watchdog-6.0.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7a0e56874cfbc4b9b05c60c8a1926fedf56324bb08cfbc188969777940aef3aa"}, + {file = "watchdog-6.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6439e374fc012255b4ec786ae3c4bc838cd7309a540e5fe0952d03687d8804e"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2"}, + {file = "watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a"}, + {file = "watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680"}, + {file = "watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f"}, + {file = "watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282"}, ] [package.extras] @@ -2251,13 +2291,13 @@ files = [ [[package]] name = "win32-setctime" -version = "1.1.0" +version = "1.2.0" description = "A small Python utility to set file creation time on Windows" optional = false python-versions = ">=3.5" files = [ - {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"}, - {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"}, + {file = "win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390"}, + {file = "win32_setctime-1.2.0.tar.gz", hash = "sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0"}, ] [package.extras] @@ -2265,81 +2305,76 @@ dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"] [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [[package]] @@ -2491,4 +2526,4 @@ cffi = ["cffi (>=1.11)"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "7193746daa73f589d96617384b1e9dc9cc3e52893cef0b80c33499f4cd644ea9" +content-hash = "e375aa4100bd07523d0272705c587d76ab359a845f9457a518f38d14c8a30cf9" diff --git a/pyproject.toml b/pyproject.toml index 991f28f5..f13ad95a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -84,7 +84,9 @@ mypy = "^1.7.0" deprecated = "^1.2.14" events = "^0.5" numpy = "^1.26.2" -jito-searcher-client = "0.1.4" +# jito-searcher-client = "0.1.5" +grpcio = "1.68.1" +protobuf = "5.29.2" [tool.poetry.dev-dependencies] pytest = "^7.2.0" @@ -97,6 +99,9 @@ mkdocs-material = "^8.1.8" bump2version = "^1.0.1" autopep8 = "^2.0.4" mypy = "^1.7.0" +python-dotenv = "^1.0.0" +ruff = "^0.8.4" + [tool.poetry.group.dev.dependencies] pytest = "^7.4.4" @@ -111,7 +116,7 @@ build-backend = "poetry.core.masonry.api" asyncio_mode = "strict" [tool.ruff] -exclude = [".git", "__pycache__", "docs/source/conf.py", "old", "build", "dist"] +exclude = [".git", "__pycache__", "docs/source/conf.py", "old", "build", "dist", "**/geyser_codegen/**"] [tool.ruff.pycodestyle] max-line-length = 88 diff --git a/src/driftpy/account_subscription_config.py b/src/driftpy/account_subscription_config.py index 4114ca08..2eca382e 100644 --- a/src/driftpy/account_subscription_config.py +++ b/src/driftpy/account_subscription_config.py @@ -13,6 +13,9 @@ DemoDriftClientAccountSubscriber, DemoUserAccountSubscriber, ) +from driftpy.accounts.grpc.account_subscriber import GrpcConfig +from driftpy.accounts.grpc.drift_client import GrpcDriftClientAccountSubscriber +from driftpy.accounts.grpc.user import GrpcUserAccountSubscriber from driftpy.accounts.polling import ( PollingDriftClientAccountSubscriber, PollingUserAccountSubscriber, @@ -32,13 +35,17 @@ def default(): def __init__( self, - account_subscription_type: Literal["polling", "websocket", "cached", "demo"], + account_subscription_type: Literal[ + "polling", "websocket", "cached", "demo", "grpc" + ], bulk_account_loader: Optional[BulkAccountLoader] = None, commitment: Commitment = Commitment("confirmed"), + grpc_config: Optional[GrpcConfig] = None, ): self.type = account_subscription_type self.commitment = commitment self.bulk_account_loader = None + self.grpc_config = grpc_config if self.type != "polling": return @@ -117,6 +124,18 @@ def get_drift_client_subscriber( oracle_infos, self.commitment, ) + case "grpc": + if self.grpc_config is None: + raise ValueError("A grpc config is required for grpc subscription") + return GrpcDriftClientAccountSubscriber( + program, + self.grpc_config, + perp_market_indexes, + spot_market_indexes, + cast(list[FullOracleWrapper], oracle_infos), + should_find_all_markets_and_oracles, + self.commitment, + ) def get_user_client_subscriber(self, program: Program, user_pubkey: Pubkey): match self.type: @@ -138,3 +157,13 @@ def get_user_client_subscriber(self, program: Program, user_pubkey: Pubkey): ) case "demo": return DemoUserAccountSubscriber(user_pubkey, program, self.commitment) + case "grpc": + if self.grpc_config is None: + raise ValueError("A grpc config is required for grpc subscription") + return GrpcUserAccountSubscriber( + grpc_config=self.grpc_config, + account_name="user", + account_public_key=user_pubkey, + program=program, + commitment=self.commitment, + ) diff --git a/src/driftpy/accounts/grpc/account_subscriber.py b/src/driftpy/accounts/grpc/account_subscriber.py new file mode 100644 index 00000000..b0575f38 --- /dev/null +++ b/src/driftpy/accounts/grpc/account_subscriber.py @@ -0,0 +1,155 @@ +import asyncio +import time +from typing import Callable, Optional, TypeVar + +import grpc.aio +from anchorpy.program.core import Program +from solana.rpc.commitment import Commitment +from solders.pubkey import Pubkey + +from driftpy.accounts.grpc.geyser_codegen import geyser_pb2, geyser_pb2_grpc +from driftpy.accounts.types import DataAndSlot +from driftpy.accounts.ws.account_subscriber import WebsocketAccountSubscriber +from driftpy.types import GrpcConfig + +T = TypeVar("T") + + +class TritonAuthMetadataPlugin(grpc.AuthMetadataPlugin): + def __init__(self, x_token: str): + self.x_token = x_token + + def __call__( + self, + context: grpc.AuthMetadataContext, + callback: grpc.AuthMetadataPluginCallback, + ): + metadata = (("x-token", self.x_token),) + callback(metadata, None) + + +class GrpcAccountSubscriber(WebsocketAccountSubscriber[T]): + def __init__( + self, + grpc_config: GrpcConfig, + account_name: str, + program: Program, + account_public_key: Pubkey, + commitment: Commitment = Commitment("confirmed"), + decode: Optional[Callable[[bytes], T]] = None, + initial_data: Optional[DataAndSlot[T]] = None, + ): + super().__init__(account_public_key, program, commitment, decode, initial_data) + self.client = self._create_grpc_client(grpc_config) + self.stream = None + self.listener_id = None + self.account_name = account_name + self.decode = ( + decode if decode is not None else self.program.coder.accounts.decode + ) + + def _create_grpc_client(self, config: GrpcConfig) -> geyser_pb2_grpc.GeyserStub: + auth = TritonAuthMetadataPlugin(config.token) + ssl_creds = grpc.ssl_channel_credentials() + call_creds = grpc.metadata_call_credentials(auth) + combined_creds = grpc.composite_channel_credentials(ssl_creds, call_creds) + + channel = grpc.aio.secure_channel(config.endpoint, credentials=combined_creds) + return geyser_pb2_grpc.GeyserStub(channel) + + async def subscribe(self) -> Optional[asyncio.Task[None]]: + if self.listener_id is not None: + return + + self.task = asyncio.create_task(self._subscribe_grpc()) + return self.task + + async def _subscribe_grpc(self): + """Internal method to handle the gRPC subscription""" + if self.data_and_slot is None: + await self.fetch() + + try: + request_iterator = self._create_subscribe_request() + self.stream = self.client.Subscribe(request_iterator) + await self.stream.wait_for_connection() + + self.listener_id = 1 + + async for update in self.stream: + try: + if update.HasField("ping") or update.HasField("pong"): + continue + + if not update.HasField("account"): + print(f"No account for {self.account_name}") + continue + + slot = int(update.account.slot) + account_info = { + "owner": Pubkey.from_bytes(update.account.account.owner), + "lamports": int(update.account.account.lamports), + "data": bytes(update.account.account.data), + "executable": update.account.account.executable, + "rent_epoch": int(update.account.account.rent_epoch), + } + + if not account_info["data"]: + print(f"No data for {self.account_name}") + continue + + decoded_data = ( + self.decode(account_info["data"]) + if self.decode + else account_info + ) + self.update_data(DataAndSlot(slot, decoded_data)) + + except Exception as e: + print(f"Error processing account data for {self.account_name}: {e}") + break + + except Exception as e: + print(f"Error in gRPC subscription for {self.account_name}: {e}") + if self.stream: + self.stream.cancel() + self.listener_id = None + raise e + + async def _create_subscribe_request(self): + request = geyser_pb2.SubscribeRequest() + account_filter = geyser_pb2.SubscribeRequestFilterAccounts() + account_filter.account.append(str(self.pubkey)) + account_filter.nonempty_txn_signature = True + request.accounts["account_monitor"].CopyFrom(account_filter) + + request.commitment = geyser_pb2.CommitmentLevel.CONFIRMED + if self.commitment == Commitment("finalized"): + request.commitment = geyser_pb2.CommitmentLevel.FINALIZED + if self.commitment == Commitment("processed"): + request.commitment = geyser_pb2.CommitmentLevel.PROCESSED + + yield request + + while True: + await asyncio.sleep(30) + ping_request = geyser_pb2.SubscribeRequest() + ping_request.ping.id = int(time.time()) + yield ping_request + + async def unsubscribe(self) -> None: + if self.listener_id is not None: + try: + if self.stream: + self.stream.cancel() + self.listener_id = None + except Exception as e: + print(f"Error unsubscribing from account {self.account_name}: {e}") + raise e + + def update_data(self, new_data: Optional[DataAndSlot[T]]): + if new_data is None: + return + + if self.data_and_slot is None or new_data.slot >= self.data_and_slot.slot: + self.data_and_slot = new_data diff --git a/src/driftpy/accounts/grpc/drift_client.py b/src/driftpy/accounts/grpc/drift_client.py new file mode 100644 index 00000000..7b4535c8 --- /dev/null +++ b/src/driftpy/accounts/grpc/drift_client.py @@ -0,0 +1,168 @@ +from typing import Sequence + +from anchorpy.program.core import Program +from solana.rpc.commitment import Commitment +from solders.pubkey import Pubkey + +from driftpy.accounts.grpc.account_subscriber import GrpcAccountSubscriber, GrpcConfig +from driftpy.accounts.oracle import get_oracle_decode_fn +from driftpy.accounts.types import FullOracleWrapper +from driftpy.accounts.ws.drift_client import WebsocketDriftClientAccountSubscriber +from driftpy.addresses import ( + get_perp_market_public_key, + get_spot_market_public_key, + get_state_public_key, +) +from driftpy.constants.config import find_all_market_and_oracles +from driftpy.oracles.oracle_id import get_oracle_id +from driftpy.types import ( + OraclePriceData, + PerpMarketAccount, + SpotMarketAccount, + StateAccount, +) + + +class GrpcDriftClientAccountSubscriber(WebsocketDriftClientAccountSubscriber): + def __init__( + self, + program: Program, + grpc_config: GrpcConfig, + perp_market_indexes: Sequence[int], + spot_market_indexes: Sequence[int], + full_oracle_wrappers: Sequence[FullOracleWrapper], + should_find_all_markets_and_oracles: bool, + commitment: Commitment = Commitment("confirmed"), + ): + super().__init__( + program, + perp_market_indexes, + spot_market_indexes, + full_oracle_wrappers, + should_find_all_markets_and_oracles, + commitment, + ) + self.grpc_config = grpc_config + + async def subscribe_to_spot_market(self, market_index: int): + if market_index in self.spot_market_subscribers: + return + + spot_market_public_key = get_spot_market_public_key( + self.program.program_id, market_index + ) + spot_market_subscriber = GrpcAccountSubscriber[SpotMarketAccount]( + self.grpc_config, + f"spot_market_{market_index}", + self.program, + spot_market_public_key, + self.commitment, + ) + await spot_market_subscriber.subscribe() + self.spot_market_subscribers[market_index] = spot_market_subscriber + + async def subscribe_to_perp_market(self, market_index: int): + if market_index in self.perp_market_subscribers: + return + + perp_market_public_key = get_perp_market_public_key( + self.program.program_id, market_index + ) + perp_market_subscriber = GrpcAccountSubscriber[PerpMarketAccount]( + self.grpc_config, + f"perp_market_{market_index}", + self.program, + perp_market_public_key, + self.commitment, + ) + await perp_market_subscriber.subscribe() + self.perp_market_subscribers[market_index] = perp_market_subscriber + + async def subscribe_to_oracle(self, full_oracle_wrapper: FullOracleWrapper): + if full_oracle_wrapper.pubkey == Pubkey.default(): + return + + oracle_id = get_oracle_id( + full_oracle_wrapper.pubkey, + full_oracle_wrapper.oracle_source, + ) + if oracle_id in self.oracle_subscribers: + return + + oracle_subscriber = GrpcAccountSubscriber[OraclePriceData]( + self.grpc_config, + f"oracle_{oracle_id}", + self.program, + full_oracle_wrapper.pubkey, + self.commitment, + decode=get_oracle_decode_fn(full_oracle_wrapper.oracle_source), + initial_data=full_oracle_wrapper.oracle_price_data_and_slot, + ) + + await oracle_subscriber.subscribe() + self.oracle_subscribers[oracle_id] = oracle_subscriber + + async def subscribe(self): + if self.is_subscribed(): + return + + state_public_key = get_state_public_key(self.program.program_id) + self.state_subscriber = GrpcAccountSubscriber[StateAccount]( + self.grpc_config, + "state", + self.program, + state_public_key, + self.commitment, + ) + await self.state_subscriber.subscribe() + + if self.should_find_all_markets_and_oracles: + ( + perp_ds, + spot_ds, + full_oracle_wrappers, + ) = await find_all_market_and_oracles(self.program) + + self.perp_market_indexes = [ + data_and_slot.data.market_index for data_and_slot in perp_ds + ] + self.spot_market_indexes = [ + data_and_slot.data.market_index for data_and_slot in spot_ds + ] + self.full_oracle_wrappers = full_oracle_wrappers + + for full_oracle_wrapper in self.full_oracle_wrappers: + await self.subscribe_to_oracle(full_oracle_wrapper) + + for market_index in self.perp_market_indexes: + await self.subscribe_to_perp_market(market_index) + + for market_index in self.spot_market_indexes: + await self.subscribe_to_spot_market(market_index) + else: + for market_index in self.perp_market_indexes: + await self.subscribe_to_perp_market(market_index) + + for market_index in self.spot_market_indexes: + await self.subscribe_to_spot_market(market_index) + + for full_oracle_wrapper in self.full_oracle_wrappers: + await self.subscribe_to_oracle(full_oracle_wrapper) + + await self._set_perp_oracle_map() + await self._set_spot_oracle_map() + await self.fetch() + + async def unsubscribe(self): + if self.is_subscribed(): + await self.state_subscriber.unsubscribe() + if self.spot_market_map and self.perp_market_map: + await self.spot_market_map.unsubscribe() + await self.perp_market_map.unsubscribe() + else: + for spot_market_subscriber in self.spot_market_subscribers.values(): + await spot_market_subscriber.unsubscribe() + for perp_market_subscriber in self.perp_market_subscribers.values(): + await perp_market_subscriber.unsubscribe() + for oracle_subscriber in self.oracle_subscribers.values(): + await oracle_subscriber.unsubscribe() diff --git a/src/driftpy/accounts/grpc/geyser_codegen/README.md b/src/driftpy/accounts/grpc/geyser_codegen/README.md new file mode 100644 index 00000000..29af1afa --- /dev/null +++ b/src/driftpy/accounts/grpc/geyser_codegen/README.md @@ -0,0 +1,86 @@ +# Note for driftpy: + +These generated `geyser_pb2` files were generated following +the instructions on https://github.com/jito-labs/jito-python/ and committed here. + +Original readme below: + + +# Python example + +## DISCLAIMER + +This example can contains errors or be behind of the latest stable version, please use it only as an example of how your subscription can looks like. If you want well tested production ready example, please check our implementation on Rust. + +
+ +## Instruction + +This Python example uses [grpc.io](https://grpc.io/) library. +It assumes your CA trust store on your machine allows trust the CA from your RPC endpoint. + +## Installation + +Create a virtual environment and install its dependencies: +```bash +$ python -m venv venv +$ . venv/bin/activate +(venv) $ python -m pip install -U pip +(venv) $ python -m pip install -r requirements.txt +``` + +## Launch the helloworld_geyser + +Print the usage: + +```bash +(venv) $ python helloworld_geyser.py --help +Usage: helloworld_geyser.py [OPTIONS] + + Simple program to get the latest solana slot number + +Options: + --rpc-fqdn TEXT Fully Qualified domain name of your RPC endpoint + --x-token TEXT x-token to authenticate each gRPC call + --help Show this message and exit. +``` + +- `rpc-fqdn`: is the fully qualified domain name without the `https://`, such as `index.rpcpool.com`. +- `x-token` : is the x-token to authenticate yourself to the RPC node. + +Here is a full example: + +```bash +(venv) $ python helloworld_geyser.py --rpc-fqdn 'index.rpcpool.com' --x-token '2625ae71-0823-41b3-b3bc-4ff89d762d52' +slot: 264236514 + +``` + +**NOTE**: `2625ae71-0823-41b3-b3bc-4ff89d762d52` is a fake x-token, you need to provide your own token. + +## Generate gRPC service and request signatures + +The library `grpcio` generates the stubs for you. + +From the directory of `helloword_geyser.py` you can generate all the stubs and data types using the following command: + +```bash +(venv) $ python -m grpc_tools.protoc -I../../yellowstone-grpc-proto/proto/ --python_out=. --pyi_out=. --grpc_python_out=. ../../yellowstone-grpc-proto/proto/* +``` + +This will generate: +- geyser_pb2.py +- geyser_pb2.pyi +- geyser_pb2_grpc.py +- solana_storage_pb2.py +- solana_storage_pb2.pyi +- solana_storage_pb2_grpc.py + +Which you can then import into your code. + + +## Useful documentation for grpcio authentication process + +- [secure_channel](https://grpc.github.io/grpc/python/grpc.html#create-client-credentials) + +- [extend auth method via call credentials](https://grpc.io/docs/guides/auth/#extending-grpc-to-support-other-authentication-mechanisms) diff --git a/src/driftpy/accounts/grpc/geyser_codegen/geyser_pb2.py b/src/driftpy/accounts/grpc/geyser_codegen/geyser_pb2.py new file mode 100644 index 00000000..9d8e9670 --- /dev/null +++ b/src/driftpy/accounts/grpc/geyser_codegen/geyser_pb2.py @@ -0,0 +1,142 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: geyser.proto +# Protobuf Python Version: 5.28.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 5, + 28, + 1, + '', + 'geyser.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 +import driftpy.accounts.grpc.geyser_codegen.solana_storage_pb2 as solana__storage__pb2 + +from driftpy.accounts.grpc.geyser_codegen.solana_storage_pb2 import * + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0cgeyser.proto\x12\x06geyser\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x14solana-storage.proto\"\x9c\n\n\x10SubscribeRequest\x12\x38\n\x08\x61\x63\x63ounts\x18\x01 \x03(\x0b\x32&.geyser.SubscribeRequest.AccountsEntry\x12\x32\n\x05slots\x18\x02 \x03(\x0b\x32#.geyser.SubscribeRequest.SlotsEntry\x12@\n\x0ctransactions\x18\x03 \x03(\x0b\x32*.geyser.SubscribeRequest.TransactionsEntry\x12M\n\x13transactions_status\x18\n \x03(\x0b\x32\x30.geyser.SubscribeRequest.TransactionsStatusEntry\x12\x34\n\x06\x62locks\x18\x04 \x03(\x0b\x32$.geyser.SubscribeRequest.BlocksEntry\x12=\n\x0b\x62locks_meta\x18\x05 \x03(\x0b\x32(.geyser.SubscribeRequest.BlocksMetaEntry\x12\x32\n\x05\x65ntry\x18\x08 \x03(\x0b\x32#.geyser.SubscribeRequest.EntryEntry\x12\x30\n\ncommitment\x18\x06 \x01(\x0e\x32\x17.geyser.CommitmentLevelH\x00\x88\x01\x01\x12\x46\n\x13\x61\x63\x63ounts_data_slice\x18\x07 \x03(\x0b\x32).geyser.SubscribeRequestAccountsDataSlice\x12/\n\x04ping\x18\t \x01(\x0b\x32\x1c.geyser.SubscribeRequestPingH\x01\x88\x01\x01\x12\x16\n\tfrom_slot\x18\x0b \x01(\x04H\x02\x88\x01\x01\x1aW\n\rAccountsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x35\n\x05value\x18\x02 \x01(\x0b\x32&.geyser.SubscribeRequestFilterAccounts:\x02\x38\x01\x1aQ\n\nSlotsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x32\n\x05value\x18\x02 \x01(\x0b\x32#.geyser.SubscribeRequestFilterSlots:\x02\x38\x01\x1a_\n\x11TransactionsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x39\n\x05value\x18\x02 \x01(\x0b\x32*.geyser.SubscribeRequestFilterTransactions:\x02\x38\x01\x1a\x65\n\x17TransactionsStatusEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x39\n\x05value\x18\x02 \x01(\x0b\x32*.geyser.SubscribeRequestFilterTransactions:\x02\x38\x01\x1aS\n\x0b\x42locksEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x33\n\x05value\x18\x02 \x01(\x0b\x32$.geyser.SubscribeRequestFilterBlocks:\x02\x38\x01\x1a[\n\x0f\x42locksMetaEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x37\n\x05value\x18\x02 \x01(\x0b\x32(.geyser.SubscribeRequestFilterBlocksMeta:\x02\x38\x01\x1aQ\n\nEntryEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x32\n\x05value\x18\x02 \x01(\x0b\x32#.geyser.SubscribeRequestFilterEntry:\x02\x38\x01\x42\r\n\x0b_commitmentB\x07\n\x05_pingB\x0c\n\n_from_slot\"\xbf\x01\n\x1eSubscribeRequestFilterAccounts\x12\x0f\n\x07\x61\x63\x63ount\x18\x02 \x03(\t\x12\r\n\x05owner\x18\x03 \x03(\t\x12=\n\x07\x66ilters\x18\x04 \x03(\x0b\x32,.geyser.SubscribeRequestFilterAccountsFilter\x12#\n\x16nonempty_txn_signature\x18\x05 \x01(\x08H\x00\x88\x01\x01\x42\x19\n\x17_nonempty_txn_signature\"\xf3\x01\n$SubscribeRequestFilterAccountsFilter\x12\x44\n\x06memcmp\x18\x01 \x01(\x0b\x32\x32.geyser.SubscribeRequestFilterAccountsFilterMemcmpH\x00\x12\x12\n\x08\x64\x61tasize\x18\x02 \x01(\x04H\x00\x12\x1d\n\x13token_account_state\x18\x03 \x01(\x08H\x00\x12H\n\x08lamports\x18\x04 \x01(\x0b\x32\x34.geyser.SubscribeRequestFilterAccountsFilterLamportsH\x00\x42\x08\n\x06\x66ilter\"y\n*SubscribeRequestFilterAccountsFilterMemcmp\x12\x0e\n\x06offset\x18\x01 \x01(\x04\x12\x0f\n\x05\x62ytes\x18\x02 \x01(\x0cH\x00\x12\x10\n\x06\x62\x61se58\x18\x03 \x01(\tH\x00\x12\x10\n\x06\x62\x61se64\x18\x04 \x01(\tH\x00\x42\x06\n\x04\x64\x61ta\"m\n,SubscribeRequestFilterAccountsFilterLamports\x12\x0c\n\x02\x65q\x18\x01 \x01(\x04H\x00\x12\x0c\n\x02ne\x18\x02 \x01(\x04H\x00\x12\x0c\n\x02lt\x18\x03 \x01(\x04H\x00\x12\x0c\n\x02gt\x18\x04 \x01(\x04H\x00\x42\x05\n\x03\x63mp\"Y\n\x1bSubscribeRequestFilterSlots\x12!\n\x14\x66ilter_by_commitment\x18\x01 \x01(\x08H\x00\x88\x01\x01\x42\x17\n\x15_filter_by_commitment\"\xd2\x01\n\"SubscribeRequestFilterTransactions\x12\x11\n\x04vote\x18\x01 \x01(\x08H\x00\x88\x01\x01\x12\x13\n\x06\x66\x61iled\x18\x02 \x01(\x08H\x01\x88\x01\x01\x12\x16\n\tsignature\x18\x05 \x01(\tH\x02\x88\x01\x01\x12\x17\n\x0f\x61\x63\x63ount_include\x18\x03 \x03(\t\x12\x17\n\x0f\x61\x63\x63ount_exclude\x18\x04 \x03(\t\x12\x18\n\x10\x61\x63\x63ount_required\x18\x06 \x03(\tB\x07\n\x05_voteB\t\n\x07_failedB\x0c\n\n_signature\"\xd9\x01\n\x1cSubscribeRequestFilterBlocks\x12\x17\n\x0f\x61\x63\x63ount_include\x18\x01 \x03(\t\x12!\n\x14include_transactions\x18\x02 \x01(\x08H\x00\x88\x01\x01\x12\x1d\n\x10include_accounts\x18\x03 \x01(\x08H\x01\x88\x01\x01\x12\x1c\n\x0finclude_entries\x18\x04 \x01(\x08H\x02\x88\x01\x01\x42\x17\n\x15_include_transactionsB\x13\n\x11_include_accountsB\x12\n\x10_include_entries\"\"\n SubscribeRequestFilterBlocksMeta\"\x1d\n\x1bSubscribeRequestFilterEntry\"C\n!SubscribeRequestAccountsDataSlice\x12\x0e\n\x06offset\x18\x01 \x01(\x04\x12\x0e\n\x06length\x18\x02 \x01(\x04\"\"\n\x14SubscribeRequestPing\x12\n\n\x02id\x18\x01 \x01(\x05\"\xb5\x04\n\x0fSubscribeUpdate\x12\x0f\n\x07\x66ilters\x18\x01 \x03(\t\x12\x31\n\x07\x61\x63\x63ount\x18\x02 \x01(\x0b\x32\x1e.geyser.SubscribeUpdateAccountH\x00\x12+\n\x04slot\x18\x03 \x01(\x0b\x32\x1b.geyser.SubscribeUpdateSlotH\x00\x12\x39\n\x0btransaction\x18\x04 \x01(\x0b\x32\".geyser.SubscribeUpdateTransactionH\x00\x12\x46\n\x12transaction_status\x18\n \x01(\x0b\x32(.geyser.SubscribeUpdateTransactionStatusH\x00\x12-\n\x05\x62lock\x18\x05 \x01(\x0b\x32\x1c.geyser.SubscribeUpdateBlockH\x00\x12+\n\x04ping\x18\x06 \x01(\x0b\x32\x1b.geyser.SubscribeUpdatePingH\x00\x12+\n\x04pong\x18\t \x01(\x0b\x32\x1b.geyser.SubscribeUpdatePongH\x00\x12\x36\n\nblock_meta\x18\x07 \x01(\x0b\x32 .geyser.SubscribeUpdateBlockMetaH\x00\x12-\n\x05\x65ntry\x18\x08 \x01(\x0b\x32\x1c.geyser.SubscribeUpdateEntryH\x00\x12.\n\ncreated_at\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x0e\n\x0cupdate_oneof\"o\n\x16SubscribeUpdateAccount\x12\x33\n\x07\x61\x63\x63ount\x18\x01 \x01(\x0b\x32\".geyser.SubscribeUpdateAccountInfo\x12\x0c\n\x04slot\x18\x02 \x01(\x04\x12\x12\n\nis_startup\x18\x03 \x01(\x08\"\xc8\x01\n\x1aSubscribeUpdateAccountInfo\x12\x0e\n\x06pubkey\x18\x01 \x01(\x0c\x12\x10\n\x08lamports\x18\x02 \x01(\x04\x12\r\n\x05owner\x18\x03 \x01(\x0c\x12\x12\n\nexecutable\x18\x04 \x01(\x08\x12\x12\n\nrent_epoch\x18\x05 \x01(\x04\x12\x0c\n\x04\x64\x61ta\x18\x06 \x01(\x0c\x12\x15\n\rwrite_version\x18\x07 \x01(\x04\x12\x1a\n\rtxn_signature\x18\x08 \x01(\x0cH\x00\x88\x01\x01\x42\x10\n\x0e_txn_signature\"\x94\x01\n\x13SubscribeUpdateSlot\x12\x0c\n\x04slot\x18\x01 \x01(\x04\x12\x13\n\x06parent\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\'\n\x06status\x18\x03 \x01(\x0e\x32\x17.geyser.CommitmentLevel\x12\x17\n\ndead_error\x18\x04 \x01(\tH\x01\x88\x01\x01\x42\t\n\x07_parentB\r\n\x0b_dead_error\"g\n\x1aSubscribeUpdateTransaction\x12;\n\x0btransaction\x18\x01 \x01(\x0b\x32&.geyser.SubscribeUpdateTransactionInfo\x12\x0c\n\x04slot\x18\x02 \x01(\x04\"\xd8\x01\n\x1eSubscribeUpdateTransactionInfo\x12\x11\n\tsignature\x18\x01 \x01(\x0c\x12\x0f\n\x07is_vote\x18\x02 \x01(\x08\x12?\n\x0btransaction\x18\x03 \x01(\x0b\x32*.solana.storage.ConfirmedBlock.Transaction\x12\x42\n\x04meta\x18\x04 \x01(\x0b\x32\x34.solana.storage.ConfirmedBlock.TransactionStatusMeta\x12\r\n\x05index\x18\x05 \x01(\x04\"\xa1\x01\n SubscribeUpdateTransactionStatus\x12\x0c\n\x04slot\x18\x01 \x01(\x04\x12\x11\n\tsignature\x18\x02 \x01(\x0c\x12\x0f\n\x07is_vote\x18\x03 \x01(\x08\x12\r\n\x05index\x18\x04 \x01(\x04\x12<\n\x03\x65rr\x18\x05 \x01(\x0b\x32/.solana.storage.ConfirmedBlock.TransactionError\"\xa0\x04\n\x14SubscribeUpdateBlock\x12\x0c\n\x04slot\x18\x01 \x01(\x04\x12\x11\n\tblockhash\x18\x02 \x01(\t\x12\x37\n\x07rewards\x18\x03 \x01(\x0b\x32&.solana.storage.ConfirmedBlock.Rewards\x12@\n\nblock_time\x18\x04 \x01(\x0b\x32,.solana.storage.ConfirmedBlock.UnixTimestamp\x12@\n\x0c\x62lock_height\x18\x05 \x01(\x0b\x32*.solana.storage.ConfirmedBlock.BlockHeight\x12\x13\n\x0bparent_slot\x18\x07 \x01(\x04\x12\x18\n\x10parent_blockhash\x18\x08 \x01(\t\x12\"\n\x1a\x65xecuted_transaction_count\x18\t \x01(\x04\x12<\n\x0ctransactions\x18\x06 \x03(\x0b\x32&.geyser.SubscribeUpdateTransactionInfo\x12\x1d\n\x15updated_account_count\x18\n \x01(\x04\x12\x34\n\x08\x61\x63\x63ounts\x18\x0b \x03(\x0b\x32\".geyser.SubscribeUpdateAccountInfo\x12\x15\n\rentries_count\x18\x0c \x01(\x04\x12-\n\x07\x65ntries\x18\r \x03(\x0b\x32\x1c.geyser.SubscribeUpdateEntry\"\xe2\x02\n\x18SubscribeUpdateBlockMeta\x12\x0c\n\x04slot\x18\x01 \x01(\x04\x12\x11\n\tblockhash\x18\x02 \x01(\t\x12\x37\n\x07rewards\x18\x03 \x01(\x0b\x32&.solana.storage.ConfirmedBlock.Rewards\x12@\n\nblock_time\x18\x04 \x01(\x0b\x32,.solana.storage.ConfirmedBlock.UnixTimestamp\x12@\n\x0c\x62lock_height\x18\x05 \x01(\x0b\x32*.solana.storage.ConfirmedBlock.BlockHeight\x12\x13\n\x0bparent_slot\x18\x06 \x01(\x04\x12\x18\n\x10parent_blockhash\x18\x07 \x01(\t\x12\"\n\x1a\x65xecuted_transaction_count\x18\x08 \x01(\x04\x12\x15\n\rentries_count\x18\t \x01(\x04\"\x9d\x01\n\x14SubscribeUpdateEntry\x12\x0c\n\x04slot\x18\x01 \x01(\x04\x12\r\n\x05index\x18\x02 \x01(\x04\x12\x12\n\nnum_hashes\x18\x03 \x01(\x04\x12\x0c\n\x04hash\x18\x04 \x01(\x0c\x12\"\n\x1a\x65xecuted_transaction_count\x18\x05 \x01(\x04\x12\"\n\x1astarting_transaction_index\x18\x06 \x01(\x04\"\x15\n\x13SubscribeUpdatePing\"!\n\x13SubscribeUpdatePong\x12\n\n\x02id\x18\x01 \x01(\x05\"\x1c\n\x0bPingRequest\x12\r\n\x05\x63ount\x18\x01 \x01(\x05\"\x1d\n\x0cPongResponse\x12\r\n\x05\x63ount\x18\x01 \x01(\x05\"\\\n\x19GetLatestBlockhashRequest\x12\x30\n\ncommitment\x18\x01 \x01(\x0e\x32\x17.geyser.CommitmentLevelH\x00\x88\x01\x01\x42\r\n\x0b_commitment\"^\n\x1aGetLatestBlockhashResponse\x12\x0c\n\x04slot\x18\x01 \x01(\x04\x12\x11\n\tblockhash\x18\x02 \x01(\t\x12\x1f\n\x17last_valid_block_height\x18\x03 \x01(\x04\"X\n\x15GetBlockHeightRequest\x12\x30\n\ncommitment\x18\x01 \x01(\x0e\x32\x17.geyser.CommitmentLevelH\x00\x88\x01\x01\x42\r\n\x0b_commitment\".\n\x16GetBlockHeightResponse\x12\x14\n\x0c\x62lock_height\x18\x01 \x01(\x04\"Q\n\x0eGetSlotRequest\x12\x30\n\ncommitment\x18\x01 \x01(\x0e\x32\x17.geyser.CommitmentLevelH\x00\x88\x01\x01\x42\r\n\x0b_commitment\"\x1f\n\x0fGetSlotResponse\x12\x0c\n\x04slot\x18\x01 \x01(\x04\"\x13\n\x11GetVersionRequest\"%\n\x12GetVersionResponse\x12\x0f\n\x07version\x18\x01 \x01(\t\"m\n\x17IsBlockhashValidRequest\x12\x11\n\tblockhash\x18\x01 \x01(\t\x12\x30\n\ncommitment\x18\x02 \x01(\x0e\x32\x17.geyser.CommitmentLevelH\x00\x88\x01\x01\x42\r\n\x0b_commitment\"7\n\x18IsBlockhashValidResponse\x12\x0c\n\x04slot\x18\x01 \x01(\x04\x12\r\n\x05valid\x18\x02 \x01(\x08*\x83\x01\n\x0f\x43ommitmentLevel\x12\r\n\tPROCESSED\x10\x00\x12\r\n\tCONFIRMED\x10\x01\x12\r\n\tFINALIZED\x10\x02\x12\x18\n\x14\x46IRST_SHRED_RECEIVED\x10\x03\x12\r\n\tCOMPLETED\x10\x04\x12\x10\n\x0c\x43REATED_BANK\x10\x05\x12\x08\n\x04\x44\x45\x41\x44\x10\x06\x32\x93\x04\n\x06Geyser\x12\x44\n\tSubscribe\x12\x18.geyser.SubscribeRequest\x1a\x17.geyser.SubscribeUpdate\"\x00(\x01\x30\x01\x12\x33\n\x04Ping\x12\x13.geyser.PingRequest\x1a\x14.geyser.PongResponse\"\x00\x12]\n\x12GetLatestBlockhash\x12!.geyser.GetLatestBlockhashRequest\x1a\".geyser.GetLatestBlockhashResponse\"\x00\x12Q\n\x0eGetBlockHeight\x12\x1d.geyser.GetBlockHeightRequest\x1a\x1e.geyser.GetBlockHeightResponse\"\x00\x12<\n\x07GetSlot\x12\x16.geyser.GetSlotRequest\x1a\x17.geyser.GetSlotResponse\"\x00\x12W\n\x10IsBlockhashValid\x12\x1f.geyser.IsBlockhashValidRequest\x1a .geyser.IsBlockhashValidResponse\"\x00\x12\x45\n\nGetVersion\x12\x19.geyser.GetVersionRequest\x1a\x1a.geyser.GetVersionResponse\"\x00\x42;Z9github.com/rpcpool/yellowstone-grpc/examples/golang/protoP\x01\x62\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'geyser_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'Z9github.com/rpcpool/yellowstone-grpc/examples/golang/proto' + _globals['_SUBSCRIBEREQUEST_ACCOUNTSENTRY']._loaded_options = None + _globals['_SUBSCRIBEREQUEST_ACCOUNTSENTRY']._serialized_options = b'8\001' + _globals['_SUBSCRIBEREQUEST_SLOTSENTRY']._loaded_options = None + _globals['_SUBSCRIBEREQUEST_SLOTSENTRY']._serialized_options = b'8\001' + _globals['_SUBSCRIBEREQUEST_TRANSACTIONSENTRY']._loaded_options = None + _globals['_SUBSCRIBEREQUEST_TRANSACTIONSENTRY']._serialized_options = b'8\001' + _globals['_SUBSCRIBEREQUEST_TRANSACTIONSSTATUSENTRY']._loaded_options = None + _globals['_SUBSCRIBEREQUEST_TRANSACTIONSSTATUSENTRY']._serialized_options = b'8\001' + _globals['_SUBSCRIBEREQUEST_BLOCKSENTRY']._loaded_options = None + _globals['_SUBSCRIBEREQUEST_BLOCKSENTRY']._serialized_options = b'8\001' + _globals['_SUBSCRIBEREQUEST_BLOCKSMETAENTRY']._loaded_options = None + _globals['_SUBSCRIBEREQUEST_BLOCKSMETAENTRY']._serialized_options = b'8\001' + _globals['_SUBSCRIBEREQUEST_ENTRYENTRY']._loaded_options = None + _globals['_SUBSCRIBEREQUEST_ENTRYENTRY']._serialized_options = b'8\001' + _globals['_COMMITMENTLEVEL']._serialized_start=6139 + _globals['_COMMITMENTLEVEL']._serialized_end=6270 + _globals['_SUBSCRIBEREQUEST']._serialized_start=80 + _globals['_SUBSCRIBEREQUEST']._serialized_end=1388 + _globals['_SUBSCRIBEREQUEST_ACCOUNTSENTRY']._serialized_start=719 + _globals['_SUBSCRIBEREQUEST_ACCOUNTSENTRY']._serialized_end=806 + _globals['_SUBSCRIBEREQUEST_SLOTSENTRY']._serialized_start=808 + _globals['_SUBSCRIBEREQUEST_SLOTSENTRY']._serialized_end=889 + _globals['_SUBSCRIBEREQUEST_TRANSACTIONSENTRY']._serialized_start=891 + _globals['_SUBSCRIBEREQUEST_TRANSACTIONSENTRY']._serialized_end=986 + _globals['_SUBSCRIBEREQUEST_TRANSACTIONSSTATUSENTRY']._serialized_start=988 + _globals['_SUBSCRIBEREQUEST_TRANSACTIONSSTATUSENTRY']._serialized_end=1089 + _globals['_SUBSCRIBEREQUEST_BLOCKSENTRY']._serialized_start=1091 + _globals['_SUBSCRIBEREQUEST_BLOCKSENTRY']._serialized_end=1174 + _globals['_SUBSCRIBEREQUEST_BLOCKSMETAENTRY']._serialized_start=1176 + _globals['_SUBSCRIBEREQUEST_BLOCKSMETAENTRY']._serialized_end=1267 + _globals['_SUBSCRIBEREQUEST_ENTRYENTRY']._serialized_start=1269 + _globals['_SUBSCRIBEREQUEST_ENTRYENTRY']._serialized_end=1350 + _globals['_SUBSCRIBEREQUESTFILTERACCOUNTS']._serialized_start=1391 + _globals['_SUBSCRIBEREQUESTFILTERACCOUNTS']._serialized_end=1582 + _globals['_SUBSCRIBEREQUESTFILTERACCOUNTSFILTER']._serialized_start=1585 + _globals['_SUBSCRIBEREQUESTFILTERACCOUNTSFILTER']._serialized_end=1828 + _globals['_SUBSCRIBEREQUESTFILTERACCOUNTSFILTERMEMCMP']._serialized_start=1830 + _globals['_SUBSCRIBEREQUESTFILTERACCOUNTSFILTERMEMCMP']._serialized_end=1951 + _globals['_SUBSCRIBEREQUESTFILTERACCOUNTSFILTERLAMPORTS']._serialized_start=1953 + _globals['_SUBSCRIBEREQUESTFILTERACCOUNTSFILTERLAMPORTS']._serialized_end=2062 + _globals['_SUBSCRIBEREQUESTFILTERSLOTS']._serialized_start=2064 + _globals['_SUBSCRIBEREQUESTFILTERSLOTS']._serialized_end=2153 + _globals['_SUBSCRIBEREQUESTFILTERTRANSACTIONS']._serialized_start=2156 + _globals['_SUBSCRIBEREQUESTFILTERTRANSACTIONS']._serialized_end=2366 + _globals['_SUBSCRIBEREQUESTFILTERBLOCKS']._serialized_start=2369 + _globals['_SUBSCRIBEREQUESTFILTERBLOCKS']._serialized_end=2586 + _globals['_SUBSCRIBEREQUESTFILTERBLOCKSMETA']._serialized_start=2588 + _globals['_SUBSCRIBEREQUESTFILTERBLOCKSMETA']._serialized_end=2622 + _globals['_SUBSCRIBEREQUESTFILTERENTRY']._serialized_start=2624 + _globals['_SUBSCRIBEREQUESTFILTERENTRY']._serialized_end=2653 + _globals['_SUBSCRIBEREQUESTACCOUNTSDATASLICE']._serialized_start=2655 + _globals['_SUBSCRIBEREQUESTACCOUNTSDATASLICE']._serialized_end=2722 + _globals['_SUBSCRIBEREQUESTPING']._serialized_start=2724 + _globals['_SUBSCRIBEREQUESTPING']._serialized_end=2758 + _globals['_SUBSCRIBEUPDATE']._serialized_start=2761 + _globals['_SUBSCRIBEUPDATE']._serialized_end=3326 + _globals['_SUBSCRIBEUPDATEACCOUNT']._serialized_start=3328 + _globals['_SUBSCRIBEUPDATEACCOUNT']._serialized_end=3439 + _globals['_SUBSCRIBEUPDATEACCOUNTINFO']._serialized_start=3442 + _globals['_SUBSCRIBEUPDATEACCOUNTINFO']._serialized_end=3642 + _globals['_SUBSCRIBEUPDATESLOT']._serialized_start=3645 + _globals['_SUBSCRIBEUPDATESLOT']._serialized_end=3793 + _globals['_SUBSCRIBEUPDATETRANSACTION']._serialized_start=3795 + _globals['_SUBSCRIBEUPDATETRANSACTION']._serialized_end=3898 + _globals['_SUBSCRIBEUPDATETRANSACTIONINFO']._serialized_start=3901 + _globals['_SUBSCRIBEUPDATETRANSACTIONINFO']._serialized_end=4117 + _globals['_SUBSCRIBEUPDATETRANSACTIONSTATUS']._serialized_start=4120 + _globals['_SUBSCRIBEUPDATETRANSACTIONSTATUS']._serialized_end=4281 + _globals['_SUBSCRIBEUPDATEBLOCK']._serialized_start=4284 + _globals['_SUBSCRIBEUPDATEBLOCK']._serialized_end=4828 + _globals['_SUBSCRIBEUPDATEBLOCKMETA']._serialized_start=4831 + _globals['_SUBSCRIBEUPDATEBLOCKMETA']._serialized_end=5185 + _globals['_SUBSCRIBEUPDATEENTRY']._serialized_start=5188 + _globals['_SUBSCRIBEUPDATEENTRY']._serialized_end=5345 + _globals['_SUBSCRIBEUPDATEPING']._serialized_start=5347 + _globals['_SUBSCRIBEUPDATEPING']._serialized_end=5368 + _globals['_SUBSCRIBEUPDATEPONG']._serialized_start=5370 + _globals['_SUBSCRIBEUPDATEPONG']._serialized_end=5403 + _globals['_PINGREQUEST']._serialized_start=5405 + _globals['_PINGREQUEST']._serialized_end=5433 + _globals['_PONGRESPONSE']._serialized_start=5435 + _globals['_PONGRESPONSE']._serialized_end=5464 + _globals['_GETLATESTBLOCKHASHREQUEST']._serialized_start=5466 + _globals['_GETLATESTBLOCKHASHREQUEST']._serialized_end=5558 + _globals['_GETLATESTBLOCKHASHRESPONSE']._serialized_start=5560 + _globals['_GETLATESTBLOCKHASHRESPONSE']._serialized_end=5654 + _globals['_GETBLOCKHEIGHTREQUEST']._serialized_start=5656 + _globals['_GETBLOCKHEIGHTREQUEST']._serialized_end=5744 + _globals['_GETBLOCKHEIGHTRESPONSE']._serialized_start=5746 + _globals['_GETBLOCKHEIGHTRESPONSE']._serialized_end=5792 + _globals['_GETSLOTREQUEST']._serialized_start=5794 + _globals['_GETSLOTREQUEST']._serialized_end=5875 + _globals['_GETSLOTRESPONSE']._serialized_start=5877 + _globals['_GETSLOTRESPONSE']._serialized_end=5908 + _globals['_GETVERSIONREQUEST']._serialized_start=5910 + _globals['_GETVERSIONREQUEST']._serialized_end=5929 + _globals['_GETVERSIONRESPONSE']._serialized_start=5931 + _globals['_GETVERSIONRESPONSE']._serialized_end=5968 + _globals['_ISBLOCKHASHVALIDREQUEST']._serialized_start=5970 + _globals['_ISBLOCKHASHVALIDREQUEST']._serialized_end=6079 + _globals['_ISBLOCKHASHVALIDRESPONSE']._serialized_start=6081 + _globals['_ISBLOCKHASHVALIDRESPONSE']._serialized_end=6136 + _globals['_GEYSER']._serialized_start=6273 + _globals['_GEYSER']._serialized_end=6804 +# @@protoc_insertion_point(module_scope) diff --git a/src/driftpy/accounts/grpc/geyser_codegen/geyser_pb2.pyi b/src/driftpy/accounts/grpc/geyser_codegen/geyser_pb2.pyi new file mode 100644 index 00000000..a90209e2 --- /dev/null +++ b/src/driftpy/accounts/grpc/geyser_codegen/geyser_pb2.pyi @@ -0,0 +1,490 @@ +from google.protobuf import timestamp_pb2 as _timestamp_pb2 +import solana_storage_pb2 as _solana_storage_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union +from solana_storage_pb2 import ConfirmedBlock as ConfirmedBlock +from solana_storage_pb2 import ConfirmedTransaction as ConfirmedTransaction +from solana_storage_pb2 import Transaction as Transaction +from solana_storage_pb2 import Message as Message +from solana_storage_pb2 import MessageHeader as MessageHeader +from solana_storage_pb2 import MessageAddressTableLookup as MessageAddressTableLookup +from solana_storage_pb2 import TransactionStatusMeta as TransactionStatusMeta +from solana_storage_pb2 import TransactionError as TransactionError +from solana_storage_pb2 import InnerInstructions as InnerInstructions +from solana_storage_pb2 import InnerInstruction as InnerInstruction +from solana_storage_pb2 import CompiledInstruction as CompiledInstruction +from solana_storage_pb2 import TokenBalance as TokenBalance +from solana_storage_pb2 import UiTokenAmount as UiTokenAmount +from solana_storage_pb2 import ReturnData as ReturnData +from solana_storage_pb2 import Reward as Reward +from solana_storage_pb2 import Rewards as Rewards +from solana_storage_pb2 import UnixTimestamp as UnixTimestamp +from solana_storage_pb2 import BlockHeight as BlockHeight +from solana_storage_pb2 import NumPartitions as NumPartitions +from solana_storage_pb2 import RewardType as RewardType + +DESCRIPTOR: _descriptor.FileDescriptor +Unspecified: _solana_storage_pb2.RewardType +Fee: _solana_storage_pb2.RewardType +Rent: _solana_storage_pb2.RewardType +Staking: _solana_storage_pb2.RewardType +Voting: _solana_storage_pb2.RewardType + +class CommitmentLevel(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + PROCESSED: _ClassVar[CommitmentLevel] + CONFIRMED: _ClassVar[CommitmentLevel] + FINALIZED: _ClassVar[CommitmentLevel] + FIRST_SHRED_RECEIVED: _ClassVar[CommitmentLevel] + COMPLETED: _ClassVar[CommitmentLevel] + CREATED_BANK: _ClassVar[CommitmentLevel] + DEAD: _ClassVar[CommitmentLevel] +PROCESSED: CommitmentLevel +CONFIRMED: CommitmentLevel +FINALIZED: CommitmentLevel +FIRST_SHRED_RECEIVED: CommitmentLevel +COMPLETED: CommitmentLevel +CREATED_BANK: CommitmentLevel +DEAD: CommitmentLevel + +class SubscribeRequest(_message.Message): + __slots__ = ("accounts", "slots", "transactions", "transactions_status", "blocks", "blocks_meta", "entry", "commitment", "accounts_data_slice", "ping", "from_slot") + class AccountsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: SubscribeRequestFilterAccounts + def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[SubscribeRequestFilterAccounts, _Mapping]] = ...) -> None: ... + class SlotsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: SubscribeRequestFilterSlots + def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[SubscribeRequestFilterSlots, _Mapping]] = ...) -> None: ... + class TransactionsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: SubscribeRequestFilterTransactions + def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[SubscribeRequestFilterTransactions, _Mapping]] = ...) -> None: ... + class TransactionsStatusEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: SubscribeRequestFilterTransactions + def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[SubscribeRequestFilterTransactions, _Mapping]] = ...) -> None: ... + class BlocksEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: SubscribeRequestFilterBlocks + def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[SubscribeRequestFilterBlocks, _Mapping]] = ...) -> None: ... + class BlocksMetaEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: SubscribeRequestFilterBlocksMeta + def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[SubscribeRequestFilterBlocksMeta, _Mapping]] = ...) -> None: ... + class EntryEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: SubscribeRequestFilterEntry + def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[SubscribeRequestFilterEntry, _Mapping]] = ...) -> None: ... + ACCOUNTS_FIELD_NUMBER: _ClassVar[int] + SLOTS_FIELD_NUMBER: _ClassVar[int] + TRANSACTIONS_FIELD_NUMBER: _ClassVar[int] + TRANSACTIONS_STATUS_FIELD_NUMBER: _ClassVar[int] + BLOCKS_FIELD_NUMBER: _ClassVar[int] + BLOCKS_META_FIELD_NUMBER: _ClassVar[int] + ENTRY_FIELD_NUMBER: _ClassVar[int] + COMMITMENT_FIELD_NUMBER: _ClassVar[int] + ACCOUNTS_DATA_SLICE_FIELD_NUMBER: _ClassVar[int] + PING_FIELD_NUMBER: _ClassVar[int] + FROM_SLOT_FIELD_NUMBER: _ClassVar[int] + accounts: _containers.MessageMap[str, SubscribeRequestFilterAccounts] + slots: _containers.MessageMap[str, SubscribeRequestFilterSlots] + transactions: _containers.MessageMap[str, SubscribeRequestFilterTransactions] + transactions_status: _containers.MessageMap[str, SubscribeRequestFilterTransactions] + blocks: _containers.MessageMap[str, SubscribeRequestFilterBlocks] + blocks_meta: _containers.MessageMap[str, SubscribeRequestFilterBlocksMeta] + entry: _containers.MessageMap[str, SubscribeRequestFilterEntry] + commitment: CommitmentLevel + accounts_data_slice: _containers.RepeatedCompositeFieldContainer[SubscribeRequestAccountsDataSlice] + ping: SubscribeRequestPing + from_slot: int + def __init__(self, accounts: _Optional[_Mapping[str, SubscribeRequestFilterAccounts]] = ..., slots: _Optional[_Mapping[str, SubscribeRequestFilterSlots]] = ..., transactions: _Optional[_Mapping[str, SubscribeRequestFilterTransactions]] = ..., transactions_status: _Optional[_Mapping[str, SubscribeRequestFilterTransactions]] = ..., blocks: _Optional[_Mapping[str, SubscribeRequestFilterBlocks]] = ..., blocks_meta: _Optional[_Mapping[str, SubscribeRequestFilterBlocksMeta]] = ..., entry: _Optional[_Mapping[str, SubscribeRequestFilterEntry]] = ..., commitment: _Optional[_Union[CommitmentLevel, str]] = ..., accounts_data_slice: _Optional[_Iterable[_Union[SubscribeRequestAccountsDataSlice, _Mapping]]] = ..., ping: _Optional[_Union[SubscribeRequestPing, _Mapping]] = ..., from_slot: _Optional[int] = ...) -> None: ... + +class SubscribeRequestFilterAccounts(_message.Message): + __slots__ = ("account", "owner", "filters", "nonempty_txn_signature") + ACCOUNT_FIELD_NUMBER: _ClassVar[int] + OWNER_FIELD_NUMBER: _ClassVar[int] + FILTERS_FIELD_NUMBER: _ClassVar[int] + NONEMPTY_TXN_SIGNATURE_FIELD_NUMBER: _ClassVar[int] + account: _containers.RepeatedScalarFieldContainer[str] + owner: _containers.RepeatedScalarFieldContainer[str] + filters: _containers.RepeatedCompositeFieldContainer[SubscribeRequestFilterAccountsFilter] + nonempty_txn_signature: bool + def __init__(self, account: _Optional[_Iterable[str]] = ..., owner: _Optional[_Iterable[str]] = ..., filters: _Optional[_Iterable[_Union[SubscribeRequestFilterAccountsFilter, _Mapping]]] = ..., nonempty_txn_signature: bool = ...) -> None: ... + +class SubscribeRequestFilterAccountsFilter(_message.Message): + __slots__ = ("memcmp", "datasize", "token_account_state", "lamports") + MEMCMP_FIELD_NUMBER: _ClassVar[int] + DATASIZE_FIELD_NUMBER: _ClassVar[int] + TOKEN_ACCOUNT_STATE_FIELD_NUMBER: _ClassVar[int] + LAMPORTS_FIELD_NUMBER: _ClassVar[int] + memcmp: SubscribeRequestFilterAccountsFilterMemcmp + datasize: int + token_account_state: bool + lamports: SubscribeRequestFilterAccountsFilterLamports + def __init__(self, memcmp: _Optional[_Union[SubscribeRequestFilterAccountsFilterMemcmp, _Mapping]] = ..., datasize: _Optional[int] = ..., token_account_state: bool = ..., lamports: _Optional[_Union[SubscribeRequestFilterAccountsFilterLamports, _Mapping]] = ...) -> None: ... + +class SubscribeRequestFilterAccountsFilterMemcmp(_message.Message): + __slots__ = ("offset", "bytes", "base58", "base64") + OFFSET_FIELD_NUMBER: _ClassVar[int] + BYTES_FIELD_NUMBER: _ClassVar[int] + BASE58_FIELD_NUMBER: _ClassVar[int] + BASE64_FIELD_NUMBER: _ClassVar[int] + offset: int + bytes: bytes + base58: str + base64: str + def __init__(self, offset: _Optional[int] = ..., bytes: _Optional[bytes] = ..., base58: _Optional[str] = ..., base64: _Optional[str] = ...) -> None: ... + +class SubscribeRequestFilterAccountsFilterLamports(_message.Message): + __slots__ = ("eq", "ne", "lt", "gt") + EQ_FIELD_NUMBER: _ClassVar[int] + NE_FIELD_NUMBER: _ClassVar[int] + LT_FIELD_NUMBER: _ClassVar[int] + GT_FIELD_NUMBER: _ClassVar[int] + eq: int + ne: int + lt: int + gt: int + def __init__(self, eq: _Optional[int] = ..., ne: _Optional[int] = ..., lt: _Optional[int] = ..., gt: _Optional[int] = ...) -> None: ... + +class SubscribeRequestFilterSlots(_message.Message): + __slots__ = ("filter_by_commitment",) + FILTER_BY_COMMITMENT_FIELD_NUMBER: _ClassVar[int] + filter_by_commitment: bool + def __init__(self, filter_by_commitment: bool = ...) -> None: ... + +class SubscribeRequestFilterTransactions(_message.Message): + __slots__ = ("vote", "failed", "signature", "account_include", "account_exclude", "account_required") + VOTE_FIELD_NUMBER: _ClassVar[int] + FAILED_FIELD_NUMBER: _ClassVar[int] + SIGNATURE_FIELD_NUMBER: _ClassVar[int] + ACCOUNT_INCLUDE_FIELD_NUMBER: _ClassVar[int] + ACCOUNT_EXCLUDE_FIELD_NUMBER: _ClassVar[int] + ACCOUNT_REQUIRED_FIELD_NUMBER: _ClassVar[int] + vote: bool + failed: bool + signature: str + account_include: _containers.RepeatedScalarFieldContainer[str] + account_exclude: _containers.RepeatedScalarFieldContainer[str] + account_required: _containers.RepeatedScalarFieldContainer[str] + def __init__(self, vote: bool = ..., failed: bool = ..., signature: _Optional[str] = ..., account_include: _Optional[_Iterable[str]] = ..., account_exclude: _Optional[_Iterable[str]] = ..., account_required: _Optional[_Iterable[str]] = ...) -> None: ... + +class SubscribeRequestFilterBlocks(_message.Message): + __slots__ = ("account_include", "include_transactions", "include_accounts", "include_entries") + ACCOUNT_INCLUDE_FIELD_NUMBER: _ClassVar[int] + INCLUDE_TRANSACTIONS_FIELD_NUMBER: _ClassVar[int] + INCLUDE_ACCOUNTS_FIELD_NUMBER: _ClassVar[int] + INCLUDE_ENTRIES_FIELD_NUMBER: _ClassVar[int] + account_include: _containers.RepeatedScalarFieldContainer[str] + include_transactions: bool + include_accounts: bool + include_entries: bool + def __init__(self, account_include: _Optional[_Iterable[str]] = ..., include_transactions: bool = ..., include_accounts: bool = ..., include_entries: bool = ...) -> None: ... + +class SubscribeRequestFilterBlocksMeta(_message.Message): + __slots__ = () + def __init__(self) -> None: ... + +class SubscribeRequestFilterEntry(_message.Message): + __slots__ = () + def __init__(self) -> None: ... + +class SubscribeRequestAccountsDataSlice(_message.Message): + __slots__ = ("offset", "length") + OFFSET_FIELD_NUMBER: _ClassVar[int] + LENGTH_FIELD_NUMBER: _ClassVar[int] + offset: int + length: int + def __init__(self, offset: _Optional[int] = ..., length: _Optional[int] = ...) -> None: ... + +class SubscribeRequestPing(_message.Message): + __slots__ = ("id",) + ID_FIELD_NUMBER: _ClassVar[int] + id: int + def __init__(self, id: _Optional[int] = ...) -> None: ... + +class SubscribeUpdate(_message.Message): + __slots__ = ("filters", "account", "slot", "transaction", "transaction_status", "block", "ping", "pong", "block_meta", "entry", "created_at") + FILTERS_FIELD_NUMBER: _ClassVar[int] + ACCOUNT_FIELD_NUMBER: _ClassVar[int] + SLOT_FIELD_NUMBER: _ClassVar[int] + TRANSACTION_FIELD_NUMBER: _ClassVar[int] + TRANSACTION_STATUS_FIELD_NUMBER: _ClassVar[int] + BLOCK_FIELD_NUMBER: _ClassVar[int] + PING_FIELD_NUMBER: _ClassVar[int] + PONG_FIELD_NUMBER: _ClassVar[int] + BLOCK_META_FIELD_NUMBER: _ClassVar[int] + ENTRY_FIELD_NUMBER: _ClassVar[int] + CREATED_AT_FIELD_NUMBER: _ClassVar[int] + filters: _containers.RepeatedScalarFieldContainer[str] + account: SubscribeUpdateAccount + slot: SubscribeUpdateSlot + transaction: SubscribeUpdateTransaction + transaction_status: SubscribeUpdateTransactionStatus + block: SubscribeUpdateBlock + ping: SubscribeUpdatePing + pong: SubscribeUpdatePong + block_meta: SubscribeUpdateBlockMeta + entry: SubscribeUpdateEntry + created_at: _timestamp_pb2.Timestamp + def __init__(self, filters: _Optional[_Iterable[str]] = ..., account: _Optional[_Union[SubscribeUpdateAccount, _Mapping]] = ..., slot: _Optional[_Union[SubscribeUpdateSlot, _Mapping]] = ..., transaction: _Optional[_Union[SubscribeUpdateTransaction, _Mapping]] = ..., transaction_status: _Optional[_Union[SubscribeUpdateTransactionStatus, _Mapping]] = ..., block: _Optional[_Union[SubscribeUpdateBlock, _Mapping]] = ..., ping: _Optional[_Union[SubscribeUpdatePing, _Mapping]] = ..., pong: _Optional[_Union[SubscribeUpdatePong, _Mapping]] = ..., block_meta: _Optional[_Union[SubscribeUpdateBlockMeta, _Mapping]] = ..., entry: _Optional[_Union[SubscribeUpdateEntry, _Mapping]] = ..., created_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ... + +class SubscribeUpdateAccount(_message.Message): + __slots__ = ("account", "slot", "is_startup") + ACCOUNT_FIELD_NUMBER: _ClassVar[int] + SLOT_FIELD_NUMBER: _ClassVar[int] + IS_STARTUP_FIELD_NUMBER: _ClassVar[int] + account: SubscribeUpdateAccountInfo + slot: int + is_startup: bool + def __init__(self, account: _Optional[_Union[SubscribeUpdateAccountInfo, _Mapping]] = ..., slot: _Optional[int] = ..., is_startup: bool = ...) -> None: ... + +class SubscribeUpdateAccountInfo(_message.Message): + __slots__ = ("pubkey", "lamports", "owner", "executable", "rent_epoch", "data", "write_version", "txn_signature") + PUBKEY_FIELD_NUMBER: _ClassVar[int] + LAMPORTS_FIELD_NUMBER: _ClassVar[int] + OWNER_FIELD_NUMBER: _ClassVar[int] + EXECUTABLE_FIELD_NUMBER: _ClassVar[int] + RENT_EPOCH_FIELD_NUMBER: _ClassVar[int] + DATA_FIELD_NUMBER: _ClassVar[int] + WRITE_VERSION_FIELD_NUMBER: _ClassVar[int] + TXN_SIGNATURE_FIELD_NUMBER: _ClassVar[int] + pubkey: bytes + lamports: int + owner: bytes + executable: bool + rent_epoch: int + data: bytes + write_version: int + txn_signature: bytes + def __init__(self, pubkey: _Optional[bytes] = ..., lamports: _Optional[int] = ..., owner: _Optional[bytes] = ..., executable: bool = ..., rent_epoch: _Optional[int] = ..., data: _Optional[bytes] = ..., write_version: _Optional[int] = ..., txn_signature: _Optional[bytes] = ...) -> None: ... + +class SubscribeUpdateSlot(_message.Message): + __slots__ = ("slot", "parent", "status", "dead_error") + SLOT_FIELD_NUMBER: _ClassVar[int] + PARENT_FIELD_NUMBER: _ClassVar[int] + STATUS_FIELD_NUMBER: _ClassVar[int] + DEAD_ERROR_FIELD_NUMBER: _ClassVar[int] + slot: int + parent: int + status: CommitmentLevel + dead_error: str + def __init__(self, slot: _Optional[int] = ..., parent: _Optional[int] = ..., status: _Optional[_Union[CommitmentLevel, str]] = ..., dead_error: _Optional[str] = ...) -> None: ... + +class SubscribeUpdateTransaction(_message.Message): + __slots__ = ("transaction", "slot") + TRANSACTION_FIELD_NUMBER: _ClassVar[int] + SLOT_FIELD_NUMBER: _ClassVar[int] + transaction: SubscribeUpdateTransactionInfo + slot: int + def __init__(self, transaction: _Optional[_Union[SubscribeUpdateTransactionInfo, _Mapping]] = ..., slot: _Optional[int] = ...) -> None: ... + +class SubscribeUpdateTransactionInfo(_message.Message): + __slots__ = ("signature", "is_vote", "transaction", "meta", "index") + SIGNATURE_FIELD_NUMBER: _ClassVar[int] + IS_VOTE_FIELD_NUMBER: _ClassVar[int] + TRANSACTION_FIELD_NUMBER: _ClassVar[int] + META_FIELD_NUMBER: _ClassVar[int] + INDEX_FIELD_NUMBER: _ClassVar[int] + signature: bytes + is_vote: bool + transaction: _solana_storage_pb2.Transaction + meta: _solana_storage_pb2.TransactionStatusMeta + index: int + def __init__(self, signature: _Optional[bytes] = ..., is_vote: bool = ..., transaction: _Optional[_Union[_solana_storage_pb2.Transaction, _Mapping]] = ..., meta: _Optional[_Union[_solana_storage_pb2.TransactionStatusMeta, _Mapping]] = ..., index: _Optional[int] = ...) -> None: ... + +class SubscribeUpdateTransactionStatus(_message.Message): + __slots__ = ("slot", "signature", "is_vote", "index", "err") + SLOT_FIELD_NUMBER: _ClassVar[int] + SIGNATURE_FIELD_NUMBER: _ClassVar[int] + IS_VOTE_FIELD_NUMBER: _ClassVar[int] + INDEX_FIELD_NUMBER: _ClassVar[int] + ERR_FIELD_NUMBER: _ClassVar[int] + slot: int + signature: bytes + is_vote: bool + index: int + err: _solana_storage_pb2.TransactionError + def __init__(self, slot: _Optional[int] = ..., signature: _Optional[bytes] = ..., is_vote: bool = ..., index: _Optional[int] = ..., err: _Optional[_Union[_solana_storage_pb2.TransactionError, _Mapping]] = ...) -> None: ... + +class SubscribeUpdateBlock(_message.Message): + __slots__ = ("slot", "blockhash", "rewards", "block_time", "block_height", "parent_slot", "parent_blockhash", "executed_transaction_count", "transactions", "updated_account_count", "accounts", "entries_count", "entries") + SLOT_FIELD_NUMBER: _ClassVar[int] + BLOCKHASH_FIELD_NUMBER: _ClassVar[int] + REWARDS_FIELD_NUMBER: _ClassVar[int] + BLOCK_TIME_FIELD_NUMBER: _ClassVar[int] + BLOCK_HEIGHT_FIELD_NUMBER: _ClassVar[int] + PARENT_SLOT_FIELD_NUMBER: _ClassVar[int] + PARENT_BLOCKHASH_FIELD_NUMBER: _ClassVar[int] + EXECUTED_TRANSACTION_COUNT_FIELD_NUMBER: _ClassVar[int] + TRANSACTIONS_FIELD_NUMBER: _ClassVar[int] + UPDATED_ACCOUNT_COUNT_FIELD_NUMBER: _ClassVar[int] + ACCOUNTS_FIELD_NUMBER: _ClassVar[int] + ENTRIES_COUNT_FIELD_NUMBER: _ClassVar[int] + ENTRIES_FIELD_NUMBER: _ClassVar[int] + slot: int + blockhash: str + rewards: _solana_storage_pb2.Rewards + block_time: _solana_storage_pb2.UnixTimestamp + block_height: _solana_storage_pb2.BlockHeight + parent_slot: int + parent_blockhash: str + executed_transaction_count: int + transactions: _containers.RepeatedCompositeFieldContainer[SubscribeUpdateTransactionInfo] + updated_account_count: int + accounts: _containers.RepeatedCompositeFieldContainer[SubscribeUpdateAccountInfo] + entries_count: int + entries: _containers.RepeatedCompositeFieldContainer[SubscribeUpdateEntry] + def __init__(self, slot: _Optional[int] = ..., blockhash: _Optional[str] = ..., rewards: _Optional[_Union[_solana_storage_pb2.Rewards, _Mapping]] = ..., block_time: _Optional[_Union[_solana_storage_pb2.UnixTimestamp, _Mapping]] = ..., block_height: _Optional[_Union[_solana_storage_pb2.BlockHeight, _Mapping]] = ..., parent_slot: _Optional[int] = ..., parent_blockhash: _Optional[str] = ..., executed_transaction_count: _Optional[int] = ..., transactions: _Optional[_Iterable[_Union[SubscribeUpdateTransactionInfo, _Mapping]]] = ..., updated_account_count: _Optional[int] = ..., accounts: _Optional[_Iterable[_Union[SubscribeUpdateAccountInfo, _Mapping]]] = ..., entries_count: _Optional[int] = ..., entries: _Optional[_Iterable[_Union[SubscribeUpdateEntry, _Mapping]]] = ...) -> None: ... + +class SubscribeUpdateBlockMeta(_message.Message): + __slots__ = ("slot", "blockhash", "rewards", "block_time", "block_height", "parent_slot", "parent_blockhash", "executed_transaction_count", "entries_count") + SLOT_FIELD_NUMBER: _ClassVar[int] + BLOCKHASH_FIELD_NUMBER: _ClassVar[int] + REWARDS_FIELD_NUMBER: _ClassVar[int] + BLOCK_TIME_FIELD_NUMBER: _ClassVar[int] + BLOCK_HEIGHT_FIELD_NUMBER: _ClassVar[int] + PARENT_SLOT_FIELD_NUMBER: _ClassVar[int] + PARENT_BLOCKHASH_FIELD_NUMBER: _ClassVar[int] + EXECUTED_TRANSACTION_COUNT_FIELD_NUMBER: _ClassVar[int] + ENTRIES_COUNT_FIELD_NUMBER: _ClassVar[int] + slot: int + blockhash: str + rewards: _solana_storage_pb2.Rewards + block_time: _solana_storage_pb2.UnixTimestamp + block_height: _solana_storage_pb2.BlockHeight + parent_slot: int + parent_blockhash: str + executed_transaction_count: int + entries_count: int + def __init__(self, slot: _Optional[int] = ..., blockhash: _Optional[str] = ..., rewards: _Optional[_Union[_solana_storage_pb2.Rewards, _Mapping]] = ..., block_time: _Optional[_Union[_solana_storage_pb2.UnixTimestamp, _Mapping]] = ..., block_height: _Optional[_Union[_solana_storage_pb2.BlockHeight, _Mapping]] = ..., parent_slot: _Optional[int] = ..., parent_blockhash: _Optional[str] = ..., executed_transaction_count: _Optional[int] = ..., entries_count: _Optional[int] = ...) -> None: ... + +class SubscribeUpdateEntry(_message.Message): + __slots__ = ("slot", "index", "num_hashes", "hash", "executed_transaction_count", "starting_transaction_index") + SLOT_FIELD_NUMBER: _ClassVar[int] + INDEX_FIELD_NUMBER: _ClassVar[int] + NUM_HASHES_FIELD_NUMBER: _ClassVar[int] + HASH_FIELD_NUMBER: _ClassVar[int] + EXECUTED_TRANSACTION_COUNT_FIELD_NUMBER: _ClassVar[int] + STARTING_TRANSACTION_INDEX_FIELD_NUMBER: _ClassVar[int] + slot: int + index: int + num_hashes: int + hash: bytes + executed_transaction_count: int + starting_transaction_index: int + def __init__(self, slot: _Optional[int] = ..., index: _Optional[int] = ..., num_hashes: _Optional[int] = ..., hash: _Optional[bytes] = ..., executed_transaction_count: _Optional[int] = ..., starting_transaction_index: _Optional[int] = ...) -> None: ... + +class SubscribeUpdatePing(_message.Message): + __slots__ = () + def __init__(self) -> None: ... + +class SubscribeUpdatePong(_message.Message): + __slots__ = ("id",) + ID_FIELD_NUMBER: _ClassVar[int] + id: int + def __init__(self, id: _Optional[int] = ...) -> None: ... + +class PingRequest(_message.Message): + __slots__ = ("count",) + COUNT_FIELD_NUMBER: _ClassVar[int] + count: int + def __init__(self, count: _Optional[int] = ...) -> None: ... + +class PongResponse(_message.Message): + __slots__ = ("count",) + COUNT_FIELD_NUMBER: _ClassVar[int] + count: int + def __init__(self, count: _Optional[int] = ...) -> None: ... + +class GetLatestBlockhashRequest(_message.Message): + __slots__ = ("commitment",) + COMMITMENT_FIELD_NUMBER: _ClassVar[int] + commitment: CommitmentLevel + def __init__(self, commitment: _Optional[_Union[CommitmentLevel, str]] = ...) -> None: ... + +class GetLatestBlockhashResponse(_message.Message): + __slots__ = ("slot", "blockhash", "last_valid_block_height") + SLOT_FIELD_NUMBER: _ClassVar[int] + BLOCKHASH_FIELD_NUMBER: _ClassVar[int] + LAST_VALID_BLOCK_HEIGHT_FIELD_NUMBER: _ClassVar[int] + slot: int + blockhash: str + last_valid_block_height: int + def __init__(self, slot: _Optional[int] = ..., blockhash: _Optional[str] = ..., last_valid_block_height: _Optional[int] = ...) -> None: ... + +class GetBlockHeightRequest(_message.Message): + __slots__ = ("commitment",) + COMMITMENT_FIELD_NUMBER: _ClassVar[int] + commitment: CommitmentLevel + def __init__(self, commitment: _Optional[_Union[CommitmentLevel, str]] = ...) -> None: ... + +class GetBlockHeightResponse(_message.Message): + __slots__ = ("block_height",) + BLOCK_HEIGHT_FIELD_NUMBER: _ClassVar[int] + block_height: int + def __init__(self, block_height: _Optional[int] = ...) -> None: ... + +class GetSlotRequest(_message.Message): + __slots__ = ("commitment",) + COMMITMENT_FIELD_NUMBER: _ClassVar[int] + commitment: CommitmentLevel + def __init__(self, commitment: _Optional[_Union[CommitmentLevel, str]] = ...) -> None: ... + +class GetSlotResponse(_message.Message): + __slots__ = ("slot",) + SLOT_FIELD_NUMBER: _ClassVar[int] + slot: int + def __init__(self, slot: _Optional[int] = ...) -> None: ... + +class GetVersionRequest(_message.Message): + __slots__ = () + def __init__(self) -> None: ... + +class GetVersionResponse(_message.Message): + __slots__ = ("version",) + VERSION_FIELD_NUMBER: _ClassVar[int] + version: str + def __init__(self, version: _Optional[str] = ...) -> None: ... + +class IsBlockhashValidRequest(_message.Message): + __slots__ = ("blockhash", "commitment") + BLOCKHASH_FIELD_NUMBER: _ClassVar[int] + COMMITMENT_FIELD_NUMBER: _ClassVar[int] + blockhash: str + commitment: CommitmentLevel + def __init__(self, blockhash: _Optional[str] = ..., commitment: _Optional[_Union[CommitmentLevel, str]] = ...) -> None: ... + +class IsBlockhashValidResponse(_message.Message): + __slots__ = ("slot", "valid") + SLOT_FIELD_NUMBER: _ClassVar[int] + VALID_FIELD_NUMBER: _ClassVar[int] + slot: int + valid: bool + def __init__(self, slot: _Optional[int] = ..., valid: bool = ...) -> None: ... diff --git a/src/driftpy/accounts/grpc/geyser_codegen/geyser_pb2_grpc.py b/src/driftpy/accounts/grpc/geyser_codegen/geyser_pb2_grpc.py new file mode 100644 index 00000000..c4d89408 --- /dev/null +++ b/src/driftpy/accounts/grpc/geyser_codegen/geyser_pb2_grpc.py @@ -0,0 +1,355 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc +import warnings + +import driftpy.accounts.grpc.geyser_codegen.geyser_pb2 as geyser__pb2 + +GRPC_GENERATED_VERSION = '1.68.1' +GRPC_VERSION = grpc.__version__ +_version_not_supported = False + +try: + from grpc._utilities import first_version_is_lower + _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION) +except ImportError: + _version_not_supported = True + +if _version_not_supported: + raise RuntimeError( + f'The grpc package installed is at version {GRPC_VERSION},' + + f' but the generated code in geyser_pb2_grpc.py depends on' + + f' grpcio>={GRPC_GENERATED_VERSION}.' + + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' + ) + + +class GeyserStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.Subscribe = channel.stream_stream( + '/geyser.Geyser/Subscribe', + request_serializer=geyser__pb2.SubscribeRequest.SerializeToString, + response_deserializer=geyser__pb2.SubscribeUpdate.FromString, + _registered_method=True) + self.Ping = channel.unary_unary( + '/geyser.Geyser/Ping', + request_serializer=geyser__pb2.PingRequest.SerializeToString, + response_deserializer=geyser__pb2.PongResponse.FromString, + _registered_method=True) + self.GetLatestBlockhash = channel.unary_unary( + '/geyser.Geyser/GetLatestBlockhash', + request_serializer=geyser__pb2.GetLatestBlockhashRequest.SerializeToString, + response_deserializer=geyser__pb2.GetLatestBlockhashResponse.FromString, + _registered_method=True) + self.GetBlockHeight = channel.unary_unary( + '/geyser.Geyser/GetBlockHeight', + request_serializer=geyser__pb2.GetBlockHeightRequest.SerializeToString, + response_deserializer=geyser__pb2.GetBlockHeightResponse.FromString, + _registered_method=True) + self.GetSlot = channel.unary_unary( + '/geyser.Geyser/GetSlot', + request_serializer=geyser__pb2.GetSlotRequest.SerializeToString, + response_deserializer=geyser__pb2.GetSlotResponse.FromString, + _registered_method=True) + self.IsBlockhashValid = channel.unary_unary( + '/geyser.Geyser/IsBlockhashValid', + request_serializer=geyser__pb2.IsBlockhashValidRequest.SerializeToString, + response_deserializer=geyser__pb2.IsBlockhashValidResponse.FromString, + _registered_method=True) + self.GetVersion = channel.unary_unary( + '/geyser.Geyser/GetVersion', + request_serializer=geyser__pb2.GetVersionRequest.SerializeToString, + response_deserializer=geyser__pb2.GetVersionResponse.FromString, + _registered_method=True) + + +class GeyserServicer(object): + """Missing associated documentation comment in .proto file.""" + + def Subscribe(self, request_iterator, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Ping(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetLatestBlockhash(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetBlockHeight(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetSlot(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def IsBlockhashValid(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetVersion(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_GeyserServicer_to_server(servicer, server): + rpc_method_handlers = { + 'Subscribe': grpc.stream_stream_rpc_method_handler( + servicer.Subscribe, + request_deserializer=geyser__pb2.SubscribeRequest.FromString, + response_serializer=geyser__pb2.SubscribeUpdate.SerializeToString, + ), + 'Ping': grpc.unary_unary_rpc_method_handler( + servicer.Ping, + request_deserializer=geyser__pb2.PingRequest.FromString, + response_serializer=geyser__pb2.PongResponse.SerializeToString, + ), + 'GetLatestBlockhash': grpc.unary_unary_rpc_method_handler( + servicer.GetLatestBlockhash, + request_deserializer=geyser__pb2.GetLatestBlockhashRequest.FromString, + response_serializer=geyser__pb2.GetLatestBlockhashResponse.SerializeToString, + ), + 'GetBlockHeight': grpc.unary_unary_rpc_method_handler( + servicer.GetBlockHeight, + request_deserializer=geyser__pb2.GetBlockHeightRequest.FromString, + response_serializer=geyser__pb2.GetBlockHeightResponse.SerializeToString, + ), + 'GetSlot': grpc.unary_unary_rpc_method_handler( + servicer.GetSlot, + request_deserializer=geyser__pb2.GetSlotRequest.FromString, + response_serializer=geyser__pb2.GetSlotResponse.SerializeToString, + ), + 'IsBlockhashValid': grpc.unary_unary_rpc_method_handler( + servicer.IsBlockhashValid, + request_deserializer=geyser__pb2.IsBlockhashValidRequest.FromString, + response_serializer=geyser__pb2.IsBlockhashValidResponse.SerializeToString, + ), + 'GetVersion': grpc.unary_unary_rpc_method_handler( + servicer.GetVersion, + request_deserializer=geyser__pb2.GetVersionRequest.FromString, + response_serializer=geyser__pb2.GetVersionResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'geyser.Geyser', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + server.add_registered_method_handlers('geyser.Geyser', rpc_method_handlers) + + + # This class is part of an EXPERIMENTAL API. +class Geyser(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def Subscribe(request_iterator, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.stream_stream( + request_iterator, + target, + '/geyser.Geyser/Subscribe', + geyser__pb2.SubscribeRequest.SerializeToString, + geyser__pb2.SubscribeUpdate.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Ping(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/geyser.Geyser/Ping', + geyser__pb2.PingRequest.SerializeToString, + geyser__pb2.PongResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GetLatestBlockhash(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/geyser.Geyser/GetLatestBlockhash', + geyser__pb2.GetLatestBlockhashRequest.SerializeToString, + geyser__pb2.GetLatestBlockhashResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GetBlockHeight(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/geyser.Geyser/GetBlockHeight', + geyser__pb2.GetBlockHeightRequest.SerializeToString, + geyser__pb2.GetBlockHeightResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GetSlot(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/geyser.Geyser/GetSlot', + geyser__pb2.GetSlotRequest.SerializeToString, + geyser__pb2.GetSlotResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def IsBlockhashValid(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/geyser.Geyser/IsBlockhashValid', + geyser__pb2.IsBlockhashValidRequest.SerializeToString, + geyser__pb2.IsBlockhashValidResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GetVersion(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/geyser.Geyser/GetVersion', + geyser__pb2.GetVersionRequest.SerializeToString, + geyser__pb2.GetVersionResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) diff --git a/src/driftpy/accounts/grpc/geyser_codegen/solana_storage_pb2.py b/src/driftpy/accounts/grpc/geyser_codegen/solana_storage_pb2.py new file mode 100644 index 00000000..f4349867 --- /dev/null +++ b/src/driftpy/accounts/grpc/geyser_codegen/solana_storage_pb2.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: solana-storage.proto +# Protobuf Python Version: 5.28.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 5, + 28, + 1, + '', + 'solana-storage.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14solana-storage.proto\x12\x1dsolana.storage.ConfirmedBlock\"\xa1\x03\n\x0e\x43onfirmedBlock\x12\x1a\n\x12previous_blockhash\x18\x01 \x01(\t\x12\x11\n\tblockhash\x18\x02 \x01(\t\x12\x13\n\x0bparent_slot\x18\x03 \x01(\x04\x12I\n\x0ctransactions\x18\x04 \x03(\x0b\x32\x33.solana.storage.ConfirmedBlock.ConfirmedTransaction\x12\x36\n\x07rewards\x18\x05 \x03(\x0b\x32%.solana.storage.ConfirmedBlock.Reward\x12@\n\nblock_time\x18\x06 \x01(\x0b\x32,.solana.storage.ConfirmedBlock.UnixTimestamp\x12@\n\x0c\x62lock_height\x18\x07 \x01(\x0b\x32*.solana.storage.ConfirmedBlock.BlockHeight\x12\x44\n\x0enum_partitions\x18\x08 \x01(\x0b\x32,.solana.storage.ConfirmedBlock.NumPartitions\"\x9b\x01\n\x14\x43onfirmedTransaction\x12?\n\x0btransaction\x18\x01 \x01(\x0b\x32*.solana.storage.ConfirmedBlock.Transaction\x12\x42\n\x04meta\x18\x02 \x01(\x0b\x32\x34.solana.storage.ConfirmedBlock.TransactionStatusMeta\"Z\n\x0bTransaction\x12\x12\n\nsignatures\x18\x01 \x03(\x0c\x12\x37\n\x07message\x18\x02 \x01(\x0b\x32&.solana.storage.ConfirmedBlock.Message\"\xad\x02\n\x07Message\x12<\n\x06header\x18\x01 \x01(\x0b\x32,.solana.storage.ConfirmedBlock.MessageHeader\x12\x14\n\x0c\x61\x63\x63ount_keys\x18\x02 \x03(\x0c\x12\x18\n\x10recent_blockhash\x18\x03 \x01(\x0c\x12H\n\x0cinstructions\x18\x04 \x03(\x0b\x32\x32.solana.storage.ConfirmedBlock.CompiledInstruction\x12\x11\n\tversioned\x18\x05 \x01(\x08\x12W\n\x15\x61\x64\x64ress_table_lookups\x18\x06 \x03(\x0b\x32\x38.solana.storage.ConfirmedBlock.MessageAddressTableLookup\"~\n\rMessageHeader\x12\x1f\n\x17num_required_signatures\x18\x01 \x01(\r\x12$\n\x1cnum_readonly_signed_accounts\x18\x02 \x01(\r\x12&\n\x1enum_readonly_unsigned_accounts\x18\x03 \x01(\r\"d\n\x19MessageAddressTableLookup\x12\x13\n\x0b\x61\x63\x63ount_key\x18\x01 \x01(\x0c\x12\x18\n\x10writable_indexes\x18\x02 \x01(\x0c\x12\x18\n\x10readonly_indexes\x18\x03 \x01(\x0c\"\xda\x05\n\x15TransactionStatusMeta\x12<\n\x03\x65rr\x18\x01 \x01(\x0b\x32/.solana.storage.ConfirmedBlock.TransactionError\x12\x0b\n\x03\x66\x65\x65\x18\x02 \x01(\x04\x12\x14\n\x0cpre_balances\x18\x03 \x03(\x04\x12\x15\n\rpost_balances\x18\x04 \x03(\x04\x12L\n\x12inner_instructions\x18\x05 \x03(\x0b\x32\x30.solana.storage.ConfirmedBlock.InnerInstructions\x12\x1f\n\x17inner_instructions_none\x18\n \x01(\x08\x12\x14\n\x0clog_messages\x18\x06 \x03(\t\x12\x19\n\x11log_messages_none\x18\x0b \x01(\x08\x12G\n\x12pre_token_balances\x18\x07 \x03(\x0b\x32+.solana.storage.ConfirmedBlock.TokenBalance\x12H\n\x13post_token_balances\x18\x08 \x03(\x0b\x32+.solana.storage.ConfirmedBlock.TokenBalance\x12\x36\n\x07rewards\x18\t \x03(\x0b\x32%.solana.storage.ConfirmedBlock.Reward\x12!\n\x19loaded_writable_addresses\x18\x0c \x03(\x0c\x12!\n\x19loaded_readonly_addresses\x18\r \x03(\x0c\x12>\n\x0breturn_data\x18\x0e \x01(\x0b\x32).solana.storage.ConfirmedBlock.ReturnData\x12\x18\n\x10return_data_none\x18\x0f \x01(\x08\x12#\n\x16\x63ompute_units_consumed\x18\x10 \x01(\x04H\x00\x88\x01\x01\x42\x19\n\x17_compute_units_consumed\"\x1f\n\x10TransactionError\x12\x0b\n\x03\x65rr\x18\x01 \x01(\x0c\"i\n\x11InnerInstructions\x12\r\n\x05index\x18\x01 \x01(\r\x12\x45\n\x0cinstructions\x18\x02 \x03(\x0b\x32/.solana.storage.ConfirmedBlock.InnerInstruction\"x\n\x10InnerInstruction\x12\x18\n\x10program_id_index\x18\x01 \x01(\r\x12\x10\n\x08\x61\x63\x63ounts\x18\x02 \x01(\x0c\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c\x12\x19\n\x0cstack_height\x18\x04 \x01(\rH\x00\x88\x01\x01\x42\x0f\n\r_stack_height\"O\n\x13\x43ompiledInstruction\x12\x18\n\x10program_id_index\x18\x01 \x01(\r\x12\x10\n\x08\x61\x63\x63ounts\x18\x02 \x01(\x0c\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c\"\x9d\x01\n\x0cTokenBalance\x12\x15\n\raccount_index\x18\x01 \x01(\r\x12\x0c\n\x04mint\x18\x02 \x01(\t\x12\x45\n\x0fui_token_amount\x18\x03 \x01(\x0b\x32,.solana.storage.ConfirmedBlock.UiTokenAmount\x12\r\n\x05owner\x18\x04 \x01(\t\x12\x12\n\nprogram_id\x18\x05 \x01(\t\"^\n\rUiTokenAmount\x12\x11\n\tui_amount\x18\x01 \x01(\x01\x12\x10\n\x08\x64\x65\x63imals\x18\x02 \x01(\r\x12\x0e\n\x06\x61mount\x18\x03 \x01(\t\x12\x18\n\x10ui_amount_string\x18\x04 \x01(\t\".\n\nReturnData\x12\x12\n\nprogram_id\x18\x01 \x01(\x0c\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x94\x01\n\x06Reward\x12\x0e\n\x06pubkey\x18\x01 \x01(\t\x12\x10\n\x08lamports\x18\x02 \x01(\x03\x12\x14\n\x0cpost_balance\x18\x03 \x01(\x04\x12>\n\x0breward_type\x18\x04 \x01(\x0e\x32).solana.storage.ConfirmedBlock.RewardType\x12\x12\n\ncommission\x18\x05 \x01(\t\"\x87\x01\n\x07Rewards\x12\x36\n\x07rewards\x18\x01 \x03(\x0b\x32%.solana.storage.ConfirmedBlock.Reward\x12\x44\n\x0enum_partitions\x18\x02 \x01(\x0b\x32,.solana.storage.ConfirmedBlock.NumPartitions\"\"\n\rUnixTimestamp\x12\x11\n\ttimestamp\x18\x01 \x01(\x03\"#\n\x0b\x42lockHeight\x12\x14\n\x0c\x62lock_height\x18\x01 \x01(\x04\"\'\n\rNumPartitions\x12\x16\n\x0enum_partitions\x18\x01 \x01(\x04*I\n\nRewardType\x12\x0f\n\x0bUnspecified\x10\x00\x12\x07\n\x03\x46\x65\x65\x10\x01\x12\x08\n\x04Rent\x10\x02\x12\x0b\n\x07Staking\x10\x03\x12\n\n\x06Voting\x10\x04\x42;Z9github.com/rpcpool/yellowstone-grpc/examples/golang/protob\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'solana_storage_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'Z9github.com/rpcpool/yellowstone-grpc/examples/golang/proto' + _globals['_REWARDTYPE']._serialized_start=3042 + _globals['_REWARDTYPE']._serialized_end=3115 + _globals['_CONFIRMEDBLOCK']._serialized_start=56 + _globals['_CONFIRMEDBLOCK']._serialized_end=473 + _globals['_CONFIRMEDTRANSACTION']._serialized_start=476 + _globals['_CONFIRMEDTRANSACTION']._serialized_end=631 + _globals['_TRANSACTION']._serialized_start=633 + _globals['_TRANSACTION']._serialized_end=723 + _globals['_MESSAGE']._serialized_start=726 + _globals['_MESSAGE']._serialized_end=1027 + _globals['_MESSAGEHEADER']._serialized_start=1029 + _globals['_MESSAGEHEADER']._serialized_end=1155 + _globals['_MESSAGEADDRESSTABLELOOKUP']._serialized_start=1157 + _globals['_MESSAGEADDRESSTABLELOOKUP']._serialized_end=1257 + _globals['_TRANSACTIONSTATUSMETA']._serialized_start=1260 + _globals['_TRANSACTIONSTATUSMETA']._serialized_end=1990 + _globals['_TRANSACTIONERROR']._serialized_start=1992 + _globals['_TRANSACTIONERROR']._serialized_end=2023 + _globals['_INNERINSTRUCTIONS']._serialized_start=2025 + _globals['_INNERINSTRUCTIONS']._serialized_end=2130 + _globals['_INNERINSTRUCTION']._serialized_start=2132 + _globals['_INNERINSTRUCTION']._serialized_end=2252 + _globals['_COMPILEDINSTRUCTION']._serialized_start=2254 + _globals['_COMPILEDINSTRUCTION']._serialized_end=2333 + _globals['_TOKENBALANCE']._serialized_start=2336 + _globals['_TOKENBALANCE']._serialized_end=2493 + _globals['_UITOKENAMOUNT']._serialized_start=2495 + _globals['_UITOKENAMOUNT']._serialized_end=2589 + _globals['_RETURNDATA']._serialized_start=2591 + _globals['_RETURNDATA']._serialized_end=2637 + _globals['_REWARD']._serialized_start=2640 + _globals['_REWARD']._serialized_end=2788 + _globals['_REWARDS']._serialized_start=2791 + _globals['_REWARDS']._serialized_end=2926 + _globals['_UNIXTIMESTAMP']._serialized_start=2928 + _globals['_UNIXTIMESTAMP']._serialized_end=2962 + _globals['_BLOCKHEIGHT']._serialized_start=2964 + _globals['_BLOCKHEIGHT']._serialized_end=2999 + _globals['_NUMPARTITIONS']._serialized_start=3001 + _globals['_NUMPARTITIONS']._serialized_end=3040 +# @@protoc_insertion_point(module_scope) diff --git a/src/driftpy/accounts/grpc/geyser_codegen/solana_storage_pb2.pyi b/src/driftpy/accounts/grpc/geyser_codegen/solana_storage_pb2.pyi new file mode 100644 index 00000000..10312a60 --- /dev/null +++ b/src/driftpy/accounts/grpc/geyser_codegen/solana_storage_pb2.pyi @@ -0,0 +1,238 @@ +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class RewardType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + Unspecified: _ClassVar[RewardType] + Fee: _ClassVar[RewardType] + Rent: _ClassVar[RewardType] + Staking: _ClassVar[RewardType] + Voting: _ClassVar[RewardType] +Unspecified: RewardType +Fee: RewardType +Rent: RewardType +Staking: RewardType +Voting: RewardType + +class ConfirmedBlock(_message.Message): + __slots__ = ("previous_blockhash", "blockhash", "parent_slot", "transactions", "rewards", "block_time", "block_height", "num_partitions") + PREVIOUS_BLOCKHASH_FIELD_NUMBER: _ClassVar[int] + BLOCKHASH_FIELD_NUMBER: _ClassVar[int] + PARENT_SLOT_FIELD_NUMBER: _ClassVar[int] + TRANSACTIONS_FIELD_NUMBER: _ClassVar[int] + REWARDS_FIELD_NUMBER: _ClassVar[int] + BLOCK_TIME_FIELD_NUMBER: _ClassVar[int] + BLOCK_HEIGHT_FIELD_NUMBER: _ClassVar[int] + NUM_PARTITIONS_FIELD_NUMBER: _ClassVar[int] + previous_blockhash: str + blockhash: str + parent_slot: int + transactions: _containers.RepeatedCompositeFieldContainer[ConfirmedTransaction] + rewards: _containers.RepeatedCompositeFieldContainer[Reward] + block_time: UnixTimestamp + block_height: BlockHeight + num_partitions: NumPartitions + def __init__(self, previous_blockhash: _Optional[str] = ..., blockhash: _Optional[str] = ..., parent_slot: _Optional[int] = ..., transactions: _Optional[_Iterable[_Union[ConfirmedTransaction, _Mapping]]] = ..., rewards: _Optional[_Iterable[_Union[Reward, _Mapping]]] = ..., block_time: _Optional[_Union[UnixTimestamp, _Mapping]] = ..., block_height: _Optional[_Union[BlockHeight, _Mapping]] = ..., num_partitions: _Optional[_Union[NumPartitions, _Mapping]] = ...) -> None: ... + +class ConfirmedTransaction(_message.Message): + __slots__ = ("transaction", "meta") + TRANSACTION_FIELD_NUMBER: _ClassVar[int] + META_FIELD_NUMBER: _ClassVar[int] + transaction: Transaction + meta: TransactionStatusMeta + def __init__(self, transaction: _Optional[_Union[Transaction, _Mapping]] = ..., meta: _Optional[_Union[TransactionStatusMeta, _Mapping]] = ...) -> None: ... + +class Transaction(_message.Message): + __slots__ = ("signatures", "message") + SIGNATURES_FIELD_NUMBER: _ClassVar[int] + MESSAGE_FIELD_NUMBER: _ClassVar[int] + signatures: _containers.RepeatedScalarFieldContainer[bytes] + message: Message + def __init__(self, signatures: _Optional[_Iterable[bytes]] = ..., message: _Optional[_Union[Message, _Mapping]] = ...) -> None: ... + +class Message(_message.Message): + __slots__ = ("header", "account_keys", "recent_blockhash", "instructions", "versioned", "address_table_lookups") + HEADER_FIELD_NUMBER: _ClassVar[int] + ACCOUNT_KEYS_FIELD_NUMBER: _ClassVar[int] + RECENT_BLOCKHASH_FIELD_NUMBER: _ClassVar[int] + INSTRUCTIONS_FIELD_NUMBER: _ClassVar[int] + VERSIONED_FIELD_NUMBER: _ClassVar[int] + ADDRESS_TABLE_LOOKUPS_FIELD_NUMBER: _ClassVar[int] + header: MessageHeader + account_keys: _containers.RepeatedScalarFieldContainer[bytes] + recent_blockhash: bytes + instructions: _containers.RepeatedCompositeFieldContainer[CompiledInstruction] + versioned: bool + address_table_lookups: _containers.RepeatedCompositeFieldContainer[MessageAddressTableLookup] + def __init__(self, header: _Optional[_Union[MessageHeader, _Mapping]] = ..., account_keys: _Optional[_Iterable[bytes]] = ..., recent_blockhash: _Optional[bytes] = ..., instructions: _Optional[_Iterable[_Union[CompiledInstruction, _Mapping]]] = ..., versioned: bool = ..., address_table_lookups: _Optional[_Iterable[_Union[MessageAddressTableLookup, _Mapping]]] = ...) -> None: ... + +class MessageHeader(_message.Message): + __slots__ = ("num_required_signatures", "num_readonly_signed_accounts", "num_readonly_unsigned_accounts") + NUM_REQUIRED_SIGNATURES_FIELD_NUMBER: _ClassVar[int] + NUM_READONLY_SIGNED_ACCOUNTS_FIELD_NUMBER: _ClassVar[int] + NUM_READONLY_UNSIGNED_ACCOUNTS_FIELD_NUMBER: _ClassVar[int] + num_required_signatures: int + num_readonly_signed_accounts: int + num_readonly_unsigned_accounts: int + def __init__(self, num_required_signatures: _Optional[int] = ..., num_readonly_signed_accounts: _Optional[int] = ..., num_readonly_unsigned_accounts: _Optional[int] = ...) -> None: ... + +class MessageAddressTableLookup(_message.Message): + __slots__ = ("account_key", "writable_indexes", "readonly_indexes") + ACCOUNT_KEY_FIELD_NUMBER: _ClassVar[int] + WRITABLE_INDEXES_FIELD_NUMBER: _ClassVar[int] + READONLY_INDEXES_FIELD_NUMBER: _ClassVar[int] + account_key: bytes + writable_indexes: bytes + readonly_indexes: bytes + def __init__(self, account_key: _Optional[bytes] = ..., writable_indexes: _Optional[bytes] = ..., readonly_indexes: _Optional[bytes] = ...) -> None: ... + +class TransactionStatusMeta(_message.Message): + __slots__ = ("err", "fee", "pre_balances", "post_balances", "inner_instructions", "inner_instructions_none", "log_messages", "log_messages_none", "pre_token_balances", "post_token_balances", "rewards", "loaded_writable_addresses", "loaded_readonly_addresses", "return_data", "return_data_none", "compute_units_consumed") + ERR_FIELD_NUMBER: _ClassVar[int] + FEE_FIELD_NUMBER: _ClassVar[int] + PRE_BALANCES_FIELD_NUMBER: _ClassVar[int] + POST_BALANCES_FIELD_NUMBER: _ClassVar[int] + INNER_INSTRUCTIONS_FIELD_NUMBER: _ClassVar[int] + INNER_INSTRUCTIONS_NONE_FIELD_NUMBER: _ClassVar[int] + LOG_MESSAGES_FIELD_NUMBER: _ClassVar[int] + LOG_MESSAGES_NONE_FIELD_NUMBER: _ClassVar[int] + PRE_TOKEN_BALANCES_FIELD_NUMBER: _ClassVar[int] + POST_TOKEN_BALANCES_FIELD_NUMBER: _ClassVar[int] + REWARDS_FIELD_NUMBER: _ClassVar[int] + LOADED_WRITABLE_ADDRESSES_FIELD_NUMBER: _ClassVar[int] + LOADED_READONLY_ADDRESSES_FIELD_NUMBER: _ClassVar[int] + RETURN_DATA_FIELD_NUMBER: _ClassVar[int] + RETURN_DATA_NONE_FIELD_NUMBER: _ClassVar[int] + COMPUTE_UNITS_CONSUMED_FIELD_NUMBER: _ClassVar[int] + err: TransactionError + fee: int + pre_balances: _containers.RepeatedScalarFieldContainer[int] + post_balances: _containers.RepeatedScalarFieldContainer[int] + inner_instructions: _containers.RepeatedCompositeFieldContainer[InnerInstructions] + inner_instructions_none: bool + log_messages: _containers.RepeatedScalarFieldContainer[str] + log_messages_none: bool + pre_token_balances: _containers.RepeatedCompositeFieldContainer[TokenBalance] + post_token_balances: _containers.RepeatedCompositeFieldContainer[TokenBalance] + rewards: _containers.RepeatedCompositeFieldContainer[Reward] + loaded_writable_addresses: _containers.RepeatedScalarFieldContainer[bytes] + loaded_readonly_addresses: _containers.RepeatedScalarFieldContainer[bytes] + return_data: ReturnData + return_data_none: bool + compute_units_consumed: int + def __init__(self, err: _Optional[_Union[TransactionError, _Mapping]] = ..., fee: _Optional[int] = ..., pre_balances: _Optional[_Iterable[int]] = ..., post_balances: _Optional[_Iterable[int]] = ..., inner_instructions: _Optional[_Iterable[_Union[InnerInstructions, _Mapping]]] = ..., inner_instructions_none: bool = ..., log_messages: _Optional[_Iterable[str]] = ..., log_messages_none: bool = ..., pre_token_balances: _Optional[_Iterable[_Union[TokenBalance, _Mapping]]] = ..., post_token_balances: _Optional[_Iterable[_Union[TokenBalance, _Mapping]]] = ..., rewards: _Optional[_Iterable[_Union[Reward, _Mapping]]] = ..., loaded_writable_addresses: _Optional[_Iterable[bytes]] = ..., loaded_readonly_addresses: _Optional[_Iterable[bytes]] = ..., return_data: _Optional[_Union[ReturnData, _Mapping]] = ..., return_data_none: bool = ..., compute_units_consumed: _Optional[int] = ...) -> None: ... + +class TransactionError(_message.Message): + __slots__ = ("err",) + ERR_FIELD_NUMBER: _ClassVar[int] + err: bytes + def __init__(self, err: _Optional[bytes] = ...) -> None: ... + +class InnerInstructions(_message.Message): + __slots__ = ("index", "instructions") + INDEX_FIELD_NUMBER: _ClassVar[int] + INSTRUCTIONS_FIELD_NUMBER: _ClassVar[int] + index: int + instructions: _containers.RepeatedCompositeFieldContainer[InnerInstruction] + def __init__(self, index: _Optional[int] = ..., instructions: _Optional[_Iterable[_Union[InnerInstruction, _Mapping]]] = ...) -> None: ... + +class InnerInstruction(_message.Message): + __slots__ = ("program_id_index", "accounts", "data", "stack_height") + PROGRAM_ID_INDEX_FIELD_NUMBER: _ClassVar[int] + ACCOUNTS_FIELD_NUMBER: _ClassVar[int] + DATA_FIELD_NUMBER: _ClassVar[int] + STACK_HEIGHT_FIELD_NUMBER: _ClassVar[int] + program_id_index: int + accounts: bytes + data: bytes + stack_height: int + def __init__(self, program_id_index: _Optional[int] = ..., accounts: _Optional[bytes] = ..., data: _Optional[bytes] = ..., stack_height: _Optional[int] = ...) -> None: ... + +class CompiledInstruction(_message.Message): + __slots__ = ("program_id_index", "accounts", "data") + PROGRAM_ID_INDEX_FIELD_NUMBER: _ClassVar[int] + ACCOUNTS_FIELD_NUMBER: _ClassVar[int] + DATA_FIELD_NUMBER: _ClassVar[int] + program_id_index: int + accounts: bytes + data: bytes + def __init__(self, program_id_index: _Optional[int] = ..., accounts: _Optional[bytes] = ..., data: _Optional[bytes] = ...) -> None: ... + +class TokenBalance(_message.Message): + __slots__ = ("account_index", "mint", "ui_token_amount", "owner", "program_id") + ACCOUNT_INDEX_FIELD_NUMBER: _ClassVar[int] + MINT_FIELD_NUMBER: _ClassVar[int] + UI_TOKEN_AMOUNT_FIELD_NUMBER: _ClassVar[int] + OWNER_FIELD_NUMBER: _ClassVar[int] + PROGRAM_ID_FIELD_NUMBER: _ClassVar[int] + account_index: int + mint: str + ui_token_amount: UiTokenAmount + owner: str + program_id: str + def __init__(self, account_index: _Optional[int] = ..., mint: _Optional[str] = ..., ui_token_amount: _Optional[_Union[UiTokenAmount, _Mapping]] = ..., owner: _Optional[str] = ..., program_id: _Optional[str] = ...) -> None: ... + +class UiTokenAmount(_message.Message): + __slots__ = ("ui_amount", "decimals", "amount", "ui_amount_string") + UI_AMOUNT_FIELD_NUMBER: _ClassVar[int] + DECIMALS_FIELD_NUMBER: _ClassVar[int] + AMOUNT_FIELD_NUMBER: _ClassVar[int] + UI_AMOUNT_STRING_FIELD_NUMBER: _ClassVar[int] + ui_amount: float + decimals: int + amount: str + ui_amount_string: str + def __init__(self, ui_amount: _Optional[float] = ..., decimals: _Optional[int] = ..., amount: _Optional[str] = ..., ui_amount_string: _Optional[str] = ...) -> None: ... + +class ReturnData(_message.Message): + __slots__ = ("program_id", "data") + PROGRAM_ID_FIELD_NUMBER: _ClassVar[int] + DATA_FIELD_NUMBER: _ClassVar[int] + program_id: bytes + data: bytes + def __init__(self, program_id: _Optional[bytes] = ..., data: _Optional[bytes] = ...) -> None: ... + +class Reward(_message.Message): + __slots__ = ("pubkey", "lamports", "post_balance", "reward_type", "commission") + PUBKEY_FIELD_NUMBER: _ClassVar[int] + LAMPORTS_FIELD_NUMBER: _ClassVar[int] + POST_BALANCE_FIELD_NUMBER: _ClassVar[int] + REWARD_TYPE_FIELD_NUMBER: _ClassVar[int] + COMMISSION_FIELD_NUMBER: _ClassVar[int] + pubkey: str + lamports: int + post_balance: int + reward_type: RewardType + commission: str + def __init__(self, pubkey: _Optional[str] = ..., lamports: _Optional[int] = ..., post_balance: _Optional[int] = ..., reward_type: _Optional[_Union[RewardType, str]] = ..., commission: _Optional[str] = ...) -> None: ... + +class Rewards(_message.Message): + __slots__ = ("rewards", "num_partitions") + REWARDS_FIELD_NUMBER: _ClassVar[int] + NUM_PARTITIONS_FIELD_NUMBER: _ClassVar[int] + rewards: _containers.RepeatedCompositeFieldContainer[Reward] + num_partitions: NumPartitions + def __init__(self, rewards: _Optional[_Iterable[_Union[Reward, _Mapping]]] = ..., num_partitions: _Optional[_Union[NumPartitions, _Mapping]] = ...) -> None: ... + +class UnixTimestamp(_message.Message): + __slots__ = ("timestamp",) + TIMESTAMP_FIELD_NUMBER: _ClassVar[int] + timestamp: int + def __init__(self, timestamp: _Optional[int] = ...) -> None: ... + +class BlockHeight(_message.Message): + __slots__ = ("block_height",) + BLOCK_HEIGHT_FIELD_NUMBER: _ClassVar[int] + block_height: int + def __init__(self, block_height: _Optional[int] = ...) -> None: ... + +class NumPartitions(_message.Message): + __slots__ = ("num_partitions",) + NUM_PARTITIONS_FIELD_NUMBER: _ClassVar[int] + num_partitions: int + def __init__(self, num_partitions: _Optional[int] = ...) -> None: ... diff --git a/src/driftpy/accounts/grpc/geyser_codegen/solana_storage_pb2_grpc.py b/src/driftpy/accounts/grpc/geyser_codegen/solana_storage_pb2_grpc.py new file mode 100644 index 00000000..a777633a --- /dev/null +++ b/src/driftpy/accounts/grpc/geyser_codegen/solana_storage_pb2_grpc.py @@ -0,0 +1,24 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc +import warnings + + +GRPC_GENERATED_VERSION = '1.68.1' +GRPC_VERSION = grpc.__version__ +_version_not_supported = False + +try: + from grpc._utilities import first_version_is_lower + _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION) +except ImportError: + _version_not_supported = True + +if _version_not_supported: + raise RuntimeError( + f'The grpc package installed is at version {GRPC_VERSION},' + + f' but the generated code in solana_storage_pb2_grpc.py depends on' + + f' grpcio>={GRPC_GENERATED_VERSION}.' + + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' + ) diff --git a/src/driftpy/accounts/grpc/geyser_codegen/subscribe_geyser.py b/src/driftpy/accounts/grpc/geyser_codegen/subscribe_geyser.py new file mode 100644 index 00000000..a2ea6d18 --- /dev/null +++ b/src/driftpy/accounts/grpc/geyser_codegen/subscribe_geyser.py @@ -0,0 +1,106 @@ +import logging +import os +import time +from typing import Iterator, Optional + +import geyser_pb2 +import geyser_pb2_grpc +import grpc + + +def _triton_sign_request( + callback: grpc.AuthMetadataPluginCallback, + x_token: Optional[str], + error: Optional[Exception], +): + metadata = (("x-token", x_token),) + return callback(metadata, error) + + +class TritonAuthMetadataPlugin(grpc.AuthMetadataPlugin): + def __init__(self, x_token: str): + self.x_token = x_token + + def __call__( + self, + context: grpc.AuthMetadataContext, + callback: grpc.AuthMetadataPluginCallback, + ): + return _triton_sign_request(callback, self.x_token, None) + + +def create_subscribe_request() -> Iterator[geyser_pb2.SubscribeRequest]: + request = geyser_pb2.SubscribeRequest() + + # Create the account filter + account_filter = geyser_pb2.SubscribeRequestFilterAccounts() + + # Add a specific account to monitor + # Note: This needs to be the base58 encoded public key + account_filter.account.append("dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH") + account_filter.account.append("DRiP8pChV3hr8FkdgPpxpVwQh3dHnTzHgdbn5Z3fmwHc") + account_filter.account.append("Fe4hMZrg7R97ZrbSScWBXUpQwZB9gzBnhodTCGyjkHsG") + account_filter.nonempty_txn_signature = True + + # Copy the filter into the request + request.accounts["account_monitor"].CopyFrom(account_filter) + request.commitment = geyser_pb2.CommitmentLevel.CONFIRMED + + yield request + + # Keep connection alive with pings + while True: + time.sleep(30) + ping_request = geyser_pb2.SubscribeRequest() + ping_request.ping.id = int(time.time()) + yield ping_request + + +def handle_subscribe_updates(stub: geyser_pb2_grpc.GeyserStub): + """ + Handles the streaming updates from the subscription. + Each update can contain different types of data based on our filters. + """ + try: + request_iterator = create_subscribe_request() + print("Starting subscription stream...") + + response_stream = stub.Subscribe(request_iterator) + + for update in response_stream: + if update.HasField("account"): + print("\nAccount Update:") + print(f" Pubkey: {update.account.account.pubkey.hex()}") + print(f" Owner: {update.account.account.owner.hex()}") + print(f" Lamports: {update.account.account.lamports}") + print(f" Slot: {update.account.slot}") + if update.account.account.txn_signature: + print( + f" Transaction: {update.account.account.txn_signature.hex()}" + ) + + elif update.HasField("pong"): + print(f"Received pong: {update.pong.id}") + + except grpc.RpcError as e: + logging.error(f"RPC error occurred: {str(e)}") + raise + + +def run_subscription_client(): + rpc_fqdn = os.environ.get("RPC_FDQN") + x_token = os.environ.get("X_TOKEN") + + auth = TritonAuthMetadataPlugin(x_token) + ssl_creds = grpc.ssl_channel_credentials() + call_creds = grpc.metadata_call_credentials(auth) + combined_creds = grpc.composite_channel_credentials(ssl_creds, call_creds) + + with grpc.secure_channel(rpc_fqdn, credentials=combined_creds) as channel: + stub = geyser_pb2_grpc.GeyserStub(channel) + handle_subscribe_updates(stub) + + +if __name__ == "__main__": + logging.basicConfig(level=logging.INFO) + run_subscription_client() diff --git a/src/driftpy/accounts/grpc/user.py b/src/driftpy/accounts/grpc/user.py new file mode 100644 index 00000000..6d6b3bee --- /dev/null +++ b/src/driftpy/accounts/grpc/user.py @@ -0,0 +1,12 @@ +from typing import Optional + +from driftpy.accounts.grpc.account_subscriber import GrpcAccountSubscriber +from driftpy.accounts.types import DataAndSlot, UserAccountSubscriber +from driftpy.types import UserAccount + + +class GrpcUserAccountSubscriber( + GrpcAccountSubscriber[UserAccount], UserAccountSubscriber +): + def get_user_account_and_slot(self) -> Optional[DataAndSlot[UserAccount]]: + return self.data_and_slot diff --git a/src/driftpy/accounts/grpc/user_stats.py b/src/driftpy/accounts/grpc/user_stats.py new file mode 100644 index 00000000..20d41570 --- /dev/null +++ b/src/driftpy/accounts/grpc/user_stats.py @@ -0,0 +1,14 @@ +from typing import Optional + +from driftpy.accounts.grpc.account_subscriber import GrpcAccountSubscriber +from driftpy.accounts.types import DataAndSlot, UserStatsAccountSubscriber +from driftpy.types import UserStatsAccount + + +class GrpcUserStatsAccountSubscriber( + GrpcAccountSubscriber[UserStatsAccount], UserStatsAccountSubscriber +): + def get_user_stats_account_and_slot( + self, + ) -> Optional[DataAndSlot[UserStatsAccount]]: + return self.data_and_slot diff --git a/src/driftpy/accounts/polling/drift_client.py b/src/driftpy/accounts/polling/drift_client.py index 9199a1b4..d377863a 100644 --- a/src/driftpy/accounts/polling/drift_client.py +++ b/src/driftpy/accounts/polling/drift_client.py @@ -12,7 +12,7 @@ get_spot_market_public_key, get_state_public_key, ) -from driftpy.constants.config import find_all_market_and_oracles +from driftpy.constants.config import find_all_market_and_oracles_no_data_and_slots from driftpy.oracles.oracle_id import get_oracle_id from driftpy.types import ( OracleInfo, @@ -64,7 +64,7 @@ async def subscribe(self): perp_market_indexes, spot_market_indexes, oracle_infos, - ) = await find_all_market_and_oracles(self.program) + ) = await find_all_market_and_oracles_no_data_and_slots(self.program) self.perp_market_indexes = perp_market_indexes self.spot_market_indexes = spot_market_indexes self.oracle_infos = oracle_infos diff --git a/src/driftpy/accounts/ws/account_subscriber.py b/src/driftpy/accounts/ws/account_subscriber.py index 1f04cb12..3c0a6de0 100644 --- a/src/driftpy/accounts/ws/account_subscriber.py +++ b/src/driftpy/accounts/ws/account_subscriber.py @@ -1,23 +1,19 @@ import asyncio -from typing import Optional +from typing import Callable, Generic, Optional, TypeVar, cast -from anchorpy import Program -from solders.pubkey import Pubkey +import websockets +import websockets.exceptions # force eager imports +from anchorpy.program.core import Program from solana.rpc.commitment import Commitment +from solana.rpc.websocket_api import SolanaWsClientProtocol, connect +from solders.pubkey import Pubkey -from driftpy.accounts import get_account_data_and_slot from driftpy.accounts import ( - UserAccountSubscriber, DataAndSlot, + UserAccountSubscriber, UserStatsAccountSubscriber, + get_account_data_and_slot, ) - -import websockets -import websockets.exceptions # force eager imports -from solana.rpc.websocket_api import connect - -from typing import cast, Generic, TypeVar, Callable - from driftpy.types import get_ws_url T = TypeVar("T") @@ -30,7 +26,7 @@ def __init__( self, pubkey: Pubkey, program: Program, - commitment: Commitment = "confirmed", + commitment: Commitment = Commitment("confirmed"), decode: Optional[Callable[[bytes], T]] = None, initial_data: Optional[DataAndSlot] = None, ): @@ -42,7 +38,7 @@ def __init__( self.decode = ( decode if decode is not None else self.program.coder.accounts.decode ) - self.ws = None + self.ws: Optional[SolanaWsClientProtocol] = None async def subscribe(self): if self.data_and_slot is None: @@ -60,8 +56,8 @@ async def subscribe_ws(self): async for ws in connect(ws_endpoint): try: - self.ws = ws - await ws.account_subscribe( + self.ws = cast(SolanaWsClientProtocol, ws) + await self.ws.account_subscribe( self.pubkey, commitment=self.commitment, encoding="base64", @@ -82,7 +78,7 @@ async def subscribe_ws(self): except Exception: print("Error processing account data") break - await ws.account_unsubscribe(subscription_id) + await self.ws.account_unsubscribe(subscription_id) except websockets.exceptions.ConnectionClosed: print("Websocket closed, reconnecting...") continue diff --git a/src/driftpy/accounts/ws/drift_client.py b/src/driftpy/accounts/ws/drift_client.py index fa64d09e..91647a8e 100644 --- a/src/driftpy/accounts/ws/drift_client.py +++ b/src/driftpy/accounts/ws/drift_client.py @@ -1,7 +1,7 @@ import asyncio from typing import Optional, Sequence, Union -from anchorpy import Program +from anchorpy.program.core import Program from solana.rpc.commitment import Commitment from driftpy.accounts.oracle import get_oracle_decode_fn @@ -11,7 +11,12 @@ FullOracleWrapper, ) from driftpy.accounts.ws.account_subscriber import WebsocketAccountSubscriber -from driftpy.addresses import * +from driftpy.addresses import ( + Pubkey, + get_perp_market_public_key, + get_spot_market_public_key, + get_state_public_key, +) from driftpy.constants.config import find_all_market_and_oracles from driftpy.constants.perp_markets import mainnet_perp_market_configs from driftpy.market_map.market_map import MarketMap @@ -35,7 +40,7 @@ def __init__( spot_market_indexes: Sequence[int], full_oracle_wrappers: Sequence[FullOracleWrapper], should_find_all_markets_and_oracles: bool, - commitment: Commitment = "confirmed", + commitment: Commitment = Commitment("confirmed"), ): self.program = program self.commitment = commitment @@ -71,7 +76,8 @@ async def subscribe(self): perp_ds, spot_ds, full_oracle_wrappers, - ) = await find_all_market_and_oracles(self.program, data_and_slots=True) + ) = await find_all_market_and_oracles(self.program) + self.perp_market_indexes = [ data_and_slot.data.market_index for data_and_slot in perp_ds ] @@ -82,14 +88,14 @@ async def subscribe(self): spot_market_config = MarketMapConfig( self.program, - MarketType.Spot(), + MarketType.Spot(), # type: ignore WebsocketConfig(), self.program.provider.connection, ) perp_market_config = MarketMapConfig( self.program, - MarketType.Perp(), + MarketType.Perp(), # type: ignore WebsocketConfig(), self.program.provider.connection, ) @@ -183,8 +189,16 @@ async def subscribe_to_oracle(self, full_oracle_wrapper: FullOracleWrapper): await oracle_subscriber.subscribe() self.oracle_subscribers[oracle_id] = oracle_subscriber - async def subscribe_to_oracle_info(self, oracle_info: OracleInfo): - oracle_id = get_oracle_id(oracle_info.pubkey, oracle_info.source) + async def subscribe_to_oracle_info( + self, oracle_info: OracleInfo | FullOracleWrapper + ): + source = None + if isinstance(oracle_info, FullOracleWrapper): + source = oracle_info.oracle_source + else: + source = oracle_info.source + + oracle_id = get_oracle_id(oracle_info.pubkey, source) if oracle_info.pubkey == Pubkey.default(): return @@ -195,7 +209,7 @@ async def subscribe_to_oracle_info(self, oracle_info: OracleInfo): oracle_info.pubkey, self.program, self.commitment, - get_oracle_decode_fn(oracle_info.source), + get_oracle_decode_fn(source), ) await oracle_subscriber.subscribe() @@ -234,6 +248,8 @@ async def add_oracle(self, oracle_info: OracleInfo): return await self.subscribe_to_oracle_info(oracle_info) def get_state_account_and_slot(self) -> Optional[DataAndSlot[StateAccount]]: + if not self.state_subscriber: + raise ValueError("State subscriber not found") return self.state_subscriber.data_and_slot def get_perp_market_and_slot( diff --git a/src/driftpy/accounts/ws/user_stats.py b/src/driftpy/accounts/ws/user_stats.py index 2e569377..4069e719 100644 --- a/src/driftpy/accounts/ws/user_stats.py +++ b/src/driftpy/accounts/ws/user_stats.py @@ -1,10 +1,9 @@ from typing import Optional from driftpy.accounts import DataAndSlot -from driftpy.types import UserStatsAccount - -from driftpy.accounts.ws.account_subscriber import WebsocketAccountSubscriber from driftpy.accounts.types import UserStatsAccountSubscriber +from driftpy.accounts.ws.account_subscriber import WebsocketAccountSubscriber +from driftpy.types import UserStatsAccount class WebsocketUserStatsAccountSubscriber( diff --git a/src/driftpy/constants/config.py b/src/driftpy/constants/config.py index ce02d0bc..7d3fa967 100644 --- a/src/driftpy/constants/config.py +++ b/src/driftpy/constants/config.py @@ -4,7 +4,7 @@ from typing import Literal, Optional, Sequence, Tuple, Union import jsonrpcclient -from anchorpy import Program +from anchorpy.program.core import Program from solders.pubkey import Pubkey from driftpy.accounts.oracle import decode_oracle @@ -84,142 +84,147 @@ class Config: } -async def find_all_market_and_oracles( - program: Program, data_and_slots: bool = False +async def find_all_market_and_oracles_no_data_and_slots( + program: Program, ) -> Tuple[ - Union[list[int], list[DataAndSlot[PerpMarketAccount]]], - Union[list[int], list[DataAndSlot[SpotMarketAccount]]], - Union[list[OracleInfo], list[FullOracleWrapper]], + list[int], + list[int], + list[OracleInfo], ]: - if not data_and_slots: - perp_market_indexes = [] - spot_market_indexes = [] - oracle_infos = {} - - perp_markets = await program.account["PerpMarket"].all() - for perp_market in perp_markets: - perp_market_indexes.append(perp_market.account.market_index) - oracle = perp_market.account.amm.oracle - oracle_source = perp_market.account.amm.oracle_source - oracle_infos[str(oracle)] = OracleInfo(oracle, oracle_source) - - spot_markets = await program.account["SpotMarket"].all() - for spot_market in spot_markets: - spot_market_indexes.append(spot_market.account.market_index) - oracle = spot_market.account.oracle - oracle_source = spot_market.account.oracle_source - oracle_infos[str(oracle)] = OracleInfo(oracle, oracle_source) - - return perp_market_indexes, spot_market_indexes, oracle_infos.values() - else: - perp_markets = [] - spot_markets = [] - oracle_infos = {} - - perp_filters = [{"memcmp": {"offset": 0, "bytes": "2pTyMkwXuti"}}] - spot_filters = [{"memcmp": {"offset": 0, "bytes": "HqqNdyfVbzv"}}] - - perp_request = jsonrpcclient.request( - "getProgramAccounts", - ( - str(program.program_id), - {"filters": perp_filters, "encoding": "base64", "withContext": True}, - ), - ) - - post = program.provider.connection._provider.session.post( - program.provider.connection._provider.endpoint_uri, - json=perp_request, - headers={"content-encoding": "gzip"}, - ) - resp = await asyncio.wait_for(post, timeout=10) - parsed_resp = jsonrpcclient.parse(resp.json()) - - if isinstance(parsed_resp, jsonrpcclient.Error): - raise ValueError(f"Error fetching perp markets: {parsed_resp.message}") - - if not isinstance(parsed_resp, jsonrpcclient.Ok): - raise ValueError(f"Error fetching perp markets - not ok: {parsed_resp}") - - perp_slot = int(parsed_resp.result["context"]["slot"]) - perp_markets: list[PerpMarketAccount] = [] - for account in parsed_resp.result["value"]: - perp_market = decode_account(account["account"]["data"][0], program) - perp_markets.append(perp_market) - - perp_ds: list[DataAndSlot] = [ - DataAndSlot(perp_slot, perp_market) for perp_market in perp_markets - ] - - spot_request = jsonrpcclient.request( - "getProgramAccounts", - ( - str(program.program_id), - {"filters": spot_filters, "encoding": "base64", "withContext": True}, - ), - ) - - post = program.provider.connection._provider.session.post( - program.provider.connection._provider.endpoint_uri, - json=spot_request, - headers={"content-encoding": "gzip"}, - ) - resp = await asyncio.wait_for(post, timeout=10) - parsed_resp = jsonrpcclient.parse(resp.json()) - - if isinstance(parsed_resp, jsonrpcclient.Error): - raise ValueError(f"Error fetching spot markets: {parsed_resp.message}") - if not isinstance(parsed_resp, jsonrpcclient.Ok): - raise ValueError(f"Error fetching spot markets - not ok: {parsed_resp}") - - spot_slot = int(parsed_resp.result["context"]["slot"]) + perp_market_indexes = [] + spot_market_indexes = [] + oracle_infos: dict[str, OracleInfo] = {} - spot_markets: list[SpotMarketAccount] = [] - for account in parsed_resp.result["value"]: - spot_market = decode_account(account["account"]["data"][0], program) - spot_markets.append(spot_market) + perp_markets = await program.account["PerpMarket"].all() + for perp_market in perp_markets: + perp_market_indexes.append(perp_market.account.market_index) + oracle = perp_market.account.amm.oracle + oracle_source = perp_market.account.amm.oracle_source + oracle_infos[str(oracle)] = OracleInfo(oracle, oracle_source) - spot_ds: list[DataAndSlot] = [ - DataAndSlot(spot_slot, spot_market) for spot_market in spot_markets - ] + spot_markets = await program.account["SpotMarket"].all() + for spot_market in spot_markets: + spot_market_indexes.append(spot_market.account.market_index) + oracle = spot_market.account.oracle + oracle_source = spot_market.account.oracle_source + oracle_infos[str(oracle)] = OracleInfo(oracle, oracle_source) - oracle_infos.update( - {market.amm.oracle: market.amm.oracle_source for market in perp_markets} - ) - oracle_infos.update( - {market.oracle: market.oracle_source for market in spot_markets} - ) + return perp_market_indexes, spot_market_indexes, list(oracle_infos.values()) - oracle_keys = list(oracle_infos.keys()) - oracle_ais = await program.provider.connection.get_multiple_accounts( - oracle_keys +async def find_all_market_and_oracles( + program: Program, +) -> Tuple[ + list[DataAndSlot[PerpMarketAccount]], + list[DataAndSlot[SpotMarketAccount]], + list[FullOracleWrapper], +]: + perp_markets = [] + spot_markets = [] + oracle_infos = {} + + perp_filters = [{"memcmp": {"offset": 0, "bytes": "2pTyMkwXuti"}}] + spot_filters = [{"memcmp": {"offset": 0, "bytes": "HqqNdyfVbzv"}}] + + perp_request = jsonrpcclient.request( + "getProgramAccounts", + ( + str(program.program_id), + {"filters": perp_filters, "encoding": "base64", "withContext": True}, + ), + ) + + post = program.provider.connection._provider.session.post( + program.provider.connection._provider.endpoint_uri, + json=perp_request, + headers={"content-encoding": "gzip"}, + ) + resp = await asyncio.wait_for(post, timeout=10) + parsed_resp = jsonrpcclient.parse(resp.json()) + + if isinstance(parsed_resp, jsonrpcclient.Error): + raise ValueError(f"Error fetching perp markets: {parsed_resp.message}") + + if not isinstance(parsed_resp, jsonrpcclient.Ok): + raise ValueError(f"Error fetching perp markets - not ok: {parsed_resp}") + + perp_slot = int(parsed_resp.result["context"]["slot"]) + perp_markets: list[PerpMarketAccount] = [] + for account in parsed_resp.result["value"]: + perp_market = decode_account(account["account"]["data"][0], program) + perp_markets.append(perp_market) + + perp_ds: list[DataAndSlot] = [ + DataAndSlot(perp_slot, perp_market) for perp_market in perp_markets + ] + + spot_request = jsonrpcclient.request( + "getProgramAccounts", + ( + str(program.program_id), + {"filters": spot_filters, "encoding": "base64", "withContext": True}, + ), + ) + + post = program.provider.connection._provider.session.post( + program.provider.connection._provider.endpoint_uri, + json=spot_request, + headers={"content-encoding": "gzip"}, + ) + resp = await asyncio.wait_for(post, timeout=10) + parsed_resp = jsonrpcclient.parse(resp.json()) + + if isinstance(parsed_resp, jsonrpcclient.Error): + raise ValueError(f"Error fetching spot markets: {parsed_resp.message}") + if not isinstance(parsed_resp, jsonrpcclient.Ok): + raise ValueError(f"Error fetching spot markets - not ok: {parsed_resp}") + + spot_slot = int(parsed_resp.result["context"]["slot"]) + + spot_markets: list[SpotMarketAccount] = [] + for account in parsed_resp.result["value"]: + spot_market = decode_account(account["account"]["data"][0], program) + spot_markets.append(spot_market) + + spot_ds: list[DataAndSlot] = [ + DataAndSlot(spot_slot, spot_market) for spot_market in spot_markets + ] + + oracle_infos.update( + {market.amm.oracle: market.amm.oracle_source for market in perp_markets} + ) + oracle_infos.update( + {market.oracle: market.oracle_source for market in spot_markets} + ) + + oracle_keys = list(oracle_infos.keys()) + + oracle_ais = await program.provider.connection.get_multiple_accounts(oracle_keys) + + oracle_slot = oracle_ais.context.slot + + oracle_price_datas = [ + decode_oracle(account.data, oracle_infos[oracle_keys[i]]) + for i, account in enumerate(oracle_ais.value) + if account is not None + ] + + oracle_ds: list[DataAndSlot] = [ + DataAndSlot(oracle_slot, oracle_price_data) + for oracle_price_data in oracle_price_datas + ] + + full_oracle_wrappers: list[FullOracleWrapper] = [ + FullOracleWrapper( + pubkey=oracle_keys[i], + oracle_source=oracle_infos[oracle_keys[i]], + oracle_price_data_and_slot=oracle_ds[i], ) + for i in range(len(oracle_keys)) + if oracle_ais.value[i] is not None + ] - oracle_slot = oracle_ais.context.slot - - oracle_price_datas = [ - decode_oracle(account.data, oracle_infos[oracle_keys[i]]) - for i, account in enumerate(oracle_ais.value) - if account is not None - ] - - oracle_ds: list[DataAndSlot] = [ - DataAndSlot(oracle_slot, oracle_price_data) - for oracle_price_data in oracle_price_datas - ] - - full_oracle_wrappers: list[FullOracleWrapper] = [ - FullOracleWrapper( - pubkey=oracle_keys[i], - oracle_source=oracle_infos[oracle_keys[i]], - oracle_price_data_and_slot=oracle_ds[i], - ) - for i in range(len(oracle_keys)) - if oracle_ais.value[i] is not None - ] - - return perp_ds, spot_ds, full_oracle_wrappers + return perp_ds, spot_ds, full_oracle_wrappers def decode_account(decoded_data: bytes | str, program): diff --git a/src/driftpy/drift_client.py b/src/driftpy/drift_client.py index 73910120..a92a430c 100644 --- a/src/driftpy/drift_client.py +++ b/src/driftpy/drift_client.py @@ -258,6 +258,8 @@ def __init__( ) async def subscribe(self): + if self.account_subscriber is None: + raise ValueError("No account subscriber found") await self.account_subscriber.subscribe() if self.enforce_tx_sequencing: await self.load_sequence_info() @@ -300,6 +302,8 @@ async def add_user_stats(self, authority: Pubkey): await self.user_stats[authority].fetch_accounts() async def unsubscribe(self): + if self.account_subscriber is None: + raise ValueError("No account subscriber found") await self.account_subscriber.unsubscribe() def get_user(self, sub_account_id=None) -> DriftUser: diff --git a/src/driftpy/drift_user.py b/src/driftpy/drift_user.py index 6f36ca38..1f705d1c 100644 --- a/src/driftpy/drift_user.py +++ b/src/driftpy/drift_user.py @@ -6,16 +6,20 @@ from driftpy.account_subscription_config import AccountSubscriptionConfig from driftpy.accounts.oracle import * from driftpy.math.amm import calculate_market_open_bid_ask -from driftpy.math.fuel import calculate_insurance_fuel_bonus -from driftpy.math.fuel import calculate_perp_fuel_bonus -from driftpy.math.fuel import calculate_spot_fuel_bonus +from driftpy.math.fuel import ( + calculate_insurance_fuel_bonus, + calculate_perp_fuel_bonus, + calculate_spot_fuel_bonus, +) from driftpy.math.margin import * from driftpy.math.oracles import calculate_live_oracle_twap from driftpy.math.perp_position import * from driftpy.math.spot_balance import get_strict_token_value from driftpy.math.spot_market import * -from driftpy.math.spot_position import get_worst_case_token_amounts -from driftpy.math.spot_position import is_spot_position_available +from driftpy.math.spot_position import ( + get_worst_case_token_amounts, + is_spot_position_available, +) from driftpy.oracles.strict_oracle_price import StrictOraclePrice from driftpy.types import OraclePriceData @@ -27,9 +31,7 @@ def __init__( self, drift_client, user_public_key: Pubkey, - account_subscription: Optional[ - AccountSubscriptionConfig - ] = AccountSubscriptionConfig.default(), + account_subscription: AccountSubscriptionConfig = AccountSubscriptionConfig.default(), ): """Initialize the user object @@ -52,19 +54,23 @@ def __init__( ) async def subscribe(self): + if self.account_subscriber is None: + raise ValueError("No account subscriber found") await self.account_subscriber.subscribe() def unsubscribe(self): + if self.account_subscriber is None: + raise ValueError("No account subscriber found") self.account_subscriber.unsubscribe() def get_oracle_data_for_spot_market( self, market_index: int - ) -> Optional[OraclePriceData]: + ) -> OraclePriceData | None: return self.drift_client.get_oracle_price_data_for_spot_market(market_index) def get_oracle_data_for_perp_market( self, market_index: int - ) -> Optional[OraclePriceData]: + ) -> OraclePriceData | None: return self.drift_client.get_oracle_price_data_for_perp_market(market_index) def get_perp_market_account(self, market_index: int) -> PerpMarketAccount: diff --git a/src/driftpy/tx/jito_subscriber.py b/src/driftpy/tx/jito_subscriber.py index cf5789c3..8d661876 100644 --- a/src/driftpy/tx/jito_subscriber.py +++ b/src/driftpy/tx/jito_subscriber.py @@ -1,25 +1,29 @@ +raise ImportError( + "The jito_subscriber module is deprecated and has been removed in driftpy." +) + import asyncio import random - from typing import Optional, Tuple, Union -from solders.keypair import Keypair # type: ignore -from solders.pubkey import Pubkey # type: ignore - -from solana.rpc.async_api import AsyncClient -from solana.rpc.commitment import Confirmed - -from solders.system_program import TransferParams, transfer - -from jito_searcher_client.async_searcher import get_async_searcher_client # type: ignore -from jito_searcher_client.generated.searcher_pb2_grpc import SearcherServiceStub # type: ignore +from jito_searcher_client.async_searcher import ( + get_async_searcher_client, # type: ignore +) from jito_searcher_client.generated.searcher_pb2 import ( - ConnectedLeadersResponse, ConnectedLeadersRequest, + ConnectedLeadersResponse, GetTipAccountsRequest, GetTipAccountsResponse, SubscribeBundleResultsRequest, ) # type: ignore +from jito_searcher_client.generated.searcher_pb2_grpc import ( + SearcherServiceStub, # type: ignore +) +from solana.rpc.async_api import AsyncClient +from solana.rpc.commitment import Confirmed +from solders.keypair import Keypair # type: ignore +from solders.pubkey import Pubkey # type: ignore +from solders.system_program import TransferParams, transfer class JitoSubscriber: diff --git a/src/driftpy/tx/jito_tx_sender.py b/src/driftpy/tx/jito_tx_sender.py index 73e4fc3c..77e7df94 100644 --- a/src/driftpy/tx/jito_tx_sender.py +++ b/src/driftpy/tx/jito_tx_sender.py @@ -1,11 +1,22 @@ -import asyncio +raise ImportError( + "The jito_tx_sender module is deprecated and has been removed in driftpy. " +) +import asyncio from typing import Optional, Union -from solana.transaction import Transaction -from solana.rpc.types import TxOpts +from jito_searcher_client.convert import ( + tx_to_protobuf_packet, + versioned_tx_to_protobuf_packet, +) +from jito_searcher_client.generated.bundle_pb2 import Bundle +from jito_searcher_client.generated.searcher_pb2 import ( + SendBundleRequest, + SendBundleResponse, +) from solana.rpc.commitment import Commitment, Confirmed - +from solana.rpc.types import TxOpts +from solana.transaction import Transaction from solders.keypair import Keypair # type: ignore from solders.transaction import VersionedTransaction # type: ignore @@ -15,16 +26,6 @@ from driftpy.tx.jito_subscriber import JitoSubscriber from driftpy.tx.types import TxSigAndSlot -from jito_searcher_client.convert import ( - versioned_tx_to_protobuf_packet, - tx_to_protobuf_packet, -) -from jito_searcher_client.generated.bundle_pb2 import Bundle -from jito_searcher_client.generated.searcher_pb2 import ( - SendBundleRequest, - SendBundleResponse, -) - class JitoTxSender(FastTxSender): def __init__( diff --git a/src/driftpy/types.py b/src/driftpy/types.py index ec4dc9e9..5a8982ea 100644 --- a/src/driftpy/types.py +++ b/src/driftpy/types.py @@ -5,6 +5,7 @@ from urllib.parse import urlparse, urlunparse from borsh_construct.enum import _rust_enum +from solana.rpc.commitment import Commitment from solders.pubkey import Pubkey from sumtypes import constructor @@ -1412,3 +1413,10 @@ class PriceFeedMessage: class PriceUpdateV2: price_message: PriceFeedMessage posted_slot: int + + +@dataclass +class GrpcConfig: + endpoint: str + token: str + commitment: Commitment = Commitment("confirmed") diff --git a/src/driftpy/user_map/user_map_config.py b/src/driftpy/user_map/user_map_config.py index 58e22fdb..bf40b0c6 100644 --- a/src/driftpy/user_map/user_map_config.py +++ b/src/driftpy/user_map/user_map_config.py @@ -1,7 +1,9 @@ -from solana.rpc.async_api import AsyncClient -from solana.rpc.commitment import Commitment from dataclasses import dataclass from typing import Optional, Union + +from solana.rpc.async_api import AsyncClient +from solana.rpc.commitment import Commitment + from driftpy.drift_client import DriftClient