Skip to content
ewanc26Public

About

A C/C++ SDK for the AT Protocol: a client-side, wire-level implementation, not a port of the upstream service backends.

Topics

Resources

Contributing

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Latest commit

 

History

1,060 Commits

Folders and files

Repository files navigation

Wolfram

CI Latest release Licence Sponsor

Wolfram

A C/C++ SDK for the AT Protocol: a client-side, wire-level implementation, not a port of the upstream service backends.

Not affiliated with Wolfram Alpha. Despite the name, this project is an independent AT Protocol SDK and has no connection to, or endorsement from, Wolfram Alpha, Wolfram Research, Mathematica, or Stephen Wolfram.

The runtime library and all generated client code are pure C23. The optional Lexicon generator is a development-time C++ tool (tools/wf_lexgen.cpp, built as the wf_lexgen_tool CMake target) and is never linked into, embedded in, or required by applications using libwolfram.

C is the default language; C++ is used for complex or sensitive components where C is insufficient — RAII-based resource management (e.g. cJSON in syntax and json), performance-critical code, and third-party library integrations. All C++ code exposes a C ABI via extern "C" so the SDK never requires a C++ toolchain at runtime. See the policy in AGENTS.md.

Core Features

  • XRPC client with bearer authentication, DPoP-bound OAuth, and binary blob upload
  • Current AT Protocol lexicon snapshot: 402 documents and 319 query/procedure definitions; JSON calls are generated and binary procedures use the dedicated upload/import APIs
  • Streaming subscriptions: subscribeRepos (firehose), subscribeLabels, and subscribeRepos with cursor reconnect/backoff
  • Identity: DID resolution (did:plc, did:web), handle DNS TXT resolution, PLC operations
  • Repo: DAG-CBOR encoding/decoding, CAR import/export, MST, signed v3 commits, record CRUD, diff verify/apply
  • Agent: high-level wf_agent_* wrappers for com.atproto.*, app.bsky.*, chat.bsky.*, tools.ozone.*, and app.bsky.graph write operations
  • OAuth: discovery, PKCE S256, ES256 DPoP, PAR, callback validation, token refresh/revoke, and resource-server token verification
  • Moderation: offline decision engine (blur/alert/inform/filter) from labels, blocks, mutes, muted words, hidden posts
  • Validation: runtime lexicon validation, JSON canonicalize/validate, rich-text facets
  • Optional SQLite persistence (WOLFRAM_BUILD_STORE) with at-rest encryption via libsodium (WOLFRAM_BUILD_STORE_CRYPTO)
  • Optional libmicrohttpd-backed XRPC server (WOLFRAM_BUILD_SERVER) with buffered JSON procedures, bounded-memory binary procedures, SSE streaming, WebSocket subscriptions, and relay forwarding

Documentation

Per-module usage guides (runnable C snippets):

Topic guides:

Quick start

cmake -S . -B build && cmake --build build && ctest --test-dir build

That builds ./build/wolf, the CLI, which is the quickest way to check the SDK end to end:

./build/wolf post https://bsky.social you@example.com yourpassword "Hello from wolfram!"
./build/wolf help post

See docs/cli.md for the full command reference. The examples/ programs referenced elsewhere in the docs are a separate set of small, single-purpose binaries built only with -DWOLFRAM_BUILD_EXAMPLES=ON.

wolfram is organized into small, layered modules — transport → identity → repo → agent. See docs/modules.md for the full status table.

Build and test

cmake -S . -B build && cmake --build build && ctest --test-dir build --output-on-failure

The default desktop configure requires libcurl and OpenSSL, fetches pinned cJSON/libcbor sources, and builds examples and tests. A clean configure may require network access even when tests themselves are offline.

On macOS the WebSocket tests (relay_server, sync_publish_server, chat_modevents_sub) depend on which libcurl is linked. Apple's own libcurl exports the WebSocket API but was built without it, so wf_websocket_supported() asks it with a probe connect, finds ws unsupported, and the tests take their degraded path and say why in their output. With Homebrew's libcurl they run in full. CI runs both on macOS, and both are part of CI gate.

Releases

Wolfram is a source library, so a release is a version bump, an annotated tag and a GitHub release whose notes are that version's section of CHANGELOG.md, with the source tarball and its SHA-256 attached. It takes two steps and a pull request:

tools/release.sh prepare --consumers-verified minor   # 0.26.0 -> 0.27.0 on release/v0.27.0
tools/release.sh prepare --dry-run minor              # run the checks, print the notes, change nothing
# open a PR from release/v0.27.0, rebase-merge it once CI is green, then:
tools/release.sh publish 0.27.0

