Skip to content

Platform Integration Examples ​

This guide provides integration examples for embedding the P2P.org Widget across different platforms and technologies. Each platform requires specific implementation approaches while maintaining the core functionality.

Swift (iOS) ​

Integrate the widget into iOS applications using WKWebView with proper wallet injection.

Implementation ​

  • Use WKWebView with unique client url
  • injected in window must be initialized with your wallet

Code Example ​

swift
// A simple widget scene that displays web content in a SwiftUI view
public struct WidgetScene: View {
    @Environment(\.dismiss) private var dismiss

    private let url: URL
    private let title: String

    public init(url: URL, title: String) {
        self.url = url
        self.title = title
    }

    public var body: some View {
        VStack(spacing: 0) {
            WebView(url: url)
                .navigationBarTitle(title, displayMode: .inline)
        }
        .background(Colors.background)
    }
}

fileprivate struct WebView: UIViewRepresentable {
    let url: URL

    func makeUIView(context: Context) -> WKWebView {
        let webView = WKWebView()
        webView.navigationDelegate = context.coordinator
        webView.allowsBackForwardNavigationGestures = true
        return webView
    }

    func updateUIView(_ webView: WKWebView, context: Context) {
        let request = URLRequest(url: url)
        webView.load(request)
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, WKNavigationDelegate {
        var parent: WebView

        init(_ parent: WebView) {
            self.parent = parent
        }

        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            // Here must be JS injection of your wallet
            // You can check example of implementation in opensource, like here
            // https://github.com/AlphaWallet/alpha-wallet-ios/blob/master/modules/AlphaWalletBrowser/AlphaWalletBrowser/WKWebViewConfiguration.swift
        }
    }
}

View Model ​

swift
/// A simple view model for widget scenes
public struct WidgetViewModel {
    private let urlString: String
    private let widgetTitle: String

    public init(urlString: String, title: String) {
        self.urlString = urlString
        self.widgetTitle = title
    }

    /// The URL to load in the widget
    public var url: URL {
        guard let url = URL(string: urlString) else {
            // Fallback to a default URL if the provided string is invalid
            return URL(string: "https://url_of_widget_instance/")!
        }
        return url
    }

    /// The title to display in the navigation bar
    public var title: String {
        return widgetTitle
    }
}

Kotlin (Android) ​

Integrate the widget into Android applications using WebView with custom wallet injection.

Implementation ​

  • Use WebView with unique client url
  • injected in window must be initialized with your wallet

Activity Code ​

kotlin
import android.os.Bundle
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.appcompat.app.AppCompatActivity
import androidx.activity.viewModels

class WebViewActivity : AppCompatActivity() {
    private lateinit var webView: WebView
    private val viewModel: WebViewViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_webview)

        webView = findViewById(R.id.webView)
        setupWebView()

        val url = viewModel.url
        webView.loadUrl(url.toString())
    }

    private fun setupWebView() {
        webView.webViewClient = object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
                view?.loadUrl(request?.url.toString())
                return false
            }

            override fun onPageFinished(view: WebView?, url: String?) {
                super.onPageFinished(view, url)
                val jsCode = // Injection of your wallet with actual wallet object
                webView.evaluateJavascript(jsCode) { result ->

                }
            }
        }

        // WebView settings
        webView.settings.apply {
            javaScriptEnabled = true
            loadWithOverviewMode = true
            useWideViewPort = true
        }
    }
}

View Model ​

kotlin
import android.net.Uri
import androidx.lifecycle.ViewModel

class WebViewViewModel : ViewModel() {
    private val urlString: String = "https://url_of_widget_instance/" // Your dynamic URL
    private val widgetTitle: String = "Widget Title" // The widget title

    val url: Uri
        get() = Uri.parse(urlString)

    val title: String
        get() = widgetTitle
}

Layout XML ​

xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

React Native ​

Integrate the widget into React Native applications using react-native-webview.

Implementation ​

  • Use WebView with unique client url
  • injected in window must be initialized with your wallet

Code Example ​

tsx
import React, { useEffect, useRef } from "react";
import { View, Text, StyleSheet } from "react-native";
import { WebView } from "react-native-webview";

const WebViewScreen = () => {
  // Ref to interact with the WebView
  const webViewRef = useRef(null);

  const url = "https://url_of_widget_instance/";

  // UseEffect to inject JS after the page has loaded
  const onLoadEnd = () => {
    const jsCode = `
      // Injection of your wallet with actual wallet object
    `;
    // Inject JavaScript after page load
    if (webViewRef.current) {
      webViewRef.current.injectJavaScript(jsCode);
    }
  };

  return (
    <View>
      <WebView
        ref={webViewRef}
        source={{ uri: url }}
        style={styles.webview}
        javaScriptEnabled={true}
        onLoadEnd={onLoadEnd} // Trigger JS injection after page load
        startInLoadingState={true}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  webview: {
    flex: 1,
  },
});

export default WebViewScreen;

Web Integration (No Custom Wallet) ​

For web applications where you don't need custom wallet integration, use a simple iframe approach.

Implementation ​

  • Use iframe with unique client url
  • For wallet connection, RainbowKit is used internally

Code Example ​

html
<iframe src="https://url_of_widget_instance/" frameborder="0" width="100%" height="100%" />

Sending events from host to widget (postMessage) ​

If you embed the widget via an iframe and need to notify it about host-side events (e.g. theme change), use postMessage.

Host → widget message format:

js
iframeEl.contentWindow?.postMessage(
  { scope: "p2p-widget", type: "setTheme", payload: { theme: "dark" } },
  "https://url_of_widget_instance",
);

Supported message types:

  • setTheme with payload { theme: "light" | "dark" }

Security / origin allowlist:

The widget validates event.origin. Configure allowed origins contacting our team.

Responsive Integration ​

html
<div style="position: relative; width: 100%; height: 600px;">
  <iframe
    src="https://url_of_widget_instance/"
    frameborder="0"
    style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
    allowfullscreen
  />
</div>

Security Considerations ​

When integrating the widget across platforms, consider these security aspects:

JavaScript Injection ​

  • Always validate and sanitize any data before injecting JavaScript
  • Use secure communication channels between your app and the widget
  • Implement proper error handling for wallet injection failures

Network Security ​

  • Ensure HTTPS is used for all widget URLs
  • Implement certificate pinning where possible
  • Handle network failures gracefully

Wallet Security ​

  • Never expose private keys or sensitive wallet data
  • Use secure storage mechanisms for wallet credentials
  • Implement proper session management

Testing Integration ​

Platform-Specific Testing ​

iOS Testing:

  • Test on different iOS versions and device sizes
  • Verify WKWebView security settings
  • Test wallet injection scenarios

Android Testing:

  • Test on various Android versions and devices
  • Verify WebView security configurations
  • Test JavaScript bridge functionality

React Native Testing:

  • Test on both iOS and Android platforms
  • Verify WebView component behavior
  • Test navigation and state management

Web Testing:

  • Test iframe behavior across browsers
  • Verify responsive design
  • Test wallet connection flows

Troubleshooting ​

Common Issues ​

Wallet Injection Failures:

javascript
// Check if wallet injection was successful
if (typeof window.ethereum === "undefined") {
  console.error("Wallet injection failed");
  // Implement fallback or error handling
}

Network Connectivity:

javascript
// Handle network errors
webView.onerror = function (error) {
  console.error("WebView error:", error);
  // Show error message to user
};

Cross-Platform Compatibility:

  • Ensure URLs are properly formatted for each platform
  • Test deep linking and navigation flows
  • Verify consistent behavior across platforms