ShareRing Me Modules Developer Guide
Estimated reading time: less than 1 minuteThis guide is for external developers who want to build a Me Module for the ShareRing Me app.
- A Me Module is a web application that runs inside the ShareRing Me mobile app (in an embedded WebView).
- A Me Module communicates with the ShareRing Me app only via a message bridge (
postMessageandaddEventListener). - This document covers the Me Module API.
What you build (high-level)
- A static web app (React/Vue/Svelte/Vanilla JS—your choice)
- Hosted at a public URL (typically
https://...) - With a required
manifest.jsonat the domain root - Optionally packaged for offline caching using a zip bundle
Quickstart (recommended scaffolding)
You can use any stack. For best results (TypeScript + fast iteration + predictable build output) use Vite + React + TypeScript.
1) Scaffold a module
2) Make the build work from file:// (required for offline mode)
When ShareRing Me loads an offline bundle it loads your index.html from a local file path, so asset URLs must be relative.
Update vite.config.ts:
If you use client-side routing, note that:
- Online mode: You can use either hash routing (e.g.
/#/route) or path routing. - Offline mode: You must use hash routing (e.g.
/#/route) because your module will be loaded from local file paths.
3) Add a small bridge helper
Create src/shareringMeBridge.ts:
4) Use the bridge in your UI
Example src/App.tsx:
5) Add manifest.json (required)
Your module must serve a ShareRing manifest at /<manifest.json>.
If you use Vite, create public/manifest.json so it is available at:
- dev:
http://localhost:5173/manifest.json - prod build:
dist/manifest.json
Minimal example (online-only):
6) Build & host
Host the dist/ folder (any static hosting works).
Testing inside ShareRing Me (Developer Mode → Custom dApps)
To test a module during development:
- Ensure your ShareRing Me user has Developer Mode enabled (this is typically enabled per user/account).
- In the app, go to Settings → Developer Tool → Add Custom dApps.
- Paste your module URL and save.
- If you're using a local dev server, use a URL reachable from the device (LAN IP or a tunnel).
- Open it from the same area (or wherever your build exposes it in the app UI).
Required hosting
Your module MUST serve both index.html and manifest.json at the domain root of the host.
Important: Me modules do not support hosting in subpaths. You must use a dedicated domain or subdomain for your module.
Examples:
https://example.com→index.htmlandmanifest.jsonathttps://example.com/https://module.example.com→index.htmlandmanifest.jsonathttps://module.example.com/
If manifest.json is missing or invalid, the ShareRing Me app can refuse to load the module (especially on first open).
Manifest schema
The ShareRing Me app uses a PWA manifest with some additional attributes.
Recommended fields:
version(string): version identifier. Bump this when you deploy a new build.offline_mode(boolean): enable offline zip caching.zip_name(string): zip file name (required whenoffline_mode: true).checksum(string, optional): checksum for the zip file (see below).isMaintenance(boolean, optional): if true, the app may show a maintenance page.enable_secure_screen(boolean, optional): request screenshot prevention while your module is open.
Minimal example (online-only)
Offline-enabled example
Offline mode (zip bundle) (optional — use only when you need it)
Offline mode lets the ShareRing Me app download a zip build and load it locally.
Offline mode is powerful, but it has real trade-offs:
- It increases first-run bandwidth (the zip must be downloaded).
- It increases device storage usage (the extracted bundle is cached locally).
- It can increase memory pressure (unzipping + loading larger local assets).
When offline mode is useful
- Low / unreliable bandwidth: users can still open and use the module after a successful initial cache.
- No mobile service: modules that must work in-flight/underground/remote areas.
- Stateful/offline-first workflows: e.g. ticketing / scanning / check-in flows that must keep working and sync later.
When to avoid offline mode
- The module is used infrequently (downloading a zip is wasted bandwidth/storage).
- The module changes often (users will download many versions over time).
- The module is mostly static content that works fine online.
- The module requires real-time data or frequent API calls (offline caching provides no benefit).
1) Zip download URL
The app downloads the zip from:
Examples:
- module URL
https://example.com+zip_name: "build-1.0.3.zip"→https://example.com/build-1.0.3.zip - module URL
https://example.com/my-module+zip_name: "build-1.0.3.zip"→https://example.com/my-module/build-1.0.3.zip
2) Zip file contents (critical)
When unzipped, the app expects:
index.htmlat the root of the extracted folder- your static assets referenced by relative paths
Do not ship a zip that nests everything inside another folder level.
Good zip (root):
Bad zip (nested):
3) Checksum format
If you provide checksum, the app verifies it as:
- read the zip file as a base64 string
- compute
sha256(base64String)→ hex
Example command (Node.js) to generate this checksum:
4) Update process (recommended)
When deploying a new version:
- Build your web app (
npm run build). - Zip the build output with
index.htmlat the zip root. - Upload the zip to
<moduleUrl>/<zip_name>. - Update the domain-root
manifest.json:- bump
version - set
zip_nameto the new file - set
checksumif used
- bump
Messaging protocol
Message envelopes
All messages MUST be JSON objects.
Request (WebView → App)
Response (App → WebView)
Conventions
typeis an event name (string literal), e.g.'COMMON_APP_INFO'.payloadvaries by event:- scalar (e.g.
string,boolean) - object
- array
- scalar (e.g.
erroris optional and only present when the native handler fails.
Web → App (request)
App → Web (response)
User confirmation (PIN) for sensitive operations
Some calls require the ShareRing Me app to show a PIN confirmation UI to the user. Your module must handle:
- a delay (user is interacting)
- the user cancelling (you'll receive an error)
PIN confirmation is required for:
CRYPTO_DECRYPTCRYPTO_SIGNWALLET_SIGN_TRANSACTIONWALLET_SIGN_AND_BROADCAST_TRANSACTIONVAULT_EXEC_QUERY_SILENT
Best practices & common pitfalls
1) Always validate messages
On receive, validate:
typeexists and is a stringpayloadshape matches what your code expects
2) Treat the bridge like an RPC channel
- Don't fire many concurrent requests without a strategy.
- The safest approach is sequential RPC (the provided bridge helper).
3) Keep storage small and non-sensitive
COMMON_WRITE_ASYNC_STORAGE is for small preferences/state.
Do not store secrets. Do not assume it is backed up.
4) Offline mode: make all asset paths relative
If your module must work offline, validate by loading the built dist/index.html from disk in a browser and ensuring assets resolve correctly.
5) Be a good mobile web citizen
Design principles (mobile-first)
- Responsive layout by default: avoid fixed widths/heights; use flexible layouts (Flex/Grid),
max-width, and responsive spacing. - Safe areas / notches: ensure content isn't hidden behind rounded corners/notches. Consider using:
and CSS like:
- Touch targets: design for thumbs; keep interactive elements comfortably sized and spaced (avoid tiny icons with no padding).
- Keyboard & forms: expect the on-screen keyboard to cover parts of the page; ensure focused inputs scroll into view and primary actions remain reachable.
- Dark mode & language: respect app theme (
COMMON_APP_INFO.darkMode) and language (COMMON_APP_INFO.language). - Accessibility: good contrast, visible focus states, labels for inputs, and sensible heading structure. Support reduced motion where possible.
- Performance on mid-range devices: avoid heavy animations and huge bundles; lazy-load large features, compress images, and keep JS work per frame small.
Testing checklist (practical)
- Screen sizes: small phone, large phone, and tablet; portrait + landscape.
- Text scaling: increase system font size / display size and verify layout doesn't clip or overlap.
- Keyboard behavior: test every form field; ensure it's never obscured and the page doesn't get "stuck" after closing the keyboard.
- Theme: dark + light mode; verify contrast and any images/icons.
- Network:
- slow network (throttled)
- offline
- if using offline mode: first run (download) vs subsequent runs (cached)
- Error handling: test user cancellation / timeouts for PIN-gated and long-running operations and show clear recovery options.