@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/index.js CHANGED
@@ -30253,49 +30253,22 @@ catch (error) {
30253
30253
  console.warn('[useTransactionSigner] PERS Signer SDK not available:', error.message);
30254
30254
  console.warn('[useTransactionSigner] Real blockchain signing will not be available');
30255
30255
  }
30256
- /**
30257
- * Utility to decode JWT and extract user information
30258
- * This will be used to extract user data for the signer
30259
- */
30260
- const extractUserInfoFromJWT = async (jwt) => {
30261
- try {
30262
- // Dynamically import jwt-decode to avoid bundling issues
30263
- const { jwtDecode } = await Promise.resolve().then(function () { return index; });
30264
- const decoded = jwtDecode(jwt);
30265
- return {
30266
- userId: decoded.user_id || decoded.userId || decoded.uid || decoded.sub,
30267
- email: decoded.email,
30268
- sub: decoded.sub
30269
- };
30270
- }
30271
- catch (error) {
30272
- console.warn('[useTransactionSigner] Failed to decode JWT:', error);
30273
- return {};
30274
- }
30275
- };
30276
30256
  // Constants - TODO: Move to environment config later
30277
30257
  const DEFAULT_ETHERS_PROVIDER = "https://sepolia.infura.io/v3/2781b4b5242343d5b0954c98f287b29e";
30278
30258
  /**
30279
30259
  * React Native hook for blockchain transaction signing using PERS Signer SDK
30280
30260
  *
30281
- * Provides WebAuthn-based transaction signing capabilities integrated with PERS ecosystem.
30282
- * Automatically handles user authentication and transaction signing workflows.
30261
+ * Simplified interface matching web frontend - uses high-level SDK methods
30262
+ * that handle all complexity internally (tenant setup, project keys, etc.).
30283
30263
  *
30284
30264
  * @example
30285
30265
  * ```typescript
30286
30266
  * function TransactionComponent() {
30287
- * const { signTransaction, initializeSigner, isSignerAvailable } = useTransactionSigner();
30288
- *
30289
- * useEffect(() => {
30290
- * initializeSigner({
30291
- * tenantId: 'my-tenant',
30292
- * ethersProviderUrl: 'https://sepolia.infura.io/v3/...'
30293
- * });
30294
- * }, []);
30267
+ * const { signTransactionWithJWT, isSignerAvailable } = useTransactionSigner();
30295
30268
  *
30296
- * const handleSign = async () => {
30269
+ * const handleSign = async (jwtFromRedemption: string) => {
30297
30270
  * try {
30298
- * const result = await signTransaction('transaction-id-123');
30271
+ * const result = await signTransactionWithJWT(jwtFromRedemption);
30299
30272
  * if (result.success) {
30300
30273
  * console.log('Transaction signed:', result.transactionHash);
30301
30274
  * }
@@ -30313,268 +30286,136 @@ const DEFAULT_ETHERS_PROVIDER = "https://sepolia.infura.io/v3/2781b4b5242343d5b0
30313
30286
  * ```
30314
30287
  */
