mirror of
https://github.com/trezor/trezor-suite.git
synced 2026-02-20 00:33:07 +01:00
329 lines
11 KiB
TypeScript
329 lines
11 KiB
TypeScript
/* eslint-disable import/no-default-export */
|
|
/* eslint-disable import/no-anonymous-default-export */
|
|
import { execFileSync } from 'child_process';
|
|
import { createHash } from 'crypto';
|
|
import { ConfigContext, ExpoConfig } from 'expo/config';
|
|
|
|
import { suiteNativeVersion } from './package.json';
|
|
|
|
type BuildType = 'debug' | 'preview' | 'develop' | 'production';
|
|
|
|
type ExpoPlugins = ExpoConfig['plugins'];
|
|
|
|
const bundleIdentifiers = {
|
|
debug: 'io.trezor.suite.debug',
|
|
preview: 'io.trezor.suite.preview',
|
|
develop: 'io.trezor.suite.develop',
|
|
production: 'io.trezor.suite',
|
|
} as const satisfies Record<BuildType, string>;
|
|
|
|
const appIconsIos = {
|
|
debug: './assets/debug/appIcon.png',
|
|
preview: './assets/preview/appIcon.png',
|
|
develop: './assets/develop/appIcon.png',
|
|
production: './assets/production/appIcon.png',
|
|
} as const satisfies Record<BuildType, string>;
|
|
|
|
const appIconsAndroid = {
|
|
debug: {
|
|
backgroundColor: '#2587A5',
|
|
},
|
|
preview: {
|
|
backgroundColor: '#E59D17',
|
|
},
|
|
develop: {
|
|
backgroundColor: '#900B0B',
|
|
},
|
|
production: {
|
|
backgroundColor: '#60E198',
|
|
},
|
|
} as const;
|
|
|
|
const appNames = {
|
|
debug: 'Trezor Suite Debug',
|
|
preview: 'Trezor Suite Preview',
|
|
develop: 'Trezor Suite Develop',
|
|
production: 'Trezor Suite',
|
|
} as const satisfies Record<BuildType, string>;
|
|
|
|
const appSlugs = {
|
|
debug: 'trezor-suite-debug',
|
|
preview: 'trezor-suite-preview',
|
|
develop: 'trezor-suite-develop',
|
|
production: 'trezor-suite',
|
|
} as const satisfies Record<BuildType, string>;
|
|
|
|
const appOwners = {
|
|
debug: 'trezorcompany',
|
|
preview: 'trezorcompany-develop',
|
|
develop: 'trezorcompany',
|
|
production: 'trezorcompany',
|
|
} as const satisfies Record<BuildType, string>;
|
|
|
|
const projectIds = {
|
|
develop: '3e4ea82b-6c9f-4cd3-8975-54bddda3ec2d',
|
|
preview: '15998f8a-e75c-4b60-959d-6f68e5ff4936',
|
|
production: 'b9bbf16c-3d44-4d58-8f0c-ba9e6265276a',
|
|
debug: '',
|
|
} as const satisfies Record<BuildType, string>;
|
|
|
|
const buildType = (process.env.EXPO_PUBLIC_ENVIRONMENT as BuildType) ?? 'debug';
|
|
|
|
// This is used only as a fallback for the local development.
|
|
const getLocalCommitHash = (): string => {
|
|
try {
|
|
return execFileSync('git', ['rev-parse', '--short', 'HEAD'], { encoding: 'utf-8' }).trim();
|
|
} catch {
|
|
return 'unknown';
|
|
}
|
|
};
|
|
|
|
// Generate a hash of active EXPO_PUBLIC env variables
|
|
const getExpoPublicEnvHash = () => {
|
|
const envString = Object.entries(process.env)
|
|
.filter(([key]) => key.startsWith('EXPO_PUBLIC_'))
|
|
.map(([key, value]) => `${key}=${value}`)
|
|
.join(',');
|
|
|
|
return createHash('sha256').update(envString).digest('hex');
|
|
};
|
|
|
|
const getPlugins = (): ExpoPlugins => {
|
|
const plugins: ExpoPlugins = [
|
|
[
|
|
'expo-font',
|
|
{
|
|
fonts: [
|
|
'../../packages/theme/fonts/TTSatoshi-Medium.otf',
|
|
'../../packages/theme/fonts/TTSatoshi-DemiBold.otf',
|
|
`../../suite-common/icons/iconFontsMobile/TrezorSuiteIcons.ttf`,
|
|
],
|
|
},
|
|
],
|
|
[
|
|
'expo-splash-screen',
|
|
{
|
|
backgroundColor: '#25292E',
|
|
image: './assets/splash_icon.png',
|
|
dark: {
|
|
backgroundColor: '#25292E',
|
|
image: './assets/splash_icon.png',
|
|
},
|
|
imageWidth: '200',
|
|
},
|
|
],
|
|
[
|
|
'expo-camera',
|
|
{
|
|
cameraPermission: 'Allow $(PRODUCT_NAME) to access camera for QR code scanning.',
|
|
microphonePermission: false,
|
|
recordAudioAndroid: false,
|
|
},
|
|
],
|
|
[
|
|
'expo-image-picker',
|
|
{
|
|
photosPermission:
|
|
'Allow $(PRODUCT_NAME) to access your photos to let you import QR code images.',
|
|
microphonePermission: false,
|
|
},
|
|
],
|
|
['expo-video'],
|
|
[
|
|
'expo-build-properties',
|
|
{
|
|
android: {
|
|
minSdkVersion: 28,
|
|
// this fixes expo-updates build error
|
|
kotlinVersion: '2.1.20',
|
|
ndkVersion: '27.0.12077973',
|
|
},
|
|
ios: {
|
|
deploymentTarget: '15.1',
|
|
},
|
|
},
|
|
],
|
|
'@trezor/react-native-usb/plugins/withUSBDevice.js',
|
|
[
|
|
'./plugins/withAndroidMainActivityAttributes.js',
|
|
{
|
|
'android:allowBackup': false,
|
|
},
|
|
],
|
|
'./plugins/withGradleProperties.js',
|
|
[
|
|
'@config-plugins/detox',
|
|
{
|
|
subdomains: '*',
|
|
},
|
|
],
|
|
['react-native-edge-to-edge'],
|
|
[
|
|
'@sentry/react-native/expo',
|
|
{
|
|
url: 'https://sentry.io/',
|
|
project: 'suite-native',
|
|
organization: 'satoshilabs',
|
|
},
|
|
],
|
|
['expo-secure-store'],
|
|
['react-native-ble-plx', {}],
|
|
[
|
|
'react-native-permissions',
|
|
{
|
|
iosPermissions: ['Bluetooth'],
|
|
},
|
|
],
|
|
['expo-localization'],
|
|
[
|
|
'expo-sqlite',
|
|
{
|
|
useSQLCipher: true,
|
|
},
|
|
],
|
|
[
|
|
'expo-web-browser',
|
|
{
|
|
experimentalLauncherActivity: true,
|
|
},
|
|
],
|
|
];
|
|
|
|
return [
|
|
...plugins,
|
|
// These should come last
|
|
'./plugins/withRemoveXcodeLocalEnv.js',
|
|
'./plugins/withRemoveiOSNotificationEntitlement.js',
|
|
] as ExpoPlugins;
|
|
};
|
|
|
|
export default ({ config }: ConfigContext): ExpoConfig => {
|
|
const name = appNames[buildType];
|
|
const bundleIdentifier = bundleIdentifiers[buildType];
|
|
const projectId = projectIds[buildType];
|
|
const appIconIos = appIconsIos[buildType];
|
|
const appIconAndroid = appIconsAndroid[buildType];
|
|
|
|
return {
|
|
...config,
|
|
name,
|
|
scheme: buildType === 'production' ? undefined : 'trezorsuite',
|
|
slug: appSlugs[buildType],
|
|
owner: appOwners[buildType],
|
|
version: suiteNativeVersion,
|
|
runtimeVersion: '47',
|
|
...(buildType === 'production'
|
|
? {}
|
|
: {
|
|
updates: {
|
|
url: `https://u.expo.dev/${projectId}`,
|
|
requestHeaders: {
|
|
'expo-channel-name': buildType,
|
|
},
|
|
},
|
|
}),
|
|
orientation: 'portrait',
|
|
userInterfaceStyle: 'automatic',
|
|
android: {
|
|
package: bundleIdentifier,
|
|
adaptiveIcon: {
|
|
foregroundImage: './assets/appIcon_android.png',
|
|
monochromeImage: './assets/appIcon_android.png',
|
|
...appIconAndroid,
|
|
},
|
|
intentFilters: [
|
|
{
|
|
action: 'VIEW',
|
|
autoVerify: true,
|
|
data:
|
|
buildType === 'production'
|
|
? [
|
|
{
|
|
scheme: 'https',
|
|
host: 'connect.trezor.io',
|
|
pathPattern: '/9/deeplink/.*',
|
|
},
|
|
{
|
|
scheme: 'https',
|
|
host: 'trezor.io',
|
|
pathPattern: '/setup/.*',
|
|
},
|
|
{
|
|
scheme: 'https',
|
|
host: 'trezor.io',
|
|
pathPattern: '/suite/deeplinks/.*',
|
|
},
|
|
]
|
|
: [
|
|
{
|
|
scheme: 'https',
|
|
host: 'dev.suite.sldev.cz',
|
|
pathPattern: '/connect/.*/deeplink/.*',
|
|
},
|
|
{
|
|
scheme: 'https',
|
|
host: 'dev.suite.sldev.cz',
|
|
// for branches with a slash in the name
|
|
pathPattern: '/connect/.*/.*/deeplink/.*',
|
|
},
|
|
{
|
|
scheme: 'https',
|
|
host: 'dev.trezorio.sldev.cz',
|
|
pathPattern: '/setup/.*',
|
|
},
|
|
],
|
|
category: ['BROWSABLE', 'DEFAULT'],
|
|
},
|
|
],
|
|
// These permission are included by expo-video, but we don't need them. The video is always played when is the app open and user is on the specific screen.
|
|
blockedPermissions: ['FOREGROUND_SERVICE', 'FOREGROUND_SERVICE_MEDIA_PLAYBACK'],
|
|
},
|
|
ios: {
|
|
bundleIdentifier,
|
|
appleTeamId: 'C3P22XVH2C',
|
|
icon: appIconIos,
|
|
supportsTablet: true,
|
|
infoPlist: {
|
|
NSBluetoothAlwaysUsageDescription:
|
|
'$(PRODUCT_NAME) needs access to Bluetooth to connect to your Trezor device.',
|
|
NSBluetoothPeripheralUsageDescription:
|
|
'$(PRODUCT_NAME) needs access to Bluetooth to connect to your Trezor device.',
|
|
NSCameraUsageDescription:
|
|
'$(PRODUCT_NAME) needs access to your Camera to scan your XPUB.',
|
|
NSFaceIDUsageDescription:
|
|
'$(PRODUCT_NAME) needs Face ID and Touch ID to keep sensitive data about your portfolio private.',
|
|
NSMicrophoneUsageDescription: 'This app does not require access to the microphone.',
|
|
ITSAppUsesNonExemptEncryption: false,
|
|
NSAppTransportSecurity: {
|
|
NSAllowsArbitraryLoads: true,
|
|
NSExceptionDomains: {
|
|
localhost: {
|
|
NSExceptionAllowsInsecureHTTPLoads: true,
|
|
},
|
|
'data.trezor.io': {
|
|
NSExceptionAllowsInsecureHTTPLoads: true,
|
|
NSIncludesSubdomains: true,
|
|
},
|
|
},
|
|
},
|
|
UIRequiredDeviceCapabilities: ['armv7'],
|
|
},
|
|
associatedDomains:
|
|
buildType === 'production'
|
|
? ['applinks:connect.trezor.io', 'applinks:trezor.io']
|
|
: ['applinks:dev.suite.sldev.cz', 'applinks:dev.trezorio.sldev.cz'],
|
|
},
|
|
plugins: getPlugins(),
|
|
extra: {
|
|
commitHash:
|
|
process.env.EAS_BUILD_GIT_COMMIT_HASH ||
|
|
process.env.COMMIT_HASH ||
|
|
getLocalCommitHash(),
|
|
expoPublicEnvHash: getExpoPublicEnvHash(), // Only to change fingerprint of the build on environment variables change
|
|
eas: {
|
|
projectId,
|
|
},
|
|
},
|
|
};
|
|
};
|