Skip to content

Conversation

ByteZhang1024
Copy link
Contributor

@ByteZhang1024 ByteZhang1024 commented Aug 26, 2025

Summary by CodeRabbit

  • Chores
    • Modernized Android CI to current actions and JDK 17 and improved Gradle caching.
    • Added a new workspace package for shared constants and updated example projects to use it.
  • Bug Fixes
    • Improved React Native crypto polyfill to use a robust global random-values provider (no public API changes).
  • New Features
    • Example app: consolidated passphrase controls into a new top block for clearer configuration.

Copy link
Contributor

coderabbitai bot commented Aug 26, 2025

Walkthrough

Add a new shared constants workspace and switch example imports to it, bump two GitHub Actions in an Android workflow, update a react-native-crypto patch to use react-native-get-random-values with a globalThis.crypto polyfill, and add passphrase UI controls in an example component. No public API signatures changed.

Changes

Cohort / File(s) Summary
CI workflow version bumps
.github/workflows/build-example-android.yml
Updated actions/setup-java -> actions/setup-java@v4 and actions/cache -> actions/cache@v4. No other steps changed.
Workspace & new package manifest
package.json, packages/connect-examples/shared-constants/package.json
Added packages/connect-examples/shared-constants to root workspaces; added @onekey-internal/shared-constants package manifest (private, ESM, main constants.js, version 1.1.10-alpha.2).
Example imports updated
packages/connect-examples/expo-example/src/constants/connect.ts, packages/connect-examples/expo-playground/app/constants/connect.ts
Switched import of getConnectSrc from ../../../constants to @onekey-internal/shared-constants; CONNECT_SRC export remains unchanged.
React Native crypto patch
patches/react-native-crypto+2.2.0.patch
Replaced window-based polyfill with react-native-get-random-values; ensure globalThis.crypto exists and assign getRandomValues; removed react-native-randombytes approach; preserved exported constructors.
Example UI: passphrase controls
packages/connect-examples/expo-example/src/components/CommonParamsView.tsx
Added four passphrase-related controls (text input for passphraseState, switches for useEmptyPassphrase, skipPassphraseCheck, initSession) at the top of the view; removed duplicate controls from lower section and adjusted input order.

Sequence Diagram(s)

sequenceDiagram
  participant App as Example App
  participant Shared as @onekey-internal/shared-constants
  participant CryptoPatch as react-native-crypto patch
  participant RNGetRand as react-native-get-random-values

  Note over App,Shared: Example code imports shared constants
  App->>Shared: import getConnectSrc
  Shared-->>App: provide CONNECT_SRC

  Note over App,CryptoPatch: Crypto module load (patch applied)
  App->>CryptoPatch: import 'crypto' shim
  alt globalThis.crypto.getRandomValues exists
    CryptoPatch-->>App: export crypto APIs (no polyfill)
  else
    CryptoPatch->>RNGetRand: import getRandomValues
    RNGetRand-->>CryptoPatch: getRandomValues fn
    CryptoPatch->>CryptoPatch: ensure globalThis.crypto and bind getRandomValues
    CryptoPatch-->>App: export crypto APIs (polyfilled)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/androidCi

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary or Summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@revan-zhang
Copy link
Contributor

revan-zhang commented Aug 26, 2025

🎉 Snyk checks have passed. No issues have been found so far.

security/snyk check is complete. No issues have been found. (View Details)

license/snyk check is complete. No issues have been found. (View Details)

Copy link

