@finspringinnovations/fdsdk 0.0.5 → 0.0.7

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.
@@ -42,9 +42,11 @@ const react_native_webview_1 = require("react-native-webview");
42
42
  const SafeAreaWrapper_1 = __importDefault(require("../components/SafeAreaWrapper"));
43
43
  const ThemeContext_1 = require("../theme/ThemeContext");
44
44
  const encryption_1 = require("../utils/encryption");
45
+ const sseParser_1 = require("../utils/sseParser");
45
46
  const encryptionConfig_1 = require("../config/encryptionConfig");
47
+ const appDataConfig_1 = require("../config/appDataConfig");
48
+ const apiConfig_1 = require("../config/apiConfig");
46
49
  const store_1 = require("../store");
47
- const usePaymentSSE_1 = require("../hooks/usePaymentSSE");
48
50
  const Payment = ({ onGoBack, onPaymentSuccess, onPaymentFailure, onPaymentPending, paymentUrl, successUrl = 'payment/success', failureUrl = 'payment/failure', }) => {
49
51
  const colors = (0, ThemeContext_1.useColors)();
50
52
  const styles = createStyles(colors);
@@ -54,11 +56,21 @@ const Payment = ({ onGoBack, onPaymentSuccess, onPaymentFailure, onPaymentPendin
54
56
  const workflowInstanceId = (0, store_1.useAppSelector)((state) => { var _a; return (_a = state === null || state === void 0 ? void 0 : state.onboarding) === null || _a === void 0 ? void 0 : _a.workflowInstanceId; });
55
57
  const entityId = (0, store_1.useAppSelector)((state) => { var _a; return (_a = state === null || state === void 0 ? void 0 : state.onboarding) === null || _a === void 0 ? void 0 : _a.entityid; });
56
58
  const providerId = (0, store_1.useAppSelector)((state) => { var _a; return (_a = state === null || state === void 0 ? void 0 : state.onboarding) === null || _a === void 0 ? void 0 : _a.providerId; });
57
- const { start: startPaymentSSE, stop: stopPaymentSSE } = (0, usePaymentSSE_1.usePaymentSSE)();
59
+ const sseXhrRef = (0, react_1.useRef)(null);
60
+ const sseLastIndexRef = (0, react_1.useRef)(0);
61
+ const sseBufferRef = (0, react_1.useRef)({ value: '' });
58
62
  const onSuccessRef = (0, react_1.useRef)(onPaymentSuccess);
59
63
  const onFailureRef = (0, react_1.useRef)(onPaymentFailure);
60
64
  onSuccessRef.current = onPaymentSuccess;
61
65
  onFailureRef.current = onPaymentFailure;
66
+ const stopPaymentSSE = (0, react_1.useCallback)(() => {
67
+ if (sseXhrRef.current) {
68
+ sseXhrRef.current.abort();
69
+ sseXhrRef.current = null;
70
+ }
71
+ sseLastIndexRef.current = 0;
72
+ sseBufferRef.current = { value: '' };
73
+ }, []);
62
74
  const handleNavigationStateChange = async (navState) => {
63
75
  const { url } = navState;
64
76
  if (url.includes('payment/status')) {
@@ -82,35 +94,141 @@ const Payment = ({ onGoBack, onPaymentSuccess, onPaymentFailure, onPaymentPendin
82
94
  };
83
95
  // SSE: listen for payment status while user is on Payment WebView (same as web integration)
84
96
  (0, react_1.useEffect)(() => {
85
- if (!applicationId || !(paymentUrl === null || paymentUrl === void 0 ? void 0 : paymentUrl.trim()))
97
+ var _a;
98
+ if (!applicationId || !(paymentUrl === null || paymentUrl === void 0 ? void 0 : paymentUrl.trim())) {
99
+ stopPaymentSSE();
86
100
  return;
87
- startPaymentSSE(applicationId, {
88
- onPaymentStatus: (status, payload) => {
89
- var _a, _b;
90
- const normalized = String(status || '').toUpperCase();
91
- if (normalized === 'SUCCESS') {
101
+ }
102
+ const envData = (0, appDataConfig_1.getEnvironmentData)();
103
+ const apiConfig = (0, apiConfig_1.getApiConfig)();
104
+ const baseUrl = ((envData === null || envData === void 0 ? void 0 : envData.apiBaseUrl) || (apiConfig === null || apiConfig === void 0 ? void 0 : apiConfig.baseUrl) || '').replace(/\/$/, '');
105
+ const url = baseUrl ? `${baseUrl}/events?applicationId=${encodeURIComponent(applicationId)}` : '';
106
+ if (!url)
107
+ return;
108
+ stopPaymentSSE();
109
+ const xhr = new XMLHttpRequest();
110
+ sseXhrRef.current = xhr;
111
+ xhr.open('GET', url);
112
+ const apiKey = (envData === null || envData === void 0 ? void 0 : envData.apiKey) || ((_a = apiConfig === null || apiConfig === void 0 ? void 0 : apiConfig.headers) === null || _a === void 0 ? void 0 : _a['X-API-Key']) || '';
113
+ if (apiKey) {
114
+ xhr.setRequestHeader('x-api-key', apiKey);
115
+ xhr.setRequestHeader('X-API-Key', apiKey);
116
+ }
117
+ const secureHeaders = (0, apiConfig_1.getSecureHeaders)();
118
+ Object.entries(secureHeaders).forEach(([key, value]) => {
119
+ if (key.toLowerCase() !== 'content-type') {
120
+ xhr.setRequestHeader(key, value);
121
+ }
122
+ });
123
+ xhr.setRequestHeader('Accept', 'text/event-stream');
124
+ xhr.setRequestHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
125
+ xhr.setRequestHeader('Pragma', 'no-cache');
126
+ xhr.setRequestHeader('Expires', '0');
127
+ try {
128
+ const userInfo = (0, appDataConfig_1.getUserInfoForAPI)();
129
+ const userRefId = (userInfo === null || userInfo === void 0 ? void 0 : userInfo.userReferenceId) || (userInfo === null || userInfo === void 0 ? void 0 : userInfo.id);
130
+ if (userRefId) {
131
+ xhr.setRequestHeader('userreferenceid', userRefId);
132
+ xhr.setRequestHeader('userReferenceId', userRefId);
133
+ }
134
+ }
135
+ catch (_b) {
136
+ // ignore
137
+ }
138
+ if (providerId) {
139
+ xhr.setRequestHeader('provider', providerId);
140
+ xhr.setRequestHeader('providerid', providerId);
141
+ xhr.setRequestHeader('providerId', providerId);
142
+ }
143
+ if (workflowInstanceId) {
144
+ xhr.setRequestHeader('workflowInstanceId', workflowInstanceId);
145
+ xhr.setRequestHeader('workflowinstanceid', workflowInstanceId);
146
+ }
147
+ if (applicationId) {
148
+ xhr.setRequestHeader('applicationId', applicationId);
149
+ xhr.setRequestHeader('applicationid', applicationId);
150
+ }
151
+ if (entityId) {
152
+ xhr.setRequestHeader('entityid', entityId);
153
+ xhr.setRequestHeader('entityId', entityId);
154
+ }
155
+ const handleEventData = async (rawData) => {
156
+ var _a, _b, _c, _d, _e, _f;
157
+ try {
158
+ const parsed = JSON.parse(rawData || '{}');
159
+ let payload = parsed;
160
+ if (typeof (parsed === null || parsed === void 0 ? void 0 : parsed.encryptedResponse) === 'string' && parsed.encryptedResponse) {
161
+ try {
162
+ const config = (0, encryptionConfig_1.getEncryptionConfig)();
163
+ const decrypted = await (0, encryption_1.decryptResponse)({ encryptedResponse: parsed.encryptedResponse }, config);
164
+ payload = (decrypted || {});
165
+ }
166
+ catch (_g) {
167
+ // ignore and use raw payload
168
+ }
169
+ }
170
+ const payloadData = (payload === null || payload === void 0 ? void 0 : payload.data) || {};
171
+ const status = String((_d = (_c = (_b = (_a = payload === null || payload === void 0 ? void 0 : payload.paymentStatus) !== null && _a !== void 0 ? _a : payload === null || payload === void 0 ? void 0 : payload.payment_status) !== null && _b !== void 0 ? _b : payloadData === null || payloadData === void 0 ? void 0 : payloadData.paymentStatus) !== null && _c !== void 0 ? _c : payloadData === null || payloadData === void 0 ? void 0 : payloadData.payment_status) !== null && _d !== void 0 ? _d : '').toUpperCase();
172
+ if (status === 'SUCCESS') {
92
173
  stopPaymentSSE();
93
- (_a = onSuccessRef.current) === null || _a === void 0 ? void 0 : _a.call(onSuccessRef, payload);
174
+ (_e = onSuccessRef.current) === null || _e === void 0 ? void 0 : _e.call(onSuccessRef, payload);
94
175
  return;
95
176
  }
96
- if (normalized === 'FAILED') {
177
+ if (status === 'FAILED') {
97
178
  stopPaymentSSE();
98
- (_b = onFailureRef.current) === null || _b === void 0 ? void 0 : _b.call(onFailureRef, payload);
179
+ (_f = onFailureRef.current) === null || _f === void 0 ? void 0 : _f.call(onFailureRef, payload);
99
180
  }
100
- },
101
- onError: () => {
102
- if (__DEV__)
103
- console.warn('[Payment] SSE connection error');
104
- },
105
- onConnected: () => {
181
+ }
182
+ catch (_h) {
183
+ // ignore parse errors
184
+ }
185
+ };
186
+ xhr.onprogress = () => {
187
+ setLoading(false);
188
+ const newText = xhr.responseText.slice(sseLastIndexRef.current);
189
+ sseLastIndexRef.current = xhr.responseText.length;
190
+ if (!newText)
191
+ return;
192
+ const events = (0, sseParser_1.parseSSEBuffer)(sseBufferRef.current, newText);
193
+ for (const { eventType, data } of events) {
194
+ if (!data)
195
+ continue;
196
+ const normalizedEventType = String(eventType || '').trim().toLowerCase();
197
+ if (normalizedEventType === 'fd_payment_status') {
198
+ handleEventData(data);
199
+ }
200
+ else if (normalizedEventType === 'message') {
201
+ try {
202
+ const parsed = JSON.parse(data);
203
+ const embeddedEvent = String((parsed === null || parsed === void 0 ? void 0 : parsed.event) || '').trim().toLowerCase();
204
+ if (embeddedEvent === 'fd_payment_status') {
205
+ handleEventData(data);
206
+ }
207
+ }
208
+ catch (_a) {
209
+ // ignore
210
+ }
211
+ }
212
+ }
213
+ };
214
+ xhr.onreadystatechange = () => {
215
+ if ((xhr.readyState === XMLHttpRequest.HEADERS_RECEIVED ||
216
+ xhr.readyState === XMLHttpRequest.LOADING) &&
217
+ xhr.status === 200) {
218
+ setLoading(false);
106
219
  if (__DEV__)
107
220
  console.log('[Payment] SSE connected for payment status');
108
- },
109
- }, { workflowInstanceId, applicationId, entityid: entityId, providerId });
221
+ }
222
+ };
223
+ xhr.onerror = () => {
224
+ if (__DEV__)
225
+ console.warn('[Payment] SSE connection error');
226
+ };
227
+ xhr.send();
110
228
  return () => {
111
229
  stopPaymentSSE();
112
230
  };
113
- }, [applicationId, paymentUrl, workflowInstanceId, entityId, providerId, startPaymentSSE, stopPaymentSSE]);
231
+ }, [applicationId, paymentUrl, workflowInstanceId, entityId, providerId, stopPaymentSSE]);
114
232
  const handleMessage = async (event) => {
115
233
  var _a, _b, _c;
116
234
  try {
@@ -48,12 +48,15 @@ const fdApi_1 = require("../api/fdApi");
48
48
  const customerApi_1 = require("../api/customerApi");
49
49
  const store_1 = require("../store");
50
50
  const appDataConfig_1 = require("../config/appDataConfig");
51
+ const apiConfig_1 = require("../config/apiConfig");
51
52
  const helpers_1 = require("../navigation/helpers");
52
53
  const paymentSession_1 = require("../state/paymentSession");
53
54
  const native_1 = require("@react-navigation/native");
54
55
  const bank_1 = require("../constants/strings/bank");
55
56
  const common_1 = require("../constants/strings/common");
56
- const usePaymentSSE_1 = require("../hooks/usePaymentSSE");
57
+ const sseParser_1 = require("../utils/sseParser");
58
+ const encryption_1 = require("../utils/encryption");
59
+ const encryptionConfig_1 = require("../config/encryptionConfig");
57
60
  const PaymentStatus = ({ onRetry, onContinue, status, transactionId, fdData }) => {
58
61
  var _a;
59
62
  const colors = (0, ThemeContext_1.useColors)();
@@ -74,7 +77,9 @@ const PaymentStatus = ({ onRetry, onContinue, status, transactionId, fdData }) =
74
77
  const applicationId = (0, store_1.useAppSelector)((state) => { var _a; return (_a = state === null || state === void 0 ? void 0 : state.onboarding) === null || _a === void 0 ? void 0 : _a.applicationId; });
75
78
  const entityId = (0, store_1.useAppSelector)((state) => { var _a; return (_a = state === null || state === void 0 ? void 0 : state.onboarding) === null || _a === void 0 ? void 0 : _a.entityid; });
76
79
  const providerId = (0, store_1.useAppSelector)((state) => { var _a; return (_a = state === null || state === void 0 ? void 0 : state.onboarding) === null || _a === void 0 ? void 0 : _a.providerId; });
77
- const { start: startPaymentSSE, stop: stopPaymentSSE } = (0, usePaymentSSE_1.usePaymentSSE)();
80
+ const sseXhrRef = (0, react_1.useRef)(null);
81
+ const sseLastIndexRef = (0, react_1.useRef)(0);
82
+ const sseBufferRef = (0, react_1.useRef)({ value: '' });
78
83
  // Payment Retry API
79
84
  const [paymentRetry, { data: paymentRetryResponse, error: paymentRetryError, isLoading: isLoadingPaymentRetry, }] = (0, fdApi_1.usePaymentRetryMutation)();
80
85
  // Get Customer Applications API
@@ -98,32 +103,143 @@ const PaymentStatus = ({ onRetry, onContinue, status, transactionId, fdData }) =
98
103
  const formatAmount = (amount) => {
99
104
  return amount.toLocaleString('en-IN');
100
105
  };
106
+ const stopPaymentSSE = (0, react_1.useCallback)(() => {
107
+ if (sseXhrRef.current) {
108
+ sseXhrRef.current.abort();
109
+ sseXhrRef.current = null;
110
+ }
111
+ sseLastIndexRef.current = 0;
112
+ sseBufferRef.current = { value: '' };
113
+ }, []);
101
114
  (0, react_1.useEffect)(() => {
115
+ var _a;
102
116
  if (currentStatus !== 'pending' || !applicationId) {
103
117
  stopPaymentSSE();
104
118
  return;
105
119
  }
106
- startPaymentSSE(applicationId, {
107
- onPaymentStatus: (status) => {
108
- const normalized = String(status || '').toUpperCase();
109
- if (normalized === 'SUCCESS') {
120
+ const envData = (0, appDataConfig_1.getEnvironmentData)();
121
+ const apiConfig = (0, apiConfig_1.getApiConfig)();
122
+ const baseUrl = ((envData === null || envData === void 0 ? void 0 : envData.apiBaseUrl) || (apiConfig === null || apiConfig === void 0 ? void 0 : apiConfig.baseUrl) || '').replace(/\/$/, '');
123
+ const url = baseUrl ? `${baseUrl}/events?applicationId=${encodeURIComponent(applicationId)}` : '';
124
+ if (!url)
125
+ return;
126
+ stopPaymentSSE();
127
+ const xhr = new XMLHttpRequest();
128
+ sseXhrRef.current = xhr;
129
+ xhr.open('GET', url);
130
+ const apiKey = (envData === null || envData === void 0 ? void 0 : envData.apiKey) || ((_a = apiConfig === null || apiConfig === void 0 ? void 0 : apiConfig.headers) === null || _a === void 0 ? void 0 : _a['X-API-Key']) || '';
131
+ if (apiKey) {
132
+ xhr.setRequestHeader('x-api-key', apiKey);
133
+ xhr.setRequestHeader('X-API-Key', apiKey);
134
+ }
135
+ const secureHeaders = (0, apiConfig_1.getSecureHeaders)();
136
+ Object.entries(secureHeaders).forEach(([key, value]) => {
137
+ if (key.toLowerCase() !== 'content-type') {
138
+ xhr.setRequestHeader(key, value);
139
+ }
140
+ });
141
+ xhr.setRequestHeader('Accept', 'text/event-stream');
142
+ xhr.setRequestHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
143
+ xhr.setRequestHeader('Pragma', 'no-cache');
144
+ xhr.setRequestHeader('Expires', '0');
145
+ try {
146
+ const userInfo = (0, appDataConfig_1.getUserInfoForAPI)();
147
+ const userRefId = (userInfo === null || userInfo === void 0 ? void 0 : userInfo.userReferenceId) || (userInfo === null || userInfo === void 0 ? void 0 : userInfo.id);
148
+ if (userRefId) {
149
+ xhr.setRequestHeader('userreferenceid', userRefId);
150
+ xhr.setRequestHeader('userReferenceId', userRefId);
151
+ }
152
+ }
153
+ catch (_b) {
154
+ // ignore
155
+ }
156
+ if (providerId) {
157
+ xhr.setRequestHeader('provider', providerId);
158
+ xhr.setRequestHeader('providerid', providerId);
159
+ xhr.setRequestHeader('providerId', providerId);
160
+ }
161
+ if (workflowInstanceId) {
162
+ xhr.setRequestHeader('workflowInstanceId', workflowInstanceId);
163
+ xhr.setRequestHeader('workflowinstanceid', workflowInstanceId);
164
+ }
165
+ if (applicationId) {
166
+ xhr.setRequestHeader('applicationId', applicationId);
167
+ xhr.setRequestHeader('applicationid', applicationId);
168
+ }
169
+ if (entityId) {
170
+ xhr.setRequestHeader('entityid', entityId);
171
+ xhr.setRequestHeader('entityId', entityId);
172
+ }
173
+ const handleEventData = async (rawData) => {
174
+ var _a, _b, _c, _d;
175
+ try {
176
+ const parsed = JSON.parse(rawData || '{}');
177
+ let payload = parsed;
178
+ if (typeof (parsed === null || parsed === void 0 ? void 0 : parsed.encryptedResponse) === 'string' && parsed.encryptedResponse) {
179
+ try {
180
+ const config = (0, encryptionConfig_1.getEncryptionConfig)();
181
+ const decrypted = await (0, encryption_1.decryptResponse)({ encryptedResponse: parsed.encryptedResponse }, config);
182
+ payload = (decrypted || {});
183
+ }
184
+ catch (_e) {
185
+ // ignore and use raw payload
186
+ }
187
+ }
188
+ const payloadData = (payload === null || payload === void 0 ? void 0 : payload.data) || {};
189
+ const status = String((_d = (_c = (_b = (_a = payload === null || payload === void 0 ? void 0 : payload.paymentStatus) !== null && _a !== void 0 ? _a : payload === null || payload === void 0 ? void 0 : payload.payment_status) !== null && _b !== void 0 ? _b : payloadData === null || payloadData === void 0 ? void 0 : payloadData.paymentStatus) !== null && _c !== void 0 ? _c : payloadData === null || payloadData === void 0 ? void 0 : payloadData.payment_status) !== null && _d !== void 0 ? _d : '').toUpperCase();
190
+ if (status === 'SUCCESS') {
110
191
  setCurrentStatus('success');
111
192
  stopPaymentSSE();
112
193
  return;
113
194
  }
114
- if (normalized === 'FAILED') {
195
+ if (status === 'FAILED') {
115
196
  setCurrentStatus('failed');
116
197
  stopPaymentSSE();
117
198
  }
118
- },
119
- onError: () => {
120
- // keep pending state; stream can be restarted on re-render
121
- },
122
- });
199
+ }
200
+ catch (_f) {
201
+ // ignore parse errors
202
+ }
203
+ };
204
+ xhr.onprogress = () => {
205
+ const newText = xhr.responseText.slice(sseLastIndexRef.current);
206
+ sseLastIndexRef.current = xhr.responseText.length;
207
+ if (!newText)
208
+ return;
209
+ const events = (0, sseParser_1.parseSSEBuffer)(sseBufferRef.current, newText);
210
+ for (const { eventType, data } of events) {
211
+ if (!data)
212
+ continue;
213
+ const normalizedEventType = String(eventType || '').trim().toLowerCase();
214
+ if (normalizedEventType === 'fd_payment_status') {
215
+ handleEventData(data);
216
+ }
217
+ else if (normalizedEventType === 'message') {
218
+ try {
219
+ const parsed = JSON.parse(data);
220
+ const embeddedEvent = String((parsed === null || parsed === void 0 ? void 0 : parsed.event) || '').trim().toLowerCase();
221
+ if (embeddedEvent === 'fd_payment_status') {
222
+ handleEventData(data);
223
+ }
224
+ }
225
+ catch (_a) {
226
+ // ignore
227
+ }
228
+ }
229
+ }
230
+ };
231
+ xhr.send();
123
232
  return () => {
124
233
  stopPaymentSSE();
125
234
  };
126
- }, [applicationId, currentStatus, startPaymentSSE, stopPaymentSSE]);
235
+ }, [
236
+ applicationId,
237
+ currentStatus,
238
+ entityId,
239
+ providerId,
240
+ stopPaymentSSE,
241
+ workflowInstanceId
242
+ ]);
127
243
  // Handle payment retry when status is failed
128
244
  const handlePaymentRetry = async () => {
129
245
  var _a;
@@ -4,10 +4,26 @@ exports.parseSSEBuffer = parseSSEBuffer;
4
4
  function parseSSEBuffer(buffer, chunk) {
5
5
  const results = [];
6
6
  buffer.value += chunk;
7
- let idx;
8
- while ((idx = buffer.value.indexOf('\n\n')) >= 0) {
7
+ let idx = -1;
8
+ let delimiterLength = 0;
9
+ const findDelimiter = () => {
10
+ const unixIdx = buffer.value.indexOf('\n\n');
11
+ const windowsIdx = buffer.value.indexOf('\r\n\r\n');
12
+ if (windowsIdx >= 0 && (unixIdx < 0 || windowsIdx < unixIdx)) {
13
+ idx = windowsIdx;
14
+ delimiterLength = 4;
15
+ return true;
16
+ }
17
+ if (unixIdx >= 0) {
18
+ idx = unixIdx;
19
+ delimiterLength = 2;
20
+ return true;
21
+ }
22
+ return false;
23
+ };
24
+ while (findDelimiter()) {
9
25
  const block = buffer.value.slice(0, idx);
10
- buffer.value = buffer.value.slice(idx + 2);
26
+ buffer.value = buffer.value.slice(idx + delimiterLength);
11
27
  let eventType = 'message';
12
28
  const dataparts = [];
13
29
  for (const line of block.split(/\r?\n/)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finspringinnovations/fdsdk",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "FD SDK for React Native applications",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -5,12 +5,18 @@ import { useColors, useTypography, useTheme } from '../theme/ThemeContext';
5
5
  interface InterestRateCardProps {
6
6
  interestRate: string;
7
7
  maturityAmount: string;
8
+ /** Interest payout amount (e.g. from sdrCalc[0].intPayAmt), shown below Interest Rate */
9
+ intPayAmt?: string;
10
+ /** Total interest earnings (e.g. from sdrCalc[0].totalInterestEarnings), shown below On Maturity */
11
+ totalInterestEarnings?: string;
8
12
  children?: React.ReactNode;
9
13
  }
10
14
 
11
15
  const InterestRateCard: React.FC<InterestRateCardProps> = ({
12
16
  interestRate,
13
17
  maturityAmount,
18
+ intPayAmt,
19
+ totalInterestEarnings,
14
20
  children,
15
21
  }) => {
16
22
  const colors = useColors();
@@ -26,15 +32,31 @@ const InterestRateCard: React.FC<InterestRateCardProps> = ({
26
32
  <Text style={styles.value}>{interestRate}</Text>
27
33
  </View>
28
34
  <View style={styles.right}>
29
-
30
- <Text style={styles.label}>On Maturity</Text>
35
+ <Text style={styles.label}>Amount On Maturity</Text>
31
36
  <Text style={styles.valueRight}>{maturityAmount}</Text>
32
-
33
37
  </View>
34
-
35
38
  </View>
39
+ {(intPayAmt != null || totalInterestEarnings != null) && (
40
+ <View style={[styles.row, styles.secondRow]}>
41
+ <View style={styles.left}>
42
+ {intPayAmt != null && (
43
+ <>
44
+ <Text style={styles.label}>Total Interest</Text>
45
+ <Text style={styles.value}>{intPayAmt}</Text>
46
+ </>
47
+ )}
48
+ </View>
49
+ <View style={styles.right}>
50
+ {totalInterestEarnings != null && (
51
+ <>
52
+ <Text style={styles.label}>On Maturity Interest</Text>
53
+ <Text style={styles.valueRight}>{totalInterestEarnings}</Text>
54
+ </>
55
+ )}
56
+ </View>
57
+ </View>
58
+ )}
36
59
  {children}
37
-
38
60
  </View>
39
61
  );
40
62
  };
@@ -51,6 +73,9 @@ const createStyles = (colors: any, typography: any, themeName: string) => StyleS
51
73
  flexDirection: 'row',
52
74
  justifyContent: 'space-between',
53
75
  },
76
+ secondRow: {
77
+ marginTop: 12,
78
+ },
54
79
  left: {
55
80
  flex: 1,
56
81
  },
@@ -72,6 +97,9 @@ const createStyles = (colors: any, typography: any, themeName: string) => StyleS
72
97
  ...typography.styles.bodyLarge,
73
98
  fontWeight: '700',
74
99
  color: colors.text,
100
+ alignItems: 'center',
101
+ justifyContent: 'center',
102
+ marginRight: 10,
75
103
  },
76
104
  });
77
105
 
@@ -6,6 +6,11 @@ export interface EnvironmentData {
6
6
  apiKey?: string;
7
7
  encryptionKey?: string;
8
8
  enableLogging?: boolean;
9
+ sseMinimalLogs?: boolean;
10
+ enableVerboseSSELogging?: boolean;
11
+ sseReconnectAttempts?: number;
12
+ sseReconnectDelayMs?: number;
13
+ sseConnectTimeoutMs?: number;
9
14
  }
10
15
 
11
16
  /**