prepare refuses to run unless it is on main with a clean tree identical to origin/main, and without --consumers-verified: I only release once MetalBear, Cobalt, Indigo and Platinum have been built against the change, and the script cannot check that for me. It runs the default build and tests (--full adds the server, store, store-crypto and C++ configuration), bumps the version in project() in CMakeLists.txt, moves the Unreleased changelog section into a dated one, and pushes the branch. Nothing goes to main directly. publish creates the release at the commit that carries the version only if its CI gate check is green, and never re-tags an existing version. The release workflow runs it after a merged release PR. The rest of the working flow is in docs/flow.md.

Cross-compilation Support

Cross-compilation targets for Nintendo platforms and other architectures are supported:

Wii

A cross-compilation target for the Nintendo Wii (devkitPPC/libogc) is supported. The Wii build is client-only — server modules, OAuth flows, and desktop dependencies (libcurl, OpenSSL, pthreads) are excluded.

cmake -S . -B build-wii \
  -DCMAKE_TOOLCHAIN_FILE=.devdeps/wii.cmake \
  -DWOLFRAM_BUILD_WII=ON \
  -DCMAKE_BUILD_TYPE=Debug
cmake --build build-wii

Requires devkitPro with devkitPPC and libogc installed. The toolchain file is at .devdeps/wii.cmake.

Wii U

A cross-compilation target for the Nintendo Wii U (devkitPPC/wut) is supported.

cmake -S . -B build-wiiu \
  -DCMAKE_TOOLCHAIN_FILE=.devdeps/wiiu.cmake \
  -DWOLFRAM_BUILD_WIIU=ON \
  -DCMAKE_BUILD_TYPE=Debug
cmake --build build-wiiu

Requires devkitPro with devkitPPC and the wut SDK installed. The toolchain file is at .devdeps/wiiu.cmake.

The Wii U is the one console target that can also build the XRPC server, using the bundled libmicrohttpd shim (src/server/mhd_shim.c) in place of a library that has no console port. devkitPro packages no SQLite, so point the build at the amalgamation:

cmake -S . -B build-wiiu \
  -DCMAKE_TOOLCHAIN_FILE=.devdeps/wiiu.cmake \
  -DWOLFRAM_BUILD_WIIU=ON \
  -DWOLFRAM_BUILD_SERVER=ON \
  -DWOLFRAM_SQLITE_AMALGAMATION=/path/to/sqlite-amalgamation
cmake --build build-wiiu

The Wii U build is theoretically compatible: it compiles and links, and it has never been run on hardware. Everything it depends on cross-compiles — secp256k1, SQLite, mbedTLS (including server-side TLS), curl — and the shim is exercised by the full test suite natively, where -DWOLFRAM_MHD_SHIM=ON substitutes it for the real library on any platform. That is evidence the code is portable and honours MHD's contract. It is not evidence that it boots, and a clean cross-compile says nothing about a runtime that has never executed a single instruction of it. Treat it as a starting point for someone with a console, not as a supported target.

3DS

A cross-compilation target for the Nintendo 3DS (devkitARM/libctru) is supported.

cmake -S . -B build-3ds \
  -DCMAKE_TOOLCHAIN_FILE=.devdeps/3ds.cmake \
  -DWOLFRAM_BUILD_3DS=ON \
  -DCMAKE_BUILD_TYPE=Debug
cmake --build build-3ds

Requires devkitPro with devkitARM and libctru installed. The toolchain file is at .devdeps/3ds.cmake.

Crypto on the consoles

