@algorandfoundation/react-native-passkey-autofill 1.0.0-canary.7 → 1.0.0-canary.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # [1.0.0-canary.9](https://github.com/algorandfoundation/react-native-passkey-autofill/compare/v1.0.0-canary.8...v1.0.0-canary.9) (2026-03-30)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * x logins, refactor example views to be dialogs ([e7a1ccf](https://github.com/algorandfoundation/react-native-passkey-autofill/commit/e7a1ccf91f88b5c369ff3082f06d538fc8b3db89))
7
+
8
+ # [1.0.0-canary.8](https://github.com/algorandfoundation/react-native-passkey-autofill/compare/v1.0.0-canary.7...v1.0.0-canary.8) (2026-03-27)
9
+
10
+
11
+ ### Features
12
+
13
+ * passkey added and authenticated events ([b9871f4](https://github.com/algorandfoundation/react-native-passkey-autofill/commit/b9871f475a9a633ae98d30a702ef2814ec8ae5e0))
14
+
1
15
  # [1.0.0-canary.7](https://github.com/algorandfoundation/react-native-passkey-autofill/compare/v1.0.0-canary.6...v1.0.0-canary.7) (2026-03-24)
2
16
 
3
17
 
package/README.md CHANGED
@@ -66,6 +66,31 @@ await ReactNativePasskeyAutofill.configureIntentActions(
66
66
  await ReactNativePasskeyAutofill.clearCredentials();
67
67
  ```
68
68
 
69
+ ## Events
70
+
71
+ You can listen for events emitted by the native module when a passkey is successfully added or authenticated.
72
+
73
+ ```typescript
74
+ import ReactNativePasskeyAutofill from '@algorandfoundation/react-native-passkey-autofill';
75
+ import { useEffect } from 'react';
76
+
77
+ // ... inside a component or hook
78
+ useEffect(() => {
79
+ const addedSubscription = ReactNativePasskeyAutofill.addListener('onPasskeyAdded', (event) => {
80
+ console.log('Passkey added successfully:', event.success);
81
+ });
82
+
83
+ const authSubscription = ReactNativePasskeyAutofill.addListener('onPasskeyAuthenticated', (event) => {
84
+ console.log('Passkey authenticated successfully:', event.success);
85
+ });
86
+
87
+ return () => {
88
+ addedSubscription.remove();
89
+ authSubscription.remove();
90
+ };
91
+ }, []);
92
+ ```
93
+
69
94
  ## 🧪 Testing
70
95
 
71
96
  The project is set up with a comprehensive testing approach covering both JavaScript and Native (Kotlin) sides.
@@ -15,13 +15,19 @@
15
15
  android:name="android.credentials.provider"
16
16
  android:resource="@xml/provider" />
17
17
  </service>
18
- <activity android:name=".GetPasskeyActivity" android:exported="true">
18
+ <activity android:name="co.algorand.passkeyautofill.GetPasskeyActivity"
19
+ android:exported="true"
20
+ android:launchMode="singleTop"
21
+ android:theme="@style/Theme.PasskeyAutofill.Dialog">
19
22
  <intent-filter>
20
23
  <action android:name="co.algorand.passkeyautofill.GET_PASSKEY"/>
21
24
  <category android:name="android.intent.category.DEFAULT"/>
22
25
  </intent-filter>
23
26
  </activity>
24
- <activity android:name=".CreatePasskeyActivity" android:exported="true">
27
+ <activity android:name="co.algorand.passkeyautofill.CreatePasskeyActivity"
28
+ android:exported="true"
29
+ android:launchMode="singleTop"
30
+ android:theme="@style/Theme.PasskeyAutofill.Dialog">
25
31
  <intent-filter>
26
32
  <action android:name="co.algorand.passkeyautofill.CREATE_PASSKEY"/>
27
33
  <category android:name="android.intent.category.DEFAULT"/>
@@ -205,6 +205,11 @@ class CreatePasskeyActivity : AppCompatActivity() {
205
205
  layout.addView(cancelButton)
206
206
 
207
207
  setContentView(layout)
208
+
209
+ // Ensure the activity is focusable and can receive touches
210
+ layout.isFocusable = true
211
+ layout.isFocusableInTouchMode = true
212
+ layout.requestFocus()
208
213
  }
209
214
 
210
215
  @SuppressLint("RestrictedApi")
@@ -301,6 +306,9 @@ class CreatePasskeyActivity : AppCompatActivity() {
301
306
  )
302
307
 
303
308
  setResult(Activity.RESULT_OK, resultIntent)
309
+ ReactNativePasskeyAutofillModule.instance?.sendEvent("onPasskeyAdded", Bundle().apply {
310
+ putBoolean("success", true)
311
+ })
304
312
  } catch (e: Exception) {
305
313
  Log.e(TAG, "Error during passkey creation", e)
306
314
  setResult(Activity.RESULT_CANCELED)
@@ -193,6 +193,11 @@ class GetPasskeyActivity : AppCompatActivity() {
193
193
  layout.addView(cancelButton)
194
194
 
195
195
  setContentView(layout)
196
+
197
+ // Ensure the activity is focusable and can receive touches
198
+ layout.isFocusable = true
199
+ layout.isFocusableInTouchMode = true
200
+ layout.requestFocus()
196
201
  }
197
202
 
198
203
  @SuppressLint("RestrictedApi")
@@ -309,6 +314,9 @@ class GetPasskeyActivity : AppCompatActivity() {
309
314
  )
310
315
 
311
316
  setResult(Activity.RESULT_OK, resultIntent)
317
+ ReactNativePasskeyAutofillModule.instance?.sendEvent("onPasskeyAuthenticated", Bundle().apply {
318
+ putBoolean("success", true)
319
+ })
312
320
  } catch (e: Exception) {
313
321
  Log.e(TAG, "Error during passkey assertion", e)
314
322
  setResult(Activity.RESULT_CANCELED)
@@ -12,6 +12,10 @@ import java.security.Security
12
12
  class ReactNativePasskeyAutofillModule : Module() {
13
13
  private val credentialRepository = CredentialRepository()
14
14
 
15
+ companion object {
16
+ var instance: ReactNativePasskeyAutofillModule? = null
17
+ }
18
+
15
19
  init {
16
20
  Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME)
17
21
  Security.addProvider(BouncyCastleProvider())
@@ -26,6 +30,16 @@ class ReactNativePasskeyAutofillModule : Module() {
26
30
  // The module will be accessible from `requireNativeModule('ReactNativeLiquidAuth')` in JavaScript.
27
31
  Name("ReactNativePasskeyAutofill")
28
32
 
33
+ OnCreate {
34
+ instance = this@ReactNativePasskeyAutofillModule
35
+ }
36
+
37
+ OnDestroy {
38
+ instance = null
39
+ }
40
+
41
+ Events("onPasskeyAdded", "onPasskeyAuthenticated")
42
+
29
43
  AsyncFunction("setMasterKey") { secret: String ->
30
44
  val context = (appContext.reactContext ?: appContext.hostingRuntimeContext) as? Context
31
45
  if (context != null) {
@@ -0,0 +1,10 @@
1
+ <resources>
2
+ <style name="Theme.PasskeyAutofill.Dialog" parent="Theme.AppCompat.Light.Dialog.MinWidth">
3
+ <item name="android:windowIsTranslucent">true</item>
4
+ <item name="android:windowBackground">@android:color/transparent</item>
5
+ <item name="android:windowContentOverlay">@null</item>
6
+ <item name="android:windowNoTitle">true</item>
7
+ <item name="android:windowIsFloating">true</item>
8
+ <item name="android:backgroundDimEnabled">true</item>
9
+ </style>
10
+ </resources>
package/app.plugin.js CHANGED
@@ -231,13 +231,13 @@ const withPasskeyAutofill = (config, props = {}) => {
231
231
  if (config.modResults.contents.includes("dP256Android-release")) {
232
232
  return config;
233
233
  }
234
- const libsDir = path.join(__dirname, "android/libs");
234
+ const libsDir = "../../android/libs";
235
235
  config.modResults.contents = config.modResults.contents.replace(
236
236
  /allprojects\s*{[\s\n]*repositories\s*{/,
237
237
  `allprojects {
238
238
  repositories {
239
239
  flatDir {
240
- dirs "${libsDir}"
240
+ dirs "$rootDir/${libsDir}"
241
241
  }`
242
242
  );
243
243
  return config;
@@ -1,2 +1,9 @@
1
- export type ReactNativePasskeyAutofillModuleEvents = {};
1
+ export type ReactNativePasskeyAutofillModuleEvents = {
2
+ onPasskeyAdded: (event: {
3
+ success: boolean;
4
+ }) => void;
5
+ onPasskeyAuthenticated: (event: {
6
+ success: boolean;
7
+ }) => void;
8
+ };
2
9
  //# sourceMappingURL=ReactNativePasskeyAutofill.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReactNativePasskeyAutofill.types.d.ts","sourceRoot":"","sources":["../src/ReactNativePasskeyAutofill.types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,sCAAsC,GAAG,EAEpD,CAAC"}
1
+ {"version":3,"file":"ReactNativePasskeyAutofill.types.d.ts","sourceRoot":"","sources":["../src/ReactNativePasskeyAutofill.types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,sCAAsC,GAAG;IACnD,cAAc,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACtD,sBAAsB,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC/D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ReactNativePasskeyAutofill.types.js","sourceRoot":"","sources":["../src/ReactNativePasskeyAutofill.types.ts"],"names":[],"mappings":"","sourcesContent":["export type ReactNativePasskeyAutofillModuleEvents = {\n\n};\n"]}
1
+ {"version":3,"file":"ReactNativePasskeyAutofill.types.js","sourceRoot":"","sources":["../src/ReactNativePasskeyAutofill.types.ts"],"names":[],"mappings":"","sourcesContent":["export type ReactNativePasskeyAutofillModuleEvents = {\n onPasskeyAdded: (event: { success: boolean }) => void;\n onPasskeyAuthenticated: (event: { success: boolean }) => void;\n};\n"]}
@@ -10,6 +10,8 @@ public class ReactNativePasskeyAutofillModule: Module {
10
10
  // The module will be accessible from `requireNativeModule('ReactNativePasskeyAutofill')` in JavaScript.
11
11
  Name("ReactNativePasskeyAutofill")
12
12
 
13
+ Events("onPasskeyAdded", "onPasskeyAuthenticated")
14
+
13
15
  AsyncFunction("setMasterKey") { (secret: String) in
14
16
  // TODO: Implement for iOS
15
17
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@algorandfoundation/react-native-passkey-autofill",
3
- "version": "1.0.0-canary.7",
3
+ "version": "1.0.0-canary.9",
4
4
  "description": "Passkey AutoFill React Native",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -1,3 +1,4 @@
1
1
  export type ReactNativePasskeyAutofillModuleEvents = {
2
-
2
+ onPasskeyAdded: (event: { success: boolean }) => void;
3
+ onPasskeyAuthenticated: (event: { success: boolean }) => void;
3
4
  };