• iOS WebKit provides a built-in way to inject custom JS (WKUserScript) • web3 object is injected right after DOM initialization and before page load • This is very reliable Start navigation/ HTTP request Initialize DOM Receive HTTP response Load document Inject web3 Document ready (window.onload)
• Android WebView does not provide a way to inject JS before page load • Workaround: To inject web3 before page load, the HTTP request is intercepted and its response body is mutated ◦ <script> containing web3 is injected right after <head> Start navigation/ HTTP request Initialize DOM Receive HTTP response Load document Intercept req, look for <head>, inject <script> containing web3 Document ready (window.onload)
• Only GET requests for the main page load can be intercepted ◦ Form submissions (POST) can’t be intercepted • <head> tag must be present (without any attributes) • Cookies don’t get loaded • A more reliable and hack-free web3 injection is possible after page load ◦ However, most existing DApps expect web3 object to be available immediately
a single page app that uses AJAX to load or submit data ◦ A SPA is loaded via a single GET request ◦ Only the main page (containing SPA) needs web3 injection • If the DApp has be a backend-rendered multi-page app, ensure responses to form submissions are 302 redirects ◦ This forces browser to issue a GET request to load page content • Use localStorage/sessionStorage to store user data ◦ Cookies don’t get loaded on intercepted pages on Android • Ensure HTML contains <head> (must be exact match) Android: Cookies aren’t loaded on web3-injected pages Android: Responses to form submissions or non-GET requests don’t get web3 injection
is available immediately • Instead, poll and wait for it to become available. • In near future, DApp browsers (both mobile and desktop) may only inject web3 when requested by user for privacy
can render app unresponsive and may also inadvertently cause a DoS attack on a node • Instead of relying on events and logs, poll and read blockchain for changes ◦ Do not poll too aggressively (once every 4 or 5 seconds is OK) ◦ Near future: web3.js 1.0 and WebSocket provider will make event tracking easier Avoid Filter/Watch API
or new tabs (e.g. <a target=”_blank”>) • Avoid window.alert/confirm/prompt (blocks JS) ◦ Instead, show modal dialogs within the web app • Frequently save app state and restore state when app is reloaded ◦ Use localStorage to persist state ◦ Mobile OSes kill background apps aggressively • Use polyfills for ES6/ES7+ functions! (core-js)