30315
30288
  const useTransactionSigner = () => {
30316
- const { sdk, isInitialized, isAuthenticated, user, authProvider } = usePersSDK();
30289
+ const { isInitialized, isAuthenticated, user } = usePersSDK();
30317
30290
  const [isSignerInitialized, setIsSignerInitialized] = react.useState(false);
30318
30291
  const signerSDKRef = react.useRef(null);
30319
- // Auto-initialize signer when user is authenticated and real SDK is available
30292
+ // Auto-initialize signer SDK when PERS SDK is ready
30320
30293
  react.useEffect(() => {
30321
- console.log('[useTransactionSigner] useEffect triggered:', {
30322
- isInitialized,
30323
- isAuthenticated,
30324
- hasUser: !!user,
30325
- isSignerInitialized,
30326
- hasSDK: !!sdk,
30327
- hasAuthProvider: !!authProvider,
30328
- hasCreatePersSignerSDK: !!createPersSignerSDK
30329
- });
30330
- if (isInitialized && isAuthenticated && user && !isSignerInitialized && sdk && authProvider) {
30331
- console.log('[useTransactionSigner] Auto-initializing PERS transaction signer...');
30332
- // Async auto-initialization function
30333
- const autoInitialize = async () => {
30334
- try {
30335
- // Get configuration from the PERS SDK
30336
- const sdkConfig = sdk.config || {};
30337
- console.log('[useTransactionSigner] SDK config:', sdkConfig);
30338
- // Try to extract tenantId from JWT token if available
30339
- let tenantIdFromJWT;
30340
- let authToken;
30341
- if (authProvider.getToken) {
30342
- try {
30343
- authToken = await authProvider.getToken();
30344
- if (authToken) {
30345
- // Decode JWT to get tenant information
30346
- const tokenParts = authToken.split('.');
30347
- if (tokenParts.length >= 2) {
30348
- const payload = JSON.parse(atob(tokenParts[1]));
30349
- console.log('[useTransactionSigner] JWT payload decoded:', payload);
30350
- // Look for tenant ID in various possible fields
30351
- tenantIdFromJWT = payload.tenantId || payload.tenant_id || payload.tenant;
30352
- if (tenantIdFromJWT) {
30353
- console.log('[useTransactionSigner] Found tenant ID in JWT:', tenantIdFromJWT);
30354
- }
30355
- }
30356
- }
30357
- }
30358
- catch (e) {
30359
- console.warn('[useTransactionSigner] Failed to decode JWT for tenant ID:', e);
30360
- }
30361
- }
30362
- // For React Native, we should get tenantId from JWT, then user/auth context, then config
30363
- const userTenantId = user.tenantId || user.tenant_id;
30364
- const configTenantId = sdkConfig.tenantId || 'vq-demo';
30365
- const tenantId = tenantIdFromJWT || userTenantId || configTenantId;
30366
- console.log('[useTransactionSigner] Extracted tenant ID:', tenantId, 'from JWT:', tenantIdFromJWT, 'user:', userTenantId, 'or config:', configTenantId);
30367
- // Don't use apiProjectKey since we'll get it via tenant initialization
30368
- await initializeSigner({
30369
- tenantId: tenantId,
30370
- ethersProviderUrl: DEFAULT_ETHERS_PROVIDER
30371
- });
30372
- }
30373
- catch (error) {
30374
- console.error('[useTransactionSigner] Auto-initialization failed:', error);
30375
- }
30376
- };
30377
- autoInitialize();
30378
- }
30379
- }, [isInitialized, isAuthenticated, user, isSignerInitialized, sdk, authProvider]);
30380
- /**
30381
- * Initialize the blockchain signer with configuration
30382
- *
30383
- * @param config - Signer configuration options
30384
- * @param config.tenantId - Multi-tenant identifier for the signer
30385
- * @param config.projectKey - PERS project API key for authentication
30386
- * @param config.ethersProviderUrl - Custom blockchain provider URL
30387
- *
30388
- * @example
30389
- * ```typescript
30390
- * await initializeSigner({
30391
- * tenantId: 'my-tenant-id',
30392
- * projectKey: 'your-pers-api-key',
30393
- * ethersProviderUrl: 'https://sepolia.infura.io/v3/your-key'
30394
- * });
30395
- * ```
30396
- */
30397
- const initializeSigner = react.useCallback(async (config) => {
30398
- if (!createPersSignerSDK) {
30399
- throw new Error('PERS Signer SDK not available. Please ensure dependencies are properly installed.');
30400
- }
30401
- try {
30402
- console.log('[useTransactionSigner] Initializing PERS transaction signer...');
30403
- // Configure the PERS service before creating SDK
30404
- if (config?.projectKey) {
30405
- console.log('[useTransactionSigner] Configuring PERS service with project key:', config.projectKey);
30406
- try {
30407
- // Import and configure the PERS service
30408
- const { PersService } = await Promise.resolve().then(function () { return require('./react-native.esm-BtyCg4n1.js'); });
30409
- console.log('[useTransactionSigner] PersService imported successfully');
30410
- PersService.configure({
30411
- projectKey: config.projectKey
30412
- });
30413
- console.log('[useTransactionSigner] PERS service configured with project key');
30414
- // Verify configuration
30415
- const persConfig = PersService.getConfig();
30416
- console.log('[useTransactionSigner] PERS service config after configuration:', persConfig);
30417
- }
30418
- catch (configError) {
30419
- console.error('[useTransactionSigner] Failed to configure PERS service:', configError);
30420
- }
30294
+ console.log('[useTransactionSigner] Auto-initializing signer SDK...');
30295
+ const initializeSignerSDK = async () => {
30296
+ if (!createPersSignerSDK) {
30297
+ console.warn('[useTransactionSigner] Signer SDK not available');
30298
+ return;
30421
30299
  }
30422
- else if (config?.tenantId) {
30423
- console.log('[useTransactionSigner] No project key provided, will initialize tenant with tenantId:', config.tenantId);
30424
- try {
30425
- // Import and initialize tenant environment to get project key
30426
- const { PersService } = await Promise.resolve().then(function () { return require('./react-native.esm-BtyCg4n1.js'); });
30427
- console.log('[useTransactionSigner] Initializing tenant for tenantId:', config.tenantId);
30428
- // We need to set the auth token first for tenant initialization
30429
- let authToken;
30430
- if (authProvider) {
30431
- try {
30432
- authToken = await authProvider.getToken();
30433
- if (authToken) {
30434
- console.log('[useTransactionSigner] Setting auth token for tenant initialization');
30435
- PersService.configure({
30436
- token: authToken
30437
- });
30438
- }
30439
- }
30440
- catch (tokenError) {
30441
- console.warn('[useTransactionSigner] Could not get auth token for tenant initialization:', tokenError);
30442
- }
30443
- }
30444
- await PersService.initializeTenant(config.tenantId, authToken);
30445
- console.log('[useTransactionSigner] Tenant initialized successfully');
30446
- // Get tenant data to extract project key manually
30447
- try {
30448
- const tenantData = await PersService.getTenantById(config.tenantId, authToken);
30449
- console.log('[useTransactionSigner] Tenant data retrieved:', tenantData);
30450
- // Extract and set project key manually if initializeTenant didn't set it
30451
- const projectKey = tenantData.projectApiKey || tenantData.projectKey || tenantData.apiKey;
30452
- if (projectKey) {
30453
- console.log('[useTransactionSigner] Setting project key manually:', projectKey);
30454
- PersService.configure({
30455
- token: authToken,
30456
- projectKey: projectKey
30457
- });
30458
- }
30459
- else {
30460
- console.warn('[useTransactionSigner] No project key found in tenant data:', tenantData);
30461
- }
30462
- }
30463
- catch (tenantError) {
30464
- console.error('[useTransactionSigner] Failed to retrieve tenant data for project key:', tenantError);
30465
- }
30466
- // Verify configuration
30467
- const persConfig = PersService.getConfig();
30468
- console.log('[useTransactionSigner] PERS service config after tenant initialization:', persConfig);
30469
- }
30470
- catch (configError) {
30471
- console.error('[useTransactionSigner] Failed to initialize tenant:', configError);
30472
- }
30300
+ try {
30301
+ console.log('[useTransactionSigner] Creating PERS Signer SDK...');
30302
+ const signerSDK = await createPersSignerSDK({
30303
+ ethersProviderUrl: DEFAULT_ETHERS_PROVIDER
30304
+ });
30305
+ signerSDKRef.current = signerSDK;
30306
+ setIsSignerInitialized(true);
30307
+ console.log('[useTransactionSigner] PERS Signer SDK initialized successfully');
30473
30308
  }
30474
- const signerSDK = await createPersSignerSDK({
30475
- tenantId: config?.tenantId,
30476
- ethersProviderUrl: config?.ethersProviderUrl || DEFAULT_ETHERS_PROVIDER
30477
- });
30478
- signerSDKRef.current = signerSDK;
30479
- setIsSignerInitialized(true);
30480
- console.log('[useTransactionSigner] PERS Signer SDK initialized successfully');
30481
- }
30482
- catch (error) {
30483
- console.error('[useTransactionSigner] Failed to initialize transaction signer:', error);
30484
- throw new Error(`Signer initialization failed: ${error}`);
30309
+ catch (error) {
30310
+ console.error('[useTransactionSigner] Failed to initialize signer SDK:', error);
30311
+ }
30312
+ };
30313
+ if (!isSignerInitialized) {
30314
+ initializeSignerSDK();
30485
30315
  }
30486
- }, [authProvider]);
30316
+ }, [isSignerInitialized]);
30487
30317
  /**
30488
- * Sign a blockchain transaction using WebAuthn authentication
30489
- *
30490
- * @param jwt - JWT token containing transaction information and user context
30491
- * @returns Promise resolving to signing result with transaction hash
30318
+ * Sign a blockchain transaction using JWT token (matching web frontend pattern)
30492
30319
  *
30493
- * @throws {Error} When SDK not initialized, user not authenticated, or signer not initialized
30320
+ * This method replicates the web frontend flow:
30321
+ * 1. Extract transaction info from JWT
30322
+ * 2. Authenticate user with WebAuthn
30323
+ * 3. Sign transaction with authenticated user
30494
30324
  *
30495
- * @example
30496
- * ```typescript
30497
- * try {
30498
- * const result = await signTransaction(jwtToken);
30499
- * if (result.success) {
30500
- * console.log('Signed transaction hash:', result.transactionHash);
30501
- * } else {
30502
- * console.error('Signing failed:', result.error);
30503
- * }
30504
- * } catch (error) {
30505
- * console.error('Signing error:', error);
30506
- * }
30507
- * ```
30325
+ * @param jwt - JWT token from redemption flow containing transaction ID
30326
+ * @returns Promise resolving to signing result with transaction hash
30508
30327
  */
30509
- const signTransaction = react.useCallback(async (jwt) => {
30510
- if (!isInitialized || !sdk) {
30511
- throw new Error('SDK not initialized. Call initialize() first.');
30512
- }
30513
- if (!isAuthenticated || !user) {
30514
- throw new Error('User must be authenticated to sign transactions.');
30515
- }
30328
+ const signTransactionWithJWT = react.useCallback(async (jwt) => {
30516
30329
  if (!isSignerInitialized || !signerSDKRef.current) {
30517
- throw new Error('Transaction signer not initialized. Call initializeSigner() first.');
30330
+ throw new Error('Transaction signer not initialized');
30518
30331
  }
30519
30332
  if (!createPersSignerSDK) {
30520
30333
  throw new Error('PERS Signer SDK not available. Blockchain signing is not supported.');
30521
30334
  }
30522
30335
  try {
30523
- console.log('[useTransactionSigner] Extracting user info from JWT for transaction signing...');
30524
- // Extract user information from JWT
30525
- const jwtUserInfo = await extractUserInfoFromJWT(jwt);
30526
- // Create user info for signer, prioritizing current user data
30527
- const currentUser = user;
30528
- const signerUserInfo = {
30529
- identifier: currentUser.email || currentUser.id || jwtUserInfo.userId || jwtUserInfo.sub || `user-${Date.now()}`,
30530
- email: currentUser.email || jwtUserInfo.email,
30531
- id: currentUser.id || jwtUserInfo.userId
30532
- };
30533
- // Get PERS access token from the auth provider
30534
- console.log('[useTransactionSigner] Auth provider found:', !!authProvider);
30535
- const persAccessToken = authProvider ? await authProvider.getToken() : '';
30536
- console.log('[useTransactionSigner] PERS access token extracted:', persAccessToken ? 'Token found' : 'No token');
30537
- // Authenticate user with blockchain signer and pass PERS token
30538
- console.log('[useTransactionSigner] Authenticating user with signer:', signerUserInfo.identifier);
30539
- const signerUser = await signerSDKRef.current.authenticateUser({
30540
- ...signerUserInfo,
30541
- persAccessToken: persAccessToken || undefined
30542
- });
30543
- // Sign the PERS transaction using JWT
30544
- console.log('[useTransactionSigner] Signing PERS transaction with JWT containing transaction data');
30545
- const result = await signerSDKRef.current.signPersTransaction(signerUser, jwt);
30546
- // Convert PERS SDK result to our format
30547
- const convertedResult = {
30548
- success: result.success || false,
30549
- transactionHash: result.transactionHash,
30550
- signature: result.signature,
30551
- error: result.error
30336
+ console.log('[useTransactionSigner] Starting JWT-based transaction signing...');
30337
+ // Create URLSearchParams from JWT token (matching web frontend)
30338
+ const searchParams = new URLSearchParams();
30339
+ searchParams.set('jwt', jwt);
30340
+ // Step 1: Authenticate with JWT (handles tenant setup, project keys automatically)
30341
+ console.log('[useTransactionSigner] Authenticating with JWT...');
30342
+ const authResult = await signerSDKRef.current.authenticateWithJWT(searchParams);
30343
+ if (!authResult) {
30344
+ throw new Error('JWT authentication failed - no valid token found');
30345
+ }
30346
+ if (authResult.isExpired) {
30347
+ throw new Error('JWT token is expired');
30348
+ }
30349
+ console.log('[useTransactionSigner] JWT authentication successful:', authResult.user.identifier);
30350
+ // Step 2: Extract transaction ID from JWT
30351
+ const jwtParts = jwt.split('.');
30352
+ if (jwtParts.length !== 3) {
30353
+ throw new Error('Invalid JWT token format');
30354
+ }
30355
+ const payload = JSON.parse(atob(jwtParts[1]));
30356
+ const transactionId = payload.transactionId;
30357
+ if (!transactionId) {
30358
+ throw new Error('No transaction ID found in JWT token');
30359
+ }
30360
+ console.log('[useTransactionSigner] Found transaction ID:', transactionId);
30361
+ // Step 3: Sign transaction using authenticated user
30362
+ console.log('[useTransactionSigner] Signing transaction...');
30363
+ const signingResult = await signerSDKRef.current.signPersTransaction(authResult.user, transactionId);
30364
+ console.log('[useTransactionSigner] Transaction signing result:', signingResult);
30365
+ return {
30366
+ success: signingResult.success,
30367
+ transactionHash: signingResult.transactionHash,
30368
+ error: signingResult.error
30552
30369
  };
30553
- if (convertedResult.success) {
30554
- console.log('[useTransactionSigner] Transaction signed successfully:', convertedResult.transactionHash);
30555
- }
30556
- else {
30557
- console.warn('[useTransactionSigner] Transaction signing completed with warnings:', convertedResult.error);
30558
- }
30559
- return convertedResult;
30560
30370
  }
30561
30371
  catch (error) {
30562
- console.error('[useTransactionSigner] Failed to sign transaction:', error);
30372
+ console.error('[useTransactionSigner] JWT transaction signing failed:', error);
30563
30373
  return {
30564
30374
  success: false,
30565
30375
  error: `Transaction signing failed: ${error}`
30566
30376
  };
30567
30377
  }
30568
- }, [sdk, isInitialized, isAuthenticated, user, isSignerInitialized]);
30378
+ }, [isSignerInitialized]);
30379
+ /**
30380
+ * Manual user authentication (fallback method)
30381
+ */
30382
+ const authenticateUser = react.useCallback(async (identifier) => {
30383
+ if (!isSignerInitialized || !signerSDKRef.current) {
30384
+ throw new Error('Transaction signer not initialized');
30385
+ }
30386
+ try {
30387
+ console.log('[useTransactionSigner] Manual user authentication:', identifier);
30388
+ const user = await signerSDKRef.current.authenticateUser(identifier);
30389
+ console.log('[useTransactionSigner] Manual authentication successful');
30390
+ return user;
30391
+ }
30392
+ catch (error) {
30393
+ console.error('[useTransactionSigner] Manual authentication failed:', error);
30394
+ return null;
30395
+ }
30396
+ }, [isSignerInitialized]);
30397
+ /**
30398
+ * Legacy method for backward compatibility
30399
+ * @deprecated Use signTransactionWithJWT instead
30400
+ */
30401
+ const signTransaction = react.useCallback(async (jwt) => {
30402
+ console.warn('[useTransactionSigner] signTransaction is deprecated, use signTransactionWithJWT');
30403
+ return signTransactionWithJWT(jwt);
30404
+ }, [signTransactionWithJWT]);
30569
30405
  return {
30570
30406
  /**
30571
- * Sign a blockchain transaction with WebAuthn authentication
30407
+ * Sign a blockchain transaction using JWT token (recommended method)
30408
+ */
30409
+ signTransactionWithJWT,
30410
+ /**
30411
+ * Legacy transaction signing method
30412
+ * @deprecated Use signTransactionWithJWT instead
30572
30413
  */
30573
30414
  signTransaction,
30574
30415
  /**
30575
- * Initialize the transaction signer with configuration
30416
+ * Manual user authentication (for advanced use cases)
30576
30417
  */
30577
- initializeSigner,
30418
+ authenticateUser,
30578
30419
  /**
30579
30420
  * Whether the transaction signer has been initialized
30580
30421
  */
@@ -30582,7 +30423,7 @@ const useTransactionSigner = () => {
30582
30423
  /**
30583
30424
  * Whether transaction signing is available (all requirements met)
30584
30425
  */
30585
- isSignerAvailable: isInitialized && isAuthenticated && isSignerInitialized,
30426
+ isSignerAvailable: isSignerInitialized && !!createPersSignerSDK,
30586
30427
  };
30587
30428
  };
30588
30429