react-native-fpay 0.3.4 → 0.3.6
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/lib/module/FountainPayProvider.js +106 -16
- package/lib/module/FountainPayProvider.js.map +1 -1
- package/lib/module/core/api/client.js +13 -1
- package/lib/module/core/api/client.js.map +1 -1
- package/lib/module/core/api/index.js +66 -24
- package/lib/module/core/api/index.js.map +1 -1
- package/lib/module/engine/BLEReceiverService.js.map +1 -1
- package/lib/module/engine/BLESenderService.js.map +1 -1
- package/lib/module/engine/FPEngine.js +164 -43
- package/lib/module/engine/FPEngine.js.map +1 -1
- package/lib/module/engine/NearbyUsersService.js +1 -1
- package/lib/module/engine/NearbyUsersService.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/store/FPStore.js +155 -0
- package/lib/module/store/FPStore.js.map +1 -0
- package/lib/module/ui/components/AnimatedDots.js +3 -3
- package/lib/module/ui/components/AnimatedDots.js.map +1 -1
- package/lib/module/ui/components/ConfirmScreen.js +137 -123
- package/lib/module/ui/components/ConfirmScreen.js.map +1 -1
- package/lib/module/ui/components/FPButton.js.map +1 -1
- package/lib/module/ui/components/LoadingAnimation/InLoading.js +3 -3
- package/lib/module/ui/components/LoadingAnimation/InLoading.js.map +1 -1
- package/lib/module/ui/components/LoadingAnimation/index.js +3 -3
- package/lib/module/ui/components/LoadingAnimation/index.js.map +1 -1
- package/lib/module/ui/components/OtpInput/OTPInputView.js +11 -11
- package/lib/module/ui/components/OtpInput/OTPInputView.js.map +1 -1
- package/lib/module/ui/components/OtpInput/Styles.js +1 -1
- package/lib/module/ui/components/OtpInput/helpers/codeToArray.js +1 -1
- package/lib/module/ui/components/OtpInput/helpers/device.js.map +1 -1
- package/lib/module/ui/components/OtpInput/helpers/styles.js.map +1 -1
- package/lib/module/ui/components/OtpInput/index.js +3 -1
- package/lib/module/ui/components/OtpInput/index.js.map +1 -1
- package/lib/module/ui/components/PulseAnimation.js +2 -2
- package/lib/module/ui/components/PulseAnimation.js.map +1 -1
- package/lib/module/ui/modals/FPPaymentRequestModal.js +8 -7
- package/lib/module/ui/modals/FPPaymentRequestModal.js.map +1 -1
- package/lib/module/ui/modals/FPShell.js +2 -0
- package/lib/module/ui/modals/FPShell.js.map +1 -1
- package/lib/module/ui/screens/ReceiveScreen.js +8 -9
- package/lib/module/ui/screens/ReceiveScreen.js.map +1 -1
- package/lib/module/ui/screens/SendScreen.js +43 -94
- package/lib/module/ui/screens/SendScreen.js.map +1 -1
- package/lib/module/ui/screens/styles.js +15 -3
- package/lib/module/ui/screens/styles.js.map +1 -1
- package/lib/module/ui/screens/sub/receivePayment/Nfc/index.js +4 -4
- package/lib/module/ui/screens/sub/receivePayment/Nfc/index.js.map +1 -1
- package/lib/module/ui/screens/sub/receivePayment/Qr/index.js +5 -5
- package/lib/module/ui/screens/sub/receivePayment/Qr/index.js.map +1 -1
- package/lib/module/ui/screens/sub/receivePayment/Transfer/index.js +10 -11
- package/lib/module/ui/screens/sub/receivePayment/Transfer/index.js.map +1 -1
- package/lib/module/ui/screens/sub/sendPayment/BluetoothSubScreen.js +31 -8
- package/lib/module/ui/screens/sub/sendPayment/BluetoothSubScreen.js.map +1 -1
- package/lib/module/ui/screens/sub/sendPayment/NFCSubScreen.js +12 -8
- package/lib/module/ui/screens/sub/sendPayment/NFCSubScreen.js.map +1 -1
- package/lib/module/ui/screens/sub/sendPayment/NQRSubScreen.js +17 -5
- package/lib/module/ui/screens/sub/sendPayment/NQRSubScreen.js.map +1 -1
- package/lib/module/ui/screens/sub/sendPayment/ProximitySubScreen.js +67 -35
- package/lib/module/ui/screens/sub/sendPayment/ProximitySubScreen.js.map +1 -1
- package/lib/module/ui/screens/sub/sendPayment/TransferSubScreen.js +110 -34
- package/lib/module/ui/screens/sub/sendPayment/TransferSubScreen.js.map +1 -1
- package/lib/module/ui/theme/index.js.map +1 -1
- package/lib/typescript/src/FountainPayProvider.d.ts +1 -1
- package/lib/typescript/src/FountainPayProvider.d.ts.map +1 -1
- package/lib/typescript/src/core/api/client.d.ts.map +1 -1
- package/lib/typescript/src/core/api/index.d.ts +42 -26
- package/lib/typescript/src/core/api/index.d.ts.map +1 -1
- package/lib/typescript/src/core/types/index.d.ts +53 -28
- package/lib/typescript/src/core/types/index.d.ts.map +1 -1
- package/lib/typescript/src/engine/BLEReceiverService.d.ts +2 -0
- package/lib/typescript/src/engine/BLEReceiverService.d.ts.map +1 -1
- package/lib/typescript/src/engine/BLESenderService.d.ts.map +1 -1
- package/lib/typescript/src/engine/FPEngine.d.ts +5 -3
- package/lib/typescript/src/engine/FPEngine.d.ts.map +1 -1
- package/lib/typescript/src/engine/useIsForeground.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/store/FPStore.d.ts +60 -0
- package/lib/typescript/src/store/FPStore.d.ts.map +1 -0
- package/lib/typescript/src/ui/components/AnimatedDots.d.ts.map +1 -1
- package/lib/typescript/src/ui/components/ConfirmScreen.d.ts +5 -5
- package/lib/typescript/src/ui/components/ConfirmScreen.d.ts.map +1 -1
- package/lib/typescript/src/ui/components/FPButton.d.ts +1 -1
- package/lib/typescript/src/ui/components/FPButton.d.ts.map +1 -1
- package/lib/typescript/src/ui/components/LoadingAnimation/InLoading.d.ts.map +1 -1
- package/lib/typescript/src/ui/components/LoadingAnimation/index.d.ts.map +1 -1
- package/lib/typescript/src/ui/components/OtpInput/OTPInputView.d.ts.map +1 -1
- package/lib/typescript/src/ui/components/OtpInput/helpers/codeToArray.d.ts.map +1 -1
- package/lib/typescript/src/ui/components/OtpInput/helpers/device.d.ts.map +1 -1
- package/lib/typescript/src/ui/components/OtpInput/helpers/styles.d.ts.map +1 -1
- package/lib/typescript/src/ui/components/OtpInput/helpers/types.d.ts +1 -2
- package/lib/typescript/src/ui/components/OtpInput/helpers/types.d.ts.map +1 -1
- package/lib/typescript/src/ui/components/OtpInput/index.d.ts +3 -1
- package/lib/typescript/src/ui/components/OtpInput/index.d.ts.map +1 -1
- package/lib/typescript/src/ui/components/PulseAnimation.d.ts.map +1 -1
- package/lib/typescript/src/ui/modals/FPPaymentRequestModal.d.ts.map +1 -1
- package/lib/typescript/src/ui/modals/FPShell.d.ts.map +1 -1
- package/lib/typescript/src/ui/screens/ReceiveScreen.d.ts +1 -1
- package/lib/typescript/src/ui/screens/ReceiveScreen.d.ts.map +1 -1
- package/lib/typescript/src/ui/screens/SendScreen.d.ts +1 -1
- package/lib/typescript/src/ui/screens/SendScreen.d.ts.map +1 -1
- package/lib/typescript/src/ui/screens/styles.d.ts +197 -0
- package/lib/typescript/src/ui/screens/styles.d.ts.map +1 -1
- package/lib/typescript/src/ui/screens/sub/receivePayment/Nfc/index.d.ts.map +1 -1
- package/lib/typescript/src/ui/screens/sub/receivePayment/Qr/index.d.ts.map +1 -1
- package/lib/typescript/src/ui/screens/sub/receivePayment/Transfer/index.d.ts.map +1 -1
- package/lib/typescript/src/ui/screens/sub/sendPayment/BluetoothSubScreen.d.ts.map +1 -1
- package/lib/typescript/src/ui/screens/sub/sendPayment/NFCSubScreen.d.ts +1 -1
- package/lib/typescript/src/ui/screens/sub/sendPayment/NFCSubScreen.d.ts.map +1 -1
- package/lib/typescript/src/ui/screens/sub/sendPayment/NQRSubScreen.d.ts +1 -1
- package/lib/typescript/src/ui/screens/sub/sendPayment/NQRSubScreen.d.ts.map +1 -1
- package/lib/typescript/src/ui/screens/sub/sendPayment/ProximitySubScreen.d.ts +1 -1
- package/lib/typescript/src/ui/screens/sub/sendPayment/ProximitySubScreen.d.ts.map +1 -1
- package/lib/typescript/src/ui/screens/sub/sendPayment/TransferSubScreen.d.ts +1 -1
- package/lib/typescript/src/ui/screens/sub/sendPayment/TransferSubScreen.d.ts.map +1 -1
- package/lib/typescript/src/ui/theme/index.d.ts.map +1 -1
- package/package.json +4 -5
- package/src/FountainPayProvider.tsx +164 -23
- package/src/core/api/client.ts +26 -4
- package/src/core/api/index.ts +170 -49
- package/src/core/types/index.ts +81 -48
- package/src/engine/BLEReceiverService.ts +86 -28
- package/src/engine/BLESenderService.ts +133 -69
- package/src/engine/FPEngine.ts +316 -97
- package/src/engine/NearbyUsersService.ts +6 -6
- package/src/engine/useIsForeground.ts +12 -12
- package/src/index.ts +10 -4
- package/src/store/FPStore.ts +216 -0
- package/src/ui/components/AnimatedDots.tsx +4 -5
- package/src/ui/components/ConfirmScreen.tsx +182 -169
- package/src/ui/components/FPButton.tsx +50 -9
- package/src/ui/components/LoadingAnimation/InLoading.tsx +23 -27
- package/src/ui/components/LoadingAnimation/index.tsx +3 -7
- package/src/ui/components/OtpInput/OTPInputView.tsx +254 -205
- package/src/ui/components/OtpInput/Styles.ts +1 -1
- package/src/ui/components/OtpInput/helpers/codeToArray.ts +2 -2
- package/src/ui/components/OtpInput/helpers/device.ts +4 -3
- package/src/ui/components/OtpInput/helpers/styles.ts +13 -14
- package/src/ui/components/OtpInput/helpers/types.ts +83 -79
- package/src/ui/components/OtpInput/index.tsx +18 -15
- package/src/ui/components/PulseAnimation.tsx +3 -5
- package/src/ui/modals/FPPaymentRequestModal.tsx +111 -28
- package/src/ui/modals/FPShell.tsx +60 -34
- package/src/ui/screens/ReceiveScreen.tsx +245 -84
- package/src/ui/screens/SendScreen.tsx +419 -167
- package/src/ui/screens/styles.ts +17 -5
- package/src/ui/screens/sub/receivePayment/Nfc/index.tsx +17 -25
- package/src/ui/screens/sub/receivePayment/Qr/index.tsx +21 -20
- package/src/ui/screens/sub/receivePayment/Transfer/index.tsx +34 -28
- package/src/ui/screens/sub/sendPayment/BluetoothSubScreen.tsx +135 -67
- package/src/ui/screens/sub/sendPayment/NFCSubScreen.tsx +188 -112
- package/src/ui/screens/sub/sendPayment/NQRSubScreen.tsx +102 -69
- package/src/ui/screens/sub/sendPayment/ProximitySubScreen.tsx +225 -99
- package/src/ui/screens/sub/sendPayment/TransferSubScreen.tsx +209 -89
- package/src/ui/theme/index.ts +14 -2
package/src/core/types/index.ts
CHANGED
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
// FountainPay SDK — Master Types
|
|
2
2
|
|
|
3
|
-
import type { Device } from
|
|
3
|
+
import type { Device } from 'react-native-ble-plx';
|
|
4
4
|
|
|
5
5
|
export type FPCurrency = 'NGN' | 'USD' | 'GBP' | 'EUR' | string;
|
|
6
|
-
export type FPChannel
|
|
7
|
-
export type FPTxStatus =
|
|
8
|
-
|
|
6
|
+
export type FPChannel = 'transfer' | 'nqr' | 'proximity' | 'bluetooth' | 'nfc';
|
|
7
|
+
export type FPTxStatus =
|
|
8
|
+
| 'pending'
|
|
9
|
+
| 'processing'
|
|
10
|
+
| 'successful'
|
|
11
|
+
| 'failed'
|
|
12
|
+
| 'reversed';
|
|
13
|
+
export type FPTxType = 'debit' | 'credit';
|
|
9
14
|
|
|
10
15
|
export interface FPUserInfo {
|
|
11
|
-
|
|
16
|
+
firstName: string;
|
|
17
|
+
lastName: string;
|
|
12
18
|
phone: string;
|
|
13
19
|
email: string;
|
|
20
|
+
bvn?: string;
|
|
21
|
+
nin?: string;
|
|
22
|
+
dateOfBirth?: string;
|
|
14
23
|
userId: string;
|
|
15
24
|
}
|
|
16
25
|
|
|
@@ -28,6 +37,13 @@ export interface FPTransferRecipient {
|
|
|
28
37
|
bankName: string;
|
|
29
38
|
}
|
|
30
39
|
|
|
40
|
+
export interface FPWalletTransferRecipient {
|
|
41
|
+
accountNumber: string;
|
|
42
|
+
type: 'USER' | 'AGENT';
|
|
43
|
+
accountName: string;
|
|
44
|
+
agentId?: string;
|
|
45
|
+
userId?: string;
|
|
46
|
+
}
|
|
31
47
|
|
|
32
48
|
export interface FPNfcRecipient {
|
|
33
49
|
accountNumber: string;
|
|
@@ -51,23 +67,45 @@ export interface FPParty {
|
|
|
51
67
|
|
|
52
68
|
export interface FPSendPaymentRequest {
|
|
53
69
|
sender?: FPUserInfo;
|
|
54
|
-
amount: number;
|
|
55
|
-
narration?: string;
|
|
56
|
-
reference?: string
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
70
|
+
amount: number;
|
|
71
|
+
narration?: string;
|
|
72
|
+
reference?: string;
|
|
73
|
+
isBank?: boolean;
|
|
74
|
+
channel: 'transfer' | 'proximity' | 'bluetooth' | 'nfc' | 'nqr';
|
|
75
|
+
currency?: string;
|
|
76
|
+
recipient:
|
|
77
|
+
| FPTransferRecipient
|
|
78
|
+
| FPNfcRecipient
|
|
79
|
+
| FPNqrRecipient
|
|
80
|
+
| FPWalletTransferRecipient;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface FPSendWalletPaymentRequest {
|
|
84
|
+
sender_id: string;
|
|
85
|
+
sender_type: 'USER';
|
|
86
|
+
recipient: FPWalletTransferRecipient;
|
|
87
|
+
amount: string;
|
|
88
|
+
reference: string;
|
|
89
|
+
narration: string;
|
|
90
|
+
currency?: string;
|
|
91
|
+
isBank?: false;
|
|
92
|
+
channel: 'transfer' | 'proximity' | 'bluetooth';
|
|
60
93
|
}
|
|
61
94
|
|
|
62
|
-
|
|
63
95
|
export interface FPNfcTransfer {
|
|
64
|
-
amount: number;
|
|
65
|
-
narration?: string;
|
|
66
|
-
reference?: string
|
|
67
|
-
currency?: string
|
|
96
|
+
amount: number;
|
|
97
|
+
narration?: string;
|
|
98
|
+
reference?: string;
|
|
99
|
+
currency?: string;
|
|
68
100
|
channel: 'nfc';
|
|
69
101
|
}
|
|
70
102
|
|
|
103
|
+
export interface FPTransactionResponse {
|
|
104
|
+
status: string;
|
|
105
|
+
message: string;
|
|
106
|
+
payload: FPTransaction;
|
|
107
|
+
}
|
|
108
|
+
|
|
71
109
|
export interface FPTransaction {
|
|
72
110
|
id: string;
|
|
73
111
|
reference: string;
|
|
@@ -83,31 +121,6 @@ export interface FPTransaction {
|
|
|
83
121
|
createdAt: string;
|
|
84
122
|
}
|
|
85
123
|
|
|
86
|
-
export interface FPGenerateAccountRequest {
|
|
87
|
-
accountName: string;
|
|
88
|
-
email?: string;
|
|
89
|
-
phone?: string;
|
|
90
|
-
reference?: string;
|
|
91
|
-
amount?: number;
|
|
92
|
-
currency?: FPCurrency;
|
|
93
|
-
expiresInMinutes?: number;
|
|
94
|
-
metadata?: Record<string, unknown>;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export interface FPVirtualAccount {
|
|
98
|
-
accountNumber: string;
|
|
99
|
-
accountName: string;
|
|
100
|
-
bankName: string;
|
|
101
|
-
bankCode: string;
|
|
102
|
-
currency: FPCurrency;
|
|
103
|
-
balance: number;
|
|
104
|
-
reference: string;
|
|
105
|
-
walletId: string;
|
|
106
|
-
qrCode?: string;
|
|
107
|
-
expiresAt?: string;
|
|
108
|
-
createdAt: string;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
124
|
export interface FPBluetoothPaymentRequest {
|
|
112
125
|
requestId: string;
|
|
113
126
|
sender: FPUserInfo & { deviceId: string; deviceName?: string };
|
|
@@ -142,12 +155,27 @@ export interface FPBankItem {
|
|
|
142
155
|
logo?: string;
|
|
143
156
|
}
|
|
144
157
|
|
|
158
|
+
export interface FPAccount {
|
|
159
|
+
id: string; // PSSP-assigned — stored internally, host app never needs this
|
|
160
|
+
accountNumber: string;
|
|
161
|
+
accountName: string;
|
|
162
|
+
firstName: string;
|
|
163
|
+
lastName?: string;
|
|
164
|
+
phone: string;
|
|
165
|
+
bankName?: string;
|
|
166
|
+
bankCode?: string;
|
|
167
|
+
balance?: number;
|
|
168
|
+
currency?: string;
|
|
169
|
+
}
|
|
170
|
+
|
|
145
171
|
export interface FPCallbacks {
|
|
146
172
|
onPaymentRequest?: (request: FPBluetoothPaymentRequest) => void;
|
|
147
173
|
onPaymentReceived?: (transaction: FPTransaction) => void;
|
|
148
174
|
onPaymentDeclined?: (request: FPBluetoothPaymentRequest) => void;
|
|
149
175
|
onPaymentSent?: (transaction: FPTransaction) => void;
|
|
150
176
|
onError?: (error: FPError) => void;
|
|
177
|
+
onAccountReady?: (account: FPAccount) => void;
|
|
178
|
+
onAccountError?: (error: FPError, user: FPUserInfo) => void;
|
|
151
179
|
}
|
|
152
180
|
|
|
153
181
|
export interface FPError {
|
|
@@ -160,14 +188,18 @@ export interface FPInstance {
|
|
|
160
188
|
initializeSDK: (user: FPUserInfo, callbacks?: FPCallbacks) => Promise<void>;
|
|
161
189
|
send: (amount: number, currency: FPCurrency) => void;
|
|
162
190
|
receive: (amount?: number, currency?: FPCurrency) => void;
|
|
163
|
-
generateAccountNumber: (
|
|
191
|
+
generateAccountNumber: (user: FPUserInfo) => Promise<FPAccount>;
|
|
192
|
+
refreshBalance: () => Promise<void>;
|
|
164
193
|
listen: () => void;
|
|
165
194
|
destroy: () => void;
|
|
166
195
|
isReady: boolean;
|
|
167
196
|
currentUser: FPUserInfo | null;
|
|
197
|
+
isAuthenticated: boolean;
|
|
198
|
+
authError: string | null;
|
|
199
|
+
account: FPAccount | null;
|
|
200
|
+
balance: number | null;
|
|
168
201
|
}
|
|
169
202
|
|
|
170
|
-
|
|
171
203
|
export interface FintechDevice {
|
|
172
204
|
id: string;
|
|
173
205
|
name: string;
|
|
@@ -178,16 +210,17 @@ export interface FintechDevice {
|
|
|
178
210
|
waiting?: boolean;
|
|
179
211
|
}
|
|
180
212
|
|
|
181
|
-
|
|
182
213
|
export interface Props {
|
|
183
|
-
|
|
214
|
+
psspId?: string;
|
|
215
|
+
amount: number;
|
|
184
216
|
currency: FPCurrency;
|
|
185
217
|
onClose: () => void;
|
|
186
|
-
onProcessTransaction?: (
|
|
218
|
+
onProcessTransaction?: (
|
|
219
|
+
tx: FPSendPaymentRequest | FPSendWalletPaymentRequest | null
|
|
220
|
+
) => void;
|
|
187
221
|
onError?: (err: FPError) => void;
|
|
188
222
|
}
|
|
189
223
|
|
|
190
|
-
|
|
191
224
|
export interface ReceiveTransferScreenProps {
|
|
192
225
|
amount?: number;
|
|
193
226
|
description?: string;
|
|
@@ -195,4 +228,4 @@ export interface ReceiveTransferScreenProps {
|
|
|
195
228
|
recipient: FPTransferRecipient;
|
|
196
229
|
onClose?: () => void;
|
|
197
230
|
onPaymentReceived?: (data: any) => void;
|
|
198
|
-
}
|
|
231
|
+
}
|
|
@@ -4,12 +4,15 @@
|
|
|
4
4
|
// Only changes: removed useBoundStore dependency, appName is 'FountainPay'.
|
|
5
5
|
|
|
6
6
|
import { PermissionsAndroid, Platform } from 'react-native';
|
|
7
|
-
import Peripheral, {
|
|
7
|
+
import Peripheral, {
|
|
8
|
+
Permission,
|
|
9
|
+
Property,
|
|
10
|
+
} from 'react-native-multi-ble-peripheral';
|
|
8
11
|
import { Buffer } from 'buffer';
|
|
9
12
|
|
|
10
13
|
// ── UUIDs — shared with BLESenderService ─────────────────────
|
|
11
|
-
export const FP_SERVICE_UUID
|
|
12
|
-
export const FP_REQUEST_CHAR_UUID
|
|
14
|
+
export const FP_SERVICE_UUID = 'E8E66D12-C217-425A-AB36-DDBA22F22A5D';
|
|
15
|
+
export const FP_REQUEST_CHAR_UUID = 'E1CC0349-343A-4E12-A4EF-CF69A681EE86';
|
|
13
16
|
export const FP_RESPONSE_CHAR_UUID = 'DA9318CA-C740-4951-9C7C-5747FE002EF9';
|
|
14
17
|
export const FP_USERINFO_CHAR_UUID = '933CA5AE-4D53-4CF4-864A-2FF51AFA05E9';
|
|
15
18
|
|
|
@@ -36,13 +39,18 @@ export interface BLEPaymentResponse {
|
|
|
36
39
|
accountNumber: string;
|
|
37
40
|
bankName: string;
|
|
38
41
|
bankCode: string;
|
|
42
|
+
userId?: string;
|
|
43
|
+
type: 'USER' | 'AGENT';
|
|
39
44
|
};
|
|
40
45
|
// Echo of the original request timestamp — used by sender's polling
|
|
41
46
|
// to confirm this response belongs to their specific request
|
|
42
47
|
requestTimestamp?: number;
|
|
43
48
|
}
|
|
44
49
|
|
|
45
|
-
export type PaymentRequestCallback = (
|
|
50
|
+
export type PaymentRequestCallback = (
|
|
51
|
+
request: BLEPaymentRequest,
|
|
52
|
+
deviceId: string
|
|
53
|
+
) => void;
|
|
46
54
|
|
|
47
55
|
// ── Class ─────────────────────────────────────────────────────
|
|
48
56
|
|
|
@@ -54,7 +62,11 @@ class BLEReceiverService {
|
|
|
54
62
|
|
|
55
63
|
// ── Init ───────────────────────────────────────────────────
|
|
56
64
|
|
|
57
|
-
async initializeWithUserInfo(
|
|
65
|
+
async initializeWithUserInfo(
|
|
66
|
+
userId: string,
|
|
67
|
+
userName: string,
|
|
68
|
+
appName = 'FountainPay'
|
|
69
|
+
): Promise<void> {
|
|
58
70
|
this.userInfo = { userId, userName, appName };
|
|
59
71
|
await this._requestPermissions();
|
|
60
72
|
}
|
|
@@ -67,9 +79,13 @@ class BLEReceiverService {
|
|
|
67
79
|
PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
|
|
68
80
|
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
|
|
69
81
|
]);
|
|
70
|
-
return Object.values(results).every(
|
|
82
|
+
return Object.values(results).every(
|
|
83
|
+
(r) => r === PermissionsAndroid.RESULTS.GRANTED
|
|
84
|
+
);
|
|
71
85
|
}
|
|
72
|
-
const granted = await PermissionsAndroid.request(
|
|
86
|
+
const granted = await PermissionsAndroid.request(
|
|
87
|
+
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
|
|
88
|
+
);
|
|
73
89
|
return granted === PermissionsAndroid.RESULTS.GRANTED;
|
|
74
90
|
}
|
|
75
91
|
|
|
@@ -101,30 +117,37 @@ class BLEReceiverService {
|
|
|
101
117
|
console.log('[FPay BLE Receiver] Peripheral ready');
|
|
102
118
|
|
|
103
119
|
await Peripheral.setDeviceName(this.userInfo.userName);
|
|
104
|
-
console.log(
|
|
120
|
+
console.log(
|
|
121
|
+
'[FPay BLE Receiver] Device name set:',
|
|
122
|
+
this.userInfo.userName
|
|
123
|
+
);
|
|
105
124
|
|
|
106
125
|
await this.peripheral.addService(FP_SERVICE_UUID, true);
|
|
107
126
|
|
|
108
127
|
// User info characteristic — READ only.
|
|
109
128
|
// Sender reads this to get display name and userId.
|
|
110
129
|
const userInfoPayload = JSON.stringify({
|
|
111
|
-
appName:
|
|
130
|
+
appName: this.userInfo.appName,
|
|
112
131
|
userName: this.userInfo.userName,
|
|
113
|
-
userId:
|
|
132
|
+
userId: this.userInfo.userId,
|
|
114
133
|
});
|
|
115
134
|
await this.peripheral.addCharacteristic(
|
|
116
|
-
FP_SERVICE_UUID,
|
|
117
|
-
|
|
135
|
+
FP_SERVICE_UUID,
|
|
136
|
+
FP_USERINFO_CHAR_UUID,
|
|
137
|
+
Property.READ,
|
|
138
|
+
Permission.READABLE
|
|
118
139
|
);
|
|
119
140
|
await this.peripheral.updateValue(
|
|
120
|
-
FP_SERVICE_UUID,
|
|
141
|
+
FP_SERVICE_UUID,
|
|
142
|
+
FP_USERINFO_CHAR_UUID,
|
|
121
143
|
Buffer.from(userInfoPayload)
|
|
122
144
|
);
|
|
123
145
|
|
|
124
146
|
// Payment request characteristic — WRITE / WRITE_NO_RESPONSE.
|
|
125
147
|
// Sender writes the payment request JSON here.
|
|
126
148
|
await this.peripheral.addCharacteristic(
|
|
127
|
-
FP_SERVICE_UUID,
|
|
149
|
+
FP_SERVICE_UUID,
|
|
150
|
+
FP_REQUEST_CHAR_UUID,
|
|
128
151
|
Property.WRITE | Property.WRITE_NO_RESPONSE,
|
|
129
152
|
Permission.WRITEABLE
|
|
130
153
|
);
|
|
@@ -132,14 +155,16 @@ class BLEReceiverService {
|
|
|
132
155
|
// Payment response characteristic — READ + NOTIFY.
|
|
133
156
|
// Receiver writes accept/decline here; sender polls or subscribes.
|
|
134
157
|
await this.peripheral.addCharacteristic(
|
|
135
|
-
FP_SERVICE_UUID,
|
|
158
|
+
FP_SERVICE_UUID,
|
|
159
|
+
FP_RESPONSE_CHAR_UUID,
|
|
136
160
|
Property.READ | Property.NOTIFY,
|
|
137
161
|
Permission.READABLE
|
|
138
162
|
);
|
|
139
163
|
// Seed a default value so the characteristic is always readable
|
|
140
164
|
// (prevents "characteristic not found" errors on first poll)
|
|
141
165
|
await this.peripheral.updateValue(
|
|
142
|
-
FP_SERVICE_UUID,
|
|
166
|
+
FP_SERVICE_UUID,
|
|
167
|
+
FP_RESPONSE_CHAR_UUID,
|
|
143
168
|
Buffer.from(JSON.stringify({ accepted: false, timestamp: 0 }))
|
|
144
169
|
);
|
|
145
170
|
|
|
@@ -149,7 +174,11 @@ class BLEReceiverService {
|
|
|
149
174
|
});
|
|
150
175
|
|
|
151
176
|
this.isAdvertising = true;
|
|
152
|
-
console.log(
|
|
177
|
+
console.log(
|
|
178
|
+
'[FPay BLE Receiver] Advertising as "' +
|
|
179
|
+
this.userInfo.userName +
|
|
180
|
+
'"'
|
|
181
|
+
);
|
|
153
182
|
resolve();
|
|
154
183
|
} catch (err) {
|
|
155
184
|
clearTimeout(timeout);
|
|
@@ -174,9 +203,15 @@ class BLEReceiverService {
|
|
|
174
203
|
}
|
|
175
204
|
});
|
|
176
205
|
|
|
177
|
-
this.peripheral.on('read',
|
|
178
|
-
|
|
179
|
-
|
|
206
|
+
this.peripheral.on('read', () =>
|
|
207
|
+
console.log('[FPay BLE Receiver] Read event')
|
|
208
|
+
);
|
|
209
|
+
this.peripheral.on('subscribe', () =>
|
|
210
|
+
console.log('[FPay BLE Receiver] Central subscribed')
|
|
211
|
+
);
|
|
212
|
+
this.peripheral.on('unsubscribe', () =>
|
|
213
|
+
console.log('[FPay BLE Receiver] Central unsubscribed')
|
|
214
|
+
);
|
|
180
215
|
}
|
|
181
216
|
|
|
182
217
|
private _handlePaymentRequest(data: { value: any }): void {
|
|
@@ -191,22 +226,34 @@ class BLEReceiverService {
|
|
|
191
226
|
} else if (Array.isArray(data.value)) {
|
|
192
227
|
decoded = Buffer.from(data.value).toString('utf8');
|
|
193
228
|
} else {
|
|
194
|
-
console.warn(
|
|
229
|
+
console.warn(
|
|
230
|
+
'[FPay BLE Receiver] Unknown value format:',
|
|
231
|
+
typeof data.value
|
|
232
|
+
);
|
|
195
233
|
return;
|
|
196
234
|
}
|
|
197
235
|
|
|
198
236
|
const request: BLEPaymentRequest = JSON.parse(decoded);
|
|
199
237
|
const deviceId = request.senderId?.toString() ?? 'unknown';
|
|
200
238
|
|
|
201
|
-
console.log(
|
|
239
|
+
console.log(
|
|
240
|
+
'[FPay BLE Receiver] Payment request parsed:',
|
|
241
|
+
request.senderName,
|
|
242
|
+
request.currency + request.amount
|
|
243
|
+
);
|
|
202
244
|
|
|
203
245
|
if (this.onRequestCallback) {
|
|
204
246
|
this.onRequestCallback(request, deviceId);
|
|
205
247
|
} else {
|
|
206
|
-
console.warn(
|
|
248
|
+
console.warn(
|
|
249
|
+
'[FPay BLE Receiver] No callback registered — request dropped'
|
|
250
|
+
);
|
|
207
251
|
}
|
|
208
252
|
} catch (err) {
|
|
209
|
-
console.error(
|
|
253
|
+
console.error(
|
|
254
|
+
'[FPay BLE Receiver] Failed to parse payment request:',
|
|
255
|
+
err
|
|
256
|
+
);
|
|
210
257
|
}
|
|
211
258
|
}
|
|
212
259
|
|
|
@@ -219,11 +266,20 @@ class BLEReceiverService {
|
|
|
219
266
|
|
|
220
267
|
async sendPaymentResponse(response: BLEPaymentResponse): Promise<void> {
|
|
221
268
|
if (!this.peripheral || !this.isAdvertising) {
|
|
222
|
-
throw new Error(
|
|
269
|
+
throw new Error(
|
|
270
|
+
'[FPay BLE Receiver] Cannot send response — not advertising'
|
|
271
|
+
);
|
|
223
272
|
}
|
|
224
273
|
const buffer = Buffer.from(JSON.stringify(response));
|
|
225
|
-
await this.peripheral.updateValue(
|
|
226
|
-
|
|
274
|
+
await this.peripheral.updateValue(
|
|
275
|
+
FP_SERVICE_UUID,
|
|
276
|
+
FP_RESPONSE_CHAR_UUID,
|
|
277
|
+
buffer
|
|
278
|
+
);
|
|
279
|
+
console.log(
|
|
280
|
+
'[FPay BLE Receiver] Response sent:',
|
|
281
|
+
response.accepted ? 'ACCEPTED' : 'DECLINED'
|
|
282
|
+
);
|
|
227
283
|
}
|
|
228
284
|
|
|
229
285
|
async stopAdvertising(): Promise<void> {
|
|
@@ -234,7 +290,9 @@ class BLEReceiverService {
|
|
|
234
290
|
}
|
|
235
291
|
}
|
|
236
292
|
|
|
237
|
-
getIsAdvertising(): boolean {
|
|
293
|
+
getIsAdvertising(): boolean {
|
|
294
|
+
return this.isAdvertising;
|
|
295
|
+
}
|
|
238
296
|
|
|
239
297
|
destroy(): void {
|
|
240
298
|
this.stopAdvertising();
|