diff --git a/Makefile b/Makefile index 94f55d2a..2485ee70 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,6 @@ copy-proto: done tests: - pytest -v tests/** + pytest -v .PHONY: all gen gen-client copy-proto tests diff --git a/Pipfile b/Pipfile index f07ae931..97f04274 100644 --- a/Pipfile +++ b/Pipfile @@ -25,6 +25,7 @@ websockets = "*" [dev-packages] pytest = "*" pytest-asyncio = "*" +pytest-grpc = "*" requests-mock = "*" [requires] diff --git a/Pipfile.lock b/Pipfile.lock index 4865929d..58fc968b 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "ddd9c0acafbf86fc3b26c88650bee0a2aa19d05a537541bfcbd8c8c2a1401266" + "sha256": "414c3e95a8abb1f4986d0ae4814e25f8c7eba47e5343b5c67cf0bab32b21eadc" }, "pipfile-spec": 6, "requires": { @@ -26,96 +26,97 @@ }, "aiohttp": { "hashes": [ - "sha256:03543dcf98a6619254b409be2d22b51f21ec66272be4ebda7b04e6412e4b2e14", - "sha256:03baa76b730e4e15a45f81dfe29a8d910314143414e528737f8589ec60cf7391", - "sha256:0a63f03189a6fa7c900226e3ef5ba4d3bd047e18f445e69adbd65af433add5a2", - "sha256:10c8cefcff98fd9168cdd86c4da8b84baaa90bf2da2269c6161984e6737bf23e", - "sha256:147ae376f14b55f4f3c2b118b95be50a369b89b38a971e80a17c3fd623f280c9", - "sha256:176a64b24c0935869d5bbc4c96e82f89f643bcdf08ec947701b9dbb3c956b7dd", - "sha256:17b79c2963db82086229012cff93ea55196ed31f6493bb1ccd2c62f1724324e4", - "sha256:1a45865451439eb320784918617ba54b7a377e3501fb70402ab84d38c2cd891b", - "sha256:1b3ea7edd2d24538959c1c1abf97c744d879d4e541d38305f9bd7d9b10c9ec41", - "sha256:22f6eab15b6db242499a16de87939a342f5a950ad0abaf1532038e2ce7d31567", - "sha256:3032dcb1c35bc330134a5b8a5d4f68c1a87252dfc6e1262c65a7e30e62298275", - "sha256:33587f26dcee66efb2fff3c177547bd0449ab7edf1b73a7f5dea1e38609a0c54", - "sha256:34ce9f93a4a68d1272d26030655dd1b58ff727b3ed2a33d80ec433561b03d67a", - "sha256:3a80464982d41b1fbfe3154e440ba4904b71c1a53e9cd584098cd41efdb188ef", - "sha256:3b90467ebc3d9fa5b0f9b6489dfb2c304a1db7b9946fa92aa76a831b9d587e99", - "sha256:3d89efa095ca7d442a6d0cbc755f9e08190ba40069b235c9886a8763b03785da", - "sha256:3d8ef1a630519a26d6760bc695842579cb09e373c5f227a21b67dc3eb16cfea4", - "sha256:3f43255086fe25e36fd5ed8f2ee47477408a73ef00e804cb2b5cba4bf2ac7f5e", - "sha256:40653609b3bf50611356e6b6554e3a331f6879fa7116f3959b20e3528783e699", - "sha256:41a86a69bb63bb2fc3dc9ad5ea9f10f1c9c8e282b471931be0268ddd09430b04", - "sha256:493f5bc2f8307286b7799c6d899d388bbaa7dfa6c4caf4f97ef7521b9cb13719", - "sha256:4a6cadebe132e90cefa77e45f2d2f1a4b2ce5c6b1bfc1656c1ddafcfe4ba8131", - "sha256:4c745b109057e7e5f1848c689ee4fb3a016c8d4d92da52b312f8a509f83aa05e", - "sha256:4d347a172f866cd1d93126d9b239fcbe682acb39b48ee0873c73c933dd23bd0f", - "sha256:4dac314662f4e2aa5009977b652d9b8db7121b46c38f2073bfeed9f4049732cd", - "sha256:4ddaae3f3d32fc2cb4c53fab020b69a05c8ab1f02e0e59665c6f7a0d3a5be54f", - "sha256:5393fb786a9e23e4799fec788e7e735de18052f83682ce2dfcabaf1c00c2c08e", - "sha256:59f029a5f6e2d679296db7bee982bb3d20c088e52a2977e3175faf31d6fb75d1", - "sha256:5a7bdf9e57126dc345b683c3632e8ba317c31d2a41acd5800c10640387d193ed", - "sha256:5b3f2e06a512e94722886c0827bee9807c86a9f698fac6b3aee841fab49bbfb4", - "sha256:5ce45967538fb747370308d3145aa68a074bdecb4f3a300869590f725ced69c1", - "sha256:5e14f25765a578a0a634d5f0cd1e2c3f53964553a00347998dfdf96b8137f777", - "sha256:618c901dd3aad4ace71dfa0f5e82e88b46ef57e3239fc7027773cb6d4ed53531", - "sha256:652b1bff4f15f6287550b4670546a2947f2a4575b6c6dff7760eafb22eacbf0b", - "sha256:6c08e8ed6fa3d477e501ec9db169bfac8140e830aa372d77e4a43084d8dd91ab", - "sha256:6ddb2a2026c3f6a68c3998a6c47ab6795e4127315d2e35a09997da21865757f8", - "sha256:6e601588f2b502c93c30cd5a45bfc665faaf37bbe835b7cfd461753068232074", - "sha256:6e74dd54f7239fcffe07913ff8b964e28b712f09846e20de78676ce2a3dc0bfc", - "sha256:7235604476a76ef249bd64cb8274ed24ccf6995c4a8b51a237005ee7a57e8643", - "sha256:7ab43061a0c81198d88f39aaf90dae9a7744620978f7ef3e3708339b8ed2ef01", - "sha256:7c7837fe8037e96b6dd5cfcf47263c1620a9d332a87ec06a6ca4564e56bd0f36", - "sha256:80575ba9377c5171407a06d0196b2310b679dc752d02a1fcaa2bc20b235dbf24", - "sha256:80a37fe8f7c1e6ce8f2d9c411676e4bc633a8462844e38f46156d07a7d401654", - "sha256:8189c56eb0ddbb95bfadb8f60ea1b22fcfa659396ea36f6adcc521213cd7b44d", - "sha256:854f422ac44af92bfe172d8e73229c270dc09b96535e8a548f99c84f82dde241", - "sha256:880e15bb6dad90549b43f796b391cfffd7af373f4646784795e20d92606b7a51", - "sha256:8b631e26df63e52f7cce0cce6507b7a7f1bc9b0c501fcde69742130b32e8782f", - "sha256:8c29c77cc57e40f84acef9bfb904373a4e89a4e8b74e71aa8075c021ec9078c2", - "sha256:91f6d540163f90bbaef9387e65f18f73ffd7c79f5225ac3d3f61df7b0d01ad15", - "sha256:92c0cea74a2a81c4c76b62ea1cac163ecb20fb3ba3a75c909b9fa71b4ad493cf", - "sha256:9bcb89336efa095ea21b30f9e686763f2be4478f1b0a616969551982c4ee4c3b", - "sha256:a1f4689c9a1462f3df0a1f7e797791cd6b124ddbee2b570d34e7f38ade0e2c71", - "sha256:a3fec6a4cb5551721cdd70473eb009d90935b4063acc5f40905d40ecfea23e05", - "sha256:a5d794d1ae64e7753e405ba58e08fcfa73e3fad93ef9b7e31112ef3c9a0efb52", - "sha256:a86d42d7cba1cec432d47ab13b6637bee393a10f664c425ea7b305d1301ca1a3", - "sha256:adfbc22e87365a6e564c804c58fc44ff7727deea782d175c33602737b7feadb6", - "sha256:aeb29c84bb53a84b1a81c6c09d24cf33bb8432cc5c39979021cc0f98c1292a1a", - "sha256:aede4df4eeb926c8fa70de46c340a1bc2c6079e1c40ccf7b0eae1313ffd33519", - "sha256:b744c33b6f14ca26b7544e8d8aadff6b765a80ad6164fb1a430bbadd593dfb1a", - "sha256:b7a00a9ed8d6e725b55ef98b1b35c88013245f35f68b1b12c5cd4100dddac333", - "sha256:bb96fa6b56bb536c42d6a4a87dfca570ff8e52de2d63cabebfd6fb67049c34b6", - "sha256:bbcf1a76cf6f6dacf2c7f4d2ebd411438c275faa1dc0c68e46eb84eebd05dd7d", - "sha256:bca5f24726e2919de94f047739d0a4fc01372801a3672708260546aa2601bf57", - "sha256:bf2e1a9162c1e441bf805a1fd166e249d574ca04e03b34f97e2928769e91ab5c", - "sha256:c4eb3b82ca349cf6fadcdc7abcc8b3a50ab74a62e9113ab7a8ebc268aad35bb9", - "sha256:c6cc15d58053c76eacac5fa9152d7d84b8d67b3fde92709195cb984cfb3475ea", - "sha256:c6cd05ea06daca6ad6a4ca3ba7fe7dc5b5de063ff4daec6170ec0f9979f6c332", - "sha256:c844fd628851c0bc309f3c801b3a3d58ce430b2ce5b359cd918a5a76d0b20cb5", - "sha256:c9cb1565a7ad52e096a6988e2ee0397f72fe056dadf75d17fa6b5aebaea05622", - "sha256:cab9401de3ea52b4b4c6971db5fb5c999bd4260898af972bf23de1c6b5dd9d71", - "sha256:cd468460eefef601ece4428d3cf4562459157c0f6523db89365202c31b6daebb", - "sha256:d1e6a862b76f34395a985b3cd39a0d949ca80a70b6ebdea37d3ab39ceea6698a", - "sha256:d1f9282c5f2b5e241034a009779e7b2a1aa045f667ff521e7948ea9b56e0c5ff", - "sha256:d265f09a75a79a788237d7f9054f929ced2e69eb0bb79de3798c468d8a90f945", - "sha256:db3fc6120bce9f446d13b1b834ea5b15341ca9ff3f335e4a951a6ead31105480", - "sha256:dbf3a08a06b3f433013c143ebd72c15cac33d2914b8ea4bea7ac2c23578815d6", - "sha256:de04b491d0e5007ee1b63a309956eaed959a49f5bb4e84b26c8f5d49de140fa9", - "sha256:e4b09863aae0dc965c3ef36500d891a3ff495a2ea9ae9171e4519963c12ceefd", - "sha256:e595432ac259af2d4630008bf638873d69346372d38255774c0e286951e8b79f", - "sha256:e75b89ac3bd27d2d043b234aa7b734c38ba1b0e43f07787130a0ecac1e12228a", - "sha256:ea9eb976ffdd79d0e893869cfe179a8f60f152d42cb64622fca418cd9b18dc2a", - "sha256:eafb3e874816ebe2a92f5e155f17260034c8c341dad1df25672fb710627c6949", - "sha256:ee3c36df21b5714d49fc4580247947aa64bcbe2939d1b77b4c8dcb8f6c9faecc", - "sha256:f352b62b45dff37b55ddd7b9c0c8672c4dd2eb9c0f9c11d395075a84e2c40f75", - "sha256:fabb87dd8850ef0f7fe2b366d44b77d7e6fa2ea87861ab3844da99291e81e60f", - "sha256:fe11310ae1e4cd560035598c3f29d86cef39a83d244c7466f95c27ae04850f10", - "sha256:fe7ba4a51f33ab275515f66b0a236bcde4fb5561498fe8f898d4e549b2e4509f" + "sha256:00ad4b6f185ec67f3e6562e8a1d2b69660be43070bd0ef6fcec5211154c7df67", + "sha256:0175d745d9e85c40dcc51c8f88c74bfbaef9e7afeeeb9d03c37977270303064c", + "sha256:01d4c0c874aa4ddfb8098e85d10b5e875a70adc63db91f1ae65a4b04d3344cda", + "sha256:043d2299f6dfdc92f0ac5e995dfc56668e1587cea7f9aa9d8a78a1b6554e5755", + "sha256:0c413c633d0512df4dc7fd2373ec06cc6a815b7b6d6c2f208ada7e9e93a5061d", + "sha256:0d21c684808288a98914e5aaf2a7c6a3179d4df11d249799c32d1808e79503b5", + "sha256:0e584a10f204a617d71d359fe383406305a4b595b333721fa50b867b4a0a1548", + "sha256:1274477e4c71ce8cfe6c1ec2f806d57c015ebf84d83373676036e256bc55d690", + "sha256:13bf85afc99ce6f9ee3567b04501f18f9f8dbbb2ea11ed1a2e079670403a7c84", + "sha256:153c2549f6c004d2754cc60603d4668899c9895b8a89397444a9c4efa282aaf4", + "sha256:1f7372f7341fcc16f57b2caded43e81ddd18df53320b6f9f042acad41f8e049a", + "sha256:23fb25a9f0a1ca1f24c0a371523546366bb642397c94ab45ad3aedf2941cec6a", + "sha256:28c543e54710d6158fc6f439296c7865b29e0b616629767e685a7185fab4a6b9", + "sha256:2a482e6da906d5e6e653be079b29bc173a48e381600161c9932d89dfae5942ef", + "sha256:2ad5c3c4590bb3cc28b4382f031f3783f25ec223557124c68754a2231d989e2b", + "sha256:2ce2ac5708501afc4847221a521f7e4b245abf5178cf5ddae9d5b3856ddb2f3a", + "sha256:2cf57fb50be5f52bda004b8893e63b48530ed9f0d6c96c84620dc92fe3cd9b9d", + "sha256:2e1b1e51b0774408f091d268648e3d57f7260c1682e7d3a63cb00d22d71bb945", + "sha256:2e2e9839e14dd5308ee773c97115f1e0a1cb1d75cbeeee9f33824fa5144c7634", + "sha256:2e460be6978fc24e3df83193dc0cc4de46c9909ed92dd47d349a452ef49325b7", + "sha256:312fcfbacc7880a8da0ae8b6abc6cc7d752e9caa0051a53d217a650b25e9a691", + "sha256:33279701c04351a2914e1100b62b2a7fdb9a25995c4a104259f9a5ead7ed4802", + "sha256:33776e945d89b29251b33a7e7d006ce86447b2cfd66db5e5ded4e5cd0340585c", + "sha256:34dd0c107799dcbbf7d48b53be761a013c0adf5571bf50c4ecad5643fe9cfcd0", + "sha256:3562b06567c06439d8b447037bb655ef69786c590b1de86c7ab81efe1c9c15d8", + "sha256:368a42363c4d70ab52c2c6420a57f190ed3dfaca6a1b19afda8165ee16416a82", + "sha256:4149d34c32f9638f38f544b3977a4c24052042affa895352d3636fa8bffd030a", + "sha256:461908b2578955045efde733719d62f2b649c404189a09a632d245b445c9c975", + "sha256:4a01951fabc4ce26ab791da5f3f24dca6d9a6f24121746eb19756416ff2d881b", + "sha256:4e874cbf8caf8959d2adf572a78bba17cb0e9d7e51bb83d86a3697b686a0ab4d", + "sha256:4f21e83f355643c345177a5d1d8079f9f28b5133bcd154193b799d380331d5d3", + "sha256:5443910d662db951b2e58eb70b0fbe6b6e2ae613477129a5805d0b66c54b6cb7", + "sha256:5798a9aad1879f626589f3df0f8b79b3608a92e9beab10e5fda02c8a2c60db2e", + "sha256:5d20003b635fc6ae3f96d7260281dfaf1894fc3aa24d1888a9b2628e97c241e5", + "sha256:5db3a5b833764280ed7618393832e0853e40f3d3e9aa128ac0ba0f8278d08649", + "sha256:5ed1c46fb119f1b59304b5ec89f834f07124cd23ae5b74288e364477641060ff", + "sha256:62360cb771707cb70a6fd114b9871d20d7dd2163a0feafe43fd115cfe4fe845e", + "sha256:6809a00deaf3810e38c628e9a33271892f815b853605a936e2e9e5129762356c", + "sha256:68c5a82c8779bdfc6367c967a4a1b2aa52cd3595388bf5961a62158ee8a59e22", + "sha256:6e4a280e4b975a2e7745573e3fc9c9ba0d1194a3738ce1cbaa80626cc9b4f4df", + "sha256:6e6783bcc45f397fdebc118d772103d751b54cddf5b60fbcc958382d7dd64f3e", + "sha256:72a860c215e26192379f57cae5ab12b168b75db8271f111019509a1196dfc780", + "sha256:7607ec3ce4993464368505888af5beb446845a014bc676d349efec0e05085905", + "sha256:773dd01706d4db536335fcfae6ea2440a70ceb03dd3e7378f3e815b03c97ab51", + "sha256:78d847e4cde6ecc19125ccbc9bfac4a7ab37c234dd88fbb3c5c524e8e14da543", + "sha256:7dde0009408969a43b04c16cbbe252c4f5ef4574ac226bc8815cd7342d2028b6", + "sha256:80bd372b8d0715c66c974cf57fe363621a02f359f1ec81cba97366948c7fc873", + "sha256:841cd8233cbd2111a0ef0a522ce016357c5e3aff8a8ce92bcfa14cef890d698f", + "sha256:84de26ddf621d7ac4c975dbea4c945860e08cccde492269db4e1538a6a6f3c35", + "sha256:84f8ae3e09a34f35c18fa57f015cc394bd1389bce02503fb30c394d04ee6b938", + "sha256:8af740fc2711ad85f1a5c034a435782fbd5b5f8314c9a3ef071424a8158d7f6b", + "sha256:8b929b9bd7cd7c3939f8bcfffa92fae7480bd1aa425279d51a89327d600c704d", + "sha256:910bec0c49637d213f5d9877105d26e0c4a4de2f8b1b29405ff37e9fc0ad52b8", + "sha256:96943e5dcc37a6529d18766597c491798b7eb7a61d48878611298afc1fca946c", + "sha256:a0215ce6041d501f3155dc219712bc41252d0ab76474615b9700d63d4d9292af", + "sha256:a3cf433f127efa43fee6b90ea4c6edf6c4a17109d1d037d1a52abec84d8f2e42", + "sha256:a6ce61195c6a19c785df04e71a4537e29eaa2c50fe745b732aa937c0c77169f3", + "sha256:a7a75ef35f2df54ad55dbf4b73fe1da96f370e51b10c91f08b19603c64004acc", + "sha256:a94159871304770da4dd371f4291b20cac04e8c94f11bdea1c3478e557fbe0d8", + "sha256:aa1990247f02a54185dc0dff92a6904521172a22664c863a03ff64c42f9b5410", + "sha256:ab88bafedc57dd0aab55fa728ea10c1911f7e4d8b43e1d838a1739f33712921c", + "sha256:ad093e823df03bb3fd37e7dec9d4670c34f9e24aeace76808fc20a507cace825", + "sha256:ae871a964e1987a943d83d6709d20ec6103ca1eaf52f7e0d36ee1b5bebb8b9b9", + "sha256:b0ba0d15164eae3d878260d4c4df859bbdc6466e9e6689c344a13334f988bb53", + "sha256:b5411d82cddd212644cf9360879eb5080f0d5f7d809d03262c50dad02f01421a", + "sha256:b9552ec52cc147dbf1944ac7ac98af7602e51ea2dcd076ed194ca3c0d1c7d0bc", + "sha256:bfb9162dcf01f615462b995a516ba03e769de0789de1cadc0f916265c257e5d8", + "sha256:c0a9034379a37ae42dea7ac1e048352d96286626251862e448933c0f59cbd79c", + "sha256:c1161b345c0a444ebcf46bf0a740ba5dcf50612fd3d0528883fdc0eff578006a", + "sha256:c11f5b099adafb18e65c2c997d57108b5bbeaa9eeee64a84302c0978b1ec948b", + "sha256:c44e65da1de4403d0576473e2344828ef9c4c6244d65cf4b75549bb46d40b8dd", + "sha256:c48c5c0271149cfe467c0ff8eb941279fd6e3f65c9a388c984e0e6cf57538e14", + "sha256:c7a815258e5895d8900aec4454f38dca9aed71085f227537208057853f9d13f2", + "sha256:cae533195e8122584ec87531d6df000ad07737eaa3c81209e85c928854d2195c", + "sha256:cc14be025665dba6202b6a71cfcdb53210cc498e50068bc088076624471f8bb9", + "sha256:cd56db019015b6acfaaf92e1ac40eb8434847d9bf88b4be4efe5bfd260aee692", + "sha256:d827176898a2b0b09694fbd1088c7a31836d1a505c243811c87ae53a3f6273c1", + "sha256:df72ac063b97837a80d80dec8d54c241af059cc9bb42c4de68bd5b61ceb37caa", + "sha256:e5980a746d547a6ba173fd5ee85ce9077e72d118758db05d229044b469d9029a", + "sha256:e5d47ae48db0b2dcf70bc8a3bc72b3de86e2a590fc299fdbbb15af320d2659de", + "sha256:e91d635961bec2d8f19dfeb41a539eb94bd073f075ca6dae6c8dc0ee89ad6f91", + "sha256:ea353162f249c8097ea63c2169dd1aa55de1e8fecbe63412a9bc50816e87b761", + "sha256:eaeed7abfb5d64c539e2db173f63631455f1196c37d9d8d873fc316470dfbacd", + "sha256:eca4bf3734c541dc4f374ad6010a68ff6c6748f00451707f39857f429ca36ced", + "sha256:f83a552443a526ea38d064588613aca983d0ee0038801bc93c0c916428310c28", + "sha256:fb1558def481d84f03b45888473fc5a1f35747b5f334ef4e7a571bc0dfcb11f8", + "sha256:fd1ed388ea7fbed22c4968dd64bab0198de60750a25fe8c0c9d4bef5abe13824" ], "index": "pypi", - "version": "==3.8.4" + "markers": "python_version >= '3.6'", + "version": "==3.8.5" }, "aiosignal": { "hashes": [ @@ -134,11 +135,11 @@ }, "async-timeout": { "hashes": [ - "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15", - "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c" + "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", + "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028" ], - "markers": "python_version >= '3.6'", - "version": "==4.0.2" + "markers": "python_version >= '3.7'", + "version": "==4.0.3" }, "asyncio": { "hashes": [ @@ -172,6 +173,7 @@ "sha256:990dc8e5a5e4feabbdf55207b5315fdd9b73db40be294a19b3752cde9e79d981" ], "index": "pypi", + "markers": "python_version >= '3.5'", "version": "==1.2.0" }, "bip32": { @@ -184,118 +186,118 @@ }, "bitarray": { "hashes": [ - "sha256:0052e0cfa15810b0dbb1e347b2e4676caa1a7a65c6f6838f50aca6518e8bc153", - "sha256:0400c5a6d68dcf4546e763b10239f916fc7145d909b7e72f0fcb372bf1d44b81", - "sha256:0655cb36ac48c7253af3de83e7c1132d04cf999c065a3afdf970d8f0fa0ed180", - "sha256:07a604d41e2a9ee88fb6f8dd6744b4c1845a537970321588485e4a55bd09e403", - "sha256:0d60f26cbfbea04d3960e442ff1d2e439dc0accc10412e0551ec743b399c1595", - "sha256:0d78d26ab9ab3b0bf684fcb4b947af71e164d2c6def892914d10d6b512383d52", - "sha256:11367e4e29d79295b83a3bbfaa9a928531b958e9db37f80497b7c6100950d049", - "sha256:128f398b119751c39abba1395764ff43995d5756844005c9d4db0e97867e6474", - "sha256:14dc0e1938955b340dc364591422a28e7c5d9c4cbb42ba215b6855b7edd5b9dc", - "sha256:15046a69aac33940fe14bdfc049a9ade5e8bd680eb662704e2581d2860be5ff7", - "sha256:158d099722ebf7294385f2071734b90e5665bba3ad56418c81b3fe3f9d39f720", - "sha256:1617c6fbe36f91e4aaa1552da57270e102a8733008d53239eac1d9f2cf15b265", - "sha256:1d8d5df5d0872edb1e1c50cd0d7fc04b0f373ad7b678ff1b1b48228d28c91f25", - "sha256:22a48b5682a6eb235d1a2ac82147e17bb4bb045afcb5869f53f42d1ba34e2bab", - "sha256:252bd62619339818a520d6ef0763086986611a2d27d2f3c0681d3d6ff7d78213", - "sha256:25321952806d070bd12fc652416047438a2f1984011f1e23e4f2391f7e3ab3d2", - "sha256:263e6239203e453a1e33b2232978012966a4e1fec47a1a519f715936e605b4e6", - "sha256:26cd0ec1a556fb5062d0bda13d8664f3bf5b0f9023a0254fbd76db366cd12673", - "sha256:2c5ed8ef5366a33a92bccb423529a8215b6dcc1a1ad095fab360eac9be94bcae", - "sha256:2e9e69d24b557fc614360e61d373b8e3114204c590c84b26ff31ac212a398052", - "sha256:37fb5777f155e5f2abc98e6db00c8bf7def8bcf2e36d736db025fa3cd7ad044e", - "sha256:38bda909b392f80b1fc04d2f86511cdec05e4a6151d0a660a50589ee0da394ae", - "sha256:3f4f8fd69642313e1ec288a22eb2ef49b8b0e6a6fb98afab0fb227a35a06543c", - "sha256:4024882e77dcb19c6e874faca47f637b97e02a9fcddc20289eabd427c641e902", - "sha256:41ef308abe02aed03058451ed17dad1365d4b4d32a7e63efa81a0becbc36b5ff", - "sha256:42b740e565858b51e8e64160ed204a8dd874293d9c78d513548da8b640b2d3c9", - "sha256:4819ad0640348da61d88e4820f2fbc66927cf6378c4fd609259a000c170660b7", - "sha256:4b729d2ee6a8b9ed9573ffd7fb3f66c5b340658013a73e334c8f7dc09d8e2bba", - "sha256:4bf7b7da77a275e937c2a42fcb846af581fc3f698683b9629827acda40bf96d1", - "sha256:4cfd9590a81606fb08adb7e08aefe1eae0b38ef65c82263b08cdb8daca1f6763", - "sha256:4d3503017ba68689b118f921b008750c955b8dd12ede9148cf99b97125670067", - "sha256:4d801f31a88f544b46c707dbfc095d427f81d02bffcfc1732a3359702550b87b", - "sha256:52baaf7c23f4416fc6ab4654cc7290ed0048950775125bed40b89bc331ede0d8", - "sha256:555f7fd1ec7b2d1b911929615df272bc831ff7b57e0d56bd6aefba427ed79c58", - "sha256:5677ca0196bf340c41c72038141e4da9ed0ac8159b7644ed4ae507d016f12787", - "sha256:576f1fd95043959cb2c04aa6835cafaa25c7f8c1b191ce99dbdd41137c6356eb", - "sha256:59b02a18100a0c94dd79d62903d29f830517291dc32fa5e36d08aea37277ae1a", - "sha256:5a862f19c387b9c53423bc5bed097c0394cead5b85dd1b55941d029889c681c3", - "sha256:5b7cdb62535b2c0851011856bb4eed233dfd183b06a254c7826a7b4b7cfaa714", - "sha256:5dabc0c23af19e48470740d4ab22cb04871f636ef297d7ae4e6a0b7f746e5500", - "sha256:67a740475995a6a53f58a922210c3d267d14780dae3cbd997a0ffc0640416fe6", - "sha256:6fd7b5c762a922df8b75080e6f976f4ce62d2b7e7648bb277b44ed482e19cf31", - "sha256:7606369109a1451623837a272c04020d47c92ea9af1bc6d074cbcceb9f9481f2", - "sha256:761bfac893c18d90b82bbdcc243e887ff315059c63f13459397e3d955834e4e9", - "sha256:761cc24012b0be2acebc2929eeaee3d9036655478974c847a0b5d5ac24d54d70", - "sha256:78b88c247ef366ad07b6877fd13fc96e363d791b200bed10706c4b5522853371", - "sha256:7e25891c8b3c29d785c18716202eacc237a9b65361e17d22d433639a3b1c0126", - "sha256:7e8ab9fa522c878afe2a049087ea723d932bbb15b0a08239d572945158731636", - "sha256:801639ec1663cde71eec343c81936aa6e2480d1ce1345560df7f63c9d49a6a4f", - "sha256:81f7c02f4a8ac119751d6350da0dba64dd4a5b4f1dd61da882b4adce0c1e3e4d", - "sha256:83ec9ea40f74bdbd4018a6d05f2ab68b20935e9c32fc1bdd3164db0a7214764a", - "sha256:8536467187b027bf40cdb1b20c0d2f0087893e427218f0db3cde0a9bd93548c6", - "sha256:85a3c39d55945f86541bc74fcecf107b0a8098b3b7f14f5126b515c9ec61857e", - "sha256:878f2c840ed693351d3531a127424af5e38e2c059727b8d47c0b8a56dc6800f2", - "sha256:8a0f3f1bb9c485f5120f49f37e18ca000beaad4c5bcb709be9a2f0061dcbdee4", - "sha256:8cf406ac78997bad3fc1b1eb99799934b309014177f0ebe46fc52d5e11e381a3", - "sha256:8de204abcb13bcfbea964e50e08dc1ee8d493b6a2da424fac1a866c24aab8557", - "sha256:9061e217e3b6041cd8eeff029681026e4c8f8c96821803e9358dc3cd2f21ce97", - "sha256:91b9de7c52fba6627c38aefda3acafc049a62aae398d0a7af6303b15dd1ad7bc", - "sha256:9225c310b34ba37627b917d49bb9ab9fb3192afdc15c4a2e466fdc3a1f3f7656", - "sha256:94871d66db2370409830b0f3a147e0bc83ebcdc7a233dfe856b989687ea29ab5", - "sha256:994de983cd6153931b98b28a3a37b14e3297d367975031f3a1610e716026bb98", - "sha256:9b66bc21240b150d14310464fe70d8b64350d3d7d1ba377251e75873d9980f2b", - "sha256:a40f3014e579372713a2f589a22dc2a95c46d04cb5c96111cc1e02b5fec398e8", - "sha256:a53f104555788164c3cc44c6e23ff2700b2aee53165d129577db0d21a697cb0d", - "sha256:a670877159565154d68c261e4a0eed151cae1ca05459d4967bfa7ed8f97785e7", - "sha256:a7fed384fc49b280533ba685aec6e3a2e0f72cd70819688991b01a23d6632f89", - "sha256:a81f6815ea3612aa490dccfb9a22274349fe4c7e83c97c6c97a6a57fb1e779b5", - "sha256:b1bdcb3c0e58087b2f38d27e91faa871a872fc8d5e7ceab4e89dd5029943030f", - "sha256:b363105ae888f305addf543471fa6bfe272a7db34c56f3e777f86c32f66c9f88", - "sha256:b43ea42693715a6a7ca11d8eb8b13c8148306559ce277a29c85afa48e9739b54", - "sha256:b44ad887182dd1b6236bc49b4f422e3360edadc0c31511764c82d5da272498b5", - "sha256:b4bc74c81184a2571b6b35bff9b0d749e8e3934ea682e5ea64b53f2b759fe111", - "sha256:b82dbc0a0b6ed67b4c9fa411c945ba642ff40a91799c0d6ce68ef623d951e468", - "sha256:b9b56d36e57ddf1b17d91597a4666adb947c38b76cba59e315ef58fa7a4d5ca9", - "sha256:bb26c370a4001cfe65115ffb564fc09401a8cf51a2cdc20def7526d253656146", - "sha256:bc3a297b9cef1210b43435d74ad8c5aea07c947676fe32306573ec42d94ff426", - "sha256:bc5a6a68fbb716a07a8cce47a9bae6db360cceb0fb60e304a51715f324f73bc8", - "sha256:becfb1f803fe380d5bcdf985e439cd4ae0ed06e19e52d5130bef2186908e350d", - "sha256:c528f2ee881e135b95306612b023c46556a811afa2ec509eab7b8d0559395bcb", - "sha256:c8bfcc26140486e52bbfb70e95fba8d4bd18f72b2aeb9659ecd2ee44f2514af0", - "sha256:ca9133085bec365957040aa88778dce400cbb9620e31a133233769d9c57567b4", - "sha256:d16fe3da83a6d7afc21313ebb17d63d820e34f736a0cf8c2da689c4c46cbc76e", - "sha256:d335e0cf7fd81ff687cfffe35ea862be582b1164fee6276ff3dec86de7dc7dfe", - "sha256:d356b956ee20a74ebe625be1cbf6536302bc09cc8ee39e29faf1ae671dee4263", - "sha256:d36b6b14ef5fa5108290c16f9af4e486e95b362468154c0ba654523674c3b877", - "sha256:d420b298a76acf7400df1d4296ab37d19157aa3397ececf3b5c288d6a76a2f8c", - "sha256:d5a76f9c263b0ed622d2ca99ad07b65dd0ebbd6d4ef4937cdd2a060ada5c6df4", - "sha256:d9e1ea490cb2760b1369b5033445b7389364c6b457d0d90524eced6c262f6bfc", - "sha256:e01bf467c3291e56ddaefb18599434c925479465d8658e5771bada6261926db9", - "sha256:e4bb54dcf8880722678e4f9fa32e7b7bfe4bd5281fd43441426767fe0afd8244", - "sha256:e73109715d748b6890c807b8a70d68939fedfda665a15ebe72009e1538f3d6fc", - "sha256:e86d7ffff696b11867c3624615461f7e91aa415ab53e3b0a08a595da78c653dc", - "sha256:e92212abfba29b903138b3be5c59d082e9dfe1e7054ed287a15f119d569046a3", - "sha256:ea1ec56b9e90ad186af7396cab8c44db720e77d34e9664c3e448c3d8b9234ea4", - "sha256:ede561bd1b20e7a647ecd00a84c15db4ba31d43bf36738337ec36f5c0ac01d31", - "sha256:f05e813ff8a06e1ef6feb23176e3d11ca4348ccd0e6715ed0e0888cb38886815", - "sha256:f66366166632e36a878e519cb91afba5ea067a65253cda747436236cd1637017", - "sha256:f89b9d0b1e09ca711e8100e78e1883b6fa6eb086f49dc8c8b4d53657188dce6e", - "sha256:fca906f07f9e3e782204366a34ddd55b405de50fd73c1c7b97e9c542076e2964", - "sha256:fe9aab0aca202df3170833c390496ca1f91ff7899076a4f7e9edf2cb04cc4d0c", - "sha256:ff91db785adc05f4f4ad6e9aa57333cb30346d2177c6470f3dbc8860121140bc" - ], - "version": "==2.7.5" + "sha256:00ff372dfaced7dd6cc2dffd052fafc118053cf81a442992b9a23367479d77d7", + "sha256:0cc066c7290151600b8872865708d2d00fb785c5db8a0df20d70d518e02f172b", + "sha256:0de1bc5f971aba46de88a4eb0dbb5779e30bbd7514f4dcbff743c209e0c02667", + "sha256:1414582b3b7516d2282433f0914dd9846389b051b2aea592ae7cc165806c24ac", + "sha256:17c32ba584e8fb9322419390e0e248769ed7d59de3ffa7432562a4c0ec4f1f82", + "sha256:18530ed3ddd71e9ff95440afce531efc3df7a3e0657f1c201c2c3cb41dd65869", + "sha256:1a0d27aad02d8abcb1d3b7d85f463877c4937e71adf9b6adb9367f2cdad91a52", + "sha256:1e859c664500d57526fe07140889a3b58dca54ff3b16ac6dc6d534a65c933084", + "sha256:214c05a7642040f6174e29f3e099549d3c40ac44616405081bf230dcafb38767", + "sha256:28dee92edd0d21655e56e1870c22468d0dabe557df18aa69f6d06b1543614180", + "sha256:29e19cb80a69f6d1a64097bfbe1766c418e1a785d901b583ef0328ea10a30399", + "sha256:2aa2267eb6d2b88ef7d139e79a6daaa84cd54d241b9797478f10dcb95a9cd620", + "sha256:2ab81c74a1805fe74330859b38e70d7525cdd80953461b59c06660046afaffcf", + "sha256:2b0f754a5791635b8239abdcc0258378111b8ee7a8eb3e2bbc24bcc48a0f0b08", + "sha256:2b977c39e3734e73540a2e3a71501c2c6261c70c6ce59d427bb7c4ecf6331c7e", + "sha256:2d38ceca90ed538706e3f111513073590f723f90659a7af0b992b29776a6e816", + "sha256:2d3f28a80f2e6bb96e9360a4baf3fbacb696b5aba06a14c18a15488d4b6f398f", + "sha256:2dc064a63445366f6b26eaf77230d326b9463e903ba59d6ff5efde0c5ec1ea0e", + "sha256:3024ab4c4906c3681408ca17c35833237d18813ebb9f24ae9f9e3157a4a66939", + "sha256:3243e4b8279ff2fe4c6e7869f0e6930c17799ee9f8d07317f68d44a66b46281e", + "sha256:3994f7dc48d21af40c0d69fca57d8040b02953f4c7c3652c2341d8947e9cbedf", + "sha256:3b999fb66980f885961d197d97d7ff5a13b7ab524ccf45ccb4704f4b82ce02e3", + "sha256:3bb5f2954dd897b0bac13b5449e5c977534595b688120c8af054657a08b01f46", + "sha256:443726af4bd60515e4e41ea36c5dbadb29a59bc799bcbf431011d1c6fd4363e3", + "sha256:4677477a406f2a9e064920463f69172b865e4d69117e1f2160064d3f5912b0bd", + "sha256:46fdd27c8fa4186d8b290bf74a28cbd91b94127b1b6a35c265a002e394fa9324", + "sha256:4a637bcd199c1366c65b98f18884f0d0b87403f04676b21e4635831660d722a7", + "sha256:4ce2ef9291a193a0e0cd5e23970bf3b682cc8b95220561d05b775b8d616d665f", + "sha256:542358b178b025dcc95e7fb83389e9954f701c41d312cbb66bdd763cbe5414b5", + "sha256:55020d6fb9b72bd3606969f5431386c592ed3666133bd475af945aa0fa9e84ec", + "sha256:57aeab27120a8a50917845bb81b0976e33d4759f2156b01359e2b43d445f5127", + "sha256:5934e3a623a1d485e1dcfc1990246e3c32c6fc6e7f0fd894750800d35fdb5794", + "sha256:5b0493ab66c6b8e17e9fde74c646b39ee09c236cf28a787cb8cbd3a83c05bff7", + "sha256:5f6175c1cf07dadad3213d60075704cf2e2f1232975cfd4ac8328c24a05e8f78", + "sha256:6033303431a7c85a535b3f1b0ec28abc2ebc2167c263f244993b56ccb87cae6b", + "sha256:62ac31059a3c510ef64ed93d930581b262fd4592e6d95ede79fca91e8d3d3ef6", + "sha256:63fa75e87ad8c57d5722cc87902ca148ef8bbbba12b5c5b3c3730a1bc9ac2886", + "sha256:67e8fb18df51e649adbc81359e1db0f202d72708fba61b06f5ac8db47c08d107", + "sha256:69ab51d551d50e4d6ca35abc95c9d04b33ad28418019bb5481ab09bdbc0df15c", + "sha256:6be965028785413a6163dd55a639b898b22f67f9b6ed554081c23e94a602031e", + "sha256:6c26a923080bc211cab8f5a5e242e3657b32951fec8980db0616e9239aade482", + "sha256:6df04efdba4e1bf9d93a1735e42005f8fcf812caf40c03934d9322412d563499", + "sha256:6ea51ba4204d086d5b76e84c31d2acbb355ed1b075ded54eb9b7070b0b95415d", + "sha256:741c3a2c0997c8f8878edfc65a4a8f7aa72eede337c9bc0b7bd8a45cf6e70dbc", + "sha256:74cd1725d08325b6669e6e9a5d09cec29e7c41f7d58e082286af5387414d046d", + "sha256:75104c3076676708c1ac2484ebf5c26464fb3850312de33a5b5bf61bfa7dbec5", + "sha256:797de3465f5f6c6be9a412b4e99eb6e8cdb86b83b6756655c4d83a65d0b9a376", + "sha256:7b29d4bf3d3da1847f2be9e30105bf51caaf5922e94dc827653e250ed33f4e8a", + "sha256:7c17dd8fb146c2c680bf1cb28b358f9e52a14076e44141c5442148863ee95d7d", + "sha256:81e83ed7e0b1c09c5a33b97712da89e7a21fd3e5598eff3975c39540f5619792", + "sha256:82bfb6ab9b1b5451a5483c9a2ae2a8f83799d7503b384b54f6ab56ea74abb305", + "sha256:8367768ab797105eb97dfbd4577fcde281618de4d8d3b16ad62c477bb065f347", + "sha256:843af12991161b358b6379a8dc5f6636798f3dacdae182d30995b6a2df3b263e", + "sha256:848af80518d0ed2aee782018588c7c88805f51b01271935df5b256c8d81c726e", + "sha256:861850d6a58e7b6a7096d0b0efed9c6d993a6ab8b9d01e781df1f4d80cc00efa", + "sha256:8c361201e1c3ee6d6b2266f8b7a645389880bccab1b29e22e7a6b7b6e7831ad5", + "sha256:904719fb7304d4115228b63c178f0cc725ad3b73e285c4b328e45a99a8e3fad6", + "sha256:9061c0a50216f24c97fb2325de84200e5ad5555f25c854ddcb3ceb6f12136055", + "sha256:9186cf8135ca170cd907d8c4df408a87747570d192d89ec4ff23805611c702a0", + "sha256:9336300fd0acf07ede92e424930176dc4b43ef1b298489e93ba9a1695e8ea752", + "sha256:9aad7b4670f090734b272c072c9db375c63bd503512be9a9393e657dcacfc7e2", + "sha256:9b65d487451e0e287565c8436cf4da45260f958f911299f6122a20d7ec76525c", + "sha256:9d5df3d6358425c9dfb6bdbd4f576563ec4173d24693a9042d05aadcb23c0b98", + "sha256:9d6a9c72354327c7aa9890ff87904cbe86830cb1fb58c39750a0afac8df5e051", + "sha256:9fed8aba8d1b09cf641b50f1e6dd079c31677106ea4b63ec29f4c49adfabd63f", + "sha256:a04d4851e83730f03c4a6aac568c7d8b42f78f0f9cc8231d6db66192b030ce1e", + "sha256:a0f6d705860f59721d7282496a4d29b5fd78690e1c1473503832c983e762b01b", + "sha256:aa08a9b03888c768b9b2383949a942804d50d8164683b39fe62f0bfbfd9b4204", + "sha256:ad440c17ef2ff42e94286186b5bcf82bf87c4026f91822675239102ebe1f7035", + "sha256:ae32ac7217e83646b9f64d7090bf7b737afaa569665621f110a05d9738ca841a", + "sha256:b2015a9dd718393e814ff7b9e80c58190eb1cef7980f86a97a33e8440e158ce2", + "sha256:b2560475c5a1ff96fcab01fae7cf6b9a6da590f02659556b7fccc7991e401884", + "sha256:b65a04b2e029b0694b52d60786732afd15b1ec6517de61a36afbb7808a2ffac1", + "sha256:b67733a240a96f09b7597af97ac4d60c59140cfcfd180f11a7221863b82f023a", + "sha256:b8d6e5ff385fea25caf26fd58b43f087deb763dcaddd18d3df2895235cf1b484", + "sha256:bc03bb358ae3917247d257207c79162e666d407ac473718d1b95316dac94162b", + "sha256:bf80804014e3736515b84044c2be0e70080616b4ceddd4e38d85f3167aeb8165", + "sha256:c2426dc7a0d92d8254def20ab7a231626397ce5b6fb3d4f44be74cc1370a60c3", + "sha256:c54b0af16be45de534af9d77e8a180126cd059f72db8b6550f62dda233868942", + "sha256:c5582dd7d906e6f9ec1704f99d56d812f7d395d28c02262bc8b50834d51250c3", + "sha256:c9efcee311d9ba0c619743060585af9a9b81496e97b945843d5e954c67722a75", + "sha256:cbe54685cf6b17b3e15faf6c4b76773bc1c484bc447020737d2550a9dde5f6e6", + "sha256:cf38871ed4cd89df9db7c70f729b948fa3e2848a07c69f78e4ddfbe4f23db63c", + "sha256:d175e16419a52d54c0ac44c93309ba76dc2cfd33ee9d20624f1a5eb86b8e162e", + "sha256:d2f13b7d0694ce2024c82fc595e6ccc3918e7f069747c3de41b1ce72a9a1e346", + "sha256:d32ccd2c0d906eae103ef84015f0545a395052b0b6eb0e02e9023ca0132557f6", + "sha256:d34790a919f165b6f537935280ef5224957d9ce8ab11d339f5e6d0319a683ccc", + "sha256:dc7acffee09822b334d1b46cd384e969804abdf18f892c82c05c2328066cd2ae", + "sha256:dd76bbf5a4b2ab84b8ffa229f5648e80038ba76bf8d7acc5de9dd06031b38117", + "sha256:df9d8a9a46c46950f306394705512553c552b633f8bf3c11359c4204289f11e3", + "sha256:e48c45ea7944225bcee026c457a70eaea61db3659d9603f07fc8a643ab7e633b", + "sha256:e4cd81ffd2d58ef68c22c825aff89f4a47bd721e2ada0a3a96793169f370ae21", + "sha256:e68ceef35a88625d16169550768fcc8d3894913e363c24ecbf6b8c07eb02c8f3", + "sha256:e7f7231ef349e8f4955d9b39561f4683a418a73443cfce797a4eddbee1ba9664", + "sha256:e88a706f92ad1e0e1e66f6811d10b6155d5f18f0de9356ee899a7966a4e41992", + "sha256:ea71e0a50060f96ad0821e0ac785e91e44807f8b69555970979d81934961d5bd", + "sha256:ee772c20dcb56b03d666a4e4383d0b5b942b0ccc27815e42fe0737b34cba2082", + "sha256:f0af01e1f61fe627f63648c0c6f52de8eac56710a2ef1dbce4851d867084cc7e", + "sha256:f30cdce22af3dc7c73e70af391bfd87c4574cc40c74d651919e20efc26e014b5", + "sha256:f3128234bde3629ab301a501950587e847d30031a9cbf04d95f35cbf44469a9e", + "sha256:f7d2ec2174d503cbb092f8353527842633c530b4e03b9922411640ac9c018a19", + "sha256:f9a66745682e175e143a180524a63e692acb2b8c86941073f6dd4ee906e69608" + ], + "version": "==2.8.1" }, "certifi": { "hashes": [ - "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7", - "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716" + "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082", + "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9" ], "markers": "python_version >= '3.6'", - "version": "==2023.5.7" + "version": "==2023.7.22" }, "cffi": { "hashes": [ @@ -368,84 +370,84 @@ }, "charset-normalizer": { "hashes": [ - "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6", - "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1", - "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e", - "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373", - "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62", - "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230", - "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be", - "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c", - "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0", - "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448", - "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f", - "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649", - "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d", - "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0", - "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706", - "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a", - "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59", - "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23", - "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5", - "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb", - "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e", - "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e", - "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c", - "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28", - "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d", - "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41", - "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974", - "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce", - "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f", - "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1", - "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d", - "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8", - "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017", - "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31", - "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7", - "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8", - "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e", - "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14", - "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd", - "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d", - "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795", - "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b", - "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b", - "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b", - "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203", - "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f", - "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19", - "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1", - "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a", - "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac", - "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9", - "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0", - "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137", - "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f", - "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6", - "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5", - "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909", - "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f", - "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0", - "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324", - "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755", - "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb", - "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854", - "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c", - "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60", - "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84", - "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0", - "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b", - "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1", - "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531", - "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1", - "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11", - "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326", - "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df", - "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab" - ], - "markers": "python_version >= '3.7'", - "version": "==3.1.0" + "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96", + "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c", + "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710", + "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706", + "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020", + "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252", + "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad", + "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329", + "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a", + "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f", + "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6", + "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4", + "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a", + "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46", + "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2", + "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23", + "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace", + "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd", + "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982", + "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10", + "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2", + "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea", + "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09", + "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5", + "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149", + "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489", + "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9", + "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80", + "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592", + "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3", + "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6", + "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed", + "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c", + "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200", + "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a", + "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e", + "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d", + "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6", + "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623", + "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669", + "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3", + "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa", + "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9", + "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2", + "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f", + "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1", + "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4", + "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a", + "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8", + "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3", + "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029", + "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f", + "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959", + "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22", + "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7", + "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952", + "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346", + "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e", + "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d", + "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299", + "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd", + "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a", + "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3", + "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037", + "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94", + "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c", + "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858", + "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a", + "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449", + "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c", + "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918", + "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1", + "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c", + "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac", + "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.2.0" }, "coincurve": { "hashes": [ @@ -493,6 +495,7 @@ "sha256:fceca9d6ecaa1e8f891675e4f4ff530d54e41c648fc6e8a816835ffa640fa899" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==18.0.0" }, "croniter": { @@ -505,107 +508,102 @@ }, "cytoolz": { "hashes": [ - "sha256:02975e2b1e61e47e9afa311f4c1783d155136fad37c54a1cebfe991c5a0798a1", - "sha256:03ab22c9aeb1535f8647d23b6520b0c3d41aaa18d04ef42b352dde1931f2e2b1", - "sha256:061387aa39b9c1576c25d0c59142513c09e77a2a07bd5d6211a43c7a758b6f45", - "sha256:06d38a40fe153f23cda0e823413fe9d9ebee89dd461827285316eff929fb121e", - "sha256:0d474dacbafbdbb44c7de986bbf71ff56ae62df0d52ab3b6fa966784dc88737a", - "sha256:117871f036926e42d3abcee587eafa9dc7383f1064ac53a806d33e76604de311", - "sha256:14f4dbc3f0ec8f6fc68865489af21dcf042ff007d2737c27bfd73296f15db544", - "sha256:1a1eae39656a1685e8b3f433eecfd72015ce5c1d7519e9c8f9402153c68331bb", - "sha256:1b6761791973b1e839b8309d5853b40eeb413368e31beaf5f2b6ed44c6fc7cf0", - "sha256:1be368623e46ad3c1ce807e7a436acb119c26001507b31f92ceb21b86e08c386", - "sha256:1c29dd04e282ddfd45b457e3551075beec9128aa9271245e58ce924bf6e055f8", - "sha256:23c3f57c48eb939d2986eba4aeaeedf930ebf94d58c91a42d4e0fc45ed5427dc", - "sha256:25ff13c468c06da9ef26651dc389e7e8bb7af548f8c1dfb96305f57f18d398a8", - "sha256:2a48940ff0449ffcf690310bf9228bb57885f7571406ed2fe05c98e299987195", - "sha256:2b245b824f4705aef0e4a03fafef3ad6cb59ef43cc564cdbf683ee28dfc11ad5", - "sha256:2ec296f01c29c809698eaf677211b6255691295c2b35caab2131e1e7eaadfbac", - "sha256:2eed428b5e68c28abf2c71195e799850e040d67a27c05f7785319c611665b86a", - "sha256:2f32452e833f0605b871626e6c61b71b0cba24233aad0e04accc3240497d4995", - "sha256:3032c0ba42dee5836d6b57a72a569b65df2c29e8ed266cb900d569003cf933a9", - "sha256:30936ae8fa68b6a1ac8ad6c4bacb5a8a00d51bc6c89f9614a1557b0105d09f8a", - "sha256:31131b54a0c72efc0eb432dc66df546c6a54f2a7d396c9a34cf65ac1c26b1df8", - "sha256:35fae4eaa0eaf9072a5fe2d244a79e65baae4e5ddbe9cc629c5037af800213a2", - "sha256:37320669c364f7d370392af33cc1034b4563da66c22cd3261e3530f4d30dbe4b", - "sha256:37c53f456a1c84566a7d911eec57c4c6280b915ab0600e7671582793cc2769fe", - "sha256:3c9a16a5b4f54d5c0a131f56b0ca65998a9a74958b5b36840c280edba4f8b907", - "sha256:3cb95d23defb2322cddf70efb4af6dac191d95edaa343e8c1f58f1afa4f92ecd", - "sha256:3d6d0b0075731832343eb88229cea4bf39e96f3fc7acbc449aadbdfec2842703", - "sha256:421b224dc4157a0d66625acb5798cf50858cfa06a5232d39a8bd6cf1fa88aca3", - "sha256:4284120c978fb7039901bf6e66832cb3e82ac1b2a107512e735bdb04fd5533ed", - "sha256:42c9e5cd2a48a257b1f2402334b48122501f249b8dcf77082f569f2680f185eb", - "sha256:4534cbfad73cdb1a6dad495530d4186d57d73089c01e9cb0558caab50e46cb3b", - "sha256:48bc2f30d1b2646d675bb8e7778ab59379bf9edc59fe06fb0e7f85ba1271bf44", - "sha256:49911cb533c96d275e31e7eaeb0742ac3f7afe386a1d8c40937814d75039a0f7", - "sha256:499af2aff04f65b4c23de1df08e1d1484a93b23ddaaa0163e44b5070b68356eb", - "sha256:4a0055943074c6c85b77fcc3f42f7c54010a3478daa2ed9d6243d0411c84a4d3", - "sha256:4d700e011156ff112966c6d77faaae125fcaf538f4cec2b9ce8957de82858f0f", - "sha256:50db41e875e36aec11881b8b12bc69c6f4836b7dd9e88a9e5bbf26c2cb3ba6cd", - "sha256:5158ae6d8dd112d003f677039a3613ca7d2592bfe35d7accf23684edb961fc26", - "sha256:56e1ebf6eb4438b8c45cbe7e7b22fc65df0c9efa97a70d3bf2f51e08b19756a5", - "sha256:59641eb1f41cb688b3cb2f98c9003c493a5024325f76b5c02333d08dd972127c", - "sha256:5af43ca7026ead3dd08b261e4f7163cd2cf3ceaa74fa5a81f7b7ea5d445e41d6", - "sha256:5c59bb4ca88e1c69931468bf21f91c8f64d8bf1999eb163b7a2df336f60c304a", - "sha256:633f19d1990b1cf9c67dce9c28bf8b5a18e42785d15548607a100e1236384d5d", - "sha256:6716855f9c669c9e25a185d88e0f169839bf8553d16496796325acd114607c11", - "sha256:6805b007af3557ee6c20dab491b6e55a8177f5b6845d9e6c653374d540366ba7", - "sha256:695dd8231e4f1bfb9a2363775a6e4e56ad9d2058058f817203a49614f4bfe33b", - "sha256:6fa7009c843667868aa8bdb3d68e5ef3d6356dd418b17ed5ca4e1340e82483a5", - "sha256:794cce219bbcb2f36ca220f27d5afd64eaa854e04901bd6f240be156a578b607", - "sha256:7b60caf0fa5f1b49f1062f7dc0f66c7b23e2736bad50fa8296bfb845995e3051", - "sha256:7e903df991f0957e2b271a37bb25d28e0d260c52825ae67507d15ca55a935961", - "sha256:7eb9e6fa8a82c3d2f519f7d3942898a97792e3895569e9501b9431048289b82f", - "sha256:816c2038008ebf50d81171ddfae377f1af9e71d504ec609469dcb0906bfcf2ae", - "sha256:849f461bffa1e7700ccfcb5186df29cd4cdcc9efdb7199cb8b5681dc37045d72", - "sha256:8506d1863f30d26f577c4ed59d2cfd03d2f39569f9cbaa02a764a9de73d312d5", - "sha256:867bebe6be30ee36a836f9b835790762a74f46be8cc339ea57b68dcecdbc1133", - "sha256:97a24c0d0806fcf9a6e75fc18aeb95adc37eb0baf6451f10a2de23ffd815329d", - "sha256:980e7eb7205e01816a92f3290cfc80507957e64656b9271a0dfebb85fe3718c0", - "sha256:9bae431a5985cdb2014be09d37206c288e0d063940cf9539e9769bd2ec26b220", - "sha256:9bebe58f7a160db7838eb70990c704db4bdc2d58bd364290fd69be0587be8bac", - "sha256:9e324a94856d88ecf10f34c102d0ded67d7c3cf644153d77e34a29720ce6aa47", - "sha256:a6e63fc67b23830947b51e0a488992e3c904fce825ead565f3904dcf621d05f7", - "sha256:a72440305f634604827f96810e4469877b89f5c060d6852267650a49b0e3768c", - "sha256:a734511144309ea6e105406633affb74e303a3df07d8a3954f9b01946e27ecb1", - "sha256:a816bff6bf424753e1ac2441902ceaf37ae6718b745a53f6aa1a60c617fb4f5f", - "sha256:a8a7a325b8fe885a6dd91093616c703134f2dacbd869bc519970df3849c2a15b", - "sha256:aa61e3da751a2dfe95aeca603f3ef510071a136ba9905f61ae6cb5d0696271ad", - "sha256:ac5895d5f78dbd8646fe37266655ba4995f9cfec38a86595282fee69e41787da", - "sha256:ac6784cc43aec51a86cf9058a2a343084f8cf46a9281bea5762bfa608127c53b", - "sha256:b1bd8017ef0da935a20106272c5f5ff6b1114add1ccb09cfed1ff7ec5cc01c6d", - "sha256:b2ac288f27a2689d9e39f4cf4df5437a8eb038eaae515169586c77f9f8fb343a", - "sha256:b30cd083ef8af4ba66d9fe5cc75c653ede3f2655f97a032db1a14cc8a006719c", - "sha256:b46ebc463bb45f278a2b94e630061c26e10077cb68d4c93583d8f4199699a5ef", - "sha256:b575393dd431b8e211de35bd593d831dac870172b16e2b7934f3566b8fc89377", - "sha256:b6569f6038133909cd658dbdcc6fc955f791dc47a7f5b55d2066f742253dcbfe", - "sha256:b8b8f88251b84b3877254cdd59c86a1dc6b2b39a03c6c9c067d344ef879562e0", - "sha256:b8eceaa12b7f152b046b67cb053ec2b5b00f73593983de69bc5e63a8aca4a7a8", - "sha256:ba74c239fc6cb6e962eabc420967c7565f3f363b776c89b3df5234caecf1f463", - "sha256:be5a454a95797343d0fb1ed02caecae73a023b1393c112951c84f17ec9f4076c", - "sha256:bef934bd3e024d512c6c0ad1c66eb173f61d9ccb4dbca8d75f727a5604f7c2f6", - "sha256:c1964dcb5f250fd13fac210944b20810d61ef4094a17fbbe502ab7a7eaeeace7", - "sha256:c34e69be4429633fc614febe3127fa03aa418a1abb9252f29d9ba5b3394573a5", - "sha256:c576bd63495150385b8d05eaae775387f378be2fd9805d3ffb4d17c87271fbad", - "sha256:cb8b10405960a8e6801a4702af98ea640130ec6ecfc1208195762de3f5503ba9", - "sha256:cc3645cf6b9246cb8e179db2803e4f0d148211d2a2cf22d5c9b5219111cd91a0", - "sha256:cd35c0be4c46274129dd1678bb911dd4e93d23968b26f4e39cd55bc7cb3b1bac", - "sha256:d540e9c34a61b53b6a374ea108794a48388178f7889d772e364cdbd6df37774c", - "sha256:d72415b0110f7958dd3a5ee98a70166f47bd42ede85e3535669c794d06f57406", - "sha256:dbae37d48ef5a0ab90cfaf2b9312d96f034b1c828208a9cbe25377a1b19ba129", - "sha256:e1c5434db53f3a94a37ad8aedb231901e001995d899af6ed1165f3d27fa04a6a", - "sha256:e75e287787e6adafed9d8c3d3e7647c0b5eb460221f9f92d7dfe48b45ba77c0d", - "sha256:e797c4afb1b7962d3205b1959e1051f7e6bfbba29da44042a9efc2391f1feb38", - "sha256:efd1b2da3ee577fcfa723a214f73186aef9674dd5b28242d90443c7a82722b0f", - "sha256:f5b43ce952a5a31441556c55f5f5f5a8e62c28581a0ff2a2c31c04ef992d73bd", - "sha256:f7194a22a4a24f3561cb6ad1cca9c9b2f2cf34cc8d4bce6d6a24c80960323fa8", - "sha256:f8101ab6de5aa0b26a2b5032bc488d430010c91863e701812d65836b03a12f61", - "sha256:fc33909397481c90de3cec831bfb88d97e220dc91939d996920202f184b4648e", - "sha256:fcc378fa97f02fbcef090b3611305425d72bd1c0afdd13ef4a82dc67d40638b6", - "sha256:ff478682e8ee6dbaa37201bb71bf4a6eee744006ab000e8f5cea05066fc7c845" + "sha256:00547da587f124b32b072ce52dd5e4b37cf199fedcea902e33c67548523e4678", + "sha256:0295289c4510efa41174850e75bc9188f82b72b1b54d0ea57d1781729c2924d5", + "sha256:03b58f843f09e73414e82e57f7e8d88f087eaabf8f276b866a40661161da6c51", + "sha256:0568d4da0a9ee9f9f5ab318f6501557f1cfe26d18c96c8e0dac7332ae04c6717", + "sha256:08a0e03f287e45eb694998bb55ac1643372199c659affa8319dfbbdec7f7fb3c", + "sha256:0a9d12436fd64937bd2c9609605f527af7f1a8db6e6637639b44121c0fe715d6", + "sha256:101b5bd32badfc8b1f9c7be04ba3ae04fb47f9c8736590666ce9449bff76e0b1", + "sha256:14108cafb140dd68fdda610c2bbc6a37bf052cd48cfebf487ed44145f7a2b67f", + "sha256:18580d060fa637ff01541640ecde6de832a248df02b8fb57e6dd578f189d62c7", + "sha256:18a0f838677f9510aef0330c0096778dd6406d21d4ff9504bf79d85235a18460", + "sha256:1ce324d1b413636ea5ee929f79637821f13c9e55e9588f38228947294944d2ed", + "sha256:246368e983eaee9851b15d7755f82030eab4aa82098d2a34f6bef9c689d33fcc", + "sha256:24c0d71e9ac91f4466b1bd280f7de43aa4d94682daaf34d85d867a9b479b87cc", + "sha256:275d53fd769df2102d6c9fc98e553bd8a9a38926f54d6b20cf29f0dd00bf3b75", + "sha256:294d24edc747ef4e1b28e54365f713becb844e7898113fafbe3e9165dc44aeea", + "sha256:2fb740482794a72e2e5fec58e4d9b00dcd5a60a8cef68431ff12f2ba0e0d9a7e", + "sha256:31d4b0455d72d914645f803d917daf4f314d115c70de0578d3820deb8b101f66", + "sha256:388f840fd911d61a96e9e595eaf003f9dc39e847c9060b8e623ab29e556f009b", + "sha256:3e993804e6b04113d61fdb9541b6df2f096ec265a506dad7437517470919c90f", + "sha256:4180b2785d1278e6abb36a72ac97c92432db53fa2df00ee943d2c15a33627d31", + "sha256:4416ee86a87180b6a28e7483102c92debc077bec59c67eda8cc63fc52a218ac0", + "sha256:45c7b4eac7571707269ebc2893facdf87e359cd5c7cfbfa9e6bd8b33fb1079c5", + "sha256:460c05238fbfe6d848141669d17a751a46c923f9f0c9fd8a3a462ab737623a44", + "sha256:478051e5ef8278b2429864c8d148efcebdc2be948a61c9a44757cd8c816c98f5", + "sha256:481e3129a76ea01adcc0e7097ccb8dbddab1cfc40b6f0e32c670153512957c0f", + "sha256:48425107fbb1af3f0f2410c004f16be10ffc9374358e5600b57fa543f46f8def", + "sha256:4a7d8b869ded171f6cdf584fc2fc6ae03b30a0e1e37a9daf213a59857a62ed90", + "sha256:4bff49986c9bae127928a2f9fd6313146a342bfae8292f63e562f872bd01b871", + "sha256:51d3495235af09f21aa92a7cdd51504bda640b108b6be834448b774f52852c09", + "sha256:5556acde785a61d4cf8b8534ae109b023cbd2f9df65ee2afbe070be47c410f8c", + "sha256:55e94124af9c8fbb1df54195cc092688fdad0765641b738970b6f1d5ea72e776", + "sha256:5616d386dfbfba7c39e9418ba668c734f6ceaacc0130877e8a100cad11e6838b", + "sha256:57233e1600560ceb719bed759dc78393edd541b9a3e7fefc3079abd83c26a6ea", + "sha256:593e89e2518eaf81e96edcc9ef2c5fca666e8fc922b03d5cb7a7b8964dbee336", + "sha256:5998f81bf6a2b28a802521efe14d9fc119f74b64e87b62ad1b0e7c3d8366d0c7", + "sha256:5e4e612b7ecc9596e7c859cd9e0cd085e6d0c576b4f0d917299595eb56bf9c05", + "sha256:5fef7b602ccf8a3c77ab483479ccd7a952a8c5bb1c263156671ba7aaa24d1035", + "sha256:63b31345e20afda2ae30dba246955517a4264464d75e071fc2fa641e88c763ec", + "sha256:663911786dcde3e4a5d88215c722c531c7548903dc07d418418c0d1c768072c0", + "sha256:673d6e9e3aa86949343b46ac2b7be266c36e07ce77fa1d40f349e6987a814d6e", + "sha256:68ae7091cc73a752f0b938f15bb193de80ca5edf5ae2ea6360d93d3e9228357b", + "sha256:698da4fa1f7baeea0607738cb1f9877ed1ba50342b29891b0223221679d6f729", + "sha256:6a93644d7996fd696ab7f1f466cd75d718d0a00d5c8118b9fe8c64231dc1f85e", + "sha256:6c8d0dff4865da54ae825d43e1721925721b19f3b9aca8e730c2ce73dee2c630", + "sha256:732d08228fa8d366fec284f7032cc868d28a99fa81fc71e3adf7ecedbcf33a0f", + "sha256:735147aa41b8eeb104da186864b55e2a6623c758000081d19c93d759cd9523e3", + "sha256:7a92aab8dd1d427ac9bc7480cfd3481dbab0ef024558f2f5a47de672d8a5ffaa", + "sha256:7d352d4de060604e605abdc5c8a5d0429d5f156cb9866609065d3003454d4cea", + "sha256:81074edf3c74bc9bd250d223408a5df0ff745d1f7a462597536cd26b9390e2d6", + "sha256:81e6a9a8fda78a2f4901d2915b25bf620f372997ca1f20a14f7cefef5ad6f6f4", + "sha256:843500cd3e4884b92fd4037912bc42d5f047108d2c986d36352e880196d465b0", + "sha256:89247ac220031a4f9f689688bcee42b38fd770d4cce294e5d914afc53b630abe", + "sha256:8bb624dbaef4661f5e3625c1e39ad98ecceef281d1380e2774d8084ad0810275", + "sha256:9007bb1290c79402be6b84bcf9e7a622a073859d61fcee146dc7bc47afe328f3", + "sha256:9070ae35c410d644e6df98a8f69f3ed2807e657d0df2a26b2643127cbf6944a5", + "sha256:908c13f305d34322e11b796de358edaeea47dd2d115c33ca22909c5e8fb036fd", + "sha256:9480b4b327be83c4d29cb88bcace761b11f5e30198ffe2287889455c6819e934", + "sha256:960d85ebaa974ecea4e71fa56d098378fa51fd670ee744614cbb95bf95e28fc7", + "sha256:96796594c770bc6587376e74ddc7d9c982d68f47116bb69d90873db5e0ea88b6", + "sha256:97cf514a9f3426228d8daf880f56488330e4b2948a6d183a106921217850d9eb", + "sha256:997b7e0960072f6bb445402da162f964ea67387b9f18bda2361edcc026e13597", + "sha256:9b28787eaf2174e68f0acb3c66f9c6b98bdfeb0930c0d0b08e1941c7aedc8d27", + "sha256:9bf51354e15520715f068853e6ab8190e77139940e8b8b633bdb587956a08fb0", + "sha256:9e5075e30be626ef0f9bedf7a15f55ed4d7209e832bc314fdc232dbd61dcbf44", + "sha256:a08b4346350660799d81d4016e748bcb134a9083301d41f9618f64a6077f89f2", + "sha256:a67f75cc51a2dc7229a8ac84291e4d61dc5abfc8940befcf37a2836d95873340", + "sha256:a973f5286758f76824ecf19ae1999f6697371a9121c8f163295d181d19a819d7", + "sha256:ab911033e5937fc221a2c165acce7f66ae5ac9d3e54bec56f3c9c197a96be574", + "sha256:ad92e37be0b106fdbc575a3a669b43b364a5ef334495c9764de4c2d7541f7a99", + "sha256:ad9ea4a50d2948738351790047d45f2b1a023facc01bf0361988109b177e8b2f", + "sha256:b029bdd5a8b6c9a7c0e8fdbe4fc25ffaa2e09b77f6f3462314696e3a20511829", + "sha256:b41a85b9b9a2530b72b0d3d10e383fc3c2647ae88169d557d5e216f881860318", + "sha256:baf020f4b708f800b353259cd7575e335a79f1ac912d9dda55b2aa0bf3616e42", + "sha256:c08094b9e5d1b6dfb0845a0253cc2655ca64ce70d15162dfdb102e28c8993493", + "sha256:c26805b6c8dc8565ed91045c44040bf6c0fe5cb5b390c78cd1d9400d08a6cd39", + "sha256:c6ee222671eed5c5b16a5ad2aea07f0a715b8b199ee534834bc1dd2798f1ade7", + "sha256:c820608e7077416f766b148d75e158e454881961881b657cff808529d261dd24", + "sha256:cb081b2b02bf4405c804de1ece6f904916838ab0e057f1446e4ac12fac827960", + "sha256:cbe038bb78d599b5a29d09c438905defaa615a522bc7e12f8016823179439497", + "sha256:cd461e402e24929d866f05061d2f8337e3a8456e75e21b72c125abff2477c7f7", + "sha256:cde6dbb788a4cbc4a80a72aa96386ba4c2b17bdfff3ace0709799adbe16d6476", + "sha256:ce7889dc3701826d519ede93cdff11940fb5567dbdc165dce0e78047eece02b7", + "sha256:d0086ba8d41d73647b13087a3ca9c020f6bfec338335037e8f5172b4c7c8dce5", + "sha256:d29988bde28a90a00367edcf92afa1a2f7ecf43ea3ae383291b7da6d380ccc25", + "sha256:d494befe648c13c98c0f3d56d05489c839c9228a32f58e9777305deb6c2c1cee", + "sha256:df4e32badb2ccf1773e1e74020b7e3b8caf9e92f842c6be7d14888ecdefc2c6c", + "sha256:e6de6a4bdfaee382c2de2a3580b3ae76fce6105da202bbd835e5efbeae6a9c6e", + "sha256:f039c5373f7b314b151432c73219216857b19ab9cb834f0eb5d880f74fc7851c", + "sha256:f6e86ac2b45a95f75c6f744147483e0fc9697ce7dfe1726083324c236f873f8b", + "sha256:f9c690b359f503f18bf1c46a6456370e4f6f3fc4320b8774ae69c4f85ecc6c94", + "sha256:fa436abd4ac9ca71859baf5794614e6ec8fa27362f0162baedcc059048da55f7", + "sha256:fa44215bc31675a6380cd896dadb7f2054a7b94cfb87e53e52af844c65406a54", + "sha256:ff451d614ca1d4227db0ffa627fb51df71968cf0d9baf0210528dad10fdbc3ab" ], "markers": "implementation_name == 'cpython'", - "version": "==0.12.1" + "version": "==0.12.2" }, "dataclassy": { "hashes": [ @@ -621,6 +619,7 @@ "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd" ], "index": "pypi", + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", "version": "==0.18.0" }, "eip712": { @@ -629,15 +628,16 @@ "sha256:c984c577358d1c7e5d4e52802bf4bd0432e965ba7326448998f95fcc1b6d5269" ], "index": "pypi", + "markers": "python_version >= '3.8' and python_version < '4'", "version": "==0.2.1" }, "eth-abi": { "hashes": [ - "sha256:15f9870ca054c09a8e474d2d7e81aff0c32421aebdac896193183fc143e31b50", - "sha256:fe738cdb24983adfe89abf727c723c288f8d0029e97fb08160b20bb5290ab475" + "sha256:0d50469de2f9948bacd764fc3f8f337a090bbb6ac3a759ef22c094bf56c1e6d9", + "sha256:a9adae5e0c2b9a35703b76856d6db3a0498effdf1243011b2d56280165db1cdd" ], "markers": "python_full_version >= '3.7.2' and python_version < '4'", - "version": "==4.1.0" + "version": "==4.2.0" }, "eth-account": { "hashes": [ @@ -690,193 +690,182 @@ }, "eth-utils": { "hashes": [ - "sha256:4938ab742f91cdf19bae024261af090664f63ccf83bdb1213e7146c14209e899", - "sha256:7cccfb0b0749431d0d001e327e9a7289bf07308316a73850ae3895020e5682f4" + "sha256:7f1a9e10400ee332432a778c321f446abaedb8f538df550e7c9964f446f7e265", + "sha256:d6e107d522f83adff31237a95bdcc329ac0819a3ac698fe43c8a56fd80813eab" ], "markers": "python_version >= '3.7' and python_version < '4'", - "version": "==2.1.1" + "version": "==2.2.0" }, "frozenlist": { "hashes": [ - "sha256:008a054b75d77c995ea26629ab3a0c0d7281341f2fa7e1e85fa6153ae29ae99c", - "sha256:02c9ac843e3390826a265e331105efeab489ffaf4dd86384595ee8ce6d35ae7f", - "sha256:034a5c08d36649591be1cbb10e09da9f531034acfe29275fc5454a3b101ce41a", - "sha256:05cdb16d09a0832eedf770cb7bd1fe57d8cf4eaf5aced29c4e41e3f20b30a784", - "sha256:0693c609e9742c66ba4870bcee1ad5ff35462d5ffec18710b4ac89337ff16e27", - "sha256:0771aed7f596c7d73444c847a1c16288937ef988dc04fb9f7be4b2aa91db609d", - "sha256:0af2e7c87d35b38732e810befb9d797a99279cbb85374d42ea61c1e9d23094b3", - "sha256:14143ae966a6229350021384870458e4777d1eae4c28d1a7aa47f24d030e6678", - "sha256:180c00c66bde6146a860cbb81b54ee0df350d2daf13ca85b275123bbf85de18a", - "sha256:1841e200fdafc3d51f974d9d377c079a0694a8f06de2e67b48150328d66d5483", - "sha256:23d16d9f477bb55b6154654e0e74557040575d9d19fe78a161bd33d7d76808e8", - "sha256:2b07ae0c1edaa0a36339ec6cce700f51b14a3fc6545fdd32930d2c83917332cf", - "sha256:2c926450857408e42f0bbc295e84395722ce74bae69a3b2aa2a65fe22cb14b99", - "sha256:2e24900aa13212e75e5b366cb9065e78bbf3893d4baab6052d1aca10d46d944c", - "sha256:303e04d422e9b911a09ad499b0368dc551e8c3cd15293c99160c7f1f07b59a48", - "sha256:352bd4c8c72d508778cf05ab491f6ef36149f4d0cb3c56b1b4302852255d05d5", - "sha256:3843f84a6c465a36559161e6c59dce2f2ac10943040c2fd021cfb70d58c4ad56", - "sha256:394c9c242113bfb4b9aa36e2b80a05ffa163a30691c7b5a29eba82e937895d5e", - "sha256:3bbdf44855ed8f0fbcd102ef05ec3012d6a4fd7c7562403f76ce6a52aeffb2b1", - "sha256:40de71985e9042ca00b7953c4f41eabc3dc514a2d1ff534027f091bc74416401", - "sha256:41fe21dc74ad3a779c3d73a2786bdf622ea81234bdd4faf90b8b03cad0c2c0b4", - "sha256:47df36a9fe24054b950bbc2db630d508cca3aa27ed0566c0baf661225e52c18e", - "sha256:4ea42116ceb6bb16dbb7d526e242cb6747b08b7710d9782aa3d6732bd8d27649", - "sha256:58bcc55721e8a90b88332d6cd441261ebb22342e238296bb330968952fbb3a6a", - "sha256:5c11e43016b9024240212d2a65043b70ed8dfd3b52678a1271972702d990ac6d", - "sha256:5cf820485f1b4c91e0417ea0afd41ce5cf5965011b3c22c400f6d144296ccbc0", - "sha256:5d8860749e813a6f65bad8285a0520607c9500caa23fea6ee407e63debcdbef6", - "sha256:6327eb8e419f7d9c38f333cde41b9ae348bec26d840927332f17e887a8dcb70d", - "sha256:65a5e4d3aa679610ac6e3569e865425b23b372277f89b5ef06cf2cdaf1ebf22b", - "sha256:66080ec69883597e4d026f2f71a231a1ee9887835902dbe6b6467d5a89216cf6", - "sha256:783263a4eaad7c49983fe4b2e7b53fa9770c136c270d2d4bbb6d2192bf4d9caf", - "sha256:7f44e24fa70f6fbc74aeec3e971f60a14dde85da364aa87f15d1be94ae75aeef", - "sha256:7fdfc24dcfce5b48109867c13b4cb15e4660e7bd7661741a391f821f23dfdca7", - "sha256:810860bb4bdce7557bc0febb84bbd88198b9dbc2022d8eebe5b3590b2ad6c842", - "sha256:841ea19b43d438a80b4de62ac6ab21cfe6827bb8a9dc62b896acc88eaf9cecba", - "sha256:84610c1502b2461255b4c9b7d5e9c48052601a8957cd0aea6ec7a7a1e1fb9420", - "sha256:899c5e1928eec13fd6f6d8dc51be23f0d09c5281e40d9cf4273d188d9feeaf9b", - "sha256:8bae29d60768bfa8fb92244b74502b18fae55a80eac13c88eb0b496d4268fd2d", - "sha256:8df3de3a9ab8325f94f646609a66cbeeede263910c5c0de0101079ad541af332", - "sha256:8fa3c6e3305aa1146b59a09b32b2e04074945ffcfb2f0931836d103a2c38f936", - "sha256:924620eef691990dfb56dc4709f280f40baee568c794b5c1885800c3ecc69816", - "sha256:9309869032abb23d196cb4e4db574232abe8b8be1339026f489eeb34a4acfd91", - "sha256:9545a33965d0d377b0bc823dcabf26980e77f1b6a7caa368a365a9497fb09420", - "sha256:9ac5995f2b408017b0be26d4a1d7c61bce106ff3d9e3324374d66b5964325448", - "sha256:9bbbcedd75acdfecf2159663b87f1bb5cfc80e7cd99f7ddd9d66eb98b14a8411", - "sha256:a4ae8135b11652b08a8baf07631d3ebfe65a4c87909dbef5fa0cdde440444ee4", - "sha256:a6394d7dadd3cfe3f4b3b186e54d5d8504d44f2d58dcc89d693698e8b7132b32", - "sha256:a97b4fe50b5890d36300820abd305694cb865ddb7885049587a5678215782a6b", - "sha256:ae4dc05c465a08a866b7a1baf360747078b362e6a6dbeb0c57f234db0ef88ae0", - "sha256:b1c63e8d377d039ac769cd0926558bb7068a1f7abb0f003e3717ee003ad85530", - "sha256:b1e2c1185858d7e10ff045c496bbf90ae752c28b365fef2c09cf0fa309291669", - "sha256:b4395e2f8d83fbe0c627b2b696acce67868793d7d9750e90e39592b3626691b7", - "sha256:b756072364347cb6aa5b60f9bc18e94b2f79632de3b0190253ad770c5df17db1", - "sha256:ba64dc2b3b7b158c6660d49cdb1d872d1d0bf4e42043ad8d5006099479a194e5", - "sha256:bed331fe18f58d844d39ceb398b77d6ac0b010d571cba8267c2e7165806b00ce", - "sha256:c188512b43542b1e91cadc3c6c915a82a5eb95929134faf7fd109f14f9892ce4", - "sha256:c21b9aa40e08e4f63a2f92ff3748e6b6c84d717d033c7b3438dd3123ee18f70e", - "sha256:ca713d4af15bae6e5d79b15c10c8522859a9a89d3b361a50b817c98c2fb402a2", - "sha256:cd4210baef299717db0a600d7a3cac81d46ef0e007f88c9335db79f8979c0d3d", - "sha256:cfe33efc9cb900a4c46f91a5ceba26d6df370ffddd9ca386eb1d4f0ad97b9ea9", - "sha256:d5cd3ab21acbdb414bb6c31958d7b06b85eeb40f66463c264a9b343a4e238642", - "sha256:dfbac4c2dfcc082fcf8d942d1e49b6aa0766c19d3358bd86e2000bf0fa4a9cf0", - "sha256:e235688f42b36be2b6b06fc37ac2126a73b75fb8d6bc66dd632aa35286238703", - "sha256:eb82dbba47a8318e75f679690190c10a5e1f447fbf9df41cbc4c3afd726d88cb", - "sha256:ebb86518203e12e96af765ee89034a1dbb0c3c65052d1b0c19bbbd6af8a145e1", - "sha256:ee78feb9d293c323b59a6f2dd441b63339a30edf35abcb51187d2fc26e696d13", - "sha256:eedab4c310c0299961ac285591acd53dc6723a1ebd90a57207c71f6e0c2153ab", - "sha256:efa568b885bca461f7c7b9e032655c0c143d305bf01c30caf6db2854a4532b38", - "sha256:efce6ae830831ab6a22b9b4091d411698145cb9b8fc869e1397ccf4b4b6455cb", - "sha256:f163d2fd041c630fed01bc48d28c3ed4a3b003c00acd396900e11ee5316b56bb", - "sha256:f20380df709d91525e4bee04746ba612a4df0972c1b8f8e1e8af997e678c7b81", - "sha256:f30f1928162e189091cf4d9da2eac617bfe78ef907a761614ff577ef4edfb3c8", - "sha256:f470c92737afa7d4c3aacc001e335062d582053d4dbe73cda126f2d7031068dd", - "sha256:ff8bf625fe85e119553b5383ba0fb6aa3d0ec2ae980295aaefa552374926b3f4" - ], - "markers": "python_version >= '3.7'", - "version": "==1.3.3" + "sha256:007df07a6e3eb3e33e9a1fe6a9db7af152bbd8a185f9aaa6ece10a3529e3e1c6", + "sha256:008eb8b31b3ea6896da16c38c1b136cb9fec9e249e77f6211d479db79a4eaf01", + "sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251", + "sha256:0c7c1b47859ee2cac3846fde1c1dc0f15da6cec5a0e5c72d101e0f83dcb67ff9", + "sha256:0e5c8764c7829343d919cc2dfc587a8db01c4f70a4ebbc49abde5d4b158b007b", + "sha256:10ff5faaa22786315ef57097a279b833ecab1a0bfb07d604c9cbb1c4cdc2ed87", + "sha256:17ae5cd0f333f94f2e03aaf140bb762c64783935cc764ff9c82dff626089bebf", + "sha256:19488c57c12d4e8095a922f328df3f179c820c212940a498623ed39160bc3c2f", + "sha256:1a0848b52815006ea6596c395f87449f693dc419061cc21e970f139d466dc0a0", + "sha256:1e78fb68cf9c1a6aa4a9a12e960a5c9dfbdb89b3695197aa7064705662515de2", + "sha256:261b9f5d17cac914531331ff1b1d452125bf5daa05faf73b71d935485b0c510b", + "sha256:2b8bcf994563466db019fab287ff390fffbfdb4f905fc77bc1c1d604b1c689cc", + "sha256:38461d02d66de17455072c9ba981d35f1d2a73024bee7790ac2f9e361ef1cd0c", + "sha256:490132667476f6781b4c9458298b0c1cddf237488abd228b0b3650e5ecba7467", + "sha256:491e014f5c43656da08958808588cc6c016847b4360e327a62cb308c791bd2d9", + "sha256:515e1abc578dd3b275d6a5114030b1330ba044ffba03f94091842852f806f1c1", + "sha256:556de4430ce324c836789fa4560ca62d1591d2538b8ceb0b4f68fb7b2384a27a", + "sha256:5833593c25ac59ede40ed4de6d67eb42928cca97f26feea219f21d0ed0959b79", + "sha256:6221d84d463fb110bdd7619b69cb43878a11d51cbb9394ae3105d082d5199167", + "sha256:6918d49b1f90821e93069682c06ffde41829c346c66b721e65a5c62b4bab0300", + "sha256:6c38721585f285203e4b4132a352eb3daa19121a035f3182e08e437cface44bf", + "sha256:71932b597f9895f011f47f17d6428252fc728ba2ae6024e13c3398a087c2cdea", + "sha256:7211ef110a9194b6042449431e08c4d80c0481e5891e58d429df5899690511c2", + "sha256:764226ceef3125e53ea2cb275000e309c0aa5464d43bd72abd661e27fffc26ab", + "sha256:7645a8e814a3ee34a89c4a372011dcd817964ce8cb273c8ed6119d706e9613e3", + "sha256:76d4711f6f6d08551a7e9ef28c722f4a50dd0fc204c56b4bcd95c6cc05ce6fbb", + "sha256:7f4f399d28478d1f604c2ff9119907af9726aed73680e5ed1ca634d377abb087", + "sha256:88f7bc0fcca81f985f78dd0fa68d2c75abf8272b1f5c323ea4a01a4d7a614efc", + "sha256:8d0edd6b1c7fb94922bf569c9b092ee187a83f03fb1a63076e7774b60f9481a8", + "sha256:901289d524fdd571be1c7be054f48b1f88ce8dddcbdf1ec698b27d4b8b9e5d62", + "sha256:93ea75c050c5bb3d98016b4ba2497851eadf0ac154d88a67d7a6816206f6fa7f", + "sha256:981b9ab5a0a3178ff413bca62526bb784249421c24ad7381e39d67981be2c326", + "sha256:9ac08e601308e41eb533f232dbf6b7e4cea762f9f84f6357136eed926c15d12c", + "sha256:a02eb8ab2b8f200179b5f62b59757685ae9987996ae549ccf30f983f40602431", + "sha256:a0c6da9aee33ff0b1a451e867da0c1f47408112b3391dd43133838339e410963", + "sha256:a6c8097e01886188e5be3e6b14e94ab365f384736aa1fca6a0b9e35bd4a30bc7", + "sha256:aa384489fefeb62321b238e64c07ef48398fe80f9e1e6afeff22e140e0850eef", + "sha256:ad2a9eb6d9839ae241701d0918f54c51365a51407fd80f6b8289e2dfca977cc3", + "sha256:b206646d176a007466358aa21d85cd8600a415c67c9bd15403336c331a10d956", + "sha256:b826d97e4276750beca7c8f0f1a4938892697a6bcd8ec8217b3312dad6982781", + "sha256:b89ac9768b82205936771f8d2eb3ce88503b1556324c9f903e7156669f521472", + "sha256:bd7bd3b3830247580de99c99ea2a01416dfc3c34471ca1298bccabf86d0ff4dc", + "sha256:bdf1847068c362f16b353163391210269e4f0569a3c166bc6a9f74ccbfc7e839", + "sha256:c11b0746f5d946fecf750428a95f3e9ebe792c1ee3b1e96eeba145dc631a9672", + "sha256:c5374b80521d3d3f2ec5572e05adc94601985cc526fb276d0c8574a6d749f1b3", + "sha256:ca265542ca427bf97aed183c1676e2a9c66942e822b14dc6e5f42e038f92a503", + "sha256:ce31ae3e19f3c902de379cf1323d90c649425b86de7bbdf82871b8a2a0615f3d", + "sha256:ceb6ec0a10c65540421e20ebd29083c50e6d1143278746a4ef6bcf6153171eb8", + "sha256:d081f13b095d74b67d550de04df1c756831f3b83dc9881c38985834387487f1b", + "sha256:d5655a942f5f5d2c9ed93d72148226d75369b4f6952680211972a33e59b1dfdc", + "sha256:d5a32087d720c608f42caed0ef36d2b3ea61a9d09ee59a5142d6070da9041b8f", + "sha256:d6484756b12f40003c6128bfcc3fa9f0d49a687e171186c2d85ec82e3758c559", + "sha256:dd65632acaf0d47608190a71bfe46b209719bf2beb59507db08ccdbe712f969b", + "sha256:de343e75f40e972bae1ef6090267f8260c1446a1695e77096db6cfa25e759a95", + "sha256:e29cda763f752553fa14c68fb2195150bfab22b352572cb36c43c47bedba70eb", + "sha256:e41f3de4df3e80de75845d3e743b3f1c4c8613c3997a912dbf0229fc61a8b963", + "sha256:e66d2a64d44d50d2543405fb183a21f76b3b5fd16f130f5c99187c3fb4e64919", + "sha256:e74b0506fa5aa5598ac6a975a12aa8928cbb58e1f5ac8360792ef15de1aa848f", + "sha256:f0ed05f5079c708fe74bf9027e95125334b6978bf07fd5ab923e9e55e5fbb9d3", + "sha256:f61e2dc5ad442c52b4887f1fdc112f97caeff4d9e6ebe78879364ac59f1663e1", + "sha256:fec520865f42e5c7f050c2a79038897b1c7d1595e907a9e08e3353293ffc948e" + ], + "markers": "python_version >= '3.8'", + "version": "==1.4.0" }, "grpcio": { "hashes": [ - "sha256:0212e2f7fdf7592e4b9d365087da30cb4d71e16a6f213120c89b4f8fb35a3ab3", - "sha256:09d4bfd84686cd36fd11fd45a0732c7628308d094b14d28ea74a81db0bce2ed3", - "sha256:1e623e0cf99a0ac114f091b3083a1848dbc64b0b99e181473b5a4a68d4f6f821", - "sha256:2288d76e4d4aa7ef3fe7a73c1c470b66ea68e7969930e746a8cd8eca6ef2a2ea", - "sha256:2296356b5c9605b73ed6a52660b538787094dae13786ba53080595d52df13a98", - "sha256:2a1e601ee31ef30a9e2c601d0867e236ac54c922d32ed9f727b70dd5d82600d5", - "sha256:2be88c081e33f20630ac3343d8ad9f1125f32987968e9c8c75c051c9800896e8", - "sha256:33d40954199bddbb6a78f8f6f2b2082660f381cd2583ec860a6c2fa7c8400c08", - "sha256:40e1cbf69d6741b40f750f3cccc64326f927ac6145a9914d33879e586002350c", - "sha256:46a057329938b08e5f0e12ea3d7aed3ecb20a0c34c4a324ef34e00cecdb88a12", - "sha256:4864f99aac207e3e45c5e26c6cbb0ad82917869abc2f156283be86c05286485c", - "sha256:4c44e1a765b31e175c391f22e8fc73b2a2ece0e5e6ff042743d8109b5d2eff9f", - "sha256:4cb283f630624ebb16c834e5ac3d7880831b07cbe76cb08ab7a271eeaeb8943e", - "sha256:5008964885e8d23313c8e5ea0d44433be9bfd7e24482574e8cc43c02c02fc796", - "sha256:50a9f075eeda5097aa9a182bb3877fe1272875e45370368ac0ee16ab9e22d019", - "sha256:51630c92591d6d3fe488a7c706bd30a61594d144bac7dee20c8e1ce78294f474", - "sha256:5cc928cfe6c360c1df636cf7991ab96f059666ac7b40b75a769410cc6217df9c", - "sha256:61f7203e2767800edee7a1e1040aaaf124a35ce0c7fe0883965c6b762defe598", - "sha256:66233ccd2a9371158d96e05d082043d47dadb18cbb294dc5accfdafc2e6b02a7", - "sha256:70fcac7b94f4c904152809a050164650ac81c08e62c27aa9f156ac518029ebbe", - "sha256:714242ad0afa63a2e6dabd522ae22e1d76e07060b5af2ddda5474ba4f14c2c94", - "sha256:782f4f8662a2157c4190d0f99eaaebc602899e84fb1e562a944e5025929e351c", - "sha256:7fc2b4edb938c8faa4b3c3ea90ca0dd89b7565a049e8e4e11b77e60e4ed2cc05", - "sha256:881d058c5ccbea7cc2c92085a11947b572498a27ef37d3eef4887f499054dca8", - "sha256:89dde0ac72a858a44a2feb8e43dc68c0c66f7857a23f806e81e1b7cc7044c9cf", - "sha256:8cdbcbd687e576d48f7886157c95052825ca9948c0ed2afdc0134305067be88b", - "sha256:8d6192c37a30a115f4663592861f50e130caed33efc4eec24d92ec881c92d771", - "sha256:96a41817d2c763b1d0b32675abeb9179aa2371c72aefdf74b2d2b99a1b92417b", - "sha256:9bdbb7624d65dc0ed2ed8e954e79ab1724526f09b1efa88dcd9a1815bf28be5f", - "sha256:9bf88004fe086c786dc56ef8dd6cb49c026833fdd6f42cb853008bce3f907148", - "sha256:a08920fa1a97d4b8ee5db2f31195de4a9def1a91bc003544eb3c9e6b8977960a", - "sha256:a2f5a1f1080ccdc7cbaf1171b2cf384d852496fe81ddedeb882d42b85727f610", - "sha256:b04202453941a63b36876a7172b45366dc0cde10d5fd7855c0f4a4e673c0357a", - "sha256:b38b3de8cff5bc70f8f9c615f51b48eff7313fc9aca354f09f81b73036e7ddfa", - "sha256:b52d00d1793d290c81ad6a27058f5224a7d5f527867e5b580742e1bd211afeee", - "sha256:b74ae837368cfffeb3f6b498688a123e6b960951be4dec0e869de77e7fa0439e", - "sha256:be48496b0e00460717225e7680de57c38be1d8629dc09dadcd1b3389d70d942b", - "sha256:c0e3155fc5335ec7b3b70f15230234e529ca3607b20a562b6c75fb1b1218874c", - "sha256:c2392f5b5d84b71d853918687d806c1aa4308109e5ca158a16e16a6be71041eb", - "sha256:c72956972e4b508dd39fdc7646637a791a9665b478e768ffa5f4fe42123d5de1", - "sha256:dc80c9c6b608bf98066a038e0172013a49cfa9a08d53335aefefda2c64fc68f4", - "sha256:e416c8baf925b5a1aff31f7f5aecc0060b25d50cce3a5a7255dc5cf2f1d4e5eb", - "sha256:f8da84bbc61a4e92af54dc96344f328e5822d574f767e9b08e1602bb5ddc254a", - "sha256:f900ed4ad7a0f1f05d35f955e0943944d5a75f607a836958c6b8ab2a81730ef2", - "sha256:fd6c6c29717724acf9fc1847c4515d57e4dc12762452457b9cb37461f30a81bb" + "sha256:00258cbe3f5188629828363ae8ff78477ce976a6f63fb2bb5e90088396faa82e", + "sha256:092fa155b945015754bdf988be47793c377b52b88d546e45c6a9f9579ac7f7b6", + "sha256:0f80bf37f09e1caba6a8063e56e2b87fa335add314cf2b78ebf7cb45aa7e3d06", + "sha256:20ec6fc4ad47d1b6e12deec5045ec3cd5402d9a1597f738263e98f490fe07056", + "sha256:2313b124e475aa9017a9844bdc5eafb2d5abdda9d456af16fc4535408c7d6da6", + "sha256:23e7d8849a0e58b806253fd206ac105b328171e01b8f18c7d5922274958cc87e", + "sha256:2f708a6a17868ad8bf586598bee69abded4996b18adf26fd2d91191383b79019", + "sha256:2f7349786da979a94690cc5c2b804cab4e8774a3cf59be40d037c4342c906649", + "sha256:34950353539e7d93f61c6796a007c705d663f3be41166358e3d88c45760c7d98", + "sha256:40b72effd4c789de94ce1be2b5f88d7b9b5f7379fe9645f198854112a6567d9a", + "sha256:4b089f7ad1eb00a104078bab8015b0ed0ebcb3b589e527ab009c53893fd4e613", + "sha256:4faea2cfdf762a664ab90589b66f416274887641ae17817de510b8178356bf73", + "sha256:5371bcd861e679d63b8274f73ac281751d34bd54eccdbfcd6aa00e692a82cd7b", + "sha256:5613a2fecc82f95d6c51d15b9a72705553aa0d7c932fad7aed7afb51dc982ee5", + "sha256:57b183e8b252825c4dd29114d6c13559be95387aafc10a7be645462a0fc98bbb", + "sha256:5b7a4ce8f862fe32b2a10b57752cf3169f5fe2915acfe7e6a1e155db3da99e79", + "sha256:5e5b58e32ae14658085c16986d11e99abd002ddbf51c8daae8a0671fffb3467f", + "sha256:60fe15288a0a65d5c1cb5b4a62b1850d07336e3ba728257a810317be14f0c527", + "sha256:6907b1cf8bb29b058081d2aad677b15757a44ef2d4d8d9130271d2ad5e33efca", + "sha256:76c44efa4ede1f42a9d5b2fed1fe9377e73a109bef8675fb0728eb80b0b8e8f2", + "sha256:7a635589201b18510ff988161b7b573f50c6a48fae9cb567657920ca82022b37", + "sha256:7b400807fa749a9eb286e2cd893e501b110b4d356a218426cb9c825a0474ca56", + "sha256:82640e57fb86ea1d71ea9ab54f7e942502cf98a429a200b2e743d8672171734f", + "sha256:871f9999e0211f9551f368612460442a5436d9444606184652117d6a688c9f51", + "sha256:9338bacf172e942e62e5889b6364e56657fbf8ac68062e8b25c48843e7b202bb", + "sha256:a8a8e560e8dbbdf29288872e91efd22af71e88b0e5736b0daf7773c1fecd99f0", + "sha256:aed90d93b731929e742967e236f842a4a2174dc5db077c8f9ad2c5996f89f63e", + "sha256:b363bbb5253e5f9c23d8a0a034dfdf1b7c9e7f12e602fc788c435171e96daccc", + "sha256:b4098b6b638d9e0ca839a81656a2fd4bc26c9486ea707e8b1437d6f9d61c3941", + "sha256:b53333627283e7241fcc217323f225c37783b5f0472316edcaa4479a213abfa6", + "sha256:b670c2faa92124b7397b42303e4d8eb64a4cd0b7a77e35a9e865a55d61c57ef9", + "sha256:bb396952cfa7ad2f01061fbc7dc1ad91dd9d69243bcb8110cf4e36924785a0fe", + "sha256:c60b83c43faeb6d0a9831f0351d7787a0753f5087cc6fa218d78fdf38e5acef0", + "sha256:c6ebecfb7a31385393203eb04ed8b6a08f5002f53df3d59e5e795edb80999652", + "sha256:d78d8b86fcdfa1e4c21f8896614b6cc7ee01a2a758ec0c4382d662f2a62cf766", + "sha256:d7f8df114d6b4cf5a916b98389aeaf1e3132035420a88beea4e3d977e5f267a5", + "sha256:e1cb52fa2d67d7f7fab310b600f22ce1ff04d562d46e9e0ac3e3403c2bb4cc16", + "sha256:e3fdf04e402f12e1de8074458549337febb3b45f21076cc02ef4ff786aff687e", + "sha256:e503cb45ed12b924b5b988ba9576dc9949b2f5283b8e33b21dcb6be74a7c58d0", + "sha256:f19ac6ac0a256cf77d3cc926ef0b4e64a9725cc612f97228cd5dc4bd9dbab03b", + "sha256:f1fb0fd4a1e9b11ac21c30c169d169ef434c6e9344ee0ab27cfa6f605f6387b2", + "sha256:fada6b07ec4f0befe05218181f4b85176f11d531911b64c715d1875c4736d73a", + "sha256:fd173b4cf02b20f60860dc2ffe30115c18972d7d6d2d69df97ac38dee03be5bf", + "sha256:fe752639919aad9ffb0dee0d87f29a6467d1ef764f13c4644d212a9a853a078d", + "sha256:fee387d2fab144e8a34e0e9c5ca0f45c9376b99de45628265cfa9886b1dbe62b" ], "index": "pypi", - "version": "==1.54.2" + "markers": "python_version >= '3.7'", + "version": "==1.57.0" }, "grpcio-tools": { "hashes": [ - "sha256:0239b929eb8b3b30b2397eef3b9abb245087754d77c3721e3be43c44796de87d", - "sha256:0ab1b323905d449298523db5d34fa5bf5fffd645bd872b25598e2f8a01f0ea39", - "sha256:0de05c7698c655e9a240dc34ae91d6017b93143ac89e5b20046d7ca3bd09c27c", - "sha256:0f952c8a5c47e9204fe8959f7e9add149e660f6579d67cf65024c32736d34caf", - "sha256:10dd41862f579d185c60f629b5ee89103e216f63b576079d258d974d980bad87", - "sha256:11939c9a8a39bd4815c7e88cb2fee48e1948775b59dbb06de8fcae5991e84f9e", - "sha256:129de5579f95d6a55dde185f188b4cbe19d1e2f1471425431d9930c31d300d70", - "sha256:1b8ee3099c51ce987fa8a08e6b93fc342b10228415dd96b5c0caa0387f636a6f", - "sha256:21b1467e31e44429d2a78b50135c9cdbd4b8f6d3b5cd548bc98985d3bdc352d0", - "sha256:21b9d2dee80f3f77e4097252e7f0db89772335a7300b72ab3d2e5c280872b1db", - "sha256:27671c68c7e0e3c5ff9967f5500799f65a04e7b153b8ce10243c87c43199039d", - "sha256:2b96f5f17d3156058be247fd25b062b4768138665694c00b056659618b8fb418", - "sha256:30a49b8b168aced2a4ff40959e6c4383ad6cfd7a20839a47a215e9837eb722dc", - "sha256:3237149beec39e897fd62cef4aa1e1cd9422d7a95661d24bd0a79200b167e730", - "sha256:37393ef90674964175923afe3859fc5a208e1ece565f642b4f76a8c0224a0993", - "sha256:39fd530cfdf58dc05125775cc233b05554d553d27478f14ae5fd8a6306f0cb28", - "sha256:3bb9ec4aea0f2b3006fb002fa59e5c10f92b48fc374619fbffd14d2b0e388c3e", - "sha256:49c2846dcc4803476e839d8bd4db8845e928f19130e0ea86121f2d1f43d2b452", - "sha256:4abfc1892380abe6cef381eab86f9350cbd703bfe5d834095aa66fd91c886b6d", - "sha256:4f285f8ef3de422717a36bd372239ae778b8cc112ce780ca3c7fe266dadc49fb", - "sha256:503ef1351c62fb1d6747eaf74932b609d8fdd4345b3591ef910adef8fa9969d0", - "sha256:5ef30c2dbc63c1e0a462423ca4f95001814d26ef4fe66208e53fcf220ea3b717", - "sha256:6037f123905dc0141f7c8383ca616ef0195e79cd3b4d82faaee789d4045e891b", - "sha256:72d15de4c4b6a764a76c4ae69d99c35f7a0751223688c3f7e62dfa95eb4f61be", - "sha256:7b24fbab9e7598518ce4549e066df00aab79c2bf9bedcdde23fb5ef6a3cf532f", - "sha256:7baa210c20f71a242d9ae0e02734628f6948e8bee3bf538647894af427d28800", - "sha256:7d7e6e8d62967b3f037f952620cb7381cc39a4bd31790c75fcfba56cc975d70b", - "sha256:7f4624ef2e76a3a5313c4e61a81be38bcc16b59a68a85d30758b84cd2102b161", - "sha256:8742122782953d2fd038f0a199f047a24e941cc9718b1aac90876dbdb7167739", - "sha256:8e4531267736d88fde1022b36dd42ed8163e3575bcbd12bfed96662872aa93fe", - "sha256:8e4c5a48f7b2e8798ce381498ee7b9a83c65b87ae66ee5022387394e5eb51771", - "sha256:9acf443dcf6f68fbea3b7fb519e1716e014db1a561939f5aecc4abda74e4015d", - "sha256:a0b7049814442f918b522d66b1d015286afbeb9e6d141af54bbfafe31710a3c8", - "sha256:a3ce0b98fb581c471424d2cda45120f57658ed97677c6fec4d6decf5d7c1b976", - "sha256:b80585e06c4f0082327eb5c9ad96fbdb2b0e7c14971ea5099fe78c22f4608451", - "sha256:b82ca472db9c914c44e39a41e9e8bd3ed724523dd7aff5ce37592b8d16920ed9", - "sha256:c4128c01cd6f5ea8f7c2db405dbfd8582cd967d36e6fa0952565436633b0e591", - "sha256:d512de051342a576bb89777476d13c5266d9334cf4badb6468aed9dc8f5bdec1", - "sha256:df079479fb1b9e488334312e35ebbf30cbf5ecad6c56599f1a961800b33ab7c1", - "sha256:e11c2c2aee53f340992e8e4d6a59172cbbbd0193f1351de98c4f810a5041d5ca", - "sha256:e3d0e5188ff8dbaddac2ee44731d36f09c4eccd3eac7328e547862c44f75cacd", - "sha256:e543f457935ba7b763b121f1bf893974393b4d30065042f947f85a8d81081b80", - "sha256:e5c7292dd899ad8fa09a2be96719648cee37b17909fe8c12007e3bff58ebee61", - "sha256:f39d8e8806b8857fb473ca6a9c7bd800b0673dfdb7283ff569af0345a222f32c", - "sha256:f6787d07fdab31a32c433c1ba34883dea6559d8a3fbe08fb93d834ca34136b71" + "sha256:02d78c034109f46032c7217260066d49d41e6bcaf588fa28fa40fe2f83445347", + "sha256:0cf5fc0a1c23f8ea34b408b72fb0e90eec0f404ad4dba98e8f6da3c9ce34e2ed", + "sha256:1c0e8a1a32973a5d59fbcc19232f925e5c48116e9411f788033a31c5ca5130b4", + "sha256:1f9e917a9f18087f6c14b4d4508fb94fca5c2f96852363a89232fb9b2124ac1f", + "sha256:26e69d08a515554e0cfe1ec4d31568836f4b17f0ff82294f957f629388629eb9", + "sha256:2b417c97936d94874a3ce7ed8deab910f2233e3612134507cfee4af8735c38a6", + "sha256:2db25f15ed44327f2e02d0c4fe741ac966f9500e407047d8a7c7fccf2df65616", + "sha256:2f16130d869ce27ecd623194547b649dd657333ec7e8644cc571c645781a9b85", + "sha256:34b36217b17b5bea674a414229913e1fd80ede328be51e1b531fcc62abd393b0", + "sha256:35bf0dad8a3562043345236c26d0053a856fb06c04d7da652f2ded914e508ae7", + "sha256:495e2946406963e0b9f063f76d5af0f2a19517dac2b367b5b044432ac9194296", + "sha256:4a7ad7f328e28fc97c356d0f10fb10d8b5151bb65aa7cf14bf8084513f0b7306", + "sha256:4fb8a8468031f858381a576078924af364a08833d8f8f3237018252c4573a802", + "sha256:5bc3e6d338aefb052e19cedabe00452be46d0c10a4ed29ee77abb00402e438fe", + "sha256:6fa52972c9647876ea35f6dc2b51002a74ed900ec7894586cbb2fe76f64f99de", + "sha256:76c0eea89d7542719594e50e2283f51a072978b953e8b3e9fd7c59a2c762d4c1", + "sha256:784574709b9690dc28696617ea69352e2132352fdfc9bc89afa8e39f99ae538e", + "sha256:7b46fc6aa8eb7edd18cafcd21fd98703cb6c09e46b507de335fca7f0161dfccb", + "sha256:81ec4dbb696e095057b2528d11a8da04be6bbe2b967fa07d4ea9ba6354338cbf", + "sha256:850cbda0ec5d24c39e7215ede410276040692ca45d105fbbeada407fa03f0ac0", + "sha256:85ac4e62eb44428cde025fd9ab7554002315fc7880f791c553fc5a0015cc9931", + "sha256:8a42dc220eb5305f470855c9284f4c8e85ae59d6d742cd07946b0cbe5e9ca186", + "sha256:9053c2f655589545be08b9d6a673e92970173a4bf11a4b9f18cd6e9af626b587", + "sha256:90d10d9038ba46a595a223a34f136c9230e3d6d7abc2433dbf0e1c31939d3a8b", + "sha256:9867f2817b1a0c93c523f89ac6c9d8625548af4620a7ce438bf5a76e23327284", + "sha256:9a3d60fb8d46ede26c1907c146561b3a9caa20a7aff961bc661ef8226f85a2e9", + "sha256:9f2aefa8a37bd2c4db1a3f1aca11377e2766214520fb70e67071f4ff8d8b0fa5", + "sha256:a0256f8786ac9e4db618a1aa492bb3472569a0946fd3ee862ffe23196323da55", + "sha256:aac98ecad8f7bd4301855669d42a5d97ef7bb34bec2b1e74c7a0641d47e313cf", + "sha256:c026bdf5c1366ce88b7bbe2d8207374d675afd3fd911f60752103de3da4a41d2", + "sha256:c39a3656576b6fdaaf28abe0467f7a7231df4230c1bee132322dbc3209419e7f", + "sha256:cdd020cb68b51462983b7c2dfbc3eb6ede032b8bf438d4554df0c3f08ce35c76", + "sha256:d2a134756f4db34759a5cc7f7e43f7eb87540b68d1cca62925593c6fb93924f7", + "sha256:dbde4004a0688400036342ff73e3706e8940483e2871547b1354d59e93a38277", + "sha256:dc771d4db5701f280957bbcee91745e0686d00ed1c6aa7e05ba30a58b02d70a1", + "sha256:dfb6f6120587b8e228a3cae5ee4985b5bdc18501bad05c49df61965dfc9d70a9", + "sha256:e868cd6feb3ef07d4b35be104fe1fd0657db05259ff8f8ec5e08f4f89ca1191d", + "sha256:ec9aab2fb6783c7fc54bc28f58eb75f1ca77594e6b0fd5e5e7a8114a95169fe0", + "sha256:ed85a0291fff45b67f2557fe7f117d3bc7af8b54b8619d27bf374b5c8b7e3ca2", + "sha256:f3ac06703c412f8167a9062eaf6099409967e33bf98fa5b02be4b4689b6bdf39", + "sha256:f3da5240211252fc70a6451fe00c143e2ab2f7bfc2445695ad2ed056b8e48d96", + "sha256:f54081b08419a39221cd646363b5708857c696b3ad4784f1dcf310891e33a5f7", + "sha256:f64f8ab22d27d4a5693310748d35a696061c3b5c7b8c4fb4ab3b4bc1068b6b56", + "sha256:f717cce5093e6b6049d9ea6d12fdf3658efdb1a80772f7737db1f8510b876df6", + "sha256:fb81ff861692111fa81bd85f64584e624cb4013bd66fbce8a209b8893f5ce398" ], "index": "pypi", - "version": "==1.54.2" + "markers": "python_version >= '3.7'", + "version": "==1.57.0" }, "hdwallets": { "hashes": [ @@ -884,6 +873,7 @@ "sha256:c85d08b59c3fd3bc5b29398583d7d7dc46f95456f69ff15a3ab0353084ee7529" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==0.1.2" }, "hexbytes": { @@ -908,6 +898,7 @@ "sha256:acd2168872d0379e7a10873bb3e12bf6c91b35de758135c4fbd1015ef18fafc5" ], "index": "pypi", + "markers": "python_version >= '3.5'", "version": "==0.20" }, "multidict": { @@ -998,22 +989,23 @@ }, "protobuf": { "hashes": [ - "sha256:0149053336a466e3e0b040e54d0b615fc71de86da66791c592cc3c8d18150bf8", - "sha256:08fe19d267608d438aa37019236db02b306e33f6b9902c3163838b8e75970223", - "sha256:29660574cd769f2324a57fb78127cda59327eb6664381ecfe1c69731b83e8288", - "sha256:2991f5e7690dab569f8f81702e6700e7364cc3b5e572725098215d3da5ccc6ac", - "sha256:3b01a5274ac920feb75d0b372d901524f7e3ad39c63b1a2d55043f3887afe0c1", - "sha256:3bcbeb2bf4bb61fe960dd6e005801a23a43578200ea8ceb726d1f6bd0e562ba1", - "sha256:447b9786ac8e50ae72cae7a2eec5c5df6a9dbf9aa6f908f1b8bda6032644ea62", - "sha256:514b6bbd54a41ca50c86dd5ad6488afe9505901b3557c5e0f7823a0cf67106fb", - "sha256:5cb9e41188737f321f4fce9a4337bf40a5414b8d03227e1d9fbc59bc3a216e35", - "sha256:7a92beb30600332a52cdadbedb40d33fd7c8a0d7f549c440347bc606fb3fe34b", - "sha256:84ea0bd90c2fdd70ddd9f3d3fc0197cc24ecec1345856c2b5ba70e4d99815359", - "sha256:aca6e86a08c5c5962f55eac9b5bd6fce6ed98645d77e8bfc2b952ecd4a8e4f6a", - "sha256:cc14358a8742c4e06b1bfe4be1afbdf5c9f6bd094dff3e14edb78a1513893ff5" + "sha256:237b9a50bd3b7307d0d834c1b0eb1a6cd47d3f4c2da840802cd03ea288ae8880", + "sha256:25ae91d21e3ce8d874211110c2f7edd6384816fb44e06b2867afe35139e1fd1c", + "sha256:2b23bd6e06445699b12f525f3e92a916f2dcf45ffba441026357dea7fa46f42b", + "sha256:3b7b170d3491ceed33f723bbf2d5a260f8a4e23843799a3906f16ef736ef251e", + "sha256:4e69965e7e54de4db989289a9b971a099e626f6167a9351e9d112221fc691bc1", + "sha256:58e12d2c1aa428ece2281cef09bbaa6938b083bcda606db3da4e02e991a0d924", + "sha256:6bd26c1fa9038b26c5c044ee77e0ecb18463e957fefbaeb81a3feb419313a54e", + "sha256:77700b55ba41144fc64828e02afb41901b42497b8217b558e4a001f18a85f2e3", + "sha256:7fda70797ddec31ddfa3576cbdcc3ddbb6b3078b737a1a87ab9136af0570cd6e", + "sha256:839952e759fc40b5d46be319a265cf94920174d88de31657d5622b5d8d6be5cd", + "sha256:bb7aa97c252279da65584af0456f802bd4b2de429eb945bbc9b3d61a42a8cd16", + "sha256:c00c3c7eb9ad3833806e21e86dca448f46035242a680f81c3fe068ff65e79c74", + "sha256:c5cdd486af081bf752225b26809d2d0a85e575b80a84cde5172a05bbb1990099" ], "index": "pypi", - "version": "==4.23.3" + "markers": "python_version >= '3.7'", + "version": "==4.24.2" }, "pycparser": { "hashes": [ @@ -1069,97 +1061,97 @@ }, "regex": { "hashes": [ - "sha256:0385e73da22363778ef2324950e08b689abdf0b108a7d8decb403ad7f5191938", - "sha256:051da80e6eeb6e239e394ae60704d2b566aa6a7aed6f2890a7967307267a5dc6", - "sha256:05ed27acdf4465c95826962528f9e8d41dbf9b1aa8531a387dee6ed215a3e9ef", - "sha256:0654bca0cdf28a5956c83839162692725159f4cda8d63e0911a2c0dc76166525", - "sha256:09e4a1a6acc39294a36b7338819b10baceb227f7f7dbbea0506d419b5a1dd8af", - "sha256:0b49c764f88a79160fa64f9a7b425620e87c9f46095ef9c9920542ab2495c8bc", - "sha256:0b71e63226e393b534105fcbdd8740410dc6b0854c2bfa39bbda6b0d40e59a54", - "sha256:0c29ca1bd61b16b67be247be87390ef1d1ef702800f91fbd1991f5c4421ebae8", - "sha256:10590510780b7541969287512d1b43f19f965c2ece6c9b1c00fc367b29d8dce7", - "sha256:10cb847aeb1728412c666ab2e2000ba6f174f25b2bdc7292e7dd71b16db07568", - "sha256:12b74fbbf6cbbf9dbce20eb9b5879469e97aeeaa874145517563cca4029db65c", - "sha256:20326216cc2afe69b6e98528160b225d72f85ab080cbdf0b11528cbbaba2248f", - "sha256:2239d95d8e243658b8dbb36b12bd10c33ad6e6933a54d36ff053713f129aa536", - "sha256:25be746a8ec7bc7b082783216de8e9473803706723b3f6bef34b3d0ed03d57e2", - "sha256:271f0bdba3c70b58e6f500b205d10a36fb4b58bd06ac61381b68de66442efddb", - "sha256:29cdd471ebf9e0f2fb3cac165efedc3c58db841d83a518b082077e612d3ee5df", - "sha256:2d44dc13229905ae96dd2ae2dd7cebf824ee92bc52e8cf03dcead37d926da019", - "sha256:3676f1dd082be28b1266c93f618ee07741b704ab7b68501a173ce7d8d0d0ca18", - "sha256:36efeba71c6539d23c4643be88295ce8c82c88bbd7c65e8a24081d2ca123da3f", - "sha256:3e5219bf9e75993d73ab3d25985c857c77e614525fac9ae02b1bebd92f7cecac", - "sha256:43e1dd9d12df9004246bacb79a0e5886b3b6071b32e41f83b0acbf293f820ee8", - "sha256:457b6cce21bee41ac292d6753d5e94dcbc5c9e3e3a834da285b0bde7aa4a11e9", - "sha256:463b6a3ceb5ca952e66550a4532cef94c9a0c80dc156c4cc343041951aec1697", - "sha256:4959e8bcbfda5146477d21c3a8ad81b185cd252f3d0d6e4724a5ef11c012fb06", - "sha256:4d3850beab9f527f06ccc94b446c864059c57651b3f911fddb8d9d3ec1d1b25d", - "sha256:5708089ed5b40a7b2dc561e0c8baa9535b77771b64a8330b684823cfd5116036", - "sha256:5c6b48d0fa50d8f4df3daf451be7f9689c2bde1a52b1225c5926e3f54b6a9ed1", - "sha256:61474f0b41fe1a80e8dfa70f70ea1e047387b7cd01c85ec88fa44f5d7561d787", - "sha256:6343c6928282c1f6a9db41f5fd551662310e8774c0e5ebccb767002fcf663ca9", - "sha256:65ba8603753cec91c71de423a943ba506363b0e5c3fdb913ef8f9caa14b2c7e0", - "sha256:687ea9d78a4b1cf82f8479cab23678aff723108df3edeac098e5b2498879f4a7", - "sha256:6b2675068c8b56f6bfd5a2bda55b8accbb96c02fd563704732fd1c95e2083461", - "sha256:7117d10690c38a622e54c432dfbbd3cbd92f09401d622902c32f6d377e2300ee", - "sha256:7178bbc1b2ec40eaca599d13c092079bf529679bf0371c602edaa555e10b41c3", - "sha256:72d1a25bf36d2050ceb35b517afe13864865268dfb45910e2e17a84be6cbfeb0", - "sha256:742e19a90d9bb2f4a6cf2862b8b06dea5e09b96c9f2df1779e53432d7275331f", - "sha256:74390d18c75054947e4194019077e243c06fbb62e541d8817a0fa822ea310c14", - "sha256:74419d2b50ecb98360cfaa2974da8689cb3b45b9deff0dcf489c0d333bcc1477", - "sha256:824bf3ac11001849aec3fa1d69abcb67aac3e150a933963fb12bda5151fe1bfd", - "sha256:83320a09188e0e6c39088355d423aa9d056ad57a0b6c6381b300ec1a04ec3d16", - "sha256:837328d14cde912af625d5f303ec29f7e28cdab588674897baafaf505341f2fc", - "sha256:841d6e0e5663d4c7b4c8099c9997be748677d46cbf43f9f471150e560791f7ff", - "sha256:87b2a5bb5e78ee0ad1de71c664d6eb536dc3947a46a69182a90f4410f5e3f7dd", - "sha256:890e5a11c97cf0d0c550eb661b937a1e45431ffa79803b942a057c4fb12a2da2", - "sha256:8abbc5d54ea0ee80e37fef009e3cec5dafd722ed3c829126253d3e22f3846f1e", - "sha256:8e3f1316c2293e5469f8f09dc2d76efb6c3982d3da91ba95061a7e69489a14ef", - "sha256:8f56fcb7ff7bf7404becdfc60b1e81a6d0561807051fd2f1860b0d0348156a07", - "sha256:9427a399501818a7564f8c90eced1e9e20709ece36be701f394ada99890ea4b3", - "sha256:976d7a304b59ede34ca2921305b57356694f9e6879db323fd90a80f865d355a3", - "sha256:9a5bfb3004f2144a084a16ce19ca56b8ac46e6fd0651f54269fc9e230edb5e4a", - "sha256:9beb322958aaca059f34975b0df135181f2e5d7a13b84d3e0e45434749cb20f7", - "sha256:9edcbad1f8a407e450fbac88d89e04e0b99a08473f666a3f3de0fd292badb6aa", - "sha256:9edce5281f965cf135e19840f4d93d55b3835122aa76ccacfd389e880ba4cf82", - "sha256:a4c3b7fa4cdaa69268748665a1a6ff70c014d39bb69c50fda64b396c9116cf77", - "sha256:a8105e9af3b029f243ab11ad47c19b566482c150c754e4c717900a798806b222", - "sha256:a99b50300df5add73d307cf66abea093304a07eb017bce94f01e795090dea87c", - "sha256:aad51907d74fc183033ad796dd4c2e080d1adcc4fd3c0fd4fd499f30c03011cd", - "sha256:af4dd387354dc83a3bff67127a124c21116feb0d2ef536805c454721c5d7993d", - "sha256:b28f5024a3a041009eb4c333863d7894d191215b39576535c6734cd88b0fcb68", - "sha256:b4598b1897837067a57b08147a68ac026c1e73b31ef6e36deeeb1fa60b2933c9", - "sha256:b6192d5af2ccd2a38877bfef086d35e6659566a335b1492786ff254c168b1693", - "sha256:b862c2b9d5ae38a68b92e215b93f98d4c5e9454fa36aae4450f61dd33ff48487", - "sha256:b956231ebdc45f5b7a2e1f90f66a12be9610ce775fe1b1d50414aac1e9206c06", - "sha256:bb60b503ec8a6e4e3e03a681072fa3a5adcbfa5479fa2d898ae2b4a8e24c4591", - "sha256:bbb02fd4462f37060122e5acacec78e49c0fbb303c30dd49c7f493cf21fc5b27", - "sha256:bdff5eab10e59cf26bc479f565e25ed71a7d041d1ded04ccf9aee1d9f208487a", - "sha256:c123f662be8ec5ab4ea72ea300359023a5d1df095b7ead76fedcd8babbedf969", - "sha256:c2b867c17a7a7ae44c43ebbeb1b5ff406b3e8d5b3e14662683e5e66e6cc868d3", - "sha256:c5f8037000eb21e4823aa485149f2299eb589f8d1fe4b448036d230c3f4e68e0", - "sha256:c6a57b742133830eec44d9b2290daf5cbe0a2f1d6acee1b3c7b1c7b2f3606df7", - "sha256:ccf91346b7bd20c790310c4147eee6ed495a54ddb6737162a36ce9dbef3e4751", - "sha256:cf67ca618b4fd34aee78740bea954d7c69fdda419eb208c2c0c7060bb822d747", - "sha256:d2da3abc88711bce7557412310dfa50327d5769a31d1c894b58eb256459dc289", - "sha256:d4f03bb71d482f979bda92e1427f3ec9b220e62a7dd337af0aa6b47bf4498f72", - "sha256:d54af539295392611e7efbe94e827311eb8b29668e2b3f4cadcfe6f46df9c777", - "sha256:d77f09bc4b55d4bf7cc5eba785d87001d6757b7c9eec237fe2af57aba1a071d9", - "sha256:d831c2f8ff278179705ca59f7e8524069c1a989e716a1874d6d1aab6119d91d1", - "sha256:dbbbfce33cd98f97f6bffb17801b0576e653f4fdb1d399b2ea89638bc8d08ae1", - "sha256:dcba6dae7de533c876255317c11f3abe4907ba7d9aa15d13e3d9710d4315ec0e", - "sha256:e0bb18053dfcfed432cc3ac632b5e5e5c5b7e55fb3f8090e867bfd9b054dbcbf", - "sha256:e2fbd6236aae3b7f9d514312cdb58e6494ee1c76a9948adde6eba33eb1c4264f", - "sha256:e5087a3c59eef624a4591ef9eaa6e9a8d8a94c779dade95d27c0bc24650261cd", - "sha256:e8915cc96abeb8983cea1df3c939e3c6e1ac778340c17732eb63bb96247b91d2", - "sha256:ea353ecb6ab5f7e7d2f4372b1e779796ebd7b37352d290096978fea83c4dba0c", - "sha256:ee2d1a9a253b1729bb2de27d41f696ae893507c7db224436abe83ee25356f5c1", - "sha256:f415f802fbcafed5dcc694c13b1292f07fe0befdb94aa8a52905bd115ff41e88", - "sha256:fb5ec16523dc573a4b277663a2b5a364e2099902d3944c9419a40ebd56a118f9", - "sha256:fea75c3710d4f31389eed3c02f62d0b66a9da282521075061ce875eb5300cf23" + "sha256:0085da0f6c6393428bf0d9c08d8b1874d805bb55e17cb1dfa5ddb7cfb11140bf", + "sha256:06c57e14ac723b04458df5956cfb7e2d9caa6e9d353c0b4c7d5d54fcb1325c46", + "sha256:09b7f4c66aa9d1522b06e31a54f15581c37286237208df1345108fcf4e050c18", + "sha256:0c59122ceccb905a941fb23b087b8eafc5290bf983ebcb14d2301febcbe199c7", + "sha256:1005c60ed7037be0d9dea1f9c53cc42f836188227366370867222bda4c3c6bd7", + "sha256:14898830f0a0eb67cae2bbbc787c1a7d6e34ecc06fbd39d3af5fe29a4468e2c9", + "sha256:14dc6f2d88192a67d708341f3085df6a4f5a0c7b03dec08d763ca2cd86e9f559", + "sha256:1e7d84d64c84ad97bf06f3c8cb5e48941f135ace28f450d86af6b6512f1c9a71", + "sha256:2162ae2eb8b079622176a81b65d486ba50b888271302190870b8cc488587d280", + "sha256:22283c769a7b01c8ac355d5be0715bf6929b6267619505e289f792b01304d898", + "sha256:239c3c2a339d3b3ddd51c2daef10874410917cd2b998f043c13e2084cb191684", + "sha256:293352710172239bf579c90a9864d0df57340b6fd21272345222fb6371bf82b3", + "sha256:2ae54a338191e1356253e7883d9d19f8679b6143703086245fb14d1f20196be9", + "sha256:2e73e5243af12d9cd6a9d6a45a43570dbe2e5b1cdfc862f5ae2b031e44dd95a8", + "sha256:2e9216e0d2cdce7dbc9be48cb3eacb962740a09b011a116fd7af8c832ab116ca", + "sha256:3026cbcf11d79095a32d9a13bbc572a458727bd5b1ca332df4a79faecd45281c", + "sha256:3611576aff55918af2697410ff0293d6071b7e00f4b09e005d614686ac4cd57c", + "sha256:3ae646c35cb9f820491760ac62c25b6d6b496757fda2d51be429e0e7b67ae0ab", + "sha256:3b8e6ea6be6d64104d8e9afc34c151926f8182f84e7ac290a93925c0db004bfd", + "sha256:3d370ff652323c5307d9c8e4c62efd1956fb08051b0e9210212bc51168b4ff56", + "sha256:3f7454aa427b8ab9101f3787eb178057c5250478e39b99540cfc2b889c7d0586", + "sha256:40f029d73b10fac448c73d6eb33d57b34607f40116e9f6e9f0d32e9229b147d7", + "sha256:423adfa872b4908843ac3e7a30f957f5d5282944b81ca0a3b8a7ccbbfaa06103", + "sha256:4873ef92e03a4309b3ccd8281454801b291b689f6ad45ef8c3658b6fa761d7ac", + "sha256:48c640b99213643d141550326f34f0502fedb1798adb3c9eb79650b1ecb2f177", + "sha256:4ae594c66f4a7e1ea67232a0846649a7c94c188d6c071ac0210c3e86a5f92109", + "sha256:4b694430b3f00eb02c594ff5a16db30e054c1b9589a043fe9174584c6efa8033", + "sha256:51d8ea2a3a1a8fe4f67de21b8b93757005213e8ac3917567872f2865185fa7fb", + "sha256:54de2619f5ea58474f2ac211ceea6b615af2d7e4306220d4f3fe690c91988a61", + "sha256:551ad543fa19e94943c5b2cebc54c73353ffff08228ee5f3376bd27b3d5b9800", + "sha256:5543c055d8ec7801901e1193a51570643d6a6ab8751b1f7dd9af71af467538bb", + "sha256:5cd9cd7170459b9223c5e592ac036e0704bee765706445c353d96f2890e816c8", + "sha256:5ec4b3f0aebbbe2fc0134ee30a791af522a92ad9f164858805a77442d7d18570", + "sha256:67ecd894e56a0c6108ec5ab1d8fa8418ec0cff45844a855966b875d1039a2e34", + "sha256:6ab2ed84bf0137927846b37e882745a827458689eb969028af8032b1b3dac78e", + "sha256:704f63b774218207b8ccc6c47fcef5340741e5d839d11d606f70af93ee78e4d4", + "sha256:7098c524ba9f20717a56a8d551d2ed491ea89cbf37e540759ed3b776a4f8d6eb", + "sha256:7aed90a72fc3654fba9bc4b7f851571dcc368120432ad68b226bd593f3f6c0b7", + "sha256:7ce606c14bb195b0e5108544b540e2c5faed6843367e4ab3deb5c6aa5e681208", + "sha256:7eb95fe8222932c10d4436e7a6f7c99991e3fdd9f36c949eff16a69246dee2dc", + "sha256:80b80b889cb767cc47f31d2b2f3dec2db8126fbcd0cff31b3925b4dc6609dcdb", + "sha256:82cd0a69cd28f6cc3789cc6adeb1027f79526b1ab50b1f6062bbc3a0ccb2dbc3", + "sha256:83215147121e15d5f3a45d99abeed9cf1fe16869d5c233b08c56cdf75f43a504", + "sha256:88900f521c645f784260a8d346e12a1590f79e96403971241e64c3a265c8ecdb", + "sha256:91129ff1bb0619bc1f4ad19485718cc623a2dc433dff95baadbf89405c7f6b57", + "sha256:920974009fb37b20d32afcdf0227a2e707eb83fe418713f7a8b7de038b870d0b", + "sha256:9233ac249b354c54146e392e8a451e465dd2d967fc773690811d3a8c240ac601", + "sha256:941460db8fe3bd613db52f05259c9336f5a47ccae7d7def44cc277184030a116", + "sha256:942f8b1f3b223638b02df7df79140646c03938d488fbfb771824f3d05fc083a8", + "sha256:964b16dcc10c79a4a2be9f1273fcc2684a9eedb3906439720598029a797b46e6", + "sha256:9691a549c19c22d26a4f3b948071e93517bdf86e41b81d8c6ac8a964bb71e5a6", + "sha256:96979d753b1dc3b2169003e1854dc67bfc86edf93c01e84757927f810b8c3c93", + "sha256:987b9ac04d0b38ef4f89fbc035e84a7efad9cdd5f1e29024f9289182c8d99e09", + "sha256:988631b9d78b546e284478c2ec15c8a85960e262e247b35ca5eaf7ee22f6050a", + "sha256:9a96edd79661e93327cfeac4edec72a4046e14550a1d22aa0dd2e3ca52aec921", + "sha256:9b7408511fca48a82a119d78a77c2f5eb1b22fe88b0d2450ed0756d194fe7a9a", + "sha256:9dd6082f4e2aec9b6a0927202c85bc1b09dcab113f97265127c1dc20e2e32495", + "sha256:a2ad5add903eb7cdde2b7c64aaca405f3957ab34f16594d2b78d53b8b1a6a7d6", + "sha256:a8c65c17aed7e15a0c824cdc63a6b104dfc530f6fa8cb6ac51c437af52b481c7", + "sha256:aadf28046e77a72f30dcc1ab185639e8de7f4104b8cb5c6dfa5d8ed860e57236", + "sha256:b076da1ed19dc37788f6a934c60adf97bd02c7eea461b73730513921a85d4235", + "sha256:b2aeab3895d778155054abea5238d0eb9a72e9242bd4b43f42fd911ef9a13470", + "sha256:b82edc98d107cbc7357da7a5a695901b47d6eb0420e587256ba3ad24b80b7d0b", + "sha256:b8a0ccc8f2698f120e9e5742f4b38dc944c38744d4bdfc427616f3a163dd9de5", + "sha256:b993b6f524d1e274a5062488a43e3f9f8764ee9745ccd8e8193df743dbe5ee61", + "sha256:bb34d1605f96a245fc39790a117ac1bac8de84ab7691637b26ab2c5efb8f228c", + "sha256:bd3366aceedf274f765a3a4bc95d6cd97b130d1dda524d8f25225d14123c01db", + "sha256:c12f6f67495ea05c3d542d119d270007090bad5b843f642d418eb601ec0fa7be", + "sha256:c662a4cbdd6280ee56f841f14620787215a171c4e2d1744c9528bed8f5816c96", + "sha256:c884d1a59e69e03b93cf0dfee8794c63d7de0ee8f7ffb76e5f75be8131b6400a", + "sha256:ca339088839582d01654e6f83a637a4b8194d0960477b9769d2ff2cfa0fa36d2", + "sha256:cd2b6c5dfe0929b6c23dde9624483380b170b6e34ed79054ad131b20203a1a63", + "sha256:ce0f9fbe7d295f9922c0424a3637b88c6c472b75eafeaff6f910494a1fa719ef", + "sha256:cf0633e4a1b667bfe0bb10b5e53fe0d5f34a6243ea2530eb342491f1adf4f739", + "sha256:cf9273e96f3ee2ac89ffcb17627a78f78e7516b08f94dc435844ae72576a276e", + "sha256:d909b5a3fff619dc7e48b6b1bedc2f30ec43033ba7af32f936c10839e81b9217", + "sha256:d9b6627408021452dcd0d2cdf8da0534e19d93d070bfa8b6b4176f99711e7f90", + "sha256:de35342190deb7b866ad6ba5cbcccb2d22c0487ee0cbb251efef0843d705f0d4", + "sha256:e51c80c168074faa793685656c38eb7a06cbad7774c8cbc3ea05552d615393d8", + "sha256:e6bd1e9b95bc5614a7a9c9c44fde9539cba1c823b43a9f7bc11266446dd568e3", + "sha256:e7a9aaa5a1267125eef22cef3b63484c3241aaec6f48949b366d26c7250e0357", + "sha256:e951d1a8e9963ea51efd7f150450803e3b95db5939f994ad3d5edac2b6f6e2b4", + "sha256:e9941a4ada58f6218694f382e43fdd256e97615db9da135e77359da257a7168b", + "sha256:f0640913d2c1044d97e30d7c41728195fc37e54d190c5385eacb52115127b882", + "sha256:f0ccf3e01afeb412a1a9993049cb160d0352dba635bbca7762b2dc722aa5742a", + "sha256:f2181c20ef18747d5f4a7ea513e09ea03bdd50884a11ce46066bb90fe4213675", + "sha256:f2200e00b62568cfd920127782c61bc1c546062a879cdc741cfcc6976668dfcf", + "sha256:fcbdc5f2b0f1cd0f6a56cdb46fe41d2cce1e644e3b68832f3eeebc5fb0f7712e" ], "markers": "python_version >= '3.6'", - "version": "==2023.6.3" + "version": "==2023.8.8" }, "requests": { "hashes": [ @@ -1167,6 +1159,7 @@ "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==2.31.0" }, "rlp": { @@ -1185,11 +1178,11 @@ }, "setuptools": { "hashes": [ - "sha256:5df61bf30bb10c6f756eb19e7c9f3b473051f48db77fddbe06ff2ca307df9a6f", - "sha256:62642358adc77ffa87233bc4d2354c4b2682d214048f500964dbe760ccedf102" + "sha256:3d4dfa6d95f1b101d695a6160a7626e15583af71a5f52176efa5d39a054d475d", + "sha256:3d8083eed2d13afc9426f227b24fd1659489ec107c0e86cec2ffdde5c92e790b" ], - "markers": "python_version >= '3.7'", - "version": "==67.8.0" + "markers": "python_version >= '3.8'", + "version": "==68.1.2" }, "six": { "hashes": [ @@ -1221,6 +1214,7 @@ "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", "version": "==1.26.16" }, "websockets": { @@ -1297,6 +1291,7 @@ "sha256:ffd7dcaf744f25f82190856bc26ed81721508fc5cbf2a330751e135ff1283564" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==11.0.3" }, "yarl": { @@ -1383,92 +1378,92 @@ "develop": { "certifi": { "hashes": [ - "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7", - "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716" + "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082", + "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9" ], "markers": "python_version >= '3.6'", - "version": "==2023.5.7" + "version": "==2023.7.22" }, "charset-normalizer": { "hashes": [ - "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6", - "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1", - "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e", - "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373", - "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62", - "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230", - "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be", - "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c", - "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0", - "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448", - "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f", - "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649", - "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d", - "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0", - "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706", - "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a", - "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59", - "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23", - "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5", - "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb", - "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e", - "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e", - "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c", - "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28", - "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d", - "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41", - "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974", - "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce", - "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f", - "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1", - "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d", - "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8", - "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017", - "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31", - "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7", - "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8", - "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e", - "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14", - "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd", - "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d", - "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795", - "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b", - "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b", - "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b", - "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203", - "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f", - "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19", - "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1", - "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a", - "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac", - "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9", - "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0", - "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137", - "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f", - "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6", - "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5", - "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909", - "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f", - "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0", - "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324", - "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755", - "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb", - "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854", - "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c", - "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60", - "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84", - "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0", - "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b", - "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1", - "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531", - "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1", - "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11", - "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326", - "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df", - "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab" - ], - "markers": "python_version >= '3.7'", - "version": "==3.1.0" + "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96", + "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c", + "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710", + "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706", + "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020", + "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252", + "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad", + "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329", + "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a", + "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f", + "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6", + "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4", + "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a", + "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46", + "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2", + "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23", + "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace", + "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd", + "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982", + "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10", + "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2", + "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea", + "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09", + "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5", + "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149", + "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489", + "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9", + "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80", + "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592", + "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3", + "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6", + "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed", + "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c", + "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200", + "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a", + "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e", + "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d", + "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6", + "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623", + "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669", + "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3", + "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa", + "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9", + "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2", + "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f", + "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1", + "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4", + "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a", + "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8", + "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3", + "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029", + "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f", + "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959", + "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22", + "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7", + "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952", + "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346", + "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e", + "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d", + "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299", + "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd", + "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a", + "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3", + "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037", + "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94", + "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c", + "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858", + "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a", + "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449", + "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c", + "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918", + "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1", + "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c", + "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac", + "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.2.0" }, "idna": { "hashes": [ @@ -1496,27 +1491,37 @@ }, "pluggy": { "hashes": [ - "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159", - "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3" + "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", + "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" ], - "markers": "python_version >= '3.6'", - "version": "==1.0.0" + "markers": "python_version >= '3.8'", + "version": "==1.3.0" }, "pytest": { "hashes": [ - "sha256:cdcbd012c9312258922f8cd3f1b62a6580fdced17db6014896053d47cddf9295", - "sha256:ee990a3cc55ba808b80795a79944756f315c67c12b56abd3ac993a7b8c17030b" + "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32", + "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a" ], "index": "pypi", - "version": "==7.3.2" + "markers": "python_version >= '3.7'", + "version": "==7.4.0" }, "pytest-asyncio": { "hashes": [ - "sha256:2b38a496aef56f56b0e87557ec313e11e1ab9276fc3863f6a7be0f1d0e415e1b", - "sha256:f2b3366b7cd501a4056858bd39349d5af19742aed2d81660b7998b6341c7eb9c" + "sha256:40a7eae6dded22c7b604986855ea48400ab15b069ae38116e8c01238e9eeb64d", + "sha256:8666c1c8ac02631d7c51ba282e0c69a8a452b211ffedf2599099845da5c5c37b" ], "index": "pypi", - "version": "==0.21.0" + "markers": "python_version >= '3.7'", + "version": "==0.21.1" + }, + "pytest-grpc": { + "hashes": [ + "sha256:0bd2683ffd34199444d707c0ab01970b22e0afbba6cb1ddb6d578c85ebfe09bd", + "sha256:5b062cf498e59995e84b3051da76f7bcff8cfe307927869f7bdc27ab967eee35" + ], + "index": "pypi", + "version": "==0.8.0" }, "requests": { "hashes": [ @@ -1524,6 +1529,7 @@ "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==2.31.0" }, "requests-mock": { @@ -1548,6 +1554,7 @@ "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", "version": "==1.26.16" } } diff --git a/README.md b/README.md index 8c2ec6e2..381d3401 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,23 @@ make tests ``` ### Changelogs +**0.8.1** +* Moved the configuration to use a secure or insecure connection inside the Network class. The AsyncClient's `insecure` parameter is no longer used for anything and will be removed in the future. +* Made the new load balanced bare-metal node the default one for mainnet (it is called `lb`). The legacy one (load balanced k8s node) is called `lb_k8s` + +**0.8** +* Refactor Composer to be created with all the markets and tokens. The Composer now uses the real markets and tokens to convert human-readable values to chain format +* The Composer can still be instantiated without markets and tokens. When markets and tokens are not provided the Composer loads the required information from the Denoms used in previous versions +* Change in AsyncClient to be able to create Composer instances for the client network, markets and tokens +* Examples have been adapted to create Composer instances using the AsyncClient +* Added new nodes (bare-metal load balancing nodes) for mainnet and testnet +* Deprecated the kubernetes load balanced nodes for testnet +* Refactored the cookies management logic into a cookie assistant. Added the required logic to support the new cookies format for bare-metal load balanced nodes +* Removed class Client. The only supported now is the async version called AsyncClient. + +**0.7.1.1** +* Fixed Testnet network URLs + **0.7.2.1** * Synchronization of denoms configuration files. diff --git a/examples/SendToInjective.py b/examples/SendToInjective.py index 7a27841b..5d0d1072 100644 --- a/examples/SendToInjective.py +++ b/examples/SendToInjective.py @@ -4,7 +4,7 @@ import asyncio import logging -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.sendtocosmos import Peggo import importlib.resources as pkg_resources diff --git a/examples/chain_client/0_LocalOrderHash.py b/examples/chain_client/0_LocalOrderHash.py index e1c8e290..0e20049b 100644 --- a/examples/chain_client/0_LocalOrderHash.py +++ b/examples/chain_client/0_LocalOrderHash.py @@ -1,20 +1,19 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient +from pyinjective.composer import Composer from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey from pyinjective.orderhash import OrderHashManager async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/13_MsgIncreasePositionMargin.py b/examples/chain_client/13_MsgIncreasePositionMargin.py index ff0c33a6..d5e1d7cd 100644 --- a/examples/chain_client/13_MsgIncreasePositionMargin.py +++ b/examples/chain_client/13_MsgIncreasePositionMargin.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/15_MsgWithdraw.py b/examples/chain_client/15_MsgWithdraw.py index 74fc8bce..fb585719 100644 --- a/examples/chain_client/15_MsgWithdraw.py +++ b/examples/chain_client/15_MsgWithdraw.py @@ -13,22 +13,20 @@ # limitations under the License. import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/16_MsgSubaccountTransfer.py b/examples/chain_client/16_MsgSubaccountTransfer.py index 50f6205b..e3dbde9b 100644 --- a/examples/chain_client/16_MsgSubaccountTransfer.py +++ b/examples/chain_client/16_MsgSubaccountTransfer.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/17_MsgBatchUpdateOrders.py b/examples/chain_client/17_MsgBatchUpdateOrders.py index 59bbb111..853b85ee 100644 --- a/examples/chain_client/17_MsgBatchUpdateOrders.py +++ b/examples/chain_client/17_MsgBatchUpdateOrders.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account @@ -132,7 +130,7 @@ async def main() -> None: print(sim_res) return - sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res, simulation=True) + sim_res_msg = composer.MsgResponses(sim_res, simulation=True) print("---Simulation Response---") print(sim_res_msg) diff --git a/examples/chain_client/18_MsgBid.py b/examples/chain_client/18_MsgBid.py index 35ab0256..001fde7c 100644 --- a/examples/chain_client/18_MsgBid.py +++ b/examples/chain_client/18_MsgBid.py @@ -1,19 +1,17 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/19_MsgGrant.py b/examples/chain_client/19_MsgGrant.py index da9fbbb5..17a8ffee 100644 --- a/examples/chain_client/19_MsgGrant.py +++ b/examples/chain_client/19_MsgGrant.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/1_MsgSend.py b/examples/chain_client/1_MsgSend.py index f3a48769..f4894b4d 100644 --- a/examples/chain_client/1_MsgSend.py +++ b/examples/chain_client/1_MsgSend.py @@ -1,21 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - # set custom cookie location (optional) - defaults to current dir - client = AsyncClient(network, insecure=False, chain_cookie_location="/tmp/.chain_cookie") + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/20_MsgExec.py b/examples/chain_client/20_MsgExec.py index 8aafd5d4..e0f6854e 100644 --- a/examples/chain_client/20_MsgExec.py +++ b/examples/chain_client/20_MsgExec.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey, Address async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account @@ -63,9 +61,9 @@ async def main() -> None: print(sim_res) return - sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res, simulation=True) + sim_res_msg = composer.MsgResponses(sim_res, simulation=True) data=sim_res_msg[0] - unpacked_msg_res = ProtoMsgComposer.UnpackMsgExecResponse( + unpacked_msg_res = composer.UnpackMsgExecResponse( msg_type=msg0.__class__.__name__, data=data ) diff --git a/examples/chain_client/21_MsgRevoke.py b/examples/chain_client/21_MsgRevoke.py index b01d799c..51b23f8b 100644 --- a/examples/chain_client/21_MsgRevoke.py +++ b/examples/chain_client/21_MsgRevoke.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/22_MsgSendToEth.py b/examples/chain_client/22_MsgSendToEth.py index 91ecceb3..aed1442f 100644 --- a/examples/chain_client/22_MsgSendToEth.py +++ b/examples/chain_client/22_MsgSendToEth.py @@ -1,20 +1,18 @@ import asyncio -import logging import requests -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/23_MsgRelayPriceFeedPrice.py b/examples/chain_client/23_MsgRelayPriceFeedPrice.py index 592e993e..d0a96996 100644 --- a/examples/chain_client/23_MsgRelayPriceFeedPrice.py +++ b/examples/chain_client/23_MsgRelayPriceFeedPrice.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/24_MsgRewardsOptOut.py b/examples/chain_client/24_MsgRewardsOptOut.py index eb413004..ef876c35 100644 --- a/examples/chain_client/24_MsgRewardsOptOut.py +++ b/examples/chain_client/24_MsgRewardsOptOut.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/25_MsgDelegate.py b/examples/chain_client/25_MsgDelegate.py index fb78dba8..7df4eb17 100644 --- a/examples/chain_client/25_MsgDelegate.py +++ b/examples/chain_client/25_MsgDelegate.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/26_MsgWithdrawDelegatorReward.py b/examples/chain_client/26_MsgWithdrawDelegatorReward.py index a1b955a7..2ee30e32 100644 --- a/examples/chain_client/26_MsgWithdrawDelegatorReward.py +++ b/examples/chain_client/26_MsgWithdrawDelegatorReward.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/27_Grants.py b/examples/chain_client/27_Grants.py index 7f16ecac..e94ce9b8 100644 --- a/examples/chain_client/27_Grants.py +++ b/examples/chain_client/27_Grants.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) granter = "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku" grantee = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" msg_type_url = "/injective.exchange.v1beta1.MsgCreateDerivativeLimitOrder" diff --git a/examples/chain_client/28_BankBalances.py b/examples/chain_client/28_BankBalances.py index 6a185ccc..5a52939f 100644 --- a/examples/chain_client/28_BankBalances.py +++ b/examples/chain_client/28_BankBalances.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) address = "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r" all_bank_balances = await client.get_bank_balances(address=address) print(all_bank_balances) diff --git a/examples/chain_client/29_BankBalance.py b/examples/chain_client/29_BankBalance.py index aab01086..d5d2d533 100644 --- a/examples/chain_client/29_BankBalance.py +++ b/examples/chain_client/29_BankBalance.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) address = "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r" denom = "inj" bank_balance = await client.get_bank_balance(address=address, denom=denom) diff --git a/examples/chain_client/2_MsgDeposit.py b/examples/chain_client/2_MsgDeposit.py index bcb6f78e..1484b1ed 100644 --- a/examples/chain_client/2_MsgDeposit.py +++ b/examples/chain_client/2_MsgDeposit.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet - network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) + network = Network.testnet(node="sentry") # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/30_ExternalTransfer.py b/examples/chain_client/30_ExternalTransfer.py index 26defc09..a973e4b2 100644 --- a/examples/chain_client/30_ExternalTransfer.py +++ b/examples/chain_client/30_ExternalTransfer.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/31_MsgCreateBinaryOptionsLimitOrder.py b/examples/chain_client/31_MsgCreateBinaryOptionsLimitOrder.py index ab79d52a..25652212 100644 --- a/examples/chain_client/31_MsgCreateBinaryOptionsLimitOrder.py +++ b/examples/chain_client/31_MsgCreateBinaryOptionsLimitOrder.py @@ -1,19 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network, Denom +from pyinjective.constant import Denom +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account @@ -62,7 +61,7 @@ async def main() -> None: print(sim_res) return - sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res, simulation=True) + sim_res_msg = composer.MsgResponses(sim_res, simulation=True) print("---Simulation Response---") print(sim_res_msg) diff --git a/examples/chain_client/32_MsgCreateBinaryOptionsMarketOrder.py b/examples/chain_client/32_MsgCreateBinaryOptionsMarketOrder.py index 31d9cf04..8bd5ae77 100644 --- a/examples/chain_client/32_MsgCreateBinaryOptionsMarketOrder.py +++ b/examples/chain_client/32_MsgCreateBinaryOptionsMarketOrder.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account @@ -57,7 +55,7 @@ async def main() -> None: print(sim_res) return - sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res, simulation=True) + sim_res_msg = composer.MsgResponses(sim_res, simulation=True) print("---Simulation Response---") print(sim_res_msg) diff --git a/examples/chain_client/33_MsgCancelBinaryOptionsOrder.py b/examples/chain_client/33_MsgCancelBinaryOptionsOrder.py index ca51d084..f3e534b7 100644 --- a/examples/chain_client/33_MsgCancelBinaryOptionsOrder.py +++ b/examples/chain_client/33_MsgCancelBinaryOptionsOrder.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account @@ -53,7 +51,7 @@ async def main() -> None: print(sim_res) return - sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res, simulation=True) + sim_res_msg = composer.MsgResponses(sim_res, simulation=True) print("---Simulation Response---") print(sim_res_msg) diff --git a/examples/chain_client/34_MsgAdminUpdateBinaryOptionsMarket.py b/examples/chain_client/34_MsgAdminUpdateBinaryOptionsMarket.py index 2f665919..073529ae 100644 --- a/examples/chain_client/34_MsgAdminUpdateBinaryOptionsMarket.py +++ b/examples/chain_client/34_MsgAdminUpdateBinaryOptionsMarket.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account @@ -58,7 +56,7 @@ async def main() -> None: print(sim_res) return - sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res, simulation=True) + sim_res_msg = composer.MsgResponses(sim_res, simulation=True) print("---Simulation Response---") print(sim_res_msg) diff --git a/examples/chain_client/35_MsgInstantBinaryOptionsMarketLaunch.py b/examples/chain_client/35_MsgInstantBinaryOptionsMarketLaunch.py index 3b12ab87..35c30c39 100644 --- a/examples/chain_client/35_MsgInstantBinaryOptionsMarketLaunch.py +++ b/examples/chain_client/35_MsgInstantBinaryOptionsMarketLaunch.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account @@ -60,7 +58,7 @@ async def main() -> None: print(sim_res) return - sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res, simulation=True) + sim_res_msg = composer.MsgResponses(sim_res, simulation=True) print("---Simulation Response---") print(sim_res_msg) diff --git a/examples/chain_client/36_MsgRelayProviderPrices.py b/examples/chain_client/36_MsgRelayProviderPrices.py index a579fb6a..23c9ac94 100644 --- a/examples/chain_client/36_MsgRelayProviderPrices.py +++ b/examples/chain_client/36_MsgRelayProviderPrices.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account @@ -53,7 +51,7 @@ async def main() -> None: print(sim_res) return - sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res, simulation=True) + sim_res_msg = composer.MsgResponses(sim_res, simulation=True) print("---Simulation Response---") print(sim_res_msg) diff --git a/examples/chain_client/37_GetTx.py b/examples/chain_client/37_GetTx.py index 2e2487bc..77d13eb9 100644 --- a/examples/chain_client/37_GetTx.py +++ b/examples/chain_client/37_GetTx.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) tx_hash = "7746BC12EB82B4D59D036FBFF2F67BDCA6F62A20B3DBC25661707DD61D4DC1B7" tx_logs = await client.get_tx(tx_hash=tx_hash) print(tx_logs) diff --git a/examples/chain_client/38_StreamEventOrderFail.py b/examples/chain_client/38_StreamEventOrderFail.py index 1b3f760f..e453fd12 100644 --- a/examples/chain_client/38_StreamEventOrderFail.py +++ b/examples/chain_client/38_StreamEventOrderFail.py @@ -4,7 +4,8 @@ import websockets import base64 -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.mainnet() diff --git a/examples/chain_client/39_Account.py b/examples/chain_client/39_Account.py index 50d30c76..4089a5dd 100644 --- a/examples/chain_client/39_Account.py +++ b/examples/chain_client/39_Account.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) address = "inj1knhahceyp57j5x7xh69p7utegnnnfgxavmahjr" acc = await client.get_account(address=address) print(acc) diff --git a/examples/chain_client/3_MsgCreateSpotLimitOrder.py b/examples/chain_client/3_MsgCreateSpotLimitOrder.py index 04cb0ffa..34466874 100644 --- a/examples/chain_client/3_MsgCreateSpotLimitOrder.py +++ b/examples/chain_client/3_MsgCreateSpotLimitOrder.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account @@ -58,7 +56,7 @@ async def main() -> None: print(sim_res) return - sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res, simulation=True) + sim_res_msg = composer.MsgResponses(sim_res, simulation=True) print("---Simulation Response---") print(sim_res_msg) diff --git a/examples/chain_client/40_MsgExecuteContract.py b/examples/chain_client/40_MsgExecuteContract.py index 4661f4b4..cde8c480 100644 --- a/examples/chain_client/40_MsgExecuteContract.py +++ b/examples/chain_client/40_MsgExecuteContract.py @@ -1,21 +1,19 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client # set custom cookie location (optional) - defaults to current dir - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/41_MsgCreateInsuranceFund.py b/examples/chain_client/41_MsgCreateInsuranceFund.py index 255419b0..89007e23 100644 --- a/examples/chain_client/41_MsgCreateInsuranceFund.py +++ b/examples/chain_client/41_MsgCreateInsuranceFund.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client # set custom cookie location (optional) - defaults to current dir - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/42_MsgUnderwrite.py b/examples/chain_client/42_MsgUnderwrite.py index 49aa7313..7c143e51 100644 --- a/examples/chain_client/42_MsgUnderwrite.py +++ b/examples/chain_client/42_MsgUnderwrite.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client # set custom cookie location (optional) - defaults to current dir - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/43_MsgRequestRedemption.py b/examples/chain_client/43_MsgRequestRedemption.py index a37a774d..a32add66 100644 --- a/examples/chain_client/43_MsgRequestRedemption.py +++ b/examples/chain_client/43_MsgRequestRedemption.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client # set custom cookie location (optional) - defaults to current dir - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/44_MessageBroadcaster.py b/examples/chain_client/44_MessageBroadcaster.py index b144c0cc..4fbeb719 100644 --- a/examples/chain_client/44_MessageBroadcaster.py +++ b/examples/chain_client/44_MessageBroadcaster.py @@ -2,7 +2,7 @@ from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.core.broadcaster import MsgBroadcasterWithPk -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey @@ -15,7 +15,6 @@ async def main() -> None: message_broadcaster = MsgBroadcasterWithPk.new_using_simulation( network=network, private_key=private_key_in_hexa, - use_secure_connection=True ) priv_key = PrivateKey.from_hex(private_key_in_hexa) diff --git a/examples/chain_client/45_MessageBroadcasterWithGranteeAccount.py b/examples/chain_client/45_MessageBroadcasterWithGranteeAccount.py index f0b4c7e8..dc017f3f 100644 --- a/examples/chain_client/45_MessageBroadcasterWithGranteeAccount.py +++ b/examples/chain_client/45_MessageBroadcasterWithGranteeAccount.py @@ -3,7 +3,7 @@ from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.core.broadcaster import MsgBroadcasterWithPk -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey, Address @@ -13,7 +13,7 @@ async def main() -> None: composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) await client.sync_timeout_height() # load account @@ -25,7 +25,6 @@ async def main() -> None: message_broadcaster = MsgBroadcasterWithPk.new_for_grantee_account_using_simulation( network=network, grantee_private_key=private_key_in_hexa, - use_secure_connection=True ) # prepare tx msg diff --git a/examples/chain_client/46_MessageBroadcasterWithoutSimulation.py b/examples/chain_client/46_MessageBroadcasterWithoutSimulation.py index 847c79a9..dc804b24 100644 --- a/examples/chain_client/46_MessageBroadcasterWithoutSimulation.py +++ b/examples/chain_client/46_MessageBroadcasterWithoutSimulation.py @@ -2,7 +2,7 @@ from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.core.broadcaster import MsgBroadcasterWithPk -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey @@ -15,7 +15,6 @@ async def main() -> None: message_broadcaster = MsgBroadcasterWithPk.new_without_simulation( network=network, private_key=private_key_in_hexa, - use_secure_connection=True ) priv_key = PrivateKey.from_hex(private_key_in_hexa) diff --git a/examples/chain_client/47_MessageBroadcasterWithGranteeAccountWithoutSimulation.py b/examples/chain_client/47_MessageBroadcasterWithGranteeAccountWithoutSimulation.py index b3311279..4221d795 100644 --- a/examples/chain_client/47_MessageBroadcasterWithGranteeAccountWithoutSimulation.py +++ b/examples/chain_client/47_MessageBroadcasterWithGranteeAccountWithoutSimulation.py @@ -3,7 +3,7 @@ from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.core.broadcaster import MsgBroadcasterWithPk -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey, Address @@ -13,7 +13,7 @@ async def main() -> None: composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) await client.sync_timeout_height() # load account @@ -25,7 +25,6 @@ async def main() -> None: message_broadcaster = MsgBroadcasterWithPk.new_for_grantee_account_without_simulation( network=network, grantee_private_key=private_key_in_hexa, - use_secure_connection=True ) # prepare tx msg diff --git a/examples/chain_client/48_WithdrawValidatorCommission_Rewards b/examples/chain_client/48_WithdrawValidatorCommission_Rewards new file mode 100644 index 00000000..7d360790 --- /dev/null +++ b/examples/chain_client/48_WithdrawValidatorCommission_Rewards @@ -0,0 +1,79 @@ + +import asyncio +import logging + +from pyinjective.composer import Composer as ProtoMsgComposer +from pyinjective.async_client import AsyncClient +from pyinjective.transaction import Transaction +from pyinjective.constant import Network +from pyinjective.wallet import PrivateKey + + +async def main() -> None: + """For a validator to withdraw his rewards & commissions simultaneously""" + # select network: local, testnet, mainnet + network = Network.testnet() + composer = ProtoMsgComposer(network=network.string()) + + # initialize grpc client + client = AsyncClient(network, insecure=False) + await client.sync_timeout_height() + + # load account + # private key is that from the validator's wallet + priv_key = PrivateKey.from_hex("f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3") + pub_key = priv_key.to_public_key() + address = pub_key.to_address() + account = await client.get_account(address.to_acc_bech32()) + + # prepare tx msg + validator_address = "injvaloper1ultw9r29l8nxy5u6thcgusjn95vsy2caw722q5" + + msg0 = composer.MsgWithdrawDelegatorReward( + delegator_address=address.to_acc_bech32(), + validator_address=validator_address + ) + + msg1 = composer.MsgWithdrawValidatorCommission( + validator_address=validator_address + ) + + # build sim tx + tx = ( + Transaction() + .with_messages(msg0, msg1) + .with_sequence(client.get_sequence()) + .with_account_num(client.get_number()) + .with_chain_id(network.chain_id) + ) + sim_sign_doc = tx.get_sign_doc(pub_key) + sim_sig = priv_key.sign(sim_sign_doc.SerializeToString()) + sim_tx_raw_bytes = tx.get_tx_data(sim_sig, pub_key) + + # simulate tx + (sim_res, success) = await client.simulate_tx(sim_tx_raw_bytes) + if not success: + print(sim_res) + return + + # build tx + gas_price = 500000000 + gas_limit = sim_res.gas_info.gas_used + 20000 # add 20k for gas, fee computation + gas_fee = '{:.18f}'.format((gas_price * gas_limit) / pow(10, 18)).rstrip('0') + fee = [composer.Coin( + amount=gas_price * gas_limit, + denom=network.fee_denom, + )] + tx = tx.with_gas(gas_limit).with_fee(fee).with_memo('').with_timeout_height(client.timeout_height) + sign_doc = tx.get_sign_doc(pub_key) + sig = priv_key.sign(sign_doc.SerializeToString()) + tx_raw_bytes = tx.get_tx_data(sig, pub_key) + + # broadcast tx: send_tx_async_mode, send_tx_sync_mode, send_tx_block_mode + res = await client.send_tx_sync_mode(tx_raw_bytes) + print(res) + print("gas wanted: {}".format(gas_limit)) + print("gas fee: {} INJ".format(gas_fee)) + +if __name__ == "__main__": + asyncio.get_event_loop().run_until_complete(main()) diff --git a/examples/chain_client/4_MsgCreateSpotMarketOrder.py b/examples/chain_client/4_MsgCreateSpotMarketOrder.py index d851517c..3185cafa 100644 --- a/examples/chain_client/4_MsgCreateSpotMarketOrder.py +++ b/examples/chain_client/4_MsgCreateSpotMarketOrder.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account @@ -57,7 +55,7 @@ async def main() -> None: print(sim_res) return - sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res, simulation=True) + sim_res_msg = composer.MsgResponses(sim_res, simulation=True) print("---Simulation Response---") print(sim_res_msg) diff --git a/examples/chain_client/5_MsgCancelSpotOrder.py b/examples/chain_client/5_MsgCancelSpotOrder.py index a347a54b..93030ecd 100644 --- a/examples/chain_client/5_MsgCancelSpotOrder.py +++ b/examples/chain_client/5_MsgCancelSpotOrder.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/chain_client/6_MsgCreateDerivativeLimitOrder.py b/examples/chain_client/6_MsgCreateDerivativeLimitOrder.py index d7847289..add38833 100644 --- a/examples/chain_client/6_MsgCreateDerivativeLimitOrder.py +++ b/examples/chain_client/6_MsgCreateDerivativeLimitOrder.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account @@ -59,7 +57,7 @@ async def main() -> None: print(sim_res) return - sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res, simulation=True) + sim_res_msg = composer.MsgResponses(sim_res, simulation=True) print("---Simulation Response---") print(sim_res_msg) diff --git a/examples/chain_client/7_MsgCreateDerivativeMarketOrder.py b/examples/chain_client/7_MsgCreateDerivativeMarketOrder.py index ffdade8d..f1e71b1c 100644 --- a/examples/chain_client/7_MsgCreateDerivativeMarketOrder.py +++ b/examples/chain_client/7_MsgCreateDerivativeMarketOrder.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account @@ -58,7 +56,7 @@ async def main() -> None: print(sim_res) return - sim_res_msg = ProtoMsgComposer.MsgResponses(sim_res, simulation=True) + sim_res_msg = composer.MsgResponses(sim_res, simulation=True) print("---Simulation Response---") print(sim_res_msg) diff --git a/examples/chain_client/8_MsgCancelDerivativeOrder.py b/examples/chain_client/8_MsgCancelDerivativeOrder.py index 6934d283..1ea9001c 100644 --- a/examples/chain_client/8_MsgCancelDerivativeOrder.py +++ b/examples/chain_client/8_MsgCancelDerivativeOrder.py @@ -1,20 +1,18 @@ import asyncio -import logging -from pyinjective.composer import Composer as ProtoMsgComposer from pyinjective.async_client import AsyncClient from pyinjective.transaction import Transaction -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.wallet import PrivateKey async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - composer = ProtoMsgComposer(network=network.string()) # initialize grpc client - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) + composer = await client.composer() await client.sync_timeout_height() # load account diff --git a/examples/exchange_client/accounts_rpc/1_StreamSubaccountBalance.py b/examples/exchange_client/accounts_rpc/1_StreamSubaccountBalance.py index 53d85f90..25c6163c 100644 --- a/examples/exchange_client/accounts_rpc/1_StreamSubaccountBalance.py +++ b/examples/exchange_client/accounts_rpc/1_StreamSubaccountBalance.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) subaccount_id = "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000001" denoms = ["inj", "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"] subaccount = await client.stream_subaccount_balance( diff --git a/examples/exchange_client/accounts_rpc/2_SubaccountBalance.py b/examples/exchange_client/accounts_rpc/2_SubaccountBalance.py index 61ef0396..13a5bfba 100644 --- a/examples/exchange_client/accounts_rpc/2_SubaccountBalance.py +++ b/examples/exchange_client/accounts_rpc/2_SubaccountBalance.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000" denom = "inj" balance = await client.get_subaccount_balance( diff --git a/examples/exchange_client/accounts_rpc/3_SubaccountsList.py b/examples/exchange_client/accounts_rpc/3_SubaccountsList.py index d037106c..390200e1 100644 --- a/examples/exchange_client/accounts_rpc/3_SubaccountsList.py +++ b/examples/exchange_client/accounts_rpc/3_SubaccountsList.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) account_address = "inj1clw20s2uxeyxtam6f7m84vgae92s9eh7vygagt" subacc_list = await client.get_subaccount_list(account_address) print(subacc_list) diff --git a/examples/exchange_client/accounts_rpc/4_SubaccountBalancesList.py b/examples/exchange_client/accounts_rpc/4_SubaccountBalancesList.py index c5c8b9de..1bb746b5 100644 --- a/examples/exchange_client/accounts_rpc/4_SubaccountBalancesList.py +++ b/examples/exchange_client/accounts_rpc/4_SubaccountBalancesList.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) subaccount = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000" denoms = ["inj", "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5"] subacc_balances_list = await client.get_subaccount_balances_list( diff --git a/examples/exchange_client/accounts_rpc/5_SubaccountHistory.py b/examples/exchange_client/accounts_rpc/5_SubaccountHistory.py index 66d9875b..fa871b7f 100644 --- a/examples/exchange_client/accounts_rpc/5_SubaccountHistory.py +++ b/examples/exchange_client/accounts_rpc/5_SubaccountHistory.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) subaccount = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000" denom = "inj" transfer_types = ["withdraw", "deposit"] diff --git a/examples/exchange_client/accounts_rpc/6_SubaccountOrderSummary.py b/examples/exchange_client/accounts_rpc/6_SubaccountOrderSummary.py index f0bf85fd..606e75a3 100644 --- a/examples/exchange_client/accounts_rpc/6_SubaccountOrderSummary.py +++ b/examples/exchange_client/accounts_rpc/6_SubaccountOrderSummary.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) subaccount = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000" order_direction = "buy" market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" diff --git a/examples/exchange_client/accounts_rpc/7_OrderStates.py b/examples/exchange_client/accounts_rpc/7_OrderStates.py index c0851ed6..1c4117e8 100644 --- a/examples/exchange_client/accounts_rpc/7_OrderStates.py +++ b/examples/exchange_client/accounts_rpc/7_OrderStates.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) spot_order_hashes = ["0xce0d9b701f77cd6ddfda5dd3a4fe7b2d53ba83e5d6c054fb2e9e886200b7b7bb", "0x2e2245b5431638d76c6e0cc6268970418a1b1b7df60a8e94b8cf37eae6105542"] derivative_order_hashes = ["0x82113f3998999bdc3892feaab2c4e53ba06c5fe887a2d5f9763397240f24da50", "0xbb1f036001378cecb5fff1cc69303919985b5bf058c32f37d5aaf9b804c07a06"] orders = await client.get_order_states(spot_order_hashes=spot_order_hashes, derivative_order_hashes=derivative_order_hashes) diff --git a/examples/exchange_client/accounts_rpc/8_Portfolio.py b/examples/exchange_client/accounts_rpc/8_Portfolio.py index 9fea55a5..04e709bc 100644 --- a/examples/exchange_client/accounts_rpc/8_Portfolio.py +++ b/examples/exchange_client/accounts_rpc/8_Portfolio.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) account_address = "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku" portfolio = await client.get_portfolio(account_address=account_address) print(portfolio) diff --git a/examples/exchange_client/accounts_rpc/9_Rewards.py b/examples/exchange_client/accounts_rpc/9_Rewards.py index f99d804f..687f3a1a 100644 --- a/examples/exchange_client/accounts_rpc/9_Rewards.py +++ b/examples/exchange_client/accounts_rpc/9_Rewards.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) # account_address = "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku" epoch = -1 rewards = await client.get_rewards( diff --git a/examples/exchange_client/auctions_rpc/1_Auction.py b/examples/exchange_client/auctions_rpc/1_Auction.py index 79fd2dc8..02307e00 100644 --- a/examples/exchange_client/auctions_rpc/1_Auction.py +++ b/examples/exchange_client/auctions_rpc/1_Auction.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) bid_round = 31 auction = await client.get_auction(bid_round=bid_round) print(auction) diff --git a/examples/exchange_client/auctions_rpc/2_Auctions.py b/examples/exchange_client/auctions_rpc/2_Auctions.py index fca61338..5f161f5d 100644 --- a/examples/exchange_client/auctions_rpc/2_Auctions.py +++ b/examples/exchange_client/auctions_rpc/2_Auctions.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) auctions = await client.get_auctions() print(auctions) diff --git a/examples/exchange_client/auctions_rpc/3_StreamBids.py b/examples/exchange_client/auctions_rpc/3_StreamBids.py index 60b6927f..3119670d 100644 --- a/examples/exchange_client/auctions_rpc/3_StreamBids.py +++ b/examples/exchange_client/auctions_rpc/3_StreamBids.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) bids = await client.stream_bids() async for bid in bids: print(bid) diff --git a/examples/exchange_client/derivative_exchange_rpc/10_StreamHistoricalOrders.py b/examples/exchange_client/derivative_exchange_rpc/10_StreamHistoricalOrders.py index 33ef76e4..429862d1 100644 --- a/examples/exchange_client/derivative_exchange_rpc/10_StreamHistoricalOrders.py +++ b/examples/exchange_client/derivative_exchange_rpc/10_StreamHistoricalOrders.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" order_side = "sell" subaccount_id = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000" diff --git a/examples/exchange_client/derivative_exchange_rpc/11_Trades.py b/examples/exchange_client/derivative_exchange_rpc/11_Trades.py index 056d2155..f822babb 100644 --- a/examples/exchange_client/derivative_exchange_rpc/11_Trades.py +++ b/examples/exchange_client/derivative_exchange_rpc/11_Trades.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" subaccount_id = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000" trades = await client.get_derivative_trades( diff --git a/examples/exchange_client/derivative_exchange_rpc/12_StreamTrades.py b/examples/exchange_client/derivative_exchange_rpc/12_StreamTrades.py index 31dabd25..03136700 100644 --- a/examples/exchange_client/derivative_exchange_rpc/12_StreamTrades.py +++ b/examples/exchange_client/derivative_exchange_rpc/12_StreamTrades.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_ids = [ "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6", "0xd5e4b12b19ecf176e4e14b42944731c27677819d2ed93be4104ad7025529c7ff" diff --git a/examples/exchange_client/derivative_exchange_rpc/13_SubaccountOrdersList.py b/examples/exchange_client/derivative_exchange_rpc/13_SubaccountOrdersList.py index 587e3b0e..62609850 100644 --- a/examples/exchange_client/derivative_exchange_rpc/13_SubaccountOrdersList.py +++ b/examples/exchange_client/derivative_exchange_rpc/13_SubaccountOrdersList.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000" market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" skip = 1 diff --git a/examples/exchange_client/derivative_exchange_rpc/14_SubaccountTradesList.py b/examples/exchange_client/derivative_exchange_rpc/14_SubaccountTradesList.py index 0d835437..d6b0bf81 100644 --- a/examples/exchange_client/derivative_exchange_rpc/14_SubaccountTradesList.py +++ b/examples/exchange_client/derivative_exchange_rpc/14_SubaccountTradesList.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000" market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" execution_type = "market" diff --git a/examples/exchange_client/derivative_exchange_rpc/15_FundingPayments.py b/examples/exchange_client/derivative_exchange_rpc/15_FundingPayments.py index ebde0a71..4ff983c5 100644 --- a/examples/exchange_client/derivative_exchange_rpc/15_FundingPayments.py +++ b/examples/exchange_client/derivative_exchange_rpc/15_FundingPayments.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" subaccount_id = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000" skip=0 diff --git a/examples/exchange_client/derivative_exchange_rpc/17_FundingRates.py b/examples/exchange_client/derivative_exchange_rpc/17_FundingRates.py index 089b89b6..47a14794 100644 --- a/examples/exchange_client/derivative_exchange_rpc/17_FundingRates.py +++ b/examples/exchange_client/derivative_exchange_rpc/17_FundingRates.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" skip=0 limit=3 diff --git a/examples/exchange_client/derivative_exchange_rpc/18_Orderbooks.py b/examples/exchange_client/derivative_exchange_rpc/18_Orderbooks.py index 3996c9f2..d3583aff 100644 --- a/examples/exchange_client/derivative_exchange_rpc/18_Orderbooks.py +++ b/examples/exchange_client/derivative_exchange_rpc/18_Orderbooks.py @@ -2,13 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_ids = [ "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6", "0xd5e4b12b19ecf176e4e14b42944731c27677819d2ed93be4104ad7025529c7ff" diff --git a/examples/exchange_client/derivative_exchange_rpc/19_Binary_Options_Markets.py b/examples/exchange_client/derivative_exchange_rpc/19_Binary_Options_Markets.py index f7e9b111..233dce5f 100644 --- a/examples/exchange_client/derivative_exchange_rpc/19_Binary_Options_Markets.py +++ b/examples/exchange_client/derivative_exchange_rpc/19_Binary_Options_Markets.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_status = "active" quote_denom = "peggy0xdAC17F958D2ee523a2206206994597C13D831ec7" market = await client.get_binary_options_markets( diff --git a/examples/exchange_client/derivative_exchange_rpc/1_Market.py b/examples/exchange_client/derivative_exchange_rpc/1_Market.py index 7666efe3..520f55c8 100644 --- a/examples/exchange_client/derivative_exchange_rpc/1_Market.py +++ b/examples/exchange_client/derivative_exchange_rpc/1_Market.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" market = await client.get_derivative_market(market_id=market_id) print(market) diff --git a/examples/exchange_client/derivative_exchange_rpc/20_Binary_Options_Market.py b/examples/exchange_client/derivative_exchange_rpc/20_Binary_Options_Market.py index 59949fee..7cbf0924 100644 --- a/examples/exchange_client/derivative_exchange_rpc/20_Binary_Options_Market.py +++ b/examples/exchange_client/derivative_exchange_rpc/20_Binary_Options_Market.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_id = "0x175513943b8677368d138e57bcd6bef53170a0da192e7eaa8c2cd4509b54f8db" market = await client.get_binary_options_market(market_id=market_id) print(market) diff --git a/examples/exchange_client/derivative_exchange_rpc/21_Historical_Orders.py b/examples/exchange_client/derivative_exchange_rpc/21_Historical_Orders.py index 367ee214..ea864397 100644 --- a/examples/exchange_client/derivative_exchange_rpc/21_Historical_Orders.py +++ b/examples/exchange_client/derivative_exchange_rpc/21_Historical_Orders.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" subaccount_id = "0x295639d56c987f0e24d21bb167872b3542a6e05a000000000000000000000000" is_conditional = "false" diff --git a/examples/exchange_client/derivative_exchange_rpc/22_OrderbooksV2.py b/examples/exchange_client/derivative_exchange_rpc/22_OrderbooksV2.py index 35fe128f..2a21d145 100644 --- a/examples/exchange_client/derivative_exchange_rpc/22_OrderbooksV2.py +++ b/examples/exchange_client/derivative_exchange_rpc/22_OrderbooksV2.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_ids = [ "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6", "0xd5e4b12b19ecf176e4e14b42944731c27677819d2ed93be4104ad7025529c7ff" diff --git a/examples/exchange_client/derivative_exchange_rpc/2_Markets.py b/examples/exchange_client/derivative_exchange_rpc/2_Markets.py index 89242d02..275d372f 100644 --- a/examples/exchange_client/derivative_exchange_rpc/2_Markets.py +++ b/examples/exchange_client/derivative_exchange_rpc/2_Markets.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_status = "active" quote_denom = "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5" market = await client.get_derivative_markets( diff --git a/examples/exchange_client/derivative_exchange_rpc/3_StreamMarket.py b/examples/exchange_client/derivative_exchange_rpc/3_StreamMarket.py index f4f09d9a..d3b15a71 100644 --- a/examples/exchange_client/derivative_exchange_rpc/3_StreamMarket.py +++ b/examples/exchange_client/derivative_exchange_rpc/3_StreamMarket.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) markets = await client.stream_derivative_markets() async for market in markets: print(market) diff --git a/examples/exchange_client/derivative_exchange_rpc/4_Orderbook.py b/examples/exchange_client/derivative_exchange_rpc/4_Orderbook.py index 61575bc8..9020a949 100644 --- a/examples/exchange_client/derivative_exchange_rpc/4_Orderbook.py +++ b/examples/exchange_client/derivative_exchange_rpc/4_Orderbook.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" market = await client.get_derivative_orderbook(market_id=market_id) print(market) diff --git a/examples/exchange_client/derivative_exchange_rpc/5_StreamOrderbooks.py b/examples/exchange_client/derivative_exchange_rpc/5_StreamOrderbooks.py index b50535ee..8a5a88f6 100644 --- a/examples/exchange_client/derivative_exchange_rpc/5_StreamOrderbooks.py +++ b/examples/exchange_client/derivative_exchange_rpc/5_StreamOrderbooks.py @@ -2,13 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" markets = await client.stream_derivative_orderbook_snapshot(market_ids=[market_id]) async for market in markets: diff --git a/examples/exchange_client/derivative_exchange_rpc/6_StreamOrderbookUpdate.py b/examples/exchange_client/derivative_exchange_rpc/6_StreamOrderbookUpdate.py index b1ac8804..4dd446db 100644 --- a/examples/exchange_client/derivative_exchange_rpc/6_StreamOrderbookUpdate.py +++ b/examples/exchange_client/derivative_exchange_rpc/6_StreamOrderbookUpdate.py @@ -3,7 +3,7 @@ from decimal import * from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network class PriceLevel: @@ -50,7 +50,7 @@ async def load_orderbook_snapshot(async_client: AsyncClient, orderbook: Orderboo async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - async_client = AsyncClient(network, insecure=False) + async_client = AsyncClient(network) market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" orderbook = Orderbook(market_id=market_id) diff --git a/examples/exchange_client/derivative_exchange_rpc/7_Positions.py b/examples/exchange_client/derivative_exchange_rpc/7_Positions.py index f91ec4e8..50500c14 100644 --- a/examples/exchange_client/derivative_exchange_rpc/7_Positions.py +++ b/examples/exchange_client/derivative_exchange_rpc/7_Positions.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_ids = [ "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6", "0xd97d0da6f6c11710ef06315971250e4e9aed4b7d4cd02059c9477ec8cf243782" diff --git a/examples/exchange_client/derivative_exchange_rpc/9_StreamPositions.py b/examples/exchange_client/derivative_exchange_rpc/9_StreamPositions.py index c1bad053..425363ff 100644 --- a/examples/exchange_client/derivative_exchange_rpc/9_StreamPositions.py +++ b/examples/exchange_client/derivative_exchange_rpc/9_StreamPositions.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" subaccount_id = "0xea98e3aa091a6676194df40ac089e40ab4604bf9000000000000000000000000" positions = await client.stream_derivative_positions( diff --git a/examples/exchange_client/explorer_rpc/10_GetIBCTransfers.py b/examples/exchange_client/explorer_rpc/10_GetIBCTransfers.py index 38602907..68daf8d9 100644 --- a/examples/exchange_client/explorer_rpc/10_GetIBCTransfers.py +++ b/examples/exchange_client/explorer_rpc/10_GetIBCTransfers.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) sender = "inj1cll5cv3ezgal30gagkhnq2um6zf6qrmhw4r6c8" receiver = "cosmos1usr9g5a4s2qrwl63sdjtrs2qd4a7huh622pg82" src_channel = "channel-2" diff --git a/examples/exchange_client/explorer_rpc/1_GetTxByHash.py b/examples/exchange_client/explorer_rpc/1_GetTxByHash.py index 7362d1e0..7fd480f8 100644 --- a/examples/exchange_client/explorer_rpc/1_GetTxByHash.py +++ b/examples/exchange_client/explorer_rpc/1_GetTxByHash.py @@ -3,12 +3,13 @@ from pyinjective.async_client import AsyncClient from pyinjective.composer import Composer -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) composer = Composer(network=network.string()) tx_hash = "0F3EBEC1882E1EEAC5B7BDD836E976250F1CD072B79485877CEACCB92ACDDF52" transaction_response = await client.get_tx_by_hash(tx_hash=tx_hash) diff --git a/examples/exchange_client/explorer_rpc/2_AccountTxs.py b/examples/exchange_client/explorer_rpc/2_AccountTxs.py index 7e5c7a3f..2fc3958b 100644 --- a/examples/exchange_client/explorer_rpc/2_AccountTxs.py +++ b/examples/exchange_client/explorer_rpc/2_AccountTxs.py @@ -3,12 +3,13 @@ from pyinjective.async_client import AsyncClient from pyinjective.composer import Composer -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) composer = Composer(network=network.string()) address = "inj1phd706jqzd9wznkk5hgsfkrc8jqxv0kmlj0kex" message_type = "cosmos.bank.v1beta1.MsgSend" diff --git a/examples/exchange_client/explorer_rpc/3_Blocks.py b/examples/exchange_client/explorer_rpc/3_Blocks.py index 0b636ffd..23d30dba 100644 --- a/examples/exchange_client/explorer_rpc/3_Blocks.py +++ b/examples/exchange_client/explorer_rpc/3_Blocks.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) limit = 2 block = await client.get_blocks(limit=limit) print(block) diff --git a/examples/exchange_client/explorer_rpc/4_Block.py b/examples/exchange_client/explorer_rpc/4_Block.py index 91aac693..92b17b12 100644 --- a/examples/exchange_client/explorer_rpc/4_Block.py +++ b/examples/exchange_client/explorer_rpc/4_Block.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) block_height = "5825046" block = await client.get_block(block_height=block_height) print(block) diff --git a/examples/exchange_client/explorer_rpc/5_TxsRequest.py b/examples/exchange_client/explorer_rpc/5_TxsRequest.py index d8c53771..434b0779 100644 --- a/examples/exchange_client/explorer_rpc/5_TxsRequest.py +++ b/examples/exchange_client/explorer_rpc/5_TxsRequest.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) limit = 2 txs = await client.get_txs(limit=limit) print(txs) diff --git a/examples/exchange_client/explorer_rpc/6_StreamTxs.py b/examples/exchange_client/explorer_rpc/6_StreamTxs.py index d146ea81..6c173091 100644 --- a/examples/exchange_client/explorer_rpc/6_StreamTxs.py +++ b/examples/exchange_client/explorer_rpc/6_StreamTxs.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) stream_txs = await client.stream_txs( ) async for tx in stream_txs: diff --git a/examples/exchange_client/explorer_rpc/7_StreamBlocks.py b/examples/exchange_client/explorer_rpc/7_StreamBlocks.py index da755cdb..96b83935 100644 --- a/examples/exchange_client/explorer_rpc/7_StreamBlocks.py +++ b/examples/exchange_client/explorer_rpc/7_StreamBlocks.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) stream_blocks = await client.stream_blocks( ) async for block in stream_blocks: diff --git a/examples/exchange_client/explorer_rpc/8_GetPeggyDeposits.py b/examples/exchange_client/explorer_rpc/8_GetPeggyDeposits.py index b2ecb90a..97a8ab10 100644 --- a/examples/exchange_client/explorer_rpc/8_GetPeggyDeposits.py +++ b/examples/exchange_client/explorer_rpc/8_GetPeggyDeposits.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) receiver = "inj1phd706jqzd9wznkk5hgsfkrc8jqxv0kmlj0kex" peggy_deposits = await client.get_peggy_deposits(receiver=receiver) print(peggy_deposits) diff --git a/examples/exchange_client/explorer_rpc/9_GetPeggyWithdrawals.py b/examples/exchange_client/explorer_rpc/9_GetPeggyWithdrawals.py index fc12d7a6..12264475 100644 --- a/examples/exchange_client/explorer_rpc/9_GetPeggyWithdrawals.py +++ b/examples/exchange_client/explorer_rpc/9_GetPeggyWithdrawals.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) sender = "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku" limit = 2 peggy_deposits = await client.get_peggy_withdrawals( diff --git a/examples/exchange_client/insurance_rpc/1_InsuranceFunds.py b/examples/exchange_client/insurance_rpc/1_InsuranceFunds.py index 7dd3a207..487e64df 100644 --- a/examples/exchange_client/insurance_rpc/1_InsuranceFunds.py +++ b/examples/exchange_client/insurance_rpc/1_InsuranceFunds.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) insurance_funds = await client.get_insurance_funds() print(insurance_funds) diff --git a/examples/exchange_client/insurance_rpc/2_Redemptions.py b/examples/exchange_client/insurance_rpc/2_Redemptions.py index de0582e7..8db3238b 100644 --- a/examples/exchange_client/insurance_rpc/2_Redemptions.py +++ b/examples/exchange_client/insurance_rpc/2_Redemptions.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) redeemer = "inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku" redemption_denom = "share4" status = "disbursed" diff --git a/examples/exchange_client/meta_rpc/1_Ping.py b/examples/exchange_client/meta_rpc/1_Ping.py index 0745dcbc..dc505a7a 100644 --- a/examples/exchange_client/meta_rpc/1_Ping.py +++ b/examples/exchange_client/meta_rpc/1_Ping.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) resp = await client.ping() print('Health OK?', resp) diff --git a/examples/exchange_client/meta_rpc/2_Version.py b/examples/exchange_client/meta_rpc/2_Version.py index 3ed2581d..48cb0b4c 100644 --- a/examples/exchange_client/meta_rpc/2_Version.py +++ b/examples/exchange_client/meta_rpc/2_Version.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) resp = await client.version() print('Version:', resp) diff --git a/examples/exchange_client/meta_rpc/3_Info.py b/examples/exchange_client/meta_rpc/3_Info.py index c6b5ba32..9c3c2693 100644 --- a/examples/exchange_client/meta_rpc/3_Info.py +++ b/examples/exchange_client/meta_rpc/3_Info.py @@ -3,12 +3,13 @@ import time from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) resp = await client.info() print('[!] Info:') print(resp) diff --git a/examples/exchange_client/meta_rpc/4_StreamKeepAlive.py b/examples/exchange_client/meta_rpc/4_StreamKeepAlive.py index e73ef56b..5d3c531b 100644 --- a/examples/exchange_client/meta_rpc/4_StreamKeepAlive.py +++ b/examples/exchange_client/meta_rpc/4_StreamKeepAlive.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) task1 = asyncio.create_task(get_markets(client)) task2 = asyncio.create_task(keepalive(client, [task1])) diff --git a/examples/exchange_client/oracle_rpc/1_StreamPrices.py b/examples/exchange_client/oracle_rpc/1_StreamPrices.py index c4233229..788f02f2 100644 --- a/examples/exchange_client/oracle_rpc/1_StreamPrices.py +++ b/examples/exchange_client/oracle_rpc/1_StreamPrices.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) base_symbol = 'BTC' quote_symbol = 'USDT' oracle_type = 'bandibc' diff --git a/examples/exchange_client/oracle_rpc/2_Price.py b/examples/exchange_client/oracle_rpc/2_Price.py index eb3abdd2..094d82d7 100644 --- a/examples/exchange_client/oracle_rpc/2_Price.py +++ b/examples/exchange_client/oracle_rpc/2_Price.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) base_symbol = 'BTC' quote_symbol = 'USDT' oracle_type = 'bandibc' diff --git a/examples/exchange_client/oracle_rpc/3_OracleList.py b/examples/exchange_client/oracle_rpc/3_OracleList.py index 0eb58036..94cbd70b 100644 --- a/examples/exchange_client/oracle_rpc/3_OracleList.py +++ b/examples/exchange_client/oracle_rpc/3_OracleList.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) oracle_list = await client.get_oracle_list() print(oracle_list) diff --git a/examples/exchange_client/portfolio_rpc/1_AccountPortfolio.py b/examples/exchange_client/portfolio_rpc/1_AccountPortfolio.py index 4ab4def8..707f602a 100644 --- a/examples/exchange_client/portfolio_rpc/1_AccountPortfolio.py +++ b/examples/exchange_client/portfolio_rpc/1_AccountPortfolio.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) account_address = "inj1clw20s2uxeyxtam6f7m84vgae92s9eh7vygagt" portfolio = await client.get_account_portfolio( account_address=account_address diff --git a/examples/exchange_client/portfolio_rpc/2_StreamAccountPortfolio.py b/examples/exchange_client/portfolio_rpc/2_StreamAccountPortfolio.py index 9c37cb42..33c064f8 100644 --- a/examples/exchange_client/portfolio_rpc/2_StreamAccountPortfolio.py +++ b/examples/exchange_client/portfolio_rpc/2_StreamAccountPortfolio.py @@ -2,12 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) account_address = "inj1clw20s2uxeyxtam6f7m84vgae92s9eh7vygagt" updates = await client.stream_account_portfolio(account_address=account_address) async for update in updates: diff --git a/examples/exchange_client/spot_exchange_rpc/10_StreamTrades.py b/examples/exchange_client/spot_exchange_rpc/10_StreamTrades.py index 392be977..8f488d9b 100644 --- a/examples/exchange_client/spot_exchange_rpc/10_StreamTrades.py +++ b/examples/exchange_client/spot_exchange_rpc/10_StreamTrades.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_ids = [ "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe", "0x7a57e705bb4e09c88aecfc295569481dbf2fe1d5efe364651fbe72385938e9b0" diff --git a/examples/exchange_client/spot_exchange_rpc/11_SubaccountOrdersList.py b/examples/exchange_client/spot_exchange_rpc/11_SubaccountOrdersList.py index 178934c5..40a198db 100644 --- a/examples/exchange_client/spot_exchange_rpc/11_SubaccountOrdersList.py +++ b/examples/exchange_client/spot_exchange_rpc/11_SubaccountOrdersList.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) subaccount_id = "0xc7dca7c15c364865f77a4fb67ab11dc95502e6fe000000000000000000000001" market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" skip = 10 diff --git a/examples/exchange_client/spot_exchange_rpc/12_SubaccountTradesList.py b/examples/exchange_client/spot_exchange_rpc/12_SubaccountTradesList.py index f67816d8..9c6fbd5b 100644 --- a/examples/exchange_client/spot_exchange_rpc/12_SubaccountTradesList.py +++ b/examples/exchange_client/spot_exchange_rpc/12_SubaccountTradesList.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000" market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" execution_type = "market" diff --git a/examples/exchange_client/spot_exchange_rpc/13_StreamOrderbooks.py b/examples/exchange_client/spot_exchange_rpc/13_StreamOrderbooks.py index 5638b0d3..5592878b 100644 --- a/examples/exchange_client/spot_exchange_rpc/13_StreamOrderbooks.py +++ b/examples/exchange_client/spot_exchange_rpc/13_StreamOrderbooks.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_ids = [ "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe", "0x7a57e705bb4e09c88aecfc295569481dbf2fe1d5efe364651fbe72385938e9b0" diff --git a/examples/exchange_client/spot_exchange_rpc/14_Orderbooks.py b/examples/exchange_client/spot_exchange_rpc/14_Orderbooks.py index 59d23047..82f59a69 100644 --- a/examples/exchange_client/spot_exchange_rpc/14_Orderbooks.py +++ b/examples/exchange_client/spot_exchange_rpc/14_Orderbooks.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_ids = [ "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe", "0x7a57e705bb4e09c88aecfc295569481dbf2fe1d5efe364651fbe72385938e9b0" diff --git a/examples/exchange_client/spot_exchange_rpc/15_HistoricalOrders.py b/examples/exchange_client/spot_exchange_rpc/15_HistoricalOrders.py index 1e3266c9..a2ff4cec 100644 --- a/examples/exchange_client/spot_exchange_rpc/15_HistoricalOrders.py +++ b/examples/exchange_client/spot_exchange_rpc/15_HistoricalOrders.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" subaccount_id = "0xbdaedec95d563fb05240d6e01821008454c24c36000000000000000000000000" skip = 10 diff --git a/examples/exchange_client/spot_exchange_rpc/16_OrderbooksV2.py b/examples/exchange_client/spot_exchange_rpc/16_OrderbooksV2.py deleted file mode 100644 index 6a28009e..00000000 --- a/examples/exchange_client/spot_exchange_rpc/16_OrderbooksV2.py +++ /dev/null @@ -1,19 +0,0 @@ -import asyncio -import logging - -from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network - -async def main() -> None: - # select network: local, testnet, mainnet - network = Network.testnet() - client = AsyncClient(network, insecure=False) - market_ids = [ - "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe", - "0x7a57e705bb4e09c88aecfc295569481dbf2fe1d5efe364651fbe72385938e9b0" - ] - orderbooks = await client.get_spot_orderbooksV2(market_ids=market_ids) - print(orderbooks) - -if __name__ == '__main__': - asyncio.get_event_loop().run_until_complete(main()) diff --git a/examples/exchange_client/spot_exchange_rpc/1_Market.py b/examples/exchange_client/spot_exchange_rpc/1_Market.py index abc3b47a..e96f8d57 100644 --- a/examples/exchange_client/spot_exchange_rpc/1_Market.py +++ b/examples/exchange_client/spot_exchange_rpc/1_Market.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" market = await client.get_spot_market(market_id=market_id) print(market) diff --git a/examples/exchange_client/spot_exchange_rpc/2_Markets.py b/examples/exchange_client/spot_exchange_rpc/2_Markets.py index 59f0590b..36f90f86 100644 --- a/examples/exchange_client/spot_exchange_rpc/2_Markets.py +++ b/examples/exchange_client/spot_exchange_rpc/2_Markets.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_status = "active" base_denom = "inj" quote_denom = "peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5" diff --git a/examples/exchange_client/spot_exchange_rpc/3_StreamMarkets.py b/examples/exchange_client/spot_exchange_rpc/3_StreamMarkets.py index 90b4a1a2..d5e37a55 100644 --- a/examples/exchange_client/spot_exchange_rpc/3_StreamMarkets.py +++ b/examples/exchange_client/spot_exchange_rpc/3_StreamMarkets.py @@ -2,12 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) markets = await client.stream_spot_markets() async for market in markets: print(market) diff --git a/examples/exchange_client/spot_exchange_rpc/4_Orderbook.py b/examples/exchange_client/spot_exchange_rpc/4_Orderbook.py index 19b58933..60822926 100644 --- a/examples/exchange_client/spot_exchange_rpc/4_Orderbook.py +++ b/examples/exchange_client/spot_exchange_rpc/4_Orderbook.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" orderbook = await client.get_spot_orderbookV2(market_id=market_id) print(orderbook) diff --git a/examples/exchange_client/spot_exchange_rpc/6_Trades.py b/examples/exchange_client/spot_exchange_rpc/6_Trades.py index 46cf0ee8..4745296f 100644 --- a/examples/exchange_client/spot_exchange_rpc/6_Trades.py +++ b/examples/exchange_client/spot_exchange_rpc/6_Trades.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_ids = ["0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"] execution_side = "taker" direction = "buy" diff --git a/examples/exchange_client/spot_exchange_rpc/7_StreamOrderbookSnapshot.py b/examples/exchange_client/spot_exchange_rpc/7_StreamOrderbookSnapshot.py index 5514502e..e46a8ca8 100644 --- a/examples/exchange_client/spot_exchange_rpc/7_StreamOrderbookSnapshot.py +++ b/examples/exchange_client/spot_exchange_rpc/7_StreamOrderbookSnapshot.py @@ -2,13 +2,13 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_ids = ["0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"] orderbooks = await client.stream_spot_orderbook_snapshot(market_ids=market_ids) async for orderbook in orderbooks: diff --git a/examples/exchange_client/spot_exchange_rpc/8_StreamOrderbookUpdate.py b/examples/exchange_client/spot_exchange_rpc/8_StreamOrderbookUpdate.py index b39bf981..bd5fc5fc 100644 --- a/examples/exchange_client/spot_exchange_rpc/8_StreamOrderbookUpdate.py +++ b/examples/exchange_client/spot_exchange_rpc/8_StreamOrderbookUpdate.py @@ -3,7 +3,7 @@ from decimal import * from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network class PriceLevel: @@ -50,7 +50,7 @@ async def load_orderbook_snapshot(async_client: AsyncClient, orderbook: Orderboo async def main() -> None: # select network: local, testnet, mainnet network = Network.testnet() - async_client = AsyncClient(network, insecure=False) + async_client = AsyncClient(network) market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" orderbook = Orderbook(market_id=market_id) diff --git a/examples/exchange_client/spot_exchange_rpc/9_StreamHistoricalOrders.py b/examples/exchange_client/spot_exchange_rpc/9_StreamHistoricalOrders.py index 6a10b2f4..96d0898c 100644 --- a/examples/exchange_client/spot_exchange_rpc/9_StreamHistoricalOrders.py +++ b/examples/exchange_client/spot_exchange_rpc/9_StreamHistoricalOrders.py @@ -2,11 +2,12 @@ import logging from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network + async def main() -> None: network = Network.testnet() - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" order_side = "buy" subaccount_id = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000" diff --git a/pyinjective/__init__.py b/pyinjective/__init__.py index e17ef7b1..841ee3e8 100644 --- a/pyinjective/__init__.py +++ b/pyinjective/__init__.py @@ -1,3 +1,3 @@ -from .client import Client +from .async_client import AsyncClient from .transaction import Transaction from .wallet import PrivateKey, PublicKey, Address diff --git a/pyinjective/async_client.py b/pyinjective/async_client.py index 965d1549..3374f6c1 100644 --- a/pyinjective/async_client.py +++ b/pyinjective/async_client.py @@ -1,13 +1,18 @@ -import os +import asyncio import time +from copy import deepcopy + import grpc import aiocron -import logging -import datetime -from http.cookies import SimpleCookie -from typing import List, Optional, Tuple, Union +from decimal import Decimal +from typing import Dict, List, Optional, Tuple, Union, Coroutine + +from pyinjective.composer import Composer -from .exceptions import NotFoundError, EmptyMsgError +from . import constant +from .core.market import BinaryOptionMarket, DerivativeMarket, SpotMarket +from .core.token import Token +from .exceptions import NotFoundError from .proto.cosmos.base.abci.v1beta1 import abci_pb2 as abci_type @@ -19,17 +24,10 @@ from .proto.cosmos.auth.v1beta1 import ( query_pb2_grpc as auth_query_grpc, query_pb2 as auth_query, - auth_pb2 as auth_type, ) from .proto.cosmos.authz.v1beta1 import ( query_pb2_grpc as authz_query_grpc, query_pb2 as authz_query, - authz_pb2 as authz_type, -) -from .proto.cosmos.authz.v1beta1 import ( - query_pb2_grpc as authz_query_grpc, - query_pb2 as authz_query, - authz_pb2 as authz_type, ) from .proto.cosmos.bank.v1beta1 import ( query_pb2_grpc as bank_query_grpc, @@ -64,7 +62,7 @@ account_pb2 ) -from .constant import Network +from .core.network import Network from .utils.logger import LoggerProvider DEFAULT_TIMEOUTHEIGHT_SYNC_INTERVAL = 20 # seconds @@ -78,39 +76,23 @@ def __init__( self, network: Network, insecure: bool = False, - load_balancer: bool = True, credentials=grpc.ssl_channel_credentials(), - chain_cookie_location=".chain_cookie", ): - - # use append mode to create file if not exist - self.chain_cookie_location = chain_cookie_location - cookie_file = open(chain_cookie_location, "a+") - cookie_file.close() + # the `insecure` parameter is ignored and will be deprecated soon. The value is taken directly from `network` self.addr = "" self.number = 0 self.sequence = 0 - self.cookie_type = None - self.expiration_format = None - self.load_balancer = load_balancer self.network = network - self.cookie_type = "GCLB" - self.expiration_format = "{}" - - if self.network.string() == "testnet": - self.load_balancer = False - self.cookie_type = "grpc-cookie" - self.expiration_format = "20{}" # chain stubs self.chain_channel = ( - grpc.aio.insecure_channel(network.grpc_endpoint) - if (insecure or credentials is None) - else grpc.aio.secure_channel(network.grpc_endpoint, credentials) + grpc.aio.secure_channel(network.grpc_endpoint, credentials) + if (network.use_secure_connection and credentials is not None) + else grpc.aio.insecure_channel(network.grpc_endpoint) ) - self.insecure = insecure + self.stubCosmosTendermint = tendermint_query_grpc.ServiceStub( self.chain_channel ) @@ -119,22 +101,14 @@ def __init__( self.stubBank = bank_query_grpc.QueryStub(self.chain_channel) self.stubTx = tx_service_grpc.ServiceStub(self.chain_channel) - # attempt to load from disk - cookie_file = open(chain_cookie_location, "r+") - self.chain_cookie = cookie_file.read() - cookie_file.close() - LoggerProvider().logger_for_class(logging_class=self.__class__).info( - f"chain session cookie loaded from disk: {self.chain_cookie}" - ) - self.exchange_cookie = "" self.timeout_height = 1 # exchange stubs self.exchange_channel = ( - grpc.aio.insecure_channel(network.grpc_exchange_endpoint) - if (insecure or credentials is None) - else grpc.aio.secure_channel(network.grpc_exchange_endpoint, credentials) + grpc.aio.secure_channel(network.grpc_exchange_endpoint, credentials) + if (network.use_secure_connection and credentials is not None) + else grpc.aio.insecure_channel(network.grpc_exchange_endpoint) ) self.stubMeta = exchange_meta_rpc_grpc.InjectiveMetaRPCStub( self.exchange_channel @@ -163,9 +137,9 @@ def __init__( # explorer stubs self.explorer_channel = ( - grpc.aio.insecure_channel(network.grpc_explorer_endpoint) - if (insecure or credentials is None) - else grpc.aio.secure_channel(network.grpc_explorer_endpoint, credentials) + grpc.aio.secure_channel(network.grpc_explorer_endpoint, credentials) + if (network.use_secure_connection and credentials is not None) + else grpc.aio.insecure_channel(network.grpc_explorer_endpoint) ) self.stubExplorer = explorer_rpc_grpc.InjectiveExplorerRPCStub( self.explorer_channel @@ -179,6 +153,40 @@ def __init__( start=True, ) + self._tokens_and_markets_initialization_lock = asyncio.Lock() + self._tokens: Optional[Dict[str, Token]] = None + self._spot_markets: Optional[Dict[str, SpotMarket]] = None + self._derivative_markets: Optional[Dict[str, DerivativeMarket]] = None + self._binary_option_markets: Optional[Dict[str, BinaryOptionMarket]] = None + + async def all_tokens(self) -> Dict[str, Token]: + if self._tokens is None: + async with self._tokens_and_markets_initialization_lock: + if self._tokens is None: + await self._initialize_tokens_and_markets() + return deepcopy(self._tokens) + + async def all_spot_markets(self) -> Dict[str, SpotMarket]: + if self._spot_markets is None: + async with self._tokens_and_markets_initialization_lock: + if self._spot_markets is None: + await self._initialize_tokens_and_markets() + return deepcopy(self._spot_markets) + + async def all_derivative_markets(self) -> Dict[str, DerivativeMarket]: + if self._derivative_markets is None: + async with self._tokens_and_markets_initialization_lock: + if self._derivative_markets is None: + await self._initialize_tokens_and_markets() + return deepcopy(self._derivative_markets) + + async def all_binary_option_markets(self) -> Dict[str, BinaryOptionMarket]: + if self._binary_option_markets is None: + async with self._tokens_and_markets_initialization_lock: + if self._binary_option_markets is None: + await self._initialize_tokens_and_markets() + return deepcopy(self._binary_option_markets) + def get_sequence(self): current_seq = self.sequence self.sequence += 1 @@ -208,91 +216,6 @@ async def sync_timeout_height(self): ) self.timeout_height = 0 - # cookie helper methods - async def fetch_cookie(self, type): - metadata = None - if type == "chain": - req = tendermint_query.GetLatestBlockRequest() - metadata = await self.stubCosmosTendermint.GetLatestBlock( - req - ).initial_metadata() - time.sleep(DEFAULT_BLOCK_TIME) - if type == "exchange": - req = exchange_meta_rpc_pb.VersionRequest() - metadata = await self.stubMeta.Version(req).initial_metadata() - return metadata - - async def renew_cookie(self, existing_cookie, type): - metadata = None - # format cookie date into RFC1123 standard - cookie = SimpleCookie() - cookie.load(existing_cookie) - - expires_at = cookie.get(f"{self.cookie_type}").get("expires") - expires_at = expires_at.replace("-", " ") - yyyy = f"{self.expiration_format}".format(expires_at[12:14]) - expires_at = expires_at[:12] + yyyy + expires_at[14:] - - # parse expire field to unix timestamp - expire_timestamp = datetime.datetime.strptime( - expires_at, "%a, %d %b %Y %H:%M:%S GMT" - ).timestamp() - - # renew session if timestamp diff < offset - timestamp_diff = expire_timestamp - int(time.time()) - if timestamp_diff < DEFAULT_SESSION_RENEWAL_OFFSET: - metadata = await self.fetch_cookie(type) - else: - metadata = (("cookie", existing_cookie),) - return metadata - - async def load_cookie(self, type): - metadata = None - if self.insecure: - return metadata - - if type == "chain": - if self.chain_cookie != "": - metadata = await self.renew_cookie(self.chain_cookie, type) - self.set_cookie(metadata, type) - else: - metadata = await self.fetch_cookie(type) - self.set_cookie(metadata, type) - - if type == "exchange": - if self.exchange_cookie != "": - metadata = await self.renew_cookie(self.exchange_cookie, type) - self.set_cookie(metadata, type) - else: - metadata = await self.fetch_cookie(type) - self.set_cookie(metadata, type) - - return metadata - - def set_cookie(self, metadata, type): - new_cookie = None - if self.insecure: - return new_cookie - - for k, v in metadata: - if k == "set-cookie": - new_cookie = v - - if new_cookie == None: - return - - if type == "chain": - # write to client instance - self.chain_cookie = new_cookie - # write to disk - cookie_file = open(self.chain_cookie_location, "w") - cookie_file.write(new_cookie) - cookie_file.close() - LoggerProvider().logger_for_class(logging_class=self.__class__).info("chain session cookie saved to disk") - - if type == "exchange": - self.exchange_cookie = new_cookie - # default client methods async def get_latest_block(self) -> tendermint_query.GetLatestBlockResponse: req = tendermint_query.GetLatestBlockRequest() @@ -300,7 +223,8 @@ async def get_latest_block(self) -> tendermint_query.GetLatestBlockResponse: async def get_account(self, address: str) -> Optional[account_pb2.EthAccount]: try: - metadata = await self.load_cookie(type="chain") + metadata = await self.network.chain_metadata( + metadata_query_provider=self._chain_cookie_metadata_requestor) account_any = (await self.stubAuth.Account( auth_query.QueryAccountRequest(address=address), metadata=metadata )).account @@ -338,7 +262,8 @@ async def simulate_tx( ) -> Tuple[Union[abci_type.SimulationResponse, grpc.RpcError], bool]: try: req = tx_service.SimulateRequest(tx_bytes=tx_byte) - metadata = await self.load_cookie(type="chain") + metadata = await self.network.chain_metadata( + metadata_query_provider=self._chain_cookie_metadata_requestor) return await self.stubTx.Simulate(request=req, metadata=metadata), True except grpc.RpcError as err: return err, False @@ -347,7 +272,7 @@ async def send_tx_sync_mode(self, tx_byte: bytes) -> abci_type.TxResponse: req = tx_service.BroadcastTxRequest( tx_bytes=tx_byte, mode=tx_service.BroadcastMode.BROADCAST_MODE_SYNC ) - metadata = await self.load_cookie(type="chain") + metadata = await self.network.chain_metadata(metadata_query_provider=self._chain_cookie_metadata_requestor) result = await self.stubTx.BroadcastTx(request=req, metadata=metadata) return result.tx_response @@ -355,7 +280,7 @@ async def send_tx_async_mode(self, tx_byte: bytes) -> abci_type.TxResponse: req = tx_service.BroadcastTxRequest( tx_bytes=tx_byte, mode=tx_service.BroadcastMode.BROADCAST_MODE_ASYNC ) - metadata = await self.load_cookie(type="chain") + metadata = await self.network.chain_metadata(metadata_query_provider=self._chain_cookie_metadata_requestor) result = await self.stubTx.BroadcastTx(request=req, metadata=metadata) return result.tx_response @@ -363,7 +288,7 @@ async def send_tx_block_mode(self, tx_byte: bytes) -> abci_type.TxResponse: req = tx_service.BroadcastTxRequest( tx_bytes=tx_byte, mode=tx_service.BroadcastMode.BROADCAST_MODE_BLOCK ) - metadata = await self.load_cookie(type="chain") + metadata = await self.network.chain_metadata(metadata_query_provider=self._chain_cookie_metadata_requestor) result = await self.stubTx.BroadcastTx(request=req, metadata=metadata) return result.tx_response @@ -631,7 +556,9 @@ async def stream_spot_markets(self, **kwargs): req = spot_exchange_rpc_pb.StreamMarketsRequest( market_ids=kwargs.get("market_ids") ) - metadata = await self.load_cookie(type="exchange") + metadata = await self.network.exchange_metadata( + metadata_query_provider=self._exchange_cookie_metadata_requestor + ) return self.stubSpotExchange.StreamMarkets(request=req, metadata=metadata) async def get_spot_orderbookV2(self, market_id: str): @@ -688,12 +615,16 @@ async def get_spot_trades(self, **kwargs): async def stream_spot_orderbook_snapshot(self, market_ids: List[str]): req = spot_exchange_rpc_pb.StreamOrderbookV2Request(market_ids=market_ids) - metadata = await self.load_cookie(type="exchange") + metadata = await self.network.exchange_metadata( + metadata_query_provider=self._exchange_cookie_metadata_requestor + ) return self.stubSpotExchange.StreamOrderbookV2(request=req, metadata=metadata) async def stream_spot_orderbook_update(self, market_ids: List[str]): req = spot_exchange_rpc_pb.StreamOrderbookUpdateRequest(market_ids=market_ids) - metadata = await self.load_cookie(type="exchange") + metadata = await self.network.exchange_metadata( + metadata_query_provider=self._exchange_cookie_metadata_requestor + ) return self.stubSpotExchange.StreamOrderbookUpdate(request=req, metadata=metadata) async def stream_spot_orders(self, market_id: str, **kwargs): @@ -702,7 +633,9 @@ async def stream_spot_orders(self, market_id: str, **kwargs): order_side=kwargs.get("order_side"), subaccount_id=kwargs.get("subaccount_id"), ) - metadata = await self.load_cookie(type="exchange") + metadata = await self.network.exchange_metadata( + metadata_query_provider=self._exchange_cookie_metadata_requestor + ) return self.stubSpotExchange.StreamOrders(request=req, metadata=metadata) async def stream_historical_spot_orders(self, market_id: str, **kwargs): @@ -714,7 +647,9 @@ async def stream_historical_spot_orders(self, market_id: str, **kwargs): state=kwargs.get("state"), execution_types=kwargs.get("execution_types") ) - metadata = await self.load_cookie(type="exchange") + metadata = await self.network.exchange_metadata( + metadata_query_provider=self._exchange_cookie_metadata_requestor + ) return self.stubSpotExchange.StreamOrdersHistory(request=req, metadata=metadata) async def stream_historical_derivative_orders(self, market_id: str, **kwargs): @@ -726,7 +661,9 @@ async def stream_historical_derivative_orders(self, market_id: str, **kwargs): state=kwargs.get("state"), execution_types=kwargs.get("execution_types") ) - metadata = await self.load_cookie(type="exchange") + metadata = await self.network.exchange_metadata( + metadata_query_provider=self._exchange_cookie_metadata_requestor + ) return self.stubDerivativeExchange.StreamOrdersHistory(request=req, metadata=metadata) async def stream_spot_trades(self, **kwargs): @@ -739,7 +676,9 @@ async def stream_spot_trades(self, **kwargs): subaccount_ids=kwargs.get("subaccount_ids"), execution_types=kwargs.get("execution_types"), ) - metadata = await self.load_cookie(type="exchange") + metadata = await self.network.exchange_metadata( + metadata_query_provider=self._exchange_cookie_metadata_requestor + ) return self.stubSpotExchange.StreamTrades(request=req, metadata=metadata) async def get_spot_subaccount_orders(self, subaccount_id: str, **kwargs): @@ -779,7 +718,9 @@ async def stream_derivative_markets(self, **kwargs): req = derivative_exchange_rpc_pb.StreamMarketRequest( market_ids=kwargs.get("market_ids") ) - metadata = await self.load_cookie(type="exchange") + metadata = await self.network.exchange_metadata( + metadata_query_provider=self._exchange_cookie_metadata_requestor + ) return self.stubDerivativeExchange.StreamMarket(request=req, metadata=metadata) async def get_derivative_orderbook(self, market_id: str): @@ -845,12 +786,16 @@ async def get_derivative_trades(self, **kwargs): async def stream_derivative_orderbook_snapshot(self, market_ids: List[str]): req = derivative_exchange_rpc_pb.StreamOrderbookV2Request(market_ids=market_ids) - metadata = await self.load_cookie(type="exchange") + metadata = await self.network.exchange_metadata( + metadata_query_provider=self._exchange_cookie_metadata_requestor + ) return self.stubDerivativeExchange.StreamOrderbookV2(request=req, metadata=metadata) async def stream_derivative_orderbook_update(self, market_ids: List[str]): req = derivative_exchange_rpc_pb.StreamOrderbookUpdateRequest(market_ids=market_ids) - metadata = await self.load_cookie(type="exchange") + metadata = await self.network.exchange_metadata( + metadata_query_provider=self._exchange_cookie_metadata_requestor + ) return self.stubDerivativeExchange.StreamOrderbookUpdate(request=req, metadata=metadata) async def stream_derivative_orders(self, market_id: str, **kwargs): @@ -859,7 +804,9 @@ async def stream_derivative_orders(self, market_id: str, **kwargs): order_side=kwargs.get("order_side"), subaccount_id=kwargs.get("subaccount_id"), ) - metadata = await self.load_cookie(type="exchange") + metadata = await self.network.exchange_metadata( + metadata_query_provider=self._exchange_cookie_metadata_requestor + ) return self.stubDerivativeExchange.StreamOrders(request=req, metadata=metadata) async def stream_derivative_trades(self, **kwargs): @@ -874,7 +821,9 @@ async def stream_derivative_trades(self, **kwargs): limit=kwargs.get("limit"), execution_types=kwargs.get("execution_types"), ) - metadata = await self.load_cookie(type="exchange") + metadata = await self.network.exchange_metadata( + metadata_query_provider=self._exchange_cookie_metadata_requestor + ) return self.stubDerivativeExchange.StreamTrades(request=req, metadata=metadata) async def get_derivative_positions(self, **kwargs): @@ -896,7 +845,9 @@ async def stream_derivative_positions(self, **kwargs): subaccount_id=kwargs.get("subaccount_id"), subaccount_ids=kwargs.get("subaccount_ids"), ) - metadata = await self.load_cookie(type="exchange") + metadata = await self.network.exchange_metadata( + metadata_query_provider=self._exchange_cookie_metadata_requestor + ) return self.stubDerivativeExchange.StreamPositions(request=req, metadata=metadata) async def get_derivative_liquidable_positions(self, **kwargs): @@ -944,7 +895,7 @@ async def get_funding_rates(self, market_id: str, **kwargs): skip=kwargs.get("skip"), limit=kwargs.get("limit"), end_time=kwargs.get("end_time"), -) + ) return await self.stubDerivativeExchange.FundingRates(req) async def get_binary_options_markets(self, **kwargs): @@ -972,5 +923,157 @@ async def stream_account_portfolio(self, account_address: str, **kwargs): subaccount_id=kwargs.get("subaccount_id"), type=kwargs.get("type") ) - metadata = await self.load_cookie(type="exchange") + metadata = await self.network.exchange_metadata( + metadata_query_provider=self._exchange_cookie_metadata_requestor + ) return self.stubPortfolio.StreamAccountPortfolio(request=req, metadata=metadata) + + async def composer(self): + return Composer( + network=self.network.string(), + spot_markets=await self.all_spot_markets(), + derivative_markets=await self.all_derivative_markets(), + binary_option_markets=await self.all_binary_option_markets(), + tokens=await self.all_tokens(), + ) + + async def _initialize_tokens_and_markets(self): + spot_markets = dict() + derivative_markets = dict() + binary_option_markets = dict() + tokens = dict() + tokens_by_denom = dict() + markets_info = (await self.get_spot_markets()).markets + + for market_info in markets_info: + if "/" in market_info.ticker: + base_token_symbol, quote_token_symbol = market_info.ticker.split(constant.TICKER_TOKENS_SEPARATOR) + else: + base_token_symbol = market_info.base_token_meta.symbol + quote_token_symbol = market_info.quote_token_meta.symbol + + base_token = self._token_representation( + symbol=base_token_symbol, + token_meta=market_info.base_token_meta, + denom=market_info.base_denom, + all_tokens=tokens, + ) + if base_token.denom not in tokens_by_denom: + tokens_by_denom[base_token.denom] = base_token + + quote_token = self._token_representation( + symbol=quote_token_symbol, + token_meta=market_info.quote_token_meta, + denom=market_info.quote_denom, + all_tokens=tokens, + ) + if quote_token.denom not in tokens_by_denom: + tokens_by_denom[quote_token.denom] = quote_token + + market = SpotMarket( + id=market_info.market_id, + status=market_info.market_status, + ticker=market_info.ticker, + base_token=base_token, + quote_token=quote_token, + maker_fee_rate=Decimal(market_info.maker_fee_rate), + taker_fee_rate=Decimal(market_info.taker_fee_rate), + service_provider_fee=Decimal(market_info.service_provider_fee), + min_price_tick_size=Decimal(market_info.min_price_tick_size), + min_quantity_tick_size=Decimal(market_info.min_quantity_tick_size), + ) + + spot_markets[market.id] = market + + markets_info = (await self.get_derivative_markets()).markets + for market_info in markets_info: + quote_token_symbol = market_info.quote_token_meta.symbol + + quote_token = self._token_representation( + symbol=quote_token_symbol, + token_meta=market_info.quote_token_meta, + denom=market_info.quote_denom, + all_tokens=tokens, + ) + if quote_token.denom not in tokens_by_denom: + tokens_by_denom[quote_token.denom] = quote_token + + market = DerivativeMarket( + id=market_info.market_id, + status=market_info.market_status, + ticker=market_info.ticker, + oracle_base=market_info.oracle_base, + oracle_quote=market_info.oracle_quote, + oracle_type=market_info.oracle_type, + oracle_scale_factor=market_info.oracle_scale_factor, + initial_margin_ratio=Decimal(market_info.initial_margin_ratio), + maintenance_margin_ratio=Decimal(market_info.maintenance_margin_ratio), + quote_token=quote_token, + maker_fee_rate=Decimal(market_info.maker_fee_rate), + taker_fee_rate = Decimal(market_info.taker_fee_rate), + service_provider_fee = Decimal(market_info.service_provider_fee), + min_price_tick_size = Decimal(market_info.min_price_tick_size), + min_quantity_tick_size = Decimal(market_info.min_quantity_tick_size), + ) + + derivative_markets[market.id] = market + + markets_info = (await self.get_binary_options_markets()).markets + for market_info in markets_info: + quote_token = tokens_by_denom.get(market_info.quote_denom, None) + + market = BinaryOptionMarket( + id=market_info.market_id, + status=market_info.market_status, + ticker=market_info.ticker, + oracle_symbol=market_info.oracle_symbol, + oracle_provider=market_info.oracle_provider, + oracle_type=market_info.oracle_type, + oracle_scale_factor=market_info.oracle_scale_factor, + expiration_timestamp=market_info.expiration_timestamp, + settlement_timestamp=market_info.settlement_timestamp, + quote_token=quote_token, + maker_fee_rate=Decimal(market_info.maker_fee_rate), + taker_fee_rate=Decimal(market_info.taker_fee_rate), + service_provider_fee=Decimal(market_info.service_provider_fee), + min_price_tick_size=Decimal(market_info.min_price_tick_size), + min_quantity_tick_size=Decimal(market_info.min_quantity_tick_size), + ) + + binary_option_markets[market.id] = market + + self._tokens = tokens + self._spot_markets = spot_markets + self._derivative_markets = derivative_markets + self._binary_option_markets = binary_option_markets + + def _token_representation(self, symbol: str, token_meta, denom: str, all_tokens: Dict[str, Token]) -> Token: + token = Token( + name=token_meta.name, + symbol=symbol, + denom=denom, + address=token_meta.address, + decimals=token_meta.decimals, + logo=token_meta.logo, + updated=token_meta.updated_at, + ) + + existing_token = all_tokens.get(token.symbol, None) + if existing_token is None: + all_tokens[token.symbol] = token + existing_token = token + elif existing_token.denom != denom: + existing_token = all_tokens.get(token.name, None) + if existing_token is None: + all_tokens[token.name] = token + existing_token = token + + return existing_token + + def _chain_cookie_metadata_requestor(self) -> Coroutine: + request = tendermint_query.GetLatestBlockRequest() + return self.stubCosmosTendermint.GetLatestBlock(request).initial_metadata() + + def _exchange_cookie_metadata_requestor(self) -> Coroutine: + request = exchange_meta_rpc_pb.VersionRequest() + return self.stubMeta.Version(request).initial_metadata() diff --git a/pyinjective/client.py b/pyinjective/client.py deleted file mode 100644 index 662d9840..00000000 --- a/pyinjective/client.py +++ /dev/null @@ -1,692 +0,0 @@ -import os -import time -import grpc -import datetime -import threading -from http.cookies import SimpleCookie -from typing import List, Optional, Tuple, Union - -from .exceptions import NotFoundError, EmptyMsgError - -from .proto.cosmos.base.abci.v1beta1 import abci_pb2 as abci_type - -from .proto.cosmos.base.tendermint.v1beta1 import ( - query_pb2_grpc as tendermint_query_grpc, - query_pb2 as tendermint_query, -) -from .proto.cosmos.auth.v1beta1 import ( - query_pb2_grpc as auth_query_grpc, - query_pb2 as auth_query, - auth_pb2 as auth_type, -) -from .proto.cosmos.authz.v1beta1 import ( - query_pb2_grpc as authz_query_grpc, - query_pb2 as authz_query, - authz_pb2 as authz_type, -) -from .proto.cosmos.tx.v1beta1 import ( - service_pb2_grpc as tx_service_grpc, - service_pb2 as tx_service, -) -from .proto.exchange import ( - injective_accounts_rpc_pb2 as exchange_accounts_rpc_pb, - injective_accounts_rpc_pb2_grpc as exchange_accounts_rpc_grpc, - injective_oracle_rpc_pb2 as oracle_rpc_pb, - injective_oracle_rpc_pb2_grpc as oracle_rpc_grpc, - injective_insurance_rpc_pb2 as insurance_rpc_pb, - injective_insurance_rpc_pb2_grpc as insurance_rpc_grpc, - injective_spot_exchange_rpc_pb2 as spot_exchange_rpc_pb, - injective_spot_exchange_rpc_pb2_grpc as spot_exchange_rpc_grpc, - injective_derivative_exchange_rpc_pb2 as derivative_exchange_rpc_pb, - injective_derivative_exchange_rpc_pb2_grpc as derivative_exchange_rpc_grpc, - injective_meta_rpc_pb2 as exchange_meta_rpc_pb, - injective_meta_rpc_pb2_grpc as exchange_meta_rpc_grpc, - injective_explorer_rpc_pb2 as explorer_rpc_pb, - injective_explorer_rpc_pb2_grpc as explorer_rpc_grpc, - injective_auction_rpc_pb2 as auction_rpc_pb, - injective_auction_rpc_pb2_grpc as auction_rpc_grpc, -) - -from .constant import Network - -DEFAULT_TIMEOUTHEIGHT_SYNC_INTERVAL = 10 # seconds -DEFAULT_TIMEOUTHEIGHT = 20 # blocks -DEFAULT_SESSION_RENEWAL_OFFSET = 120 # seconds -DEFAULT_BLOCK_TIME = 3 # seconds - -class Client: - def __init__( - self, - network: Network, - insecure: bool = False, - credentials = grpc.ssl_channel_credentials() - ): - - # chain stubs - self.chain_channel = ( - grpc.insecure_channel(network.grpc_endpoint) - if insecure else grpc.secure_channel(network.grpc_endpoint, credentials) - ) - self.stubCosmosTendermint = tendermint_query_grpc.ServiceStub(self.chain_channel) - self.stubAuth = auth_query_grpc.QueryStub(self.chain_channel) - self.stubAuthz = authz_query_grpc.QueryStub(self.chain_channel) - self.stubTx = tx_service_grpc.ServiceStub(self.chain_channel) - self.chain_cookie = "" - self.exchange_cookie = "" - self.timeout_height = 1 - - # exchange stubs - self.exchange_channel = ( - grpc.insecure_channel(network.grpc_exchange_endpoint) - if insecure else grpc.secure_channel(network.grpc_exchange_endpoint, credentials) - ) - - self.stubMeta = exchange_meta_rpc_grpc.InjectiveMetaRPCStub(self.exchange_channel) - self.stubExchangeAccount = exchange_accounts_rpc_grpc.InjectiveAccountsRPCStub( - self.exchange_channel - ) - self.stubOracle = oracle_rpc_grpc.InjectiveOracleRPCStub(self.exchange_channel) - self.stubInsurance = insurance_rpc_grpc.InjectiveInsuranceRPCStub( - self.exchange_channel - ) - self.stubSpotExchange = spot_exchange_rpc_grpc.InjectiveSpotExchangeRPCStub( - self.exchange_channel - ) - self.stubDerivativeExchange = ( - derivative_exchange_rpc_grpc.InjectiveDerivativeExchangeRPCStub( - self.exchange_channel - ) - ) - self.stubExplorer = explorer_rpc_grpc.InjectiveExplorerRPCStub(self.exchange_channel) - self.stubAuction = auction_rpc_grpc.InjectiveAuctionRPCStub(self.exchange_channel) - - def close_exchange_channel(self): - self.exchange_channel.close() - - def close_chain_channel(self): - self.chain_channel.close() - - # timeout height update routine - self.sync_timeout_height() - - def sync_timeout_height(self): - threading.Timer(DEFAULT_TIMEOUTHEIGHT_SYNC_INTERVAL, self.sync_timeout_height).start() - block = self.get_latest_block() - self.timeout_height = block.block.header.height + DEFAULT_TIMEOUTHEIGHT - - # cookie helper methods - def get_cookie(self, type): - metadata = None - if type == "chain": - if self.chain_cookie != "": - metadata = (("cookie", self.chain_cookie),) - - # format cookie date into RFC1123 standard - cookie = SimpleCookie() - cookie.load(self.chain_cookie) - expires_at = cookie.get("grpc-cookie").get("expires") - expires_at = expires_at.replace("-"," ") - yyyy = "20{}".format(expires_at[12:14]) - expires_at = expires_at[:12] + yyyy + expires_at[14:] - - # parse expire field to unix timestamp - expire_timestamp = datetime.datetime.strptime(expires_at, "%a, %d %b %Y %H:%M:%S GMT").timestamp() - - # renew session if timestamp diff < offset - timestamp_diff = expire_timestamp - int(time.time()) - if timestamp_diff < DEFAULT_SESSION_RENEWAL_OFFSET: - # request and set new cookie - req = tendermint_query.GetLatestBlockRequest() - res, call = self.stubCosmosTendermint.GetLatestBlock.with_call(req) - self.set_cookie(call,type="chain") - time.sleep(DEFAULT_BLOCK_TIME) - metadata = (("cookie", self.chain_cookie),) - return metadata - return metadata - - if type == "exchange": - if self.exchange_cookie != "": - metadata = (("cookie", self.exchange_cookie),) - return metadata - - def set_cookie(self, call, type): - new_cookie = None - for k, v in call.initial_metadata(): - if k == "set-cookie": - new_cookie = v - - if new_cookie == None: - return - - if type == "chain": - self.chain_cookie = new_cookie - if type == "exchange": - self.exchange_cookie = new_cookie - - # default client methods - def get_latest_block(self) -> tendermint_query.GetLatestBlockResponse: - return self.stubCosmosTendermint.GetLatestBlock( - tendermint_query.GetLatestBlockRequest() - ) - - def get_account(self, address: str) -> Optional[auth_type.BaseAccount]: - try: - account_any = self.stubAuth.Account( - auth_query.QueryAccountRequest(address=address) - ).account - account = auth_type.BaseAccount() - if account_any.Is(account.DESCRIPTOR): - account_any.Unpack(account) - return account - except: - return None - - def get_request_id_by_tx_hash(self, tx_hash: bytes) -> List[int]: - tx = self.stubTx.GetTx(tx_service.GetTxRequest(hash=tx_hash)) - request_ids = [] - for tx in tx.tx_response.logs: - request_event = [ - event - for event in tx.events - if event.type == "request" or event.type == "report" - ] - if len(request_event) == 1: - attrs = request_event[0].attributes - attr_id = [attr for attr in attrs if attr.key == "id"] - if len(attr_id) == 1: - request_id = attr_id[0].value - request_ids.append(int(request_id)) - if len(request_ids) == 0: - raise NotFoundError("Request Id is not found") - return request_ids - - def simulate_tx( - self, tx_byte: bytes - ) -> Tuple[Union[abci_type.SimulationResponse, grpc.RpcError], bool]: - try: - req = tx_service.SimulateRequest(tx_bytes=tx_byte) - - metadata = self.get_cookie(type="chain") - res, call = self.stubTx.Simulate.with_call(req, metadata=metadata) - self.set_cookie(call,type="chain") - - return res, True - - except grpc.RpcError as err: - return err, False - - def send_tx_sync_mode(self, tx_byte: bytes) -> abci_type.TxResponse: - req = tx_service.BroadcastTxRequest( - tx_bytes=tx_byte, mode=tx_service.BroadcastMode.BROADCAST_MODE_SYNC - ) - metadata = self.get_cookie(type="chain") - res, call = self.stubTx.BroadcastTx.with_call(req, metadata=metadata) - self.set_cookie(call,type="chain") - - return res.tx_response - - def send_tx_async_mode(self, tx_byte: bytes) -> abci_type.TxResponse: - req = tx_service.BroadcastTxRequest( - tx_bytes=tx_byte, - mode=tx_service.BroadcastMode.BROADCAST_MODE_ASYNC - ) - metadata = self.get_cookie(type="chain") - res, call = self.stubTx.BroadcastTx.with_call(req, metadata=metadata) - self.set_cookie(call,type="chain") - - return res.tx_response - - def send_tx_block_mode(self, tx_byte: bytes) -> abci_type.TxResponse: - req = tx_service.BroadcastTxRequest( - tx_bytes=tx_byte, - mode=tx_service.BroadcastMode.BROADCAST_MODE_BLOCK - ) - metadata = self.get_cookie(type="chain") - res, call = self.stubTx.BroadcastTx.with_call(req, metadata=metadata) - self.set_cookie(call,type="chain") - - return res.tx_response - - def get_chain_id(self) -> str: - latest_block = self.get_latest_block() - return latest_block.block.header.chain_id - - def get_grants(self, granter: str, grantee: str, **kwargs): - return self.stubAuthz.Grants( - authz_query.QueryGrantsRequest( - granter=granter, - grantee=grantee, - msg_type_url=kwargs.get("msg_type_url"), - ) - ) - - # Injective Exchange client methods - - # Auction RPC - - def get_auction(self, bid_round: int): - req = auction_rpc_pb.AuctionRequest(round=bid_round) - return self.stubAuction.AuctionEndpoint(req) - - def get_auctions(self): - req = auction_rpc_pb.AuctionsRequest() - return self.stubAuction.Auctions(req) - - def stream_bids(self): - req = auction_rpc_pb.StreamBidsRequest() - return self.stubAuction.StreamBids(req) - - # Meta RPC - - def ping(self): - req = exchange_meta_rpc_pb.PingRequest() - return self.stubMeta.Ping(req) - - def version(self): - req = exchange_meta_rpc_pb.VersionRequest() - return self.stubMeta.Version(req) - - def info(self): - req = exchange_meta_rpc_pb.InfoRequest( - timestamp=int(time.time() * 1000), - ) - return self.stubMeta.Info(req) - - def stream_keepalive(self): - req = exchange_meta_rpc_pb.StreamKeepaliveRequest() - return self.stubMeta.StreamKeepalive(req) - - # Explorer RPC - - def get_tx_by_hash(self, tx_hash: str): - req = explorer_rpc_pb.GetTxByTxHashRequest(hash=tx_hash) - return self.stubExplorer.GetTxByTxHash(req) - - # AccountsRPC - - def stream_subaccount_balance(self, subaccount_id: str): - req = exchange_accounts_rpc_pb.StreamSubaccountBalanceRequest( - subaccount_id=subaccount_id - ) - return self.stubExchangeAccount.StreamSubaccountBalance(req) - - def get_subaccount_balance(self, subaccount_id: str, denom: str): - req = exchange_accounts_rpc_pb.SubaccountBalanceRequest( - subaccount_id=subaccount_id, denom=denom - ) - return self.stubExchangeAccount.SubaccountBalanceEndpoint(req) - - def get_subaccount_list(self, account_address: str): - req = exchange_accounts_rpc_pb.SubaccountsListRequest( - account_address=account_address - ) - return self.stubExchangeAccount.SubaccountsList(req) - - def get_subaccount_balances_list(self, subaccount_id: str): - req = exchange_accounts_rpc_pb.SubaccountBalancesListRequest( - subaccount_id=subaccount_id - ) - return self.stubExchangeAccount.SubaccountBalancesList(req) - - def get_subaccount_history(self, subaccount_id: str, **kwargs): - req = exchange_accounts_rpc_pb.SubaccountHistoryRequest( - subaccount_id=subaccount_id, - denom=kwargs.get("denom"), - transfer_types=kwargs.get("transfer_types"), - ) - return self.stubExchangeAccount.SubaccountHistory(req) - - def get_subaccount_order_summary(self, subaccount_id: str, **kwargs): - req = exchange_accounts_rpc_pb.SubaccountOrderSummaryRequest( - subaccount_id=subaccount_id, - order_direction=kwargs.get("order_direction"), - market_id=kwargs.get("market_id"), - ) - return self.stubExchangeAccount.SubaccountOrderSummary(req) - - def get_order_states(self, **kwargs): - req = exchange_accounts_rpc_pb.OrderStatesRequest( - spot_order_hashes=kwargs.get("spot_order_hashes"), - derivative_order_hashes=kwargs.get("derivative_order_hashes"), - ) - return self.stubExchangeAccount.OrderStates(req) - - def get_portfolio(self, account_address: str): - req = exchange_accounts_rpc_pb.PortfolioRequest(account_address=account_address) - return self.stubExchangeAccount.Portfolio(req) - - def get_rewards(self, **kwargs): - req = exchange_accounts_rpc_pb.RewardsRequest( - account_address=kwargs.get("account_address"), epoch=kwargs.get("epoch") - ) - return self.stubExchangeAccount.Rewards(req) - - # OracleRPC - - def stream_oracle_prices( - self, base_symbol: str, quote_symbol: str, oracle_type: str - ): - req = oracle_rpc_pb.StreamPricesRequest( - base_symbol=base_symbol, quote_symbol=quote_symbol, oracle_type=oracle_type - ) - return self.stubOracle.StreamPrices(req) - - def get_oracle_prices( - self, - base_symbol: str, - quote_symbol: str, - oracle_type: str, - oracle_scale_factor: int, - ): - req = oracle_rpc_pb.PriceRequest( - base_symbol=base_symbol, - quote_symbol=quote_symbol, - oracle_type=oracle_type, - oracle_scale_factor=oracle_scale_factor, - ) - return self.stubOracle.Price(req) - - def get_oracle_list(self): - req = oracle_rpc_pb.OracleListRequest() - return self.stubOracle.OracleList(req) - - # InsuranceRPC - - def get_insurance_funds(self): - req = insurance_rpc_pb.FundsRequest() - return self.stubInsurance.Funds(req) - - def get_redemptions(self, **kwargs): - req = insurance_rpc_pb.RedemptionsRequest( - redeemer=kwargs.get("redeemer"), - redemption_denom=kwargs.get("redemption_denom"), - status=kwargs.get("status"), - ) - return self.stubInsurance.Redemptions(req) - - # SpotRPC - - def get_spot_market(self, market_id: str): - req = spot_exchange_rpc_pb.MarketRequest(market_id=market_id) - return self.stubSpotExchange.Market(req) - - def get_spot_markets(self, **kwargs): - req = spot_exchange_rpc_pb.MarketsRequest( - market_status=kwargs.get("market_status"), - base_denom=kwargs.get("base_denom"), - quote_denom=kwargs.get("quote_denom"), - ) - return self.stubSpotExchange.Markets(req) - - def stream_spot_markets(self, **kwargs): - req = spot_exchange_rpc_pb.StreamMarketsRequest( - market_ids=kwargs.get("market_ids")) - metadata = self.get_cookie(type="exchange") - res = self.stubSpotExchange.StreamMarkets(req, metadata=metadata) - self.set_cookie(res,type="exchange") - return res.tx_response - - def get_spot_orderbook(self, market_id: str): - req = spot_exchange_rpc_pb.OrderbookRequest(market_id=market_id) - return self.stubSpotExchange.Orderbook(req) - - def get_spot_orderbooks(self, market_ids: List): - req = spot_exchange_rpc_pb.OrderbooksRequest(market_ids=market_ids) - return self.stubSpotExchange.Orderbooks(req) - - def get_spot_orderbook_v2(self, market_id: str): - req = spot_exchange_rpc_pb.OrderbookV2Request(market_id=market_id) - return self.stubSpotExchange.OrderbookV2(req) - - def get_spot_orderbooks_v2(self, market_ids: List): - req = spot_exchange_rpc_pb.OrderbooksV2Request(market_ids=market_ids) - return self.stubSpotExchange.OrderbooksV2(req) - - def get_spot_orders(self, market_id: str, **kwargs): - req = spot_exchange_rpc_pb.OrdersRequest( - market_id=market_id, - order_side=kwargs.get("order_side"), - subaccount_id=kwargs.get("subaccount_id"), - ) - return self.stubSpotExchange.Orders(req) - - def get_spot_trades(self, market_id: str, **kwargs): - req = spot_exchange_rpc_pb.TradesRequest( - market_id=market_id, - execution_side=kwargs.get("execution_side"), - direction=kwargs.get("direction"), - subaccount_id=kwargs.get("subaccount_id"), - skip=kwargs.get("skip"), - limit=kwargs.get("limit"), - ) - return self.stubSpotExchange.Trades(req) - - def stream_spot_orderbook(self, market_id: str): - return self.stream_spot_orderbook_snapshot(market_ids=[market_id]) - - def stream_spot_orderbook_snapshot(self, market_ids: List[str]): - req = spot_exchange_rpc_pb.StreamOrderbookSnapshotRequest(market_ids=market_ids) - metadata = self.get_cookie(type="exchange") - res = self.stubSpotExchange.StreamOrderbookSnapshot(req, metadata=metadata) - self.set_cookie(res, type="exchange") - return res - - def stream_spot_orderbook_update(self, market_ids: List[str]): - req = spot_exchange_rpc_pb.StreamOrderbookUpdateRequest(market_ids=market_ids) - metadata = self.get_cookie(type="exchange") - res = self.stubSpotExchange.StreamOrderbookUpdate(req, metadata=metadata) - self.set_cookie(res, type="exchange") - return res - - def stream_spot_orderbooks(self, market_ids: List): - req = spot_exchange_rpc_pb.StreamOrderbookRequest(market_ids=market_ids) - metadata = self.get_cookie(type="exchange") - res = self.stubSpotExchange.StreamOrderbook(req, metadata=metadata) - self.set_cookie(res,type="exchange") - return res - - def stream_spot_orders(self, market_id: str, **kwargs): - req = spot_exchange_rpc_pb.StreamOrdersRequest( - market_id=market_id, - order_side=kwargs.get("order_side"), - subaccount_id=kwargs.get("subaccount_id"), - ) - metadata = self.get_cookie(type="exchange") - res = self.stubSpotExchange.StreamOrders(req, metadata=metadata) - self.set_cookie(res,type="exchange") - return res - - def stream_spot_trades(self, **kwargs): - req = spot_exchange_rpc_pb.StreamTradesRequest( - market_id=kwargs.get("market_id"), - market_ids=kwargs.get("market_ids"), - execution_side=kwargs.get("execution_side"), - direction=kwargs.get("direction"), - subaccount_id=kwargs.get("subaccount_id"), - subaccount_ids=kwargs.get("subaccount_ids"), - skip=kwargs.get("skip"), - limit=kwargs.get("limit"), - ) - metadata = self.get_cookie(type="exchange") - res = self.stubSpotExchange.StreamTrades(req, metadata=metadata) - self.set_cookie(res,type="exchange") - return res - - def get_spot_subaccount_orders(self, subaccount_id: str, **kwargs): - req = spot_exchange_rpc_pb.SubaccountOrdersListRequest( - subaccount_id=subaccount_id, market_id=kwargs.get("market_id") - ) - return self.stubSpotExchange.SubaccountOrdersList(req) - - def get_spot_subaccount_trades(self, subaccount_id: str, **kwargs): - req = spot_exchange_rpc_pb.SubaccountTradesListRequest( - subaccount_id=subaccount_id, - market_id=kwargs.get("market_id"), - execution_type=kwargs.get("execution_type"), - direction=kwargs.get("direction"), - ) - return self.stubSpotExchange.SubaccountTradesList(req) - - # DerivativeRPC - - def get_derivative_market(self, market_id: str): - req = derivative_exchange_rpc_pb.MarketRequest(market_id=market_id) - return self.stubDerivativeExchange.Market(req) - - def get_derivative_markets(self, **kwargs): - req = derivative_exchange_rpc_pb.MarketsRequest( - market_status=kwargs.get("market_status"), - quote_denom=kwargs.get("quote_denom"), - ) - return self.stubDerivativeExchange.Markets(req) - - def stream_derivative_markets(self, **kwargs): - req = derivative_exchange_rpc_pb.StreamMarketRequest( - market_ids=kwargs.get("market_ids")) - metadata = self.get_cookie(type="exchange") - res = self.stubDerivativeExchange.StreamMarket(req, metadata=metadata) - self.set_cookie(res,type="exchange") - return res - - def get_derivative_orderbook(self, market_id: str): - req = derivative_exchange_rpc_pb.OrderbookRequest(market_id=market_id) - return self.stubDerivativeExchange.Orderbook(req) - - def get_derivative_orderbooks(self, market_ids: List): - req = derivative_exchange_rpc_pb.OrderbooksRequest(market_ids=market_ids) - return self.stubDerivativeExchange.Orderbooks(req) - - def get_derivative_orderbook_v2(self, market_id: str): - req = derivative_exchange_rpc_pb.OrderbookV2Request(market_id=market_id) - return self.stubDerivativeExchange.OrderbookV2(req) - - def get_derivative_orderbooks_v2(self, market_ids: List): - req = derivative_exchange_rpc_pb.OrderbooksV2Request(market_ids=market_ids) - return self.stubDerivativeExchange.OrderbooksV2(req) - - def get_derivative_orders(self, market_id: str, **kwargs): - req = derivative_exchange_rpc_pb.OrdersRequest( - market_id=market_id, - order_side=kwargs.get("order_side"), - subaccount_id=kwargs.get("subaccount_id"), - ) - return self.stubDerivativeExchange.Orders(req) - - def get_derivative_trades(self, market_id: str, **kwargs): - req = derivative_exchange_rpc_pb.TradesRequest( - market_id=market_id, - subaccount_id=kwargs.get("subaccount_id"), - execution_side=kwargs.get("execution_side"), - direction=kwargs.get("direction"), - skip=kwargs.get("skip"), - limit=kwargs.get("limit"), - ) - return self.stubDerivativeExchange.Trades(req) - - # deprecated: use stream_derivative_orderbook_snapshot - def stream_derivative_orderbook(self, market_id: str): - return self.stream_derivative_orderbook_snapshot(market_ids=[market_id]) - - def stream_derivative_orderbook_snapshot(self, market_ids: List[str]): - req = derivative_exchange_rpc_pb.StreamOrderbookSnapshotRequest(market_ids=market_ids) - metadata = self.get_cookie(type="exchange") - res = self.stubDerivativeExchange.StreamOrderbookSnapshot(req, metadata=metadata) - self.set_cookie(res, type="exchange") - return res - - def stream_derivative_orderbook_update(self, market_ids: List[str]): - req = derivative_exchange_rpc_pb.StreamOrderbookUpdateRequest(market_ids=market_ids) - metadata = self.get_cookie(type="exchange") - res = self.stubDerivativeExchange.StreamOrderbookUpdate(req, metadata=metadata) - self.set_cookie(res, type="exchange") - return res - - def stream_derivative_orderbooks(self, market_ids: List): - req = derivative_exchange_rpc_pb.StreamOrderbookRequest(market_ids=market_ids) - metadata = self.get_cookie(type="exchange") - res = self.stubDerivativeExchange.StreamOrderbook(req, metadata=metadata) - self.set_cookie(res,type="exchange") - return res - - def stream_derivative_orders(self, market_id: str, **kwargs): - req = derivative_exchange_rpc_pb.StreamOrdersRequest( - market_id=market_id, - order_side=kwargs.get("order_side"), - subaccount_id=kwargs.get("subaccount_id"), - ) - metadata = self.get_cookie(type="exchange") - res = self.stubDerivativeExchange.StreamOrders(req, metadata=metadata) - self.set_cookie(res,type="exchange") - return res - - def stream_derivative_trades(self, **kwargs): - req = derivative_exchange_rpc_pb.StreamTradesRequest( - market_id=kwargs.get("market_id"), - market_ids=kwargs.get("market_ids"), - subaccount_id=kwargs.get("subaccount_id"), - subaccount_ids=kwargs.get("subaccount_ids"), - execution_side=kwargs.get("execution_side"), - direction=kwargs.get("direction"), - skip=kwargs.get("skip"), - limit=kwargs.get("limit"), - ) - metadata = self.get_cookie(type="exchange") - res = self.stubDerivativeExchange.StreamTrades(req, metadata=metadata) - self.set_cookie(res,type="exchange") - return res - - def get_derivative_positions(self, market_id: str, **kwargs): - req = derivative_exchange_rpc_pb.PositionsRequest( - market_id=market_id, subaccount_id=kwargs.get("subaccount_id") - ) - return self.stubDerivativeExchange.Positions(req) - - def stream_derivative_positions(self, **kwargs): - req = derivative_exchange_rpc_pb.StreamPositionsRequest( - market_id=kwargs.get("market_id"), - market_ids=kwargs.get("market_ids"), - subaccount_id=kwargs.get("subaccount_id"), - subaccount_ids=kwargs.get("subaccount_ids") - ) - metadata = self.get_cookie(type="exchange") - res = self.stubDerivativeExchange.StreamPositions(req, metadata=metadata) - self.set_cookie(res,type="exchange") - return res - - def get_derivative_liquidable_positions(self, **kwargs): - req = derivative_exchange_rpc_pb.LiquidablePositionsRequest( - market_id=kwargs.get("market_id") - ) - return self.stubDerivativeExchange.LiquidablePositions(req) - - def get_derivative_subaccount_orders(self, subaccount_id: str, **kwargs): - req = derivative_exchange_rpc_pb.SubaccountOrdersListRequest( - subaccount_id=subaccount_id, market_id=kwargs.get("market_id") - ) - return self.stubDerivativeExchange.SubaccountOrdersList(req) - - def get_derivative_subaccount_trades(self, subaccount_id: str, **kwargs): - req = derivative_exchange_rpc_pb.SubaccountTradesListRequest( - subaccount_id=subaccount_id, - market_id=kwargs.get("market_id"), - execution_type=kwargs.get("execution_type"), - direction=kwargs.get("direction"), - ) - return self.stubDerivativeExchange.SubaccountTradesList(req) - - def get_funding_payments(self, subaccount_id: str, **kwargs): - req = derivative_exchange_rpc_pb.FundingPaymentsRequest( - subaccount_id=subaccount_id, - market_id=kwargs.get("market_id"), - skip=kwargs.get("skip"), - limit=kwargs.get("limit"), - ) - return self.stubDerivativeExchange.FundingPayments(req) - - def get_funding_rates(self, market_id: str, **kwargs): - req = derivative_exchange_rpc_pb.FundingRatesRequest( - market_id=market_id, - skip=kwargs.get("skip"), - limit=kwargs.get("limit"), - ) - return self.stubDerivativeExchange.FundingRates(req) diff --git a/pyinjective/composer.py b/pyinjective/composer.py index e8fd274c..41140aea 100644 --- a/pyinjective/composer.py +++ b/pyinjective/composer.py @@ -1,9 +1,12 @@ -from time import time import json -import logging +from configparser import ConfigParser +from decimal import Decimal +from time import time from google.protobuf import any_pb2, timestamp_pb2, json_format +from .core.market import BinaryOptionMarket, DerivativeMarket, SpotMarket +from .core.token import Token from .proto.cosmos.authz.v1beta1 import authz_pb2 as cosmos_authz_pb from .proto.cosmos.authz.v1beta1 import tx_pb2 as cosmos_authz_tx_pb @@ -32,16 +35,51 @@ from .proto.cosmwasm.wasm.v1 import tx_pb2 as wasm_tx_pb -from .constant import Denom -from .utils.utils import * -from typing import List +from .constant import ADDITIONAL_CHAIN_FORMAT_DECIMALS, INJ_DENOM +from typing import Dict, List, Optional -from pyinjective.utils.logger import LoggerProvider +from pyinjective import constant class Composer: - def __init__(self, network: str): + def __init__( + self, + network: str, + spot_markets: Optional[Dict[str, SpotMarket]] = None, + derivative_markets: Optional[Dict[str, DerivativeMarket]] = None, + binary_option_markets: Optional[Dict[str, BinaryOptionMarket]] = None, + tokens: Optional[Dict[str, Token]] = None): + """ Composer is used to create the requests to send to the nodes using the Client + + :param network: the name of the network to use (mainnet, testnet, devnet) + :type network: str + + :param spot_markets: a dictionary containing all spot markets + :type spot_markets: Dictionary + + :param derivative_markets: a dictionary containing all derivative markets + :type derivative_markets: Dictionary + + :param binary_option_markets: a dictionary containing all derivative markets + :type binary_option_markets: Dictionary + + :param tokens: a dictionary with all the possible tokens + :type tokens: Dictionary + + + """ self.network = network + self.spot_markets = dict() + self.derivative_markets = dict() + self.binary_option_markets = dict() + self.tokens = dict() + if spot_markets is None or derivative_markets is None or binary_option_markets is None or tokens is None: + self._initialize_markets_and_tokens_from_files() + else: + self.spot_markets = spot_markets + self.derivative_markets = derivative_markets + self.binary_option_markets = binary_option_markets + self.tokens = tokens def Coin(self, amount: int, denom: str): return cosmos_dot_base_dot_v1beta1_dot_coin__pb2.Coin(amount=str(amount), denom=denom) @@ -91,15 +129,12 @@ def SpotOrder( quantity: float, **kwargs, ): - # load denom metadata - denom = Denom.load_market(self.network, market_id) - LoggerProvider().logger_for_class(logging_class=self.__class__).info( - f"Loaded market metadata for: {denom.description}") + market = self.spot_markets[market_id] # prepare values - quantity = spot_quantity_to_backend(quantity, denom) - price = spot_price_to_backend(price, denom) - trigger_price = spot_price_to_backend(0, denom) + quantity = market.quantity_to_chain_format(human_readable_value=Decimal(str(quantity))) + price = market.price_to_chain_format(human_readable_value=Decimal(str(price))) + trigger_price = market.price_to_chain_format(human_readable_value=Decimal(0)) if kwargs.get("is_buy") and not kwargs.get("is_po"): order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.BUY @@ -118,11 +153,11 @@ def SpotOrder( order_info=injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderInfo( subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=str(price), - quantity=str(quantity), + price=str(int(price)), + quantity=str(int(quantity)), ), order_type=order_type, - trigger_price=str(trigger_price), + trigger_price=str(int(trigger_price)), ) def DerivativeOrder( @@ -135,26 +170,21 @@ def DerivativeOrder( trigger_price: float = 0, **kwargs, ): - # load denom metadata - denom = Denom.load_market(self.network, market_id) - LoggerProvider().logger_for_class(logging_class=self.__class__).info( - f"Loaded market metadata for: {denom.description}") - - if kwargs.get("is_reduce_only") is None: - margin = derivative_margin_to_backend( - price, quantity, kwargs.get("leverage"), denom - ) - elif kwargs.get("is_reduce_only", True): + market = self.derivative_markets[market_id] + + if kwargs.get("is_reduce_only", False): margin = 0 else: - margin = derivative_margin_to_backend( - price, quantity, kwargs.get("leverage"), denom + margin = market.calculate_margin_in_chain_format( + human_readable_quantity=Decimal(str(quantity)), + human_readable_price=Decimal(str(price)), + leverage=Decimal(str(kwargs["leverage"])), ) # prepare values - price = derivative_price_to_backend(price, denom) - trigger_price = derivative_price_to_backend(trigger_price, denom) - quantity = derivative_quantity_to_backend(quantity, denom) + quantity = market.quantity_to_chain_format(human_readable_value=Decimal(str(quantity))) + price = market.price_to_chain_format(human_readable_value=Decimal(str(price))) + trigger_price = market.price_to_chain_format(human_readable_value=Decimal(str(trigger_price))) if kwargs.get("is_buy") and not kwargs.get("is_po"): order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.BUY @@ -185,12 +215,12 @@ def DerivativeOrder( order_info=injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderInfo( subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=str(price), - quantity=str(quantity), + price=str(int(price)), + quantity=str(int(quantity)), ), - margin=str(margin), + margin=str(int(margin)), order_type=order_type, - trigger_price=str(trigger_price), + trigger_price=str(int(trigger_price)), ) def BinaryOptionsOrder( @@ -203,30 +233,23 @@ def BinaryOptionsOrder( **kwargs, ): - if "denom" in kwargs: - denom = kwargs.get("denom") - else: - denom = Denom.load_market(self.network, market_id) - - # load denom metadata - LoggerProvider().logger_for_class(logging_class=self.__class__).info( - f"Loaded market metadata for: {denom.description}") - - if kwargs.get("is_reduce_only") is None and kwargs.get("is_buy"): - margin = binary_options_buy_margin_to_backend(price, quantity, denom) - elif kwargs.get("is_reduce_only") is None and not kwargs.get("is_buy"): - margin = binary_options_sell_margin_to_backend(price, quantity, denom) - elif kwargs.get("is_reduce_only") is False and kwargs.get("is_buy"): - margin = binary_options_buy_margin_to_backend(price, quantity, denom) - elif kwargs.get("is_reduce_only") is False and not kwargs.get("is_buy"): - margin = binary_options_sell_margin_to_backend(price, quantity, denom) - elif kwargs.get("is_reduce_only", True): + market = self.binary_option_markets[market_id] + denom = kwargs.get("denom", None) + + if kwargs.get("is_reduce_only", False): margin = 0 + else: + margin = market.calculate_margin_in_chain_format( + human_readable_quantity=Decimal(str(quantity)), + human_readable_price=Decimal(str(price)), + is_buy=kwargs["is_buy"], + special_denom=denom, + ) # prepare values - price = binary_options_price_to_backend(price, denom) - trigger_price = binary_options_price_to_backend(0, denom) - quantity = binary_options_quantity_to_backend(quantity, denom) + price = market.price_to_chain_format(human_readable_value=Decimal(str(price)), special_denom=denom) + trigger_price = market.price_to_chain_format(human_readable_value=Decimal(str(0)), special_denom=denom) + quantity = market.quantity_to_chain_format(human_readable_value=Decimal(str(quantity)), special_denom=denom) if kwargs.get("is_buy") and not kwargs.get("is_po"): order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.BUY @@ -245,25 +268,22 @@ def BinaryOptionsOrder( order_info=injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderInfo( subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=str(price), - quantity=str(quantity), + price=str(int(price)), + quantity=str(int(quantity)), ), - margin=str(margin), + margin=str(int(margin)), order_type=order_type, - trigger_price=str(trigger_price), + trigger_price=str(int(trigger_price)), ) def MsgSend(self, from_address: str, to_address: str, amount: float, denom: str): - peggy_denom, decimals = Denom.load_peggy_denom(self.network, denom) - be_amount = amount_to_backend(amount, decimals) - LoggerProvider().logger_for_class(logging_class=self.__class__).info( - f"Loaded send symbol {denom} ({peggy_denom}) with decimals = {decimals}" - ) + token = self.tokens[denom] + be_amount = token.chain_formatted_value(human_readable_value=Decimal(str(amount))) return cosmos_bank_tx_pb.MsgSend( from_address=from_address, to_address=to_address, - amount=[self.Coin(amount=be_amount, denom=peggy_denom)], + amount=[self.Coin(amount=int(be_amount), denom=token.denom)], ) def MsgExecuteContract(self, sender: str, contract: str, msg: str, **kwargs): @@ -275,16 +295,13 @@ def MsgExecuteContract(self, sender: str, contract: str, msg: str, **kwargs): ) def MsgDeposit(self, sender: str, subaccount_id: str, amount: float, denom: str): - peggy_denom, decimals = Denom.load_peggy_denom(self.network, denom) - be_amount = amount_to_backend(amount, decimals) - LoggerProvider().logger_for_class(logging_class=self.__class__).info( - f"Loaded deposit symbol {denom} ({peggy_denom}) with decimals = {decimals}" - ) + token = self.tokens[denom] + be_amount = token.chain_formatted_value(human_readable_value=Decimal(str(amount))) return injective_exchange_tx_pb.MsgDeposit( sender=sender, subaccount_id=subaccount_id, - amount=self.Coin(amount=be_amount, denom=peggy_denom), + amount=self.Coin(amount=int(be_amount), denom=token.denom), ) def MsgCreateSpotLimitOrder( @@ -607,14 +624,15 @@ def MsgIncreasePositionMargin( market_id: str, amount: float, ): - denom = Denom.load_market(self.network, market_id) - additional_margin = derivative_additional_margin_to_backend(amount, denom) + market = self.derivative_markets[market_id] + + additional_margin = market.margin_to_chain_format(human_readable_value=Decimal(str(amount))) return injective_exchange_tx_pb.MsgIncreasePositionMargin( sender=sender, source_subaccount_id=source_subaccount_id, destination_subaccount_id=destination_subaccount_id, market_id=market_id, - amount=str(additional_margin), + amount=str(int(additional_margin)), ) def MsgSubaccountTransfer( @@ -635,16 +653,13 @@ def MsgSubaccountTransfer( ) def MsgWithdraw(self, sender: str, subaccount_id: str, amount: float, denom: str): - peggy_denom, decimals = Denom.load_peggy_denom(self.network, denom) - be_amount = amount_to_backend(amount, decimals) - LoggerProvider().logger_for_class(logging_class=self.__class__).info( - f"Loaded withdrawal symbol {denom} ({peggy_denom}) with decimals = {decimals}" - ) + token = self.tokens[denom] + be_amount = token.chain_formatted_value(human_readable_value=Decimal(str(amount))) return injective_exchange_tx_pb.MsgWithdraw( sender=sender, subaccount_id=subaccount_id, - amount=self.Coin(amount=be_amount, denom=peggy_denom), + amount=self.Coin(amount=int(be_amount), denom=token.denom), ) def MsgExternalTransfer( @@ -655,27 +670,24 @@ def MsgExternalTransfer( amount: int, denom: str, ): - peggy_denom, decimals = Denom.load_peggy_denom(self.network, denom) - be_amount = amount_to_backend(amount, decimals) - LoggerProvider().logger_for_class(logging_class=self.__class__).info( - f"Loaded send symbol {denom} ({peggy_denom}) with decimals = {decimals}" - ) + token = self.tokens[denom] + be_amount = token.chain_formatted_value(human_readable_value=Decimal(str(amount))) return injective_exchange_tx_pb.MsgExternalTransfer( sender=sender, source_subaccount_id=source_subaccount_id, destination_subaccount_id=destination_subaccount_id, - amount=self.Coin(amount=be_amount, denom=peggy_denom), + amount=self.Coin(amount=int(be_amount), denom=token.denom), ) def MsgBid(self, sender: str, bid_amount: float, round: float): - be_amount = amount_to_backend(bid_amount, 18) + be_amount = Decimal(str(bid_amount)) * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") return injective_auction_tx_pb.MsgBid( sender=sender, round=round, - bid_amount=self.Coin(amount=be_amount, denom="inj"), + bid_amount=self.Coin(amount=int(be_amount), denom=INJ_DENOM), ) def MsgGrantGeneric( @@ -788,31 +800,27 @@ def MsgRelayPriceFeedPrice( def MsgSendToEth( self, denom: str, sender: str, eth_dest: str, amount: float, bridge_fee: float ): - - peggy_denom, decimals = Denom.load_peggy_denom(self.network, denom) - be_amount = amount_to_backend(amount, decimals) - be_bridge_fee = amount_to_backend(bridge_fee, decimals) - LoggerProvider().logger_for_class(logging_class=self.__class__).info( - f"Loaded withdrawal symbol {denom} ({peggy_denom}) with decimals = {decimals}" - ) + token = self.tokens[denom] + be_amount = token.chain_formatted_value(human_readable_value=Decimal(str(amount))) + be_bridge_fee = token.chain_formatted_value(human_readable_value=Decimal(str(bridge_fee))) return injective_peggy_tx_pb.MsgSendToEth( sender=sender, eth_dest=eth_dest, - amount=self.Coin(amount=be_amount, denom=peggy_denom), - bridge_fee=self.Coin(amount=be_bridge_fee, denom=peggy_denom), + amount=self.Coin(amount=int(be_amount), denom=token.denom), + bridge_fee=self.Coin(amount=int(be_bridge_fee), denom=token.denom), ) def MsgDelegate( self, delegator_address: str, validator_address: str, amount: float ): - be_amount = amount_to_backend(amount, 18) + be_amount = Decimal(str(amount)) * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") return cosmos_staking_tx_pb.MsgDelegate( delegator_address=delegator_address, validator_address=validator_address, - amount=self.Coin(amount=be_amount, denom="inj"), + amount=self.Coin(amount=int(be_amount), denom=INJ_DENOM), ) def MsgCreateInsuranceFund( @@ -826,15 +834,18 @@ def MsgCreateInsuranceFund( expiry: int, initial_deposit: int ): - peggy_denom, decimals = Denom.load_peggy_denom(self.network, quote_denom) - be_amount = amount_to_backend(initial_deposit, decimals) - LoggerProvider().logger_for_class(logging_class=self.__class__).info( - f"Loaded send symbol {quote_denom} ({peggy_denom}) with decimals = {decimals}" - ) + token = self.tokens[quote_denom] + be_amount = token.chain_formatted_value(human_readable_value=Decimal(str(initial_deposit))) return injective_insurance_tx_pb.MsgCreateInsuranceFund( - sender=sender, ticker=ticker, quote_denom=peggy_denom, oracle_base=oracle_base, oracle_quote=oracle_quote, - oracle_type=oracle_type, expiry=expiry, initial_deposit=self.Coin(amount=be_amount, denom=peggy_denom), + sender=sender, + ticker=ticker, + quote_denom=token.denom, + oracle_base=oracle_base, + oracle_quote=oracle_quote, + oracle_type=oracle_type, + expiry=expiry, + initial_deposit=self.Coin(amount=int(be_amount), denom=token.denom), ) def MsgUnderwrite( @@ -844,14 +855,11 @@ def MsgUnderwrite( quote_denom: str, amount: int, ): - peggy_denom, decimals = Denom.load_peggy_denom(self.network, quote_denom) - be_amount = amount_to_backend(amount, decimals) - LoggerProvider().logger_for_class(logging_class=self.__class__).info( - f"Loaded send symbol {quote_denom} ({peggy_denom}) with decimals = {decimals}" - ) + token = self.tokens[quote_denom] + be_amount = token.chain_formatted_value(human_readable_value=Decimal(str(amount))) return injective_insurance_tx_pb.MsgUnderwrite( - sender=sender, market_id=market_id, deposit=self.Coin(amount=be_amount, denom=peggy_denom), + sender=sender, market_id=market_id, deposit=self.Coin(amount=int(be_amount), denom=token.denom), ) def MsgRequestRedemption( @@ -874,6 +882,14 @@ def MsgWithdrawDelegatorReward( delegator_address=delegator_address, validator_address=validator_address ) + def MsgWithdrawValidatorCommission( + self, validator_address: str + ): + + return cosmos_distribution_tx_pb.MsgWithdrawValidatorCommission( + validator_address=validator_address + ) + def MsgVote( self, proposal_id: str, @@ -964,14 +980,14 @@ def UnpackTransactionMessages(transaction): meta_messages = json.loads(transaction.messages.decode()) header_map = { - "/injective.exchange.v1beta1.MsgCreateSpotLimitOrder": injective_exchange_tx_pb.MsgCreateSpotLimitOrderResponse, - "/injective.exchange.v1beta1.MsgCreateSpotMarketOrder": injective_exchange_tx_pb.MsgCreateSpotMarketOrderResponse, - "/injective.exchange.v1beta1.MsgCreateDerivativeLimitOrder": injective_exchange_tx_pb.MsgCreateDerivativeLimitOrderResponse, - "/injective.exchange.v1beta1.MsgCreateDerivativeMarketOrder": injective_exchange_tx_pb.MsgCreateDerivativeMarketOrderResponse, - "/injective.exchange.v1beta1.MsgCancelSpotOrder": injective_exchange_tx_pb.MsgCancelSpotOrderResponse, - "/injective.exchange.v1beta1.MsgCancelDerivativeOrder": injective_exchange_tx_pb.MsgCancelDerivativeOrderResponse, - "/injective.exchange.v1beta1.MsgBatchCancelSpotOrders": injective_exchange_tx_pb.MsgBatchCancelSpotOrdersResponse, - "/injective.exchange.v1beta1.MsgBatchCancelDerivativeOrders": injective_exchange_tx_pb.MsgBatchCancelDerivativeOrdersResponse, + "/injective.exchange.v1beta1.MsgCreateSpotLimitOrder": injective_exchange_tx_pb.MsgCreateSpotLimitOrder, + "/injective.exchange.v1beta1.MsgCreateSpotMarketOrder": injective_exchange_tx_pb.MsgCreateSpotMarketOrder, + "/injective.exchange.v1beta1.MsgCreateDerivativeLimitOrder": injective_exchange_tx_pb.MsgCreateDerivativeLimitOrder, + "/injective.exchange.v1beta1.MsgCreateDerivativeMarketOrder": injective_exchange_tx_pb.MsgCreateDerivativeMarketOrder, + "/injective.exchange.v1beta1.MsgCancelSpotOrder": injective_exchange_tx_pb.MsgCancelSpotOrder, + "/injective.exchange.v1beta1.MsgCancelDerivativeOrder": injective_exchange_tx_pb.MsgCancelDerivativeOrder, + "/injective.exchange.v1beta1.MsgBatchCancelSpotOrders": injective_exchange_tx_pb.MsgBatchCancelSpotOrders, + "/injective.exchange.v1beta1.MsgBatchCancelDerivativeOrders": injective_exchange_tx_pb.MsgBatchCancelDerivativeOrders, "/injective.exchange.v1beta1.MsgBatchCreateSpotLimitOrders": injective_exchange_tx_pb.MsgBatchCreateSpotLimitOrders, "/injective.exchange.v1beta1.MsgBatchCreateDerivativeLimitOrders": injective_exchange_tx_pb.MsgBatchCreateDerivativeLimitOrders, "/injective.exchange.v1beta1.MsgBatchUpdateOrders": injective_exchange_tx_pb.MsgBatchUpdateOrders, @@ -1000,3 +1016,169 @@ def UnpackTransactionMessages(transaction): msgs.append(json_format.Parse(msg_as_string_dict, header_map[msg["type"]]())) return msgs + + def _initialize_markets_and_tokens_from_files(self): + config: ConfigParser = constant.CONFIGS[self.network] + spot_markets = dict() + derivative_markets = dict() + tokens = dict() + + for section_name, configuration_section in config.items(): + if section_name.startswith("0x"): + description = configuration_section["description"] + + quote_token = Token( + name="", + symbol="", + denom="", + address="", + decimals=int(configuration_section["quote"]), + logo="", + updated=-1, + ) + + if "Spot" in description: + base_token = Token( + name="", + symbol="", + denom="", + address="", + decimals=int(configuration_section["base"]), + logo="", + updated=-1, + ) + + market = SpotMarket( + id=section_name, + status="", + ticker=description, + base_token=base_token, + quote_token=quote_token, + maker_fee_rate=None, + taker_fee_rate=None, + service_provider_fee=None, + min_price_tick_size=Decimal(str(configuration_section["min_price_tick_size"])), + min_quantity_tick_size=Decimal(str(configuration_section["min_quantity_tick_size"])) + ) + spot_markets[market.id] = market + else: + market = DerivativeMarket( + id=section_name, + status="", + ticker=description, + oracle_base="", + oracle_quote="", + oracle_type="", + oracle_scale_factor=1, + initial_margin_ratio=None, + maintenance_margin_ratio=None, + quote_token=quote_token, + maker_fee_rate=None, + taker_fee_rate=None, + service_provider_fee=None, + min_price_tick_size=Decimal(str(configuration_section["min_price_tick_size"])), + min_quantity_tick_size=Decimal(str(configuration_section["min_quantity_tick_size"])), + ) + + derivative_markets[market.id] = market + + elif section_name != "DEFAULT": + token = Token( + name=section_name, + symbol=section_name, + denom=configuration_section["peggy_denom"], + address="", + decimals=int(configuration_section["decimals"]), + logo="", + updated=-1, + ) + + tokens[token.symbol] = token + + self.tokens = tokens + self.spot_markets = spot_markets + self.derivative_markets = derivative_markets + self.binary_option_markets = dict() + + def _initialize_markets_and_tokens_from_files(self): + config: ConfigParser = constant.CONFIGS[self.network] + spot_markets = dict() + derivative_markets = dict() + tokens = dict() + + for section_name, configuration_section in config.items(): + if section_name.startswith("0x"): + description = configuration_section["description"] + + quote_token = Token( + name="", + symbol="", + denom="", + address="", + decimals=int(configuration_section["quote"]), + logo="", + updated=-1, + ) + + if "Spot" in description: + base_token = Token( + name="", + symbol="", + denom="", + address="", + decimals=int(configuration_section["base"]), + logo="", + updated=-1, + ) + + market = SpotMarket( + id=section_name, + status="", + ticker=description, + base_token=base_token, + quote_token=quote_token, + maker_fee_rate=None, + taker_fee_rate=None, + service_provider_fee=None, + min_price_tick_size=Decimal(str(configuration_section["min_price_tick_size"])), + min_quantity_tick_size=Decimal(str(configuration_section["min_quantity_tick_size"])) + ) + spot_markets[market.id] = market + else: + market = DerivativeMarket( + id=section_name, + status="", + ticker=description, + oracle_base="", + oracle_quote="", + oracle_type="", + oracle_scale_factor=1, + initial_margin_ratio=None, + maintenance_margin_ratio=None, + quote_token=quote_token, + maker_fee_rate=None, + taker_fee_rate=None, + service_provider_fee=None, + min_price_tick_size=Decimal(str(configuration_section["min_price_tick_size"])), + min_quantity_tick_size=Decimal(str(configuration_section["min_quantity_tick_size"])), + ) + + derivative_markets[market.id] = market + + elif section_name != "DEFAULT": + token = Token( + name=section_name, + symbol=section_name, + denom=configuration_section["peggy_denom"], + address="", + decimals=int(configuration_section["decimals"]), + logo="", + updated=-1, + ) + + tokens[token.symbol] = token + + self.tokens = tokens + self.spot_markets = spot_markets + self.derivative_markets = derivative_markets + self.binary_option_markets = dict() diff --git a/pyinjective/constant.py b/pyinjective/constant.py index 57001ee3..49aaef3d 100644 --- a/pyinjective/constant.py +++ b/pyinjective/constant.py @@ -1,9 +1,13 @@ import os from configparser import ConfigParser +from warnings import warn MAX_CLIENT_ID_LENGTH = 128 MAX_DATA_SIZE = 256 MAX_MEMO_CHARACTERS = 256 +ADDITIONAL_CHAIN_FORMAT_DECIMALS = 18 +TICKER_TOKENS_SEPARATOR = "/" +INJ_DENOM = "inj" devnet_config = ConfigParser() devnet_config.read(os.path.join(os.path.dirname(__file__), "denoms_devnet.ini")) @@ -14,6 +18,13 @@ mainnet_config = ConfigParser() mainnet_config.read(os.path.join(os.path.dirname(__file__), "denoms_mainnet.ini")) +CONFIGS = { + "devnet": devnet_config, + "testnet": testnet_config, + "mainnet": mainnet_config, +} + + class Denom: def __init__( self, @@ -23,6 +34,7 @@ def __init__( min_price_tick_size: float, min_quantity_tick_size: float ): + self.description = description self.base = base self.quote = quote @@ -57,135 +69,3 @@ def load_peggy_denom(cls, network, symbol): else: config = mainnet_config return config[symbol]["peggy_denom"], int(config[symbol]["decimals"]) - - -class Network: - def __init__( - self, - lcd_endpoint: str , - tm_websocket_endpoint: str, - grpc_endpoint: str , - grpc_exchange_endpoint: str , - grpc_explorer_endpoint: str , - chain_id: str , - fee_denom: str , - env: str - ): - self.lcd_endpoint = lcd_endpoint - self.tm_websocket_endpoint = tm_websocket_endpoint - self.grpc_endpoint = grpc_endpoint - self.grpc_exchange_endpoint = grpc_exchange_endpoint - self.grpc_explorer_endpoint = grpc_explorer_endpoint - self.chain_id = chain_id - self.fee_denom = fee_denom - self.env = env - - @classmethod - def devnet(cls): - return cls( - lcd_endpoint="https://devnet.lcd.injective.dev", - tm_websocket_endpoint="wss://devnet.tm.injective.dev/websocket", - grpc_endpoint="devnet.injective.dev:9900", - grpc_exchange_endpoint="devnet.injective.dev:9910", - grpc_explorer_endpoint="devnet.injective.dev:9911", - chain_id="injective-777", - fee_denom="inj", - env="devnet" - ) - - @classmethod - def testnet(cls, node="lb"): - nodes = [ - "lb", - "sentry", - ] - if node not in nodes: - raise ValueError("Must be one of {}".format(nodes)) - - if node == "lb": - lcd_endpoint = "https://k8s.testnet.lcd.injective.network" - tm_websocket_endpoint = "wss://k8s.testnet.tm.injective.network/websocket" - grpc_endpoint = "k8s.testnet.chain.grpc.injective.network:443" - grpc_exchange_endpoint = "k8s.testnet.exchange.grpc.injective.network:443" - grpc_explorer_endpoint = "k8s.testnet.explorer.grpc.injective.network:443" - else: - lcd_endpoint = "https://testnet.lcd.injective.network" - tm_websocket_endpoint = "wss://testnet.tm.injective.network/websocket" - grpc_endpoint = "testnet.chain.grpc.injective.network" - grpc_exchange_endpoint = "testnet.exchange.grpc.injective.network" - grpc_explorer_endpoint = "testnet.explorer.grpc.injective.network" - - return cls( - lcd_endpoint=lcd_endpoint, - tm_websocket_endpoint=tm_websocket_endpoint, - grpc_endpoint=grpc_endpoint, - grpc_exchange_endpoint=grpc_exchange_endpoint, - grpc_explorer_endpoint=grpc_explorer_endpoint, - chain_id="injective-888", - fee_denom="inj", - env="testnet" - ) - - @classmethod - def mainnet(cls, node="lb"): - nodes = [ - "lb", # us, asia, prod - "sentry0", # ca, prod - "sentry1", # ca, prod - "sentry3", # us, prod - ] - if node not in nodes: - raise ValueError("Must be one of {}".format(nodes)) - - if node == "lb": - lcd_endpoint = "https://k8s.global.mainnet.lcd.injective.network:443" - tm_websocket_endpoint = "wss://k8s.global.mainnet.tm.injective.network:443/websocket" - grpc_endpoint = "k8s.global.mainnet.chain.grpc.injective.network:443" - grpc_exchange_endpoint = "k8s.global.mainnet.exchange.grpc.injective.network:443" - grpc_explorer_endpoint = "k8s.global.mainnet.explorer.grpc.injective.network:443" - else: - lcd_endpoint = f"http://{node}.injective.network:10337" - tm_websocket_endpoint = f"ws://{node}.injective.network:26657/websocket" - grpc_endpoint = f"{node}.injective.network:9900" - grpc_exchange_endpoint = f"{node}.injective.network:9910" - grpc_explorer_endpoint = f"{node}.injective.network:9911" - - return cls( - lcd_endpoint=lcd_endpoint, - tm_websocket_endpoint=tm_websocket_endpoint, - grpc_endpoint=grpc_endpoint, - grpc_exchange_endpoint=grpc_exchange_endpoint, - grpc_explorer_endpoint=grpc_explorer_endpoint, - chain_id="injective-1", - fee_denom="inj", - env="mainnet" - ) - - @classmethod - def local(cls): - return cls( - lcd_endpoint="http://localhost:10337", - tm_websocket_endpoint="ws://localhost:26657/websocket", - grpc_endpoint="localhost:9900", - grpc_exchange_endpoint="localhost:9910", - grpc_explorer_endpoint="localhost:9911", - chain_id="injective-1", - fee_denom="inj", - env="local" - ) - - @classmethod - def custom(cls, lcd_endpoint, tm_websocket_endpoint, grpc_endpoint, grpc_exchange_endpoint, grpc_explorer_endpoint, chain_id, env): - return cls( - lcd_endpoint=lcd_endpoint, - tm_websocket_endpoint=tm_websocket_endpoint, - grpc_endpoint=grpc_endpoint, - grpc_exchange_endpoint=grpc_exchange_endpoint, - grpc_explorer_endpoint=grpc_explorer_endpoint, - chain_id=chain_id, - fee_denom="inj", - env=env - ) - - def string(self): - return self.env diff --git a/pyinjective/core/__init__.py b/pyinjective/core/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pyinjective/core/broadcaster.py b/pyinjective/core/broadcaster.py index cc9dc2bb..7fb54278 100644 --- a/pyinjective/core/broadcaster.py +++ b/pyinjective/core/broadcaster.py @@ -8,7 +8,7 @@ from pyinjective import PrivateKey, Transaction, PublicKey from pyinjective.async_client import AsyncClient from pyinjective.composer import Composer -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.core.gas_limit_estimator import GasLimitEstimator @@ -67,11 +67,10 @@ def new_using_simulation( cls, network: Network, private_key: str, - use_secure_connection: bool = True, client: Optional[AsyncClient] = None, composer: Optional[Composer] = None, ): - client = client or AsyncClient(network=network, insecure=not(use_secure_connection)) + client = client or AsyncClient(network=network) composer = composer or Composer(network=client.network.string()) account_config = StandardAccountBroadcasterConfig(private_key=private_key) fee_calculator = SimulatedTransactionFeeCalculator( @@ -92,11 +91,10 @@ def new_without_simulation( cls, network: Network, private_key: str, - use_secure_connection: bool = True, client: Optional[AsyncClient] = None, composer: Optional[Composer] = None, ): - client = client or AsyncClient(network=network, insecure=not (use_secure_connection)) + client = client or AsyncClient(network=network) composer = composer or Composer(network=client.network.string()) account_config = StandardAccountBroadcasterConfig(private_key=private_key) fee_calculator = MessageBasedTransactionFeeCalculator( @@ -117,11 +115,10 @@ def new_for_grantee_account_using_simulation( cls, network: Network, grantee_private_key: str, - use_secure_connection: bool = True, client: Optional[AsyncClient] = None, composer: Optional[Composer] = None, ): - client = client or AsyncClient(network=network, insecure=not (use_secure_connection)) + client = client or AsyncClient(network=network) composer = composer or Composer(network=client.network.string()) account_config = GranteeAccountBroadcasterConfig(grantee_private_key=grantee_private_key, composer=composer) fee_calculator = SimulatedTransactionFeeCalculator( @@ -142,11 +139,10 @@ def new_for_grantee_account_without_simulation( cls, network: Network, grantee_private_key: str, - use_secure_connection: bool = True, client: Optional[AsyncClient] = None, composer: Optional[Composer] = None, ): - client = client or AsyncClient(network=network, insecure=not (use_secure_connection)) + client = client or AsyncClient(network=network) composer = composer or Composer(network=client.network.string()) account_config = GranteeAccountBroadcasterConfig(grantee_private_key=grantee_private_key, composer=composer) fee_calculator = MessageBasedTransactionFeeCalculator( diff --git a/pyinjective/core/market.py b/pyinjective/core/market.py new file mode 100644 index 00000000..9a42b88c --- /dev/null +++ b/pyinjective/core/market.py @@ -0,0 +1,151 @@ +from dataclasses import dataclass +from decimal import Decimal +from typing import Optional + +from pyinjective.constant import ADDITIONAL_CHAIN_FORMAT_DECIMALS, Denom +from pyinjective.core.token import Token + + +@dataclass(eq=True, frozen=True) +class SpotMarket: + id: str + status: str + ticker: str + base_token: Token + quote_token: Token + maker_fee_rate: Decimal + taker_fee_rate: Decimal + service_provider_fee: Decimal + min_price_tick_size: Decimal + min_quantity_tick_size: Decimal + + def quantity_to_chain_format(self, human_readable_value: Decimal) -> Decimal: + chain_formatted_value = human_readable_value * Decimal(f"1e{self.base_token.decimals}") + quantized_value = chain_formatted_value // self.min_quantity_tick_size * self.min_quantity_tick_size + extended_chain_formatted_value = quantized_value * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + return extended_chain_formatted_value + + def price_to_chain_format(self, human_readable_value: Decimal) -> Decimal: + decimals = self.quote_token.decimals - self.base_token.decimals + chain_formatted_value = human_readable_value * Decimal(f"1e{decimals}") + quantized_value = (chain_formatted_value // self.min_price_tick_size) * self.min_price_tick_size + extended_chain_formatted_value = quantized_value * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + return extended_chain_formatted_value + +@dataclass(eq=True, frozen=True) +class DerivativeMarket: + id: str + status: str + ticker: str + oracle_base: str + oracle_quote: str + oracle_type: str + oracle_scale_factor: int + initial_margin_ratio: Decimal + maintenance_margin_ratio: Decimal + quote_token: Token + maker_fee_rate: Decimal + taker_fee_rate: Decimal + service_provider_fee: Decimal + min_price_tick_size: Decimal + min_quantity_tick_size: Decimal + + def quantity_to_chain_format(self, human_readable_value: Decimal) -> Decimal: + # Derivative markets do not have a base market to provide the number of decimals + chain_formatted_value = human_readable_value + quantized_value = chain_formatted_value // self.min_quantity_tick_size * self.min_quantity_tick_size + extended_chain_formatted_value = quantized_value * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + return extended_chain_formatted_value + + def price_to_chain_format(self, human_readable_value: Decimal) -> Decimal: + decimals = self.quote_token.decimals + chain_formatted_value = human_readable_value * Decimal(f"1e{decimals}") + quantized_value = (chain_formatted_value // self.min_price_tick_size) * self.min_price_tick_size + extended_chain_formatted_value = quantized_value * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + return extended_chain_formatted_value + + def margin_to_chain_format(self, human_readable_value: Decimal) -> Decimal: + decimals = self.quote_token.decimals + chain_formatted_value = human_readable_value * Decimal(f"1e{decimals}") + quantized_value = (chain_formatted_value // self.min_quantity_tick_size) * self.min_quantity_tick_size + extended_chain_formatted_value = quantized_value * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + return extended_chain_formatted_value + + def calculate_margin_in_chain_format( + self, + human_readable_quantity: Decimal, + human_readable_price: Decimal, + leverage: Decimal + ) -> Decimal: + chain_formatted_quantity = human_readable_quantity + chain_formatted_price = human_readable_price * Decimal(f"1e{self.quote_token.decimals}") + margin = (chain_formatted_price * chain_formatted_quantity) / leverage + # We are using the min_quantity_tick_size to quantize the margin because that is the way margin is validated + # in the chain (it might be changed to a min_notional in the future) + quantized_margin = (margin // self.min_quantity_tick_size) * self.min_quantity_tick_size + extended_chain_formatted_margin = quantized_margin * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + return extended_chain_formatted_margin + +@dataclass(eq=True, frozen=True) +class BinaryOptionMarket: + id: str + status: str + ticker: str + oracle_symbol: str + oracle_provider: str + oracle_type: str + oracle_scale_factor: int + expiration_timestamp: int + settlement_timestamp: int + quote_token: Token + maker_fee_rate: Decimal + taker_fee_rate: Decimal + service_provider_fee: Decimal + min_price_tick_size: Decimal + min_quantity_tick_size: Decimal + + def quantity_to_chain_format(self, human_readable_value: Decimal, special_denom: Optional[Denom] = None) -> Decimal: + # Binary option markets do not have a base market to provide the number of decimals + decimals = 0 if special_denom is None else special_denom.base + min_quantity_tick_size = self.min_quantity_tick_size if special_denom is None else special_denom.min_quantity_tick_size + chain_formatted_value = human_readable_value * Decimal(f"1e{decimals}") + quantized_value = chain_formatted_value // min_quantity_tick_size * min_quantity_tick_size + extended_chain_formatted_value = quantized_value * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + return extended_chain_formatted_value + + def price_to_chain_format(self, human_readable_value: Decimal, special_denom: Optional[Denom] = None) -> Decimal: + decimals = self.quote_token.decimals if special_denom is None else special_denom.quote + min_price_tick_size = self.min_price_tick_size if special_denom is None else special_denom.min_price_tick_size + chain_formatted_value = human_readable_value * Decimal(f"1e{decimals}") + quantized_value = (chain_formatted_value // min_price_tick_size) * min_price_tick_size + extended_chain_formatted_value = quantized_value * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + return extended_chain_formatted_value + + def calculate_margin_in_chain_format( + self, + human_readable_quantity: Decimal, + human_readable_price: Decimal, + is_buy: bool, + special_denom: Optional[Denom] = None, + ) -> Decimal: + quantity_decimals = 0 if special_denom is None else special_denom.base + price_decimals = self.quote_token.decimals if special_denom is None else special_denom.quote + min_quantity_tick_size = self.min_quantity_tick_size if special_denom is None else special_denom.min_quantity_tick_size + price = human_readable_price if is_buy else 1 - human_readable_price + chain_formatted_quantity = human_readable_quantity * Decimal(f"1e{quantity_decimals}") + chain_formatted_price = price * Decimal(f"1e{price_decimals}") + margin = (chain_formatted_price * chain_formatted_quantity) + # We are using the min_quantity_tick_size to quantize the margin because that is the way margin is validated + # in the chain (it might be changed to a min_notional in the future) + quantized_margin = (margin // min_quantity_tick_size) * min_quantity_tick_size + extended_chain_formatted_margin = quantized_margin * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + return extended_chain_formatted_margin \ No newline at end of file diff --git a/pyinjective/core/network.py b/pyinjective/core/network.py new file mode 100644 index 00000000..420d0152 --- /dev/null +++ b/pyinjective/core/network.py @@ -0,0 +1,344 @@ +import asyncio +import datetime +import time +from abc import ABC, abstractmethod +from http.cookies import SimpleCookie +from typing import Callable, Optional, Tuple + + +class CookieAssistant(ABC): + SESSION_RENEWAL_OFFSET = 120 + + @abstractmethod + async def chain_cookie(self, metadata_query_provider: Callable) -> str: + ... + + @abstractmethod + async def exchange_cookie(self, metadata_query_provider: Callable) -> str: + ... + + async def chain_metadata(self, metadata_query_provider: Callable) -> Tuple[Tuple[str, str]]: + cookie = await self.chain_cookie(metadata_query_provider=metadata_query_provider) + return (("cookie", cookie),) + + async def exchange_metadata(self, metadata_query_provider: Callable) -> Tuple[Tuple[str, str]]: + cookie = await self.exchange_cookie(metadata_query_provider=metadata_query_provider) + return (("cookie", cookie),) + + +class KubernetesLoadBalancedCookieAssistant(CookieAssistant): + + def __init__(self): + self._chain_cookie: Optional[str] = None + self._exchange_cookie: Optional[str] = None + self._chain_cookie_initialization_lock = asyncio.Lock() + self._exchange_cookie_initialization_lock = asyncio.Lock() + + async def chain_cookie(self, metadata_query_provider: Callable) -> str: + if self._chain_cookie == None: + async with self._chain_cookie_initialization_lock: + if self._chain_cookie == None: + await self._fetch_chain_cookie(metadata_query_provider=metadata_query_provider) + cookie = self._chain_cookie + self._check_chain_cookie_expiration() + + return cookie + + async def exchange_cookie(self, metadata_query_provider: Callable) -> str: + if self._exchange_cookie == None: + async with self._exchange_cookie_initialization_lock: + if self._exchange_cookie == None: + await self._fetch_exchange_cookie(metadata_query_provider=metadata_query_provider) + cookie = self._exchange_cookie + self._check_exchange_cookie_expiration() + + return cookie + + async def _fetch_chain_cookie(self, metadata_query_provider: Callable): + metadata = await metadata_query_provider() + cookie_info = next((value for key, value in metadata if key == "set-cookie"), None) + + if cookie_info is None: + raise RuntimeError(f"Error fetching chain cookie ({metadata})") + + self._chain_cookie = cookie_info + + async def _fetch_exchange_cookie(self, metadata_query_provider: Callable): + metadata = await metadata_query_provider() + cookie_info = next((value for key, value in metadata if key == "set-cookie"), None) + + if cookie_info is None: + raise RuntimeError(f"Error fetching exchange cookie ({metadata})") + + self._exchange_cookie = cookie_info + + def _check_chain_cookie_expiration(self): + if self._is_cookie_expired(cookie_data=self._chain_cookie): + self._chain_cookie = None + + def _check_exchange_cookie_expiration(self): + if self._is_cookie_expired(cookie_data=self._exchange_cookie): + self._exchange_cookie = None + + def _is_cookie_expired(self, cookie_data: str) -> bool: + cookie = SimpleCookie() + cookie.load(cookie_data) + + expiration_time = datetime.datetime.strptime(cookie["GCLB"]["expires"], + "%a, %d-%b-%Y %H:%M:%S %Z").timestamp() + + timestamp_diff = expiration_time - time.time() + return timestamp_diff < self.SESSION_RENEWAL_OFFSET + + +class BareMetalLoadBalancedCookieAssistant(CookieAssistant): + + def __init__(self): + self._chain_cookie: Optional[str] = None + self._exchange_cookie: Optional[str] = None + self._chain_cookie_initialization_lock = asyncio.Lock() + self._exchange_cookie_initialization_lock = asyncio.Lock() + + async def chain_cookie(self, metadata_query_provider: Callable) -> str: + if self._chain_cookie == None: + async with self._chain_cookie_initialization_lock: + if self._chain_cookie == None: + await self._fetch_chain_cookie(metadata_query_provider=metadata_query_provider) + cookie = self._chain_cookie + self._check_chain_cookie_expiration() + + return cookie + + async def exchange_cookie(self, metadata_query_provider: Callable) -> str: + if self._exchange_cookie == None: + async with self._exchange_cookie_initialization_lock: + if self._exchange_cookie == None: + await self._fetch_exchange_cookie(metadata_query_provider=metadata_query_provider) + cookie = self._exchange_cookie + self._check_exchange_cookie_expiration() + + return cookie + + async def _fetch_chain_cookie(self, metadata_query_provider: Callable): + metadata = await metadata_query_provider() + cookie_info = next((value for key, value in metadata if key == "set-cookie"), None) + + if cookie_info is None: + raise RuntimeError(f"Error fetching chain cookie ({metadata})") + + self._chain_cookie = cookie_info + + async def _fetch_exchange_cookie(self, metadata_query_provider: Callable): + metadata = await metadata_query_provider() + cookie_info = next((value for key, value in metadata if key == "set-cookie"), None) + + if cookie_info is None: + raise RuntimeError(f"Error fetching exchange cookie ({metadata})") + + self._exchange_cookie = cookie_info + + def _check_chain_cookie_expiration(self): + if self._is_cookie_expired(cookie_data=self._chain_cookie): + self._chain_cookie = None + + def _check_exchange_cookie_expiration(self): + if self._is_cookie_expired(cookie_data=self._exchange_cookie): + self._exchange_cookie = None + + def _is_cookie_expired(self, cookie_data: str) -> bool: + # The cookies for these nodes do not expire + return False + + +class DisabledCookieAssistant(CookieAssistant): + async def chain_cookie(self, metadata_query_provider: Callable) -> str: + pass + + async def exchange_cookie(self, metadata_query_provider: Callable) -> str: + pass + + async def chain_metadata(self, metadata_query_provider: Callable) -> Tuple[Tuple[str, str]]: + return None + + async def exchange_metadata(self, metadata_query_provider: Callable) -> Tuple[Tuple[str, str]]: + return None + + +class Network: + def __init__( + self, + lcd_endpoint: str, + tm_websocket_endpoint: str, + grpc_endpoint: str, + grpc_exchange_endpoint: str, + grpc_explorer_endpoint: str, + chain_id: str, + fee_denom: str, + env: str, + cookie_assistant: CookieAssistant, + use_secure_connection: bool = False, + ): + self.lcd_endpoint = lcd_endpoint + self.tm_websocket_endpoint = tm_websocket_endpoint + self.grpc_endpoint = grpc_endpoint + self.grpc_exchange_endpoint = grpc_exchange_endpoint + self.grpc_explorer_endpoint = grpc_explorer_endpoint + self.chain_id = chain_id + self.fee_denom = fee_denom + self.env = env + self.cookie_assistant = cookie_assistant + self.use_secure_connection = use_secure_connection + + @classmethod + def devnet(cls): + return cls( + lcd_endpoint="https://devnet.lcd.injective.dev", + tm_websocket_endpoint="wss://devnet.tm.injective.dev/websocket", + grpc_endpoint="devnet.injective.dev:9900", + grpc_exchange_endpoint="devnet.injective.dev:9910", + grpc_explorer_endpoint="devnet.injective.dev:9911", + chain_id="injective-777", + fee_denom="inj", + env="devnet", + cookie_assistant=DisabledCookieAssistant(), + ) + + @classmethod + def testnet(cls, node="lb"): + nodes = [ + "lb", + "sentry", + ] + if node not in nodes: + raise ValueError("Must be one of {}".format(nodes)) + + if node == "lb": + lcd_endpoint = "https://testnet.sentry.lcd.injective.network:443" + tm_websocket_endpoint = "wss://testnet.sentry.tm.injective.network:443/websocket" + grpc_endpoint = "testnet.sentry.chain.grpc.injective.network:443" + grpc_exchange_endpoint = "testnet.sentry.exchange.grpc.injective.network:443" + grpc_explorer_endpoint = "testnet.sentry.explorer.grpc.injective.network:443" + cookie_assistant = BareMetalLoadBalancedCookieAssistant() + use_secure_connection = True + else: + lcd_endpoint = "https://testnet.lcd.injective.network" + tm_websocket_endpoint = "wss://testnet.tm.injective.network/websocket" + grpc_endpoint = "testnet.chain.grpc.injective.network" + grpc_exchange_endpoint = "testnet.exchange.grpc.injective.network" + grpc_explorer_endpoint = "testnet.explorer.grpc.injective.network" + cookie_assistant = DisabledCookieAssistant() + use_secure_connection = True + + return cls( + lcd_endpoint=lcd_endpoint, + tm_websocket_endpoint=tm_websocket_endpoint, + grpc_endpoint=grpc_endpoint, + grpc_exchange_endpoint=grpc_exchange_endpoint, + grpc_explorer_endpoint=grpc_explorer_endpoint, + chain_id="injective-888", + fee_denom="inj", + env="testnet", + cookie_assistant=cookie_assistant, + use_secure_connection=use_secure_connection + ) + + @classmethod + def mainnet(cls, node="lb"): + nodes = [ + "lb", # us, asia, prod + "lb_k8s", + "sentry0", # ca, prod + "sentry1", # ca, prod + "sentry3", # us, prod + ] + if node not in nodes: + raise ValueError("Must be one of {}".format(nodes)) + + if node == "lb": + lcd_endpoint = "https://sentry.lcd.injective.network:443" + tm_websocket_endpoint = "wss://sentry.tm.injective.network:443/websocket" + grpc_endpoint = "sentry.chain.grpc.injective.network:443" + grpc_exchange_endpoint = "sentry.exchange.grpc.injective.network:443" + grpc_explorer_endpoint = "sentry.explorer.grpc.injective.network:443" + cookie_assistant = BareMetalLoadBalancedCookieAssistant() + use_secure_connection = True + elif node == "lb_k8s": + lcd_endpoint = "https://k8s.global.mainnet.lcd.injective.network:443" + tm_websocket_endpoint = "wss://k8s.global.mainnet.tm.injective.network:443/websocket" + grpc_endpoint = "k8s.global.mainnet.chain.grpc.injective.network:443" + grpc_exchange_endpoint = "k8s.global.mainnet.exchange.grpc.injective.network:443" + grpc_explorer_endpoint = "k8s.global.mainnet.explorer.grpc.injective.network:443" + cookie_assistant = KubernetesLoadBalancedCookieAssistant() + use_secure_connection = True + else: + lcd_endpoint = f"http://{node}.injective.network:10337" + tm_websocket_endpoint = f"ws://{node}.injective.network:26657/websocket" + grpc_endpoint = f"{node}.injective.network:9900" + grpc_exchange_endpoint = f"{node}.injective.network:9910" + grpc_explorer_endpoint = f"{node}.injective.network:9911" + cookie_assistant = DisabledCookieAssistant() + use_secure_connection = False + + return cls( + lcd_endpoint=lcd_endpoint, + tm_websocket_endpoint=tm_websocket_endpoint, + grpc_endpoint=grpc_endpoint, + grpc_exchange_endpoint=grpc_exchange_endpoint, + grpc_explorer_endpoint=grpc_explorer_endpoint, + chain_id="injective-1", + fee_denom="inj", + env="mainnet", + cookie_assistant=cookie_assistant, + use_secure_connection=use_secure_connection, + ) + + @classmethod + def local(cls): + return cls( + lcd_endpoint="http://localhost:10337", + tm_websocket_endpoint="ws://localhost:26657/websocket", + grpc_endpoint="localhost:9900", + grpc_exchange_endpoint="localhost:9910", + grpc_explorer_endpoint="localhost:9911", + chain_id="injective-1", + fee_denom="inj", + env="local", + cookie_assistant=DisabledCookieAssistant(), + use_secure_connection=False, + ) + + @classmethod + def custom( + cls, + lcd_endpoint, + tm_websocket_endpoint, + grpc_endpoint, + grpc_exchange_endpoint, + grpc_explorer_endpoint, + chain_id, + env, + cookie_assistant: Optional[CookieAssistant] = None, + use_secure_connection: bool = False, + ): + assistant = cookie_assistant or DisabledCookieAssistant() + return cls( + lcd_endpoint=lcd_endpoint, + tm_websocket_endpoint=tm_websocket_endpoint, + grpc_endpoint=grpc_endpoint, + grpc_exchange_endpoint=grpc_exchange_endpoint, + grpc_explorer_endpoint=grpc_explorer_endpoint, + chain_id=chain_id, + fee_denom="inj", + env=env, + cookie_assistant=assistant, + use_secure_connection=use_secure_connection + ) + + def string(self): + return self.env + + async def chain_metadata(self, metadata_query_provider: Callable) -> Tuple[Tuple[str, str]]: + return await self.cookie_assistant.chain_metadata(metadata_query_provider=metadata_query_provider) + + async def exchange_metadata(self, metadata_query_provider: Callable) -> Tuple[Tuple[str, str]]: + return await self.cookie_assistant.exchange_metadata(metadata_query_provider=metadata_query_provider) diff --git a/pyinjective/core/token.py b/pyinjective/core/token.py new file mode 100644 index 00000000..c6af6c0d --- /dev/null +++ b/pyinjective/core/token.py @@ -0,0 +1,15 @@ +from dataclasses import dataclass +from decimal import Decimal + +@dataclass(eq=True, frozen=True) +class Token: + name: str + symbol: str + denom: str + address: str + decimals: int + logo: str + updated: int + + def chain_formatted_value(self, human_readable_value: Decimal) -> Decimal: + return human_readable_value * Decimal(f"1e{self.decimals}") diff --git a/pyinjective/denoms_devnet.ini b/pyinjective/denoms_devnet.ini index 7b2df629..4e4f2797 100644 --- a/pyinjective/denoms_devnet.ini +++ b/pyinjective/denoms_devnet.ini @@ -92,7 +92,7 @@ min_display_quantity_tick_size = 0.001 description = 'Devnet Spot GF/USDT' base = 18 quote = 6 -min_price_tick_size = 0.000000000000001 +min_price_tick_size = 0.0000000000000001 min_display_price_tick_size = 0.001 min_quantity_tick_size = 100000 min_display_quantity_tick_size = 1e-13 diff --git a/pyinjective/transaction.py b/pyinjective/transaction.py index 7a02228f..afe7bd24 100644 --- a/pyinjective/transaction.py +++ b/pyinjective/transaction.py @@ -5,9 +5,8 @@ from .proto.cosmos.tx.v1beta1 import tx_pb2 as cosmos_tx_type from .proto.cosmos.tx.signing.v1beta1 import signing_pb2 as tx_sign -from .client import Client from .constant import MAX_MEMO_CHARACTERS -from .exceptions import EmptyMsgError, NotFoundError, UndefinedError, ValueTooLargeError +from .exceptions import EmptyMsgError, UndefinedError, ValueTooLargeError from .wallet import PublicKey class Transaction: @@ -44,16 +43,6 @@ def with_messages(self, *msgs: message.Message) -> "Transaction": self.msgs.extend(self.__convert_msgs(msgs)) return self - def with_sender(self, client: Client, sender: str) -> "Transaction": - if len(self.msgs) == 0: - raise EmptyMsgError("message is empty, please use with_messages at least 1 message") - account = client.get_account(sender) - if account: - self.account_num = account.account_number - self.sequence = account.sequence - return self - raise NotFoundError("Account doesn't exist") - def with_account_num(self, account_num: int) -> "Transaction": self.account_num = account_num return self diff --git a/pyinjective/fetch_metadata.py b/pyinjective/utils/fetch_metadata.py similarity index 82% rename from pyinjective/fetch_metadata.py rename to pyinjective/utils/fetch_metadata.py index 1abbd815..68269b74 100644 --- a/pyinjective/fetch_metadata.py +++ b/pyinjective/utils/fetch_metadata.py @@ -1,15 +1,7 @@ import asyncio -import logging -import grpc -import pyinjective.proto.exchange.injective_spot_exchange_rpc_pb2 as spot_exchange_rpc_pb -import pyinjective.proto.exchange.injective_spot_exchange_rpc_pb2_grpc as spot_exchange_rpc_grpc -import pyinjective.proto.exchange.injective_derivative_exchange_rpc_pb2 as derivative_exchange_rpc_pb -import pyinjective.proto.exchange.injective_derivative_exchange_rpc_pb2_grpc as derivative_exchange_rpc_grpc - -from decimal import * from pyinjective.async_client import AsyncClient -from pyinjective.constant import Network +from pyinjective.core.network import Network metadata_template = """[{}] description = '{} {} {}' @@ -36,7 +28,7 @@ async def fetch_denom(network) -> str: symbols = {} # fetch meta data for spot markets - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) status = 'active' mresp = await client.get_spot_markets(market_status=status) for market in mresp.markets: @@ -63,7 +55,7 @@ async def fetch_denom(network) -> str: denom_output += config # fetch meta data for derivative markets - client = AsyncClient(network, insecure=False) + client = AsyncClient(network) status = 'active' mresp = await client.get_derivative_markets(market_status=status) for market in mresp.markets: @@ -96,12 +88,12 @@ async def fetch_denom(network) -> str: async def main() -> None: testnet = Network.testnet() data = await fetch_denom(testnet) - with open("denoms_testnet.ini", "w") as text_file: + with open("../denoms_testnet.ini", "w") as text_file: text_file.write(data) mainnet = Network.mainnet() data = await fetch_denom(mainnet) - with open("denoms_mainnet.ini", "w") as text_file: + with open("../denoms_mainnet.ini", "w") as text_file: text_file.write(data) if __name__ == '__main__': diff --git a/pyinjective/utils/metadata_validation.py b/pyinjective/utils/metadata_validation.py new file mode 100644 index 00000000..366aa0aa --- /dev/null +++ b/pyinjective/utils/metadata_validation.py @@ -0,0 +1,106 @@ +import asyncio +from decimal import Decimal +from typing import Any, List, Tuple + +import pyinjective.constant as constant +from pyinjective.async_client import AsyncClient +from pyinjective.core.network import Network +from pyinjective.core.market import SpotMarket, DerivativeMarket, BinaryOptionMarket + + +def find_metadata_inconsistencies(network: Network) -> Tuple[List[Any]]: + client = AsyncClient(network) + ini_config = constant.CONFIGS[network.string()] + + spot_markets = asyncio.get_event_loop().run_until_complete(client.all_spot_markets()) + derivative_markets = asyncio.get_event_loop().run_until_complete(client.all_derivative_markets()) + binary_option_markets = asyncio.get_event_loop().run_until_complete(client.all_binary_option_markets()) + all_tokens = asyncio.get_event_loop().run_until_complete(client.all_tokens()) + + markets_not_found = [] + markets_with_diffs = [] + peggy_denoms_not_found = [] + peggy_denoms_with_diffs = [] + + for config_key in ini_config: + if config_key.startswith("0x"): + denom = constant.Denom.load_market(network=network.string(), market_id=config_key) + if config_key in spot_markets: + market: SpotMarket = spot_markets[config_key] + if (market.base_token.decimals != denom.base + or market.quote_token.decimals != denom.quote + or market.min_price_tick_size != Decimal(str(denom.min_price_tick_size)) + or market.min_quantity_tick_size != Decimal(str(denom.min_quantity_tick_size))): + markets_with_diffs.append([ + {"denom-market": config_key, "base_decimals": denom.base, "quote_decimals": denom.quote, + "min_quantity_tick_size": denom.min_quantity_tick_size, + "min_price_tick_size": denom.min_price_tick_size}, + {"newer-market": market.id, "base_decimals": market.base_token.decimals, + "quote_decimals": market.quote_token.decimals, + "min_quantity_tick_size": float(market.min_quantity_tick_size), + "min_price_tick_size": float(market.min_price_tick_size), "ticker": market.ticker}, + ]) + elif config_key in derivative_markets: + market: DerivativeMarket = derivative_markets[config_key] + if (market.quote_token.decimals != denom.quote + or market.min_price_tick_size != Decimal(str(denom.min_price_tick_size)) + or market.min_quantity_tick_size != Decimal(str(denom.min_quantity_tick_size))): + markets_with_diffs.append([ + {"denom-market": config_key, "quote_decimals": denom.quote, + "min_quantity_tick_size": denom.min_quantity_tick_size, + "min_price_tick_size": denom.min_price_tick_size}, + {"newer-market": market.id, "quote_decimals": market.quote_token.decimals, + "min_quantity_tick_size": float(market.min_quantity_tick_size), + "min_price_tick_size": float(market.min_price_tick_size), "ticker": market.ticker}, + ]) + elif config_key in binary_option_markets: + market: BinaryOptionMarket = binary_option_markets[config_key] + if (market.quote_token.decimals != denom.quote + or market.min_price_tick_size != Decimal(str(denom.min_price_tick_size)) + or market.min_quantity_tick_size != Decimal(str(denom.min_quantity_tick_size))): + markets_with_diffs.append([ + {"denom-market": config_key, "quote_decimals": denom.quote, + "min_quantity_tick_size": denom.min_quantity_tick_size, + "min_price_tick_size": denom.min_price_tick_size}, + {"newer-market": market.id, "quote_decimals": market.quote_token.decimals, + "min_quantity_tick_size": float(market.min_quantity_tick_size), + "min_price_tick_size": float(market.min_price_tick_size), "ticker": market.ticker}, + ]) + else: + markets_not_found.append({"denom-market": config_key, "description": denom.description}) + + elif config_key == "DEFAULT": + continue + else: + # the configuration is a token + peggy_denom, decimals = constant.Denom.load_peggy_denom(network=network.string(), symbol=config_key) + if config_key in all_tokens: + token = all_tokens[config_key] + if (token.denom != peggy_denom + or token.decimals != decimals): + peggy_denoms_with_diffs.append([ + {"denom_token": config_key, "peggy_denom": peggy_denom, "decimals": decimals}, + {"newer_token": token.symbol, "peggy_denom": token.denom, "decimals": token.decimals} + ]) + else: + peggy_denoms_not_found.append( + {"denom_token": config_key, "peggy_denom": peggy_denom, "decimals": decimals}) + + return markets_with_diffs, markets_not_found, peggy_denoms_with_diffs, peggy_denoms_not_found + + +def print_metadata_mismatches(network: Network): + markets_with_diffs, markets_not_found, peggy_denoms_with_diffs, peggy_denoms_not_found = find_metadata_inconsistencies( + network=network) + + for diff_pair in markets_with_diffs: + print(f"{diff_pair[0]}\n{diff_pair[1]}") + print(f"\n\n") + for missing_market in markets_not_found: + print(f"{missing_market}") + print(f"\n\n") + for diff_token in peggy_denoms_with_diffs: + print(f"{diff_token[0]}\n{diff_token[1]}") + print(f"\n\n") + for missing_peggy in peggy_denoms_not_found: + print(f"{missing_peggy}") diff --git a/pyinjective/utils/utils.py b/pyinjective/utils/utils.py deleted file mode 100644 index 61a02472..00000000 --- a/pyinjective/utils/utils.py +++ /dev/null @@ -1,108 +0,0 @@ -from decimal import Decimal -from math import floor -from typing import Union - -""" -One thing you may need to pay more attention to is how to deal with decimals on the Injective Exchange. -Different cryptocurrencies may require different decimal precisions. More specifically, ERC-20 tokens(e.g. INJ) have 18 decimals whereas USDT/USC have 6 decimals. -So in our system that means ** having 1 INJ is 1e18 inj ** and that ** 1 USDT is actually 100000 peggy0xdac17f958d2ee523a2206206994597c13d831ec7**. - -For spot markets, a price reflects the ** relative exchange rate ** between two tokens. -If the tokens have the same decimal scale, that's great since the prices become interpretable e.g. USDT/USDC (both have 6 decimals e.g. for USDT https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7#readContract) -or MATIC/INJ (both have 18 decimals) since the decimals cancel out. -Prices however start to look wonky once you have exchanges between two tokens of different decimals, which unfortunately is most pairs with USDT or USDC denominations e.g. INJ/USDT. -As such, I've created some simple utility functions by keeping a hardcoded dictionary in injective-py and you can also achieve such utilities by yourself -(e.g. you can use external API like Alchemy's getTokenMetadata to fetch decimal of base and quote asset). - -So for INJ/USDT of 6.9, the price you end up getting is 6.9*10 ^ (6 - 18) = 6.9e-12. Note that this market also happens to have a MinPriceTickSize of 1e-15. -This makes sense since since it's defining th3e minimum price increment of the relative exchange of INJ to USDT. - -Note that this market also happens to have a MinQuantityTickSize of 1e15. -This also makes sense since it refers to the minimum INJ quantity tick size each order must have, which is 1e15/1e18 = 0.001 INJ. - -""" - -def spot_price_to_backend(price, denom) -> int: - price_tick_size = denom.min_price_tick_size - scale_price = Decimal(18 + denom.quote - denom.base) - exchange_price = floor_to(price, price_tick_size) * pow(Decimal(10), scale_price) - return int(exchange_price) - -def spot_quantity_to_backend(quantity, denom) -> int: - quantity_tick_size = float(denom.min_quantity_tick_size) / pow(10, denom.base) - scale_quantity = Decimal(18 + denom.base) - exchange_quantity = floor_to(quantity, quantity_tick_size) * pow(Decimal(10), scale_quantity) - return int(exchange_quantity) - -def derivative_price_to_backend(price, denom) -> int: - price_tick_size = Decimal(denom.min_price_tick_size) / pow(10, denom.quote) - exchange_price = floor_to(price, float(price_tick_size)) * pow(10, 18 + denom.quote) - return int(exchange_price) - -def binary_options_price_to_backend(price, denom) -> int: - price_tick_size = Decimal(denom.min_price_tick_size) / pow(10, denom.quote) - exchange_price = floor_to(price, float(price_tick_size)) * pow(10, 18 + denom.quote) - return int(exchange_price) - -def derivative_quantity_to_backend(quantity, denom) -> int: - quantity_tick_size = float(denom.min_quantity_tick_size) / pow(10, denom.base) - scale_quantity = Decimal(18 + denom.base) - exchange_quantity = floor_to(quantity, quantity_tick_size) * pow(Decimal(10), scale_quantity) - return int(exchange_quantity) - -def binary_options_quantity_to_backend(quantity, denom) -> int: - quantity_tick_size = float(denom.min_quantity_tick_size) / pow(10, denom.base) - scale_quantity = Decimal(18 + denom.base) - exchange_quantity = floor_to(quantity, quantity_tick_size) * pow(Decimal(10), scale_quantity) - return int(exchange_quantity) - -def derivative_margin_to_backend(price, quantity, leverage, denom) -> int: - chain_format_price = Decimal(str(price)) * Decimal(f"1e{denom.quote}") - chain_format_quantity = Decimal(str(quantity)) * Decimal(f"1e{denom.base}") - decimal_leverage = Decimal(str(leverage)) - margin = (chain_format_price * chain_format_quantity) / decimal_leverage - # We are using the min_quantity_tick_size to quantize the margin because that is the way margin is validated - # in the chain (it might be changed to a min_notional in the future) - exchange_margin = floor_to(margin, denom.min_quantity_tick_size) * Decimal(f"1e18") - return int(exchange_margin) - -def binary_options_buy_margin_to_backend(price, quantity, denom) -> int: - price_tick_size = Decimal(denom.min_price_tick_size) / pow(10, denom.quote) - margin = Decimal(str(price)) * Decimal(str(quantity)) - exchange_margin = floor_to(margin, float(price_tick_size)) * pow(10, 18 + denom.quote) - return int(exchange_margin) - -def binary_options_sell_margin_to_backend(price, quantity, denom) -> int: - price_tick_size = Decimal(denom.min_price_tick_size) / pow(10, denom.quote) - margin = (1 - (Decimal(str(price)))) * (Decimal(str(quantity))) - exchange_margin = floor_to(margin, float(price_tick_size)) * pow(10, 18 + denom.quote) - return int(exchange_margin) - -def derivative_additional_margin_to_backend(amount, denom) -> int: - price_tick_size = float(denom.min_price_tick_size) / pow(10, denom.quote) - additional_margin = floor_to(amount, price_tick_size) * pow(10, 18 + denom.quote) - return int(additional_margin) - -def amount_to_backend(amount, decimals) -> int: - be_amount = amount * pow(10, decimals) - return int(be_amount) - -def floor_to(value: Union[float, Decimal], target: Union[float, Decimal]) -> Decimal: - value_tmp = Decimal(str(value)) - target_tmp = Decimal(str(target)) - result = int(floor(value_tmp / target_tmp)) * target_tmp - return result - -def spot_price_from_backend(price, denom) -> float: - scale = float(denom.quote - denom.base) - return float(price) / pow(10, scale) - -def spot_quantity_from_backend(quantity, denom) -> Decimal: - scale = float(denom.base) - quantity_tick_size = float(denom.min_quantity_tick_size) / pow(10, scale) - quantity = float(quantity) / pow(10, scale) - return floor_to(quantity, quantity_tick_size) - -def derivative_price_from_backend(price, denom) -> float: - scale = float(denom.quote) - return float(price) / pow(10, scale) diff --git a/run-examples.sh b/run-examples.sh index 8196e9d9..4b376ce9 100755 --- a/run-examples.sh +++ b/run-examples.sh @@ -1,5 +1,5 @@ runChainExamples(){ - examples=$(find -s examples/chain_client_examples -type f -mindepth 1 -name '*.py') + examples=$(find -s examples/chain_client -type f -mindepth 1 -name '*.py') echo "Running all chain examples..." for example in $examples do @@ -10,7 +10,7 @@ runChainExamples(){ } runExchangeExamples(){ - dirs=$(find -s examples/exchange_api_examples -type d -mindepth 1) + dirs=$(find -s examples/exchange_client -type d -mindepth 1) for dir in $dirs do examples=$(find -s $dir -type f -name '*.py') @@ -26,6 +26,8 @@ runExchangeExamples(){ done } +export PYTHONPATH=$PYTHONPATH:$(pwd) + TYPE=$1 case $TYPE in "chain") diff --git a/setup.py b/setup.py index f8275c57..ec5c78ae 100755 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ EMAIL = "achilleas@injectivelabs.com" AUTHOR = "Injective Labs" REQUIRES_PYTHON = ">=3.9" -VERSION = "0.7.2.1" +VERSION = "0.8.1" REQUIRED = [ "aiohttp", @@ -42,6 +42,7 @@ DEV_REQUIRED = [ "pytest", "pytest-asyncio", + "pytest-grpc", "request-mock", ] diff --git a/tests/async_client_tests.py b/tests/async_client_tests.py deleted file mode 100644 index 0446d9ec..00000000 --- a/tests/async_client_tests.py +++ /dev/null @@ -1,84 +0,0 @@ -import logging - -import pytest -from pyinjective.constant import Network - -from pyinjective.async_client import AsyncClient - - -class TestAsyncClient: - - def test_instance_creation_logs_session_cookie_load_info(self, caplog): - caplog.set_level(logging.INFO) - - AsyncClient( - network=Network.local(), - insecure=False, - ) - - expected_log_message_prefix = "chain session cookie loaded from disk: " - found_log = next( - (record for record in caplog.record_tuples if record[2].startswith(expected_log_message_prefix)), - None, - ) - assert(found_log is not None) - assert(found_log[0] == "pyinjective.async_client.AsyncClient") - assert(found_log[1] == logging.INFO) - - - @pytest.mark.asyncio - async def test_sync_timeout_height_logs_exception(self, caplog): - client = AsyncClient( - network=Network.local(), - insecure=False, - ) - - with caplog.at_level(logging.DEBUG): - await client.sync_timeout_height() - - expected_log_message_prefix = "error while fetching latest block, setting timeout height to 0: " - found_log = next( - (record for record in caplog.record_tuples if record[2].startswith(expected_log_message_prefix)), - None, - ) - assert (found_log is not None) - assert (found_log[0] == "pyinjective.async_client.AsyncClient") - assert (found_log[1] == logging.DEBUG) - - def test_set_cookie_logs_chain_session_cookie_saved(self, caplog): - caplog.set_level(logging.INFO) - - client = AsyncClient( - network=Network.local(), - insecure=False, - ) - - client.set_cookie(metadata=[("set-cookie", "test-value")], type="chain") - - expected_log_message_prefix = "chain session cookie saved to disk" - found_log = next( - (record for record in caplog.record_tuples if record[2].startswith(expected_log_message_prefix)), - None, - ) - assert (found_log is not None) - assert (found_log[0] == "pyinjective.async_client.AsyncClient") - assert (found_log[1] == logging.INFO) - - @pytest.mark.asyncio - async def test_get_account_logs_exception(self, caplog): - client = AsyncClient( - network=Network.local(), - insecure=False, - ) - - with caplog.at_level(logging.DEBUG): - await client.get_account(address="") - - expected_log_message_prefix = "error while fetching sequence and number " - found_log = next( - (record for record in caplog.record_tuples if record[2].startswith(expected_log_message_prefix)), - None, - ) - assert (found_log is not None) - assert (found_log[0] == "pyinjective.async_client.AsyncClient") - assert (found_log[1] == logging.DEBUG) \ No newline at end of file diff --git a/tests/composer_tests.py b/tests/composer_tests.py deleted file mode 100644 index eabef128..00000000 --- a/tests/composer_tests.py +++ /dev/null @@ -1,183 +0,0 @@ -import logging - -import pytest - -from pyinjective.composer import Composer -from pyinjective.constant import Denom, Network - - -class TestComposer: - - @pytest.fixture - def inj_usdt_market_id(self): - return "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0" - - def test_spot_order_creation_logs_market_data_loaded_info(self, caplog, inj_usdt_market_id): - caplog.set_level(logging.INFO) - - composer = Composer(network=Network.devnet().string()) - - composer.SpotOrder( - market_id=inj_usdt_market_id, - subaccount_id="", - fee_recipient="", - price=1.0, - quantity=1.0, - ) - - expected_log_message_prefix = "Loaded market metadata for: 'Devnet Spot INJ/USDT'" - expected_log_record = ("pyinjective.composer.Composer", logging.INFO, expected_log_message_prefix) - assert(expected_log_record in caplog.record_tuples) - - def test_derivative_order_creation_logs_market_data_loaded_info(self, caplog, inj_usdt_market_id): - caplog.set_level(logging.INFO) - - composer = Composer(network=Network.devnet().string()) - - composer.DerivativeOrder( - market_id=inj_usdt_market_id, - subaccount_id="", - fee_recipient="", - price=1.0, - quantity=1.0, - leverage=1.0, - ) - - expected_log_message_prefix = "Loaded market metadata for: 'Devnet Spot INJ/USDT'" - expected_log_record = ("pyinjective.composer.Composer", logging.INFO, expected_log_message_prefix) - assert(expected_log_record in caplog.record_tuples) - - def test_binary_order_creation_logs_market_data_loaded_info(self, caplog, inj_usdt_market_id): - caplog.set_level(logging.INFO) - - composer = Composer(network=Network.devnet().string()) - - composer.BinaryOptionsOrder( - market_id=inj_usdt_market_id, - subaccount_id="", - fee_recipient="", - price=1.0, - quantity=1.0, - ) - - expected_log_message_prefix = "Loaded market metadata for: 'Devnet Spot INJ/USDT'" - expected_log_record = ("pyinjective.composer.Composer", logging.INFO, expected_log_message_prefix) - assert(expected_log_record in caplog.record_tuples) - - def test_msg_send_logs_market_data_loaded_info(self, caplog): - caplog.set_level(logging.INFO) - - composer = Composer(network=Network.devnet().string()) - - composer.MsgSend( - from_address="", - to_address="", - amount=1.0, - denom="INJ", - ) - - expected_log_message_prefix = f"Loaded send symbol INJ (inj) with decimals = 18" - expected_log_record = ("pyinjective.composer.Composer", logging.INFO, expected_log_message_prefix) - assert(expected_log_record in caplog.record_tuples) - - def test_msg_deposit_logs_market_data_loaded_info(self, caplog): - caplog.set_level(logging.INFO) - - composer = Composer(network=Network.devnet().string()) - - composer.MsgDeposit( - sender="", - subaccount_id="", - amount=1.0, - denom="INJ", - ) - - expected_log_message_prefix = f"Loaded deposit symbol INJ (inj) with decimals = 18" - expected_log_record = ("pyinjective.composer.Composer", logging.INFO, expected_log_message_prefix) - assert(expected_log_record in caplog.record_tuples) - - def test_msg_withdraw_logs_market_data_loaded_info(self, caplog): - caplog.set_level(logging.INFO) - - composer = Composer(network=Network.devnet().string()) - - composer.MsgWithdraw( - sender="", - subaccount_id="", - amount=1.0, - denom="INJ", - ) - - expected_log_message_prefix = f"Loaded withdrawal symbol INJ (inj) with decimals = 18" - expected_log_record = ("pyinjective.composer.Composer", logging.INFO, expected_log_message_prefix) - assert(expected_log_record in caplog.record_tuples) - - def test_msg_external_transfer_logs_market_data_loaded_info(self, caplog): - caplog.set_level(logging.INFO) - - composer = Composer(network=Network.devnet().string()) - - composer.MsgExternalTransfer( - sender="", - source_subaccount_id="", - destination_subaccount_id="", - amount=1.0, - denom="INJ", - ) - - expected_log_message_prefix = f"Loaded send symbol INJ (inj) with decimals = 18" - expected_log_record = ("pyinjective.composer.Composer", logging.INFO, expected_log_message_prefix) - assert(expected_log_record in caplog.record_tuples) - - def test_msg_send_to_eth_logs_market_data_loaded_info(self, caplog): - caplog.set_level(logging.INFO) - - composer = Composer(network=Network.devnet().string()) - - composer.MsgSendToEth( - denom="INJ", - sender="", - eth_dest="", - amount=1.0, - bridge_fee=1.0, - ) - - expected_log_message_prefix = f"Loaded withdrawal symbol INJ (inj) with decimals = 18" - expected_log_record = ("pyinjective.composer.Composer", logging.INFO, expected_log_message_prefix) - assert(expected_log_record in caplog.record_tuples) - - def test_msg_create_insurance_fund_logs_market_data_loaded_info(self, caplog): - caplog.set_level(logging.INFO) - - composer = Composer(network=Network.devnet().string()) - - composer.MsgCreateInsuranceFund( - sender="", - ticker="", - quote_denom="INJ", - oracle_base="", - oracle_quote="", - oracle_type=1, - expiry=1, - initial_deposit=1, - ) - - expected_log_message_prefix = f"Loaded send symbol INJ (inj) with decimals = 18" - expected_log_record = ("pyinjective.composer.Composer", logging.INFO, expected_log_message_prefix) - assert(expected_log_record in caplog.record_tuples) - - def test_msg_underwrite_logs_market_data_loaded_info(self, caplog, inj_usdt_market_id): - caplog.set_level(logging.INFO) - - composer = Composer(network=Network.devnet().string()) - - composer.MsgUnderwrite( - sender="", - market_id=inj_usdt_market_id, - quote_denom="INJ", - amount=1, - ) - - expected_log_message_prefix = f"Loaded send symbol INJ (inj) with decimals = 18" - expected_log_record = ("pyinjective.composer.Composer", logging.INFO, expected_log_message_prefix) - assert(expected_log_record in caplog.record_tuples) diff --git a/tests/core/__init__.py b/tests/core/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/core/test_gas_limit_estimator.py b/tests/core/test_gas_limit_estimator.py index 070ebb26..9ccbc98b 100644 --- a/tests/core/test_gas_limit_estimator.py +++ b/tests/core/test_gas_limit_estimator.py @@ -1,9 +1,13 @@ +from decimal import Decimal + from pyinjective.composer import Composer from pyinjective.core.gas_limit_estimator import GasLimitEstimator +from pyinjective.core.market import BinaryOptionMarket from pyinjective.proto.cosmos.gov.v1beta1 import tx_pb2 as gov_tx_pb from pyinjective.proto.cosmwasm.wasm.v1 import tx_pb2 as wasm_tx_pb from pyinjective.proto.injective.exchange.v1beta1 import tx_pb2 as injective_exchange_tx_pb +from tests.model_fixtures.markets_fixtures import usdt_token class TestGasLimitEstimator: @@ -155,7 +159,7 @@ def test_estimation_for_batch_cancel_derivative_orders(self): assert((expected_order_gas_limit * 3) + expected_message_gas_limit == estimator.gas_limit()) def test_estimation_for_batch_update_orders_to_create_spot_orders(self): - market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" + market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" composer = Composer(network="testnet") orders = [ composer.SpotOrder( @@ -230,9 +234,27 @@ def test_estimation_for_batch_update_orders_to_create_derivative_orders(self): assert((expected_order_gas_limit * 2) + expected_message_gas_limit == estimator.gas_limit()) - def test_estimation_for_batch_update_orders_to_create_binary_orders(self): - market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" + def test_estimation_for_batch_update_orders_to_create_binary_orders(self, usdt_token): + market_id = "0x230dcce315364ff6360097838701b14713e2f4007d704df20ed3d81d09eec957" composer = Composer(network="testnet") + market = BinaryOptionMarket( + id=market_id, + status="active", + ticker="5fdbe0b1-1707800399-WAS", + oracle_symbol="Frontrunner", + oracle_provider="Frontrunner", + oracle_type="provider", + oracle_scale_factor=6, + expiration_timestamp=1707800399, + settlement_timestamp=1707843599, + quote_token=usdt_token, + maker_fee_rate=Decimal("0"), + taker_fee_rate=Decimal("0"), + service_provider_fee=Decimal("0.4"), + min_price_tick_size=Decimal("10000"), + min_quantity_tick_size=Decimal("1"), + ) + composer.binary_option_markets[market.id] = market orders = [ composer.BinaryOptionsOrder( market_id=market_id, @@ -434,7 +456,7 @@ def test_estimation_for_batch_update_orders_to_cancel_all_for_binary_options_mar assert(expected_gas_limit + expected_message_gas_limit == estimator.gas_limit()) def test_estimation_for_exec_message(self): - market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" + market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" composer = Composer(network="testnet") orders = [ composer.SpotOrder( diff --git a/tests/core/test_market.py b/tests/core/test_market.py new file mode 100644 index 00000000..1038c51b --- /dev/null +++ b/tests/core/test_market.py @@ -0,0 +1,213 @@ +import pytest +from decimal import Decimal + +from pyinjective.constant import Denom + +from pyinjective.core.market import BinaryOptionMarket, DerivativeMarket, SpotMarket +from tests.model_fixtures.markets_fixtures import ( + first_match_bet_market, + inj_token, + usdt_token, + usdt_perp_token, + inj_usdt_spot_market, + btc_usdt_perp_market, +) + + +class TestSpotMarket: + + def test_convert_quantity_to_chain_format(self, inj_usdt_spot_market: SpotMarket): + original_quantity = Decimal("123.456789") + + chain_value = inj_usdt_spot_market.quantity_to_chain_format(human_readable_value=original_quantity) + expected_value = original_quantity * Decimal(f"1e{inj_usdt_spot_market.base_token.decimals}") + quantized_value = ((expected_value // inj_usdt_spot_market.min_quantity_tick_size) + * inj_usdt_spot_market.min_quantity_tick_size) + quantized_chain_format_value = quantized_value * Decimal(f"1e18") + + assert (quantized_chain_format_value == chain_value) + + def test_convert_price_to_chain_format(self, inj_usdt_spot_market: SpotMarket): + original_quantity = Decimal("123.456789") + + chain_value = inj_usdt_spot_market.price_to_chain_format(human_readable_value=original_quantity) + price_decimals = inj_usdt_spot_market.quote_token.decimals - inj_usdt_spot_market.base_token.decimals + expected_value = original_quantity * Decimal(f"1e{price_decimals}") + quantized_value = ((expected_value // inj_usdt_spot_market.min_price_tick_size) + * inj_usdt_spot_market.min_price_tick_size) + quantized_chain_format_value = quantized_value * Decimal(f"1e18") + + assert (quantized_chain_format_value == chain_value) + + +class TestDerivativeMarket: + + def test_convert_quantity_to_chain_format(self, btc_usdt_perp_market: DerivativeMarket): + original_quantity = Decimal("123.456789") + + chain_value = btc_usdt_perp_market.quantity_to_chain_format(human_readable_value=original_quantity) + quantized_value = ((original_quantity // btc_usdt_perp_market.min_quantity_tick_size) + * btc_usdt_perp_market.min_quantity_tick_size) + quantized_chain_format_value = quantized_value * Decimal(f"1e18") + + assert (quantized_chain_format_value == chain_value) + + def test_convert_price_to_chain_format(self, btc_usdt_perp_market: DerivativeMarket): + original_quantity = Decimal("123.456789") + + chain_value = btc_usdt_perp_market.price_to_chain_format(human_readable_value=original_quantity) + price_decimals = btc_usdt_perp_market.quote_token.decimals + expected_value = original_quantity * Decimal(f"1e{price_decimals}") + quantized_value = ((expected_value // btc_usdt_perp_market.min_price_tick_size) + * btc_usdt_perp_market.min_price_tick_size) + quantized_chain_format_value = quantized_value * Decimal(f"1e18") + + assert (quantized_chain_format_value == chain_value) + + def test_convert_margin_to_chain_format(self, btc_usdt_perp_market: DerivativeMarket): + original_quantity = Decimal("123.456789") + + chain_value = btc_usdt_perp_market.margin_to_chain_format(human_readable_value=original_quantity) + margin_decimals = btc_usdt_perp_market.quote_token.decimals + expected_value = original_quantity * Decimal(f"1e{margin_decimals}") + quantized_value = ((expected_value // btc_usdt_perp_market.min_quantity_tick_size) + * btc_usdt_perp_market.min_quantity_tick_size) + quantized_chain_format_value = quantized_value * Decimal(f"1e18") + + assert (quantized_chain_format_value == chain_value) + +class TestBinaryOptionMarket: + + def test_convert_quantity_to_chain_format_with_fixed_denom(self, first_match_bet_market: BinaryOptionMarket): + original_quantity = Decimal("123.456789") + fixed_denom = Denom( + description="Fixed denom", + base=2, + quote=4, + min_quantity_tick_size=100, + min_price_tick_size=10000, + ) + + chain_value = first_match_bet_market.quantity_to_chain_format( + human_readable_value=original_quantity, + special_denom=fixed_denom + ) + chain_formatted_quantity = original_quantity * Decimal(f"1e{fixed_denom.base}") + quantized_value = ((chain_formatted_quantity // Decimal(str(fixed_denom.min_quantity_tick_size))) + * Decimal(str(fixed_denom.min_quantity_tick_size))) + quantized_chain_format_value = quantized_value * Decimal(f"1e18") + + assert (quantized_chain_format_value == chain_value) + + def test_convert_quantity_to_chain_format_without_fixed_denom(self, first_match_bet_market: BinaryOptionMarket): + original_quantity = Decimal("123.456789") + + chain_value = first_match_bet_market.quantity_to_chain_format( + human_readable_value=original_quantity, + ) + quantized_value = ((original_quantity // first_match_bet_market.min_quantity_tick_size) + * first_match_bet_market.min_quantity_tick_size) + quantized_chain_format_value = quantized_value * Decimal(f"1e18") + + assert (quantized_chain_format_value == chain_value) + + def test_convert_price_to_chain_format_with_fixed_denom(self, first_match_bet_market: BinaryOptionMarket): + original_quantity = Decimal("123.456789") + fixed_denom = Denom( + description="Fixed denom", + base=2, + quote=4, + min_quantity_tick_size=100, + min_price_tick_size=10000, + ) + + chain_value = first_match_bet_market.price_to_chain_format( + human_readable_value=original_quantity, + special_denom=fixed_denom, + ) + price_decimals = fixed_denom.quote + expected_value = original_quantity * Decimal(f"1e{price_decimals}") + quantized_value = ((expected_value // Decimal(str(fixed_denom.min_price_tick_size))) + * Decimal(str(fixed_denom.min_price_tick_size))) + quantized_chain_format_value = quantized_value * Decimal(f"1e18") + + assert (quantized_chain_format_value == chain_value) + + def test_convert_price_to_chain_format_without_fixed_denom(self, first_match_bet_market: BinaryOptionMarket): + original_quantity = Decimal("123.456789") + + chain_value = first_match_bet_market.price_to_chain_format(human_readable_value=original_quantity) + price_decimals = first_match_bet_market.quote_token.decimals + expected_value = original_quantity * Decimal(f"1e{price_decimals}") + quantized_value = ((expected_value // first_match_bet_market.min_price_tick_size) + * first_match_bet_market.min_price_tick_size) + quantized_chain_format_value = quantized_value * Decimal(f"1e18") + + assert (quantized_chain_format_value == chain_value) + + def test_calculate_margin_for_buy_with_fixed_denom(self, first_match_bet_market: BinaryOptionMarket): + original_quantity = Decimal("123.456789") + original_price = Decimal("0.6789") + fixed_denom = Denom( + description="Fixed denom", + base=2, + quote=4, + min_quantity_tick_size=100, + min_price_tick_size=10000, + ) + + chain_value = first_match_bet_market.calculate_margin_in_chain_format( + human_readable_quantity=original_quantity, + human_readable_price=original_price, + is_buy=True, + special_denom=fixed_denom, + ) + + quantity_decimals = fixed_denom.base + price_decimals = fixed_denom.quote + expected_quantity = original_quantity * Decimal(f"1e{quantity_decimals}") + expected_price = original_price * Decimal(f"1e{price_decimals}") + expected_margin = expected_quantity * expected_price + quantized_margin = ((expected_margin // Decimal(str(fixed_denom.min_quantity_tick_size))) + * Decimal(str(fixed_denom.min_quantity_tick_size))) + quantized_chain_format_margin = quantized_margin * Decimal(f"1e18") + + assert (quantized_chain_format_margin == chain_value) + + def test_calculate_margin_for_buy_without_fixed_denom(self, first_match_bet_market: BinaryOptionMarket): + original_quantity = Decimal("123.456789") + original_price = Decimal("0.6789") + + chain_value = first_match_bet_market.calculate_margin_in_chain_format( + human_readable_quantity=original_quantity, + human_readable_price=original_price, + is_buy=True, + ) + + price_decimals = first_match_bet_market.quote_token.decimals + expected_price = original_price * Decimal(f"1e{price_decimals}") + expected_margin = original_quantity * expected_price + quantized_margin = ((expected_margin // Decimal(str(first_match_bet_market.min_quantity_tick_size))) + * Decimal(str(first_match_bet_market.min_quantity_tick_size))) + quantized_chain_format_margin = quantized_margin * Decimal(f"1e18") + + assert (quantized_chain_format_margin == chain_value) + + def test_calculate_margin_for_sell_without_fixed_denom(self, first_match_bet_market: BinaryOptionMarket): + original_quantity = Decimal("123.456789") + original_price = Decimal("0.6789") + + chain_value = first_match_bet_market.calculate_margin_in_chain_format( + human_readable_quantity=original_quantity, + human_readable_price=original_price, + is_buy=False, + ) + + price_decimals = first_match_bet_market.quote_token.decimals + expected_price = (Decimal(1) - original_price) * Decimal(f"1e{price_decimals}") + expected_margin = original_quantity * expected_price + quantized_margin = ((expected_margin // Decimal(str(first_match_bet_market.min_quantity_tick_size))) + * Decimal(str(first_match_bet_market.min_quantity_tick_size))) + quantized_chain_format_margin = quantized_margin * Decimal(f"1e18") + + assert (quantized_chain_format_margin == chain_value) diff --git a/tests/core/test_message_based_transaction_fee_calculator.py b/tests/core/test_message_based_transaction_fee_calculator.py index 602b71af..2c3c4441 100644 --- a/tests/core/test_message_based_transaction_fee_calculator.py +++ b/tests/core/test_message_based_transaction_fee_calculator.py @@ -6,7 +6,7 @@ from pyinjective import Transaction from pyinjective.async_client import AsyncClient from pyinjective.composer import Composer -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.core.broadcaster import MessageBasedTransactionFeeCalculator from pyinjective.proto.cosmos.gov.v1beta1 import tx_pb2 as gov_tx_pb2 from pyinjective.proto.cosmwasm.wasm.v1 import tx_pb2 as wasm_tx_pb2 @@ -18,7 +18,7 @@ class TestMessageBasedTransactionFeeCalculator: @pytest.mark.asyncio async def test_gas_fee_for_privileged_execute_contract_message(self): network = Network.testnet(node="sentry") - client = AsyncClient(network=network, insecure=False) + client = AsyncClient(network=network) composer = Composer(network=network.string()) calculator = MessageBasedTransactionFeeCalculator( client=client, @@ -40,7 +40,7 @@ async def test_gas_fee_for_privileged_execute_contract_message(self): @pytest.mark.asyncio async def test_gas_fee_for_execute_contract_message(self): network = Network.testnet(node="sentry") - client = AsyncClient(network=network, insecure=False) + client = AsyncClient(network=network) composer = Composer(network=network.string()) calculator = MessageBasedTransactionFeeCalculator( client=client, @@ -66,7 +66,7 @@ async def test_gas_fee_for_execute_contract_message(self): @pytest.mark.asyncio async def test_gas_fee_for_wasm_message(self): network = Network.testnet(node="sentry") - client = AsyncClient(network=network, insecure=False) + client = AsyncClient(network=network) composer = Composer(network=network.string()) calculator = MessageBasedTransactionFeeCalculator( client=client, @@ -88,7 +88,7 @@ async def test_gas_fee_for_wasm_message(self): @pytest.mark.asyncio async def test_gas_fee_for_governance_message(self): network = Network.testnet(node="sentry") - client = AsyncClient(network=network, insecure=False) + client = AsyncClient(network=network) composer = Composer(network=network.string()) calculator = MessageBasedTransactionFeeCalculator( client=client, @@ -110,7 +110,7 @@ async def test_gas_fee_for_governance_message(self): @pytest.mark.asyncio async def test_gas_fee_for_exchange_message(self): network = Network.testnet(node="sentry") - client = AsyncClient(network=network, insecure=False) + client = AsyncClient(network=network) composer = Composer(network=network.string()) calculator = MessageBasedTransactionFeeCalculator( client=client, @@ -141,7 +141,7 @@ async def test_gas_fee_for_exchange_message(self): @pytest.mark.asyncio async def test_gas_fee_for_msg_exec_message(self): network = Network.testnet(node="sentry") - client = AsyncClient(network=network, insecure=False) + client = AsyncClient(network=network) composer = Composer(network=network.string()) calculator = MessageBasedTransactionFeeCalculator( client=client, @@ -180,7 +180,7 @@ async def test_gas_fee_for_msg_exec_message(self): @pytest.mark.asyncio async def test_gas_fee_for_two_messages_in_one_transaction(self): network = Network.testnet(node="sentry") - client = AsyncClient(network=network, insecure=False) + client = AsyncClient(network=network) composer = Composer(network=network.string()) calculator = MessageBasedTransactionFeeCalculator( client=client, diff --git a/tests/core/test_token.py b/tests/core/test_token.py new file mode 100644 index 00000000..66cb6cd7 --- /dev/null +++ b/tests/core/test_token.py @@ -0,0 +1,15 @@ +import pytest +from decimal import Decimal + +from tests.model_fixtures.markets_fixtures import inj_token + + +class TestToken: + + def test_chain_formatted_value(self, inj_token): + value = Decimal("1.3456") + + chain_formatted_value = inj_token.chain_formatted_value(human_readable_value=value) + expected_value = value * Decimal(f"1e{inj_token.decimals}") + + assert (chain_formatted_value == expected_value) diff --git a/tests/model_fixtures/__init__.py b/tests/model_fixtures/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/model_fixtures/markets_fixtures.py b/tests/model_fixtures/markets_fixtures.py new file mode 100644 index 00000000..cca40680 --- /dev/null +++ b/tests/model_fixtures/markets_fixtures.py @@ -0,0 +1,113 @@ +import pytest +from decimal import Decimal + +from pyinjective.core.market import BinaryOptionMarket, DerivativeMarket, SpotMarket +from pyinjective.core.token import Token + + +@pytest.fixture +def inj_token(): + token = Token( + name="Injective Protocol", + symbol="INJ", + denom="peggy0x44C21afAaF20c270EBbF5914Cfc3b5022173FEB7", + address="0xe28b3B32B6c345A34Ff64674606124Dd5Aceca30", + decimals=18, + logo="https://static.alchemyapi.io/images/assets/7226.png", + updated=1681739137644, + ) + + return token + + +@pytest.fixture +def usdt_token(): + token = Token( + name="USDT", + symbol="USDT", + denom="peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5", + address="0x0000000000000000000000000000000000000000", + decimals=6, + logo="https://static.alchemyapi.io/images/assets/825.png", + updated=1681739137645, + ) + + return token + + +@pytest.fixture +def usdt_perp_token(): + token = Token( + name="USDT PERP", + symbol="USDT", + denom="peggy0xdAC17F958D2ee523a2206206994597C13D831ec7", + address="0xdAC17F958D2ee523a2206206994597C13D831ec7", + decimals=6, + logo="https://static.alchemyapi.io/images/assets/825.png", + updated=1681739137645, + ) + + return token + + +@pytest.fixture +def inj_usdt_spot_market(inj_token, usdt_token): + market = SpotMarket( + id="0x7a57e705bb4e09c88aecfc295569481dbf2fe1d5efe364651fbe72385938e9b0", + status="active", + ticker="INJ/USDT", + base_token=inj_token, + quote_token=usdt_token, + maker_fee_rate=Decimal("-0.0001"), + taker_fee_rate=Decimal("0.001"), + service_provider_fee=Decimal("0.4"), + min_price_tick_size=Decimal("0.000000000000001"), + min_quantity_tick_size=Decimal("1000000000000000"), + ) + + return market + + +@pytest.fixture +def btc_usdt_perp_market(usdt_perp_token): + market = DerivativeMarket( + id="0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce", + status="active", + ticker="BTC/USDT PERP", + oracle_base="BTC", + oracle_quote=usdt_perp_token.symbol, + oracle_type="bandibc", + oracle_scale_factor=6, + initial_margin_ratio=Decimal("0.095"), + maintenance_margin_ratio=Decimal("0.025"), + quote_token=usdt_perp_token, + maker_fee_rate=Decimal("-0.0001"), + taker_fee_rate=Decimal("0.001"), + service_provider_fee=Decimal("0.4"), + min_price_tick_size=Decimal("1000000"), + min_quantity_tick_size=Decimal("0.0001"), + ) + + return market + +@pytest.fixture +def first_match_bet_market(usdt_token): + market = BinaryOptionMarket( + id="0x230dcce315364ff6360097838701b14713e2f4007d704df20ed3d81d09eec957", + status="active", + ticker="5fdbe0b1-1707800399-WAS", + oracle_symbol="Frontrunner", + oracle_provider="Frontrunner", + oracle_type="provider", + oracle_scale_factor=6, + expiration_timestamp=1707800399, + settlement_timestamp=1707843599, + quote_token=usdt_token, + maker_fee_rate=Decimal("0"), + taker_fee_rate=Decimal("0"), + service_provider_fee=Decimal("0.4"), + min_price_tick_size=Decimal("10000"), + min_quantity_tick_size=Decimal("1"), + ) + + return market diff --git a/tests/rpc_fixtures/__init__.py b/tests/rpc_fixtures/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/rpc_fixtures/configurable_servicers.py b/tests/rpc_fixtures/configurable_servicers.py new file mode 100644 index 00000000..136491ce --- /dev/null +++ b/tests/rpc_fixtures/configurable_servicers.py @@ -0,0 +1,38 @@ +from collections import deque + +import pytest +from pyinjective.proto.exchange.injective_derivative_exchange_rpc_pb2_grpc import InjectiveDerivativeExchangeRPCServicer + +from pyinjective.proto.exchange import ( + injective_spot_exchange_rpc_pb2, + injective_derivative_exchange_rpc_pb2, +) +from pyinjective.proto.exchange.injective_spot_exchange_rpc_pb2_grpc import InjectiveSpotExchangeRPCServicer + + +class ConfigurableInjectiveSpotExchangeRPCServicer(InjectiveSpotExchangeRPCServicer): + + def __init__(self): + super().__init__() + self.markets_queue = deque() + + async def Markets(self, request: injective_spot_exchange_rpc_pb2.MarketsRequest, context=None): + return self.markets_queue.pop() + + +class ConfigurableInjectiveDerivativeExchangeRPCServicer(InjectiveDerivativeExchangeRPCServicer): + + def __init__(self): + super().__init__() + self.markets_queue = deque() + self.binary_option_markets_queue = deque() + + async def Markets(self, request: injective_derivative_exchange_rpc_pb2.MarketsRequest, context=None): + return self.markets_queue.pop() + + async def BinaryOptionsMarkets( + self, + request: injective_derivative_exchange_rpc_pb2.BinaryOptionsMarketsRequest, + context=None + ): + return self.binary_option_markets_queue.pop() diff --git a/tests/rpc_fixtures/markets_fixtures.py b/tests/rpc_fixtures/markets_fixtures.py new file mode 100644 index 00000000..b6a2d3a3 --- /dev/null +++ b/tests/rpc_fixtures/markets_fixtures.py @@ -0,0 +1,189 @@ +import pytest + + +@pytest.fixture +def inj_token_meta(): + from pyinjective.proto.exchange.injective_spot_exchange_rpc_pb2 import TokenMeta + + token = TokenMeta( + name="Injective Protocol", + address="0xe28b3B32B6c345A34Ff64674606124Dd5Aceca30", + symbol="INJ", + logo="https://static.alchemyapi.io/images/assets/7226.png", + decimals=18, + updated_at=1681739137644 + ) + + return token + +@pytest.fixture +def ape_token_meta(): + from pyinjective.proto.exchange.injective_spot_exchange_rpc_pb2 import TokenMeta + + token = TokenMeta( + name="APE", + address="0x0000000000000000000000000000000000000000", + symbol="APE", + logo="https://assets.coingecko.com/coins/images/24383/small/apecoin.jpg?1647476455", + decimals=18, + updated_at=1681739137646 + ) + + return token + +@pytest.fixture +def usdt_token_meta(): + from pyinjective.proto.exchange.injective_spot_exchange_rpc_pb2 import TokenMeta + + token = TokenMeta( + name="USDT", + address="0x0000000000000000000000000000000000000000", + symbol="USDT", + logo="https://static.alchemyapi.io/images/assets/825.png", + decimals=6, + updated_at=1681739137645 + ) + + return token + +@pytest.fixture +def usdt_token_meta_second_denom(): + from pyinjective.proto.exchange.injective_spot_exchange_rpc_pb2 import TokenMeta + + token = TokenMeta( + name="USDT Second Denom", + address="0x0000000000000000000000000000000000000000", + symbol="USDT", + logo="https://static.alchemyapi.io/images/assets/826.png", + decimals=6, + updated_at=1691739137645 + ) + + return token + + +@pytest.fixture +def usdt_perp_token_meta(): + from pyinjective.proto.exchange.injective_derivative_exchange_rpc_pb2 import TokenMeta + + token = TokenMeta( + name="Tether", + address="0xdAC17F958D2ee523a2206206994597C13D831ec7", + symbol="USDTPerp", + logo="https://static.alchemyapi.io/images/assets/825.png", + decimals=6, + updated_at=1683929869866 + ) + + return token + + +@pytest.fixture +def ape_usdt_spot_market_meta(ape_token_meta, usdt_token_meta_second_denom): + from pyinjective.proto.exchange.injective_spot_exchange_rpc_pb2 import SpotMarketInfo + + market = SpotMarketInfo( + market_id="0x8b67e705bb4e09c88aecfc295569481dbf2fe1d5efe364651fbe72385938e000", + market_status="active", + ticker="APE/USDT", + base_denom="peggy0x44C21afAaF20c270EBbF5914Cfc3b5022173FEB7", + base_token_meta=ape_token_meta, + quote_denom="factory/peggy0x87aB3B4C8661e07D6372361211B96ed4Dc300000", + quote_token_meta=usdt_token_meta_second_denom, + maker_fee_rate="-0.0001", + taker_fee_rate="0.001", + service_provider_fee="0.4", + min_price_tick_size="0.000000000000001", + min_quantity_tick_size="1000000000000000", + ) + + return market + +@pytest.fixture +def inj_usdt_spot_market_meta(inj_token_meta, usdt_token_meta): + from pyinjective.proto.exchange.injective_spot_exchange_rpc_pb2 import SpotMarketInfo + + market = SpotMarketInfo( + market_id="0x7a57e705bb4e09c88aecfc295569481dbf2fe1d5efe364651fbe72385938e9b0", + market_status="active", + ticker="INJ/USDT", + base_denom="peggy0x44C21afAaF20c270EBbF5914Cfc3b5022173FEB7", + base_token_meta=inj_token_meta, + quote_denom="peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5", + quote_token_meta=usdt_token_meta, + maker_fee_rate="-0.0001", + taker_fee_rate="0.001", + service_provider_fee="0.4", + min_price_tick_size="0.000000000000001", + min_quantity_tick_size="1000000000000000", + ) + + return market + +@pytest.fixture +def btc_usdt_perp_market_meta(usdt_perp_token_meta): + from pyinjective.proto.exchange.injective_derivative_exchange_rpc_pb2 import ( + DerivativeMarketInfo, + PerpetualMarketInfo, + PerpetualMarketFunding, + ) + + perpetual_market_info = PerpetualMarketInfo( + hourly_funding_rate_cap="0.0000625", + hourly_interest_rate="0.00000416666", + next_funding_timestamp=1684764000, + funding_interval=3600, + ) + perpetual_market_funding = PerpetualMarketFunding( + cumulative_funding="6880500093.266083891331674194", + cumulative_price="-0.952642601240470199", + last_timestamp=1684763442, + ) + + market = DerivativeMarketInfo( + market_id="0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce", + market_status="active", + ticker="BTC/USDT PERP", + oracle_base="BTC", + oracle_quote="USDT", + oracle_type="bandibc", + oracle_scale_factor=6, + initial_margin_ratio="0.095", + maintenance_margin_ratio="0.025", + quote_denom="peggy0xdAC17F958D2ee523a2206206994597C13D831ec7", + quote_token_meta=usdt_perp_token_meta, + maker_fee_rate="-0.0001", + taker_fee_rate="0.001", + service_provider_fee="0.4", + is_perpetual=True, + min_price_tick_size="1000000", + min_quantity_tick_size="0.0001", + perpetual_market_info=perpetual_market_info, + perpetual_market_funding=perpetual_market_funding, + ) + + return market + +@pytest.fixture +def first_match_bet_market_meta(inj_usdt_spot_market_meta): + from pyinjective.proto.exchange.injective_derivative_exchange_rpc_pb2 import BinaryOptionsMarketInfo + + market = BinaryOptionsMarketInfo( + market_id="0x230dcce315364ff6360097838701b14713e2f4007d704df20ed3d81d09eec957", + market_status="active", + ticker="5fdbe0b1-1707800399-WAS", + oracle_symbol="Frontrunner", + oracle_provider="Frontrunner", + oracle_type="provider", + oracle_scale_factor=6, + expiration_timestamp=1707800399, + settlement_timestamp=1707843599, + quote_denom=inj_usdt_spot_market_meta.quote_denom, + maker_fee_rate="0", + taker_fee_rate="0", + service_provider_fee="0.4", + min_price_tick_size="10000", + min_quantity_tick_size="1", + ) + + return market \ No newline at end of file diff --git a/tests/test_async_client.py b/tests/test_async_client.py new file mode 100644 index 00000000..8cbab554 --- /dev/null +++ b/tests/test_async_client.py @@ -0,0 +1,130 @@ +import logging + +import pytest +from pyinjective.core.network import Network + +from pyinjective.async_client import AsyncClient +from pyinjective.proto.exchange import ( + injective_spot_exchange_rpc_pb2, + injective_derivative_exchange_rpc_pb2, +) +from tests.rpc_fixtures.markets_fixtures import ( + inj_token_meta, + ape_token_meta, + usdt_token_meta, + usdt_token_meta_second_denom, + usdt_perp_token_meta, + inj_usdt_spot_market_meta, + ape_usdt_spot_market_meta, + btc_usdt_perp_market_meta, + first_match_bet_market_meta, +) +from tests.rpc_fixtures.configurable_servicers import ConfigurableInjectiveDerivativeExchangeRPCServicer, \ + ConfigurableInjectiveSpotExchangeRPCServicer + + +@pytest.fixture +def spot_servicer(): + return ConfigurableInjectiveSpotExchangeRPCServicer() + + +@pytest.fixture +def derivative_servicer(): + return ConfigurableInjectiveDerivativeExchangeRPCServicer() + + +class TestAsyncClient: + + @pytest.mark.asyncio + async def test_sync_timeout_height_logs_exception(self, caplog): + client = AsyncClient( + network=Network.local(), + insecure=False, + ) + + with caplog.at_level(logging.DEBUG): + await client.sync_timeout_height() + + expected_log_message_prefix = "error while fetching latest block, setting timeout height to 0: " + found_log = next( + (record for record in caplog.record_tuples if record[2].startswith(expected_log_message_prefix)), + None, + ) + assert (found_log is not None) + assert (found_log[0] == "pyinjective.async_client.AsyncClient") + assert (found_log[1] == logging.DEBUG) + + @pytest.mark.asyncio + async def test_get_account_logs_exception(self, caplog): + client = AsyncClient( + network=Network.local(), + insecure=False, + ) + + with caplog.at_level(logging.DEBUG): + await client.get_account(address="") + + expected_log_message_prefix = "error while fetching sequence and number " + found_log = next( + (record for record in caplog.record_tuples if record[2].startswith(expected_log_message_prefix)), + None, + ) + assert (found_log is not None) + assert (found_log[0] == "pyinjective.async_client.AsyncClient") + assert (found_log[1] == logging.DEBUG) + + @pytest.mark.asyncio + async def test_initialize_tokens_and_markets( + self, + spot_servicer, + derivative_servicer, + inj_usdt_spot_market_meta, + ape_usdt_spot_market_meta, + btc_usdt_perp_market_meta, + first_match_bet_market_meta, + ): + spot_servicer.markets_queue.append(injective_spot_exchange_rpc_pb2.MarketsResponse( + markets=[inj_usdt_spot_market_meta, ape_usdt_spot_market_meta] + )) + derivative_servicer.markets_queue.append(injective_derivative_exchange_rpc_pb2.MarketsResponse( + markets=[btc_usdt_perp_market_meta] + )) + derivative_servicer.binary_option_markets_queue.append( + injective_derivative_exchange_rpc_pb2.BinaryOptionsMarketsResponse( + markets=[first_match_bet_market_meta] + )) + + client = AsyncClient( + network=Network.local(), + insecure=False, + ) + + client.stubSpotExchange = spot_servicer + client.stubDerivativeExchange = derivative_servicer + + await client._initialize_tokens_and_markets() + + all_tokens = await client.all_tokens() + assert(5 == len(all_tokens)) + inj_symbol, usdt_symbol = inj_usdt_spot_market_meta.ticker.split("/") + ape_symbol, _ = ape_usdt_spot_market_meta.ticker.split("/") + alternative_usdt_name = ape_usdt_spot_market_meta.quote_token_meta.name + usdt_perp_symbol = btc_usdt_perp_market_meta.quote_token_meta.symbol + assert(inj_symbol in all_tokens) + assert(usdt_symbol in all_tokens) + assert(alternative_usdt_name in all_tokens) + assert(ape_symbol in all_tokens) + assert(usdt_perp_symbol in all_tokens) + + all_spot_markets = await client.all_spot_markets() + assert (2 == len(all_spot_markets)) + assert (any((inj_usdt_spot_market_meta.market_id == market.id for market in all_spot_markets.values()))) + assert (any((ape_usdt_spot_market_meta.market_id == market.id for market in all_spot_markets.values()))) + + all_derivative_markets = await client.all_derivative_markets() + assert (1 == len(all_derivative_markets)) + assert (any((btc_usdt_perp_market_meta.market_id == market.id for market in all_derivative_markets.values()))) + + all_binary_option_markets = await client.all_binary_option_markets() + assert (1 == len(all_binary_option_markets)) + assert (any((first_match_bet_market_meta.market_id == market.id for market in all_binary_option_markets.values()))) diff --git a/tests/test_composer.py b/tests/test_composer.py new file mode 100644 index 00000000..449854ad --- /dev/null +++ b/tests/test_composer.py @@ -0,0 +1,235 @@ +import pytest +from decimal import Decimal + +from pyinjective.composer import Composer +from pyinjective.core.network import Network +from pyinjective.constant import Denom +from pyinjective.core.market import BinaryOptionMarket, DerivativeMarket, SpotMarket +from pyinjective.proto.injective.exchange.v1beta1 import exchange_pb2 +from tests.model_fixtures.markets_fixtures import ( + btc_usdt_perp_market, + first_match_bet_market, + inj_token, + inj_usdt_spot_market, + usdt_token, + usdt_perp_token +) + + +class TestComposer: + + @pytest.fixture + def inj_usdt_market_id(self): + return "0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0" + + @pytest.fixture + def basic_composer(self, inj_usdt_spot_market, btc_usdt_perp_market, first_match_bet_market): + composer = Composer( + network=Network.devnet().string(), + spot_markets={inj_usdt_spot_market.id: inj_usdt_spot_market}, + derivative_markets={btc_usdt_perp_market.id: btc_usdt_perp_market}, + binary_option_markets={first_match_bet_market.id: first_match_bet_market}, + tokens={ + inj_usdt_spot_market.base_token.symbol: inj_usdt_spot_market.base_token, + inj_usdt_spot_market.quote_token.symbol: inj_usdt_spot_market.quote_token, + btc_usdt_perp_market.quote_token.symbol: btc_usdt_perp_market.quote_token, + } + ) + + return composer + + def test_composer_initialization_from_ini_files(self): + composer = Composer(network=Network.devnet().string()) + + inj_token = composer.tokens["INJ"] + inj_usdt_spot_market = next((market for market in composer.spot_markets.values() if market.ticker == "'Devnet Spot INJ/USDT'")) + inj_usdt_perp_market = next((market for market in composer.derivative_markets.values() if market.ticker == "'Devnet Derivative INJ/USDT PERP'")) + + assert (18 == inj_token.decimals) + assert (18 == inj_usdt_spot_market.base_token.decimals) + assert (6 == inj_usdt_spot_market.quote_token.decimals) + assert (6 == inj_usdt_perp_market.quote_token.decimals) + + + def test_buy_spot_order_creation(self, basic_composer: Composer, inj_usdt_spot_market: SpotMarket): + fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" + price = 6.869 + quantity = 1587 + order = basic_composer.SpotOrder( + market_id=inj_usdt_spot_market.id, + subaccount_id="1", + fee_recipient=fee_recipient, + price=price, + quantity=quantity, + is_buy=True, + ) + + price_decimals = inj_usdt_spot_market.quote_token.decimals - inj_usdt_spot_market.base_token.decimals + chain_format_price = Decimal(str(price)) * Decimal(f"1e{price_decimals}") + expected_price = ((chain_format_price // inj_usdt_spot_market.min_price_tick_size) + * inj_usdt_spot_market.min_price_tick_size + * Decimal(f"1e18")) + chain_format_quantity = Decimal(str(quantity)) * Decimal(f"1e{inj_usdt_spot_market.base_token.decimals}") + expected_quantity = ((chain_format_quantity // inj_usdt_spot_market.min_quantity_tick_size) + * inj_usdt_spot_market.min_quantity_tick_size + * Decimal(f"1e18")) + + assert (order.market_id == inj_usdt_spot_market.id) + assert (order.order_info.subaccount_id == "1") + assert (order.order_info.fee_recipient == fee_recipient) + assert (order.order_info.price == str(int(expected_price))) + assert (order.order_info.quantity == str(int(expected_quantity))) + assert (order.order_type == exchange_pb2.OrderType.BUY) + assert (order.trigger_price == "0") + + def test_buy_derivative_order_creation(self, basic_composer: Composer, btc_usdt_perp_market: DerivativeMarket): + fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" + price = 6.869 + quantity = 1587 + leverage = 2 + order = basic_composer.DerivativeOrder( + market_id=btc_usdt_perp_market.id, + subaccount_id="1", + fee_recipient=fee_recipient, + price=price, + quantity=quantity, + is_buy=True, + leverage=leverage, + ) + + price_decimals = btc_usdt_perp_market.quote_token.decimals + chain_format_price = Decimal(str(price)) * Decimal(f"1e{price_decimals}") + expected_price = ((chain_format_price // btc_usdt_perp_market.min_price_tick_size) + * btc_usdt_perp_market.min_price_tick_size + * Decimal(f"1e18")) + chain_format_quantity = Decimal(str(quantity)) + expected_quantity = ((chain_format_quantity // btc_usdt_perp_market.min_quantity_tick_size) + * btc_usdt_perp_market.min_quantity_tick_size + * Decimal(f"1e18")) + chain_format_margin = (chain_format_quantity * chain_format_price) / Decimal(leverage) + expected_margin = ((chain_format_margin // btc_usdt_perp_market.min_quantity_tick_size) + * btc_usdt_perp_market.min_quantity_tick_size + * Decimal(f"1e18")) + + assert (order.market_id == btc_usdt_perp_market.id) + assert (order.order_info.subaccount_id == "1") + assert (order.order_info.fee_recipient == fee_recipient) + assert (order.order_info.price == str(int(expected_price))) + assert (order.order_info.quantity == str(int(expected_quantity))) + assert (order.order_type == exchange_pb2.OrderType.BUY) + assert (order.margin == str(int(expected_margin))) + assert (order.trigger_price == "0") + + def test_increase_position_margin(self, basic_composer: Composer, btc_usdt_perp_market: DerivativeMarket): + sender = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" + amount = 1587.789 + message = basic_composer.MsgIncreasePositionMargin( + sender=sender, + source_subaccount_id="1", + destination_subaccount_id="2", + market_id=btc_usdt_perp_market.id, + amount=amount, + ) + + price_decimals = btc_usdt_perp_market.quote_token.decimals + chain_format_margin = Decimal(str(amount)) * Decimal(f"1e{price_decimals}") + expected_margin = ((chain_format_margin // btc_usdt_perp_market.min_quantity_tick_size) + * btc_usdt_perp_market.min_quantity_tick_size + * Decimal(f"1e18")) + + assert (message.market_id == btc_usdt_perp_market.id) + assert (message.sender == sender) + assert (message.source_subaccount_id == "1") + assert (message.destination_subaccount_id == "2") + assert (message.amount == str(int(expected_margin))) + + def test_buy_binary_option_order_creation_with_fixed_denom( + self, + basic_composer: Composer, + first_match_bet_market: BinaryOptionMarket + ): + fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" + price = 6.869 + quantity = 1587 + fixed_denom = Denom( + description="Fixed denom", + base=2, + quote=6, + min_price_tick_size=1000, + min_quantity_tick_size=10000, + ) + + order = basic_composer.BinaryOptionsOrder( + market_id=first_match_bet_market.id, + subaccount_id="1", + fee_recipient=fee_recipient, + price=price, + quantity=quantity, + is_buy=True, + denom=fixed_denom, + ) + + price_decimals = fixed_denom.quote + chain_format_price = Decimal(str(price)) * Decimal(f"1e{price_decimals}") + expected_price = ((chain_format_price // Decimal(str(fixed_denom.min_price_tick_size))) + * Decimal(str(fixed_denom.min_price_tick_size)) + * Decimal(f"1e18")) + quantity_decimals = fixed_denom.base + chain_format_quantity = Decimal(str(quantity)) * Decimal(f"1e{quantity_decimals}") + expected_quantity = ((chain_format_quantity // Decimal(str(fixed_denom.min_quantity_tick_size))) + * Decimal(str(fixed_denom.min_quantity_tick_size)) + * Decimal(f"1e18")) + chain_format_margin = chain_format_quantity * chain_format_price + expected_margin = ((chain_format_margin // Decimal(str(fixed_denom.min_quantity_tick_size))) + * Decimal(str(fixed_denom.min_quantity_tick_size)) + * Decimal(f"1e18")) + + assert (order.market_id == first_match_bet_market.id) + assert (order.order_info.subaccount_id == "1") + assert (order.order_info.fee_recipient == fee_recipient) + assert (order.order_info.price == str(int(expected_price))) + assert (order.order_info.quantity == str(int(expected_quantity))) + assert (order.order_type == exchange_pb2.OrderType.BUY) + assert (order.margin == str(int(expected_margin))) + assert (order.trigger_price == "0") + + def test_buy_binary_option_order_creation_without_fixed_denom( + self, + basic_composer: Composer, + first_match_bet_market: BinaryOptionMarket, + ): + fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" + price = 6.869 + quantity = 1587 + + order = basic_composer.BinaryOptionsOrder( + market_id=first_match_bet_market.id, + subaccount_id="1", + fee_recipient=fee_recipient, + price=price, + quantity=quantity, + is_buy=True, + ) + + price_decimals = first_match_bet_market.quote_token.decimals + chain_format_price = Decimal(str(price)) * Decimal(f"1e{price_decimals}") + expected_price = ((chain_format_price // first_match_bet_market.min_price_tick_size) + * first_match_bet_market.min_price_tick_size + * Decimal(f"1e18")) + chain_format_quantity = Decimal(str(quantity)) + expected_quantity = ((chain_format_quantity // first_match_bet_market.min_quantity_tick_size) + * first_match_bet_market.min_quantity_tick_size + * Decimal(f"1e18")) + chain_format_margin = (chain_format_quantity * chain_format_price) + expected_margin = ((chain_format_margin // first_match_bet_market.min_quantity_tick_size) + * first_match_bet_market.min_quantity_tick_size + * Decimal(f"1e18")) + + assert (order.market_id == first_match_bet_market.id) + assert (order.order_info.subaccount_id == "1") + assert (order.order_info.fee_recipient == fee_recipient) + assert (order.order_info.price == str(int(expected_price))) + assert (order.order_info.quantity == str(int(expected_quantity))) + assert (order.order_type == exchange_pb2.OrderType.BUY) + assert (order.margin == str(int(expected_margin))) + assert (order.trigger_price == "0") diff --git a/tests/test_orderhash.py b/tests/test_orderhash.py index 2aff84a0..c5331e26 100644 --- a/tests/test_orderhash.py +++ b/tests/test_orderhash.py @@ -1,6 +1,6 @@ from pyinjective import PrivateKey from pyinjective.composer import Composer -from pyinjective.constant import Network +from pyinjective.core.network import Network from pyinjective.orderhash import OrderHashManager