Recommended: JavaScript SDK for React Native
While this SDK is still supported, we recommend using newer JavaScript SDK, which is optimized for React Native, but also comes with a host of other benefits.
reactNative module, which provides access to a webview component
that must be rendered to your app.
Since our client was built with a modular approach, each extension must be installed as a separate
package, so to keep the client’s package size to a minimum.
Installation
From v4.83.0 onwards, the React Native SDK requires Expo SDK 52 or later.
@dynamic-labs/react-native-extension declares expo-modules-core: >=2.0.0 as a peer dependency, which is first satisfied by Expo SDK 52. Stay on v4.82.x if you need to support Expo SDK 50 or 51.- expo
- npm
- yarn
Shell
Prebuild (Expo) / Native linking
Since our SDK relies on native modules (e.g.react-native-webview, expo-secure-store), you need to
rebuild the native layer of your app after installing.
- Expo (managed)
- EAS Build
- Bare React Native
If you’re using Expo with a managed workflow, run:Then rebuild your app with
Shell
npx expo run:ios or npx expo run:android.Usage with React Native
First, extend your client with our extension:Embedded WebView (native overlay)
Available from v4.82.0.
react-native-webview) that you mount in your app tree. If your app’s navigation
aggressively unmounts and remounts screens — or you simply want the wallet session to be
fully decoupled from your view tree — you can opt in to embedded WebView mode.
Pass embeddedWebView: true to the extension:
WKWebView on iOS, android.webkit.WebView on Android) owned outside the React Native
view tree. The overlay is created lazily on first use and retained for the process
lifetime.
On platforms other than iOS / Android (e.g. web), the
embeddedWebView flag is ignored
and the standard react-native-webview path is used.Caveats
- Same load engine as the standard path. The embedded overlay runs the same
bounded-retry load engine as the
react-native-webviewpath, so a transient failure is retried automatically and you can observe progress and trigger a manual retry through the same API — see Tuning and monitoring the WebView load. When every attempt is exhausted, the failure surfaces ascore.initialization.errorwithWebViewFailedToLoadError; treat the SDK as un-initialised in your error handler. - Singleton. Re-invoking
ReactNativeExtension({ embeddedWebView: true })(e.g. when you recreate the client with a differentenvironmentId) re-binds the JS bridge to the same native overlay rather than creating a new one. - Debugging still works via
webviewDebuggingEnabled: true(Safari Web Inspector on iOS,chrome://inspecton Android).
Tuning and monitoring the WebView load
Whichever WebView path you use, the SDK loads its webview through a bounded-retry engine: each load attempt is given a time budget, a transient failure (network drop, wedged CDN edge) is retried automatically after a short backoff, and the failure only becomes terminal once every attempt is exhausted. You can tune the budgets, observe the load in real time, and trigger a manual retry.Tuning the load budgets
Pass awebviewLoad group to the extension to tune how long each attempt may take and how
many attempts to make. Every field is optional — only tune these for pathological networks.
A misconfigured value warns and is clamped into its safe range — it never throws, so a
config typo cannot crash SDK initialisation.
Observing the load state
client.sdk.loadState is a live snapshot of the load engine. Read it through
useReactiveClient to re-render on
every change:
loadState has the following shape:
Outside React, subscribe to the
loadStateChanged event instead:
Retrying a failed load
Whenstatus is failed, call client.sdk.retry() to start a fresh load cycle. It
resolves with the load state of the next ready or failed transition. Calling it while
waiting_to_retry skips the remaining backoff and retries immediately; in any other state
it is a safe no-op.