@circle-fin/w3s-pw-react-native-sdk 0.0.175 → 1.0.0

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 (61) hide show
  1. package/LICENSE.md +4 -17
  2. package/android/build.gradle +137 -0
  3. package/android/gradle.properties +19 -0
  4. package/android/src/main/AndroidManifest.xml +21 -0
  5. package/android/src/main/AndroidManifestNew.xml +20 -0
  6. package/android/src/main/java/com/circlefin/programmablewalletrnsdk/BridgeHelper.kt +388 -0
  7. package/android/src/main/java/com/circlefin/programmablewalletrnsdk/ProgrammablewalletRnSdkModule.kt +226 -0
  8. package/android/src/main/java/com/circlefin/programmablewalletrnsdk/ProgrammablewalletRnSdkPackage.kt +47 -0
  9. package/android/src/main/java/com/circlefin/programmablewalletrnsdk/PromiseCallback.kt +87 -0
  10. package/android/src/main/java/com/circlefin/programmablewalletrnsdk/TestHelper.kt +35 -0
  11. package/android/src/main/java/com/circlefin/programmablewalletrnsdk/pwcustom/RnImageSetter.kt +40 -0
  12. package/android/src/main/java/com/circlefin/programmablewalletrnsdk/pwcustom/RnLayoutProvider.kt +86 -0
  13. package/android/src/main/java/com/circlefin/programmablewalletrnsdk/pwcustom/RnViewSetterProvider.kt +75 -0
  14. package/android/src/newarch/ProgrammablewalletRnSdkSpec.kt +27 -0
  15. package/android/src/oldarch/ProgrammablewalletRnSdkSpec.kt +65 -0
  16. package/circlefin-w3s-pw-react-native-sdk.podspec +41 -0
  17. package/ios/Array+Extension.swift +25 -0
  18. package/ios/BridgeHelper.swift +183 -0
  19. package/ios/EventEmitter.swift +47 -0
  20. package/ios/ProgrammablewalletRnSdk.h +27 -0
  21. package/ios/ProgrammablewalletRnSdk.mm +144 -0
  22. package/ios/ReactNativeEventEmitter.m +25 -0
  23. package/ios/ReactNativeEventEmitter.swift +34 -0
  24. package/ios/RnWalletSdk+CustomizeAdapter.swift +367 -0
  25. package/ios/RnWalletSdk.swift +330 -0
  26. package/ios/TextConfig.swift +26 -0
  27. package/ios/TextKey.swift +102 -0
  28. package/ios/UIApplication+Extension.swift +38 -0
  29. package/ios/UIColor+Extension.swift +97 -0
  30. package/ios/UIView+Extension.swift +59 -0
  31. package/ios/programmablewallet-rn-sdk-Bridging-Header.h +20 -0
  32. package/lib/commonjs/NativeProgrammablewalletRnSdk.js +13 -0
  33. package/lib/commonjs/NativeProgrammablewalletRnSdk.js.map +1 -1
  34. package/lib/commonjs/ProgrammablewalletRnSdkModule.js +14 -0
  35. package/lib/commonjs/ProgrammablewalletRnSdkModule.js.map +1 -1
  36. package/lib/commonjs/WalletSdk.js +14 -0
  37. package/lib/commonjs/WalletSdk.js.map +1 -1
  38. package/lib/commonjs/index.js.map +1 -1
  39. package/lib/commonjs/types.js +13 -0
  40. package/lib/commonjs/types.js.map +1 -1
  41. package/lib/module/NativeProgrammablewalletRnSdk.js +14 -0
  42. package/lib/module/NativeProgrammablewalletRnSdk.js.map +1 -1
  43. package/lib/module/ProgrammablewalletRnSdkModule.js +13 -0
  44. package/lib/module/ProgrammablewalletRnSdkModule.js.map +1 -1
  45. package/lib/module/WalletSdk.js +13 -0
  46. package/lib/module/WalletSdk.js.map +1 -1
  47. package/lib/module/index.js +13 -0
  48. package/lib/module/index.js.map +1 -1
  49. package/lib/module/types.js +14 -0
  50. package/lib/module/types.js.map +1 -1
  51. package/lib/typescript/src/NativeProgrammablewalletRnSdk.d.ts.map +1 -1
  52. package/lib/typescript/src/ProgrammablewalletRnSdkModule.d.ts.map +1 -1
  53. package/lib/typescript/src/WalletSdk.d.ts.map +1 -1
  54. package/lib/typescript/src/index.d.ts.map +1 -1
  55. package/lib/typescript/src/types.d.ts.map +1 -1
  56. package/package.json +18 -9
  57. package/src/NativeProgrammablewalletRnSdk.ts +13 -0
  58. package/src/ProgrammablewalletRnSdkModule.ts +13 -0
  59. package/src/WalletSdk.ts +13 -0
  60. package/src/index.tsx +13 -0
  61. package/src/types.ts +13 -0
