Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

All notable changes to `status-python-sdk` will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.2.3] - 2026-10-10

### Fixed

- Updated outdated documentation

### Changed

- Split `models.py` into separate files

## [1.2.2] - 2026-10-08

### Added
Expand Down Expand Up @@ -219,6 +229,7 @@ will try to log in without a hashed password
- Launch [status-go] Docker container with Python instead of manual `docker compose up -d` setup.
- Custom library errors

[1.2.3]: https://github.com/status-im/status-python-sdk/releases/tag/1.2.3
[1.2.2]: https://github.com/status-im/status-python-sdk/releases/tag/1.2.2
[1.2.1]: https://github.com/status-im/status-python-sdk/releases/tag/1.2.1
[1.2.0]: https://github.com/status-im/status-python-sdk/releases/tag/1.2.0
Expand Down
63 changes: 34 additions & 29 deletions docs/account.md

Large diffs are not rendered by default.

28 changes: 12 additions & 16 deletions docs/community.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ As of now `Community` works with already created Status App communities. To get
- **By invite URL** - pass a shared community `url`.


If the account is already a member, the community is ready to use. Otherwise a **join request is sent** and the instance is left unusable until an administrator accepts it (see [Joining a community](./community.md#joining-a-community)).
If the account is already a member, the community is ready to use. Otherwise a **join request is sent** and the instance is left unusable until an administrator accepts it.

Only members can read a community's state, and only privileged members (owner / admin / token master) can [ban](./community.md#banpublic_keys-delete_messagesfalse), [accept](./community.md#acceptpending_request_id) or manage channels.

Expand Down Expand Up @@ -55,7 +55,7 @@ Create a `Community` instance bound to a **logged-in** [`Account`](./account.md)
|-----|-----|-----|-------------|
| `account` | `Account` | Yes | A **logged-in** [`Account`](./account.md). If the account is not logged in, a custom exception is raised. |
| `community_id` | `str` | No* | The id of a community the account is **already a member of**. Community ids can be obtained from [`communities`](./account.md#communities) on `Account`. |
| `url` | `str` | No* | A shared community invite URL. Used to join the community if the account is not already a member. See [Joining a community](./community.md#joining-a-community). |
| `url` | `str` | No* | A shared community invite URL. Used to join the community if the account is not already a member. See [Membership](./community.md#membership). |
| `data_folder` | `str` | No | The folder on **your machine** that [`launch_docker_container`](./utils.md#launch_docker_containercommitnone-wait_seconds5-platformlinuxamd64-data_foldernone) mounts into Status Backend. That is the only place the account data written by Status Backend lives, so a different folder cannot be reached. The path is resolved to its `data` subfolder, so `"status-backend-data"` and `"status-backend-data/data"` are equivalent. This property is only needed when the **same account is logged into Status App**, created a community there, and you want [`status-im/status-go`](https://github.com/status-im/status-go) (Status Backend) to take over as its [control node](./community.md#control-node) - it is where [`upload_control_node`](./community.md#upload_control_nodefolder) writes the uploaded account data. Leave it unset for every other use. |


Expand Down Expand Up @@ -534,24 +534,20 @@ community.delete_channel("announcements")

Listen for join requests to the community **in real time**.

Returns a `Generator` that yields one `models.CommunityRequest` **dataclass** per request event, so the fields are reached as attributes (`request.state`) rather than dictionary keys:
Returns a `Generator` that yields one `models.CommunityRequest` **dataclass** per request event, so the fields are reached as attributes (`request.pending`) rather than dictionary keys:

| Attribute | Type | Description |
|----|----|-------------|
| `id` | `str` | The join request id. Pass this to [`accept`](./community.md#acceptpending_request_id) or [`decline`](./community.md#declinepending_request_id). |
| `state` | `str` | The state the request moved into - see the table below. |
| `public_key` | `str` | Public key of the requesting member. |
| `pending` | `bool` | The request is waiting to be [accepted](./community.md#acceptpending_request_id) or [declined](./community.md#declinepending_request_id). |
| `reject` | `bool` | The request was declined. |
| `accept` | `bool` | The request was accepted and the member joined. |
| `cancel` | `bool` | The request was cancelled. |

**Request states**
The state is carried by **four booleans** rather than one string, and **exactly one of them is `True`** on any yielded request - the one matching the state the request just moved into. The rest stay `False`.

| Code | State | Description |
|-----|-----|-------------|
| `1` | `pending` | The request is waiting to be [accepted](./community.md#acceptpending_request_id) or [declined](./community.md#declinepending_request_id). |
| `2` | `reject` | The request was declined. |
| `3` | `accept` | The request was accepted and the member joined. |
| `4` | `cancel` | The request was cancelled. |

Events belonging to **other communities**, and requests whose state is not one of the four above, are skipped - so everything yielded is a request for this community.
Events belonging to **other communities**, and requests whose state code is not one of the four above, are skipped - so everything yielded is a request for this community.

```python
from status_sdk import Account, Community
Expand All @@ -568,9 +564,9 @@ community = Community(account, url=url)

# Auto-accept everyone who asks to join
for request in community.listen_requests():
print(f"{request.public_key}\t{request.state}")
print(f"{request.public_key}\tpending={request.pending}")

if request.state != "pending":
if not request.pending:
continue

community.accept(request.id)
Expand Down Expand Up @@ -1309,7 +1305,7 @@ Relay a message that came from **another messaging platform** - Discord, Telegra
| `reply_to_message_id` | `str` | No | The **other platform's** id of the message being replied to - *not* a Status message id, unlike in [`send_message`](./community.md#send_messagemessage-reply_to_message_idnone) and [`send_image`](./community.md#send_imagefile_paths-messagenone-reply_to_message_idnone). It threads correctly only when the message it points at was itself relayed with that same value as its `message_id`. |
| `image_url` | `str` | No | URL of the author's avatar on the other platform. Defaults to no avatar. |

Returns `str` - the `id` of the message **in Status App**, delegated from [`send_bridged_message`](./account.md#send_bridged_messagechat_id-message-namenone-usernamenone-user_idnone-message_idnone-reply_to_message_idnone-image_urlnone) on `Account`. This is a different value from the `message_id` you passed in, and it can be used with [`delete_message`](./community.md#delete_messageid) like any other sent message. Returns `None` when [`can_post`](./community.md#can_post) is `False` - nothing is relayed and no error is raised.
Returns `str` - the `id` of the message **in Status App**, delegated from [`send_bridged_message`](./account.md#send_bridged_messagechat_id-message-namenone-usernamenone-user_idnone-message_idnone-reply_to_message_idnone-image_urlnone) on `Account`. This is a different value from the `message_id` you passed in, and it can be used with [`delete_message`](./community.md#delete_messageid) like any other sent message. When the account is not allowed to post in the channel, a custom exception is raised carrying the backend's message - the call is **not** silently skipped.

```python
from status_sdk import Account, Community
Expand Down
2 changes: 1 addition & 1 deletion docs/group-chat.md
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ for message in messages:
print(f"{message['timestamp']}\t{message['text']}")
```

**Note**: This is the group chat equivalent of [`delete_message`](./account.md#delete_messagemessage_id) on `Account`. The only difference is that it first verifies the group chat exists - a custom exception is raised if the chat has not been created or joined.
**Note**: This is the group chat equivalent of [`delete_message`](./account.md#delete_messageid) on `Account`. The only difference is that it first verifies the group chat exists - a custom exception is raised if the chat has not been created or joined.

### `add(public_keys)`

Expand Down
32 changes: 23 additions & 9 deletions docs/utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,29 @@ The image is always rebuilt (`docker compose up --build`) so a newly chosen `com

| Name | Type | Required | Description |
|-----|-----|-----|-------------|
| `commit` | `str` | No | The `status-im/status-go` git ref to build from - a commit SHA, branch, or tag. When omitted, the latest `develop` branch is built. |
| `commit` | `str` | No | The `status-im/status-go` git ref to build from - a commit SHA, branch, or tag. When omitted, the newest commit is **resolved to a full SHA** before the build starts - see [Resolving the commit](./utils.md#resolving-the-commit). |
| `wait_seconds` | `int` | No | Number of seconds to pause after the `docker compose up` command returns, giving Status Backend enough time to finish booting before subsequent code runs. Defaults to `5`. This matters mainly when the container already exists and is being restarted, because `docker compose up` returns immediately while the backend is still warming up - instantiating [`Account`](./account.md#accountdomainlocalhost-backend_port8080-media_port9000-is_securefalse-backup_foldernone-volume_foldernone-show_logstrue) too quickly will fail to connect. On [Windows](./utils.md#windows) the same value is used to wait between retries after WSL has been restarted. |
| `platform` | `str` | No | The platform the image is built for. Defaults to `linux/amd64`. Run `docker buildx ls` to see the platforms your Docker installation supports, and pass the matching value if the default does not build on your machine. |
| `data_folder` | `str` | No | The folder on **your machine** where Status Backend keeps the accounts it creates. If you are a **[Community Control Node](./community.md#control-node)** you will need to create a Docker container with a volume folder, and pass that **same** folder to [`Community`](./community.md#communityaccount-community_idnone-urlnone-data_foldernone) so [`upload_control_node`](./community.md#upload_control_nodefolder) can reach it. |

#### Resolving the commit

When no `commit` is given, the repository is read out of the `context` in `docker-compose.yaml` and its newest commit is looked up through the **GitHub API**, so `STATUS_GO_COMMIT` is always a concrete 40-character SHA rather than a branch name. The resolved value is logged:

```
2026-10-09 13:39:48 [INFO] status_sdk.utils.external: status-im/status-go SHA: f89efa62503f4969b8b78a19f7ccf98ef08d4bf5
```

This way:

- The build is reproducible.
- The version is stamped into the image.

Wait time after container has launched:
```python
from status_sdk import launch_docker_container

# Build from the latest develop branch
# Resolves the newest commit, then builds it
launch_docker_container(wait_seconds=10)
```

Expand Down Expand Up @@ -104,24 +117,26 @@ Build `status-backend` **natively** from a local clone of [`status-im/status-go`
|---|---|---|
| Needs | Docker (and WSL on Windows) | Nix and `git` |
| Windows | Supported | **Not supported** - use Docker, or run from inside WSL |
| Backend runs as | A container | A process on your machine |
| Stopping it | `docker compose down` | Terminate the returned process |
| Backend runs as | A container | A child process of your script |
| Stopping it | `docker compose down` | `Ctrl+C`, or `pkill -f status-backend` |

The build runs inside the repository's **Nix dev shell**, so the Go toolchain and every build dependency come from Nix rather than your system - nothing has to be installed by hand beyond Nix itself.

| Name | Type | Required | Description |
|-----|-----|-----|-------------|
| `commit` | `str` | No | The `status-im/status-go` git commit SHA,. When omitted, the latest `develop` branch is built. |
| `commit` | `str` | No | The `status-im/status-go` git ref to build - a commit SHA, branch, or tag. When omitted, the latest `develop` branch is built. |
| `repo_dir` | `str` | No | Local folder to clone `status-go` into, and reuse on later calls. Defaults to a `status-go` folder next to this package's installation. When the folder does not already hold a clone, the repository is fetched from GitHub. |
| `address` | `str` | No | The `host:port` to run `status-backend` on. Defaults to `localhost:8080`, which matches the defaults of [`Account`](./account.md#accountdomainlocalhost-backend_port8080-media_port9000-is_securefalse-backup_foldernone-volume_foldernone-show_logstrue). If you change it, pass the matching `domain` and `backend_port` when creating the `Account`. |
| `wait_seconds` | `int` | No | How long to poll the backend's `/health` endpoint before giving up, in seconds. Defaults to `30`. **The build itself is not subject to this timeout** - only the startup that follows it. |
| `install_deps` | `bool` | No | Whether to run `make status-go-deps` before building. This also runs `go clean -cache` and `go clean -modcache`, which throws away every cached Go build on your machine and makes the next build much slower. Only needed on a first build or after a Go toolchain upgrade. |

Returns `None` - the function waits until the backend answers on `/health` and then hands control back, leaving it running in the background. A custom exception is raised when Nix or `git` are missing, when you are on Windows, when any git or build step fails, when the binary is missing after the build, or when the backend does not become reachable within `wait_seconds`.

```python
from status_sdk import build_and_launch, Account

# First run clones status-go and builds it - this takes a while
process = build_and_launch()
build_and_launch()

account = Account()
params = {
Expand All @@ -131,9 +146,6 @@ params = {
account.login(**params)

print(account.info["public_key"])

# Stop the backend when you are done
process.terminate()
```

Build a specific ref into a folder of your choosing:
Expand All @@ -156,6 +168,8 @@ build_and_launch(address="localhost:9500", wait_seconds=60)
account = Account(backend_port=9500)
```

A backend left over from an earlier run is **reused rather than replaced**: the next call sees `/health` already answering, logs `status-backend is already running on <address>. Skipping launch.` and returns without building anything. That is convenient during development, but it also means you can be talking to an older build than the `commit` you just asked for - stop the old process first when the build matters.

### `download_build_and_launch(launcher=None, repo_name="status-im/status-go", tag=None, token=None, address="localhost:8080", wait_seconds=30)`

Download a prebuilt `status-backend` bundle from a GitHub release, extract it and launch it. This is an **alternative to [`build_and_launch`](./utils.md#build_and_launchcommitnone-repo_dirnone-addresslocalhost8080-wait_seconds30-install_depstrue)** for setups that do not want to build [`status-im/status-go`](https://github.com/status-im/status-go) from source - no Nix or Go toolchain is needed.
Expand Down
4 changes: 2 additions & 2 deletions examples/agents/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Each tool is a thin wrapper around the [Python SDK](../../README.md). They are d
| `get_balance` | [`balance`](../../docs/account.md#balance) | Read the account's wallet balance, optionally enriched with market data. |
| `get_account_info` | [`info`](../../docs/account.md#info) | Read public account details. `password` and `mnemonic` are **excluded**. |
| `get_account_contacts` | [`contacts`](../../docs/account.md#contacts) | List contacts, contact requests and group chats. |
| `manage_contact` | [`add_contact`](../../docs/account.md#add_contactpublic_key-display_namenone) / `remove_contact` | Accept, send, decline and remove contact requests. |
| `manage_contact` | [`add_contact`](../../docs/account.md#add_contactpublic_key-request_idnone-display_namenone) / `remove_contact` | Accept, send, decline and remove contact requests. |
| `get_token_info` | [`get_tokens`](../../docs/account.md#get_tokens) | Look up chains, token symbols and token addresses. |
| `search_external_balance` | [`get_balance`](../../docs/account.md#get_balancetoken_addresses-chain_ids1-walletsnone-ccynone) | Read the balance of **any** wallet address, not just the account's. |
| `search_messages` | [`get_messages`](../../docs/account.md#get_messageschat_id-start_timestampnone-end_timestampnone) | Read chat history for a date range, including payment requests. |
Expand Down Expand Up @@ -92,7 +92,7 @@ cd examples/agents
python main.py
```

On the first run, [`launch_docker_container`](../../docs/utils.md#launch_docker_container) builds the Status Backend image, which takes a few minutes. The account is then recovered from `MNEMONIC` and the bot starts listening:
On the first run, [`launch_docker_container`](../../docs/utils.md#launch_docker_containercommitnone-wait_seconds5-platformlinuxamd64-data_foldernone) builds the Status Backend image, which takes a few minutes. The account is then recovered from `MNEMONIC` and the bot starts listening:

```
[INFO] Running Docker on <your-os-here>
Expand Down
2 changes: 1 addition & 1 deletion examples/community-greet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ cp env.example .env
| `PASSWORD` | The password of the greeting Status account. |
| `NAME` | The [display name](../../docs/account.md#display-name) or ENS name of the account. If you have previously logged in with the SDK you can provide an ENS. For first time log ins, it is best to provide a [display name](../../docs/account.md#display-name). |
| `MNEMONIC` | The [recovery phrase](https://status.app/help/profile/understand-your-status-keys-and-recovery-phrase) of the account. Used to recover it into the container. |
| `COMMUNITY_URL` | The invite [`url`](../../docs/community.md#url) of the community to greet in. If the account is not a member yet, constructing the [`Community`](../../docs/community.md#communityaccount-community_idnone-urlnone) sends a join request instead - see [Membership](../../docs/community.md#membership). |
| `COMMUNITY_URL` | The invite [`url`](../../docs/community.md#url) of the community to greet in. If the account is not a member yet, constructing the [`Community`](../../docs/community.md#communityaccount-community_idnone-urlnone-data_foldernone) sends a join request instead - see [Membership](../../docs/community.md#membership). |
| `MODEL_NAME` | The Ollama model used for the greeting, e.g. `llama3.2`. |

### 4. Run
Expand Down
2 changes: 1 addition & 1 deletion examples/group-chat-moderator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ cd examples/group-chat-moderator
python main.py
```

On the first run, [`launch_docker_container`](../../docs/utils.md#launch_docker_container) builds the Status Backend image, which takes a few minutes. Tthe bot starts listening:
On the first run, [`launch_docker_container`](../../docs/utils.md#launch_docker_containercommitnone-wait_seconds5-platformlinuxamd64-data_foldernone) builds the Status Backend image, which takes a few minutes. Tthe bot starts listening:

```
[INFO] Successfully logged in!
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "status-sdk"
version = "1.2.2"
version = "1.2.3"
description = "Private chat. Communities. Multi-chain wallet. Browser. dApps all in one app, powered by SNT."
readme = "README.md"
requires-python = ">=3.11"
Expand Down Expand Up @@ -54,7 +54,7 @@ Issues = "https://github.com/status-im/status-python-sdk/issues"
"Status Backend" = "https://github.com/status-im/status-go"

[tool.setuptools]
packages = ["status_sdk", "status_sdk.community", "status_sdk.utils"]
packages = ["status_sdk", "status_sdk.community", "status_sdk.utils", "status_sdk.models"]

[tool.setuptools.package-data]
status_sdk = ["docker-compose.yaml"]
Expand Down
2 changes: 2 additions & 0 deletions status_sdk/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .community import CommunityRequest, TokenPermission
from .message import ContactRequest, PaymentRequest, BridgedContent, Message
Loading
Loading