This is a standalone, separately installed Android source extension using Relay's Mihon-style source API. Relay verifies the APK signer against its signed repository catalog, then loads the declared RelaySource/RelaySourceFactory class from the APK.
- Replace
example.relay.sourceeverywhere with your stable package and extension ID. - Implement
RelaySourceorRelaySourceFactory; set the same stable ID inrelay.source.idand the signed catalog, then declare its class inrelay.source.class. - Set the same extension package name and APK certificate digest in the signed Relay repository catalog's
androidPackageNameandandroidSigningCertificateSha256fields. - Build Relay's source API first, then build the extension with JDK 17:
../gradlew :relay-source-api:jarfollowed by../gradlew -p relay-android-extension-template :app:assembleDebug.
Run scripts/create-signing-key.sh once, place the generated public key in repository.json and Relay's trusted repository form, then run scripts/sign-index.sh after every index.json change. Commit index.json and index.json.sig; never commit keys/.
The committed catalog is a debug-only test release. Replace its APK URL, size, APK certificate digest, and artifact digest after producing your own signed release APK.
Relay reads relay.source.api, relay.source.id, and relay.source.class from the extension manifest, verifies the API version and catalog identity, creates a child-first APK class loader, then instantiates the declared class. The dev.relay.music.source.extension feature marks the APK for source-extension tooling. Relay's source API itself is parent-loaded so the extension must use it as a compileOnly dependency and must not package a second copy.
The source owns its own HTTP API requests, authentication, and site parsing. Prefer a provider's documented API; otherwise parse only pages the user may normally access. Do not bypass authentication, subscriptions, DRM, rate limits, or access controls. Return normalised track records to Relay; never write Relay's database or control playback directly. The included demo source exposes three short test streams so browsing, search, and playback can be checked before building a real provider.
Two source shapes beyond a plain public API are allowed. Account-based sources ask the user for their own credentials through RelaySourceSetting (TEXT) — never embed or log them. Peer-to-peer sources speak the network's protocol directly, log in with the user's account, and serve transfers over http://127.0.0.1:<port>/... (loopback only; Relay's host rejects every other http:// URL). See relay-extensions/EXTENSION_AUTHORING.md §1.1 and §1.5 for the exact rules; the Soulseek source in relay-extensions is the reference implementation.
Relay sends plain text for an all-field search and title:, artist:, or album: prefixes for field searches. Empty text is always a browse request.
Because trusted source code runs in Relay's process, only add repositories whose signing keys you trust. Relay keeps an APK disabled if its signer, source metadata, API version, or entry class fails validation.