@gnosispay/pse-react-native 1.0.1
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 +262 -0
- package/lib/PSEWebView.d.ts +4 -0
- package/lib/PSEWebView.js +64 -0
- package/lib/PSEWebView.tsx +93 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +1 -0
- package/lib/index.ts +2 -0
- package/lib/types.d.ts +19 -0
- package/lib/types.js +0 -0
- package/lib/types.ts +21 -0
- package/package.json +72 -0
package/README.md
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# PSE React Native
|
|
2
|
+
|
|
3
|
+
A React Native library that provides a secure WebView component for integrating Gnosis Pay card functionality into your mobile applications.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔒 **Secure WebView Integration** - Safely embed Gnosis Pay card interfaces
|
|
8
|
+
- 📱 **Cross-Platform** - Works on both iOS and Android
|
|
9
|
+
- ⚡ **Easy Integration** - Simple component with minimal setup
|
|
10
|
+
- 🎛️ **Configurable** - Flexible configuration options for different environments
|
|
11
|
+
- 📨 **Message Handling** - Built-in communication between WebView and React Native
|
|
12
|
+
- 🔄 **WebView Controls** - Programmatic navigation and reload capabilities
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install pse-react-native
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Peer Dependencies
|
|
21
|
+
|
|
22
|
+
Make sure you have the required peer dependencies installed:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install react-native-webview
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
For Expo projects:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx expo install react-native-webview
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Basic Usage
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
import React, { useRef } from "react";
|
|
38
|
+
import { View, Button, Alert } from "react-native";
|
|
39
|
+
import { PSEWebView, PSEWebViewRef } from "pse-react-native";
|
|
40
|
+
|
|
41
|
+
export default function PaymentScreen() {
|
|
42
|
+
const webViewRef = useRef<PSEWebViewRef>(null);
|
|
43
|
+
|
|
44
|
+
const config = {
|
|
45
|
+
appId: "your-app-id",
|
|
46
|
+
authToken: "your-auth-token",
|
|
47
|
+
cardToken: "your-card-token",
|
|
48
|
+
baseUrl: "https://pse-backend.v2.gnosispay.com", // Optional
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const handleError = (error: string) => {
|
|
52
|
+
Alert.alert("Payment Error", error);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const handleMessage = (message: any) => {
|
|
56
|
+
console.log("Received message from WebView:", message);
|
|
57
|
+
// Handle different message types from the WebView
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const handleLoad = () => {
|
|
61
|
+
console.log("WebView loaded successfully");
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<View style={{ flex: 1 }}>
|
|
66
|
+
<PSEWebView
|
|
67
|
+
ref={webViewRef}
|
|
68
|
+
config={config}
|
|
69
|
+
onError={handleError}
|
|
70
|
+
onMessage={handleMessage}
|
|
71
|
+
onLoad={handleLoad}
|
|
72
|
+
style={{ flex: 1 }}
|
|
73
|
+
testID="pse-webview"
|
|
74
|
+
/>
|
|
75
|
+
|
|
76
|
+
<View style={{ padding: 16 }}>
|
|
77
|
+
<Button title="Reload" onPress={() => webViewRef.current?.reload()} />
|
|
78
|
+
<Button title="Go Back" onPress={() => webViewRef.current?.goBack()} />
|
|
79
|
+
</View>
|
|
80
|
+
</View>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## API Reference
|
|
86
|
+
|
|
87
|
+
### PSEWebView Props
|
|
88
|
+
|
|
89
|
+
| Prop | Type | Required | Description |
|
|
90
|
+
| ----------- | ------------------------- | -------- | ------------------------------------------------ |
|
|
91
|
+
| `config` | `PSEConfig` | ✅ | Configuration object with authentication details |
|
|
92
|
+
| `onError` | `(error: string) => void` | ❌ | Callback fired when an error occurs |
|
|
93
|
+
| `onMessage` | `(message: any) => void` | ❌ | Callback fired when WebView sends a message |
|
|
94
|
+
| `onLoad` | `() => void` | ❌ | Callback fired when WebView finishes loading |
|
|
95
|
+
| `style` | `ViewStyle` | ❌ | Style object for the WebView container |
|
|
96
|
+
| `testID` | `string` | ❌ | Test identifier for testing frameworks |
|
|
97
|
+
|
|
98
|
+
### PSEConfig
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
interface PSEConfig {
|
|
102
|
+
appId: string; // Your application identifier
|
|
103
|
+
authToken: string; // Authentication token
|
|
104
|
+
cardToken: string; // Card-specific token
|
|
105
|
+
baseUrl?: string; // Optional: Custom backend URL
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### PSEWebViewRef Methods
|
|
110
|
+
|
|
111
|
+
The component exposes these methods via ref:
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
interface PSEWebViewRef {
|
|
115
|
+
goBack: () => void; // Navigate back in WebView history
|
|
116
|
+
reload: () => void; // Reload the current page
|
|
117
|
+
postMessage: (message: string) => void; // Send message to WebView
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Message Handling
|
|
122
|
+
|
|
123
|
+
The WebView can send various message types. Handle them in your `onMessage` callback:
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
const handleMessage = (message: any) => {
|
|
127
|
+
switch (message.type) {
|
|
128
|
+
case "error":
|
|
129
|
+
console.error("WebView error:", message.message);
|
|
130
|
+
break;
|
|
131
|
+
case "success":
|
|
132
|
+
console.log("Operation successful:", message.data);
|
|
133
|
+
break;
|
|
134
|
+
case "navigation":
|
|
135
|
+
console.log("Navigation event:", message.url);
|
|
136
|
+
break;
|
|
137
|
+
default:
|
|
138
|
+
console.log("Unknown message type:", message);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Error Handling
|
|
144
|
+
|
|
145
|
+
The component provides comprehensive error handling:
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
const handleError = (error: string) => {
|
|
149
|
+
// Common error scenarios:
|
|
150
|
+
// - Network connectivity issues
|
|
151
|
+
// - Invalid authentication tokens
|
|
152
|
+
// - WebView loading failures
|
|
153
|
+
// - Backend service unavailable
|
|
154
|
+
|
|
155
|
+
console.error("PSE WebView Error:", error);
|
|
156
|
+
|
|
157
|
+
// Show user-friendly error message
|
|
158
|
+
Alert.alert(
|
|
159
|
+
"Payment Error",
|
|
160
|
+
"Unable to load payment interface. Please try again.",
|
|
161
|
+
[{ text: "OK", onPress: () => webViewRef.current?.reload() }]
|
|
162
|
+
);
|
|
163
|
+
};
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Configuration Environments
|
|
167
|
+
|
|
168
|
+
### Production
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
const config = {
|
|
172
|
+
appId: "your-prod-app-id",
|
|
173
|
+
authToken: "your-prod-auth-token",
|
|
174
|
+
cardToken: "your-prod-card-token",
|
|
175
|
+
baseUrl: "https://pse-backend.v2.gnosispay.com",
|
|
176
|
+
};
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Staging/Testing
|
|
180
|
+
|
|
181
|
+
```tsx
|
|
182
|
+
const config = {
|
|
183
|
+
appId: "your-staging-app-id",
|
|
184
|
+
authToken: "your-staging-auth-token",
|
|
185
|
+
cardToken: "your-staging-card-token",
|
|
186
|
+
baseUrl: "https://pse-backend-staging.v2.gnosispay.com",
|
|
187
|
+
};
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Requirements
|
|
191
|
+
|
|
192
|
+
- React Native >= 0.70.0
|
|
193
|
+
- React >= 18.0.0
|
|
194
|
+
- react-native-webview >= 13.0.0
|
|
195
|
+
|
|
196
|
+
## Development
|
|
197
|
+
|
|
198
|
+
This repository includes an example app to test the library:
|
|
199
|
+
|
|
200
|
+
### Running the Example App
|
|
201
|
+
|
|
202
|
+
1. Clone the repository:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
git clone <repository-url>
|
|
206
|
+
cd pse-react-native
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
2. Install dependencies:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
npm install
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
3. Start the example app:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
npx expo start
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
4. Open the app in your preferred development environment:
|
|
222
|
+
- iOS Simulator
|
|
223
|
+
- Android Emulator
|
|
224
|
+
- Physical device with Expo Go
|
|
225
|
+
|
|
226
|
+
### Building the Library
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
npm run build
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
This compiles the TypeScript source files and generates the distribution files in the `lib/` directory.
|
|
233
|
+
|
|
234
|
+
## Troubleshooting
|
|
235
|
+
|
|
236
|
+
### Common Issues
|
|
237
|
+
|
|
238
|
+
**WebView not loading:**
|
|
239
|
+
|
|
240
|
+
- Verify your authentication tokens are valid
|
|
241
|
+
- Check network connectivity
|
|
242
|
+
- Ensure the baseUrl is accessible
|
|
243
|
+
|
|
244
|
+
**Authentication errors:**
|
|
245
|
+
|
|
246
|
+
- Double-check your appId, authToken, and cardToken
|
|
247
|
+
- Verify tokens haven't expired
|
|
248
|
+
- Contact your PSE provider for token validation
|
|
249
|
+
|
|
250
|
+
**Build errors:**
|
|
251
|
+
|
|
252
|
+
- Ensure react-native-webview is properly installed
|
|
253
|
+
- Check that peer dependencies match the required versions
|
|
254
|
+
- Clear your Metro cache: `npx expo start --clear`
|
|
255
|
+
|
|
256
|
+
## License
|
|
257
|
+
|
|
258
|
+
[Add your license information here]
|
|
259
|
+
|
|
260
|
+
## Support
|
|
261
|
+
|
|
262
|
+
For technical support or questions about integration, please contact your PSE provider or create an issue in this repository.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React, { forwardRef, useImperativeHandle, useRef } from "react";
|
|
2
|
+
import { Alert, StyleSheet } from "react-native";
|
|
3
|
+
import { WebView } from "react-native-webview";
|
|
4
|
+
const PSEWebView = forwardRef(({ config, onError, onMessage, onLoad, style, testID }, ref) => {
|
|
5
|
+
const webViewRef = useRef(null);
|
|
6
|
+
useImperativeHandle(ref, () => ({
|
|
7
|
+
goBack: () => {
|
|
8
|
+
webViewRef.current?.goBack();
|
|
9
|
+
},
|
|
10
|
+
reload: () => {
|
|
11
|
+
webViewRef.current?.reload();
|
|
12
|
+
},
|
|
13
|
+
postMessage: (message) => {
|
|
14
|
+
webViewRef.current?.postMessage(message);
|
|
15
|
+
},
|
|
16
|
+
}));
|
|
17
|
+
const handleWebViewLoad = () => {
|
|
18
|
+
// Send parameters to webview after it loads
|
|
19
|
+
const params = {
|
|
20
|
+
appId: config.appId.trim(),
|
|
21
|
+
authToken: config.authToken.trim(),
|
|
22
|
+
cardToken: config.cardToken.trim(),
|
|
23
|
+
};
|
|
24
|
+
const message = JSON.stringify(params);
|
|
25
|
+
webViewRef.current?.postMessage(message);
|
|
26
|
+
console.log("PSE: Message sent to WebView:", message);
|
|
27
|
+
onLoad?.();
|
|
28
|
+
};
|
|
29
|
+
const handleWebViewMessage = (event) => {
|
|
30
|
+
try {
|
|
31
|
+
const data = JSON.parse(event.nativeEvent.data);
|
|
32
|
+
console.log("PSE: Message from WebView:", data);
|
|
33
|
+
// Handle error messages from the webview
|
|
34
|
+
if (data.type === "error") {
|
|
35
|
+
const errorMessage = data.message || "Unknown WebView error";
|
|
36
|
+
onError?.(errorMessage);
|
|
37
|
+
Alert.alert("PSE WebView Error", errorMessage);
|
|
38
|
+
}
|
|
39
|
+
// Pass all messages to the parent component
|
|
40
|
+
onMessage?.(data);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
console.log("PSE: Failed to parse WebView message:", error);
|
|
44
|
+
onError?.("Failed to parse WebView message");
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const handleWebViewError = (syntheticEvent) => {
|
|
48
|
+
const { nativeEvent } = syntheticEvent;
|
|
49
|
+
const errorMessage = `Failed to load PSE WebView: ${nativeEvent.description}`;
|
|
50
|
+
console.error("PSE: WebView Error:", errorMessage);
|
|
51
|
+
onError?.(errorMessage);
|
|
52
|
+
Alert.alert("PSE WebView Error", errorMessage);
|
|
53
|
+
};
|
|
54
|
+
const baseUrl = config.baseUrl || "https://pse-backend.v2.gnosispay.com";
|
|
55
|
+
const webViewUrl = `${baseUrl}/native-webview`;
|
|
56
|
+
return (<WebView ref={webViewRef} source={{ uri: webViewUrl }} style={[styles.webview, style]} startInLoadingState={true} scalesPageToFit={true} onLoad={handleWebViewLoad} onMessage={handleWebViewMessage} onError={handleWebViewError} javaScriptEnabled={true} testID={testID}/>);
|
|
57
|
+
});
|
|
58
|
+
PSEWebView.displayName = "PSEWebView";
|
|
59
|
+
const styles = StyleSheet.create({
|
|
60
|
+
webview: {
|
|
61
|
+
flex: 1,
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
export default PSEWebView;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import React, { forwardRef, useImperativeHandle, useRef } from "react";
|
|
2
|
+
import { Alert, StyleSheet } from "react-native";
|
|
3
|
+
import { WebView } from "react-native-webview";
|
|
4
|
+
import type { PSEWebViewProps, PSEWebViewRef } from "./types";
|
|
5
|
+
|
|
6
|
+
const PSEWebView = forwardRef<PSEWebViewRef, PSEWebViewProps>(
|
|
7
|
+
({ config, onError, onMessage, onLoad, style, testID }, ref) => {
|
|
8
|
+
const webViewRef = useRef<WebView>(null);
|
|
9
|
+
|
|
10
|
+
useImperativeHandle(ref, () => ({
|
|
11
|
+
goBack: () => {
|
|
12
|
+
webViewRef.current?.goBack();
|
|
13
|
+
},
|
|
14
|
+
reload: () => {
|
|
15
|
+
webViewRef.current?.reload();
|
|
16
|
+
},
|
|
17
|
+
postMessage: (message: string) => {
|
|
18
|
+
webViewRef.current?.postMessage(message);
|
|
19
|
+
},
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
const handleWebViewLoad = () => {
|
|
23
|
+
// Send parameters to webview after it loads
|
|
24
|
+
const params = {
|
|
25
|
+
appId: config.appId.trim(),
|
|
26
|
+
authToken: config.authToken.trim(),
|
|
27
|
+
cardToken: config.cardToken.trim(),
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const message = JSON.stringify(params);
|
|
31
|
+
webViewRef.current?.postMessage(message);
|
|
32
|
+
|
|
33
|
+
console.log("PSE: Message sent to WebView:", message);
|
|
34
|
+
onLoad?.();
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const handleWebViewMessage = (event: any) => {
|
|
38
|
+
try {
|
|
39
|
+
const data = JSON.parse(event.nativeEvent.data);
|
|
40
|
+
console.log("PSE: Message from WebView:", data);
|
|
41
|
+
|
|
42
|
+
// Handle error messages from the webview
|
|
43
|
+
if (data.type === "error") {
|
|
44
|
+
const errorMessage = data.message || "Unknown WebView error";
|
|
45
|
+
onError?.(errorMessage);
|
|
46
|
+
Alert.alert("PSE WebView Error", errorMessage);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Pass all messages to the parent component
|
|
50
|
+
onMessage?.(data);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.log("PSE: Failed to parse WebView message:", error);
|
|
53
|
+
onError?.("Failed to parse WebView message");
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const handleWebViewError = (syntheticEvent: any) => {
|
|
58
|
+
const { nativeEvent } = syntheticEvent;
|
|
59
|
+
const errorMessage = `Failed to load PSE WebView: ${nativeEvent.description}`;
|
|
60
|
+
console.error("PSE: WebView Error:", errorMessage);
|
|
61
|
+
onError?.(errorMessage);
|
|
62
|
+
Alert.alert("PSE WebView Error", errorMessage);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const baseUrl = config.baseUrl || "https://pse-backend.v2.gnosispay.com";
|
|
66
|
+
const webViewUrl = `${baseUrl}/native-webview`;
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<WebView
|
|
70
|
+
ref={webViewRef}
|
|
71
|
+
source={{ uri: webViewUrl }}
|
|
72
|
+
style={[styles.webview, style]}
|
|
73
|
+
startInLoadingState={true}
|
|
74
|
+
scalesPageToFit={true}
|
|
75
|
+
onLoad={handleWebViewLoad}
|
|
76
|
+
onMessage={handleWebViewMessage}
|
|
77
|
+
onError={handleWebViewError}
|
|
78
|
+
javaScriptEnabled={true}
|
|
79
|
+
testID={testID}
|
|
80
|
+
/>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
PSEWebView.displayName = "PSEWebView";
|
|
86
|
+
|
|
87
|
+
const styles = StyleSheet.create({
|
|
88
|
+
webview: {
|
|
89
|
+
flex: 1,
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
export default PSEWebView;
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as PSEWebView } from "./PSEWebView";
|
package/lib/index.ts
ADDED
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface PSEConfig {
|
|
2
|
+
appId: string;
|
|
3
|
+
authToken: string;
|
|
4
|
+
cardToken: string;
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface PSEWebViewProps {
|
|
8
|
+
config: PSEConfig;
|
|
9
|
+
onError?: (error: string) => void;
|
|
10
|
+
onMessage?: (message: any) => void;
|
|
11
|
+
onLoad?: () => void;
|
|
12
|
+
style?: any;
|
|
13
|
+
testID?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PSEWebViewRef {
|
|
16
|
+
goBack: () => void;
|
|
17
|
+
reload: () => void;
|
|
18
|
+
postMessage: (message: string) => void;
|
|
19
|
+
}
|
package/lib/types.js
ADDED
|
File without changes
|
package/lib/types.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface PSEConfig {
|
|
2
|
+
appId: string;
|
|
3
|
+
authToken: string;
|
|
4
|
+
cardToken: string;
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface PSEWebViewProps {
|
|
9
|
+
config: PSEConfig;
|
|
10
|
+
onError?: (error: string) => void;
|
|
11
|
+
onMessage?: (message: any) => void;
|
|
12
|
+
onLoad?: () => void;
|
|
13
|
+
style?: any;
|
|
14
|
+
testID?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface PSEWebViewRef {
|
|
18
|
+
goBack: () => void;
|
|
19
|
+
reload: () => void;
|
|
20
|
+
postMessage: (message: string) => void;
|
|
21
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gnosispay/pse-react-native",
|
|
3
|
+
"main": "lib/index.js",
|
|
4
|
+
"version": "1.0.1",
|
|
5
|
+
"types": "lib/index.d.ts",
|
|
6
|
+
"files": [
|
|
7
|
+
"lib/",
|
|
8
|
+
"README.md"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "expo start",
|
|
12
|
+
"android": "expo start --android",
|
|
13
|
+
"ios": "expo start --ios",
|
|
14
|
+
"web": "expo start --web",
|
|
15
|
+
"lint": "expo lint",
|
|
16
|
+
"build": "tsc --project tsconfig.lib.json",
|
|
17
|
+
"prepublishOnly": "npm run build"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/gnosispay/pse-react-native"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"react-native",
|
|
25
|
+
"pse",
|
|
26
|
+
"gnosis-pay",
|
|
27
|
+
"webview",
|
|
28
|
+
"payment",
|
|
29
|
+
"card",
|
|
30
|
+
"iframe"
|
|
31
|
+
],
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"react": ">=18.0.0",
|
|
34
|
+
"react-native": ">=0.70.0",
|
|
35
|
+
"react-native-webview": ">=13.0.0"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@expo/vector-icons": "^14.1.0",
|
|
39
|
+
"@react-navigation/bottom-tabs": "^7.3.10",
|
|
40
|
+
"@react-navigation/elements": "^2.3.8",
|
|
41
|
+
"@react-navigation/native": "^7.1.6",
|
|
42
|
+
"expo": "~53.0.20",
|
|
43
|
+
"expo-blur": "~14.1.5",
|
|
44
|
+
"expo-constants": "~17.1.7",
|
|
45
|
+
"expo-font": "~13.3.2",
|
|
46
|
+
"expo-haptics": "~14.1.4",
|
|
47
|
+
"expo-image": "~2.4.0",
|
|
48
|
+
"expo-linking": "~7.1.7",
|
|
49
|
+
"expo-router": "~5.1.4",
|
|
50
|
+
"expo-splash-screen": "~0.30.10",
|
|
51
|
+
"expo-status-bar": "~2.2.3",
|
|
52
|
+
"expo-symbols": "~0.4.5",
|
|
53
|
+
"expo-system-ui": "~5.0.10",
|
|
54
|
+
"expo-web-browser": "~14.2.0",
|
|
55
|
+
"react": "19.0.0",
|
|
56
|
+
"react-dom": "19.0.0",
|
|
57
|
+
"react-native": "0.79.5",
|
|
58
|
+
"react-native-gesture-handler": "~2.24.0",
|
|
59
|
+
"react-native-reanimated": "~3.17.4",
|
|
60
|
+
"react-native-safe-area-context": "5.4.0",
|
|
61
|
+
"react-native-screens": "~4.11.1",
|
|
62
|
+
"react-native-web": "~0.20.0",
|
|
63
|
+
"react-native-webview": "13.13.5"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@babel/core": "^7.25.2",
|
|
67
|
+
"@types/react": "~19.0.10",
|
|
68
|
+
"typescript": "~5.8.3",
|
|
69
|
+
"eslint": "^9.25.0",
|
|
70
|
+
"eslint-config-expo": "~9.2.0"
|
|
71
|
+
}
|
|
72
|
+
}
|