Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 16 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -250,3 +250,19 @@ RUST_LOG=buzz_relay=debug,buzz_datastore=info,buzz_db=debug,buzz_auth=debug,buzz
# BUZZ_TERMS_OF_SERVICE_MARKDOWN="# Terms of Service\n\nFull terms here."
# BUZZ_PRIVACY_POLICY_MARKDOWN="# Privacy Policy\n\nFull policy here."
# BUZZ_AGE_ATTESTATION_REQUIRED=true

# ── Bitcoin Markets (fork) ───────────────────────────────────────────────────
# Required env (or product public host). NO localhost default.
# Loopback http://127.0.0.1:8787 was listing-proof only — do not ship it.
# Listing/health (no auth): GET $INDEXER_URL/api/markets , GET $INDEXER_URL/health
# Do NOT put ADMIN_API_KEY or AVNU_API_KEY values in this repo.
INDEXER_URL=https://markets.bitcoinmarkets.app
# VITE_INDEXER_URL=https://markets.bitcoinmarkets.app

# Server-side AVNU SNIP-29 paymaster proxy (buzz-avnu-proxy).
# The API key must NEVER appear in the repo, frontend, or Tauri binary.
# AVNU_API_KEY=
# AVNU_PAYMASTER_URL=https://starknet.paymaster.avnu.fi
# BIND_ADDR=0.0.0.0:8788
# Desktop talks to the proxy (not AVNU directly):
# AVNU_PROXY_URL=http://127.0.0.1:8788
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ place.
| `migrations/0029_channels_id_lookup_index.sql`, `0030_long_reaction_payloads.sql`, `0031_community_deletion.sql`, `0032_community_deletion_recovery.sql`, `0033_workflow_run_error_codes.sql` | upstream's `0027_channels_id_lookup_index.sql`, `0028_long_reaction_payloads.sql`, `0029_community_deletion.sql`, `0030_community_deletion_recovery.sql` and `0031_workflow_run_error_codes.sql`, **renumbered**; contents byte-identical | The fork holds 0027 and 0028, so upstream's own new migrations have to arrive above them. Five syncs running, and it has now fired on every sync that touched `migrations/` — treat this as the standing cost of the fork's migration block rather than a special case. See [Upstream migrations arrive renumbered](#upstream-migrations-arrive-renumbered) |
| `crates/buzz-db/src/migration.rs` | `migrations.len()` assertion is 33, not upstream's 31; upstream's channel-index assertion reads `migrations[28].version == 29`, long-reaction `migrations[29].version == 30`, deletion `migrations[30].version == 31`, deletion-recovery `migrations[31].version == 32`, workflow-error-codes `migrations[32].version == 33`; and `deletion_surface_parity_between_migration_0029_and_schema_sql` looks up `version == 31` | Counts embedded migrations, so it moves whenever *either* side adds one. `0027` landed without bumping it and left the test failing on `main`; fixed in PR #9. Beyond the count, every upstream assertion that indexes `migrations[…]` past 25 or names a version above 26 has to be shifted by the fork's two — see the section below for why the test suite will *not* catch it if you forget. **The highest-applied-version assertion is no longer a fork patch**: upstream's 2026-08-13 range replaced the hardcoded `Some(30)` with a `latest_version` derived from `MIGRATOR`, so it now tracks the renumber on its own — take upstream's version if it ever conflicts again |
| `.github/workflows/macos-canary.yml` | new; `push` trigger on `main` with desktop path filters | Unsigned macOS canary; upstream only has a *signed* one, which a fork cannot run. Builds automatically when `desktop/**`, `crates/**` or the root `Cargo.*` change, so the newest artifact always matches `main` — it was dispatch-only, and the sole artifact went 13 commits stale. Free: the repo is public, so GitHub-hosted macOS runners are unbilled. Stages the artifact and the usage notes under the product name read from `tauri.conf.json`, not a hardcoded one, so the brand rename below cannot publish a build under the old name. Sets `signingIdentity: "-"` in its inline config and runs **without** `--no-sign`, which would silently discard it; asserts the bundle signature of the `.app` inside the mounted DMG. Its **sidecar list must track upstream's non-Windows lanes**: `tauri.conf.json`'s `externalBin` is shared, and `scripts/bundle-sidecars.sh` exits 1 on a missing binary, so a sidecar upstream adds breaks this workflow without ever conflicting — `buzz-backend-kubernetes` (#4289) did exactly that in the 2026-08-03 sync |
| `Dockerfile` | `buzz-paymaster` added to the cargo build, the strip step, and both `COPY` stages | The sponsor ships in the relay's image so there is one publish pipeline and one immutable `:sha-<7>` tag for `deploy-aws.yml` to pin. Four one-line additions, each inside an existing parallel list, so a conflict resolves as *keep ours, take upstream's*. It is **not** the `ENTRYPOINT` — `infra/aws/paymaster.tf` overrides `entryPoint` |
| `Dockerfile` | `buzz-paymaster` and `buzz-avnu-proxy` added to the cargo build, the strip step, and both `COPY` stages | The sponsor and the AVNU API-key proxy ship in the relay's image so there is one publish pipeline and one immutable `:sha-<7>` tag for `deploy-aws.yml` to pin. Four-to-eight one-line additions, each inside an existing parallel list, so a conflict resolves as *keep ours, take upstream's*. Neither is the `ENTRYPOINT` — ECS tasks override `command`. `AVNU_API_KEY` is injected at runtime from secrets, never baked into the image |
| `Cargo.toml`, `crates/buzz-core/Cargo.toml`, `crates/buzz-cli/Cargo.toml`, `crates/buzz-core/src/lib.rs`, `crates/buzz-cli/src/lib.rs`, `crates/buzz-cli/src/commands/mod.rs`, `crates/buzz-cli/TESTING.md` | Starknet/paymaster wiring: `crates/buzz-paymaster` joins the workspace members; `starknet-crypto`/`starknet-core`/`starknet-providers`/`starknet-accounts`/`secp256k1`/`async-trait` deps; `pub mod` lines for `outside_execution`, `sponsorship`, `starknet_account`, `commands::wallet`; the `WalletCmd` enum and its dispatch | The declaration surface for [Starknet accounts](#starknet-accounts) and [sponsorship](#sponsorship-buzz-paymaster). Each is a one-to-few-line insertion into an existing alphabetical list, so conflicts resolve as *keep ours, take upstream's*. **None carries an in-file `FORK-LOCAL` marker** — a manifest list takes a comment badly and the module lines are self-evidently fork-local from the module names — so this row is the only record. The new deps are all genuinely reachable: `secp256k1` from `starknet_account::sign_tx_hash` and `starknet_factory`, the `starknet-*` crates from `buzz-paymaster` and `wallet.rs`. `buzz-core` keeps its "zero I/O dependencies" contract — none of these pull tokio/sqlx/redis/axum |
| `crates/buzz-relay/src/handlers/ingest.rs` | `KIND_SPONSOR_REQUEST`, `KIND_SPONSOR_RESULT` and `KIND_SPONSOR_DEPLOY_REQUEST` added to the `required_scope_for_kind` `UsersWrite` arm and to `is_global_only_kind` | The relay half of [sponsorship](#sponsorship-buzz-paymaster). `UsersWrite` because sponsorship is a user acting on their own Starknet account; global-only because that account belongs to the author and never to a channel. Both hunks land inside long `|`-separated match arms that upstream extends regularly, so expect conflicts here whenever upstream adds a kind — resolve as *keep our three, take upstream's* |
| `CHANGELOG.md` | fork-test release notes appended at the **bottom** | `release.yml`'s "Create or verify versioned draft" step greps `^## v<version>$` anywhere in the file, so position does not affect the gate — while upstream only ever prepends at the top. Anchoring fork entries at the bottom keeps a file upstream rewrites every release from conflicting on every sync. **Add new fork-test versions below, never above** |
Expand Down
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ members = [
"crates/buzz-workflow",
"crates/buzz-media",
"crates/buzz-paymaster",
"crates/buzz-avnu-proxy",
"crates/buzz-cli",
"crates/buzz-pairing-cli",
"crates/buzz-sdk",
Expand Down
18 changes: 12 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,18 @@ COPY --from=planner /build/recipe.json recipe.json
# scoping to -p buzz-relay misses transitive deps and re-builds them later.
RUN cargo chef cook --release --recipe-path recipe.json
COPY . .
# FORK-LOCAL PATCH (adrienlacombe/buzz): buzz-paymaster ships in this image rather
# than one of its own. A second image would need a second publish workflow, and
# deploy-aws.yml pins the commit's immutable :sha-<7> tag — so it would have to wait
# on both pipelines or fall back to a floating tag, losing the property the deploy
# depends on. One line here is cheaper than that. The paymaster is not the ENTRYPOINT;
# its ECS task overrides `command`.
# FORK-LOCAL PATCH (adrienlacombe/buzz): buzz-paymaster and buzz-avnu-proxy ship
# in this image rather than ones of their own. A second image would need a second
# publish workflow, and deploy-aws.yml pins the commit's immutable :sha-<7> tag —
# so it would have to wait on both pipelines or fall back to a floating tag,
# losing the property the deploy depends on. Neither is the ENTRYPOINT; their
# ECS tasks override `command`.
# buzz-avnu-proxy holds AVNU_API_KEY server-side — never bake the key into the
# image; inject it at runtime from secrets.
RUN cargo build --release --locked -p buzz-relay --bin buzz-relay \
-p buzz-admin --bin buzz-admin \
-p buzz-paymaster --bin buzz-paymaster \
-p buzz-avnu-proxy --bin buzz-avnu-proxy \
-p buzz-pair-relay --bin buzz-pair-relay

# Derive the normal release binaries from the same optimized ELF files as the
Expand All @@ -84,6 +87,7 @@ FROM builder AS stripped-binaries
RUN strip target/release/buzz-relay \
&& strip target/release/buzz-admin \
&& strip target/release/buzz-paymaster \
&& strip target/release/buzz-avnu-proxy \
&& strip target/release/buzz-pair-relay

# ─── Stage 4: web bundle (pnpm + vite) ──────────────────────────────────────
Expand Down Expand Up @@ -178,6 +182,7 @@ COPY --from=builder /build/target/release/buzz-relay /usr/local/bin/buzz-relay
COPY --from=builder /build/target/release/buzz-admin /usr/local/bin/buzz-admin
# FORK-LOCAL PATCH (adrienlacombe/buzz): see the cargo build step above.
COPY --from=builder /build/target/release/buzz-paymaster /usr/local/bin/buzz-paymaster
COPY --from=builder /build/target/release/buzz-avnu-proxy /usr/local/bin/buzz-avnu-proxy
COPY --from=builder /build/target/release/buzz-pair-relay /usr/local/bin/buzz-pair-relay

# Keep the stripped runtime as the final/default Dockerfile target so existing
Expand All @@ -187,4 +192,5 @@ COPY --from=stripped-binaries /build/target/release/buzz-relay /usr/local/bin/bu
COPY --from=stripped-binaries /build/target/release/buzz-admin /usr/local/bin/buzz-admin
# FORK-LOCAL PATCH (adrienlacombe/buzz): see the cargo build step above.
COPY --from=stripped-binaries /build/target/release/buzz-paymaster /usr/local/bin/buzz-paymaster
COPY --from=stripped-binaries /build/target/release/buzz-avnu-proxy /usr/local/bin/buzz-avnu-proxy
COPY --from=stripped-binaries /build/target/release/buzz-pair-relay /usr/local/bin/buzz-pair-relay
22 changes: 22 additions & 0 deletions crates/buzz-avnu-proxy/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "buzz-avnu-proxy"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
repository.workspace = true
description = "Server-side AVNU SNIP-29 paymaster proxy (API key stays off the client)"

[[bin]]
name = "buzz-avnu-proxy"
path = "src/main.rs"

[dependencies]
axum = { workspace = true }
reqwest = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
thiserror = { workspace = true }
Loading
Loading