@portal-hq/webview 4.5.1 → 4.6.0

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.
@@ -71,12 +71,14 @@ const WebviewComponent = (0, react_1.forwardRef)(({ onNavigationStateChange, onS
71
71
  uri: currentUrl,
72
72
  }), [currentUrl]);
73
73
  // Filter out "eip155:" from the gateway config.
74
- const onlyEip155GatewayConfig = {};
75
- Object.entries(portal.gatewayConfig).forEach(([key, value]) => {
76
- if (key.startsWith(`${utils_1.CHAIN_NAMESPACES.EIP155}:`)) {
77
- onlyEip155GatewayConfig[key.replace(`${utils_1.CHAIN_NAMESPACES.EIP155}:`, '')] = value;
78
- }
79
- });
74
+ const onlyEip155GatewayConfig = typeof portal.gatewayConfig === 'string'
75
+ ? portal.gatewayConfig
76
+ : Object.entries(portal.gatewayConfig).reduce((gatewayConfig, [key, value]) => {
77
+ if (key.startsWith(`${utils_1.CHAIN_NAMESPACES.EIP155}:`)) {
78
+ gatewayConfig[key.replace(`${utils_1.CHAIN_NAMESPACES.EIP155}:`, '')] = value;
79
+ }
80
+ return gatewayConfig;
81
+ }, {});
80
82
  const scriptToInject = (0, injected_provider_1.injectionScript)({
81
83
  address: walletAddress,
82
84
  apiKey: portal.apiKey,
@@ -85,7 +87,7 @@ const WebviewComponent = (0, react_1.forwardRef)(({ onNavigationStateChange, onS
85
87
  });
86
88
  const handleBackPress = () => {
87
89
  var _a;
88
- if (react_native_1.Platform.OS === 'android' && canGoBack) {
90
+ if (react_native_1.Platform.OS === 'android' && canGoBack.current) {
89
91
  (_a = webView.current) === null || _a === void 0 ? void 0 : _a.goBack();
90
92
  }
91
93
  else if (react_native_1.Platform.OS === 'ios') {
@@ -115,44 +117,45 @@ const WebviewComponent = (0, react_1.forwardRef)(({ onNavigationStateChange, onS
115
117
  });
116
118
  // Initialize Portal Bindings and set the wallet address
117
119
  (0, react_1.useEffect)(() => {
118
- if (portal && !initialized.current) {
119
- // Prevent this from running again
120
- initialized.current = true;
121
- // Bind to signature messages after signing
122
- portal.on('portal_signatureReceived', (data) => {
123
- var _a;
124
- (_a = webView.current) === null || _a === void 0 ? void 0 : _a.postMessage(JSON.stringify({
125
- type: 'portal_signatureReceived',
126
- data,
127
- }));
128
- });
129
- portal.on('chainChanged', ({ chainId }) => {
130
- var _a;
131
- setChainId(chainId);
132
- (_a = webView.current) === null || _a === void 0 ? void 0 : _a.postMessage(JSON.stringify({
133
- type: 'portal_chainChanged',
134
- data: { chainId },
135
- }));
136
- });
137
- // Bind to signing requests
138
- if (onSigningRequested) {
139
- portal.on('portal_signingRequested', onSigningRequested);
140
- }
141
- // Store the wallet address in the state
142
- const storeWalletAddress = () => __awaiter(void 0, void 0, void 0, function* () {
143
- const address = yield portal.address;
144
- setWalletAddress(address);
145
- });
146
- void storeWalletAddress();
120
+ if (!portal || initialized.current)
121
+ return;
122
+ // Prevent this from running again
123
+ initialized.current = true;
124
+ // Bind to signature messages after signing
125
+ const handleSignatureReceived = (data) => {
126
+ var _a;
127
+ (_a = webView.current) === null || _a === void 0 ? void 0 : _a.postMessage(JSON.stringify({
128
+ type: 'portal_signatureReceived',
129
+ data,
130
+ }));
131
+ };
132
+ const handleChainChanged = ({ chainId }) => {
133
+ var _a;
134
+ setChainId(chainId);
135
+ (_a = webView.current) === null || _a === void 0 ? void 0 : _a.postMessage(JSON.stringify({
136
+ type: 'portal_chainChanged',
137
+ data: { chainId },
138
+ }));
139
+ };
140
+ portal.on('portal_signatureReceived', handleSignatureReceived);
141
+ portal.on('chainChanged', handleChainChanged);
142
+ if (onSigningRequested) {
143
+ portal.on('portal_signingRequested', onSigningRequested);
147
144
  }
148
- }, [portal]);
149
- // Clean up Portal Provider bindings
150
- (0, react_1.useEffect)(() => {
145
+ // Store the wallet address in the state
146
+ const storeWalletAddress = () => __awaiter(void 0, void 0, void 0, function* () {
147
+ const address = yield portal.address;
148
+ setWalletAddress(address);
149
+ });
150
+ void storeWalletAddress();
151
151
  return () => {
152
- portal.provider.removeEventListener('portal_signatureReceived');
153
- portal.provider.removeEventListener('portal_signingRequested', onSigningRequested);
152
+ portal.removeEventListener('portal_signatureReceived', handleSignatureReceived);
153
+ portal.removeEventListener('chainChanged', handleChainChanged);
154
+ if (onSigningRequested) {
155
+ portal.removeEventListener('portal_signingRequested', onSigningRequested);
156
+ }
154
157
  };
155
- }, []);
158
+ }, [portal, onSigningRequested]);
156
159
  // Handle Android stuff
157
160
  (0, react_1.useEffect)(() => {
158
161
  const subscription = react_native_1.BackHandler.addEventListener('hardwareBackPress', handleBackPress);
@@ -163,8 +166,8 @@ const WebviewComponent = (0, react_1.forwardRef)(({ onNavigationStateChange, onS
163
166
  // Ensure that the webView ref gets forwarded to the parent component
164
167
  (0, react_1.useImperativeHandle)(webViewRef, () => webView.current);
165
168
  return (<react_native_1.View style={styles.container}>
166
- {walletAddress && source && (<react_native_webview_1.default allowsBackForwardNavigationGestures allowsFullscreenVideo={false} allowsInlineMediaPlayback={true} incognito={true} injectedJavaScriptBeforeContentLoaded={scriptToInject} injectedJavaScriptBeforeContentLoadedForMainFrameOnly={true} mediaPlaybackRequiresUserAction={true} onMessage={handlePostMessage} onNavigationStateChange={handleNavigationStateChange} ref={webView} renderLoading={() => <loading_1.default />} source={source} startInLoadingState={true} webviewDebuggingEnabled={true}/>)}
167
- </react_native_1.View>);
169
+ {walletAddress && source && (<react_native_webview_1.default allowsBackForwardNavigationGestures allowsFullscreenVideo={false} allowsInlineMediaPlayback={true} incognito={true} injectedJavaScriptBeforeContentLoaded={scriptToInject} injectedJavaScriptBeforeContentLoadedForMainFrameOnly={true} mediaPlaybackRequiresUserAction={true} onMessage={handlePostMessage} onNavigationStateChange={handleNavigationStateChange} ref={webView} renderLoading={() => <loading_1.default />} source={source} startInLoadingState={true} webviewDebuggingEnabled={true}/>)}
170
+ </react_native_1.View>);
168
171
  };
169
172
  return <Webview />;
170
173
  });
package/lib/esm/index.js CHANGED
@@ -33,12 +33,14 @@ const WebviewComponent = forwardRef(({ onNavigationStateChange, onSigningRequest
33
33
  uri: currentUrl,
34
34
  }), [currentUrl]);
35
35
  // Filter out "eip155:" from the gateway config.
36
- const onlyEip155GatewayConfig = {};
37
- Object.entries(portal.gatewayConfig).forEach(([key, value]) => {
38
- if (key.startsWith(`${CHAIN_NAMESPACES.EIP155}:`)) {
39
- onlyEip155GatewayConfig[key.replace(`${CHAIN_NAMESPACES.EIP155}:`, '')] = value;
40
- }
41
- });
36
+ const onlyEip155GatewayConfig = typeof portal.gatewayConfig === 'string'
37
+ ? portal.gatewayConfig
38
+ : Object.entries(portal.gatewayConfig).reduce((gatewayConfig, [key, value]) => {
39
+ if (key.startsWith(`${CHAIN_NAMESPACES.EIP155}:`)) {
40
+ gatewayConfig[key.replace(`${CHAIN_NAMESPACES.EIP155}:`, '')] = value;
41
+ }
42
+ return gatewayConfig;
43
+ }, {});
42
44
  const scriptToInject = injectionScript({
43
45
  address: walletAddress,
44
46
  apiKey: portal.apiKey,
@@ -47,7 +49,7 @@ const WebviewComponent = forwardRef(({ onNavigationStateChange, onSigningRequest
47
49
  });
48
50
  const handleBackPress = () => {
49
51
  var _a;
50
- if (Platform.OS === 'android' && canGoBack) {
52
+ if (Platform.OS === 'android' && canGoBack.current) {
51
53
  (_a = webView.current) === null || _a === void 0 ? void 0 : _a.goBack();
52
54
  }
53
55
  else if (Platform.OS === 'ios') {
@@ -77,44 +79,45 @@ const WebviewComponent = forwardRef(({ onNavigationStateChange, onSigningRequest
77
79
  });
78
80
  // Initialize Portal Bindings and set the wallet address
79
81
  useEffect(() => {
80
- if (portal && !initialized.current) {
81
- // Prevent this from running again
82
- initialized.current = true;
83
- // Bind to signature messages after signing
84
- portal.on('portal_signatureReceived', (data) => {
85
- var _a;
86
- (_a = webView.current) === null || _a === void 0 ? void 0 : _a.postMessage(JSON.stringify({
87
- type: 'portal_signatureReceived',
88
- data,
89
- }));
90
- });
91
- portal.on('chainChanged', ({ chainId }) => {
92
- var _a;
93
- setChainId(chainId);
94
- (_a = webView.current) === null || _a === void 0 ? void 0 : _a.postMessage(JSON.stringify({
95
- type: 'portal_chainChanged',
96
- data: { chainId },
97
- }));
98
- });
99
- // Bind to signing requests
100
- if (onSigningRequested) {
101
- portal.on('portal_signingRequested', onSigningRequested);
102
- }
103
- // Store the wallet address in the state
104
- const storeWalletAddress = () => __awaiter(void 0, void 0, void 0, function* () {
105
- const address = yield portal.address;
106
- setWalletAddress(address);
107
- });
108
- void storeWalletAddress();
82
+ if (!portal || initialized.current)
83
+ return;
84
+ // Prevent this from running again
85
+ initialized.current = true;
86
+ // Bind to signature messages after signing
87
+ const handleSignatureReceived = (data) => {
88
+ var _a;
89
+ (_a = webView.current) === null || _a === void 0 ? void 0 : _a.postMessage(JSON.stringify({
90
+ type: 'portal_signatureReceived',
91
+ data,
92
+ }));
93
+ };
94
+ const handleChainChanged = ({ chainId }) => {
95
+ var _a;
96
+ setChainId(chainId);
97
+ (_a = webView.current) === null || _a === void 0 ? void 0 : _a.postMessage(JSON.stringify({
98
+ type: 'portal_chainChanged',
99
+ data: { chainId },
100
+ }));
101
+ };
102
+ portal.on('portal_signatureReceived', handleSignatureReceived);
103
+ portal.on('chainChanged', handleChainChanged);
104
+ if (onSigningRequested) {
105
+ portal.on('portal_signingRequested', onSigningRequested);
109
106
  }
110
- }, [portal]);
111
- // Clean up Portal Provider bindings
112
- useEffect(() => {
107
+ // Store the wallet address in the state
108
+ const storeWalletAddress = () => __awaiter(void 0, void 0, void 0, function* () {
109
+ const address = yield portal.address;
110
+ setWalletAddress(address);
111
+ });
112
+ void storeWalletAddress();
113
113
  return () => {
114
- portal.provider.removeEventListener('portal_signatureReceived');
115
- portal.provider.removeEventListener('portal_signingRequested', onSigningRequested);
114
+ portal.removeEventListener('portal_signatureReceived', handleSignatureReceived);
115
+ portal.removeEventListener('chainChanged', handleChainChanged);
116
+ if (onSigningRequested) {
117
+ portal.removeEventListener('portal_signingRequested', onSigningRequested);
118
+ }
116
119
  };
117
- }, []);
120
+ }, [portal, onSigningRequested]);
118
121
  // Handle Android stuff
119
122
  useEffect(() => {
120
123
  const subscription = BackHandler.addEventListener('hardwareBackPress', handleBackPress);
@@ -125,8 +128,8 @@ const WebviewComponent = forwardRef(({ onNavigationStateChange, onSigningRequest
125
128
  // Ensure that the webView ref gets forwarded to the parent component
126
129
  useImperativeHandle(webViewRef, () => webView.current);
127
130
  return (<View style={styles.container}>
128
- {walletAddress && source && (<WebView allowsBackForwardNavigationGestures allowsFullscreenVideo={false} allowsInlineMediaPlayback={true} incognito={true} injectedJavaScriptBeforeContentLoaded={scriptToInject} injectedJavaScriptBeforeContentLoadedForMainFrameOnly={true} mediaPlaybackRequiresUserAction={true} onMessage={handlePostMessage} onNavigationStateChange={handleNavigationStateChange} ref={webView} renderLoading={() => <Loading />} source={source} startInLoadingState={true} webviewDebuggingEnabled={true}/>)}
129
- </View>);
131
+ {walletAddress && source && (<WebView allowsBackForwardNavigationGestures allowsFullscreenVideo={false} allowsInlineMediaPlayback={true} incognito={true} injectedJavaScriptBeforeContentLoaded={scriptToInject} injectedJavaScriptBeforeContentLoadedForMainFrameOnly={true} mediaPlaybackRequiresUserAction={true} onMessage={handlePostMessage} onNavigationStateChange={handleNavigationStateChange} ref={webView} renderLoading={() => <Loading />} source={source} startInLoadingState={true} webviewDebuggingEnabled={true}/>)}
132
+ </View>);
130
133
  };
131
134
  return <Webview />;
132
135
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portal-hq/webview",
3
- "version": "4.5.1",
3
+ "version": "4.6.0",
4
4
  "license": "MIT",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/esm/index",
@@ -18,9 +18,9 @@
18
18
  "test": "jest --passWithNoTests"
19
19
  },
20
20
  "dependencies": {
21
- "@portal-hq/core": "^4.5.1",
22
- "@portal-hq/injected-provider": "^4.5.1",
23
- "@portal-hq/utils": "^4.5.1"
21
+ "@portal-hq/core": "^4.6.0",
22
+ "@portal-hq/injected-provider": "^4.6.0",
23
+ "@portal-hq/utils": "^4.6.0"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@types/jest": "^29.2.0",
@@ -35,5 +35,5 @@
35
35
  "react-native": "*",
36
36
  "react-native-webview": "*"
37
37
  },
38
- "gitHead": "7f010a0c86c95b2d28daa1b6640519bb9a22920a"
38
+ "gitHead": "81e3ade6164a87aa8fc8942af4c770d04f73bc55"
39
39
  }
package/src/index.tsx CHANGED
@@ -31,189 +31,191 @@ interface WebviewProps {
31
31
  url: string
32
32
  }
33
33
 
34
- const WebviewComponent =
35
- forwardRef<WebView, WebviewProps>(
36
- ({ onNavigationStateChange, onSigningRequested, url }, webViewRef) => {
37
- const Webview: FC = () => {
38
- // Derive context.
39
- const portal = usePortal()
40
- // Derive refs.
41
- const canGoBack = useRef<boolean>(false)
42
- const initialized = useRef<boolean>(false)
43
- const webView = useRef<WebView | null>(null)
44
-
45
- // Derive state.
46
- const [currentUrl, setCurrentUrl] = useState<string>(url)
47
- const [walletAddress, setWalletAddress] = useState<string>()
48
- const [chainId, setChainId] = useState<number>(
49
- portal.chainId ?? DEFAULT_CHAIN_ID_NUMERIC,
50
- )
34
+ const WebviewComponent = forwardRef<WebView, WebviewProps>(
35
+ ({ onNavigationStateChange, onSigningRequested, url }, webViewRef) => {
36
+ const Webview: FC = () => {
37
+ // Derive context.
38
+ const portal = usePortal()
39
+ // Derive refs.
40
+ const canGoBack = useRef<boolean>(false)
41
+ const initialized = useRef<boolean>(false)
42
+ const webView = useRef<WebView | null>(null)
43
+
44
+ // Derive state.
45
+ const [currentUrl, setCurrentUrl] = useState<string>(url)
46
+ const [walletAddress, setWalletAddress] = useState<string>()
47
+ const [chainId, setChainId] = useState<number>(
48
+ portal.chainId ?? DEFAULT_CHAIN_ID_NUMERIC,
49
+ )
50
+
51
+ const source = useMemo(
52
+ (): WebViewSourceUri => ({
53
+ uri: currentUrl,
54
+ }),
55
+ [currentUrl],
56
+ )
57
+
58
+ // Filter out "eip155:" from the gateway config.
59
+ const onlyEip155GatewayConfig =
60
+ typeof portal.gatewayConfig === 'string'
61
+ ? portal.gatewayConfig
62
+ : Object.entries(portal.gatewayConfig).reduce(
63
+ (gatewayConfig, [key, value]) => {
64
+ if (key.startsWith(`${CHAIN_NAMESPACES.EIP155}:`)) {
65
+ gatewayConfig[
66
+ key.replace(`${CHAIN_NAMESPACES.EIP155}:`, '')
67
+ ] = value
68
+ }
69
+
70
+ return gatewayConfig
71
+ },
72
+ {} as Record<string, string>,
73
+ )
51
74
 
52
- const source = useMemo(
53
- (): WebViewSourceUri => ({
54
- uri: currentUrl,
55
- }),
56
- [currentUrl],
57
- )
75
+ const scriptToInject = injectionScript({
76
+ address: walletAddress as string,
77
+ apiKey: portal.apiKey,
78
+ chainId: portal.chainId,
79
+ gatewayConfig: onlyEip155GatewayConfig,
80
+ })
81
+
82
+ const handleBackPress = (): boolean => {
83
+ if (Platform.OS === 'android' && canGoBack.current) {
84
+ webView.current?.goBack()
85
+ } else if (Platform.OS === 'ios') {
86
+ // Don't need to handle this on IOS I don't think
87
+ }
88
+ return true
89
+ }
58
90
 
59
- // Filter out "eip155:" from the gateway config.
60
- const onlyEip155GatewayConfig: typeof portal.gatewayConfig = {}
61
- Object.entries(portal.gatewayConfig).forEach(([key, value]) => {
62
- if (key.startsWith(`${CHAIN_NAMESPACES.EIP155}:`)) {
63
- onlyEip155GatewayConfig[key.replace(`${CHAIN_NAMESPACES.EIP155}:`, '')] = value
64
- }
65
- })
66
-
67
- const scriptToInject = injectionScript({
68
- address: walletAddress as string,
69
- apiKey: portal.apiKey,
70
- chainId: portal.chainId,
71
- gatewayConfig: onlyEip155GatewayConfig,
72
- })
73
-
74
- const handleBackPress = (): boolean => {
75
- if (Platform.OS === 'android' && canGoBack) {
76
- webView.current?.goBack()
77
- } else if (Platform.OS === 'ios') {
78
- // Don't need to handle this on IOS I don't think
91
+ const handleNavigationStateChange = (event: WebViewNavigation) => {
92
+ const { canGoBack: _canGoBack, loading, url } = event
93
+
94
+ if (loading) {
95
+ if (onNavigationStateChange) {
96
+ onNavigationStateChange(event)
79
97
  }
80
- return true
98
+
99
+ // Set the source
100
+ setCurrentUrl(url)
101
+
102
+ canGoBack.current = _canGoBack
81
103
  }
104
+ }
82
105
 
83
- const handleNavigationStateChange = (event: WebViewNavigation) => {
84
- const { canGoBack: _canGoBack, loading, url } = event
106
+ const handlePostMessage = async (event: WebViewMessageEvent) => {
107
+ const { type, data } = JSON.parse(event.nativeEvent.data)
108
+ const { method, params, options } = data as RequestArguments
109
+
110
+ switch (type) {
111
+ case 'portal_sign':
112
+ await portal.request(
113
+ method,
114
+ params as unknown[],
115
+ `${CHAIN_NAMESPACES.EIP155}:${chainId}`,
116
+ options,
117
+ )
118
+ break
119
+ }
120
+ }
85
121
 
86
- if (loading) {
87
- if (onNavigationStateChange) {
88
- onNavigationStateChange(event)
89
- }
122
+ // Initialize Portal Bindings and set the wallet address
123
+ useEffect(() => {
124
+ if (!portal || initialized.current) return
90
125
 
91
- // Set the source
92
- setCurrentUrl(url)
126
+ // Prevent this from running again
127
+ initialized.current = true
93
128
 
94
- canGoBack.current = _canGoBack
95
- }
129
+ // Bind to signature messages after signing
130
+ const handleSignatureReceived = (data: any) => {
131
+ webView.current?.postMessage(
132
+ JSON.stringify({
133
+ type: 'portal_signatureReceived',
134
+ data,
135
+ }),
136
+ )
96
137
  }
97
138
 
98
- const handlePostMessage = async (event: WebViewMessageEvent) => {
99
- const { type, data } = JSON.parse(event.nativeEvent.data)
100
- const { method, params, options } = data as RequestArguments
101
-
102
- switch (type) {
103
- case 'portal_sign':
104
- await portal.request(
105
- method,
106
- params as unknown[],
107
- `${CHAIN_NAMESPACES.EIP155}:${chainId}`,
108
- options,
109
- )
110
- break
111
- }
139
+ const handleChainChanged = ({ chainId }: { chainId: number }) => {
140
+ setChainId(chainId)
141
+ webView.current?.postMessage(
142
+ JSON.stringify({
143
+ type: 'portal_chainChanged',
144
+ data: { chainId },
145
+ }),
146
+ )
112
147
  }
113
148
 
114
- // Initialize Portal Bindings and set the wallet address
115
- useEffect(() => {
116
- if (portal && !initialized.current) {
117
- // Prevent this from running again
118
- initialized.current = true
119
-
120
- // Bind to signature messages after signing
121
- portal.on('portal_signatureReceived', (data: any) => {
122
- webView.current?.postMessage(
123
- JSON.stringify({
124
- type: 'portal_signatureReceived',
125
- data,
126
- }),
127
- )
128
- })
129
-
130
- portal.on('chainChanged', ({ chainId }: { chainId: number }) => {
131
- setChainId(chainId)
132
- webView.current?.postMessage(
133
- JSON.stringify({
134
- type: 'portal_chainChanged',
135
- data: { chainId },
136
- }),
137
- )
138
- })
139
-
140
- // Bind to signing requests
141
- if (onSigningRequested) {
142
- portal.on('portal_signingRequested', onSigningRequested)
143
- }
144
-
145
- // Store the wallet address in the state
146
- const storeWalletAddress = async () => {
147
- const address = await portal.address
148
- setWalletAddress(address)
149
- }
150
-
151
- void storeWalletAddress()
152
- }
153
- }, [portal])
154
-
155
- // Clean up Portal Provider bindings
156
- useEffect(() => {
157
- return () => {
158
- portal.provider.removeEventListener('portal_signatureReceived')
159
- portal.provider.removeEventListener(
160
- 'portal_signingRequested',
161
- onSigningRequested,
162
- )
163
- }
164
- }, [])
149
+ portal.on('portal_signatureReceived', handleSignatureReceived)
150
+ portal.on('chainChanged', handleChainChanged)
165
151
 
166
- // Handle Android stuff
167
- useEffect(() => {
168
- const subscription = BackHandler.addEventListener(
169
- 'hardwareBackPress',
170
- handleBackPress,
171
- )
152
+ if (onSigningRequested) {
153
+ portal.on('portal_signingRequested', onSigningRequested)
154
+ }
172
155
 
173
- return () => {
174
- subscription.remove()
175
- }
176
- }, [])
177
-
178
- // Ensure that the webView ref gets forwarded to the parent component
179
- useImperativeHandle(webViewRef, () => webView.current!)
180
-
181
- return (
182
- <View style={styles.container}>
183
- {walletAddress && source && (
184
- <WebView
185
- allowsBackForwardNavigationGestures
186
- allowsFullscreenVideo={false}
187
- allowsInlineMediaPlayback={true}
188
- incognito={true}
189
- injectedJavaScriptBeforeContentLoaded={scriptToInject}
190
- injectedJavaScriptBeforeContentLoadedForMainFrameOnly={true}
191
- mediaPlaybackRequiresUserAction={true}
192
- onMessage={handlePostMessage}
193
- onNavigationStateChange={handleNavigationStateChange}
194
- ref={webView}
195
- renderLoading={() => <Loading />}
196
- source={source}
197
- startInLoadingState={true}
198
- webviewDebuggingEnabled={true}
199
- />
200
- )}
201
- </View>
202
- )
203
- }
156
+ // Store the wallet address in the state
157
+ const storeWalletAddress = async () => {
158
+ const address = await portal.address
159
+ setWalletAddress(address)
160
+ }
204
161
 
205
- return <Webview />
206
- },
207
- )
162
+ void storeWalletAddress()
208
163
 
164
+ return () => {
165
+ portal.removeEventListener('portal_signatureReceived', handleSignatureReceived)
166
+ portal.removeEventListener('chainChanged', handleChainChanged)
167
+ if (onSigningRequested) {
168
+ portal.removeEventListener('portal_signingRequested', onSigningRequested)
169
+ }
170
+ }
171
+ }, [portal, onSigningRequested])
172
+
173
+ // Handle Android stuff
174
+ useEffect(() => {
175
+ const subscription = BackHandler.addEventListener(
176
+ 'hardwareBackPress',
177
+ handleBackPress,
178
+ )
209
179
 
210
- const Webview =
211
- memo(WebviewComponent,
212
- (prevProps, nextProps) => {
213
- return prevProps.url === nextProps.url
180
+ return () => {
181
+ subscription.remove()
182
+ }
183
+ }, [])
184
+
185
+ // Ensure that the webView ref gets forwarded to the parent component
186
+ useImperativeHandle(webViewRef, () => webView.current!)
187
+
188
+ return (
189
+ <View style={styles.container}>
190
+ {walletAddress && source && (
191
+ <WebView
192
+ allowsBackForwardNavigationGestures
193
+ allowsFullscreenVideo={false}
194
+ allowsInlineMediaPlayback={true}
195
+ incognito={true}
196
+ injectedJavaScriptBeforeContentLoaded={scriptToInject}
197
+ injectedJavaScriptBeforeContentLoadedForMainFrameOnly={true}
198
+ mediaPlaybackRequiresUserAction={true}
199
+ onMessage={handlePostMessage}
200
+ onNavigationStateChange={handleNavigationStateChange}
201
+ ref={webView}
202
+ renderLoading={() => <Loading />}
203
+ source={source}
204
+ startInLoadingState={true}
205
+ webviewDebuggingEnabled={true}
206
+ />
207
+ )}
208
+ </View>
209
+ )
214
210
  }
215
- )
216
211
 
212
+ return <Webview />
213
+ },
214
+ )
215
+
216
+ const Webview = memo(WebviewComponent, (prevProps, nextProps) => {
217
+ return prevProps.url === nextProps.url
218
+ })
217
219
 
218
220
  const styles = StyleSheet.create({
219
221
  container: {