71 KiB
Account
The account class allows you to easily work with a Status account.
Display name
The display name is the human‑readable identifier for a Status account. It is used when creating an account, resolving an existing account during login, and when updating the account name through the display_name property.
Display names must follow strict validation rules enforced by the library and expected by the Status application. A valid display name must satisfy all of the following conditions:
- It may contain uppercase letters (
A–Z) - It may contain spaces (
) - It may contain numbers (
0–9) - It may contain hyphens (
-) - It may contain underscores (
_) - It must be at least 5 characters long
- It cannot be more than 24 characters long
- It cannot start or end with a space
Characters such as spaces, punctuation, emojis, or other symbols are not allowed.
Valid examples
alpha_01
STATUS-01
bot_user_5
HELLO123
node-42
Invalid examples
| Example | Reason |
|---|---|
bot |
Too short (minimum length is 5) |
mybot |
Leading space |
mybot |
Trailing space |
bot!123 |
Contains invalid character ! |
If a display name does not follow these rules, a ValueError will be raised by the account validation logic.
Backups
Backup files (.bkp) can be both created in Status App and the Python SDK.
Status Backend backup folder is exposed in a Docker volume so users can:
- Upload backup - by dropping
.bkpfiles in thebackupsfolder locally (linked to Status Backend Docker container). Backups are automatically uploaded if amnemonicis provided duringlogin. - Create backup - by using
backup()or creating one in Status App.
Note: Status App will not automatically backup messages. This has to be manually overridden on the app (above screenshot). When using the Python SDK, the messages are automatically stored in the .bkp files.
You can point backup_folder at the folder Status App uses for its own local backups. Because both Status App and the SDK name .bkp files deterministically from the account's compressed key (see backup()), a backup created by the SDK lands with the exact filename Status App expects, and Status App will pick it up and load it directly - and likewise, a backup created in Status App can be auto-loaded by the SDK during recovery. This lets you move backups between the app and the SDK without renaming anything.
flowchart LR
app[Status App]
sdk[Python SDK]
subgraph shared["Shared folder"]
bkp1[.bkp 1]
bkp2[.bkp 2]
bkpn[.bkp n]
end
subgraph backend[status-im/status-go]
Vol1[(Backup)]
end
app <--> shared <--> sdk <--> Vol1
Because the file name is derived from the account's key rather than from whoever wrote it, the same account always maps to the same .bkp file - so neither side needs to know which tool produced the backup.
Public keys
Every Status account is identified by one key, but that key appears in three different forms depending on where you look at it.
| Format | Example | What it is | Where to find it |
|---|---|---|---|
| Public key | 0x04ebcad... |
The full, uncompressed key. This is what Status Backend works with internally, and what the SDK keys its data by. | public_key in info / contacts |
| Chat key (compressed key) | zQ3shYSHp7... |
The same key in its compressed form. This is the value Status App shows and what users copy when they share their chat key. | compressed_key in info / contacts, or the chat key in Status App |
| Account URL | https://status.app/u/... |
A shareable profile link with the chat key embedded in it. This is what Share profile produces in Status App. | url in info / contacts, or Share profile in Status App |
Where a list is accepted, the formats can even be mixed within the same list, since each value is normalised on its own.
Note: An account URL (https://status.app/u/...) is not the same as a community URL (https://status.app/c/...). Community URLs identify a community and belong in the Community constructor.
Wallet
Wallet features are optional and can be omitted if not required for your use case. They provide functionality equivalent to the Wallet and Market tabs.
Installation ID
Currently installation IDs can be found in Debug Mode only. To turn Debug Mode:
Once Debug Mode is turned on and Status App is restarted, you can go to Syncing tab.
The Installation ID should be used when calling sync and unsync.
Account(domain="localhost", backend_port=8080, media_port=9000, is_secure=False, backup_folder=None, volume_folder=None)
Create a new Account instance ready to be logged in. The constructor wires the SDK to a running Status Backend at the given domain and backend_port, prepares the local assets/ folder (used for image uploads, such as the profile picture) and backups/ folder (used for backup uploads and recovery).
| Name | Type | Required | Description |
|---|---|---|---|
domain |
str |
No | Domain where Status Backend is reachable. Defaults to localhost when running through launch_docker_container on the same machine. Use the container name when the SDK runs inside the same Docker network as Status Backend. |
backend_port |
int |
No | Port exposed by Status Backend. Defaults to 8080. If this is changed, the published port for backend_port must be updated to match in docker-compose.yaml as well. |
media_port |
int |
No | Port exposed by the Status media server, used to fetch localhost images such as the profile picture. Defaults to 9000. If this is changed, the published port for media_port must be updated to match in docker-compose.yaml as well. |
is_secure |
bool |
No | When True, the SDK communicates over https; otherwise http is used. Defaults to False. |
backup_folder |
str |
No | Absolute path on the host machine where .bkp files will be created and loaded from. If not provided, the SDK's own backups/ folder is used. See Backups. |
volume_folder |
str |
No | Directory containing the docker-compose.yaml whose backups/ and assets/ folders are mounted into the Status Backend container. Defaults to this package's own installation folder (e.g. the status_sdk folder under site-packages when installed via pip). Set this when Status Backend is launched from a different docker-compose.yaml, such as a local clone of the repository. |
The constructor does not log into any account on its own - call login afterwards. To discover what accounts already exist in the configured data directory, use the available_accounts property, which is also populated automatically during initialization.
from status_sdk import Account
account = Account()
Use a custom backup folder:
from status_sdk import Account
account = Account(backup_folder=r"C:\\Users\\me\\status-backups")
Connect to a Status Backend running on a different host or port:
from status_sdk import Account
account = Account(
domain="status-backend.internal",
port=9090,
is_secure=True
)
Run against a local clone of the repository instead of with launch_docker_container:
from status_sdk import Account
account = Account(volume_folder="/path/to/status-python-sdk/status_sdk")
Note: Status Backend must be running before initializing Account. You can launch the backend container with launch_docker_container. If the backend is not reachable on domain:port, calls to login will fail.
Note: When backup_folder is set, backup moves the generated .bkp file out of the SDK's internal backups/ folder into the provided path, and recovery via mnemonic will look in this same folder for .bkp files to auto-load. Make sure the folder exists and is writable.
Note: volume_folder must match the directory containing the docker-compose.yaml actually used to launch Status Backend, since that is what determines where Docker mounts backups/ and assets/ on the host. If volume_folder points elsewhere, Account will create and use folders that are never seen by the running container.
Methods
login(password, key_uid=None, display_name=None, mnemonic=None, infura_token=None, alchemy_token=None, coingecko_api_key=None)
Login to an existing Status account. If the account does not exist in the initialized data directory, a new account will be created and automatically logged in.
After a successful login, the decentralized messenger service is automatically started so the account can send and receive messages.
An account can also be recovered if the mnemonic is passed.
| Name | Type | Required | Description |
|---|---|---|---|
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. |
name |
str |
Yes* | Display name or ENS 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. |
mnemonic |
str |
No | The mnemonic from info. Use this field with password and display_name to recover the account. If you have .bkp files, in the backup Docker volume they will be automatically picked up and loaded.Note: You can pass a different display_name but that will be internal only. When an account is recovered setting display_name can be buggy. Ideally when recovering the account, use the original display_name of the account. |
infura_token |
str |
No | RPC token used by Status Backend for the Ethereum RPC component of the wallet. |
alchemy_token |
str |
No | Used to fetch wallet transactions 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 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.
Returns the current Account instance, allowing method chaining.
Login with Display name
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
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
from status_sdk 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
from status_sdk import Account
account = Account()
params = {
"key_uid": "0xff2c3...",
"password": "SNTPUMP"
}
account.login(**params)
Recover account
from status_sdk import Account
account = Account()
params = {
"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"
}
account.login(**params)
The code above is equivalent to the following screen on Status App:
Note: When in recovery mode, the display name is updated on Status App as well so it is consistent locally and to other users.
Wallet setup
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP",
"infura_token": "token from https://www.infura.io/",
"alchemy_token": "token from https://www.alchemy.com/",
"coingecko_api_key": "API key from https://www.coingecko.com/"
}
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.
logout()
Logout from the currently logged-in Status account. This method also clears the internal account state and stops the active messenger session. This function is also supported in del and when the script automatically finishes.
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# Optional - even if not specified __del__ will log you out
account.logout()
Returns the current Account instance. This allows chaining additional operations if needed.
Note: Currently logout works for a single sign in and may break because it does not listen for signals.
backup()
Create a local backup file (.bkp) for the currently logged‑in account. The backup is generated by the Status Backend and stored inside the configured Docker backup volume. Each file is uniquely associated with an account. If the backup creation fails, an exception will be raised.
Returns str representing the Docker path of the generated backup file. The returned path refers to the Docker container path where the backup was created. If the backup directory is mounted as a Docker volume, the file will also appear on the host machine in the mapped folder.
The filename is generated by the Status Backend and follows the pattern <suffix>_user_data.bkp, where <suffix> is the last 6 characters of the account's compressed public key. For example, an account whose compressed key ends in abc123 produces abc123_user_data.bkp. Because the suffix is derived deterministically from the account's key, the same account always maps to the same filename, which is how a backup is uniquely associated with its account.
from status_sdk import Account
account = Account(backup_folder=r"C:\\Users\\me\\status-backups")
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
backup_path = account.backup()
print(f"Backup created at: {backup_path}")
sync(installation_id, name=None)
Pair another device with the account, so messages, contacts and settings are synced between them. This is the SDK equivalent of Sync new device in Status App - useful for running a remotely while keeping the same account on a phone or desktop.
Each device that logs into an account is registered with the backend as an installation, identified by an installation_id. A device reports its own id under installation_id in info, so pairing means passing the other device's id to this method. Both devices must have logged in to the same Status account for the installation to be known to the backend.
| Name | Type | Required | Description |
|---|---|---|---|
installation_id |
str |
Yes | The id of the device to pair with. It is the value that device reports under installation_id in its own info. |
name |
str |
No | The name of the paired device, so it is easier to recognise locally. When omitted, the device keeps whatever name it already has. |
Returns None. Passing the logged-in account's own installation_id is a no-op, so a device can safely loop over a list of ids without filtering itself out first.
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# The id the other device reports under `installation_id` in its own `info`
account.sync("6a2f9c1e-...", "raspberry-pi")
Note: login deletes every installation that is not enabled. A device that was never synced, or that was unsynced, is therefore removed on the next login and has to be re-registered by logging in from that device again.
unsync(installation_id)
Stop syncing with a device that was paired with sync. The device stops receiving the account's messages, contacts and settings.
| Name | Type | Required | Description |
|---|---|---|---|
installation_id |
str |
Yes | The id of the device to stop syncing with, in the same format accepted by sync. |
Returns None. As with sync, passing the account's own installation_id is a no-op - an account cannot unsync itself. A custom exception is raised if the backend rejects the call.
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
account.unsync("6a2f9c1e-...")
Note: unsyncing only disables the installation, so it can be paired again with sync within the same session. It does not survive a restart though - the next login deletes disabled installations, and the other device has to log in again before it can be synced.
Chat
send_message(chat_id, message, reply_to_message_id=None)
Send a text message to a specific chat. This method currently supports text messages only. A message can also be sent as a reply to an existing message in the same chat, which renders in Status App with the original message quoted above it - the same as replying to a message in the app.
A message can be at most 2000 characters long, matching the limit enforced by Status App. Sending a longer message raises a custom exception.
| Name | Type | Required | Description |
|---|---|---|---|
chat_id |
str |
Yes | Identifier of the chat where the message will be sent. All available chat IDs can be obtained from the chats property. |
message |
str |
Yes | The text message to send. Cannot be longer than 2000 characters. |
reply_to_message_id |
str |
No | The id of the message being replied to. Message IDs can be obtained from the id key of get_messages or from a listen_messages event. When omitted (default), the message is sent as a standalone message. |
Returns str - the id of the message that was just sent. It is the same identifier that appears under the id key in get_messages, so it can be passed straight into delete_message or used as the reply_to_message_id of a follow-up message, without having to fetch the chat's messages first.
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# This is under the assumption you already have a contact / joined a community
chat = account.chats[0]
message_id = account.send_message(chat["id"], "Hello from my Status bot!")
print(f"Sent message: {message_id}")
Reply to a message:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
chat = account.chats[0]
# Messages are returned newest first, so this is the latest message in the chat
messages = account.get_messages(chat["id"])
latest = messages[0]
account.send_message(
chat_id=chat["id"],
message="Thanks for the update!",
reply_to_message_id=latest["id"]
)
get_messages(chat_id, start_timestamp=None, end_timestamp=None)
Retrieve messages from the specified chat within an optional time range. Messages are returned in descending order (newest to oldest). The method automatically paginates through the backend until all messages in the specified range are collected. This method is ideal for backfilling, batch processing or micro batch processing.
Messages can be fetched from:
- Direct messages - current contacts and contacts that were later removed
- Community channels - the bot must have read access from the admin
| Name | Type | Required | Description |
|---|---|---|---|
chat_id |
str |
Yes | Identifier of the chat. All available chat IDs can be obtained from the chats property. |
start_timestamp |
datetime.datetime |
No | The earliest timestamp to include. Messages older than this value will stop the fetch process. |
end_timestamp |
datetime.datetime |
No | The latest timestamp to include. Messages newer than this value will be skipped. |
Returns list[dict] containing message objects. Timestamp fields returned by the backend are automatically converted into datetime.datetime objects.
from status_sdk import Account
import datetime
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
chat = account.chats[0]
messages = account.get_messages(
chat_id=chat["id"],
start_timestamp=datetime.datetime(2024, 1, 1)
)
for message in messages:
print(f"{message['timestamp']}\t{message['text']}")
Note: If there are missing messages in a chat that might be because the node (Status Backend) has not received them yet. They may appear later.
delete_message(id)
Delete one of your own messages from a chat. The deletion is propagated to the other members of the chat, so the message disappears for everybody - the same as deleting a message in Status App.
You can only delete messages that the logged-in account has sent. Messages sent by other accounts cannot be deleted, even in a group chat where the account is the administrator.
| Name | Type | Required | Description |
|---|---|---|---|
id |
str |
Yes | The id of the message to delete. Message IDs can be obtained from the id key of get_messages, or directly from the return value of send_message. |
Returns bool.
| Value | Meaning |
|---|---|
True |
The message was deleted. |
False |
The message was not deleted, because the account does not have permission to delete it. |
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
chat = account.chats[0]
message_id = account.send_message(chat["id"], "Oops, this was a mistake!")
deleted = account.delete_message(message_id)
print(f"Deleted: {deleted}")
listen_messages()
Listen for new incoming messages in real time. This method yields raw message events as they are received from the Status Backend signal messages.new. This method is ideal for developing real time chat applications
from status_sdk import Account
import datetime
# For terminal readability only
from rich import print as rprint
from rich.pretty import Pretty
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
for msg in account.listen_messages():
rprint(Pretty(msg))
Note: If you receive multiple messages at once, contacts and chats will grow.
add_contact(public_key, display_name=None)
Send a contact request or approve an existing contact request. The mode depends on how the contact shows up in contacts. Best practice would be to look at the the following contacts keys:
has_added_us-boolvalue to check if the other user has added the account as a friendadded-boolvalue to check if the account has added the other user as a friendmutual-boolvalue to check if the account and other user are in contactscontact_state-strvalue to see the account's current stateexternal_contact_state-strvalue to see the other user's state as it is in your node
Modes:
- Approve mode -
has_added_usisTrueandaddedisFalse - Add mode -
has_added_usisFalse
The contact can be identified in three different ways, so you can pass whichever value you have at hand - the public key, the chat key as shown in Status App, or the profile link a user shares with you:
| Format | Example | Where to find it |
|---|---|---|
| Public key | 0x04ebcad... |
public_key in contacts / info |
| Chat key (compressed key) | zQ3shYSHp7... |
compressed_key in contacts / info, or the chat key in Status App |
| Account URL | https://status.app/u/... |
url in contacts / info, or Share profile in Status App |
When an account URL is passed, the public key is resolved from it automatically before the contact request is sent, so the contact is always added with the same identity regardless of which format you used.
| Name | Type | Required | Description |
|---|---|---|---|
public_key |
str |
Yes | The contact's Status public key (0x...), chat key (zQ...) or account URL (https://...). |
display_name |
str |
Yes / No | Display name for the contact. If the contact already exists in contacts, the display_name parameter is optional and the existing name will be reused. If the contact has never interacted with the bot before, display_name must be provided so the contact can be created locally. |
Returns the current Account instance, allowing method chaining.
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# Send a contact request
account.add_contact(
public_key="0x04ebcad...",
display_name="status-enjoyer"
)
Add a contact with their chat key:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# Send a contact request
account.add_contact(
public_key="zQ3shYSHp7...",
display_name="status-enjoyer"
)
Add a contact with their account URL:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# Send a contact request
account.add_contact(
public_key="https://status.app/u/...",
display_name="status-enjoyer"
)
remove_contact(public_key)
Remove a contact or decline a pending contact request. The mode depends on how the contact shows up in contacts. Best practice would be to look at the the following contacts keys:
has_added_us-boolvalue to check if the other user has added the account as a friendadded-boolvalue to check if the account has added the other user as a friendmutual-boolvalue to check if the account and other user are in contactscontact_state-strvalue to see the account's current stateexternal_contact_state-strvalue to see the other user's state as it is in your node
Modes:
- Remove -
has_added_usisTrueandaddedisTrue - Reject mode -
has_added_usisTrue
Just like add_contact, the contact can be identified in three different ways:
| Format | Example | Key in contacts |
|---|---|---|
| Public key | 0x04ebcad... |
public_key |
| Chat key (compressed key) | zQ3shYSHp7... |
compressed_key |
| Account URL | https://status.app/u/... |
url |
Whichever format is used, the value is matched against contacts - so it must belong to a user that has already interacted with the account.
| Name | Type | Required | Description |
|---|---|---|---|
public_key |
str |
Yes | The contact's Status public key (0x...), chat key (zQ...) or account URL (https://...). All three values correspond to the ones exposed in contacts. |
Returns bool.
| Value | Meaning |
|---|---|
True |
The contact was successfully removed or the request was declined. |
False |
The contact does not exist or was already removed. |
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# NOTE: contacts are returned as a dict for
# internal class checks and scalability
contact = list(account.contacts.values())[0]
removed = account.remove_contact(contact["public_key"])
print(f"Removed: {removed}")
get_public_key(value)
Normalise any of the three account identifiers into a public key (0x...). This normalisation is used internally by the library as well, so methods that accept a contact identifier work the same regardless of which format is passed.
The behaviour depends on the format of value:
| Format | Example | Behaviour |
|---|---|---|
| Public key | 0x04ebcad... |
Returned as is - no backend call is made. |
| Chat key (compressed key) | zQ3shYSHp7... |
Uncompressed by Status Backend into the public key. |
| Account URL | https://status.app/u/... |
The chat key is parsed out of the URL and then uncompressed into the public key. |
| Name | Type | Required | Description |
|---|---|---|---|
value |
str |
Yes | The public key (0x...), chat key (zQ...) or account URL (https://...) to resolve. All three values correspond to the public_key, compressed_key and url keys in contacts / info. |
Returns str representing the account's public key, always prefixed with 0x.
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# All three return the same public key
for key in ["public_key", "url", "compressed_key"]:
value = account.info[key]
print(f"\n{key}: {value}\nkey: {account.get_public_key(value)}\n")
Look up a contact when all you have is a shared profile link:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
public_key = account.get_public_key("https://status.app/u/...")
# contacts are keyed by public key
contact = account.contacts.get(public_key)
if contact:
print(contact["display_name"], contact["contact_state"])
Note: An exception will be raised when:
valuedoes not start with0x,zQorhttp(PublicKeyError)- the chat key cannot be uncompressed by Status Backend (
PublicKeyError) - the URL cannot be parsed, or it is a community / channel URL rather than an account URL (
InvalidContactError)
Wallet
get_tokens()
Retrieve all tokens available in Status Backend across all supported chains.
Returns pd.DataFrame.
| Column | Type | Description |
|---|---|---|
chain_id |
int |
Chain ID where the token exists. Matches values from chains. |
address |
str |
Token contract address. |
symbol |
str |
Token symbol (e.g. ETH, USDT). |
decimals |
int |
Number of decimals used for the token. |
cross_chain_id |
strNone |
Cross-chain identifier (if available). |
source_id |
str |
Source list from which the token was fetched. |
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP",
"infura_token": "token from https://www.infura.io/",
"alchemy_token": "token from https://www.alchemy.com/",
"coingecko_api_key": "API key from https://www.coingecko.com/"
}
account.login(**params)
available_tokens = account.get_tokens()
get_balance(token_addresses, chain_ids=1, wallets=None, ccy=None)
Retrieve token balances for one or more wallets across specified chains. This method supports querying multiple tokens, chains, and wallets. Balances are adjusted using token decimals. Optionally, values can be converted to fiat currencies.
Returns pd.DataFrame.
| Column | Type | Description |
|---|---|---|
timestamp |
datetime.datetime |
Timestamp when the balance was fetched. |
wallet_address |
str |
Wallet address for which the balance was retrieved. |
token_address |
str |
Token contract address. |
token_symbol |
str |
Token symbol (e.g. ETH, USDT). |
amount |
float |
Token balance (adjusted using token decimals). |
chain_id |
int |
Chain ID where the token exists. |
ccy |
str |
Fiat currency (only present if ccy is provided). |
price |
float |
Token price for 1 token_symbol in the given fiat currency (only present if ccy is provided). If you want to get the amount in the wallet, you must amount * price. |
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP",
"infura_token": "token from https://www.infura.io/",
"alchemy_token": "token from https://www.alchemy.com/",
"coingecko_api_key": "API key from https://www.coingecko.com/"
}
account.login(**params)
token_mapping = {
'ETH': '0x0000000000000000000000000000000000000000',
'SNT': '0x744d70fdbe2ba4cf95131626614a1763df805b9e',
'USDT': '0xdac17f958d2ee523a2206206994597c13d831ec7',
'CELO': '0x9b88d293b7a791e40d36a39765ffd5a1b9b5c349'
}
token_addresses = list(token_mapping.values())
# Returns data for logged in wallet
data = account.get_balance(token_addresses)
Access multuple chains:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP",
"infura_token": "token from https://www.infura.io/",
"alchemy_token": "token from https://www.alchemy.com/",
"coingecko_api_key": "API key from https://www.coingecko.com/"
}
account.login(**params)
token_mapping = {
'ETH': '0x0000000000000000000000000000000000000000',
'SNT': '0x744d70fdbe2ba4cf95131626614a1763df805b9e',
'USDT': '0xdac17f958d2ee523a2206206994597c13d831ec7',
'CELO': '0x9b88d293b7a791e40d36a39765ffd5a1b9b5c349'
}
token_addresses = list(token_mapping.values())
chain_ids = [1, 10] # Can be a single int value as well
# Returns data for logged in wallet
data = account.get_balance(token_addresses, chain_ids)
Access multiple wallets:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP",
"infura_token": "token from https://www.infura.io/",
"alchemy_token": "token from https://www.alchemy.com/",
"coingecko_api_key": "API key from https://www.coingecko.com/"
}
account.login(**params)
token_mapping = {
'ETH': '0x0000000000000000000000000000000000000000',
'SNT': '0x744d70fdbe2ba4cf95131626614a1763df805b9e',
'USDT': '0xdac17f958d2ee523a2206206994597c13d831ec7',
'CELO': '0x9b88d293b7a791e40d36a39765ffd5a1b9b5c349'
}
token_addresses = list(token_mapping.values())
chain_ids = [1, 10] # Can be a single int value as well
vitalik_address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
bot_wallet = account.info["wallet_address"]
wallets = [bot_wallet, vitalik_address]
data = account.get_balance(token_addresses, chain_ids, wallets)
Get token prices:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP",
"infura_token": "token from https://www.infura.io/",
"alchemy_token": "token from https://www.alchemy.com/",
"coingecko_api_key": "API key from https://www.coingecko.com/"
}
account.login(**params)
token_mapping = {
'ETH': '0x0000000000000000000000000000000000000000',
'SNT': '0x744d70fdbe2ba4cf95131626614a1763df805b9e',
'USDT': '0xdac17f958d2ee523a2206206994597c13d831ec7',
'CELO': '0x9b88d293b7a791e40d36a39765ffd5a1b9b5c349'
}
token_addresses = list(token_mapping.values())
chain_ids = [1, 10] # Can be a single int value as well
vitalik_address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
bot_wallet = account.info["wallet_address"]
wallets = [bot_wallet, vitalik_address] # Can be a single str value as well
ccy = ["GBP", "USD"] # Can be a single str value as well
data = account.get_balance(token_addresses, chain_ids, wallets, ccy)
get_market(token_addresses, chain_ids=1, ccy="USD")
Retrieve market data for one or more tokens across specified chains.
Returns pd.DataFrame.
| Column | Type | Description |
|---|---|---|
timestamp |
datetime.datetime |
Timestamp when the market data was fetched. |
chain_id |
int |
Chain ID where the token exists. |
token_address |
str |
Token contract address. |
token_symbol |
str |
Token symbol (e.g. ETH, USDT). |
fiat_ccy |
str |
Fiat currency used for the market data. |
market_cap |
float |
Total market capitalization of the token. |
high_price |
float |
Highest price in the last 24 hours. |
low_price |
float |
Lowest price in the last 24 hours. |
pnl_24hr |
float |
Absolute price change over the last 24 hours. |
pct_change |
float |
Percentage price change (day-level). |
pct_change_1hr |
float |
Percentage price change over the last hour. |
pct_change_24hr |
float |
Percentage price change over the last 24 hours. |
get_transactions(refresh=False)
Retrieve the historical transactions for the logged-in account wallet across all chains in chains. Data is fetched from the Alchemy REST API using the alchemy_token provided during login and combines three transaction types into a single DataFrame: regular transactions (transaction), internal transactions (internal) and ERC-20 token transfers (ERC-20).
| Name | Type | Required | Description |
|---|---|---|---|
refresh |
bool |
No | When True, the full transaction history is refetched from Alchemy and the cache is replaced. When False (default), the cached DataFrame from the first call is returned. |
Returns pd.DataFrame, sorted by timestamp in descending order (newest first).
| Column | Type | Description |
|---|---|---|
timestamp |
datetime.datetime |
Block timestamp when the transaction was confirmed. |
trx_type |
str |
Type of transaction: transaction (regular EOA call), internal (contract-initiated transfer) or ERC-20 (token transfer). |
trx_hash |
str |
Unique transaction hash. Can be appended to https://etherscan.io/tx/ to inspect the transaction on Etherscan. |
from_address |
str |
Wallet address that initiated the transaction. |
to_address |
str |
Wallet address that received the transaction. |
movement |
str |
sent if the wallet has made the transaction, otherwise received. |
token_address |
str |
Token contract address. |
token_symbol |
str |
Token symbol (e.g. ETH, SNT, USDT). |
amount |
float |
Decimal-adjusted transaction amount. Negative when movement is sent, positive when received. |
is_error |
bool |
True if the transaction failed on-chain. |
chain_id |
int |
Chain ID where the transaction occurred. Matches values from chains. |
decimals |
int |
Number of decimals used to scale amount. Defaults to 18 for native-token transfers. |
trx_fee |
float |
Gas fee paid in the chain's native token, computed as gas_price * gas_used / 10**18. Populated only for sent rows; 0 for received rows since the receiver does not pay gas. |
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP",
"infura_token": "token from https://www.infura.io/",
"alchemy_token": "token from https://www.alchemy.com/",
"coingecko_api_key": "API key from https://www.coingecko.com/"
}
account.login(**params)
transactions = account.get_transactions()
print(transactions.head().to_markdown(index=False))
Force a fresh fetch (e.g. after sending a new transaction with send_transaction):
transactions = account.get_transactions(refresh=True)
send_transaction(address, symbol, amount, chain_id=1)
Send crypto from the logged-in account's wallet to another wallet address on the same chain. This method supports both ETH and ERC-20 tokens. The token can be identified either by its Status symbol (e.g. ETH, SNT, USDT) or by its contract address. Before broadcasting, the method validates that the token exists on the given chain and that the wallet holds enough balance for the requested amount.
| Name | Type | Required | Description |
|---|---|---|---|
address |
str |
Yes | The wallet address of the receiver. |
symbol |
str |
Yes | Either a valid Status token symbol from get_tokens or the token's contract address (must start with 0x). |
amount |
float |
Yes | The amount of the token to send. Must be less than or equal to the wallet's current balance for that token. |
chain_id |
int |
No | Chain ID where the transaction will be broadcast. Defaults to 1 (Ethereum mainnet). All available chain IDs can be obtained from the chains property. |
Returns str representing the transaction hash. The hash can be appended to https://etherscan.io/tx/ to monitor the transaction's progress. The transaction URL is also written to logger at INFO level. If the backend fails to broadcast and does not return a hash, None is returned instead.
Send ETH:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP",
"infura_token": "token from https://www.infura.io/",
"alchemy_token": "token from https://www.alchemy.com/",
"coingecko_api_key": "API key from https://www.coingecko.com/"
}
account.login(**params)
vitalik_address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
tx_hash = account.send_transaction(
address=vitalik_address,
symbol="ETH",
amount=0.01
)
print(f"Transaction: https://etherscan.io/tx/{tx_hash}")
Send an ERC-20 token by symbol:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP",
"infura_token": "token from https://www.infura.io/",
"alchemy_token": "token from https://www.alchemy.com/",
"coingecko_api_key": "API key from https://www.coingecko.com/"
}
account.login(**params)
vitalik_address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
tx_hash = account.send_transaction(
address=vitalik_address,
symbol="SNT",
amount=10
)
Send an ERC-20 token by contract address:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP",
"infura_token": "token from https://www.infura.io/",
"alchemy_token": "token from https://www.alchemy.com/",
"coingecko_api_key": "API key from https://www.coingecko.com/"
}
account.login(**params)
vitalik_address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
snt_address = "0x744d70fdbe2ba4cf95131626614a1763df805b9e"
tx_hash = account.send_transaction(
address=vitalik_address,
symbol=snt_address,
amount=10
)
Send on a different chain:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP",
"infura_token": "token from https://www.infura.io/",
"alchemy_token": "token from https://www.alchemy.com/",
"coingecko_api_key": "API key from https://www.coingecko.com/"
}
account.login(**params)
vitalik_address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
tx_hash = account.send_transaction(
address=vitalik_address,
symbol="ETH",
amount=0.01,
chain_id=10 # Optimism
)
Note: This is a wallet method, so it requires infura_token, alchemy_token and coingecko_api_key to all be provided in login. If any is missing, a WalletNotConfiguredError is raised when this method is called.
Note: The sender and receiver must be on the same chain. Cross-chain transfers are not supported by this method - set chain_id to the chain where the funds currently exist.
Note: An exception will be raised when:
- the
symbol(or contract address) does not exist on the givenchain_id - the token is not present in the logged-in wallet's balance
- the requested
amountexceeds the current wallet balance
swap_tokens(from_token, to_token, amount, chain_id=1)
Swap one token for another on a single chain. The swap happens on a single chain - both from_token and to_token must exist on the given chain_id. Cross-chain swaps are not supported. Swaps are submitted with a fixed slippage tolerance of 0.5%. Each token can be identified either by its Status symbol (e.g. ETH, SNT, USDT) or by its contract address. Before submitting, the method validates that from_token exists in the wallet's balance and that the wallet holds enough of it for the requested amount.
| Name | Type | Required | Description |
|---|---|---|---|
from_token |
str |
Yes | The token to swap from. Either a valid Status token symbol from get_tokens or the token's contract address (must start with 0x). |
to_token |
str |
Yes | The token to swap to. Either a valid Status token symbol from get_tokens or the token's contract address (must start with 0x). |
amount |
float |
Yes | The amount of from_token to swap. Must be less than or equal to the wallet's current balance for that token. |
chain_id |
int |
No | Chain ID where the swap will happen. Defaults to 1 (Ethereum mainnet). Both from_token and to_token must exist on this chain. All available chain IDs can be obtained from the chains property. |
Returns str representing the transaction hash. The hash can be appended to https://etherscan.io/tx/ to monitor the swap's progress. An exception will be raised when:
- either
from_tokenorto_tokenis not available on the givenchain_id(InvalidTokenError) - both
from_tokenandto_tokenare ERC-20 tokens, i.e. neither side isETH(InvalidTokenError) from_tokenis not present in the logged-in wallet's balance, or the requestedamountexceeds the current balance (InvalidTokenError)- the Status Backend cannot build a swap route or the swap transaction fails (
BackendError)
Swap ETH for an ERC-20 token:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP",
"infura_token": "token from https://www.infura.io/",
"alchemy_token": "token from https://www.alchemy.com/",
"coingecko_api_key": "API key from https://www.coingecko.com/"
}
account.login(**params)
tx_hash = account.swap_tokens(
from_token="ETH",
to_token="SNT",
amount=0.0001
)
print(f"Swap: https://etherscan.io/tx/{tx_hash}")
Swap ERC-20 for an ETH token:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP",
"infura_token": "token from https://www.infura.io/",
"alchemy_token": "token from https://www.alchemy.com/",
"coingecko_api_key": "API key from https://www.coingecko.com/"
}
account.login(**params)
tx_hash = account.swap_tokens(
from_token="USDC",
to_token="ETH",
amount=100
)
print(f"Swap: https://etherscan.io/tx/{tx_hash}")
Swap ERC-20 for an ERC-20 token:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP",
"infura_token": "token from https://www.infura.io/",
"alchemy_token": "token from https://www.alchemy.com/",
"coingecko_api_key": "API key from https://www.coingecko.com/"
}
account.login(**params)
tx_hash = account.swap_tokens(
from_token="USDC",
to_token="USDT",
amount=0.01
)
print(f"Swap: https://etherscan.io/tx/{tx_hash}")
Properties
available_accounts
Returns all Status accounts that are locally available in the initialized data directory. These accounts are detected when the Account class is initialized.
This property is useful when you want to:
- inspect which accounts exist locally
- retrieve a
key_uidfor login - display metadata about stored accounts
You will have to know the passwords for the given key_uid.
Returns list[dict], one entry per locally available account.
| Key | Type | Description |
|---|---|---|
name |
str |
The account's name. For accounts using an ENS 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 as key_uid. |
created_at |
datetime.datetime |
Timestamp when the account was created locally. |
from status_sdk import Account
# For terminal readability only
from rich import print as rprint
from rich.pretty import Pretty
account = Account()
rprint(Pretty(account.available_accounts))
info
Provides information about the currently logged-in account. If login() has not been called, accessing this property will raise an exception. Returns dict containing account metadata.
| Key | Type | Description |
|---|---|---|
public_key |
str |
Public key that uniquely identifies the account. |
url |
str |
The URL that can be shared with other users. |
emojis |
str |
Emoji hash associated with the account identity. |
key_uid |
str |
Internal Status key identifier for the account. |
compressed_key |
str |
The chat key as it is in Status App. |
mnemonic |
str |
Mnemonic phrase used to generate the account keys. |
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 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. |
installation_id |
str |
Id of this device's installation. Pass it to another device's sync to pair the two. None if the backend did not return one. |
logged_in_timestamp |
datetime.datetime |
Timestamp when the account successfully logged in. |
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
print(account.info)
display_name
Get or update the current display name of the logged‑in account.
Returns str when reading the property.
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# Get the current display name
print(account.display_name)
You can update the display name by assigning a new value:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# Change the display name
account.display_name = "status_bot_42"
print(account.display_name)
Note: Next time you login with the changed display name, you will have to put in the new display name, instead of the initial one.
bio
Get or update the bio of the currently logged‑in account. The length of the bio (as in Status App) is 240 characters.
Returns str when reading the property.
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# Read the current bio
print(account.bio)
The value assigned to bio will automatically be converted to a string before being sent to the backend. You can update the bio by assigning a new value:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# Update the bio
account.bio = "Monitoring Status communities and chats"
print(account.bio)
You can also clear the bio by deleting the property:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# Clears the bio - same as:
# account.bio = ""
# account.bio = None
del account.bio
profile_picture
Get or update the profile picture of the currently logged‑in account. The image is the same one shown on the user's profile in Status App.
Returns PIL.Image.Image when reading the property, or None if no profile picture has been set.
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# Read the current profile picture
image = account.profile_picture
if image:
image.show()
The file path assigned to profile_picture will be automatically set as the latest profile picture in Status App. If the given file does not exist or the extension is not supported, an exception will be raised. Supported image formats are .jpg, .jpeg and .png.
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# Update the profile picture
account.profile_picture = "./full_path/to/my_image.png"
account.profile_picture.show()
When a new profile picture is set, any previous image in the assets folder is removed. The image is also copied into the Status Backend Docker volume so it is picked up by the backend when updating the account identity.
status
Get or update the presence status of the currently logged‑in account. This is the same presence indicator shown next to the account in Status App, and it controls how the account appears to other users.
Returns str when reading the property - one of the options below. After a successful login, the status is automatically set to on.
The value is case‑insensitive and must be one of the following options:
| Option | Description |
|---|---|
on |
Always online. The account is shown as online to other users. This is the default after login. |
auto |
Automatic. Status App decides the presence automatically based on activity. |
dnd |
Do Not Disturb. The account is shown as do not disturb. This is experimental. |
off |
Inactive. The account is shown as offline / inactive to other users. |
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# Read the current status
print(account.status)
You can update the status by assigning a new value:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# Update the presence status
account.status = "off"
print(account.status)
Note: Assigning any value other than on, auto, dnd or off raises a custom exception. The comparison is case‑insensitive, so ON and on are equivalent.
signal
The property exists in Account because signals require an active logged‑in session. Attempting to use signals before calling login() will raise an exception. Signals are low‑level events emitted by the Status Backend.
The property exposes the following methods:
signal.get()- fetch a single event. If the event is not found, you may end up in an infinite loop.signal.listen()- stream events continuously. Example usage of this is found inlisten_messages()signal.connect()- open a persistent websocket connection that buffers every incoming signal in the background. Must be called beforeexpect().signal.disconnect()- tear down the persistent connection opened byconnect().signal.expect()- return a context manager that waits for one or more matching signals to arrive after you perform an action. This is the recommended way to make async message calls, since it removes the race conditions and infinite-loop risk ofget().
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
account.signal.connect()
with account.signal.expect("messages.new") as exp:
account.send_message(chat_id, "hello")
# Available only after the `with` block exits
print(exp.result)
account.signal.disconnect()
Note: Some signals arrive faster than others - the Status Backend does not emit every signal type at the same speed (for example, a local envelope.sent confirmation typically arrives well before a messages.new event that depends on network propagation). Tune the timeout per signal type, and use count when an action is expected to produce multiple signals, rather than assuming they all land at once or in a fixed order.
logger
Provides access to the internal Python logger for monitoring the lifecycle of the account and backend operations such as login, account creation, messenger startup, and recovery.
Returns logging.Logger.
Default logger configuration:
- Name:
status-bot - Level:
INFO - Output: standard output (terminal)
Example:
from status_sdk import Account
account = Account()
print("Starting Status bot")
account.logger.warning("This is a warning")
account.logger.error("Something went wrong")
Chat
contacts
This property returns contacts that have interacted with the account, including:
- active contacts.
- users who sent a contact request.
- users whose contact request was sent by the bot.
- contacts that were previously removed. If the contact is removed on both sides then it might disappear from the property.
The property always fetches the latest state directly from the Status Backend. The lifecycle is as follows:
none- no relationshipsent- request sent by this accountreceived- request received from another accountmutual- both users have added each other
Returns dict[str, dict] where the key is the contact's public key. This makes internal searching for account specific information faster. If you only have a contact's chat key or account URL, pass it through get_public_key to get the key used in this property.
| Key | Type | Description |
|---|---|---|
public_key |
str |
Public key that uniquely identifies the contact. |
url |
str |
The URL that can be shared with other users. |
chat_id |
str |
Chat identifier used for direct messaging. |
compressed_key |
str |
Internal compressed key identifier used by Status Backend. |
emojis |
str |
Emoji hash associated with the contact identity. |
contact_state |
str |
Current state of the contact relationship (none, mutual, sent, received, dismissed). |
external_contact_state |
str |
How the contact relationship appears from the other user's perspective. |
has_added_us |
bool |
Whether the other user has added this account as a contact. |
added |
bool |
Whether this account has added the other user as a contact. |
mutual |
bool |
Whether both users have added each other. |
display_name |
str |
The current display name of the contact. |
bio |
str |
The contact's profile bio. |
last_updated |
datetime.datetime |
Timestamp when the contact information was last updated. |
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
contacts = account.contacts
for contact in contacts.values():
print(contact["display_name"], contact["contact_state"])
communities
Get all communities that the account is currently a member of. This property always fetches the latest community state directly from the Status Backend, so dynamic values such as community metadata and member count are always up to date.
Each community contains information about:
- community metadata (name, tags)
- membership status
- number of members
- every channel in the community, with the account's permissions on it
Returns list[dict] where each element represents a community.
| Key | Type | Description |
|---|---|---|
id |
str |
Unique identifier of the community. |
url |
str |
The URL that can be shared with other users. |
name |
str |
Name of the community. |
verified |
bool |
Whether the community is verified. |
tags |
list[str] |
Tags associated with the community. |
is_member |
bool |
Whether the account is currently a member of the community. |
joined |
bool |
Whether the account has joined the community. |
joined_timestamp |
datetime.datetimeNone |
Timestamp when the account joined the community. None when the account has not joined. |
requested_timestamp |
datetime.datetimeNone |
Timestamp when the join request was submitted. None when no request was made. |
encrypted |
bool |
Whether the community messaging is encrypted. |
members |
int |
Total number of community members. |
channels |
list[dict] |
Every channel in the community. See channels below. |
channels
Each entry of channels describes one channel and what the account is allowed to do in it.
| Key | Type | Description |
|---|---|---|
id |
str |
The channel's own id, without the community id in front of it. |
chat_id |
str |
The community id and channel id joined together. This is the value to pass to send_message and get_messages - id on its own will not work. |
name |
str |
The channel name, as shown in Status App. |
description |
str |
The channel description. |
permissions |
dict |
What the account can do in the channel - see below. |
permissions holds four booleans:
| Key | Type | Description |
|---|---|---|
posting |
bool |
Whether the account can send messages to the channel. chats only lists channels where this is True. |
viewing |
bool |
Whether the account can read the channel. |
reactions |
bool |
Whether the account can post emoji reactions. |
token_gated |
bool |
Whether access to the channel is gated behind a token. |
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
for community in account.communities:
print(community["name"], community["members"])
Find every channel the account can post in, without going through chats:
for community in account.communities:
for channel in community["channels"]:
if not channel["permissions"]["posting"]:
continue
print(f"{community['name']} #{channel['name']}\t{channel['chat_id']}")
Note: To work with a community's channels, members and settings, wrap its id in the Community class - for example Community(account, community["id"]). communities is a read-only snapshot: it lists the channels but cannot create, edit or delete them.
Note: joined currently returns the same value as verified, because communities reads community["verified"] for both. Use is_member to check membership until that is fixed.
chats
Get all chats that the account can send messages to. This includes:
contacts- direct messages with userscommunities- community channels where the account has posting permission- Group chats that the account is in
Returns list[dict] where each dict represents a chat that can be used with send_message and get_messages.
| Key | Type | Description |
|---|---|---|
type |
str |
Type of chat (contact, channel or group_chat). |
id |
str |
Chat identifier used when sending messages. |
name |
str |
Either the display name of the user or the community channel name. |
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP"
}
account.login(**params)
# This is under the assumption you already have a contact / joined a community
for chat in account.chats:
print(f"{chat['type']}\t{chat['name']}\t{chat['id']}")
Wallet
chains
Retrieve all production blockchain networks available in Status Backend. This property returns a mapping between chain_id and the corresponding chain name.
Returns dict[int, str].
| Key | Type | Description |
|---|---|---|
chain_id |
int |
Unique identifier of the blockchain network. |
chain_name |
str |
Human-readable name of the chain (e.g. Ethereum, Optimism). |
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP",
"infura_token": "token from https://www.infura.io/",
"alchemy_token": "token from https://www.alchemy.com/",
"coingecko_api_key": "API key from https://www.coingecko.com/"
}
account.login(**params)
print(account.chains)
balance
Retrieve the current non-zero balances token balances for the logged-in account wallet across all supported chains.
Returns pd.DataFrame.
| Column | Type | Description |
|---|---|---|
timestamp |
datetime.datetime |
Timestamp when the balance was fetched. |
address |
str |
Token contract address. |
chain_id |
int |
Chain ID where the token exists. |
amount |
float |
Token balance (adjusted using token decimals). |
symbol |
str |
Token symbol (e.g. ETH, USDT). |
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP",
"infura_token": "token from https://www.infura.io/",
"alchemy_token": "token from https://www.alchemy.com/",
"coingecko_api_key": "API key from https://www.coingecko.com/"
}
account.login(**params)
print(account.balance)
You can convert the current balance into fiat currency by using a ISO 4217 currency code in the [] accessor:
from status_sdk import Account
account = Account()
params = {
"name": "status-app-bot",
"password": "SNTPUMP",
"infura_token": "token from https://www.infura.io/",
"alchemy_token": "token from https://www.alchemy.com/",
"coingecko_api_key": "API key from https://www.coingecko.com/"
}
account.login(**params)
print(account["GBP"])










