react-native-iap 14.2.2 → 14.2.3

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.
Files changed (32) hide show
  1. package/NitroIap.podspec +4 -1
  2. package/README.md +10 -0
  3. package/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +5 -1
  4. package/app.plugin.js +1 -1
  5. package/lib/module/helpers/subscription.js.map +1 -1
  6. package/lib/module/hooks/useIAP.js.map +1 -1
  7. package/lib/module/index.js.map +1 -1
  8. package/lib/module/types/react-test-renderer.d.js +2 -0
  9. package/lib/module/types/react-test-renderer.d.js.map +1 -0
  10. package/lib/module/utils/error.js.map +1 -1
  11. package/lib/module/utils/errorMapping.js.map +1 -1
  12. package/lib/module/utils/type-bridge.js.map +1 -1
  13. package/lib/typescript/plugin/src/withIAP.d.ts.map +1 -1
  14. package/lib/typescript/src/helpers/subscription.d.ts.map +1 -1
  15. package/lib/typescript/src/hooks/useIAP.d.ts.map +1 -1
  16. package/lib/typescript/src/index.d.ts.map +1 -1
  17. package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -1
  18. package/lib/typescript/src/types.d.ts.map +1 -1
  19. package/lib/typescript/src/utils/error.d.ts.map +1 -1
  20. package/lib/typescript/src/utils/errorMapping.d.ts.map +1 -1
  21. package/lib/typescript/src/utils/type-bridge.d.ts.map +1 -1
  22. package/package.json +1 -9
  23. package/plugin/src/withIAP.ts +59 -59
  24. package/src/helpers/subscription.ts +21 -21
  25. package/src/hooks/useIAP.ts +193 -193
  26. package/src/index.ts +346 -344
  27. package/src/specs/RnIap.nitro.ts +160 -157
  28. package/src/types/react-test-renderer.d.ts +7 -0
  29. package/src/types.ts +294 -294
  30. package/src/utils/error.ts +19 -19
  31. package/src/utils/errorMapping.ts +13 -13
  32. package/src/utils/type-bridge.ts +94 -93
package/src/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  // External dependencies
2
- import { Platform } from 'react-native'
3
- import { NitroModules } from 'react-native-nitro-modules'
2
+ import {Platform} from 'react-native';
3
+ import {NitroModules} from 'react-native-nitro-modules';
4
4
 
5
5
  // Internal modules
6
6
  import type {
@@ -9,7 +9,7 @@ import type {
9
9
  NitroReceiptValidationParams,
10
10
  NitroReceiptValidationResultIOS,
11
11
  NitroReceiptValidationResultAndroid,
12
- } from './specs/RnIap.nitro'
12
+ } from './specs/RnIap.nitro';
13
13
  import type {
14
14
  Product,
15
15
  Purchase,
@@ -24,16 +24,16 @@ import type {
24
24
  RequestPurchaseIosProps,
25
25
  RequestPurchaseAndroidProps,
26
26
  SubscriptionStatusIOS,
27
- } from './types'
28
- import type { ProductRequest } from './types'
27
+ } from './types';
28
+ import type {ProductRequest} from './types';
29
29
  import {
30
30
  convertNitroProductToProduct,
31
31
  convertNitroPurchaseToPurchase,
32
32
  validateNitroProduct,
33
33
  validateNitroPurchase,
34
34
  convertNitroSubscriptionStatusToSubscriptionStatusIOS,
35
- } from './utils/type-bridge'
36
- import { parseErrorStringToJsonObj } from './utils/error'
35
+ } from './utils/type-bridge';
36
+ import {parseErrorStringToJsonObj} from './utils/error';
37
37
 
38
38
  // Export all types
39
39
  export type {
@@ -41,67 +41,67 @@ export type {
41
41
  NitroProduct,
42
42
  NitroPurchase,
43
43
  NitroPurchaseResult,
44
- } from './specs/RnIap.nitro'
45
- export * from './types'
46
- export * from './utils/error'
44
+ } from './specs/RnIap.nitro';
45
+ export * from './types';
46
+ export * from './utils/error';
47
47
 
48
48
  // Types for event listeners
49
49
  export interface EventSubscription {
50
- remove(): void
50
+ remove(): void;
51
51
  }
52
52
 
53
53
  // ActiveSubscription and PurchaseError types are already exported via 'export * from ./types'
54
54
 
55
55
  // Export hooks
56
- export { useIAP } from './hooks/useIAP'
56
+ export {useIAP} from './hooks/useIAP';
57
57
 
58
58
  // iOS promoted product aliases for API parity
59
59
  export const getPromotedProductIOS = async (): Promise<Product | null> =>
60
- requestPromotedProductIOS()
60
+ requestPromotedProductIOS();
61
61
  export const requestPurchaseOnPromotedProductIOS = async (): Promise<void> =>
62
- buyPromotedProductIOS()
62
+ buyPromotedProductIOS();
63
63
 
64
64
  // Restore completed transactions (cross-platform)
65
65
  export const restorePurchases = async (
66
66
  options: PurchaseOptions = {
67
67
  alsoPublishToEventListenerIOS: false,
68
68
  onlyIncludeActiveItemsIOS: true,
69
- }
69
+ },
70
70
  ): Promise<Purchase[]> => {
71
71
  if (Platform.OS === 'ios') {
72
- await syncIOS()
72
+ await syncIOS();
73
73
  }
74
- return getAvailablePurchases(options)
75
- }
74
+ return getAvailablePurchases(options);
75
+ };
76
76
 
77
77
  // Development utilities removed - use type bridge functions directly if needed
78
78
 
79
79
  // Create the RnIap HybridObject instance (internal use only)
80
- const iap = NitroModules.createHybridObject<RnIap>('RnIap')
80
+ const iap = NitroModules.createHybridObject<RnIap>('RnIap');
81
81
 
82
82
  /**
83
83
  * Initialize connection to the store
84
84
  */
85
85
  export const initConnection = async (): Promise<boolean> => {
86
86
  try {
87
- return await iap.initConnection()
87
+ return await iap.initConnection();
88
88
  } catch (error) {
89
- console.error('Failed to initialize IAP connection:', error)
90
- throw error
89
+ console.error('Failed to initialize IAP connection:', error);
90
+ throw error;
91
91
  }
92
- }
92
+ };
93
93
 
94
94
  /**
95
95
  * End connection to the store
96
96
  */
97
97
  export const endConnection = async (): Promise<boolean> => {
98
98
  try {
99
- return await iap.endConnection()
99
+ return await iap.endConnection();
100
100
  } catch (error) {
101
- console.error('Failed to end IAP connection:', error)
102
- throw error
101
+ console.error('Failed to end IAP connection:', error);
102
+ throw error;
103
103
  }
104
- }
104
+ };
105
105
 