socket-security bot commented Aug 26, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​nicolo-ribaudo/​eslint-scope-5-internals@​5.1.1-v11001004675100
Addedasynciterator.prototype@​1.0.0671007251100
Addedarray-buffer-byte-length@​1.0.0671007351100
Addedarray.prototype.tosorted@​1.1.2671009151100
Addedavailable-typed-arrays@​1.0.5671007951100
Addedarraybuffer.prototype.slice@​1.0.2661008751100
Addedarray.prototype.flat@​1.3.2671009152100
Addedes-set-tostringtag@​2.0.2671007852100
Addedarray.prototype.findlastindex@​1.2.3671009252100
Addedes-iterator-helpers@​1.0.15661009753100
Added@​lerna/​output@​4.0.01001005479100
Added@​lerna/​timer@​4.0.01001005479100
Added@​lerna/​validation-error@​4.0.01001005579100
Added@​types/​parse-json@​4.0.01001005577100
Added@​jest/​globals@​28.1.31001005691100
Added@​lerna/​get-npm-exec-opts@​4.0.01001005679100
Added@​lerna/​prerelease-id-from-version@​4.0.01001005779100
Added@​npmcli/​node-gyp@​1.0.31001005883100
Added@​lerna/​npm-run-script@​4.0.01001005879100
Added@​tootallnate/​once@​1.1.21001005976100
Added@​babel/​plugin-transform-react-jsx-development@​7.22.51001005989100
Added@​types/​graceful-fs@​4.1.51001005976100
Added@​lerna/​write-log-file@​4.0.01001005979100
Added@​lerna/​has-npm-version@​4.0.01001006079100
Added@​babel/​plugin-syntax-async-generators@​7.8.41001006081100
Added@​babel/​plugin-syntax-bigint@​7.8.31001006081100
Added@​babel/​plugin-syntax-import-meta@​7.10.41001006081100
Added@​babel/​plugin-syntax-json-strings@​7.8.31001006081100
Added@​babel/​plugin-syntax-logical-assignment-operators@​7.10.41001006081100
Added@​babel/​plugin-syntax-nullish-coalescing-operator@​7.8.31001006081100
Added@​babel/​plugin-syntax-numeric-separator@​7.10.41001006081100
Added@​babel/​plugin-syntax-object-rest-spread@​7.8.31001006081100
Added@​babel/​plugin-syntax-optional-catch-binding@​7.8.31001006081100
See 317 more rows in the dashboard

View full report

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
.github/workflows/build-example-android.yml (3)

13-16: Fix Node version mismatch (step name says 20, action installs 22).

This can break CI and confuse readers. Align the value with the name. Node 20 is also safer for RN builds today.

Apply:

-      - name: Use Node.js 20
-        uses: actions/setup-node@v4
-        with:
-          node-version: '22'
+      - name: Use Node.js 20
+        uses: actions/setup-node@v4
+        with:
+          node-version: '20'

19-23: Good upgrade to setup-java v4. Consider enabling its built-in Gradle cache.

You can drop the separate cache step and let setup-java handle it.

Option A — add cache here:

       - name: Set up JDK 17
         uses: actions/setup-java@v4
         with:
           java-version: '17'
           distribution: 'zulu'
+          cache: 'gradle'

Then remove the dedicated “Cache Gradle packages” step below.


29-36: Prefer gradle/actions/setup-gradle for smarter caching.

It’s more reliable than a generic cache step and cleans up old entries.

Replace this step with:

-      - name: Cache Gradle packages
-        uses: actions/cache@v4
-        with:
-          path: |
-            ~/.gradle/caches
-            ~/.gradle/wrapper
-          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
-          restore-keys: |
-            ${{ runner.os }}-gradle-
+      - name: Setup Gradle with caching
+        uses: gradle/actions/setup-gradle@v4
+        with:
+          gradle-home-cache-includes: |
+            caches
+            notifications
+            wrapper
+          gradle-home-cache-cleanup: true
patches/react-native-crypto+2.2.0.patch (1)

1-42: Action required — verify polyfill wiring & restore randomBytes compatibility before merging

Short: the patch replaces react-native-randombytes with react-native-get-random-values and sets globalThis.crypto.getRandomValues, but it removed the exported crypto.randomBytes API. That will break callers of crypto.randomBytes and the patch in /patches may not even be applied in CI.

