@airxpay/sdk-ui 1.0.6 → 1.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.
- package/dist/api/client.d.ts +6 -0
- package/dist/api/client.js +104 -0
- package/dist/api/merchant.d.ts +30 -9
- package/dist/api/merchant.js +51 -17
- package/dist/components/steps/KYCVerification.d.ts +2 -2
- package/dist/components/steps/KYCVerification.js +226 -45
- package/dist/components/steps/OnboardingComplete.d.ts +17 -12
- package/dist/components/steps/OnboardingComplete.js +266 -665
- package/dist/components/ui/MerchantOnboard/MerchantOnboarding.js +1 -1
- package/dist/contexts/AirXPayProvider.d.ts +11 -7
- package/dist/contexts/AirXPayProvider.js +49 -29
- package/dist/hooks/MerchantOnboarding.d.ts +12 -3
- package/dist/hooks/MerchantOnboarding.js +118 -4
- package/dist/index.d.ts +12 -7
- package/dist/index.js +23 -9
- package/dist/sdk/airxpay.d.ts +4 -1
- package/dist/types/merchantTypes.d.ts +58 -29
- package/dist/types/merchantTypes.js +4 -1
- package/dist/types/merchantTypes.ts +66 -30
- package/dist/types/type.ts +0 -1
- package/dist/utils/jwt.d.ts +14 -0
- package/dist/utils/jwt.js +40 -0
- package/dist/utils/tokenStorage.d.ts +12 -0
- package/dist/utils/tokenStorage.js +59 -0
- package/package.json +3 -1
- package/dist/components/ui/MerchantOnboard/CustomSegmentedButtons.d.ts +0 -15
- package/dist/components/ui/MerchantOnboard/CustomSegmentedButtons.js +0 -64
- package/dist/hooks/useAirXPayReady.d.ts +0 -6
- package/dist/hooks/useAirXPayReady.js +0 -27
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontend SDK - JWT Utilities
|
|
3
|
+
* Secure JWT decoding without external libraries
|
|
4
|
+
*/
|
|
5
|
+
export interface JWTPayload {
|
|
6
|
+
merchantId?: string;
|
|
7
|
+
sub?: string;
|
|
8
|
+
exp?: number;
|
|
9
|
+
iat?: number;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
export declare function decodeJWT(token: string): JWTPayload | null;
|
|
13
|
+
export declare function getMerchantIdFromToken(token: string): string | null;
|
|
14
|
+
export declare function isTokenExpired(token: string): boolean;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Frontend SDK - JWT Utilities
|
|
4
|
+
* Secure JWT decoding without external libraries
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.decodeJWT = decodeJWT;
|
|
8
|
+
exports.getMerchantIdFromToken = getMerchantIdFromToken;
|
|
9
|
+
exports.isTokenExpired = isTokenExpired;
|
|
10
|
+
function decodeJWT(token) {
|
|
11
|
+
try {
|
|
12
|
+
const parts = token.split('.');
|
|
13
|
+
if (parts.length !== 3) {
|
|
14
|
+
throw new Error('Invalid JWT format');
|
|
15
|
+
}
|
|
16
|
+
const payload = parts[1];
|
|
17
|
+
const base64 = payload.replace(/-/g, '+').replace(/_/g, '/');
|
|
18
|
+
const jsonPayload = decodeURIComponent(atob(base64)
|
|
19
|
+
.split('')
|
|
20
|
+
.map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
|
|
21
|
+
.join(''));
|
|
22
|
+
return JSON.parse(jsonPayload);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
console.error('[AirXPay] Error decoding JWT:', error);
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function getMerchantIdFromToken(token) {
|
|
30
|
+
const payload = decodeJWT(token);
|
|
31
|
+
// Try different possible claim names
|
|
32
|
+
return (payload === null || payload === void 0 ? void 0 : payload.merchantId) || (payload === null || payload === void 0 ? void 0 : payload.sub) || null;
|
|
33
|
+
}
|
|
34
|
+
function isTokenExpired(token) {
|
|
35
|
+
const payload = decodeJWT(token);
|
|
36
|
+
if (!(payload === null || payload === void 0 ? void 0 : payload.exp))
|
|
37
|
+
return false;
|
|
38
|
+
const currentTime = Math.floor(Date.now() / 1000);
|
|
39
|
+
return payload.exp < currentTime;
|
|
40
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontend SDK - Token Storage
|
|
3
|
+
* AsyncStorage-based token management
|
|
4
|
+
*/
|
|
5
|
+
export declare const getStoredToken: () => Promise<string | null>;
|
|
6
|
+
export declare const setStoredToken: (token: string) => Promise<void>;
|
|
7
|
+
export declare const clearStoredToken: () => Promise<void>;
|
|
8
|
+
export declare const tokenStorage: {
|
|
9
|
+
get: () => Promise<string | null>;
|
|
10
|
+
set: (token: string) => Promise<void>;
|
|
11
|
+
clear: () => Promise<void>;
|
|
12
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Frontend SDK - Token Storage
|
|
4
|
+
* AsyncStorage-based token management
|
|
5
|
+
*/
|
|
6
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
7
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
8
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
9
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
10
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
11
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
12
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
16
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.tokenStorage = exports.clearStoredToken = exports.setStoredToken = exports.getStoredToken = void 0;
|
|
20
|
+
const async_storage_1 = __importDefault(require("@react-native-async-storage/async-storage"));
|
|
21
|
+
const TOKEN_KEY = 'AIRXPAY_MERCHANT_TOKEN';
|
|
22
|
+
const getStoredToken = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
23
|
+
try {
|
|
24
|
+
return yield async_storage_1.default.getItem(TOKEN_KEY);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
console.error('[AirXPay] Error getting stored token:', error);
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
exports.getStoredToken = getStoredToken;
|
|
32
|
+
const setStoredToken = (token) => __awaiter(void 0, void 0, void 0, function* () {
|
|
33
|
+
if (!(token === null || token === void 0 ? void 0 : token.trim())) {
|
|
34
|
+
throw new Error('Invalid token provided');
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
yield async_storage_1.default.setItem(TOKEN_KEY, token);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
console.error('[AirXPay] Error setting stored token:', error);
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
exports.setStoredToken = setStoredToken;
|
|
45
|
+
const clearStoredToken = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
46
|
+
try {
|
|
47
|
+
yield async_storage_1.default.removeItem(TOKEN_KEY);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.error('[AirXPay] Error clearing stored token:', error);
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
exports.clearStoredToken = clearStoredToken;
|
|
55
|
+
exports.tokenStorage = {
|
|
56
|
+
get: exports.getStoredToken,
|
|
57
|
+
set: exports.setStoredToken,
|
|
58
|
+
clear: exports.clearStoredToken,
|
|
59
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@airxpay/sdk-ui",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "AirXPay Initialization UI Components for React & React Native",
|
|
5
5
|
"author": "Tafseel Khan",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,7 +21,9 @@
|
|
|
21
21
|
"axios": "^1.13.5"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
+
"@react-native-async-storage/async-storage": "^2.2.0",
|
|
24
25
|
"@react-native-community/datetimepicker": "^8.6.0",
|
|
26
|
+
"@react-navigation/native": "^7.1.28",
|
|
25
27
|
"@types/react": "^19.2.14",
|
|
26
28
|
"copyfiles": "^2.4.1",
|
|
27
29
|
"cpx": "^1.5.0",
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { ViewStyle } from 'react-native';
|
|
3
|
-
interface ButtonType {
|
|
4
|
-
value: string;
|
|
5
|
-
label: string;
|
|
6
|
-
showSelectedCheck?: boolean;
|
|
7
|
-
}
|
|
8
|
-
interface CustomSegmentedButtonsProps {
|
|
9
|
-
value: string;
|
|
10
|
-
onValueChange: (value: string) => void;
|
|
11
|
-
buttons: ButtonType[];
|
|
12
|
-
style?: ViewStyle;
|
|
13
|
-
}
|
|
14
|
-
declare const CustomSegmentedButtons: React.FC<CustomSegmentedButtonsProps>;
|
|
15
|
-
export default CustomSegmentedButtons;
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const react_1 = __importDefault(require("react"));
|
|
7
|
-
const react_native_1 = require("react-native");
|
|
8
|
-
const styles = react_native_1.StyleSheet.create({
|
|
9
|
-
segmentedContainer: {
|
|
10
|
-
flexDirection: 'row',
|
|
11
|
-
backgroundColor: '#f0f0f0',
|
|
12
|
-
borderRadius: 8,
|
|
13
|
-
padding: 4,
|
|
14
|
-
},
|
|
15
|
-
segmentedButton: {
|
|
16
|
-
flex: 1,
|
|
17
|
-
flexDirection: 'row',
|
|
18
|
-
justifyContent: 'center',
|
|
19
|
-
alignItems: 'center',
|
|
20
|
-
paddingVertical: 8,
|
|
21
|
-
paddingHorizontal: 12,
|
|
22
|
-
borderRadius: 6,
|
|
23
|
-
backgroundColor: 'transparent',
|
|
24
|
-
},
|
|
25
|
-
segmentedButtonActive: {
|
|
26
|
-
backgroundColor: '#6200ee',
|
|
27
|
-
elevation: 2,
|
|
28
|
-
shadowColor: '#000',
|
|
29
|
-
shadowOffset: { width: 0, height: 1 },
|
|
30
|
-
shadowOpacity: 0.2,
|
|
31
|
-
shadowRadius: 1,
|
|
32
|
-
},
|
|
33
|
-
segmentedButtonText: {
|
|
34
|
-
fontSize: 14,
|
|
35
|
-
fontWeight: '500',
|
|
36
|
-
color: '#666',
|
|
37
|
-
},
|
|
38
|
-
segmentedButtonTextActive: {
|
|
39
|
-
color: 'white',
|
|
40
|
-
},
|
|
41
|
-
segmentedButtonCheck: {
|
|
42
|
-
color: 'white',
|
|
43
|
-
marginLeft: 4,
|
|
44
|
-
fontSize: 14,
|
|
45
|
-
fontWeight: 'bold',
|
|
46
|
-
},
|
|
47
|
-
});
|
|
48
|
-
const CustomSegmentedButtons = ({ value, onValueChange, buttons, style, }) => {
|
|
49
|
-
return (<react_native_1.View style={[styles.segmentedContainer, style]}>
|
|
50
|
-
{buttons.map((button) => (<react_native_1.TouchableOpacity key={button.value} style={[
|
|
51
|
-
styles.segmentedButton,
|
|
52
|
-
value === button.value && styles.segmentedButtonActive
|
|
53
|
-
]} onPress={() => onValueChange(button.value)}>
|
|
54
|
-
<react_native_1.Text style={[
|
|
55
|
-
styles.segmentedButtonText,
|
|
56
|
-
value === button.value && styles.segmentedButtonTextActive
|
|
57
|
-
]}>
|
|
58
|
-
{button.label}
|
|
59
|
-
</react_native_1.Text>
|
|
60
|
-
{button.showSelectedCheck && value === button.value && (<react_native_1.Text style={styles.segmentedButtonCheck}>✓</react_native_1.Text>)}
|
|
61
|
-
</react_native_1.TouchableOpacity>))}
|
|
62
|
-
</react_native_1.View>);
|
|
63
|
-
};
|
|
64
|
-
exports.default = CustomSegmentedButtons;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.AirXPayReady = void 0;
|
|
13
|
-
const merchant_1 = require("../api/merchant");
|
|
14
|
-
class AirXPayReady {
|
|
15
|
-
constructor(config) {
|
|
16
|
-
if (!config.publicKey) {
|
|
17
|
-
throw new Error("Public key is required");
|
|
18
|
-
}
|
|
19
|
-
this.publicKey = config.publicKey;
|
|
20
|
-
}
|
|
21
|
-
initialize() {
|
|
22
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
-
return yield (0, merchant_1.verifyPublicKey)(this.publicKey);
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
exports.AirXPayReady = AirXPayReady;
|