├── .gitignore ├── README.md ├── bin ├── sixgpt └── sixgpt_miner ├── cli ├── __init__.py ├── account │ ├── __init__.py │ └── rewards │ │ ├── __init__.py │ │ └── _impl.py ├── auth │ ├── __init__.py │ ├── drive │ │ ├── __init__.py │ │ └── _impl.py │ ├── openai │ │ ├── __init__.py │ │ └── _impl.py │ ├── sixgpt │ │ ├── __init__.py │ │ └── _impl.py │ ├── twitter │ │ ├── __init__.py │ │ └── _impl.py │ └── vana │ │ ├── __init__.py │ │ └── _impl.py ├── debug.py ├── drive_entry.py ├── entry.py ├── miner │ ├── __init__.py │ └── _impl.py ├── openai_entry.py ├── twitter_entry.py └── update │ └── __init__.py ├── constants └── __init__.py ├── miner ├── build.py ├── dlp │ ├── dlp-implementation-abi.json │ └── volara.py ├── drive.py ├── extract.py ├── run.py └── task.py ├── poetry.lock ├── pyproject.toml └── setup.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | .idea/ 161 | 162 | # Temporary file used to communicate with a validator via API 163 | cli.json 164 | 165 | account.cookies 166 | .vscode 167 | .DS_Store 168 | *.data 169 | *.zip 170 | data/ 171 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SixGPT Miner [DEPRECATED] 2 | 3 | This is the OLD version of the SixGPT miner. 4 | Our official miner is here: https://github.com/sixgpt/miner 5 | 6 | # About 7 | 8 | SixGPT is a decentralized synthetic data generation platform built on the Vana network. We empower users by giving them ownership of their data and enabling them to earn from it. 9 | 10 | The SixGPT Miner is a software package which allows users to contribute data they generate for wikipedia question-answer based tasks to the network for rewards. 11 | In the future, we will support other tasks such as chatbot conversations, image captioning, etc. 12 | 13 | # Credentials 14 | 15 | SixGPT uses two credentials to perform mining on Vana: 16 | 17 | 1. OpenAI api key, for access to the OpenAPI API 18 | 2. Google OAUTH, for storing your mined data in Google Drive. 19 | 20 | # Install 21 | 22 | ## Prerequisites 23 | 24 | SixGPT uses several dependencies to operate. 25 | 26 | - Python 3.12 27 | - Poetry 28 | 29 | ```shell 30 | brew install python 31 | curl -sSL https://install.python-poetry.org | python3 - 32 | ``` 33 | 34 | ## Quick Start 35 | 36 | ```shell 37 | git clone https://github.com/sixgpt/minercli.git 38 | cd minercli 39 | source setup.sh 40 | ``` 41 | 42 | You should now have access to the `sixgpt` cli command. 43 | 44 | # Interface 45 | 46 | The interface can be accessed via the CLI at `./bin/sixgpt` 47 | 48 | ## Mining 49 | 50 | By default, miner runs as a background daemon. 51 | 52 | #### Start Mining 53 | 54 | ```shell 55 | sixgpt mine start 56 | ``` 57 | 58 | | Flag | Description | 59 | | ---- | ------------------------------------- | 60 | | -b | Run the miner in a background process | 61 | 62 | #### Stop Mining 63 | 64 | ```shell 65 | sixgpt mine stop 66 | ``` 67 | 68 | #### See Mining Logs 69 | 70 | ```shell 71 | sixgpt mine logs 72 | ``` 73 | 74 | ## Auth 75 | 76 | ### Google Drive 77 | 78 | #### Login to Drive 79 | 80 | ```shell 81 | sixgpt auth drive login 82 | ``` 83 | 84 | #### Logout to Drive 85 | 86 | ```shell 87 | sixgpt auth drive logout 88 | ``` 89 | 90 | ### OpenAI 91 | 92 | #### Set OpenAI API Key 93 | 94 | ```shell 95 | sixgpt auth openai login 96 | ``` 97 | 98 | #### Reset OpenAI API Key 99 | 100 | ```shell 101 | sixgpt auth openai logout 102 | ``` 103 | 104 | ## Misc 105 | 106 | #### Update the SixGPT CLI 107 | 108 | ```shell 109 | sixgpt update 110 | ``` 111 | 112 | #### Check the SixGPT CLI version 113 | 114 | ```shell 115 | sixgpt --version 116 | ``` 117 | -------------------------------------------------------------------------------- /bin/sixgpt: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | cd $SCRIPT_DIR/.. 5 | 6 | poetry run python -m cli.entry $@ 7 | -------------------------------------------------------------------------------- /bin/sixgpt_miner: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | cd $SCRIPT_DIR/.. 5 | 6 | poetry run python -m miner.run $@ 7 | -------------------------------------------------------------------------------- /cli/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sixgpt/minercli/bcb402aa1156226321d97c31ccc9f3e21e4350cf/cli/__init__.py -------------------------------------------------------------------------------- /cli/account/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sixgpt/minercli/bcb402aa1156226321d97c31ccc9f3e21e4350cf/cli/account/__init__.py -------------------------------------------------------------------------------- /cli/account/rewards/__init__.py: -------------------------------------------------------------------------------- 1 | from ._impl import print_rewards 2 | -------------------------------------------------------------------------------- /cli/account/rewards/_impl.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import click 3 | from dataclasses import dataclass 4 | 5 | import cli.auth.sixgpt as volara_auth 6 | from constants import SIXGPT_API 7 | 8 | 9 | @dataclass 10 | class IndexStats: 11 | totalFiles: int 12 | totalIndexedTweets: int 13 | 14 | 15 | @dataclass 16 | class RewardStats: 17 | ownershipScore: float 18 | miningScore: float 19 | validatorScore: float 20 | 21 | 22 | @dataclass 23 | class RankStats: 24 | rank: str 25 | ownershipRank: str 26 | miningRank: str 27 | validatorRank: str 28 | 29 | 30 | @dataclass 31 | class Stats: 32 | indexStats: IndexStats 33 | rewardStats: RewardStats 34 | rankStats: RankStats 35 | 36 | 37 | def _fetch_rewards() -> Stats: 38 | jwt = volara_auth.get_sixgpt_jwt() 39 | resp = requests.get( 40 | f"{SIXGPT_API}/v1/user/stats", 41 | headers={"Authorization": f"Bearer {jwt}"}, 42 | ) 43 | data = resp.json()["data"] 44 | return Stats( 45 | indexStats=IndexStats(**data["indexStats"]), 46 | rewardStats=RewardStats(**data["rewardStats"]), 47 | rankStats=RankStats(**data["rankStats"]), 48 | ) 49 | 50 | 51 | def print_rewards(): 52 | rewards = _fetch_rewards() 53 | 54 | click.echo("=" * 40) 55 | click.echo(click.style("Volara Rewards Stats", fg="green", bold=True)) 56 | click.echo("=" * 40) 57 | 58 | sections = [ 59 | ( 60 | "Index Stats:", 61 | [ 62 | ("Total Files", rewards.indexStats.totalFiles), 63 | ("Total Indexed Tweets", rewards.indexStats.totalIndexedTweets), 64 | ], 65 | ), 66 | ( 67 | "Reward Stats:", 68 | [ 69 | ("Ownership Score", f"{rewards.rewardStats.ownershipScore:.2f}"), 70 | ("Mining Score", f"{rewards.rewardStats.miningScore:.2f}"), 71 | ("Validator Score", f"{rewards.rewardStats.validatorScore:.2f}"), 72 | ], 73 | ), 74 | ( 75 | "Rank Stats:", 76 | [ 77 | ("Overall Rank", rewards.rankStats.rank), 78 | ("Ownership Rank", rewards.rankStats.ownershipRank), 79 | ("Mining Rank", rewards.rankStats.miningRank), 80 | ("Validator Rank", rewards.rankStats.validatorRank), 81 | ], 82 | ), 83 | ] 84 | 85 | for section_title, items in sections: 86 | click.echo(click.style(section_title, fg="yellow", bold=True)) 87 | for label, value in items: 88 | click.echo(f"{label}: {value}") 89 | click.echo() 90 | -------------------------------------------------------------------------------- /cli/auth/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sixgpt/minercli/bcb402aa1156226321d97c31ccc9f3e21e4350cf/cli/auth/__init__.py -------------------------------------------------------------------------------- /cli/auth/drive/__init__.py: -------------------------------------------------------------------------------- 1 | from ._impl import get_active_account, set_active_account, remove_active_account 2 | -------------------------------------------------------------------------------- /cli/auth/drive/_impl.py: -------------------------------------------------------------------------------- 1 | import typing as T 2 | import os 3 | import click 4 | import requests 5 | import json 6 | import datetime as dt 7 | import logging 8 | from google.oauth2.credentials import Credentials 9 | 10 | from constants import TMP_DRIVE_AUTH, SIXGPT_API 11 | 12 | SCOPES = ["https://www.googleapis.com/auth/drive.file"] 13 | 14 | 15 | def get_active_account() -> T.Optional[Credentials]: 16 | if os.path.exists(TMP_DRIVE_AUTH): 17 | logging.debug("Found existing drive auth token.") 18 | with open(TMP_DRIVE_AUTH, "r") as token: 19 | code = json.load(token) 20 | code["expiry"] = dt.datetime.fromisoformat(code["expiry"][:-1]).replace( 21 | tzinfo=None 22 | ) 23 | creds = Credentials(**code) 24 | if creds.expired: 25 | logging.debug("Drive auth token expired. Refreshing...") 26 | click.echo("Refreshing drive auth token...") 27 | click.echo(f"Current token: {creds}") 28 | creds = _call_volara_api_server_refresh(creds) 29 | if creds is not None: 30 | _persist_credentials(creds) 31 | return creds 32 | if creds.valid: 33 | return creds 34 | logging.debug("No active drive account found.") 35 | return None 36 | 37 | 38 | def set_active_account() -> T.Optional[Credentials]: 39 | if os.path.exists(TMP_DRIVE_AUTH): 40 | os.remove(TMP_DRIVE_AUTH) 41 | click.echo("Removed existing active account.") 42 | click.echo("Setting active account...") 43 | creds = _call_volara_api_server() 44 | if not creds: 45 | click.echo("Failed to get the drive auth code from SixGPT's auth server.") 46 | return 47 | _persist_credentials(creds) 48 | click.echo("Active account set.") 49 | return creds 50 | 51 | 52 | def remove_active_account() -> None: 53 | click.echo("Removing active account...") 54 | if os.path.exists(TMP_DRIVE_AUTH): 55 | os.remove(TMP_DRIVE_AUTH) 56 | click.echo("Active account removed.") 57 | else: 58 | click.echo("No active account found.") 59 | 60 | 61 | def _persist_credentials(creds: Credentials) -> None: 62 | os.makedirs(os.path.dirname(TMP_DRIVE_AUTH), exist_ok=True) 63 | with open(TMP_DRIVE_AUTH, "w") as token: 64 | token.write(creds.to_json()) 65 | 66 | 67 | def _call_volara_api_server() -> T.Optional[Credentials]: 68 | url_response = requests.get(f"{SIXGPT_API}/drive/get-url") 69 | if url_response.status_code != 200: 70 | return 71 | url = url_response.json()["url"] 72 | click.echo(f"Copy and paste this URL into your browser: {url}") 73 | code = click.prompt("Paste your code") 74 | code_response = requests.get(f"{SIXGPT_API}/drive/callback?code={code}") 75 | code_response.raise_for_status() 76 | if code_response.status_code != 200: 77 | return 78 | resp = code_response.json()["tokens"] 79 | return _form_credentials_from_token(resp) 80 | 81 | 82 | def _call_volara_api_server_refresh(creds: Credentials) -> T.Optional[Credentials]: 83 | url_response = requests.get( 84 | f"{SIXGPT_API}/drive/refresh-token", 85 | params={ 86 | "refreshToken": creds.refresh_token, 87 | }, 88 | ) 89 | if url_response.status_code != 200 and url_response.status_code != 502: 90 | logging.error(f"Failed to refresh drive token: {url_response.json()}") 91 | url_response.raise_for_status() 92 | return 93 | resp = url_response.json()["tokens"] 94 | resp["refresh_token"] = creds.refresh_token 95 | return _form_credentials_from_token(resp) 96 | 97 | 98 | def _form_credentials_from_token(resp: T.Dict[str, T.Any]) -> Credentials: 99 | code = { 100 | "token": resp["access_token"], 101 | "refresh_token": resp["refresh_token"], 102 | "scopes": [resp["scope"]], 103 | "expiry": dt.datetime.fromtimestamp( 104 | resp["expiry_date"] / 1000, dt.timezone.utc 105 | ), 106 | } 107 | return Credentials(**code) 108 | 109 | 110 | if __name__ == "__main__": 111 | creds = get_active_account() 112 | print(creds) 113 | -------------------------------------------------------------------------------- /cli/auth/openai/__init__.py: -------------------------------------------------------------------------------- 1 | from ._impl import set_active_account, get_active_account, remove_active_account -------------------------------------------------------------------------------- /cli/auth/openai/_impl.py: -------------------------------------------------------------------------------- 1 | import os 2 | from twitter.account import Account 3 | import click 4 | import typing as T 5 | import json 6 | from openai import OpenAI 7 | 8 | from constants import TMP_OPENAI_TOKEN 9 | 10 | 11 | def get_active_account() -> T.Optional[Account]: 12 | try: 13 | with open(TMP_OPENAI_TOKEN, "r") as token: 14 | code = json.load(token) 15 | return OpenAI(api_key=code["token"]) 16 | except FileNotFoundError: 17 | click.echo("No active account found.") 18 | return None 19 | except Exception: 20 | click.echo("Failed to authenticate.") 21 | return None 22 | 23 | 24 | def set_active_account() -> bool: 25 | click.echo("Setting active openai account...") 26 | api_key = click.prompt("Enter your OpenAI API Key") 27 | try: 28 | _set_active_account(api_key) 29 | except Exception as e: 30 | click.echo(click.style(str(e), fg="red")) 31 | click.echo( 32 | click.style(f"Failed to authenticate openai account {api_key}.", fg="red"), 33 | err=True, 34 | ) 35 | return False 36 | click.echo("Active openai account successfully set.") 37 | return True 38 | 39 | 40 | def remove_active_account() -> None: 41 | click.echo("Removing active openai account...") 42 | try: 43 | os.remove(TMP_OPENAI_TOKEN) 44 | click.echo("Active openai account successfully removed.") 45 | except FileNotFoundError: 46 | click.echo("No active openai account found.") 47 | 48 | 49 | def _set_active_account(api_key: str) -> None: 50 | client = OpenAI(api_key=api_key) 51 | completion = client.chat.completions.create( 52 | model="gpt-3.5-turbo", 53 | messages=[ 54 | { 55 | "role": "user", 56 | "content": "Tell a good joke in the form of a question. Do not yet give the answer.", 57 | } 58 | ], 59 | ) 60 | click.echo(completion) 61 | os.makedirs(os.path.dirname(TMP_OPENAI_TOKEN), exist_ok=True) 62 | with open(TMP_OPENAI_TOKEN, "w") as file: 63 | file.write(json.dumps(dict({"token": api_key}))) 64 | -------------------------------------------------------------------------------- /cli/auth/sixgpt/__init__.py: -------------------------------------------------------------------------------- 1 | from ._impl import get_sixgpt_jwt, submit_data 2 | -------------------------------------------------------------------------------- /cli/auth/sixgpt/_impl.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import vana 3 | import os 4 | import click 5 | import typing as T 6 | 7 | from eth_account.messages import encode_defunct 8 | 9 | from constants import TMP_SIXGPT_TOKEN, SIXGPT_API, VANA_COLDKEY, VANA_HOTKEY 10 | from miner.task import SyntheticData 11 | 12 | 13 | 14 | def _request_challenge(): 15 | wallet = vana.Wallet(name=VANA_COLDKEY, hotkey=VANA_HOTKEY) 16 | resp = requests.post( 17 | f"{SIXGPT_API}/auth/get-message", 18 | json={"walletAddress": wallet.hotkey.address}, 19 | ) 20 | resp.raise_for_status() 21 | return resp.json()["challenge"] 22 | 23 | 24 | def _submit_signature(challenge): 25 | print(VANA_COLDKEY, VANA_HOTKEY) 26 | wallet = vana.Wallet(name=VANA_COLDKEY, hotkey=VANA_HOTKEY) 27 | vana.Message() 28 | message = encode_defunct(text=challenge["message"]) 29 | signature = wallet.hotkey.sign_message(message).signature.hex() 30 | resp = requests.post( 31 | f"{SIXGPT_API}/auth/submit-signature", 32 | json={"signature": signature, "extraData": challenge["extraData"]}, 33 | ) 34 | resp.raise_for_status() 35 | return resp.json()["accessToken"] 36 | 37 | 38 | def _get_volara_jwt() -> T.Optional[str]: 39 | challenge = _request_challenge() 40 | jwt = _submit_signature(challenge) 41 | return jwt 42 | 43 | 44 | def get_sixgpt_jwt() -> T.Optional[str]: 45 | if os.path.exists(TMP_SIXGPT_TOKEN): 46 | with open(TMP_SIXGPT_TOKEN, "r") as f: 47 | return f.read() 48 | try: 49 | jwt = _get_volara_jwt() 50 | except Exception as e: 51 | click.echo(f"Error getting SixGPT JWT: {e}") 52 | return None 53 | if jwt: 54 | if os.path.exists(TMP_SIXGPT_TOKEN): 55 | os.remove(TMP_SIXGPT_TOKEN) 56 | with open(TMP_SIXGPT_TOKEN, "w") as f: 57 | f.write(jwt) 58 | return jwt 59 | click.echo("Error getting SixGPT JWT") 60 | 61 | def submit_data(jwt: str | None, data: T.Iterable[SyntheticData]): 62 | if jwt is None: 63 | jwt = get_sixgpt_jwt() 64 | if jwt is None: 65 | click.echo("Error getting SixGPT JWT") 66 | return None 67 | 68 | # Convert SyntheticData objects to dictionaries 69 | data_dicts = [item.to_dict() for item in data] 70 | 71 | requests.post( 72 | f"{SIXGPT_API}/miner/submit-data", 73 | json={"data": data_dicts}, 74 | headers={"Authorization": f"Bearer {jwt}"}, 75 | ) 76 | 77 | -------------------------------------------------------------------------------- /cli/auth/twitter/__init__.py: -------------------------------------------------------------------------------- 1 | from ._impl import set_active_account, get_active_account, remove_active_account 2 | -------------------------------------------------------------------------------- /cli/auth/twitter/_impl.py: -------------------------------------------------------------------------------- 1 | import os 2 | from twitter.account import Account 3 | import click 4 | import typing as T 5 | import json 6 | 7 | from constants import TMP_TWITTER_AUTH 8 | 9 | 10 | def get_active_account() -> T.Optional[Account]: 11 | try: 12 | with open(TMP_TWITTER_AUTH, "r"): 13 | pass 14 | return Account(cookies=TMP_TWITTER_AUTH) 15 | except FileNotFoundError: 16 | click.echo("No active account found.") 17 | return None 18 | except Exception: 19 | click.echo("Failed to authenticate.") 20 | return None 21 | 22 | 23 | def set_active_account() -> bool: 24 | click.echo("Setting active twitter account...") 25 | email = click.prompt("Enter your twitter email") 26 | username = click.prompt("Enter your twitter username") 27 | password = click.prompt("Enter your twitter password", hide_input=True) 28 | try: 29 | _set_active_account(email, username, password) 30 | except Exception as e: 31 | click.echo(click.style(str(e), fg="red")) 32 | click.echo( 33 | click.style(f"Failed to authenticate X account {username}.", fg="red"), 34 | err=True, 35 | ) 36 | return False 37 | click.echo("Active twitter account successfully set.") 38 | return True 39 | 40 | def remove_active_account() -> None: 41 | """Remove the active Twitter account by deleting the authentication file.""" 42 | click.echo("Removing active twitter account...") 43 | try: 44 | os.remove(TMP_TWITTER_AUTH) 45 | click.echo("Active twitter account successfully removed.") 46 | except FileNotFoundError: 47 | click.echo("No active twitter account found.") 48 | 49 | 50 | def _set_active_account(email: str, username: str, password: str) -> None: 51 | account = Account(email=email, username=username, password=password) 52 | os.makedirs(os.path.dirname(TMP_TWITTER_AUTH), exist_ok=True) 53 | with open(TMP_TWITTER_AUTH, "w") as file: 54 | file.write(json.dumps(dict(account.session.cookies))) 55 | -------------------------------------------------------------------------------- /cli/auth/vana/__init__.py: -------------------------------------------------------------------------------- 1 | from ._impl import get_vana_hotkey 2 | -------------------------------------------------------------------------------- /cli/auth/vana/_impl.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | import typing as T 3 | 4 | import vana 5 | from constants import NETWORK, VANA_COLDKEY, VANA_HOTKEY 6 | 7 | @dataclass 8 | class ChainConfig: 9 | network: str 10 | 11 | 12 | def get_vana_hotkey() -> T.Optional[str]: 13 | try: 14 | config = vana.Config() 15 | config.chain = ChainConfig(network=NETWORK) 16 | wallet = vana.Wallet(name=VANA_COLDKEY, hotkey=VANA_HOTKEY) 17 | key = wallet.hotkey.address 18 | return key 19 | except Exception: 20 | return None 21 | 22 | -------------------------------------------------------------------------------- /cli/debug.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import click 3 | 4 | 5 | def set_debug_level(ctx, param, value): 6 | if value: 7 | click.echo("Debug logging enabled.") 8 | logging.basicConfig(level=logging.DEBUG) 9 | return value 10 | 11 | 12 | class DebugCommandGroup(click.Group): 13 | def add_command(self, cmd, name=None): 14 | cmd.params.insert( 15 | 0, 16 | click.Option( 17 | ("--debug", "-d"), 18 | is_flag=True, 19 | callback=set_debug_level, 20 | expose_value=False, 21 | help="Enable debug logging", 22 | ), 23 | ) 24 | super().add_command(cmd, name) 25 | -------------------------------------------------------------------------------- /cli/drive_entry.py: -------------------------------------------------------------------------------- 1 | import click 2 | 3 | import cli.auth.drive as drive_auth 4 | 5 | 6 | def register(auth: click.Group): 7 | @auth.group() 8 | def drive(): 9 | """Manage Google Drive Authentication""" 10 | pass 11 | 12 | @drive.command() 13 | def login(): 14 | """Login to Google Drive""" 15 | drive_auth.set_active_account() 16 | 17 | @drive.command() 18 | def logout(): 19 | """Logout from Google Drive""" 20 | drive_auth.remove_active_account() 21 | -------------------------------------------------------------------------------- /cli/entry.py: -------------------------------------------------------------------------------- 1 | import click 2 | 3 | from constants import VERSION 4 | 5 | from cli.debug import DebugCommandGroup 6 | 7 | import cli.miner as mining 8 | import cli.twitter_entry as twitter_entry 9 | import cli.drive_entry as drive_entry 10 | import cli.openai_entry as openai_entry 11 | import cli.auth.twitter as twitter_auth 12 | import cli.auth.drive as drive_auth 13 | import cli.auth.vana as vana_auth 14 | import cli.auth.openai as openai_auth 15 | 16 | import cli.account.rewards as volara_rewards 17 | 18 | import cli.update as volara_update 19 | 20 | 21 | @click.group(cls=DebugCommandGroup) 22 | @click.version_option(version=VERSION) 23 | @click.pass_context 24 | def volara(ctx): 25 | """SixGPT CLI tool""" 26 | ctx.ensure_object(dict) 27 | 28 | 29 | @volara.group() 30 | def auth(): 31 | """Commands related to authentication""" 32 | pass 33 | 34 | 35 | drive_entry.register(auth) 36 | openai_entry.register(auth) 37 | 38 | @volara.group(cls=DebugCommandGroup) 39 | def mine(): 40 | """Commands related to mining""" 41 | pass 42 | 43 | 44 | @mine.command() 45 | @click.option( 46 | "--background", "-b", is_flag=True, help="Run the miner in a background process" 47 | ) 48 | def start(background: bool): 49 | """Start the mining process""" 50 | click.echo("Checking Vana credentials...") 51 | if vana_auth.get_vana_hotkey() is None: 52 | click.echo( 53 | "Vana account is not present. Please install the Vana CLI and create a wallet." 54 | ) 55 | return 56 | click.echo("Checking drive credentials...") 57 | if drive_auth.get_active_account() is None: 58 | click.echo("No active drive account found. Requesting credentials...") 59 | drive_auth.set_active_account() 60 | click.echo("Checking openai credentials...") 61 | if openai_auth.get_active_account() is None: 62 | click.echo("No active openai api key found. Requesting credentials...") 63 | openai_auth.set_active_account() 64 | click.echo("Starting mining daemon...") 65 | if background: 66 | mining.start_daemon() 67 | else: 68 | mining.start_inline() 69 | 70 | 71 | @mine.command() 72 | def stop(): 73 | """Stop the mining process""" 74 | click.echo("Stopping mining daemon...") 75 | mining.stop_daemon() 76 | 77 | 78 | @mine.command() 79 | def logs(): 80 | """Get the logs from the mining process""" 81 | click.echo("Getting mining logs...") 82 | mining.echo_logs() 83 | 84 | 85 | @volara.command() 86 | def update(): 87 | """Update the SixGPT CLI""" 88 | volara_update.update_cli() 89 | 90 | 91 | 92 | if __name__ == "__main__": 93 | volara(obj={}) 94 | -------------------------------------------------------------------------------- /cli/miner/__init__.py: -------------------------------------------------------------------------------- 1 | from ._impl import start_daemon, stop_daemon, echo_logs, start_inline 2 | -------------------------------------------------------------------------------- /cli/miner/_impl.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import os 3 | import signal 4 | import click 5 | 6 | from constants import TMP_MINER_LOG, TMP_PID_FILE 7 | 8 | 9 | def start_inline(): 10 | import asyncio 11 | from miner.run import start_mining 12 | 13 | click.echo("Starting mining process in this shell...") 14 | asyncio.run(start_mining()) 15 | 16 | 17 | # Function to start the daemon 18 | def start_daemon(): 19 | try: 20 | with open(TMP_PID_FILE, "r") as file: 21 | pid = file.read() 22 | if pid: 23 | click.echo(f"Mining daemon already running with PID {pid}") 24 | return 25 | except FileNotFoundError: 26 | pass 27 | 28 | absolute_path = os.path.join( 29 | os.path.dirname(os.path.abspath(__file__)), "../../bin/sixgpt_miner" 30 | ) 31 | process = subprocess.Popen( 32 | [absolute_path], 33 | stdout=subprocess.PIPE, 34 | stderr=subprocess.PIPE, 35 | preexec_fn=os.setpgrp, 36 | ) 37 | # Save the PID to a file to use it later in the stop command 38 | os.makedirs(os.path.dirname(TMP_PID_FILE), exist_ok=True) 39 | with open(TMP_PID_FILE, "w") as file: 40 | file.write(str(process.pid)) 41 | click.echo(f"Mining daemon started with PID {process.pid}") 42 | 43 | 44 | # Function to stop the daemon 45 | def stop_daemon(): 46 | # Read the PID from the file 47 | try: 48 | with open(TMP_PID_FILE, "r") as file: 49 | pid = int(file.read()) 50 | except FileNotFoundError: 51 | click.echo("Mining daemon not running") 52 | return 53 | # Send SIGTERM signal to the process 54 | try: 55 | os.kill(pid, signal.SIGTERM) 56 | except ProcessLookupError: 57 | click.echo("Mining daemon not found... removing state") 58 | pass 59 | # Remove the pid file and log file 60 | os.remove(TMP_PID_FILE) 61 | os.remove(TMP_MINER_LOG) 62 | click.echo(f"Mining daemon stopped with PID {pid}") 63 | 64 | 65 | def echo_logs(): 66 | click.echo(_get_logs()) 67 | 68 | 69 | def _get_logs(): 70 | try: 71 | with open(TMP_MINER_LOG, "r") as file: 72 | return file.read() 73 | except FileNotFoundError: 74 | return "No logs found. Start the mining daemon to get logs." 75 | -------------------------------------------------------------------------------- /cli/openai_entry.py: -------------------------------------------------------------------------------- 1 | import click 2 | 3 | import cli.auth.openai as openai_auth 4 | 5 | 6 | def register(auth: click.Group): 7 | @auth.group() 8 | def openai(): 9 | """Manage OpenAI Authentication""" 10 | pass 11 | 12 | @openai.command() 13 | def login(): 14 | """Set OpenAI API Key""" 15 | openai_auth.set_active_account() 16 | 17 | @openai.command() 18 | def logout(): 19 | """Reset OpenAI API Key""" 20 | openai_auth.remove_active_account() 21 | -------------------------------------------------------------------------------- /cli/twitter_entry.py: -------------------------------------------------------------------------------- 1 | import click 2 | 3 | import cli.auth.twitter as twitter_auth 4 | 5 | 6 | def register(auth: click.Group): 7 | @auth.group() 8 | def twitter(): 9 | """Manage Twitter Authentication""" 10 | pass 11 | 12 | @twitter.command() 13 | def login(): 14 | """Login to Twitter""" 15 | twitter_auth.set_active_account() 16 | 17 | @twitter.command() 18 | def logout(): 19 | """Logout from Twitter""" 20 | twitter_auth.remove_active_account() 21 | -------------------------------------------------------------------------------- /cli/update/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | import click 3 | 4 | 5 | def update_cli(): 6 | try: 7 | resp = os.system("git pull") 8 | except Exception: 9 | click.echo("Failed to update CLI due to exception.") 10 | return 11 | if resp == 0: 12 | click.echo("CLI updated successfully.") 13 | else: 14 | click.echo("Failed to update CLI.") 15 | 16 | 17 | if __name__ == "__main__": 18 | update_cli() 19 | -------------------------------------------------------------------------------- /constants/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | VERSION = "0.1.0" 4 | APPLICATION_NAME = 'sixgpt' 5 | 6 | SIXGPT_TMP_DIR = os.path.expanduser("~/.sixgpt") 7 | 8 | TMP_MINER_LOG = f"{SIXGPT_TMP_DIR}/miner.log" 9 | TMP_PID_FILE = f"{SIXGPT_TMP_DIR}/miner.pid" 10 | TMP_TWITTER_AUTH = f"{SIXGPT_TMP_DIR}/twitter.cookies" 11 | TMP_DRIVE_AUTH = f"{SIXGPT_TMP_DIR}/drive.token" 12 | TMP_SIXGPT_TOKEN = f"{SIXGPT_TMP_DIR}/sixgpt.jwt" 13 | TMP_OPENAI_TOKEN = f"{SIXGPT_TMP_DIR}/openai.token" 14 | 15 | TIMELINE_SLEEP_INTERVAL = 1 16 | ERROR_SLEEP_INTERVAL = 15 17 | TARGET_EXAMPLE_COUNT = 20 18 | 19 | NETWORK = "satori" 20 | SIXGPT_API = "https://api.sixgpt.xyz/v1-sixgpt" 21 | 22 | DLP_ADDRESS = "0x60eD65116Ea6356C9D682718916690E967338850" 23 | MODEL_NAME = "gpt-4o" 24 | 25 | VANA_HOTKEY = os.getenv("VANA_HOTKEY", "default") 26 | VANA_COLDKEY = os.getenv("VANA_COLDKEY", "default") 27 | -------------------------------------------------------------------------------- /miner/build.py: -------------------------------------------------------------------------------- 1 | import flatbuffers 2 | import zipfile 3 | import io 4 | import typing as T 5 | import json 6 | 7 | from miner.extract import SyntheticData 8 | 9 | 10 | def build_buffer(examples: T.Iterable[SyntheticData]) -> bytes: 11 | return json.dumps([example.to_dict() for example in examples]).encode('utf-8') 12 | 13 | 14 | def build_zip_buffer(buffer: bytes) -> bytes: 15 | zip_buffer = io.BytesIO() 16 | with zipfile.ZipFile(zip_buffer, "w", zipfile.ZIP_DEFLATED) as zip_file: 17 | zip_file.writestr("examples.data", buffer) 18 | zip_buffer.seek(0) 19 | return zip_buffer.getvalue() 20 | -------------------------------------------------------------------------------- /miner/dlp/dlp-implementation-abi.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "AccessControlBadConfirmation", 5 | "type": "error" 6 | }, 7 | { 8 | "inputs": [ 9 | { 10 | "internalType": "address", 11 | "name": "account", 12 | "type": "address" 13 | }, 14 | { 15 | "internalType": "bytes32", 16 | "name": "neededRole", 17 | "type": "bytes32" 18 | } 19 | ], 20 | "name": "AccessControlUnauthorizedAccount", 21 | "type": "error" 22 | }, 23 | { 24 | "inputs": [ 25 | { 26 | "internalType": "address", 27 | "name": "target", 28 | "type": "address" 29 | } 30 | ], 31 | "name": "AddressEmptyCode", 32 | "type": "error" 33 | }, 34 | { 35 | "inputs": [ 36 | { 37 | "internalType": "address", 38 | "name": "account", 39 | "type": "address" 40 | } 41 | ], 42 | "name": "AddressInsufficientBalance", 43 | "type": "error" 44 | }, 45 | { 46 | "inputs": [], 47 | "name": "ArityMismatch", 48 | "type": "error" 49 | }, 50 | { 51 | "inputs": [ 52 | { 53 | "internalType": "address", 54 | "name": "implementation", 55 | "type": "address" 56 | } 57 | ], 58 | "name": "ERC1967InvalidImplementation", 59 | "type": "error" 60 | }, 61 | { 62 | "inputs": [], 63 | "name": "ERC1967NonPayable", 64 | "type": "error" 65 | }, 66 | { 67 | "inputs": [], 68 | "name": "EnforcedPause", 69 | "type": "error" 70 | }, 71 | { 72 | "inputs": [], 73 | "name": "ExpectedPause", 74 | "type": "error" 75 | }, 76 | { 77 | "inputs": [], 78 | "name": "FailedInnerCall", 79 | "type": "error" 80 | }, 81 | { 82 | "inputs": [], 83 | "name": "FileAlreadyAdded", 84 | "type": "error" 85 | }, 86 | { 87 | "inputs": [], 88 | "name": "FileAlreadyVerified", 89 | "type": "error" 90 | }, 91 | { 92 | "inputs": [], 93 | "name": "InvalidFileId", 94 | "type": "error" 95 | }, 96 | { 97 | "inputs": [], 98 | "name": "InvalidInitialization", 99 | "type": "error" 100 | }, 101 | { 102 | "inputs": [], 103 | "name": "InvalidStakeAmount", 104 | "type": "error" 105 | }, 106 | { 107 | "inputs": [], 108 | "name": "InvalidValidatorStatus", 109 | "type": "error" 110 | }, 111 | { 112 | "inputs": [], 113 | "name": "MasterKeyAlreadySet", 114 | "type": "error" 115 | }, 116 | { 117 | "inputs": [], 118 | "name": "NotAllowed", 119 | "type": "error" 120 | }, 121 | { 122 | "inputs": [], 123 | "name": "NotFileOwner", 124 | "type": "error" 125 | }, 126 | { 127 | "inputs": [], 128 | "name": "NotFinalized", 129 | "type": "error" 130 | }, 131 | { 132 | "inputs": [], 133 | "name": "NotInitializing", 134 | "type": "error" 135 | }, 136 | { 137 | "inputs": [], 138 | "name": "NotValidatorOwner", 139 | "type": "error" 140 | }, 141 | { 142 | "inputs": [], 143 | "name": "NothingToClaim", 144 | "type": "error" 145 | }, 146 | { 147 | "inputs": [ 148 | { 149 | "internalType": "address", 150 | "name": "owner", 151 | "type": "address" 152 | } 153 | ], 154 | "name": "OwnableInvalidOwner", 155 | "type": "error" 156 | }, 157 | { 158 | "inputs": [ 159 | { 160 | "internalType": "address", 161 | "name": "account", 162 | "type": "address" 163 | } 164 | ], 165 | "name": "OwnableUnauthorizedAccount", 166 | "type": "error" 167 | }, 168 | { 169 | "inputs": [], 170 | "name": "ReentrancyGuardReentrantCall", 171 | "type": "error" 172 | }, 173 | { 174 | "inputs": [ 175 | { 176 | "internalType": "address", 177 | "name": "token", 178 | "type": "address" 179 | } 180 | ], 181 | "name": "SafeERC20FailedOperation", 182 | "type": "error" 183 | }, 184 | { 185 | "inputs": [], 186 | "name": "TooManyValidators", 187 | "type": "error" 188 | }, 189 | { 190 | "inputs": [], 191 | "name": "UUPSUnauthorizedCallContext", 192 | "type": "error" 193 | }, 194 | { 195 | "inputs": [ 196 | { 197 | "internalType": "bytes32", 198 | "name": "slot", 199 | "type": "bytes32" 200 | } 201 | ], 202 | "name": "UUPSUnsupportedProxiableUUID", 203 | "type": "error" 204 | }, 205 | { 206 | "inputs": [], 207 | "name": "WithdrawNotAllowed", 208 | "type": "error" 209 | }, 210 | { 211 | "anonymous": false, 212 | "inputs": [ 213 | { 214 | "indexed": true, 215 | "internalType": "address", 216 | "name": "contributorAddress", 217 | "type": "address" 218 | }, 219 | { 220 | "indexed": false, 221 | "internalType": "uint256", 222 | "name": "fileId", 223 | "type": "uint256" 224 | }, 225 | { 226 | "indexed": false, 227 | "internalType": "uint256", 228 | "name": "amount", 229 | "type": "uint256" 230 | } 231 | ], 232 | "name": "ContributionRewardClaimed", 233 | "type": "event" 234 | }, 235 | { 236 | "anonymous": false, 237 | "inputs": [ 238 | { 239 | "indexed": false, 240 | "internalType": "uint256", 241 | "name": "epochId", 242 | "type": "uint256" 243 | } 244 | ], 245 | "name": "EpochCreated", 246 | "type": "event" 247 | }, 248 | { 249 | "anonymous": false, 250 | "inputs": [ 251 | { 252 | "indexed": false, 253 | "internalType": "uint256", 254 | "name": "newEpochRewardAmount", 255 | "type": "uint256" 256 | } 257 | ], 258 | "name": "EpochRewardAmountUpdated", 259 | "type": "event" 260 | }, 261 | { 262 | "anonymous": false, 263 | "inputs": [ 264 | { 265 | "indexed": false, 266 | "internalType": "address", 267 | "name": "validator", 268 | "type": "address" 269 | }, 270 | { 271 | "indexed": false, 272 | "internalType": "uint256", 273 | "name": "epochId", 274 | "type": "uint256" 275 | }, 276 | { 277 | "indexed": false, 278 | "internalType": "uint256", 279 | "name": "claimAmount", 280 | "type": "uint256" 281 | } 282 | ], 283 | "name": "EpochRewardClaimed", 284 | "type": "event" 285 | }, 286 | { 287 | "anonymous": false, 288 | "inputs": [ 289 | { 290 | "indexed": false, 291 | "internalType": "uint256", 292 | "name": "newEpochSize", 293 | "type": "uint256" 294 | } 295 | ], 296 | "name": "EpochSizeUpdated", 297 | "type": "event" 298 | }, 299 | { 300 | "anonymous": false, 301 | "inputs": [ 302 | { 303 | "indexed": true, 304 | "internalType": "address", 305 | "name": "contributorAddress", 306 | "type": "address" 307 | }, 308 | { 309 | "indexed": false, 310 | "internalType": "uint256", 311 | "name": "fileId", 312 | "type": "uint256" 313 | } 314 | ], 315 | "name": "FileAdded", 316 | "type": "event" 317 | }, 318 | { 319 | "anonymous": false, 320 | "inputs": [ 321 | { 322 | "indexed": false, 323 | "internalType": "uint256", 324 | "name": "newFileRewardDelay", 325 | "type": "uint256" 326 | } 327 | ], 328 | "name": "FileRewardDelayUpdated", 329 | "type": "event" 330 | }, 331 | { 332 | "anonymous": false, 333 | "inputs": [ 334 | { 335 | "indexed": false, 336 | "internalType": "uint256", 337 | "name": "newFileRewardFactor", 338 | "type": "uint256" 339 | } 340 | ], 341 | "name": "FileRewardFactorUpdated", 342 | "type": "event" 343 | }, 344 | { 345 | "anonymous": false, 346 | "inputs": [ 347 | { 348 | "indexed": true, 349 | "internalType": "address", 350 | "name": "validatorAddress", 351 | "type": "address" 352 | }, 353 | { 354 | "indexed": false, 355 | "internalType": "uint256", 356 | "name": "fileId", 357 | "type": "uint256" 358 | }, 359 | { 360 | "indexed": false, 361 | "internalType": "uint256", 362 | "name": "score", 363 | "type": "uint256" 364 | } 365 | ], 366 | "name": "FileVerified", 367 | "type": "event" 368 | }, 369 | { 370 | "anonymous": false, 371 | "inputs": [ 372 | { 373 | "indexed": false, 374 | "internalType": "uint64", 375 | "name": "version", 376 | "type": "uint64" 377 | } 378 | ], 379 | "name": "Initialized", 380 | "type": "event" 381 | }, 382 | { 383 | "anonymous": false, 384 | "inputs": [ 385 | { 386 | "indexed": false, 387 | "internalType": "string", 388 | "name": "newMasterKey", 389 | "type": "string" 390 | } 391 | ], 392 | "name": "MasterKeySet", 393 | "type": "event" 394 | }, 395 | { 396 | "anonymous": false, 397 | "inputs": [ 398 | { 399 | "indexed": false, 400 | "internalType": "uint256", 401 | "name": "newMaxNumberOfValidators", 402 | "type": "uint256" 403 | } 404 | ], 405 | "name": "MaxNumberOfValidatorsUpdated", 406 | "type": "event" 407 | }, 408 | { 409 | "anonymous": false, 410 | "inputs": [ 411 | { 412 | "indexed": false, 413 | "internalType": "uint256", 414 | "name": "newMinStakeAmount", 415 | "type": "uint256" 416 | } 417 | ], 418 | "name": "MinStakeAmountUpdated", 419 | "type": "event" 420 | }, 421 | { 422 | "anonymous": false, 423 | "inputs": [ 424 | { 425 | "indexed": true, 426 | "internalType": "address", 427 | "name": "previousOwner", 428 | "type": "address" 429 | }, 430 | { 431 | "indexed": true, 432 | "internalType": "address", 433 | "name": "newOwner", 434 | "type": "address" 435 | } 436 | ], 437 | "name": "OwnershipTransferStarted", 438 | "type": "event" 439 | }, 440 | { 441 | "anonymous": false, 442 | "inputs": [ 443 | { 444 | "indexed": true, 445 | "internalType": "address", 446 | "name": "previousOwner", 447 | "type": "address" 448 | }, 449 | { 450 | "indexed": true, 451 | "internalType": "address", 452 | "name": "newOwner", 453 | "type": "address" 454 | } 455 | ], 456 | "name": "OwnershipTransferred", 457 | "type": "event" 458 | }, 459 | { 460 | "anonymous": false, 461 | "inputs": [ 462 | { 463 | "indexed": false, 464 | "internalType": "address", 465 | "name": "account", 466 | "type": "address" 467 | } 468 | ], 469 | "name": "Paused", 470 | "type": "event" 471 | }, 472 | { 473 | "anonymous": false, 474 | "inputs": [ 475 | { 476 | "indexed": true, 477 | "internalType": "bytes32", 478 | "name": "role", 479 | "type": "bytes32" 480 | }, 481 | { 482 | "indexed": true, 483 | "internalType": "bytes32", 484 | "name": "previousAdminRole", 485 | "type": "bytes32" 486 | }, 487 | { 488 | "indexed": true, 489 | "internalType": "bytes32", 490 | "name": "newAdminRole", 491 | "type": "bytes32" 492 | } 493 | ], 494 | "name": "RoleAdminChanged", 495 | "type": "event" 496 | }, 497 | { 498 | "anonymous": false, 499 | "inputs": [ 500 | { 501 | "indexed": true, 502 | "internalType": "bytes32", 503 | "name": "role", 504 | "type": "bytes32" 505 | }, 506 | { 507 | "indexed": true, 508 | "internalType": "address", 509 | "name": "account", 510 | "type": "address" 511 | }, 512 | { 513 | "indexed": true, 514 | "internalType": "address", 515 | "name": "sender", 516 | "type": "address" 517 | } 518 | ], 519 | "name": "RoleGranted", 520 | "type": "event" 521 | }, 522 | { 523 | "anonymous": false, 524 | "inputs": [ 525 | { 526 | "indexed": true, 527 | "internalType": "bytes32", 528 | "name": "role", 529 | "type": "bytes32" 530 | }, 531 | { 532 | "indexed": true, 533 | "internalType": "address", 534 | "name": "account", 535 | "type": "address" 536 | }, 537 | { 538 | "indexed": true, 539 | "internalType": "address", 540 | "name": "sender", 541 | "type": "address" 542 | } 543 | ], 544 | "name": "RoleRevoked", 545 | "type": "event" 546 | }, 547 | { 548 | "anonymous": false, 549 | "inputs": [ 550 | { 551 | "indexed": true, 552 | "internalType": "address", 553 | "name": "validatorAddress", 554 | "type": "address" 555 | }, 556 | { 557 | "indexed": false, 558 | "internalType": "uint256", 559 | "name": "amount", 560 | "type": "uint256" 561 | }, 562 | { 563 | "indexed": false, 564 | "internalType": "uint256", 565 | "name": "totalAmount", 566 | "type": "uint256" 567 | } 568 | ], 569 | "name": "Staked", 570 | "type": "event" 571 | }, 572 | { 573 | "anonymous": false, 574 | "inputs": [ 575 | { 576 | "indexed": false, 577 | "internalType": "address", 578 | "name": "account", 579 | "type": "address" 580 | } 581 | ], 582 | "name": "Unpaused", 583 | "type": "event" 584 | }, 585 | { 586 | "anonymous": false, 587 | "inputs": [ 588 | { 589 | "indexed": true, 590 | "internalType": "address", 591 | "name": "stakerAddress", 592 | "type": "address" 593 | }, 594 | { 595 | "indexed": false, 596 | "internalType": "uint256", 597 | "name": "amount", 598 | "type": "uint256" 599 | } 600 | ], 601 | "name": "Unstaked", 602 | "type": "event" 603 | }, 604 | { 605 | "anonymous": false, 606 | "inputs": [ 607 | { 608 | "indexed": true, 609 | "internalType": "address", 610 | "name": "implementation", 611 | "type": "address" 612 | } 613 | ], 614 | "name": "Upgraded", 615 | "type": "event" 616 | }, 617 | { 618 | "anonymous": false, 619 | "inputs": [ 620 | { 621 | "indexed": false, 622 | "internalType": "uint256", 623 | "name": "newValidationPeriod", 624 | "type": "uint256" 625 | } 626 | ], 627 | "name": "ValidationPeriodUpdated", 628 | "type": "event" 629 | }, 630 | { 631 | "anonymous": false, 632 | "inputs": [ 633 | { 634 | "indexed": true, 635 | "internalType": "address", 636 | "name": "validatorAddress", 637 | "type": "address" 638 | } 639 | ], 640 | "name": "ValidatorApproved", 641 | "type": "event" 642 | }, 643 | { 644 | "anonymous": false, 645 | "inputs": [ 646 | { 647 | "indexed": true, 648 | "internalType": "address", 649 | "name": "validatorAddress", 650 | "type": "address" 651 | } 652 | ], 653 | "name": "ValidatorDeregistered", 654 | "type": "event" 655 | }, 656 | { 657 | "anonymous": false, 658 | "inputs": [ 659 | { 660 | "indexed": true, 661 | "internalType": "address", 662 | "name": "validatorAddress", 663 | "type": "address" 664 | }, 665 | { 666 | "indexed": false, 667 | "internalType": "uint256", 668 | "name": "unstakedAmount", 669 | "type": "uint256" 670 | }, 671 | { 672 | "indexed": false, 673 | "internalType": "uint256", 674 | "name": "penaltyAmount", 675 | "type": "uint256" 676 | } 677 | ], 678 | "name": "ValidatorDeregisteredByOwner", 679 | "type": "event" 680 | }, 681 | { 682 | "anonymous": false, 683 | "inputs": [ 684 | { 685 | "indexed": true, 686 | "internalType": "address", 687 | "name": "validatorAddress", 688 | "type": "address" 689 | }, 690 | { 691 | "indexed": true, 692 | "internalType": "address", 693 | "name": "ownerAddress", 694 | "type": "address" 695 | }, 696 | { 697 | "indexed": false, 698 | "internalType": "uint256", 699 | "name": "amount", 700 | "type": "uint256" 701 | } 702 | ], 703 | "name": "ValidatorRegistered", 704 | "type": "event" 705 | }, 706 | { 707 | "anonymous": false, 708 | "inputs": [ 709 | { 710 | "indexed": false, 711 | "internalType": "uint256", 712 | "name": "newValidatorScoreKappa", 713 | "type": "uint256" 714 | } 715 | ], 716 | "name": "ValidatorScoreKappaUpdated", 717 | "type": "event" 718 | }, 719 | { 720 | "anonymous": false, 721 | "inputs": [ 722 | { 723 | "indexed": false, 724 | "internalType": "uint256", 725 | "name": "newValidatorScoreMinTrust", 726 | "type": "uint256" 727 | } 728 | ], 729 | "name": "ValidatorScoreMinTrustUpdated", 730 | "type": "event" 731 | }, 732 | { 733 | "anonymous": false, 734 | "inputs": [ 735 | { 736 | "indexed": false, 737 | "internalType": "uint256", 738 | "name": "newValidatorScoreRho", 739 | "type": "uint256" 740 | } 741 | ], 742 | "name": "ValidatorScoreRhoUpdated", 743 | "type": "event" 744 | }, 745 | { 746 | "anonymous": false, 747 | "inputs": [ 748 | { 749 | "indexed": true, 750 | "internalType": "address", 751 | "name": "validatorAddress", 752 | "type": "address" 753 | } 754 | ], 755 | "name": "ValidatorUnregistered", 756 | "type": "event" 757 | }, 758 | { 759 | "anonymous": false, 760 | "inputs": [ 761 | { 762 | "indexed": true, 763 | "internalType": "address", 764 | "name": "validatorAddress", 765 | "type": "address" 766 | }, 767 | { 768 | "indexed": false, 769 | "internalType": "address[]", 770 | "name": "validators", 771 | "type": "address[]" 772 | }, 773 | { 774 | "indexed": false, 775 | "internalType": "uint256[]", 776 | "name": "weights", 777 | "type": "uint256[]" 778 | } 779 | ], 780 | "name": "WeightsUpdated", 781 | "type": "event" 782 | }, 783 | { 784 | "inputs": [], 785 | "name": "DEFAULT_ADMIN_ROLE", 786 | "outputs": [ 787 | { 788 | "internalType": "bytes32", 789 | "name": "", 790 | "type": "bytes32" 791 | } 792 | ], 793 | "stateMutability": "view", 794 | "type": "function" 795 | }, 796 | { 797 | "inputs": [], 798 | "name": "UPGRADE_INTERFACE_VERSION", 799 | "outputs": [ 800 | { 801 | "internalType": "string", 802 | "name": "", 803 | "type": "string" 804 | } 805 | ], 806 | "stateMutability": "view", 807 | "type": "function" 808 | }, 809 | { 810 | "inputs": [], 811 | "name": "acceptOwnership", 812 | "outputs": [], 813 | "stateMutability": "nonpayable", 814 | "type": "function" 815 | }, 816 | { 817 | "inputs": [ 818 | { 819 | "internalType": "uint256", 820 | "name": "id", 821 | "type": "uint256" 822 | } 823 | ], 824 | "name": "activeValidatorsLists", 825 | "outputs": [ 826 | { 827 | "internalType": "address[]", 828 | "name": "", 829 | "type": "address[]" 830 | } 831 | ], 832 | "stateMutability": "view", 833 | "type": "function" 834 | }, 835 | { 836 | "inputs": [], 837 | "name": "activeValidatorsListsCount", 838 | "outputs": [ 839 | { 840 | "internalType": "uint256", 841 | "name": "", 842 | "type": "uint256" 843 | } 844 | ], 845 | "stateMutability": "view", 846 | "type": "function" 847 | }, 848 | { 849 | "inputs": [ 850 | { 851 | "internalType": "string", 852 | "name": "url", 853 | "type": "string" 854 | }, 855 | { 856 | "internalType": "string", 857 | "name": "encryptedKey", 858 | "type": "string" 859 | } 860 | ], 861 | "name": "addFile", 862 | "outputs": [], 863 | "stateMutability": "nonpayable", 864 | "type": "function" 865 | }, 866 | { 867 | "inputs": [ 868 | { 869 | "internalType": "uint256", 870 | "name": "validatorsRewardAmount", 871 | "type": "uint256" 872 | } 873 | ], 874 | "name": "addRewardForValidators", 875 | "outputs": [], 876 | "stateMutability": "nonpayable", 877 | "type": "function" 878 | }, 879 | { 880 | "inputs": [ 881 | { 882 | "internalType": "uint256", 883 | "name": "contributorsRewardAmount", 884 | "type": "uint256" 885 | } 886 | ], 887 | "name": "addRewardsForContributors", 888 | "outputs": [], 889 | "stateMutability": "nonpayable", 890 | "type": "function" 891 | }, 892 | { 893 | "inputs": [ 894 | { 895 | "internalType": "bytes32", 896 | "name": "userId", 897 | "type": "bytes32" 898 | }, 899 | { 900 | "internalType": "address", 901 | "name": "newOwner", 902 | "type": "address" 903 | } 904 | ], 905 | "name": "addUserIdOwner", 906 | "outputs": [], 907 | "stateMutability": "nonpayable", 908 | "type": "function" 909 | }, 910 | { 911 | "inputs": [ 912 | { 913 | "internalType": "address", 914 | "name": "validatorAddress", 915 | "type": "address" 916 | } 917 | ], 918 | "name": "approveValidator", 919 | "outputs": [], 920 | "stateMutability": "nonpayable", 921 | "type": "function" 922 | }, 923 | { 924 | "inputs": [ 925 | { 926 | "internalType": "uint256", 927 | "name": "fileId", 928 | "type": "uint256" 929 | } 930 | ], 931 | "name": "claimContributionReward", 932 | "outputs": [], 933 | "stateMutability": "nonpayable", 934 | "type": "function" 935 | }, 936 | { 937 | "inputs": [ 938 | { 939 | "internalType": "address", 940 | "name": "validatorAddress", 941 | "type": "address" 942 | }, 943 | { 944 | "internalType": "uint256", 945 | "name": "epochNumber", 946 | "type": "uint256" 947 | } 948 | ], 949 | "name": "claimUnsentReward", 950 | "outputs": [], 951 | "stateMutability": "nonpayable", 952 | "type": "function" 953 | }, 954 | { 955 | "inputs": [ 956 | { 957 | "internalType": "address", 958 | "name": "contributorAddress", 959 | "type": "address" 960 | }, 961 | { 962 | "internalType": "uint256", 963 | "name": "index", 964 | "type": "uint256" 965 | } 966 | ], 967 | "name": "contributorFiles", 968 | "outputs": [ 969 | { 970 | "components": [ 971 | { 972 | "internalType": "uint256", 973 | "name": "fileId", 974 | "type": "uint256" 975 | }, 976 | { 977 | "internalType": "address", 978 | "name": "ownerAddress", 979 | "type": "address" 980 | }, 981 | { 982 | "internalType": "string", 983 | "name": "url", 984 | "type": "string" 985 | }, 986 | { 987 | "internalType": "string", 988 | "name": "encryptedKey", 989 | "type": "string" 990 | }, 991 | { 992 | "internalType": "uint256", 993 | "name": "addedTimestamp", 994 | "type": "uint256" 995 | }, 996 | { 997 | "internalType": "uint256", 998 | "name": "addedAtBlock", 999 | "type": "uint256" 1000 | }, 1001 | { 1002 | "internalType": "bool", 1003 | "name": "valid", 1004 | "type": "bool" 1005 | }, 1006 | { 1007 | "internalType": "bool", 1008 | "name": "finalized", 1009 | "type": "bool" 1010 | }, 1011 | { 1012 | "internalType": "uint256", 1013 | "name": "score", 1014 | "type": "uint256" 1015 | }, 1016 | { 1017 | "internalType": "uint256", 1018 | "name": "authenticity", 1019 | "type": "uint256" 1020 | }, 1021 | { 1022 | "internalType": "uint256", 1023 | "name": "ownership", 1024 | "type": "uint256" 1025 | }, 1026 | { 1027 | "internalType": "uint256", 1028 | "name": "quality", 1029 | "type": "uint256" 1030 | }, 1031 | { 1032 | "internalType": "uint256", 1033 | "name": "uniqueness", 1034 | "type": "uint256" 1035 | }, 1036 | { 1037 | "internalType": "uint256", 1038 | "name": "reward", 1039 | "type": "uint256" 1040 | }, 1041 | { 1042 | "internalType": "uint256", 1043 | "name": "rewardWithdrawn", 1044 | "type": "uint256" 1045 | }, 1046 | { 1047 | "internalType": "uint256", 1048 | "name": "verificationsCount", 1049 | "type": "uint256" 1050 | } 1051 | ], 1052 | "internalType": "struct IDataLiquidityPool.FileResponse", 1053 | "name": "", 1054 | "type": "tuple" 1055 | } 1056 | ], 1057 | "stateMutability": "view", 1058 | "type": "function" 1059 | }, 1060 | { 1061 | "inputs": [ 1062 | { 1063 | "internalType": "address", 1064 | "name": "contributorAddress", 1065 | "type": "address" 1066 | } 1067 | ], 1068 | "name": "contributorInfo", 1069 | "outputs": [ 1070 | { 1071 | "components": [ 1072 | { 1073 | "internalType": "address", 1074 | "name": "contributorAddress", 1075 | "type": "address" 1076 | }, 1077 | { 1078 | "internalType": "uint256", 1079 | "name": "fileIdsCount", 1080 | "type": "uint256" 1081 | } 1082 | ], 1083 | "internalType": "struct IDataLiquidityPool.ContributorInfoResponse", 1084 | "name": "", 1085 | "type": "tuple" 1086 | } 1087 | ], 1088 | "stateMutability": "view", 1089 | "type": "function" 1090 | }, 1091 | { 1092 | "inputs": [ 1093 | { 1094 | "internalType": "uint256", 1095 | "name": "index", 1096 | "type": "uint256" 1097 | } 1098 | ], 1099 | "name": "contributors", 1100 | "outputs": [ 1101 | { 1102 | "components": [ 1103 | { 1104 | "internalType": "address", 1105 | "name": "contributorAddress", 1106 | "type": "address" 1107 | }, 1108 | { 1109 | "internalType": "uint256", 1110 | "name": "fileIdsCount", 1111 | "type": "uint256" 1112 | } 1113 | ], 1114 | "internalType": "struct IDataLiquidityPool.ContributorInfoResponse", 1115 | "name": "", 1116 | "type": "tuple" 1117 | } 1118 | ], 1119 | "stateMutability": "view", 1120 | "type": "function" 1121 | }, 1122 | { 1123 | "inputs": [], 1124 | "name": "contributorsCount", 1125 | "outputs": [ 1126 | { 1127 | "internalType": "uint256", 1128 | "name": "", 1129 | "type": "uint256" 1130 | } 1131 | ], 1132 | "stateMutability": "view", 1133 | "type": "function" 1134 | }, 1135 | { 1136 | "inputs": [], 1137 | "name": "createEpochs", 1138 | "outputs": [], 1139 | "stateMutability": "nonpayable", 1140 | "type": "function" 1141 | }, 1142 | { 1143 | "inputs": [ 1144 | { 1145 | "internalType": "uint256", 1146 | "name": "blockNumber", 1147 | "type": "uint256" 1148 | } 1149 | ], 1150 | "name": "createEpochsUntilBlockNumber", 1151 | "outputs": [], 1152 | "stateMutability": "nonpayable", 1153 | "type": "function" 1154 | }, 1155 | { 1156 | "inputs": [ 1157 | { 1158 | "internalType": "address", 1159 | "name": "validatorAddress", 1160 | "type": "address" 1161 | } 1162 | ], 1163 | "name": "deregisterValidator", 1164 | "outputs": [], 1165 | "stateMutability": "nonpayable", 1166 | "type": "function" 1167 | }, 1168 | { 1169 | "inputs": [ 1170 | { 1171 | "internalType": "address", 1172 | "name": "validatorAddress", 1173 | "type": "address" 1174 | }, 1175 | { 1176 | "internalType": "uint256", 1177 | "name": "unstakeAmount", 1178 | "type": "uint256" 1179 | } 1180 | ], 1181 | "name": "deregisterValidatorByOwner", 1182 | "outputs": [], 1183 | "stateMutability": "nonpayable", 1184 | "type": "function" 1185 | }, 1186 | { 1187 | "inputs": [], 1188 | "name": "epochRewardAmount", 1189 | "outputs": [ 1190 | { 1191 | "internalType": "uint256", 1192 | "name": "", 1193 | "type": "uint256" 1194 | } 1195 | ], 1196 | "stateMutability": "view", 1197 | "type": "function" 1198 | }, 1199 | { 1200 | "inputs": [ 1201 | { 1202 | "internalType": "uint256", 1203 | "name": "epochId", 1204 | "type": "uint256" 1205 | } 1206 | ], 1207 | "name": "epochRewards", 1208 | "outputs": [ 1209 | { 1210 | "internalType": "address[]", 1211 | "name": "validators", 1212 | "type": "address[]" 1213 | }, 1214 | { 1215 | "internalType": "uint256[]", 1216 | "name": "scores", 1217 | "type": "uint256[]" 1218 | }, 1219 | { 1220 | "internalType": "uint256[]", 1221 | "name": "withdrawnAmounts", 1222 | "type": "uint256[]" 1223 | } 1224 | ], 1225 | "stateMutability": "view", 1226 | "type": "function" 1227 | }, 1228 | { 1229 | "inputs": [], 1230 | "name": "epochSize", 1231 | "outputs": [ 1232 | { 1233 | "internalType": "uint256", 1234 | "name": "", 1235 | "type": "uint256" 1236 | } 1237 | ], 1238 | "stateMutability": "view", 1239 | "type": "function" 1240 | }, 1241 | { 1242 | "inputs": [ 1243 | { 1244 | "internalType": "uint256", 1245 | "name": "epochId", 1246 | "type": "uint256" 1247 | } 1248 | ], 1249 | "name": "epochs", 1250 | "outputs": [ 1251 | { 1252 | "components": [ 1253 | { 1254 | "internalType": "uint256", 1255 | "name": "startBlock", 1256 | "type": "uint256" 1257 | }, 1258 | { 1259 | "internalType": "uint256", 1260 | "name": "endBlock", 1261 | "type": "uint256" 1262 | }, 1263 | { 1264 | "internalType": "uint256", 1265 | "name": "reward", 1266 | "type": "uint256" 1267 | }, 1268 | { 1269 | "internalType": "uint256", 1270 | "name": "validatorsListId", 1271 | "type": "uint256" 1272 | } 1273 | ], 1274 | "internalType": "struct IDataLiquidityPool.EpochResponse", 1275 | "name": "", 1276 | "type": "tuple" 1277 | } 1278 | ], 1279 | "stateMutability": "view", 1280 | "type": "function" 1281 | }, 1282 | { 1283 | "inputs": [], 1284 | "name": "epochsCount", 1285 | "outputs": [ 1286 | { 1287 | "internalType": "uint256", 1288 | "name": "", 1289 | "type": "uint256" 1290 | } 1291 | ], 1292 | "stateMutability": "view", 1293 | "type": "function" 1294 | }, 1295 | { 1296 | "inputs": [], 1297 | "name": "fileRewardDelay", 1298 | "outputs": [ 1299 | { 1300 | "internalType": "uint256", 1301 | "name": "", 1302 | "type": "uint256" 1303 | } 1304 | ], 1305 | "stateMutability": "view", 1306 | "type": "function" 1307 | }, 1308 | { 1309 | "inputs": [], 1310 | "name": "fileRewardFactor", 1311 | "outputs": [ 1312 | { 1313 | "internalType": "uint256", 1314 | "name": "", 1315 | "type": "uint256" 1316 | } 1317 | ], 1318 | "stateMutability": "view", 1319 | "type": "function" 1320 | }, 1321 | { 1322 | "inputs": [ 1323 | { 1324 | "internalType": "uint256", 1325 | "name": "fileId", 1326 | "type": "uint256" 1327 | }, 1328 | { 1329 | "internalType": "address", 1330 | "name": "validatorAddress", 1331 | "type": "address" 1332 | } 1333 | ], 1334 | "name": "fileScores", 1335 | "outputs": [ 1336 | { 1337 | "components": [ 1338 | { 1339 | "internalType": "bool", 1340 | "name": "valid", 1341 | "type": "bool" 1342 | }, 1343 | { 1344 | "internalType": "uint256", 1345 | "name": "score", 1346 | "type": "uint256" 1347 | }, 1348 | { 1349 | "internalType": "uint256", 1350 | "name": "reportedAtBlock", 1351 | "type": "uint256" 1352 | }, 1353 | { 1354 | "internalType": "uint256", 1355 | "name": "authenticity", 1356 | "type": "uint256" 1357 | }, 1358 | { 1359 | "internalType": "uint256", 1360 | "name": "ownership", 1361 | "type": "uint256" 1362 | }, 1363 | { 1364 | "internalType": "uint256", 1365 | "name": "quality", 1366 | "type": "uint256" 1367 | }, 1368 | { 1369 | "internalType": "uint256", 1370 | "name": "uniqueness", 1371 | "type": "uint256" 1372 | } 1373 | ], 1374 | "internalType": "struct IDataLiquidityPool.FileScore", 1375 | "name": "", 1376 | "type": "tuple" 1377 | } 1378 | ], 1379 | "stateMutability": "view", 1380 | "type": "function" 1381 | }, 1382 | { 1383 | "inputs": [ 1384 | { 1385 | "internalType": "uint256", 1386 | "name": "fileId", 1387 | "type": "uint256" 1388 | } 1389 | ], 1390 | "name": "files", 1391 | "outputs": [ 1392 | { 1393 | "components": [ 1394 | { 1395 | "internalType": "uint256", 1396 | "name": "fileId", 1397 | "type": "uint256" 1398 | }, 1399 | { 1400 | "internalType": "address", 1401 | "name": "ownerAddress", 1402 | "type": "address" 1403 | }, 1404 | { 1405 | "internalType": "string", 1406 | "name": "url", 1407 | "type": "string" 1408 | }, 1409 | { 1410 | "internalType": "string", 1411 | "name": "encryptedKey", 1412 | "type": "string" 1413 | }, 1414 | { 1415 | "internalType": "uint256", 1416 | "name": "addedTimestamp", 1417 | "type": "uint256" 1418 | }, 1419 | { 1420 | "internalType": "uint256", 1421 | "name": "addedAtBlock", 1422 | "type": "uint256" 1423 | }, 1424 | { 1425 | "internalType": "bool", 1426 | "name": "valid", 1427 | "type": "bool" 1428 | }, 1429 | { 1430 | "internalType": "bool", 1431 | "name": "finalized", 1432 | "type": "bool" 1433 | }, 1434 | { 1435 | "internalType": "uint256", 1436 | "name": "score", 1437 | "type": "uint256" 1438 | }, 1439 | { 1440 | "internalType": "uint256", 1441 | "name": "authenticity", 1442 | "type": "uint256" 1443 | }, 1444 | { 1445 | "internalType": "uint256", 1446 | "name": "ownership", 1447 | "type": "uint256" 1448 | }, 1449 | { 1450 | "internalType": "uint256", 1451 | "name": "quality", 1452 | "type": "uint256" 1453 | }, 1454 | { 1455 | "internalType": "uint256", 1456 | "name": "uniqueness", 1457 | "type": "uint256" 1458 | }, 1459 | { 1460 | "internalType": "uint256", 1461 | "name": "reward", 1462 | "type": "uint256" 1463 | }, 1464 | { 1465 | "internalType": "uint256", 1466 | "name": "rewardWithdrawn", 1467 | "type": "uint256" 1468 | }, 1469 | { 1470 | "internalType": "uint256", 1471 | "name": "verificationsCount", 1472 | "type": "uint256" 1473 | } 1474 | ], 1475 | "internalType": "struct IDataLiquidityPool.FileResponse", 1476 | "name": "", 1477 | "type": "tuple" 1478 | } 1479 | ], 1480 | "stateMutability": "view", 1481 | "type": "function" 1482 | }, 1483 | { 1484 | "inputs": [], 1485 | "name": "filesCount", 1486 | "outputs": [ 1487 | { 1488 | "internalType": "uint256", 1489 | "name": "", 1490 | "type": "uint256" 1491 | } 1492 | ], 1493 | "stateMutability": "view", 1494 | "type": "function" 1495 | }, 1496 | { 1497 | "inputs": [ 1498 | { 1499 | "internalType": "uint256", 1500 | "name": "epochNumber", 1501 | "type": "uint256" 1502 | } 1503 | ], 1504 | "name": "getEmissionScores", 1505 | "outputs": [ 1506 | { 1507 | "internalType": "uint256[]", 1508 | "name": "", 1509 | "type": "uint256[]" 1510 | } 1511 | ], 1512 | "stateMutability": "view", 1513 | "type": "function" 1514 | }, 1515 | { 1516 | "inputs": [ 1517 | { 1518 | "internalType": "address", 1519 | "name": "validatorAddress", 1520 | "type": "address" 1521 | } 1522 | ], 1523 | "name": "getNextFileToVerify", 1524 | "outputs": [ 1525 | { 1526 | "components": [ 1527 | { 1528 | "internalType": "uint256", 1529 | "name": "fileId", 1530 | "type": "uint256" 1531 | }, 1532 | { 1533 | "internalType": "address", 1534 | "name": "ownerAddress", 1535 | "type": "address" 1536 | }, 1537 | { 1538 | "internalType": "string", 1539 | "name": "url", 1540 | "type": "string" 1541 | }, 1542 | { 1543 | "internalType": "string", 1544 | "name": "encryptedKey", 1545 | "type": "string" 1546 | }, 1547 | { 1548 | "internalType": "uint256", 1549 | "name": "addedTimestamp", 1550 | "type": "uint256" 1551 | }, 1552 | { 1553 | "internalType": "uint256", 1554 | "name": "addedAtBlock", 1555 | "type": "uint256" 1556 | }, 1557 | { 1558 | "internalType": "bool", 1559 | "name": "valid", 1560 | "type": "bool" 1561 | }, 1562 | { 1563 | "internalType": "bool", 1564 | "name": "finalized", 1565 | "type": "bool" 1566 | }, 1567 | { 1568 | "internalType": "uint256", 1569 | "name": "score", 1570 | "type": "uint256" 1571 | }, 1572 | { 1573 | "internalType": "uint256", 1574 | "name": "authenticity", 1575 | "type": "uint256" 1576 | }, 1577 | { 1578 | "internalType": "uint256", 1579 | "name": "ownership", 1580 | "type": "uint256" 1581 | }, 1582 | { 1583 | "internalType": "uint256", 1584 | "name": "quality", 1585 | "type": "uint256" 1586 | }, 1587 | { 1588 | "internalType": "uint256", 1589 | "name": "uniqueness", 1590 | "type": "uint256" 1591 | }, 1592 | { 1593 | "internalType": "uint256", 1594 | "name": "reward", 1595 | "type": "uint256" 1596 | }, 1597 | { 1598 | "internalType": "uint256", 1599 | "name": "rewardWithdrawn", 1600 | "type": "uint256" 1601 | }, 1602 | { 1603 | "internalType": "uint256", 1604 | "name": "verificationsCount", 1605 | "type": "uint256" 1606 | } 1607 | ], 1608 | "internalType": "struct IDataLiquidityPool.FileResponse", 1609 | "name": "", 1610 | "type": "tuple" 1611 | } 1612 | ], 1613 | "stateMutability": "view", 1614 | "type": "function" 1615 | }, 1616 | { 1617 | "inputs": [ 1618 | { 1619 | "internalType": "bytes32", 1620 | "name": "role", 1621 | "type": "bytes32" 1622 | } 1623 | ], 1624 | "name": "getRoleAdmin", 1625 | "outputs": [ 1626 | { 1627 | "internalType": "bytes32", 1628 | "name": "", 1629 | "type": "bytes32" 1630 | } 1631 | ], 1632 | "stateMutability": "view", 1633 | "type": "function" 1634 | }, 1635 | { 1636 | "inputs": [ 1637 | { 1638 | "internalType": "bytes32", 1639 | "name": "userId", 1640 | "type": "bytes32" 1641 | } 1642 | ], 1643 | "name": "getUserIdTweetCount", 1644 | "outputs": [ 1645 | { 1646 | "internalType": "uint256", 1647 | "name": "", 1648 | "type": "uint256" 1649 | } 1650 | ], 1651 | "stateMutability": "view", 1652 | "type": "function" 1653 | }, 1654 | { 1655 | "inputs": [ 1656 | { 1657 | "internalType": "bytes32", 1658 | "name": "userId", 1659 | "type": "bytes32" 1660 | } 1661 | ], 1662 | "name": "getUserIdTweetScore", 1663 | "outputs": [ 1664 | { 1665 | "internalType": "uint256", 1666 | "name": "", 1667 | "type": "uint256" 1668 | } 1669 | ], 1670 | "stateMutability": "view", 1671 | "type": "function" 1672 | }, 1673 | { 1674 | "inputs": [ 1675 | { 1676 | "internalType": "bytes32", 1677 | "name": "role", 1678 | "type": "bytes32" 1679 | }, 1680 | { 1681 | "internalType": "address", 1682 | "name": "account", 1683 | "type": "address" 1684 | } 1685 | ], 1686 | "name": "grantRole", 1687 | "outputs": [], 1688 | "stateMutability": "nonpayable", 1689 | "type": "function" 1690 | }, 1691 | { 1692 | "inputs": [ 1693 | { 1694 | "internalType": "bytes32", 1695 | "name": "role", 1696 | "type": "bytes32" 1697 | }, 1698 | { 1699 | "internalType": "address", 1700 | "name": "account", 1701 | "type": "address" 1702 | } 1703 | ], 1704 | "name": "hasRole", 1705 | "outputs": [ 1706 | { 1707 | "internalType": "bool", 1708 | "name": "", 1709 | "type": "bool" 1710 | } 1711 | ], 1712 | "stateMutability": "view", 1713 | "type": "function" 1714 | }, 1715 | { 1716 | "inputs": [ 1717 | { 1718 | "internalType": "uint256[]", 1719 | "name": "tweetIds", 1720 | "type": "uint256[]" 1721 | } 1722 | ], 1723 | "name": "hasTweetIds", 1724 | "outputs": [ 1725 | { 1726 | "internalType": "bool[]", 1727 | "name": "", 1728 | "type": "bool[]" 1729 | } 1730 | ], 1731 | "stateMutability": "view", 1732 | "type": "function" 1733 | }, 1734 | { 1735 | "inputs": [ 1736 | { 1737 | "components": [ 1738 | { 1739 | "internalType": "string", 1740 | "name": "name", 1741 | "type": "string" 1742 | }, 1743 | { 1744 | "internalType": "address", 1745 | "name": "ownerAddress", 1746 | "type": "address" 1747 | }, 1748 | { 1749 | "internalType": "address", 1750 | "name": "tokenAddress", 1751 | "type": "address" 1752 | }, 1753 | { 1754 | "internalType": "uint256", 1755 | "name": "newMaxNumberOfValidators", 1756 | "type": "uint256" 1757 | }, 1758 | { 1759 | "internalType": "uint256", 1760 | "name": "newValidatorScoreMinTrust", 1761 | "type": "uint256" 1762 | }, 1763 | { 1764 | "internalType": "uint256", 1765 | "name": "newValidatorScoreKappa", 1766 | "type": "uint256" 1767 | }, 1768 | { 1769 | "internalType": "uint256", 1770 | "name": "newValidatorScoreRho", 1771 | "type": "uint256" 1772 | }, 1773 | { 1774 | "internalType": "uint256", 1775 | "name": "newValidationPeriod", 1776 | "type": "uint256" 1777 | }, 1778 | { 1779 | "internalType": "uint256", 1780 | "name": "newMinStakeAmount", 1781 | "type": "uint256" 1782 | }, 1783 | { 1784 | "internalType": "uint256", 1785 | "name": "startBlock", 1786 | "type": "uint256" 1787 | }, 1788 | { 1789 | "internalType": "uint256", 1790 | "name": "newEpochSize", 1791 | "type": "uint256" 1792 | }, 1793 | { 1794 | "internalType": "uint256", 1795 | "name": "newEpochRewardAmount", 1796 | "type": "uint256" 1797 | }, 1798 | { 1799 | "internalType": "uint256", 1800 | "name": "newFileRewardFactor", 1801 | "type": "uint256" 1802 | }, 1803 | { 1804 | "internalType": "uint256", 1805 | "name": "newFileRewardDelay", 1806 | "type": "uint256" 1807 | } 1808 | ], 1809 | "internalType": "struct DataLiquidityPool.InitParams", 1810 | "name": "params", 1811 | "type": "tuple" 1812 | } 1813 | ], 1814 | "name": "initialize", 1815 | "outputs": [], 1816 | "stateMutability": "nonpayable", 1817 | "type": "function" 1818 | }, 1819 | { 1820 | "inputs": [], 1821 | "name": "lastFinalizedFileId", 1822 | "outputs": [ 1823 | { 1824 | "internalType": "uint256", 1825 | "name": "", 1826 | "type": "uint256" 1827 | } 1828 | ], 1829 | "stateMutability": "view", 1830 | "type": "function" 1831 | }, 1832 | { 1833 | "inputs": [], 1834 | "name": "masterKey", 1835 | "outputs": [ 1836 | { 1837 | "internalType": "string", 1838 | "name": "", 1839 | "type": "string" 1840 | } 1841 | ], 1842 | "stateMutability": "view", 1843 | "type": "function" 1844 | }, 1845 | { 1846 | "inputs": [], 1847 | "name": "maxNumberOfValidators", 1848 | "outputs": [ 1849 | { 1850 | "internalType": "uint256", 1851 | "name": "", 1852 | "type": "uint256" 1853 | } 1854 | ], 1855 | "stateMutability": "view", 1856 | "type": "function" 1857 | }, 1858 | { 1859 | "inputs": [], 1860 | "name": "minStakeAmount", 1861 | "outputs": [ 1862 | { 1863 | "internalType": "uint256", 1864 | "name": "", 1865 | "type": "uint256" 1866 | } 1867 | ], 1868 | "stateMutability": "view", 1869 | "type": "function" 1870 | }, 1871 | { 1872 | "inputs": [], 1873 | "name": "name", 1874 | "outputs": [ 1875 | { 1876 | "internalType": "string", 1877 | "name": "", 1878 | "type": "string" 1879 | } 1880 | ], 1881 | "stateMutability": "view", 1882 | "type": "function" 1883 | }, 1884 | { 1885 | "inputs": [], 1886 | "name": "owner", 1887 | "outputs": [ 1888 | { 1889 | "internalType": "address", 1890 | "name": "", 1891 | "type": "address" 1892 | } 1893 | ], 1894 | "stateMutability": "view", 1895 | "type": "function" 1896 | }, 1897 | { 1898 | "inputs": [], 1899 | "name": "pause", 1900 | "outputs": [], 1901 | "stateMutability": "nonpayable", 1902 | "type": "function" 1903 | }, 1904 | { 1905 | "inputs": [], 1906 | "name": "paused", 1907 | "outputs": [ 1908 | { 1909 | "internalType": "bool", 1910 | "name": "", 1911 | "type": "bool" 1912 | } 1913 | ], 1914 | "stateMutability": "view", 1915 | "type": "function" 1916 | }, 1917 | { 1918 | "inputs": [], 1919 | "name": "pendingOwner", 1920 | "outputs": [ 1921 | { 1922 | "internalType": "address", 1923 | "name": "", 1924 | "type": "address" 1925 | } 1926 | ], 1927 | "stateMutability": "view", 1928 | "type": "function" 1929 | }, 1930 | { 1931 | "inputs": [], 1932 | "name": "proxiableUUID", 1933 | "outputs": [ 1934 | { 1935 | "internalType": "bytes32", 1936 | "name": "", 1937 | "type": "bytes32" 1938 | } 1939 | ], 1940 | "stateMutability": "view", 1941 | "type": "function" 1942 | }, 1943 | { 1944 | "inputs": [ 1945 | { 1946 | "internalType": "uint256", 1947 | "name": "xWAD", 1948 | "type": "uint256" 1949 | }, 1950 | { 1951 | "internalType": "uint256", 1952 | "name": "aWAD", 1953 | "type": "uint256" 1954 | }, 1955 | { 1956 | "internalType": "uint256", 1957 | "name": "pWAD", 1958 | "type": "uint256" 1959 | }, 1960 | { 1961 | "internalType": "uint256", 1962 | "name": "kWAD", 1963 | "type": "uint256" 1964 | }, 1965 | { 1966 | "internalType": "uint256", 1967 | "name": "cWAD", 1968 | "type": "uint256" 1969 | } 1970 | ], 1971 | "name": "rationalSigmoid", 1972 | "outputs": [ 1973 | { 1974 | "internalType": "uint256", 1975 | "name": "", 1976 | "type": "uint256" 1977 | } 1978 | ], 1979 | "stateMutability": "pure", 1980 | "type": "function" 1981 | }, 1982 | { 1983 | "inputs": [ 1984 | { 1985 | "internalType": "address", 1986 | "name": "validatorAddress", 1987 | "type": "address" 1988 | }, 1989 | { 1990 | "internalType": "address", 1991 | "name": "validatorOwnerAddress", 1992 | "type": "address" 1993 | }, 1994 | { 1995 | "internalType": "uint256", 1996 | "name": "stakeAmount", 1997 | "type": "uint256" 1998 | } 1999 | ], 2000 | "name": "registerValidator", 2001 | "outputs": [], 2002 | "stateMutability": "nonpayable", 2003 | "type": "function" 2004 | }, 2005 | { 2006 | "inputs": [], 2007 | "name": "renounceOwnership", 2008 | "outputs": [], 2009 | "stateMutability": "nonpayable", 2010 | "type": "function" 2011 | }, 2012 | { 2013 | "inputs": [ 2014 | { 2015 | "internalType": "bytes32", 2016 | "name": "role", 2017 | "type": "bytes32" 2018 | }, 2019 | { 2020 | "internalType": "address", 2021 | "name": "callerConfirmation", 2022 | "type": "address" 2023 | } 2024 | ], 2025 | "name": "renounceRole", 2026 | "outputs": [], 2027 | "stateMutability": "nonpayable", 2028 | "type": "function" 2029 | }, 2030 | { 2031 | "inputs": [ 2032 | { 2033 | "internalType": "bytes32", 2034 | "name": "role", 2035 | "type": "bytes32" 2036 | }, 2037 | { 2038 | "internalType": "address", 2039 | "name": "account", 2040 | "type": "address" 2041 | } 2042 | ], 2043 | "name": "revokeRole", 2044 | "outputs": [], 2045 | "stateMutability": "nonpayable", 2046 | "type": "function" 2047 | }, 2048 | { 2049 | "inputs": [ 2050 | { 2051 | "internalType": "string", 2052 | "name": "newMasterKey", 2053 | "type": "string" 2054 | } 2055 | ], 2056 | "name": "setMasterKey", 2057 | "outputs": [], 2058 | "stateMutability": "nonpayable", 2059 | "type": "function" 2060 | }, 2061 | { 2062 | "inputs": [ 2063 | { 2064 | "internalType": "bytes4", 2065 | "name": "interfaceId", 2066 | "type": "bytes4" 2067 | } 2068 | ], 2069 | "name": "supportsInterface", 2070 | "outputs": [ 2071 | { 2072 | "internalType": "bool", 2073 | "name": "", 2074 | "type": "bool" 2075 | } 2076 | ], 2077 | "stateMutability": "view", 2078 | "type": "function" 2079 | }, 2080 | { 2081 | "inputs": [], 2082 | "name": "token", 2083 | "outputs": [ 2084 | { 2085 | "internalType": "contract IERC20", 2086 | "name": "", 2087 | "type": "address" 2088 | } 2089 | ], 2090 | "stateMutability": "view", 2091 | "type": "function" 2092 | }, 2093 | { 2094 | "inputs": [], 2095 | "name": "totalContributorsRewardAmount", 2096 | "outputs": [ 2097 | { 2098 | "internalType": "uint256", 2099 | "name": "", 2100 | "type": "uint256" 2101 | } 2102 | ], 2103 | "stateMutability": "view", 2104 | "type": "function" 2105 | }, 2106 | { 2107 | "inputs": [], 2108 | "name": "totalStaked", 2109 | "outputs": [ 2110 | { 2111 | "internalType": "uint256", 2112 | "name": "", 2113 | "type": "uint256" 2114 | } 2115 | ], 2116 | "stateMutability": "view", 2117 | "type": "function" 2118 | }, 2119 | { 2120 | "inputs": [], 2121 | "name": "totalValidatorsRewardAmount", 2122 | "outputs": [ 2123 | { 2124 | "internalType": "uint256", 2125 | "name": "", 2126 | "type": "uint256" 2127 | } 2128 | ], 2129 | "stateMutability": "view", 2130 | "type": "function" 2131 | }, 2132 | { 2133 | "inputs": [ 2134 | { 2135 | "internalType": "address", 2136 | "name": "newOwner", 2137 | "type": "address" 2138 | } 2139 | ], 2140 | "name": "transferOwnership", 2141 | "outputs": [], 2142 | "stateMutability": "nonpayable", 2143 | "type": "function" 2144 | }, 2145 | { 2146 | "inputs": [], 2147 | "name": "unpause", 2148 | "outputs": [], 2149 | "stateMutability": "nonpayable", 2150 | "type": "function" 2151 | }, 2152 | { 2153 | "inputs": [ 2154 | { 2155 | "internalType": "uint256", 2156 | "name": "newEpochRewardAmount", 2157 | "type": "uint256" 2158 | } 2159 | ], 2160 | "name": "updateEpochRewardAmount", 2161 | "outputs": [], 2162 | "stateMutability": "nonpayable", 2163 | "type": "function" 2164 | }, 2165 | { 2166 | "inputs": [ 2167 | { 2168 | "internalType": "uint256", 2169 | "name": "newEpochSize", 2170 | "type": "uint256" 2171 | } 2172 | ], 2173 | "name": "updateEpochSize", 2174 | "outputs": [], 2175 | "stateMutability": "nonpayable", 2176 | "type": "function" 2177 | }, 2178 | { 2179 | "inputs": [ 2180 | { 2181 | "internalType": "uint256", 2182 | "name": "newFileRewardDelay", 2183 | "type": "uint256" 2184 | } 2185 | ], 2186 | "name": "updateFileRewardDelay", 2187 | "outputs": [], 2188 | "stateMutability": "nonpayable", 2189 | "type": "function" 2190 | }, 2191 | { 2192 | "inputs": [ 2193 | { 2194 | "internalType": "uint256", 2195 | "name": "newFileRewardFactor", 2196 | "type": "uint256" 2197 | } 2198 | ], 2199 | "name": "updateFileRewardFactor", 2200 | "outputs": [], 2201 | "stateMutability": "nonpayable", 2202 | "type": "function" 2203 | }, 2204 | { 2205 | "inputs": [ 2206 | { 2207 | "internalType": "uint256", 2208 | "name": "newMaxNumberOfValidators", 2209 | "type": "uint256" 2210 | } 2211 | ], 2212 | "name": "updateMaxNumberOfValidators", 2213 | "outputs": [], 2214 | "stateMutability": "nonpayable", 2215 | "type": "function" 2216 | }, 2217 | { 2218 | "inputs": [ 2219 | { 2220 | "internalType": "uint256", 2221 | "name": "newMinStakeAmount", 2222 | "type": "uint256" 2223 | } 2224 | ], 2225 | "name": "updateMinStakeAmount", 2226 | "outputs": [], 2227 | "stateMutability": "nonpayable", 2228 | "type": "function" 2229 | }, 2230 | { 2231 | "inputs": [ 2232 | { 2233 | "internalType": "uint256", 2234 | "name": "newValidationPeriod", 2235 | "type": "uint256" 2236 | } 2237 | ], 2238 | "name": "updateValidationPeriod", 2239 | "outputs": [], 2240 | "stateMutability": "nonpayable", 2241 | "type": "function" 2242 | }, 2243 | { 2244 | "inputs": [ 2245 | { 2246 | "internalType": "uint256", 2247 | "name": "newValidatorScoreKappa", 2248 | "type": "uint256" 2249 | } 2250 | ], 2251 | "name": "updateValidatorScoreKappa", 2252 | "outputs": [], 2253 | "stateMutability": "nonpayable", 2254 | "type": "function" 2255 | }, 2256 | { 2257 | "inputs": [ 2258 | { 2259 | "internalType": "uint256", 2260 | "name": "newValidatorScoreMinTrust", 2261 | "type": "uint256" 2262 | } 2263 | ], 2264 | "name": "updateValidatorScoreMinTrust", 2265 | "outputs": [], 2266 | "stateMutability": "nonpayable", 2267 | "type": "function" 2268 | }, 2269 | { 2270 | "inputs": [ 2271 | { 2272 | "internalType": "uint256", 2273 | "name": "newValidatorScoreRho", 2274 | "type": "uint256" 2275 | } 2276 | ], 2277 | "name": "updateValidatorScoreRho", 2278 | "outputs": [], 2279 | "stateMutability": "nonpayable", 2280 | "type": "function" 2281 | }, 2282 | { 2283 | "inputs": [ 2284 | { 2285 | "internalType": "address[]", 2286 | "name": "validators", 2287 | "type": "address[]" 2288 | }, 2289 | { 2290 | "internalType": "uint256[]", 2291 | "name": "weights", 2292 | "type": "uint256[]" 2293 | } 2294 | ], 2295 | "name": "updateWeights", 2296 | "outputs": [], 2297 | "stateMutability": "nonpayable", 2298 | "type": "function" 2299 | }, 2300 | { 2301 | "inputs": [ 2302 | { 2303 | "internalType": "address", 2304 | "name": "newImplementation", 2305 | "type": "address" 2306 | }, 2307 | { 2308 | "internalType": "bytes", 2309 | "name": "data", 2310 | "type": "bytes" 2311 | } 2312 | ], 2313 | "name": "upgradeToAndCall", 2314 | "outputs": [], 2315 | "stateMutability": "payable", 2316 | "type": "function" 2317 | }, 2318 | { 2319 | "inputs": [], 2320 | "name": "validationPeriod", 2321 | "outputs": [ 2322 | { 2323 | "internalType": "uint256", 2324 | "name": "", 2325 | "type": "uint256" 2326 | } 2327 | ], 2328 | "stateMutability": "view", 2329 | "type": "function" 2330 | }, 2331 | { 2332 | "inputs": [], 2333 | "name": "validatorScoreKappa", 2334 | "outputs": [ 2335 | { 2336 | "internalType": "uint256", 2337 | "name": "", 2338 | "type": "uint256" 2339 | } 2340 | ], 2341 | "stateMutability": "view", 2342 | "type": "function" 2343 | }, 2344 | { 2345 | "inputs": [], 2346 | "name": "validatorScoreMinTrust", 2347 | "outputs": [ 2348 | { 2349 | "internalType": "uint256", 2350 | "name": "", 2351 | "type": "uint256" 2352 | } 2353 | ], 2354 | "stateMutability": "view", 2355 | "type": "function" 2356 | }, 2357 | { 2358 | "inputs": [], 2359 | "name": "validatorScoreRho", 2360 | "outputs": [ 2361 | { 2362 | "internalType": "uint256", 2363 | "name": "", 2364 | "type": "uint256" 2365 | } 2366 | ], 2367 | "stateMutability": "view", 2368 | "type": "function" 2369 | }, 2370 | { 2371 | "inputs": [ 2372 | { 2373 | "internalType": "address", 2374 | "name": "validatorAddress", 2375 | "type": "address" 2376 | } 2377 | ], 2378 | "name": "validatorWeights", 2379 | "outputs": [ 2380 | { 2381 | "internalType": "address[]", 2382 | "name": "validators", 2383 | "type": "address[]" 2384 | }, 2385 | { 2386 | "internalType": "uint256[]", 2387 | "name": "weights", 2388 | "type": "uint256[]" 2389 | } 2390 | ], 2391 | "stateMutability": "view", 2392 | "type": "function" 2393 | }, 2394 | { 2395 | "inputs": [ 2396 | { 2397 | "internalType": "uint256", 2398 | "name": "index", 2399 | "type": "uint256" 2400 | } 2401 | ], 2402 | "name": "validators", 2403 | "outputs": [ 2404 | { 2405 | "components": [ 2406 | { 2407 | "internalType": "address", 2408 | "name": "validatorAddress", 2409 | "type": "address" 2410 | }, 2411 | { 2412 | "internalType": "address", 2413 | "name": "ownerAddress", 2414 | "type": "address" 2415 | }, 2416 | { 2417 | "internalType": "uint256", 2418 | "name": "stakeAmount", 2419 | "type": "uint256" 2420 | }, 2421 | { 2422 | "internalType": "enum IDataLiquidityPool.ValidatorStatus", 2423 | "name": "status", 2424 | "type": "uint8" 2425 | }, 2426 | { 2427 | "internalType": "uint256", 2428 | "name": "firstBlockNumber", 2429 | "type": "uint256" 2430 | }, 2431 | { 2432 | "internalType": "uint256", 2433 | "name": "lastBlockNumber", 2434 | "type": "uint256" 2435 | }, 2436 | { 2437 | "internalType": "uint256", 2438 | "name": "grantedAmount", 2439 | "type": "uint256" 2440 | }, 2441 | { 2442 | "internalType": "uint256", 2443 | "name": "lastVerifiedFile", 2444 | "type": "uint256" 2445 | } 2446 | ], 2447 | "internalType": "struct IDataLiquidityPool.ValidatorInfoResponse", 2448 | "name": "", 2449 | "type": "tuple" 2450 | } 2451 | ], 2452 | "stateMutability": "view", 2453 | "type": "function" 2454 | }, 2455 | { 2456 | "inputs": [], 2457 | "name": "validatorsCount", 2458 | "outputs": [ 2459 | { 2460 | "internalType": "uint256", 2461 | "name": "", 2462 | "type": "uint256" 2463 | } 2464 | ], 2465 | "stateMutability": "view", 2466 | "type": "function" 2467 | }, 2468 | { 2469 | "inputs": [ 2470 | { 2471 | "internalType": "address", 2472 | "name": "validatorAddress", 2473 | "type": "address" 2474 | } 2475 | ], 2476 | "name": "validatorsInfo", 2477 | "outputs": [ 2478 | { 2479 | "components": [ 2480 | { 2481 | "internalType": "address", 2482 | "name": "validatorAddress", 2483 | "type": "address" 2484 | }, 2485 | { 2486 | "internalType": "address", 2487 | "name": "ownerAddress", 2488 | "type": "address" 2489 | }, 2490 | { 2491 | "internalType": "uint256", 2492 | "name": "stakeAmount", 2493 | "type": "uint256" 2494 | }, 2495 | { 2496 | "internalType": "enum IDataLiquidityPool.ValidatorStatus", 2497 | "name": "status", 2498 | "type": "uint8" 2499 | }, 2500 | { 2501 | "internalType": "uint256", 2502 | "name": "firstBlockNumber", 2503 | "type": "uint256" 2504 | }, 2505 | { 2506 | "internalType": "uint256", 2507 | "name": "lastBlockNumber", 2508 | "type": "uint256" 2509 | }, 2510 | { 2511 | "internalType": "uint256", 2512 | "name": "grantedAmount", 2513 | "type": "uint256" 2514 | }, 2515 | { 2516 | "internalType": "uint256", 2517 | "name": "lastVerifiedFile", 2518 | "type": "uint256" 2519 | } 2520 | ], 2521 | "internalType": "struct IDataLiquidityPool.ValidatorInfoResponse", 2522 | "name": "", 2523 | "type": "tuple" 2524 | } 2525 | ], 2526 | "stateMutability": "view", 2527 | "type": "function" 2528 | }, 2529 | { 2530 | "inputs": [ 2531 | { 2532 | "internalType": "uint256", 2533 | "name": "fileId", 2534 | "type": "uint256" 2535 | }, 2536 | { 2537 | "internalType": "bool", 2538 | "name": "valid", 2539 | "type": "bool" 2540 | }, 2541 | { 2542 | "internalType": "uint256", 2543 | "name": "score", 2544 | "type": "uint256" 2545 | }, 2546 | { 2547 | "internalType": "uint256", 2548 | "name": "authenticity", 2549 | "type": "uint256" 2550 | }, 2551 | { 2552 | "internalType": "uint256", 2553 | "name": "ownership", 2554 | "type": "uint256" 2555 | }, 2556 | { 2557 | "internalType": "uint256", 2558 | "name": "quality", 2559 | "type": "uint256" 2560 | }, 2561 | { 2562 | "internalType": "uint256", 2563 | "name": "uniqueness", 2564 | "type": "uint256" 2565 | }, 2566 | { 2567 | "components": [ 2568 | { 2569 | "internalType": "uint256", 2570 | "name": "tweetId", 2571 | "type": "uint256" 2572 | }, 2573 | { 2574 | "internalType": "uint256", 2575 | "name": "userId", 2576 | "type": "uint256" 2577 | }, 2578 | { 2579 | "internalType": "uint256", 2580 | "name": "score", 2581 | "type": "uint256" 2582 | } 2583 | ], 2584 | "internalType": "struct IDataLiquidityPool.TweetInfo[]", 2585 | "name": "tweets", 2586 | "type": "tuple[]" 2587 | } 2588 | ], 2589 | "name": "verifyFile", 2590 | "outputs": [], 2591 | "stateMutability": "nonpayable", 2592 | "type": "function" 2593 | }, 2594 | { 2595 | "inputs": [], 2596 | "name": "version", 2597 | "outputs": [ 2598 | { 2599 | "internalType": "uint256", 2600 | "name": "", 2601 | "type": "uint256" 2602 | } 2603 | ], 2604 | "stateMutability": "pure", 2605 | "type": "function" 2606 | } 2607 | ] 2608 | -------------------------------------------------------------------------------- /miner/dlp/volara.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | import os 3 | import vana 4 | import json 5 | 6 | from constants import DLP_ADDRESS, NETWORK, VANA_COLDKEY, VANA_HOTKEY 7 | 8 | dlp_implementation_abi_path = os.path.join( 9 | os.path.dirname(__file__), "dlp-implementation-abi.json" 10 | ) 11 | 12 | 13 | @dataclass 14 | class ChainConfig: 15 | network: str 16 | 17 | 18 | async def submit(file_url: str) -> None: 19 | """Uploads a file to the Vana DLP implementation. 20 | 21 | Args: 22 | file_url: The URL of the file to upload to the DLP. 23 | """ 24 | config = vana.Config() 25 | config.chain = ChainConfig(network=NETWORK) 26 | chain_manager = vana.ChainManager(config=config) 27 | wallet = vana.Wallet(name=VANA_COLDKEY, hotkey=VANA_HOTKEY) 28 | with open(dlp_implementation_abi_path) as f: 29 | dlp_contract = chain_manager.web3.eth.contract( 30 | address=DLP_ADDRESS, abi=json.load(f) 31 | ) 32 | add_file_fn = dlp_contract.functions.addFile(file_url, "nil") 33 | chain_manager.send_transaction(add_file_fn, wallet.hotkey) 34 | -------------------------------------------------------------------------------- /miner/drive.py: -------------------------------------------------------------------------------- 1 | import io 2 | from uuid import uuid4 3 | 4 | from googleapiclient.discovery import build 5 | from googleapiclient.http import MediaIoBaseUpload 6 | 7 | import cli.auth.drive as drive 8 | from constants import APPLICATION_NAME 9 | 10 | async def write_uuid_file(data: bytes) -> str: 11 | """Uploads a file to the Volara drive bucket with a random UUID. 12 | 13 | Args: 14 | data: The data to upload. 15 | 16 | Returns: 17 | The URL of the uploaded file. 18 | """ 19 | creds = drive.get_active_account() 20 | if not creds: 21 | raise Exception("No active drive account found.") 22 | service = build("drive", "v3", credentials=creds) 23 | 24 | # Check if the folder already exists 25 | query = f"name='{APPLICATION_NAME}' and mimeType='application/vnd.google-apps.folder' and trashed=false" 26 | results = ( 27 | service.files() 28 | .list(q=query, spaces="drive", fields="files(id, name)") 29 | .execute() 30 | ) 31 | items = results.get("files", []) 32 | if items: 33 | folder_id = items[0]["id"] 34 | else: 35 | # Create sixgpt folder if it did not exist 36 | folder_metadata = { 37 | "name": APPLICATION_NAME, 38 | "mimeType": "application/vnd.google-apps.folder", 39 | } 40 | folder = service.files().create(body=folder_metadata).execute() 41 | folder_id = folder.get("id") 42 | 43 | uuid_path = str(uuid4()) 44 | file_metadata = {"name": uuid_path, "parents": [folder_id]} 45 | media = MediaIoBaseUpload(io.BytesIO(data), mimetype="application/zip") 46 | resp = service.files().create(body=file_metadata, media_body=media).execute() 47 | 48 | # Make the file publicly shareable 49 | permission = {"type": "anyone", "role": "reader", "allowFileDiscovery": False} 50 | service.permissions().create(fileId=resp["id"], body=permission).execute() 51 | 52 | # Get the downloadable link 53 | file = service.files().get(fileId=resp["id"], fields="webContentLink").execute() 54 | downloadable_link = file.get("webContentLink") 55 | return downloadable_link 56 | -------------------------------------------------------------------------------- /miner/extract.py: -------------------------------------------------------------------------------- 1 | import typing as T 2 | import time 3 | from dataclasses import dataclass 4 | 5 | 6 | @dataclass 7 | class SyntheticData: 8 | input: str 9 | output: str 10 | context: T.Any 11 | task: str 12 | 13 | def __hash__(self) -> int: 14 | return hash((self.input, self.task)) 15 | 16 | def __eq__(self, other: object) -> bool: 17 | if not isinstance(other, SyntheticData): 18 | return NotImplemented 19 | return self.prompt == other.prompt 20 | 21 | def to_dict(self) -> dict: 22 | return { 23 | "input": self.input, 24 | "output": self.output, 25 | "context": self.context, 26 | "task": self.task, 27 | } -------------------------------------------------------------------------------- /miner/run.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import logging 3 | import os 4 | 5 | import miner.dlp.volara as sixgpt 6 | from constants import ( 7 | ERROR_SLEEP_INTERVAL, 8 | TARGET_EXAMPLE_COUNT, 9 | TIMELINE_SLEEP_INTERVAL, 10 | TMP_MINER_LOG, 11 | MODEL_NAME 12 | ) 13 | from miner.build import build_buffer, build_zip_buffer 14 | from miner.extract import SyntheticData 15 | from miner.drive import write_uuid_file 16 | from cli.auth.openai import get_active_account, set_active_account 17 | from openai import OpenAI 18 | from miner.task import WikipediaSummarization 19 | import cli.auth.sixgpt as sixgpt_auth 20 | 21 | 22 | logger = logging.getLogger(__name__) 23 | 24 | async def start_mining(): 25 | logger.info("Starting mining...") 26 | client = get_active_account() 27 | if client is None: 28 | result = set_active_account() 29 | if not result: 30 | logger.error("Failed to set active openai account. Exiting..") 31 | return 32 | client = get_active_account() 33 | if client is None: 34 | logger.error("OpenAI client not found. Exiting..") 35 | return 36 | jwt = sixgpt_auth.get_sixgpt_jwt() 37 | if jwt is None: 38 | logger.error("Failed to get sixgpt jwt. Exiting..") 39 | return 40 | 41 | task = WikipediaSummarization(client) 42 | 43 | while True: 44 | examples: set[SyntheticData] = set() 45 | while len(examples) < TARGET_EXAMPLE_COUNT: 46 | logger.info("Generating completion:") 47 | 48 | try: 49 | example = task.run() 50 | except Exception: 51 | logger.exception("Error generating dataset") 52 | logger.info(f"Sleeping {ERROR_SLEEP_INTERVAL}s for next attempt...") 53 | await asyncio.sleep(ERROR_SLEEP_INTERVAL) 54 | continue 55 | examples.add(example) 56 | logger.info( 57 | f"Pulled {example.context['title']}... total buffer: {len(examples)}" 58 | ) 59 | if len(examples) >= TARGET_EXAMPLE_COUNT: 60 | break 61 | await asyncio.sleep(TIMELINE_SLEEP_INTERVAL) 62 | tweet_buffer = build_buffer(examples) 63 | logger.info("Uploading tweet buffer to drive...") 64 | zip_buffer = build_zip_buffer(tweet_buffer) 65 | file_url = await write_uuid_file(zip_buffer) 66 | logger.info(f"Uploaded examples buffer to {file_url}") 67 | logger.info("Submitting to sixgpt...") 68 | await sixgpt.submit(file_url) 69 | sixgpt_auth.submit_data(jwt, examples) 70 | logger.info("Submitted to sixgpt.") 71 | 72 | 73 | if __name__ == "__main__": 74 | os.makedirs(os.path.dirname(TMP_MINER_LOG), exist_ok=True) 75 | try: 76 | os.remove(TMP_MINER_LOG) 77 | except FileNotFoundError: 78 | pass 79 | output_handler = logging.FileHandler(TMP_MINER_LOG) 80 | logger.setLevel(logging.INFO) 81 | logger.addHandler(output_handler) 82 | try: 83 | asyncio.run(start_mining()) 84 | except Exception: 85 | logger.exception("Exception encountered") 86 | logger.info("Exiting...") 87 | -------------------------------------------------------------------------------- /miner/task.py: -------------------------------------------------------------------------------- 1 | from openai import OpenAI 2 | 3 | from typing import Dict 4 | import requests 5 | import random 6 | from miner.extract import SyntheticData 7 | import logging 8 | from constants import MODEL_NAME 9 | 10 | logger = logging.getLogger(__name__) 11 | 12 | def chunk(text, sep, n_chunks=None): 13 | # choose a random chunk from the article 14 | chunks = [chunk for chunk in text.split(sep) if chunk.strip()] 15 | # select a subsequence of paragraphs 16 | if n_chunks is None: 17 | n_chunks = random.randint(1, len(chunks)) 18 | 19 | start_chunk = random.randint(0, len(chunks) - n_chunks) 20 | 21 | return sep.join(chunks[start_chunk : start_chunk + n_chunks]) 22 | 23 | class Task: 24 | def __init__(self, client: OpenAI): 25 | self.client = client 26 | 27 | def run(self) -> SyntheticData: 28 | return self._run() 29 | 30 | def _run(self) -> SyntheticData: 31 | raise NotImplementedError() 32 | 33 | def get_task(self): 34 | raise NotImplementedError() 35 | 36 | 37 | 38 | class WikipediaSummarization(Task): 39 | def __init__( 40 | self, 41 | client: OpenAI, 42 | min_length_words: int = 250, 43 | min_length_bytes: int = 1000, 44 | max_tries: int = 10, 45 | min_backlinks: int = 1, 46 | ): 47 | super().__init__(client) 48 | self.url = "https://en.wikipedia.org/w/api.php" 49 | self.min_length_words = min_length_words 50 | self.min_length_bytes = min_length_bytes 51 | self.max_tries = max_tries 52 | self.min_backlinks = min_backlinks 53 | 54 | def get_task(self): 55 | return "wikipedia_summarization" 56 | 57 | def _run(self) -> SyntheticData: 58 | article = self.get_random_wikipedia_article() 59 | logger.info(f"Generating wikipedia summarization task for {article['title']}...") 60 | content = self.get_wikipedia_article_content(article["title"])[None] 61 | 62 | questions = self.client.chat.completions.create( 63 | model=MODEL_NAME, 64 | messages=[ 65 | {"role": "system", "content": "Your responsibility is to generate a question that could be answered by the content asked by the user."}, 66 | {"role": "user", "content": content}, 67 | ], 68 | ) 69 | 70 | answers = self.client.chat.completions.create( 71 | model=MODEL_NAME, 72 | messages=[ 73 | {"role": "system", "content": "Your responsibility is to answer the following question based on the content provided."}, 74 | {"role": "user", "content": """ 75 | Question: {question} 76 | Context: {context} 77 | """.format(question=questions.choices[0].message.content, context=content)}, 78 | ], 79 | ) 80 | 81 | return SyntheticData(input=questions.choices[0].message.content, output=answers.choices[0].message.content, context={"content": content, "title": article["title"]}, task=self.get_task()) 82 | 83 | 84 | def get_random_wikipedia_article(self) -> Dict: 85 | """sample random wikipedia article 86 | 87 | Args: 88 | min_length (int, optional): min number of words in article. Defaults to 1000. 89 | min_backlinks (int, optional): backlink is a hyperlink from one webpage to another webpage. Defaults to 1. 90 | """ 91 | 92 | # Parameters for the API request 93 | params = { 94 | "action": "query", 95 | "format": "json", 96 | "prop": "info|linkshere|categories|categoryinfo|extracts", 97 | "generator": "random", 98 | "grnnamespace": 0, # Namespace 0 indicates articles 99 | "grnlimit": 10, # Number of random articles to fetch 100 | "inprop": "url|displaytitle|length", # Requesting URL, title, and length of the page 101 | "lhprop": "pageid", # Properties for links here (backlinks) 102 | "lhlimit": "max", # Maximum number of backlinks to retrieve 103 | "exlimit": "max", # Get extracts for each page 104 | "cllimit": "max", # Get all categories for each page 105 | } 106 | 107 | tries = 0 108 | while tries < self.max_tries: 109 | # TODO: to avoid blocking from Wikipedia, we should provide a headers argument, where headers = {'User-Agent': 'Bittensor/0.0 (https://Bittensor.org; someone@opentensor.dev)'} 110 | response = requests.get(self.url, params=params) 111 | tries += 1 112 | 113 | data = response.json() 114 | if not data.get("query"): 115 | continue 116 | 117 | for page_id, page_info in data["query"]["pages"].items(): 118 | length = page_info.get("length", 0) 119 | backlinks = len(page_info.get("linkshere", [])) 120 | categories = [ 121 | cat.get("title", "").strip("Category:") 122 | for cat in page_info.get("categories", [{}]) 123 | ] 124 | # filter out any mention of articles 125 | categories = [cat for cat in categories if "article" not in cat.lower()] 126 | extract = page_info.get("extract") 127 | 128 | if ( 129 | length >= self.min_length_bytes 130 | and backlinks >= self.min_backlinks 131 | and extract 132 | ): # and views >= min_views: 133 | return { 134 | "title": page_info["title"], 135 | "url": page_info["fullurl"], 136 | "length": length, 137 | "extract": extract, 138 | "backlinks": backlinks, 139 | "categories": categories, 140 | } 141 | 142 | raise Exception( 143 | f"Could not find an article with length >= {self.min_length_bytes} and backlinks >= {self.min_backlinks} after {self.max_tries} tries." 144 | ) 145 | 146 | def get_wikipedia_article_content(self, title: str) -> str: 147 | """Return wikipedia article content 148 | 149 | Args: 150 | title (str): title of the article 151 | remove_headers (bool, optional): remove the headers in the content body. Defaults to False. 152 | 153 | Returns: 154 | str: article content 155 | """ 156 | # Parameters for the API request to get article content 157 | params = { 158 | "action": "query", 159 | "format": "json", 160 | "titles": title, 161 | "prop": "extracts", 162 | "explaintext": True, # Get plain text content 163 | } 164 | 165 | # Making the API request 166 | # TODO: to avoid blocking from Wikipedia, we should provide a headers argument, where headers = {'User-Agent': 'Bittensor/0.0 (https://Bittensor.org; someone@opentensor.dev)'} 167 | response = requests.get(self.url, params=params) 168 | data = response.json() 169 | 170 | # Extracting the page content 171 | page = next(iter(data["query"]["pages"].values())) 172 | content = page.get("extract", "Content not found.") 173 | 174 | text = {None: ""} 175 | section = None 176 | for line in content.split("\n"): 177 | if line.startswith("==") and line.endswith("=="): 178 | section = line.strip("=").strip() 179 | text[section] = "" 180 | continue 181 | text[section] += line + "\n" 182 | 183 | return text 184 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "sixgpt-miner" 3 | version = "0.1.0" 4 | description = "Synthetic data generation for the SixGPT DLP" 5 | authors = ["SixGPT"] 6 | readme = "README.md" 7 | package-mode = false 8 | 9 | [tool.poetry.dependencies] 10 | python = ">=3.11,<3.13" 11 | click = "^8.1.7" 12 | twitter-api-client = "^0.10.22" 13 | flatbuffers = "^24.3.25" 14 | google-api-python-client = "^2.134.0" 15 | google-auth-httplib2 = "^0.2.0" 16 | google-auth-oauthlib = "^1.2.0" 17 | vana = "^0.7.0" 18 | openai = "^1.47.0" 19 | python-dotenv = "^1.0.1" 20 | 21 | 22 | [build-system] 23 | requires = ["poetry-core"] 24 | build-backend = "poetry.core.masonry.api" 25 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Function to check if a command exists 4 | command_exists() { 5 | command -v "$1" >/dev/null 2>&1 6 | } 7 | 8 | # Check if Python is installed 9 | if ! command_exists python3; then 10 | echo "Python 3 is not installed. Please install Python 3 and try again." 11 | exit 1 12 | fi 13 | 14 | # Check if Poetry is installed 15 | if ! command_exists poetry; then 16 | echo "Poetry is not installed. Installing Poetry..." 17 | curl -sSL https://install.python-poetry.org | python3 - 18 | fi 19 | 20 | # Install dependencies using Poetry 21 | echo "Installing dependencies..." 22 | poetry install 23 | 24 | # Get the absolute directory of this script 25 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 26 | 27 | # Add the bin directory to PATH in both .zshrc and .bashrc 28 | echo "export PATH=$SCRIPT_DIR/bin:\$PATH" >> ~/.zshrc 29 | echo "export PATH=$SCRIPT_DIR/bin:\$PATH" >> ~/.bashrc 30 | 31 | # Update current session's PATH 32 | export PATH=$SCRIPT_DIR/bin:$PATH 33 | 34 | # Inform success 35 | GREEN='\033[0;32m' 36 | NC='\033[0m' # No Color 37 | printf "${GREEN}### SixGPT setup successful ###${NC}\n" 38 | echo 'Please restart your terminal or run 'source ~/.zshrc' or 'source ~/.bashrc' to use the 'sixgpt' command.' 39 | echo 'Start mining with `./bin/sixgpt mine start`' --------------------------------------------------------------------------------