mirror of
https://github.com/selfxyz/self.git
synced 2026-01-09 14:48:06 -05:00
* 2.9 release * 2.9 release * Remove debug console logs from generateTEEInputsRegister function in registerInputs.ts * parse only the passport data during the dsc step * Add ReferralScreen and integrate referral functionality - Introduced ReferralScreen for sharing referral links via messages, WhatsApp, and clipboard. - Updated navigation to include ReferralScreen in the home stack. - Added new icons for sharing and messaging. - Enhanced points utility functions to check user identity document registration and points disclosure status. - Minor adjustments to existing components for better integration with the new referral feature. * fix types * fix font * fix vertical spacing * save current abstraction * clean up linking * clean up spurious ai slop comments * add dinot bold font * minify animations * update fonts and add placeholder animation * fix pipelines * fix order * Update dependencies and enhance Points component functionality - Added `@react-native-masked-view/masked-view` and `react-native-linear-gradient` to dependencies for improved UI components. - Refactored `PointHistoryList` to accept `ListHeaderComponent` and `onRefreshRef` props for better integration with parent components. - Enhanced `Points` component to manage notification and backup point events, including user feedback through modals. - Updated navigation to use `PointsNavBar` for a more cohesive user experience. - Introduced new utility functions for managing incoming points and point event records. * update lock * update lock and project settings * fix line height for android * save wip referral message fix and deeplink setup * Fix whatsapp link (#1352) * add 2 new lines * use path based param instead of query string * use staging url for now * SELF-1089: Fix black screen on Points (#1351) * Fix black screen on Points * Fix: black screen on Referral Page * fix: prevent BlurView from displaying when IdDetailsScreen loses focus * Fix Android message share (#1355) * Referral flow (#1354) * SELF-1139: update getUserAddress() (#1353) * update getUserAddress() * rename getUserAddress to getPointsAddress * [SELF-1098, SELF-1099] polish gratification screen post referrer update history (#1356) * fix: mark document as registered after restoring secret (#1350) * update lock * create useRegisterReferral hook and test * add referral message test * save wip register referral flow request * use register referral from the home screen * fix typing and sort screens * fix linting issues * register poitns and update tests * use package * fix tests * simplify HomeScreen with hooks * fix tests * address tests * abstract points logic, fix types and linting * add test referral flow hook * coderabbit feedback: fix refereral logic issues, remove sensitive logs * move test referral flow button to dev settings screen * close modal after referring and viewing gratification screen * fix tests, remove alert, format --------- Co-authored-by: Seshanth.S <35675963+seshanthS@users.noreply.github.com> * add gratification bg; use safe bottom padding hook on home screen * prep 2.7.4 as 2.9.0 * manually bump version for custom deploy * match version code * fix types * formatting * fix tests * SELF-1144 - use real points on home screen and improve points screen (#1361) * fix whitespace * move effects for fetching points and incoming points to hooks, add items to deps array so that they refresh when we expect points to change. * cleanup * Add events for new Points Flow (#1362) * remove deeplinkCallback from pointsSelfApp. (#1365) * fix pipelines * SELF-978: wire cloudbackup with points (#1360) * wire cloudbackup with points * wire cloudbackup with points * Remove redundant setSelfPoints() * add signature and simplify POST api requests (#1367) * add signature and simplify POST api requests * better gitleaks ignore * update toml * have gitguardian ignore gitleaks * add buffer lib * update api with 202 success code * update scope and contract-address (#1366) * fix navigation test * SELF-915: Setup and add turnkey utils (#1314) * Setup and add turnkey utils * update CloudBackupScreen * fix: turnkey * add yarn.lock * lint * add podfile.lock * fix deeplink * fix tests: mock turnkey * yarn nice * update .gitleaksignore * patch react-native-svg * fix patch-package * fix lineHeight * points.tsx: fix lineHeight * fix: recover with turnkey disabled state * fix turnkey flow * fix: address generation * minify animations (#1368) * fix pipelines * fix false positives * fix gitguardian --------- Co-authored-by: Justin Hernandez <justin.hernandez@self.xyz> * enable turnkey only on success * use prod url * fix tests and update mocks * update version and fastlane readme * pointsSelfApp: update scope * bump android version to 117 * incremenet timestamp * abstract points css, hide explore button for now, add points guardrail * better logic * simplify point event list data acquisition (#1375) * simplify point event list data acquisition * explain * Remove BlurView in Points.tsx * Move Points and IncomingPoints to the Point Events Store (#1363) * add polling for event processing. atomically update store state * handle failed states and use real backend api * improve concurrency reliability of pointevents * move points to the store * refresh all points on pull * add points tracking events * fix imports * fix headers * fix import * fix misspelling * enable apps link * remove __DEV__ logging * remove additional referall dev mode features * Add turnkey env * don't allow users to refer themselves * prettier * trim both addresses * fix close webview button * fix tests and format * lint and format * Update point rewards in NavBar component: change earned points from 20 to 44 and from 100 to 32. * Refactor point rewards in NavBar component: replace hardcoded values with constants for backup and notification points, and update subscription state variable names for clarity. * Update POINT_VALUES in types.ts: adjust point rewards for disclosure, notification, and backup events to 8, 44, and 32 respectively. * App/fix backup points (#1381) * Enhance backup completion tracking in Points component: Introduce a ref to manage backup check flag, ensuring points are recorded only when explicitly set, preventing false triggers from other navigation flows. * Update API endpoint in getTotalPoints function: change URL from /distribution to /points for accurate points retrieval. * formatting * update points url * Clear referrer on modal dismiss in useEarnPointsFlow hook to prevent retry loop * use points private key to sign api requests * formatting * save working version of referral confirmation * fix circular dependency * don't fetch private key if unable to fetch points key * add url * add debug info * Refactor optimistic points calculation in usePointEventStore: update return value to only include incomingPoints.amount, marking the optimistic approach for future improvement. * save clean up * clean useReferralConfirmation logic * fix tests * tests pass * standardize android compile sdk version * fix package version * don't log errors * Update app/src/hooks/useReferralConfirmation.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * better test * add turnkey entitlements * fix linting * remove entitlements * prettier and fix lint * update gradle version * update lock file * fix tests * fix build failure * bump android version to 118 * update date * bump version for next build * address failing pipelines due to cache issues * Hide turnkey button (#1387) * prep for 2.9.0 release * fix mobile e2e test * fix tests * bump android version --------- Co-authored-by: Justin Hernandez <justin.hernandez@self.xyz> Co-authored-by: Seshanth.S <35675963+seshanthS@users.noreply.github.com> Co-authored-by: Leszek Stachowski <leszek.stachowski@self.xyz> Co-authored-by: Aaron DeRuvo <aaron.deruvo@clabs.co> Co-authored-by: seshanthS <seshanth@protonmail.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
441 lines
15 KiB
JavaScript
441 lines
15 KiB
JavaScript
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
|
|
|
|
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
|
|
const path = require('node:path');
|
|
const fs = require('node:fs');
|
|
const findYarnWorkspaceRoot = require('find-yarn-workspace-root');
|
|
|
|
const defaultConfig = getDefaultConfig(__dirname);
|
|
const { assetExts, sourceExts } = defaultConfig.resolver;
|
|
|
|
const projectRoot = __dirname;
|
|
const workspaceRoot =
|
|
findYarnWorkspaceRoot(__dirname) || path.resolve(__dirname, '..');
|
|
|
|
/**
|
|
* Modern Metro configuration using native workspace capabilities
|
|
* Eliminates need for manual symlink management through:
|
|
* - enableGlobalPackages: Automatic workspace package discovery
|
|
* - unstable_enablePackageExports: Native subpath import support
|
|
* - unstable_enableSymlinks: Optional symlink resolution
|
|
*
|
|
* @type {import('metro-config').MetroConfig}
|
|
*/
|
|
const config = {
|
|
projectRoot,
|
|
|
|
watchFolders: [
|
|
workspaceRoot, // Watch entire workspace root for changes
|
|
path.resolve(workspaceRoot, 'common'),
|
|
path.resolve(workspaceRoot, 'packages/mobile-sdk-alpha'),
|
|
path.resolve(projectRoot, 'node_modules'), // Watch app's node_modules for custom resolved modules
|
|
],
|
|
|
|
transformer: {
|
|
babelTransformerPath: require.resolve(
|
|
'react-native-svg-transformer/react-native',
|
|
),
|
|
disableImportExportTransform: true,
|
|
inlineRequires: true,
|
|
},
|
|
|
|
resolver: {
|
|
// Prevent Haste module naming collisions from duplicate package.json files
|
|
blockList: [
|
|
// Ignore built package.json files to prevent Haste collisions
|
|
/.*\/dist\/package\.json$/,
|
|
/.*\/dist\/esm\/package\.json$/,
|
|
/.*\/dist\/cjs\/package\.json$/,
|
|
/.*\/build\/package\.json$/,
|
|
// Prevent duplicate React/React Native - block workspace root versions and use app's versions
|
|
// Use precise regex patterns to avoid blocking packages like react-native-get-random-values
|
|
new RegExp(
|
|
`^${workspaceRoot.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}/node_modules/react(/|$)`,
|
|
),
|
|
new RegExp(
|
|
`^${workspaceRoot.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}/node_modules/react-dom(/|$)`,
|
|
),
|
|
new RegExp(
|
|
`^${workspaceRoot.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}/node_modules/react-native(/|$)`,
|
|
),
|
|
new RegExp(
|
|
`^${workspaceRoot.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}/node_modules/scheduler(/|$)`,
|
|
),
|
|
new RegExp('packages/mobile-sdk-alpha/node_modules/react(/|$)'),
|
|
new RegExp('packages/mobile-sdk-alpha/node_modules/react-dom(/|$)'),
|
|
new RegExp('packages/mobile-sdk-alpha/node_modules/react-native(/|$)'),
|
|
new RegExp(
|
|
'packages/mobile-sdk-alpha/node_modules/lottie-react-native(/|$)',
|
|
),
|
|
new RegExp('packages/mobile-sdk-alpha/node_modules/scheduler(/|$)'),
|
|
new RegExp(
|
|
'packages/mobile-sdk-alpha/node_modules/react-native-svg(/|$)',
|
|
),
|
|
new RegExp('packages/mobile-sdk-demo/node_modules/react(/|$)'),
|
|
new RegExp('packages/mobile-sdk-demo/node_modules/react-dom(/|$)'),
|
|
new RegExp('packages/mobile-sdk-demo/node_modules/react-native(/|$)'),
|
|
new RegExp('packages/mobile-sdk-demo/node_modules/scheduler(/|$)'),
|
|
new RegExp('packages/mobile-sdk-demo/node_modules/react-native-svg(/|$)'),
|
|
],
|
|
// Enable automatic workspace package resolution
|
|
enableGlobalPackages: true,
|
|
|
|
// Handle subpath exports (@selfxyz/common/constants)
|
|
unstable_enablePackageExports: true,
|
|
|
|
// Enable native symlink support (optional, for compatibility)
|
|
unstable_enableSymlinks: true,
|
|
|
|
// Define search order for node modules - prioritize app's modules for React consistency
|
|
nodeModulesPaths: [
|
|
path.resolve(projectRoot, 'node_modules'), // App's own node_modules FIRST
|
|
path.resolve(workspaceRoot, 'node_modules'), // Workspace root node_modules SECOND
|
|
],
|
|
|
|
// Essential polyfills for React Native
|
|
extraNodeModules: {
|
|
stream: require.resolve('stream-browserify'),
|
|
buffer: require.resolve('buffer'),
|
|
util: require.resolve('util'),
|
|
assert: require.resolve('assert'),
|
|
events: require.resolve('events'),
|
|
process: require.resolve('process'),
|
|
'react-native-svg': path.resolve(
|
|
projectRoot,
|
|
'node_modules/react-native-svg',
|
|
),
|
|
// App-specific alias
|
|
'@': path.join(__dirname, 'src'),
|
|
},
|
|
|
|
// Support package exports with conditions
|
|
unstable_conditionNames: ['react-native', 'import', 'require'],
|
|
|
|
// SVG support
|
|
assetExts: assetExts.filter(ext => ext !== 'svg'),
|
|
sourceExts: [...sourceExts, 'svg'],
|
|
|
|
// Custom resolver to handle both .js imports in TypeScript and Node.js modules
|
|
resolveRequest: (context, moduleName, platform) => {
|
|
// Handle React Native gesture handler that needs app-level resolution
|
|
const appLevelModules = {
|
|
'react-native-gesture-handler':
|
|
'react-native-gesture-handler/lib/commonjs/index.js',
|
|
};
|
|
const sdkAlphaPath = path.resolve(
|
|
workspaceRoot,
|
|
'packages/mobile-sdk-alpha',
|
|
);
|
|
|
|
// Custom resolver to handle Node.js modules and dynamic flow imports
|
|
if (moduleName.startsWith('@selfxyz/mobile-sdk-alpha/')) {
|
|
const subPath = moduleName.replace('@selfxyz/mobile-sdk-alpha/', '');
|
|
|
|
// Check if it's a flow import (onboarding/* or disclosing/*)
|
|
if (
|
|
subPath.startsWith('onboarding/') ||
|
|
subPath.startsWith('disclosing/')
|
|
) {
|
|
const flowPath = path.resolve(
|
|
sdkAlphaPath,
|
|
'dist/esm/flows',
|
|
`${subPath}.js`,
|
|
);
|
|
|
|
// Check if the file exists
|
|
if (fs.existsSync(flowPath)) {
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: flowPath,
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
if (appLevelModules[moduleName]) {
|
|
try {
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: require.resolve(appLevelModules[moduleName], {
|
|
paths: [projectRoot],
|
|
}),
|
|
};
|
|
} catch (error) {
|
|
console.warn(`Failed to resolve ${moduleName}:`, error);
|
|
// Fall back to default resolution
|
|
return context.resolveRequest(context, moduleName, platform);
|
|
}
|
|
}
|
|
|
|
// React modules now resolve naturally through nodeModulesPaths (app's node_modules first)
|
|
|
|
// Force SDK to use built ESM to avoid duplicate React and source transpilation issues
|
|
if (moduleName === '@selfxyz/mobile-sdk-alpha') {
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: path.resolve(
|
|
workspaceRoot,
|
|
'packages/mobile-sdk-alpha/dist/esm/index.js',
|
|
),
|
|
};
|
|
}
|
|
// For relative imports in common source files that end with .js
|
|
if (
|
|
context.originModulePath?.includes('/common/src/') &&
|
|
moduleName.endsWith('.js')
|
|
) {
|
|
const tsModuleName = moduleName.replace(/\.js$/, '.ts');
|
|
return context.resolveRequest(context, tsModuleName, platform);
|
|
}
|
|
|
|
// Handle problematic package exports and Node.js modules
|
|
|
|
// Fix @turnkey/encoding to use CommonJS instead of ESM
|
|
if (moduleName === '@turnkey/encoding') {
|
|
const filePath = path.resolve(
|
|
projectRoot,
|
|
'node_modules/@turnkey/encoding/dist/index.js',
|
|
);
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath,
|
|
};
|
|
}
|
|
|
|
// Fix @turnkey/encoding submodules to use CommonJS
|
|
if (moduleName.startsWith('@turnkey/encoding/')) {
|
|
const subpath = moduleName.replace('@turnkey/encoding/', '');
|
|
const filePath = path.resolve(
|
|
projectRoot,
|
|
`node_modules/@turnkey/encoding/dist/${subpath}.js`,
|
|
);
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath,
|
|
};
|
|
}
|
|
|
|
// Fix @turnkey/api-key-stamper to use CommonJS instead of ESM
|
|
if (moduleName === '@turnkey/api-key-stamper') {
|
|
const filePath = path.resolve(
|
|
projectRoot,
|
|
'node_modules/@turnkey/api-key-stamper/dist/index.js',
|
|
);
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath,
|
|
};
|
|
}
|
|
|
|
// Fix @turnkey/api-key-stamper dynamic imports by resolving submodules statically
|
|
if (moduleName.startsWith('@turnkey/api-key-stamper/')) {
|
|
const subpath = moduleName.replace('@turnkey/api-key-stamper/', '');
|
|
const filePath = path.resolve(
|
|
projectRoot,
|
|
`node_modules/@turnkey/api-key-stamper/dist/${subpath}`,
|
|
);
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath,
|
|
};
|
|
}
|
|
|
|
// Fix viem dynamic import resolution
|
|
if (moduleName === 'viem') {
|
|
try {
|
|
// Viem uses package exports, so we need to resolve to the actual file path
|
|
const viemPath = path.resolve(
|
|
projectRoot,
|
|
'node_modules/viem/_cjs/index.js',
|
|
);
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: viemPath,
|
|
};
|
|
} catch (error) {
|
|
console.warn('Failed to resolve viem:', error);
|
|
}
|
|
}
|
|
|
|
// Fix @tamagui/config v2-native export resolution
|
|
if (moduleName === '@tamagui/config/v2-native') {
|
|
try {
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: require.resolve('@tamagui/config/dist/esm/v2-native.js'),
|
|
};
|
|
} catch {
|
|
// Fallback to main export if specific file doesn't exist
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: require.resolve('@tamagui/config'),
|
|
};
|
|
}
|
|
}
|
|
|
|
// Fix @noble/hashes subpath export resolution
|
|
if (moduleName.startsWith('@noble/hashes/')) {
|
|
try {
|
|
// Extract the subpath (e.g., 'crypto.js', 'sha256', 'hmac')
|
|
const subpath = moduleName.replace('@noble/hashes/', '');
|
|
const basePath = require.resolve('@noble/hashes');
|
|
|
|
// For .js files, look in the package directory
|
|
if (subpath.endsWith('.js')) {
|
|
const subpathFile = path.join(path.dirname(basePath), subpath);
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: subpathFile,
|
|
};
|
|
} else {
|
|
// For other imports like 'sha256', 'hmac', etc., try the main directory
|
|
const subpathFile = path.join(
|
|
path.dirname(basePath),
|
|
`${subpath}.js`,
|
|
);
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: subpathFile,
|
|
};
|
|
}
|
|
} catch {
|
|
// Fallback to main package if subpath doesn't exist
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: require.resolve('@noble/hashes'),
|
|
};
|
|
}
|
|
}
|
|
|
|
// Fix snarkjs and ffjavascript platform exports for Android
|
|
if (platform === 'android') {
|
|
// Handle snarkjs and its nested dependencies that have platform export issues
|
|
if (
|
|
moduleName.includes('/snarkjs') &&
|
|
(moduleName.endsWith('/snarkjs') ||
|
|
moduleName.includes('/snarkjs/node_modules'))
|
|
) {
|
|
try {
|
|
// Try to resolve the main package file
|
|
const packagePath = moduleName.split('/node_modules/').pop();
|
|
const resolved = require.resolve(packagePath || 'snarkjs');
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: resolved,
|
|
};
|
|
} catch {
|
|
// Fallback to basic snarkjs resolution
|
|
try {
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: require.resolve('snarkjs'),
|
|
};
|
|
} catch {
|
|
// Continue to next check
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle ffjavascript from any nested location
|
|
if (
|
|
moduleName.includes('/ffjavascript') &&
|
|
moduleName.endsWith('/ffjavascript')
|
|
) {
|
|
try {
|
|
// Try to resolve ffjavascript from the specific nested location first
|
|
const resolved = require.resolve(moduleName);
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: resolved,
|
|
};
|
|
} catch {
|
|
// Fallback to resolving ffjavascript from the closest available location
|
|
try {
|
|
const resolved = require.resolve('ffjavascript');
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: resolved,
|
|
};
|
|
} catch {
|
|
// Continue to next check
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle direct package imports for known problematic packages
|
|
const platformProblematicPackages = ['snarkjs', 'ffjavascript'];
|
|
for (const pkg of platformProblematicPackages) {
|
|
if (moduleName === pkg || moduleName.startsWith(`${pkg}/`)) {
|
|
try {
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: require.resolve(pkg),
|
|
};
|
|
} catch {
|
|
// Continue to next check
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const nodeModuleRedirects = {
|
|
crypto: path.resolve(__dirname, '../common/src/polyfills/crypto.ts'),
|
|
fs: false, // Disable filesystem access
|
|
os: false, // Disable OS-specific modules
|
|
readline: false, // Disable readline module
|
|
constants: require.resolve('constants-browserify'),
|
|
path: require.resolve('path-browserify'),
|
|
'web-worker': false, // Disable web workers (not available in React Native)
|
|
};
|
|
|
|
if (
|
|
Object.prototype.hasOwnProperty.call(nodeModuleRedirects, moduleName)
|
|
) {
|
|
if (nodeModuleRedirects[moduleName] === false) {
|
|
// Return empty module for disabled modules
|
|
return { type: 'empty' };
|
|
}
|
|
// Redirect to polyfill
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: nodeModuleRedirects[moduleName],
|
|
};
|
|
}
|
|
|
|
// Handle optional peer dependencies by returning empty modules
|
|
const optionalPeerDependencies = [
|
|
'react-native-reanimated',
|
|
'@react-native-masked-view/masked-view',
|
|
'@react-native-firebase/analytics',
|
|
];
|
|
|
|
if (optionalPeerDependencies.includes(moduleName)) {
|
|
// Return empty module for optional peer dependencies
|
|
return { type: 'empty' };
|
|
}
|
|
|
|
// Fall back to default Metro resolver for all other modules
|
|
try {
|
|
return context.resolveRequest(context, moduleName, platform);
|
|
} catch (error) {
|
|
// Check if this is one of our expected optional dependencies
|
|
if (optionalPeerDependencies.some(dep => moduleName.includes(dep))) {
|
|
return { type: 'empty' };
|
|
}
|
|
|
|
// If default resolution fails, log and re-throw
|
|
console.warn(
|
|
`Metro resolver failed for module "${moduleName}":`,
|
|
error.message,
|
|
);
|
|
throw error;
|
|
}
|
|
},
|
|
},
|
|
};
|
|
|
|
module.exports = mergeConfig(defaultConfig, config);
|