Gunnar

nordisk/monetize

Cargo.toml

[workspace]
resolver = "2"
members = [
    "crates/monetize",           # core: Plan, Entitlement, the ladder, the TRANSACTION, the ledger. No vendor code.
    "crates/monetize-pay",       # the Payment trait (ten ops) + the factory seam + the open vendors (invoice, sandbox), each a feature; klarna/stripe/swish are in the private monetize-impl
    "crates/monetize-cloud",     # Cloud trait + the factory seam + the open clouds (server — the box's own iron, in default; sandbox), each a feature; upcloud/scaleway are in the private monetize-impl
    "crates/monetize-product",   # Product plugin trait: how a product reports usage and receives entitlement
    "crates/monetize-product-guest", # what a product GUEST compiles against: the op table, the wire, the host doors, export_product!
    "crates/monetize-product-wasm",  # the guest host: one ProductFactory per signed .wasm, loaded through edda's guest-host
    "crates/monetize-pay-guest",     # what a payment VENDOR guest compiles against: the vendor op table, the wire, VendorGuest, export_vendor!
    "crates/monetize-cloud-guest",   # what a cloud GUEST compiles against: the cloud op table, the wire, CloudGuest, export_cloud! (the product guest's doors, reused)
    "crates/monetize-cloud-wasm",    # the cloud guest host: one CloudFactory per signed .wasm named in `[clouds.<name>] guest = …`, spend-capped on the host
    "crates/monetize-signup-guest",  # what a SIGNUP guest compiles against: the sink that creates the paying customer's account (ops 300..), SignupGuest, export_signup!
    "crates/monetize-dns-guest",     # what a DNS GUEST compiles against: the DNS writer's doors (ops 400..), DnsGuest, export_dns! — the provider (Cloudflare) is a signed plugin, never linked
    "crates/monetize-proto",     # the gRPC contract between monetize-server, monetize-embed and the UI
    "crates/monetize-site-buy",  # the buy flow a product SITE relays to the ONE monetize, behind one provider trait (BuySite): Gunnar and Holger, only their pages differ
    "crates/monetize-guardian",  # the estate guardian's shared runner (5.4): order queue, reports, cases, auto-fix, the fence invariant; monetize never calls into an estate
    "crates/monetize-embed",     # the thin client a PRODUCT compiles in: entitlement cache, offline, nanoseconds
    "crates/monetize-estate-side", # the estate side of the wire every product shares (P4a): the box pump (Fleet) and the front's SoldEstate client
    "crates/monetize-server",    # the service (skidbladnir): gRPC, vendor webhooks, license authority
    "crates/monetize-front",     # the ONE monetize's intake, the attach mint and the ledger backup (a member since T14, A28 M1)
    "crates/monetize-shop-pairing", # the shop pairs a sold estate itself over nordisk-pairing (a member since T14)
    "crates/monetize-cli",       # `monetize`, the operator's command line at the ONE box's door (a member since T14)
    "crates/fast-edge",          # the fast test's TLS door in front of the ONE box container (a member since T14)
    "crates/estate-svg",         # the estate, drawn: ONE renderer, shared with gunnar's console (nordisk-estate-svg; zero dependencies)
    "crates/monetize-mail",      # the ONE mail path: an SMTP submission relay, TLS always (the welcome mail, the nonpay and renewal notices)
    "crates/monetize-ui-server", # the BFF for the operator console (same shape as gunnar-ui-server)
    "crates/monetize-ui-web",    # the operator console, Leptos 0.8 csr (same stack as gunnar-ui-web)
    "crates/lake-product",       # the LAKE (v2.0 P1, grown from A17's echo): the prototype product for testing monetize, parametric and pulled, each call printed; `cargo xtask bench lake` lays it on the ONE box's real code and writes a receipt
    "crates/mock-upcloud",       # the UpCloud API 1.3, faithfully wrong: the fake provider the upcloud plugin is driven against. Open, and HERE rather than in gunnar, because monetize-cloud owns the seam it fakes; see its Cargo.toml for the full argument.
    "crates/mock-scaleway",      # the Scaleway Instance API v1, faithfully wrong: the fake the scaleway cloud guest is driven against; mock-upcloud's container engine behind it
    "guests/toy",                # the toy guest the guest host's tests load (cdylib for wasm32; never shipped)
    "guests/toy-vendor",         # the toy payment VENDOR guest the vendor host's tests load (never shipped)
    "guests/toy-cloud",          # the toy CLOUD guest the cloud guest host's tests load: pool ledger in host state, a host wait
    "guests/toy-dns",            # the toy DNS guest the DNS guest host's tests load: its records to a test's fake API, the token presented by the host
    "guests/lake",               # the LAKE's guest (v2.0 P1): no grants, its plan from the buyer's numbers, its own roles, no twin; the guest `cargo xtask bench lake` lays
    "guests/toy-signup",         # the toy SIGNUP guest the signup guest host's tests load: the account and the delivered fact in host state
    # (the gunnar guest lives in the gunnar repository since 2026-09-25: crates/gunnar-monetize-guest)
    # (the holger guest lives in the holger repository since 2026-09-27: crates/holger-monetize-guest;
    #  its live and real-module tests went with products/holger in v2.0 P2; the signed module is
    #  tested in monetize-server's the_signed_holger_guest_* tests)
    "uitest",                    # the console's browser-level matrix + the mock monetize it runs against (see uitest/Cargo.toml)
    # (xtask is a DETACHED workspace since 2026-10-23, `xtask/Cargo.toml`: its nornir-xtask-support
    #  reaches rustls on aws-lc-rs, which as a member unified into the server's ring. The alias in
    #  .cargo/config.toml runs it by manifest path.)
    # (Five workspaces stay DETACHED, each with its own lock, and xtask/tests/detached_locks.rs
    #  says why: xtask, crates/monetize-fast, crates/monetize-build-thing,
    #  crates/mock-upcloud/kvm-guest and crates/monetize-admin. A28 M1, T14.)
]

