react-native-iap 11.0.0-rc.2 → 11.0.0-rc.4

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 (57) hide show
  1. package/ios/IapSerializationUtils.swift +50 -11
  2. package/ios/IapTypes.swift +1 -6
  3. package/ios/RNIapIos.m +3 -0
  4. package/ios/RNIapIos.swift +12 -3
  5. package/ios/RNIapIosSk2.m +6 -1
  6. package/ios/RNIapIosSk2.swift +37 -16
  7. package/lib/commonjs/eventEmitter.js +145 -2
  8. package/lib/commonjs/eventEmitter.js.map +1 -1
  9. package/lib/commonjs/hooks/withIAPContext.js +8 -1
  10. package/lib/commonjs/hooks/withIAPContext.js.map +1 -1
  11. package/lib/commonjs/iap.js +81 -37
  12. package/lib/commonjs/iap.js.map +1 -1
  13. package/lib/commonjs/internal/platform.js +33 -4
  14. package/lib/commonjs/internal/platform.js.map +1 -1
  15. package/lib/commonjs/modules/ios.js +5 -2
  16. package/lib/commonjs/modules/ios.js.map +1 -1
  17. package/lib/commonjs/modules/iosSk2.js.map +1 -1
  18. package/lib/commonjs/types/apple.js +24 -0
  19. package/lib/commonjs/types/apple.js.map +1 -1
  20. package/lib/commonjs/types/appleSk2.js +3 -3
  21. package/lib/commonjs/types/appleSk2.js.map +1 -1
  22. package/lib/commonjs/types/index.js.map +1 -1
  23. package/lib/module/eventEmitter.js +141 -1
  24. package/lib/module/eventEmitter.js.map +1 -1
  25. package/lib/module/hooks/withIAPContext.js +9 -2
  26. package/lib/module/hooks/withIAPContext.js.map +1 -1
  27. package/lib/module/iap.js +77 -30
  28. package/lib/module/iap.js.map +1 -1
  29. package/lib/module/internal/platform.js +25 -2
  30. package/lib/module/internal/platform.js.map +1 -1
  31. package/lib/module/modules/ios.js +5 -2
  32. package/lib/module/modules/ios.js.map +1 -1
  33. package/lib/module/modules/iosSk2.js.map +1 -1
  34. package/lib/module/types/apple.js +15 -0
  35. package/lib/module/types/apple.js.map +1 -1
  36. package/lib/module/types/appleSk2.js +3 -3
  37. package/lib/module/types/appleSk2.js.map +1 -1
  38. package/lib/module/types/index.js.map +1 -1
  39. package/lib/typescript/eventEmitter.d.ts +133 -0
  40. package/lib/typescript/hooks/withIAPContext.d.ts +2 -0
  41. package/lib/typescript/iap.d.ts +25 -4
  42. package/lib/typescript/internal/platform.d.ts +3 -1
  43. package/lib/typescript/modules/ios.d.ts +2 -1
  44. package/lib/typescript/modules/iosSk2.d.ts +3 -2
  45. package/lib/typescript/types/apple.d.ts +1 -0
  46. package/lib/typescript/types/appleSk2.d.ts +31 -2
  47. package/lib/typescript/types/index.d.ts +1 -0
  48. package/package.json +1 -1
  49. package/src/eventEmitter.ts +144 -2
  50. package/src/hooks/withIAPContext.tsx +15 -0
  51. package/src/iap.ts +55 -17
  52. package/src/internal/platform.ts +24 -2
  53. package/src/modules/ios.ts +7 -3
  54. package/src/modules/iosSk2.ts +5 -2
  55. package/src/types/apple.ts +15 -0
  56. package/src/types/appleSk2.ts +42 -5
  57. package/src/types/index.ts +1 -0
@@ -50,9 +50,28 @@ func serialize(_ si: Product.SubscriptionInfo?) -> [String: Any?]? {
50
50
  "introductoryOffer": serialize(si.introductoryOffer),
51
51
  "promotionalOffers": si.promotionalOffers.map {(offer: Product.SubscriptionOffer) in serialize(offer)},
52
52
  "subscriptionGroupID": si.subscriptionGroupID,
53
- "subscriptionPeriod": si.subscriptionPeriod
53
+ "subscriptionPeriod": serialize(si.subscriptionPeriod)
54
54
  ]
55
55
  }
56
+ @available(iOS 15.0, *)
57
+ func serialize(_ sp: Product.SubscriptionPeriod?) -> [String: Any?]? {
58
+ guard let sp = sp else {return nil}
59
+ return ["value": sp.value,
60
+ "unit": serialize(sp.unit)]
61
+ }
62
+ @available(iOS 15.0, *)
63
+ func serialize(_ sp: Product.SubscriptionPeriod.Unit?) -> String? {
64
+ guard let sp = sp else {return nil}
65
+ switch sp {
66
+ case .day: return "day"
67
+ case .week: return "week"
68
+ case .month: return "month"
69
+ case .year: return "year"
70
+ default:
71
+ return nil
72
+ }
73
+ }
74
+
56
75
  @available(iOS 15.0, *)