106
106
  /**
107
107
  * Fetch products from the store
@@ -125,41 +125,41 @@ export const fetchProducts = async ({
125
125
  }: ProductRequest): Promise<Product[]> => {
126
126
  try {
127
127
  if (!skus || skus.length === 0) {
128
- throw new Error('No SKUs provided')
128
+ throw new Error('No SKUs provided');
129
129
  }
130
130
 
131
131
  if (type === 'all') {
132
132
  const [inappNitro, subsNitro] = await Promise.all([
133
133
  iap.fetchProducts(skus, 'inapp'),
134
134
  iap.fetchProducts(skus, 'subs'),
135
- ])
136
- const allNitro = [...inappNitro, ...subsNitro]
137
- const validAll = allNitro.filter(validateNitroProduct)
135
+ ]);
136
+ const allNitro = [...inappNitro, ...subsNitro];
137
+ const validAll = allNitro.filter(validateNitroProduct);
138
138
  if (validAll.length !== allNitro.length) {
139
139
  console.warn(
140
- `[fetchProducts] Some products failed validation: ${allNitro.length - validAll.length} invalid`
141
- )
140
+ `[fetchProducts] Some products failed validation: ${allNitro.length - validAll.length} invalid`,
141
+ );
142
142
  }
143
- return validAll.map(convertNitroProductToProduct)
143
+ return validAll.map(convertNitroProductToProduct);
144
144
  }
145
145
 
146
- const nitroProducts = await iap.fetchProducts(skus, type)
146
+ const nitroProducts = await iap.fetchProducts(skus, type);
147
147
 
148
148
  // Validate and convert NitroProducts to TypeScript Products
149
- const validProducts = nitroProducts.filter(validateNitroProduct)
149
+ const validProducts = nitroProducts.filter(validateNitroProduct);
150
150
  if (validProducts.length !== nitroProducts.length) {
151
151
  console.warn(
152
- `[fetchProducts] Some products failed validation: ${nitroProducts.length - validProducts.length} invalid`
153
- )
152
+ `[fetchProducts] Some products failed validation: ${nitroProducts.length - validProducts.length} invalid`,
153
+ );
154
154
  }
155
155
 
156
- const typedProducts = validProducts.map(convertNitroProductToProduct)
157
- return typedProducts
156
+ const typedProducts = validProducts.map(convertNitroProductToProduct);
157
+ return typedProducts;
158
158
  } catch (error) {
159
- console.error('[fetchProducts] Failed:', error)
160
- throw error
159
+ console.error('[fetchProducts] Failed:', error);
160
+ throw error;
161
161
  }
162
- }
162
+ };
163
163
 
164
164
  /**
165
165
  * Request a purchase for products or subscriptions
@@ -203,65 +203,65 @@ export const requestPurchase = async ({
203
203
  request,
204
204
  type = 'inapp',
205
205
  }: {
206
- request: RequestPurchaseProps | RequestSubscriptionProps
207
- type?: 'inapp' | 'subs'
206
+ request: RequestPurchaseProps | RequestSubscriptionProps;
207
+ type?: 'inapp' | 'subs';
208
208
  }): Promise<void> => {
209
209
  try {
210
210
  // Validate platform-specific requests
211
211
  if (Platform.OS === 'ios') {
212
- const iosRequest = request.ios
212
+ const iosRequest = request.ios;
213
213
  if (!iosRequest?.sku) {
214
214
  throw new Error(
215
- 'Invalid request for iOS. The `sku` property is required.'
216
- )
215
+ 'Invalid request for iOS. The `sku` property is required.',
216
+ );
217
217
  }
218
218
  } else if (Platform.OS === 'android') {
219
- const androidRequest = request.android
219
+ const androidRequest = request.android;
220
220
  if (!androidRequest?.skus?.length) {
221
221
  throw new Error(
222
- 'Invalid request for Android. The `skus` property is required and must be a non-empty array.'
223
- )
222
+ 'Invalid request for Android. The `skus` property is required and must be a non-empty array.',
223
+ );
224
224
  }
225
225
  } else {
226
- throw new Error('Unsupported platform')
226
+ throw new Error('Unsupported platform');
227
227
  }
228
228
 
229
229
  // Transform the request for the unified interface
230
- const unifiedRequest: any = {}
230
+ const unifiedRequest: any = {};
231
231
 
232
232
  if (Platform.OS === 'ios' && request.ios) {
233
- const iosReq = request.ios as RequestPurchaseIosProps
233
+ const iosReq = request.ios as RequestPurchaseIosProps;
234
234
  const autoFinishSubs =
235
235
  type === 'subs' &&
236
- iosReq.andDangerouslyFinishTransactionAutomatically == null
236
+ iosReq.andDangerouslyFinishTransactionAutomatically == null;
237
237
  unifiedRequest.ios = {
238
238
  ...iosReq,
239
239
  // Align with native SwiftUI flow: auto-finish subscriptions by default
240
240
  ...(autoFinishSubs
241
- ? { andDangerouslyFinishTransactionAutomatically: true }
241
+ ? {andDangerouslyFinishTransactionAutomatically: true}
242
242
  : {}),
243
- } as RequestPurchaseIosProps
243
+ } as RequestPurchaseIosProps;
244
244
  }
245
245
 
246
246
  if (Platform.OS === 'android' && request.android) {
247
247
  if (type === 'subs') {
248
- const subsRequest = request.android as RequestSubscriptionAndroidProps
248
+ const subsRequest = request.android as RequestSubscriptionAndroidProps;
249
249
  unifiedRequest.android = {
250
250
  ...subsRequest,
251
251
  subscriptionOffers: subsRequest.subscriptionOffers || [],
252
- } as RequestPurchaseAndroidProps
252
+ } as RequestPurchaseAndroidProps;
253
253
  } else {
254
- unifiedRequest.android = request.android
254
+ unifiedRequest.android = request.android;
255
255
  }
256
256
  }
257
257
 
258
258
  // Call unified method - returns void, listen for events instead
259
- await iap.requestPurchase(unifiedRequest)
259
+ await iap.requestPurchase(unifiedRequest);
260
260
  } catch (error) {
261
- console.error('Failed to request purchase:', error)
262
- throw error
261
+ console.error('Failed to request purchase:', error);
262
+ throw error;
263
263
  }
264
- }
264
+ };
265
265
 
266
266
  /**
267
267
  * Get available purchases (purchased items not yet consumed/finished)
@@ -282,7 +282,7 @@ export const getAvailablePurchases = async ({
282
282
  }: PurchaseOptions = {}): Promise<Purchase[]> => {
283
283
  try {
284
284
  // Create unified options
285
- const options: any = {}
285
+ const options: any = {};
286
286
 
287
287
  if (Platform.OS === 'ios') {
288
288
  // Provide both new and deprecated keys for compatibility
@@ -291,46 +291,46 @@ export const getAvailablePurchases = async ({
291
291
  onlyIncludeActiveItemsIOS,
292
292
  alsoPublishToEventListener: alsoPublishToEventListenerIOS,
293
293
  onlyIncludeActiveItems: onlyIncludeActiveItemsIOS,
294
- }
294
+ };
295
295
  } else if (Platform.OS === 'android') {
296
296
  // For Android, we need to call twice for inapp and subs
297
297
  const inappNitroPurchases = await iap.getAvailablePurchases({
298
- android: { type: 'inapp' },
299
- })
298
+ android: {type: 'inapp'},
299
+ });
300
300
  const subsNitroPurchases = await iap.getAvailablePurchases({
301
- android: { type: 'subs' },
302
- })
301
+ android: {type: 'subs'},
302
+ });
303
303
 
304
304
  // Validate and convert both sets of purchases
305
- const allNitroPurchases = [...inappNitroPurchases, ...subsNitroPurchases]
306
- const validPurchases = allNitroPurchases.filter(validateNitroPurchase)
305
+ const allNitroPurchases = [...inappNitroPurchases, ...subsNitroPurchases];
306
+ const validPurchases = allNitroPurchases.filter(validateNitroPurchase);
307
307
  if (validPurchases.length !== allNitroPurchases.length) {
308
308
  console.warn(
309
- `[getAvailablePurchases] Some Android purchases failed validation: ${allNitroPurchases.length - validPurchases.length} invalid`
310
- )
309
+ `[getAvailablePurchases] Some Android purchases failed validation: ${allNitroPurchases.length - validPurchases.length} invalid`,
310
+ );
311
311
  }
312
312
 
313
- return validPurchases.map(convertNitroPurchaseToPurchase)
313
+ return validPurchases.map(convertNitroPurchaseToPurchase);
314
314
  } else {
315
- throw new Error('Unsupported platform')
315
+ throw new Error('Unsupported platform');
316
316
  }
317
317
 
318
- const nitroPurchases = await iap.getAvailablePurchases(options)
318
+ const nitroPurchases = await iap.getAvailablePurchases(options);
319
319
 
320
320
  // Validate and convert NitroPurchases to TypeScript Purchases
321
- const validPurchases = nitroPurchases.filter(validateNitroPurchase)
321
+ const validPurchases = nitroPurchases.filter(validateNitroPurchase);
322
322
  if (validPurchases.length !== nitroPurchases.length) {
323
323
  console.warn(
324
- `[getAvailablePurchases] Some purchases failed validation: ${nitroPurchases.length - validPurchases.length} invalid`
325
- )
324
+ `[getAvailablePurchases] Some purchases failed validation: ${nitroPurchases.length - validPurchases.length} invalid`,
325
+ );
326
326
  }
327
327
 
328
- return validPurchases.map(convertNitroPurchaseToPurchase)
328
+ return validPurchases.map(convertNitroPurchaseToPurchase);
329
329
  } catch (error) {
330
- console.error('Failed to get available purchases:', error)
331
- throw error
330
+ console.error('Failed to get available purchases:', error);
331
+ throw error;
332
332
  }
333
- }
333
+ };
334
334
 
335
335
  /**
336
336
  * Finish a transaction (consume or acknowledge)
@@ -352,58 +352,58 @@ export const finishTransaction = async ({
352
352
  }: FinishTransactionParams): Promise<NitroPurchaseResult | boolean> => {
353
353
  try {
354
354
  // Create unified params
355
- const params: any = {}
355
+ const params: any = {};
356
356
 
357
357
  if (Platform.OS === 'ios') {
358
358
  if (!purchase.id) {
359
- throw new Error('purchase.id required to finish iOS transaction')
359
+ throw new Error('purchase.id required to finish iOS transaction');
360
360
  }
361
361
  params.ios = {
362
362
  transactionId: purchase.id,
363
- }
363
+ };
364
364
  } else if (Platform.OS === 'android') {
365
- const androidPurchase = purchase as PurchaseAndroid
365
+ const androidPurchase = purchase as PurchaseAndroid;
366
366
  const token =
367
- androidPurchase.purchaseToken || androidPurchase.purchaseTokenAndroid
367
+ androidPurchase.purchaseToken || androidPurchase.purchaseTokenAndroid;
368
368
 
369
369
  if (!token) {
370
- throw new Error('purchaseToken required to finish Android transaction')
370
+ throw new Error('purchaseToken required to finish Android transaction');
371
371
  }
372
372
 
373
373
  params.android = {
374
374
  purchaseToken: token,
375
375
  isConsumable,
376
- }
376
+ };
377
377
  } else {
378
- throw new Error('Unsupported platform')
378
+ throw new Error('Unsupported platform');
379
379
  }
380
380
 
381
- const result = await iap.finishTransaction(params)
381
+ const result = await iap.finishTransaction(params);
382
382
 
383
383
  // Handle variant return type
384
384
  if (typeof result === 'boolean') {
385
- return result
385
+ return result;
386
386
  }
387
387
  // It's a PurchaseResult
388
- return result as NitroPurchaseResult
388
+ return result as NitroPurchaseResult;
389
389
  } catch (error) {
390
390
  // If iOS transaction has already been auto-finished natively, treat as success
391
391
  if (Platform.OS === 'ios') {
392
- const err = parseErrorStringToJsonObj(error)
393
- const msg = (err?.message || '').toString()
394
- const code = (err?.code || '').toString()
392
+ const err = parseErrorStringToJsonObj(error);
393
+ const msg = (err?.message || '').toString();
394
+ const code = (err?.code || '').toString();
395
395
  if (
396
396
  msg.includes('Transaction not found') ||
397
397
  code === 'E_ITEM_UNAVAILABLE'
398
398
  ) {
399
399
  // Consider already finished
400
- return true
400
+ return true;
401
401
  }
402
402
  }
403
- console.error('Failed to finish transaction:', error)
404
- throw error
403
+ console.error('Failed to finish transaction:', error);
404
+ throw error;
405
405
  }
406
- }
406
+ };
407
407
 
408
408
  /**
409
409
  * Acknowledge a purchase (Android only)
@@ -415,11 +415,13 @@ export const finishTransaction = async ({
415
415
  * ```
416
416
  */