[workspace.package]
authors = ["Rickard Ernst Björn Lundin <rickard@ignalina.dk>", "Vetra Automation AB", "Ignalina ApS"]
version = "0.3.0"
edition = "2021"
rust-version = "1.85"
repository = "https://git.gunnar.rs/nordisk/monetize"
license = "AGPL-3.0-only"
publish = false

[workspace.dependencies]
# Same wire stack as gunnar and gunnar-ui (tonic/prost 0.14, leptos 0.8, axum 0.8).
# TLS: `tls-ring` (rustls over ring) and `tls-webpki-roots` (the compiled-in
# Mozilla root set). rustls and NOT native-tls because the law is pure Rust —
# native-tls is openssl on Linux — and `ring` and `webpki-roots` because BOTH
# are already in this lock via reqwest's `rustls-tls`, so the whole capability
# costs no new package. `tls-native-roots` would add `rustls-native-certs` and
# would make verification depend on whatever trust store the box happens to
# hold; a compiled-in root set is the same on every box, and a private CA is
# named per block (`[products.<id>] tls_ca`) rather than installed system-wide.
tonic = { version = "0.14", features = ["transport", "codegen", "tls-ring", "tls-webpki-roots"] }
tonic-prost = "0.14"
tonic-prost-build = "0.14"
prost = "0.14"
prost-types = "0.14"
protox = "0.9"
axum = { version = "0.8", features = ["json", "query"] }
leptos = { version = "0.8", features = ["csr"] }
leptos_router = "0.8"
tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "time"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
anyhow = "1"
thiserror = "2"
redb = "2"
ed25519-dalek = { version = "3", features = ["rand_core"] }
rand = "0.10"
# Every service in the suite goes through skidbladnir (systemd/initrc units, install/uninstall).
#
# A crates.io VERSION since 2026-09-09, not `path = "../Skidbladnir"`. Cargo reads a
# path dependency's manifest at RESOLVE time, so that spelling made a Skidbladnir
# checkout a hard requirement of `cargo metadata` on this WHOLE workspace — a fresh
# clone of monetize did not resolve, and the error named a directory that has nothing
# to do with this repository. 0.1.16 is the version this tree was already building.
skidbladnir = { version = "0.2.3", default-features = false }

[profile.release]
lto = true
codegen-units = 1

# Line tables only: enough for a panic backtrace to name the line, without the
# full DWARF that makes a workspace test build several GB and minutes slower.
[profile.test]
debug = "line-tables-only"

# fast-edge, the fast test's TLS door (crates/monetize-fast kit.rs builds it static musl): small
# and quick to build, as its detached release profile was before T14 (no LTO, opt-level s).
[profile.fast-edge]
inherits = "release"
opt-level = "s"
lto = false
codegen-units = 16

# holger's own plugin (`holger-monetize-guest`, a dev-dependency of
# `products/holger`) takes monetize's OPEN crates from the registry, because
# holger builds from its own clone. (gunnar's plugin was patched in here too
# until 2026-09-28; its tests against this tree live in gunnar, and no manifest
# in this repo names a gunnar path.) Built inside THIS workspace it must see THIS
# tree's copies, or its `monetize_product_guest::wire` and this workspace's
# would be two crates with the same name and the parity tests would compare
# types that cannot meet.
[patch.crates-io]
monetize-product = { path = "crates/monetize-product" }
monetize-product-guest = { path = "crates/monetize-product-guest" }
monetize-embed = { path = "crates/monetize-embed" }