luxd serves chain routes under /v1/chain, and the node, cli and sdk releases
already ship it. The deployed gateways still answer the old prefix, so remote
reads break until they are redeployed; the estate moves together rather than
sitting half converted.
Lines that record an observation - a probe, a status code, a past release -
keep the prefix they were written against, as do URLs on hosts that are not
ours. Avalanche endpoints move to /ext/bc, which is the path that host serves.
One family. Font stacks name Zen and fall back to the native faces, tokens
name the role rather than a face, and the packages that used to supply a
face now point at @hanzo/font.
Self-hosted @font-face blocks are removed rather than renamed: rewriting the
family in one would leave a src pointing at a file this repo no longer ships.
@hanzo/font carries the binaries and declares the faces, so the local copies
go with the declaration that used them.
Comments naming a face we no longer use are deleted, not reworded.
luxd serves chain APIs under one segment from constants.ChainAliasPrefix
(constants v1.6.4, node v1.36.181):
/v1/bc/<alias>/... -> /v1/chain/<alias>/...
/ext/bc/<alias>/... -> /v1/chain/<alias>/...
Observations keep their original addresses: a dated note or a recorded status
code is a fact about when it was written, not an instruction to follow.
The dev server served a dead page: nav rendered, the swap form's asset pickers
stayed loading skeletons forever, and no request to /api/settings was ever made.
No error on screen.
The requested module '/@fs/.../use-sync-external-store/shim/index.js'
does not provide an export named 'useSyncExternalStore'
mobx-react-lite does a NAMED import from that shim, which is CommonJS
(`module.exports = require('../cjs/…')`). Vite can only discover the named
exports of a CJS module by pre-bundling it; left externalised it serves the file
raw and the import throws at module scope, taking out `observer()` and with it
every observed component — which is the whole swap form.
It started when use-sync-external-store 1.6.0 added an `exports` map. The shim's
code is byte-identical to 1.4.0; only its resolution changed, and the optimizer
stopped picking it up. So this names mobx-react-lite in optimizeDeps.include
rather than pinning the version back: the CJS-ness is permanent, and a pin would
just defer the next resolution bump.
It must be mobx-react-lite and not the shim itself — under pnpm the shim exists
only inside mobx-react-lite's own node_modules, so Vite cannot resolve it from
this app and rejects the entry outright ("Failed to resolve dependency ...
present in optimizeDeps.include"). Pre-bundling the package that owns the import
resolves it from where it actually lives; the shim's source ends up inlined.
optimizeDeps is dev-only — the production build goes through rollup's commonjs
plugin, which never had this problem.
Co-authored-by: Hanzo Dev <[email protected]>
The destination picker was built from a local copy of the swap-pair table that
the client overwrote the server's response with — and the two had drifted. The
local copy was missing DOT and XRP entirely and did not list native SOL or TON
as destinations, so six assets the bridge routes could not be selected at all.
The server already sends the table it validates against; the client now uses
it. A second copy of a table is a copy that is already stale.
Reading it in one direction was the other half. 33 rows name a destination that
does not name them back — BTC lists LBTC, while LBTC lists WBTC, ZBTC and cbBTC
but not BTC — so the same route was offered inbound and refused outbound, with
nothing in the UI to say why. Wrapping and unwrapping are one route, so the
relation is symmetric by nature and is now read that way rather than written
twice; adding 33 reverse entries by hand would just re-open the gap the next
time an asset is added. 169 declared edges, 202 usable routes.
`swapPairs[src.asset].includes(...)` also threw outright for an asset with no
row of its own (LSIXR and ZSIXR are named as destinations but have none). The
throw escaped the mobx reaction, so setToNetworks never ran and the picker
rendered EMPTY — a crash that presented as a blank UI.
.env.example pointed at api-bridge.lux.network, which answers 530. The deployed
app has always called bridge-api.lux.network; copying the example into a .env
built an app that could not load its settings at all.
Co-authored-by: Hanzo Dev <[email protected]>
luxd serves exactly one prefix, /v1 (node/server/http/server.go:33), and
has never served /ext. createBridgeRPCClient's two defaults are the SDK's
whole contract for a caller who passes only nodeUrl — both pointed at a
404, and a caller had no way to see it from the outside.
Two Zoo endpoints were also aimed at the wrong network entirely:
api.lux.network/ext/bc/zoo/rpc and api.zoo.network/ext/bc/Z/rpc. Zoo is
sovereign on api.zoo.network (200200) and api.zoo-test.network (200201),
both confirmed serving /v1/bc/C/rpc; /v1/bc/Z/rpc and /v1/bc/zoo/rpc are
404. Env is the hostname, never a path segment.
Patch-bumps @luxfi/bridge 1.0.6 -> 1.0.7 so the fixed defaults ship. Note
1.0.6 was never actually on the registry — `npm view @luxfi/bridge` is a
hard 404 with no versions, while @luxfi/ui resolves fine from the same
scope, so this is a first publish rather than a re-publish.
Tests pin both defaults and assert the overrides still win. They fail on
/ext and pass on /v1. Full suite: 11 files, 94 tests.
Co-authored-by: Hanzo Dev <[email protected]>
The repo resolved three majors of the same set at once — 0.307.0 (via
@luxdefi/ui), 0.456.0 (the catalog, used by bridge3) and 1.16.0 (pinned
directly by explorer). Same import name, three different drawings. Every
app now takes lucide from `catalog:`, and an override collapses the
transitive copy, so one version resolves for the whole tree.
app/bridge3/app/components/icons/ was a second set wearing the first
one's clothes: avatar/bag/left-arrow/right-arrow were hand-drawn, typed
as LucideProps, off-grid (17x21, 9x16, 1019x1281) and filled rather than
stroked — three of them with `fill="white"` baked into the path, so they
were invisible on a light background and could never take the theme.
None had a consumer. Deleted; Lucide draws all four (User, ShoppingBag,
ChevronLeft, ChevronRight).
What stays in that directory is not an icon set: the Lux mark and the
third-party network marks are logos, and logos are not glyphs.
explorer also declared @heroicons/react and heroicons with zero imports
of either — a set you cannot see is still a set you can reach for.
Co-authored-by: Hanzo Dev <[email protected]>
TypeScript 7 is the native Go compiler and removes `baseUrl` and
`moduleResolution: node|node10`. Both appear here, so `tsc` from TS7
refuses the config outright (TS5102 / TS5108) and cannot typecheck.
`paths` targets resolve relative to `baseUrl` when it is set and relative
to the tsconfig file otherwise. Every `baseUrl` folded here already
pointed at the config's own directory, so dropping it moves nothing and
the targets are left byte-identical. Where a baseUrl pointed elsewhere,
each affected target was rewritten as join(baseUrl, target).
`moduleResolution` was chosen from the declared `module`: commonjs ->
node16, esnext/preserve -> bundler. Configs whose `module` is unset or
exotic were left alone rather than guessed at.
The result is accepted by BOTH toolchains, so nothing has to upgrade
TypeScript in lockstep. Verified on hanzo/chat packages/api: tsc 5.9
779 -> 778 errors (no regression), and tsc 7.0.2 now runs the project
in 2s where it previously refused the config.
Co-authored-by: Hanzo Dev <[email protected]>
Phase 1.5 inlined the bridge UI into pkg/bridge/src/app/ and added a
slim consumer at app/lux-bridge/. With the @luxbridge/app workspace
cycle severed there is no longer any reason to keep two tenant
directories or the legacy 400-file UI under app/bridge/.
This commit picks Path A:
- delete legacy app/bridge/ (406-file @luxbridge/app, now lives in
pkg/bridge/src/app/ as 16-file inlined SDK UI)
- delete unused app/bridge3/ (Remix @luxbridge/app-v3, never shipped)
- move app/lux-bridge/ → app/bridge/ (canonical tenant dir matches
bridge.lux.network DNS; "lux-bridge" was a temporary worktree name
needed while the legacy dir still existed)
- delete root Dockerfile.bridge-ui (referenced deleted app/bridge3
paths and the old Next.js standalone output; superseded by
app/bridge/Dockerfile which builds the Vite SPA into ghcr.io/hanzoai/spa)
After this commit:
- one and only one bridge tenant: app/bridge/ (slim, consumes @luxfi/bridge)
- SDK: pkg/bridge/ (publishes @luxfi/bridge with inlined UI)
- zero references to @luxbridge/app or @luxbridge/app-v3
- zero references to app/bridge3 or app/lux-bridge
- Terms: /terms (or NEXT_PUBLIC_TERMS_URL)
- Privacy: /privacy (or NEXT_PUBLIC_PRIVACY_URL)
- Added Regulatory Status link to lps.lux.network
- All URLs env-configurable for white-label deployments
- Update pnpm version to 9.15.0 across all workflows
- Deprecate obsolete mpc-nodes.yml and mpc-tests.yml workflows
- Fix workspace name conflict by renaming bridge3 package
- Remove test script from bridge-server workflow (no tests defined)
- All workflows now passing:
- ✅ MPC E2E Tests
- ✅ Bridge Server CI
- ✅ Integration Tests
- ✅ Build and Push Images
- ✅ Server deployment
Infrastructure components verified:
- KMS (Vault) integration working
- Bridge components tested
- Lux ID (Casdoor) configured
* added server url and version to VITE_ env
impl getAssetPrice()
simplified store
* fixed getAssetPrice;
fixed total value display;
added loading state to network cb
* module versions
* Fixed hmr issue (now using link() function in rout.tsx vs import);
Start of debounced and animated ReceiveCard;
set 1rem to 16px in lux-global-non-next.css
* fixed Asset Amount
* removed menu-icons and use @luxfi/menu-icons
cleaned up maxChars display and moved to @hanzo/ui/util;
* improvements to asset quantity input,
value display, and avail display
* improved bridge state and display;
fixed white screen bug;
removed unused component and dep;
* added server url and version to VITE_ env
impl getAssetPrice()
simplified store
* fixed getAssetPrice;
fixed total value display;
added loading state to network cb
* module versions
* Fixed hmr issue (now using link() function in rout.tsx vs import);
Start of debounced and animated ReceiveCard;
set 1rem to 16px in lux-global-non-next.css
* fixed Asset Amount
* removed menu-icons and use @luxfi/menu-icons
cleaned up maxChars display and moved to @hanzo/ui/util;
* improvements to asset quantity input,
value display, and avail display
* added server url and version to VITE_ env
impl getAssetPrice()
simplified store
fixed total value display;
added loading state to network cb
* Fixed hmr issue (now using link() function in rout.tsx vs import);
Initial debounced and animated ReceiveCard;
set 1rem to 16px in lux-global-non-next.css
added server url and version to VITE_ env
impl getAssetPrice()
simplified store
fixed getAssetPrice;
fixed total value display;
added loading state to network cb