Merge pull request #8 from switchboard-xyz/6-python-wrapper-fix
6 python wrapper fix
This commit is contained in:
commit
b580a2beb4
|
@ -1,6 +1,6 @@
|
|||
[[package]]
|
||||
name = "anchorpy"
|
||||
version = "0.9.1"
|
||||
version = "0.9.2"
|
||||
description = "The Python Anchor client."
|
||||
category = "main"
|
||||
optional = false
|
||||
|
@ -8,12 +8,8 @@ python-versions = ">=3.9,<4.0"
|
|||
|
||||
[package.dependencies]
|
||||
apischema = ">=0.16.6,<0.17.0"
|
||||
autoflake = {version = ">=1.4,<2.0", optional = true, markers = "extra == \"cli\""}
|
||||
black = {version = ">=22.3.0,<23.0.0", optional = true, markers = "extra == \"cli\""}
|
||||
borsh-construct = ">=0.1.0,<0.2.0"
|
||||
construct-typing = ">=0.5.1,<0.6.0"
|
||||
genpy = {version = ">=2021.1,<2022.0", optional = true, markers = "extra == \"cli\""}
|
||||
ipython = {version = ">=8.0.1,<9.0.0", optional = true, markers = "extra == \"cli\""}
|
||||
jsonrpcclient = ">=4.0.1,<5.0.0"
|
||||
more-itertools = ">=8.11.0,<9.0.0"
|
||||
pyheck = ">=0.1.4,<0.2.0"
|
||||
|
@ -23,7 +19,6 @@ pytest-xprocess = ">=0.18.1,<0.19.0"
|
|||
solana = ">=0.23.1,<0.23.3"
|
||||
sumtypes = ">=0.1a6,<0.2"
|
||||
toolz = ">=0.11.2,<0.12.0"
|
||||
typer = {version = "0.4.1", optional = true, markers = "extra == \"cli\""}
|
||||
websockets = ">=10.0,<11.0"
|
||||
zstandard = ">=0.17.0,<0.18.0"
|
||||
|
||||
|
@ -59,28 +54,6 @@ python-versions = ">=3.6"
|
|||
examples = ["graphql-core (>=3.0.0)", "attrs", "docstring-parser", "bson", "orjson", "pydantic", "pytest", "sqlalchemy"]
|
||||
graphql = ["graphql-core (>=3.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "appnope"
|
||||
version = "0.1.3"
|
||||
description = "Disable App Nap on macOS >= 10.9"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "asttokens"
|
||||
version = "2.0.5"
|
||||
description = "Annotate AST trees with source code positions"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
six = "*"
|
||||
|
||||
[package.extras]
|
||||
test = ["astroid", "pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "atomicwrites"
|
||||
version = "1.4.0"
|
||||
|
@ -103,25 +76,6 @@ docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
|
|||
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"]
|
||||
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"]
|
||||
|
||||
[[package]]
|
||||
name = "autoflake"
|
||||
version = "1.4"
|
||||
description = "Removes unused imports and unused variables"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
pyflakes = ">=1.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "backcall"
|
||||
version = "0.2.0"
|
||||
description = "Specifications for callback functions passed in to an API"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "base58"
|
||||
version = "2.1.1"
|
||||
|
@ -141,28 +95,6 @@ category = "main"
|
|||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "black"
|
||||
version = "22.3.0"
|
||||
description = "The uncompromising code formatter."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6.2"
|
||||
|
||||
[package.dependencies]
|
||||
click = ">=8.0.0"
|
||||
mypy-extensions = ">=0.4.3"
|
||||
pathspec = ">=0.9.0"
|
||||
platformdirs = ">=2"
|
||||
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||
typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}
|
||||
|
||||
[package.extras]
|
||||
colorama = ["colorama (>=0.4.3)"]
|
||||
d = ["aiohttp (>=3.7.4)"]
|
||||
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
|
||||
uvloop = ["uvloop (>=0.15.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "borsh-construct"
|
||||
version = "0.1.0"
|
||||
|
@ -254,34 +186,6 @@ python-versions = ">=3.7"
|
|||
[package.dependencies]
|
||||
construct = "2.10.67"
|
||||
|
||||
[[package]]
|
||||
name = "decorator"
|
||||
version = "5.1.1"
|
||||
description = "Decorators for Humans"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "executing"
|
||||
version = "0.8.3"
|
||||
description = "Get the currently executing AST node of a frame, and other information"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "genpy"
|
||||
version = "2021.1"
|
||||
description = "AST-based generation of Python source code"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "~=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
numpy = ">=1.6"
|
||||
pytools = ">=2015.1.2"
|
||||
|
||||
[[package]]
|
||||
name = "h11"
|
||||
version = "0.12.0"
|
||||
|
@ -348,56 +252,6 @@ category = "main"
|
|||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "ipython"
|
||||
version = "8.4.0"
|
||||
description = "IPython: Productive Interactive Computing"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
|
||||
[package.dependencies]
|
||||
appnope = {version = "*", markers = "sys_platform == \"darwin\""}
|
||||
backcall = "*"
|
||||
colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
decorator = "*"
|
||||
jedi = ">=0.16"
|
||||
matplotlib-inline = "*"
|
||||
pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""}
|
||||
pickleshare = "*"
|
||||
prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0"
|
||||
pygments = ">=2.4.0"
|
||||
stack-data = "*"
|
||||
traitlets = ">=5"
|
||||
|
||||
[package.extras]
|
||||
all = ["black", "Sphinx (>=1.3)", "ipykernel", "nbconvert", "nbformat", "ipywidgets", "notebook", "ipyparallel", "qtconsole", "pytest (<7.1)", "pytest-asyncio", "testpath", "curio", "matplotlib (!=3.2.0)", "numpy (>=1.19)", "pandas", "trio"]
|
||||
black = ["black"]
|
||||
doc = ["Sphinx (>=1.3)"]
|
||||
kernel = ["ipykernel"]
|
||||
nbconvert = ["nbconvert"]
|
||||
nbformat = ["nbformat"]
|
||||
notebook = ["ipywidgets", "notebook"]
|
||||
parallel = ["ipyparallel"]
|
||||
qtconsole = ["qtconsole"]
|
||||
test = ["pytest (<7.1)", "pytest-asyncio", "testpath"]
|
||||
test_extra = ["pytest (<7.1)", "pytest-asyncio", "testpath", "curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.19)", "pandas", "trio"]
|
||||
|
||||
[[package]]
|
||||
name = "jedi"
|
||||
version = "0.18.1"
|
||||
description = "An autocompletion tool for Python that can be used for text editors."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
parso = ">=0.8.0,<0.9.0"
|
||||
|
||||
[package.extras]
|
||||
qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
|
||||
testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "jinja2"
|
||||
version = "3.1.1"
|
||||
|
@ -460,17 +314,6 @@ category = "dev"
|
|||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "matplotlib-inline"
|
||||
version = "0.1.3"
|
||||
description = "Inline Matplotlib backend for Jupyter"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[package.dependencies]
|
||||
traitlets = "*"
|
||||
|
||||
[[package]]
|
||||
name = "more-itertools"
|
||||
version = "8.12.0"
|
||||
|
@ -479,22 +322,6 @@ category = "main"
|
|||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "mypy-extensions"
|
||||
version = "0.4.3"
|
||||
description = "Experimental type system extensions for programs checked with the mypy typechecker."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "1.22.4"
|
||||
description = "NumPy is the fundamental package for array computing with Python."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
|
||||
[[package]]
|
||||
name = "oslash"
|
||||
version = "0.6.3"
|
||||
|
@ -517,26 +344,6 @@ python-versions = ">=3.6"
|
|||
[package.dependencies]
|
||||
pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
|
||||
|
||||
[[package]]
|
||||
name = "parso"
|
||||
version = "0.8.3"
|
||||
description = "A Python Parser"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.extras]
|
||||
qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
|
||||
testing = ["docopt", "pytest (<6.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pathspec"
|
||||
version = "0.9.0"
|
||||
description = "Utility library for gitignore style pattern matching of file paths."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
|
||||
|
||||
[[package]]
|
||||
name = "pdoc"
|
||||
version = "11.0.0"
|
||||
|
@ -553,37 +360,6 @@ pygments = "*"
|
|||
[package.extras]
|
||||
dev = ["flake8", "hypothesis", "mypy", "pytest", "pytest-cov", "pytest-timeout", "tox"]
|
||||
|
||||
[[package]]
|
||||
name = "pexpect"
|
||||
version = "4.8.0"
|
||||
description = "Pexpect allows easy control of interactive console applications."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
ptyprocess = ">=0.5"
|
||||
|
||||
[[package]]
|
||||
name = "pickleshare"
|
||||
version = "0.7.5"
|
||||
description = "Tiny 'shelve'-like database with concurrency support"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "2.5.2"
|
||||
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"]
|
||||
test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.0.0"
|
||||
|
@ -596,17 +372,6 @@ python-versions = ">=3.6"
|
|||
dev = ["pre-commit", "tox"]
|
||||
testing = ["pytest", "pytest-benchmark"]
|
||||
|
||||
[[package]]
|
||||
name = "prompt-toolkit"
|
||||
version = "3.0.29"
|
||||
description = "Library for building powerful interactive command lines in Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6.2"
|
||||
|
||||
[package.dependencies]
|
||||
wcwidth = "*"
|
||||
|
||||
[[package]]
|
||||
name = "protobuf"
|
||||
version = "3.20.0"
|
||||
|
@ -626,25 +391,6 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|||
[package.extras]
|
||||
test = ["ipaddress", "mock", "unittest2", "enum34", "pywin32", "wmi"]
|
||||
|
||||
[[package]]
|
||||
name = "ptyprocess"
|
||||
version = "0.7.0"
|
||||
description = "Run a subprocess in a pseudo terminal"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "pure-eval"
|
||||
version = "0.2.2"
|
||||
description = "Safely evaluate AST nodes without side effects"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.extras]
|
||||
tests = ["pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "py"
|
||||
version = "1.11.0"
|
||||
|
@ -661,19 +407,11 @@ category = "main"
|
|||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "pyflakes"
|
||||
version = "2.4.0"
|
||||
description = "passive checker of Python programs"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "pygments"
|
||||
version = "2.11.2"
|
||||
description = "Pygments is a syntax highlighting package written in Python."
|
||||
category = "main"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
|
@ -767,19 +505,6 @@ python-versions = ">=3.5"
|
|||
psutil = "*"
|
||||
pytest = ">=2.8"
|
||||
|
||||
[[package]]
|
||||
name = "pytools"
|
||||
version = "2022.1.4"
|
||||
description = "A collection of tools for Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "~=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
numpy = ">=1.6.0"
|
||||
platformdirs = ">=2.2.0"
|
||||
typing_extensions = {version = "*", markers = "python_version < \"3.11\""}
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.26.0"
|
||||
|
@ -850,22 +575,6 @@ types-cachetools = ">=4.2.4,<5.0.0"
|
|||
typing-extensions = ">=3.10.0"
|
||||
websockets = ">=10.1,<11.0"
|
||||
|
||||
[[package]]
|
||||
name = "stack-data"
|
||||
version = "0.2.0"
|
||||
description = "Extract data from python stack frames and tracebacks for informative displays"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
asttokens = "*"
|
||||
executing = "*"
|
||||
pure-eval = "*"
|
||||
|
||||
[package.extras]
|
||||
tests = ["pytest", "typeguard", "pygments", "littleutils", "cython"]
|
||||
|
||||
[[package]]
|
||||
name = "sumtypes"
|
||||
version = "0.1a6"
|
||||
|
@ -885,14 +594,6 @@ category = "main"
|
|||
optional = false
|
||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "2.0.1"
|
||||
description = "A lil' TOML parser"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "toolz"
|
||||
version = "0.11.2"
|
||||
|
@ -901,17 +602,6 @@ category = "main"
|
|||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "traitlets"
|
||||
version = "5.2.2.post1"
|
||||
description = ""
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
test = ["pre-commit", "pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "typer"
|
||||
version = "0.4.1"
|
||||
|
@ -958,14 +648,6 @@ brotli = ["brotlipy (>=0.6.0)"]
|
|||
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
|
||||
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "wcwidth"
|
||||
version = "0.2.5"
|
||||
description = "Measures the displayed width of unicode strings in a terminal"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "websockets"
|
||||
version = "10.1"
|
||||
|
@ -991,12 +673,12 @@ cffi = ["cffi (>=1.11)"]
|
|||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.9"
|
||||
content-hash = "49f6a90d0ae1e8cb1070d767f1c8e63bda4da0bcbe1780a8f8f6af5e555957bd"
|
||||
content-hash = "45003fc29eae952b587685f3106b4f7e95f1169cef8ccf5585b69af5cf3f0751"
|
||||
|
||||
[metadata.files]
|
||||
anchorpy = [
|
||||
{file = "anchorpy-0.9.1-py3-none-any.whl", hash = "sha256:889af502605a20c8c4cc21e71396163ad42c4f2da6b0a6599f166aca23e70676"},
|
||||
{file = "anchorpy-0.9.1.tar.gz", hash = "sha256:172e51b13b42a92b006eb5d91af5430ed95353b6acb07e2112603dbac545126e"},
|
||||
{file = "anchorpy-0.9.2-py3-none-any.whl", hash = "sha256:d977ada7b800507b05ebcec43f4dbcbbb1217e47cf3eda5cb30b32e47e997bc2"},
|
||||
{file = "anchorpy-0.9.2.tar.gz", hash = "sha256:dd1619e4322d9dbeeaafe648b5559cd6051b393cda62fe9694537ba6a529e563"},
|
||||
]
|
||||
anyio = [
|
||||
{file = "anyio-3.4.0-py3-none-any.whl", hash = "sha256:2855a9423524abcdd652d942f8932fda1735210f77a6b392eafd9ff34d3fe020"},
|
||||
|
@ -1006,14 +688,6 @@ apischema = [
|
|||
{file = "apischema-0.16.6-py3-none-any.whl", hash = "sha256:b1ffcc19831fceb99c175ce53d81125bb46b8b22a019f4d8307f6d23f13e5647"},
|
||||
{file = "apischema-0.16.6.tar.gz", hash = "sha256:5e53830269d17a3586103c71d7961f23df5fe8844f93afbcc3e7a1a7cbac0c75"},
|
||||
]
|
||||
appnope = [
|
||||
{file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"},
|
||||
{file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"},
|
||||
]
|
||||
asttokens = [
|
||||
{file = "asttokens-2.0.5-py2.py3-none-any.whl", hash = "sha256:0844691e88552595a6f4a4281a9f7f79b8dd45ca4ccea82e5e05b4bbdb76705c"},
|
||||
{file = "asttokens-2.0.5.tar.gz", hash = "sha256:9a54c114f02c7a9480d56550932546a3f1fe71d8a02f1bc7ccd0ee3ee35cf4d5"},
|
||||
]
|
||||
atomicwrites = [
|
||||
{file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
|
||||
{file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
|
||||
|
@ -1022,13 +696,6 @@ attrs = [
|
|||
{file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"},
|
||||
{file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"},
|
||||
]
|
||||
autoflake = [
|
||||
{file = "autoflake-1.4.tar.gz", hash = "sha256:61a353012cff6ab94ca062823d1fb2f692c4acda51c76ff83a8d77915fba51ea"},
|
||||
]
|
||||
backcall = [
|
||||
{file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"},
|
||||
{file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"},
|
||||
]
|
||||
base58 = [
|
||||
{file = "base58-2.1.1-py3-none-any.whl", hash = "sha256:11a36f4d3ce51dfc1043f3218591ac4eb1ceb172919cebe05b52a5bcc8d245c2"},
|
||||
{file = "base58-2.1.1.tar.gz", hash = "sha256:c5d0cb3f5b6e81e8e35da5754388ddcc6d0d14b6c6a132cb93d69ed580a7278c"},
|
||||
|
@ -1049,31 +716,6 @@ based58 = [
|
|||
{file = "based58-0.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:ab85804a401a7b5a7141fbb14ef5b5f7d85288357d1d3f0085d47e616cef8f5a"},
|
||||
{file = "based58-0.1.1.tar.gz", hash = "sha256:80804b346b34196c89dc7a3dc89b6021f910f4cd75aac41d433ca1880b1672dc"},
|
||||
]
|
||||
black = [
|
||||
{file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"},
|
||||
{file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"},
|
||||
{file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"},
|
||||
{file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"},
|
||||
{file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"},
|
||||
{file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"},
|
||||
{file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"},
|
||||
{file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"},
|
||||
{file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"},
|
||||
{file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"},
|
||||
{file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"},
|
||||
{file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"},
|
||||
{file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"},
|
||||
{file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"},
|
||||
{file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"},
|
||||
{file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"},
|
||||
{file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"},
|
||||
{file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"},
|
||||
{file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"},
|
||||
{file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"},
|
||||
{file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"},
|
||||
{file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"},
|
||||
{file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"},
|
||||
]
|
||||
borsh-construct = [
|
||||
{file = "borsh-construct-0.1.0.tar.gz", hash = "sha256:c916758ceba70085d8f456a1cc26991b88cb64233d347767766473b651b37263"},
|
||||
{file = "borsh_construct-0.1.0-py3-none-any.whl", hash = "sha256:f584c791e2a03f8fc36e6c13011a27bcaf028c9c54ba89cd70f485a7d1c687ed"},
|
||||
|
@ -1157,17 +799,6 @@ construct-typing = [
|
|||
{file = "construct-typing-0.5.2.tar.gz", hash = "sha256:26da1ed7383c5dfe7f38a43c6281ad06bce2059bf02d5a0d2cc3c0e52632c0bd"},
|
||||
{file = "construct_typing-0.5.2-py3-none-any.whl", hash = "sha256:553ecf36b44ae8d87e2f9c28a6fc8ffd75d050bd0b66ac72e433046c45b52116"},
|
||||
]
|
||||
decorator = [
|
||||
{file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"},
|
||||
{file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"},
|
||||
]
|
||||
executing = [
|
||||
{file = "executing-0.8.3-py2.py3-none-any.whl", hash = "sha256:d1eef132db1b83649a3905ca6dd8897f71ac6f8cac79a7e58a1a09cf137546c9"},
|
||||
{file = "executing-0.8.3.tar.gz", hash = "sha256:c6554e21c6b060590a6d3be4b82fb78f8f0194d809de5ea7df1c093763311501"},
|
||||
]
|
||||
genpy = [
|
||||
{file = "genpy-2021.1.tar.gz", hash = "sha256:9bc062fa98c5c466ff464d8974be81a6bf67af9247b5e5176215ad1e81a6cdac"},
|
||||
]
|
||||
h11 = [
|
||||
{file = "h11-0.12.0-py3-none-any.whl", hash = "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6"},
|
||||
{file = "h11-0.12.0.tar.gz", hash = "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"},
|
||||
|
@ -1192,14 +823,6 @@ iniconfig = [
|
|||
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
|
||||
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
|
||||
]
|
||||
ipython = [
|
||||
{file = "ipython-8.4.0-py3-none-any.whl", hash = "sha256:7ca74052a38fa25fe9bedf52da0be7d3fdd2fb027c3b778ea78dfe8c212937d1"},
|
||||
{file = "ipython-8.4.0.tar.gz", hash = "sha256:f2db3a10254241d9b447232cec8b424847f338d9d36f9a577a6192c332a46abd"},
|
||||
]
|
||||
jedi = [
|
||||
{file = "jedi-0.18.1-py2.py3-none-any.whl", hash = "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d"},
|
||||
{file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"},
|
||||
]
|
||||
jinja2 = [
|
||||
{file = "Jinja2-3.1.1-py3-none-any.whl", hash = "sha256:539835f51a74a69f41b848a9645dbdc35b4f20a3b601e2d9a7e22947b15ff119"},
|
||||
{file = "Jinja2-3.1.1.tar.gz", hash = "sha256:640bed4bb501cbd17194b3cace1dc2126f5b619cf068a726b98192a0fde74ae9"},
|
||||
|
@ -1256,42 +879,10 @@ markupsafe = [
|
|||
{file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"},
|
||||
{file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"},
|
||||
]
|
||||
matplotlib-inline = [
|
||||
{file = "matplotlib-inline-0.1.3.tar.gz", hash = "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee"},
|
||||
{file = "matplotlib_inline-0.1.3-py3-none-any.whl", hash = "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c"},
|
||||
]
|
||||
more-itertools = [
|
||||
{file = "more-itertools-8.12.0.tar.gz", hash = "sha256:7dc6ad46f05f545f900dd59e8dfb4e84a4827b97b3cfecb175ea0c7d247f6064"},
|
||||
{file = "more_itertools-8.12.0-py3-none-any.whl", hash = "sha256:43e6dd9942dffd72661a2c4ef383ad7da1e6a3e968a927ad7a6083ab410a688b"},
|
||||
]
|
||||
mypy-extensions = [
|
||||
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
|
||||
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
|
||||
]
|
||||
numpy = [
|
||||
{file = "numpy-1.22.4-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:ba9ead61dfb5d971d77b6c131a9dbee62294a932bf6a356e48c75ae684e635b3"},
|
||||
{file = "numpy-1.22.4-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:1ce7ab2053e36c0a71e7a13a7475bd3b1f54750b4b433adc96313e127b870887"},
|
||||
{file = "numpy-1.22.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7228ad13744f63575b3a972d7ee4fd61815b2879998e70930d4ccf9ec721dce0"},
|
||||
{file = "numpy-1.22.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:43a8ca7391b626b4c4fe20aefe79fec683279e31e7c79716863b4b25021e0e74"},
|
||||
{file = "numpy-1.22.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a911e317e8c826ea632205e63ed8507e0dc877dcdc49744584dfc363df9ca08c"},
|
||||
{file = "numpy-1.22.4-cp310-cp310-win32.whl", hash = "sha256:9ce7df0abeabe7fbd8ccbf343dc0db72f68549856b863ae3dd580255d009648e"},
|
||||
{file = "numpy-1.22.4-cp310-cp310-win_amd64.whl", hash = "sha256:3e1ffa4748168e1cc8d3cde93f006fe92b5421396221a02f2274aab6ac83b077"},
|
||||
{file = "numpy-1.22.4-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:59d55e634968b8f77d3fd674a3cf0b96e85147cd6556ec64ade018f27e9479e1"},
|
||||
{file = "numpy-1.22.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c1d937820db6e43bec43e8d016b9b3165dcb42892ea9f106c70fb13d430ffe72"},
|
||||
{file = "numpy-1.22.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4c5d5eb2ec8da0b4f50c9a843393971f31f1d60be87e0fb0917a49133d257d6"},
|
||||
{file = "numpy-1.22.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64f56fc53a2d18b1924abd15745e30d82a5782b2cab3429aceecc6875bd5add0"},
|
||||
{file = "numpy-1.22.4-cp38-cp38-win32.whl", hash = "sha256:fb7a980c81dd932381f8228a426df8aeb70d59bbcda2af075b627bbc50207cba"},
|
||||
{file = "numpy-1.22.4-cp38-cp38-win_amd64.whl", hash = "sha256:e96d7f3096a36c8754207ab89d4b3282ba7b49ea140e4973591852c77d09eb76"},
|
||||
{file = "numpy-1.22.4-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:4c6036521f11a731ce0648f10c18ae66d7143865f19f7299943c985cdc95afb5"},
|
||||
{file = "numpy-1.22.4-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:b89bf9b94b3d624e7bb480344e91f68c1c6c75f026ed6755955117de00917a7c"},
|
||||
{file = "numpy-1.22.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2d487e06ecbf1dc2f18e7efce82ded4f705f4bd0cd02677ffccfb39e5c284c7e"},
|
||||
{file = "numpy-1.22.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3eb268dbd5cfaffd9448113539e44e2dd1c5ca9ce25576f7c04a5453edc26fa"},
|
||||
{file = "numpy-1.22.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37431a77ceb9307c28382c9773da9f306435135fae6b80b62a11c53cfedd8802"},
|
||||
{file = "numpy-1.22.4-cp39-cp39-win32.whl", hash = "sha256:cc7f00008eb7d3f2489fca6f334ec19ca63e31371be28fd5dad955b16ec285bd"},
|
||||
{file = "numpy-1.22.4-cp39-cp39-win_amd64.whl", hash = "sha256:f0725df166cf4785c0bc4cbfb320203182b1ecd30fee6e541c8752a92df6aa32"},
|
||||
{file = "numpy-1.22.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0791fbd1e43bf74b3502133207e378901272f3c156c4df4954cad833b1380207"},
|
||||
{file = "numpy-1.22.4.zip", hash = "sha256:425b390e4619f58d8526b3dcf656dde069133ae5c240229821f01b5f44ea07af"},
|
||||
]
|
||||
oslash = [
|
||||
{file = "OSlash-0.6.3-py3-none-any.whl", hash = "sha256:89b978443b7db3ac2666106bdc3680add3c886a6d8fcdd02fd062af86d29494f"},
|
||||
{file = "OSlash-0.6.3.tar.gz", hash = "sha256:868aeb58a656f2ed3b73d9dd6abe387b20b74fc9413d3e8653b615b15bf728f3"},
|
||||
|
@ -1300,38 +891,14 @@ packaging = [
|
|||
{file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
|
||||
{file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
|
||||
]
|
||||
parso = [
|
||||
{file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"},
|
||||
{file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"},
|
||||
]
|
||||
pathspec = [
|
||||
{file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"},
|
||||
{file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
|
||||
]
|
||||
pdoc = [
|
||||
{file = "pdoc-11.0.0-py3-none-any.whl", hash = "sha256:36922f9eebf90a5e546ab4e7d92d4dbf9f2cdae7679fbc9b1a0906ef8ef03214"},
|
||||
{file = "pdoc-11.0.0.tar.gz", hash = "sha256:722b4ff662574033de50b3061e55a81e5b0b54ff460f52f0c8a4abc25f08ce5b"},
|
||||
]
|
||||
pexpect = [
|
||||
{file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"},
|
||||
{file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"},
|
||||
]
|
||||
pickleshare = [
|
||||
{file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"},
|
||||
{file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"},
|
||||
]
|
||||
platformdirs = [
|
||||
{file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"},
|
||||
{file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"},
|
||||
]
|
||||
pluggy = [
|
||||
{file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
|
||||
{file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
|
||||
]
|
||||
prompt-toolkit = [
|
||||
{file = "prompt_toolkit-3.0.29-py3-none-any.whl", hash = "sha256:62291dad495e665fca0bda814e342c69952086afb0f4094d0893d357e5c78752"},
|
||||
{file = "prompt_toolkit-3.0.29.tar.gz", hash = "sha256:bd640f60e8cecd74f0dc249713d433ace2ddc62b65ee07f96d358e0b152b6ea7"},
|
||||
]
|
||||
protobuf = [
|
||||
{file = "protobuf-3.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9d0f3aca8ca51c8b5e204ab92bd8afdb2a8e3df46bd0ce0bd39065d79aabcaa4"},
|
||||
{file = "protobuf-3.20.0-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:001c2160c03b6349c04de39cf1a58e342750da3632f6978a1634a3dcca1ec10e"},
|
||||
|
@ -1388,14 +955,6 @@ psutil = [
|
|||
{file = "psutil-5.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:f4634b033faf0d968bb9220dd1c793b897ab7f1189956e1aa9eae752527127d3"},
|
||||
{file = "psutil-5.8.0.tar.gz", hash = "sha256:0c9ccb99ab76025f2f0bbecf341d4656e9c1351db8cc8a03ccd62e318ab4b5c6"},
|
||||
]
|
||||
ptyprocess = [
|
||||
{file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"},
|
||||
{file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"},
|
||||
]
|
||||
pure-eval = [
|
||||
{file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"},
|
||||
{file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"},
|
||||
]
|
||||
py = [
|
||||
{file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
|
||||
{file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
|
||||
|
@ -1404,10 +963,6 @@ pycparser = [
|
|||
{file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
|
||||
{file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
|
||||
]
|
||||
pyflakes = [
|
||||
{file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"},
|
||||
{file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"},
|
||||
]
|
||||
pygments = [
|
||||
{file = "Pygments-2.11.2-py3-none-any.whl", hash = "sha256:44238f1b60a76d78fc8ca0528ee429702aae011c265fe6a8dd8b63049ae41c65"},
|
||||
{file = "Pygments-2.11.2.tar.gz", hash = "sha256:4e426f72023d88d03b2fa258de560726ce890ff3b630f88c21cbb8b2503b8c6a"},
|
||||
|
@ -1487,9 +1042,6 @@ pytest-xprocess = [
|
|||
{file = "pytest-xprocess-0.18.1.tar.gz", hash = "sha256:fd9f30ed1584b5833bc34494748adf0fb9de3ca7bacc4e88ad71989c21cba266"},
|
||||
{file = "pytest_xprocess-0.18.1-py3-none-any.whl", hash = "sha256:6f2aba817d842518d9d9dfb7e9adfe2a6e354a4359f4166bef0822ef4be1c9db"},
|
||||
]
|
||||
pytools = [
|
||||
{file = "pytools-2022.1.4.tar.gz", hash = "sha256:ae25f7c9b196fcd0d15e53bfe05236fe7bc5efd923810fbaeeee1a4bc4b6764a"},
|
||||
]
|
||||
requests = [
|
||||
{file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"},
|
||||
{file = "requests-2.26.0.tar.gz", hash = "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"},
|
||||
|
@ -1510,10 +1062,6 @@ solana = [
|
|||
{file = "solana-0.23.2-py3-none-any.whl", hash = "sha256:6c43a6013bc0b5358cafd94a4fa091d30f7917fe578960329a8977b9dd1b21a5"},
|
||||
{file = "solana-0.23.2.tar.gz", hash = "sha256:57c98be97d944440146780a4e175c0dbf50a988d75f05d81b5083620bf4331b0"},
|
||||
]
|
||||
stack-data = [
|
||||
{file = "stack_data-0.2.0-py3-none-any.whl", hash = "sha256:999762f9c3132308789affa03e9271bbbe947bf78311851f4d485d8402ed858e"},
|
||||
{file = "stack_data-0.2.0.tar.gz", hash = "sha256:45692d41bd633a9503a5195552df22b583caf16f0b27c4e58c98d88c8b648e12"},
|
||||
]
|
||||
sumtypes = [
|
||||
{file = "sumtypes-0.1a6-py2.py3-none-any.whl", hash = "sha256:3e9d71322dd927d25d935072f8be7daec655ea292fd392359a5bb2c1e53dfdc3"},
|
||||
{file = "sumtypes-0.1a6.tar.gz", hash = "sha256:1a6ff095e06a1885f340ddab803e0f38e3f9bed81f9090164ca9682e04e96b43"},
|
||||
|
@ -1522,18 +1070,10 @@ toml = [
|
|||
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
|
||||
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
|
||||
]
|
||||
tomli = [
|
||||
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
|
||||
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
||||
]
|
||||
toolz = [
|
||||
{file = "toolz-0.11.2-py3-none-any.whl", hash = "sha256:a5700ce83414c64514d82d60bcda8aabfde092d1c1a8663f9200c07fdcc6da8f"},
|
||||
{file = "toolz-0.11.2.tar.gz", hash = "sha256:6b312d5e15138552f1bda8a4e66c30e236c831b612b2bf0005f8a1df10a4bc33"},
|
||||
]
|
||||
traitlets = [
|
||||
{file = "traitlets-5.2.2.post1-py3-none-any.whl", hash = "sha256:1530d04badddc6a73d50b7ee34667d4b96914da352109117b4280cb56523a51b"},
|
||||
{file = "traitlets-5.2.2.post1.tar.gz", hash = "sha256:74803a1baa59af70f023671d86d5c7a834c931186df26d50d362ee6a1ff021fd"},
|
||||
]
|
||||
typer = [
|
||||
{file = "typer-0.4.1-py3-none-any.whl", hash = "sha256:e8467f0ebac0c81366c2168d6ad9f888efdfb6d4e1d3d5b4a004f46fa444b5c3"},
|
||||
{file = "typer-0.4.1.tar.gz", hash = "sha256:5646aef0d936b2c761a10393f0384ee6b5c7fe0bb3e5cd710b17134ca1d99cff"},
|
||||
|
@ -1551,10 +1091,6 @@ urllib3 = [
|
|||
{file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"},
|
||||
{file = "urllib3-1.26.7.tar.gz", hash = "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece"},
|
||||
]
|
||||
wcwidth = [
|
||||
{file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
|
||||
{file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
|
||||
]
|
||||
websockets = [
|
||||
{file = "websockets-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:38db6e2163b021642d0a43200ee2dec8f4980bdbda96db54fde72b283b54cbfc"},
|
||||
{file = "websockets-10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e1b60fd297adb9fc78375778a5220da7f07bf54d2a33ac781319650413fc6a60"},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "switchboardpy"
|
||||
version = "0.0.5"
|
||||
version = "0.0.7"
|
||||
description = "Switchboard V2 API"
|
||||
repository = "https://github.com/switchboard-xyz/switchboard-v2/tree/main/libraries/py"
|
||||
homepage = "https://docs.switchboard.xyz"
|
||||
|
@ -9,7 +9,7 @@ license = "MIT"
|
|||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.9"
|
||||
anchorpy = {extras = ["cli"], version = "^0.9.1"}
|
||||
anchorpy = "^0.9.2"
|
||||
anyio = "3.4.0"
|
||||
apischema = "0.16.6"
|
||||
attrs = "21.2.0"
|
||||
|
@ -55,6 +55,7 @@ urllib3 = "1.26.7"
|
|||
websockets = "10.1"
|
||||
zstandard = ">=0.17.0"
|
||||
typer = "^0.4.1"
|
||||
pytest-xprocess = "0.18.1"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "6.2.5"
|
||||
|
|
|
@ -6,7 +6,7 @@ from switchboardpy.aggregator import (
|
|||
AggregatorInitParams,
|
||||
AggregatorOpenRoundParams,
|
||||
AggregatorSaveResultParams,
|
||||
AggregatorSetHistoryBufferParams
|
||||
AggregatorSetHistoryBufferParams,
|
||||
)
|
||||
from switchboardpy.compiled import OracleJob
|
||||
from switchboardpy.common import SBV2_DEVNET_PID, AccountParams, SwitchboardDecimal
|
||||
|
@ -49,5 +49,7 @@ __all__ = [
|
|||
"ProgramStateAccount",
|
||||
"ProgramInitParams",
|
||||
"VaultTransferParams",
|
||||
"SwitchboardDecimal"
|
||||
"SwitchboardDecimal",
|
||||
"readRawVarint32",
|
||||
"readDelimitedFrom"
|
||||
]
|
|
@ -11,14 +11,17 @@ from typing import Optional, Any, NamedTuple
|
|||
|
||||
from solana.keypair import Keypair
|
||||
from solana.publickey import PublicKey
|
||||
from spl.token.async_client import AsyncToken
|
||||
from spl.token.constants import TOKEN_PROGRAM_ID
|
||||
from solana.transaction import TransactionSignature
|
||||
from spl.token.instructions import get_associated_token_address
|
||||
from solana.rpc.commitment import Confirmed
|
||||
from solana.system_program import CreateAccountParams, create_account
|
||||
|
||||
from spl.token.async_client import AsyncToken
|
||||
from spl.token.constants import TOKEN_PROGRAM_ID
|
||||
from spl.token.instructions import get_associated_token_address
|
||||
|
||||
from switchboardpy.compiled import OracleJob
|
||||
from switchboardpy.common import AccountParams, SwitchboardDecimal
|
||||
from switchboardpy.common import AccountParams, SwitchboardDecimal, parseOracleJob
|
||||
|
||||
from switchboardpy.program import ProgramStateAccount
|
||||
from switchboardpy.oraclequeue import OracleQueueAccount
|
||||
from switchboardpy.oracle import OracleAccount
|
||||
|
@ -26,6 +29,8 @@ from switchboardpy.job import JobAccount
|
|||
from switchboardpy.lease import LeaseAccount
|
||||
from switchboardpy.permission import PermissionAccount
|
||||
|
||||
from .generated.accounts import AggregatorAccountData
|
||||
|
||||
# Parameters for which oracles must submit for responding to update requests.
|
||||
@dataclass
|
||||
class AggregatorSaveResultParams:
|
||||
|
@ -64,7 +69,6 @@ class AggregatorSaveResultParams:
|
|||
oracles: list[Any]
|
||||
|
||||
|
||||
|
||||
# Parameters for creating and setting a history buffer
|
||||
@dataclass
|
||||
class AggregatorSetHistoryBufferParams:
|
||||
|
@ -75,6 +79,16 @@ class AggregatorSetHistoryBufferParams:
|
|||
"""Authority keypair for the aggregator"""
|
||||
authority: Keypair = None
|
||||
|
||||
# Parameters for creating and setting a history buffer
|
||||
@dataclass
|
||||
class AggregatorSetUpdateIntervalParams:
|
||||
|
||||
"""Seconds between updates"""
|
||||
new_interval: int
|
||||
|
||||
"""Authority keypair for the aggregator"""
|
||||
authority: Keypair = None
|
||||
|
||||
# Parameters required to open an aggregator round
|
||||
@dataclass
|
||||
class AggregatorOpenRoundParams:
|
||||
|
@ -85,6 +99,80 @@ class AggregatorOpenRoundParams:
|
|||
"""The token wallet which will receive rewards for calling update on this feed."""
|
||||
payout_wallet: PublicKey
|
||||
|
||||
"""
|
||||
Data feeds on a crank are ordered by their next available update time with some
|
||||
level of jitter to mitigate oracles being assigned to the same update request upon
|
||||
each iteration of the queue, which makes them susceptible to a malicous oracle.
|
||||
"""
|
||||
jitter: int = None
|
||||
|
||||
# Result of returning loadedJobs
|
||||
@dataclass
|
||||
class AggregatorLoadedJob:
|
||||
|
||||
"""The oracle queue from which oracles are assigned this update."""
|
||||
job: OracleJob
|
||||
|
||||
"""Public Key of a given job"""
|
||||
public_key: PublicKey
|
||||
|
||||
"""Job account data"""
|
||||
account: Any
|
||||
|
||||
|
||||
|
||||
# Parameters required to set min jobs for Aggregator
|
||||
@dataclass
|
||||
class AggregatorSetMinJobsParams:
|
||||
|
||||
"""The min number of jobs required"""
|
||||
min_job_results: int
|
||||
|
||||
"""The feed authority."""
|
||||
authority: Keypair = None
|
||||
|
||||
|
||||
# Parameters required to set batch size for Aggregator
|
||||
@dataclass
|
||||
class AggregatorSetBatchSizeParams:
|
||||
|
||||
"""The batch size."""
|
||||
batch_size: int
|
||||
|
||||
"""The feed authority."""
|
||||
authority: Keypair = None
|
||||
|
||||
|
||||
# Parameters required to set min oracles for Aggregator
|
||||
@dataclass
|
||||
class AggregatorSetMinOraclesParams:
|
||||
|
||||
"""The min results required"""
|
||||
min_oracle_results: int
|
||||
|
||||
"""The feed authority."""
|
||||
authority: Keypair = None
|
||||
|
||||
|
||||
# Parameters required to set min oracles for Aggregator
|
||||
@dataclass
|
||||
class AggregatorSetQueueParams:
|
||||
|
||||
"""The min results required"""
|
||||
queue_account: OracleQueueAccount
|
||||
|
||||
"""The feed authority."""
|
||||
authority: Keypair = None
|
||||
|
||||
# Parameters required to set min oracles for Aggregator
|
||||
@dataclass
|
||||
class AggregatorSetVarianceThresholdParams:
|
||||
|
||||
"""The % change needed to trigger an update"""
|
||||
threshold: Decimal
|
||||
|
||||
"""The feed authority."""
|
||||
authority: Keypair = None
|
||||
|
||||
# Init Params for Aggregators
|
||||
@dataclass
|
||||
|
@ -149,6 +237,9 @@ class AggregatorInitParams:
|
|||
"""
|
||||
authority: PublicKey = None
|
||||
|
||||
"""Disable automatic updates"""
|
||||
disable_crank: bool = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class AggregatorHistoryRow:
|
||||
|
@ -228,9 +319,8 @@ class AggregatorAccount:
|
|||
AccountInvalidDiscriminator: If the discriminator doesn't match the IDL.
|
||||
"""
|
||||
async def load_data(self):
|
||||
aggregator = await self.program.account["AggregatorAccountData"].fetch(self.public_key)
|
||||
aggregator.ebuf = None
|
||||
return aggregator
|
||||
return await AggregatorAccountData.fetch(self.program.provider.connection, self.public_key)
|
||||
|
||||
|
||||
"""
|
||||
Get AggregatorAccount historical data
|
||||
|
@ -350,11 +440,14 @@ class AggregatorAccount:
|
|||
last_timestamp = aggregator.latest_confirmed_round.round_open_timestamp
|
||||
if last_timestamp + force_report_period < timestamp:
|
||||
return True
|
||||
if value < latest_result - variance_threshold:
|
||||
diff = latest_result / value
|
||||
if abs(diff) > 1:
|
||||
diff = value / latest_result
|
||||
if diff < 0:
|
||||
return True
|
||||
if value > latest_result + variance_threshold:
|
||||
return True
|
||||
return False
|
||||
|
||||
change_percentage = 1 - diff * 100
|
||||
return change_percentage > variance_threshold
|
||||
|
||||
"""
|
||||
Get the individual oracle results of the latest confirmed round.
|
||||
|
@ -410,7 +503,7 @@ class AggregatorAccount:
|
|||
aggregator (Any): Optional aggregator
|
||||
|
||||
Returns:
|
||||
jobs (list[OracleJob]): latest feed timestamp as hex string
|
||||
jobs (list[{ "job": OracleJob, "public_key": PublicKey, "account": JobAccountData }])
|
||||
|
||||
Raises:
|
||||
ValueError: Failed to load feed jobs.
|
||||
|
@ -420,12 +513,12 @@ class AggregatorAccount:
|
|||
async def load_jobs(self, aggregator: Optional[Any] = None) -> Decimal:
|
||||
coder = anchorpy.AccountsCoder(self.program.idl)
|
||||
aggregator = aggregator if aggregator else await self.load_data()
|
||||
job_accounts_raw = await anchorpy.utils.rpc.get_multiple_accounts(self.program.provider, aggregator.job_pubkeys_data)[:aggregator.job_pubkeys_size]
|
||||
job_accounts_raw = await anchorpy.utils.rpc.get_multiple_accounts(self.program.provider.connection, aggregator.job_pubkeys_data[:aggregator.job_pubkeys_size], 10, Confirmed)
|
||||
if not job_accounts_raw:
|
||||
raise ValueError('Failed to load feed jobs.')
|
||||
|
||||
# Deserialize OracleJob objects from each decoded JobAccountData
|
||||
return [OracleJob.ParseFromString(coder.decode(job)) for job in job_accounts_raw]
|
||||
return [AggregatorLoadedJob(parseOracleJob(coder.decode(job.account.data).data), job.pubkey, coder.decode(job.account.data)) for job in job_accounts_raw]
|
||||
|
||||
"""
|
||||
Load all job hashes for each job stored in this aggregator
|
||||
|
@ -443,12 +536,12 @@ class AggregatorAccount:
|
|||
async def load_hashes(self, aggregator: Optional[Any] = None) -> Decimal:
|
||||
coder = anchorpy.AccountsCoder(self.program.idl)
|
||||
aggregator = aggregator if aggregator else await self.loadData()
|
||||
job_accounts_raw = await anchorpy.utils.rpc.get_multiple_accounts(self.program.provider, aggregator.job_pubkeys_data)[:aggregator.job_pubkeys_size]
|
||||
job_accounts_raw = await anchorpy.utils.rpc.get_multiple_accounts(self.program.provider.connection, aggregator.job_pubkeys_data[:aggregator.job_pubkeys_size])
|
||||
if not job_accounts_raw:
|
||||
raise ValueError('Failed to load feed jobs.')
|
||||
|
||||
# get hashes from each decoded JobAccountData
|
||||
return [coder.decode(job).hash for job in job_accounts_raw]
|
||||
return [coder.decode(job.account.data).hash for job in job_accounts_raw]
|
||||
|
||||
|
||||
"""
|
||||
|
@ -479,7 +572,7 @@ class AggregatorAccount:
|
|||
state = await state_account.load_data()
|
||||
response = await program.provider.connection.get_minimum_balance_for_rent_exemption(size)
|
||||
lamports = response["result"]
|
||||
zero_decimal = program.type['SwitchboardDecimal'](0, 0)
|
||||
zero_decimal = SwitchboardDecimal(0, 0).as_proper_sbd(program)
|
||||
|
||||
await program.rpc["aggregator_init"](
|
||||
{
|
||||
|
@ -493,7 +586,8 @@ class AggregatorAccount:
|
|||
"force_report_period": aggregator_init_params.force_report_period or 0,
|
||||
"expiration": aggregator_init_params.expiration or 0,
|
||||
"state_bump": state_bump,
|
||||
"start_after": aggregator_init_params.start_after,
|
||||
"disable_crank": aggregator_init_params.disable_crank or False,
|
||||
"start_after": aggregator_init_params.start_after or 0,
|
||||
},
|
||||
ctx=anchorpy.Context(
|
||||
accounts={
|
||||
|
@ -561,16 +655,23 @@ class AggregatorAccount:
|
|||
)
|
||||
)
|
||||
|
||||
# TODO: Verify this function
|
||||
"""
|
||||
Open round on aggregator to get an update
|
||||
|
||||
Args:
|
||||
program (anchorpy.Program): Switchboard program representation holding connection and IDL
|
||||
params (AggregatorOpenRoundParams)
|
||||
|
||||
Returns:
|
||||
TransactionSignature
|
||||
"""
|
||||
async def open_round(self, params: AggregatorOpenRoundParams):
|
||||
program = self.program
|
||||
authority = params.authority or self.keypair
|
||||
state_account, state_bump = ProgramStateAccount.from_seed(program)
|
||||
mint = await state_account.get_token_mint()
|
||||
queue = await params.oracle_queue_account.load_data()
|
||||
lease_account, lease_bump = LeaseAccount.from_seed(
|
||||
self.program,
|
||||
queue_account,
|
||||
params.oracle_queue_account,
|
||||
self
|
||||
)
|
||||
lease = await lease_account.load_data()
|
||||
|
@ -580,17 +681,18 @@ class AggregatorAccount:
|
|||
params.oracle_queue_account.public_key,
|
||||
self.public_key
|
||||
)
|
||||
await program.rpc["aggregator_open_round"](
|
||||
return await program.rpc["aggregator_open_round"](
|
||||
{
|
||||
"state_bump": state_bump,
|
||||
"lease_bump": lease_bump,
|
||||
"permission_bump": permission_bump,
|
||||
"jitter": params.jitter or 0
|
||||
},
|
||||
ctx=anchorpy.Context(
|
||||
accounts={
|
||||
"aggregator": self.public_key,
|
||||
"lease": self.public_key,
|
||||
"oracle_queue": self.public_key,
|
||||
"lease": lease_account.public_key,
|
||||
"oracle_queue": params.oracle_queue_account.public_key,
|
||||
"queue_authority": queue.authority,
|
||||
"permission": permission_account.public_key,
|
||||
"escrow": lease.escrow,
|
||||
|
@ -598,9 +700,58 @@ class AggregatorAccount:
|
|||
"payout_wallet": params.payout_wallet,
|
||||
"token_program": TOKEN_PROGRAM_ID,
|
||||
"data_buffer": queue.data_buffer,
|
||||
"mint": mint.public_key,
|
||||
"mint": (await params.oracle_queue_account.load_mint()).pubkey,
|
||||
},
|
||||
signers=[self.keypair]
|
||||
)
|
||||
)
|
||||
|
||||
"""
|
||||
Set min jobs sets the min jobs parameter. This is a suggestion to oracles
|
||||
of the number of jobs that must resolve for a job to be considered valid.
|
||||
|
||||
Args:
|
||||
params (AggregatorSetMinJobsParams): parameters pecifying the min jobs that must respond
|
||||
Returns:
|
||||
TransactionSignature
|
||||
|
||||
"""
|
||||
async def set_min_jobs(self, params: AggregatorSetMinJobsParams):
|
||||
authority = authority or self.keypair
|
||||
return await self.program.rpc['aggregator_set_min_jobs'](
|
||||
{
|
||||
"min_job_results": params.min_job_results
|
||||
},
|
||||
ctx=anchorpy.Context(
|
||||
accounts={
|
||||
"aggregator": self.public_key,
|
||||
"authority": authority.public_key,
|
||||
},
|
||||
signers=[authority]
|
||||
)
|
||||
)
|
||||
|
||||
"""
|
||||
Set min oracles sets the min oracles parameter. This will determine how many oracles need to come back with a
|
||||
valid response for a result to be accepted.
|
||||
|
||||
Args:
|
||||
params (AggregatorSetMinOraclesParams): parameters pecifying the min jobs that must respond
|
||||
Returns:
|
||||
TransactionSignature
|
||||
|
||||
"""
|
||||
async def set_min_jobs(self, params: AggregatorSetMinJobsParams):
|
||||
authority = authority or self.keypair
|
||||
return await self.program.rpc['aggregator_set_min_jobs'](
|
||||
{
|
||||
"min_job_results": params.min_job_results
|
||||
},
|
||||
ctx=anchorpy.Context(
|
||||
accounts={
|
||||
"aggregator": self.public_key,
|
||||
"authority": authority.public_key,
|
||||
},
|
||||
signers=[authority]
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -613,12 +764,12 @@ class AggregatorAccount:
|
|||
Returns:
|
||||
TransactionSignature
|
||||
"""
|
||||
async def add_job(self, job: JobAccount, authority: Optional[Keypair] = None) -> TransactionSignature:
|
||||
async def add_job(self, job: JobAccount, weight: int = 0, authority: Optional[Keypair] = None) -> TransactionSignature:
|
||||
authority = authority or self.keypair
|
||||
|
||||
return await self.program.rpc['aggregator_add_job'](
|
||||
{
|
||||
"params": None
|
||||
"weight": weight
|
||||
},
|
||||
ctx=anchorpy.Context(
|
||||
accounts={
|
||||
|
@ -629,6 +780,102 @@ class AggregatorAccount:
|
|||
signers=[authority]
|
||||
)
|
||||
)
|
||||
|
||||
"""
|
||||
RPC Set batch size / the number of oracles that'll respond to updates
|
||||
|
||||
Args:
|
||||
params (AggregatorSetBatchSizeParams)
|
||||
Returns:
|
||||
TransactionSignature
|
||||
"""
|
||||
async def set_batch_size(self, params: AggregatorSetBatchSizeParams) -> TransactionSignature:
|
||||
authority = authority or self.keypair
|
||||
return await self.program.rpc['aggregator_set_batch_size'](
|
||||
{
|
||||
"batch_size": params.batch_size
|
||||
},
|
||||
ctx=anchorpy.Context(
|
||||
accounts={
|
||||
"aggregator": self.public_key,
|
||||
"authority": authority.public_key,
|
||||
},
|
||||
signers=[authority]
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
"""
|
||||
RPC set variance threshold (only write updates when response is > variance threshold %)
|
||||
|
||||
Args:
|
||||
params (AggregatorSetVarianceThresholdParams)
|
||||
Returns:
|
||||
TransactionSignature
|
||||
"""
|
||||
async def set_variance_threshold(self, params: AggregatorSetVarianceThresholdParams) -> TransactionSignature:
|
||||
authority = authority or self.keypair
|
||||
|
||||
return await self.program.rpc['aggregator_set_variance_threshold'](
|
||||
{
|
||||
"variance_threshold": SwitchboardDecimal.from_decimal(params.threshold)
|
||||
},
|
||||
ctx=anchorpy.Context(
|
||||
accounts={
|
||||
"aggregator": self.public_key,
|
||||
"authority": authority.public_key,
|
||||
},
|
||||
signers=[authority]
|
||||
)
|
||||
)
|
||||
|
||||
"""
|
||||
RPC set min oracles
|
||||
|
||||
Args:
|
||||
params (AggregatorSetMinOraclesParams)
|
||||
Returns:
|
||||
TransactionSignature
|
||||
"""
|
||||
async def set_min_oracles(self, params: AggregatorSetMinOraclesParams) -> TransactionSignature:
|
||||
authority = authority or self.keypair
|
||||
|
||||
return await self.program.rpc['aggregator_set_min_oracles'](
|
||||
{
|
||||
"min_oracle_results": params.min_oracle_results
|
||||
},
|
||||
ctx=anchorpy.Context(
|
||||
accounts={
|
||||
"aggregator": self.public_key,
|
||||
"authority": authority.public_key,
|
||||
},
|
||||
signers=[authority]
|
||||
)
|
||||
)
|
||||
|
||||
"""
|
||||
RPC set update interval
|
||||
|
||||
Args:
|
||||
params (AggregatorSetUpdateIntervalParams)
|
||||
Returns:
|
||||
TransactionSignature
|
||||
"""
|
||||
async def set_update_interval(self, params: AggregatorSetUpdateIntervalParams) -> TransactionSignature:
|
||||
authority = authority or self.keypair
|
||||
|
||||
return await self.program.rpc['aggregator_set_update_interval'](
|
||||
{
|
||||
"new_interval": params.new_interval
|
||||
},
|
||||
ctx=anchorpy.Context(
|
||||
accounts={
|
||||
"aggregator": self.public_key,
|
||||
"authority": authority.public_key,
|
||||
},
|
||||
signers=[authority]
|
||||
)
|
||||
)
|
||||
|
||||
"""
|
||||
Prevent new jobs from being added to the feed.
|
||||
|
@ -802,7 +1049,8 @@ class AggregatorAccount:
|
|||
"escrow": escrow,
|
||||
"token_program": TOKEN_PROGRAM_ID,
|
||||
"program_state": program_state_account.public_key,
|
||||
"history_buffer": history_buffer
|
||||
"history_buffer": history_buffer,
|
||||
"mint": params.token_mint
|
||||
},
|
||||
remaining_accounts=[{"is_signer": False, "is_writable": True, "pubkey": pubkey} for pubkey in remaining_accounts]
|
||||
)
|
||||
|
|
|
@ -1,17 +1,70 @@
|
|||
import io
|
||||
import six
|
||||
import anchorpy
|
||||
|
||||
from dataclasses import dataclass
|
||||
from functools import reduce
|
||||
from typing import Any
|
||||
from typing import Any, Type
|
||||
from decimal import Decimal
|
||||
from solana.publickey import PublicKey
|
||||
from solana.keypair import Keypair
|
||||
from google.protobuf.internal import decoder
|
||||
from switchboardpy.compiled import OracleJob
|
||||
|
||||
|
||||
# Devnet Program ID.
|
||||
SBV2_DEVNET_PID = PublicKey(
|
||||
'2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG'
|
||||
)
|
||||
|
||||
# Mainnet-Beta Program ID.
|
||||
SBV2_MAINNET_PID = PublicKey(
|
||||
'SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f'
|
||||
)
|
||||
|
||||
# https://stackoverflow.com/a/34539706
|
||||
def readRawVarint32(stream: io.BytesIO):
|
||||
mask = 0x80 # (1 << 7)
|
||||
raw_varint32 = []
|
||||
while 1:
|
||||
b = stream.read(1)
|
||||
#eof
|
||||
if b == "":
|
||||
break
|
||||
raw_varint32.append(b)
|
||||
if not (ord(b) & mask):
|
||||
#we found a byte starting with a 0, which means it's the last byte of this varint
|
||||
break
|
||||
return raw_varint32
|
||||
|
||||
def getSize(raw_varint32):
|
||||
result = 0
|
||||
shift = 0
|
||||
b = six.indexbytes(raw_varint32, 0)
|
||||
result |= ((ord(b) & 0x7f) << shift)
|
||||
return result
|
||||
|
||||
def readDelimitedFrom(MessageType: Type[OracleJob], stream: io.BytesIO):
|
||||
raw_varint32 = readRawVarint32(stream)
|
||||
message = None
|
||||
if raw_varint32:
|
||||
size = getSize(raw_varint32)
|
||||
|
||||
data = stream.read(size)
|
||||
if len(data) < size:
|
||||
raise Exception("Unexpected end of file")
|
||||
|
||||
message = MessageType()
|
||||
message.ParseFromString(data)
|
||||
|
||||
return message
|
||||
|
||||
# take OracleJob data and return bytes
|
||||
def parseOracleJob(data: bytes):
|
||||
dataStream = io.BytesIO(data)
|
||||
return readDelimitedFrom(OracleJob, dataStream);
|
||||
|
||||
|
||||
|
||||
# Input parameters for constructing wrapped representations of Switchboard accounts.
|
||||
@dataclass
|
||||
class AccountParams:
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -19,6 +19,8 @@ from solana.system_program import CreateAccountParams, create_account
|
|||
|
||||
from switchboardpy.program import ProgramStateAccount
|
||||
|
||||
from .generated.accounts import CrankAccountData
|
||||
|
||||
# Parameters for initializing a CrankAccount
|
||||
@dataclass
|
||||
class CrankInitParams:
|
||||
|
@ -129,9 +131,8 @@ class CrankAccount:
|
|||
AccountInvalidDiscriminator: If the discriminator doesn't match the IDL.
|
||||
"""
|
||||
async def load_data(self):
|
||||
crank = await self.program.account["CrankAccountData"].fetch(self.public_key)
|
||||
crank.ebuf = None
|
||||
return crank
|
||||
return await CrankAccountData.fetch(self.program.provider.connection, self.public_key)
|
||||
|
||||
|
||||
"""
|
||||
Create and initialize the CrankAccount.
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
import os
|
||||
from solana.publickey import PublicKey
|
||||
|
||||
PROGRAM_ID = PublicKey("SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f")
|
||||
os.environ.setdefault('SWITCHBOARD_PID', '2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG')
|
||||
|
||||
|
||||
PROGRAM_ID = PublicKey(os.environ['SWITCHBOARD_PID'] or "SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f")
|
||||
|
|
|
@ -4,6 +4,7 @@ from dataclasses import dataclass
|
|||
from construct import Container
|
||||
from solana.publickey import PublicKey
|
||||
import borsh_construct as borsh
|
||||
from anchorpy.borsh_extension import BorshPubkey
|
||||
|
||||
|
||||
class AccountMetaBorshJSON(typing.TypedDict):
|
||||
|
|
|
@ -4,6 +4,7 @@ from dataclasses import dataclass
|
|||
from construct import Container
|
||||
from solana.publickey import PublicKey
|
||||
import borsh_construct as borsh
|
||||
from anchorpy.borsh_extension import BorshPubkey
|
||||
|
||||
|
||||
class AccountMetaZCJSON(typing.TypedDict):
|
||||
|
|
|
@ -7,6 +7,7 @@ from dataclasses import dataclass
|
|||
from construct import Container
|
||||
from solana.publickey import PublicKey
|
||||
import borsh_construct as borsh
|
||||
from anchorpy.borsh_extension import BorshPubkey
|
||||
|
||||
|
||||
class AggregatorRoundJSON(typing.TypedDict):
|
||||
|
|
|
@ -7,6 +7,7 @@ from dataclasses import dataclass
|
|||
from construct import Container, Construct
|
||||
from solana.publickey import PublicKey
|
||||
import borsh_construct as borsh
|
||||
from anchorpy.borsh_extension import BorshPubkey
|
||||
|
||||
|
||||
class CallbackJSON(typing.TypedDict):
|
||||
|
|
|
@ -7,6 +7,7 @@ from dataclasses import dataclass
|
|||
from construct import Container
|
||||
from solana.publickey import PublicKey
|
||||
import borsh_construct as borsh
|
||||
from anchorpy.borsh_extension import BorshPubkey
|
||||
|
||||
|
||||
class CallbackZCJSON(typing.TypedDict):
|
||||
|
|
|
@ -4,6 +4,7 @@ from dataclasses import dataclass
|
|||
from construct import Container
|
||||
from solana.publickey import PublicKey
|
||||
import borsh_construct as borsh
|
||||
from anchorpy.borsh_extension import BorshPubkey
|
||||
|
||||
|
||||
class CrankRowJSON(typing.TypedDict):
|
||||
|
|
|
@ -3,6 +3,8 @@ import typing
|
|||
from dataclasses import dataclass
|
||||
from construct import Container
|
||||
from solana.publickey import PublicKey
|
||||
from anchorpy.borsh_extension import BorshPubkey
|
||||
|
||||
import borsh_construct as borsh
|
||||
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ from dataclasses import dataclass
|
|||
from construct import Container
|
||||
from solana.publickey import PublicKey
|
||||
import borsh_construct as borsh
|
||||
from anchorpy.borsh_extension import BorshPubkey
|
||||
|
||||
|
||||
class ProgramConfigParamsJSON(typing.TypedDict):
|
||||
|
|
|
@ -13,6 +13,7 @@ from dataclasses import dataclass
|
|||
from construct import Container
|
||||
from solana.publickey import PublicKey
|
||||
import borsh_construct as borsh
|
||||
from anchorpy.borsh_extension import BorshPubkey
|
||||
|
||||
|
||||
class VrfBuilderJSON(typing.TypedDict):
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import io
|
||||
import anchorpy
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
@ -6,9 +7,12 @@ from solana.publickey import PublicKey
|
|||
from solana.system_program import CreateAccountParams, create_account
|
||||
|
||||
from switchboardpy.compiled import OracleJob
|
||||
from switchboardpy.common import AccountParams
|
||||
from switchboardpy.common import AccountParams, parseOracleJob
|
||||
from switchboardpy.program import ProgramStateAccount
|
||||
|
||||
from .generated.accounts import JobAccountData
|
||||
|
||||
|
||||
# Parameters for initializing a JobAccount
|
||||
@dataclass
|
||||
class JobInitParams:
|
||||
|
@ -30,9 +34,8 @@ class JobInitParams:
|
|||
|
||||
"""
|
||||
An optional wallet for receiving kickbacks from job usage in feeds.
|
||||
Defaults to token vault.
|
||||
"""
|
||||
author_wallet: PublicKey = None
|
||||
authority: PublicKey = None
|
||||
|
||||
class JobAccount:
|
||||
""" A Switchboard account representing a job for an oracle to perform, stored as
|
||||
|
@ -68,9 +71,8 @@ class JobAccount:
|
|||
AccountInvalidDiscriminator: If the discriminator doesn't match the IDL.
|
||||
"""
|
||||
async def load_data(self):
|
||||
job = await self.program.account["JobAccountData"].fetch(self.public_key)
|
||||
job.ebuf = None
|
||||
return job
|
||||
return await JobAccountData.fetch(self.program.provider.connection, self.public_key)
|
||||
|
||||
|
||||
"""
|
||||
Load and parse the protobuf from the raw buffer stored in the JobAccount.
|
||||
|
@ -83,8 +85,8 @@ class JobAccount:
|
|||
AccountInvalidDiscriminator: If the discriminator doesn't match the IDL.
|
||||
"""
|
||||
async def load_job(self):
|
||||
job = await self.load_job()
|
||||
return OracleJob.ParseFromString(job.data)
|
||||
job = await self.load_data()
|
||||
return parseOracleJob(job.data);
|
||||
|
||||
"""
|
||||
Load and parse JobAccount data based on the program IDL from a buffer.
|
||||
|
@ -132,7 +134,7 @@ class JobAccount:
|
|||
ctx=anchorpy.Context(
|
||||
accounts={
|
||||
"job": job_account.public_key,
|
||||
"author_wallet": params.author_wallet or state.token_vault,
|
||||
"authority": params.authority or state.token_vault,
|
||||
"program_state": state_account.public_key
|
||||
},
|
||||
signers=[job_account],
|
||||
|
|
|
@ -5,10 +5,11 @@ import anchorpy
|
|||
from typing import TYPE_CHECKING
|
||||
from dataclasses import dataclass
|
||||
|
||||
from decimal import Decimal
|
||||
from solana import publickey, system_program
|
||||
from solana.keypair import Keypair
|
||||
from solana.publickey import PublicKey
|
||||
from solana.transaction import AccountMeta
|
||||
|
||||
from spl.token.constants import ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID
|
||||
from spl.token.instructions import get_associated_token_address
|
||||
|
||||
|
@ -16,6 +17,8 @@ from switchboardpy.oraclequeue import OracleQueueAccount
|
|||
from switchboardpy.common import AccountParams
|
||||
from switchboardpy.program import ProgramStateAccount
|
||||
|
||||
from .generated.accounts import LeaseAccountData
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from switchboardpy.aggregator import AggregatorAccount
|
||||
|
||||
|
@ -113,9 +116,8 @@ class LeaseAccount:
|
|||
AccountInvalidDiscriminator: If the discriminator doesn't match the IDL.
|
||||
"""
|
||||
async def load_data(self):
|
||||
lease = await self.program.account["LeaseAccountData"].fetch(self.public_key)
|
||||
lease.ebuf = None
|
||||
return lease
|
||||
return await LeaseAccountData.fetch(self.program.provider.connection, self.public_key)
|
||||
|
||||
|
||||
"""
|
||||
Loads a LeaseAccount from the expected PDA seed format
|
||||
|
@ -160,14 +162,34 @@ class LeaseAccount:
|
|||
params.oracle_queue_account,
|
||||
params.aggregator_account
|
||||
)
|
||||
|
||||
|
||||
|
||||
job_account_data = await params.aggregator_account.load_jobs()
|
||||
aggregator_account_data = await params.aggregator_account.load_data()
|
||||
job_pubkeys: list[PublicKey] = aggregator_account_data.job_pubkeys_data[:aggregator_account_data.job_pubkeys_size]
|
||||
job_wallets: list[PublicKey] = []
|
||||
wallet_bumps: list[int] = []
|
||||
for job in job_account_data:
|
||||
authority = job.account.authority or PublicKey('11111111111111111111111111111111')
|
||||
pubkey, bump = publickey.PublicKey.find_program_address(
|
||||
[
|
||||
bytes(authority),
|
||||
bytes(TOKEN_PROGRAM_ID),
|
||||
bytes(switch_token_mint.pubkey),
|
||||
],
|
||||
ASSOCIATED_TOKEN_PROGRAM_ID
|
||||
)
|
||||
job_wallets.append(pubkey)
|
||||
wallet_bumps.append(bump)
|
||||
|
||||
escrow = await switch_token_mint.create_associated_token_account(lease_account.public_key, skip_confirmation=False)
|
||||
await program.rpc["lease_init"](
|
||||
{
|
||||
"load_amount": params.load_amount,
|
||||
"state_bump": state_bump,
|
||||
"lease_bump": lease_bump,
|
||||
"withdraw_authority": params.withdraw_authority or PublicKey('11111111111111111111111111111111')
|
||||
"withdraw_authority": params.withdraw_authority or PublicKey('11111111111111111111111111111111'),
|
||||
"wallet_bumps": bytes(wallet_bumps)
|
||||
},
|
||||
ctx=anchorpy.Context(
|
||||
accounts={
|
||||
|
@ -181,12 +203,25 @@ class LeaseAccount:
|
|||
"token_program": TOKEN_PROGRAM_ID,
|
||||
"escrow": escrow,
|
||||
"owner": params.funder_authority.public_key,
|
||||
"mint": switch_token_mint.pubkey
|
||||
},
|
||||
signers=[params.funder_authority]
|
||||
signers=[params.funder_authority],
|
||||
remaining_accounts=[AccountMeta(is_signer=False, is_writable=True, pubkey=x) for x in [*job_pubkeys, *job_wallets]]
|
||||
)
|
||||
)
|
||||
return LeaseAccount(AccountParams(program=program, public_key=lease_account.public_key))
|
||||
|
||||
"""
|
||||
Get lease balance
|
||||
|
||||
Args:
|
||||
Returns:
|
||||
int balance
|
||||
"""
|
||||
async def get_balance(self):
|
||||
lease = self.load_data()
|
||||
return await self.program.provider.connection.get_balance(lease.escrow)
|
||||
|
||||
"""
|
||||
Adds fund to a LeaseAccount. Note that funds can always be withdrawn by
|
||||
the withdraw authority if one was set on lease initialization.
|
||||
|
@ -205,17 +240,37 @@ class LeaseAccount:
|
|||
queue = lease.queue
|
||||
aggregator = lease.aggregator
|
||||
program_state_account, state_bump = ProgramStateAccount.from_seed(program)
|
||||
switch_token_mint = await program_state_account.get_token_mint()
|
||||
queue_account = OracleQueueAccount(AccountParams(program=program, public_key=queue))
|
||||
switch_token_mint = await queue_account.load_mint()
|
||||
lease_account, lease_bump = LeaseAccount.from_seed(
|
||||
program,
|
||||
OracleQueueAccount(AccountParams(program=program, public_key=queue)),
|
||||
AggregatorAccount(AccountParams(program=program, public_key=aggregator))
|
||||
)
|
||||
job_account_data = await aggregator.load_jobs()
|
||||
aggregator_account_data = await aggregator.load_data()
|
||||
job_pubkeys: list[PublicKey] = aggregator_account_data.job_pubkeys_data[:aggregator_account_data.job_pubkeys_size]
|
||||
job_wallets: list[PublicKey] = []
|
||||
wallet_bumps: list[int] = []
|
||||
for job in job_account_data:
|
||||
authority = job.account.authority or PublicKey('11111111111111111111111111111111')
|
||||
pubkey, bump = publickey.PublicKey.find_program_address(
|
||||
[
|
||||
bytes(authority),
|
||||
bytes(TOKEN_PROGRAM_ID),
|
||||
bytes(switch_token_mint.pubkey),
|
||||
],
|
||||
ASSOCIATED_TOKEN_PROGRAM_ID
|
||||
)
|
||||
job_wallets.append(pubkey)
|
||||
wallet_bumps.append(bump)
|
||||
|
||||
return await program.rpc["lease_extend"](
|
||||
{
|
||||
"load_amount": params.load_amount,
|
||||
"state_bump": state_bump,
|
||||
"lease_bump": lease_bump
|
||||
"lease_bump": lease_bump,
|
||||
"wallet_bumps": bytes(wallet_bumps)
|
||||
},
|
||||
ctx=anchorpy.Context(
|
||||
accounts={
|
||||
|
@ -226,9 +281,11 @@ class LeaseAccount:
|
|||
"owner": params.funder_authority.public_key,
|
||||
"token_program": TOKEN_PROGRAM_ID,
|
||||
"escrow": escrow,
|
||||
"program_state": program_state_account.public_key
|
||||
"program_state": program_state_account.public_key,
|
||||
"mint": switch_token_mint.pubkey
|
||||
},
|
||||
signers=[params.funder_authority]
|
||||
signers=[params.funder_authority],
|
||||
remaining_accounts=[AccountMeta(is_signer=False, is_writable=True, pubkey=x) for x in [*job_pubkeys, *job_wallets]]
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -252,6 +309,8 @@ class LeaseAccount:
|
|||
queue = lease.queue
|
||||
aggregator = lease.aggregator
|
||||
program_state_account, state_bump = ProgramStateAccount.from_seed(program)
|
||||
queue_account = OracleQueueAccount(AccountParams(program=program, public_key=queue))
|
||||
switch_token_mint = await queue_account.load_mint()
|
||||
lease_account, lease_bump = LeaseAccount.from_seed(
|
||||
program,
|
||||
OracleQueueAccount(AccountParams(program=program, public_key=queue)),
|
||||
|
@ -273,6 +332,7 @@ class LeaseAccount:
|
|||
"withdraw_account": params.withdraw_wallet,
|
||||
"token_program": TOKEN_PROGRAM_ID,
|
||||
"program_state": program_state_account.public_key,
|
||||
"mint": switch_token_mint.pubkey
|
||||
},
|
||||
signers=[params.withdraw_authority]
|
||||
)
|
||||
|
|
|
@ -14,6 +14,7 @@ from switchboardpy.program import ProgramStateAccount
|
|||
from switchboardpy.common import AccountParams
|
||||
from switchboardpy.oraclequeue import OracleQueueAccount
|
||||
|
||||
from .generated.accounts import OracleAccountData
|
||||
|
||||
# Parameters for an OracleInit request
|
||||
@dataclass
|
||||
|
@ -85,9 +86,8 @@ class OracleAccount:
|
|||
AccountInvalidDiscriminator: If the discriminator doesn't match the IDL.
|
||||
"""
|
||||
async def load_data(self):
|
||||
oracle = await self.program.account["OracleAccountData"].fetch(self.public_key)
|
||||
oracle.ebuf = None
|
||||
return oracle
|
||||
return await OracleAccountData.fetch(self.program.provider.connection, self.public_key)
|
||||
|
||||
|
||||
"""
|
||||
Loads a OracleAccount from the expected PDA seed format
|
||||
|
|
|
@ -3,19 +3,27 @@ import anchorpy
|
|||
from dataclasses import dataclass
|
||||
from decimal import Decimal
|
||||
|
||||
from spl.token.async_client import AsyncToken
|
||||
from spl.token.constants import TOKEN_PROGRAM_ID, WRAPPED_SOL_MINT
|
||||
|
||||
from solana import system_program
|
||||
from solana import keypair
|
||||
from solana.publickey import PublicKey
|
||||
from solana.keypair import Keypair
|
||||
from solana.system_program import CreateAccountParams, create_account
|
||||
from switchboardpy.common import SwitchboardDecimal
|
||||
|
||||
from switchboardpy.common import AccountParams
|
||||
|
||||
from .generated.accounts import OracleQueueAccountData
|
||||
|
||||
|
||||
# Parameters for initializing OracleQueueAccount
|
||||
@dataclass
|
||||
class OracleQueueInitParams:
|
||||
|
||||
"""Mint for the oracle queue"""
|
||||
mint: PublicKey
|
||||
|
||||
"""Rewards to provide oracles and round openers on this queue."""
|
||||
reward: int
|
||||
|
||||
|
@ -74,6 +82,13 @@ class OracleQueueInitParams:
|
|||
"""Buffer for queue metadata."""
|
||||
metadata: bytes = None
|
||||
|
||||
"""
|
||||
Enabling this setting means data feeds do not need explicit permission
|
||||
to request VRF proofs and verifications from this queue.
|
||||
"""
|
||||
unpermissioned_vrf: bool = None
|
||||
|
||||
|
||||
class OracleQueueAccount:
|
||||
"""A Switchboard account representing a queue for distributing oracles to
|
||||
permitted data feeds.
|
||||
|
@ -117,9 +132,22 @@ class OracleQueueAccount:
|
|||
AccountInvalidDiscriminator: If the discriminator doesn't match the IDL.
|
||||
"""
|
||||
async def load_data(self):
|
||||
queue = await self.program.account["OracleQueueAccountData"].fetch(self.public_key)
|
||||
queue.ebuf = None
|
||||
return queue
|
||||
return await OracleQueueAccountData.fetch(self.program.provider.connection, self.public_key)
|
||||
|
||||
"""
|
||||
Fetch the token mint for this queue
|
||||
Args:
|
||||
Returns:
|
||||
AsyncToken
|
||||
"""
|
||||
async def load_mint(self) -> AsyncToken:
|
||||
payer_keypair = Keypair.from_secret_key(self.program.provider.wallet.payer.secret_key)
|
||||
queue = await self.load_data()
|
||||
try:
|
||||
mint = AsyncToken(self.program.provider.connection, queue.mint, TOKEN_PROGRAM_ID, payer_keypair)
|
||||
return mint;
|
||||
except AttributeError:
|
||||
return AsyncToken(self.program.provider.connection, WRAPPED_SOL_MINT, TOKEN_PROGRAM_ID, payer_keypair)
|
||||
|
||||
"""
|
||||
Create and initialize the OracleQueueAccount
|
||||
|
@ -154,7 +182,9 @@ class OracleQueueAccount:
|
|||
"consecutive_oracle_failure_limit": params.consecutive_oracle_failure_limit or 1000,
|
||||
"minimum_delay_seconds": params.minimum_delay_seconds or 5,
|
||||
"queue_size": params.queue_size or 0,
|
||||
"unpermissioned_feeds": params.unpermissioned_feeds or False
|
||||
"unpermissioned_feeds": params.unpermissioned_feeds or False,
|
||||
"unpermissioned_vrf": params.unpermissioned_feeds or False,
|
||||
"enable_buffer_relayers": False
|
||||
},
|
||||
ctx=anchorpy.Context(
|
||||
accounts={
|
||||
|
@ -162,7 +192,8 @@ class OracleQueueAccount:
|
|||
"authority": params.authority,
|
||||
"buffer": buffer.public_key,
|
||||
"system_program": system_program.SYS_PROGRAM_ID,
|
||||
"payer": program.provider.wallet.public_key
|
||||
"payer": program.provider.wallet.public_key,
|
||||
"mint": params.mint
|
||||
},
|
||||
signers=[oracle_queue_account, buffer],
|
||||
pre_instructions=[
|
||||
|
|
|
@ -8,6 +8,8 @@ from solana.keypair import Keypair
|
|||
from solana.publickey import PublicKey
|
||||
from switchboardpy.common import AccountParams
|
||||
|
||||
from .generated.accounts import PermissionAccountData
|
||||
|
||||
# Parameters for initializing PermissionAccount
|
||||
@dataclass
|
||||
class PermissionInitParams:
|
||||
|
@ -91,9 +93,8 @@ class PermissionAccount:
|
|||
AccountInvalidDiscriminator: If the discriminator doesn't match the IDL.
|
||||
"""
|
||||
async def load_data(self):
|
||||
permission = await self.program.account["PermissionAccountData"].fetch(self.public_key)
|
||||
permission.ebuf = None
|
||||
return permission
|
||||
return await PermissionAccountData.fetch(self.program.provider.connection, self.public_key)
|
||||
|
||||
|
||||
"""
|
||||
Get the size of a PermissionAccount on chain
|
||||
|
|
|
@ -12,11 +12,19 @@ from solana.publickey import PublicKey
|
|||
|
||||
from switchboardpy.common import AccountParams
|
||||
|
||||
from .generated.accounts import SbState
|
||||
|
||||
# Devnet Program ID.
|
||||
SBV2_DEVNET_PID = PublicKey(
|
||||
'2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG'
|
||||
)
|
||||
|
||||
# Mainnet-Beta Program ID.
|
||||
SBV2_MAINNET_PID = PublicKey(
|
||||
'SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f'
|
||||
)
|
||||
|
||||
|
||||
# Input parameters intitializing program state
|
||||
@dataclass
|
||||
class ProgramInitParams:
|
||||
|
@ -78,9 +86,8 @@ class ProgramStateAccount:
|
|||
AccountInvalidDiscriminator: If the discriminator doesn't match the IDL.
|
||||
"""
|
||||
async def load_data(self):
|
||||
state = await self.program.account["SbState"].fetch(self.public_key)
|
||||
state.ebuf = None
|
||||
return state
|
||||
return await SbState.fetch(self.program.provider.connection, self.public_key)
|
||||
|
||||
|
||||
"""
|
||||
Fetch the Switchboard token mint specified in the program state account.
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
import anchorpy
|
||||
|
||||
from dataclasses import dataclass
|
||||
from solana.keypair import Keypair
|
||||
from solana.publickey import PublicKey
|
||||
from solana.transaction import Transaction
|
||||
from solana.system_program import CreateAccountParams, create_account
|
||||
from solana.rpc.commitment import Confirmed
|
||||
from switchboardpy.common import AccountParams
|
||||
|
||||
from generated.accounts import VrfAccountData
|
||||
from generated.instructions import VrfInitArgs, VrfInitAccounts, vrf_init
|
||||
|
||||
@dataclass
|
||||
class VrfInitParams:
|
||||
|
||||
"""Generated VrfInitArgs"""
|
||||
vrf_init_args: VrfInitArgs
|
||||
|
||||
"""Buffer specifying orace name"""
|
||||
vrf_init_accounts: VrfInitAccounts
|
||||
|
||||
class VrfAccount:
|
||||
""" A Switchboard account representing a VrfAccount
|
||||
|
||||
Attributes:
|
||||
program (anchor.Program): The anchor program ref
|
||||
public_key (PublicKey | None): This aggregator's public key
|
||||
keypair (Keypair | None): this aggregator's keypair
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self, params: AccountParams):
|
||||
if params.public_key is None and params.keypair is None:
|
||||
raise ValueError('User must provide either a publicKey or keypair for account use.')
|
||||
if params.keypair and params.public_key and params.keypair.public_key != params.public_key:
|
||||
raise ValueError('User must provide either a publicKey or keypair for account use.')
|
||||
self.program = params.program
|
||||
self.public_key = params.keypair.public_key if params.keypair else params.public_key
|
||||
self.keypair = params.keypair
|
||||
|
||||
"""
|
||||
Load and parse JobAccount state based on the program IDL.
|
||||
|
||||
Returns:
|
||||
name (JobAccount): data parsed in accordance with the
|
||||
Switchboard IDL.
|
||||
|
||||
Args:
|
||||
|
||||
Raises:
|
||||
AccountDoesNotExistError: If the account doesn't exist.
|
||||
AccountInvalidDiscriminator: If the discriminator doesn't match the IDL.
|
||||
"""
|
||||
async def load_data(self):
|
||||
return await VrfAccountData.fetch(self.program.provider.connection, self.public_key)
|
||||
|
||||
|
||||
"""
|
||||
Create and initialize the VrfAccount
|
||||
|
||||
Args:
|
||||
program (anchor.Program)
|
||||
params (VrfInitArgs)
|
||||
|
||||
Returns:
|
||||
VrfAccount
|
||||
"""
|
||||
@staticmethod
|
||||
async def create(program: anchorpy.Program, params: VrfInitParams):
|
||||
ix = vrf_init(params.vrf_init_args, params.vrf_init_accounts)
|
||||
tx = Transaction().add(ix)
|
||||
sig = await program.provider.send(tx)
|
||||
await program.provider.connection.confirm_transaction(sig, Confirmed)
|
||||
return VrfAccount(AccountParams(program=program, public_key=params.vrf_init_accounts.vrf))
|
||||
|
||||
|
||||
|
|
@ -37,37 +37,36 @@ class SwitchboardProgram(object):
|
|||
async def test_load_data():
|
||||
async with SwitchboardProgram() as program:
|
||||
|
||||
agg = AggregatorAccount(AccountParams(program=program, public_key=PublicKey("88FX4tBstuwBPNhQU4EEBoPX35neSu4Le9zDSwtPRRQz")))
|
||||
agg = AggregatorAccount(AccountParams(program=program, public_key=PublicKey("HMtDNnoCPD6NQRCE2uScEWSvwaZY3hWixCK12TKNtGpc")))
|
||||
|
||||
# getting aggregator data
|
||||
data = await agg.load_data()
|
||||
|
||||
assert data.min_oracle_results == 3
|
||||
assert data.oracle_request_batch_size == 6
|
||||
assert data.min_job_results == 2
|
||||
assert data.min_oracle_results == 2
|
||||
assert data.oracle_request_batch_size == 3
|
||||
assert data.min_job_results == 1
|
||||
print(data)
|
||||
|
||||
@mark.asyncio
|
||||
async def test_get_latest_value():
|
||||
async with SwitchboardProgram() as program:
|
||||
agg = AggregatorAccount(AccountParams(program=program, public_key=PublicKey("88FX4tBstuwBPNhQU4EEBoPX35neSu4Le9zDSwtPRRQz")))
|
||||
agg = AggregatorAccount(AccountParams(program=program, public_key=PublicKey("HMtDNnoCPD6NQRCE2uScEWSvwaZY3hWixCK12TKNtGpc")))
|
||||
|
||||
# getting most recent value
|
||||
val = await agg.get_latest_value()
|
||||
|
||||
assert Decimal('180.12115') == val
|
||||
assert Decimal('39.792') == val
|
||||
|
||||
print('LATEST VALUE:')
|
||||
print(val)
|
||||
|
||||
@mark.asyncio
|
||||
async def test_get_latest_value():
|
||||
async def test_get_latest_timestamp():
|
||||
async with SwitchboardProgram() as program:
|
||||
agg = AggregatorAccount(AccountParams(program=program, public_key=PublicKey("88FX4tBstuwBPNhQU4EEBoPX35neSu4Le9zDSwtPRRQz")))
|
||||
agg = AggregatorAccount(AccountParams(program=program, public_key=PublicKey("HMtDNnoCPD6NQRCE2uScEWSvwaZY3hWixCK12TKNtGpc")))
|
||||
|
||||
# getting most recent value
|
||||
val = await agg.get_latest_feed_timestamp()
|
||||
assert Decimal('1639722030') == val
|
||||
assert Decimal('1654626799') == val
|
||||
print('LATEST TIMESTAMP:')
|
||||
print(val)
|
||||
|
||||
|
@ -87,6 +86,5 @@ async def test_create():
|
|||
public_key=PublicKey("F8ce7MsckeZAbAGmxjJNetxYXQa9mKr9nnrC3qKubyYy")
|
||||
)
|
||||
),
|
||||
start_after=0,
|
||||
)
|
||||
)
|
|
@ -23,6 +23,8 @@ from decimal import Decimal
|
|||
from solana.keypair import Keypair
|
||||
from solana.publickey import PublicKey
|
||||
from solana.rpc.async_api import AsyncClient
|
||||
from solana.rpc.commitment import Confirmed
|
||||
|
||||
from anchorpy import Program, Provider, Wallet
|
||||
from spl.token.async_client import AsyncToken
|
||||
from spl.token.constants import TOKEN_PROGRAM_ID
|
||||
|
@ -33,7 +35,7 @@ from google.protobuf.internal import encoder
|
|||
class SwitchboardProgram(object):
|
||||
|
||||
async def __aenter__(self):
|
||||
client = AsyncClient("https://api.devnet.solana.com/", commitment="confirmed")
|
||||
client = AsyncClient("https://api.devnet.solana.com/", commitment=Confirmed)
|
||||
provider = Provider(client, Wallet.local())
|
||||
self.program = await Program.at(
|
||||
SBV2_DEVNET_PID, provider
|
||||
|
@ -43,16 +45,6 @@ class SwitchboardProgram(object):
|
|||
async def __aexit__(self, exc_t, exc_v, exc_tb):
|
||||
await self.program.close()
|
||||
|
||||
@mark.asyncio
|
||||
async def test_load_data():
|
||||
async with SwitchboardProgram() as program:
|
||||
|
||||
lease = LeaseAccount(AccountParams(program=program, public_key=PublicKey("qAs3FQX2iUSRCe9WFXbRgH594LSqusTUze8BftxbiHC")))
|
||||
|
||||
# getting aggregator data
|
||||
data = await lease.load_data()
|
||||
print(data)
|
||||
|
||||
@mark.asyncio
|
||||
async def test_create():
|
||||
async with SwitchboardProgram() as program:
|
||||
|
@ -129,7 +121,7 @@ async def test_create():
|
|||
1_000_000,
|
||||
skip_confirmation=False
|
||||
)
|
||||
|
||||
|
||||
# Create lease
|
||||
lease = await LeaseAccount.create(
|
||||
program=program,
|
||||
|
@ -154,4 +146,5 @@ async def test_create():
|
|||
# Add Aggregator for auto-updates
|
||||
await crank.push(CrankPushParams(aggregator_account=aggregator))
|
||||
|
||||
print(f'Feed info at: https://api.switchboard.xyz/api/feed/{aggregator.public_key}?network=devnet')
|
||||
|
||||
print(f'Feed info at: https://switchboard.xyz/explorer/2/{aggregator.public_key}')
|
|
@ -0,0 +1,148 @@
|
|||
from pytest import fixture, mark
|
||||
|
||||
from switchboardpy import (
|
||||
SBV2_DEVNET_PID,
|
||||
AccountParams,
|
||||
LeaseAccount,
|
||||
LeaseInitParams,
|
||||
AggregatorAccount,
|
||||
AggregatorInitParams,
|
||||
AggregatorOpenRoundParams,
|
||||
OracleQueueAccount,
|
||||
JobAccount,
|
||||
JobInitParams,
|
||||
PermissionAccount,
|
||||
PermissionInitParams,
|
||||
OracleJob,
|
||||
)
|
||||
|
||||
from solana.publickey import PublicKey
|
||||
from solana.rpc.async_api import AsyncClient
|
||||
from solana.rpc.commitment import Confirmed
|
||||
|
||||
from anchorpy import Program, Provider, Wallet
|
||||
from spl.token.async_client import AsyncToken
|
||||
from spl.token.constants import TOKEN_PROGRAM_ID
|
||||
|
||||
from switchboardpy.aggregator import AggregatorAccount
|
||||
from google.protobuf.internal import encoder
|
||||
|
||||
class SwitchboardProgram(object):
|
||||
|
||||
async def __aenter__(self):
|
||||
client = AsyncClient("https://api.devnet.solana.com/", commitment=Confirmed)
|
||||
provider = Provider(client, Wallet.local())
|
||||
self.program = await Program.at(
|
||||
SBV2_DEVNET_PID, provider
|
||||
)
|
||||
print(provider.wallet.public_key)
|
||||
return self.program
|
||||
|
||||
async def __aexit__(self, exc_t, exc_v, exc_tb):
|
||||
await self.program.close()
|
||||
|
||||
@mark.asyncio
|
||||
async def test_create():
|
||||
async with SwitchboardProgram() as program:
|
||||
|
||||
# Get Permissionless Queue Devnet
|
||||
queue = OracleQueueAccount(
|
||||
AccountParams(
|
||||
program=program,
|
||||
public_key=PublicKey("F8ce7MsckeZAbAGmxjJNetxYXQa9mKr9nnrC3qKubyYy")
|
||||
)
|
||||
)
|
||||
|
||||
# Create aggregator so we can later make a lease for it
|
||||
aggregator = await AggregatorAccount.create(
|
||||
program=program,
|
||||
aggregator_init_params=AggregatorInitParams(
|
||||
batch_size=3,
|
||||
min_required_oracle_results=2,
|
||||
min_required_job_results=1,
|
||||
min_update_delay_seconds=6,
|
||||
queue_account=OracleQueueAccount(
|
||||
AccountParams(
|
||||
program=program,
|
||||
public_key=PublicKey("F8ce7MsckeZAbAGmxjJNetxYXQa9mKr9nnrC3qKubyYy")
|
||||
)
|
||||
),
|
||||
start_after=0,
|
||||
disable_crank=True
|
||||
)
|
||||
)
|
||||
|
||||
# Create Job Definition
|
||||
oracleJob = OracleJob()
|
||||
task1 = oracleJob.tasks.add()
|
||||
httpTask = OracleJob.HttpTask()
|
||||
httpTask.url = "https://ftx.us/api/markets/sol/usd"
|
||||
task1.http_task.CopyFrom(httpTask)
|
||||
task2 = oracleJob.tasks.add()
|
||||
parseTask = OracleJob.JsonParseTask()
|
||||
parseTask.path = "$.result.price"
|
||||
task2.json_parse_task.CopyFrom(parseTask)
|
||||
serializedMessage = oracleJob.SerializeToString()
|
||||
delimiter = encoder._VarintBytes(len(serializedMessage)) # Encode Delimited
|
||||
delimitedOJ = delimiter + serializedMessage
|
||||
|
||||
# Create Job on Chain
|
||||
job = await JobAccount.create(
|
||||
program=program,
|
||||
params=JobInitParams(
|
||||
data=delimitedOJ
|
||||
)
|
||||
)
|
||||
|
||||
# Add SOL / USD job to Aggregator
|
||||
await aggregator.add_job(job)
|
||||
|
||||
queue_data = await queue.load_data()
|
||||
|
||||
# Create Permission Account
|
||||
await PermissionAccount.create(
|
||||
program,
|
||||
PermissionInitParams(
|
||||
granter=queue.public_key,
|
||||
grantee=aggregator.public_key,
|
||||
authority=queue_data.authority
|
||||
)
|
||||
)
|
||||
|
||||
# Create tokenAccount to fund lease - this is needed for
|
||||
tokenAccount = await AsyncToken.create_wrapped_native_account(
|
||||
program.provider.connection,
|
||||
TOKEN_PROGRAM_ID,
|
||||
program.provider.wallet.public_key,
|
||||
program.provider.wallet.payer,
|
||||
1_000_000, # start it off with lamports
|
||||
skip_confirmation=False
|
||||
)
|
||||
|
||||
# Create lease - this is where funding comes from
|
||||
await LeaseAccount.create(
|
||||
program=program,
|
||||
params=LeaseInitParams(
|
||||
withdraw_authority=program.provider.wallet.public_key,
|
||||
load_amount=1_000_000,
|
||||
funder=tokenAccount,
|
||||
funder_authority=program.provider.wallet.payer,
|
||||
aggregator_account=aggregator,
|
||||
oracle_queue_account=OracleQueueAccount(
|
||||
AccountParams(
|
||||
program=program,
|
||||
public_key=PublicKey("F8ce7MsckeZAbAGmxjJNetxYXQa9mKr9nnrC3qKubyYy")
|
||||
)
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
await aggregator.open_round(AggregatorOpenRoundParams(OracleQueueAccount(
|
||||
AccountParams(
|
||||
program=program,
|
||||
public_key=PublicKey("F8ce7MsckeZAbAGmxjJNetxYXQa9mKr9nnrC3qKubyYy")
|
||||
)
|
||||
), payout_wallet=tokenAccount))
|
||||
|
||||
|
||||
print(f'Feed info at: https://switchboard.xyz/explorer/2/{aggregator.public_key}')
|
|
@ -14,6 +14,7 @@ from solana.keypair import Keypair
|
|||
from solana.publickey import PublicKey
|
||||
from solana.rpc.async_api import AsyncClient
|
||||
from anchorpy import Program, Provider, Wallet
|
||||
from switchboardpy.program import ProgramStateAccount
|
||||
|
||||
ORACLE_QUEUE_STANDARD_DEVNET = 'F8ce7MsckeZAbAGmxjJNetxYXQa9mKr9nnrC3qKubyYy' # <-- new key | old key - 'B4yBQ3hYcjnrNLxUnauJqwpFJnjtm7s8gHybgkAdgXhQ';
|
||||
|
||||
|
@ -44,12 +45,15 @@ async def test_load_data():
|
|||
@mark.asyncio
|
||||
async def test_create():
|
||||
async with SwitchboardProgram() as program:
|
||||
program_state_account, state_bump = ProgramStateAccount.from_seed(program)
|
||||
switch_token_mint = await program_state_account.get_token_mint()
|
||||
await OracleQueueAccount.create(
|
||||
program=program,
|
||||
params=OracleQueueInitParams(
|
||||
reward=3000,
|
||||
min_stake=300,
|
||||
authority=program.provider.wallet.public_key, #
|
||||
oracle_timeout=20000,
|
||||
oracle_timeout=20000,
|
||||
mint=switch_token_mint.pubkey
|
||||
)
|
||||
)
|
Loading…
Reference in New Issue