From c158869725558d36d1d24e7b9435b8ccfc1ebe3b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:26:50 -0800 Subject: [PATCH 1/6] chore: bump mobile app version to 2.9.16 (#1746) Update build numbers and deployment timestamps after successful deployment. Co-authored-by: github-actions[bot] --- app/version.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/version.json b/app/version.json index e8600bc29..a2eb7480e 100644 --- a/app/version.json +++ b/app/version.json @@ -1,10 +1,10 @@ { "ios": { - "build": 213, - "lastDeployed": "2026-02-09T22:47:48.603Z" + "build": 214, + "lastDeployed": "2026-02-13T03:05:45.284Z" }, "android": { - "build": 142, - "lastDeployed": "2026-02-10T00:22:34Z" + "build": 143, + "lastDeployed": "2026-02-13T03:05:45.284Z" } } From a632727fee949708b9a16d7a1f8680cdabc45900 Mon Sep 17 00:00:00 2001 From: Justin Hernandez Date: Thu, 12 Feb 2026 19:29:56 -0800 Subject: [PATCH 2/6] Add tech debt baseline snapshot generator and baseline docs (#1743) * Add cruft baseline snapshot * pr feedback * rename cruft to tech deb * improve baseline --- docs/maintenance/tech-debt-baseline.json | 1071 ++++++++++++++++++++++ docs/maintenance/tech-debt-baseline.md | 26 + package.json | 1 + scripts/audit/tech-debt-baseline.mjs | 325 +++++++ 4 files changed, 1423 insertions(+) create mode 100644 docs/maintenance/tech-debt-baseline.json create mode 100644 docs/maintenance/tech-debt-baseline.md create mode 100644 scripts/audit/tech-debt-baseline.mjs diff --git a/docs/maintenance/tech-debt-baseline.json b/docs/maintenance/tech-debt-baseline.json new file mode 100644 index 000000000..152e64ffa --- /dev/null +++ b/docs/maintenance/tech-debt-baseline.json @@ -0,0 +1,1071 @@ +{ + "workspacePatterns": [ + "app", + "circuits", + "common", + "contracts", + "packages/*", + "prover/tests", + "scripts/tests", + "sdk/*" + ], + "workspaceCount": 11, + "workspaces": [ + { + "name": "@selfxyz/mobile-app", + "path": "app", + "dependencies": { + "@babel/runtime": "^7.28.6", + "@ethersproject/shims": "^5.8.0", + "@noble/hashes": "^1.5.0", + "@openpassport/zk-kit-imt": "^0.0.5", + "@openpassport/zk-kit-lean-imt": "^0.0.6", + "@openpassport/zk-kit-smt": "^0.0.1", + "@peculiar/x509": "^1.14.3", + "@react-native-async-storage/async-storage": "^2.2.0", + "@react-native-clipboard/clipboard": "1.16.3", + "@react-native-community/blur": "^4.4.1", + "@react-native-community/netinfo": "^11.4.1", + "@react-native-firebase/app": "^19.0.1", + "@react-native-firebase/messaging": "^19.0.1", + "@react-native-firebase/remote-config": "^19.0.1", + "@react-navigation/native": "^7.0.14", + "@react-navigation/native-stack": "^7.2.0", + "@robinbobin/react-native-google-drive-api-wrapper": "^2.2.3", + "@segment/analytics-react-native": "^2.21.2", + "@segment/sovran-react-native": "^1.1.3", + "@selfxyz/common": "workspace:^", + "@selfxyz/euclid": "^0.6.1", + "@selfxyz/mobile-sdk-alpha": "workspace:^", + "@sentry/react": "^9.32.0", + "@sentry/react-native": "7.0.0", + "@stablelib/cbor": "^2.0.1", + "@sumsub/react-native-mobilesdk-module": "1.40.2", + "@tamagui/animations-css": "1.126.14", + "@tamagui/animations-react-native": "1.126.14", + "@tamagui/config": "1.126.14", + "@tamagui/lucide-icons": "1.126.14", + "@tamagui/toast": "1.126.14", + "@turnkey/api-key-stamper": "^0.5.0", + "@turnkey/core": "1.7.0", + "@turnkey/encoding": "^0.6.0", + "@turnkey/react-native-wallet-kit": "1.1.5", + "@walletconnect/react-native-compat": "^2.23.0", + "@xstate/react": "^5.0.3", + "asn1js": "^3.0.7", + "axios": "^1.13.2", + "buffer": "^6.0.3", + "country-emoji": "^1.5.6", + "elliptic": "^6.6.1", + "ethers": "^6.11.0", + "expo-application": "^7.0.7", + "expo-modules-core": "^2.2.1", + "hash.js": "^1.1.7", + "js-sha1": "^0.7.0", + "js-sha256": "^0.11.1", + "js-sha512": "^0.9.0", + "lottie-react": "^2.4.1", + "lottie-react-native": "7.2.2", + "node-forge": "^1.3.3", + "pkijs": "^3.3.3", + "poseidon-lite": "^0.2.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-native": "0.76.9", + "react-native-app-auth": "^8.0.3", + "react-native-biometrics": "^3.0.1", + "react-native-blur-effect": "^1.1.3", + "react-native-check-version": "^1.3.0", + "react-native-cloud-storage": "^2.2.2", + "react-native-device-info": "^15.0.1", + "react-native-dotenv": "^3.4.11", + "react-native-edge-to-edge": "^1.7.0", + "react-native-gesture-handler": "2.19.0", + "react-native-get-random-values": "^1.11.0", + "react-native-haptic-feedback": "^2.3.3", + "react-native-inappbrowser-reborn": "^3.7.0", + "react-native-keychain": "^10.0.0", + "react-native-linear-gradient": "^2.8.3", + "react-native-localize": "^3.6.1", + "react-native-logs": "^5.5.0", + "react-native-nfc-manager": "3.17.2", + "react-native-passkey": "^3.3.2", + "react-native-passport-reader": "1.0.3", + "react-native-safe-area-context": "^5.6.2", + "react-native-screens": "4.15.3", + "react-native-sqlite-storage": "^6.0.1", + "react-native-svg": "15.12.1", + "react-native-svg-web": "1.0.9", + "react-native-url-polyfill": "^3.0.0", + "react-native-web": "^0.21.2", + "react-native-webview": "^13.16.0", + "react-qr-barcode-scanner": "^2.1.8", + "socket.io-client": "^4.8.3", + "tamagui": "1.126.14", + "uuid": "^11.1.0", + "xstate": "^5.20.2", + "zustand": "^4.5.2" + }, + "devDependencies": { + "@babel/core": "^7.28.6", + "@babel/plugin-syntax-flow": "^7.28.6", + "@babel/plugin-transform-classes": "^7.28.6", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-flow-strip-types": "^7.27.1", + "@babel/plugin-transform-private-methods": "^7.28.6", + "@babel/preset-env": "^7.28.6", + "@babel/preset-react": "^7.28.5", + "@react-native-community/cli": "^16.0.3", + "@react-native/babel-preset": "0.76.9", + "@react-native/eslint-config": "0.76.9", + "@react-native/gradle-plugin": "0.76.9", + "@react-native/metro-config": "0.76.9", + "@react-native/typescript-config": "0.76.9", + "@tamagui/types": "1.126.14", + "@tamagui/vite-plugin": "1.126.14", + "@testing-library/react-native": "^13.3.3", + "@tsconfig/react-native": "^3.0.6", + "@types/bn.js": "^5.2.0", + "@types/dompurify": "^3.2.0", + "@types/elliptic": "^6.4.18", + "@types/jest": "^30.0.0", + "@types/node": "^22.18.3", + "@types/node-forge": "^1.3.14", + "@types/path-browserify": "^1", + "@types/react": "^18.3.4", + "@types/react-dom": "^18.3.0", + "@types/react-native-dotenv": "^0.2.0", + "@types/react-native-sqlite-storage": "^6.0.5", + "@types/react-native-web": "^0", + "@types/react-test-renderer": "^18", + "@typescript-eslint/eslint-plugin": "^8.39.0", + "@typescript-eslint/parser": "^8.39.0", + "@vitejs/plugin-react-swc": "^4.2.2", + "babel-plugin-module-resolver": "^5.0.2", + "babel-plugin-transform-remove-console": "^6.9.4", + "constants-browserify": "^1.0.0", + "dompurify": "^3.3.1", + "eslint": "^8.57.0", + "eslint-config-prettier": "10.1.8", + "eslint-import-resolver-typescript": "^3.7.0", + "eslint-plugin-ft-flow": "^3.0.11", + "eslint-plugin-header": "^3.1.1", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jest": "^29.1.0", + "eslint-plugin-prettier": "^5.2.6", + "eslint-plugin-simple-import-sort": "^12.1.1", + "eslint-plugin-sort-exports": "^0.9.1", + "hermes-eslint": "^0.19.1", + "jest": "^30.2.0", + "path-browserify": "^1.0.1", + "prettier": "^3.5.3", + "prop-types": "^15.8.1", + "react-native-svg-transformer": "^1.5.2", + "react-test-renderer": "^18.3.1", + "rollup-plugin-visualizer": "^6.0.5", + "stream-browserify": "^3.0.0", + "ts-morph": "^22.0.0", + "ts-node": "^10.9.2", + "typescript": "^5.9.3", + "vite": "^7.3.1", + "vite-plugin-svgr": "^4.5.0" + }, + "peerDependencies": {}, + "dependencyCount": { + "dependencies": 90, + "devDependencies": 62, + "peerDependencies": 0, + "total": 152 + }, + "scripts": [ + "analyze:bundle:android", + "analyze:bundle:ios", + "analyze:tree-shaking", + "analyze:tree-shaking:web", + "android", + "android:ci", + "build:deps", + "bump-version:major", + "bump-version:minor", + "bump-version:patch", + "clean", + "clean:android-deps", + "clean:build", + "clean:ios", + "clean:node", + "clean:pod-cache", + "clean:watchman", + "clean:xcode", + "clean:xcode-env-local", + "find:type-imports", + "fmt", + "fmt:fix", + "format", + "ia", + "imports:fix", + "install-app", + "install-app:mobile-deploy", + "install-app:setup", + "ios", + "ios:fastlane-debug", + "jest:clear", + "jest:run", + "lint", + "lint:fix", + "mobile-deploy", + "mobile-deploy:android", + "mobile-deploy:ios", + "mobile-local-deploy", + "mobile-local-deploy:android", + "mobile-local-deploy:ios", + "nice", + "postinstall", + "reinstall", + "release", + "release:major", + "release:minor", + "release:patch", + "setup", + "setup:android-deps", + "start", + "start:clean", + "sync-versions", + "tag:release", + "tag:remove", + "test", + "test:build", + "test:ci", + "test:coverage", + "test:coverage:ci", + "test:e2e:android", + "test:e2e:ios", + "test:fastlane", + "test:tree-shaking", + "test:web-build", + "types", + "watch:sdk", + "web", + "web:build", + "web:preview" + ], + "sourceFiles": { + "byExtension": { + ".cjs": 27, + ".css": 2, + ".js": 10, + ".mjs": 1, + ".py": 1, + ".rb": 8, + ".sh": 6, + ".ts": 189, + ".tsx": 157 + }, + "total": 401 + } + }, + { + "name": "@selfxyz/circuits", + "path": "circuits", + "dependencies": { + "@anon-aadhaar/core": "npm:@selfxyz/anon-aadhaar-core@^0.0.1", + "@noble/curves": "^1.4.2", + "@openpassport/zk-email-circuits": "^6.1.2", + "@openpassport/zk-kit-imt": "^0.0.4", + "@openpassport/zk-kit-lean-imt": "^0.0.4", + "@openpassport/zk-kit-smt": "^0.0.1", + "@selfxyz/common": "workspace:^", + "@zk-email/circuits": "^6.3.2", + "@zk-email/helpers": "^6.1.1", + "@zk-email/jwt-tx-builder-circuits": "0.1.0", + "@zk-email/jwt-tx-builder-helpers": "0.1.0", + "@zk-email/zk-regex-circom": "^1.2.1", + "@zk-kit/binary-merkle-root.circom": "npm:@selfxyz/binary-merkle-root.circom@^0.0.1", + "@zk-kit/circuits": "^1.0.0-beta", + "anon-aadhaar-circuits": "npm:@selfxyz/aa-circuits@^0.0.1", + "asn1": "^0.2.6", + "asn1.js": "^5.4.1", + "asn1js": "^3.0.5", + "chai-as-promised": "^7.1.1", + "circom_tester": "github:remicolin/circom_tester#main", + "circom-bigint": "https://github.com/0xbok/circom-bigint", + "circom-dl": "https://github.com/distributed-lab/circom-dl", + "circomlib": "^2.0.5", + "circomlibjs": "^0.1.7", + "crypto": "^1.0.1", + "dotenv": "^16.4.7", + "elliptic": "^6.5.5", + "hash.js": "^1.1.7", + "js-sha256": "^0.10.1", + "jsrsasign": "^11.1.0", + "modpow": "^1.0.0", + "node-forge": "https://github.com/remicolin/forge", + "poseidon-lite": "^0.2.0", + "snarkjs": "^0.7.1" + }, + "devDependencies": { + "@babel/core": "^7.28.6", + "@types/chai": "4.3.11", + "@types/chai-as-promised": "^7.1.6", + "@types/circomlibjs": "^0.1.6", + "@types/mocha": "^10.0.10", + "@types/node": "^22.18.3", + "@types/node-forge": "^1.3.5", + "@yarnpkg/sdks": "^3.2.0", + "chai": "^4.4.1", + "eslint": "^8.57.0", + "eslint-plugin-import": "^2.31.0", + "mocha": "^10.7.3", + "prettier": "^3.5.3", + "ts-mocha": "^10.0.0", + "tsconfig-paths": "^4.2.0", + "tsx": "^4.21.0", + "typescript": "^5.9.2" + }, + "peerDependencies": {}, + "dependencyCount": { + "dependencies": 34, + "devDependencies": 17, + "peerDependencies": 0, + "total": 51 + }, + "scripts": [ + "build-all", + "build-disclose", + "build-dsc", + "build-gcp-jwt-verifier", + "build-register", + "build-register-id", + "build-register-selfrica", + "build:deps", + "download", + "format", + "install-circuits", + "lint", + "nice", + "test", + "test-base", + "test-custom-hasher", + "test-disclose", + "test-disclose-aadhaar", + "test-disclose-id", + "test-disclose-kyc", + "test-dsc", + "test-ecdsa", + "test-gcp-jwt-verifier", + "test-is-older-than", + "test-is-valid", + "test-not-in-list", + "test-ofac", + "test-qr-extractor", + "test-register", + "test-register-aadhaar", + "test-register-id", + "test-register-kyc", + "test-rsa", + "test-rsa-pss" + ], + "sourceFiles": { + "byExtension": { + ".circom": 257, + ".sh": 4, + ".ts": 33 + }, + "total": 294 + } + }, + { + "name": "@selfxyz/common", + "path": "common", + "dependencies": { + "@anon-aadhaar/core": "npm:@selfxyz/anon-aadhaar-core@^0.0.1", + "@noble/hashes": "^1.5.0", + "@openpassport/zk-kit-imt": "^0.0.5", + "@openpassport/zk-kit-lean-imt": "^0.0.6", + "@openpassport/zk-kit-smt": "^0.0.1", + "@peculiar/x509": "^1.14.3", + "@stablelib/cbor": "^2.0.1", + "@zk-kit/baby-jubjub": "^1.0.3", + "@zk-kit/eddsa-poseidon": "^1.1.0", + "asn1.js": "^5.4.1", + "asn1js": "^3.0.7", + "axios": "^1.7.2", + "buffer": "^6.0.3", + "country-emoji": "^1.5.6", + "elliptic": "^6.5.5", + "ethers": "^6.14.4", + "fs": "^0.0.1-security", + "hash.js": "^1.1.7", + "i18n-iso-countries": "^7.13.0", + "js-sha1": "^0.7.0", + "js-sha256": "^0.11.0", + "js-sha512": "^0.9.0", + "json-to-ts": "^2.1.0", + "jsrsasign": "^11.1.0", + "node-forge": "github:remicolin/forge#17a11a632dd0e50343b3b8393245a2696f78afbb", + "path": "^0.12.7", + "pkijs": "^3.3.3", + "poseidon-lite": "^0.2.0", + "snarkjs": "^0.7.5", + "typescript-parser": "^2.6.1", + "uuid": "^11.1.0" + }, + "devDependencies": { + "@types/js-sha1": "^0.6.3", + "@types/node": "^22.18.3", + "@types/node-forge": "^1.3.10", + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", + "@vitest/ui": "^2.1.8", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-simple-import-sort": "^12.1.1", + "eslint-plugin-sort-exports": "^0.9.1", + "prettier": "^3.5.3", + "tsup": "^8.5.0", + "typescript": "^5.9.3", + "vitest": "^2.1.8" + }, + "peerDependencies": {}, + "dependencyCount": { + "dependencies": 31, + "devDependencies": 16, + "peerDependencies": 0, + "total": 47 + }, + "scripts": [ + "build", + "build:types", + "build:watch", + "format", + "lint", + "lint:imports", + "lint:imports:check", + "nice", + "nice:check", + "postbuild", + "prepublishOnly", + "test", + "test:exports", + "test:scope", + "test:ui", + "test:watch", + "types" + ], + "sourceFiles": { + "byExtension": { + ".cjs": 1, + ".js": 3, + ".mjs": 1, + ".py": 2, + ".sh": 1, + ".ts": 111 + }, + "total": 119 + } + }, + { + "name": "@selfxyz/contracts", + "path": "contracts", + "dependencies": { + "@ashpect/smt": "https://github.com/ashpect/smt#main", + "@eth-optimism/hardhat-ovm": "^0.2.4", + "@nomiclabs/hardhat-ethers": "^2.2.3", + "@openpassport/zk-kit-lean-imt": "^0.0.6", + "@openpassport/zk-kit-smt": "^0.0.1", + "@openzeppelin/contracts": "5.4.0", + "@openzeppelin/contracts-upgradeable": "5.4.0", + "@safe-global/api-kit": "^4.0.1", + "@safe-global/protocol-kit": "^6.1.2", + "@safe-global/safe-core-sdk-types": "^5.1.0", + "@selfxyz/common": "workspace:^", + "@zk-kit/baby-jubjub": "^1.0.3", + "@zk-kit/imt": "^2.0.0-beta.4", + "@zk-kit/imt.sol": "^2.0.0-beta.12", + "@zk-kit/lean-imt": "^2.0.1", + "axios": "^1.6.2", + "circomlibjs": "^0.1.7", + "dotenv": "^16.3.1", + "hardhat-contract-sizer": "^2.10.0", + "node-forge": "^1.3.1", + "poseidon-lite": "^0.3.0", + "poseidon-solidity": "^0.0.5", + "snarkjs": "^0.7.4" + }, + "devDependencies": { + "@nomicfoundation/hardhat-chai-matchers": "^2.0.6", + "@nomicfoundation/hardhat-ethers": "^3.0.5", + "@nomicfoundation/hardhat-ignition": "^0.15.12", + "@nomicfoundation/hardhat-ignition-ethers": "^0.15.12", + "@nomicfoundation/hardhat-network-helpers": "^1.0.10", + "@nomicfoundation/hardhat-toolbox": "^3.0.0", + "@nomicfoundation/hardhat-verify": "^2.0.6", + "@nomicfoundation/ignition-core": "^0.15.12", + "@openzeppelin/hardhat-upgrades": "^3.9.1", + "@typechain/ethers-v6": "^0.4.3", + "@typechain/hardhat": "^8.0.3", + "@types/chai": "^4.3.16", + "@types/circomlibjs": "^0.1.6", + "@types/jest": "^29.5.14", + "@types/mocha": "^10.0.6", + "@types/node": "^22.18.3", + "@types/snarkjs": "^0.7.7", + "chai": "^4.4.1", + "dotenv-cli": "^7.4.2", + "ethers": "^6.12.1", + "hardhat": "^2.22.6", + "hardhat-gas-reporter": "^1.0.10", + "mocha": "^10.7.3", + "mochawesome": "^7.1.3", + "prettier": "3.5.3", + "prettier-plugin-solidity": "^2.1.0", + "solidity-coverage": "^0.8.14", + "ts-node": "^10.9.2", + "tsup": "^8.5.0", + "typechain": "^8.3.2", + "typescript": "^5.9.2" + }, + "peerDependencies": {}, + "dependencyCount": { + "dependencies": 23, + "devDependencies": 31, + "peerDependencies": 0, + "total": 54 + }, + "scripts": [ + "build", + "deploy:all", + "deploy:hub", + "deploy:hub:v2", + "deploy:pcr0", + "deploy:registry", + "deploy:registry:idcard", + "deploy:test:selfverificationroot", + "deploy:verifier:idcard", + "deploy:verifiers:all", + "export-prod", + "find:error", + "format", + "prettier:check", + "prettier:write", + "publish", + "set:hub:v2", + "set:registry", + "set:registry:hub:v2", + "set:registry:idcard", + "set:verifiers:v2", + "show:registry", + "test", + "test:airdrop", + "test:attribute", + "test:coverage", + "test:coverage:local", + "test:disclose", + "test:endtoend", + "test:example", + "test:formatter", + "test:hub", + "test:integration", + "test:local", + "test:pcr", + "test:register", + "test:registry", + "test:sdkcore", + "test:unit", + "test:v2", + "test:verifyall", + "test:view", + "types", + "update:cscaroot", + "update:hub", + "update:ofacroot", + "update:pcr0", + "upgrade", + "upgrade:history", + "upgrade:hub", + "upgrade:registry", + "upgrade:status" + ], + "sourceFiles": { + "byExtension": { + ".sh": 5, + ".sol": 160, + ".ts": 77 + }, + "total": 242 + } + }, + { + "name": "@selfxyz/mobile-sdk-alpha", + "path": "packages/mobile-sdk-alpha", + "dependencies": { + "@babel/runtime": "^7.28.6", + "@selfxyz/common": "workspace:^", + "@selfxyz/euclid": "^0.6.1", + "@xstate/react": "^5.0.5", + "node-forge": "^1.3.3", + "react-native-nfc-manager": "^3.17.2", + "react-native-svg-circle-country-flags": "^0.2.2", + "socket.io-client": "^4.8.3", + "uuid": "^11.1.0", + "xstate": "^5.20.2", + "zustand": "^4.5.2" + }, + "devDependencies": { + "@openpassport/zk-kit-lean-imt": "^0.0.6", + "@testing-library/react": "^14.1.2", + "@types/react": "^18.3.4", + "@types/react-dom": "^18.3.0", + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", + "eslint": "^8.57.0", + "eslint-config-prettier": "^10.1.8", + "eslint-import-resolver-typescript": "^4.4.4", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-prettier": "^5.5.4", + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-simple-import-sort": "^12.1.1", + "eslint-plugin-sort-exports": "^0.9.1", + "jsdom": "^25.0.1", + "lottie-react-native": "7.2.2", + "poseidon-lite": "^0.3.0", + "prettier": "^3.5.3", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-native": "0.76.9", + "react-native-blur-effect": "^1.1.3", + "react-native-haptic-feedback": "^2.3.3", + "react-native-localize": "^3.6.1", + "react-native-svg": "15.12.1", + "react-native-web": "^0.21.2", + "react-native-webview": "13.16.0", + "tsup": "^8.0.1", + "typescript": "^5.9.3", + "vitest": "^2.1.8" + }, + "peerDependencies": { + "lottie-react-native": "7.2.2", + "react": "^18.3.1", + "react-native": "0.76.9", + "react-native-blur-effect": "^1.1.3", + "react-native-haptic-feedback": "*", + "react-native-localize": "*", + "react-native-svg": "*", + "react-native-webview": "^13.16.0" + }, + "dependencyCount": { + "dependencies": 11, + "devDependencies": 30, + "peerDependencies": 8, + "total": 49 + }, + "scripts": [ + "build", + "build:android", + "build:ios", + "build:ts-only", + "fmt", + "fmt:fix", + "format", + "lint", + "lint:fix", + "nice", + "postbuild", + "prepublishOnly", + "report:exports", + "test", + "test:build", + "typecheck", + "types", + "validate:exports", + "validate:pkg", + "watch" + ], + "sourceFiles": { + "byExtension": { + ".cjs": 3, + ".js": 1, + ".mjs": 5, + ".sh": 2, + ".ts": 91, + ".tsx": 43 + }, + "total": 145 + } + }, + { + "name": "mobile-sdk-demo", + "path": "packages/mobile-sdk-demo", + "dependencies": { + "@babel/runtime": "^7.28.6", + "@faker-js/faker": "^10.0.0", + "@noble/hashes": "^1.5.0", + "@react-native-async-storage/async-storage": "^2.2.0", + "@selfxyz/common": "workspace:*", + "@selfxyz/mobile-sdk-alpha": "workspace:*", + "assert": "^2.1.0", + "buffer": "^6.0.3", + "constants-browserify": "^1.0.0", + "ethers": "^6.11.0", + "lottie-react": "^2.4.1", + "lottie-react-native": "7.2.2", + "react": "^18.3.1", + "react-native": "0.76.9", + "react-native-blur-effect": "1.1.3", + "react-native-get-random-values": "^1.11.0", + "react-native-haptic-feedback": "^2.3.3", + "react-native-keychain": "^10.0.0", + "react-native-localize": "^3.6.1", + "react-native-safe-area-context": "^5.6.2", + "react-native-svg": "15.12.1", + "react-native-vector-icons": "^10.3.0", + "react-native-webview": "13.16.0", + "stream-browserify": "^3.0.0", + "util": "^0.12.5" + }, + "devDependencies": { + "@babel/core": "^7.28.6", + "@react-native-community/cli": "^16.0.3", + "@react-native/gradle-plugin": "0.76.9", + "@react-native/metro-config": "0.76.9", + "@testing-library/dom": "^10.4.1", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.1.0", + "@testing-library/user-event": "^14.5.2", + "@tsconfig/react-native": "^3.0.6", + "@types/node": "^22.18.3", + "@types/react": "^18.3.4", + "@types/react-dom": "^18.3.0", + "@types/react-native-vector-icons": "^6.4.18", + "@typescript-eslint/eslint-plugin": "^8.44.0", + "@typescript-eslint/parser": "^8.44.0", + "@vitest/ui": "^2.1.8", + "eslint": "^8.57.0", + "eslint-config-prettier": "^10.1.8", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-prettier": "^5.5.4", + "eslint-plugin-simple-import-sort": "^12.1.1", + "eslint-plugin-sort-exports": "^0.9.1", + "find-yarn-workspace-root": "^2.0.0", + "jsdom": "^25.0.1", + "metro-react-native-babel-preset": "0.76.9", + "prettier": "^3.6.2", + "react-dom": "^18.3.1", + "react-native-svg-transformer": "^1.5.2", + "typescript": "^5.9.3", + "vitest": "^2.1.8" + }, + "peerDependencies": {}, + "dependencyCount": { + "dependencies": 25, + "devDependencies": 31, + "peerDependencies": 0, + "total": 56 + }, + "scripts": [ + "analyze:bundle:android", + "analyze:bundle:ios", + "android", + "build", + "clean", + "format", + "ia", + "install-app", + "ios", + "lint", + "lint:fix", + "nice", + "postinstall", + "preandroid", + "prebuild", + "preios", + "reinstall", + "start", + "test", + "test:e2e:android", + "test:watch", + "types" + ], + "sourceFiles": { + "byExtension": { + ".cjs": 5, + ".js": 2, + ".sh": 1, + ".ts": 24, + ".tsx": 34 + }, + "total": 66 + } + }, + { + "name": "scripts-tests", + "path": "scripts/tests", + "dependencies": {}, + "devDependencies": {}, + "peerDependencies": {}, + "dependencyCount": { + "dependencies": 0, + "devDependencies": 0, + "peerDependencies": 0, + "total": 0 + }, + "scripts": [ + "test", + "test:license-headers" + ], + "sourceFiles": { + "byExtension": { + ".mjs": 2 + }, + "total": 2 + } + }, + { + "name": "@selfxyz/core", + "path": "sdk/core", + "dependencies": { + "@selfxyz/common": "workspace:^", + "ethers": "^6.13.5", + "js-sha1": "^0.7.0", + "js-sha256": "^0.11.0", + "js-sha512": "^0.9.0", + "node-forge": "^1.3.3", + "poseidon-lite": "^0.3.0", + "snarkjs": "^0.7.4", + "uuid": "^11.1.0" + }, + "devDependencies": { + "@typechain/ethers-v6": "^0.5.1", + "@types/chai": "^4.3.6", + "@types/chai-as-promised": "^7.1.8", + "@types/circomlibjs": "^0.1.6", + "@types/expect": "^24.3.0", + "@types/mocha": "^10.0.6", + "@types/node": "^22.18.3", + "@types/node-forge": "^1.3.5", + "@types/snarkjs": "^0.7.8", + "axios": "^1.7.2", + "prettier": "^3.5.3", + "ts-loader": "^9.5.1", + "ts-node": "^10.9.2", + "tsup": "^8.5.0", + "typechain": "^8.3.2", + "typescript": "^5.9.3", + "webpack": "^5.95.0" + }, + "peerDependencies": {}, + "dependencyCount": { + "dependencies": 9, + "devDependencies": 17, + "peerDependencies": 0, + "total": 26 + }, + "scripts": [ + "build", + "build:deps", + "copy-abi", + "format", + "install-sdk", + "lint", + "prepublishOnly", + "publish", + "test", + "types" + ], + "sourceFiles": { + "byExtension": { + ".sh": 1, + ".ts": 18 + }, + "total": 19 + } + }, + { + "name": "@selfxyz/qrcode", + "path": "sdk/qrcode", + "dependencies": { + "@selfxyz/sdk-common": "workspace:^", + "js-sha1": "^0.7.0", + "js-sha256": "^0.11.0", + "js-sha512": "^0.9.0", + "lottie-react": "^2.4.0", + "node-forge": "^1.3.3", + "poseidon-lite": "^0.3.0", + "qrcode.react": "^4.1.0", + "react-spinners": "^0.14.1", + "socket.io-client": "^4.8.3", + "uuid": "^11.1.0" + }, + "devDependencies": { + "@size-limit/preset-big-lib": "^11.2.0", + "@types/node": "^22.18.3", + "@types/node-forge": "^1", + "@types/react": ">=18.0.0 <20.0.0", + "@types/react-dom": ">=18.0.0 <20.0.0", + "@types/uuid": "^10.0.0", + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^4.4.4", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-simple-import-sort": "^12.1.1", + "eslint-plugin-sort-exports": "^0.9.1", + "mocha": "^10.7.3", + "prettier": "^3.5.3", + "react": ">=18.0.0 <20.0.0", + "react-dom": ">=18.0.0 <20.0.0", + "size-limit": "^11.2.0", + "ts-loader": "^9.5.1", + "ts-mocha": "^10.0.0", + "ts-node": "^10.9.2", + "tsup": "^8.5.0", + "typescript": "^5.9.3", + "webpack": "^5.95.0" + }, + "peerDependencies": { + "lottie-react": "^2.4.0", + "react": ">=18.0.0 <20.0.0", + "react-dom": ">=18.0.0 <20.0.0" + }, + "dependencyCount": { + "dependencies": 11, + "devDependencies": 26, + "peerDependencies": 3, + "total": 40 + }, + "scripts": [ + "build", + "build:deps", + "build:types", + "build:watch", + "format", + "install-sdk", + "lint", + "lint:imports", + "lint:imports:check", + "nice", + "nice:check", + "postbuild", + "prepublishOnly", + "publish", + "test", + "types" + ], + "sourceFiles": { + "byExtension": { + ".cjs": 1, + ".js": 1, + ".mjs": 1, + ".ts": 7, + ".tsx": 3 + }, + "total": 13 + } + }, + { + "name": "@selfxyz/qrcode-angular", + "path": "sdk/qrcode-angular", + "dependencies": { + "angularx-qrcode": "^20.0.0", + "lottie-web": "^5.12.2", + "socket.io-client": "^4.8.3", + "uuid": "^11.1.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^20.3.0", + "@angular-eslint/builder": "^20.3.0", + "@angular-eslint/eslint-plugin": "^20.3.0", + "@angular-eslint/eslint-plugin-template": "^20.3.0", + "@angular-eslint/schematics": "^20.3.0", + "@angular-eslint/template-parser": "^20.3.0", + "@angular/animations": "^20.3.0", + "@angular/cli": "^20.3.0", + "@angular/common": "^20.3.0", + "@angular/compiler": "^20.3.0", + "@angular/compiler-cli": "^20.3.0", + "@angular/core": "^20.3.0", + "@angular/platform-browser": "^20.3.0", + "@angular/platform-browser-dynamic": "^20.3.0", + "@types/node": "^22.0.0", + "@types/uuid": "^10.0.0", + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", + "@typescript-eslint/types": "^8.0.0", + "@typescript-eslint/utils": "^8.0.0", + "eslint": "^8.57.0", + "ng-packagr": "^20.3.0", + "ngx-lottie": "^20.0.0", + "prettier": "^3.5.3", + "rxjs": "^7.8.0", + "tslib": "^2.6.0", + "typescript": "~5.9.3", + "zone.js": "^0.15.0" + }, + "peerDependencies": { + "@angular/animations": "^20.3.0", + "@angular/common": "^20.3.0", + "@angular/core": "^20.3.0", + "ngx-lottie": "^20.0.0", + "rxjs": "^7.8.0" + }, + "dependencyCount": { + "dependencies": 4, + "devDependencies": 28, + "peerDependencies": 5, + "total": 37 + }, + "scripts": [ + "build", + "build:deps", + "build:watch", + "format", + "lint", + "lint:fix", + "nice", + "prepublishOnly", + "publish", + "test" + ], + "sourceFiles": { + "byExtension": { + ".cjs": 1, + ".css": 2, + ".js": 1, + ".ts": 10 + }, + "total": 14 + } + }, + { + "name": "@selfxyz/sdk-common", + "path": "sdk/sdk-common", + "dependencies": { + "uuid": "^13.0.0" + }, + "devDependencies": { + "typescript": "^5.9.3" + }, + "peerDependencies": {}, + "dependencyCount": { + "dependencies": 1, + "devDependencies": 1, + "peerDependencies": 0, + "total": 2 + }, + "scripts": [ + "build", + "test" + ], + "sourceFiles": { + "byExtension": { + ".ts": 1 + }, + "total": 1 + } + } + ] +} diff --git a/docs/maintenance/tech-debt-baseline.md b/docs/maintenance/tech-debt-baseline.md new file mode 100644 index 000000000..fa2bb9886 --- /dev/null +++ b/docs/maintenance/tech-debt-baseline.md @@ -0,0 +1,26 @@ +# Tech Debt Baseline Snapshot + +Generated from `package.json` workspaces. This file is intended as an immutable baseline for cleanup PRs. + +## Top 10 largest workspaces by source-file count + +- `app` (401 source files, 152 deps) +- `circuits` (294 source files, 51 deps) +- `contracts` (242 source files, 54 deps) +- `packages/mobile-sdk-alpha` (145 source files, 49 deps) +- `common` (119 source files, 47 deps) +- `packages/mobile-sdk-demo` (66 source files, 56 deps) +- `sdk/core` (19 source files, 26 deps) +- `sdk/qrcode-angular` (14 source files, 37 deps) +- `sdk/qrcode` (13 source files, 40 deps) +- `scripts/tests` (2 source files, 0 deps) + +## Workspaces with no `test` script + +- None + +## Workspaces with unusually large dependency sets + +- Threshold: >= 85 total dependencies (mean + 1σ, minimum 50). +- `app`: 152 total (90 deps, 62 devDeps, 0 peerDeps) + diff --git a/package.json b/package.json index ac43b47c7..eb2b8daa9 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ ] }, "scripts": { + "audit:tech-debt": "node scripts/audit/tech-debt-baseline.mjs", "build": "yarn workspaces foreach --topological-dev --parallel --exclude @selfxyz/contracts --exclude @selfxyz/circuits --exclude mobile-sdk-demo -i --all run build", "build:demo": "yarn workspace mobile-sdk-demo build", "build:mobile-sdk": "yarn workspace @selfxyz/mobile-sdk-alpha build", diff --git a/scripts/audit/tech-debt-baseline.mjs b/scripts/audit/tech-debt-baseline.mjs new file mode 100644 index 000000000..bba5cb8d3 --- /dev/null +++ b/scripts/audit/tech-debt-baseline.mjs @@ -0,0 +1,325 @@ +#!/usr/bin/env node +import { promises as fs } from 'fs'; +import path from 'path'; + +const ROOT_DIR = process.cwd(); +const ROOT_PACKAGE_JSON_PATH = path.join(ROOT_DIR, 'package.json'); +const OUTPUT_JSON_PATH = path.join( + ROOT_DIR, + 'docs', + 'maintenance', + 'tech-debt-baseline.json', +); +const OUTPUT_MARKDOWN_PATH = path.join( + ROOT_DIR, + 'docs', + 'maintenance', + 'tech-debt-baseline.md', +); + +const IGNORED_DIRECTORIES = new Set([ + '__generated__', + '.cache', + '.git', + '.gradle', + '.next', + '.turbo', + '.yarn', + 'android', + 'artifacts', + 'build', + 'cache', + 'Carthage', + 'coverage', + 'DerivedData', + 'dist', + 'generated', + 'ios', + 'node_modules', + 'out', + 'Pods', + 'typechain-types', + 'vendor', +]); + +const SOURCE_EXTENSIONS = new Set([ + '.cjs', + '.circom', + '.css', + '.go', + '.h', + '.hpp', + '.java', + '.js', + '.jsx', + '.kt', + '.kts', + '.mjs', + '.noir', + '.py', + '.rb', + '.rs', + '.sh', + '.sol', + '.swift', + '.ts', + '.tsx', + '.vue', +]); + +function sortObjectKeys(obj = {}) { + const sortedEntries = Object.entries(obj).sort(([a], [b]) => + a.localeCompare(b), + ); + return Object.fromEntries(sortedEntries); +} + +function wildcardToRegex(segment) { + const escaped = segment + .replace(/[.+?^${}()|[\]\\]/g, '\\$&') + .replace(/\*/g, '[^/]*'); + return new RegExp(`^${escaped}$`); +} + +async function expandWorkspacePattern(rootDir, pattern) { + const segments = pattern.split('/').filter(Boolean); + + async function walkSegments(currentDir, segmentIndex) { + if (segmentIndex >= segments.length) { + return [currentDir]; + } + + const currentSegment = segments[segmentIndex]; + const hasWildcard = currentSegment.includes('*'); + + if (!hasWildcard) { + const nextDir = path.join(currentDir, currentSegment); + try { + const stat = await fs.stat(nextDir); + if (!stat.isDirectory()) return []; + } catch { + return []; + } + return walkSegments(nextDir, segmentIndex + 1); + } + + const matcher = wildcardToRegex(currentSegment); + const entries = await fs.readdir(currentDir, { withFileTypes: true }); + const matches = entries + .filter(entry => entry.isDirectory() && matcher.test(entry.name)) + .map(entry => path.join(currentDir, entry.name)); + + const expanded = await Promise.all( + matches.map(matchedDir => walkSegments(matchedDir, segmentIndex + 1)), + ); + + return expanded.flat(); + } + + return walkSegments(rootDir, 0); +} + +async function getWorkspaceDirectories(rootDir, workspacePatterns) { + const allMatches = await Promise.all( + workspacePatterns.map(pattern => expandWorkspacePattern(rootDir, pattern)), + ); + + const candidateDirs = [...new Set(allMatches.flat())]; + const workspaceDirs = []; + + for (const dir of candidateDirs) { + const packageJsonPath = path.join(dir, 'package.json'); + try { + await fs.access(packageJsonPath); + workspaceDirs.push(dir); + } catch { + // Skip directories without package.json. + } + } + + return workspaceDirs.sort((a, b) => a.localeCompare(b)); +} + +async function collectSourceFileCounts(workspaceDir) { + const extensionCounts = {}; + + async function walk(currentDir) { + const entries = await fs.readdir(currentDir, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = path.join(currentDir, entry.name); + + if (entry.isDirectory()) { + if (IGNORED_DIRECTORIES.has(entry.name)) continue; + await walk(fullPath); + continue; + } + + if (!entry.isFile()) continue; + + const extension = path.extname(entry.name).toLowerCase(); + if (!SOURCE_EXTENSIONS.has(extension)) continue; + + extensionCounts[extension] = (extensionCounts[extension] || 0) + 1; + } + } + + await walk(workspaceDir); + + const sortedExtensionCounts = sortObjectKeys(extensionCounts); + const totalSourceFiles = Object.values(sortedExtensionCounts).reduce( + (sum, count) => sum + count, + 0, + ); + + return { extensionCounts: sortedExtensionCounts, totalSourceFiles }; +} + +function buildMarkdownReport(report) { + const lines = []; + const topLargest = [...report.workspaces] + .sort((a, b) => b.sourceFiles.total - a.sourceFiles.total) + .slice(0, 10); + + const noTestScript = report.workspaces.filter( + workspace => !workspace.scripts.includes('test'), + ); + + const averageDeps = + report.workspaces.reduce((sum, ws) => sum + ws.dependencyCount.total, 0) / + Math.max(report.workspaces.length, 1); + + const variance = + report.workspaces.reduce( + (sum, ws) => sum + (ws.dependencyCount.total - averageDeps) ** 2, + 0, + ) / Math.max(report.workspaces.length, 1); + + const standardDeviation = Math.sqrt(variance); + const unusualThreshold = Math.max( + 50, + Math.round(averageDeps + standardDeviation), + ); + + const unusuallyLargeDeps = report.workspaces.filter( + workspace => workspace.dependencyCount.total >= unusualThreshold, + ); + + lines.push('# Tech Debt Baseline Snapshot'); + lines.push(''); + lines.push( + 'Generated from `package.json` workspaces. This file is intended as an immutable baseline for cleanup PRs.', + ); + lines.push(''); + + lines.push('## Top 10 largest workspaces by source-file count'); + lines.push(''); + for (const workspace of topLargest) { + lines.push( + `- \`${workspace.path}\` (${workspace.sourceFiles.total} source files, ${workspace.dependencyCount.total} deps)`, + ); + } + + lines.push(''); + lines.push('## Workspaces with no `test` script'); + lines.push(''); + if (noTestScript.length === 0) { + lines.push('- None'); + } else { + for (const workspace of noTestScript) { + lines.push(`- \`${workspace.path}\``); + } + } + + lines.push(''); + lines.push('## Workspaces with unusually large dependency sets'); + lines.push(''); + lines.push( + `- Threshold: >= ${unusualThreshold} total dependencies (mean + 1σ, minimum 50).`, + ); + if (unusuallyLargeDeps.length === 0) { + lines.push('- None'); + } else { + for (const workspace of unusuallyLargeDeps) { + lines.push( + `- \`${workspace.path}\`: ${workspace.dependencyCount.total} total (${workspace.dependencyCount.dependencies} deps, ${workspace.dependencyCount.devDependencies} devDeps, ${workspace.dependencyCount.peerDependencies} peerDeps)`, + ); + } + } + + lines.push(''); + + return `${lines.join('\n')}\n`; +} + +async function main() { + const rootPackageJson = JSON.parse( + await fs.readFile(ROOT_PACKAGE_JSON_PATH, 'utf8'), + ); + const workspacePatterns = rootPackageJson.workspaces?.packages; + + if (!Array.isArray(workspacePatterns) || workspacePatterns.length === 0) { + throw new Error('Root package.json does not define workspaces.packages.'); + } + + const workspaceDirs = await getWorkspaceDirectories( + ROOT_DIR, + workspacePatterns, + ); + + const workspaces = []; + for (const workspaceDir of workspaceDirs) { + const packageJsonPath = path.join(workspaceDir, 'package.json'); + const packageData = JSON.parse(await fs.readFile(packageJsonPath, 'utf8')); + const relativePath = path.relative(ROOT_DIR, workspaceDir) || '.'; + const sourceFiles = await collectSourceFileCounts(workspaceDir); + + const dependencies = sortObjectKeys(packageData.dependencies || {}); + const devDependencies = sortObjectKeys(packageData.devDependencies || {}); + const peerDependencies = sortObjectKeys(packageData.peerDependencies || {}); + + workspaces.push({ + name: packageData.name || relativePath, + path: relativePath, + dependencies, + devDependencies, + peerDependencies, + dependencyCount: { + dependencies: Object.keys(dependencies).length, + devDependencies: Object.keys(devDependencies).length, + peerDependencies: Object.keys(peerDependencies).length, + total: + Object.keys(dependencies).length + + Object.keys(devDependencies).length + + Object.keys(peerDependencies).length, + }, + scripts: Object.keys(packageData.scripts || {}).sort((a, b) => + a.localeCompare(b), + ), + sourceFiles: { + byExtension: sourceFiles.extensionCounts, + total: sourceFiles.totalSourceFiles, + }, + }); + } + + const report = { + workspacePatterns, + workspaceCount: workspaces.length, + workspaces, + }; + + const markdown = buildMarkdownReport(report); + + await fs.mkdir(path.dirname(OUTPUT_JSON_PATH), { recursive: true }); + await fs.writeFile(OUTPUT_JSON_PATH, `${JSON.stringify(report, null, 2)}\n`); + await fs.writeFile(OUTPUT_MARKDOWN_PATH, markdown); + + console.log(`Wrote ${path.relative(ROOT_DIR, OUTPUT_JSON_PATH)}`); + console.log(`Wrote ${path.relative(ROOT_DIR, OUTPUT_MARKDOWN_PATH)}`); +} + +main().catch(error => { + console.error(error); + process.exitCode = 1; +}); From 3576682e59f84886586d8e4fa0f53f47bca9f4db Mon Sep 17 00:00:00 2001 From: Nesopie <87437291+Nesopie@users.noreply.github.com> Date: Fri, 13 Feb 2026 10:58:12 +0530 Subject: [PATCH 3/6] chore: revert to aadhaar fix (#1736) * chore: revert to aadhaar fix * fix: tests --- .../circuits/register/register_aadhaar.circom | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/circuits/circuits/register/register_aadhaar.circom b/circuits/circuits/register/register_aadhaar.circom index 757ff77f1..a51b8dcfb 100644 --- a/circuits/circuits/register/register_aadhaar.circom +++ b/circuits/circuits/register/register_aadhaar.circom @@ -114,16 +114,15 @@ template REGISTER_AADHAAR(n, k, maxDataLength){ component qrDataHasher = PackBytesAndPoseidon(maxDataLength); - qrDataHasher.in <== qrDataPadded; - // for (var i = 0; i < 9; i++){ - // qrDataHasher.in[i] <== qrDataPadded[i]; - // } - // for (var i = 9; i < 26; i++) { - // qrDataHasher.in[i] <== 0; - // } - // for (var i = 26; i < maxDataLength; i++){ - // qrDataHasher.in[i] <== qrDataPadded[i]; - // } + for (var i = 0; i < 9; i++){ + qrDataHasher.in[i] <== qrDataPadded[i]; + } + for (var i = 9; i < 26; i++) { + qrDataHasher.in[i] <== 0; + } + for (var i = 26; i < maxDataLength; i++){ + qrDataHasher.in[i] <== qrDataPadded[i]; + } // Generate commitment component packedCommitment = PackBytesAndPoseidon(42 + 62); From 3298e13e60a3f8c65bb90fcc6b8dc6d5b82885b4 Mon Sep 17 00:00:00 2001 From: Evi Nova <66773372+Tranquil-Flow@users.noreply.github.com> Date: Sat, 14 Feb 2026 09:34:08 +1000 Subject: [PATCH 4/6] refactor: remove blur on document when selected + show old view ID data (#1747) * refactor: remove blur on document when selected * fix: show original 'view ID data' --- app/src/components/homescreen/IdCard.tsx | 382 +++++++++++++++++- .../documents/management/IdDetailsScreen.tsx | 42 +- 2 files changed, 390 insertions(+), 34 deletions(-) diff --git a/app/src/components/homescreen/IdCard.tsx b/app/src/components/homescreen/IdCard.tsx index afdf842ad..bd0706a9e 100644 --- a/app/src/components/homescreen/IdCard.tsx +++ b/app/src/components/homescreen/IdCard.tsx @@ -2,11 +2,10 @@ // SPDX-License-Identifier: BUSL-1.1 // NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. -import type { FC } from 'react'; -import React, { useCallback } from 'react'; -import { Image, Pressable, StyleSheet } from 'react-native'; +import React, { type FC, useCallback } from 'react'; +import { Dimensions, Image, Pressable, StyleSheet } from 'react-native'; import LinearGradient from 'react-native-linear-gradient'; -import { Text, XStack, YStack } from 'tamagui'; +import { Separator, Text, XStack, YStack } from 'tamagui'; import { useNavigation } from '@react-navigation/native'; import type { AadhaarData } from '@selfxyz/common'; @@ -20,11 +19,18 @@ import { import { WarningTriangleIcon } from '@selfxyz/euclid/dist/components/icons/WarningTriangleIcon'; import { RoundFlag } from '@selfxyz/mobile-sdk-alpha/components'; import { + black, red600, + slate100, + slate300, + slate400, + slate500, white, yellow500, } from '@selfxyz/mobile-sdk-alpha/constants/colors'; import { dinot, plexMono } from '@selfxyz/mobile-sdk-alpha/constants/fonts'; +import AadhaarIcon from '@selfxyz/mobile-sdk-alpha/svgs/icons/aadhaar.svg'; +import EPassport from '@selfxyz/mobile-sdk-alpha/svgs/icons/epassport.svg'; import CardBackgroundId1 from '@/assets/images/card_background_id1.png'; import CardBackgroundId2 from '@/assets/images/card_background_id2.png'; @@ -34,14 +40,20 @@ import CardBackgroundId5 from '@/assets/images/card_background_id5.png'; import CardBackgroundId6 from '@/assets/images/card_background_id6.png'; import DevCardLogo from '@/assets/images/dev_card_logo.svg'; import DevCardWave from '@/assets/images/dev_card_wave.svg'; +import LogoGray from '@/assets/images/logo_gray.svg'; import SelfLogoPending from '@/assets/images/self_logo_pending.svg'; import WaveOverlay from '@/assets/images/wave_overlay.png'; import { getSecurityLevel } from '@/components/homescreen/cardSecurityBadge'; import { cardStyles } from '@/components/homescreen/cardStyles'; import KycIdCard from '@/components/homescreen/KycIdCard'; +import { SvgXml } from '@/components/homescreen/SvgXmlWrapper'; import { useCardDimensions } from '@/hooks/useCardDimensions'; import { getBackgroundIndex } from '@/utils/cardBackgroundSelector'; -import { getDocumentAttributes } from '@/utils/documentAttributes'; +import { + formatDateFromYYMMDD, + getDocumentAttributes, + getNameAndSurname, +} from '@/utils/documentAttributes'; import { registerModalCallbacks } from '@/utils/modalCallbackRegistry'; const CARD_BACKGROUNDS = [ @@ -282,6 +294,12 @@ const getCountryDemonym = (code: string): string => { return COUNTRY_DEMONYMS[upperCode] || upperCode; }; +const logoSvg = ` + + + +`; + interface IdCardLayoutAttributes { idDocument: PassportData | AadhaarData | KycData | null; selected: boolean; @@ -356,6 +374,331 @@ const IdCardLayout: FC = ({