417
417
  export const acknowledgePurchaseAndroid = async (
418
- purchaseToken: string
418
+ purchaseToken: string,
419
419
  ): Promise<NitroPurchaseResult> => {
420
420
  try {
421
421
  if (Platform.OS !== 'android') {
422
- throw new Error('acknowledgePurchaseAndroid is only available on Android')
422
+ throw new Error(
423
+ 'acknowledgePurchaseAndroid is only available on Android',
424
+ );
423
425
  }
424
426
 
425
427
  const result = await iap.finishTransaction({
@@ -427,7 +429,7 @@ export const acknowledgePurchaseAndroid = async (
427
429
  purchaseToken,
428
430
  isConsumable: false,
429
431
  },
430
- })
432
+ });
431
433
 
432
434
  // Result is a variant, extract PurchaseResult
433
435
  if (typeof result === 'boolean') {
@@ -437,14 +439,14 @@ export const acknowledgePurchaseAndroid = async (
437
439
  code: '0',
438
440
  message: 'Success',
439
441
  purchaseToken,
440
- }
442
+ };
441
443
  }
442
- return result as NitroPurchaseResult
444
+ return result as NitroPurchaseResult;
443
445
  } catch (error) {
444
- console.error('Failed to acknowledge purchase Android:', error)
445
- throw error
446
+ console.error('Failed to acknowledge purchase Android:', error);
447
+ throw error;
446
448
  }
447
- }
449
+ };
448
450
 
449
451
  /**
450
452
  * Consume a purchase (Android only)
@@ -456,11 +458,11 @@ export const acknowledgePurchaseAndroid = async (
456
458
  * ```
457
459
  */
458
460
  export const consumePurchaseAndroid = async (
459
- purchaseToken: string
461
+ purchaseToken: string,
460
462
  ): Promise<NitroPurchaseResult> => {
461
463
  try {
462
464
  if (Platform.OS !== 'android') {
463
- throw new Error('consumePurchaseAndroid is only available on Android')
465
+ throw new Error('consumePurchaseAndroid is only available on Android');
464
466
  }
465
467
 
466
468
  const result = await iap.finishTransaction({
@@ -468,7 +470,7 @@ export const consumePurchaseAndroid = async (
468
470
  purchaseToken,
469
471
  isConsumable: true,
470
472
  },
471
- })
473
+ });
472
474
 
