Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

element-bot

Rust rewrite of s3krit/society.py, a Matrix/Element bot for Kusama Society status.

Behavior

The bot supports the original command set:

  • !ping
  • !defender
  • !info <address>
  • !candidates [address]
  • !head
  • !set_address <address>
  • !unset_address
  • !me
  • !period
  • !countdown
  • !skeptics
  • !skeptic

It also polls the Kusama candidate period every 60 seconds and announces period transitions to the configured Matrix room. It subscribes to chain blocks and announces bid and unbid events to the configured Matrix room.

Configuration

Copy .env.example to .env and fill in the Matrix bot settings.

cargo run

To point the bot at local Chopsticks without editing .env, pass:

cargo dev

To send one sample Matrix message to the configured room and exit:

cargo run -- --sample

Required:

  • MATRIX_ROOM: Matrix room ID (for example !room:matrix.org) or room alias (for example #room:matrix.org).
  • MATRIX_TOKEN: access token for the bot account.

Optional:

  • MATRIX_HOMESERVER: defaults to https://matrix.org.
  • MATRIX_USER_ID: defaults to @societybot:matrix.org, but you should set this explicitly to the bot account that owns MATRIX_TOKEN.
  • RPC_URL: defaults to wss://kusama-rpc.polkadot.io/.
  • DB_PATH: defaults to ./society_overrides.db.
  • PREFIX: defaults to !.
  • RUST_LOG: tracing filter, for example info or element_bot=debug.

Production deployment

The bot runs on a single DigitalOcean droplet via Docker Compose. Images are built in CI and pushed to GHCR on every merge to main.

See deploy/README.md for droplet bootstrap, firewall, updates, and backups.

After CI publishes a new image, run cargo deploy (requires DEPLOY_HOST=root@your-droplet-ip in .env).

Manual Testing

Use this when you want to validate the bot against a real Matrix homeserver and live Kusama data instead of the Docker e2e harness.

Prerequisites:

  • Rust installed locally.
  • A Matrix bot account.
  • An access token for that bot account.
  • The bot account's Matrix user ID, such as @societybot:matrix.org.
  • A dedicated Matrix test room.
  • The bot account invited to that room and already joined.
  • Outbound network access to the Matrix homeserver and RPC_URL.
  • A writable path for DB_PATH.

Setup:

  1. Copy .env.example to .env.
  2. Create a dedicated Matrix room for testing. A private room is safer because some commands write persistent address overrides.
  3. Invite the bot account to the room and confirm it has joined.
  4. Fill in at least these values in .env:
    • MATRIX_ROOM with the room ID or alias for the test room
    • MATRIX_TOKEN with the bot access token
    • MATRIX_USER_ID with the exact user ID for that token
    • MATRIX_HOMESERVER if you are not using https://matrix.org
  5. Start the bot:
cargo run
  1. Confirm startup succeeds and the bot begins syncing instead of failing with Matrix auth, room resolution, or RPC connection errors.

Suggested manual checks from another Matrix account in the test room:

  • !ping
  • !head
  • !period
  • !defender
  • !skeptics
  • !candidates
  • !info <known-kusama-address>
  • !set_address <known-member-address>
  • !me
  • !unset_address

Expected results:

  • The bot replies in the configured room.
  • Read-only commands return live Kusama-backed data.
  • !set_address stores the Matrix handle override and !me uses it.
  • After restarting the bot, the override is still present if you kept the same DB_PATH.

Notes:

  • !info and !set_address are easiest to verify with a known Kusama Society member address.
  • Period transition announcements are only emitted when the live candidate period changes while the bot is running, so that behavior is not practical to fully verify on demand.
  • Manual-test output changes over time because it depends on live chain state.

Development

cargo fmt --check
cargo check
cargo test

Coverage

Rust does not have a standard-library coverage reporter. Use cargo-llvm-cov, which wraps Rust/LLVM source-based coverage:

cargo install cargo-llvm-cov
./scripts/coverage.sh

Reports are written to:

  • target/coverage/html/index.html
  • target/coverage/lcov.info

Docker E2E

The Docker e2e harness starts Chopsticks, a mock Matrix homeserver, the bot, and an assertion runner. It exercises Matrix command handling, live Kusama state reads through Chopsticks, and SQLite address overrides:

docker compose -f tests/e2e/docker-compose.yml up --build --abort-on-container-exit --exit-code-from e2e

The default checked-in Chopsticks config is tests/e2e/kusama.yml, copied from ../kappasigmamu.github.io/config/kusama.yml. That file targets Asset Hub.

To run that copied config locally with a pinned fork block and instant block building:

cargo chopsticks

To use a different fork block:

KUSAMA_BLOCK_NUMBER=<block-number> cargo chopsticks --clean

Chopsticks writes fetched storage and produced blocks to db.sqlite. cargo chopsticks resumes from that DB by default because it is the fastest local restart path.

To force a fresh local state:

cargo chopsticks --clean

Use --custom with either command to enable the custom runtime WASM override.

Run the bot against local Chopsticks:

cargo dev

Custom Society runtime

The repo includes custom-kusama-runtime as a submodule on branch customized-society-pallet. It shortens Society rotation periods for local testing.

Initialize the submodule once:

git submodule update --init --recursive

Run Chopsticks with the custom runtime WASM override:

cargo chopsticks --custom

If ./custom-kusama-runtime.wasm is missing, this builds relay/kusama inside the submodule and copies the WASM blob to the repo root (first build can take several minutes).

Or start Chopsticks and the bot together:

cargo dev --custom

This builds the WASM when needed, starts Chopsticks with wasm-override: ./custom-kusama-runtime.wasm, waits for ws://127.0.0.1:8000, then runs the bot in dev mode.

Submit a local bid or unbid:

cargo society:bid
cargo society:unbid

The bot should log observed bid/unbid events and send exactly one Matrix message per event, keyed by block hash and event index. If the bot restarts, in-memory dedupe resets and a previously announced event could be announced again.

  • **New bid** (block X) with the bidder and amount in KSM
  • **Withdrawn bid** (block X) with the account

If Chopsticks logs Method not found: transactionWatch_v1_submitAndWatch, the caller is using an unsupported transaction-watch RPC. The local submit_bid and unbid helpers avoid that path and submit through the legacy-compatible extrinsic RPC.

Export and seed

Export a room's full Matrix history, then seed society_overrides.db from that export.

1. Export — paginates room history and writes JSONL plus media:

cargo export --output ./exports/kappasigmamulounge

Defaults to #kappasigmamulounge:parity.io when --room is omitted. Override with --room or set MATRIX_HOMESERVER for non-matrix.org homeservers.

Output:

  • events.jsonl — one JSON object per event (sender, timestamp, body, media URLs)
  • metadata.json — export summary
  • media/ — downloaded attachments (images, files, video, audio)

Use --links-only to skip media downloads. Use --all-events to include membership/state events.

Retry only missing media from a previous export:

cargo export --retry-failed --output ./exports/kappasigmamulounge

2. Seed — replays !set_address, !unset_address, and bot !me responses from events.jsonl into the override database:

cargo seed --input ./exports/kappasigmamulounge --dry-run
cargo seed --input ./exports/kappasigmamulounge --db-path ./society_overrides.db

cargo seed reads the export on disk only; it does not call Matrix. It defaults to @societybot:matrix.org for matching bot messages in the export. --input defaults to ./room-export.

Requires a Matrix token and room access for cargo export only.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages