@openfort/react-native 0.0.1 → 0.0.2
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 +20 -3
- package/dist/Iframe.js +42 -5
- package/dist/types/Iframe.d.ts +3 -1
- package/package.json +11 -7
- package/polyfills/index.ts +10 -0
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 {
|
|
67
|
+
import { Iframe } from '@openfort/react-native';
|
|
51
68
|
|
|
52
69
|
export default function RootLayout() {
|
|
53
70
|
|
|
54
71
|
return (
|
|
55
72
|
<>
|
|
56
|
-
<
|
|
73
|
+
<Iframe />
|
|
57
74
|
<Slot />
|
|
58
75
|
</>
|
|
59
76
|
);
|
package/dist/Iframe.js
CHANGED
|
@@ -2,11 +2,24 @@ import React from 'react';
|
|
|
2
2
|
import { useEffect, useRef, useState } from "react";
|
|
3
3
|
import { View } from "react-native";
|
|
4
4
|
import WebView from "react-native-webview";
|
|
5
|
+
const debugInjectedCode = `
|
|
6
|
+
console.log = function(...message) {
|
|
7
|
+
const safeMessage = JSON.stringify({ ...message, type: "log" });
|
|
8
|
+
window.ReactNativeWebView.postMessage(safeMessage);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
console.warn = console.log;
|
|
12
|
+
console.error = console.log;
|
|
13
|
+
console.info = console.log;
|
|
14
|
+
console.debug = console.log;
|
|
15
|
+
|
|
16
|
+
console.log("injecting Code");
|
|
17
|
+
`;
|
|
5
18
|
const injectedCode = `
|
|
6
19
|
window.parent = {};
|
|
7
|
-
window.parent.postMessage = (msg) => window.ReactNativeWebView.postMessage(JSON.stringify(msg))
|
|
8
|
-
|
|
9
|
-
export default function Iframe({ customUri }) {
|
|
20
|
+
window.parent.postMessage = (msg) => {console.log("---", msg); window.ReactNativeWebView.postMessage(JSON.stringify(msg))}
|
|
21
|
+
`;
|
|
22
|
+
export default function Iframe({ customUri, debug, debugVisible }) {
|
|
10
23
|
const webViewRef = useRef(null);
|
|
11
24
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12
25
|
const fnCallbackRef = useRef(null); // Ref to store the callback
|
|
@@ -17,6 +30,8 @@ export default function Iframe({ customUri }) {
|
|
|
17
30
|
};
|
|
18
31
|
global.openfortPostMessage = (message) => {
|
|
19
32
|
webViewRef?.current?.postMessage(JSON.stringify(message));
|
|
33
|
+
if (debug)
|
|
34
|
+
console.log("[Send message to web view]", message);
|
|
20
35
|
setLoaded(true);
|
|
21
36
|
};
|
|
22
37
|
}, [webViewRef?.current]);
|
|
@@ -24,12 +39,34 @@ export default function Iframe({ customUri }) {
|
|
|
24
39
|
// Trigger the stored callback, if any
|
|
25
40
|
if (fnCallbackRef.current) {
|
|
26
41
|
const origin = event.nativeEvent.url.endsWith('/') ? event.nativeEvent.url.slice(0, -1) : event.nativeEvent.url;
|
|
42
|
+
try {
|
|
43
|
+
const data = JSON.parse(event.nativeEvent.data);
|
|
44
|
+
if (data?.type === "log") {
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
46
|
+
const { type, ...dataWithoutType } = data;
|
|
47
|
+
if (debug)
|
|
48
|
+
console.log("[Webview LOG]", Object.values(dataWithoutType).join(", "));
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
if (debug)
|
|
52
|
+
console.log("[Webview message received]", data);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
if (debug)
|
|
57
|
+
console.log("[Webview message received]", event.nativeEvent.data);
|
|
58
|
+
}
|
|
27
59
|
fnCallbackRef.current({ origin, data: event.nativeEvent.data });
|
|
28
60
|
}
|
|
29
61
|
};
|
|
30
62
|
if (!loaded)
|
|
31
63
|
return null;
|
|
32
64
|
const uri = customUri ? customUri : "https://embedded.openfort.xyz";
|
|
33
|
-
|
|
34
|
-
|
|
65
|
+
const finalUri = new URL(uri);
|
|
66
|
+
if (debug) {
|
|
67
|
+
finalUri.searchParams.set('debug', 'true');
|
|
68
|
+
}
|
|
69
|
+
const uriWithParams = finalUri.toString();
|
|
70
|
+
return (React.createElement(View, { style: { flex: debugVisible ? 1 : 0 } },
|
|
71
|
+
React.createElement(WebView, { ref: webViewRef, source: { uri: uriWithParams }, onMessage: handleMessage, injectedJavaScript: injectedCode + (debug ? debugInjectedCode : "") })));
|
|
35
72
|
}
|
package/dist/types/Iframe.d.ts
CHANGED
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.
|
|
4
|
+
"version": "0.0.2",
|
|
5
|
+
"license": "MIT",
|
|
5
6
|
"scripts": {
|
|
6
7
|
"build": "rimraf dist && tsc",
|
|
7
8
|
"lint": "eslint . --ignore-pattern dist"
|
|
@@ -13,30 +14,33 @@
|
|
|
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
21
|
"react-native-webview": "13.12.5",
|
|
20
|
-
"text-encoding": "^0.7.0"
|
|
22
|
+
"text-encoding": "^0.7.0",
|
|
23
|
+
"uuid": "^11.1.0"
|
|
21
24
|
},
|
|
22
25
|
"peerDependencies": {
|
|
23
|
-
"@openfort/openfort-js": "^0.8.
|
|
26
|
+
"@openfort/openfort-js": "^0.8.31",
|
|
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
|
+
"@openfort/openfort-js": "^0.8.31",
|
|
33
|
+
"@types/jsrsasign": "^10.5.15",
|
|
32
34
|
"@types/react": "~18.3.12",
|
|
33
35
|
"@types/react-test-renderer": "^18.3.0",
|
|
34
36
|
"eslint": "^9.17.0",
|
|
35
37
|
"eslint-plugin-react": "^7.37.3",
|
|
36
38
|
"globals": "^15.14.0",
|
|
39
|
+
"react": "18.3.1",
|
|
40
|
+
"react-native": "0.76.5",
|
|
37
41
|
"typescript": "^5.3.3",
|
|
38
42
|
"typescript-eslint": "^8.19.0"
|
|
39
43
|
},
|
|
40
44
|
"private": false,
|
|
41
45
|
"packageManager": "yarn@1.22.17"
|
|
42
|
-
}
|
|
46
|
+
}
|
package/polyfills/index.ts
CHANGED
|
@@ -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,13 @@ const localStorage: Storage = {
|
|
|
67
70
|
global.localStorage = localStorage;
|
|
68
71
|
global.sessionStorage = localStorage;
|
|
69
72
|
|
|
73
|
+
global.JWK_UTILS = {
|
|
74
|
+
getKey: KEYUTIL.getKey,
|
|
75
|
+
parse: KJUR.jws.JWS.parse,
|
|
76
|
+
verifyJWT: KJUR.jws.JWS.verifyJWT,
|
|
77
|
+
getNow: KJUR.jws.IntDate.getNow,
|
|
78
|
+
};
|
|
79
|
+
|
|
70
80
|
// for TextEncoder and TextDecoder
|
|
71
81
|
const applyGlobalPolyfills = () => {
|
|
72
82
|
const { TextEncoder, TextDecoder } = require("text-encoding")
|