473
475
  // Result is a variant, extract PurchaseResult
474
476
  if (typeof result === 'boolean') {
@@ -478,21 +480,21 @@ export const consumePurchaseAndroid = async (
478
480
  code: '0',
479
481
  message: 'Success',
480
482
  purchaseToken,
481
- }
483
+ };
482
484
  }
483
- return result as NitroPurchaseResult
485
+ return result as NitroPurchaseResult;
484
486
  } catch (error) {
485
- console.error('Failed to consume purchase Android:', error)
486
- throw error
487
+ console.error('Failed to consume purchase Android:', error);
488
+ throw error;
487
489
  }
488
- }
490
+ };
489
491
 
490
492
  // ============================================================================
491
493
  // EVENT LISTENERS
492
494
  // ============================================================================
493
495
 
494
496
  // Store wrapped listeners for proper removal
495
- const listenerMap = new WeakMap<Function, Function>()
497
+ const listenerMap = new WeakMap<Function, Function>();
496
498
 
497
499
  /**
498
500
  * Purchase updated event listener
@@ -515,35 +517,35 @@ const listenerMap = new WeakMap<Function, Function>()
515
517
  * ```
516
518
  */
517
519
  export const purchaseUpdatedListener = (
518
- listener: (purchase: Purchase) => void
520
+ listener: (purchase: Purchase) => void,
519
521
  ): EventSubscription => {
520
522
  // Wrap the listener to convert NitroPurchase to Purchase
521
523
  const wrappedListener = (nitroPurchase: any) => {
522
524
  if (validateNitroPurchase(nitroPurchase)) {
523
- const convertedPurchase = convertNitroPurchaseToPurchase(nitroPurchase)
524
- listener(convertedPurchase)
525
+ const convertedPurchase = convertNitroPurchaseToPurchase(nitroPurchase);
526
+ listener(convertedPurchase);
525
527
  } else {
526
528
  console.error(
527
529
  'Invalid purchase data received from native:',
528
- nitroPurchase
529
- )
530
+ nitroPurchase,
531
+ );
530
532
  }
531
- }
533
+ };
532
534
 
533
535
  // Store the wrapped listener for removal
534
- listenerMap.set(listener, wrappedListener)
535
- iap.addPurchaseUpdatedListener(wrappedListener)
536
+ listenerMap.set(listener, wrappedListener);
537
+ iap.addPurchaseUpdatedListener(wrappedListener);
536
538
 
537
539
  return {
538
540
  remove: () => {
539
- const wrapped = listenerMap.get(listener)
541
+ const wrapped = listenerMap.get(listener);
540
542
  if (wrapped) {
541
- iap.removePurchaseUpdatedListener(wrapped as any)
542
- listenerMap.delete(listener)
543
+ iap.removePurchaseUpdatedListener(wrapped as any);
544
+ listenerMap.delete(listener);
543
545
  }
544
546
  },
545
- }
546
- }
547
+ };
548
+ };
547
549
 
548
550
  /**
549
551
  * Purchase error event listener
@@ -573,19 +575,19 @@ export const purchaseUpdatedListener = (
573
575
  * ```
574
576
  */
575
577
  export const purchaseErrorListener = (
576
- listener: (error: NitroPurchaseResult) => void
578
+ listener: (error: NitroPurchaseResult) => void,
577
579
  ): EventSubscription => {
578
580
  // Store the listener for removal
579
- listenerMap.set(listener, listener)
580
- iap.addPurchaseErrorListener(listener as any)
581
+ listenerMap.set(listener, listener);
582
+ iap.addPurchaseErrorListener(listener as any);
581
583
 
582
584
  return {
583
585
  remove: () => {
584
- iap.removePurchaseErrorListener(listener as any)
585
- listenerMap.delete(listener)
586
+ iap.removePurchaseErrorListener(listener as any);
587
+ listenerMap.delete(listener);
586
588
  },
587
- }
588
- }
589
+ };
590
+ };
589
591
 
590
592
  /**
591
593
  * iOS-only listener for App Store promoted product events.
@@ -608,42 +610,42 @@ export const purchaseErrorListener = (
608
610
  * @platform iOS
609
611
  */
610
612
  export const promotedProductListenerIOS = (
611
- listener: (product: Product) => void
613
+ listener: (product: Product) => void,
612
614
  ): EventSubscription => {
613
615
  if (Platform.OS !== 'ios') {
614
616
  console.warn(
615
- 'promotedProductListenerIOS: This listener is only available on iOS'
616
- )
617
- return { remove: () => {} }
617
+ 'promotedProductListenerIOS: This listener is only available on iOS',
618
+ );
619
+ return {remove: () => {}};
618
620
  }
619
621
 
620
622
  // Wrap the listener to convert NitroProduct to Product
621
623
  const wrappedListener = (nitroProduct: any) => {
622
624
  if (validateNitroProduct(nitroProduct)) {
623
- const convertedProduct = convertNitroProductToProduct(nitroProduct)
624
- listener(convertedProduct)
625
+ const convertedProduct = convertNitroProductToProduct(nitroProduct);
626
+ listener(convertedProduct);
625
627
  } else {
626
628
  console.error(
627
629
  'Invalid promoted product data received from native:',
628
- nitroProduct
629
- )
630
+ nitroProduct,
631
+ );
630
632
  }
631
- }
633
+ };
632
634
 
633
635
  // Store the wrapped listener for removal
634
- listenerMap.set(listener, wrappedListener)
635
- iap.addPromotedProductListenerIOS(wrappedListener)
636
+ listenerMap.set(listener, wrappedListener);
637
+ iap.addPromotedProductListenerIOS(wrappedListener);
636
638
 
637
639
  return {
638
640
  remove: () => {
639
- const wrapped = listenerMap.get(listener)
641
+ const wrapped = listenerMap.get(listener);
640
642
  if (wrapped) {
641
- iap.removePromotedProductListenerIOS(wrapped as any)
642
- listenerMap.delete(listener)
643
+ iap.removePromotedProductListenerIOS(wrapped as any);
644
+ listenerMap.delete(listener);
643
645
  }
644
646
  },
645
- }
646
- }
647
+ };
648
+ };
647
649
 
648
650
  // ============================================================================
649
651
  // iOS-SPECIFIC FUNCTIONS
@@ -658,30 +660,30 @@ export const promotedProductListenerIOS = (
658
660
  export const validateReceipt = async (
659
661
  sku: string,
660
662
  androidOptions?: {
661
- packageName: string
662
- productToken: string
663
- accessToken: string
664
- isSub?: boolean
665
- }
663
+ packageName: string;
664
+ productToken: string;
665
+ accessToken: string;
666
+ isSub?: boolean;
667
+ },
666
668
  ): Promise<import('./types').ReceiptValidationResult> => {
667
669
  if (!iap) {
668
670
  const errorJson = parseErrorStringToJsonObj(
669
- 'RnIap: Service not initialized. Call initConnection() first.'
670
- )
671
- throw new Error(errorJson.message)
671
+ 'RnIap: Service not initialized. Call initConnection() first.',
672
+ );
673
+ throw new Error(errorJson.message);
672
674
  }
673
675
 
674
676
  try {
675
677
  const params: NitroReceiptValidationParams = {
676
678
  sku,
677
679
  androidOptions,
678
- }
680
+ };
679
681
 
