diff --git a/.changeset/address-enrichment-drizzle-migrations.md b/.changeset/address-enrichment-drizzle-migrations.md deleted file mode 100644 index bedf7e721..000000000 --- a/.changeset/address-enrichment-drizzle-migrations.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/address-enrichment": patch ---- - -Add committed Drizzle migrations and apply them at startup. diff --git a/.changeset/authful-ci-token-seeding.md b/.changeset/authful-ci-token-seeding.md deleted file mode 100644 index b8eec95f7..000000000 --- a/.changeset/authful-ci-token-seeding.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/authful": minor ---- - -On Railway PR previews (`RAILWAY_ENVIRONMENT_NAME` other than `dev`/`production`) the service now seeds a fixed token from the required `SEED_TOKEN_PLAINTEXT` env var on boot — idempotently, so it survives restarts — giving the rest of the preview stack a known key to authenticate with. The seeding capability is internal only; the admin API still mints exclusively with server-generated values. diff --git a/.changeset/authful-observability.md b/.changeset/authful-observability.md deleted file mode 100644 index 66b564d7b..000000000 --- a/.changeset/authful-observability.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/authful": patch ---- - -Add project-standard observability to Authful: structured Pino request logging, OpenTelemetry metrics/tracing via `@anticapture/observability`, an HTTP request-duration histogram, and a public `/metrics` Prometheus endpoint. Instrumentation is emitted as its own bundle entry and loaded with `node --import` so it registers before `pg`/`http` are required. diff --git a/.changeset/authful-require-json-body.md b/.changeset/authful-require-json-body.md deleted file mode 100644 index 758196e3d..000000000 --- a/.changeset/authful-require-json-body.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/authful": patch ---- - -Mark request bodies as `required` on the Authful `POST /tokens` and `/validate` routes. Without it, `@hono/zod-openapi` skips validation and substitutes an empty body when a request omits the JSON content-type — letting `POST /tokens` mint a token with a null `tenant` (NOT NULL violation / 500) instead of returning a 400. Malformed and empty bodies are now rejected with 400. diff --git a/.changeset/clever-peaches-rescue.md b/.changeset/clever-peaches-rescue.md deleted file mode 100644 index a845151cc..000000000 --- a/.changeset/clever-peaches-rescue.md +++ /dev/null @@ -1,2 +0,0 @@ ---- ---- diff --git a/.changeset/comp-description-escaped-newlines.md b/.changeset/comp-description-escaped-newlines.md deleted file mode 100644 index ea0890404..000000000 --- a/.changeset/comp-description-escaped-newlines.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/dashboard": patch ---- - -Fix proposal descriptions rendering blank for DAOs (e.g. Compound) whose on-chain descriptions use escaped `\n` newlines, by normalizing them to real line breaks for display. diff --git a/.changeset/create-proposal-fixes.md b/.changeset/create-proposal-fixes.md deleted file mode 100644 index e4f868fc4..000000000 --- a/.changeset/create-proposal-fixes.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/dashboard": minor ---- - -feat(create-proposal): recursive calldata builder covering every Solidity type (arrays, fixed/multidimensional, tuples/structs, nested) with two-way paste & decode and a live encoded-calldata preview; debounced contract-address validation; "Duplicate action" alongside edit/delete; and improved transfer UX — treasury "Max", always-visible helper text, per-token USD via CoinGecko, and a clearer selected-token state. diff --git a/.changeset/delete-snapshot-proposals.md b/.changeset/delete-snapshot-proposals.md deleted file mode 100644 index 5741fa3cb..000000000 --- a/.changeset/delete-snapshot-proposals.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/offchain-indexer": minor ---- - -Remove proposals and votes from the offchain indexer database when proposals are deleted from Snapshot. Reconciliation is bounded to proposals created in the last two weeks, so it never deletes older proposals and avoids overwhelming the Snapshot API and the indexer. diff --git a/.changeset/dev-758-authful-gateful.md b/.changeset/dev-758-authful-gateful.md deleted file mode 100644 index e0c8c87f9..000000000 --- a/.changeset/dev-758-authful-gateful.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@anticapture/authful": minor -"@anticapture/gateful": minor -"@anticapture/client": minor ---- - -Per-tenant API tokens (DEV-758): new Authful service issues, validates and revokes tenant tokens (sha256-only storage, manual minting); Gateful gains an optional token-auth middleware with Redis-cached validation, per-token rate limiting and per-tenant request metrics exposed on its `/metrics` endpoint (Prometheus counter `tenant_requests_total{tenant, route}`), enabled via `TOKEN_SERVICE_URL` (legacy `BLOCKFUL_API_TOKEN` behavior unchanged when unset). The MCP server can forward the caller's `Authorization` header to Gateful via `FORWARD_CLIENT_AUTH=true`; in that mode the shared `ANTICAPTURE_API_KEY` is never attached, so unauthenticated requests get a per-tenant 401 instead of riding the shared key. diff --git a/.changeset/dev-758-mcp-forward-auth.md b/.changeset/dev-758-mcp-forward-auth.md deleted file mode 100644 index 446305797..000000000 --- a/.changeset/dev-758-mcp-forward-auth.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/client": minor ---- - -MCP server can now forward each caller's own Authorization header to the upstream Gateful API (enable with `FORWARD_CLIENT_AUTH=true`), laying the groundwork for per-tenant tokens with rate limiting and usage tracking. Disabled by default; existing shared-key behavior is unchanged. diff --git a/.changeset/efp-social-stats.md b/.changeset/efp-social-stats.md deleted file mode 100644 index 8c845dfd7..000000000 --- a/.changeset/efp-social-stats.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@anticapture/address-enrichment": minor -"@anticapture/client": minor -"@anticapture/dashboard": minor ---- - -Surface ENS social records and EFP stats for addresses. - -- `address-enrichment` now reads the EFP `/details` endpoint, capturing the ENS `com.twitter`, `org.telegram`, `email`, and `com.github` text records plus EFP follower/following counts. These are exposed under `ens` (socials) and a new `efp` object, cached under the existing ENS TTL. EFP counts are returned even when the address has no primary ENS name. -- The Holders & Delegates drawer header now shows follower/following counts (linked to the EFP profile) and social links (X, Telegram, GitHub, email) for the selected address. diff --git a/.changeset/env-validation-mcp-authful.md b/.changeset/env-validation-mcp-authful.md deleted file mode 100644 index b940574f7..000000000 --- a/.changeset/env-validation-mcp-authful.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@anticapture/client": patch -"@anticapture/authful": patch -"@anticapture/gateful": patch ---- - -Standardize environment-variable handling to match the API module. The MCP server now loads `.env` via dotenv and validates `PORT`, `HOST`, `ANTICAPTURE_API_URL`, `ANTICAPTURE_API_KEY`, and `FORWARD_CLIENT_AUTH` through a single zod schema instead of ad-hoc `process.env` reads. Authful's env parsing switches to the same `safeParse` + friendly-error pattern and folds `TOKEN_PLAINTEXT` into the schema so the mint script no longer reads `process.env` directly. Gateful now normalizes `TOKEN_SERVICE_URL` (trailing-slash trimming) in its zod env schema rather than manually inside `AuthfulClient`. diff --git a/.changeset/gateful-health-fail-closed.md b/.changeset/gateful-health-fail-closed.md deleted file mode 100644 index d27b8d6b3..000000000 --- a/.changeset/gateful-health-fail-closed.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/gateful": minor ---- - -Gateful `/health` now returns 503 unless every configured DAO API, relayer, and address-enrichment service responds on `/health`. diff --git a/.changeset/gateful-health-readonly-probe.md b/.changeset/gateful-health-readonly-probe.md deleted file mode 100644 index 4c3c09656..000000000 --- a/.changeset/gateful-health-readonly-probe.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/gateful": patch ---- - -Gateful `/health` probes are now read-only: they reflect each upstream's circuit-breaker state but no longer run through `breaker.execute()`, so CI/orchestrator polling can't trip the real-traffic circuit (or steal its HALF_OPEN probe slot) and take routes offline. diff --git a/.changeset/gateful-vercel-preview-spec.md b/.changeset/gateful-vercel-preview-spec.md deleted file mode 100644 index 0e43662e5..000000000 --- a/.changeset/gateful-vercel-preview-spec.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/client": patch ---- - -Resolve the Gateful OpenAPI spec from the matching PR-preview Gateful on Vercel previews (derived from `VERCEL_GIT_PULL_REQUEST_ID`), so codegen-dependent builds (e.g. dashboard/storybook) no longer fail with "Config failed loading" when neither `ANTICAPTURE_API_URL` nor `RAILWAY_ENVIRONMENT_NAME` is set. diff --git a/.changeset/late-eagles-pick.md b/.changeset/late-eagles-pick.md deleted file mode 100644 index d0ff41185..000000000 --- a/.changeset/late-eagles-pick.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/dashboard": minor ---- - -support Tornado Cash proposal creation diff --git a/.changeset/mcp-authful-inbound-auth.md b/.changeset/mcp-authful-inbound-auth.md deleted file mode 100644 index c6c215dbc..000000000 --- a/.changeset/mcp-authful-inbound-auth.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/client": minor ---- - -The MCP HTTP server no longer does an equality check against the shared `ANTICAPTURE_MCP_API_KEY` (now removed). Token validation is delegated to Gateful: callers present their own per-tenant token, which the MCP server forwards upstream (`FORWARD_CLIENT_AUTH=true`) for Gateful's `tokenAuthMiddleware` to validate and attribute per tenant. Validation is intentionally not duplicated at the MCP layer — Gateful owns it, including the Redis cache and fail-open fallback that keep cache-warm tenants serving through an Authful restart. diff --git a/.changeset/nice-wings-stop.md b/.changeset/nice-wings-stop.md deleted file mode 100644 index a845151cc..000000000 --- a/.changeset/nice-wings-stop.md +++ /dev/null @@ -1,2 +0,0 @@ ---- ---- diff --git a/.changeset/offchain-support-guards.md b/.changeset/offchain-support-guards.md deleted file mode 100644 index 9124ff68b..000000000 --- a/.changeset/offchain-support-guards.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/api": patch ---- - -Return unsupported-offchain errors consistently across offchain proposal and vote routes. diff --git a/.changeset/preview-untrusted-gateful-fallback.md b/.changeset/preview-untrusted-gateful-fallback.md deleted file mode 100644 index c1fb7eee9..000000000 --- a/.changeset/preview-untrusted-gateful-fallback.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@anticapture/dashboard": patch -"@anticapture/client": patch ---- - -Drop the shared-dev-Gateful fallback for untrusted/fork Vercel PR previews. Those previews get no PR-scoped Railway service, so they can never reflect a PR's API/Gateful changes — pointing them at `dev-gateful` only produced a misleading preview. The dashboard `next.config.ts` and the `@anticapture/client` Gateful OpenAPI spec resolver now rely solely on an explicit `ANTICAPTURE_API_URL` (injected by CI for trusted PRs / set on dev & production) or a Railway PR-preview environment; anything else throws instead of silently falling back. diff --git a/.changeset/proposal-mobile-viewport-dvh.md b/.changeset/proposal-mobile-viewport-dvh.md deleted file mode 100644 index 9b8eb63ec..000000000 --- a/.changeset/proposal-mobile-viewport-dvh.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/dashboard": patch ---- - -fix(dashboard): use dynamic viewport height (dvh) for the app/whitelabel shells so the sticky bottom action bar (e.g. create-proposal Publish/Save Draft) is no longer hidden behind the mobile browser's bottom toolbar. diff --git a/.changeset/protect-gateful-metrics-endpoint.md b/.changeset/protect-gateful-metrics-endpoint.md deleted file mode 100644 index 4604c44f5..000000000 --- a/.changeset/protect-gateful-metrics-endpoint.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/gateful": minor ---- - -Protect the public `/metrics` endpoint with a bearer token. When the optional `GATEFUL_METRICS_TOKEN` env var is set, scrapes of `/metrics` must present it as a bearer (constant-time compare; 401 otherwise); left open when unset for local dev. The Prometheus scraper reads the same variable name so it can be wired as a single shared Railway variable. This guard is independent of per-tenant Authful auth, so scrapes never consume a tenant token or appear in per-tenant usage metrics. diff --git a/.changeset/remove-legacy-shared-token-auth.md b/.changeset/remove-legacy-shared-token-auth.md deleted file mode 100644 index 51513c889..000000000 --- a/.changeset/remove-legacy-shared-token-auth.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@anticapture/gateful": minor -"@anticapture/client": patch ---- - -Remove the transitional single shared-token auth path now that per-tenant Authful auth is fully rolled out. Gateful drops the legacy `BLOCKFUL_API_TOKEN` `bearerAuth` fallback (and the `BLOCKFUL_API_TOKEN` env var it read); per-tenant token auth via `TOKEN_SERVICE_URL` is the only auth mode. The `@anticapture/client` package drops an orphaned, never-imported `AuthfulClient` (MCP token validation is delegated to Gateful, not performed in-process). diff --git a/.changeset/shareable-proposal-drafts.md b/.changeset/shareable-proposal-drafts.md deleted file mode 100644 index d70a6ece0..000000000 --- a/.changeset/shareable-proposal-drafts.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/dashboard": minor ---- - -Shareable proposal drafts: add an Editor/Preview toggle, a read-only draft preview, and a recipient flow for shared draft links — publish the draft on-chain or edit it to fork your own copy. diff --git a/.changeset/torn-delegation-voting-power.md b/.changeset/torn-delegation-voting-power.md deleted file mode 100644 index 5d2528830..000000000 --- a/.changeset/torn-delegation-voting-power.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/indexer": minor ---- - -TORN: route locked voting power to the locker's delegate and move it between delegates on Delegated/Undelegated. TORN emits no DelegateVotesChanged, so per-account voting power is now fully synthesized from lock/unlock Transfers plus delegation shifts. diff --git a/.changeset/torn-lock-transfer-direction.md b/.changeset/torn-lock-transfer-direction.md deleted file mode 100644 index 328df6356..000000000 --- a/.changeset/torn-lock-transfer-direction.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/api": patch ---- - -Normalize TORN lock/unlock transfer direction in voting-power history so the locker (not the custody contract) is shown as the delegator. diff --git a/.changeset/torn-proposal-display.md b/.changeset/torn-proposal-display.md deleted file mode 100644 index 1dab9e17c..000000000 --- a/.changeset/torn-proposal-display.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/dashboard": minor ---- - -Render Tornado Cash proposal descriptions as Markdown (unwrapping the stringified-JSON body) and show a proposal Info card on the Actions tab for proposals without executable actions. diff --git a/.changeset/torn-treasury-transfers-phantom-voting-power.md b/.changeset/torn-treasury-transfers-phantom-voting-power.md deleted file mode 100644 index 6301485da..000000000 --- a/.changeset/torn-treasury-transfers-phantom-voting-power.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/indexer": patch ---- - -Fix TORN voting power going negative from treasury transfers. TORN derives per-account voting power from lock/unlock Transfers in/out of the governor, but TORN also flows through the governor for treasury purposes (proposal executions, batch grant payouts, the governor↔vault migration). Those were misread as user unlocks and subtracted voting power from recipients that never locked (e.g. proposal #6 funding a staking pool booked a -120k unlock against a contract with zero locked balance), producing negative voting power and phantom locked balances. A custody transfer is now only counted as a lock/unlock when its counterparty is the transaction sender, which is true for genuine `lock()`/`unlock()` calls and false for treasury flows. diff --git a/.changeset/torn-vote-change-mutability.md b/.changeset/torn-vote-change-mutability.md deleted file mode 100644 index ed3b8dd96..000000000 --- a/.changeset/torn-vote-change-mutability.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/indexer": patch ---- - -Fix TORN votes not reflecting vote changes. TORN's governor lets a voter re-cast to change their vote, but the `Voted` handler used `onConflictDoNothing` on the unique `(voter, proposal)` row and dropped every subsequent cast — so a voter who switched from For to Against still showed as For and the proposal tally kept the stale vote. The handler now overwrites the existing row and moves the voting power between the for/against buckets on a change, while still treating an exact re-processed log (backfill/reorg) as a no-op. Requires a reindex to repopulate. diff --git a/.changeset/torn-vote-options.md b/.changeset/torn-vote-options.md deleted file mode 100644 index be4c390eb..000000000 --- a/.changeset/torn-vote-options.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@anticapture/dashboard": minor ---- - -Make TORN vote recasting reachable (show "Change your vote" on already-voted onchain proposals when the DAO allows changing votes) and hide the Abstain option for Tornado Cash, whose binary governor rejects abstain votes. diff --git a/.changeset/torn-voting-power-history-transfer-link.md b/.changeset/torn-voting-power-history-transfer-link.md deleted file mode 100644 index 8ba679ef5..000000000 --- a/.changeset/torn-voting-power-history-transfer-link.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@anticapture/api": patch -"@anticapture/dashboard": patch ---- - -Fix TORN historical voting power rows being rendered as bogus zero-address delegations. TORN derives voting power directly from Transfers, so each history row shares the Transfer's log index, which the generic repository's strict `<` join never matched. Added a dedicated TORN voting-power repository that links the causing event at `logIndex <= row logIndex`. Dashboard also formats the auto-delegation fallback amount instead of dumping the raw delta. diff --git a/.changeset/tornado-cash-integration.md b/.changeset/tornado-cash-integration.md deleted file mode 100644 index d38972c71..000000000 --- a/.changeset/tornado-cash-integration.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@anticapture/indexer": minor -"@anticapture/api": minor -"@anticapture/dashboard": minor ---- - -Integrate Tornado Cash DAO (TORN): custom stake-to-vote indexer (lock-based delegated supply, timestamp governance), timestamp-based proposal-status API client, and dashboard config/icon. diff --git a/apps/address-enrichment/CHANGELOG.md b/apps/address-enrichment/CHANGELOG.md new file mode 100644 index 000000000..34aefed69 --- /dev/null +++ b/apps/address-enrichment/CHANGELOG.md @@ -0,0 +1,13 @@ +# @anticapture/address-enrichment + +## 1.1.0 + +### Minor Changes + +- [#1993](https://github.com/blockful/anticapture/pull/1993) [`add9bd1`](https://github.com/blockful/anticapture/commit/add9bd1e96ea89dd26f892fcd30353919d905126) Thanks [@caveman-eth](https://github.com/caveman-eth)! - Surface ENS social records and EFP stats for addresses. + - `address-enrichment` now reads the EFP `/details` endpoint, capturing the ENS `com.twitter`, `org.telegram`, `email`, and `com.github` text records plus EFP follower/following counts. These are exposed under `ens` (socials) and a new `efp` object, cached under the existing ENS TTL. EFP counts are returned even when the address has no primary ENS name. + - The Holders & Delegates drawer header now shows follower/following counts (linked to the EFP profile) and social links (X, Telegram, GitHub, email) for the selected address. + +### Patch Changes + +- [#2010](https://github.com/blockful/anticapture/pull/2010) [`325fccb`](https://github.com/blockful/anticapture/commit/325fccbed3d6693be643127c0ef71fb90cf1e0bd) Thanks [@pikonha](https://github.com/pikonha)! - Add committed Drizzle migrations and apply them at startup. diff --git a/apps/address-enrichment/package.json b/apps/address-enrichment/package.json index c5374eea9..97da86324 100644 --- a/apps/address-enrichment/package.json +++ b/apps/address-enrichment/package.json @@ -1,6 +1,6 @@ { "name": "@anticapture/address-enrichment", - "version": "1.0.0", + "version": "1.1.0", "private": true, "scripts": { "dev": "tsx watch src/index.ts", diff --git a/apps/api/CHANGELOG.md b/apps/api/CHANGELOG.md index 16fae83e3..444252d82 100644 --- a/apps/api/CHANGELOG.md +++ b/apps/api/CHANGELOG.md @@ -1,5 +1,19 @@ # @anticapture/api +## 1.5.0 + +### Minor Changes + +- [#2002](https://github.com/blockful/anticapture/pull/2002) [`451db65`](https://github.com/blockful/anticapture/commit/451db65d6497503ecebcae24fed44027a2e6479f) Thanks [@pikonha](https://github.com/pikonha)! - Integrate Tornado Cash DAO (TORN): custom stake-to-vote indexer (lock-based delegated supply, timestamp governance), timestamp-based proposal-status API client, and dashboard config/icon. + +### Patch Changes + +- [#2002](https://github.com/blockful/anticapture/pull/2002) [`2f0aca6`](https://github.com/blockful/anticapture/commit/2f0aca60e1a4785af8d7f52cd81c6a3cfbac63ee) Thanks [@pikonha](https://github.com/pikonha)! - Return unsupported-offchain errors consistently across offchain proposal and vote routes. + +- [#2002](https://github.com/blockful/anticapture/pull/2002) [`873bb45`](https://github.com/blockful/anticapture/commit/873bb4514e144aaece91246c86ba61e0e7f54c1f) Thanks [@pikonha](https://github.com/pikonha)! - Normalize TORN lock/unlock transfer direction in voting-power history so the locker (not the custody contract) is shown as the delegator. + +- [#2002](https://github.com/blockful/anticapture/pull/2002) [`2fc7174`](https://github.com/blockful/anticapture/commit/2fc71740f3953d5c49eaf92d5ab7947ae821ce0f) Thanks [@pikonha](https://github.com/pikonha)! - Fix TORN historical voting power rows being rendered as bogus zero-address delegations. TORN derives voting power directly from Transfers, so each history row shares the Transfer's log index, which the generic repository's strict `<` join never matched. Added a dedicated TORN voting-power repository that links the causing event at `logIndex <= row logIndex`. Dashboard also formats the auto-delegation fallback amount instead of dumping the raw delta. + ## 1.4.0 ### Minor Changes diff --git a/apps/api/package.json b/apps/api/package.json index 016d5d0eb..c9ced631c 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -1,6 +1,6 @@ { "name": "@anticapture/api", - "version": "1.4.0", + "version": "1.5.0", "private": true, "main": "dist/index.js", "type": "module", diff --git a/apps/authful/CHANGELOG.md b/apps/authful/CHANGELOG.md new file mode 100644 index 000000000..eb2090a21 --- /dev/null +++ b/apps/authful/CHANGELOG.md @@ -0,0 +1,17 @@ +# @anticapture/authful + +## 0.2.0 + +### Minor Changes + +- [#2000](https://github.com/blockful/anticapture/pull/2000) [`1e6c3fb`](https://github.com/blockful/anticapture/commit/1e6c3fb2d6a7846a5d2e9f8aa4bcb769e0beab07) Thanks [@PedroBinotto](https://github.com/PedroBinotto)! - On Railway PR previews (`RAILWAY_ENVIRONMENT_NAME` other than `dev`/`production`) the service now seeds a fixed token from the required `SEED_TOKEN_PLAINTEXT` env var on boot — idempotently, so it survives restarts — giving the rest of the preview stack a known key to authenticate with. The seeding capability is internal only; the admin API still mints exclusively with server-generated values. + +- [#1971](https://github.com/blockful/anticapture/pull/1971) [`4a85cf4`](https://github.com/blockful/anticapture/commit/4a85cf47d6a56b3f0c9de5da87978e0687755c55) Thanks [@brunod-e](https://github.com/brunod-e)! - Per-tenant API tokens (DEV-758): new Authful service issues, validates and revokes tenant tokens (sha256-only storage, manual minting); Gateful gains an optional token-auth middleware with Redis-cached validation, per-token rate limiting and per-tenant request metrics exposed on its `/metrics` endpoint (Prometheus counter `tenant_requests_total{tenant, route}`), enabled via `TOKEN_SERVICE_URL` (legacy `BLOCKFUL_API_TOKEN` behavior unchanged when unset). The MCP server can forward the caller's `Authorization` header to Gateful via `FORWARD_CLIENT_AUTH=true`; in that mode the shared `ANTICAPTURE_API_KEY` is never attached, so unauthenticated requests get a per-tenant 401 instead of riding the shared key. + +### Patch Changes + +- [#1971](https://github.com/blockful/anticapture/pull/1971) [`dd8756c`](https://github.com/blockful/anticapture/commit/dd8756c61fcb2a755a692a018a83ab36a61415c8) Thanks [@brunod-e](https://github.com/brunod-e)! - Add project-standard observability to Authful: structured Pino request logging, OpenTelemetry metrics/tracing via `@anticapture/observability`, an HTTP request-duration histogram, and a public `/metrics` Prometheus endpoint. Instrumentation is emitted as its own bundle entry and loaded with `node --import` so it registers before `pg`/`http` are required. + +- [#1971](https://github.com/blockful/anticapture/pull/1971) [`858d286`](https://github.com/blockful/anticapture/commit/858d2860afbb58344044aa8c5d4629652ba47ae4) Thanks [@brunod-e](https://github.com/brunod-e)! - Mark request bodies as `required` on the Authful `POST /tokens` and `/validate` routes. Without it, `@hono/zod-openapi` skips validation and substitutes an empty body when a request omits the JSON content-type — letting `POST /tokens` mint a token with a null `tenant` (NOT NULL violation / 500) instead of returning a 400. Malformed and empty bodies are now rejected with 400. + +- [#1971](https://github.com/blockful/anticapture/pull/1971) [`51e110a`](https://github.com/blockful/anticapture/commit/51e110a12820493c453097fc069b194f0b8c08e5) Thanks [@brunod-e](https://github.com/brunod-e)! - Standardize environment-variable handling to match the API module. The MCP server now loads `.env` via dotenv and validates `PORT`, `HOST`, `ANTICAPTURE_API_URL`, `ANTICAPTURE_API_KEY`, and `FORWARD_CLIENT_AUTH` through a single zod schema instead of ad-hoc `process.env` reads. Authful's env parsing switches to the same `safeParse` + friendly-error pattern and folds `TOKEN_PLAINTEXT` into the schema so the mint script no longer reads `process.env` directly. Gateful now normalizes `TOKEN_SERVICE_URL` (trailing-slash trimming) in its zod env schema rather than manually inside `AuthfulClient`. diff --git a/apps/authful/package.json b/apps/authful/package.json index c1f4a2d3a..7a62c4fdb 100644 --- a/apps/authful/package.json +++ b/apps/authful/package.json @@ -1,6 +1,6 @@ { "name": "@anticapture/authful", - "version": "0.1.0", + "version": "0.2.0", "private": true, "type": "module", "main": "dist/index.js", diff --git a/apps/dashboard/CHANGELOG.md b/apps/dashboard/CHANGELOG.md index 5d487bdb9..70c284670 100644 --- a/apps/dashboard/CHANGELOG.md +++ b/apps/dashboard/CHANGELOG.md @@ -1,5 +1,38 @@ # @anticapture/dashboard +## 2.7.0 + +### Minor Changes + +- [#1997](https://github.com/blockful/anticapture/pull/1997) [`8ed6328`](https://github.com/blockful/anticapture/commit/8ed6328d9864d30225a9aefb7baeb63fe790f6dd) Thanks [@brunod-e](https://github.com/brunod-e)! - feat(create-proposal): recursive calldata builder covering every Solidity type (arrays, fixed/multidimensional, tuples/structs, nested) with two-way paste & decode and a live encoded-calldata preview; debounced contract-address validation; "Duplicate action" alongside edit/delete; and improved transfer UX — treasury "Max", always-visible helper text, per-token USD via CoinGecko, and a clearer selected-token state. + +- [#1993](https://github.com/blockful/anticapture/pull/1993) [`add9bd1`](https://github.com/blockful/anticapture/commit/add9bd1e96ea89dd26f892fcd30353919d905126) Thanks [@caveman-eth](https://github.com/caveman-eth)! - Surface ENS social records and EFP stats for addresses. + - `address-enrichment` now reads the EFP `/details` endpoint, capturing the ENS `com.twitter`, `org.telegram`, `email`, and `com.github` text records plus EFP follower/following counts. These are exposed under `ens` (socials) and a new `efp` object, cached under the existing ENS TTL. EFP counts are returned even when the address has no primary ENS name. + - The Holders & Delegates drawer header now shows follower/following counts (linked to the EFP profile) and social links (X, Telegram, GitHub, email) for the selected address. + +- [#2009](https://github.com/blockful/anticapture/pull/2009) [`36992d7`](https://github.com/blockful/anticapture/commit/36992d728e562b32c87402812a54acde82092593) Thanks [@Zeugh-eth](https://github.com/Zeugh-eth)! - support Tornado Cash proposal creation + +- [#1990](https://github.com/blockful/anticapture/pull/1990) [`5cb8a21`](https://github.com/blockful/anticapture/commit/5cb8a2168b459c18645f42461078b47692da8430) Thanks [@brunod-e](https://github.com/brunod-e)! - Shareable proposal drafts: add an Editor/Preview toggle, a read-only draft preview, and a recipient flow for shared draft links — publish the draft on-chain or edit it to fork your own copy. + +- [#2012](https://github.com/blockful/anticapture/pull/2012) [`3031315`](https://github.com/blockful/anticapture/commit/303131572b12e8a9196a91ac9bd865b0977c2470) Thanks [@PedroBinotto](https://github.com/PedroBinotto)! - Render Tornado Cash proposal descriptions as Markdown (unwrapping the stringified-JSON body) and show a proposal Info card on the Actions tab for proposals without executable actions. + +- [#2002](https://github.com/blockful/anticapture/pull/2002) [`412b9e8`](https://github.com/blockful/anticapture/commit/412b9e87b11b02b5de0dfb1d21d838af53242594) Thanks [@pikonha](https://github.com/pikonha)! - Make TORN vote recasting reachable (show "Change your vote" on already-voted onchain proposals when the DAO allows changing votes) and hide the Abstain option for Tornado Cash, whose binary governor rejects abstain votes. + +- [#2002](https://github.com/blockful/anticapture/pull/2002) [`451db65`](https://github.com/blockful/anticapture/commit/451db65d6497503ecebcae24fed44027a2e6479f) Thanks [@pikonha](https://github.com/pikonha)! - Integrate Tornado Cash DAO (TORN): custom stake-to-vote indexer (lock-based delegated supply, timestamp governance), timestamp-based proposal-status API client, and dashboard config/icon. + +### Patch Changes + +- [#2015](https://github.com/blockful/anticapture/pull/2015) [`196de31`](https://github.com/blockful/anticapture/commit/196de313585e028f747190f8ea7d2d497d140c94) Thanks [@pikonha](https://github.com/pikonha)! - Fix proposal descriptions rendering blank for DAOs (e.g. Compound) whose on-chain descriptions use escaped `\n` newlines, by normalizing them to real line breaks for display. + +- [#1995](https://github.com/blockful/anticapture/pull/1995) [`eaacf28`](https://github.com/blockful/anticapture/commit/eaacf28668967881c626e673f70af43de4233f74) Thanks [@pikonha](https://github.com/pikonha)! - Drop the shared-dev-Gateful fallback for untrusted/fork Vercel PR previews. Those previews get no PR-scoped Railway service, so they can never reflect a PR's API/Gateful changes — pointing them at `dev-gateful` only produced a misleading preview. The dashboard `next.config.ts` and the `@anticapture/client` Gateful OpenAPI spec resolver now rely solely on an explicit `ANTICAPTURE_API_URL` (injected by CI for trusted PRs / set on dev & production) or a Railway PR-preview environment; anything else throws instead of silently falling back. + +- [#2011](https://github.com/blockful/anticapture/pull/2011) [`acdaf82`](https://github.com/blockful/anticapture/commit/acdaf82ad448587254f9c22aaa9b99f3e611b277) Thanks [@brunod-e](https://github.com/brunod-e)! - fix(dashboard): use dynamic viewport height (dvh) for the app/whitelabel shells so the sticky bottom action bar (e.g. create-proposal Publish/Save Draft) is no longer hidden behind the mobile browser's bottom toolbar. + +- [#2002](https://github.com/blockful/anticapture/pull/2002) [`2fc7174`](https://github.com/blockful/anticapture/commit/2fc71740f3953d5c49eaf92d5ab7947ae821ce0f) Thanks [@pikonha](https://github.com/pikonha)! - Fix TORN historical voting power rows being rendered as bogus zero-address delegations. TORN derives voting power directly from Transfers, so each history row shares the Transfer's log index, which the generic repository's strict `<` join never matched. Added a dedicated TORN voting-power repository that links the causing event at `logIndex <= row logIndex`. Dashboard also formats the auto-delegation fallback amount instead of dumping the raw delta. + +- Updated dependencies [[`4a85cf4`](https://github.com/blockful/anticapture/commit/4a85cf47d6a56b3f0c9de5da87978e0687755c55), [`e57bf06`](https://github.com/blockful/anticapture/commit/e57bf06b022728ccb9bb32f6c2622125c3d2a506), [`add9bd1`](https://github.com/blockful/anticapture/commit/add9bd1e96ea89dd26f892fcd30353919d905126), [`51e110a`](https://github.com/blockful/anticapture/commit/51e110a12820493c453097fc069b194f0b8c08e5), [`172558c`](https://github.com/blockful/anticapture/commit/172558c1b1284c085b68a8cd8316a7fb023d287f), [`2dea74c`](https://github.com/blockful/anticapture/commit/2dea74c32a99f8475894df6b2e59e759ecaf233a), [`eaacf28`](https://github.com/blockful/anticapture/commit/eaacf28668967881c626e673f70af43de4233f74), [`d94129c`](https://github.com/blockful/anticapture/commit/d94129ca6d9d488689f7ada91db4d1c7c8020394)]: + - @anticapture/client@1.4.0 + ## 2.6.0 ### Minor Changes diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json index b1e891bc8..e195bd5bc 100644 --- a/apps/dashboard/package.json +++ b/apps/dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@anticapture/dashboard", - "version": "2.6.0", + "version": "2.7.0", "private": true, "scripts": { "dev": "next dev --turbo", diff --git a/apps/gateful/CHANGELOG.md b/apps/gateful/CHANGELOG.md index aaa494ab7..f5b97aabc 100644 --- a/apps/gateful/CHANGELOG.md +++ b/apps/gateful/CHANGELOG.md @@ -1,5 +1,23 @@ # @anticapture/gateful +## 1.2.0 + +### Minor Changes + +- [#1971](https://github.com/blockful/anticapture/pull/1971) [`4a85cf4`](https://github.com/blockful/anticapture/commit/4a85cf47d6a56b3f0c9de5da87978e0687755c55) Thanks [@brunod-e](https://github.com/brunod-e)! - Per-tenant API tokens (DEV-758): new Authful service issues, validates and revokes tenant tokens (sha256-only storage, manual minting); Gateful gains an optional token-auth middleware with Redis-cached validation, per-token rate limiting and per-tenant request metrics exposed on its `/metrics` endpoint (Prometheus counter `tenant_requests_total{tenant, route}`), enabled via `TOKEN_SERVICE_URL` (legacy `BLOCKFUL_API_TOKEN` behavior unchanged when unset). The MCP server can forward the caller's `Authorization` header to Gateful via `FORWARD_CLIENT_AUTH=true`; in that mode the shared `ANTICAPTURE_API_KEY` is never attached, so unauthenticated requests get a per-tenant 401 instead of riding the shared key. + +- [#1995](https://github.com/blockful/anticapture/pull/1995) [`4d7d667`](https://github.com/blockful/anticapture/commit/4d7d66701fcefb8a1b3af2a41dd2c4af9b77862a) Thanks [@pikonha](https://github.com/pikonha)! - Gateful `/health` now returns 503 unless every configured DAO API, relayer, and address-enrichment service responds on `/health`. + +- [#1996](https://github.com/blockful/anticapture/pull/1996) [`f5b9f24`](https://github.com/blockful/anticapture/commit/f5b9f24d0a7c7081ec80b58cc45cc35eb3b29ae3) Thanks [@PedroBinotto](https://github.com/PedroBinotto)! - Protect the public `/metrics` endpoint with a bearer token. When the optional `GATEFUL_METRICS_TOKEN` env var is set, scrapes of `/metrics` must present it as a bearer (constant-time compare; 401 otherwise); left open when unset for local dev. The Prometheus scraper reads the same variable name so it can be wired as a single shared Railway variable. This guard is independent of per-tenant Authful auth, so scrapes never consume a tenant token or appear in per-tenant usage metrics. + +- [#1994](https://github.com/blockful/anticapture/pull/1994) [`d94129c`](https://github.com/blockful/anticapture/commit/d94129ca6d9d488689f7ada91db4d1c7c8020394) Thanks [@PedroBinotto](https://github.com/PedroBinotto)! - Remove the transitional single shared-token auth path now that per-tenant Authful auth is fully rolled out. Gateful drops the legacy `BLOCKFUL_API_TOKEN` `bearerAuth` fallback (and the `BLOCKFUL_API_TOKEN` env var it read); per-tenant token auth via `TOKEN_SERVICE_URL` is the only auth mode. The `@anticapture/client` package drops an orphaned, never-imported `AuthfulClient` (MCP token validation is delegated to Gateful, not performed in-process). + +### Patch Changes + +- [#1971](https://github.com/blockful/anticapture/pull/1971) [`51e110a`](https://github.com/blockful/anticapture/commit/51e110a12820493c453097fc069b194f0b8c08e5) Thanks [@brunod-e](https://github.com/brunod-e)! - Standardize environment-variable handling to match the API module. The MCP server now loads `.env` via dotenv and validates `PORT`, `HOST`, `ANTICAPTURE_API_URL`, `ANTICAPTURE_API_KEY`, and `FORWARD_CLIENT_AUTH` through a single zod schema instead of ad-hoc `process.env` reads. Authful's env parsing switches to the same `safeParse` + friendly-error pattern and folds `TOKEN_PLAINTEXT` into the schema so the mint script no longer reads `process.env` directly. Gateful now normalizes `TOKEN_SERVICE_URL` (trailing-slash trimming) in its zod env schema rather than manually inside `AuthfulClient`. + +- [#1995](https://github.com/blockful/anticapture/pull/1995) [`69c4427`](https://github.com/blockful/anticapture/commit/69c44279b1e1220b65a11c7aaf972f39544360c6) Thanks [@pikonha](https://github.com/pikonha)! - Gateful `/health` probes are now read-only: they reflect each upstream's circuit-breaker state but no longer run through `breaker.execute()`, so CI/orchestrator polling can't trip the real-traffic circuit (or steal its HALF_OPEN probe slot) and take routes offline. + ## 1.1.0 ### Minor Changes diff --git a/apps/gateful/package.json b/apps/gateful/package.json index 57f963075..f2d2f9481 100644 --- a/apps/gateful/package.json +++ b/apps/gateful/package.json @@ -1,6 +1,6 @@ { "name": "@anticapture/gateful", - "version": "1.1.0", + "version": "1.2.0", "private": true, "description": "Gateful REST API aggregator for Anticapture DAO APIs", "main": "dist/src/index.js", diff --git a/apps/indexer/CHANGELOG.md b/apps/indexer/CHANGELOG.md index 1b83cfaa4..e92435e44 100644 --- a/apps/indexer/CHANGELOG.md +++ b/apps/indexer/CHANGELOG.md @@ -1,5 +1,19 @@ # @anticapture/indexer +## 1.2.0 + +### Minor Changes + +- [#2002](https://github.com/blockful/anticapture/pull/2002) [`0d2da65`](https://github.com/blockful/anticapture/commit/0d2da6586a227f7c5382726144be1ea9797fd25e) Thanks [@pikonha](https://github.com/pikonha)! - TORN: route locked voting power to the locker's delegate and move it between delegates on Delegated/Undelegated. TORN emits no DelegateVotesChanged, so per-account voting power is now fully synthesized from lock/unlock Transfers plus delegation shifts. + +- [#2002](https://github.com/blockful/anticapture/pull/2002) [`451db65`](https://github.com/blockful/anticapture/commit/451db65d6497503ecebcae24fed44027a2e6479f) Thanks [@pikonha](https://github.com/pikonha)! - Integrate Tornado Cash DAO (TORN): custom stake-to-vote indexer (lock-based delegated supply, timestamp governance), timestamp-based proposal-status API client, and dashboard config/icon. + +### Patch Changes + +- [#2002](https://github.com/blockful/anticapture/pull/2002) [`1454329`](https://github.com/blockful/anticapture/commit/14543297f18e5992825b0a31f492ec78bc7fa935) Thanks [@pikonha](https://github.com/pikonha)! - Fix TORN voting power going negative from treasury transfers. TORN derives per-account voting power from lock/unlock Transfers in/out of the governor, but TORN also flows through the governor for treasury purposes (proposal executions, batch grant payouts, the governor↔vault migration). Those were misread as user unlocks and subtracted voting power from recipients that never locked (e.g. proposal [#6](https://github.com/blockful/anticapture/issues/6) funding a staking pool booked a -120k unlock against a contract with zero locked balance), producing negative voting power and phantom locked balances. A custody transfer is now only counted as a lock/unlock when its counterparty is the transaction sender, which is true for genuine `lock()`/`unlock()` calls and false for treasury flows. + +- [#2002](https://github.com/blockful/anticapture/pull/2002) [`1a91eb5`](https://github.com/blockful/anticapture/commit/1a91eb56fce13083adb903b28afed971f28fdfb7) Thanks [@pikonha](https://github.com/pikonha)! - Fix TORN votes not reflecting vote changes. TORN's governor lets a voter re-cast to change their vote, but the `Voted` handler used `onConflictDoNothing` on the unique `(voter, proposal)` row and dropped every subsequent cast — so a voter who switched from For to Against still showed as For and the proposal tally kept the stale vote. The handler now overwrites the existing row and moves the voting power between the for/against buckets on a change, while still treating an exact re-processed log (backfill/reorg) as a no-op. Requires a reindex to repopulate. + ## 1.1.0 ### Minor Changes diff --git a/apps/indexer/package.json b/apps/indexer/package.json index f54fa8080..8373823fb 100644 --- a/apps/indexer/package.json +++ b/apps/indexer/package.json @@ -1,6 +1,6 @@ { "name": "@anticapture/indexer", - "version": "1.1.0", + "version": "1.2.0", "private": true, "scripts": { "dev": "ponder dev", diff --git a/apps/offchain-indexer/CHANGELOG.md b/apps/offchain-indexer/CHANGELOG.md new file mode 100644 index 000000000..5c830fc51 --- /dev/null +++ b/apps/offchain-indexer/CHANGELOG.md @@ -0,0 +1,7 @@ +# @anticapture/offchain-indexer + +## 1.1.0 + +### Minor Changes + +- [#1998](https://github.com/blockful/anticapture/pull/1998) [`7f62a0e`](https://github.com/blockful/anticapture/commit/7f62a0ee0fafdc5f403f97c1bbd0a50eb96c66bf) Thanks [@pikonha](https://github.com/pikonha)! - Remove proposals and votes from the offchain indexer database when proposals are deleted from Snapshot. Reconciliation is bounded to proposals created in the last two weeks, so it never deletes older proposals and avoids overwhelming the Snapshot API and the indexer. diff --git a/apps/offchain-indexer/package.json b/apps/offchain-indexer/package.json index af16fb503..cc2b85887 100644 --- a/apps/offchain-indexer/package.json +++ b/apps/offchain-indexer/package.json @@ -1,6 +1,6 @@ { "name": "@anticapture/offchain-indexer", - "version": "1.0.0", + "version": "1.1.0", "private": true, "type": "module", "scripts": { diff --git a/packages/anticapture-client/CHANGELOG.md b/packages/anticapture-client/CHANGELOG.md index e59fae44a..d31321d3b 100644 --- a/packages/anticapture-client/CHANGELOG.md +++ b/packages/anticapture-client/CHANGELOG.md @@ -1,5 +1,29 @@ # @anticapture/client +## 1.4.0 + +### Minor Changes + +- [#1971](https://github.com/blockful/anticapture/pull/1971) [`4a85cf4`](https://github.com/blockful/anticapture/commit/4a85cf47d6a56b3f0c9de5da87978e0687755c55) Thanks [@brunod-e](https://github.com/brunod-e)! - Per-tenant API tokens (DEV-758): new Authful service issues, validates and revokes tenant tokens (sha256-only storage, manual minting); Gateful gains an optional token-auth middleware with Redis-cached validation, per-token rate limiting and per-tenant request metrics exposed on its `/metrics` endpoint (Prometheus counter `tenant_requests_total{tenant, route}`), enabled via `TOKEN_SERVICE_URL` (legacy `BLOCKFUL_API_TOKEN` behavior unchanged when unset). The MCP server can forward the caller's `Authorization` header to Gateful via `FORWARD_CLIENT_AUTH=true`; in that mode the shared `ANTICAPTURE_API_KEY` is never attached, so unauthenticated requests get a per-tenant 401 instead of riding the shared key. + +- [#1971](https://github.com/blockful/anticapture/pull/1971) [`e57bf06`](https://github.com/blockful/anticapture/commit/e57bf06b022728ccb9bb32f6c2622125c3d2a506) Thanks [@brunod-e](https://github.com/brunod-e)! - MCP server can now forward each caller's own Authorization header to the upstream Gateful API (enable with `FORWARD_CLIENT_AUTH=true`), laying the groundwork for per-tenant tokens with rate limiting and usage tracking. Disabled by default; existing shared-key behavior is unchanged. + +- [#1993](https://github.com/blockful/anticapture/pull/1993) [`add9bd1`](https://github.com/blockful/anticapture/commit/add9bd1e96ea89dd26f892fcd30353919d905126) Thanks [@caveman-eth](https://github.com/caveman-eth)! - Surface ENS social records and EFP stats for addresses. + - `address-enrichment` now reads the EFP `/details` endpoint, capturing the ENS `com.twitter`, `org.telegram`, `email`, and `com.github` text records plus EFP follower/following counts. These are exposed under `ens` (socials) and a new `efp` object, cached under the existing ENS TTL. EFP counts are returned even when the address has no primary ENS name. + - The Holders & Delegates drawer header now shows follower/following counts (linked to the EFP profile) and social links (X, Telegram, GitHub, email) for the selected address. + +- [#1971](https://github.com/blockful/anticapture/pull/1971) [`2dea74c`](https://github.com/blockful/anticapture/commit/2dea74c32a99f8475894df6b2e59e759ecaf233a) Thanks [@brunod-e](https://github.com/brunod-e)! - The MCP HTTP server no longer does an equality check against the shared `ANTICAPTURE_MCP_API_KEY` (now removed). Token validation is delegated to Gateful: callers present their own per-tenant token, which the MCP server forwards upstream (`FORWARD_CLIENT_AUTH=true`) for Gateful's `tokenAuthMiddleware` to validate and attribute per tenant. Validation is intentionally not duplicated at the MCP layer — Gateful owns it, including the Redis cache and fail-open fallback that keep cache-warm tenants serving through an Authful restart. + +### Patch Changes + +- [#1971](https://github.com/blockful/anticapture/pull/1971) [`51e110a`](https://github.com/blockful/anticapture/commit/51e110a12820493c453097fc069b194f0b8c08e5) Thanks [@brunod-e](https://github.com/brunod-e)! - Standardize environment-variable handling to match the API module. The MCP server now loads `.env` via dotenv and validates `PORT`, `HOST`, `ANTICAPTURE_API_URL`, `ANTICAPTURE_API_KEY`, and `FORWARD_CLIENT_AUTH` through a single zod schema instead of ad-hoc `process.env` reads. Authful's env parsing switches to the same `safeParse` + friendly-error pattern and folds `TOKEN_PLAINTEXT` into the schema so the mint script no longer reads `process.env` directly. Gateful now normalizes `TOKEN_SERVICE_URL` (trailing-slash trimming) in its zod env schema rather than manually inside `AuthfulClient`. + +- [#1995](https://github.com/blockful/anticapture/pull/1995) [`172558c`](https://github.com/blockful/anticapture/commit/172558c1b1284c085b68a8cd8316a7fb023d287f) Thanks [@pikonha](https://github.com/pikonha)! - Resolve the Gateful OpenAPI spec from the matching PR-preview Gateful on Vercel previews (derived from `VERCEL_GIT_PULL_REQUEST_ID`), so codegen-dependent builds (e.g. dashboard/storybook) no longer fail with "Config failed loading" when neither `ANTICAPTURE_API_URL` nor `RAILWAY_ENVIRONMENT_NAME` is set. + +- [#1995](https://github.com/blockful/anticapture/pull/1995) [`eaacf28`](https://github.com/blockful/anticapture/commit/eaacf28668967881c626e673f70af43de4233f74) Thanks [@pikonha](https://github.com/pikonha)! - Drop the shared-dev-Gateful fallback for untrusted/fork Vercel PR previews. Those previews get no PR-scoped Railway service, so they can never reflect a PR's API/Gateful changes — pointing them at `dev-gateful` only produced a misleading preview. The dashboard `next.config.ts` and the `@anticapture/client` Gateful OpenAPI spec resolver now rely solely on an explicit `ANTICAPTURE_API_URL` (injected by CI for trusted PRs / set on dev & production) or a Railway PR-preview environment; anything else throws instead of silently falling back. + +- [#1994](https://github.com/blockful/anticapture/pull/1994) [`d94129c`](https://github.com/blockful/anticapture/commit/d94129ca6d9d488689f7ada91db4d1c7c8020394) Thanks [@PedroBinotto](https://github.com/PedroBinotto)! - Remove the transitional single shared-token auth path now that per-tenant Authful auth is fully rolled out. Gateful drops the legacy `BLOCKFUL_API_TOKEN` `bearerAuth` fallback (and the `BLOCKFUL_API_TOKEN` env var it read); per-tenant token auth via `TOKEN_SERVICE_URL` is the only auth mode. The `@anticapture/client` package drops an orphaned, never-imported `AuthfulClient` (MCP token validation is delegated to Gateful, not performed in-process). + ## 1.3.0 ### Minor Changes diff --git a/packages/anticapture-client/package.json b/packages/anticapture-client/package.json index 378768ac6..ae366fc38 100644 --- a/packages/anticapture-client/package.json +++ b/packages/anticapture-client/package.json @@ -1,6 +1,6 @@ { "name": "@anticapture/client", - "version": "1.3.0", + "version": "1.4.0", "repository": { "url": "git+https://github.com/blockful/anticapture.git" },