• v1.0.0-beta.21 5fc470ff13

    Morphit v1.0.0-beta.21
    All checks were successful
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Successful in 40s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Successful in 31s
    morphit-ci / ansible-lint (playbook quality gate) (push) Successful in 14s
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Successful in 17m24s
    morphit-release / Build + publish release tarball (push) Successful in 18m10s
    Stable

    agorise released this 2026-06-18 02:54:50 +00:00 | 72 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    A sign-in and account-setup release. The headline fix is that signing in with a
    Blurt posting key — and the final naming step of creating a brand-new account —
    now work in the browser; both were crashing on a low-level type mismatch that
    only showed up in the browser build, never in tests. On top of that, signing in
    got clearer end to end: you can sign in with a seed phrase, a JSON keyfile, or a
    posting key from one screen, the account-name box checks your name against Blurt
    as you type, and the error messages now tell you exactly what went wrong instead
    of a generic "import failed." New accounts now also receive all four of their
    Blurt keys, each copyable and downloadable, with a plain warning about never
    sharing them. A couple of smaller annoyances — the order book's filter menus not
    closing when you tapped away, and the FAQ search jumping the page when you
    pressed Enter — are fixed too.

    For operators: there's nothing required beyond deploying this build. Everything
    in this release is on the visitor side — there are no configuration, service, or
    command changes since beta.20.

    Fixed

    • Signing in with your posting key now works. Pasting a Blurt posting key to
      sign in was failing with a generic "import failed" message. The cause was a
      low-level type mismatch (a key was handed to the Blurt library as the wrong
      kind of byte array) that only surfaces in the browser, so automated tests
      never caught it. It's fixed, and the same fix also repairs the final
      name-registration step when creating a brand-new account, which was hitting the
      identical problem.
    • The order book's filter menus close when you tap away. Opening the Asset,
      Fiat, or Payment filter and then tapping somewhere else — including up in the
      page header — used to leave the menu stuck open. All three now close on an
      outside tap.
    • FAQ search no longer jumps the page when you press Enter. Typing a question
      and pressing Enter used to scroll the page to a seemingly random spot. Enter is
      now ignored in the FAQ search; you pick an answer from the suggestions list by
      tapping it.

    Improved

    • Sign in with a seed phrase, a JSON keyfile, or a posting key — from one
      screen.
      The sign-in screen now says exactly that, the "go back" link is a
      real link, and the wording around using a posting key is clearer about what it
      can and can't do (you can read, post, and trade, but changing your account keys
      still needs a wallet like blurtwallet.com).
    • The account-name box checks your name as you type. It strips a leading "@"
      for you, turns red if you type a character that can't be in a Blurt username,
      and — once you've typed a valid name — quietly confirms with a "looks good!"
      that the account actually exists on Blurt.
    • Much clearer sign-in errors. Instead of one generic failure message, the
      sign-in flow now tells you precisely what happened and highlights the field at
      fault: you pasted your master password instead of your posting key; you pasted
      the wrong kind of key (owner, active, or memo); the key is valid but belongs
      to a different account; the account name wasn't found; or the Blurt network
      couldn't be reached (which is a connection problem, not a problem with your
      key).
    • Pasting a seed phrase is more forgiving. If you paste a seed with commas
      between the words, or with capital letters, Morphit tidies it up for you when
      you click away from the box.

    New

    • New accounts now receive all four Blurt keys. When you create an account,
      you can reveal your owner, active, posting, and memo keys, each with a one-tap
      copy button and a "download as a text file" option. A prominent warning
      explains, in plain language, that anyone holding one of these private keys has
      full control of the account and its funds — so they should never be shared with
      Morphit, support, friends, or any website. (Morphit never uses a master
      password; these individual keys are what you keep.) The same panel is available
      later from the Back up my keys page.

    Under the hood

    • New key-handling helpers, each proven to match the Blurt library exactly.
      This release adds the ability to write out a private key in the standard Blurt
      WIF format, to recognise when someone has pasted a master password instead of a
      key (by comparing only public, on-chain information — never an oracle for any
      secret), and to derive the four-key backup set. Each is verified byte-for-byte
      against the reference Blurt library, both in-sandbox and by automated checks
      that run on every build, and none of this key material is ever logged, stored,
      or sent over the network.
    • Regression guards for the sign-in and order-book fixes. New automated
      checks pin the posting-key conversion, the master-password detection, the seed
      tidy-up, the four-key derivation, and the order book's tap-away-to-close
      behaviour, so a future edit can't quietly undo them.
    • Translation upkeep. Every new piece of on-screen text ships in all ten
      languages, and an unused leftover string was removed.
    Downloads
  • v1.0.0-beta.20 8762c4bd4a

    Morphit v1.0.0-beta.20
    Some checks failed
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Successful in 40s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Successful in 32s
    morphit-ci / ansible-lint (playbook quality gate) (push) Successful in 14s
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Failing after 6m13s
    morphit-release / Build + publish release tarball (push) Failing after 6m56s
    Stable

    agorise released this 2026-06-16 17:12:32 +00:00 | 74 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    A reliability and polish release, with most of the new work aimed at operators.
    The optional Matrix alert bot is now something you set up and verify with two
    short commands instead of hand-editing systemd, and several bugs that quietly
    stopped it from starting on a fresh deploy are fixed. On the visitor side, the
    home page and order book start faster, the "new version available" banner now
    appears promptly when you come back to the tab, and a trade chat can offer a
    one-tap prompt to turn on reply notifications. A wrong description of the
    welcome bonus in the FAQ was corrected in every language.

    For operators: there's nothing required beyond deploying this build. If you want
    Matrix alerts, morphit-ops matrix set @you:your.server turns them on and
    morphit-ops matrix test sends you a real test alert so you know delivery works
    end to end. If you upgrade from beta.19 and had configured the alert bot, this
    build is the first one where its service unit actually starts cleanly.

    Improved

    • The home page and order book load faster. The browser no longer pulls the
      elliptic-curve signing and seed-phrase libraries (and the Blurt client) into
      the very first page load on pages that don't need them. First-paint JavaScript
      on the home page dropped by roughly a fifth. These libraries still load the
      moment you do something that needs them — create an account, sign in, open an
      encrypted chat — and not before.
    • The "a new version is available" banner now appears promptly. It used to
      rely on a slow background timer, so on mobile it could take several minutes to
      notice a freshly deployed build (and on a desktop tab that was already up to
      date it correctly showed nothing). It now re-checks the instant you bring the
      tab back to the foreground, or when your connection comes back, so the prompt
      shows up within a beat of an update being available.
    • Optional reply notifications inside a trade chat. When you open a trade
      conversation, Morphit can offer a small, dismissible prompt to turn on chat
      notifications so you're pinged when the other person replies even with the tab
      closed. It rides the same private web-push mechanism the rest of the app uses
      — an opaque browser endpoint, no email, phone number, or other personal detail
      — and "Not now" hides it for good.

    For operators

    • Manage the Matrix alert bot with morphit-ops matrix. The alert bot is
      installed by default but only runs once you give it a valid Matrix username to
      notify. morphit-ops matrix set @you:your.server turns it on (and starts it),
      morphit-ops matrix clear turns it off (and stops it), and morphit-ops matrix
      shows its current status. Upgrades re-check the setting automatically, so the
      bot's running state always matches your configuration.
    • Confirm alerts actually reach you with morphit-ops matrix test. One
      command asks the running bot to send you a clearly-labelled test alert DM, so
      you can verify the whole delivery path — token, direct message, encryption —
      without the old manual log-watching dance. (The first message from the bot
      arrives as a room invite you accept once.)
    • The alert bot's service unit now starts cleanly on a fresh deploy. Three
      packaging bugs that could stop the unit from starting — a mount path it never
      used, the wrong launcher path, and an over-restrictive /proc setting that
      broke its log reader — are fixed.
    • Alerts from the shell-based system monitors now reliably reach the bot. On
      some hosts, alerts emitted by the host/disk/firewall/etc. monitors were landing
      in the journal without the unit attribution the bot filters on, so the bot
      silently missed them. They now flow through the path that carries reliable
      attribution. (If your indexer and relay are your only alert sources, you were
      unaffected either way.)

    Fixed

    • The FAQ described the welcome bonus incorrectly. One FAQ answer said new
      traders receive "10 BP delegated"; the welcome bonus is actually 10 Blurt plus
      10 Blurt Power granted (powered up and owned, not a revocable delegation),
      and it omitted the liquid Blurt entirely. This was corrected in all ten
      languages, and a related reward-description wording fix was made in the two
      Chinese locales. The fee and reward reference docs were brought into line.

    Under the hood

    • A slimmed production install can no longer break the services at launch.
      The indexer, relay, Matrix bot, and MCP server all run their TypeScript source
      through tsx at runtime, but several of them only declared tsx as a dev
      dependency — so a production-style install (npm install --omit=dev,
      NODE_ENV=production) would have stripped it and stopped those services from
      starting. tsx is now a regular dependency wherever a service runs it, and a
      new check fails the build if that ever regresses.
    • The /dev diagnostic pages are disabled in production builds. The internal
      diagnostic pages (icon catalogue, responsive-layout preview, and a hardware
      security-key probe) were reachable on a deployed site. They now return "not
      found" in a production build and are available only when running the app
      locally for development.
    • DNS-rebinding hardening on the alert bot's local self-test endpoint, plus
      a small set of audit-driven accuracy fixes across the documentation.
    • Dependency-licensing transparency. A THIRD-PARTY-LICENSES.md now documents
      that the dependency tree is otherwise fully permissive except for one
      source-available (no-military-use) runtime library, and a new check fails the
      build if any non-free dependency license is introduced.
    Downloads
  • v1.0.0-beta.19 b71c288012

    Morphit v1.0.0-beta.19
    All checks were successful
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Successful in 41s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Successful in 31s
    morphit-ci / ansible-lint (playbook quality gate) (push) Successful in 14s
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Successful in 17m4s
    morphit-release / Build + publish release tarball (push) Successful in 17m52s
    Stable

    agorise released this 2026-06-15 19:40:09 +00:00 | 75 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    A performance, privacy, and polish release. The biggest change is invisible: the
    app no longer loads its ~1 MB cryptography library until you actually need it —
    creating an account, signing in, or opening an encrypted chat — so first visits
    to the home page, the order book, and trader profiles are now markedly lighter.
    The app also stops quietly pinging every Blurt node the moment it loads, and it
    now talks directly only to the Blurt nodes that work correctly in a browser —
    both make the site quieter on the network and steadier in use. On top of that:
    primary buttons across the site now share one brand color, the onboarding wizard
    opens each step at the top, and the "a new version is available" banner no longer
    reappears in a loop.

    For operators: there's nothing to do beyond deploying this build. The browser's
    default direct-to-Blurt node list narrowed to the three nodes that serve correct
    CORS headers, but all six remain in your server-side config and CSP, so failover
    is unchanged.

    Improved

    • Pages load faster — the cryptography library is now fetched only when it's
      used.
      Morphit's signing/encryption library (libsodium) is about a megabyte,
      and it was being pulled into the very first page load on every page,
      including ones that never touch your keys (the home page, the order book, a
      trader's profile). It now loads the first time you actually do something
      cryptographic — create an account, sign in, open an encrypted chat, import a
      key — and not before. If you're just browsing offers, that megabyte never
      downloads. Nothing about the security changes: the same library does the same
      work the moment a key is involved; it simply isn't fetched until then.
    • The app no longer probes every Blurt node the moment it opens. Previously,
      opening the site kicked off background "are you alive?" requests to every
      Blurt RPC node in the pool, so the mere act of loading a page produced a
      fan-out of connections before you'd done anything. The client now reaches a
      node only when it has a real request to make, and learns which nodes are
      fastest from real traffic. Less noise on the network, and a smaller footprint
      for simply visiting.
    • Steadier direct connections to Blurt. The set of Blurt nodes the browser
      talks to directly is now limited to the three that return correct
      cross-origin (CORS) headers, so the browser no longer spends attempts on nodes
      it can't actually read from. The full set of nodes still backs the indexer and
      relay on the server side (where CORS doesn't apply), so there's no loss of
      redundancy — this only stops the browser from trying nodes a browser can't use
      anyway.
    • One consistent button color across the whole site. Primary action buttons
      — the header Start button and every filled call-to-action — now use a single
      deepened brand teal (chosen so white text clears the WCAG AA contrast bar)
      instead of a mix of greens, so the interface reads as one coherent set.

    Fixed

    • The "a new version is available" banner no longer loops. The small banner
      that appears when a new build has been deployed could, in some navigation
      patterns, re-fire repeatedly — popping back up after you'd dismissed it. It now
      attaches its update listeners once per service-worker registration and reloads
      at most once, so it shows up a single time and stays gone after you dismiss it.
    • The onboarding wizard now opens each step at the top. When the
      create-account flow advanced from one step to the next, it could leave you
      scrolled partway down the previous step. Each step now jumps to its own
      heading, so you always start reading from the top.

    Under the hood

    • libsodium now sits behind a lazy accessor ($lib/crypto/sodium): a single
      module-level sodium binding populated by a dynamic
      import('libsodium-wrappers-sumo') the first time ensureSodium() is awaited.
      Every async crypto entry point (keygen, keystore, WIF import, desktop pairing,
      backup codes, YubiKey wrap) awaits it first; the handful of synchronous
      sodium.* uses are all on paths that can only run after an async load has
      already happened. A new libsodium-not-in-baseline-closure-smoke asserts the
      ~1 MB chunk stays out of the every-page module-preload closure, and the chat
      crypto is reached via a dynamic import('$lib/chat/crypto') in the trade event
      listener so it never anchors into the baseline either.
    • The endpoint rotator no longer calls warmup() eagerly on construction. The
      method remains available for explicit opt-in, but the default path probes
      endpoints only on real demand, and the in-app endpoint list
      (EndpointList.svelte) wires deliberate probing only where a human is actually
      looking at node health.
    • The frontend default Blurt RPC pool (config.ts DEFAULT_RPC_ENDPOINTS) is
      now a curated subset — the three browser-CORS-clean nodes
      (rpc.drakernoise.com, rpc.blurt.blog, blurt-rpc.saboin.com). The full
      six-node canonical set still lives in @morphit/operator-config
      DEFAULT_BLURT_RPC_ENDPOINTS (indexer + relay), both env examples, and the
      four-surface CSP connect-src. rpc-endpoint-canon-smoke now checks the
      frontend list is a non-empty subset (no stray nodes, at least two for
      failover, all HTTPS) while still pinning the server-side env examples to the
      full set.
    • Dependency-audit review: the npm audit gate gained documented allowlist
      entries for three dev-only advisories nested under vite (a dev-server
      path-traversal and two Windows-specific issues in vite/launch-editor) and
      the form-data CRLF advisory reached only through the matrix-bot's transitive
      request dependency. None reach production — operators serve prebuilt static
      assets with no Vite dev server running, and the matrix-bot makes only outbound,
      operator-configured homeserver calls with field names it constructs itself. No
      npm audit fix, no lockfile rewrite; the lockfile stays the tested source of
      truth.
    • The press/media kit (morphit-mediakit.zip) was regenerated for the new brand
      color (the palette grew from six entries to seven), with the build script's
      palette guard and the README color-standards table updated to match.
    Downloads
  • v1.0.0-beta.18 9af0b3f55a

    Morphit v1.0.0-beta.18
    All checks were successful
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Successful in 38s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Successful in 31s
    morphit-ci / ansible-lint (playbook quality gate) (push) Successful in 14s
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Successful in 16m52s
    morphit-release / Build + publish release tarball (push) Successful in 17m28s
    Stable

    agorise released this 2026-06-15 04:53:58 +00:00 | 76 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    A small operator-quality release, plus one user-facing fix. For users: the
    printable backup card on the onboarding screen now renders instead of producing
    a blank page. For operators: it removes a recurring upgrade nag and makes the
    upgrade's "is the new build actually live?" check reliable — both changes are in
    morphit-ops upgrade itself, with nothing extra to do beyond deploying it. This
    release also expands the default Blurt RPC pool to six independent nodes and
    makes the client back off properly from rate-limited endpoints, so chain reads
    and broadcasts are steadier.

    Fixed

    • The printable backup card no longer prints as a blank page. On the
      onboarding "your keys are ready" screen, the Print backup card button could
      open the print/PDF dialog showing a single empty page. The card was isolated
      for printing using a position: fixed element inside a deliberately
      collapsed page subtree — a combination some print-to-PDF engines drop
      entirely. The card is now lifted to the top of the page and printed in normal
      flow, so it renders reliably as a single clean page. (The seed words still
      never leave your device — this is pure local rendering, no network, no PDF
      library.)
    • morphit-ops upgrade now tidies up old backups for you. Each upgrade
      keeps a rotating set of /opt/morphit.bak-<timestamp> backups and prunes
      the oldest. Previously, if you happened to have a leftover login shell, or a
      pager left open from a systemctl status …, parked inside one of those old
      backup directories, the upgrade refused to delete it and printed a [WARN]
      asking you to go find and stop those processes — on every single upgrade.
      The upgrade now prunes those backups anyway, because a parked shell or pager
      is harmless (the system keeps it running fine even though its working
      directory is gone). It still refuses to delete a backup only when something
      is genuinely running its code from it — for example, a relay or indexer you
      started by hand from the old tree — since deleting that out from under a live
      service would be unsafe.
    • The post-upgrade "is the new frontend live?" check is now reliable. That
      check, and the manual command it printed when it couldn't confirm
      automatically, used to grep a token out of the service worker — but that
      token is assembled at runtime and doesn't survive minification, so the check
      almost always came back "could not auto-verify" and the suggested
      curl … | grep -o 'morphit-[0-9]*' command returned nothing useful. It now
      reads the morphit_version field from /verify.json instead, which is a
      single, stable value. If you ever need to confirm the served version by hand,
      the upgrade now tells you to run curl -s <your-site>/verify.json and check
      that its "morphit_version" matches the build.
    • Two more Blurt RPC endpoints in the default pool, and rate-limited nodes
      now back off properly.
      The default Blurt RPC set grew from four to six
      independent public nodes (added rpc.drakernoise.com and
      blurtrpc.dagobert.uk), giving more headroom when an endpoint is slow or
      down. Separately, when a node replies 429 Too Many Requests, the client now
      parks it on a dedicated, longer cool-off (starting at 30 s and escalating)
      rather than re-trying it every couple of seconds — which was what kept
      re-triggering the rate limit. While a node is parked, requests are served
      from the other endpoints, so this is invisible in the UI; it just removes the
      needless 429 round-trips. Operators running a hand-written reverse proxy or
      CSP:
      if your deployment pins a connect-src allow-list, add the two new
      origins (https://rpc.drakernoise.com https://blurtrpc.dagobert.uk) to it
      and to your indexer/relay RPC env vars, or the browser/server will refuse to
      reach them. A fresh install picks all six up automatically.
    • A clearer error when the database URL was never expanded. If a
      MORPHIT_*_DATABASE_URL was set to a value containing a shell command
      substitution — e.g. a host written as $(docker inspect … ) — environment
      files are read literally (the shell never runs), so the substitution was
      passed through verbatim and morphit-ops failed with a baffling
      getaddrinfo ENOTFOUND $(docker inspect … ). The CLI now detects the
      unexpanded $(…)/backticks up front and tells you exactly what happened and
      how to fix it (resolve the host to a concrete IP, or publish the DB on
      localhost), instead of a cryptic DNS error.

    Under the hood

    • The backup-prune safeguard previously keyed on whether any process had its
      current working directory under the backup tree. That is a weak signal —
      it caught harmless campers (shells, less/pager processes) and blocked the
      prune forever. The new pidsRunningFrom check instead looks at whether a
      process's executable (/proc/<pid>/exe) or an absolute path in its command
      line lives under the tree, which is the real "unsafe to delete" condition;
      a process that merely parked its cwd there no longer blocks pruning. A new
      regression smoke (upgrade-backup-prune) pins this so the prune cannot
      silently revert to the cwd-blocks-forever behaviour.
    • The frontend freshness verification (readBuiltVersion /
      resolveServedVersion) now parses build/verify.json's morphit_version on both
      the built side and the served side, replacing the brittle service-worker
      token grep. The upgrade-frontend-deploy smoke was updated to cover the new
      parseVerifyJsonVersion parser.
    • The RPC pool gained a dedicated rate-limit cooldown ladder
      (DEFAULT_RATE_LIMIT_COOLDOWN_LADDER_MS, 30 s → 5 min) and an
      isRateLimitError predicate; a 429 now selects that longer ladder while
      any other transport failure stays on the generic one. The single source of
      truth for the default endpoint set (@morphit/operator-config
      DEFAULT_BLURT_RPC_ENDPOINTS) carries the two new nodes, and the
      non-importing copies (frontend config.ts, the two env examples, the
      four-surface CSP connect-src) are kept in sync by rpc-endpoint-canon and
      csp-header-consistency. New rpc-pool-smoke scenarios cover the rate-limit
      ladder and the predicate.
    • morphit-ops' database-URL reader (readDatabaseUrl) now rejects an
      unexpanded shell command substitution ($(…) / backticks) with an actionable
      message before pg is ever handed the literal host; pinned by a new
      instance-env-loader-smoke scenario.
    Downloads
  • v1.0.0-beta.17 7dc88bc1e0

    Morphit v1.0.0-beta.17
    All checks were successful
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Successful in 40s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Successful in 31s
    morphit-ci / ansible-lint (playbook quality gate) (push) Successful in 15s
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Successful in 16m49s
    morphit-release / Build + publish release tarball (push) Successful in 17m41s
    Stable

    agorise released this 2026-06-14 19:43:03 +00:00 | 77 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    A focused follow-up to beta16: it fixes a layout regression in the orderbook
    filters and makes the in-app update prompt more reliable. Everyone gets the
    fixes; there is nothing for operators to do beyond deploying it.

    Fixed

    • The orderbook filters no longer overlap each other. On narrow screens
      (most visibly on phones), opening one filter could leave a second filter
      painted on top of the open list — for example, the payment-method pills
      appeared in the middle of the open currency list, and the controls looked
      tangled together. Each filter now lifts cleanly above the others while it
      is open and the idle filters sit behind the active one's backdrop, so only
      one list shows at a time and tapping elsewhere closes it. This was a
      display-only regression introduced in beta16; if you saw it, simply
      loading this build fixes it (no cache clearing or reset needed once the
      new build is served).
    • The "A Morphit update is available" prompt is more reliable. "Load it
      now" now always applies the update — if the new version can't take over on
      its own within a moment (which can happen right after a hard refresh), the
      page reloads to pick it up instead of the button appearing to do nothing.
      A stale prompt also no longer lingers after an update has already been
      applied. (If your browser still shows a stuck prompt from before this
      build, clearing the site's data once clears it.)

    Under the hood

    • The three orderbook selects (asset, currency, payment method) are stacked
      on one page; each is its own stacking context, and at an equal z-index
      sibling contexts paint in DOM order, so an open dropdown was being painted
      under the filters that follow it. The fix makes each select's z-index
      conditional on its open state — elevated above the shared backdrop while
      open, dropped below it while closed — which both layers the open list
      correctly and lets a tap on an idle filter close the open one.
    • A regression smoke (orderbook-select-stacking) pins this layering across
      all three components so a future edit cannot silently fall back to the flat
      z-index that caused the overlap.
    • The update banner now clears its reference to a waiting service worker once
      there is nothing left to apply (so it can't show a dead prompt), and "Load
      it now" has a short fallback reload guarded against a double reload, for the
      cases where the controllerchange event never fires (an uncontrolled page
      after a hard refresh, or a wedged worker). Two new scenarios in
      service-worker-single-registration pin both behaviours.
    Downloads
  • v1.0.0-beta.16 d26b31b204

    Morphit v1.0.0-beta.16
    Some checks failed
    morphit-release / Build + publish release tarball (push) Failing after 10m30s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Has been cancelled
    morphit-ci / ansible-lint (playbook quality gate) (push) Has been cancelled
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Has been cancelled
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Has been cancelled
    Stable

    agorise released this 2026-06-14 03:09:23 +00:00 | 78 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    This release has three threads: it makes the AI-agent (MCP) endpoint actually
    reachable over the network, lands a batch of frontend fixes (chat links, the
    currency picker, RSS filtering, the onboarding flow, and the in-app update
    prompt), and — from a top-to-bottom security and correctness audit — fixes a
    moderation bug that affected operators running a separate operator account.
    Most people simply get the frontend improvements; the MCP and moderation
    items matter only to operators who enabled those features.

    Fixed

    • The MCP server now actually runs as a network service. The persistent
      morphit-mcp service previously started and then stopped within a second
      because it only spoke stdio, leaving nothing on its port and making the
      advertised /mcp discovery URL unreachable. It now serves a real HTTP
      endpoint and stays up.

    • Upgrades roll the MCP forward automatically. morphit-ops upgrade now
      redeploys the MCP's isolated copy and restarts it as part of the upgrade
      (only if you have it installed), so you no longer have to redeploy it by
      hand after every version bump.

    • Operator instance blocks now take effect when a separate operator
      account is configured.
      If you set MORPHIT_INDEXER_OPERATOR_ACCOUNT_NAME
      to an account different from your official account, accounts you blocked
      were still appearing in your instance's orderbook, live stream, RSS feeds,
      and per-account listings — the block was recorded under the operator
      account, but the public surfaces were filtering by the official account.
      They now all filter by the operator account, so a block applies
      everywhere. The same fix was extended to two further paths: your
      instance's derived (native) price feeds no longer count a blocked
      seller's orders, and morphit-ops block now writes the block under the
      operator account so the CLI command is effective too. Instances that do
      not set a separate operator account were never affected.

    • Links in chat messages are now clickable. http/https URLs that a peer
      sends are rendered as links (opening in a new tab, with no-referrer and
      no-follow), while the rest of the message stays plain, escaped text.

    • The currency picker now reaches every currency. The orderbook's fiat
      filter previously stopped at the 50th currency alphabetically (it cut off
      around Georgian lari); all currencies are now reachable.

    • RSS feeds honor every filter, including on the all-assets feed. The
      global /rss/orderbook.{xml,atom,json} feed now applies the same side,
      currency, region, payment-method, and minimum-trades filters the per-asset
      feeds already supported, and the orderbook's RSS button now appears for
      filtered all-asset views as well.

    • The onboarding "Leave anyway" button now actually leaves. A guard bug
      could re-cancel the navigation so the confirmation did nothing; it now
      navigates as expected.

    • Switching language during onboarding no longer wipes your progress.
      The language switcher now changes locale in place on the onboarding
      screens instead of reloading the page, so your current step, your inputs,
      and any freshly generated keys survive the switch.

    • The in-app "update available" prompt is back. A new version was
      silently auto-activating and reloading the page mid-task instead of
      showing the "Load it now / Later" prompt; updates are once again
      consent-gated. The offline-shell recovery is unaffected (it comes from
      network-first navigation, not from the auto-activation that was removed).

    • The "Back up your keys" help tooltip is fixed. It now flips above the
      icon when there is no room below (so it is not cut off at the bottom of
      the screen), its "Learn more" opens the FAQ in a new tab (so it cannot
      discard your in-progress keys), and tapping the info icon reliably opens
      it on touch devices.

    Added / changed

    • Hardened HTTP transport for the MCP. It binds loopback by default and
      is locked down in depth: DNS-rebinding protection (Host/Origin
      allowlists), a per-client rate limit, a hard request-body cap, a
      concurrent-connection ceiling, slow-client timeouts, and a fail-closed
      bind that refuses all-interfaces or a public address unless you explicitly
      opt in. Local AI tools that launch the server themselves (Claude Desktop,
      Cline, Cursor, and the like) keep using the simpler stdio mode — no change
      for them.

    • Works behind a dockerized reverse proxy (e.g. BunkerWeb). Because a
      containerized proxy cannot reach the host's loopback, you can bind the MCP
      to the Docker bridge gateway instead — set MORPHIT_MCP_HTTP_HOST to your
      bridge address (commonly 172.18.0.1) in /etc/morphit/mcp.env, exactly
      the way the indexer and relay are reached. Private and bridge addresses are
      allowed without any override; only public binds require one.

    • A /health endpoint so you can confirm the MCP is up directly:
      curl http://127.0.0.1:8124/health (or your bridge address). It is also
      reflected in morphit-ops health, alongside a new web-push status line in
      the relay block.

    • Lighter first load on the orderbook. The payment-method filter's data
      now loads on first use instead of shipping in the initial bundle (the
      currency filter already worked this way), so the orderbook page starts
      smaller.

    • Smaller polish. The side, minimum-trades, and sort dropdowns now show
      a pointer cursor; password, key, and seed-phrase fields carry sensible
      maximum lengths that never truncate a valid value.

    Under the hood

    • New behavioral and static smoke tests exercise the HTTP transport end to
      end (protocol handshake, tool listing, and every defense — Host/Origin
      rejection, method/path/content-type guards, body cap, rate limit, and the
      bind guard for all-interfaces and public addresses versus private and
      bridge ones). Operator-block filtering is now guarded too, so a read
      surface cannot drift back to filtering by the wrong account.
    • ADR-0044 records the MCP transport decision (stateless JSON, loopback,
      security posture, stdio retained for local agents).
    • The operator docs (OPERATIONS, run-a-node) were reconciled — they had both
      claimed the MCP was "stdio, no HTTP health endpoint" and, elsewhere,
      described an HTTP /mcp reverse-proxy block; they are now consistent, and
      a manual-install ordering issue (deploying before creating the service
      user) is fixed. A troubleshooting entry was added for broken account
      avatars, which are caused by a stale deploy-side Content-Security-Policy
      rather than by any code change.
    • Peer-sent chat links are made safe without unescaping any peer text, and
      developer-only comments were removed from the served HTML shell.
    • A top-to-bottom security and correctness audit was completed — covering
      forged-field resistance across every chain handler, the fee and feedback
      mechanics, the featured-slot auction, the smoke battery itself, and the
      operator documentation. It surfaced the operator-block account mismatch
      above; a follow-up review then found and fixed the same mismatch in two
      more places — the derived price feeds and the operator CLI — so the block
      now applies consistently across every surface. Each is covered by a
      regression test.
    Downloads
  • v1.0.0-beta.15 d503cfc2c6

    Morphit v1.0.0-beta.15
    All checks were successful
    morphit-release / Build + publish release tarball (push) Successful in 17m41s
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Successful in 36s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Successful in 27s
    morphit-ci / ansible-lint (playbook quality gate) (push) Successful in 10s
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Successful in 16m59s
    Stable

    agorise released this 2026-06-13 05:12:08 +00:00 | 79 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    A large release on top of beta.14, accumulating three batches of front-end
    polish plus a critical mobile fix, notifications and AI-agent discovery
    enabled by default, a relay security hardening, and operator-tooling
    reliability improvements. Recommended for all operators and users — the
    mobile fix in particular resolves a blank-page issue some phone users hit
    after the beta.14 deploy.

    Added

    • Web push notifications, on by default. A fresh install now generates a
      VAPID keypair once and starts the relay's web-push delivery automatically,
      so order and chat notifications work out of the box. Operators who don't
      want it can leave it off; see the run-a-node guide.

    • AI-agent discovery (MCP) enabled by default, kept isolated. The
      read-only MCP server — which lets AI agents discover a node's public
      orderbook with no KYC and hands any actual trading back to the user's own
      device — is now installed, enabled, and started automatically as a separate
      low-privilege service. You can turn it on or off at any time with sudo morphit-ops mcp.

    • The orderbook RSS feed now mirrors your full search. A per-asset feed
      URL can carry the same filters as the orderbook — buy/sell side, fiat
      currency, region, payment methods, and minimum completed-trades — and the
      feed's title spells out the active filters. The feed picker reflects the
      search you're looking at. (Feeds stay newest-first regardless of the sort
      you chose on screen, so a reader never silently misses new matching orders.)

    • A "Payment methods accepted" filter on the orderbook, with an animated
      example of the methods an instance supports and a dropdown that lists every
      method — the previous build silently cut off the end of the alphabet.

    Fixed

    • Mobile: the app no longer shows a blank/black page after an update. The
      service worker now fetches the page shell network-first and self-heals
      cached assets, so a freshly deployed update can no longer leave a stale
      shell pointing at files the server has already rotated away. (This changes
      the worker to serve the latest deployed shell rather than pinning a
      consent-gated bundle; the chain-signed release-manifest check remains in the
      app as a tamper backstop.)

    • Orderbook multi-select filters stay open. The Fiat-currency and
      Payment-method fields no longer close after each pick, so you can select
      several at once; pressing outside still closes them.

    • FAQ search lands in the right place. Clicking a search result now
      scrolls so the question title sits just below the sticky header instead of
      being pushed above the top of the screen.

    • Identicon avatars render everywhere. The generated heart avatars no
      longer appear as a broken-image icon in Safari/WebKit.

    • The "Back up your keys" tooltip is clickable. Its "Learn more" link is
      now reachable by both mouse and keyboard.

    • The printable backup card prints on a single page, instead of with
      large blank bands above and below (sometimes spilling onto extra pages).

    • The login QR code renders correctly — the finder squares now have hollow
      centers.

    • sudo morphit-ops works on systemd deployments. The Status dashboard
      and the rest of the "Check & operate" menu — the database-backed views —
      now load the instance environment, so they no longer error with "No
      database URL configured" on a systemd install.

    • morphit-ops upgrade now refreshes installed systemd unit files. A fix
      to a unit template (for example, a missing RestrictAddressFamilies entry
      that crash-looped a relay) now reaches an already-installed node on the next
      upgrade, instead of leaving the stale unit in place.

    • The relay "not reachable" health message is clearer, naming both the
      loopback and Docker-bridge addresses it tried, with a hint to check the
      relay is running and publishing its port.

    Security

    • Relay HMAC secrets can no longer ship as a publicly-known placeholder.
      The relay's invite-token and Altcha HMAC secrets now refuse a known
      placeholder value and require a minimum length when set; leaving them unset
      still produces a secure random per-boot secret (the intended default).
      Previously a manual-install operator who copied the example environment file
      and deployed it unedited could have run with a publicly-known secret —
      enabling forgeable one-time invite tokens and an Altcha proof-of-work
      bypass. Operators on the Ansible install path were never exposed (those
      values are not templated). Recommended for all manual-install operators.

    Changed

    • The signed-out top-right button now reads "Start" (was "Login /
      Register") and is sized to match the language selector.

    • The orderbook filter card is a single accessible expand/collapse
      control
      and now stays open until you collapse it (no more auto-collapsing
      on each change).

    • Onboarding polish. The two path cards ("Build Reputation" / "Maximum
      Anonymity") now read and behave as buttons, and a couple of copy lines were
      clarified (the "no account" prompt and the "this is how you appear" note).

    • Barter is now labelled "Barter (goods/services)" with an icon.

    • The animated wordmark sheen was slowed and softened.

    Under the hood

    • A comprehensive security and correctness audit ("deep-deep"). All 17
      indexer transaction handlers were read end-to-end, and the privacy defaults
      (no analytics, no third-party requests, self-hosted fonts), fee arithmetic
      (90/10 BLURT, 100/0 BTC/XMR), and operator docs were re-verified against the
      code. It surfaced the relay HMAC issue fixed above and otherwise returned a
      clean bill of health.

    • Continuous-integration reliability. Three test scripts whose pass lines
      the CI tally couldn't read (they would have been miscounted as failures)
      were corrected, the chunked test runner was repaired so the full test
      battery is runnable end-to-end, and two guard tests were added so neither
      class can recur.

    • Repo cleanliness. Removed hardcoded build-environment paths that had
      leaked into four helper scripts.

    • More install coverage. New tests cover the by-default web-push and MCP
      install wiring and its idempotency, and the media kit's README now documents
      the brand color standards.


    Upgrade notes

    A drop-in upgrade from beta.14.

    • Web push is generated and started automatically on a fresh Ansible
      install — a VAPID keypair is created once and never rotated (rotating it
      would drop every existing subscription). On an existing node, follow the
      run-a-node guide's web-push section if you want it enabled.

    • The MCP server is deployed and started automatically as an isolated
      morphit-mcp service running from its own restricted directory as a
      separate low-privilege user. Turn it off with sudo morphit-ops mcp if you
      don't want AI-agent discovery on your node.

    • Systemd units now refresh automatically on morphit-ops upgrade — no
      manual re-install is needed for unit-template fixes.

    • Manual-install operators: if you previously set
      MORPHIT_RELAY_INVITE_HMAC_SECRET or MORPHIT_RELAY_ALTCHA_HMAC_SECRET to a
      placeholder value, set them to real secrets (≥16 characters) or remove them
      to use the secure per-boot default; the relay now refuses known
      placeholders.

    • Mobile users affected by the blank-page issue get relief once this
      release is deployed. Until then, the workaround is to clear site data /
      unregister the service worker on the affected device.

    • The front-end and copy fixes appear once the indexer restarts on beta.15 and
      the frontend redeploys; the health-endpoint and tooling changes need no
      further action.

    Downloads
  • v1.0.0-beta.14 e015e25efa

    Morphit v1.0.0-beta.14
    All checks were successful
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Successful in 37s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Successful in 28s
    morphit-ci / ansible-lint (playbook quality gate) (push) Successful in 10s
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Successful in 16m16s
    morphit-release / Build + publish release tarball (push) Successful in 17m2s
    Stable

    agorise released this 2026-06-12 04:39:48 +00:00 | 80 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    A broad release on top of beta.13: operator tooling (a one-command systemd
    installer and a single consolidated node-health view), several front-end
    fixes, and warrant-canary improvements. Recommended for all operators.

    Added

    • A one-command systemd installer. sudo bash ops/scripts/install-systemd-units.sh installs the indexer, relay, and
      matrix-bot units pointed at the directory you actually cloned into —
      /opt/morphit, ~/morphit, or anywhere else — so they start without a
      hand-written systemctl edit drop-in. (The MCP server and the weekly
      mint-acts job keep running from their own restricted directories as
      separate low-privilege users; that isolation is intentional, and the
      installer leaves it alone.)

    • A consolidated "Node health" view. morphit-ops health now reports
      the indexer, the relay, the matrix-bot and MCP service states, and
      warrant-canary freshness on one screen. It also auto-discovers an
      indexer or relay bound to the Docker bridge gateway, so it no longer
      reports "could not reach the indexer" on container deployments where the
      service isn't on loopback — no flag needed.

    • The indexer health endpoint now explains its block lag. GET /v1/health already reported lag_blocks (how many blocks behind chain
      head the indexer is); it now also returns lag_blocks_note — a plain
      hint like 0-30 is normal (~90s behind; Blurt makes a block every 3s)
      so you can tell whether a given lag is fine without memorising
      thresholds. The morphit-ops health view shows the same context line.

    Fixed

    • The instances list now shows a "Syncing" status. A node that is
      reachable but still catching up to the chain after a restart shows
      Syncing rather than Unreachable, and every status pill has a
      hover tooltip explaining what it means.

    • Consistent form-field focus styling. Every input, select, and filter
      across the site now shows a single consistent focus ring; the
      Fiat-currency and Payment-method fields no longer draw a doubled border.

    • Glossary tooltips on the run-a-node guide. The hover popovers now
      position correctly near the top of the page, stay reachable long enough
      to click through to the glossary, and that deep link now works.

    • Dates display consistently. Absolute dates across the instances
      list, the explorer, profiles, and order details now render in one
      localised "11 June, 2026" format.

    • The "Load it now" update prompt is now verified end-to-end. After an
      upgrade, the tool confirms that the freshly built frontend is actually
      what your site serves, and tells you whether returning visitors will get
      the reload prompt — instead of failing silently when a stale build is
      being served.

    • A malformed line in the matrix-bot systemd unit. The
      morphit-matrix-bot.service unit carried a comment written inline after
      a directive (MemoryDenyWriteExecute=false # ...). systemd only treats
      a line as a comment when it starts with #, so it logged a parse
      warning and ignored that directive — harmless, because the ignored value
      matched the default, but noise in the journal. The comment is now on its
      own line.

    Changed

    • The orderbook filter card collapses once you apply a filter, freeing
      space above the fold; a +/x toggle re-opens it.

    • The warrant canary's news-entropy feed now defaults to Cointelegraph
      (still overridable per operator).

    • The morphit-ops main-menu headings are de-numbered so they no
      longer collide visually with the numbered actions.

    Under the hood

    • New regression smokes cover the systemd installer, the consolidated
      health view's auto-probe and canary-freshness parsing, the "Syncing"
      status path, and the upgrade's frontend-serve verification.

    • Operator-doc cleanup. The "Set up systemd services" section of the
      run-a-node guide now points at the installer, and the old systemctl edit drop-in workaround is retired.


    Upgrade notes

    A drop-in upgrade from beta.13. After upgrading you can — optionally — run
    sudo bash ops/scripts/install-systemd-units.sh to (re)install the units
    pointed at your checkout; that's useful if you'd previously hand-edited
    paths, or if any service was still running outside systemd. The
    health-endpoint note and the front-end fixes need no action — they appear
    once the indexer restarts on beta.14 and the frontend redeploys.

    Downloads
  • v1.0.0-beta.13 8526656108

    Morphit v1.0.0-beta.13
    All checks were successful
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Successful in 36s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Successful in 28s
    morphit-ci / ansible-lint (playbook quality gate) (push) Successful in 10s
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Successful in 16m28s
    morphit-release / Build + publish release tarball (push) Successful in 17m19s
    Stable

    agorise released this 2026-06-11 18:52:45 +00:00 | 81 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    A fast follow-up to beta.12 that fixes the one thing standing between an
    operator and a genuinely unattended node, plus four front-end bugs you
    would hit on day one. Headline: the relay's systemd service now
    actually starts.
    beta.12 shipped the relay as a hardened, sandboxed
    systemd unit — but the sandbox restricted network address families to
    IPv4/IPv6 only and left out Unix domain sockets, which the TypeScript
    runtime (tsx) needs for its own internal plumbing. The result was a
    relay that crash-looped at boot with EAFNOSUPPORT. This release adds
    AF_UNIX back to every affected unit, so the relay (and the MCP and
    mint-acts units) come up cleanly. Recommended for all operators, and
    especially anyone who did the beta.12 systemd migration and found the
    relay wouldn't stay up. This release also folds in a comprehensive
    pre-release hardening audit (details under the hood).

    Added

    • A "Forget address history" control. Settings → Privacy now lets you
      clear the crypto addresses Morphit remembers on your device for
      autofill — it shows how many are stored and wipes them on a two-step
      confirm. That list was always local-only and never left your device;
      this just gives you a one-tap way to clear it.

    Fixed

    • The relay systemd service no longer crash-loops at startup. The
      shipped morphit-relay.service (and morphit-mcp.service,
      morphit-relay-mint-acts.service) sandboxed the process to
      AF_INET AF_INET6 and omitted AF_UNIX. The TypeScript runner
      communicates over a Unix domain socket internally, so that socket
      failed to open and the service never came up. All three units now
      permit AF_UNIX. The indexer unit was already correct and is
      unchanged.

    • Footer "Media kit" and "PGP keys" links no longer 404. Clicking
      the media-kit (/morphit-mediakit.zip) or PGP-keys (/pgp_keys.asc)
      links — and the warrant-canary link — used to land on a blank 404 with
      a spurious language prefix in the URL. The client-side router was
      intercepting these file links and mistaking the filename for a locale.
      They now force a real browser navigation and download/open correctly.
      The same fix was applied to the corresponding links on the Security
      and "About this instance" pages.

    • Block-explorer search for an account no longer 404s. Searching the
      explorer for an account (for example @morphit) used to land on a
      blank 404 because the resulting navigation dropped the active language
      prefix from the URL. Account, transaction, and block searches now keep
      the locale prefix and resolve correctly.

    • An instance's "Registered" date now shows the real date. The
      morphit.io card on the Instances page showed Registered: — instead
      of the operator account's on-chain creation date. It now shows the
      real date (18 April, 2026 for @morphit). On upgrade the indexer also
      repairs any directory row that still carries the old placeholder, so
      the date appears after the next indexer start — without overwriting a
      genuine registration date for any real peer.

    • An instance no longer shows itself as "Unreachable." The directory
      probe was firing a real HTTP request at the node's own public URL to
      decide reachability. Many deployments can't reach their own public
      address from inside the box (no hairpin NAT / loopback), so a healthy
      node reported itself Unreachable. The probe now recognises its own
      origin and marks it reachable locally instead of round-tripping over
      the network. Real peers are still probed exactly as before.

    • Some in-app links could land on a blank 404. A sweep of internal
      links found 23 that were missing the active language prefix —
      including two-segment chat and order-detail links (which 404'd) and a
      dead "inbox" link with no destination. All now navigate correctly.

    • The MCP server no longer exposes a lister's fee mechanics to AI
      agents.
      The read-only get_listing tool (used by AI agents querying
      the public orderbook over the MCP server) returned the raw owner-view
      record, which included the lister's internal fee method and status. It
      now returns the same public-fields-only view as the search tool.

    • The "Can I trade goods and services?" FAQ now matches the full asset
      list.
      It had enumerated only 10 of the supported assets; it now uses
      drift-proof wording ("BTC, XMR, Blurt, or any other coin Morphit
      lists") that won't go stale as the asset list changes.

    Under the hood

    • Several new regression smokes guard the fixes above: the two from
      the systemd/static-asset fixes (a check that fails if any
      tsx/node/npm unit restricts address families without AF_UNIX,
      and a check that fails if any same-origin static-asset link is missing
      the attribute that forces a real navigation), plus checks that every
      internal link carries a language prefix, that every operator-doc
      section reference in the code resolves to a real heading, that the MCP
      tools only ever return public fields, and that the test battery's
      registration stays internally consistent.

    • A comprehensive pre-release audit. Before this release every code
      path was re-walked: a hostile-operator re-pass of all 17 chain-operation
      handlers (zero new findings), plus passes over navigation, cross-stack
      wiring, error/empty states, regex and SSRF defenses, database fields,
      memory teardown, broken references, the MCP server, dead translation
      keys, the ops-cli command surface, and the privacy claims in the docs
      (no-IP-logging, no-cookies, no-analytics — each verified against the
      code). Findings were fixed in-line; the items above are the
      user-visible ones.

    • The Farsi (فارسی) translation was professionally revised — 114
      strings improved by a native translator (more natural phrasing,
      properly localized UI terms, a corrected right-to-left URL), kept at
      full key parity with the other locales.

    • Broader search descriptions. The orderbook, FAQ, post-order, and
      sign-in pages now signal the full range of supported coins in their
      search-result descriptions — not just the BTC, XMR, and Blurt
      flagships — across all ten languages, so the pages can surface for
      people searching to buy or sell the other listed coins.


    Upgrade notes

    This is a drop-in upgrade from beta.12. If you did the beta.12 systemd
    migration and the relay would not stay running, this release is the fix:
    after upgrading, re-copy the shipped unit files into place and reload
    systemd (the upgrade pulls the corrected units; copying them is what
    applies the AF_UNIX change). The indexer restart also re-seeds the
    federation directory, which is what corrects the "Registered" date and
    the self-"Unreachable" status on your own instance card.

    Downloads
  • v1.0.0-beta.12 7e98f353da

    Morphit v1.0.0-beta.12
    All checks were successful
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Successful in 36s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Successful in 27s
    morphit-ci / ansible-lint (playbook quality gate) (push) Successful in 10s
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Successful in 15m50s
    morphit-release / Build + publish release tarball (push) Successful in 16m27s
    Stable

    agorise released this 2026-06-11 03:46:02 +00:00 | 82 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    A reliability, operations, and polish release. It supersedes the
    incomplete beta.11 (whose release never finished) and folds in all of
    that work, then adds the headline change: Morphit nodes now run as
    proper systemd services that survive reboots and restart themselves —
    and the relay unlocks its signing key at boot from an encrypted
    credential, so there is no plaintext passphrase on disk and nothing to
    type by hand.
    Operators no longer need to babysit screen sessions.
    The rest is a guided web-firewall installer, a smarter upgrade that
    won't strand a running node on old code, clearer menu labelling, and a
    round of front-end polish. Recommended for all operators — the
    systemd setup is a one-time migration that makes a node genuinely
    unattended (see the migration note at the end and RUN-A-MORPHIT-NODE.md
    "Set up systemd services").

    Added

    • Proper systemd services for the indexer and relay — unattended,
      reboot-surviving, self-restarting.
      The shipped
      morphit-indexer.service and morphit-relay.service now match the
      standard /opt/morphit layout, come back automatically after any
      reboot, and restart on failure. No more running the services inside
      screen and re-attaching to fix them. (If you installed somewhere
      other than /opt/morphit, a one-line systemd drop-in points the
      units at your paths — the docs show how.)

    • The relay's signing key is unlocked at boot by an encrypted
      credential — no plaintext passphrase, ever.
      The relay's active key
      stays encrypted at rest; its passphrase is supplied via a systemd
      encrypted credential (systemd-creds), bound to the host (and the
      TPM, if present) and useless if copied off the machine. The decrypted
      value lives only in RAM and never appears in the process environment
      or on persistent disk. The relay unit refuses to start without it,
      by design, so a node can never silently fall back to a plaintext
      secret.

    • A guided, plain-English BunkerWeb installer in morphit-ops. The
      web-firewall menu entry can now install and bring up the optional
      BunkerWeb WAF for you, with a confirmation at each step, instead of
      only reporting its status.

    • A no-database "is the indexer caught up?" health view in the menu.
      A new menu item checks the running indexer over HTTP (/v1/health) —
      sync state, last indexed block, and lag — and works without database
      or config access, so you can check sync as an ordinary user.

    • Menu items that need elevated privileges now say so. Every
      morphit-ops action that reads the root-owned config, touches the
      database, or runs a privileged system operation now carries a dim
      (needs sudo) on its first line. The only unprivileged actions — the
      HTTP health check and Quit — are left unmarked.

    Changed

    • The upgrade is safer about a running node. morphit-ops upgrade
      now refuses to prune an old backup directory while processes are still
      running out of it, and warns — with process IDs and restart guidance —
      if it finds an indexer or relay still running on the old code after an
      upgrade (the exact situation that can otherwise strand a node on a
      stale tree).

    • Front-end polish. A brighter, wider shimmer on the wordmark; the
      brand gradient now headlines the glossary, explorer, instances, and
      QR-pair-login pages; and the instances list renders each node's
      registration date in a clean "18 April, 2026" form (with a guard
      against placeholder/epoch dates).

    • Clearer privacy wording. The privacy/terms copy that explains what
      is public on the blockchain now reads more plainly — your offers, and
      the feedback and reviews you leave and receive, are public for
      reputation, posterity, and your own research on other traders — across
      all ten languages.

    • A brighter "update available" marker in the upgrade menu, so it
      stays legible on pale terminal themes.

    Fixed

    • The coin carousel renders left-to-right in right-to-left locales.
      The scrolling asset strip is now forced dir="ltr" so the tickers
      don't reverse under the Farsi layout.

    • The upgrade reliably refreshes the front end. The upgrade
      identifies the running front-end container by its build bind-mount and
      restarts it directly, with no assumptions about its compose project or
      container name — so the new build is actually served afterwards.

    • Removed a dead translation key. An unused "welcome" string was
      deleted from the locale files.

    Under the hood

    • systemCheck now recognises Linux Mint and verifies Postgres and
      Docker availability, and the main menu was reorganised into a
      top-to-bottom, newcomer-friendly walkthrough with plain-English
      recommendations and their trade-offs.
    • The relay's key-unlock path gained non-interactive credential-file and
      environment-variable modes — the credential file is the enforced
      production path; the environment variable is dev-only and logs a
      warning — covered by fourteen unit scenarios.
    • New regression coverage: the menu's (needs sudo) tagging is asserted
      against the live menu, so a future command can't silently gain or skip
      the marker.

    Upgrading an existing node to unattended systemd (one time). After
    you've updated the tree to beta.12:

    1. Create the relay credential, using the same passphrase you already
      use to unlock the relay key:
      echo -n '<relay-passphrase>' | sudo systemd-creds encrypt --name=relay_passphrase - /etc/morphit/relay_passphrase.cred
      
    2. Install and enable the services:
      sudo cp /opt/morphit/ops/systemd/morphit-{indexer,relay}.service /etc/systemd/system/
      sudo systemctl daemon-reload
      sudo systemctl enable --now morphit-indexer morphit-relay
      
    3. Verify: sudo systemctl status morphit-indexer morphit-relay, and
      check the indexer with morphit-ops health.
    4. Once both are healthy, stop the old screen sessions.

    See OPERATIONS.md §3 ("Relay reboot") and RUN-A-MORPHIT-NODE.md ("Set up
    systemd services") for the full details and the threat model.

    Downloads