Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7e2f666
Docs: agents read docs.sidepit.com as Markdown; deposit address verif…
jaybny Oct 27, 2026
411074f
TUI: wallet shows today's P&L and one contract; identity screen can b…
jaybny Oct 27, 2026
97c58c1
CI: install proof on Linux, Windows, macOS Intel and Apple Silicon
jaybny Oct 28, 2026
cf60bbd
wallet: pure-Python RIPEMD-160 fallback, drop ripemd-hash
jaybny Oct 29, 2026
2464c6d
CI: stock-machine check — fail when any dependency would compile
jaybny Oct 29, 2026
dfee9e3
tests: key entropy is the OS CSPRNG only; signing is deterministic
jaybny Oct 29, 2026
c74f56a
sidepit 0.1.2: bundled secp256k1 wheels for Windows and Intel macOS
jaybny Oct 29, 2026
d75b4be
CI: build bundled wheels, prove the install on every platform, gate p…
jaybny Oct 29, 2026
fe19ba8
agent key: Windows has no POSIX mode bits, verify the file by content…
jaybny Oct 29, 2026
2f2d3f7
tests: signing nonce stays RFC 6979
jaybny Oct 29, 2026
6379bcd
Merge branch 'tui-0.1.2' into ci-install-proof
jaybny Oct 29, 2026
49dfb83
trader: poll ACTIVE_PRODUCT without a ticker so the roll is seen afte…
jaybny Sep 23, 2026
a1caa7c
TUI: start on the live market with no identity; add one later
jaybny Oct 29, 2026
f0e950b
docs: one-line install per platform, WSL2 path for Windows
jaybny Oct 29, 2026
10d3258
keep the BIP39 wordlist byte-exact on Windows checkouts
jaybny Oct 29, 2026
b6d39f3
CI: read the version without tomllib so the Python 3.10 legs run
jaybny Oct 29, 2026
4db18ab
tests: POSIX file-mode checks skip on Windows; read sources as UTF-8
jaybny Oct 29, 2026
e862829
Merge branch 'docs-agent-reading' into ci-install-proof
jaybny Oct 29, 2026
02943bd
cockpit: BUY/SELL buttons, visible shortcuts, closed-market guard, pl…
jaybny Oct 29, 2026
70bd2b1
cockpit: compact BUY/SELL row, shorter hint, 1000-contract cap per order
jaybny Oct 29, 2026
678beaa
cockpit: no command palette; quantity box takes up to 999
jaybny Oct 29, 2026
0444344
cockpit: BUY/SELL buttons, visible shortcuts, closed-market guard, pl…
jaybny Oct 30, 2026
2bb0aa2
docs: first-timer install steps per OS; WSL2 recommended on Windows; …
jaybny Oct 30, 2026
d0ce66f
cockpit: identity backup screen — words and WIF hidden until shown, o…
jaybny Oct 30, 2026
a089c0e
cockpit: copy id button in the top bar; FUND and backup copy the full…
jaybny Oct 30, 2026
99c990e
cockpit: click the top bar or session panel to copy the id; tighter t…
jaybny Oct 30, 2026
1fdfa16
cockpit: show the full account id in the top bar and session panel
jaybny Oct 30, 2026
879d2a2
cockpit: identity backup screen, full account id, copy id
jaybny Oct 30, 2026
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
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# byte-exact data: the SDK verifies this file by SHA-256 at runtime, so git must
# never convert its line endings on a Windows checkout
python-client/sidepit_trader/data/bip39_english.txt binary
154 changes: 154 additions & 0 deletions .github/workflows/install-proof.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
name: Install proof

# Clean-machine proof: build every release artifact once, then `pip install
# sidepit` into a fresh venv on every OS/Python a user might have, pulling
# dependencies from PyPI exactly as a user would. Every leg runs even when
# another fails, so one run shows the whole platform picture. publish.yml
# calls this workflow and refuses to upload unless it is all green.

on:
workflow_dispatch:
workflow_call:
pull_request:
paths:
- ".github/workflows/install-proof.yml"
- "pyproject.toml"
- "setup.py"
- "MANIFEST.in"
- "tools/**"

