@explorins/pers-sdk-react-native 1.5.13 → 1.5.15
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/hooks/useTransactionSigner.d.ts +23 -20
- package/dist/hooks/useTransactionSigner.d.ts.map +1 -1
- package/dist/hooks/useTransactionSigner.js +105 -264
- package/dist/index.js +106 -265
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/hooks/useTransactionSigner.ts +131 -301
- package/dist/react-native.esm-BtyCg4n1.js +0 -10062
- package/dist/react-native.esm-BtyCg4n1.js.map +0 -1
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
interface AuthenticationResult {
|
|
2
|
+
user: SignerAuthenticatedUser;
|
|
3
|
+
isExpired: boolean;
|
|
4
|
+
}
|
|
5
|
+
interface SignerAuthenticatedUser {
|
|
6
|
+
identifier: string;
|
|
7
|
+
signerAuthToken: string;
|
|
8
|
+
persAccessToken: string;
|
|
9
|
+
}
|
|
1
10
|
interface TransactionSigningResult {
|
|
2
11
|
success: boolean;
|
|
3
12
|
transactionHash?: string;
|
|
@@ -7,24 +16,17 @@ interface TransactionSigningResult {
|
|
|
7
16
|
/**
|
|
8
17
|
* React Native hook for blockchain transaction signing using PERS Signer SDK
|
|
9
18
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
19
|
+
* Simplified interface matching web frontend - uses high-level SDK methods
|
|
20
|
+
* that handle all complexity internally (tenant setup, project keys, etc.).
|
|
12
21
|
*
|
|
13
22
|
* @example
|
|
14
23
|
* ```typescript
|
|
15
24
|
* function TransactionComponent() {
|
|
16
|
-
* const {
|
|
17
|
-
*
|
|
18
|
-
* useEffect(() => {
|
|
19
|
-
* initializeSigner({
|
|
20
|
-
* tenantId: 'my-tenant',
|
|
21
|
-
* ethersProviderUrl: 'https://sepolia.infura.io/v3/...'
|
|
22
|
-
* });
|
|
23
|
-
* }, []);
|
|
25
|
+
* const { signTransactionWithJWT, isSignerAvailable } = useTransactionSigner();
|
|
24
26
|
*
|
|
25
|
-
* const handleSign = async () => {
|
|
27
|
+
* const handleSign = async (jwtFromRedemption: string) => {
|
|
26
28
|
* try {
|
|
27
|
-
* const result = await
|
|
29
|
+
* const result = await signTransactionWithJWT(jwtFromRedemption);
|
|
28
30
|
* if (result.success) {
|
|
29
31
|
* console.log('Transaction signed:', result.transactionHash);
|
|
30
32
|
* }
|
|
@@ -43,17 +45,18 @@ interface TransactionSigningResult {
|
|
|
43
45
|
*/
|
|
44
46
|
export declare const useTransactionSigner: () => {
|
|
45
47
|
/**
|
|
46
|
-
* Sign a blockchain transaction
|
|
48
|
+
* Sign a blockchain transaction using JWT token (recommended method)
|
|
49
|
+
*/
|
|
50
|
+
signTransactionWithJWT: (jwt: string) => Promise<TransactionSigningResult>;
|
|
51
|
+
/**
|
|
52
|
+
* Legacy transaction signing method
|
|
53
|
+
* @deprecated Use signTransactionWithJWT instead
|
|
47
54
|
*/
|
|
48
55
|
signTransaction: (jwt: string) => Promise<TransactionSigningResult>;
|
|
49
56
|
/**
|
|
50
|
-
*
|
|
57
|
+
* Manual user authentication (for advanced use cases)
|
|
51
58
|
*/
|
|
52
|
-
|
|
53
|
-
tenantId?: string;
|
|
54
|
-
projectKey?: string;
|
|
55
|
-
ethersProviderUrl?: string;
|
|
56
|
-
}) => Promise<void>;
|
|
59
|
+
authenticateUser: (identifier: string) => Promise<SignerAuthenticatedUser | null>;
|
|
57
60
|
/**
|
|
58
61
|
* Whether the transaction signer has been initialized
|
|
59
62
|
*/
|
|
@@ -70,5 +73,5 @@ export type TransactionSignerHook = ReturnType<typeof useTransactionSigner>;
|
|
|
70
73
|
/**
|
|
71
74
|
* Export the transaction signing result type for external usage
|
|
72
75
|
*/
|
|
73
|
-
export type { TransactionSigningResult };
|
|
76
|
+
export type { TransactionSigningResult, SignerAuthenticatedUser, AuthenticationResult };
|
|
74
77
|
//# sourceMappingURL=useTransactionSigner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTransactionSigner.d.ts","sourceRoot":"","sources":["../../src/hooks/useTransactionSigner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useTransactionSigner.d.ts","sourceRoot":"","sources":["../../src/hooks/useTransactionSigner.ts"],"names":[],"mappings":"AA2BA,UAAU,oBAAoB;IAC5B,IAAI,EAAE,uBAAuB,CAAC;IAC9B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,UAAU,uBAAuB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;CACzB;AASD,UAAU,wBAAwB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,oBAAoB;IA+I7B;;OAEG;kCAnGkD,MAAM,KAAG,QAAQ,wBAAwB,CAAC;IAsG/F;;;OAGG;2BAd2C,MAAM,KAAG,QAAQ,wBAAwB,CAAC;IAiBxF;;OAEG;mCAvCmD,MAAM,KAAG,QAAQ,uBAAuB,GAAG,IAAI,CAAC;IA0CtG;;OAEG;;IAGH;;OAEG;;CAGN,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAE5E;;GAEG;AACH,YAAY,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,CAAC"}
|
|
@@ -11,49 +11,22 @@ catch (error) {
|
|
|
11
11
|
console.warn('[useTransactionSigner] PERS Signer SDK not available:', error.message);
|
|
12
12
|
console.warn('[useTransactionSigner] Real blockchain signing will not be available');
|
|
13
13
|
}
|
|
14
|
-
/**
|
|
15
|
-
* Utility to decode JWT and extract user information
|
|
16
|
-
* This will be used to extract user data for the signer
|
|
17
|
-
*/
|
|
18
|
-
const extractUserInfoFromJWT = async (jwt) => {
|
|
19
|
-
try {
|
|
20
|
-
// Dynamically import jwt-decode to avoid bundling issues
|
|
21
|
-
const { jwtDecode } = await import('jwt-decode');
|
|
22
|
-
const decoded = jwtDecode(jwt);
|
|
23
|
-
return {
|
|
24
|
-
userId: decoded.user_id || decoded.userId || decoded.uid || decoded.sub,
|
|
25
|
-
email: decoded.email,
|
|
26
|
-
sub: decoded.sub
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
catch (error) {
|
|
30
|
-
console.warn('[useTransactionSigner] Failed to decode JWT:', error);
|
|
31
|
-
return {};
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
14
|
// Constants - TODO: Move to environment config later
|
|
35
15
|
const DEFAULT_ETHERS_PROVIDER = "https://sepolia.infura.io/v3/2781b4b5242343d5b0954c98f287b29e";
|
|
36
16
|
/**
|
|
37
17
|
* React Native hook for blockchain transaction signing using PERS Signer SDK
|
|
38
18
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
19
|
+
* Simplified interface matching web frontend - uses high-level SDK methods
|
|
20
|
+
* that handle all complexity internally (tenant setup, project keys, etc.).
|
|
41
21
|
*
|
|
42
22
|
* @example
|
|
43
23
|
* ```typescript
|
|
44
24
|
* function TransactionComponent() {
|
|
45
|
-
* const {
|
|
46
|
-
*
|
|
47
|
-
* useEffect(() => {
|
|
48
|
-
* initializeSigner({
|
|
49
|
-
* tenantId: 'my-tenant',
|
|
50
|
-
* ethersProviderUrl: 'https://sepolia.infura.io/v3/...'
|
|
51
|
-
* });
|
|
52
|
-
* }, []);
|
|
25
|
+
* const { signTransactionWithJWT, isSignerAvailable } = useTransactionSigner();
|
|
53
26
|
*
|
|
54
|
-
* const handleSign = async () => {
|
|
27
|
+
* const handleSign = async (jwtFromRedemption: string) => {
|
|
55
28
|
* try {
|
|
56
|
-
* const result = await
|
|
29
|
+
* const result = await signTransactionWithJWT(jwtFromRedemption);
|
|
57
30
|
* if (result.success) {
|
|
58
31
|
* console.log('Transaction signed:', result.transactionHash);
|
|
59
32
|
* }
|
|
@@ -71,268 +44,136 @@ const DEFAULT_ETHERS_PROVIDER = "https://sepolia.infura.io/v3/2781b4b5242343d5b0
|
|
|
71
44
|
* ```
|
|
72
45
|
*/
|
|
73
46
|
export const useTransactionSigner = () => {
|
|
74
|
-
const {
|
|
47
|
+
const { isInitialized, isAuthenticated, user } = usePersSDK();
|
|
75
48
|
const [isSignerInitialized, setIsSignerInitialized] = useState(false);
|
|
76
49
|
const signerSDKRef = useRef(null);
|
|
77
|
-
// Auto-initialize signer when
|
|
50
|
+
// Auto-initialize signer SDK when PERS SDK is ready
|
|
78
51
|
useEffect(() => {
|
|
79
|
-
console.log('[useTransactionSigner]
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
hasSDK: !!sdk,
|
|
85
|
-
hasAuthProvider: !!authProvider,
|
|
86
|
-
hasCreatePersSignerSDK: !!createPersSignerSDK
|
|
87
|
-
});
|
|
88
|
-
if (isInitialized && isAuthenticated && user && !isSignerInitialized && sdk && authProvider) {
|
|
89
|
-
console.log('[useTransactionSigner] Auto-initializing PERS transaction signer...');
|
|
90
|
-
// Async auto-initialization function
|
|
91
|
-
const autoInitialize = async () => {
|
|
92
|
-
try {
|
|
93
|
-
// Get configuration from the PERS SDK
|
|
94
|
-
const sdkConfig = sdk.config || {};
|
|
95
|
-
console.log('[useTransactionSigner] SDK config:', sdkConfig);
|
|
96
|
-
// Try to extract tenantId from JWT token if available
|
|
97
|
-
let tenantIdFromJWT;
|
|
98
|
-
let authToken;
|
|
99
|
-
if (authProvider.getToken) {
|
|
100
|
-
try {
|
|
101
|
-
authToken = await authProvider.getToken();
|
|
102
|
-
if (authToken) {
|
|
103
|
-
// Decode JWT to get tenant information
|
|
104
|
-
const tokenParts = authToken.split('.');
|
|
105
|
-
if (tokenParts.length >= 2) {
|
|
106
|
-
const payload = JSON.parse(atob(tokenParts[1]));
|
|
107
|
-
console.log('[useTransactionSigner] JWT payload decoded:', payload);
|
|
108
|
-
// Look for tenant ID in various possible fields
|
|
109
|
-
tenantIdFromJWT = payload.tenantId || payload.tenant_id || payload.tenant;
|
|
110
|
-
if (tenantIdFromJWT) {
|
|
111
|
-
console.log('[useTransactionSigner] Found tenant ID in JWT:', tenantIdFromJWT);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
catch (e) {
|
|
117
|
-
console.warn('[useTransactionSigner] Failed to decode JWT for tenant ID:', e);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
// For React Native, we should get tenantId from JWT, then user/auth context, then config
|
|
121
|
-
const userTenantId = user.tenantId || user.tenant_id;
|
|
122
|
-
const configTenantId = sdkConfig.tenantId || 'vq-demo';
|
|
123
|
-
const tenantId = tenantIdFromJWT || userTenantId || configTenantId;
|
|
124
|
-
console.log('[useTransactionSigner] Extracted tenant ID:', tenantId, 'from JWT:', tenantIdFromJWT, 'user:', userTenantId, 'or config:', configTenantId);
|
|
125
|
-
// Don't use apiProjectKey since we'll get it via tenant initialization
|
|
126
|
-
await initializeSigner({
|
|
127
|
-
tenantId: tenantId,
|
|
128
|
-
ethersProviderUrl: DEFAULT_ETHERS_PROVIDER
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
catch (error) {
|
|
132
|
-
console.error('[useTransactionSigner] Auto-initialization failed:', error);
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
autoInitialize();
|
|
136
|
-
}
|
|
137
|
-
}, [isInitialized, isAuthenticated, user, isSignerInitialized, sdk, authProvider]);
|
|
138
|
-
/**
|
|
139
|
-
* Initialize the blockchain signer with configuration
|
|
140
|
-
*
|
|
141
|
-
* @param config - Signer configuration options
|
|
142
|
-
* @param config.tenantId - Multi-tenant identifier for the signer
|
|
143
|
-
* @param config.projectKey - PERS project API key for authentication
|
|
144
|
-
* @param config.ethersProviderUrl - Custom blockchain provider URL
|
|
145
|
-
*
|
|
146
|
-
* @example
|
|
147
|
-
* ```typescript
|
|
148
|
-
* await initializeSigner({
|
|
149
|
-
* tenantId: 'my-tenant-id',
|
|
150
|
-
* projectKey: 'your-pers-api-key',
|
|
151
|
-
* ethersProviderUrl: 'https://sepolia.infura.io/v3/your-key'
|
|
152
|
-
* });
|
|
153
|
-
* ```
|
|
154
|
-
*/
|
|
155
|
-
const initializeSigner = useCallback(async (config) => {
|
|
156
|
-
if (!createPersSignerSDK) {
|
|
157
|
-
throw new Error('PERS Signer SDK not available. Please ensure dependencies are properly installed.');
|
|
158
|
-
}
|
|
159
|
-
try {
|
|
160
|
-
console.log('[useTransactionSigner] Initializing PERS transaction signer...');
|
|
161
|
-
// Configure the PERS service before creating SDK
|
|
162
|
-
if (config?.projectKey) {
|
|
163
|
-
console.log('[useTransactionSigner] Configuring PERS service with project key:', config.projectKey);
|
|
164
|
-
try {
|
|
165
|
-
// Import and configure the PERS service
|
|
166
|
-
const { PersService } = await import('@explorins/pers-signer/react-native');
|
|
167
|
-
console.log('[useTransactionSigner] PersService imported successfully');
|
|
168
|
-
PersService.configure({
|
|
169
|
-
projectKey: config.projectKey
|
|
170
|
-
});
|
|
171
|
-
console.log('[useTransactionSigner] PERS service configured with project key');
|
|
172
|
-
// Verify configuration
|
|
173
|
-
const persConfig = PersService.getConfig();
|
|
174
|
-
console.log('[useTransactionSigner] PERS service config after configuration:', persConfig);
|
|
175
|
-
}
|
|
176
|
-
catch (configError) {
|
|
177
|
-
console.error('[useTransactionSigner] Failed to configure PERS service:', configError);
|
|
178
|
-
}
|
|
52
|
+
console.log('[useTransactionSigner] Auto-initializing signer SDK...');
|
|
53
|
+
const initializeSignerSDK = async () => {
|
|
54
|
+
if (!createPersSignerSDK) {
|
|
55
|
+
console.warn('[useTransactionSigner] Signer SDK not available');
|
|
56
|
+
return;
|
|
179
57
|
}
|
|
180
|
-
|
|
181
|
-
console.log('[useTransactionSigner]
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (authProvider) {
|
|
189
|
-
try {
|
|
190
|
-
authToken = await authProvider.getToken();
|
|
191
|
-
if (authToken) {
|
|
192
|
-
console.log('[useTransactionSigner] Setting auth token for tenant initialization');
|
|
193
|
-
PersService.configure({
|
|
194
|
-
token: authToken
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
catch (tokenError) {
|
|
199
|
-
console.warn('[useTransactionSigner] Could not get auth token for tenant initialization:', tokenError);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
await PersService.initializeTenant(config.tenantId, authToken);
|
|
203
|
-
console.log('[useTransactionSigner] Tenant initialized successfully');
|
|
204
|
-
// Get tenant data to extract project key manually
|
|
205
|
-
try {
|
|
206
|
-
const tenantData = await PersService.getTenantById(config.tenantId, authToken);
|
|
207
|
-
console.log('[useTransactionSigner] Tenant data retrieved:', tenantData);
|
|
208
|
-
// Extract and set project key manually if initializeTenant didn't set it
|
|
209
|
-
const projectKey = tenantData.projectApiKey || tenantData.projectKey || tenantData.apiKey;
|
|
210
|
-
if (projectKey) {
|
|
211
|
-
console.log('[useTransactionSigner] Setting project key manually:', projectKey);
|
|
212
|
-
PersService.configure({
|
|
213
|
-
token: authToken,
|
|
214
|
-
projectKey: projectKey
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
console.warn('[useTransactionSigner] No project key found in tenant data:', tenantData);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
catch (tenantError) {
|
|
222
|
-
console.error('[useTransactionSigner] Failed to retrieve tenant data for project key:', tenantError);
|
|
223
|
-
}
|
|
224
|
-
// Verify configuration
|
|
225
|
-
const persConfig = PersService.getConfig();
|
|
226
|
-
console.log('[useTransactionSigner] PERS service config after tenant initialization:', persConfig);
|
|
227
|
-
}
|
|
228
|
-
catch (configError) {
|
|
229
|
-
console.error('[useTransactionSigner] Failed to initialize tenant:', configError);
|
|
230
|
-
}
|
|
58
|
+
try {
|
|
59
|
+
console.log('[useTransactionSigner] Creating PERS Signer SDK...');
|
|
60
|
+
const signerSDK = await createPersSignerSDK({
|
|
61
|
+
ethersProviderUrl: DEFAULT_ETHERS_PROVIDER
|
|
62
|
+
});
|
|
63
|
+
signerSDKRef.current = signerSDK;
|
|
64
|
+
setIsSignerInitialized(true);
|
|
65
|
+
console.log('[useTransactionSigner] PERS Signer SDK initialized successfully');
|
|
231
66
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
console.log('[useTransactionSigner] PERS Signer SDK initialized successfully');
|
|
239
|
-
}
|
|
240
|
-
catch (error) {
|
|
241
|
-
console.error('[useTransactionSigner] Failed to initialize transaction signer:', error);
|
|
242
|
-
throw new Error(`Signer initialization failed: ${error}`);
|
|
67
|
+
catch (error) {
|
|
68
|
+
console.error('[useTransactionSigner] Failed to initialize signer SDK:', error);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
if (!isSignerInitialized) {
|
|
72
|
+
initializeSignerSDK();
|
|
243
73
|
}
|
|
244
|
-
}, [
|
|
74
|
+
}, [isSignerInitialized]);
|
|
245
75
|
/**
|
|
246
|
-
* Sign a blockchain transaction using
|
|
247
|
-
*
|
|
248
|
-
* @param jwt - JWT token containing transaction information and user context
|
|
249
|
-
* @returns Promise resolving to signing result with transaction hash
|
|
76
|
+
* Sign a blockchain transaction using JWT token (matching web frontend pattern)
|
|
250
77
|
*
|
|
251
|
-
*
|
|
78
|
+
* This method replicates the web frontend flow:
|
|
79
|
+
* 1. Extract transaction info from JWT
|
|
80
|
+
* 2. Authenticate user with WebAuthn
|
|
81
|
+
* 3. Sign transaction with authenticated user
|
|
252
82
|
*
|
|
253
|
-
* @
|
|
254
|
-
*
|
|
255
|
-
* try {
|
|
256
|
-
* const result = await signTransaction(jwtToken);
|
|
257
|
-
* if (result.success) {
|
|
258
|
-
* console.log('Signed transaction hash:', result.transactionHash);
|
|
259
|
-
* } else {
|
|
260
|
-
* console.error('Signing failed:', result.error);
|
|
261
|
-
* }
|
|
262
|
-
* } catch (error) {
|
|
263
|
-
* console.error('Signing error:', error);
|
|
264
|
-
* }
|
|
265
|
-
* ```
|
|
83
|
+
* @param jwt - JWT token from redemption flow containing transaction ID
|
|
84
|
+
* @returns Promise resolving to signing result with transaction hash
|
|
266
85
|
*/
|
|
267
|
-
const
|
|
268
|
-
if (!isInitialized || !sdk) {
|
|
269
|
-
throw new Error('SDK not initialized. Call initialize() first.');
|
|
270
|
-
}
|
|
271
|
-
if (!isAuthenticated || !user) {
|
|
272
|
-
throw new Error('User must be authenticated to sign transactions.');
|
|
273
|
-
}
|
|
86
|
+
const signTransactionWithJWT = useCallback(async (jwt) => {
|
|
274
87
|
if (!isSignerInitialized || !signerSDKRef.current) {
|
|
275
|
-
throw new Error('Transaction signer not initialized
|
|
88
|
+
throw new Error('Transaction signer not initialized');
|
|
276
89
|
}
|
|
277
90
|
if (!createPersSignerSDK) {
|
|
278
91
|
throw new Error('PERS Signer SDK not available. Blockchain signing is not supported.');
|
|
279
92
|
}
|
|
280
93
|
try {
|
|
281
|
-
console.log('[useTransactionSigner]
|
|
282
|
-
//
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
console.log('[useTransactionSigner]
|
|
295
|
-
//
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
persAccessToken: persAccessToken || undefined
|
|
300
|
-
});
|
|
301
|
-
// Sign the PERS transaction using JWT
|
|
302
|
-
console.log('[useTransactionSigner] Signing PERS transaction with JWT containing transaction data');
|
|
303
|
-
const result = await signerSDKRef.current.signPersTransaction(signerUser, jwt);
|
|
304
|
-
// Convert PERS SDK result to our format
|
|
305
|
-
const convertedResult = {
|
|
306
|
-
success: result.success || false,
|
|
307
|
-
transactionHash: result.transactionHash,
|
|
308
|
-
signature: result.signature,
|
|
309
|
-
error: result.error
|
|
310
|
-
};
|
|
311
|
-
if (convertedResult.success) {
|
|
312
|
-
console.log('[useTransactionSigner] Transaction signed successfully:', convertedResult.transactionHash);
|
|
94
|
+
console.log('[useTransactionSigner] Starting JWT-based transaction signing...');
|
|
95
|
+
// Create URLSearchParams from JWT token (matching web frontend)
|
|
96
|
+
const searchParams = new URLSearchParams();
|
|
97
|
+
searchParams.set('jwt', jwt);
|
|
98
|
+
// Step 1: Authenticate with JWT (handles tenant setup, project keys automatically)
|
|
99
|
+
console.log('[useTransactionSigner] Authenticating with JWT...');
|
|
100
|
+
const authResult = await signerSDKRef.current.authenticateWithJWT(searchParams);
|
|
101
|
+
if (!authResult) {
|
|
102
|
+
throw new Error('JWT authentication failed - no valid token found');
|
|
103
|
+
}
|
|
104
|
+
if (authResult.isExpired) {
|
|
105
|
+
throw new Error('JWT token is expired');
|
|
106
|
+
}
|
|
107
|
+
console.log('[useTransactionSigner] JWT authentication successful:', authResult.user.identifier);
|
|
108
|
+
// Step 2: Extract transaction ID from JWT
|
|
109
|
+
const jwtParts = jwt.split('.');
|
|
110
|
+
if (jwtParts.length !== 3) {
|
|
111
|
+
throw new Error('Invalid JWT token format');
|
|
313
112
|
}
|
|
314
|
-
|
|
315
|
-
|
|
113
|
+
const payload = JSON.parse(atob(jwtParts[1]));
|
|
114
|
+
const transactionId = payload.transactionId;
|
|
115
|
+
if (!transactionId) {
|
|
116
|
+
throw new Error('No transaction ID found in JWT token');
|
|
316
117
|
}
|
|
317
|
-
|
|
118
|
+
console.log('[useTransactionSigner] Found transaction ID:', transactionId);
|
|
119
|
+
// Step 3: Sign transaction using authenticated user
|
|
120
|
+
console.log('[useTransactionSigner] Signing transaction...');
|
|
121
|
+
const signingResult = await signerSDKRef.current.signPersTransaction(authResult.user, transactionId);
|
|
122
|
+
console.log('[useTransactionSigner] Transaction signing result:', signingResult);
|
|
123
|
+
return {
|
|
124
|
+
success: signingResult.success,
|
|
125
|
+
transactionHash: signingResult.transactionHash,
|
|
126
|
+
error: signingResult.error
|
|
127
|
+
};
|
|
318
128
|
}
|
|
319
129
|
catch (error) {
|
|
320
|
-
console.error('[useTransactionSigner]
|
|
130
|
+
console.error('[useTransactionSigner] JWT transaction signing failed:', error);
|
|
321
131
|
return {
|
|
322
132
|
success: false,
|
|
323
133
|
error: `Transaction signing failed: ${error}`
|
|
324
134
|
};
|
|
325
135
|
}
|
|
326
|
-
}, [
|
|
136
|
+
}, [isSignerInitialized]);
|
|
137
|
+
/**
|
|
138
|
+
* Manual user authentication (fallback method)
|
|
139
|
+
*/
|
|
140
|
+
const authenticateUser = useCallback(async (identifier) => {
|
|
141
|
+
if (!isSignerInitialized || !signerSDKRef.current) {
|
|
142
|
+
throw new Error('Transaction signer not initialized');
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
console.log('[useTransactionSigner] Manual user authentication:', identifier);
|
|
146
|
+
const user = await signerSDKRef.current.authenticateUser(identifier);
|
|
147
|
+
console.log('[useTransactionSigner] Manual authentication successful');
|
|
148
|
+
return user;
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
console.error('[useTransactionSigner] Manual authentication failed:', error);
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
}, [isSignerInitialized]);
|
|
155
|
+
/**
|
|
156
|
+
* Legacy method for backward compatibility
|
|
157
|
+
* @deprecated Use signTransactionWithJWT instead
|
|
158
|
+
*/
|
|
159
|
+
const signTransaction = useCallback(async (jwt) => {
|
|
160
|
+
console.warn('[useTransactionSigner] signTransaction is deprecated, use signTransactionWithJWT');
|
|
161
|
+
return signTransactionWithJWT(jwt);
|
|
162
|
+
}, [signTransactionWithJWT]);
|
|
327
163
|
return {
|
|
328
164
|
/**
|
|
329
|
-
* Sign a blockchain transaction
|
|
165
|
+
* Sign a blockchain transaction using JWT token (recommended method)
|
|
166
|
+
*/
|
|
167
|
+
signTransactionWithJWT,
|
|
168
|
+
/**
|
|
169
|
+
* Legacy transaction signing method
|
|
170
|
+
* @deprecated Use signTransactionWithJWT instead
|
|
330
171
|
*/
|
|
331
172
|
signTransaction,
|
|
332
173
|
/**
|
|
333
|
-
*
|
|
174
|
+
* Manual user authentication (for advanced use cases)
|
|
334
175
|
*/
|
|
335
|
-
|
|
176
|
+
authenticateUser,
|
|
336
177
|
/**
|
|
337
178
|
* Whether the transaction signer has been initialized
|
|
338
179
|
*/
|
|
@@ -340,6 +181,6 @@ export const useTransactionSigner = () => {
|
|
|
340
181
|
/**
|
|
341
182
|
* Whether transaction signing is available (all requirements met)
|
|
342
183
|
*/
|
|
343
|
-
isSignerAvailable:
|
|
184
|
+
isSignerAvailable: isSignerInitialized && !!createPersSignerSDK,
|
|
344
185
|
};
|
|
345
186
|
};
|