What it is
Crypto → Wall Street for macOS is a menu-bar widget for tokenized stocks, written in 421 lines of SwiftUI with zero dependencies. The whole SODAX integration is one public HTTP endpoint. The menu bar shows the live price of the xStock you picked (for exampleTSLA $…). Click it and a small panel opens with three things:
- Live prices for the 8 xStocks: TSLA, NVDA, SPY, QQQ, MSTR, COIN, GOOGL, CRCL.
- A two-way converter. Type an amount of a coin and see how many shares it buys, or hit ⇄ to flip to shares → coin. It shows both unit rates and each leg’s USD price.
- SWAPPER ↗, which opens the Crypto → Wall Street web app where the actual swap happens.
The design idea: the price feed is the product
The web swapper does the heavy lifting: wallets, quotes, intents, settlement. A desktop companion needs one trustworthy number per asset and a cheap way to keep it fresh. SODAX already publishes that number. The solver oracle atapi.sodax.com/v1/intent/oracle is the same price feed that drives the swap engine, it is public, and it needs no API key. So the whole app reduces to: fetch one JSON array every 60 seconds, build a symbol → priceUsd map, and do division in the UI.
That is why there is no SDK in this repo. SODAX’s SDKs are TypeScript, and this is a Swift Package with a single executable target. For a read-only consumer, plain HTTP was the whole integration, which shows how open SODAX’s data is to any language.
The SODAX pieces that carried this
1. One public endpoint, no key
All of the configuration lives inCatalog.swift:
address, chainId, symbol, priceUsd, decimals, and updatedAt. The app decodes only the two fields it needs:
JSONDecoder ignores the rest, so the model stays two lines long.
2. One price per asset
The oracle lists each asset once for every network it lives on. ETH shows up under multiplechainId values, for example, which is useful for a swap engine and easy to collapse for a price widget. PriceStore keeps the first positive price it sees per symbol:
priceUsd > 0 guard keeps the converter’s division clean.
3. xStocks are just symbols with an x
On the oracle, tokenized stocks look like any other asset. Tesla is TSLAx, Nvidia is NVDAx, and so on. The catalog maps oracle symbols to display tickers:
symbol matches what the oracle returns.
4. The coin list builds itself from the feed
The coin picker lists every coin the oracle prices: the curated majors first (ETH, SOL, BTC, BNB, AVAX, USDC, USDT, bnUSD), then the long tail alphabetically._ASSET entries from the feed are filtered out, so every option is something a user can actually hold. Before the first fetch lands, it falls back to the curated list. When SODAX prices a new token, it shows up in the widget without a rebuild.
5. The converter is two prices and a division
Since both legs are priced in USD by the same feed, conversion in either direction is one line:The look
The panel uses a NieR:Automata terminal style: bone and khaki background, sepia ink, hairline boxes, monospaced labels, and SODAX Orange Sonic (#FF9048) as the accent. It forces .environment(\.colorScheme, .light) so the palette holds in both macOS appearances, and the selectors are built from a fully styleable SwiftUI Menu:
@AppStorage remembers the selected coin, stock, amount, and direction between launches.
What made it easy
- A public, keyless oracle. One
GETreturns a flat JSON array that maps straight onto aDecodablestruct. - One source of truth. The widget reads the same feed the solvers price against, so it and the swapper always agree about where the market is.
- xStocks as ordinary symbols. Tokenized equities need no special handling, just a ticker map.
- Any language works. Because the data is plain HTTP and JSON, a native Swift client was a one-file integration (
PriceStore.swiftis 52 lines).
Tips for builders
- Collapse the oracle’s per-network rows to one price per symbol for display, and filter hub-side
_ASSETsymbols out of user-facing pickers. - Use oracle prices for display and orientation, and request a real quote at swap time for anything that moves money.
- For read-only clients in any language, the oracle endpoint is all you need. Reach for the TypeScript SDK when you want to create and sign intents.
Build and distribution
It builds with the Swift command line toolchain only (xcode-select --install, no full Xcode). bundle.sh runs swift build -c release, writes an Info.plist with LSUIElement set so there is no Dock icon, and ad-hoc signs the .app. First launch is right-click, then Open.
Stack
Swift 5.9 · SwiftUIMenuBarExtra (.window style) · URLSession + JSONDecoder · @AppStorage · SODAX solver oracle (GET https://api.sodax.com/v1/intent/oracle) · no third-party dependencies
Try it
Download: v0.1.0 release (CryptoWallStreet-macOS.zip). Unzip, drag to /Applications, right-click → Open the first time.
Build from source:
swift run during development.
Repo: github.com/hazy2go/crypto-to-wallstreet-mac
The full swapper: crypto-to-wallstreet.vercel.app