mirror of
https://github.com/status-im/status-python-sdk.git
synced 2026-08-30 21:51:14 +00:00
account: ENS support
- Related to https://github.com/status-im/status-python-sdk/issues/14
This commit is contained in:
+17
-11
@@ -101,7 +101,7 @@ class Account:
|
||||
# In case if there is a hanging logged in session
|
||||
self.logout()
|
||||
|
||||
def login(self, password: str, key_uid: Optional[str] = None, display_name: Optional[str] = None, mnemonic: Optional[str] = None, infura_token: Optional[str] = None, alchemy_token: Optional[str] = None, coingecko_api_key: Optional[str] = None):
|
||||
def login(self, password: str, key_uid: Optional[str] = None, name: Optional[str] = None, mnemonic: Optional[str] = None, infura_token: Optional[str] = None, alchemy_token: Optional[str] = None, coingecko_api_key: Optional[str] = None):
|
||||
"""
|
||||
Login to the given account. If it does not exist,
|
||||
it will be created and automatically logged in.
|
||||
@@ -109,20 +109,20 @@ class Account:
|
||||
Parameters:
|
||||
- `password` - your Status password
|
||||
- `key_uid` - your key unique identifier. If not provided `display_name` will be used to fetch it. This means that each `display_name` can be linked to one `key_uid`
|
||||
- `display_name` - your Status display name. Use `display_name` and `password` parameter combination if you have a 1 to 1 mapping (each display name has a unique `key_uid`)
|
||||
- `name` - your Status display name or ENS. Use `name` and `password` parameter combination if you have a 1 to 1 mapping (ENS has a unique `key_uid`)
|
||||
- `mnemonic` - the mnemonic when creating an account. Use this field with `password` and `display_name` to recover an account
|
||||
- `infura_token` - https://www.infura.io/ RPC token to allow Status Backend to use a wallet
|
||||
- `alchemy_token` - https://alchemy.com/ RPC token to allow Status Backend to use a wallet
|
||||
- `coingecko_api_key` - https://www.coingecko.com/ API key to allow Status Backend to use a wallet
|
||||
"""
|
||||
if not key_uid and not display_name:
|
||||
if not key_uid and not name:
|
||||
raise exceptions.InvalidContactError()
|
||||
|
||||
available_accounts = self.available_accounts
|
||||
# Login combination: display_name + password
|
||||
# Login combination: display_name (or ENS) + password
|
||||
if not key_uid:
|
||||
for account in available_accounts:
|
||||
if account["display_name"] != display_name:
|
||||
if account["name"] != name:
|
||||
continue
|
||||
|
||||
key_uid = account["key_uid"]
|
||||
@@ -131,7 +131,7 @@ class Account:
|
||||
else:
|
||||
available_key_uids = [current["key_uid"] for current in available_accounts]
|
||||
if key_uid not in available_key_uids:
|
||||
info = "\n".join([f"{current['key_uid']} - {current['display_name']}" for current in self.available_accounts])
|
||||
info = "\n".join([f"{current['key_uid']} - {current['name']}" for current in self.available_accounts])
|
||||
raise exceptions.InvalidContactError(f"Given Key Unique Identifier is invalid...\nAvailable Key Unique Identifiers:\n{info}")
|
||||
|
||||
is_new_account = isinstance(key_uid, type(None))
|
||||
@@ -145,11 +145,11 @@ class Account:
|
||||
}
|
||||
|
||||
if is_new_account or is_recovery:
|
||||
self.__validate_display_name(display_name)
|
||||
self.__validate_display_name(name)
|
||||
params = {
|
||||
"rootDataDir": self.__docker_data_folder,
|
||||
"kdfIterations": self.__kd_iterations,
|
||||
"displayName": display_name,
|
||||
"displayName": name,
|
||||
"password": password,
|
||||
"customizationColor": "primary",
|
||||
"wakuV2LightClient": False,
|
||||
@@ -159,7 +159,7 @@ class Account:
|
||||
self.logger.info(f"Logging in with Key UID - {key_uid}")
|
||||
|
||||
if is_new_account:
|
||||
self.logger.info(f"Creating account with display_name {display_name}")
|
||||
self.logger.info(f"Creating account with display_name {name}")
|
||||
url_key = "create"
|
||||
|
||||
if is_recovery:
|
||||
@@ -202,6 +202,7 @@ class Account:
|
||||
|
||||
self.logger.info("Successfully logged in!")
|
||||
event: dict = signal_event["event"]["settings"]
|
||||
ens_info: list[dict] = signal_event["event"].get("ensUsernames", [])
|
||||
self.__info = {
|
||||
"public_key": event["public-key"],
|
||||
"url": None,
|
||||
@@ -213,6 +214,10 @@ class Account:
|
||||
"bio": event.get("bio", ""),
|
||||
"password": password,
|
||||
"wallet_address": event["dapps-address"],
|
||||
"ens": {
|
||||
"preferred_name": event.get("preferred-name"),
|
||||
"usernames": ens_info
|
||||
},
|
||||
"logged_in_timestamp": datetime.datetime.now()
|
||||
}
|
||||
self.__info["url"] = self.__call_rpc("urls", "shareUserURLWithData", [event["public-key"]]).get("result")
|
||||
@@ -255,7 +260,8 @@ class Account:
|
||||
|
||||
current_available_accounts = [
|
||||
{
|
||||
"display_name": account["name"],
|
||||
"name": account["name"],
|
||||
"is_ens": account["name"].endswith(".eth"),
|
||||
"key_uid": account["key-uid"],
|
||||
"created_at": datetime.datetime.fromtimestamp(account["timestamp"])
|
||||
}
|
||||
@@ -1226,7 +1232,7 @@ class Account:
|
||||
params = {
|
||||
"filePath": os.path.join(self.__docker_backup_folder, file_name).replace("\\", "/")
|
||||
}
|
||||
self.logger.info(f"Trying to load {file_path}")
|
||||
self.logger.info(f"Loading backup file: {file_path}")
|
||||
response = requests.post(self.__urls["http"]["load_backup"], json=params)
|
||||
error: str = response.json().get("error", "")
|
||||
|
||||
|
||||
+68
-41
@@ -143,23 +143,23 @@ An account can also be recovered if the [`mnemonic`](https://status.app/help/pro
|
||||
|-----|-----|-----|-------------|
|
||||
| `password` | `str` | Yes | Password used to encrypt the account |
|
||||
| `key_uid` | `str` | Yes* | Unique key identifier of the account. If provided, the account will be logged in directly using this identifier. If not provided, then you must use `display_name` and `password` to login. |
|
||||
| `display_name` | `str` | Yes* | Display name of the account. Used to resolve the `key_uid` if it is not provided, or to create a new account if one does not already exist. This field is required if an account needs to be recovered with `mnemonic`. |
|
||||
| `name` | `str` | Yes* | Display name or [ENS name](https://status.app/help/profile/transfer-your-ens-name-to-status) of the account. Used to resolve the `key_uid` if it is not provided, or to create a new account if one does not already exist. This field is required if an account needs to be recovered with `mnemonic`. |
|
||||
| `mnemonic` | `str` | No | The [mnemonic](https://status.app/help/profile/understand-your-status-keys-and-recovery-phrase#about-your-recovery-phrase) from [`info`](./account.md#info). Use this field with `password` and `display_name` to recover the account. If you have [`.bkp`](./account.md#backup) files, in the backup Docker volume they will be automatically picked up and loaded.<br><br>**Note**: You can pass a different `display_name` but that will be internal only. When an account is recovered setting [`display_name`](./account.md#display_name) can be buggy. Ideally when recovering the account, use the original `display_name` of the account. |
|
||||
| `infura_token` | `str` | No | [RPC token](https://www.infura.io/) used by Status Backend for the Ethereum RPC component of the wallet. |
|
||||
| `alchemy_token` | `str` | No | Used to fetch [wallet transactions](./account.md#get_transactionsrefreshfalse) to fetch wallet transaction history via the Alchemy REST API, so no separate key is needed for transactions. |
|
||||
| `coingecko_api_key` | `str` | No | [API key](https://www.coingecko.com/) used by Status Backend to fetch token prices. |
|
||||
|
||||
Wallet functionality is split into three components, each backed by a token: Ethereum RPC (`infura_token`), transactions (`alchemy_token`) and prices (`coingecko_api_key`). All three must be provided for wallet RPC methods to work — if any is missing, wallet calls raise a `WalletNotConfiguredError`.
|
||||
Wallet functionality is split into three components, each backed by a token: Ethereum RPC (`infura_token`), transactions (`alchemy_token`) and prices (`coingecko_api_key`). All three must be provided for wallet RPC methods to work - if any is missing, wallet calls raise a `WalletNotConfiguredError`.
|
||||
|
||||
Returns the current `Account` instance, allowing method chaining.
|
||||
|
||||
#### Login with `display_name`
|
||||
#### Login with Display name
|
||||
```python
|
||||
from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -171,6 +171,25 @@ The code above is equivalent to the following screen on Status App:
|
||||
|
||||
**Note**: This assumes that `display_name` and is unique for every `key_uid`. If there are duplicated `display_names` then the first found match will be used. You can log in with `key_uid` if you have `display_name` duplicates.
|
||||
|
||||
#### Login with ENS
|
||||
|
||||
```python
|
||||
from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"name": "malte.stateofus.eth",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
```
|
||||
|
||||
You can purchase a **universal username** on Status App:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
#### Login with `key_uid`
|
||||
|
||||
```python
|
||||
@@ -191,7 +210,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP",
|
||||
"mnemonic" : "phrase_1 phrase_2 phrase_3 phrase_4 phrase_5 phrase_6 phrase_7 phrase_8 phrase_9 phrase_10 phrase_11 phrase_12"
|
||||
}
|
||||
@@ -212,7 +231,7 @@ from bot import Account
|
||||
account = Account()
|
||||
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP",
|
||||
"infura_token": "token from https://www.infura.io/",
|
||||
"alchemy_token": "token from https://www.alchemy.com/",
|
||||
@@ -221,7 +240,7 @@ params = {
|
||||
account.login(**params)
|
||||
```
|
||||
|
||||
**Note**: `infura_token`, `alchemy_token` and `coingecko_api_key` can be used when creating, recovering and logging in to an account. All three are required to enable wallet functionality — if any is missing, those calls raise a `WalletNotConfiguredError`.
|
||||
**Note**: `infura_token`, `alchemy_token` and `coingecko_api_key` can be used when creating, recovering and logging in to an account. All three are required to enable wallet functionality - if any is missing, those calls raise a `WalletNotConfiguredError`.
|
||||
|
||||
### `logout()`
|
||||
|
||||
@@ -232,7 +251,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -258,7 +277,7 @@ from bot import Account
|
||||
|
||||
account = Account(backup_folder=r"C:\\Users\\me\\status-backups")
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -283,7 +302,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -315,7 +334,7 @@ import datetime
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -346,7 +365,7 @@ from rich.pretty import Pretty
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -384,7 +403,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -427,7 +446,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -457,7 +476,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -491,7 +510,7 @@ from bot import Account
|
||||
account = Account()
|
||||
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP",
|
||||
"infura_token": "token from https://www.infura.io/",
|
||||
"alchemy_token": "token from https://www.alchemy.com/",
|
||||
@@ -524,7 +543,7 @@ from bot import Account
|
||||
account = Account()
|
||||
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP",
|
||||
"infura_token": "token from https://www.infura.io/",
|
||||
"alchemy_token": "token from https://www.alchemy.com/",
|
||||
@@ -551,7 +570,7 @@ from bot import Account
|
||||
account = Account()
|
||||
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP",
|
||||
"infura_token": "token from https://www.infura.io/",
|
||||
"alchemy_token": "token from https://www.alchemy.com/",
|
||||
@@ -579,7 +598,7 @@ from bot import Account
|
||||
account = Account()
|
||||
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP",
|
||||
"infura_token": "token from https://www.infura.io/",
|
||||
"alchemy_token": "token from https://www.alchemy.com/",
|
||||
@@ -611,7 +630,7 @@ from bot import Account
|
||||
account = Account()
|
||||
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP",
|
||||
"infura_token": "token from https://www.infura.io/",
|
||||
"alchemy_token": "token from https://www.alchemy.com/",
|
||||
@@ -690,7 +709,7 @@ from bot import Account
|
||||
account = Account()
|
||||
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP",
|
||||
"infura_token": "token from https://www.infura.io/",
|
||||
"alchemy_token": "token from https://www.alchemy.com/",
|
||||
@@ -729,7 +748,7 @@ from bot import Account
|
||||
account = Account()
|
||||
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP",
|
||||
"infura_token": "token from https://www.infura.io/",
|
||||
"alchemy_token": "token from https://www.alchemy.com/",
|
||||
@@ -755,7 +774,7 @@ from bot import Account
|
||||
account = Account()
|
||||
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP",
|
||||
"infura_token": "token from https://www.infura.io/",
|
||||
"alchemy_token": "token from https://www.alchemy.com/",
|
||||
@@ -780,7 +799,7 @@ from bot import Account
|
||||
account = Account()
|
||||
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP",
|
||||
"infura_token": "token from https://www.infura.io/",
|
||||
"alchemy_token": "token from https://www.alchemy.com/",
|
||||
@@ -806,7 +825,7 @@ from bot import Account
|
||||
account = Account()
|
||||
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP",
|
||||
"infura_token": "token from https://www.infura.io/",
|
||||
"alchemy_token": "token from https://www.alchemy.com/",
|
||||
@@ -846,7 +865,14 @@ This property is useful when you want to:
|
||||
|
||||
**You will have to know the passwords for the given `key_uid`.**
|
||||
|
||||
Returns `list[dict]`.
|
||||
Returns `list[dict]`, one entry per locally available account.
|
||||
|
||||
| Key | Type | Description |
|
||||
|----|----|-------------|
|
||||
| `name` | `str` | The account's name. For accounts using an [ENS](https://status.app/help/profile/transfer-your-ens-name-to-status) name, this is the ENS name (e.g. `malte.stateofus.eth`). For accounts that do not have an ENS name, this will be their display name. |
|
||||
| `is_ens` | `bool` | `True` when `display_name` is an ENS name (ends with `.eth`), otherwise `False`. Useful for telling apart plain display names from universal usernames. |
|
||||
| `key_uid` | `str` | Internal Status key identifier for the account. Can be passed to [`login`](./account.md#loginpassword-key_uidnone-display_namenone-mnemonicnone-infura_tokennone-alchemy_tokennone-coingecko_api_keynone) as `key_uid`. |
|
||||
| `created_at` | `datetime.datetime` | Timestamp when the account was created locally. |
|
||||
|
||||
```python
|
||||
from bot import Account
|
||||
@@ -874,6 +900,7 @@ Provides information about the currently logged-in account. If `login()` has not
|
||||
| `display_name` | `str` | Display name of the account. |
|
||||
| `password` | `str` | Password used to encrypt the account locally. |
|
||||
| `wallet_address` | `str` | Ethereum wallet address associated with the account. |
|
||||
| `ens` | `dict` | The account's [ENS](https://status.app/help/profile/transfer-your-ens-name-to-status) details. Contains `preferred_name` (`str` or `None`) - the ENS name the account has chosen to display - and `usernames` (`list[dict]`) - every ENS username registered to the account. Both are empty / `None` when no ENS name is set. |
|
||||
| `logged_in_timestamp` | `datetime.datetime` | Timestamp when the account successfully logged in. |
|
||||
|
||||
```python
|
||||
@@ -881,7 +908,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -900,7 +927,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -916,7 +943,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -939,7 +966,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -955,7 +982,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -972,7 +999,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -994,7 +1021,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -1012,7 +1039,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -1123,7 +1150,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -1191,7 +1218,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -1228,7 +1255,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -1257,7 +1284,7 @@ from bot import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
@@ -1288,7 +1315,7 @@ from bot import Account
|
||||
account = Account()
|
||||
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP",
|
||||
"infura_token": "token from https://www.infura.io/",
|
||||
"alchemy_token": "token from https://www.alchemy.com/",
|
||||
@@ -1318,7 +1345,7 @@ from bot import Account
|
||||
account = Account()
|
||||
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP",
|
||||
"infura_token": "token from https://www.infura.io/",
|
||||
"alchemy_token": "token from https://www.alchemy.com/",
|
||||
@@ -1336,7 +1363,7 @@ from bot import Account
|
||||
account = Account()
|
||||
|
||||
params = {
|
||||
"display_name": "status-app-bot",
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP",
|
||||
"infura_token": "token from https://www.infura.io/",
|
||||
"alchemy_token": "token from https://www.alchemy.com/",
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 136 KiB |
Reference in New Issue
Block a user