No console ships OpenSSL, so all three console targets compile src/crypto/crypto_wii.c (mbedTLS, via devkitPro's 3DS/Wii portlibs) instead of src/crypto/crypto.c, and src/platform/openssl_compat.c supplies the handful of OpenSSL entry points that survive (SHA256, base64). P-256 signing, verification and did:key derivation all work, and the console and desktop backends interoperate in both directions: a signature made by one verifies under the other. This is emulator-verified on 3DS, and the DER ECDSA-Sig-Value parser agrees with the OpenSSL backend on every input tested, including the malformed ones — wf_crypto_ecdsa_der_to_raw holds the same DER minimality rule OpenSSL does so the two cannot drift.

The console crypto surface is otherwise complete, and this is worth checking when adding to crypto.h, because a function missing from crypto_wii.c does not fail the console build — it produces a link error in the application instead, long after the library looks healthy:

# every function declared in a public header must be defined in the archive
nm build-3ds/libwolfram.a | grep -E '^[0-9a-f]+ T ' | awk '{print $3}' | sort -u > /tmp/have.txt
grep -ohE '\bwf_[a-z0-9_]+\(' include/wolfram/*.h | tr -d '(' | sort -u > /tmp/want.txt
comm -23 /tmp/want.txt /tmp/have.txt

Expect the XRPC server, blob store, filesystem store, OAuth client and the other consoles' entropy hooks in that list; they are excluded on purpose (CMakeLists.txt, WOLFRAM_BUILD_EMBEDDED). Anything in crypto.h should not be.

Windows

A cross-compilation target for Windows (MinGW-w64) is supported.

cmake -S . -B build-windows \
  -DCMAKE_TOOLCHAIN_FILE=.devdeps/windows.cmake \
  -DWOLFRAM_BUILD_WINDOWS=ON \
  -DCMAKE_BUILD_TYPE=Debug
cmake --build build-windows

Requires MinGW-w64. The toolchain file is at .devdeps/windows.cmake.

Linux (ARM64)

A cross-compilation target for Linux on AArch64 is supported (e.g. from x86_64 macOS/Linux to ARM64 Linux).

cmake -S . -B build-aarch64 \
  -DCMAKE_TOOLCHAIN_FILE=.devdeps/linux-aarch64.cmake \
  -DCMAKE_BUILD_TYPE=Release
cmake --build build-aarch64

The toolchain file is at .devdeps/linux-aarch64.cmake. Toolchains for additional architectures (arm32.cmake, amd64.cmake) are also provided under .devdeps/.

The Wii platform implements libogc networking, LWP mutexes, monotonic timing, mbedTLS HTTPS with CA validation, P-256/did:key crypto, and secp256k1 (did:key) crypto via mbedTLS. It requires a unique externally provisioned entropy seed through wf_wii_set_entropy_seed. Wii WebSocket support remains an honest stub. The 3DS platform now has real libctru primitives (LightLock mutex, osGetTime clock, httpc transport) and mbedtls-based P-256/did:key crypto. The Windows target is fully implemented against the Win32 API.

The Wii and 3DS builds are client-only: server modules, OAuth flows, and the desktop dependencies (libcurl, OpenSSL, pthreads) are excluded. The Wii U can build the server as well — see above — but only as far as compiling, which is not the same as working.

Contributing

See CONTRIBUTING.md.

Support

If you find this project useful, consider supporting its development:

Ko-fi GitHub Sponsors

License

GNU AGPL-3.0. Running a modified Wolfram as part of a public network service obliges you to offer its users the corresponding source.

Star History

Star History Chart

Classic Mac OS 9 transport

Wolfram includes a standalone Classic Mac OS 9 XRPC transport for consumers such as Platinum. It uses Open Transport for TCP and the external macTLS async stream for TLS 1.3 with TLS 1.2 fallback. The transport does not use libcurl, OpenSSL, pthreads, or modern POSIX networking APIs.

Build the transport with:

cmake -S . -B build-macos9-transport \
  -DWOLFRAM_BUILD_MACOS9_TRANSPORT=ON \
  -DWOLFRAM_MACTLS_ROOT=/path/to/macTLS
cmake --build build-macos9-transport --target wolfram-macos9-transport
ctest --test-dir build-macos9-transport -R macos9_transport

The transport exposes the same low-level XRPC request semantics as every other Wolfram backend, including bearer authentication, one automatic refresh-and-retry on an expired token, DPoP nonce capture, bounded response buffering, and Content-Length/chunked HTTP responses. Every response path is bounded by wf_xrpc_client_set_max_response_bytes(), so a hostile or broken server cannot stream an unbounded body into memory. The Mac OS 9 adapter yields through an application callback so a cooperative event loop can continue servicing the UI.

Most applications should use the ordinary <wolfram/xrpc.h> API and leave the transport alone. <wolfram/macos9_tls.h> is public only because a client has to install a yield callback so a request can be pumped without freezing its UI.

The transport is written to strict C89 for CodeWarrior, and CMake enforces that rather than only documenting it: the target compiles as -std=c90 with -Wdeclaration-after-statement, -Wstrict-prototypes and -Wvla, and CI recompiles both sources with -std=c89 -pedantic-errors. It also has no cJSON dependency, because cJSON is C99 and would not compile under those settings; the XRPC error envelope is decoded by a small bounded scanner instead.

Two things this does not give you, both by design:

  • It is not a full libwolfram Mac OS 9 port. That needs a dedicated Classic Mac OS 9 crypto backend for OAuth/DPoP signing and verification, which is not in scope. Clients that authenticate through an external bridge (Platinum does) need no local signing and can use this transport as-is.
  • CI compiles and tests it on Linux against macTLS's public header, which carries plain-C fallback typedefs. That verifies the C89 dialect and the transport's own logic, but it is not a native CodeWarrior build or a real Mac OS 9 runtime test.

About

A C/C++ SDK for the AT Protocol: a client-side, wire-level implementation, not a port of the upstream service backends.

Topics

Resources

Contributing

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages