Files
safe-wallet/patches/react-native-device-crypto-npm-0.1.7-dbd2698fc4.patch
zeekay cee2dbe616 chore: migrate yarn 4 → pnpm 9 (workspace-wide)
Drop yarn 4 PnP completely; pnpm is now the only package manager.

Touched:
  package.json               packageManager yarn@4 → [email protected].0;
                              resolutions → pnpm.overrides;
                              yarn patches → pnpm.patchedDependencies;
                              "pnpm workspace X" scripts → "pnpm --filter X exec";
                              drop @yarnpkg/types dep
  pnpm-workspace.yaml         new — mirrors workspaces array
  .npmrc                      new — node-linker=hoisted; auto-install-peers
  patches/                    new — moved from .yarn/patches/
  apps/mobile/package.json    eas-build-pre-install: corepack prep pnpm
  .yarn/                      deleted (PnP state)
  .yarnrc.yml                 deleted
  yarn.lock                   deleted; pnpm-lock.yaml regenerated
  .github/actions/yarn/       renamed to .github/actions/pnpm/, rewritten
                              for pnpm/action-setup + pnpm install
                              --frozen-lockfile
  .github/actions/cache-deps  cache paths: ~/.yarn/berry/cache →
                              ~/.local/share/pnpm/store; hashFiles
                              yarn.lock → pnpm-lock.yaml
  10 workflows                ./.github/actions/yarn → /pnpm; yarn
                              workspaces foreach → pnpm -r; yarn workspace
                              → pnpm --filter; yarn install --immutable →
                              pnpm install --frozen-lockfile; cache: yarn
                              → cache: pnpm

This is a hard fork from upstream safe-global/safe-wallet-monorepo
(which mandates yarn 4 in its AGENTS.md). Per directive: no yarn in
luxfi/* — pnpm only. Upstream merges into this fork will need manual
package-manager translation going forward.
2026-05-27 01:35:38 -07:00

126 lines
5.4 KiB
Diff

diff --git a/android/build.gradle b/android/build.gradle
index 8eb758ed063d1905f538f72e3ee55a8c41e01d18..d1ee770a3594017357465e031c2edb4aae6a448c 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -3,7 +3,6 @@ buildscript {
repositories {
google()
mavenCentral()
- jcenter()
}
dependencies {
@@ -52,7 +51,6 @@ repositories {
}
google()
mavenCentral()
- jcenter()
}
dependencies {
diff --git a/android/src/main/java/com/reactnativedevicecrypto/Helpers.java b/android/src/main/java/com/reactnativedevicecrypto/Helpers.java
index 03fd79e8a389f33a2841ecf0e177ffc9ea01b78c..d903b5dc4b0110dab9a8c1a648d349200dd4e20f 100644
--- a/android/src/main/java/com/reactnativedevicecrypto/Helpers.java
+++ b/android/src/main/java/com/reactnativedevicecrypto/Helpers.java
@@ -39,6 +39,7 @@ public class Helpers {
private static final int AES_IV_SIZE = 128;
public static final String PEM_HEADER = "-----BEGIN PUBLIC KEY-----\n";
public static final String PEM_FOOTER = "-----END PUBLIC KEY-----";
+ private static Boolean sIsStrongBoxSupported = null; // Cache for StrongBox support
public interface KeyType {
@Retention(SOURCE)
@@ -81,6 +82,64 @@ public class Helpers {
}
}
+ public static boolean isStrongBoxSupported() {
+ // Return cached result if available
+ if (sIsStrongBoxSupported != null) {
+ return sIsStrongBoxSupported;
+ }
+
+ // Try to create a key with StrongBox requirement and see if it succeeds
+ String testAlias = "test_strongbox_support";
+ try {
+ // First, clean up any existing test key
+ try {
+ KeyStore keyStore = getKeyStore();
+ if (keyStore.containsAlias(testAlias)) {
+ keyStore.deleteEntry(testAlias);
+ }
+ } catch (Exception e) {
+ // Ignore errors during cleanup
+ }
+
+ // Attempt to create a key with StrongBox backing
+ KeyGenParameterSpec testSpec = new KeyGenParameterSpec.Builder(testAlias, KeyProperties.PURPOSE_ENCRYPT)
+ .setIsStrongBoxBacked(true)
+ .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+ .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+ .setKeySize(256)
+ .build();
+ KeyGenerator testKeyGen = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, KEY_STORE);
+ testKeyGen.init(testSpec);
+ testKeyGen.generateKey();
+
+ // If we reach here, StrongBox is supported
+ // Clean up the test key
+ KeyStore keyStore = getKeyStore();
+ keyStore.deleteEntry(testAlias);
+
+ // Cache the result
+ sIsStrongBoxSupported = true;
+ Log.i(RN_MODULE, "StrongBox is supported on this device");
+ return true;
+ } catch (Exception e) {
+ Log.i(RN_MODULE, "StrongBox not supported on this device: " + e.getMessage());
+
+ // Clean up any test key that might have been created
+ try {
+ KeyStore keyStore = getKeyStore();
+ if (keyStore.containsAlias(testAlias)) {
+ keyStore.deleteEntry(testAlias);
+ }
+ } catch (Exception cleanupEx) {
+ // Ignore errors during cleanup
+ }
+
+ // Cache the result
+ sIsStrongBoxSupported = false;
+ return false;
+ }
+ }
+
public static boolean isKeyExists(@NonNull String alias, @KeyType.Types int keyType) throws Exception {
KeyStore keyStore = Helpers.getKeyStore();
if (!keyStore.containsAlias(alias)) {
@@ -134,17 +193,22 @@ public class Helpers {
case AccessLevel.AUTHENTICATION_REQUIRED:
// Sets whether this key is authorized to be used only if the user has been authenticated.
builder.setUserAuthenticationRequired(true);
+
// Allow pin/pass as a fallback on API 30+
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
- builder.setUserAuthenticationParameters(0, KeyProperties.AUTH_DEVICE_CREDENTIAL | KeyProperties.AUTH_BIOMETRIC_STRONG);
- }
+ // Disabled this as it prevents invalidation of the user removes the biometric
+ // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ // builder.setUserAuthenticationParameters(0, KeyProperties.AUTH_DEVICE_CREDENTIAL | KeyProperties.AUTH_BIOMETRIC_STRONG);
+ // }
+
// Invalidate the keys if the user has registered a new biometric
// credential. The variable "invalidatedByBiometricEnrollment" is true by default.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
builder.setInvalidatedByBiometricEnrollment(invalidateOnNewBiometry);
}
- if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
- builder.setIsStrongBoxBacked(true);
+ // Only try to enable StrongBox if API level is high enough and the device
+ // actually supports it
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && isStrongBoxSupported()) {
+ builder.setIsStrongBoxBacked(true);
}
break;
}