Files/locations to inspect and fix

  • ./packages/connect-examples/expo-example/package.json — react-native-get-random-values is present here (@^1.10.0). Add it to any packages that use react-native-crypto or to the repo root if the runtime needs it globally.
  • ./package.json (repo root) — currently has no patch-package and no postinstall script (patches under /patches won't be applied). Add patch-package as a devDependency and run it in postinstall (or ensure CI applies patches).
  • patches/react-native-crypto+2.2.0.patch — the changed file removed exports.randomBytes; restore a compatibility export or provide an explicit fallback.
  • ./packages/connect-examples/expo-example/src/testTools/slip39Test/core/slip39Utils.ts — uses crypto.randomBytes() (multiple sites). Search repo for other crypto.randomBytes callers and update or keep compatibility.
  • ./packages/connect-examples/expo-example/shim/crypto/index.native.js — this shim already requires react-native-get-random-values and reassigns randomBytes (so expo-example may still work). Other packages likely lack that shim.

Recommended, minimal fixes

  • Ensure patch application: add patch-package to root devDependencies and a postinstall script to run it (or update CI).
  • Restore a compatibility randomBytes export in the patched react-native-crypto index.js so crypto.randomBytes(...) continues to work. Example (suggested insertion into the patched file):
  • import { getRandomValues } from 'react-native-get-random-values';
  • function randomBytes(length) {
  • const arr = new Uint8Array(length);
  • (globalThis.crypto && globalThis.crypto.getRandomValues
  • ? globalThis.crypto.getRandomValues
    
  • : getRandomValues)(arr);
    
  • return (typeof Buffer !== 'undefined') ? Buffer.from(arr) : arr;
  • }
  • exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = randomBytes;
  • Or, alternatively, add react-native-get-random-values to every package that will import react-native-crypto (so getRandomValues is present at runtime) and update callers to use globalThis.crypto.getRandomValues where feasible.

Why this is blocking

  • Patches won't be applied in CI unless patch-package is configured at the repo root.
  • Removing exports.randomBytes breaks existing code that expects crypto.randomBytes (we found concrete call sites).
  • react-native-get-random-values is only declared in the expo-example package.json, not globally.

Next step

  • Fix package.json (root or target packages) and either restore the randomBytes export in the patch or update all call sites. I can produce an updated patch snippet if you want.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge Base: Disabled due to data retention organization setting

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 07dac6e and 1e50f43.

📒 Files selected for processing (6)
  • .github/workflows/build-example-android.yml (2 hunks)
  • package.json (1 hunks)
  • packages/connect-examples/expo-example/src/constants/connect.ts (1 hunks)
  • packages/connect-examples/expo-playground/app/constants/connect.ts (1 hunks)
  • packages/connect-examples/shared-constants/package.json (1 hunks)
  • patches/react-native-crypto+2.2.0.patch (1 hunks)
🧰 Additional context used
🪛 ESLint
packages/connect-examples/expo-playground/app/constants/connect.ts

[error] 1-1: Resolve error: typescript with invalid interface loaded as resolver

(import/namespace)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build-and-upload
  • GitHub Check: Socket Security: Pull Request Alerts
  • GitHub Check: build (22)
  • GitHub Check: lint (22)
🔇 Additional comments (2)
package.json (1)

13-13: Workspace entry looks good.

This will let Yarn/Lerna bootstrap the new shared-constants package.

packages/connect-examples/expo-example/src/constants/connect.ts (1)

2-4: Import switch to shared package looks good.

Keeps the API the same while centralizing constants.

@@ -1,4 +1,4 @@
import { getConnectSrc } from '../../../constants';
import { getConnectSrc } from '@onekey-internal/shared-constants';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Resolve the ESLint “import/namespace” error by exposing types.

The resolver error points to missing/unknown exports for @onekey-internal/shared-constants. After adding "types" and "exports" to that package (see package.json review), this should pass.

Re-run lint after adding types:


🏁 Script executed:

#!/bin/bash
yarn lint --max-warnings=0

Length of output: 322


🏁 Script executed:

#!/bin/bash
# Locate the shared-constants package.json
pkg_path=$(find packages -type f -name package.json -exec grep -l '"name": "@onekey-internal/shared-constants"' {} \;)
echo "Shared constants package.json at: $pkg_path"

# Check for "types" field
echo
echo "Checking for types field in package.json:"
grep -n '"types"' "$pkg_path" || echo "No types field found"

# Check for "exports" field
echo
echo "Checking for exports field in package.json:"
grep -n '"exports"' "$pkg_path" || echo "No exports field found"

Length of output: 834


Add missing “types” and “exports” to shared-constants package

ESLint can’t resolve @onekey-internal/shared-constants because its package.json lacks type definitions and export paths. Please update packages/connect-examples/shared-constants/package.json:

 {
   "name": "@onekey-internal/shared-constants",
   "version": "x.y.z",
-  "main": "lib/index.js",
+  "main": "lib/index.js",
+  "types": "lib/index.d.ts",
+  "exports": {
+    ".": {
+      "import": "./lib/index.js",
+      "require": "./lib/index.cjs"
+    }
+  },
   // …other fields…
 }

After adding these fields, rerun lint to confirm the import error is resolved:

yarn lint --max-warnings=0
🧰 Tools
🪛 ESLint

[error] 1-1: Resolve error: typescript with invalid interface loaded as resolver

(import/namespace)

🤖 Prompt for AI Agents
In packages/connect-examples/expo-playground/app/constants/connect.ts line 1,
the import of @onekey-internal/shared-constants fails because the
shared-constants package.json is missing type definitions and export paths; open
packages/connect-examples/shared-constants/package.json and add a "types" field
pointing to the package's d.ts (e.g. "types": "dist/index.d.ts" or the correct
path for your build), and add an "exports" map that exposes the package entry
(and any subpaths you consume) for both import and require (e.g. an export for
"." with import and require targets); ensure main/module fields remain
consistent with your build output, update/commit the package.json, run the
TypeScript build if needed to emit .d.ts, then rerun yarn lint --max-warnings=0
to confirm the resolution.

