Built-in DApp Browser in Mobile Crypto Wallet

NOVASOLUTIONS.TECHNOLOGY is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Built-in DApp Browser in Mobile Crypto Wallet
Complex
from 1 week to 3 months
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    761
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    649
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1071
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    884
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    466

Implementing Embedded DApp Browser in Mobile Crypto Wallets

An embedded DApp browser is one of the most complex components in a crypto wallet. It must load arbitrary web applications, inject the window.ethereum provider, handle transaction signatures, and do all this without becoming a vector for attacks on user assets.

Architecture: WebView + Provider

The browser foundation is a native WebView with injected JavaScript provider. On iOS, this is WKWebView; on Android, WebView with addJavascriptInterface. MetaMask, Trust Wallet, and Coinbase Wallet implement this with the same pattern.

The window.ethereum provider is an object that DApps expect to find in the browser. It must implement the EIP-1193 interface: a request(method, params) method for all RPC requests.

Workflow:

DApp (JS) → window.ethereum.request({method: 'eth_sendTransaction'})
  → postMessage to native layer
  → native code shows user confirmation dialog
  → user approves/rejects
  → answer returned to JS via postMessage
  → Promise resolves in DApp

Provider Injection on iOS (WKWebView)

Inject the provider script via WKUserScript with injectionTime: .atDocumentStart. Critically, use atDocumentStart—otherwise the DApp may check for window.ethereum before injection and decide the wallet doesn't exist.

let providerScript = loadProviderJS() // Read from bundle
let userScript = WKUserScript(
    source: providerScript,
    injectionTime: .atDocumentStart,
    forMainFrameOnly: false
)
webView.configuration.userContentController.addUserScript(userScript)
webView.configuration.userContentController.add(self, name: "ethereum")

The JS provider sends messages via webkit.messageHandlers.ethereum.postMessage({...}). Native code receives this in userContentController(_:didReceive:).

Return responses via webView.evaluateJavaScript("window.ethereum._resolveResponse(\(id), \(result))").

Android: addJavascriptInterface

webView.addJavascriptInterface(EthereumProvider(this), "AndroidEthereum")
webView.settings.javaScriptEnabled = true

On Android, JS interfaces work synchronously, creating a problem: @JavascriptInterface methods can't return Promises. Work around this using callbacks: JS calls AndroidEthereum.request(id, method, paramsJson), native code eventually calls webView.evaluateJavascript("resolveCallback($id, $result)", null).

Important: addJavascriptInterface is potentially dangerous. Methods annotated with @JavascriptInterface are visible to all JavaScript on the page, including malicious iframes. Only annotate necessary methods. Never add a broad API interface.

Implementing the window.ethereum Provider

A minimal implementation supports EIP-1193 methods:

// Injected provider (simplified)
window.ethereum = {
  isMetaMask: true, // many DApps check this flag
  chainId: '0x1',
  selectedAddress: null,

  request: async function({ method, params }) {
    return new Promise((resolve, reject) => {
      const id = generateId();
      pendingRequests[id] = { resolve, reject };
      webkit.messageHandlers.ethereum.postMessage({ id, method, params });
    });
  },

  on: function(event, handler) {
    // chainChanged, accountsChanged, connect, disconnect
    eventHandlers[event] = eventHandlers[event] || [];
    eventHandlers[event].push(handler);
  }
};

Methods to support:

  • eth_requestAccounts — request account access, show dialog
  • eth_accounts — list connected addresses
  • eth_chainId — current network
  • eth_sendTransaction — send transaction, requires confirmation
  • personal_sign — sign message
  • eth_signTypedData_v4 — sign structured data (EIP-712)
  • wallet_switchEthereumChain — request network switch

Security: The Top Priority

Session Isolation. Each DApp must have separate cookies and localStorage. Don't allow DApp A to read DApp B's data. On iOS, use separate WKWebViewConfiguration and WKWebsiteDataStore per tab.

URL Verification Before Injection. Don't inject the provider on arbitrary pages—only on HTTPS, only on DApp domains from your whitelist, or with explicit user consent.

Transaction Confirmation Dialog. Users must see: contract address, ETH amount (if any), transaction data in human-readable form (decoded via ABI), gas estimate, and total cost in fiat. Don't show raw hex.

eth_signTypedData_v4 (EIP-712). This is structured data—the DApp asks to sign a typed object. Parse the JSON schema and show users exactly what they're signing in human-readable form. MetaMask does this by parsing the types and message fields. Blind signing is a risk.

Phishing Protection. Verify SSL certificates, display the URL in an address bar users can't hide, block alert() and prompt() from JS (DApps shouldn't hijack native dialogs). On iOS, handle webView(_:runJavaScriptAlertPanelWithMessage:) and replace with native UIAlertController.

Multi-tab and History

A single-tab browser is the minimum. Implement:

  • Tabs with isolated data
  • Browse history (optional; many wallet users prefer privacy)
  • Bookmarks for frequently used DApps
  • Curated popular DApp list for onboarding

On iOS, keep multiple WKWebView instances in memory—they're lazy until visible. On Android, WebView is heavy; for memory savings, destroy the inactive tab's WebView and restore the URL on return.

React Native and Flutter

In React Native, use react-native-webview with injection via injectedJavaScriptBeforeContentLoaded and onMessage. Limitation: injectedJavaScriptBeforeContentLoaded on Android isn't synchronous—there's a race condition. Solution: duplicate injection via evaluateJavaScript in onLoadStart.

In Flutter, use webview_flutter with addJavaScriptChannel and runJavaScript. Similar limitations on Android.

Performance

WebView renders full web content—this is resource-intensive. On older Android devices (Chromium 80-based WebView), complex DeFi DApps may stutter. Monitor via WebViewClient.onPageStarted / onPageFinished, show a progress bar.

Preload WebView at app startup (create an instance in the background) reduces cold-start browser time from ~800ms to ~200ms.

Development Process

  1. Basic WebView with navigation, address bar, progress bar
  2. Provider injection and support for eth_requestAccounts, eth_accounts, eth_chainId
  3. Transaction dialog — display, signing, sending via RPC
  4. Advanced methodspersonal_sign, eth_signTypedData_v4, wallet_switchEthereumChain
  5. Security — isolation, phishing protection, security audit
  6. Multi-tab and UX polish

Timeline: basic browser with eth_sendTransaction—3–4 weeks. Full-featured browser with multi-tab, EIP-712 display, security audit—2–3 months.