680
- const nitroResult = await iap.validateReceipt(params)
682
+ const nitroResult = await iap.validateReceipt(params);
681
683
 
682
684
  // Convert Nitro result to public API result
683
685
  if (Platform.OS === 'ios') {
684
- const iosResult = nitroResult as NitroReceiptValidationResultIOS
686
+ const iosResult = nitroResult as NitroReceiptValidationResultIOS;
685
687
  const result: ReceiptValidationResultIOS = {
686
688
  isValid: iosResult.isValid,
687
689
  receiptData: iosResult.receiptData,
@@ -689,11 +691,11 @@ export const validateReceipt = async (
689
691
  latestTransaction: iosResult.latestTransaction
690
692
  ? convertNitroPurchaseToPurchase(iosResult.latestTransaction)
691
693
  : undefined,
692
- }
693
- return result
694
+ };
695
+ return result;
694
696
  } else {
695
697
  // Android
696
- const androidResult = nitroResult as NitroReceiptValidationResultAndroid
698
+ const androidResult = nitroResult as NitroReceiptValidationResultAndroid;
697
699
  const result: ReceiptValidationResultAndroid = {
698
700
  autoRenewing: androidResult.autoRenewing,
699
701
  betaProduct: androidResult.betaProduct,
@@ -713,15 +715,15 @@ export const validateReceipt = async (
713
715
  term: androidResult.term,
714
716
  termSku: androidResult.termSku,
715
717
  testTransaction: androidResult.testTransaction,
716
- }
717
- return result
718
+ };
719
+ return result;
718
720
  }
719
721
  } catch (error) {
720
- console.error('[validateReceipt] Failed:', error)
721
- const errorJson = parseErrorStringToJsonObj(error)
722
- throw new Error(errorJson.message)
722
+ console.error('[validateReceipt] Failed:', error);
723
+ const errorJson = parseErrorStringToJsonObj(error);
724
+ throw new Error(errorJson.message);
723
725
  }
724
- }
726
+ };
725
727
 
726
728
  /**
727
729
  * Sync iOS purchases with App Store (iOS only)
@@ -730,24 +732,24 @@ export const validateReceipt = async (
730
732
  */
731
733
  export const syncIOS = async (): Promise<boolean> => {
732
734
  if (Platform.OS !== 'ios') {
733
- throw new Error('syncIOS is only available on iOS')
735
+ throw new Error('syncIOS is only available on iOS');
734
736
  }
735
737
 
736
738
  if (!iap) {
737
739
  const errorJson = parseErrorStringToJsonObj(
738
- 'RnIap: Service not initialized. Call initConnection() first.'
739
- )
740
- throw new Error(errorJson.message)
740
+ 'RnIap: Service not initialized. Call initConnection() first.',
741
+ );
742
+ throw new Error(errorJson.message);
741
743
  }
742
744
 
743
745
  try {
744
- return await iap.syncIOS()
746
+ return await iap.syncIOS();
745
747
  } catch (error) {
746
- console.error('[syncIOS] Failed:', error)
747
- const errorJson = parseErrorStringToJsonObj(error)
748
- throw new Error(errorJson.message)
748
+ console.error('[syncIOS] Failed:', error);
749
+ const errorJson = parseErrorStringToJsonObj(error);
750
+ throw new Error(errorJson.message);
749
751
  }
750
- }
752
+ };
751
753
 
752
754
  /**
753
755
  * Request the promoted product from the App Store (iOS only)
@@ -756,28 +758,28 @@ export const syncIOS = async (): Promise<boolean> => {
756
758
  */
757
759
  export const requestPromotedProductIOS = async (): Promise<Product | null> => {
758
760
  if (Platform.OS !== 'ios') {
759
- return null
761
+ return null;
760
762
  }
761
763
 
762
764
  if (!iap) {
763
765
  const errorJson = parseErrorStringToJsonObj(
764
- 'RnIap: Service not initialized. Call initConnection() first.'
765
- )
766
- throw new Error(errorJson.message)
766
+ 'RnIap: Service not initialized. Call initConnection() first.',
767
+ );
768
+ throw new Error(errorJson.message);
767
769
  }
768
770
 
769
771
  try {
770
- const nitroProduct = await iap.requestPromotedProductIOS()
772
+ const nitroProduct = await iap.requestPromotedProductIOS();
771
773
  if (nitroProduct) {
772
- return convertNitroProductToProduct(nitroProduct)
774
+ return convertNitroProductToProduct(nitroProduct);
773
775
  }
774
- return null
776
+ return null;
775
777
  } catch (error) {
776
- console.error('[getPromotedProductIOS] Failed:', error)
777
- const errorJson = parseErrorStringToJsonObj(error)
778
- throw new Error(errorJson.message)
778
+ console.error('[getPromotedProductIOS] Failed:', error);
779
+ const errorJson = parseErrorStringToJsonObj(error);
780
+ throw new Error(errorJson.message);
779
781
  }
780
- }
782
+ };
781
783
 
782
784
  /**
783
785
  * Present the code redemption sheet for offer codes (iOS only)
@@ -786,24 +788,24 @@ export const requestPromotedProductIOS = async (): Promise<Product | null> => {
786
788
  */
787
789
  export const presentCodeRedemptionSheetIOS = async (): Promise<boolean> => {
788
790
  if (Platform.OS !== 'ios') {
789
- return false
791
+ return false;
790
792
  }
791
793
 
792
794
  if (!iap) {
793
795
  const errorJson = parseErrorStringToJsonObj(
794
- 'RnIap: Service not initialized. Call initConnection() first.'
795
- )
796
- throw new Error(errorJson.message)
796
+ 'RnIap: Service not initialized. Call initConnection() first.',
797
+ );
798
+ throw new Error(errorJson.message);
797
799
  }
798
800
 
799
801
  try {
800
- return await iap.presentCodeRedemptionSheetIOS()
802
+ return await iap.presentCodeRedemptionSheetIOS();
801
803
  } catch (error) {
802
- console.error('[presentCodeRedemptionSheetIOS] Failed:', error)
803
- const errorJson = parseErrorStringToJsonObj(error)
804
- throw new Error(errorJson.message)
804
+ console.error('[presentCodeRedemptionSheetIOS] Failed:', error);
805
+ const errorJson = parseErrorStringToJsonObj(error);
806
+ throw new Error(errorJson.message);
805
807
  }
806
- }
808
+ };
807
809
 
808
810
  /**
809
811
  * Buy promoted product on iOS
@@ -812,24 +814,24 @@ export const presentCodeRedemptionSheetIOS = async (): Promise<boolean> => {
812
814
  */
813
815
  export const buyPromotedProductIOS = async (): Promise<void> => {
814
816
  if (Platform.OS !== 'ios') {
815
- throw new Error('buyPromotedProductIOS is only available on iOS')
817
+ throw new Error('buyPromotedProductIOS is only available on iOS');
816
818
  }
817
819
 
818
820
  if (!iap) {
819
821
  const errorJson = parseErrorStringToJsonObj(
820
- 'RnIap: Service not initialized. Call initConnection() first.'
821
- )
822
- throw new Error(errorJson.message)
822
+ 'RnIap: Service not initialized. Call initConnection() first.',
823
+ );
824
+ throw new Error(errorJson.message);
823
825
  }
824
826
 
