# Replace Tidal OAuth2 Backend with Public Web API + Self-Hosted Proxy ## Goal Replace Monochrome's Tidal OAuth2 backend (which is blocked in your country) with the SpotiFLAC tidal-web approach that uses: 1. **Tidal public web endpoints** (`tidal.com/v1/`) with a public token for metadata/search 2. **Self-hosted proxy** (SpotiFLAC Go backend) for audio streaming/downloads ## Changes ### 1. `js/HiFi.ts` - Complete rewrite - Remove OAuth2 token flow (`auth.tidal.com/v1/oauth2/token`) - Use public web token (`x-tidal-token` header, default: `49YxDN9a2aFV6RTG`) - Change API base from `api.tidal.com/v1/` to `tidal.com/v1/` - Keep all TypeScript type interfaces (TidalTrack, TidalAlbum, etc.) - Keep `TidalResponse` class - Update `query()` to use `tidal.com/v1/` endpoints - Methods updated: `getInfo`, `getTrack`, `getAlbum`, `getPlaylist`, `getPlaylistItems`, `getArtist`, `search`, `getVideo`, `getLyrics`, `getSimilarArtists`, `getSimilarAlbums` - Constructor accepts: `publicToken`, `countryCode`, `locale`, `deviceType` - Remove: `#fetchAppToken`, `#fetchAuthenticated`, `#fetchJson` (OAuth2-based), `fetchToken`, `getTrackManifest` ### 2. `js/api.js` - Rewrite LosslessAPI - `fetchWithRetry()` - Remove HiFiClient OAuth2 fallback, remove proxy instance iteration for metadata (use HiFiClient directly). Keep proxy logic only for streaming if needed. - `search()`, `searchTracks()`, `searchArtists()`, `searchAlbums()`, `searchPlaylists()`, `searchVideos()` - Update to use new HiFiClient.search() - `getAlbum()` - Update to handle pages API response structure (`pages/album` returns page modules with `ALBUM_HEADER` and `ALBUM_ITEMS`) - `getPlaylist()` - Update to use new HiFiClient methods - `getArtist()` - Update to handle pages API response (`pages/artist` returns `ARTIST_HEADER` module) - `getTrack()` - Route through self-hosted proxy instead of Tidal OpenAPI - `getStreamUrl()` - Route through self-hosted proxy - `getVideo()` - Update for new endpoints - `downloadTrack()` - Stream URLs come from self-hosted proxy - `enrichTrack()` - Update to use proxy for playback info - `normalizeTrackManifestResponse()` - Adapt to proxy response format - Keep: `getCoverUrl()`, `getCoverSrcset()`, `getArtistPictureUrl()`, `getArtistPictureSrcset()`, `getVideoCoverUrl()`, cache methods, prepare methods ### 3. `js/storage.js` - Add tidalWebSettings ```js export const tidalWebSettings = { STORAGE_KEY: 'tidal-web-settings', DEFAULT_PROXY_URL: '', // User must set their self-hosted proxy DEFAULT_PUBLIC_TOKEN: '49YxDN9a2aFV6RTG', DEFAULT_COUNTRY_CODE: 'US', getProxyUrl() { ... }, setProxyUrl(url) { ... }, getPublicToken() { ... }, setPublicToken(token) { ... }, getCountryCode() { ... }, setCountryCode(code) { ... }, }; ``` ### 4. `js/proxy-utils.js` - Simplify - Remove tidal CDN URL proxying (no longer needed - streaming goes through self-hosted proxy) - Keep CORS proxy list for any remaining direct stream URLs ### 5. `js/music-api.js` - Minimal changes - `getTrack()`, `getStreamUrl()`, `downloadTrack()` already delegate to LosslessAPI - No structural changes needed ### 6. `js/app.js` - Update initialization - Change `HiFiClient.initialize()` to pass `publicToken`, `countryCode` from tidalWebSettings - Remove OAuth2 token/tokenExpiry storage references ## Self-Hosted Proxy API Contract The self-hosted SpotiFLAC Go backend must expose: ``` POST {proxyUrl}/v1/dl/tid2 Body: { "id": "123456", "quality": "HI_RES_LOSSLESS" } Response: { "data": { "manifest": "base64-encoded-manifest", "manifestMimeType": "application/dash+xml", "audioQuality": "HI_RES_LOSSLESS", "bitDepth": 24, "sampleRate": 96000, "trackPresentation": "FULL" } } ``` Alternative response format (from mirror proxies): ```json [{ "OriginalTrackUrl": "https://direct-stream-url.flac" }] ``` ## Deployment Notes The SpotiFLAC Go backend is at `go_backend/` in the SpotiFLAC-Mobile repo: - Build: `cd go_backend && go build` - Run: `./go_backend` (listens on port) - Configure with Tidal credentials or public token ## Files Modified 1. `js/HiFi.ts` - Full rewrite 2. `js/api.js` - Major rewrite (LosslessAPI class) 3. `js/storage.js` - Add tidalWebSettings 4. `js/proxy-utils.js` - Simplify 5. `js/music-api.js` - Minimal changes 6. `js/app.js` - Update initialization ## Files NOT Modified - Server-side functions (Cloudflare Workers for SEO) - continue using OAuth2 - Frontend UI components - Player, downloads, metadata embedding logic (unchanged interfaces)