@explorins/pers-sdk-react-native 1.3.2
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 +200 -0
- package/dist/hooks/index.d.ts +8 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +8 -0
- package/dist/hooks/useAuth.d.ts +12 -0
- package/dist/hooks/useAuth.d.ts.map +1 -0
- package/dist/hooks/useAuth.js +16 -0
- package/dist/hooks/useBusiness.d.ts +7 -0
- package/dist/hooks/useBusiness.d.ts.map +1 -0
- package/dist/hooks/useBusiness.js +64 -0
- package/dist/hooks/useCampaigns.d.ts +8 -0
- package/dist/hooks/useCampaigns.d.ts.map +1 -0
- package/dist/hooks/useCampaigns.js +90 -0
- package/dist/hooks/useRedemptions.d.ts +9 -0
- package/dist/hooks/useRedemptions.d.ts.map +1 -0
- package/dist/hooks/useRedemptions.js +121 -0
- package/dist/hooks/useTokens.d.ts +6 -0
- package/dist/hooks/useTokens.d.ts.map +1 -0
- package/dist/hooks/useTokens.js +48 -0
- package/dist/hooks/useTransactions.d.ts +7 -0
- package/dist/hooks/useTransactions.d.ts.map +1 -0
- package/dist/hooks/useTransactions.js +78 -0
- package/dist/hooks/useWeb3.d.ts +11 -0
- package/dist/hooks/useWeb3.d.ts.map +1 -0
- package/dist/hooks/useWeb3.js +63 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.esm.js +1057 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +1077 -0
- package/dist/index.js.map +1 -0
- package/dist/polyfills/index.d.ts +3 -0
- package/dist/polyfills/index.d.ts.map +1 -0
- package/dist/polyfills/index.js +13 -0
- package/dist/polyfills/index.simple.d.ts +2 -0
- package/dist/polyfills/index.simple.d.ts.map +1 -0
- package/dist/polyfills/index.simple.js +17 -0
- package/dist/providers/PersSDKProvider.d.ts +29 -0
- package/dist/providers/PersSDKProvider.d.ts.map +1 -0
- package/dist/providers/PersSDKProvider.js +194 -0
- package/dist/providers/react-native-auth-provider.d.ts +92 -0
- package/dist/providers/react-native-auth-provider.d.ts.map +1 -0
- package/dist/providers/react-native-auth-provider.js +268 -0
- package/dist/providers/react-native-http-client.d.ts +29 -0
- package/dist/providers/react-native-http-client.d.ts.map +1 -0
- package/dist/providers/react-native-http-client.js +94 -0
- package/package.json +157 -0
- package/src/hooks/index.ts +8 -0
- package/src/hooks/useAuth.ts +43 -0
- package/src/hooks/useBusiness.ts +69 -0
- package/src/hooks/useCampaigns.ts +96 -0
- package/src/hooks/useRedemptions.ts +129 -0
- package/src/hooks/useTokens.ts +53 -0
- package/src/hooks/useTransactions.ts +85 -0
- package/src/hooks/useWeb3.ts +70 -0
- package/src/index.ts +51 -0
- package/src/polyfills/index.simple.ts +22 -0
- package/src/polyfills/index.ts +16 -0
- package/src/providers/PersSDKProvider.tsx +274 -0
- package/src/providers/react-native-auth-provider.ts +332 -0
- package/src/providers/react-native-http-client.ts +129 -0
- package/src/types/external-modules.d.ts +13 -0
- package/src/types/react-native-globals.d.ts +46 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-native-http-client.d.ts","sourceRoot":"","sources":["../../src/providers/react-native-http-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC;CACzD;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1D,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACtE,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACrE,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC9D;AAED,qBAAa,qBAAsB,YAAW,UAAU;IACtD,OAAO,CAAC,OAAO,CAAC,CAAS;gBAEb,OAAO,CAAC,EAAE,MAAM;IAItB,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAI/D,IAAI,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAI5E,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAI3E,MAAM,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;YAI1D,OAAO;IAsErB,OAAO,CAAC,QAAQ;CAcjB"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Client implementation for React Native
|
|
3
|
+
*
|
|
4
|
+
* This implementation properly implements the core SDK's HttpClient interface
|
|
5
|
+
* and uses fetch API which is available in React Native.
|
|
6
|
+
*/
|
|
7
|
+
export class ReactNativeHttpClient {
|
|
8
|
+
constructor(baseURL) {
|
|
9
|
+
this.baseURL = baseURL;
|
|
10
|
+
}
|
|
11
|
+
async get(url, options) {
|
|
12
|
+
return this.request('GET', url, undefined, options);
|
|
13
|
+
}
|
|
14
|
+
async post(url, body, options) {
|
|
15
|
+
return this.request('POST', url, body, options);
|
|
16
|
+
}
|
|
17
|
+
async put(url, body, options) {
|
|
18
|
+
return this.request('PUT', url, body, options);
|
|
19
|
+
}
|
|
20
|
+
async delete(url, options) {
|
|
21
|
+
return this.request('DELETE', url, undefined, options);
|
|
22
|
+
}
|
|
23
|
+
async request(method, url, body, options) {
|
|
24
|
+
const fullUrl = this.buildUrl(url, options?.params);
|
|
25
|
+
const config = {
|
|
26
|
+
method,
|
|
27
|
+
headers: {
|
|
28
|
+
'Content-Type': 'application/json',
|
|
29
|
+
...options?.headers,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
// Add timeout if specified
|
|
33
|
+
if (options?.timeout) {
|
|
34
|
+
const controller = new AbortController();
|
|
35
|
+
config.signal = controller.signal;
|
|
36
|
+
setTimeout(() => controller.abort(), options.timeout);
|
|
37
|
+
}
|
|
38
|
+
// Add body for POST/PUT requests
|
|
39
|
+
if (body && (method === 'POST' || method === 'PUT')) {
|
|
40
|
+
config.body = JSON.stringify(body);
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const response = await fetch(fullUrl, config);
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
// Try to get error details from response
|
|
46
|
+
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
|
|
47
|
+
try {
|
|
48
|
+
const errorBody = await response.text();
|
|
49
|
+
if (errorBody) {
|
|
50
|
+
errorMessage += ` - ${errorBody}`;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
// Ignore errors when reading error body
|
|
55
|
+
}
|
|
56
|
+
throw new Error(errorMessage);
|
|
57
|
+
}
|
|
58
|
+
// Handle different response types
|
|
59
|
+
switch (options?.responseType) {
|
|
60
|
+
case 'text':
|
|
61
|
+
return response.text();
|
|
62
|
+
case 'blob':
|
|
63
|
+
return response.blob();
|
|
64
|
+
case 'arraybuffer':
|
|
65
|
+
return response.arrayBuffer();
|
|
66
|
+
case 'json':
|
|
67
|
+
default:
|
|
68
|
+
// Check if response has content
|
|
69
|
+
const contentLength = response.headers.get('content-length');
|
|
70
|
+
if (contentLength === '0' || response.status === 204) {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
return response.json();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
78
|
+
throw new Error(`Request timeout after ${options?.timeout}ms`);
|
|
79
|
+
}
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
buildUrl(url, params) {
|
|
84
|
+
const fullUrl = this.baseURL ? `${this.baseURL}${url}` : url;
|
|
85
|
+
if (!params || Object.keys(params).length === 0) {
|
|
86
|
+
return fullUrl;
|
|
87
|
+
}
|
|
88
|
+
const urlObj = new URL(fullUrl);
|
|
89
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
90
|
+
urlObj.searchParams.append(key, value);
|
|
91
|
+
});
|
|
92
|
+
return urlObj.toString();
|
|
93
|
+
}
|
|
94
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@explorins/pers-sdk-react-native",
|
|
3
|
+
"version": "1.3.2",
|
|
4
|
+
"description": "React Native SDK for PERS Platform - Tourism Loyalty System",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc && rollup -c --bundleConfigAsCjs",
|
|
9
|
+
"dev": "tsc --watch",
|
|
10
|
+
"clean": "rimraf dist",
|
|
11
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"pers",
|
|
15
|
+
"sdk",
|
|
16
|
+
"react-native",
|
|
17
|
+
"tourism",
|
|
18
|
+
"loyalty",
|
|
19
|
+
"blockchain",
|
|
20
|
+
"web3"
|
|
21
|
+
],
|
|
22
|
+
"author": "eXplorins",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@explorins/pers-sdk": "^1.3.2",
|
|
26
|
+
"@explorins/pers-shared": "^2.1.40",
|
|
27
|
+
"buffer": "^6.0.3",
|
|
28
|
+
"ethers": "^6.15.0",
|
|
29
|
+
"web3": "^4.16.0"
|
|
30
|
+
},
|
|
31
|
+
"browser": {
|
|
32
|
+
"crypto": false,
|
|
33
|
+
"url": false,
|
|
34
|
+
"http": false,
|
|
35
|
+
"https": false,
|
|
36
|
+
"zlib": false,
|
|
37
|
+
"stream": false,
|
|
38
|
+
"assert": false,
|
|
39
|
+
"path": false,
|
|
40
|
+
"fs": false,
|
|
41
|
+
"os": false,
|
|
42
|
+
"readable-stream": false,
|
|
43
|
+
"util": false,
|
|
44
|
+
"events": false,
|
|
45
|
+
"net": false,
|
|
46
|
+
"tls": false,
|
|
47
|
+
"child_process": false,
|
|
48
|
+
"pngjs": false,
|
|
49
|
+
"pngjs/lib/bitmapper": false,
|
|
50
|
+
"pngjs/lib/parser-async": false,
|
|
51
|
+
"pngjs/lib/parser-sync": false,
|
|
52
|
+
"./bitmapper": false,
|
|
53
|
+
"hash-base": false,
|
|
54
|
+
"@ethereumjs/common": false,
|
|
55
|
+
"@ethereumjs/tx": false,
|
|
56
|
+
"@ethereumjs/util": false,
|
|
57
|
+
"stream-browserify": false,
|
|
58
|
+
"crypto-browserify": false,
|
|
59
|
+
"inherits": false,
|
|
60
|
+
"safe-buffer": false,
|
|
61
|
+
"string_decoder": false,
|
|
62
|
+
"process-nextick-args": false,
|
|
63
|
+
"isarray": false,
|
|
64
|
+
"core-util-is": false,
|
|
65
|
+
"util-deprecate": false,
|
|
66
|
+
"ethereum-cryptography": false,
|
|
67
|
+
"keccak": false,
|
|
68
|
+
"secp256k1": false,
|
|
69
|
+
"scrypt-js": false,
|
|
70
|
+
"bech32": false,
|
|
71
|
+
"ws": false,
|
|
72
|
+
"xhr2-cookies": false,
|
|
73
|
+
"aes-js": false,
|
|
74
|
+
"@ethersproject/sha2": false,
|
|
75
|
+
"@ethersproject/pbkdf2": false,
|
|
76
|
+
"@ethersproject/scrypt": false
|
|
77
|
+
},
|
|
78
|
+
"peerDependencies": {
|
|
79
|
+
"react": ">=16.8.0",
|
|
80
|
+
"react-native": ">=0.60.0"
|
|
81
|
+
},
|
|
82
|
+
"peerDependenciesMeta": {
|
|
83
|
+
"react-native-keychain": {
|
|
84
|
+
"optional": true
|
|
85
|
+
},
|
|
86
|
+
"@react-native-async-storage/async-storage": {
|
|
87
|
+
"optional": false
|
|
88
|
+
},
|
|
89
|
+
"react-native-get-random-values": {
|
|
90
|
+
"optional": true
|
|
91
|
+
},
|
|
92
|
+
"react-native-url-polyfill": {
|
|
93
|
+
"optional": true
|
|
94
|
+
},
|
|
95
|
+
"react-native-polyfill-globals": {
|
|
96
|
+
"optional": true
|
|
97
|
+
},
|
|
98
|
+
"web-streams-polyfill": {
|
|
99
|
+
"optional": true
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"overrides": {
|
|
103
|
+
"readable-stream": false,
|
|
104
|
+
"@ethereumjs/common": false,
|
|
105
|
+
"@ethereumjs/util": false,
|
|
106
|
+
"@ethereumjs/rlp": false,
|
|
107
|
+
"@ethereumjs/tx": false,
|
|
108
|
+
"stream": false,
|
|
109
|
+
"util": false,
|
|
110
|
+
"events": false,
|
|
111
|
+
"crypto": false,
|
|
112
|
+
"fs": false,
|
|
113
|
+
"path": false,
|
|
114
|
+
"os": false,
|
|
115
|
+
"net": false,
|
|
116
|
+
"tls": false,
|
|
117
|
+
"child_process": false,
|
|
118
|
+
"hash-base": false,
|
|
119
|
+
"inherits": false,
|
|
120
|
+
"safe-buffer": false,
|
|
121
|
+
"string_decoder": false,
|
|
122
|
+
"process-nextick-args": false,
|
|
123
|
+
"isarray": false,
|
|
124
|
+
"core-util-is": false,
|
|
125
|
+
"util-deprecate": false,
|
|
126
|
+
"ethereum-cryptography": false,
|
|
127
|
+
"keccak": false,
|
|
128
|
+
"secp256k1": false,
|
|
129
|
+
"scrypt-js": false,
|
|
130
|
+
"bech32": false,
|
|
131
|
+
"ws": false,
|
|
132
|
+
"xhr2-cookies": false,
|
|
133
|
+
"aes-js": false,
|
|
134
|
+
"@ethersproject/sha2": false,
|
|
135
|
+
"@ethersproject/pbkdf2": false,
|
|
136
|
+
"@ethersproject/scrypt": false
|
|
137
|
+
},
|
|
138
|
+
"devDependencies": {
|
|
139
|
+
"@react-native-async-storage/async-storage": "^1.19.0",
|
|
140
|
+
"@types/react": "^19.1.1",
|
|
141
|
+
"@types/react-native": "^0.72.8",
|
|
142
|
+
"rimraf": "^5.0.0",
|
|
143
|
+
"rollup": "^4.0.0",
|
|
144
|
+
"rollup-plugin-typescript2": "^0.36.0",
|
|
145
|
+
"typescript": "^5.2.0"
|
|
146
|
+
},
|
|
147
|
+
"files": [
|
|
148
|
+
"dist/**/*",
|
|
149
|
+
"src/**/*",
|
|
150
|
+
"README.md"
|
|
151
|
+
],
|
|
152
|
+
"repository": {
|
|
153
|
+
"type": "git",
|
|
154
|
+
"url": "git+https://github.com/eXplorins/pers-sdk.git",
|
|
155
|
+
"directory": "packages/pers-sdk-react-native"
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Export all hooks (only hooks, no providers to avoid circular dependency)
|
|
2
|
+
export { useAuth } from './useAuth';
|
|
3
|
+
export { useTokens } from './useTokens';
|
|
4
|
+
export { useTransactions } from './useTransactions';
|
|
5
|
+
export { useBusiness } from './useBusiness';
|
|
6
|
+
export { useCampaigns } from './useCampaigns';
|
|
7
|
+
export { useRedemptions } from './useRedemptions';
|
|
8
|
+
export { useWeb3 } from './useWeb3';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { usePersSDK } from '../providers/PersSDKProvider';
|
|
3
|
+
|
|
4
|
+
export interface AuthHook {
|
|
5
|
+
// State
|
|
6
|
+
isInitialized: boolean;
|
|
7
|
+
isAuthenticated: boolean;
|
|
8
|
+
user: any | null;
|
|
9
|
+
accountAddress: string | null;
|
|
10
|
+
|
|
11
|
+
// Actions
|
|
12
|
+
initialize: (config: any) => Promise<void>;
|
|
13
|
+
login: (jwtToken: string, userType?: 'user' | 'admin') => Promise<any>;
|
|
14
|
+
loginWithRawData: (rawUserData: any) => Promise<any>;
|
|
15
|
+
logout: () => Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const useAuth = (): AuthHook => {
|
|
19
|
+
const {
|
|
20
|
+
isInitialized,
|
|
21
|
+
isAuthenticated,
|
|
22
|
+
user,
|
|
23
|
+
accountAddress,
|
|
24
|
+
initialize,
|
|
25
|
+
login,
|
|
26
|
+
loginWithRawData,
|
|
27
|
+
logout,
|
|
28
|
+
} = usePersSDK();
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
// State
|
|
32
|
+
isInitialized,
|
|
33
|
+
isAuthenticated,
|
|
34
|
+
user,
|
|
35
|
+
accountAddress,
|
|
36
|
+
|
|
37
|
+
// Actions
|
|
38
|
+
initialize,
|
|
39
|
+
login,
|
|
40
|
+
loginWithRawData,
|
|
41
|
+
logout,
|
|
42
|
+
};
|
|
43
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { usePersSDK } from '../providers/PersSDKProvider';
|
|
3
|
+
|
|
4
|
+
export const useBusiness = () => {
|
|
5
|
+
const { business, isInitialized } = usePersSDK();
|
|
6
|
+
|
|
7
|
+
const getActiveBusinesses = useCallback(async () => {
|
|
8
|
+
if (!isInitialized) {
|
|
9
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
10
|
+
}
|
|
11
|
+
if (!business?.getActiveBusinesses) {
|
|
12
|
+
console.warn('getActiveBusinesses method not available');
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const result = await business.getActiveBusinesses();
|
|
18
|
+
console.log('✅ Active businesses fetched successfully:', result);
|
|
19
|
+
return result;
|
|
20
|
+
} catch (error) {
|
|
21
|
+
console.error('❌ Failed to fetch active businesses:', error);
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
24
|
+
}, [business]);
|
|
25
|
+
|
|
26
|
+
const getAllBusinessTypes = useCallback(async () => {
|
|
27
|
+
if (!isInitialized) {
|
|
28
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
29
|
+
}
|
|
30
|
+
if (!business?.getAllBusinessTypes) {
|
|
31
|
+
console.warn('getAllBusinessTypes method not available');
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
const result = await business.getAllBusinessTypes();
|
|
37
|
+
console.log('✅ Business types fetched successfully:', result);
|
|
38
|
+
return result;
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error('❌ Failed to fetch business types:', error);
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
}, [business]);
|
|
44
|
+
|
|
45
|
+
const getBusinessById = useCallback(async (businessId: string) => {
|
|
46
|
+
if (!isInitialized) {
|
|
47
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
48
|
+
}
|
|
49
|
+
if (!business?.getBusinessById) {
|
|
50
|
+
throw new Error('getBusinessById method not available');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
const result = await business.getBusinessById(businessId);
|
|
55
|
+
console.log('✅ Business fetched successfully:', result);
|
|
56
|
+
return result;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.error('❌ Failed to fetch business:', error);
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}, [business]);
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
getActiveBusinesses,
|
|
65
|
+
getAllBusinessTypes,
|
|
66
|
+
getBusinessById,
|
|
67
|
+
isAvailable: isInitialized && !!business,
|
|
68
|
+
};
|
|
69
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { usePersSDK } from '../providers/PersSDKProvider';
|
|
3
|
+
|
|
4
|
+
export const useCampaigns = () => {
|
|
5
|
+
const { campaigns, isInitialized, isAuthenticated } = usePersSDK();
|
|
6
|
+
|
|
7
|
+
const getActiveCampaigns = useCallback(async () => {
|
|
8
|
+
if (!isInitialized) {
|
|
9
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
10
|
+
}
|
|
11
|
+
if (!campaigns?.getActiveCampaigns) {
|
|
12
|
+
console.warn('getActiveCampaigns method not available');
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const result = await campaigns.getActiveCampaigns();
|
|
18
|
+
console.log('✅ Active campaigns fetched successfully:', result);
|
|
19
|
+
return result;
|
|
20
|
+
} catch (error) {
|
|
21
|
+
console.error('❌ Failed to fetch active campaigns:', error);
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
24
|
+
}, [campaigns]);
|
|
25
|
+
|
|
26
|
+
const getCampaignById = useCallback(async (campaignId: string) => {
|
|
27
|
+
if (!isInitialized) {
|
|
28
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
29
|
+
}
|
|
30
|
+
if (!campaigns?.getCampaignById) {
|
|
31
|
+
throw new Error('getCampaignById method not available');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
const result = await campaigns.getCampaignById(campaignId);
|
|
36
|
+
console.log('✅ Campaign fetched successfully:', result);
|
|
37
|
+
return result;
|
|
38
|
+
} catch (error) {
|
|
39
|
+
console.error('❌ Failed to fetch campaign:', error);
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}, [campaigns]);
|
|
43
|
+
|
|
44
|
+
const claimCampaign = useCallback(async (request: any) => {
|
|
45
|
+
if (!isInitialized) {
|
|
46
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
47
|
+
}
|
|
48
|
+
if (!isAuthenticated) {
|
|
49
|
+
throw new Error('SDK not authenticated. claimCampaign requires authentication.');
|
|
50
|
+
}
|
|
51
|
+
if (!campaigns?.claimCampaign) {
|
|
52
|
+
throw new Error('claimCampaign method not available');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
console.log('🔄 Claiming campaign with request:', request);
|
|
57
|
+
const result = await campaigns.claimCampaign(request);
|
|
58
|
+
console.log('✅ Campaign claimed successfully:', result);
|
|
59
|
+
return result;
|
|
60
|
+
} catch (error) {
|
|
61
|
+
console.error('❌ Failed to claim campaign:', error);
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
}, [isInitialized, isAuthenticated, campaigns]);
|
|
65
|
+
|
|
66
|
+
const getClaimsForLoggedUser = useCallback(async () => {
|
|
67
|
+
if (!isInitialized) {
|
|
68
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
69
|
+
}
|
|
70
|
+
if (!isAuthenticated) {
|
|
71
|
+
console.warn('SDK not authenticated. getClaimsForLoggedUser requires authentication.');
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
if (!campaigns?.getClaimsForLoggedUser) {
|
|
75
|
+
console.warn('getClaimsForLoggedUser method not available');
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
const result = await campaigns.getClaimsForLoggedUser();
|
|
81
|
+
console.log('✅ User claims fetched successfully:', result);
|
|
82
|
+
return result;
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.error('❌ Failed to fetch user claims:', error);
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
}, [isInitialized, isAuthenticated, campaigns]);
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
getActiveCampaigns,
|
|
91
|
+
getCampaignById,
|
|
92
|
+
claimCampaign,
|
|
93
|
+
getClaimsForLoggedUser,
|
|
94
|
+
isAvailable: isInitialized && !!campaigns,
|
|
95
|
+
};
|
|
96
|
+
};
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { usePersSDK } from '../providers/PersSDKProvider';
|
|
3
|
+
|
|
4
|
+
export const useRedemptions = () => {
|
|
5
|
+
const { redemptions, isInitialized, isAuthenticated } = usePersSDK();
|
|
6
|
+
|
|
7
|
+
// Admin method: Create new redemption offers
|
|
8
|
+
const createRedemption = useCallback(async (redemptionData: any) => {
|
|
9
|
+
if (!isInitialized) {
|
|
10
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
11
|
+
}
|
|
12
|
+
if (!redemptions?.createRedemption) {
|
|
13
|
+
throw new Error('createRedemption method not available - admin access required');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
console.log('🔄 Creating redemption offer with data:', redemptionData);
|
|
18
|
+
const result = await redemptions.createRedemption(redemptionData);
|
|
19
|
+
console.log('✅ Redemption offer created successfully:', result);
|
|
20
|
+
return result;
|
|
21
|
+
} catch (error) {
|
|
22
|
+
console.error('❌ Failed to create redemption offer:', error);
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
}, [redemptions]);
|
|
26
|
+
|
|
27
|
+
const getActiveRedemptions = useCallback(async () => {
|
|
28
|
+
if (!isInitialized) {
|
|
29
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
30
|
+
}
|
|
31
|
+
if (!redemptions?.getActiveRedemptions) {
|
|
32
|
+
console.warn('getActiveRedemptions method not available');
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
const result = await redemptions.getActiveRedemptions();
|
|
38
|
+
console.log('✅ Active redemptions fetched successfully:', result);
|
|
39
|
+
return result;
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error('❌ Failed to fetch active redemptions:', error);
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}, [redemptions]);
|
|
45
|
+
|
|
46
|
+
const getUserRedeems = useCallback(async () => {
|
|
47
|
+
if (!isInitialized) {
|
|
48
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
49
|
+
}
|
|
50
|
+
if (!isAuthenticated) {
|
|
51
|
+
console.warn('SDK not authenticated. getUserRedeems requires authentication.');
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
if (!redemptions?.getUserRedeems) {
|
|
55
|
+
console.warn('getUserRedeems method not available');
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
const result = await redemptions.getUserRedeems();
|
|
61
|
+
console.log('✅ User redemptions fetched successfully:', result);
|
|
62
|
+
return result;
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.error('❌ Failed to fetch user redemptions:', error);
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
}, [isInitialized, isAuthenticated, redemptions]);
|
|
68
|
+
|
|
69
|
+
const redeemRedemption = useCallback(async (redemptionId: string) => {
|
|
70
|
+
if (!isInitialized) {
|
|
71
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
72
|
+
}
|
|
73
|
+
if (!isAuthenticated) {
|
|
74
|
+
throw new Error('SDK not authenticated. redeemRedemption requires authentication.');
|
|
75
|
+
}
|
|
76
|
+
if (!redemptions?.redeemRedemption) {
|
|
77
|
+
throw new Error('redeemRedemption method not available');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
console.log('🔄 Redeeming redemption:', redemptionId);
|
|
82
|
+
const result = await redemptions.redeemRedemption(redemptionId);
|
|
83
|
+
|
|
84
|
+
// React Native specific: Handle signature URLs for redemptions
|
|
85
|
+
if (result?.actionable?.actionUrl) {
|
|
86
|
+
try {
|
|
87
|
+
const { Linking } = require('react-native');
|
|
88
|
+
console.log('🔗 Opening redemption signature URL:', result.actionable.actionUrl);
|
|
89
|
+
await Linking.openURL(result.actionable.actionUrl);
|
|
90
|
+
} catch (linkingError) {
|
|
91
|
+
console.error('❌ Failed to open redemption signature URL:', linkingError);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
console.log('✅ Redemption processed successfully:', result);
|
|
96
|
+
return result;
|
|
97
|
+
} catch (error) {
|
|
98
|
+
console.error('❌ Failed to redeem redemption:', error);
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}, [isInitialized, isAuthenticated, redemptions]);
|
|
102
|
+
|
|
103
|
+
const getRedemptionById = useCallback(async (redemptionId: string) => {
|
|
104
|
+
if (!isInitialized) {
|
|
105
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
106
|
+
}
|
|
107
|
+
if (!redemptions?.getRedemptionById) {
|
|
108
|
+
throw new Error('getRedemptionById method not available');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const result = await redemptions.getRedemptionById(redemptionId);
|
|
113
|
+
console.log('✅ Redemption fetched successfully:', result);
|
|
114
|
+
return result;
|
|
115
|
+
} catch (error) {
|
|
116
|
+
console.error('❌ Failed to fetch redemption:', error);
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
}, [redemptions]);
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
createRedemption,
|
|
123
|
+
getActiveRedemptions,
|
|
124
|
+
getUserRedeems,
|
|
125
|
+
redeemRedemption,
|
|
126
|
+
getRedemptionById,
|
|
127
|
+
isAvailable: isInitialized && !!redemptions,
|
|
128
|
+
};
|
|
129
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { usePersSDK } from '../providers/PersSDKProvider';
|
|
3
|
+
|
|
4
|
+
export const useTokens = () => {
|
|
5
|
+
const { tokens, isInitialized, isAuthenticated } = usePersSDK();
|
|
6
|
+
|
|
7
|
+
if (!isAuthenticated && isInitialized) {
|
|
8
|
+
console.warn('SDK not authenticated. Some token operations may fail.');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const getTokens = useCallback(async () => {
|
|
12
|
+
if (!isInitialized) {
|
|
13
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
14
|
+
}
|
|
15
|
+
if (!tokens?.getTokens) {
|
|
16
|
+
console.warn('getTokens method not available');
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
const result = await tokens.getTokens();
|
|
22
|
+
console.log('✅ Tokens fetched successfully:', result);
|
|
23
|
+
return result;
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.error('❌ Failed to fetch tokens:', error);
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
}, [tokens]);
|
|
29
|
+
|
|
30
|
+
const getTokenById = useCallback(async (tokenId: string) => {
|
|
31
|
+
if (!isInitialized) {
|
|
32
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
33
|
+
}
|
|
34
|
+
if (!tokens?.getTokenById) {
|
|
35
|
+
throw new Error('getTokenById method not available');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const result = await tokens.getTokenById(tokenId);
|
|
40
|
+
console.log('✅ Token fetched successfully:', result);
|
|
41
|
+
return result;
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.error('❌ Failed to fetch token:', error);
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}, [tokens]);
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
getTokens,
|
|
50
|
+
getTokenById,
|
|
51
|
+
isAvailable: isInitialized && !!tokens,
|
|
52
|
+
};
|
|
53
|
+
};
|