825
827
  try {
826
- await iap.buyPromotedProductIOS()
828
+ await iap.buyPromotedProductIOS();
827
829
  } catch (error) {
828
- console.error('[buyPromotedProductIOS] Failed:', error)
829
- const errorJson = parseErrorStringToJsonObj(error)
830
- throw new Error(errorJson.message)
830
+ console.error('[buyPromotedProductIOS] Failed:', error);
831
+ const errorJson = parseErrorStringToJsonObj(error);
832
+ throw new Error(errorJson.message);
831
833
  }
832
- }
834
+ };
833
835
 
834
836
  /**
835
837
  * Clear unfinished transactions on iOS
@@ -838,24 +840,24 @@ export const buyPromotedProductIOS = async (): Promise<void> => {
838
840
  */
839
841
  export const clearTransactionIOS = async (): Promise<void> => {
840
842
  if (Platform.OS !== 'ios') {
841
- return
843
+ return;
842
844
  }
843
845
 
844
846
  if (!iap) {
845
847
  const errorJson = parseErrorStringToJsonObj(
846
- 'RnIap: Service not initialized. Call initConnection() first.'
847
- )
848
- throw new Error(errorJson.message)
848
+ 'RnIap: Service not initialized. Call initConnection() first.',
849
+ );
850
+ throw new Error(errorJson.message);
849
851
  }
850
852
 
851
853
  try {
852
- await iap.clearTransactionIOS()
854
+ await iap.clearTransactionIOS();
853
855
  } catch (error) {
854
- console.error('[clearTransactionIOS] Failed:', error)
855
- const errorJson = parseErrorStringToJsonObj(error)
856
- throw new Error(errorJson.message)
856
+ console.error('[clearTransactionIOS] Failed:', error);
857
+ const errorJson = parseErrorStringToJsonObj(error);
858
+ throw new Error(errorJson.message);
857
859
  }
858
- }
860
+ };
859
861
 
860
862
  /**
861
863
  * Begin a refund request for a product on iOS 15+
@@ -864,27 +866,27 @@ export const clearTransactionIOS = async (): Promise<void> => {
864
866
  * @platform iOS
865
867
  */
866
868
  export const beginRefundRequestIOS = async (
867
- sku: string
869
+ sku: string,
868
870
  ): Promise<string | null> => {
869
871
  if (Platform.OS !== 'ios') {
870
- return null
872
+ return null;
871
873
  }
872
874
 
873
875
  if (!iap) {
874
876
  const errorJson = parseErrorStringToJsonObj(
875
- 'RnIap: Service not initialized. Call initConnection() first.'
876
- )
877
- throw new Error(errorJson.message)
877
+ 'RnIap: Service not initialized. Call initConnection() first.',
878
+ );
879
+ throw new Error(errorJson.message);
878
880
  }
879
881
 
880
882
  try {
881
- return await iap.beginRefundRequestIOS(sku)
883
+ return await iap.beginRefundRequestIOS(sku);
882
884
  } catch (error) {
883
- console.error('[beginRefundRequestIOS] Failed:', error)
884
- const errorJson = parseErrorStringToJsonObj(error)
885
- throw new Error(errorJson.message)
885
+ console.error('[beginRefundRequestIOS] Failed:', error);
886
+ const errorJson = parseErrorStringToJsonObj(error);
887
+ throw new Error(errorJson.message);
886
888
  }
887
- }
889
+ };
888
890
 
889
891
  /**
890
892
  * Get subscription status for a product (iOS only)
@@ -894,31 +896,31 @@ export const beginRefundRequestIOS = async (
894
896
  * @platform iOS
895
897
  */
896
898
  export const subscriptionStatusIOS = async (
897
- sku: string
899
+ sku: string,
898
900
  ): Promise<SubscriptionStatusIOS[]> => {
899
901
  if (Platform.OS !== 'ios') {
900
- throw new Error('subscriptionStatusIOS is only available on iOS')
902
+ throw new Error('subscriptionStatusIOS is only available on iOS');
901
903
  }
902
904
 
903
905
  if (!iap) {
904
906
  const errorJson = parseErrorStringToJsonObj(
905
- 'RnIap: Service not initialized. Call initConnection() first.'
906
- )
907
- throw new Error(errorJson.message)
907
+ 'RnIap: Service not initialized. Call initConnection() first.',
908
+ );
909
+ throw new Error(errorJson.message);
908
910
  }
909
911
 
910
912
  try {
911
- const statuses = await iap.subscriptionStatusIOS(sku)
912
- if (!statuses || !Array.isArray(statuses)) return []
913
+ const statuses = await iap.subscriptionStatusIOS(sku);
914
+ if (!statuses || !Array.isArray(statuses)) return [];
913
915
  return statuses.map((s) =>
914
- convertNitroSubscriptionStatusToSubscriptionStatusIOS(s as any)
915
- )
916
+ convertNitroSubscriptionStatusToSubscriptionStatusIOS(s as any),
917
+ );
916
918
  } catch (error) {
917
- console.error('[subscriptionStatusIOS] Failed:', error)
918
- const errorJson = parseErrorStringToJsonObj(error)
919
- throw new Error(errorJson.message)
919
+ console.error('[subscriptionStatusIOS] Failed:', error);
920
+ const errorJson = parseErrorStringToJsonObj(error);
921
+ throw new Error(errorJson.message);
920
922
  }
921
- }
923
+ };
922
924
 
923
925
  /**
924
926
  * Get current entitlement for a product (iOS only)
@@ -927,31 +929,31 @@ export const subscriptionStatusIOS = async (
927
929
  * @platform iOS
928
930
  */
929
931
  export const currentEntitlementIOS = async (
930
- sku: string
932
+ sku: string,
931
933
  ): Promise<Purchase | null> => {
932
934
  if (Platform.OS !== 'ios') {
933
- return null
935
+ return null;
934
936
  }
935
937
 
936
938
  if (!iap) {
937
939
  const errorJson = parseErrorStringToJsonObj(
938
- 'RnIap: Service not initialized. Call initConnection() first.'
939
- )
940
- throw new Error(errorJson.message)
940
+ 'RnIap: Service not initialized. Call initConnection() first.',
941
+ );
942
+ throw new Error(errorJson.message);
941
943
  }
942
944
 
943
945
  try {
944
- const nitroPurchase = await iap.currentEntitlementIOS(sku)
946
+ const nitroPurchase = await iap.currentEntitlementIOS(sku);
945
947
  if (nitroPurchase) {
946
- return convertNitroPurchaseToPurchase(nitroPurchase)
948
+ return convertNitroPurchaseToPurchase(nitroPurchase);
947
949
  }
948
- return null
950
+ return null;
949
951
  } catch (error) {
950
- console.error('[currentEntitlementIOS] Failed:', error)
951
- const errorJson = parseErrorStringToJsonObj(error)
952
- throw new Error(errorJson.message)
952
+ console.error('[currentEntitlementIOS] Failed:', error);
953
+ const errorJson = parseErrorStringToJsonObj(error);
954
+ throw new Error(errorJson.message);
953
955
  }
954
- }
956
+ };
955
957
 
956
958
  /**
957
959
  * Get latest transaction for a product (iOS only)
@@ -960,31 +962,31 @@ export const currentEntitlementIOS = async (
960
962
  * @platform iOS
961
963
  */