57
76
  func serialize(_ s: Product.SubscriptionInfo.Status?) -> [String: Any?]? {
58
77
  guard let s = s else {return nil}
@@ -79,7 +98,7 @@ func serialize(_ rs: Product.SubscriptionInfo.RenewalState?) -> String? {
79
98
  @available(iOS 15.0, *)
80
99
  func serialize(_ ri: Product.SubscriptionInfo.RenewalInfo?) -> [String: Any?]? {
81
100
  guard let ri = ri else {return nil}
82
- return ["signedDate": ri.signedDate
101
+ return ["signedDate": ri.signedDate.millisecondsSince1970
83
102
  ]
84
103
  }
85
104
 
@@ -89,14 +108,34 @@ func serialize(_ so: Product.SubscriptionOffer?) -> [String: Any?]? {
89
108
  return [
90
109
  "displayPrice": so.displayPrice,
91
110
  "id": so.id,
92
- "paymentMode": so.paymentMode,
93
- "period": so.period,
111
+ "paymentMode": serialize(so.paymentMode),
112
+ "period": serialize(so.period),
94
113
  "periodCount": so.periodCount,
95
114
  "price": so.price,
96
- "type": so.type
115
+ "type": serialize(so.type)
97
116
  ]
98
117
  }
99
-
118
+ @available(iOS 15.0, *)
119
+ func serialize(_ pm: Product.SubscriptionOffer.PaymentMode?) -> String? {
120
+ guard let pm = pm else {return nil}
121
+ switch pm {
122
+ case .freeTrial: return "freeTrial"
123
+ case .payAsYouGo: return "payAsYouGo"
124
+ case .payUpFront: return "payUpFront"
125
+ default:
126
+ return nil
127
+ }
128
+ }
129
+ @available(iOS 15.0, *)
130
+ func serialize(_ ot: Product.SubscriptionOffer.OfferType?) -> String? {
131
+ guard let ot = ot else {return nil}
132
+ switch ot {
133
+ case .introductory: return "introductory"
134
+ case .promotional: return "promotional"
135
+ default:
136
+ return nil
137
+ }
138
+ }
100
139
  @available(iOS 15.0, *)
101
140
  func serialize(_ t: Transaction) -> [String: Any?] {
102
141
  return ["appAccountToken": t.appAccountToken,
@@ -104,22 +143,22 @@ func serialize(_ t: Transaction) -> [String: Any?] {
104
143
  "debugDescription": serializeDebug(t.debugDescription),
105
144
  "deviceVerification": t.deviceVerification,
106
145
  "deviceVerificationNonce": t.deviceVerificationNonce,
107
- "expirationDate": t.expirationDate,
146
+ "expirationDate": t.expirationDate?.millisecondsSince1970,
108
147
  "id": t.id,
109
148
  "isUpgraded": t.isUpgraded,
110
149
  "jsonRepresentation": serializeDebug(t.jsonRepresentation),
111
150
  "offerID": t.offerID,
112
151
  "offerType": serialize(t.offerType),
113
152
  "originalID": t.originalID,
114
- "originalPurchaseDate": t.originalPurchaseDate,
153
+ "originalPurchaseDate": t.originalPurchaseDate.millisecondsSince1970,
115
154
  "ownershipType": serialize(t.ownershipType),
116
155
  "productID": t.productID,
117
156
  "productType": serialize(t.productType),
118
- "purchaseDate": t.purchaseDate,
157
+ "purchaseDate": t.purchaseDate.millisecondsSince1970,
119
158
  "purchasedQuantity": t.purchasedQuantity,
120
- "revocationDate": t.revocationDate,
159
+ "revocationDate": t.revocationDate?.millisecondsSince1970,
121
160
  "revocationReason": t.revocationReason,
122
- "signedDate": t.signedDate,
161
+ "signedDate": t.signedDate.millisecondsSince1970,
123
162
  "subscriptionGroupID": t.subscriptionGroupID,
124
163
  "webOrderLineItemID": t.webOrderLineItemID
125
164
  ]
@@ -10,12 +10,6 @@ import StoreKit
10
10
 
11
11
  typealias RNIapIosPromise = (RCTPromiseResolveBlock, RCTPromiseRejectBlock)
12
12
 
13
- @available(iOS 15.0, *)
14
- struct ProductOrError {
15
- let product: Product?
16
- let error: Error?
17
- }
18
-
19
13
  public enum StoreError: Error {
20
14
  case failedVerification
21
15
  }
@@ -34,6 +28,7 @@ enum IapErrors: String, CaseIterable {
34
28
  case E_PURCHASE_ERROR = "E_PURCHASE_ERROR"
35
29
  case E_SYNC_ERROR = "E_SYNC_ERROR"
36
30
  case E_DEFERRED_PAYMENT = "E_DEFERRED_PAYMENT"
31
+ case E_TRANSACTION_VALIDATION_FAILED = "E_TRANSACTION_VALIDATION_FAILED"
37
32
  func asInt() -> Int {
38
33
  return IapErrors.allCases.firstIndex(of: self)!
39
34
  }
package/ios/RNIapIos.m CHANGED
@@ -4,6 +4,9 @@
4
4
 
5
5
  @interface RCT_EXTERN_MODULE (RNIapIos, NSObject)
6
6
 
7
+ RCT_EXTERN_METHOD(disable:
8
+ (RCTPromiseResolveBlock)resolve
9
+ reject:(RCTPromiseRejectBlock)reject)
7
10
  RCT_EXTERN_METHOD(initConnection:
8
11
  (RCTPromiseResolveBlock)resolve
9
12
  reject:(RCTPromiseRejectBlock)reject)
@@ -49,6 +49,14 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
49
49
  removeTransactionObserver()
50
50
  }
51
51
 
52
+ @objc public func disable(
53
+ _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
54
+ reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
55
+ ) {
56
+ removeTransactionObserver()
57
+ resolve(nil)
58
+ }
59
+
52
60
  override class func requiresMainQueueSetup() -> Bool {
53
61
  return true
54
62
  }
@@ -185,6 +193,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
185
193
  }
186
194
  }
187
195
  @objc public func getAvailableItems(
196
+ alsoPublishToEventListener: Bool,
188
197
  _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
189
198
  reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
190
199
  ) {
@@ -314,7 +323,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
314
323
  ) {
315
324
  requestReceiptData(withBlock: refresh) { [self] receiptData, error in
316
325
  if error == nil {
317
- resolve(receiptData?.base64EncodedString(options: []))
326
+ resolve(receiptData?.base64EncodedString(options: [.endLineWithCarriageReturn]))
318
327
  } else {
319
328
  reject(standardErrorCode(9), "Invalid receipt", nil)
320
329
  }
@@ -347,7 +356,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
347
356
  "transactionId": item.transactionIdentifier,
348
357
  "productId": item.payment.productIdentifier,
349
358
  "quantity": "\(item.payment.quantity)",
350
- "transactionReceipt": receipt.base64EncodedString(options: [])
359
+ "transactionReceipt": receipt.base64EncodedString(options: [.endLineWithCarriageReturn])
351
360
  ]
352
361
 
353
362
  output.append(purchase)
@@ -831,7 +840,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
831
840
  "transactionDate": transaction.transactionDate?.millisecondsSince1970String,
832
841
  "transactionId": transaction.transactionIdentifier,
833
842
  "productId": transaction.payment.productIdentifier,
834
- "transactionReceipt": receiptData?.base64EncodedString(options: [])
843
+ "transactionReceipt": receiptData?.base64EncodedString(options: [.endLineWithCarriageReturn])
835
844
  ]
836
845
 
837
846
  // originalTransaction is available for restore purchase and purchase of cancelled/expired subscriptions
package/ios/RNIapIosSk2.m CHANGED
@@ -4,6 +4,10 @@
4
4
  #ifdef __IPHONE_15_0
5
5
  @interface RCT_EXTERN_MODULE (RNIapIosSk2, NSObject)
6
6
 
7
+ RCT_EXTERN_METHOD(disable:
8
+ (RCTPromiseResolveBlock)resolve
9
+ reject:(RCTPromiseRejectBlock)reject)
10
+
7
11
  RCT_EXTERN_METHOD(initConnection:
8
12
  (RCTPromiseResolveBlock)resolve
9
13
  reject:(RCTPromiseRejectBlock)reject)
@@ -18,7 +22,8 @@ RCT_EXTERN_METHOD(getItems:
18
22
  reject:(RCTPromiseRejectBlock)reject)
19
23
 
20
24
  RCT_EXTERN_METHOD(getAvailableItems:
21
- (RCTPromiseResolveBlock)resolve
25
+ alsoPublishToEventListener:(BOOL)alsoPublishToEventListener
26
+ resolve:(RCTPromiseResolveBlock)resolve
22
27
  reject:(RCTPromiseRejectBlock)reject)
23
28
 
24
29
  RCT_EXTERN_METHOD(buyProduct:
@@ -21,6 +21,14 @@ class RNIapIosSk2: RCTEventEmitter {
21
21
  removeTransactionObserver()
22
22
  }
23
23
 
24
+ @objc public func disable(
25
+ _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
26
+ reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
27
+ ) {
28
+ removeTransactionObserver()
29
+ resolve(nil)
30
+ }
31
+
24
32
  override class func requiresMainQueueSetup() -> Bool {
25
33
  return true
26
34
  }
@@ -52,21 +60,25 @@ class RNIapIosSk2: RCTEventEmitter {
52
60
 
53
61
  if self.hasListeners {
54
62
  self.sendEvent(withName: "purchase-updated", body: serialize(transaction))
63
+ self.sendEvent(withName: "iap-transaction-updated", body: ["transaction": serialize(transaction)])
55
64
  }
56
65
  // Always finish a transaction.
57
- // await transaction.finish() //TODO: Document
66
+ // await transaction.finish()
67
+ // The transaction is returned to the user. Once it has fullfilled the order,
68
+ // they can call finishTransaction
58
69
  } catch {
59
70
  // StoreKit has a transaction that fails verification. Don't deliver content to the user.
60
71
  debugMessage("Transaction failed verification")
61
72
  if self.hasListeners {
62
73
  let err = [
63
- "responseCode": "-1",
74
+ "responseCode": IapErrors.E_TRANSACTION_VALIDATION_FAILED.rawValue,
64
75
  "debugMessage": error.localizedDescription,
65
- "code": "E_RECEIPT_FINISHED_FAILED",
76
+ "code": IapErrors.E_TRANSACTION_VALIDATION_FAILED.rawValue,
66
77
  "message": error.localizedDescription
67
78
  ]
68
79
 
69
80
  self.sendEvent(withName: "purchase-error", body: err)
81
+ self.sendEvent(withName: "iap-transaction-updated", body: ["error": err])
70
82
  }
71
83
  }
72
84
  }
@@ -84,8 +96,13 @@ class RNIapIosSk2: RCTEventEmitter {
84
96
  super.addListener(eventName)
85
97
  }
86
98
 
99
+ /**
100
+ "iap-transaction-updated" is unique to Sk2.
101
+ "iap-promoted-product" is only avaiable on Sk1
102
+ "purchase-updated", "purchase-error" are for backward compatibility
103
+ */
87
104
  override func supportedEvents() -> [String]? {
88
- return [ "iap-promoted-product", "purchase-updated", "purchase-error"]
105
+ return [ "purchase-updated", "purchase-error", "iap-transaction-updated"]
89
106
  }
90
107
 
91
108
  @objc public func initConnection(
@@ -127,19 +144,23 @@ class RNIapIosSk2: RCTEventEmitter {
127
144
  }
128
145
 
129
146
  @objc public func getAvailableItems(
147
+ alsoPublishToEventListener: Bool,
130
148
  _ resolve: @escaping RCTPromiseResolveBlock = { _ in },
131
149
  reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
132
150
  ) {
133
151
  Task {
134
- var purchasedItems: [ProductOrError] = []
152
+ var purchasedItems: [Transaction] = []
135
153
 
136
154
  func addPurchase(transaction: Transaction, product: Product) {
137
- purchasedItems.append(ProductOrError(product: product, error: nil))
138
- sendEvent(withName: "purchase-update", body: serialize(transaction))
155
+ purchasedItems.append( transaction)
156
+ if alsoPublishToEventListener {
157
+ sendEvent(withName: "purchase-update", body: serialize(transaction))
158
+ }
139
159
  }
140
160
  func addError( error: Error, errorDict: [String: String]) {
141
- purchasedItems.append(ProductOrError(product: nil, error: error))
142
- sendEvent(withName: "purchase-error", body: errorDict)
161
+ if alsoPublishToEventListener {
162
+ sendEvent(withName: "purchase-error", body: errorDict)
163
+ }
143
164
  }
144
165
  // Iterate through all of the user's purchased products.
145
166
  for await result in Transaction.currentEntitlements {
@@ -178,20 +199,20 @@ class RNIapIosSk2: RCTEventEmitter {
178
199
  break
179
200
  }
180
201
  } catch StoreError.failedVerification {
181
- let err = [ "responseCode": "1", // TODO
202
+ let err = [ "responseCode": IapErrors.E_TRANSACTION_VALIDATION_FAILED.rawValue,
182
203
  "debugMessage": StoreError.failedVerification.localizedDescription,
183
- "code": "1", // TODO
204
+ "code": IapErrors.E_TRANSACTION_VALIDATION_FAILED.rawValue,
184
205
  "message": StoreError.failedVerification.localizedDescription,
185
- "productId": "unknown"// TODO
206
+ "productId": "unknown"
186
207
  ]
187
208
  addError(error: StoreError.failedVerification, errorDict: err)
188
209
  } catch {
189
210
  debugMessage(error)
190
- let err = [ "responseCode": "1", // TODO
211
+ let err = [ "responseCode": IapErrors.E_UNKNOWN.rawValue,
191
212
  "debugMessage": error.localizedDescription,
192
- "code": "1", // TODO
213
+ "code": IapErrors.E_UNKNOWN.rawValue,
193
214
  "message": error.localizedDescription,
194
- "productId": "unknown"// TODO
215
+ "productId": "unknown"
195
216
  ]
196
217
  addError(error: StoreError.failedVerification, errorDict: err)
197
218
  }
@@ -201,7 +222,7 @@ class RNIapIosSk2: RCTEventEmitter {
201
222
  // group, so products in the subscriptions array all belong to the same group. The statuses that
202
223
  // `product.subscription.status` returns apply to the entire subscription group.
203
224
  // subscriptionGroupStatus = try? await subscriptions.first?.subscription?.status.first?.state
204
- resolve(purchasedItems.map({(p: ProductOrError) in ["product": p.product.flatMap { serialize($0)}, "error": serialize(p.error)]}))
225
+ resolve(purchasedItems.map({(t: Transaction) in serialize(t)}))
205
226
  }
206
227
  }
207
228
 
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.purchaseUpdatedListener = exports.purchaseErrorListener = exports.promotedProductListener = void 0;
6
+ exports.transactionListener = exports.purchaseUpdatedListener = exports.purchaseErrorListener = exports.promotedProductListener = void 0;
7
7
 
8
8
  var _reactNative = require("react-native");
9
9
 
@@ -15,6 +15,35 @@ var _internal = require("./internal");
15
15
 
16
16
  /**
17
17
  * Add IAP purchase event
18
+ * Register a callback that gets called when the store has any updates to purchases that have not yet been finished, consumed or acknowledged. Returns a React Native `EmitterSubscription` on which you can call `.remove()` to stop receiving updates. Register you listener as soon as possible and react to updates at all times.
19
+
20
+ ## Signature
21
+
22
+ ```ts
23
+ purchaseUpdatedListener((purchase: Purchase) => {});
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ```tsx
29
+ import React, {useEffect} from 'react';
30
+ import {View} from 'react-native';
31
+ import {purchaseUpdatedListener} from 'react-native-iap';
32
+
33
+ const App = () => {
34
+ useEffect(() => {
35
+ const subscription = purchaseUpdatedListener((purchase: Purchase) => {
36
+ console.log(purchase);
37
+ });
38
+
39
+ return () => {
40
+ subscription.remove();
41
+ };
42
+ }, []);
43
+
44
+ return <View />;
45
+ };
46
+ ```
18
47
  */
19
48
  const purchaseUpdatedListener = listener => {
20
49
  const eventEmitter = new _reactNative.NativeEventEmitter((0, _internal.getNativeModule)());
@@ -31,6 +60,36 @@ const purchaseUpdatedListener = listener => {
31
60
  };
32
61
  /**
33
62
  * Add IAP purchase error event
63
+ * Register a callback that gets called when there has been an error with a purchase. Returns a React Native `EmitterSubscription` on which you can call `.remove()` to stop receiving updates.
64
+
65
+ ## Signature
66
+
67
+ ```ts
68
+ purchaseErrorListener((error: PurchaseError) => {});
69
+ ```
70
+
71
+ ## Usage
72
+
73
+ ```tsx
74
+ import React, {useEffect} from 'react';
75
+ import {View} from 'react-native';
76
+ import {purchaseErrorListener} from 'react-native-iap';
77
+
78
+ const App = () => {
79
+ useEffect(() => {
80
+ const subscription = purchaseErrorListener((error: PurchaseError) => {
81
+ console.log(error);
82
+ });
83
+
84
+ return () => {
85
+ subscription.remove();
86
+ };
87
+ }, []);
88
+
89
+ return <View />;
90
+ };
91
+ ```
92
+
34
93
  */
35
94
 
36
95
 
@@ -42,6 +101,36 @@ const purchaseErrorListener = listener => {
42
101
  };
43
102
  /**
44
103
  * Add IAP promoted subscription event
104
+ * Add IAP promoted subscription event.
105
+
106
+ ## Signature
107
+
108
+ ```ts
109
+ promotedProductListener((productId?: string) => {});
110
+ ```
111
+
112
+ ## Usage
113
+
114
+ ```tsx
115
+ import React, {useEffect} from 'react';
116
+ import {View} from 'react-native';
117
+ import {promotedProductListener} from 'react-native-iap';
118
+
119
+ const App = () => {
120
+ useEffect(() => {
121
+ const subscription = promotedProductListener((productId) => {
122
+ console.log(productId);
123
+ });
124
+
125
+ return () => {
126
+ subscription.remove();
127
+ };
128
+ }, []);
129
+
130
+ return <View />;
131
+ };
132
+ ```
133
+
45
134
  *
46
135
  * @platform iOS
47
136
  */
@@ -50,13 +139,67 @@ const purchaseErrorListener = listener => {
50
139
  exports.purchaseErrorListener = purchaseErrorListener;
51
140
 
52
141
  const promotedProductListener = listener => {
53
- if (_internal.isIos) {
142
+ if (_internal.isIos && !(0, _iap.isIosStorekit2)()) {
54
143
  const eventEmitter = new _reactNative.NativeEventEmitter((0, _internal.getIosModule)());
55
144
  return eventEmitter.addListener('iap-promoted-product', listener);
56
145
  }
57
146
 
58
147
  return null;
59
148
  };
149
+ /**
150
+ * Updated transactions for iOS Sk2
151
+ * Register a callback that gets called when the store has any updates to transactions related to purchases that have not yet been finished, consumed or acknowledged.
152
+ * Returns a React Native `EmitterSubscription` on which you can call `.remove()` to stop receiving updates. Register you listener as soon as possible and react to updates at all times.
153
+
154
+ **Warning**
155
+ This is only available for iOS 15 and higher and Storekit 2 is activated
156
+
157
+ ## Signature
158
+
159
+ ```ts
160
+ purchaseUpdatedListener((transactionOrError: TransactionOrError) => {});
161
+ ```
162
+
163
+ ## Usage
164
+
165
+ ```tsx
166
+ import React, {useEffect} from 'react';
167
+ import {View} from 'react-native';
168
+ import {purchaseUpdatedListener} from 'react-native-iap';
169
+
170
+ const App = () => {
171
+ useEffect(() => {
172
+ const subscription = purchaseUpdatedListener((transactionOrError: TransactionOrError) => {
173
+ if(transactionOrError.transaction){
174
+ console.log("There's an update to a transaction", transactionOrError.transaction);
175
+ }else{
176
+ console.log("There's been an error with a received transaction")
177
+ }
178
+ });
179
+
180
+ return () => {
181
+ subscription.remove();
182
+ };
183
+ }, []);
184
+
185
+ return <View />;
186
+ };
187
+ ```
188
+ *
189
+ * @platform iOS (Sk2)
190
+ */
191
+
60
192
 
61
193
  exports.promotedProductListener = promotedProductListener;
194
+
195
+ const transactionListener = listener => {
196
+ if (_internal.isIos && (0, _iap.isIosStorekit2)()) {
197
+ const eventEmitter = new _reactNative.NativeEventEmitter((0, _internal.getIosModule)());
198
+ return eventEmitter.addListener('iap-transaction-updated', listener);
199
+ }
200
+
201
+ return null;
202
+ };
203
+
204
+ exports.transactionListener = transactionListener;
62
205
  //# sourceMappingURL=eventEmitter.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["purchaseUpdatedListener","listener","eventEmitter","NativeEventEmitter","getNativeModule","proxyListener","isIosStorekit2","event","transactionSk2Map","emitterSubscription","addListener","isAndroid","getAndroidModule","startListening","purchaseErrorListener","promotedProductListener","isIos","getIosModule"],"sources":["eventEmitter.ts"],"sourcesContent":["import {EmitterSubscription, NativeEventEmitter} from 'react-native';\n\nimport {transactionSk2Map} from './types/appleSk2';\nimport {isIosStorekit2} from './iap';\nimport {\n getAndroidModule,\n getIosModule,\n getNativeModule,\n isAndroid,\n isIos,\n} from './internal';\nimport type {PurchaseError} from './purchaseError';\nimport type {Purchase} from './types';\n\n/**\n * Add IAP purchase event\n */\nexport const purchaseUpdatedListener = (\n listener: (event: Purchase) => void,\n) => {\n const eventEmitter = new NativeEventEmitter(getNativeModule());\n const proxyListener = isIosStorekit2()\n ? (event: Purchase) => {\n listener(transactionSk2Map(event as any));\n }\n : listener;\n const emitterSubscription = eventEmitter.addListener(\n 'purchase-updated',\n proxyListener,\n );\n\n if (isAndroid) {\n getAndroidModule().startListening();\n }\n\n return emitterSubscription;\n};\n\n/**\n * Add IAP purchase error event\n */\nexport const purchaseErrorListener = (\n listener: (error: PurchaseError) => void,\n): EmitterSubscription => {\n const eventEmitter = new NativeEventEmitter(getNativeModule());\n return eventEmitter.addListener('purchase-error', listener);\n};\n\n/**\n * Add IAP promoted subscription event\n *\n * @platform iOS\n */\nexport const promotedProductListener = (listener: () => void) => {\n if (isIos) {\n const eventEmitter = new NativeEventEmitter(getIosModule());\n return eventEmitter.addListener('iap-promoted-product', listener);\n }\n\n return null;\n};\n"],"mappings":";;;;;;;AAAA;;AAEA;;AACA;;AACA;;AAUA;AACA;AACA;AACO,MAAMA,uBAAuB,GAClCC,QADqC,IAElC;EACH,MAAMC,YAAY,GAAG,IAAIC,+BAAJ,CAAuB,IAAAC,yBAAA,GAAvB,CAArB;EACA,MAAMC,aAAa,GAAG,IAAAC,mBAAA,MACjBC,KAAD,IAAqB;IACnBN,QAAQ,CAAC,IAAAO,0BAAA,EAAkBD,KAAlB,CAAD,CAAR;EACD,CAHiB,GAIlBN,QAJJ;EAKA,MAAMQ,mBAAmB,GAAGP,YAAY,CAACQ,WAAb,CAC1B,kBAD0B,EAE1BL,aAF0B,CAA5B;;EAKA,IAAIM,mBAAJ,EAAe;IACb,IAAAC,0BAAA,IAAmBC,cAAnB;EACD;;EAED,OAAOJ,mBAAP;AACD,CAnBM;AAqBP;AACA;AACA;;;;;AACO,MAAMK,qBAAqB,GAChCb,QADmC,IAEX;EACxB,MAAMC,YAAY,GAAG,IAAIC,+BAAJ,CAAuB,IAAAC,yBAAA,GAAvB,CAArB;EACA,OAAOF,YAAY,CAACQ,WAAb,CAAyB,gBAAzB,EAA2CT,QAA3C,CAAP;AACD,CALM;AAOP;AACA;AACA;AACA;AACA;;;;;AACO,MAAMc,uBAAuB,GAAId,QAAD,IAA0B;EAC/D,IAAIe,eAAJ,EAAW;IACT,MAAMd,YAAY,GAAG,IAAIC,+BAAJ,CAAuB,IAAAc,sBAAA,GAAvB,CAArB;IACA,OAAOf,YAAY,CAACQ,WAAb,CAAyB,sBAAzB,EAAiDT,QAAjD,CAAP;EACD;;EAED,OAAO,IAAP;AACD,CAPM"}
1
+ {"version":3,"names":["purchaseUpdatedListener","listener","eventEmitter","NativeEventEmitter","getNativeModule","proxyListener","isIosStorekit2","event","transactionSk2Map","emitterSubscription","addListener","isAndroid","getAndroidModule","startListening","purchaseErrorListener","promotedProductListener","isIos","getIosModule","transactionListener"],"sources":["eventEmitter.ts"],"sourcesContent":["import {EmitterSubscription, NativeEventEmitter} from 'react-native';\n\nimport {TransactionEvent, transactionSk2Map} from './types/appleSk2';\nimport {isIosStorekit2} from './iap';\nimport {\n getAndroidModule,\n getIosModule,\n getNativeModule,\n isAndroid,\n isIos,\n} from './internal';\nimport type {PurchaseError} from './purchaseError';\nimport type {Purchase} from './types';\n\n/**\n * Add IAP purchase event\n * Register a callback that gets called when the store has any updates to purchases that have not yet been finished, consumed or acknowledged. Returns a React Native `EmitterSubscription` on which you can call `.remove()` to stop receiving updates. Register you listener as soon as possible and react to updates at all times.\n\n## Signature\n\n```ts\npurchaseUpdatedListener((purchase: Purchase) => {});\n```\n\n## Usage\n\n```tsx\nimport React, {useEffect} from 'react';\nimport {View} from 'react-native';\nimport {purchaseUpdatedListener} from 'react-native-iap';\n\nconst App = () => {\n useEffect(() => {\n const subscription = purchaseUpdatedListener((purchase: Purchase) => {\n console.log(purchase);\n });\n\n return () => {\n subscription.remove();\n };\n }, []);\n\n return <View />;\n};\n```\n */\nexport const purchaseUpdatedListener = (\n listener: (event: Purchase) => void,\n) => {\n const eventEmitter = new NativeEventEmitter(getNativeModule());\n const proxyListener = isIosStorekit2()\n ? (event: Purchase) => {\n listener(transactionSk2Map(event as any));\n }\n : listener;\n const emitterSubscription = eventEmitter.addListener(\n 'purchase-updated',\n proxyListener,\n );\n\n if (isAndroid) {\n getAndroidModule().startListening();\n }\n\n return emitterSubscription;\n};\n\n/**\n * Add IAP purchase error event\n * Register a callback that gets called when there has been an error with a purchase. Returns a React Native `EmitterSubscription` on which you can call `.remove()` to stop receiving updates.\n\n## Signature\n\n```ts\npurchaseErrorListener((error: PurchaseError) => {});\n```\n\n## Usage\n\n```tsx\nimport React, {useEffect} from 'react';\nimport {View} from 'react-native';\nimport {purchaseErrorListener} from 'react-native-iap';\n\nconst App = () => {\n useEffect(() => {\n const subscription = purchaseErrorListener((error: PurchaseError) => {\n console.log(error);\n });\n\n return () => {\n subscription.remove();\n };\n }, []);\n\n return <View />;\n};\n```\n\n */\nexport const purchaseErrorListener = (\n listener: (error: PurchaseError) => void,\n): EmitterSubscription => {\n const eventEmitter = new NativeEventEmitter(getNativeModule());\n return eventEmitter.addListener('purchase-error', listener);\n};\n\n/**\n * Add IAP promoted subscription event\n * Add IAP promoted subscription event.\n\n## Signature\n\n```ts\npromotedProductListener((productId?: string) => {});\n```\n\n## Usage\n\n```tsx\nimport React, {useEffect} from 'react';\nimport {View} from 'react-native';\nimport {promotedProductListener} from 'react-native-iap';\n\nconst App = () => {\n useEffect(() => {\n const subscription = promotedProductListener((productId) => {\n console.log(productId);\n });\n\n return () => {\n subscription.remove();\n };\n }, []);\n\n return <View />;\n};\n```\n\n *\n * @platform iOS\n */\nexport const promotedProductListener = (listener: () => void) => {\n if (isIos && !isIosStorekit2()) {\n const eventEmitter = new NativeEventEmitter(getIosModule());\n return eventEmitter.addListener('iap-promoted-product', listener);\n }\n\n return null;\n};\n\n/**\n * Updated transactions for iOS Sk2\n * Register a callback that gets called when the store has any updates to transactions related to purchases that have not yet been finished, consumed or acknowledged. \n * Returns a React Native `EmitterSubscription` on which you can call `.remove()` to stop receiving updates. Register you listener as soon as possible and react to updates at all times.\n\n**Warning**\nThis is only available for iOS 15 and higher and Storekit 2 is activated\n\n## Signature\n\n```ts\npurchaseUpdatedListener((transactionOrError: TransactionOrError) => {});\n```\n\n## Usage\n\n```tsx\nimport React, {useEffect} from 'react';\nimport {View} from 'react-native';\nimport {purchaseUpdatedListener} from 'react-native-iap';\n\nconst App = () => {\n useEffect(() => {\n const subscription = purchaseUpdatedListener((transactionOrError: TransactionOrError) => {\n if(transactionOrError.transaction){\n console.log(\"There's an update to a transaction\", transactionOrError.transaction);\n }else{\n console.log(\"There's been an error with a received transaction\")\n }\n });\n\n return () => {\n subscription.remove();\n };\n }, []);\n\n return <View />;\n};\n```\n *\n * @platform iOS (Sk2)\n */\nexport const transactionListener = (\n listener: (event: TransactionEvent) => void,\n) => {\n if (isIos && isIosStorekit2()) {\n const eventEmitter = new NativeEventEmitter(getIosModule());\n return eventEmitter.addListener('iap-transaction-updated', listener);\n }\n\n return null;\n};\n"],"mappings":";;;;;;;AAAA;;AAEA;;AACA;;AACA;;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMA,uBAAuB,GAClCC,QADqC,IAElC;EACH,MAAMC,YAAY,GAAG,IAAIC,+BAAJ,CAAuB,IAAAC,yBAAA,GAAvB,CAArB;EACA,MAAMC,aAAa,GAAG,IAAAC,mBAAA,MACjBC,KAAD,IAAqB;IACnBN,QAAQ,CAAC,IAAAO,0BAAA,EAAkBD,KAAlB,CAAD,CAAR;EACD,CAHiB,GAIlBN,QAJJ;EAKA,MAAMQ,mBAAmB,GAAGP,YAAY,CAACQ,WAAb,CAC1B,kBAD0B,EAE1BL,aAF0B,CAA5B;;EAKA,IAAIM,mBAAJ,EAAe;IACb,IAAAC,0BAAA,IAAmBC,cAAnB;EACD;;EAED,OAAOJ,mBAAP;AACD,CAnBM;AAqBP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AACO,MAAMK,qBAAqB,GAChCb,QADmC,IAEX;EACxB,MAAMC,YAAY,GAAG,IAAIC,+BAAJ,CAAuB,IAAAC,yBAAA,GAAvB,CAArB;EACA,OAAOF,YAAY,CAACQ,WAAb,CAAyB,gBAAzB,EAA2CT,QAA3C,CAAP;AACD,CALM;AAOP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AACO,MAAMc,uBAAuB,GAAId,QAAD,IAA0B;EAC/D,IAAIe,eAAA,IAAS,CAAC,IAAAV,mBAAA,GAAd,EAAgC;IAC9B,MAAMJ,YAAY,GAAG,IAAIC,+BAAJ,CAAuB,IAAAc,sBAAA,GAAvB,CAArB;IACA,OAAOf,YAAY,CAACQ,WAAb,CAAyB,sBAAzB,EAAiDT,QAAjD,CAAP;EACD;;EAED,OAAO,IAAP;AACD,CAPM;AASP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AACO,MAAMiB,mBAAmB,GAC9BjB,QADiC,IAE9B;EACH,IAAIe,eAAA,IAAS,IAAAV,mBAAA,GAAb,EAA+B;IAC7B,MAAMJ,YAAY,GAAG,IAAIC,+BAAJ,CAAuB,IAAAc,sBAAA,GAAvB,CAArB;IACA,OAAOf,YAAY,CAACQ,WAAb,CAAyB,yBAAzB,EAAoDT,QAApD,CAAP;EACD;;EAED,OAAO,IAAP;AACD,CATM"}
@@ -38,6 +38,7 @@ function withIAPContext(Component) {
38
38
  const [purchaseHistory, setPurchaseHistory] = (0, _react.useState)([]);
39
39
  const [availablePurchases, setAvailablePurchases] = (0, _react.useState)([]);
40
40
  const [currentPurchase, setCurrentPurchase] = (0, _react.useState)();
41
+ const [currentTransaction, setCurrentTransaction] = (0, _react.useState)();
41
42
  const [currentPurchaseError, setCurrentPurchaseError] = (0, _react.useState)();
42
43
  const [initConnectionError, setInitConnectionError] = (0, _react.useState)();
43
44
  const context = (0, _react.useMemo)(() => ({
@@ -48,6 +49,7 @@ function withIAPContext(Component) {
48
49
  purchaseHistory,
49
50
  availablePurchases,
50
51
  currentPurchase,
52
+ currentTransaction,
51
53
  currentPurchaseError,
52
54
  initConnectionError,
53
55
  setProducts,
@@ -56,7 +58,7 @@ function withIAPContext(Component) {
56
58
  setAvailablePurchases,
57
59
  setCurrentPurchase,
58
60
  setCurrentPurchaseError
59
- }), [connected, products, subscriptions, promotedProductsIOS, purchaseHistory, availablePurchases, currentPurchase, currentPurchaseError, initConnectionError, setProducts, setSubscriptions, setPurchaseHistory, setAvailablePurchases, setCurrentPurchase, setCurrentPurchaseError]);
61
+ }), [connected, products, subscriptions, promotedProductsIOS, purchaseHistory, availablePurchases, currentPurchase, currentTransaction, currentPurchaseError, initConnectionError, setProducts, setSubscriptions, setPurchaseHistory, setAvailablePurchases, setCurrentPurchase, setCurrentPurchaseError]);
60
62
  (0, _react.useEffect)(() => {
61
63
  (0, _iap.initConnection)().then(value => {
62
64
  setInitConnectionError(undefined);
@@ -72,6 +74,10 @@ function withIAPContext(Component) {
72
74
  setCurrentPurchaseError(undefined);
73
75
  setCurrentPurchase(purchase);
74
76
  });
77
+ const transactionUpdateSubscription = (0, _eventEmitter.transactionListener)(async transactionOrError => {
78
+ setCurrentPurchaseError(transactionOrError === null || transactionOrError === void 0 ? void 0 : transactionOrError.error);
79
+ setCurrentTransaction(transactionOrError === null || transactionOrError === void 0 ? void 0 : transactionOrError.transaction);
80
+ });
75
81
  const purchaseErrorSubscription = (0, _eventEmitter.purchaseErrorListener)(error => {
76
82
  setCurrentPurchase(undefined);
77
83
  setCurrentPurchaseError(error);
@@ -84,6 +90,7 @@ function withIAPContext(Component) {
84
90
  purchaseUpdateSubscription.remove();
85
91
  purchaseErrorSubscription.remove();
86
92
  promotedProductSubscription === null || promotedProductSubscription === void 0 ? void 0 : promotedProductSubscription.remove();
93
+ transactionUpdateSubscription === null || transactionUpdateSubscription === void 0 ? void 0 : transactionUpdateSubscription.remove();
87
94
  };
88
95
  }, [connected]);
89
96
  return /*#__PURE__*/_react.default.createElement(IAPContext.Provider, {
@@ -1 +1 @@
1
- {"version":3,"names":["IAPContext","React","createContext","useIAPContext","ctx","useContext","Error","withIAPContext","Component","WrapperComponent","props","connected","setConnected","useState","products","setProducts","promotedProductsIOS","setPromotedProductsIOS","subscriptions","setSubscriptions","purchaseHistory","setPurchaseHistory","availablePurchases","setAvailablePurchases","currentPurchase","setCurrentPurchase","currentPurchaseError","setCurrentPurchaseError","initConnectionError","setInitConnectionError","context","useMemo","useEffect","initConnection","then","value","undefined","catch","purchaseUpdateSubscription","purchaseUpdatedListener","purchase","purchaseErrorSubscription","purchaseErrorListener","error","promotedProductSubscription","promotedProductListener","product","IapIos","getPromotedProductIOS","prevProducts","remove"],"sources":["withIAPContext.tsx"],"sourcesContent":["import React, {useContext, useEffect, useMemo, useState} from 'react';\n\nimport {\n promotedProductListener,\n purchaseErrorListener,\n purchaseUpdatedListener,\n} from '../eventEmitter';\nimport {IapIos, initConnection} from '../iap';\nimport type {PurchaseError} from '../purchaseError';\nimport type {\n Product,\n ProductPurchase,\n Purchase,\n Subscription,\n SubscriptionPurchase,\n} from '../types';\n\ntype IAPContextType = {\n connected: boolean;\n products: Product[];\n promotedProductsIOS: Product[];\n subscriptions: Subscription[];\n purchaseHistory: Purchase[];\n availablePurchases: Purchase[];\n currentPurchase?: Purchase;\n currentPurchaseError?: PurchaseError;\n initConnectionError?: Error;\n setProducts: (products: Product[]) => void;\n setSubscriptions: (subscriptions: Subscription[]) => void;\n setPurchaseHistory: (purchaseHistory: Purchase[]) => void;\n setAvailablePurchases: (availablePurchases: Purchase[]) => void;\n setCurrentPurchase: (currentPurchase: Purchase | undefined) => void;\n setCurrentPurchaseError: (\n currentPurchaseError: PurchaseError | undefined,\n ) => void;\n};\n\n// @ts-ignore\nconst IAPContext = React.createContext<IAPContextType>(null);\n\nexport function useIAPContext(): IAPContextType {\n const ctx = useContext(IAPContext);\n\n if (!ctx) {\n throw new Error('You need wrap your app with withIAPContext HOC');\n }\n\n return ctx;\n}\n\nexport function withIAPContext<T>(Component: React.ComponentType<T>) {\n return function WrapperComponent(props: T) {\n const [connected, setConnected] = useState(false);\n const [products, setProducts] = useState<Product[]>([]);\n\n const [promotedProductsIOS, setPromotedProductsIOS] = useState<Product[]>(\n [],\n );\n const [subscriptions, setSubscriptions] = useState<Subscription[]>([]);\n const [purchaseHistory, setPurchaseHistory] = useState<Purchase[]>([]);\n\n const [availablePurchases, setAvailablePurchases] = useState<Purchase[]>(\n [],\n );\n const [currentPurchase, setCurrentPurchase] = useState<Purchase>();\n\n const [currentPurchaseError, setCurrentPurchaseError] =\n useState<PurchaseError>();\n\n const [initConnectionError, setInitConnectionError] = useState<Error>();\n\n const context = useMemo(\n () => ({\n connected,\n products,\n subscriptions,\n promotedProductsIOS,\n purchaseHistory,\n availablePurchases,\n currentPurchase,\n currentPurchaseError,\n initConnectionError,\n setProducts,\n setSubscriptions,\n setPurchaseHistory,\n setAvailablePurchases,\n setCurrentPurchase,\n setCurrentPurchaseError,\n }),\n [\n connected,\n products,\n subscriptions,\n promotedProductsIOS,\n purchaseHistory,\n availablePurchases,\n currentPurchase,\n currentPurchaseError,\n initConnectionError,\n setProducts,\n setSubscriptions,\n setPurchaseHistory,\n setAvailablePurchases,\n setCurrentPurchase,\n setCurrentPurchaseError,\n ],\n );\n\n useEffect(() => {\n initConnection()\n .then((value) => {\n setInitConnectionError(undefined);\n setConnected(value);\n })\n .catch(setInitConnectionError);\n }, []);\n\n useEffect(() => {\n if (!connected) {\n return;\n }\n\n const purchaseUpdateSubscription = purchaseUpdatedListener(\n async (purchase: ProductPurchase | SubscriptionPurchase) => {\n setCurrentPurchaseError(undefined);\n setCurrentPurchase(purchase);\n },\n );\n\n const purchaseErrorSubscription = purchaseErrorListener(\n (error: PurchaseError) => {\n setCurrentPurchase(undefined);\n setCurrentPurchaseError(error);\n },\n );\n\n const promotedProductSubscription = promotedProductListener(async () => {\n const product = await IapIos.getPromotedProductIOS();\n\n setPromotedProductsIOS((prevProducts) => [\n ...prevProducts,\n ...(product ? [product] : []),\n ]);\n });\n\n return () => {\n purchaseUpdateSubscription.remove();\n purchaseErrorSubscription.remove();\n promotedProductSubscription?.remove();\n };\n }, [connected]);\n\n return (\n <IAPContext.Provider value={context}>\n <Component {...props} />\n </IAPContext.Provider>\n );\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["IAPContext","React","createContext","useIAPContext","ctx","useContext","Error","withIAPContext","Component","WrapperComponent","props","connected","setConnected","useState","products","setProducts","promotedProductsIOS","setPromotedProductsIOS","subscriptions","setSubscriptions","purchaseHistory","setPurchaseHistory","availablePurchases","setAvailablePurchases","currentPurchase","setCurrentPurchase","currentTransaction","setCurrentTransaction","currentPurchaseError","setCurrentPurchaseError","initConnectionError","setInitConnectionError","context","useMemo","useEffect","initConnection","then","value","undefined","catch","purchaseUpdateSubscription","purchaseUpdatedListener","purchase","transactionUpdateSubscription","transactionListener","transactionOrError","error","transaction","purchaseErrorSubscription","purchaseErrorListener","promotedProductSubscription","promotedProductListener","product","IapIos","getPromotedProductIOS","prevProducts","remove"],"sources":["withIAPContext.tsx"],"sourcesContent":["import React, {useContext, useEffect, useMemo, useState} from 'react';\n\nimport {\n promotedProductListener,\n purchaseErrorListener,\n purchaseUpdatedListener,\n transactionListener,\n} from '../eventEmitter';\nimport {IapIos, initConnection} from '../iap';\nimport type {PurchaseError} from '../purchaseError';\nimport type {\n Product,\n ProductPurchase,\n Purchase,\n Subscription,\n SubscriptionPurchase,\n} from '../types';\nimport type {TransactionEvent, TransactionSk2} from '../types/appleSk2';\n\ntype IAPContextType = {\n connected: boolean;\n products: Product[];\n promotedProductsIOS: Product[];\n subscriptions: Subscription[];\n purchaseHistory: Purchase[];\n availablePurchases: Purchase[];\n currentPurchase?: Purchase;\n currentTransaction?: TransactionSk2;\n currentPurchaseError?: PurchaseError;\n initConnectionError?: Error;\n setProducts: (products: Product[]) => void;\n setSubscriptions: (subscriptions: Subscription[]) => void;\n setPurchaseHistory: (purchaseHistory: Purchase[]) => void;\n setAvailablePurchases: (availablePurchases: Purchase[]) => void;\n setCurrentPurchase: (currentPurchase: Purchase | undefined) => void;\n setCurrentPurchaseError: (\n currentPurchaseError: PurchaseError | undefined,\n ) => void;\n};\n\n// @ts-ignore\nconst IAPContext = React.createContext<IAPContextType>(null);\n\nexport function useIAPContext(): IAPContextType {\n const ctx = useContext(IAPContext);\n\n if (!ctx) {\n throw new Error('You need wrap your app with withIAPContext HOC');\n }\n\n return ctx;\n}\n\nexport function withIAPContext<T>(Component: React.ComponentType<T>) {\n return function WrapperComponent(props: T) {\n const [connected, setConnected] = useState(false);\n const [products, setProducts] = useState<Product[]>([]);\n\n const [promotedProductsIOS, setPromotedProductsIOS] = useState<Product[]>(\n [],\n );\n const [subscriptions, setSubscriptions] = useState<Subscription[]>([]);\n const [purchaseHistory, setPurchaseHistory] = useState<Purchase[]>([]);\n\n const [availablePurchases, setAvailablePurchases] = useState<Purchase[]>(\n [],\n );\n const [currentPurchase, setCurrentPurchase] = useState<Purchase>();\n const [currentTransaction, setCurrentTransaction] =\n useState<TransactionSk2>();\n\n const [currentPurchaseError, setCurrentPurchaseError] =\n useState<PurchaseError>();\n\n const [initConnectionError, setInitConnectionError] = useState<Error>();\n\n const context = useMemo(\n () => ({\n connected,\n products,\n subscriptions,\n promotedProductsIOS,\n purchaseHistory,\n availablePurchases,\n currentPurchase,\n currentTransaction,\n currentPurchaseError,\n initConnectionError,\n setProducts,\n setSubscriptions,\n setPurchaseHistory,\n setAvailablePurchases,\n setCurrentPurchase,\n setCurrentPurchaseError,\n }),\n [\n connected,\n products,\n subscriptions,\n promotedProductsIOS,\n purchaseHistory,\n availablePurchases,\n currentPurchase,\n currentTransaction,\n currentPurchaseError,\n initConnectionError,\n setProducts,\n setSubscriptions,\n setPurchaseHistory,\n setAvailablePurchases,\n setCurrentPurchase,\n setCurrentPurchaseError,\n ],\n );\n\n useEffect(() => {\n initConnection()\n .then((value) => {\n setInitConnectionError(undefined);\n setConnected(value);\n })\n .catch(setInitConnectionError);\n }, []);\n\n useEffect(() => {\n if (!connected) {\n return;\n }\n\n const purchaseUpdateSubscription = purchaseUpdatedListener(\n async (purchase: ProductPurchase | SubscriptionPurchase) => {\n setCurrentPurchaseError(undefined);\n setCurrentPurchase(purchase);\n },\n );\n\n const transactionUpdateSubscription = transactionListener(\n async (transactionOrError: TransactionEvent) => {\n setCurrentPurchaseError(transactionOrError?.error);\n setCurrentTransaction(transactionOrError?.transaction);\n },\n );\n\n const purchaseErrorSubscription = purchaseErrorListener(\n (error: PurchaseError) => {\n setCurrentPurchase(undefined);\n setCurrentPurchaseError(error);\n },\n );\n\n const promotedProductSubscription = promotedProductListener(async () => {\n const product = await IapIos.getPromotedProductIOS();\n\n setPromotedProductsIOS((prevProducts) => [\n ...prevProducts,\n ...(product ? [product] : []),\n ]);\n });\n\n return () => {\n purchaseUpdateSubscription.remove();\n purchaseErrorSubscription.remove();\n promotedProductSubscription?.remove();\n transactionUpdateSubscription?.remove();\n };\n }, [connected]);\n\n return (\n <IAPContext.Provider value={context}>\n <Component {...props} />\n </IAPContext.Provider>\n );\n };\n}\n"],"mappings":"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"}