permissions:
contents: read

env:
# build tools are pinned: the same inputs produce the release every time
BUILD_TOOLS: build==1.6.1 setuptools==80.10.2 wheel==0.48.0 cffi==2.1.1

jobs:
build:
name: pure wheel + sdist
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.12"
- name: Build
run: |
python -m pip install $BUILD_TOOLS
python -m build --no-isolation
python tools/check_python_dist.py dist/*
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: dist-pure
path: dist/
if-no-files-found: error

native:
# Platforms where upstream secp256k1 publishes no wheel get the compiled
# module inside sidepit's own platform wheel (setup.py, SIDEPIT_BUNDLE_SECP256K1).
# Built against the stable ABI on 3.10: one wheel per platform serves 3.10+.
name: bundled wheel (${{ matrix.os }})
strategy:
fail-fast: false
matrix:
os: [windows-latest, macos-15-intel]
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.10"
- name: Fetch the pinned upstream secp256k1 source
run: |
python -m pip install $BUILD_TOOLS
python tools/vendor_secp256k1.py
- name: Build
env:
SIDEPIT_BUNDLE_SECP256K1: "1"
run: |
python -m build --wheel --no-isolation
python tools/check_python_dist.py dist/*.whl
ls -l dist
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: dist-native-${{ matrix.os }}
path: dist/
if-no-files-found: error

install:
name: pip install (${{ matrix.os }}, ${{ matrix.python-version }})
needs: [build, native]
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-15-intel, macos-latest]
python-version: ["3.10", "3.12", "3.13"]
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
pattern: dist-*
path: dist
merge-multiple: true
- name: Fresh venv
run: |
python -m venv "$RUNNER_TEMP/clean"
if [ -d "$RUNNER_TEMP/clean/bin" ]; then
echo "$RUNNER_TEMP/clean/bin" >> "$GITHUB_PATH"
else
echo "$RUNNER_TEMP/clean/Scripts" >> "$GITHUB_PATH"
fi
- name: Describe the machine and the release artifacts
run: |
python -m pip install --quiet --upgrade pip
python -c "import platform, sys; print(platform.platform(), platform.machine(), sys.version)"
python -m pip --version
ls -l dist
python -c "import re; print('VERSION=' + re.search(r'^version = \"([^\"]+)\"', open('pyproject.toml').read(), re.M).group(1))" >> "$GITHUB_ENV"
- name: Stock-machine check — every dependency must come as a prebuilt wheel
# The runner has compilers; a user's machine may not. This resolves the
# whole dependency tree with building forbidden, so anything that would
# compile on a stock machine shows up here even though the real install
# below would succeed on the runner.
id: stock
continue-on-error: true
run: "python -m pip install --dry-run --only-binary=:all: --find-links dist sidepit==$VERSION"
- name: pip install sidepit (release artifacts + dependencies from PyPI, as a user would)
run: python -m pip install --find-links dist "sidepit==$VERSION"
- name: Show what was installed and how
if: always()
run: |
python -m pip list
python -c "import secp256k1, sidepit_trader; print('secp256k1 from', secp256k1.__file__)"
- name: Smoke-test the installed package outside the checkout
working-directory: ${{ runner.temp }}
env:
SIDEPIT_TESTNET: "true"
SIDEPIT_DEPOSIT_ADDRESS: bc1ql3e9pgs3mmwuwrh95fecme0s0qtn2880lsvsd5
SIDEPIT_KEYS_DIR: ${{ runner.temp }}/sidepit-empty-keys
SIDEPIT_STATE_DB: ${{ runner.temp }}/sidepit-empty-state.db
SIDEPIT_HOST: localhost
run: |
sidepit --help
sidepit list
python "$GITHUB_WORKSPACE/tools/smoke_installed_sidepit.py"
- name: Offline test suite against the installed package
run: |
python -m pip install pytest
python -m pytest -q python-client/tests
- name: Verdict — would this have worked on a stock machine?
if: steps.stock.outcome == 'failure'
run: |
echo "::error::a dependency has no prebuilt wheel for this platform; a user without build tools cannot pip install sidepit here"
exit 1
56 changes: 21 additions & 35 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
name: Publish Python package

# Release artifacts come from CI only, never from a developer machine. A tag
# push runs the full install proof (pure wheel + bundled platform wheels,
# pip-installed on Linux, Windows, macOS Intel and Apple Silicon); nothing is
# uploaded unless every leg is green. Upload goes through PyPI Trusted
# Publishing behind the `pypi` environment approval.

on:
push:
tags: ["v*"]
Expand All @@ -15,17 +21,13 @@ permissions:
contents: read

jobs:
build:
check-tag:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.12"
cache: pip
cache-dependency-path: pyproject.toml
- name: Install build tools and test dependencies
run: python -m pip install . build pytest twine
- name: Verify tag matches package version
if: github.event_name == 'push'
run: |
Expand All @@ -36,57 +38,41 @@ jobs:
if tag != f"v{version}":
raise SystemExit(f"tag {tag!r} does not match package version {version!r}")
PY
- name: Test and build
run: |
python -m pytest -q python-client/tests
python -m build
python -m twine check --strict dist/*
python tools/check_python_dist.py dist/*
python -m pip install --force-reinstall --no-deps dist/*.whl
- name: Smoke-test release wheel outside checkout
working-directory: ${{ runner.temp }}
env:
SIDEPIT_TESTNET: "true"
SIDEPIT_DEPOSIT_ADDRESS: bc1ql3e9pgs3mmwuwrh95fecme0s0qtn2880lsvsd5
SIDEPIT_KEYS_DIR: ${{ runner.temp }}/sidepit-empty-keys
SIDEPIT_STATE_DB: ${{ runner.temp }}/sidepit-empty-state.db
SIDEPIT_HOST: localhost
run: |
sidepit --help
sidepit list
python "$GITHUB_WORKSPACE/tools/smoke_installed_sidepit.py"
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: python-package
path: dist/
if-no-files-found: error

proof:
needs: check-tag
uses: ./.github/workflows/install-proof.yml

publish-testpypi:
if: github.event_name == 'workflow_dispatch'
needs: build
needs: proof
runs-on: ubuntu-latest
environment: testpypi
permissions:
id-token: write
steps:
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: python-package
pattern: dist-*
path: dist
- uses: pypa/gh-action-pypi-publish@release/v1
merge-multiple: true
- run: ls -l dist
- uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
with:
repository-url: https://test.pypi.org/legacy/

publish-pypi:
if: github.event_name == 'push'
needs: build
needs: proof
runs-on: ubuntu-latest
environment: pypi
permissions:
id-token: write
steps:
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: python-package
pattern: dist-*
path: dist
- uses: pypa/gh-action-pypi-publish@release/v1
merge-multiple: true
- run: ls -l dist
- uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
.env
/build/
/dist/
/dist-native/
3 changes: 3 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
**The contract lives in [`Public-API-Data`](Public-API-Data/)** — its README has
the basic facts and every port; `sidepit_api.proto` is every message, exactly as
production speaks it. This file adds the working recipes and trading facts.
The user docs are machine-readable: fetch <https://docs.sidepit.com/llms.txt>
for the index and the linked Markdown pages (any page URL plus `.md`), or
<https://docs.sidepit.com/llms-full.txt> for all of it. Do not scrape the HTML.

Sidepit is a Bitcoin-margined forwards exchange — you are using Bitcoin to
trade USD. Orders match in one-second deterministic auctions (DLOB): the best
Expand Down
14 changes: 10 additions & 4 deletions DISTRIBUTION.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
# Sidepit distribution record

Status: **v0.1.0 is live on PyPI** as `sidepit`. **v0.1.1 is the release
candidate**: the cockpit TUI no longer triggers whole-order-book snapshot
broadcasts (12129) to refresh its open-orders view; open orders come from the
account's POSITIONS reply. No SDK API changes.
Status: **v0.1.1 is live on PyPI** as `sidepit`. **v0.1.2 is in preparation**
on the `ci-install-proof` branch: `pip install sidepit` works on Linux, macOS
(Apple Silicon and Intel) and Windows with nothing to compile — upstream
`secp256k1` wheels where they exist, sidepit's own platform wheels with
libsecp256k1 compiled in (stable ABI, one per platform) on Windows and Intel
macOS; `ripemd-hash` dropped for a pure-Python fallback. Every release now
passes the four-platform install proof (`.github/workflows/install-proof.yml`)
before it can be uploaded, and release artifacts come from CI only. The cockpit
starts keyless on the live market; identities are added from the doors or
ctrl+a.

This file records the distribution decisions made for the public client. It is
the durable boundary between what works today and what is deliberately next.
Expand Down
2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
include tools/vendor_secp256k1.py
include tools/secp256k1_ffi.py
71 changes: 62 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,73 @@ sending straight to the lock address does not identify the intended account.

## Claude + Sidepit: two terminals

Install the cockpit and SDK from anywhere, then clone the skills:
**Step 1 — install the cockpit.** Python 3.10 or newer. Nothing compiles: every piece arrives as a prebuilt
wheel on Linux, macOS (Apple Silicon and Intel) and Windows. Pick your machine
and follow the steps top to bottom.

**Windows — recommended: WSL2 (Ubuntu inside Windows)**

1. Start menu → type `PowerShell` → *Run as administrator*. In it:
```powershell
wsl --install
```
(Windows 10 2004+ or Windows 11.)
2. Reboot when asked. Ubuntu opens by itself and asks for a username and a
password — pick any; this is your Linux user, not your Windows login.
3. In that Ubuntu window:
```sh
sudo apt update && sudo apt install -y pipx
pipx install sidepit
pipx ensurepath
```
4. Close the Ubuntu window, open it again (Start menu → *Ubuntu*), run:
```sh
sidepit
```
You get the Linux cockpit, and Claude Code runs beside it in the same terminal.

**Windows — native, no WSL2**

1. Start menu → `PowerShell`. In it:
```powershell
winget install Python.Python.3.12
```
(Or python.org's installer with *Add python.exe to PATH* ticked.)
2. Open a **new** terminal — the old one does not see Python yet.
3. ```powershell
python -m pip install sidepit
sidepit
```
Windows Terminal renders the cockpit best. Keys live in `%USERPROFILE%\.sidepit\keys`.

**macOS (Apple Silicon or Intel)**

1. Install Python from <https://www.python.org/downloads/> (the `.pkg`
installer). No Xcode tools, no Homebrew needed.
2. Open a **new** Terminal window (Applications → Utilities → Terminal):
```sh
pip3 install sidepit
sidepit
```
Already on Homebrew? `brew install pipx && pipx install sidepit && pipx ensurepath`,
then reopen Terminal.

**Linux (Ubuntu / Debian)**

```sh
pip install sidepit
git clone --recurse-submodules https://github.com/sidepit/Public-API
sudo apt update && sudo apt install -y pipx
pipx install sidepit
pipx ensurepath
```
Reopen the terminal, run `sidepit`. Other distros: `pip install sidepit` inside a venv.

First run opens on the live market with no identity. Create, import or watch
one from the doors, or press Escape to just look and add a key later with ctrl+a.

Prefer an isolated app install? Use `pipx install sidepit`. If your system
requires a virtual environment:
**Step 2 — clone the skills** (Claude reads them; the cockpit does not need them):

```sh
python3 -m venv .venv
source .venv/bin/activate
pip install sidepit
git clone --recurse-submodules https://github.com/sidepit/Public-API
```

Terminal one — the cockpit:
Expand All @@ -92,7 +145,7 @@ Tell Claude:

**Claude | Sidepit | make money!** Your key, your sizing, your risk, your call.

Using Sidepit as a Python SDK? The same installation gives your code:
Using Sidepit as a Python SDK? `pip install sidepit` in your project's venv gives your code:

```python
from sidepit_trader import RequestClient, Signer, Submitter
Expand Down
Loading
Loading