@@ -0,0 +1,367 @@
1
+ // Copyright (c) 2024, Circle Technologies, LLC. All rights reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ import Foundation
16
+ import CircleProgrammableWalletSDK
17
+
18
+ extension RNWalletSdk {
19
+
20
+ func customizeAdapter(controller: UIViewController) {
21
+
22
+ // UI Flow - New PIN
23
+
24
+ if let controller = controller as? NewPINCodeViewController {
25
+ if let configs = sTextsMap[.newPinCodeHeadline] { // A1
26
+ for index in configs.indices {
27
+ if index == 0 {
28
+ setText(label: controller.titleLabel1, textConfig: configs[index])
29
+ } else if index == 1 {
30
+ setText(label: controller.titleLabel2, textConfig: configs[index])
31
+ }
32
+ }
33
+ }
34
+ if let textConfig = sTextMap[.circlepw_new_pincode_subhead] { // C1
35
+ setText(label: controller.subtitleLabel, textConfig: textConfig)
36
+ }
37
+ if let textConfig = sTextMap[.circlepw_pincode_error_config] { // C5
38
+ setText(label: controller.errorMessageLabel, textConfig: textConfig, shouldReplaceText: false)
39
+ }
40
+ }
41
+
42
+ if let controller = controller as? ConfirmPINCodeViewController {
43
+ if let textConfig = sTextMap[.circlepw_confirm_pincode_headline] { // C6
44
+ setText(label: controller.titleLabel1, textConfig: textConfig)
45
+ }
46
+ if let textConfig = sTextMap[.circlepw_confirm_pincode_subhead] { // C7
47
+ setText(label: controller.subtitleLabel, textConfig: textConfig)
48
+ }
49
+ if let textConfig = sTextMap[.circlepw_pincode_error_config] { // C5
50
+ setText(label: controller.errorMessageLabel, textConfig: textConfig, shouldReplaceText: false)
51
+ }
52
+ }
53
+
54
+ if let controller = controller as? SecurityIntrosViewController {
55
+ if let configs = sTextsMap[.securityIntroHeadline] { // A3
56
+ for index in configs.indices {
57
+ if index == 0 {
58
+ setText(label: controller.titleLabel1, textConfig: configs[index])
59
+ } else if index == 1 {
60
+ setText(label: controller.titleLabel2, textConfig: configs[index])
61
+ }
62
+ }
63
+ }
64
+ if let textConfig = sTextMap[.circlepw_security_intros_description] { // C10
65
+ setText(label: controller.introDescLabel, textConfig: textConfig)
66
+ }
67
+ if let configs = sTextsMap[.securityIntroLink] { // A4
68
+ for index in configs.indices {
69
+ if index == 0 {
70
+ setText(button: controller.introLinkButton, textConfig: configs[index])
71
+ } else if index == 1, let urlString = configs[index].text {
72
+ controller.introURL = URL(string: urlString)
73
+ }
74
+ }
75
+ }
76
+ if let textConfig = sTextMap[.circlepw_continue] { // C11
77
+ setText(button: controller.continueButton, textConfig: textConfig)
78
+ }
79
+ }
80
+
81
+ if let controller = controller as? SecurityQuestionsViewController {
82
+ if let textConfig = sTextMap[.circlepw_security_questions_title] { // C12
83
+ setText(label: controller.baseNaviTitleLabel, textConfig: textConfig)
84
+ }
85
+
86
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
87
+ for (i, cell) in controller.tableView.visibleCells.enumerated() {
88
+ guard let cell = cell as? SecurityQuestionTableViewCell else { continue }
89
+
90
+ if let configs = self.sTextsMap[.securityQuestionHeaders],
91
+ let config = configs[safe: i] { // A5
92
+ self.setText(label: cell.questionTitleLabel, textConfig: config)
93
+ }
94
+ if let textConfig = self.sTextMap[.circlepw_security_questions_required_mark] { // C13
95
+ self.setText(label: cell.questionMarkLabel, textConfig: textConfig)
96
+ self.setText(label: cell.answerMarkLabel, textConfig: textConfig)
97
+ }
98
+ if let textConfig = self.sTextMap[.circlepw_security_questions_question_placeholder],
99
+ let label = cell.questionView.subviews.first as? UILabel { // C15
100
+ self.setText(label: label, textConfig: textConfig)
101
+ }
102
+
103
+ if let textConfig = self.sTextMap[.circlepw_security_questions_answer_header] { // C16
104
+ self.setText(label: cell.answerTitleLabel, textConfig: textConfig)
105
+ }
106
+ if let textField = cell.answerStackView.arrangedSubviews.last as? UITextField {
107
+ self.setText(textField: textField,
108
+ textConfig: self.sTextMap[.circlepw_security_questions_answer_input_config], // C17
109
+ placeholderTextConfig: self.sTextMap[.circlepw_security_questions_answer_placeholder] // C18
110
+ )
111
+ }
112
+
113
+ if let textConfig = self.sTextMap[.circlepw_security_questions_answer_hint_header] { // C19
114
+ self.setText(label: cell.hintTitleLabel, textConfig: textConfig)
115
+ }
116
+ if let textField = cell.hintStackView.arrangedSubviews.first(where: { $0 is UITextField }) as? UITextField {
117
+ self.setText(textField: textField,
118
+ textConfig: self.sTextMap[.circlepw_security_questions_answer_hint_input_config], // C20
119
+ placeholderTextConfig: self.sTextMap[.circlepw_security_questions_answer_hint_placeholder] // C21
120
+ )
121
+ }
122
+ if let textConfig = self.sTextMap[.circlepw_security_questions_error_config] { // C22
123
+ self.setText(label: cell.hintWarningLabel, textConfig: textConfig, shouldReplaceText: false)
124
+ }
125
+ }
126
+ }
127
+
128
+ if let textConfig = sTextMap[.circlepw_next] { // C23
129
+ setText(button: controller.nextButton, textConfig: textConfig)
130
+ }
131
+ }
132
+
133
+ if let controller = controller as? SelectQuestionViewController {
134
+ if let textConfig = sTextMap[.circlepw_select_question_title] { // C24
135
+ setText(label: controller.baseNaviTitleLabel, textConfig: textConfig)
136
+ }
137
+
138
+ if let textConfig = sTextMap[.circlepw_select_question_item_config] { // C25
139
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
140
+ for cell in controller.tableView.visibleCells {
141
+ // TODO: make SelectQuestionTableViewCell class public from SDK
142
+ // guard let cell = cell as? SelectQuestionTableViewCell else { continue }
143
+ // setText(label: cell.titleLabel, textConfig: textConfig, shouldReplaceText: false)
144
+ }
145
+ }
146
+ }
147
+ }
148
+
149
+ if let controller = controller as? SecuritySummaryViewController {
150
+ if let textConfig = sTextMap[.circlepw_security_summary_title] { // C26
151
+ setText(label: controller.baseNaviTitleLabel, textConfig: textConfig)
152
+ }
153
+
154
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
155
+ for (i, cell) in controller.tableView.visibleCells.enumerated() {
156
+ guard let cell = cell as? SecuritySummaryTableViewCell else { continue }
157
+
158
+ if let configs = self.sTextsMap[.securitySummaryQuestionHeaders],
159
+ let config = configs[safe: i] { // A6
160
+ self.setText(label: cell.titleLabel, textConfig: config)
161
+ }
162
+
163
+ if let textConfig = self.sTextMap[.circlepw_question_label] { // C27
164
+ self.setText(label: cell.questionTitleLabel, textConfig: textConfig)
165
+ }
166
+ if let textConfig = self.sTextMap[.circlepw_answer_label] { // C29
167
+ self.setText(label: cell.answerTitleLabel, textConfig: textConfig)
168
+ }
169
+ if let textConfig = self.sTextMap[.circlepw_hint_label] { // C31
170
+ self.setText(label: cell.hintTitleLabel, textConfig: textConfig)
171
+ }
172
+ }
173
+ }
174
+
175
+ if let textConfig = sTextMap[.circlepw_continue] { // C11
176
+ setText(button: controller.continueButton, textConfig: textConfig)
177
+ }
178
+ }
179
+
180
+ if let controller = controller as? SecurityConfirmViewController {
181
+ if let textConfig = sTextMap[.circlepw_security_confirm_title] { // C33
182
+ setText(label: controller.baseNaviTitleLabel, textConfig: textConfig)
183
+ }
184
+ if let textConfig = sTextMap[.circlepw_security_confirm_headline] { // C34
185
+ setText(label: controller.tipsTitleLabel, textConfig: textConfig)
186
+ }
187
+ if let textConfig = sTextMap[.circlepw_security_confirm_input_headline] { // C35
188
+ setText(label: controller.agreeTitleLabel, textConfig: textConfig)
189
+ }
190
+ self.setText(textField: controller.agreeTextField,
191
+ textConfig: self.sTextMap[.circlepw_security_confirm_input_config], // C37
192
+ placeholderTextConfig: self.sTextMap[.circlepw_security_confirm_input_placeholder] // C36
193
+ )
194
+ if let textConfig = sTextMap[.circlepw_continue] { // C11
195
+ setText(button: controller.continueButton, textConfig: textConfig)
196
+ }
197
+ }
198
+
199
+ // UI Flow - Enter PIN
200
+
201
+ if let controller = controller as? EnterPINCodeViewController {
202
+ if let configs = sTextsMap[.enterPinCodeHeadline] { // A2
203
+ for index in configs.indices {
204
+ if index == 0 {
205
+ setText(label: controller.titleLabel1, textConfig: configs[index])
206
+ } else if index == 1 {
207
+ setText(label: controller.titleLabel2, textConfig: configs[index])
208
+ }
209
+ }
210
+ }
211
+ if let textConfig = sTextMap[.circlepw_enter_pincode_subhead] { // C8
212
+ setText(label: controller.subtitleLabel, textConfig: textConfig)
213
+ }
214
+ if let textConfig = sTextMap[.circlepw_enter_pincode_forgot_pin] { // C9
215
+ setText(button: controller.forgotPINButton, textConfig: textConfig)
216
+ }
217
+ if let textConfig = sTextMap[.circlepw_enter_pincode_use_biometrics] { // C3
218
+ setText(button: controller.biometricsButton, textConfig: textConfig)
219
+ }
220
+ if let textConfig = sTextMap[.circlepw_pincode_error_config] { // C5
221
+ setText(label: controller.errorMessageLabel, textConfig: textConfig, shouldReplaceText: false)
222
+ }
223
+ }
224
+
225
+ // UI Flow - Recover PIN
226
+
227
+ if let controller = controller as? RecoverPINCodeViewController {
228
+ if let configs = sTextsMap[.recoverPinCodeHeadline] { // A7
229
+ for index in configs.indices {
230
+ if index == 0 {
231
+ setText(label: controller.titleLabel1, textConfig: configs[index])
232
+ } else if index == 1 {
233
+ setText(label: controller.titleLabel2, textConfig: configs[index])
234
+ }
235
+ }
236
+ }
237
+
238
+ if let textConfig = self.sTextMap[.circlepw_recover_pincode_error_config] { // C38
239
+ self.setText(label: controller.errorMessageLabel, textConfig: textConfig)
240
+ }
241
+
242
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
243
+ for cell in controller.tableView.visibleCells {
244
+ guard let cell = cell as? RecoverPINCodeTableViewCell else { continue }
245
+
246
+ if let textConfig = self.sTextMap[.circlepw_recover_pincode_question_config] { // C39
247
+ if let label = cell.questionHintStackView.arrangedSubviews.first as? UILabel {
248
+ self.setText(label: label, textConfig: textConfig, shouldReplaceText: false)
249
+ }
250
+ }
251
+ if let textConfig = self.sTextMap[.circlepw_hint_tag] { // C40
252
+ self.setText(label: cell.hintTitleLabel, textConfig: textConfig)
253
+ }
254
+ if let textConfig = self.sTextMap[.circlepw_recover_pincode_answer_hint_config] { // C41
255
+ if let label = cell.hintStackView.arrangedSubviews.last as? UILabel {
256
+ self.setText(label: label, textConfig: textConfig, shouldReplaceText: false)
257
+ }
258
+ }
259
+ if let textConfig = self.sTextMap[.circlepw_recover_pincode_answer_input_header] { // C42
260
+ self.setText(label: cell.answerTitleLabel, textConfig: textConfig)
261
+ }
262
+ if let textConfig = self.sTextMap[.circlepw_security_questions_required_mark] { // C13
263
+ self.setText(label: cell.answerMarkLabel, textConfig: textConfig)
264
+ }
265
+ if let textField = cell.answerStackView.arrangedSubviews.last as? UITextField {
266
+ self.setText(textField: textField,
267
+ textConfig: self.sTextMap[.circlepw_recover_pincode_input_config], // C44
268
+ placeholderTextConfig: self.sTextMap[.circlepw_recover_pincode_answer_input_placeholder] // C43
269
+ )
270
+ }
271
+ if let textConfig = self.sTextMap[.circlepw_confirm] { // C45
272
+ self.setText(button: controller.confirmButton, textConfig: textConfig)
273
+ }
274
+ }
275
+ }
276
+ }
277
+
278
+ // UI Flow - Biometrics
279
+
280
+ if let controller = controller as? BiometricsPromptViewController {
281
+ if let textConfig = sTextMap[.circlepw_pin_biometrics_allow_title] { // C46
282
+ setText(label: controller.promptTitleLabel, textConfig: textConfig)
283
+ }
284
+ if let textConfig = sTextMap[.circlepw_pin_biometrics_allow_subtitle] { // C47
285
+ setText(label: controller.promptSubtitleLabel, textConfig: textConfig)
286
+ }
287
+ if let textConfig = sTextMap[.circlepw_continue] { // C11
288
+ setText(button: controller.continueButton, textConfig: textConfig)
289
+ }
290
+ if let textConfig = sTextMap[.circlepw_skip] { // C48
291
+ setText(button: controller.skipButton, textConfig: textConfig)
292
+ }
293
+ if let textConfig = sTextMap[.circlepw_pin_biometrics_disable] { // C49
294
+ setText(button: controller.dontAskButton, textConfig: textConfig)
295
+ }
296
+ }
297
+ }
298
+ }
299
+
300
+ extension RNWalletSdk {
301
+
302
+ private func setText(label: UILabel, textConfig: TextConfig, shouldReplaceText: Bool = true) {
303
+ if let text = textConfig.text, shouldReplaceText {
304
+ label.text = text
305
+ }
306
+ if let textColor = textConfig.textColor {
307
+ label.textColor = UIColor(textColor)
308
+ }
309
+ if let gradientColors = textConfig.gradientColors {
310
+ let colors = gradientColors.map { UIColor($0) }
311
+ label.setGradientTextColors(colors)
312
+ }
313
+ if let font = textConfig.font {
314
+ let size = label.font.pointSize
315
+ label.font = UIFont(name: font, size: size)
316
+ }
317
+ }
318
+
319
+ private func setText(button: UIButton, textConfig: TextConfig) {
320
+ if let text = textConfig.text {
321
+ button.setTitle(text, for: .normal)
322
+ }
323
+ if let textColor = textConfig.textColor {
324
+ button.setTitleColor(UIColor(textColor), for: .normal)
325
+ button.setTitleColor(UIColor(textColor).withAlphaComponent(0.2), for: .highlighted)
326
+ }
327
+ if let gradientColors = textConfig.gradientColors {
328
+ let colors = gradientColors.map { UIColor($0) }
329
+ button.setGradientTextColors(colors)
330
+ }
331
+ if let font = textConfig.font,
332
+ let size = button.titleLabel?.font.pointSize {
333
+ button.titleLabel?.font = UIFont(name: font, size: size)
334
+ }
335
+ }
336
+
337
+ private func setText(textField: UITextField,
338
+ textConfig: TextConfig?,
339
+ placeholderTextConfig: TextConfig?) {
340
+
341
+ if let textColor = textConfig?.textColor {
342
+ textField.textColor = UIColor(textColor)
343
+ }
344
+ if let font = textConfig?.font, let size = textField.font?.pointSize {
345
+ textField.font = UIFont(name: font, size: size)
346
+ }
347
+
348
+ if let text = placeholderTextConfig?.text {
349
+ textField.placeholder = text
350
+ }
351
+ if let textColor = placeholderTextConfig?.textColor {
352
+ textField.placeholderColor(color: UIColor(textColor))
353
+ }
354
+ }
355
+ }
356
+
357
+ private extension UITextField {
358
+
359
+ func placeholderColor(color: UIColor) {
360
+ guard let placeholder = self.placeholder, let font = self.font else { return }
361
+ let attributeString = [
362
+ .foregroundColor: color,
363
+ .font: font,
364
+ ] as [NSAttributedString.Key: Any]
365
+ self.attributedPlaceholder = NSAttributedString(string: placeholder, attributes: attributeString)
366
+ }
367
+ }