962
964
  export const latestTransactionIOS = async (
963
- sku: string
965
+ sku: string,
964
966
  ): Promise<Purchase | null> => {
965
967
  if (Platform.OS !== 'ios') {
966
- return null
968
+ return null;
967
969
  }
968
970
 
969
971
  if (!iap) {
970
972
  const errorJson = parseErrorStringToJsonObj(
971
- 'RnIap: Service not initialized. Call initConnection() first.'
972
- )
973
- throw new Error(errorJson.message)
973
+ 'RnIap: Service not initialized. Call initConnection() first.',
974
+ );
975
+ throw new Error(errorJson.message);
974
976
  }
975
977
 
976
978
  try {
977
- const nitroPurchase = await iap.latestTransactionIOS(sku)
979
+ const nitroPurchase = await iap.latestTransactionIOS(sku);
978
980
  if (nitroPurchase) {
979
- return convertNitroPurchaseToPurchase(nitroPurchase)
981
+ return convertNitroPurchaseToPurchase(nitroPurchase);
980
982
  }
981
- return null
983
+ return null;
982
984
  } catch (error) {
983
- console.error('[latestTransactionIOS] Failed:', error)
984
- const errorJson = parseErrorStringToJsonObj(error)
985
- throw new Error(errorJson.message)
985
+ console.error('[latestTransactionIOS] Failed:', error);
986
+ const errorJson = parseErrorStringToJsonObj(error);
987
+ throw new Error(errorJson.message);
986
988
  }
987
- }
989
+ };
988
990
 
989
991
  /**
990
992
  * Get pending transactions (iOS only)
@@ -993,25 +995,25 @@ export const latestTransactionIOS = async (
993
995
  */
994
996
  export const getPendingTransactionsIOS = async (): Promise<Purchase[]> => {
995
997
  if (Platform.OS !== 'ios') {
996
- return []
998
+ return [];
997
999
  }
998
1000
 
999
1001
  if (!iap) {
1000
1002
  const errorJson = parseErrorStringToJsonObj(
1001
- 'RnIap: Service not initialized. Call initConnection() first.'
1002
- )
1003
- throw new Error(errorJson.message)
1003
+ 'RnIap: Service not initialized. Call initConnection() first.',
1004
+ );
1005
+ throw new Error(errorJson.message);
1004
1006
  }
1005
1007
 
1006
1008
  try {
1007
- const nitroPurchases = await iap.getPendingTransactionsIOS()
1008
- return nitroPurchases.map(convertNitroPurchaseToPurchase)
1009
+ const nitroPurchases = await iap.getPendingTransactionsIOS();
1010
+ return nitroPurchases.map(convertNitroPurchaseToPurchase);
1009
1011
  } catch (error) {
1010
- console.error('[getPendingTransactionsIOS] Failed:', error)
1011
- const errorJson = parseErrorStringToJsonObj(error)
1012
- throw new Error(errorJson.message)
1012
+ console.error('[getPendingTransactionsIOS] Failed:', error);
1013
+ const errorJson = parseErrorStringToJsonObj(error);
1014
+ throw new Error(errorJson.message);
1013
1015
  }
1014
- }
1016
+ };
1015
1017
 
1016
1018
  /**
1017
1019
  * Show manage subscriptions screen (iOS only)
@@ -1020,25 +1022,25 @@ export const getPendingTransactionsIOS = async (): Promise<Purchase[]> => {
1020
1022
  */
1021
1023
  export const showManageSubscriptionsIOS = async (): Promise<Purchase[]> => {
1022
1024
  if (Platform.OS !== 'ios') {
1023
- return []
1025
+ return [];
1024
1026
  }
1025
1027
 
1026
1028
  if (!iap) {
1027
1029
  const errorJson = parseErrorStringToJsonObj(
1028
- 'RnIap: Service not initialized. Call initConnection() first.'
1029
- )
1030
- throw new Error(errorJson.message)
1030
+ 'RnIap: Service not initialized. Call initConnection() first.',
1031
+ );
1032
+ throw new Error(errorJson.message);
1031
1033
  }
1032
1034
 
1033
1035
  try {
1034
- const nitroPurchases = await iap.showManageSubscriptionsIOS()
1035
- return nitroPurchases.map(convertNitroPurchaseToPurchase)
1036
+ const nitroPurchases = await iap.showManageSubscriptionsIOS();
1037
+ return nitroPurchases.map(convertNitroPurchaseToPurchase);
1036
1038
  } catch (error) {
1037
- console.error('[showManageSubscriptionsIOS] Failed:', error)
1038
- const errorJson = parseErrorStringToJsonObj(error)
1039
- throw new Error(errorJson.message)
1039
+ console.error('[showManageSubscriptionsIOS] Failed:', error);
1040
+ const errorJson = parseErrorStringToJsonObj(error);
1041
+ throw new Error(errorJson.message);
1040
1042
  }
1041
- }
1043
+ };
1042
1044
 
1043
1045
  /**
1044
1046
  * Check if user is eligible for intro offer (iOS only)
@@ -1047,27 +1049,27 @@ export const showManageSubscriptionsIOS = async (): Promise<Purchase[]> => {
1047
1049
  * @platform iOS
1048
1050
  */
1049
1051
  export const isEligibleForIntroOfferIOS = async (
1050
- groupID: string
1052
+ groupID: string,
1051
1053
  ): Promise<boolean> => {
1052
1054
  if (Platform.OS !== 'ios') {
1053
- return false
1055
+ return false;
1054
1056
  }
1055
1057
 
1056
1058
  if (!iap) {
1057
1059
  const errorJson = parseErrorStringToJsonObj(
1058
- 'RnIap: Service not initialized. Call initConnection() first.'
1059
- )
1060
- throw new Error(errorJson.message)
1060
+ 'RnIap: Service not initialized. Call initConnection() first.',
1061
+ );
1062
+ throw new Error(errorJson.message);
1061
1063
  }
1062
1064
 
1063
1065
  try {
1064
- return await iap.isEligibleForIntroOfferIOS(groupID)
1066
+ return await iap.isEligibleForIntroOfferIOS(groupID);
1065
1067
  } catch (error) {
1066
- console.error('[isEligibleForIntroOfferIOS] Failed:', error)
1067
- const errorJson = parseErrorStringToJsonObj(error)
1068
- throw new Error(errorJson.message)
1068
+ console.error('[isEligibleForIntroOfferIOS] Failed:', error);
1069
+ const errorJson = parseErrorStringToJsonObj(error);
1070
+ throw new Error(errorJson.message);
1069
1071
  }
1070
- }
1072
+ };
1071
1073
 
1072
1074
  /**
1073
1075
  * Get receipt data (iOS only)
@@ -1076,24 +1078,24 @@ export const isEligibleForIntroOfferIOS = async (
1076
1078
  */
1077
1079
  export const getReceiptDataIOS = async (): Promise<string> => {
1078
1080
  if (Platform.OS !== 'ios') {
1079
- throw new Error('getReceiptDataIOS is only available on iOS')
1081
+ throw new Error('getReceiptDataIOS is only available on iOS');
1080
1082
  }
1081
1083
 
1082
1084
  if (!iap) {
1083
1085
  const errorJson = parseErrorStringToJsonObj(
1084
- 'RnIap: Service not initialized. Call initConnection() first.'
1085
- )
1086
- throw new Error(errorJson.message)
1086
+ 'RnIap: Service not initialized. Call initConnection() first.',
1087
+ );
1088
+ throw new Error(errorJson.message);
1087
1089
  }
