@openfort/react-native 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Install required packages:
4
4
 
5
- Using the package manager of your preference, install the openfort-js react native library, e.g. with yarn: `yarn add @openfort/react-native`.
5
+ Using the package manager of your preference, install the openfort-js react native library, e.g. with yarn: `yarn add @openfort/react-native @openfort/openfort-js`.
6
6
 
7
7
  Since react native requires installing native dependencies directly, you also have to install these required dependencies
8
8
  ```
@@ -37,6 +37,23 @@ import "@openfort/react-native/polyfills";
37
37
  ```
38
38
  This will ensure the correct modules are imported and will ensure `openfort-js` works properly.
39
39
 
40
+ ## Configure `Openfort`
41
+
42
+ Configure openfort, the same way that you would with openfort-js
43
+ ```
44
+ import Openfort from "@openfort/openfort-js";
45
+
46
+ const openfort = new Openfort({
47
+ baseConfiguration: {
48
+ publishableKey: "YOUR_OPENFORT_PUBLISHABLE_KEY",
49
+ },
50
+ shieldConfiguration: {
51
+ shieldPublishableKey: "YOUR_SHIELD_PUBLISHABLE_KEY",
52
+ }
53
+ });
54
+ ```
55
+ Check out the documentation [here](https://www.openfort.xyz/docs/guides/getting-started#4-import-openfort-into-your-app)
56
+
40
57
  ## Render secure WebView
41
58
 
42
59
  Openfort uses a `WebView` (from `react-native-webview`) to operate as a secure environment, managing the private key and executing wallet operations. [Learn more](https://www.openfort.xyz/docs/security#embedded-self-custodial-signer).
@@ -47,13 +64,13 @@ Simply import it from `@openfort/react-native`
47
64
 
48
65
  ```
49
66
  // Sample app/_layout.tsx using expo router
50
- import { OpenfortCommunicationWebView } from '@openfort/react-native';
67
+ import { Iframe } from '@openfort/react-native';
51
68
 
52
69
  export default function RootLayout() {
53
70
 
54
71
  return (
55
72
  <>
56
- <OpenfortCommunicationWebView />
73
+ <Iframe />
57
74
  <Slot />
58
75
  </>
59
76
  );
package/dist/Iframe.js CHANGED
@@ -1,35 +1,84 @@
1
- import React from 'react';
2
- import { useEffect, useRef, useState } from "react";
3
- import { View } from "react-native";
1
+ import React, { useEffect, useRef, useState } from 'react';
2
+ import { Platform, Text, View } from "react-native";
4
3
  import WebView from "react-native-webview";
4
+ const debugInjectedCode = `
5
+ console.log = function(...message) {
6
+ const safeMessage = JSON.stringify({ ...message, type: "log" });
7
+ window.ReactNativeWebView.postMessage(safeMessage);
8
+ };
9
+
10
+ console.warn = console.log;
11
+ console.error = console.log;
12
+ console.info = console.log;
13
+ console.debug = console.log;
14
+
15
+ console.log("injecting Code");
16
+ `;
5
17
  const injectedCode = `
6
18
  window.parent = {};
7
- window.parent.postMessage = (msg) => window.ReactNativeWebView.postMessage(JSON.stringify(msg))
8
- `;
9
- export default function Iframe({ customUri }) {
19
+ window.parent.postMessage = (msg) => {console.log("---", msg); window.ReactNativeWebView.postMessage(JSON.stringify(msg))}
20
+
21
+ window.isAndroid = ${Platform.OS === 'android' ? 'true' : 'false'};
22
+ `;
23
+ export default function Iframe({ customUri, debug, debugVisible }) {
10
24
  const webViewRef = useRef(null);
11
25
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
26
  const fnCallbackRef = useRef(null); // Ref to store the callback
13
27
  const [loaded, setLoaded] = useState(false);
14
28
  useEffect(() => {
15
- global.openfortListener = (fn) => {
29
+ if (!global.openfort)
30
+ throw new Error("Openfort SDK not initialized. Please make sure to add `import '@openfort/react-native/polyfills';` at the top of you app before using the SDK.");
31
+ global.openfort.iframeListener = (fn) => {
16
32
  fnCallbackRef.current = fn; // Store the callback in the ref
17
33
  };
18
- global.openfortPostMessage = (message) => {
19
- webViewRef?.current?.postMessage(JSON.stringify(message));
34
+ global.openfort.iframePostMessage = (message) => {
20
35
  setLoaded(true);
36
+ if (!webViewRef.current) {
37
+ if (debug)
38
+ console.log("WebView is not initialized, trying to send message:", message);
39
+ return;
40
+ }
41
+ if (debug)
42
+ console.log("[Send message to web view]", message);
43
+ webViewRef.current.postMessage(JSON.stringify(message));
21
44
  };
22
45
  }, [webViewRef?.current]);
23
46
  const handleMessage = (event) => {
24
47
  // Trigger the stored callback, if any
25
48
  if (fnCallbackRef.current) {
26
49
  const origin = event.nativeEvent.url.endsWith('/') ? event.nativeEvent.url.slice(0, -1) : event.nativeEvent.url;
50
+ try {
51
+ const data = JSON.parse(event.nativeEvent.data);
52
+ if (data?.type === "log") {
53
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
54
+ const { type, ...dataWithoutType } = data;
55
+ if (debug)
56
+ console.log("[Webview LOG]", Object.values(dataWithoutType).join(", "));
57
+ }
58
+ else {
59
+ if (debug)
60
+ console.log("[Webview message received]", data);
61
+ }
62
+ }
63
+ catch {
64
+ if (debug)
65
+ console.log("[Webview message received]", event.nativeEvent.data);
66
+ }
27
67
  fnCallbackRef.current({ origin, data: event.nativeEvent.data });
28
68
  }
29
69
  };
30
70
  if (!loaded)
31
71
  return null;
32
72
  const uri = customUri ? customUri : "https://embedded.openfort.xyz";
33
- return (React.createElement(View, { style: { flex: 0 } },
34
- React.createElement(WebView, { ref: webViewRef, source: { uri: uri }, onMessage: handleMessage, injectedJavaScript: injectedCode })));
73
+ const finalUri = new URL(uri);
74
+ if (debug) {
75
+ finalUri.searchParams.set('debug', 'true');
76
+ }
77
+ const uriWithParams = finalUri.toString();
78
+ return (React.createElement(View, { style: { flex: debugVisible ? 1 : 0 } },
79
+ debugVisible &&
80
+ React.createElement(Text, null,
81
+ "Debug: ",
82
+ uriWithParams),
83
+ React.createElement(WebView, { ref: webViewRef, source: { uri: uriWithParams }, onMessage: handleMessage, injectedJavaScript: injectedCode + (debug ? debugInjectedCode : "") })));
35
84
  }
@@ -1,4 +1,6 @@
1
1
  import React from 'react';
2
- export default function Iframe({ customUri }: {
2
+ export default function Iframe({ customUri, debug, debugVisible }: {
3
3
  customUri?: string;
4
+ debug?: boolean;
5
+ debugVisible?: boolean;
4
6
  }): React.JSX.Element | null;
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@openfort/react-native",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.1",
4
+ "version": "0.0.3",
5
+ "license": "MIT",
5
6
  "scripts": {
6
7
  "build": "rimraf dist && tsc",
7
8
  "lint": "eslint . --ignore-pattern dist"
@@ -13,30 +14,32 @@
13
14
  ],
14
15
  "dependencies": {
15
16
  "events": "^3.3.0",
17
+ "jsrsasign": "^11.1.0",
16
18
  "react-native-get-random-values": "^1.11.0",
17
19
  "react-native-mmkv": "^3.2.0",
18
20
  "react-native-randombytes": "^3.6.1",
19
- "react-native-webview": "13.12.5",
20
- "text-encoding": "^0.7.0"
21
+ "react-native-webview": "^13.13.5",
22
+ "text-encoding": "^0.7.0",
23
+ "uuid": "^11.1.0"
21
24
  },
22
25
  "peerDependencies": {
23
- "@openfort/openfort-js": "^0.8.15",
26
+ "@openfort/openfort-js": "^0.8.42",
24
27
  "react": "*",
25
28
  "react-native": "*"
26
29
  },
27
30
  "devDependencies": {
28
- "@openfort/openfort-js": "^0.8.15",
29
- "react": "18.3.1",
30
- "react-native": "0.76.5",
31
31
  "@eslint/js": "^9.17.0",
32
+ "@types/jsrsasign": "^10.5.15",
32
33
  "@types/react": "~18.3.12",
33
34
  "@types/react-test-renderer": "^18.3.0",
34
35
  "eslint": "^9.17.0",
35
36
  "eslint-plugin-react": "^7.37.3",
36
37
  "globals": "^15.14.0",
38
+ "react": "18.3.1",
39
+ "react-native": "0.76.5",
37
40
  "typescript": "^5.3.3",
38
41
  "typescript-eslint": "^8.19.0"
39
42
  },
40
43
  "private": false,
41
44
  "packageManager": "yarn@1.22.17"
42
- }
45
+ }
@@ -1,4 +1,5 @@
1
1
  import { polyfillGlobal } from "react-native/Libraries/Utilities/PolyfillFunctions"
2
+ import { KEYUTIL, KJUR } from 'jsrsasign';
2
3
 
3
4
  // This is a workaround to fix the issue with process.version
4
5
  if (process.version === undefined) {
@@ -11,6 +12,8 @@ if (process.version === undefined) {
11
12
  // Crypto module needs getRandomValues
12
13
  import 'react-native-get-random-values';
13
14
 
15
+ crypto.randomUUID = require('uuid').v4;
16
+
14
17
  const MMKVStorage = require("react-native-mmkv").MMKV;
15
18
 
16
19
  // Initialize MMKVStorage
@@ -67,6 +70,14 @@ const localStorage: Storage = {
67
70
  global.localStorage = localStorage;
68
71
  global.sessionStorage = localStorage;
69
72
 
73
+ global.openfort = {}
74
+ global.openfort.jwk = {
75
+ getKey: KEYUTIL.getKey,
76
+ parse: KJUR.jws.JWS.parse,
77
+ verifyJWT: KJUR.jws.JWS.verifyJWT,
78
+ getNow: KJUR.jws.IntDate.getNow,
79
+ };
80
+
70
81
  // for TextEncoder and TextDecoder
71
82
  const applyGlobalPolyfills = () => {
72
83
  const { TextEncoder, TextDecoder } = require("text-encoding")