Comment on lines +1 to +10
{
"name": "@onekey-internal/shared-constants",
"version": "1.1.10-alpha.2",
"private": true,
"author": "OneKey",
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
"license": "ISC",
"type": "module",
"main": "constants.js"
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Ship types and explicit exports to fix TS/ESLint resolution.

The playground file shows an import/namespace resolver error. Add types and exports so TS and eslint-import can resolve the module cleanly.

Apply:

 {
   "name": "@onekey-internal/shared-constants",
   "version": "1.1.10-alpha.2",
   "private": true,
   "author": "OneKey",
   "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
   "license": "ISC",
   "type": "module",
-  "main": "constants.js"
+  "main": "constants.js",
+  "types": "constants.d.ts",
+  "exports": {
+    ".": {
+      "types": "./constants.d.ts",
+      "default": "./constants.js"
+    }
+  },
+  "files": [
+    "constants.js",
+    "constants.d.ts"
+  ],
+  "sideEffects": false
 }

Also add a declaration file:

// packages/connect-examples/shared-constants/constants.d.ts
export function getConnectSrc(): string;

Verify the implementation actually exports the symbol:


🏁 Script executed:

#!/bin/bash
# Confirm the JS export exists
rg -n "export\s+(const|function)\s+getConnectSrc\b" packages/connect-examples/shared-constants/constants.*

Length of output: 147


Expose types and exports in shared-constants

We confirmed getConnectSrc is already exported in constants.js. To resolve TS and ESLint import errors, add explicit type declarations and exports:

• packages/connect-examples/shared-constants/package.json
• packages/connect-examples/shared-constants/constants.d.ts

Apply:

--- a/packages/connect-examples/shared-constants/package.json
+++ b/packages/connect-examples/shared-constants/package.json
@@
   "type": "module",
-  "main": "constants.js"
+  "main": "constants.js",
+  "types": "constants.d.ts",
+  "exports": {
+    ".": {
+      "types": "./constants.d.ts",
+      "default": "./constants.js"
+    }
+  },
+  "files": [
+    "constants.js",
+    "constants.d.ts"
+  ],
+  "sideEffects": false

Add declaration file:

// packages/connect-examples/shared-constants/constants.d.ts
export function getConnectSrc(): string;

Verified export:

rg -n "export\s+(const|function)\s+getConnectSrc\b" packages/connect-examples/shared-constants/constants.js
# → 12:export const getConnectSrc = () =>
🤖 Prompt for AI Agents
In packages/connect-examples/shared-constants/package.json lines 1-10,
TypeScript/ESLint import errors occur because no type declaration is exposed;
add a constants.d.ts file with the declaration "export function getConnectSrc():
string;" at packages/connect-examples/shared-constants/constants.d.ts and update
package.json to include a "types": "constants.d.ts" entry (keep "main":
"constants.js"), so the JS export (already present in constants.js) is
accompanied by an explicit type declaration for consumers.

+++ b/node_modules/react-native-crypto/index.js
@@ -1,28 +1,16 @@
'use strict'
+import { getRandomValues } from 'react-native-get-random-values';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Avoid ESM in a CommonJS module; switch to require/side‑effect import

Metro can handle ESM, but mixing ESM imports with exports.* inside node_modules is brittle and has bitten RN projects in CI. Use a side‑effect require to ensure the polyfill runs without interop surprises.

-'use strict'
-import { getRandomValues } from 'react-native-get-random-values';
+'use strict'
+// Ensure Web Crypto RNG is registered in RN (Hermes/JSC)
+require('react-native-get-random-values');
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
+import { getRandomValues } from 'react-native-get-random-values';
'use strict'
// Ensure Web Crypto RNG is registered in RN (Hermes/JSC)
require('react-native-get-random-values');
🤖 Prompt for AI Agents
In patches/react-native-crypto+2.2.0.patch around line 7, the file currently
uses an ESM import "import { getRandomValues } from
'react-native-get-random-values';" inside a CommonJS module which can break
Metro/CI; replace the ESM import with a side-effect require call so the polyfill
is executed without creating ESM/CommonJS interop issues (i.e., remove the
import line and add a top-level require('react-native-get-random-values');).

Comment on lines +9 to +11
-import { randomBytes } from 'react-native-randombytes'
-exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = randomBytes
-
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

You removed randomBytes/rng/prng exports — this is a breaking API change

react-native-crypto used to expose randomBytes, rng, pseudoRandomBytes, and prng. Dropping them can break downstream code (and deviates from Node’s crypto API). Reintroduce a randomBytes implementation built on crypto.getRandomValues, including the 65536-per-call chunking required by the Web Crypto spec, and export the aliases.

@@
-exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = randomBytes
+// Keep Node-compatible randomBytes API (sync and callback forms) using Web Crypto.
+const { Buffer } = require('buffer');
+function randomBytes(size, cb) {
+  if (typeof size !== 'number' || size < 0) {
+    const err = new TypeError('size must be a non-negative number');
+    if (typeof cb === 'function') { setTimeout(() => cb(err), 0); return; }
+    throw err;
+  }
+  const g = typeof globalThis === 'object' ? globalThis : (typeof global === 'object' ? global : {});
+  const gv = g.crypto && typeof g.crypto.getRandomValues === 'function' ? g.crypto.getRandomValues : null;
+  const err = gv ? null : new Error('crypto.getRandomValues is unavailable. Ensure react-native-get-random-values is installed and loaded.');
+  if (!gv) {
+    if (typeof cb === 'function') { setTimeout(() => cb(err), 0); return; }
+    throw err;
+  }
+  // Web Crypto allows max 65536 bytes per call
+  const MAX = 65536;
+  const bytes = new Uint8Array(size);
+  for (let offset = 0; offset < bytes.length; offset += MAX) {
+    gv.call(g.crypto, bytes.subarray(offset, Math.min(offset + MAX, bytes.length)));
+  }
+  const buf = Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
+  if (typeof cb === 'function') { setTimeout(() => cb(null, buf), 0); return; }
+  return buf;
+}
+exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = randomBytes
@@
 exports.createHash = exports.Hash = require('create-hash')
 exports.createHmac = exports.Hmac = require('create-hmac')

Also applies to: 39-41

Comment on lines +29 to +35
+if (typeof globalThis === 'object') {
+ if (!globalThis.crypto) {
+ globalThis.crypto = {};
+ }
+ if (!globalThis.crypto.getRandomValues) {
+ globalThis.crypto.getRandomValues = getRandomValues;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

🛠️ Refactor suggestion

Harden the global guard and don’t silently skip the polyfill

Older RN environments expose global but not globalThis. Also, react-native-get-random-values typically polyfills via side‑effects; a manual assignment may fail if the package doesn’t export getRandomValues. Make the guard resilient and try a manual attach only if needed.

-if (typeof globalThis === 'object') {
-  if (!globalThis.crypto) {
-    globalThis.crypto = {};
-  }
-  if (!globalThis.crypto.getRandomValues) {
-    globalThis.crypto.getRandomValues = getRandomValues;
-  }
-}
+const g = typeof globalThis === 'object' ? globalThis : (typeof global === 'object' ? global : undefined);
+if (g) {
+  if (!g.crypto) g.crypto = {};
+  // Side-effect import should have set this; if not, try to attach defensively.
+  if (typeof g.crypto.getRandomValues !== 'function') {
+    try {
+      const maybe = require('react-native-get-random-values');
+      const gv = (maybe && (maybe.getRandomValues || (maybe.default && maybe.default.getRandomValues)));
+      if (typeof gv === 'function') g.crypto.getRandomValues = gv;
+    } catch (_) {
+      // Leave unset; randomBytes will throw a clear error.
+    }
+  }
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
+if (typeof globalThis === 'object') {
+ if (!globalThis.crypto) {
+ globalThis.crypto = {};
+ }
+ if (!globalThis.crypto.getRandomValues) {
+ globalThis.crypto.getRandomValues = getRandomValues;
}
- if (typeof globalThis === 'object') {
- if (!globalThis.crypto) {
- globalThis.crypto = {};
- }
- if (!globalThis.crypto.getRandomValues) {
- globalThis.crypto.getRandomValues = getRandomValues;
- }
const g = typeof globalThis === 'object'
? globalThis
: (typeof global === 'object' ? global : undefined);
if (g) {
if (!g.crypto) g.crypto = {};
// Side-effect import should have set this; if not, try to attach defensively.
if (typeof g.crypto.getRandomValues !== 'function') {
try {
const maybe = require('react-native-get-random-values');
const gv = maybe &&
(maybe.getRandomValues ||
(maybe.default && maybe.default.getRandomValues));
if (typeof gv === 'function') {
g.crypto.getRandomValues = gv;
}
} catch (_) {
// Leave unset; randomBytes will throw a clear error.
}
}
}
🤖 Prompt for AI Agents
In patches/react-native-crypto+2.2.0.patch around lines 29-35, the global guard
assumes globalThis exists and blindly assigns getRandomValues which can fail in
older RN or when the polyfill is provided only via side-effects; replace the
check with a resilient reference (use globalThis || global) and only attach
getRandomValues if available — if getRandomValues is missing, attempt to load
the polyfill (e.g. require or dynamic import of
'react-native-get-random-values') and then attach its exported function to the
chosen global.crypto if present, otherwise leave the environment untouched (no
silent failure).

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
.github/workflows/build-example-android.yml (3)

13-16: Fix mismatch: step says Node 20 but installs Node 22.

Rename the step (or set node-version to '20'). Also enable Yarn cache for faster installs.

-      - name: Use Node.js 20
+      - name: Use Node.js 22
         uses: actions/setup-node@v4
         with:
-          node-version: '22'
+          node-version: '22'
+          cache: 'yarn'
+          cache-dependency-path: 'yarn.lock'

18-23: Use setup-java’s built-in Gradle cache and drop the manual cache step.

This simplifies the workflow and avoids duplicate caches.

       - name: Set up JDK 17
-        uses: actions/setup-java@v4
+        uses: actions/setup-java@v4
         with:
           java-version: '17'
           distribution: 'zulu'
+          cache: 'gradle'
 
-      - name: Cache Gradle packages
-        uses: actions/cache@v4
-        with:
-          path: |
-            ~/.gradle/caches
-            ~/.gradle/wrapper
-          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
-          restore-keys: |
-            ${{ runner.os }}-gradle-

Also applies to: 28-36


12-12: Pin GitHub Actions to specific commit SHAs

We’ve found 33 floating refs across eight workflows. To harden our supply chain, replace every uses: …@v3/@v4 with the corresponding full commit SHA.

Affected workflows and lines:

  • release-web.yml: lines 12, 14, 43
  • build-example-android.yml: lines 12, 14, 19, 29, 45
  • package-publish.yml: lines 17, 44, 49
  • lint.yml: lines 25, 28
  • build-packages.yml: lines 25, 28
  • github-release.yml: lines 40, 45
  • build-example-web.yml: lines 12, 18, 50, 58, 64, 78, 88, 96, 101, 157
  • build-example-desktop.yml: lines 11, 13, 33, 41, 49

Actions to pin:

  • actions/checkout
  • actions/setup-node
  • actions/setup-java
  • actions/cache
  • actions/upload-artifact
  • actions/download-artifact
  • peaceiris/actions-gh-pages

Please update each occurrence to a fixed commit SHA (e.g. uses: actions/checkout@<full-sha>).

packages/connect-examples/expo-example/src/components/CommonParamsView.tsx (2)

12-14: Use functional state update to avoid stale writes

Multiple quick edits can drop changes because commonParams is captured by closure. Use an updater.

-  const handleSetParam = (param: string, value: any) => {
-    setOptionalParams({ ...commonParams, [param]: value });
-  };
+  type CommonParamsT = typeof commonParams;
+  const handleSetParam = <K extends keyof CommonParamsT>(key: K, value: CommonParamsT[K]) => {
+    setOptionalParams((prev: CommonParamsT) => ({ ...prev, [key]: value }));
+  };

49-49: Prevent NaN from entering state; parse numbers safely

Clearing the input sets NaN, which then renders as “NaN”. Treat empty as undefined and set radix.

-          onChange={value => handleSetParam('retryCount', parseInt(value))}
+          onChange={value =>
+            handleSetParam('retryCount', value === '' ? undefined : Number.parseInt(value, 10))
+          }
@@
-          onChange={value => handleSetParam('pollIntervalTime', parseInt(value))}
+          onChange={value =>
+            handleSetParam('pollIntervalTime', value === '' ? undefined : Number.parseInt(value, 10))
+          }
@@
-          onChange={value => handleSetParam('timeout', parseInt(value))}
+          onChange={value =>
+            handleSetParam('timeout', value === '' ? undefined : Number.parseInt(value, 10))
+          }

Also applies to: 55-55, 61-61

♻️ Duplicate comments (6)
packages/connect-examples/shared-constants/package.json (1)

1-10: Expose types and an exports map to fix TS/ESLint resolution.

Add types, exports, files, and mark sideEffects false. This unblocks the import in the example apps.

 {
   "name": "@onekey-internal/shared-constants",
   "version": "1.1.10-alpha.2",
   "private": true,
   "author": "OneKey",
   "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
   "license": "ISC",
   "type": "module",
-  "main": "constants.js"
+  "main": "constants.js",
+  "types": "constants.d.ts",
+  "exports": {
+    ".": {
+      "types": "./constants.d.ts",
+      "default": "./constants.js"
+    }
+  },
+  "files": [
+    "constants.js",
+    "constants.d.ts"
+  ],
+  "sideEffects": false
 }

Add the declaration file:

// packages/connect-examples/shared-constants/constants.d.ts
export function getConnectSrc(): string;
#!/bin/bash
# Verify the JS export exists
rg -n "export\\s+(const|function)\\s+getConnectSrc\\b" packages/connect-examples/shared-constants/constants.*
packages/connect-examples/expo-playground/app/constants/connect.ts (1)

1-1: Import path is correct; ensure shared-constants exposes types/exports.

After updating the shared package as suggested, re-run lint to clear the “import/namespace” error.

#!/bin/bash
yarn lint --max-warnings=0
packages/connect-examples/expo-example/src/constants/connect.ts (1)

2-2: Remove obsolete ESLint disable above.

The import is no longer relative; drop the suppression.

-// eslint-disable-next-line import/no-relative-packages
 import { getConnectSrc } from '@onekey-internal/shared-constants';
patches/react-native-crypto+2.2.0.patch (3)

7-7: Avoid ESM import inside a CommonJS module; use side‑effect require

Prevents Metro/CI interop issues.

-'use strict'
-import { getRandomValues } from 'react-native-get-random-values';
+'use strict'
+// Ensure Web Crypto RNG is registered in RN (Hermes/JSC)
+require('react-native-get-random-values');

9-28: Restoring randomBytes/rng/prng exports to avoid breaking consumers

Removing these is a breaking change. Reintroduce a Node‑compatible randomBytes built on crypto.getRandomValues.

- import { randomBytes } from 'react-native-randombytes'
- exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = randomBytes
+ const { Buffer } = require('buffer');
+ function randomBytes(size, cb) {
+   if (typeof size !== 'number' || size < 0) {
+     const err = new TypeError('size must be a non-negative number');
+     if (typeof cb === 'function') { setTimeout(() => cb(err), 0); return; }
+     throw err;
+   }
+   const g = typeof globalThis === 'object' ? globalThis : (typeof global === 'object' ? global : {});
+   const gv = g.crypto && typeof g.crypto.getRandomValues === 'function' ? g.crypto.getRandomValues : null;
+   const noRngErr = new Error('crypto.getRandomValues is unavailable. Ensure react-native-get-random-values is installed and loaded.');
+   if (!gv) {
+     if (typeof cb === 'function') { setTimeout(() => cb(noRngErr), 0); return; }
+     throw noRngErr;
+   }
+   const MAX = 65536; // Web Crypto max per call
+   const bytes = new Uint8Array(size);
+   for (let off = 0; off < bytes.length; off += MAX) {
+     gv.call(g.crypto, bytes.subarray(off, Math.min(off + MAX, bytes.length)));
+   }
+   const buf = Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
+   if (typeof cb === 'function') { setTimeout(() => cb(null, buf), 0); return; }
+   return buf;
+ }
+ exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = randomBytes

29-36: Harden the global guard; attach polyfill defensively

Support globalThis and global, and only attach if available.

-if (typeof globalThis === 'object') {
-  if (!globalThis.crypto) {
-    globalThis.crypto = {};
-  }
-  if (!globalThis.crypto.getRandomValues) {
-    globalThis.crypto.getRandomValues = getRandomValues;
-  }
-}
+const g = typeof globalThis === 'object' ? globalThis : (typeof global === 'object' ? global : undefined);
+if (g) {
+  if (!g.crypto) g.crypto = {};
+  // Side-effect import should set this; if not, try to attach safely.
+  if (typeof g.crypto.getRandomValues !== 'function') {
+    try {
+      const maybe = require('react-native-get-random-values');
+      const gv = maybe && (maybe.getRandomValues || (maybe.default && maybe.default.getRandomValues));
+      if (typeof gv === 'function') g.crypto.getRandomValues = gv;
+    } catch (_) {
+      // Leave unset; randomBytes will throw a clear error.
+    }
+  }
+}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge Base: Disabled due to data retention organization setting

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1e50f43 and ca7b95f.

📒 Files selected for processing (7)
  • .github/workflows/build-example-android.yml (2 hunks)
  • package.json (1 hunks)
  • packages/connect-examples/expo-example/src/components/CommonParamsView.tsx (1 hunks)
  • packages/connect-examples/expo-example/src/constants/connect.ts (1 hunks)
  • packages/connect-examples/expo-playground/app/constants/connect.ts (1 hunks)
  • packages/connect-examples/shared-constants/package.json (1 hunks)
  • patches/react-native-crypto+2.2.0.patch (1 hunks)
🧰 Additional context used
🪛 ESLint
packages/connect-examples/expo-playground/app/constants/connect.ts

[error] 1-1: Resolve error: typescript with invalid interface loaded as resolver

(import/namespace)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build (22)
  • GitHub Check: lint (22)
🔇 Additional comments (1)
package.json (1)

13-17: Workspace entry LGTM.

New shared-constants workspace is correctly added.

Comment on lines +19 to +24
<CommonInput
label="Passphrase State"
type="text"
value={commonParams.passphraseState ?? ''}
onChange={value => handleSetParam('passphraseState', value)}
/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Validate passphraseState values

If only specific states are valid, consider a select with fixed options to prevent bad inputs.


🧹 Nitpick (assertive)

Localize the “Passphrase State” label

Keep labels consistent with react-intl.

-        <CommonInput
-          label="Passphrase State"
+        <CommonInput
+          label={intl.formatMessage({
+            id: 'label__passphrase_state',
+            defaultMessage: 'Passphrase State',
+          })}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<CommonInput
label="Passphrase State"
type="text"
value={commonParams.passphraseState ?? ''}
onChange={value => handleSetParam('passphraseState', value)}
/>
<CommonInput
label={intl.formatMessage({
id: 'label__passphrase_state',
defaultMessage: 'Passphrase State',
})}
type="text"
value={commonParams.passphraseState ?? ''}
onChange={value => handleSetParam('passphraseState', value)}
/>
🤖 Prompt for AI Agents
In packages/connect-examples/expo-example/src/components/CommonParamsView.tsx
around lines 19 to 24, the hardcoded label "Passphrase State" should be
localized using react-intl; replace the literal string with a formatted message
lookup (e.g., use intl.formatMessage or <FormattedMessage
id="common.passphraseState" defaultMessage="Passphrase State" />) and add the
corresponding message id and defaultMessage to the component's messages bundle
or messages file so the label renders via react-intl.

Comment on lines +31 to +34
label="skipPassphraseCheck"
value={!!commonParams.skipPassphraseCheck}
onToggle={value => handleSetParam('skipPassphraseCheck', value)}
/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Localize the “skipPassphraseCheck” label

Avoid raw strings; align with other labels.

-        <SwitchInput
-          label="skipPassphraseCheck"
+        <SwitchInput
+          label={intl.formatMessage({
+            id: 'label__skip_passphrase_check',
+            defaultMessage: 'Skip passphrase check',
+          })}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
label="skipPassphraseCheck"
value={!!commonParams.skipPassphraseCheck}
onToggle={value => handleSetParam('skipPassphraseCheck', value)}
/>
<SwitchInput
label={intl.formatMessage({
id: 'label__skip_passphrase_check',
defaultMessage: 'Skip passphrase check',
})}
value={!!commonParams.skipPassphraseCheck}
onToggle={value => handleSetParam('skipPassphraseCheck', value)}
/>
🤖 Prompt for AI Agents
In packages/connect-examples/expo-example/src/components/CommonParamsView.tsx
around lines 31 to 34, the Switch label uses a raw string "skipPassphraseCheck";
replace it with the app's localization key like other labels (e.g. use the
existing i18n/t function or labels object) so the label reads
t('skipPassphraseCheck') or labels.common.skipPassphraseCheck (matching the
project pattern), and ensure the translation key exists in the locale files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants