Skip to content

mcjkula/taolk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

τalk

End-to-end encrypted messaging for Bittensor.

codecov

InstallGetting startedTUICLISDKSecurity


Built on SAMP (Substrate Account Messaging Protocol). Terminal UI, CLI, and embeddable Rust SDK.

Install

brew install mcjkula/tap/taolk

Or with Cargo: cargo install taolk

Or from source: git clone https://github.com/mcjkula/taolk.git && cd taolk && cargo install --path .

Linux requires libasound2-dev (Debian/Ubuntu), alsa-lib (Arch), or alsa-lib-devel (Fedora).

Getting started

1. Create a wallet

taolk wallet create --name <name>

The name identifies this wallet on the lock screen. Write down the 12-word recovery phrase before confirming.

2. Fund your account

taolk prints your address after creation. Each message is an on-chain transaction, so you need a small balance for fees. Transfer τ from an exchange or testnet faucet.

3. Launch

taolk --wallet <name> --mirror https://bittensor-finney.samp.ink

--wallet selects which wallet to unlock. --mirror connects to a SAMP mirror for channel discovery and message history. Both are optional.

4. Verify your setup

Press m, paste your own address, pick public, type something. If it appears in your inbox, the full pipeline works.

5. Start messaging

Press n to start a thread with someone. Press c to browse public channels.

TUI

Press ? for the keybind reference. Press / to open the command palette.

Context Keys
Timeline i compose, n thread, m message, c channels, g group, / commands, ? help, q quit
Composer Enter send, Shift+Enter newline, Esc save draft and leave
Confirm Enter submit transaction, Esc back to edit
Global Ctrl+L lock, Ctrl+W switch wallet, Ctrl+C quit

Messaging

  • Threads: encrypted 1:1 conversations (Ristretto255 ECDH + ChaCha20-Poly1305)
  • Channels: public, named, discoverable
  • Groups: encrypted multi-party, fixed membership
  • One-off messages: public or encrypted, standalone

All messages are signed remarks on-chain with a verifiable sender.

Commands

Commands available via /:

Command What it does
thread Start a new 1:1 thread
message Send a standalone one-off message
group Create a group conversation
search Search messages in current view
channels Browse the channel directory
inbox Jump to inbox
outbox Jump to sent
sidebar Toggle sidebar
help Show help overlay
get Get remark(s) at block:index positions
refresh Reload and fill message gaps
copy Copy a sender's address
unlock Unlock locked outbound messages
lock Lock the session
wallet Switch wallet
quit Exit

CLI

taolk wallet create --name <name> [--password <pw>]
taolk wallet import --name <name> --mnemonic "word1 word2 ..."
taolk wallet import --name <name> --seed <64-hex-chars>
taolk wallet list
taolk db clear [--wallet <name>]
taolk config get [<key>]
taolk config set <key> <value>
taolk config unset <key>

SDK

Use taolk as a library. No terminal dependencies.

[dependencies]
taolk = { path = ".", default-features = false }
use taolk::{session::Session, event::Event, wallet};

#[tokio::main]
async fn main() -> taolk::error::Result<()> {
    let seed = wallet::open("agent", "password")?;
    let (session, mut events) = Session::start(
        seed.as_bytes(), "wss://entrypoint-finney.opentensor.ai:443", "agent", true,
    ).await?;

    while let Some(event) = events.recv().await {
        match event {
            Event::NewMessage { decrypted_body: Some(body), sender, .. } => {
                println!("{}: {body}", taolk::util::ss58_short(&sender));
            }
            _ => {}
        }
    }
    Ok(())
}

Configuration

~/.config/taolk/config.toml (XDG on Linux, ~/Library/Application Support/ on macOS).

Key Default Description
wallet.default Wallet to open on launch
network.node wss://entrypoint-finney.opentensor.ai:443 Subtensor node URL
network.mirrors SAMP mirror URLs
security.lock_timeout 300 Auto-lock seconds (0 = disabled)
security.require_password_per_send false Prompt password for every transaction
ui.sidebar_width 28 Sidebar width
ui.mouse true Mouse support
ui.timestamp_format %H:%M Message time format
ui.date_format %Y-%m-%d %H:%M Full date format

Mirrors

Mirrors index SAMP remarks and serve them over HTTP for channel discovery and message history. Mirrors never see decrypted content. taolk verifies all data against the chain.

taolk config set network.mirrors https://bittensor-finney.samp.ink
Network URL
Mainnet https://bittensor-finney.samp.ink
Testnet https://bittensor-testnet.samp.ink

Run your own with mirror-template.

Security

Wallet files: Argon2id (64 MB, 3 iterations) + ChaCha20-Poly1305. Stored with 0600 permissions.

Secret types (Seed, Password, Phrase, SigningKey): no Clone, no Debug, no Display. All wrap Zeroizing and are zeroed on drop. When require_password_per_send is enabled, the signing key is not stored in memory. It exists only between password entry and transaction submission.

On the wire: 1:1 and group messages use ECDH on Ristretto255 with ChaCha20-Poly1305 AEAD. Channels are plaintext by design. The private key never leaves the client.

Trade-offs

  • Key reuse. sr25519 signing and Ristretto255 ECDH share the same scalar.
  • No post-quantum resistance. Ristretto255 is broken by Shor.
  • No forward secrecy. Seed compromise decrypts all past 1:1/thread messages.

Building

cargo build --release                        # TUI + CLI
cargo check --no-default-features --lib      # SDK only
cargo test                                   # 374 tests

License

MIT. See LICENSE.

About

Encrypted messaging client for Bittensor - TUI, CLI, and embeddable Rust SDK.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages