From a58f316b6321b1dc06149aa1d38b04f9d8570b59 Mon Sep 17 00:00:00 2001 From: TQCasey <494294315@qq.com> Date: Mon, 16 Mar 2026 15:47:51 +0800 Subject: [PATCH] fix rnpay --- App.tsx | 842 ++---------------- android/.idea/gradle.xml | 3 + package.json | 5 + .../react-native-gesture-handler+2.9.0.patch | 24 + ...eact-native-safe-area-context+4.14.1.patch | 24 + patches/react-native-screens+3.36.0.patch | 21 + screens/HomeScreen.tsx | 756 ++++++++++++++++ screens/MessageScreen.tsx | 78 ++ servers/walletman | 2 +- styles.ts | 45 - 10 files changed, 963 insertions(+), 837 deletions(-) create mode 100644 patches/react-native-gesture-handler+2.9.0.patch create mode 100644 patches/react-native-safe-area-context+4.14.1.patch create mode 100644 patches/react-native-screens+3.36.0.patch create mode 100644 screens/HomeScreen.tsx create mode 100644 screens/MessageScreen.tsx delete mode 100644 styles.ts diff --git a/App.tsx b/App.tsx index 3c87ab8..b50ed81 100644 --- a/App.tsx +++ b/App.tsx @@ -1,795 +1,55 @@ -import React, { Component } from "react"; -import { Alert, AppState, AppStateStatus, Modal, Text, TextInput, TouchableOpacity, View } from "react-native"; -import DeviceInfo from 'react-native-device-info'; -import { - PhonePeBusinessBind, - GooglePayBusinessBind, - WalletType, - PaytmBusinessBindResult, - PhonePeBusinessBindResult, - PaytmPersonalBind, - PaytmPersonalBindResult, - MobikwikPersonalBindResult, - FreechargePersonalBindResult, - GooglePayBusinessBindResult, - BharatPeBusinessBindResult, - onSmsMessage, - startSmsListener, - stopSmsListener, - checkSmsPermission, - requestSmsPermission, - PhonePePersonalBindResult, - PhonePePersonalBind, - SmsMessage, - proxyBackgroundService, - proxySendMessage, - onProxyMessage, -} from "rnwalletman"; +import React from 'react'; +import { Text } from 'react-native'; +import { NavigationContainer } from '@react-navigation/native'; +import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; +import { SafeAreaProvider } from 'react-native-safe-area-context'; +import HomeScreen from './screens/HomeScreen'; +import MessageScreen from './screens/MessageScreen'; -import { - FreeChargeBind, - MobikwikOTPBind, - PayTmPersonalOTPBind, - PhonePePersonalOTPBind, - BharatPeBusinessOTPBind, - PaytmBusinessOTPBind, -} from './components/WalletBindComponents'; +const Tab = createBottomTabNavigator(); -import Api, { loadServerDomain, saveServerDomain, getServerDomain, getUseHttps } from './services/api'; -import { AppProps, WalletmanAppState } from './types'; -import { styles } from './styles'; -import WebView from "react-native-webview"; - -export default class App extends Component { - private deviceId: string; - private tuneUserId: string; - private clientId: string = ''; - private appStateSubscription?: any; - - private webViewRef: WebView | null = null; - - constructor(props: AppProps) { - super(props); - this.state = { - paytmPersonalBindType: 'otpMode', - showPaytmPersonalBind: false, - showPaytmBusinessBind: false, - showPhonePePersonalBind: false, - phonePePersonalBindType: 'otpMode', - showPhonePeBusinessBind: false, - showGooglePayBusinessBind: false, - showBharatPeBusinessBind: false, - showMobikwikPersonalBind: false, - showFreechargePersonalBind: false, - proxyStatus: 'idle', - showServerSettings: false, - settingsHost: '', - settingsPort: '', - }; - - this.deviceId = DeviceInfo.getUniqueIdSync(); - this.tuneUserId = Math.random().toString(36).substring(2, 15); - } - - async componentDidMount() { - await loadServerDomain(); - await this.setupPermissions(); - - this.onProxyMessageSub = onProxyMessage((msg) => { - switch (msg.type) { - case 'echo': - Alert.alert('Echo 回来了', JSON.stringify(msg.data)); - break; - default: - break; - } - }); - - // Login with auto-retry every 3s until success (setTimeout, non-blocking) - const doLogin = () => { - Api.instance.login('test123', '123456') - .then(async (userId) => { - console.log('[Login] userId:', userId); - await this.startProxyClient(); - }) - .catch((error) => { - console.log('[Login] retry in 3s:', error); - setTimeout(doLogin, 3000); - }); - }; - doLogin(); - this.appStateSubscription = AppState.addEventListener('change', this.handleAppStateChange); - } - - private onProxyMessageSub?: ReturnType; - - componentWillUnmount() { - this.stopProxyClient(); - stopSmsListener(); - this.onProxyMessageSub?.remove(); - } - - sendEcho = () => { - const text = `hello_${Date.now()}`; - proxySendMessage({ type: 'echo', messageId: `echo_${Date.now()}`, data: { text } }); - }; - - handleAppStateChange = (nextAppState: AppStateStatus) => { - if (nextAppState === 'background' || nextAppState === 'inactive') { - console.log('[AppState] 应用进入后台,代理服务继续运行'); - } else if (nextAppState === 'active') { - console.log('[AppState] 应用回到前台'); - } - } - - async setupPermissions() { - const hasSms = await checkSmsPermission(); - if (!hasSms) await requestSmsPermission(); - - startSmsListener(); - - onSmsMessage((msg: SmsMessage) => { - console.log('[SMS]', msg.address, msg.body); - }); - } - - async startProxyClient() { - try { - this.clientId = DeviceInfo.getUniqueIdSync(); - const userId = Api.instance.getUserId(); - const { clientId } = this; - console.log('[Proxy] 初始化后台服务:', clientId, 'userId:', userId); - - this.setState({ proxyStatus: 'connecting' }); - await proxyBackgroundService.start({ - wsUrl: Api.WS_URL, - clientId: this.clientId || '', - userId: userId, - debug: true, - heartbeatInterval: 10000, - reconnectInterval: 5000, - reconnectMaxAttempts: Infinity, - onConnected: () => { - console.log('[Proxy] 后台服务已连接'); - this.setState({ proxyStatus: 'connected' }); - }, - onDisconnected: () => { - console.log('[Proxy] 后台服务已断开'); - this.setState({ proxyStatus: 'disconnected' }); - }, - onError: (error: string) => { - console.log('[Proxy] 错误:', error); - this.setState({ proxyStatus: 'error', proxyError: error }); - }, - }); - } catch (error) { - console.error('[Proxy] 初始化失败:', error); - } - } - - stopProxyClient() { - try { - proxyBackgroundService.stop(); - console.log('[Proxy] 后台服务已停止'); - } catch (error) { - console.error('[Proxy] 停止失败:', error); - } - } - - // Paytm Personal - handleUploadPaytmPersonalToken = async (result: PaytmPersonalBindResult) => { - try { - console.log(result); - await Api.instance.register(WalletType.PAYTM_PERSONAL, result); - this.setState({ showPaytmPersonalBind: false }); - Alert.alert('绑定成功', 'Paytm Personal Token 绑定成功'); - } catch (error) { - Alert.alert('绑定失败', (error as Error).message); - this.setState({ showPaytmPersonalBind: false }); - } - } - - // PhonePe Personal - handleUploadPhonePePersonalToken = async (result: PhonePePersonalBindResult) => { - try { - console.log('PhonePe Personal Token Data:', result); - await Api.instance.register(WalletType.PHONEPE_PERSONAL, result); - this.setState({ showPhonePePersonalBind: false }); - Alert.alert('绑定成功', 'PhonePe Personal Token 绑定成功'); - } catch (error) { - Alert.alert('绑定失败', (error as Error).message); - this.setState({ showPhonePePersonalBind: false }); - } - } - - // Paytm Business - handleUploadPaytmBusiness = async (result: PaytmBusinessBindResult) => { - try { - console.log(result); - this.setState({ showPaytmBusinessBind: false }); - Alert.alert('绑定成功', 'Paytm Business 绑定成功'); - } catch (error) { - Alert.alert('绑定失败', (error as Error).message); - this.setState({ showPaytmBusinessBind: false }); - } - } - - // PhonePe Business - handleUploadPhonePeBusiness = async (result: PhonePeBusinessBindResult) => { - try { - console.log(result); - await Api.instance.register(WalletType.PHONEPE_BUSINESS, result); - this.setState({ showPhonePeBusinessBind: false }); - Alert.alert('绑定成功', 'PhonePe Business 绑定成功'); - } catch (error) { - Alert.alert('绑定失败', (error as Error).message); - this.setState({ showPhonePeBusinessBind: false }); - } - } - - // GooglePay Business - handleUploadGooglePayBusiness = async (result: GooglePayBusinessBindResult) => { - try { - console.log(result); - await Api.instance.register(WalletType.GOOGLEPAY_BUSINESS, result); - this.setState({ showGooglePayBusinessBind: false }); - Alert.alert('绑定成功', 'Google Pay Business 绑定成功'); - } catch (error) { - Alert.alert('绑定失败', (error as Error).message); - this.setState({ showGooglePayBusinessBind: false }); - } - } - - // BharatPe Business - handleUploadBharatPeBusiness = async (result: BharatPeBusinessBindResult) => { - try { - console.log(JSON.stringify(result)); - this.setState({ showBharatPeBusinessBind: false }); - Alert.alert('绑定成功', 'BharatPe Business 绑定成功'); - } catch (error) { - Alert.alert('绑定失败', (error as Error).message); - this.setState({ showBharatPeBusinessBind: false }); - } - } - - // Mobikwik Personal - handleUploadMobikwikPersonal = async (result: MobikwikPersonalBindResult) => { - try { - console.log(JSON.stringify(result)); - this.setState({ showMobikwikPersonalBind: false }); - Alert.alert('绑定成功', 'Mobikwik Personal 绑定成功'); - } catch (error) { - Alert.alert('绑定失败', (error as Error).message); - this.setState({ showMobikwikPersonalBind: false }); - } - } - - // Freecharge Personal - handleUploadFreechargePersonal = async (result: FreechargePersonalBindResult) => { - try { - console.log(JSON.stringify(result)); - this.setState({ showFreechargePersonalBind: false }); - Alert.alert('绑定成功', 'Freecharge Personal 绑定成功'); - } catch (error) { - Alert.alert('绑定失败', (error as Error).message); - this.setState({ showFreechargePersonalBind: false }); - } - } - - renderPaytmPersonalTokenBind = () => { - return ( - this.setState({ showPaytmPersonalBind: false })}> - { - Alert.alert('绑定失败', error); - this.setState({ showPaytmPersonalBind: false }); +export default function App() { + return ( + + + - - ); - } - - renderPaytmPersonalOTPBind = () => { - return ( - this.setState({ showPaytmPersonalBind: false })}> - { - try { - return await Api.instance.requestOTP(walletType, params.mobile, {}); - } catch (error) { - return { success: false, message: (error as Error).message }; - } - }} - onVerifyOTP={async (walletType, params) => { - try { - return await Api.instance.verifyOTP(walletType, params.mobile, params.otp, { - sessionId: params.sessionId, - }); - } catch (error) { - return { success: false, message: (error as Error).message }; - } - }} - onSuccess={(result: PaytmPersonalBindResult) => { - console.log('[PaytmPersonal] OTP 绑定成功:', result); - Alert.alert('绑定成功', 'Paytm Personal OTP 绑定成功'); - this.setState({ showPaytmPersonalBind: false }); - }} - onError={(error: string) => { - console.log('[PaytmPersonal] OTP 绑定失败:', error); - Alert.alert('绑定失败', error); - this.setState({ showPaytmPersonalBind: false }); - }} - /> - - ); - } - - renderPhonePePersonalTokenBind = () => { - return ( - this.setState({ showPhonePePersonalBind: false })}> - { - Alert.alert('绑定失败', error); - this.setState({ showPhonePePersonalBind: false }); - }} - /> - - ); - } - - renderPhonePePersonalOTPBind = () => { - return ( - this.setState({ showPhonePePersonalBind: false })}> - { - try { - return await Api.instance.requestOTP(walletType, params.mobile, {}); - } catch (error) { - return { success: false, message: (error as Error).message }; - } - }} - onVerifyOTP={async (walletType, params) => { - try { - return await Api.instance.verifyOTP(walletType, params.mobile, params.otp, { - sessionId: params.sessionId, - }); - } catch (error) { - return { success: false, message: (error as Error).message }; - } - }} - onSuccess={(result: PhonePePersonalBindResult) => { - console.log('[PhonePePersonal] OTP 绑定成功:', result); - Alert.alert('绑定成功', 'PhonePe Personal OTP 绑定成功'); - this.setState({ showPhonePePersonalBind: false }); - }} - onError={(error: string) => { - Alert.alert('绑定失败', error); - this.setState({ showPhonePePersonalBind: false }); - }} - /> - - ); - } - - renderPaytmBusinessBind = () => { - return ( - this.setState({ showPaytmBusinessBind: false })}> - { - try { - return await Api.instance.requestOTP(walletType, params.mobile, { password: params.password }); - } catch (error) { - return { success: false, message: (error as Error).message }; - } - }} - onVerifyOTP={async (walletType, params) => { - try { - return await Api.instance.verifyOTP(walletType, params.mobile, params.otp, { - sessionId: params.sessionId, - }); - } catch (error) { - return { success: false, message: (error as Error).message }; - } - }} - onSuccess={this.handleUploadPaytmBusiness} - onError={(error: string) => { - Alert.alert('绑定失败', error); - this.setState({ showPaytmBusinessBind: false }); - }} - /> - - ); - } - - renderPhonePeBusinessBind = () => { - return ( - this.setState({ showPhonePeBusinessBind: false })}> - { - Alert.alert('绑定失败', error); - this.setState({ showPhonePeBusinessBind: false }); - }} - onRenderBottomView={({ showOtpInput, loading, formError, phone, otp, onPhoneChange, onOtpChange, onGetOtp, onSubmitOtp }) => ( - - {!showOtpInput ? ( - <> - - {!!formError && {formError}} - - {loading ? 'Loading...' : 'GET OTP'} - - - ) : ( - <> - - {!!formError && {formError}} - - {loading ? 'Loading...' : 'Verify OTP'} - - - )} - - )} - /> - - ); - } - - renderGooglePayBusinessBind = () => { - return ( - this.setState({ showGooglePayBusinessBind: false })}> - { - Alert.alert('绑定失败', error); - this.setState({ showGooglePayBusinessBind: false }); - }} - /> - - ); - } - - renderBharatPeBusinessBind = () => { - return ( - this.setState({ showBharatPeBusinessBind: false })}> - { - try { - return await Api.instance.requestOTP(walletType, params.mobile); - } catch (error) { - return { success: false, message: (error as Error).message }; - } - }} - onVerifyOTP={async (walletType, params) => { - try { - return await Api.instance.verifyOTP(walletType, params.mobile, params.otp, { - sessionId: params.sessionId, - }); - } catch (error) { - return { success: false, message: (error as Error).message }; - } - }} - onSuccess={this.handleUploadBharatPeBusiness} - onError={(error: string) => { - Alert.alert('绑定失败', error); - this.setState({ showBharatPeBusinessBind: false }); - }} - /> - - ); - } - - renderMobikwikPersonalOTPBind = () => { - return ( - this.setState({ showMobikwikPersonalBind: false })}> - { - try { - return await Api.instance.requestOTP(walletType, params.mobile, { - deviceId: params.deviceId, - tuneUserId: params.tuneUserId - }); - } catch (error) { - return { success: false, message: (error as Error).message }; - } - }} - onVerifyOTP={async (walletType, params) => { - try { - return await Api.instance.verifyOTP(walletType, params.mobile, params.otp, { - deviceId: params.deviceId, - tuneUserId: params.tuneUserId, - nid: params.nid - }); - } catch (error) { - return { success: false, message: (error as Error).message }; - } - }} - onSuccess={this.handleUploadMobikwikPersonal} - onError={(error: string) => { - Alert.alert('绑定失败', error); - this.setState({ showMobikwikPersonalBind: false }); - }} - /> - - ); - } - - renderFreechargePersonalOTPBind = () => { - return ( - this.setState({ showFreechargePersonalBind: false })}> - { - try { - return await Api.instance.requestOTP(walletType, params.mobile); - } catch (error) { - return { success: false, message: (error as Error).message }; - } - }} - onVerifyOTP={async (walletType, params) => { - try { - return await Api.instance.verifyOTP(walletType, params.mobile, params.otp, { - otpId: params.otpId, - deviceId: params.deviceId, - csrfId: params.csrfId, - appFc: params.appFc - }); - } catch (error) { - return { success: false, message: (error as Error).message }; - } - }} - onSuccess={this.handleUploadFreechargePersonal} - onError={(error: string) => { - Alert.alert('绑定失败', error); - this.setState({ showFreechargePersonalBind: false }); - }} - /> - - ); - } - - renderBindModal = () => { - // Paytm Personal - if (this.state.showPaytmPersonalBind) { - if (this.state.paytmPersonalBindType === 'tokenMode') { - return this.renderPaytmPersonalTokenBind(); - } else { - return this.renderPaytmPersonalOTPBind (); - } - } - - // PhonePe Personal - if (this.state.showPhonePePersonalBind) { - if (this.state.phonePePersonalBindType === 'tokenMode') { - return this.renderPhonePePersonalTokenBind(); - } else { - return this.renderPhonePePersonalOTPBind (); - } - } - - // Paytm Business - if (this.state.showPaytmBusinessBind) { - return this.renderPaytmBusinessBind (); - } - - // PhonePe Business - if (this.state.showPhonePeBusinessBind) { - return this.renderPhonePeBusinessBind (); - } - - // GooglePay Business - if (this.state.showGooglePayBusinessBind) { - return this.renderGooglePayBusinessBind (); - } - - // BharatPe Business - if (this.state.showBharatPeBusinessBind) { - return this.renderBharatPeBusinessBind (); - } - - // Mobikwik Personal - if (this.state.showMobikwikPersonalBind) { - return this.renderMobikwikPersonalOTPBind (); - } - - // Freecharge Personal - if (this.state.showFreechargePersonalBind) { - return this.renderFreechargePersonalOTPBind (); - } - - return null; - } - - openServerSettings = () => { - const domain = getServerDomain(); - const colonIdx = domain.lastIndexOf(':'); - const host = colonIdx > 0 ? domain.substring(0, colonIdx) : domain; - const port = colonIdx > 0 ? domain.substring(colonIdx + 1) : ''; - this.setState({ showServerSettings: true, settingsHost: host, settingsPort: port }); - }; - - saveDomain = async () => { - const { settingsHost, settingsPort } = this.state; - const domain = settingsPort ? `${settingsHost}:${settingsPort}` : settingsHost; - const useHttps = settingsPort === '443'; - await saveServerDomain(domain, useHttps); - this.setState({ showServerSettings: false }); - Alert.alert('已保存', '重启 App 后生效'); - }; - - renderServerSettingsModal() { - const { showServerSettings, settingsHost, settingsPort } = this.state; - const presets = [ - { label: 'aa.pfgame.org', host: 'aa.pfgame.org', port: '443' }, - { label: 'game.ainavx.com:16000', host: 'game.ainavx.com', port: '16000' }, - { label: '192.168.1.117:16000', host: '192.168.1.117', port: '16000' }, - ]; - return ( - - - - 服务器设置 - - {presets.map(p => ( - this.setState({ settingsHost: p.host, settingsPort: p.port })} - style={{ paddingHorizontal: 10, paddingVertical: 5, borderRadius: 6, backgroundColor: settingsHost === p.host && settingsPort === p.port ? '#3498db' : '#f0f0f0' }} - > - {p.label} - - ))} - - Host - this.setState({ settingsHost: t })} - placeholder="192.168.1.198" - autoCapitalize="none" - keyboardType="default" - /> - Port - this.setState({ settingsPort: t })} - placeholder="16000" - keyboardType="number-pad" - /> - - this.setState({ showServerSettings: false })} style={{ paddingHorizontal: 16, paddingVertical: 8, marginRight: 10 }}> - 取消 - - - 保存 - - - - - - ); - } - - render() { - return ( - - {(() => { - const { proxyStatus, proxyError } = this.state; - const cfg: Record = { - idle: { label: '未连接', color: '#95a5a6' }, - connecting: { label: '连接中…', color: '#f39c12' }, - connected: { label: '已连接', color: '#2ecc71' }, - disconnected: { label: '已断开', color: '#e74c3c' }, - error: { label: '连接失败', color: '#e74c3c' }, - }; - const { label, color } = cfg[proxyStatus]; - return ( - - - - Proxy {label}{proxyStatus === 'error' && proxyError ? `:${proxyError}` : ''} - - - ); - })()} - {this.renderBindModal()} - {this.renderServerSettingsModal()} - - ⚙ 服务器设置 - - - { - this.setState({ showPaytmPersonalBind: true, paytmPersonalBindType: 'otpMode' }); - }}> - 绑定 Paytm Personal(OTP) - - { - this.setState({ showPaytmPersonalBind: true, paytmPersonalBindType: 'tokenMode' }); - }}> - 绑定 Paytm Personal(Token) - - - { - this.setState({ showPaytmBusinessBind: true }); - }}> - 绑定 Paytm Business (OTP) - - - { - this.setState({ showPhonePePersonalBind: true, phonePePersonalBindType: 'otpMode' }); - }}> - 绑定 PhonePe Personal(OTP) - - { - this.setState({ showPhonePePersonalBind: true, phonePePersonalBindType: 'tokenMode' }); - }}> - 绑定 PhonePe Personal(Token) - - - { - this.setState({ showPhonePeBusinessBind: true }); - }}> - 绑定 PhonePe Business (OTP-WEB) - - { - this.setState({ showGooglePayBusinessBind: true }); - }}> - 绑定 GooglePay Business - - { - this.setState({ showBharatPeBusinessBind: true }); - }}> - 绑定 BharatPe Business (OTP) - - { - this.setState({ showMobikwikPersonalBind: true }); - }}> - 绑定 Mobikwik Personal (OTP) - - { - this.setState({ showFreechargePersonalBind: true }); - }}> - 绑定 Freecharge Personal (OTP) - - - Echo 测试 - - - ); - } + > + ( + 🏠 + ), + }} + /> + ( + 💬 + ), + }} + /> + + + + ); } diff --git a/android/.idea/gradle.xml b/android/.idea/gradle.xml index 89fcd3b..29d0d9e 100644 --- a/android/.idea/gradle.xml +++ b/android/.idea/gradle.xml @@ -29,6 +29,9 @@