1088
1090
 
1089
1091
  try {
1090
- return await iap.getReceiptDataIOS()
1092
+ return await iap.getReceiptDataIOS();
1091
1093
  } catch (error) {
1092
- console.error('[getReceiptDataIOS] Failed:', error)
1093
- const errorJson = parseErrorStringToJsonObj(error)
1094
- throw new Error(errorJson.message)
1094
+ console.error('[getReceiptDataIOS] Failed:', error);
1095
+ const errorJson = parseErrorStringToJsonObj(error);
1096
+ throw new Error(errorJson.message);
1095
1097
  }
1096
- }
1098
+ };
1097
1099
 
1098
1100
  /**
1099
1101
  * Check if transaction is verified (iOS only)
@@ -1102,27 +1104,27 @@ export const getReceiptDataIOS = async (): Promise<string> => {
1102
1104
  * @platform iOS
1103
1105
  */
1104
1106
  export const isTransactionVerifiedIOS = async (
1105
- sku: string
1107
+ sku: string,
1106
1108
  ): Promise<boolean> => {
1107
1109
  if (Platform.OS !== 'ios') {
1108
- return false
1110
+ return false;
1109
1111
  }
1110
1112
 
1111
1113
  if (!iap) {
1112
1114
  const errorJson = parseErrorStringToJsonObj(
1113
- 'RnIap: Service not initialized. Call initConnection() first.'
1114
- )
1115
- throw new Error(errorJson.message)
1115
+ 'RnIap: Service not initialized. Call initConnection() first.',
1116
+ );
1117
+ throw new Error(errorJson.message);
1116
1118
  }
1117
1119
 
1118
1120
  try {
1119
- return await iap.isTransactionVerifiedIOS(sku)
1121
+ return await iap.isTransactionVerifiedIOS(sku);
1120
1122
  } catch (error) {
1121
- console.error('[isTransactionVerifiedIOS] Failed:', error)
1122
- const errorJson = parseErrorStringToJsonObj(error)
1123
- throw new Error(errorJson.message)
1123
+ console.error('[isTransactionVerifiedIOS] Failed:', error);
1124
+ const errorJson = parseErrorStringToJsonObj(error);
1125
+ throw new Error(errorJson.message);
1124
1126
  }
1125
- }
1127
+ };
1126
1128
 
1127
1129
  /**
1128
1130
  * Get transaction JWS representation (iOS only)
@@ -1131,27 +1133,27 @@ export const isTransactionVerifiedIOS = async (
1131
1133
  * @platform iOS
1132
1134
  */
1133
1135
  export const getTransactionJwsIOS = async (
1134
- sku: string
1136
+ sku: string,
1135
1137
  ): Promise<string | null> => {
1136
1138
  if (Platform.OS !== 'ios') {
1137
- return null
1139
+ return null;
1138
1140
  }
1139
1141
 
1140
1142
  if (!iap) {
1141
1143
  const errorJson = parseErrorStringToJsonObj(
1142
- 'RnIap: Service not initialized. Call initConnection() first.'
1143
- )
1144
- throw new Error(errorJson.message)
1144
+ 'RnIap: Service not initialized. Call initConnection() first.',
1145
+ );
1146
+ throw new Error(errorJson.message);
1145
1147
  }
1146
1148
 
1147
1149
  try {
1148
- return await iap.getTransactionJwsIOS(sku)
1150
+ return await iap.getTransactionJwsIOS(sku);
1149
1151
  } catch (error) {
1150
- console.error('[getTransactionJwsIOS] Failed:', error)
1151
- const errorJson = parseErrorStringToJsonObj(error)
1152
- throw new Error(errorJson.message)
1152
+ console.error('[getTransactionJwsIOS] Failed:', error);
1153
+ const errorJson = parseErrorStringToJsonObj(error);
1154
+ throw new Error(errorJson.message);
1153
1155
  }
1154
- }
1156
+ };
1155
1157
 
1156
1158
  /**
1157
1159
  * Get the storefront identifier for the user's App Store account (iOS only)
@@ -1166,18 +1168,18 @@ export const getTransactionJwsIOS = async (
1166
1168
  */
1167
1169
  export const getStorefrontIOS = async (): Promise<string> => {
1168
1170
  if (Platform.OS !== 'ios') {
1169
- throw new Error('getStorefrontIOS is only available on iOS')
1171
+ throw new Error('getStorefrontIOS is only available on iOS');
1170
1172
  }
1171
1173
 
1172
1174
  try {
1173
1175
  // Call the native method to get storefront
1174
- const storefront = await iap.getStorefrontIOS()
1175
- return storefront
1176
+ const storefront = await iap.getStorefrontIOS();
1177
+ return storefront;
1176
1178
  } catch (error) {
1177
- console.error('Failed to get storefront:', error)
1178
- throw error
1179
+ console.error('Failed to get storefront:', error);
1180
+ throw error;
1179
1181
  }
1180
- }
1182
+ };
1181
1183
 
1182
1184
  /**
1183
1185
  * iOS only - Gets the original app transaction ID if the app was purchased from the App Store
@@ -1200,24 +1202,24 @@ export const getStorefrontIOS = async (): Promise<string> => {
1200
1202
  */
1201
1203
  export const getAppTransactionIOS = async (): Promise<string | null> => {
1202
1204
  if (Platform.OS !== 'ios') {
1203
- throw new Error('getAppTransactionIOS is only available on iOS')
1205
+ throw new Error('getAppTransactionIOS is only available on iOS');
1204
1206
  }
1205
1207
 
1206
1208
  try {
1207
1209
  // Call the native method to get app transaction
1208
- const appTransaction = await iap.getAppTransactionIOS()
1209
- return appTransaction
1210
+ const appTransaction = await iap.getAppTransactionIOS();
1211
+ return appTransaction;
1210
1212
  } catch (error) {
1211
- console.error('Failed to get app transaction:', error)
1212
- throw error
1213
+ console.error('Failed to get app transaction:', error);
1214
+ throw error;
1213
1215
  }
1214
- }
1216
+ };
1215
1217
 
1216
1218
  // Export subscription helpers
1217
1219
  export {
1218
1220
  getActiveSubscriptions,
1219
1221
  hasActiveSubscriptions,
1220
- } from './helpers/subscription'
1222
+ } from './helpers/subscription';
1221
1223
 
1222
1224
  // Type conversion utilities
1223
1225
  export {
@@ -1227,15 +1229,15 @@ export {
1227
1229
  validateNitroProduct,
1228
1230
  validateNitroPurchase,
1229
1231
  checkTypeSynchronization,
1230
- } from './utils/type-bridge'
1232
+ } from './utils/type-bridge';
1231
1233
 
1232
1234
  // Deprecated exports for backward compatibility
1233
1235
  /**
1234
1236
  * @deprecated Use acknowledgePurchaseAndroid instead
1235
1237
  */
1236
- export const acknowledgePurchase = acknowledgePurchaseAndroid
1238
+ export const acknowledgePurchase = acknowledgePurchaseAndroid;
1237
1239
 
1238
1240
  /**
1239
1241
  * @deprecated Use consumePurchaseAndroid instead
1240
1242
  */
1241
- export const consumePurchase = consumePurchaseAndroid
1243
+ export const consumePurchase = consumePurchaseAndroid;