diff --git a/.github/workflows/build-ios-release-pullrequest.yml b/.github/workflows/build-ios-release-pullrequest.yml index ed12b15d009..71f87895720 100644 --- a/.github/workflows/build-ios-release-pullrequest.yml +++ b/.github/workflows/build-ios-release-pullrequest.yml @@ -241,6 +241,9 @@ jobs: bundle config path vendor/bundle bundle install --jobs 4 --retry 3 --quiet + - name: Set default network + run: ./scripts/set-network.sh signet + - name: Install Node Modules run: npm ci --omit=dev --yes @@ -290,6 +293,38 @@ jobs: run: | bundle exec fastlane ios setup_provisioning_profiles + - name: Build App (unsigned, non-master) + if: github.ref != 'refs/heads/master' && github.ref != 'refs/heads/2025-12-03-redwallet' + run: | + cd ios && pod install + mkdir -p build_logs + xcodebuild -workspace BlueWallet.xcworkspace \ + -scheme BlueWallet \ + -configuration Release \ + -sdk iphonesimulator \ + -destination 'generic/platform=iOS Simulator' \ + -derivedDataPath build \ + CODE_SIGNING_ALLOWED=NO \ + build 2>&1 | tee build_logs/xcodebuild.log + + - name: Upload unsigned app as artifact + if: github.ref != 'refs/heads/master' && github.ref != 'refs/heads/2025-12-03-redwallet' + uses: actions/upload-artifact@v4 + with: + name: BlueWallet-unsigned-simulator + path: ios/build/Build/Products/Release-iphonesimulator/BlueWallet.app + retention-days: 7 + if-no-files-found: error + + - name: Upload build logs (non-master) + if: always() && github.ref != 'refs/heads/master' && github.ref != 'refs/heads/2025-12-03-redwallet' + uses: actions/upload-artifact@v4 + with: + name: build_logs_pr + path: ios/build_logs/xcodebuild.log + retention-days: 7 + if-no-files-found: error + - name: Build App id: build_app run: | @@ -435,6 +470,7 @@ jobs: name: build_logs path: ./ios/build_logs/ retention-days: 7 + if-no-files-found: warn - name: Verify IPA File Before Upload run: | diff --git a/.github/workflows/build-mac-catalyst.yml b/.github/workflows/build-mac-catalyst.yml index 217603f31d3..99023fa2937 100644 --- a/.github/workflows/build-mac-catalyst.yml +++ b/.github/workflows/build-mac-catalyst.yml @@ -74,6 +74,10 @@ jobs: ruby-version: 3.4.8 bundler-cache: true + - name: Set default network + if: github.event_name == 'workflow_dispatch' || steps.labels.outputs.has_mac_dmg == 'true' + run: ./scripts/set-network.sh signet + - name: Install Node modules if: github.event_name == 'workflow_dispatch' || steps.labels.outputs.has_mac_dmg == 'true' run: npm ci diff --git a/.github/workflows/build-release-apk.yml b/.github/workflows/build-release-apk.yml index 456d5cc7296..386f5974ae1 100644 --- a/.github/workflows/build-release-apk.yml +++ b/.github/workflows/build-release-apk.yml @@ -58,6 +58,9 @@ jobs: yes | sdkmanager --licenses sdkmanager "platforms;android-36" "platform-tools" "build-tools;36.0.0" "ndk;27.1.12297006" + - name: Set default network + run: ./scripts/set-network.sh signet + - name: Install node_modules (include dev deps for patch-package) run: npm ci --yes @@ -82,9 +85,16 @@ jobs: echo "NEW_BUILD_NUMBER=$NEW_BUILD_NUMBER" >> $GITHUB_ENV echo "build_number=$NEW_BUILD_NUMBER" >> $GITHUB_OUTPUT +<<<<<<< HEAD - name: Build and sign APK id: build_and_sign_apk run: bundle exec fastlane android build_release_apk +======= + - name: Build release AAB + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/2025-12-03-redwallet' + id: build_release_aab + run: bundle exec fastlane android build_release_aab +>>>>>>> 81bdf7f92 (ci: automatically upload android builds to Play Store internal testing) env: BUILD_NUMBER: ${{ steps.build_number.outputs.build_number }} KEYSTORE_FILE_HEX: ${{ secrets.KEYSTORE_FILE_HEX }} @@ -103,8 +113,14 @@ jobs: android/**/reports/**/*.log if-no-files-found: warn - - name: Determine APK Filename and Path - id: determine_apk_path + - name: Build Debug APK (non-master branches) + if: github.ref != 'refs/heads/master' && github.ref != 'refs/heads/2025-12-03-redwallet' + run: | + cd android && ./gradlew assembleDebug --no-daemon + + - name: Determine AAB Filename and Path + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/2025-12-03-redwallet' + id: determine_aab_path run: | BUILD_NUMBER=${{ steps.build_number.outputs.build_number }} VERSION_NAME=$(grep versionName android/app/build.gradle | awk '{print $2}' | tr -d '"') @@ -112,20 +128,19 @@ jobs: BRANCH_NAME=$(echo "$BRANCH_NAME" | sed 's/[^a-zA-Z0-9_-]/_/g') if [ -n "$BRANCH_NAME" ] && [ "$BRANCH_NAME" != "master" ]; then - EXPECTED_FILENAME="BlueWallet-${VERSION_NAME}-${BUILD_NUMBER}-${BRANCH_NAME}.apk" + EXPECTED_FILENAME="BlueWallet-${VERSION_NAME}-${BUILD_NUMBER}-${BRANCH_NAME}.aab" else - EXPECTED_FILENAME="BlueWallet-${VERSION_NAME}-${BUILD_NUMBER}.apk" + EXPECTED_FILENAME="BlueWallet-${VERSION_NAME}-${BUILD_NUMBER}.aab" fi - - APK_PATH="android/app/build/outputs/apk/release/${EXPECTED_FILENAME}" - echo "EXPECTED_FILENAME=${EXPECTED_FILENAME}" >> $GITHUB_ENV - echo "APK_PATH=${APK_PATH}" >> $GITHUB_ENV + AAB_PATH="android/app/build/outputs/bundle/release/${EXPECTED_FILENAME}" + echo "AAB_PATH=${AAB_PATH}" >> $GITHUB_ENV - - name: Upload APK as artifact - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 + - name: Upload signed AAB as artifact + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/2025-12-03-redwallet' + uses: actions/upload-artifact@v4 with: - name: signed-apk - path: ${{ env.APK_PATH }} + name: signed-aab + path: ${{ env.AAB_PATH }} if-no-files-found: error browserstack: @@ -146,20 +161,54 @@ jobs: - name: Install dependencies with Bundler run: bundle install --jobs 4 --retry 3 - - name: Download APK artifact - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5 + - name: Download AAB artifact + uses: actions/download-artifact@v4 with: - name: signed-apk + name: signed-aab - name: Set APK Path run: | - APK_PATH=$(find ${{ github.workspace }} -name '*.apk') + APK_PATH=$(find ${{ github.workspace }} -name '*.aab') echo "APK_PATH=$APK_PATH" >> $GITHUB_ENV - - name: Upload APK to BrowserStack and Post PR Comment + - name: Upload AAB to BrowserStack and Post PR Comment env: BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: bundle exec fastlane upload_to_browserstack_and_comment + + play-store-upload: + runs-on: ubuntu-latest + needs: buildReleaseApk + if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/2025-12-03-redwallet') + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.1.6 + bundler-cache: true + + - name: Install dependencies with Bundler + run: bundle install --jobs 4 --retry 3 + + - name: Download AAB artifact + uses: actions/download-artifact@v4 + with: + name: signed-aab + + - name: Set AAB Path + run: | + AAB_PATH=$(find ${{ github.workspace }} -name '*.aab') + echo "AAB_PATH=$AAB_PATH" >> $GITHUB_ENV + + - name: Upload to Google Play Internal Testing + env: + GOOGLE_PLAY_JSON_KEY: ${{ secrets.GOOGLE_PLAY_JSON_KEY }} + AAB_PATH: ${{ env.AAB_PATH }} + run: bundle exec fastlane android deploy_to_play_store diff --git a/android/app/build.gradle b/android/app/build.gradle index 999219fb742..cce5ce19c66 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -83,10 +83,10 @@ android { namespace "io.bluewallet.bluewallet" defaultConfig { - applicationId "io.bluewallet.bluewallet" + applicationId "com.layertwolabs.bluewallet" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 1 + versionCode System.getenv("BUILD_NUMBER")?.toInteger() ?: (int)(System.currentTimeMillis() / 1000) versionName "7.2.7" testBuildType System.getProperty('testBuildType', 'debug') testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' @@ -105,11 +105,26 @@ android { } } + signingConfigs { + release { + def keystoreFile = file("${rootProject.projectDir}/../bluewallet-release-key.keystore") + if (keystoreFile.exists()) { + storeFile keystoreFile + storePassword System.getenv("KEYSTORE_PASSWORD") ?: "" + keyAlias "l2l dev" + keyPassword System.getenv("KEYSTORE_PASSWORD") ?: "" + } + } + } + buildTypes { release { minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro" + if (signingConfigs.release.storeFile != null && signingConfigs.release.storeFile.exists()) { + signingConfig signingConfigs.release + } } } diff --git a/android/app/google-services.json b/android/app/google-services.json index 27439a9d5be..4e9f63d5f26 100644 --- a/android/app/google-services.json +++ b/android/app/google-services.json @@ -10,7 +10,7 @@ "client_info": { "mobilesdk_app_id": "1:993804676679:android:3e611cf30d58bac8b5cb62", "android_client_info": { - "package_name": "io.bluewallet.bluewallet" + "package_name": "com.layertwolabs.bluewallet" } }, "oauth_client": [ diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 218e62ef4fd..7e6097c2554 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -101,7 +101,7 @@ diff --git a/android/app/src/main/java/io/bluewallet/bluewallet/BitcoinPriceWidget.kt b/android/app/src/main/java/io/bluewallet/bluewallet/BitcoinPriceWidget.kt index 70752e362a7..03be7363886 100644 --- a/android/app/src/main/java/io/bluewallet/bluewallet/BitcoinPriceWidget.kt +++ b/android/app/src/main/java/io/bluewallet/bluewallet/BitcoinPriceWidget.kt @@ -13,7 +13,7 @@ class BitcoinPriceWidget : AppWidgetProvider() { companion object { private const val TAG = "BitcoinPriceWidget" - private const val SHARED_PREF_NAME = "group.io.bluewallet.bluewallet" + private const val SHARED_PREF_NAME = "group.com.layertwolabs.bluewallet" fun updateNetworkStatus(context: Context, appWidgetIds: IntArray) { val isNetworkAvailable = NetworkUtils.isNetworkAvailable(context) diff --git a/android/app/src/main/java/io/bluewallet/bluewallet/MainActivity.kt b/android/app/src/main/java/io/bluewallet/bluewallet/MainActivity.kt index ad2d173a13b..7b8146507ca 100644 --- a/android/app/src/main/java/io/bluewallet/bluewallet/MainActivity.kt +++ b/android/app/src/main/java/io/bluewallet/bluewallet/MainActivity.kt @@ -21,7 +21,7 @@ class MainActivity : ReactActivity() { * This is used to schedule rendering of the component. */ override fun getMainComponentName(): String { - return "BlueWallet" + return "RedWallet" } override fun onCreate(savedInstanceState: Bundle?) { @@ -42,7 +42,7 @@ class MainActivity : ReactActivity() { } private fun checkAndShowCacheClearedAlert() { - val sharedPref = getSharedPreferences("group.io.bluewallet.bluewallet", Context.MODE_PRIVATE) + val sharedPref = getSharedPreferences("group.com.layertwolabs.bluewallet", Context.MODE_PRIVATE) val shouldShowAlert = sharedPref.getBoolean("shouldShowCacheClearedAlert", false) if (shouldShowAlert) { diff --git a/android/app/src/main/java/io/bluewallet/bluewallet/MainApplication.kt b/android/app/src/main/java/io/bluewallet/bluewallet/MainApplication.kt index ccdcaf17850..6c3a863f2c0 100644 --- a/android/app/src/main/java/io/bluewallet/bluewallet/MainApplication.kt +++ b/android/app/src/main/java/io/bluewallet/bluewallet/MainApplication.kt @@ -85,7 +85,7 @@ class MainApplication : Application(), ReactApplication { override fun onCreate() { super.onCreate() - sharedPref = getSharedPreferences("group.io.bluewallet.bluewallet", Context.MODE_PRIVATE) + sharedPref = getSharedPreferences("group.com.layertwolabs.bluewallet", Context.MODE_PRIVATE) // Handle clearFilesOnLaunch before registering listeners clearFilesIfNeeded() diff --git a/android/app/src/main/java/io/bluewallet/bluewallet/MarketWidget.kt b/android/app/src/main/java/io/bluewallet/bluewallet/MarketWidget.kt index e0c7d168fb6..91174cdd3e9 100644 --- a/android/app/src/main/java/io/bluewallet/bluewallet/MarketWidget.kt +++ b/android/app/src/main/java/io/bluewallet/bluewallet/MarketWidget.kt @@ -19,7 +19,7 @@ class MarketWidget : AppWidgetProvider() { companion object { private const val TAG = "MarketWidget" - private const val SHARED_PREF_NAME = "group.io.bluewallet.bluewallet" + private const val SHARED_PREF_NAME = "group.com.layertwolabs.bluewallet" private const val DEFAULT_CURRENCY = "USD" private const val KEY_LAST_ONLINE_STATUS = "market_widget_last_online_status" diff --git a/android/app/src/main/java/io/bluewallet/bluewallet/MarketWidgetUpdateWorker.kt b/android/app/src/main/java/io/bluewallet/bluewallet/MarketWidgetUpdateWorker.kt index 236f727a833..aef684f215e 100644 --- a/android/app/src/main/java/io/bluewallet/bluewallet/MarketWidgetUpdateWorker.kt +++ b/android/app/src/main/java/io/bluewallet/bluewallet/MarketWidgetUpdateWorker.kt @@ -16,7 +16,7 @@ class MarketWidgetUpdateWorker(context: Context, workerParams: WorkerParameters) const val TAG = "MarketWidgetUpdateWorker" const val WORK_NAME = "market_widget_update_work" const val NETWORK_RETRY_WORK_NAME = "market_network_retry_work" - private const val SHARED_PREF_NAME = "group.io.bluewallet.bluewallet" + private const val SHARED_PREF_NAME = "group.com.layertwolabs.bluewallet" private const val DEFAULT_CURRENCY = "USD" private const val KEY_LAST_UPDATE_TIME = "market_widget_last_update_time" private const val MIN_UPDATE_INTERVAL_MS = 15L * 60 * 1000 diff --git a/android/app/src/main/java/io/bluewallet/bluewallet/SettingsActivity.kt b/android/app/src/main/java/io/bluewallet/bluewallet/SettingsActivity.kt index 5eb40ce9ff1..38a55e97a02 100644 --- a/android/app/src/main/java/io/bluewallet/bluewallet/SettingsActivity.kt +++ b/android/app/src/main/java/io/bluewallet/bluewallet/SettingsActivity.kt @@ -35,7 +35,7 @@ class SettingsActivity : AppCompatActivity() { class SettingsFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { // Set the SharedPreferences name to match the app's preferences - preferenceManager.sharedPreferencesName = "group.io.bluewallet.bluewallet" + preferenceManager.sharedPreferencesName = "group.com.layertwolabs.bluewallet" // Load preferences from XML setPreferencesFromResource(R.xml.settings_preferences, rootKey) diff --git a/android/app/src/main/java/io/bluewallet/bluewallet/SettingsModule.kt b/android/app/src/main/java/io/bluewallet/bluewallet/SettingsModule.kt index 4c32ef6e06b..4a6711b0602 100644 --- a/android/app/src/main/java/io/bluewallet/bluewallet/SettingsModule.kt +++ b/android/app/src/main/java/io/bluewallet/bluewallet/SettingsModule.kt @@ -13,7 +13,7 @@ import io.bluewallet.bluewallet.NativeSettingsModuleSpec class SettingsModule(reactContext: ReactApplicationContext) : NativeSettingsModuleSpec(reactContext) { private val sharedPref: SharedPreferences = reactContext.getSharedPreferences( - "group.io.bluewallet.bluewallet", + "group.com.layertwolabs.bluewallet", Context.MODE_PRIVATE ) diff --git a/android/app/src/main/java/io/bluewallet/bluewallet/ThemeHelper.kt b/android/app/src/main/java/io/bluewallet/bluewallet/ThemeHelper.kt index 2872bb0215d..eea8c75e762 100644 --- a/android/app/src/main/java/io/bluewallet/bluewallet/ThemeHelper.kt +++ b/android/app/src/main/java/io/bluewallet/bluewallet/ThemeHelper.kt @@ -5,7 +5,7 @@ import android.content.res.Configuration import androidx.appcompat.app.AppCompatDelegate object ThemeHelper { - private const val SHARED_PREF_NAME = "group.io.bluewallet.bluewallet" + private const val SHARED_PREF_NAME = "group.com.layertwolabs.bluewallet" private const val KEY_FORCE_DARK_MODE = "force_dark_mode" /** diff --git a/android/app/src/main/java/io/bluewallet/bluewallet/WidgetUpdateWorker.kt b/android/app/src/main/java/io/bluewallet/bluewallet/WidgetUpdateWorker.kt index 14e5e2f8f3d..570d032ec02 100644 --- a/android/app/src/main/java/io/bluewallet/bluewallet/WidgetUpdateWorker.kt +++ b/android/app/src/main/java/io/bluewallet/bluewallet/WidgetUpdateWorker.kt @@ -26,7 +26,7 @@ class WidgetUpdateWorker(context: Context, workerParams: WorkerParameters) : Cor const val WORK_NAME = "bitcoin_price_widget_update_work" const val NETWORK_RETRY_WORK_NAME = "bitcoin_price_network_retry_work" const val REPEAT_INTERVAL_MINUTES = 15L - private const val SHARED_PREF_NAME = "group.io.bluewallet.bluewallet" + private const val SHARED_PREF_NAME = "group.com.layertwolabs.bluewallet" private const val DEFAULT_CURRENCY = "USD" private const val NETWORK_RETRY_DELAY_SECONDS = 30L diff --git a/android/app/src/main/res/drawable-mdpi/splash_icon.png b/android/app/src/main/res/drawable-mdpi/splash_icon.png index ec541528a9a..02bc2883a29 100644 Binary files a/android/app/src/main/res/drawable-mdpi/splash_icon.png and b/android/app/src/main/res/drawable-mdpi/splash_icon.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/splash_icon.png b/android/app/src/main/res/drawable-xhdpi/splash_icon.png index a72c80addc6..02bc2883a29 100644 Binary files a/android/app/src/main/res/drawable-xhdpi/splash_icon.png and b/android/app/src/main/res/drawable-xhdpi/splash_icon.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/splash_icon.png b/android/app/src/main/res/drawable-xxhdpi/splash_icon.png index 5727bf33172..02bc2883a29 100644 Binary files a/android/app/src/main/res/drawable-xxhdpi/splash_icon.png and b/android/app/src/main/res/drawable-xxhdpi/splash_icon.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index a9f1311182d..8a11cba2760 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png index a9f1311182d..8a11cba2760 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index 6a294aa8a80..631eeddc79e 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png index 6a294aa8a80..631eeddc79e 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 3166c802f37..7ce4b0fd218 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png index 3166c802f37..7ce4b0fd218 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 2d00b392c52..4f0d2a3a2b4 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png index 2d00b392c52..4f0d2a3a2b4 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index fe4a66ea54c..9d1ca78096e 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png index fe4a66ea54c..9d1ca78096e 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index af6599907c8..dee80d4ce8d 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -1,5 +1,5 @@ - BlueWallet + RedWallet Loading... Last Updated From diff --git a/android/settings.gradle b/android/settings.gradle index 2221f878143..abb4882f394 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,7 +1,7 @@ pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } plugins { id("com.facebook.react.settings") } extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } -rootProject.name = 'BlueWallet' +rootProject.name = 'RedWallet' include ':app' includeBuild('../node_modules/@react-native/gradle-plugin') include ':detox' diff --git a/blue_modules/BlueElectrum.ts b/blue_modules/BlueElectrum.ts index 4d484fe84dd..1e132ee2a79 100644 --- a/blue_modules/BlueElectrum.ts +++ b/blue_modules/BlueElectrum.ts @@ -13,6 +13,7 @@ import { ElectrumServerItem } from '../screen/settings/ElectrumSettings'; import { triggerWarningHapticFeedback } from './hapticFeedback'; import { AlertButton } from 'react-native'; import { uint8ArrayToHex, stringToUint8Array, hexToUint8Array } from './uint8array-extras/index'; +import { getNetwork, NetworkType } from '../models/network'; const ElectrumClient = require('electrum-client'); const net = require('net'); @@ -84,6 +85,7 @@ export const ELECTRUM_SERVER_HISTORY = 'electrum_server_history'; const ELECTRUM_CONNECTION_DISABLED = 'electrum_disabled'; const storageKey = 'ELECTRUM_PEERS'; const defaultPeer = { host: 'electrum1.bluewallet.io', ssl: 443 }; + export const hardcodedPeers: Peer[] = [ { host: 'mainnet.foundationdevices.com', ssl: 50002 }, { host: 'bitcoin.lu.ke', ssl: 50002 }, @@ -92,16 +94,43 @@ export const hardcodedPeers: Peer[] = [ { host: 'electrum.acinq.co', ssl: 50002 }, ]; +function getHardcodedPeersForNetwork(network: NetworkType): Peer[] { + switch (network) { + case 'testnet': + return [ + { host: 'testnet4-electrumx.wakiyamap.dev', ssl: 51002 }, + { host: 'mempool.space', ssl: 40002 }, + ]; + case 'signet': + // For some reason SSL is not working here. SSL works via Sparrow, but + // this throws kCFStreamSSLPeerName with an error code indicating an + // internal SSL error + return [{ host: 'node.signet.drivechain.info', tcp: 50001 }]; + case 'mainnet': + default: + return hardcodedPeers; + } +} + export const suggestedServers: Peer[] = hardcodedPeers.map(peer => ({ ...peer, })); +export function getHardcodedPeersForCurrentNetwork(): Peer[] { + return getHardcodedPeersForNetwork(currentNetwork); +} + +export function getSuggestedServersForCurrentNetwork(): Peer[] { + return getHardcodedPeersForNetwork(currentNetwork).map(peer => ({ ...peer })); +} + let mainClient: typeof ElectrumClient | undefined; let mainConnected: boolean = false; let wasConnectedAtLeastOnce: boolean = false; let serverName: string | false = false; let disableBatching: boolean = false; let connectionAttempt: number = 0; +let currentNetwork: NetworkType = 'signet'; let currentPeerIndex = hardcodedPeers.findIndex(peer => peer.host === defaultPeer.host && peer.ssl === defaultPeer.ssl); if (currentPeerIndex < 0) currentPeerIndex = 0; let latestBlock: { height: number; time: number } | { height: undefined; time: undefined } = { height: undefined, time: undefined }; @@ -205,16 +234,19 @@ export async function setDisabled(disabled = true) { } function getCurrentPeer() { - return hardcodedPeers[currentPeerIndex]; + const peers = getHardcodedPeersForNetwork(currentNetwork); + if (currentPeerIndex >= peers.length) currentPeerIndex = 0; + return peers[currentPeerIndex]; } /** * Returns NEXT hardcoded electrum server (increments index after use) */ function getNextPeer() { + const peers = getHardcodedPeersForNetwork(currentNetwork); const peer = getCurrentPeer(); currentPeerIndex++; - if (currentPeerIndex >= hardcodedPeers.length) currentPeerIndex = 0; + if (currentPeerIndex >= peers.length) currentPeerIndex = 0; return peer; } @@ -246,11 +278,15 @@ async function getSavedPeer(): Promise { } } -export async function connectMain(): Promise { +export async function connectMain(network: NetworkType = 'mainnet'): Promise { if (await isDisabled()) { console.log('Electrum connection disabled by user. Skipping connectMain call'); return; } + if (network !== currentNetwork) { + currentNetwork = network; + currentPeerIndex = 0; + } let usingPeer = getNextPeer(); const savedPeer = await getSavedPeer(); if (savedPeer && savedPeer.host && (savedPeer.tcp || savedPeer.ssl)) { @@ -275,7 +311,7 @@ export async function connectMain(): Promise { // dropping `mainConnected` flag ensures there wont be reconnection race condition if several // errors triggered console.log('reconnecting after socket error'); - setTimeout(connectMain, usingPeer.host.endsWith('.onion') ? 4000 : 500); + setTimeout(() => connectMain(currentNetwork), usingPeer.host.endsWith('.onion') ? 4000 : 500); } }; const ver = await mainClient.initElectrum({ client: 'bluewallet', version: '1.4' }); @@ -284,7 +320,12 @@ export async function connectMain(): Promise { serverName = ver[0]; mainConnected = true; wasConnectedAtLeastOnce = true; - if (ver[0].startsWith('ElectrumPersonalServer') || ver[0].startsWith('electrs') || ver[0].startsWith('Fulcrum')) { + if ( + ver[0].startsWith('ElectrumPersonalServer') || + ver[0].startsWith('electrs') || + ver[0].startsWith('mempool-electrs') || + ver[0].startsWith('Fulcrum') + ) { disableBatching = true; // exeptions for versions: @@ -332,7 +373,7 @@ export async function connectMain(): Promise { } else { console.log('reconnection attempt #', connectionAttempt); await new Promise(resolve => setTimeout(resolve, 500)); // sleep - return connectMain(); + return connectMain(currentNetwork); } } } @@ -420,7 +461,7 @@ const presentNetworkErrorAlert = async (usingPeer?: Peer) => { connectionAttempt = 0; mainClient?.close(); mainClient = undefined; - setTimeout(connectMain, 500); + setTimeout(() => connectMain(currentNetwork), 500); }, style: 'default', }, @@ -432,7 +473,7 @@ const presentNetworkErrorAlert = async (usingPeer?: Peer) => { connectionAttempt = 0; mainClient?.close(); mainClient = undefined; - setTimeout(connectMain, 500); + setTimeout(() => connectMain(currentNetwork), 500); } }); }, @@ -490,7 +531,7 @@ async function getRandomDynamicPeer(): Promise { export const getBalanceByAddress = async function (address: string): Promise<{ confirmed: number; unconfirmed: number }> { try { if (!mainClient) throw new Error('Electrum client is not connected'); - const script = bitcoin.address.toOutputScript(address); + const script = bitcoin.address.toOutputScript(address, getNetwork()); const hash = bitcoinjs_crypto_sha256(script); const reversedHash = new Uint8Array(hash).reverse(); const balance = await mainClient.blockchainScripthash_getBalance(uint8ArrayToHex(reversedHash)); @@ -518,7 +559,7 @@ export const getSecondsSinceLastRequest = function () { export const getTransactionsByAddress = async function (address: string): Promise { if (!mainClient) throw new Error('Electrum client is not connected'); - const script = bitcoin.address.toOutputScript(address); + const script = bitcoin.address.toOutputScript(address, getNetwork()); const hash = bitcoinjs_crypto_sha256(script); const reversedHash = new Uint8Array(hash).reverse(); const history = await mainClient.blockchainScripthash_getHistory(uint8ArrayToHex(reversedHash)); @@ -531,7 +572,7 @@ export const getTransactionsByAddress = async function (address: string): Promis export const getMempoolTransactionsByAddress = async function (address: string): Promise { if (!mainClient) throw new Error('Electrum client is not connected'); - const script = bitcoin.address.toOutputScript(address); + const script = bitcoin.address.toOutputScript(address, getNetwork()); const hash = bitcoinjs_crypto_sha256(script); const reversedHash = new Uint8Array(hash).reverse(); return mainClient.blockchainScripthash_getMempool(uint8ArrayToHex(reversedHash)); @@ -717,7 +758,7 @@ export const multiGetBalanceByAddress = async (addresses: string[], batchsize: n const scripthashes = []; const scripthash2addr: Record = {}; for (const addr of chunk) { - const script = bitcoin.address.toOutputScript(addr); + const script = bitcoin.address.toOutputScript(addr, getNetwork()); const hash = bitcoinjs_crypto_sha256(script); const reversedHash = uint8ArrayToHex(new Uint8Array(hash).reverse()); scripthashes.push(reversedHash); @@ -761,7 +802,7 @@ export const multiGetUtxoByAddress = async function (addresses: string[], batchs const scripthashes = []; const scripthash2addr: Record = {}; for (const addr of chunk) { - const script = bitcoin.address.toOutputScript(addr); + const script = bitcoin.address.toOutputScript(addr, getNetwork()); const hash = bitcoinjs_crypto_sha256(script); const reversedHash = uint8ArrayToHex(new Uint8Array(hash).reverse()); scripthashes.push(reversedHash); @@ -811,7 +852,7 @@ export const multiGetHistoryByAddress = async function ( const scripthashes = []; const scripthash2addr: Record = {}; for (const addr of chunk) { - const script = bitcoin.address.toOutputScript(addr); + const script = bitcoin.address.toOutputScript(addr, getNetwork()); const hash = bitcoinjs_crypto_sha256(script); const reversedHash = uint8ArrayToHex(new Uint8Array(hash).reverse()); scripthashes.push(reversedHash); diff --git a/blue_modules/currency.ts b/blue_modules/currency.ts index acdd3ba158f..fd9b2c6ca84 100644 --- a/blue_modules/currency.ts +++ b/blue_modules/currency.ts @@ -8,7 +8,7 @@ const PREFERRED_CURRENCY_STORAGE_KEY = 'preferredCurrency'; const PREFERRED_CURRENCY_LOCALE_STORAGE_KEY = 'preferredCurrencyLocale'; const EXCHANGE_RATES_STORAGE_KEY = 'exchangeRates'; const LAST_UPDATED = 'LAST_UPDATED'; -export const GROUP_IO_BLUEWALLET = 'group.io.bluewallet.bluewallet'; +export const GROUP_IO_BLUEWALLET = 'group.com.layertwolabs.bluewallet'; const BTC_PREFIX = 'BTC_'; export interface CurrencyRate { diff --git a/class/contact-list.ts b/class/contact-list.ts index 28fa673d42c..29eda35e722 100644 --- a/class/contact-list.ts +++ b/class/contact-list.ts @@ -5,6 +5,7 @@ import { SilentPayment } from 'silent-payments'; import ecc from '../blue_modules/noble_ecc'; import { concatUint8Arrays } from '../blue_modules/uint8array-extras'; import * as bitcoin from 'bitcoinjs-lib'; +import { getNetwork } from '../models/network'; export class ContactList { isBip47PaymentCodeValid(pc: string) { @@ -26,9 +27,10 @@ export class ContactList { isAddressValid(address: string): boolean { try { - bitcoin.address.toOutputScript(address); // throws, no? + bitcoin.address.toOutputScript(address, getNetwork()); // throws, no? - if (!address.toLowerCase().startsWith('bc1')) return true; + const lowerAddr = address.toLowerCase(); + if (!lowerAddr.startsWith('bc1') && !lowerAddr.startsWith('tb1')) return true; const decoded = bitcoin.address.fromBech32(address); if (decoded.version === 0) return true; if (decoded.version === 1 && decoded.data.length !== 32) return false; diff --git a/class/deeplink-schema-match.ts b/class/deeplink-schema-match.ts index c3dfd82d8e3..8b484468ba3 100644 --- a/class/deeplink-schema-match.ts +++ b/class/deeplink-schema-match.ts @@ -3,6 +3,7 @@ import * as bitcoin from 'bitcoinjs-lib'; import URL from 'url'; import { readFileOutsideSandbox } from '../blue_modules/fs'; import { Chain } from '../models/bitcoinUnits'; +import { getNetwork } from '../models/network'; import { WatchOnlyWallet } from './'; import Azteco from './azteco'; import Lnurl from './lnurl'; @@ -305,7 +306,7 @@ class DeeplinkSchemaMatch { address = address.replace('://', ':').replace('bitcoin:', '').replace('BITCOIN:', '').replace('bitcoin=', '').split('?')[0]; let isValidBitcoinAddress = false; try { - bitcoin.address.toOutputScript(address); + bitcoin.address.toOutputScript(address, getNetwork()); isValidBitcoinAddress = true; } catch (err) { isValidBitcoinAddress = false; @@ -397,7 +398,7 @@ class DeeplinkSchemaMatch { static bip21encode(address: string, options?: TOptions): string { // uppercase address if bech32 to satisfy BIP_0173 - const isBech32 = address.startsWith('bc1'); + const isBech32 = address.startsWith('bc1') || address.startsWith('tb1'); if (isBech32) { address = address.toUpperCase(); } diff --git a/class/multisig-cosigner.ts b/class/multisig-cosigner.ts index d8c938520c9..b6a40784d38 100644 --- a/class/multisig-cosigner.ts +++ b/class/multisig-cosigner.ts @@ -2,6 +2,7 @@ import BIP32Factory from 'bip32'; import b58 from 'bs58check'; import ecc from '../blue_modules/noble_ecc'; +import { getNetwork } from '../models/network'; import { MultisigHDWallet } from './wallets/multisig-hd-wallet'; import assert from 'assert'; const bip32 = BIP32Factory(ecc); @@ -173,7 +174,7 @@ export class MultisigCosigner { try { const tempWallet = new MultisigHDWallet(); xpub = tempWallet._zpubToXpub(key); - bip32.fromBase58(xpub); + bip32.fromBase58(xpub, getNetwork()); return true; } catch (_) {} diff --git a/class/payjoin-transaction.ts b/class/payjoin-transaction.ts index 358ecaa1ac0..d1758179e73 100644 --- a/class/payjoin-transaction.ts +++ b/class/payjoin-transaction.ts @@ -7,6 +7,7 @@ import presentAlert from '../components/Alert'; import { HDSegwitBech32Wallet } from './wallets/hd-segwit-bech32-wallet'; import assert from 'assert'; import { uint8ArrayToHex } from '../blue_modules/uint8array-extras'; +import { getNetwork } from '../models/network'; const ECPair = ECPairFactory(ecc); const delay = (milliseconds: number) => new Promise(resolve => setTimeout(resolve, milliseconds)); @@ -33,9 +34,9 @@ export default class PayjoinTransaction { delete input.finalScriptWitness; assert(input.witnessUtxo, 'Internal error: input.witnessUtxo is not set'); - const address = bitcoin.address.fromOutputScript(input.witnessUtxo.script); + const address = bitcoin.address.fromOutputScript(input.witnessUtxo.script, getNetwork()); const wif = this._wallet._getWifForAddress(address); - const keyPair = ECPair.fromWIF(wif); + const keyPair = ECPair.fromWIF(wif, getNetwork()); unfinalized.signInput(index, keyPair); } @@ -77,10 +78,10 @@ export default class PayjoinTransaction { for (const [index, input] of payjoinPsbt.data.inputs.entries()) { assert(input.witnessUtxo, 'Internal error: input.witnessUtxo is not set'); - const address = bitcoin.address.fromOutputScript(input.witnessUtxo.script); + const address = bitcoin.address.fromOutputScript(input.witnessUtxo.script, getNetwork()); try { const wif = this._wallet._getWifForAddress(address); - const keyPair = ECPair.fromWIF(wif); + const keyPair = ECPair.fromWIF(wif, getNetwork()); payjoinPsbt.signInput(index, keyPair).finalizeInput(index); } catch (e) {} } diff --git a/class/wallets/abstract-hd-electrum-wallet.ts b/class/wallets/abstract-hd-electrum-wallet.ts index 08f4b0d4e80..d20a2496f07 100644 --- a/class/wallets/abstract-hd-electrum-wallet.ts +++ b/class/wallets/abstract-hd-electrum-wallet.ts @@ -19,6 +19,7 @@ import { AbstractHDWallet } from './abstract-hd-wallet'; import { CreateTransactionResult, CreateTransactionTarget, CreateTransactionUtxo, Transaction, Utxo } from './types'; import { SilentPayment, UTXOType as SPUTXOType, UTXO as SPUTXO } from 'silent-payments'; import { isValidBech32Address } from '../../util/isValidBech32Address.ts'; +import { getNetwork, isTestnet } from '../../models/network'; const ECPair = ECPairFactory(ecc); const bip32 = BIP32Factory(ecc); @@ -42,6 +43,8 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { // @ts-ignore: override public readonly typeReadable = AbstractHDElectrumWallet.typeReadable; + public readonly network?: bitcoin.networks.Network; + _balances_by_external_index: Record; _balances_by_internal_index: Record; @@ -188,7 +191,7 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { _getWIFByIndex(internal: boolean, index: number): string | false { if (!this.secret) return false; const seed = this._getSeed(); - const root = bip32.fromSeed(seed); + const root = bip32.fromSeed(seed, getNetwork()); const path = `${this.getDerivationPath()}/${internal ? 1 : 0}/${index}`; const child = root.derivePath(path); @@ -207,13 +210,13 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { if (node === 0 && !this._node0) { const xpub = this._zpubToXpub(this.getXpub()); - const hdNode = bip32.fromBase58(xpub); + const hdNode = bip32.fromBase58(xpub, getNetwork()); this._node0 = hdNode.derive(node); } if (node === 1 && !this._node1) { const xpub = this._zpubToXpub(this.getXpub()); - const hdNode = bip32.fromBase58(xpub); + const hdNode = bip32.fromBase58(xpub, getNetwork()); this._node1 = hdNode.derive(node); } @@ -240,13 +243,13 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { if (node === 0 && !this._node0) { const xpub = this._zpubToXpub(this.getXpub()); - const hdNode = bip32.fromBase58(xpub); + const hdNode = bip32.fromBase58(xpub, getNetwork()); this._node0 = hdNode.derive(node); } if (node === 1 && !this._node1) { const xpub = this._zpubToXpub(this.getXpub()); - const hdNode = bip32.fromBase58(xpub); + const hdNode = bip32.fromBase58(xpub, getNetwork()); this._node1 = hdNode.derive(node); } @@ -281,7 +284,7 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { } // first, getting xpub const seed = this._getSeed(); - const root = bip32.fromSeed(seed); + const root = bip32.fromSeed(seed, getNetwork()); const path = this.getDerivationPath(); if (!path) { @@ -290,10 +293,12 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { const child = root.derivePath(path).neutered(); const xpub = child.toBase58(); - // bitcoinjs does not support zpub yet, so we just convert it from xpub + // bitcoinjs does not support zpub yet, so we just convert it from xpub/tpub let data = b58.decode(xpub); data = data.slice(4); - const concatenated = concatUint8Arrays([hexToUint8Array('04b24746'), data]); + // mainnet zpub prefix: 04b24746, testnet vpub prefix: 045f1cf6 + const prefix = isTestnet() ? '045f1cf6' : '04b24746'; + const concatenated = concatUint8Arrays([hexToUint8Array(prefix), data]); this._xpub = b58.encode(concatenated); return this._xpub; @@ -1214,7 +1219,7 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { } sequence = sequence || AbstractHDElectrumWallet.defaultRBFSequence; - let psbt = new bitcoin.Psbt(); + let psbt = new bitcoin.Psbt({ network: getNetwork() }); let c = 0; const keypairs: Record = {}; const values: Record = {}; @@ -1223,7 +1228,7 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { let keyPair; if (!skipSigning) { // skiping signing related stuff - keyPair = ECPair.fromWIF(this._getWifForAddress(String(input.address))); + keyPair = ECPair.fromWIF(this._getWifForAddress(String(input.address)), getNetwork()); keypairs[c] = keyPair; } values[c] = input.value; @@ -1340,7 +1345,7 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { if (!pubkey || !path) { throw new Error('Internal error: pubkey or path are invalid'); } - const p2wpkh = bitcoin.payments.p2wpkh({ pubkey }); + const p2wpkh = bitcoin.payments.p2wpkh({ pubkey, network: getNetwork() }); if (!p2wpkh.output) { throw new Error('Internal error: could not create p2wpkh output during _addPsbtInput'); } @@ -1395,6 +1400,7 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { _nodeToBech32SegwitAddress(hdNode: BIP32Interface): string { const { address } = bitcoin.payments.p2wpkh({ pubkey: hdNode.publicKey, + network: getNetwork(), }); if (!address) { @@ -1407,6 +1413,7 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { _nodeToLegacyAddress(hdNode: BIP32Interface): string { const { address } = bitcoin.payments.p2pkh({ pubkey: hdNode.publicKey, + network: getNetwork(), }); if (!address) { @@ -1421,7 +1428,8 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { */ _nodeToP2shSegwitAddress(hdNode: BIP32Interface): string { const { address } = bitcoin.payments.p2sh({ - redeem: bitcoin.payments.p2wpkh({ pubkey: hdNode.publicKey }), + redeem: bitcoin.payments.p2wpkh({ pubkey: hdNode.publicKey, network: getNetwork() }), + network: getNetwork(), }); if (!address) { @@ -1464,7 +1472,11 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { return false; } // only check BIP47 if derivation path is regular, otherwise too many wallets will be found - if (!["m/84'/0'/0'", "m/44'/0'/0'", "m/49'/0'/0'"].includes(this.getDerivationPath() as string)) { + if ( + !["m/84'/0'/0'", "m/44'/0'/0'", "m/49'/0'/0'", "m/84'/1'/0'", "m/44'/1'/0'", "m/49'/1'/0'"].includes( + this.getDerivationPath() as string, + ) + ) { return false; } @@ -1528,7 +1540,7 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { */ cosignPsbt(psbt: Psbt) { const seed = this._getSeed(); - const hdRoot = bip32.fromSeed(seed); + const hdRoot = bip32.fromSeed(seed, getNetwork()); for (let cc = 0; cc < psbt.inputCount; cc++) { try { @@ -1544,7 +1556,7 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { if (!wif) { throw new Error('Internal error: cant get WIF by index during cosingPsbt'); } - const keyPair = ECPair.fromWIF(wif); + const keyPair = ECPair.fromWIF(wif, getNetwork()); try { psbt.signInput(cc, keyPair); } catch (e) {} // protects agains duplicate cosignings or if this output can't be signed with current wallet @@ -1565,7 +1577,7 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { * @returns {string} Hex string of fingerprint derived from mnemonics. Always has length of 8 chars and correct leading zeroes. All caps */ static seedToFingerprint(seed: Uint8Array) { - const root = bip32.fromSeed(seed); + const root = bip32.fromSeed(seed, getNetwork()); let hex = uint8ArrayToHex(root.fingerprint); while (hex.length < 8) hex = '0' + hex; // leading zeroes return hex.toUpperCase(); @@ -1711,7 +1723,7 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet { // utxo selected. lets create op_return payload using the correct (first!) utxo and correct targets with that payload - const keyPair = ECPair.fromWIF(inputsTemp[0].wif); + const keyPair = ECPair.fromWIF(inputsTemp[0].wif, getNetwork()); const outputNumber = new Uint8Array(4); // 00000000 in hex new DataView(outputNumber.buffer).setUint32(0, inputsTemp[0].vout, true); // little-endian const blindedPaymentCode = aliceBip47.getBlindedPaymentCode( diff --git a/class/wallets/abstract-hd-wallet.ts b/class/wallets/abstract-hd-wallet.ts index a7ccbb04efa..a463cfc8bd2 100644 --- a/class/wallets/abstract-hd-wallet.ts +++ b/class/wallets/abstract-hd-wallet.ts @@ -3,6 +3,7 @@ import * as bip39 from 'bip39'; import * as bip39custom from '../../blue_modules/bip39'; import * as BlueElectrum from '../../blue_modules/BlueElectrum'; +import { isTestnet } from '../../models/network'; import { LegacyWallet } from './legacy-wallet'; import { Transaction } from './types'; @@ -32,6 +33,7 @@ export class AbstractHDWallet extends LegacyWallet { passphrase?: string; _node0?: BIP32Interface; _node1?: BIP32Interface; + _cachedForNetwork?: string; constructor() { super(); @@ -45,6 +47,7 @@ export class AbstractHDWallet extends LegacyWallet { this._address_to_wif_cache = {}; this.gap_limit = 20; this._derivationPath = Constructor.derivationPath; + this._cachedForNetwork = isTestnet() ? 'testnet' : 'mainnet'; } getNextFreeAddressIndex(): number { @@ -55,6 +58,24 @@ export class AbstractHDWallet extends LegacyWallet { return this.next_free_change_address_index; } + static fromJson(obj: string): AbstractHDWallet { + const wallet = super.fromJson(obj) as AbstractHDWallet; + const currentNetworkKey = isTestnet() ? 'testnet' : 'mainnet'; + if (wallet._cachedForNetwork !== currentNetworkKey) { + // Network changed since wallet was last saved — clear all derived caches + // so addresses and xpubs are re-derived for the correct network. + wallet.external_addresses_cache = {}; + wallet.internal_addresses_cache = {}; + wallet._address_to_wif_cache = {}; + wallet._address = false; + delete wallet._node0; + delete wallet._node1; + wallet._xpub = ''; + wallet._cachedForNetwork = currentNetworkKey; + } + return wallet; + } + prepareForSerialization(): void { // deleting structures that cant be serialized delete this._node0; @@ -322,7 +343,12 @@ export class AbstractHDWallet extends LegacyWallet { /** * @returns {string} Root derivation path for wallet if any */ - getDerivationPath() { + getDerivationPath(): string { + if (!this._derivationPath) return this._derivationPath || ''; + // On testnet/signet, swap coin type 0 to 1 (e.g. m/84'/0'/0' -> m/84'/1'/0') + if (isTestnet()) { + return this._derivationPath.replace(/^(m\/\d+')\/0'\//, "$1/1'/"); + } return this._derivationPath; } diff --git a/class/wallets/abstract-wallet.ts b/class/wallets/abstract-wallet.ts index cae1f856b2b..60ac836e981 100644 --- a/class/wallets/abstract-wallet.ts +++ b/class/wallets/abstract-wallet.ts @@ -3,6 +3,7 @@ import { sha256 } from '@noble/hashes/sha256'; import wif from 'wif'; import { BitcoinUnit, Chain } from '../../models/bitcoinUnits'; +import { isTestnet } from '../../models/network'; import { CreateTransactionResult, CreateTransactionUtxo, Transaction, Utxo } from './types'; import { hexToUint8Array, concatUint8Arrays, uint8ArrayToHex } from '../../blue_modules/uint8array-extras'; @@ -456,7 +457,9 @@ export class AbstractWallet { _zpubToXpub(zpub: string): string { let data = b58.decode(zpub); data = data.slice(4); - const concatenated = concatUint8Arrays([hexToUint8Array('0488b21e'), data]); + // mainnet xpub prefix: 0488b21e, testnet tpub prefix: 043587cf + const prefix = isTestnet() ? '043587cf' : '0488b21e'; + const concatenated = concatUint8Arrays([hexToUint8Array(prefix), data]); return b58.encode(concatenated); } diff --git a/class/wallets/hd-aezeed-wallet.ts b/class/wallets/hd-aezeed-wallet.ts index aea2e92aee4..f772e8a71a5 100644 --- a/class/wallets/hd-aezeed-wallet.ts +++ b/class/wallets/hd-aezeed-wallet.ts @@ -5,6 +5,7 @@ import b58 from 'bs58check'; import ecc from '../../blue_modules/noble_ecc'; import { concatUint8Arrays, hexToUint8Array, uint8ArrayToHex } from '../../blue_modules/uint8array-extras'; +import { getNetwork } from '../../models/network'; import { AbstractHDElectrumWallet } from './abstract-hd-electrum-wallet'; const bip32 = BIP32Factory(ecc); @@ -48,9 +49,9 @@ export class HDAezeedWallet extends AbstractHDElectrumWallet { getXpub() { // first, getting xpub - const root = bip32.fromSeed(this._getEntropyCached()); + const root = bip32.fromSeed(this._getEntropyCached(), getNetwork()); - const path = "m/84'/0'/0'"; + const path = this.getDerivationPath(); const child = root.derivePath(path).neutered(); const xpub = child.toBase58(); @@ -94,14 +95,16 @@ export class HDAezeedWallet extends AbstractHDElectrumWallet { } _getNode0() { - const root = bip32.fromSeed(this._getEntropyCached()); - const node = root.derivePath("m/84'/0'/0'"); + const root = bip32.fromSeed(this._getEntropyCached(), getNetwork()); + const path = this.getDerivationPath(); + const node = root.derivePath(path); return node.derive(0); } _getNode1() { - const root = bip32.fromSeed(this._getEntropyCached()); - const node = root.derivePath("m/84'/0'/0'"); + const root = bip32.fromSeed(this._getEntropyCached(), getNetwork()); + const path = this.getDerivationPath(); + const node = root.derivePath(path); return node.derive(1); } @@ -113,6 +116,7 @@ export class HDAezeedWallet extends AbstractHDElectrumWallet { const address = bitcoin.payments.p2wpkh({ pubkey: this._node1.derive(index).publicKey, + network: getNetwork(), }).address; if (!address) { throw new Error('Internal error: no address in _getInternalAddressByIndex'); @@ -129,6 +133,7 @@ export class HDAezeedWallet extends AbstractHDElectrumWallet { const address = bitcoin.payments.p2wpkh({ pubkey: this._node0.derive(index).publicKey, + network: getNetwork(), }).address; if (!address) { throw new Error('Internal error: no address in _getExternalAddressByIndex'); @@ -139,8 +144,9 @@ export class HDAezeedWallet extends AbstractHDElectrumWallet { _getWIFByIndex(internal: boolean, index: number): string | false { if (!this.secret) return false; - const root = bip32.fromSeed(this._getEntropyCached()); - const path = `m/84'/0'/0'/${internal ? 1 : 0}/${index}`; + const root = bip32.fromSeed(this._getEntropyCached(), getNetwork()); + const derivationPath = this.getDerivationPath(); + const path = `${derivationPath}/${internal ? 1 : 0}/${index}`; const child = root.derivePath(path); return child.toWIF(); @@ -169,7 +175,7 @@ export class HDAezeedWallet extends AbstractHDElectrumWallet { } getIdentityPubkey() { - const root = bip32.fromSeed(this._getEntropyCached()); + const root = bip32.fromSeed(this._getEntropyCached(), getNetwork()); const node = root.derivePath("m/1017'/0'/6'/0/0"); return uint8ArrayToHex(node.publicKey); diff --git a/class/wallets/hd-legacy-breadwallet-wallet.ts b/class/wallets/hd-legacy-breadwallet-wallet.ts index adc1e027b79..430395ba11f 100644 --- a/class/wallets/hd-legacy-breadwallet-wallet.ts +++ b/class/wallets/hd-legacy-breadwallet-wallet.ts @@ -8,6 +8,7 @@ import { ElectrumHistory } from '../../blue_modules/BlueElectrum'; import ecc from '../../blue_modules/noble_ecc'; import { AbstractHDElectrumWallet } from './abstract-hd-electrum-wallet'; import { HDLegacyP2PKHWallet } from './hd-legacy-p2pkh-wallet'; +import { getNetwork } from '../../models/network'; const bip32 = BIP32Factory(ecc); @@ -32,10 +33,10 @@ export class HDLegacyBreadwalletWallet extends HDLegacyP2PKHWallet { _calcNodeAddressByIndex(node: number, index: number, p2wpkh: boolean = false) { let _node: BIP32Interface | undefined; if (node === 0) { - _node = this._node0 || (this._node0 = bip32.fromBase58(this.getXpub()).derive(node)); + _node = this._node0 || (this._node0 = bip32.fromBase58(this.getXpub(), getNetwork()).derive(node)); } if (node === 1) { - _node = this._node1 || (this._node1 = bip32.fromBase58(this.getXpub()).derive(node)); + _node = this._node1 || (this._node1 = bip32.fromBase58(this.getXpub(), getNetwork()).derive(node)); } if (!_node) { @@ -43,7 +44,9 @@ export class HDLegacyBreadwalletWallet extends HDLegacyP2PKHWallet { } const pubkey = _node.derive(index).publicKey; - const address = p2wpkh ? bitcoinjs.payments.p2wpkh({ pubkey }).address : bitcoinjs.payments.p2pkh({ pubkey }).address; + const address = p2wpkh + ? bitcoinjs.payments.p2wpkh({ pubkey, network: getNetwork() }).address + : bitcoinjs.payments.p2pkh({ pubkey, network: getNetwork() }).address; if (!address) { throw new Error('Internal error: no address in _calcNodeAddressByIndex'); diff --git a/class/wallets/hd-legacy-electrum-seed-p2pkh-wallet.ts b/class/wallets/hd-legacy-electrum-seed-p2pkh-wallet.ts index 6ce6aac804d..face3e5f268 100644 --- a/class/wallets/hd-legacy-electrum-seed-p2pkh-wallet.ts +++ b/class/wallets/hd-legacy-electrum-seed-p2pkh-wallet.ts @@ -4,6 +4,7 @@ import * as mn from 'electrum-mnemonic'; import ecc from '../../blue_modules/noble_ecc'; import { HDLegacyP2PKHWallet } from './hd-legacy-p2pkh-wallet'; +import { getNetwork } from '../../models/network'; const bip32 = BIP32Factory(ecc); const PREFIX = mn.PREFIXES.standard; @@ -46,7 +47,7 @@ export class HDLegacyElectrumSeedP2PKHWallet extends HDLegacyP2PKHWallet { } const args: SeedOpts = { prefix: PREFIX }; if (this.passphrase) args.passphrase = this.passphrase; - const root = bip32.fromSeed(mn.mnemonicToSeedSync(this.secret, args)); + const root = bip32.fromSeed(mn.mnemonicToSeedSync(this.secret, args), getNetwork()); this._xpub = root.neutered().toBase58(); return this._xpub; } @@ -55,9 +56,10 @@ export class HDLegacyElectrumSeedP2PKHWallet extends HDLegacyP2PKHWallet { index = index * 1; // cast to int if (this.internal_addresses_cache[index]) return this.internal_addresses_cache[index]; // cache hit - const node = bip32.fromBase58(this.getXpub()); + const node = bip32.fromBase58(this.getXpub(), getNetwork()); const address = bitcoin.payments.p2pkh({ pubkey: node.derive(1).derive(index).publicKey, + network: getNetwork(), }).address; if (!address) { throw new Error('Internal error: no address in _getInternalAddressByIndex'); @@ -70,9 +72,10 @@ export class HDLegacyElectrumSeedP2PKHWallet extends HDLegacyP2PKHWallet { index = index * 1; // cast to int if (this.external_addresses_cache[index]) return this.external_addresses_cache[index]; // cache hit - const node = bip32.fromBase58(this.getXpub()); + const node = bip32.fromBase58(this.getXpub(), getNetwork()); const address = bitcoin.payments.p2pkh({ pubkey: node.derive(0).derive(index).publicKey, + network: getNetwork(), }).address; if (!address) { throw new Error('Internal error: no address in _getExternalAddressByIndex'); @@ -85,7 +88,7 @@ export class HDLegacyElectrumSeedP2PKHWallet extends HDLegacyP2PKHWallet { if (!this.secret) return false; const args: SeedOpts = { prefix: PREFIX }; if (this.passphrase) args.passphrase = this.passphrase; - const root = bip32.fromSeed(mn.mnemonicToSeedSync(this.secret, args)); + const root = bip32.fromSeed(mn.mnemonicToSeedSync(this.secret, args), getNetwork()); const path = `m/${internal ? 1 : 0}/${index}`; const child = root.derivePath(path); @@ -97,13 +100,13 @@ export class HDLegacyElectrumSeedP2PKHWallet extends HDLegacyP2PKHWallet { if (node === 0 && !this._node0) { const xpub = this.getXpub(); - const hdNode = bip32.fromBase58(xpub); + const hdNode = bip32.fromBase58(xpub, getNetwork()); this._node0 = hdNode.derive(node); } if (node === 1 && !this._node1) { const xpub = this.getXpub(); - const hdNode = bip32.fromBase58(xpub); + const hdNode = bip32.fromBase58(xpub, getNetwork()); this._node1 = hdNode.derive(node); } diff --git a/class/wallets/hd-legacy-p2pkh-wallet.ts b/class/wallets/hd-legacy-p2pkh-wallet.ts index 8b81f9e8689..5ee7e4aebd3 100644 --- a/class/wallets/hd-legacy-p2pkh-wallet.ts +++ b/class/wallets/hd-legacy-p2pkh-wallet.ts @@ -6,6 +6,7 @@ import * as BlueElectrum from '../../blue_modules/BlueElectrum'; import ecc from '../../blue_modules/noble_ecc'; import { AbstractHDElectrumWallet } from './abstract-hd-electrum-wallet'; import { hexToUint8Array } from '../../blue_modules/uint8array-extras'; +import { getNetwork } from '../../models/network'; const bip32 = BIP32Factory(ecc); @@ -52,7 +53,7 @@ export class HDLegacyP2PKHWallet extends AbstractHDElectrumWallet { return this._xpub; // cache hit } const seed = this._getSeed(); - const root = bip32.fromSeed(seed); + const root = bip32.fromSeed(seed, getNetwork()); const path = this.getDerivationPath(); if (!path) { diff --git a/class/wallets/hd-segwit-electrum-seed-p2wpkh-wallet.ts b/class/wallets/hd-segwit-electrum-seed-p2wpkh-wallet.ts index 0ec4071844d..f7c188f6c2b 100644 --- a/class/wallets/hd-segwit-electrum-seed-p2wpkh-wallet.ts +++ b/class/wallets/hd-segwit-electrum-seed-p2wpkh-wallet.ts @@ -6,6 +6,7 @@ import * as mn from 'electrum-mnemonic'; import ecc from '../../blue_modules/noble_ecc'; import { concatUint8Arrays, hexToUint8Array } from '../../blue_modules/uint8array-extras'; import { HDSegwitBech32Wallet } from './hd-segwit-bech32-wallet'; +import { getNetwork } from '../../models/network'; const bip32 = BIP32Factory(ecc); const PREFIX = mn.PREFIXES.segwit; @@ -48,7 +49,7 @@ export class HDSegwitElectrumSeedP2WPKHWallet extends HDSegwitBech32Wallet { } const args: SeedOpts = { prefix: PREFIX }; if (this.passphrase) args.passphrase = this.passphrase; - const root = bip32.fromSeed(mn.mnemonicToSeedSync(this.secret, args)); + const root = bip32.fromSeed(mn.mnemonicToSeedSync(this.secret, args), getNetwork()); const xpub = root.derivePath("m/0'").neutered().toBase58(); // bitcoinjs does not support zpub yet, so we just convert it from xpub @@ -65,9 +66,10 @@ export class HDSegwitElectrumSeedP2WPKHWallet extends HDSegwitBech32Wallet { if (this.internal_addresses_cache[index]) return this.internal_addresses_cache[index]; // cache hit const xpub = this._zpubToXpub(this.getXpub()); - const node = bip32.fromBase58(xpub); + const node = bip32.fromBase58(xpub, getNetwork()); const address = bitcoin.payments.p2wpkh({ pubkey: node.derive(1).derive(index).publicKey, + network: getNetwork(), }).address; if (!address) { throw new Error('Internal error: no address in _getInternalAddressByIndex'); @@ -81,9 +83,10 @@ export class HDSegwitElectrumSeedP2WPKHWallet extends HDSegwitBech32Wallet { if (this.external_addresses_cache[index]) return this.external_addresses_cache[index]; // cache hit const xpub = this._zpubToXpub(this.getXpub()); - const node = bip32.fromBase58(xpub); + const node = bip32.fromBase58(xpub, getNetwork()); const address = bitcoin.payments.p2wpkh({ pubkey: node.derive(0).derive(index).publicKey, + network: getNetwork(), }).address; if (!address) { throw new Error('Internal error: no address in _getExternalAddressByIndex'); @@ -96,7 +99,7 @@ export class HDSegwitElectrumSeedP2WPKHWallet extends HDSegwitBech32Wallet { if (!this.secret) return false; const args: SeedOpts = { prefix: PREFIX }; if (this.passphrase) args.passphrase = this.passphrase; - const root = bip32.fromSeed(mn.mnemonicToSeedSync(this.secret, args)); + const root = bip32.fromSeed(mn.mnemonicToSeedSync(this.secret, args), getNetwork()); const path = `m/0'/${internal ? 1 : 0}/${index}`; const child = root.derivePath(path); @@ -108,13 +111,13 @@ export class HDSegwitElectrumSeedP2WPKHWallet extends HDSegwitBech32Wallet { if (node === 0 && !this._node0) { const xpub = this._zpubToXpub(this.getXpub()); - const hdNode = bip32.fromBase58(xpub); + const hdNode = bip32.fromBase58(xpub, getNetwork()); this._node0 = hdNode.derive(node); } if (node === 1 && !this._node1) { const xpub = this._zpubToXpub(this.getXpub()); - const hdNode = bip32.fromBase58(xpub); + const hdNode = bip32.fromBase58(xpub, getNetwork()); this._node1 = hdNode.derive(node); } diff --git a/class/wallets/hd-segwit-p2sh-wallet.ts b/class/wallets/hd-segwit-p2sh-wallet.ts index 0e3d88f6ed0..fcf09fb2a76 100644 --- a/class/wallets/hd-segwit-p2sh-wallet.ts +++ b/class/wallets/hd-segwit-p2sh-wallet.ts @@ -7,6 +7,7 @@ import { CoinSelectReturnInput } from 'coinselect'; import ecc from '../../blue_modules/noble_ecc'; import { concatUint8Arrays, hexToUint8Array } from '../../blue_modules/uint8array-extras'; import { AbstractHDElectrumWallet } from './abstract-hd-electrum-wallet'; +import { getNetwork } from '../../models/network'; const bip32 = BIP32Factory(ecc); @@ -61,7 +62,7 @@ export class HDSegwitP2SHWallet extends AbstractHDElectrumWallet { } // first, getting xpub const seed = this._getSeed(); - const root = bip32.fromSeed(seed); + const root = bip32.fromSeed(seed, getNetwork()); const path = this.getDerivationPath(); if (!path) { @@ -88,8 +89,8 @@ export class HDSegwitP2SHWallet extends AbstractHDElectrumWallet { if (!pubkey || !path) { throw new Error('Internal error: pubkey or path are invalid'); } - const p2wpkh = bitcoin.payments.p2wpkh({ pubkey }); - const p2sh = bitcoin.payments.p2sh({ redeem: p2wpkh }); + const p2wpkh = bitcoin.payments.p2wpkh({ pubkey, network: getNetwork() }); + const p2sh = bitcoin.payments.p2sh({ redeem: p2wpkh, network: getNetwork() }); if (!p2sh.output) { throw new Error('Internal error: no p2sh.output during _addPsbtInput()'); } diff --git a/class/wallets/hd-taproot-wallet.ts b/class/wallets/hd-taproot-wallet.ts index 8d0851b1a2a..5fecb725d78 100644 --- a/class/wallets/hd-taproot-wallet.ts +++ b/class/wallets/hd-taproot-wallet.ts @@ -4,6 +4,7 @@ import ecc from '../../blue_modules/noble_ecc'; import * as bitcoin from 'bitcoinjs-lib'; import { Psbt } from 'bitcoinjs-lib'; import { CoinSelectReturnInput } from 'coinselect'; +import { getNetwork } from '../../models/network'; const bip32 = BIP32Factory(ecc); @@ -25,7 +26,7 @@ export class HDTaprootWallet extends AbstractHDElectrumWallet { return this._xpub; // cache hit } const seed = this._getSeed(); - const root = bip32.fromSeed(seed); + const root = bip32.fromSeed(seed, getNetwork()); const path = this.getDerivationPath(); if (!path) { @@ -49,6 +50,7 @@ export class HDTaprootWallet extends AbstractHDElectrumWallet { const { address } = bitcoin.payments.p2tr({ internalPubkey: xOnlyPubkey, + network: getNetwork(), }); if (!address) { @@ -67,7 +69,7 @@ export class HDTaprootWallet extends AbstractHDElectrumWallet { // bip32.fromBase58() wont work with zpub prefix, need to swap it for the traditional one xpub = this._zpubToXpub(xpub); } - const hdNode = bip32.fromBase58(xpub); + const hdNode = bip32.fromBase58(xpub, getNetwork()); this._node0 = hdNode.derive(node); } @@ -77,7 +79,7 @@ export class HDTaprootWallet extends AbstractHDElectrumWallet { // bip32.fromBase58() wont work with zpub prefix, need to swap it for the traditional one xpub = this._zpubToXpub(xpub); } - const hdNode = bip32.fromBase58(xpub); + const hdNode = bip32.fromBase58(xpub, getNetwork()); this._node1 = hdNode.derive(node); } @@ -104,6 +106,7 @@ export class HDTaprootWallet extends AbstractHDElectrumWallet { const p2tr = bitcoin.payments.p2tr({ internalPubkey: pubkey, + network: getNetwork(), }); if (!p2tr.output) throw new Error('Could not build p2tr.output'); diff --git a/class/wallets/legacy-wallet.ts b/class/wallets/legacy-wallet.ts index 2684dd75c64..6634947146d 100644 --- a/class/wallets/legacy-wallet.ts +++ b/class/wallets/legacy-wallet.ts @@ -12,6 +12,7 @@ import { HDSegwitBech32Wallet } from '..'; import { randomBytes } from '../rng'; import { AbstractWallet } from './abstract-wallet'; import { CreateTransactionResult, CreateTransactionTarget, CreateTransactionUtxo, Transaction, Utxo } from './types'; +import { getNetwork } from '../../models/network'; const ECPair: ECPairAPI = ECPairFactory(ecc); bitcoin.initEccLib(ecc); @@ -60,23 +61,24 @@ export class LegacyWallet extends AbstractWallet { async generate(): Promise { const buf = await randomBytes(32); - this.secret = ECPair.makeRandom({ rng: () => buf }).toWIF(); + this.secret = ECPair.makeRandom({ rng: () => buf, network: getNetwork() }).toWIF(); } async generateFromEntropy(user: Uint8Array): Promise { if (user.length !== 32) { throw new Error('Entropy should be 32 bytes'); } - this.secret = ECPair.fromPrivateKey(user).toWIF(); + this.secret = ECPair.fromPrivateKey(user, { network: getNetwork() }).toWIF(); } getAddress(): string | false { if (this._address) return this._address; let address; try { - const keyPair = ECPair.fromWIF(this.secret); + const keyPair = ECPair.fromWIF(this.secret, getNetwork()); address = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, + network: getNetwork(), }).address; } catch (err) { return false; @@ -404,9 +406,9 @@ export class LegacyWallet extends AbstractWallet { } for (const t of _targets) { - if (t.address?.startsWith('bc1')) { + if (t.address?.startsWith('bc1') || t.address?.startsWith('tb1')) { // in case address is non-typical and takes more bytes than coinselect library anticipates by default - t.script = { length: bitcoin.address.toOutputScript(t.address).length + 3 }; + t.script = { length: bitcoin.address.toOutputScript(t.address, getNetwork()).length + 3 }; } if (t.script?.hex) { @@ -448,14 +450,14 @@ export class LegacyWallet extends AbstractWallet { if (targets.length === 0) throw new Error('No destination provided'); const { inputs, outputs, fee } = this.coinselect(utxos, targets, feeRate); sequence = sequence || 0xffffffff; // disable RBF by default - const psbt = new bitcoin.Psbt(); + const psbt = new bitcoin.Psbt({ network: getNetwork() }); let c = 0; const values: Record = {}; let keyPair: Signer | null = null; if (!skipSigning) { // skiping signing related stuff - keyPair = ECPair.fromWIF(this.secret); // secret is WIF + keyPair = ECPair.fromWIF(this.secret, getNetwork()); // secret is WIF } inputs.forEach(input => { @@ -526,9 +528,9 @@ export class LegacyWallet extends AbstractWallet { */ isAddressValid(address: string): boolean { try { - bitcoin.address.toOutputScript(address); // throws, no? + bitcoin.address.toOutputScript(address, getNetwork()); // throws, no? - if (!address.toLowerCase().startsWith('bc1')) return true; + if (!address.toLowerCase().startsWith('bc1') && !address.toLowerCase().startsWith('tb1')) return true; const decoded = bitcoin.address.fromBech32(address); if (decoded.version === 0) return true; if (decoded.version === 1 && decoded.data.length !== 32) return false; @@ -553,7 +555,7 @@ export class LegacyWallet extends AbstractWallet { return ( bitcoin.payments.p2pkh({ output: scriptPubKey2, - network: bitcoin.networks.bitcoin, + network: getNetwork(), }).address ?? false ); } catch (_) { @@ -615,7 +617,7 @@ export class LegacyWallet extends AbstractWallet { signMessage(message: string, address: string, useSegwit = true): string { const wif = this._getWIFbyAddress(address); if (!wif) throw new Error('Invalid address'); - const keyPair = ECPair.fromWIF(wif); + const keyPair = ECPair.fromWIF(wif, getNetwork()); const privateKey = keyPair.privateKey; if (!privateKey) throw new Error('Invalid private key'); let segwitType: 'p2wpkh' | 'p2sh(p2wpkh)'; diff --git a/class/wallets/lightning-ark-wallet.ts b/class/wallets/lightning-ark-wallet.ts index 20639e0af49..2471830fb28 100644 --- a/class/wallets/lightning-ark-wallet.ts +++ b/class/wallets/lightning-ark-wallet.ts @@ -15,6 +15,7 @@ import { LightningTransaction, Transaction } from './types.ts'; import { hexToUint8Array, uint8ArrayToHex } from '../../blue_modules/uint8array-extras/index'; import assert from 'assert'; import ecc from '../../blue_modules/noble_ecc.ts'; +import { getNetwork, isTestnet } from '../../models/network'; import { Measure } from '../measure.ts'; const { bech32m } = require('bech32'); @@ -69,8 +70,8 @@ export class LightningArkWallet extends LightningCustodianWallet { const index = 0; const internal = 0; const accountNumber = 0; - const root = bip32.fromSeed(seed); - const path = `m/86'/0'/${accountNumber}'/${internal}/${index}`; + const root = bip32.fromSeed(seed, getNetwork()); + const path = `m/86'/${isTestnet() ? 1 : 0}'/${accountNumber}'/${internal}/${index}`; const child = root.derivePath(path); assert(child.privateKey, 'Internal error: no private key for child'); diff --git a/class/wallets/multisig-hd-wallet.ts b/class/wallets/multisig-hd-wallet.ts index 1ffe2cd0c8d..1f649d53d8e 100644 --- a/class/wallets/multisig-hd-wallet.ts +++ b/class/wallets/multisig-hd-wallet.ts @@ -9,6 +9,7 @@ import { ECPairFactory } from 'ecpair'; import * as mn from 'electrum-mnemonic'; import * as BlueElectrum from '../../blue_modules/BlueElectrum'; +import { getNetwork } from '../../models/network'; import ecc from '../../blue_modules/noble_ecc'; import { decodeUR } from '../../blue_modules/ur'; import { AbstractHDElectrumWallet } from './abstract-hd-electrum-wallet'; @@ -183,7 +184,7 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { try { const tempWallet = new MultisigHDWallet(); xpub = tempWallet._zpubToXpub(key); - bip32.fromBase58(xpub); + bip32.fromBase58(xpub, getNetwork()); return true; } catch (_) {} @@ -193,7 +194,7 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { static isXprvValid(xprv: string): boolean { try { xprv = MultisigHDWallet.convertMultisigXprvToRegularXprv(xprv); - bip32.fromBase58(xprv); + bip32.fromBase58(xprv, getNetwork()); return true; } catch (_) { return false; @@ -260,7 +261,7 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { } static convertXprvToXpub(xprv: string) { - const restored = bip32.fromBase58(MultisigHDWallet.convertMultisigXprvToRegularXprv(xprv)); + const restored = bip32.fromBase58(MultisigHDWallet.convertMultisigXprvToRegularXprv(xprv), getNetwork()); return restored.neutered().toBase58(); } @@ -307,7 +308,7 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { if (!this._nodes[nodeIndex][cosignerIndex]) { const xpub = this._getXpubFromCosignerIndex(cosignerIndex); - const hdNode = bip32.fromBase58(xpub); + const hdNode = bip32.fromBase58(xpub, getNetwork()); _node = hdNode.derive(nodeIndex); this._nodes[nodeIndex][cosignerIndex] = _node; } else { @@ -320,8 +321,10 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { if (this.isWrappedSegwit()) { const { address } = bitcoin.payments.p2sh({ redeem: bitcoin.payments.p2wsh({ - redeem: bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys) }), + redeem: bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys), network: getNetwork() }), + network: getNetwork(), }), + network: getNetwork(), }); if (!address) { throw new Error('Internal error: could not make p2sh address'); @@ -330,7 +333,8 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { return address; } else if (this.isNativeSegwit()) { const { address } = bitcoin.payments.p2wsh({ - redeem: bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys) }), + redeem: bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys), network: getNetwork() }), + network: getNetwork(), }); if (!address) { throw new Error('Internal error: could not make p2wsh address'); @@ -339,7 +343,8 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { return address; } else if (this.isLegacy()) { const { address } = bitcoin.payments.p2sh({ - redeem: bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys) }), + redeem: bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys), network: getNetwork() }), + network: getNetwork(), }); if (!address) { throw new Error('Internal error: could not make p2sh address'); @@ -369,7 +374,7 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { seed = bip39.mnemonicToSeedSync(mnemonic, passphrase); } - const root = bip32.fromSeed(seed); + const root = bip32.fromSeed(seed, getNetwork()); const child = root.derivePath(path).neutered(); return child.toBase58(); } @@ -754,7 +759,7 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { } const xpub = this._getXpubFromCosignerIndex(cosignerIndex); - const hdNode0 = bip32.fromBase58(xpub); + const hdNode0 = bip32.fromBase58(xpub, getNetwork()); const splt = path.split('/'); const internal = +splt[splt.length - 2]; const index = +splt[splt.length - 1]; @@ -775,7 +780,8 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { if (this.isNativeSegwit()) { const p2wsh = bitcoin.payments.p2wsh({ - redeem: bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys) }), + redeem: bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys), network: getNetwork() }), + network: getNetwork(), }); if (!p2wsh.redeem || !p2wsh.output) { throw new Error('Could not create p2wsh output'); @@ -799,8 +805,10 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { } else if (this.isWrappedSegwit()) { const p2shP2wsh = bitcoin.payments.p2sh({ redeem: bitcoin.payments.p2wsh({ - redeem: bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys) }), + redeem: bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys), network: getNetwork() }), + network: getNetwork(), }), + network: getNetwork(), }); if (!p2shP2wsh?.redeem?.redeem?.output || !p2shP2wsh?.redeem?.output || !p2shP2wsh.output) { throw new Error('Could not create p2sh-p2wsh output'); @@ -826,7 +834,8 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { }); } else if (this.isLegacy()) { const p2sh = bitcoin.payments.p2sh({ - redeem: bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys) }), + redeem: bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys), network: getNetwork() }), + network: getNetwork(), }); if (!p2sh?.redeem?.output) { throw new Error('Could not create p2sh output'); @@ -863,7 +872,7 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { } const xpub = this._getXpubFromCosignerIndex(cosignerIndex); - const hdNode0 = bip32.fromBase58(xpub); + const hdNode0 = bip32.fromBase58(xpub, getNetwork()); const splt = path.split('/'); const internal = +splt[splt.length - 2]; const index = +splt[splt.length - 1]; @@ -879,7 +888,7 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { } if (this.isLegacy()) { - const p2sh = bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys) }); + const p2sh = bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys), network: getNetwork() }); if (!p2sh.output) { throw new Error('Could not create redeemScript'); } @@ -892,8 +901,10 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { if (this.isWrappedSegwit()) { const p2shP2wsh = bitcoin.payments.p2sh({ redeem: bitcoin.payments.p2wsh({ - redeem: bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys) }), + redeem: bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys), network: getNetwork() }), + network: getNetwork(), }), + network: getNetwork(), }); const witnessScript = p2shP2wsh?.redeem?.redeem?.output; const redeemScript = p2shP2wsh?.redeem?.output; @@ -910,7 +921,8 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { if (this.isNativeSegwit()) { // not needed by coldcard, apparently..? const p2wsh = bitcoin.payments.p2wsh({ - redeem: bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys) }), + redeem: bitcoin.payments.p2ms({ m: this._m, pubkeys: MultisigHDWallet.sortBuffers(pubkeys), network: getNetwork() }), + network: getNetwork(), }); const witnessScript = p2wsh?.redeem?.output; if (!witnessScript) { @@ -983,7 +995,7 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { const { inputs, outputs, fee } = this.coinselect(utxos, targets, feeRate); sequence = sequence || AbstractHDElectrumWallet.defaultRBFSequence; - let psbt = new bitcoin.Psbt(); + let psbt = new bitcoin.Psbt({ network: getNetwork() }); let c = 0; inputs.forEach(input => { @@ -1032,7 +1044,7 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { seed = MultisigHDWallet.convertElectrumMnemonicToSeed(cosigner, passphrase); } - const hdRoot = bip32.fromSeed(seed); + const hdRoot = bip32.fromSeed(seed, getNetwork()); psbt.signInputHD(cc, hdRoot); signaturesMade++; } @@ -1074,7 +1086,7 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { } static isPathValid(path: string): boolean { - const root = bip32.fromSeed(new Uint8Array(32)); + const root = bip32.fromSeed(new Uint8Array(32), getNetwork()); try { root.derivePath(path); return true; @@ -1171,13 +1183,13 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { let hdRoot; if (MultisigHDWallet.isXprvString(cosigner)) { const xprv = MultisigHDWallet.convertMultisigXprvToRegularXprv(cosigner); - hdRoot = bip32.fromBase58(xprv); + hdRoot = bip32.fromBase58(xprv, getNetwork()); } else { const passphrase = this._cosignersPassphrases[cosignerIndex]; const seed = cosigner.startsWith(ELECTRUM_SEED_PREFIX) ? MultisigHDWallet.convertElectrumMnemonicToSeed(cosigner, passphrase) : bip39.mnemonicToSeedSync(cosigner, passphrase); - hdRoot = bip32.fromSeed(seed); + hdRoot = bip32.fromSeed(seed, getNetwork()); } try { @@ -1206,7 +1218,7 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet { // if hdRoot.depth !== 0 than this hdnode was recovered from xprv and it already has been set to root path const child = hdRoot.derivePath(path); if (child.privateKey && psbt.inputHasPubkey(cc, child.publicKey)) { - const keyPair = ECPair.fromPrivateKey(child.privateKey); + const keyPair = ECPair.fromPrivateKey(child.privateKey, { network: getNetwork() }); try { psbt.signInput(cc, keyPair); } catch (_) {} diff --git a/class/wallets/segwit-bech32-wallet.ts b/class/wallets/segwit-bech32-wallet.ts index 3e3f49db40b..43568d8caaf 100644 --- a/class/wallets/segwit-bech32-wallet.ts +++ b/class/wallets/segwit-bech32-wallet.ts @@ -6,6 +6,7 @@ import ecc from '../../blue_modules/noble_ecc'; import { LegacyWallet } from './legacy-wallet'; import { CreateTransactionResult, CreateTransactionUtxo } from './types'; import { hexToUint8Array } from '../../blue_modules/uint8array-extras'; +import { getNetwork } from '../../models/network'; const ECPair = ECPairFactory(ecc); @@ -22,13 +23,14 @@ export class SegwitBech32Wallet extends LegacyWallet { if (this._address) return this._address; let address; try { - const keyPair = ECPair.fromWIF(this.secret); + const keyPair = ECPair.fromWIF(this.secret, getNetwork()); if (!keyPair.compressed) { console.warn('only compressed public keys are good for segwit'); return false; } address = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey, + network: getNetwork(), }).address; } catch (err) { return false; @@ -44,7 +46,7 @@ export class SegwitBech32Wallet extends LegacyWallet { return ( bitcoin.payments.p2wpkh({ pubkey, - network: bitcoin.networks.bitcoin, + network: getNetwork(), }).address ?? false ); } catch (_) { @@ -64,7 +66,7 @@ export class SegwitBech32Wallet extends LegacyWallet { return ( bitcoin.payments.p2wpkh({ output: scriptPubKey2, - network: bitcoin.networks.bitcoin, + network: getNetwork(), }).address ?? false ); } catch (_) { @@ -84,17 +86,17 @@ export class SegwitBech32Wallet extends LegacyWallet { if (targets.length === 0) throw new Error('No destination provided'); const { inputs, outputs, fee } = this.coinselect(utxos, targets, feeRate); sequence = sequence || 0xffffffff; // disable RBF by default - const psbt = new bitcoin.Psbt(); + const psbt = new bitcoin.Psbt({ network: getNetwork() }); let c = 0; const values: Record = {}; - const keyPair = ECPair.fromWIF(this.secret); + const keyPair = ECPair.fromWIF(this.secret, getNetwork()); inputs.forEach(input => { values[c] = input.value; c++; const pubkey = keyPair.publicKey; - const p2wpkh = bitcoin.payments.p2wpkh({ pubkey }); + const p2wpkh = bitcoin.payments.p2wpkh({ pubkey, network: getNetwork() }); if (!p2wpkh.output) { throw new Error('Internal error: no p2wpkh.output during createTransaction()'); } diff --git a/class/wallets/segwit-p2sh-wallet.ts b/class/wallets/segwit-p2sh-wallet.ts index 4c382fa3e9b..928eae223a1 100644 --- a/class/wallets/segwit-p2sh-wallet.ts +++ b/class/wallets/segwit-p2sh-wallet.ts @@ -6,6 +6,7 @@ import ecc from '../../blue_modules/noble_ecc'; import { LegacyWallet } from './legacy-wallet'; import { CreateTransactionResult, CreateTransactionUtxo } from './types'; import { hexToUint8Array } from '../../blue_modules/uint8array-extras'; +import { getNetwork } from '../../models/network'; const ECPair = ECPairFactory(ecc); @@ -17,7 +18,8 @@ const ECPair = ECPairFactory(ecc); */ function pubkeyToP2shSegwitAddress(pubkey: Uint8Array): string | false { const { address } = bitcoin.payments.p2sh({ - redeem: bitcoin.payments.p2wpkh({ pubkey }), + redeem: bitcoin.payments.p2wpkh({ pubkey, network: getNetwork() }), + network: getNetwork(), }); return address ?? false; } @@ -52,7 +54,7 @@ export class SegwitP2SHWallet extends LegacyWallet { return ( bitcoin.payments.p2sh({ output: scriptPubKey2, - network: bitcoin.networks.bitcoin, + network: getNetwork(), }).address ?? false ); } catch (_) { @@ -64,7 +66,7 @@ export class SegwitP2SHWallet extends LegacyWallet { if (this._address) return this._address; let address; try { - const keyPair = ECPair.fromWIF(this.secret); + const keyPair = ECPair.fromWIF(this.secret, getNetwork()); const pubKey = keyPair.publicKey; if (!keyPair.compressed) { console.warn('only compressed public keys are good for segwit'); @@ -102,18 +104,18 @@ export class SegwitP2SHWallet extends LegacyWallet { if (targets.length === 0) throw new Error('No destination provided'); const { inputs, outputs, fee } = this.coinselect(utxos, targets, feeRate); sequence = sequence || 0xffffffff; // disable RBF by default - const psbt = new bitcoin.Psbt(); + const psbt = new bitcoin.Psbt({ network: getNetwork() }); let c = 0; const values: Record = {}; - const keyPair = ECPair.fromWIF(this.secret); + const keyPair = ECPair.fromWIF(this.secret, getNetwork()); inputs.forEach(input => { values[c] = input.value; c++; const pubkey = keyPair.publicKey; - const p2wpkh = bitcoin.payments.p2wpkh({ pubkey }); - const p2sh = bitcoin.payments.p2sh({ redeem: p2wpkh }); + const p2wpkh = bitcoin.payments.p2wpkh({ pubkey, network: getNetwork() }); + const p2sh = bitcoin.payments.p2sh({ redeem: p2wpkh, network: getNetwork() }); if (!p2sh.output) { throw new Error('Internal error: no p2sh.output during createTransaction()'); } diff --git a/class/wallets/taproot-wallet.ts b/class/wallets/taproot-wallet.ts index b8ec4e91e05..650f6aa5d3b 100644 --- a/class/wallets/taproot-wallet.ts +++ b/class/wallets/taproot-wallet.ts @@ -7,6 +7,7 @@ import { SegwitBech32Wallet } from './segwit-bech32-wallet'; import { CreateTransactionResult, CreateTransactionUtxo } from './types.ts'; import { CoinSelectTarget } from 'coinselect'; import { hexToUint8Array } from '../../blue_modules/uint8array-extras'; +import { getNetwork } from '../../models/network'; const ECPair = ECPairFactory(ecc); export class TaprootWallet extends SegwitBech32Wallet { @@ -27,7 +28,7 @@ export class TaprootWallet extends SegwitBech32Wallet { static scriptPubKeyToAddress(scriptPubKey: string): string | false { try { const publicKey = hexToUint8Array(scriptPubKey); - return bitcoin.address.fromOutputScript(publicKey, bitcoin.networks.bitcoin); + return bitcoin.address.fromOutputScript(publicKey, getNetwork()); } catch (_) { return false; } @@ -53,7 +54,7 @@ export class TaprootWallet extends SegwitBech32Wallet { if (this._address) return this._address; let address; try { - const keyPair = ECPair.fromWIF(this.secret); + const keyPair = ECPair.fromWIF(this.secret, getNetwork()); if (!keyPair.compressed) { console.warn('only compressed public keys are good for segwit'); return false; @@ -61,6 +62,7 @@ export class TaprootWallet extends SegwitBech32Wallet { const xOnlyPubkey = keyPair.publicKey.subarray(1, 33); address = bitcoin.payments.p2tr({ internalPubkey: xOnlyPubkey, + network: getNetwork(), }).address; } catch (err: any) { console.log(err.message); @@ -85,17 +87,18 @@ export class TaprootWallet extends SegwitBech32Wallet { sequence = sequence || 0xffffffff; // default if not passed // Derive keyPair & x-only pubkey - const keyPair = ECPair.fromWIF(this.secret); + const keyPair = ECPair.fromWIF(this.secret, getNetwork()); const pubkey = keyPair.publicKey; // compressed: 0x02/03 || X const xOnlyPub = pubkey.subarray(1, 33); // strip prefix // Precompute the P2TR payment (to rebuild scriptPubKey) const p2tr = bitcoin.payments.p2tr({ internalPubkey: xOnlyPub, + network: getNetwork(), }); if (!p2tr.output) throw new Error('Could not build p2tr.output'); - const psbt = new bitcoin.Psbt(); + const psbt = new bitcoin.Psbt({ network: getNetwork() }); // Add Taproot inputs inputs.forEach((input, idx) => { diff --git a/class/wallets/watch-only-wallet.ts b/class/wallets/watch-only-wallet.ts index e1cfbf86f49..163dd28940c 100644 --- a/class/wallets/watch-only-wallet.ts +++ b/class/wallets/watch-only-wallet.ts @@ -2,6 +2,7 @@ import BIP32Factory from 'bip32'; import * as bitcoin from 'bitcoinjs-lib'; import ecc from '../../blue_modules/noble_ecc'; +import { getNetwork } from '../../models/network'; import { AbstractWallet } from './abstract-wallet'; import { HDLegacyP2PKHWallet } from './hd-legacy-p2pkh-wallet'; import { HDSegwitBech32Wallet } from './hd-segwit-bech32-wallet'; @@ -10,6 +11,29 @@ import { LegacyWallet } from './legacy-wallet'; import { THDWalletForWatchOnly } from './types'; import { HDTaprootWallet } from './hd-taproot-wallet'; +/** + * Checks if a string starts with any known extended public key prefix (mainnet or testnet). + * Mainnet: xpub, ypub, zpub. Testnet: tpub, upub, vpub. + */ +function isExtendedPubKey(secret: string): boolean { + return /^(xpub|ypub|zpub|tpub|upub|vpub)/.test(secret); +} + +/** Returns true if the secret is a zpub (mainnet) or vpub (testnet) — native segwit BIP84 */ +function isZpub(secret: string): boolean { + return secret.startsWith('zpub') || secret.startsWith('vpub'); +} + +/** Returns true if the secret is a ypub (mainnet) or upub (testnet) — wrapped segwit BIP49 */ +function isYpub(secret: string): boolean { + return secret.startsWith('ypub') || secret.startsWith('upub'); +} + +/** Returns true if the secret is an xpub (mainnet) or tpub (testnet) — legacy BIP44 */ +function isXpub(secret: string): boolean { + return secret.startsWith('xpub') || secret.startsWith('tpub'); +} + const bip32 = BIP32Factory(ecc); export class WatchOnlyWallet extends LegacyWallet { @@ -58,10 +82,10 @@ export class WatchOnlyWallet extends LegacyWallet { } valid() { - if (this.secret.startsWith('xpub') || this.secret.startsWith('ypub') || this.secret.startsWith('zpub')) return this.isXpubValid(); + if (isExtendedPubKey(this.secret)) return this.isXpubValid(); try { - bitcoin.address.toOutputScript(this.getAddress()); + bitcoin.address.toOutputScript(this.getAddress(), getNetwork()); return true; } catch (_) { return false; @@ -96,10 +120,10 @@ export class WatchOnlyWallet extends LegacyWallet { hdWalletInstance = new HDSegwitP2SHWallet(); } // Final fallback to xpub prefix (legacy behavior for bare xpub/ypub/zpub) - else if (this.secret.startsWith('xpub')) { + else if (isXpub(this.secret)) { hdWalletInstance = new HDLegacyP2PKHWallet(); - } else if (this.secret.startsWith('ypub')) hdWalletInstance = new HDSegwitP2SHWallet(); - else if (this.secret.startsWith('zpub')) hdWalletInstance = new HDSegwitBech32Wallet(); + } else if (isYpub(this.secret)) hdWalletInstance = new HDSegwitP2SHWallet(); + else if (isZpub(this.secret)) hdWalletInstance = new HDSegwitBech32Wallet(); else return this; hdWalletInstance._xpub = this.secret; @@ -143,7 +167,7 @@ export class WatchOnlyWallet extends LegacyWallet { } async fetchBalance() { - if (this.secret.startsWith('xpub') || this.secret.startsWith('ypub') || this.secret.startsWith('zpub')) { + if (isExtendedPubKey(this.secret)) { if (!this._hdWalletInstance) this.init(); if (!this._hdWalletInstance) throw new Error('Internal error: _hdWalletInstance is not initialized'); return this._hdWalletInstance.fetchBalance(); @@ -154,7 +178,7 @@ export class WatchOnlyWallet extends LegacyWallet { } async fetchTransactions() { - if (this.secret.startsWith('xpub') || this.secret.startsWith('ypub') || this.secret.startsWith('zpub')) { + if (isExtendedPubKey(this.secret)) { if (!this._hdWalletInstance) this.init(); if (!this._hdWalletInstance) throw new Error('Internal error: _hdWalletInstance is not initialized'); return this._hdWalletInstance.fetchTransactions(); @@ -252,7 +276,7 @@ export class WatchOnlyWallet extends LegacyWallet { } isHd() { - return this.secret.startsWith('xpub') || this.secret.startsWith('ypub') || this.secret.startsWith('zpub'); + return isExtendedPubKey(this.secret); } weOwnAddress(address: string) { @@ -261,13 +285,13 @@ export class WatchOnlyWallet extends LegacyWallet { throw new Error('Not initialized'); } - if (address && address.startsWith('BC1')) address = address.toLowerCase(); + if (address && (address.startsWith('BC1') || address.startsWith('TB1'))) address = address.toLowerCase(); return this.getAddress() === address; } allowMasterFingerprint() { - return this.getSecret().startsWith('zpub') || this.getSecret().startsWith('ypub') || this.getSecret().startsWith('xpub'); + return isExtendedPubKey(this.getSecret()); } useWithHardwareWalletEnabled() { @@ -290,15 +314,15 @@ export class WatchOnlyWallet extends LegacyWallet { let xpub; try { - if (this.secret.startsWith('zpub')) { + if (isZpub(this.secret)) { xpub = this._zpubToXpub(this.secret); - } else if (this.secret.startsWith('ypub')) { + } else if (isYpub(this.secret)) { xpub = AbstractWallet._ypubToXpub(this.secret); } else { xpub = this.secret; } - const hdNode = bip32.fromBase58(xpub); + const hdNode = bip32.fromBase58(xpub, getNetwork()); hdNode.derive(0); return true; } catch (_) {} diff --git a/components/Context/SettingsProvider.tsx b/components/Context/SettingsProvider.tsx index ac1c6123e01..a1f515e0cf4 100644 --- a/components/Context/SettingsProvider.tsx +++ b/components/Context/SettingsProvider.tsx @@ -16,9 +16,12 @@ import { BitcoinUnit } from '../../models/bitcoinUnits'; import { TotalWalletsBalanceKey, TotalWalletsBalancePreferredUnit } from '../TotalWalletsBalance'; import { BLOCK_EXPLORERS, getBlockExplorerUrl, saveBlockExplorer, BlockExplorer, normalizeUrl } from '../../models/blockExplorer'; import * as BlueElectrum from '../../blue_modules/BlueElectrum'; +import { setNetworkType as setGlobalNetworkType, NetworkType } from '../../models/network'; import { isBalanceDisplayAllowed, setBalanceDisplayAllowed } from '../../hooks/useWidgetCommunication'; import AsyncStorage from '@react-native-async-storage/async-storage'; +const NETWORK_TYPE_KEY = 'network_type'; + const getDoNotTrackStorage = async (): Promise => { try { await DefaultPreference.setName(GROUP_IO_BLUEWALLET); @@ -99,6 +102,8 @@ interface SettingsContextType { setBlockExplorerStorage: (explorer: BlockExplorer) => Promise; isElectrumDisabled: boolean; setIsElectrumDisabled: (value: boolean) => void; + networkType: NetworkType; + setNetworkTypeStorage: (network: NetworkType) => Promise; } const defaultSettingsContext: SettingsContextType = { @@ -128,6 +133,8 @@ const defaultSettingsContext: SettingsContextType = { setBlockExplorerStorage: async () => false, isElectrumDisabled: false, setIsElectrumDisabled: () => {}, + networkType: 'mainnet' as NetworkType, + setNetworkTypeStorage: async () => {}, }; export const SettingsContext = createContext(defaultSettingsContext); @@ -146,6 +153,8 @@ export const SettingsProvider: React.FC<{ children: React.ReactNode }> = React.m const [totalBalancePreferredUnit, setTotalBalancePreferredUnit] = useState(BitcoinUnit.BTC); const [selectedBlockExplorer, setSelectedBlockExplorer] = useState(BLOCK_EXPLORERS.default); const [isElectrumDisabled, setIsElectrumDisabled] = useState(true); + const [networkType, setNetworkType] = useState(defaultSettingsContext.networkType); + const [settingsLoaded, setSettingsLoaded] = useState(false); const { walletsInitialized } = useStorage(); @@ -161,6 +170,13 @@ export const SettingsProvider: React.FC<{ children: React.ReactNode }> = React.m BlueElectrum.isDisabled().then(disabled => { setIsElectrumDisabled(disabled); }), + DefaultPreference.get(NETWORK_TYPE_KEY).then(maybeNetwork => { + // Can be null if nothing is set + const network = (maybeNetwork as NetworkType) || defaultSettingsContext.networkType; + console.log(`[BlueWallet] Starting with network: ${network}`); + setNetworkType(network); + setGlobalNetworkType(network); + }), getIsHandOffUseEnabled().then(handOff => { setIsHandOffUseEnabledState(handOff); }), @@ -201,6 +217,8 @@ export const SettingsProvider: React.FC<{ children: React.ReactNode }> = React.m console.error(`Error loading setting ${index}:`, result.reason); } }); + + setSettingsLoaded(true); }; loadSettings(); @@ -219,10 +237,10 @@ export const SettingsProvider: React.FC<{ children: React.ReactNode }> = React.m }, []); useEffect(() => { - if (walletsInitialized) { - isElectrumDisabled ? BlueElectrum.forceDisconnect() : BlueElectrum.connectMain(); + if (walletsInitialized && settingsLoaded) { + isElectrumDisabled ? BlueElectrum.forceDisconnect() : BlueElectrum.connectMain(networkType); } - }, [isElectrumDisabled, walletsInitialized]); + }, [isElectrumDisabled, walletsInitialized, networkType, settingsLoaded]); const setPreferredFiatCurrencyStorage = useCallback(async (currency: TFiatUnit): Promise => { try { @@ -323,6 +341,24 @@ export const SettingsProvider: React.FC<{ children: React.ReactNode }> = React.m } }, []); + const setNetworkTypeStorage = useCallback( + async (network: NetworkType): Promise => { + try { + DefaultPreference.setName(GROUP_IO_BLUEWALLET); + await DefaultPreference.set(NETWORK_TYPE_KEY, network); + setNetworkType(network); + setGlobalNetworkType(network); + BlueElectrum.forceDisconnect(); + if (!isElectrumDisabled) { + BlueElectrum.connectMain(network); + } + } catch (e) { + console.error('Error setting networkType:', e); + } + }, + [isElectrumDisabled], + ); + const setBlockExplorerStorage = useCallback(async (explorer: BlockExplorer): Promise => { try { const success = await saveBlockExplorer(explorer.url); @@ -364,6 +400,8 @@ export const SettingsProvider: React.FC<{ children: React.ReactNode }> = React.m setBlockExplorerStorage, isElectrumDisabled, setIsElectrumDisabled, + networkType, + setNetworkTypeStorage, }), [ preferredFiatCurrency, @@ -391,6 +429,8 @@ export const SettingsProvider: React.FC<{ children: React.ReactNode }> = React.m selectedBlockExplorer, setBlockExplorerStorage, isElectrumDisabled, + networkType, + setNetworkTypeStorage, ], ); diff --git a/components/TransactionListItem.tsx b/components/TransactionListItem.tsx index 799eb78fe72..3fef386c987 100644 --- a/components/TransactionListItem.tsx +++ b/components/TransactionListItem.tsx @@ -14,6 +14,7 @@ import TransactionPendingIcon from '../components/icons/TransactionPendingIcon'; import loc, { formatBalanceWithoutSuffix, formatTransactionListDate, transactionTimeToReadable } from '../loc'; import { BitcoinUnit } from '../models/bitcoinUnits'; import { useSettings } from '../hooks/context/useSettings'; +import { adjustBlockExplorerUrlForNetwork } from '../models/blockExplorer'; import { useTheme } from './themes'; import { Action } from './types'; import { useExtendedNavigation } from '../hooks/useExtendedNavigation'; @@ -99,7 +100,8 @@ export const TransactionListItem: React.FC = memo( const { colors } = useTheme(); const { navigate } = useExtendedNavigation(); const { txMetadata, counterpartyMetadata, wallets } = useStorage(); - const { language, selectedBlockExplorer } = useSettings(); + const { language, selectedBlockExplorer, networkType } = useSettings(); + const blockExplorerUrl = adjustBlockExplorerUrlForNetwork(selectedBlockExplorer.url, networkType); const insets = useSafeAreaInsets(); const containerStyle = useMemo( () => ({ @@ -344,16 +346,16 @@ export const TransactionListItem: React.FC = memo( const handleOnCopyTransactionID = useCallback(() => Clipboard.setString(item.hash), [item.hash]); const handleOnCopyNote = useCallback(() => Clipboard.setString(noteForCopy ?? ''), [noteForCopy]); const handleOnViewOnBlockExplorer = useCallback(() => { - const url = `${selectedBlockExplorer.url}/tx/${item.hash}`; + const url = `${blockExplorerUrl}/tx/${item.hash}`; Linking.canOpenURL(url).then(supported => { if (supported) { Linking.openURL(url); } }); - }, [item.hash, selectedBlockExplorer]); + }, [item.hash, blockExplorerUrl]); const handleCopyOpenInBlockExplorerPress = useCallback(() => { - Clipboard.setString(`${selectedBlockExplorer.url}/tx/${item.hash}`); - }, [item.hash, selectedBlockExplorer]); + Clipboard.setString(`${blockExplorerUrl}/tx/${item.hash}`); + }, [item.hash, blockExplorerUrl]); const onToolTipPress = useCallback( (id: any) => { diff --git a/components/types.ts b/components/types.ts index f110a9b7034..cf95201fa57 100644 --- a/components/types.ts +++ b/components/types.ts @@ -43,9 +43,9 @@ export interface ToolTipMenuProps { } export enum HandOffActivityType { - ReceiveOnchain = 'io.bluewallet.bluewallet.receiveonchain', - Xpub = 'io.bluewallet.bluewallet.xpub', - ViewInBlockExplorer = 'io.bluewallet.bluewallet.blockexplorer', + ReceiveOnchain = 'com.layertwolabs.bluewallet.receiveonchain', + Xpub = 'com.layertwolabs.bluewallet.xpub', + ViewInBlockExplorer = 'com.layertwolabs.bluewallet.blockexplorer', } export interface HandOffComponentProps { diff --git a/fastlane/Appfile b/fastlane/Appfile index 18e61f786d0..d70eee59da1 100644 --- a/fastlane/Appfile +++ b/fastlane/Appfile @@ -1,3 +1,3 @@ -app_identifier("io.bluewallet.bluewallet") +app_identifier("com.layertwolabs.bluewallet") apple_id(ENV["APPLE_ID"]) # Your Apple email ID itc_team_id(ENV["ITC_TEAM_ID"]) # App Store Connect Team ID \ No newline at end of file diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 3c226c7e0e3..d6295f84ab2 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -1,11 +1,7 @@ # Define app identifiers once for reuse across lanes def app_identifiers [ - "io.bluewallet.bluewallet", - "io.bluewallet.bluewallet.watch", - "io.bluewallet.bluewallet.watch.extension", - "io.bluewallet.bluewallet.Stickers", - "io.bluewallet.bluewallet.MarketWidget" + "com.layertwolabs.bluewallet" ] end @@ -204,10 +200,17 @@ before_all do |lane, options| next end + # Skip App Store Connect auth for Android lanes + current_platform = lane_context[SharedValues::PLATFORM_NAME] + if current_platform == :android + UI.message("Skipping App Store Connect auth for Android lane") + next + end + skip_auth_lanes = ['register_devices_from_txt', 'build_catalyst_app_lane', 'install_pods', 'clear_derived_data_lane'] lane_name = lane.to_s should_skip_auth = skip_auth_lanes.any? { |skip_lane| lane_name == skip_lane || lane_name.end_with?(" #{skip_lane}") } - + # Check if we need App Store Connect for this lane unless should_skip_auth begin @@ -307,6 +310,38 @@ platform :android do end end + desc "Upload AAB to Google Play internal/closed testing" + lane :deploy_to_play_store do + Dir.chdir(PROJECT_ROOT) do + aab_path = ENV['AAB_PATH'] + + if aab_path.nil? || aab_path.empty? + UI.message("No AAB path provided, searching for AAB...") + aab_path = Dir.glob(File.join(PROJECT_ROOT, "android/app/build/outputs/bundle/release/*.aab")).last + UI.user_error!("No AAB file found") if aab_path.nil? || aab_path.empty? + end + + # Ensure absolute path + aab_path = File.expand_path(aab_path, PROJECT_ROOT) unless aab_path.start_with?('/') + + UI.user_error!("AAB file not found at: #{aab_path}") unless File.exist?(aab_path) + UI.message("Uploading AAB to Play Store: #{aab_path}") + + upload_to_play_store( + track: "internal", + aab: aab_path, + json_key_data: ENV['GOOGLE_PLAY_JSON_KEY'], + package_name: "com.layertwolabs.bluewallet", + skip_upload_metadata: true, + skip_upload_images: true, + skip_upload_screenshots: true, + skip_upload_changelogs: true + ) + + UI.success("Successfully uploaded AAB to Play Store internal track!") + end + end + desc "Upload APK to BrowserStack and post result as PR comment" lane :upload_to_browserstack_and_comment do Dir.chdir(PROJECT_ROOT) do @@ -492,7 +527,7 @@ platform :ios do with_retry(3, "Fetching provisioning profile for #{app_identifier}") do UI.message("Fetching provisioning profile for #{app_identifier}...") match( - git_basic_authorization: ENV["GIT_ACCESS_TOKEN"], + git_basic_authorization: ENV["GIT_USERNAME"] ? Base64.strict_encode64("#{ENV["GIT_USERNAME"]}:#{ENV["GIT_ACCESS_TOKEN"]}") : ENV["GIT_ACCESS_TOKEN"], git_url: ENV["GIT_URL"], type: "appstore", clone_branch_directly: true, @@ -958,7 +993,7 @@ platform :ios do upload_to_testflight( - api_key_path: "./appstore_api_key.json", + api_key_path: ENV["APPLE_API_KEY_PATH"] || "./appstore_api_key.json", ipa: ipa_path, skip_waiting_for_build_processing: true, changelog: changelog diff --git a/fastlane/Matchfile b/fastlane/Matchfile index 9772ca474d4..9448000cf6e 100644 --- a/fastlane/Matchfile +++ b/fastlane/Matchfile @@ -9,11 +9,7 @@ type(ENV["MATCH_TYPE"] || "appstore") # App identifiers for all BlueWallet apps app_identifier([ - "io.bluewallet.bluewallet", - "io.bluewallet.bluewallet.watch", - "io.bluewallet.bluewallet.watch.extension", - "io.bluewallet.bluewallet.Stickers", - "io.bluewallet.bluewallet.MarketWidget" + "com.layertwolabs.bluewallet" ]) # Your Apple Developer account email address diff --git a/img/icon.png b/img/icon.png index ec541528a9a..02bc2883a29 100644 Binary files a/img/icon.png and b/img/icon.png differ diff --git a/img/icon@2x.png b/img/icon@2x.png deleted file mode 100644 index a72c80addc6..00000000000 Binary files a/img/icon@2x.png and /dev/null differ diff --git a/img/icon@3x.png b/img/icon@3x.png deleted file mode 100644 index 5727bf33172..00000000000 Binary files a/img/icon@3x.png and /dev/null differ diff --git a/img/qr-code.png b/img/qr-code.png index 779843bd892..db26f36e752 100644 Binary files a/img/qr-code.png and b/img/qr-code.png differ diff --git a/img/qr-code@2x.png b/img/qr-code@2x.png deleted file mode 100644 index 51d00021105..00000000000 Binary files a/img/qr-code@2x.png and /dev/null differ diff --git a/img/qr-code@3x.png b/img/qr-code@3x.png deleted file mode 100644 index efefa8926da..00000000000 Binary files a/img/qr-code@3x.png and /dev/null differ diff --git a/index.js b/index.js index 3fa2e813922..0ac17146515 100644 --- a/index.js +++ b/index.js @@ -31,4 +31,4 @@ const BlueAppComponent = () => { return ; }; -AppRegistry.registerComponent('BlueWallet', () => BlueAppComponent); +AppRegistry.registerComponent('RedWallet', () => BlueAppComponent); diff --git a/ios/BlueWallet.xcodeproj/project.pbxproj b/ios/BlueWallet.xcodeproj/project.pbxproj index fd98650e16b..68ab73f6416 100644 --- a/ios/BlueWallet.xcodeproj/project.pbxproj +++ b/ios/BlueWallet.xcodeproj/project.pbxproj @@ -9,172 +9,58 @@ /* Begin PBXBuildFile section */ 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 17CDA0718F42DB2CE856C872 /* libPods-BlueWallet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 040819EDF8BD9C50A9C83E24 /* libPods-BlueWallet.a */; }; - 32F0A29A2311DBB20095C559 /* ComplicationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32F0A2992311DBB20095C559 /* ComplicationController.swift */; }; - 6D2A6464258BA92D0092292B /* Stickers.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2A6463258BA92D0092292B /* Stickers.xcassets */; }; - 6D2A6468258BA92D0092292B /* Stickers.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 6D2A6461258BA92C0092292B /* Stickers.appex */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 6D4AF15925D21172009DD853 /* MarketAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D9A2E6A254BAB1B007B5B82 /* MarketAPI.swift */; }; - 6D4AF16D25D21192009DD853 /* Placeholders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEB4BFA254FBA0E00E9F9AA /* Placeholders.swift */; }; - 6D4AF17825D211A3009DD853 /* FiatUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2AA8072568B8F40090B089 /* FiatUnit.swift */; }; - 6D4AF18425D215D1009DD853 /* UserDefaultsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D4AF18325D215D1009DD853 /* UserDefaultsExtension.swift */; }; - 6DD4109D266CADF10087DE03 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D333B3A252FE1A3004D72DF /* WidgetKit.framework */; }; - 6DD4109E266CADF10087DE03 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D333B3C252FE1A3004D72DF /* SwiftUI.framework */; }; - 6DD410A1266CADF10087DE03 /* Widgets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DD410A0266CADF10087DE03 /* Widgets.swift */; }; - 6DD410A7266CADF40087DE03 /* WidgetsExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 6DD4109C266CADF10087DE03 /* WidgetsExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 6DD410AC266CAE470087DE03 /* PriceWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D6CA4BC255872E3009312A5 /* PriceWidget.swift */; }; - 6DD410AF266CAF5C0087DE03 /* WalletInformationAndMarketWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D9A2E06254BA347007B5B82 /* WalletInformationAndMarketWidget.swift */; }; - 6DD410B0266CAF5C0087DE03 /* WalletInformationWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEB4AB1254FB59C00E9F9AA /* WalletInformationWidget.swift */; }; - 6DD410B1266CAF5C0087DE03 /* MarketAPI+Electrum.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D6CA5142558EBA3009312A5 /* MarketAPI+Electrum.swift */; }; - 6DD410B2266CAF5C0087DE03 /* WalletInformationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D641F2225525053003792DF /* WalletInformationView.swift */; }; - 6DD410B3266CAF5C0087DE03 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEB4C3A254FBF4800E9F9AA /* Colors.swift */; }; - 6DD410B4266CAF5C0087DE03 /* MarketAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D9A2E6A254BAB1B007B5B82 /* MarketAPI.swift */; }; - 6DD410B6266CAF5C0087DE03 /* PriceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D6CA5272558EC52009312A5 /* PriceView.swift */; }; - 6DD410B7266CAF5C0087DE03 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D9A2E08254BA348007B5B82 /* Assets.xcassets */; }; - 6DD410B8266CAF5C0087DE03 /* UserDefaultsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D4AF18325D215D1009DD853 /* UserDefaultsExtension.swift */; }; - 6DD410B9266CAF5C0087DE03 /* UserDefaultsGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DA7047D254E24D5005FE5E2 /* UserDefaultsGroup.swift */; }; - 6DD410BA266CAF5C0087DE03 /* FiatUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2AA8072568B8F40090B089 /* FiatUnit.swift */; }; - 6DD410BB266CAF5C0087DE03 /* MarketView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D641F17255226DA003792DF /* MarketView.swift */; }; - 6DD410BE266CAF5C0087DE03 /* SendReceiveButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D641F3425526311003792DF /* SendReceiveButtons.swift */; }; - 6DD410BF266CB13D0087DE03 /* Placeholders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEB4BFA254FBA0E00E9F9AA /* Placeholders.swift */; }; - 6DD410C0266CB1460087DE03 /* MarketWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D9946622555A660000E52E8 /* MarketWidget.swift */; }; + 32B5A32A2334450100F8D608 /* Bridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32B5A3292334450100F8D608 /* Bridge.swift */; }; 6DF25A9F249DB97E001D06F5 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6DF25A9E249DB97E001D06F5 /* LaunchScreen.storyboard */; }; - 6DFC807024EA0B6C007B8700 /* EFQRCode in Frameworks */ = {isa = PBXBuildFile; productRef = 6DFC806F24EA0B6C007B8700 /* EFQRCode */; }; - 6DFC807224EA2FA9007B8700 /* ViewQRCodefaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DFC807124EA2FA9007B8700 /* ViewQRCodefaceController.swift */; }; 764B49B1420D4AEB8109BF62 /* libsqlite3.0.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B468CC34D5B41F3950078EF /* libsqlite3.0.tbd */; }; 782F075B5DD048449E2DECE9 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = B9D9B3A7B2CB4255876B67AF /* libz.tbd */; }; - 849047CA2702A32A008EE567 /* Handoff.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849047C92702A32A008EE567 /* Handoff.swift */; }; 84E05A842721191B001A0D3A /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 84E05A832721191B001A0D3A /* Settings.bundle */; }; B409AB062D71E07500BA06F8 /* MenuElementsEmitter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B409AB052D71E07500BA06F8 /* MenuElementsEmitter.swift */; }; - B40D4E34225841EC00428FCC /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B40D4E32225841EC00428FCC /* Interface.storyboard */; }; - B40D4E36225841ED00428FCC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B40D4E35225841ED00428FCC /* Assets.xcassets */; }; - B40D4E46225841ED00428FCC /* NotificationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B40D4E45225841ED00428FCC /* NotificationController.swift */; }; - B40D4E4D225841ED00428FCC /* BlueWalletWatch.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = B40D4E30225841EC00428FCC /* BlueWalletWatch.app */; platformFilter = ios; }; - B40D4E5D2258425500428FCC /* InterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B40D4E552258425400428FCC /* InterfaceController.swift */; }; - B40D4E5E2258425500428FCC /* NumericKeypadInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B40D4E562258425400428FCC /* NumericKeypadInterfaceController.swift */; }; - B40D4E602258425500428FCC /* SpecifyInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B40D4E582258425400428FCC /* SpecifyInterfaceController.swift */; }; - B40D4E632258425500428FCC /* ReceiveInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B40D4E5B2258425500428FCC /* ReceiveInterfaceController.swift */; }; - B40D4E642258425500428FCC /* WalletDetailsInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B40D4E5C2258425500428FCC /* WalletDetailsInterfaceController.swift */; }; - B40FC3FA29CCD1D00007EBAC /* SwiftTCPClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B40FC3F829CCD1AC0007EBAC /* SwiftTCPClient.swift */; }; - B41B76852B66B2FF002C48D5 /* Bugsnag in Frameworks */ = {isa = PBXBuildFile; productRef = B41B76842B66B2FF002C48D5 /* Bugsnag */; }; - B41B76872B66B2FF002C48D5 /* BugsnagNetworkRequestPlugin in Frameworks */ = {isa = PBXBuildFile; productRef = B41B76862B66B2FF002C48D5 /* BugsnagNetworkRequestPlugin */; }; B41C2E562BB3DCB8000FE097 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = B41C2E552BB3DCB8000FE097 /* PrivacyInfo.xcprivacy */; }; - B41C2E572BB3DCB8000FE097 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = B41C2E552BB3DCB8000FE097 /* PrivacyInfo.xcprivacy */; }; - B41C2E582BB3DCB8000FE097 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = B41C2E552BB3DCB8000FE097 /* PrivacyInfo.xcprivacy */; }; - B43D0378225847C500FBAA95 /* WalletGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B43D0372225847C500FBAA95 /* WalletGradient.swift */; }; - B43D0379225847C500FBAA95 /* WatchDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = B43D0373225847C500FBAA95 /* WatchDataSource.swift */; }; - B43D037A225847C500FBAA95 /* Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B43D0374225847C500FBAA95 /* Transaction.swift */; }; - B43D037B225847C500FBAA95 /* TransactionTableRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B43D0375225847C500FBAA95 /* TransactionTableRow.swift */; }; - B43D037C225847C500FBAA95 /* Wallet.swift in Sources */ = {isa = PBXBuildFile; fileRef = B43D0376225847C500FBAA95 /* Wallet.swift */; }; - B43D037D225847C500FBAA95 /* WalletInformation.swift in Sources */ = {isa = PBXBuildFile; fileRef = B43D0377225847C500FBAA95 /* WalletInformation.swift */; }; B44033BF2BCC32F800162242 /* BitcoinUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033BE2BCC32F800162242 /* BitcoinUnit.swift */; }; - B44033C02BCC32F800162242 /* BitcoinUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033BE2BCC32F800162242 /* BitcoinUnit.swift */; }; - B44033C12BCC32F800162242 /* BitcoinUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033BE2BCC32F800162242 /* BitcoinUnit.swift */; }; B44033C42BCC332400162242 /* Balance.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033C32BCC332400162242 /* Balance.swift */; }; - B44033C52BCC332400162242 /* Balance.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033C32BCC332400162242 /* Balance.swift */; }; - B44033C62BCC332400162242 /* Balance.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033C32BCC332400162242 /* Balance.swift */; }; B44033CA2BCC350A00162242 /* Currency.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033C92BCC350A00162242 /* Currency.swift */; }; - B44033CB2BCC350A00162242 /* Currency.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033C92BCC350A00162242 /* Currency.swift */; }; - B44033CC2BCC350A00162242 /* Currency.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033C92BCC350A00162242 /* Currency.swift */; }; B44033CE2BCC352900162242 /* UserDefaultsGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DA7047D254E24D5005FE5E2 /* UserDefaultsGroup.swift */; }; - B44033D02BCC352F00162242 /* UserDefaultsGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DA7047D254E24D5005FE5E2 /* UserDefaultsGroup.swift */; }; B44033D32BCC368800162242 /* UserDefaultsGroupKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033D22BCC368800162242 /* UserDefaultsGroupKey.swift */; }; - B44033D42BCC368800162242 /* UserDefaultsGroupKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033D22BCC368800162242 /* UserDefaultsGroupKey.swift */; }; - B44033D52BCC368800162242 /* UserDefaultsGroupKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033D22BCC368800162242 /* UserDefaultsGroupKey.swift */; }; B44033D82BCC369500162242 /* UserDefaultsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D4AF18325D215D1009DD853 /* UserDefaultsExtension.swift */; }; B44033DA2BCC369A00162242 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEB4C3A254FBF4800E9F9AA /* Colors.swift */; }; B44033DD2BCC36C300162242 /* LatestTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033DC2BCC36C300162242 /* LatestTransaction.swift */; }; - B44033DE2BCC36C300162242 /* LatestTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033DC2BCC36C300162242 /* LatestTransaction.swift */; }; - B44033DF2BCC36C300162242 /* LatestTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033DC2BCC36C300162242 /* LatestTransaction.swift */; }; B44033E22BCC36CB00162242 /* Placeholders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEB4BFA254FBA0E00E9F9AA /* Placeholders.swift */; }; B44033E42BCC36FF00162242 /* WalletData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033E32BCC36FF00162242 /* WalletData.swift */; }; - B44033E52BCC36FF00162242 /* WalletData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033E32BCC36FF00162242 /* WalletData.swift */; }; - B44033E62BCC36FF00162242 /* WalletData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033E32BCC36FF00162242 /* WalletData.swift */; }; - B44033EA2BCC371A00162242 /* MarketData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033E82BCC371A00162242 /* MarketData.swift */; }; - B44033EB2BCC371A00162242 /* MarketData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033E82BCC371A00162242 /* MarketData.swift */; }; B44033EE2BCC374500162242 /* Numeric+abbreviated.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033ED2BCC374500162242 /* Numeric+abbreviated.swift */; }; - B44033EF2BCC374500162242 /* Numeric+abbreviated.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033ED2BCC374500162242 /* Numeric+abbreviated.swift */; }; - B44033F02BCC374500162242 /* Numeric+abbreviated.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033ED2BCC374500162242 /* Numeric+abbreviated.swift */; }; B44033F42BCC377F00162242 /* WidgetData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033F32BCC377F00162242 /* WidgetData.swift */; }; - B44033F52BCC377F00162242 /* WidgetData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033F32BCC377F00162242 /* WidgetData.swift */; }; - B44033F62BCC377F00162242 /* WidgetData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033F32BCC377F00162242 /* WidgetData.swift */; }; B44033F92BCC379200162242 /* WidgetDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033F82BCC379200162242 /* WidgetDataStore.swift */; }; - B44033FA2BCC379200162242 /* WidgetDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033F82BCC379200162242 /* WidgetDataStore.swift */; }; - B44033FB2BCC379200162242 /* WidgetDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033F82BCC379200162242 /* WidgetDataStore.swift */; }; B44033FE2BCC37D700162242 /* MarketAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D9A2E6A254BAB1B007B5B82 /* MarketAPI.swift */; }; B44034002BCC37F800162242 /* Bundle+decode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033FF2BCC37F800162242 /* Bundle+decode.swift */; }; - B44034012BCC37F800162242 /* Bundle+decode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033FF2BCC37F800162242 /* Bundle+decode.swift */; }; - B44034022BCC37F800162242 /* Bundle+decode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033FF2BCC37F800162242 /* Bundle+decode.swift */; }; B44034052BCC389200162242 /* XMLParserDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4AB225C2B02AD12001F4328 /* XMLParserDelegate.swift */; }; B44034072BCC38A000162242 /* FiatUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2AA8072568B8F40090B089 /* FiatUnit.swift */; }; B440340F2BCC40A400162242 /* fiatUnits.json in Resources */ = {isa = PBXBuildFile; fileRef = B440340E2BCC40A400162242 /* fiatUnits.json */; }; - B44034102BCC40A400162242 /* fiatUnits.json in Resources */ = {isa = PBXBuildFile; fileRef = B440340E2BCC40A400162242 /* fiatUnits.json */; }; - B44034112BCC40A400162242 /* fiatUnits.json in Resources */ = {isa = PBXBuildFile; fileRef = B440340E2BCC40A400162242 /* fiatUnits.json */; }; B450109C2C0FCD8A00619044 /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = B450109B2C0FCD8A00619044 /* Utilities.swift */; }; - B450109D2C0FCD9F00619044 /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = B450109B2C0FCD8A00619044 /* Utilities.swift */; }; - B450109F2C0FCDA500619044 /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = B450109B2C0FCD8A00619044 /* Utilities.swift */; }; B4549F362B82B10D002E3153 /* ci_post_clone.sh in Resources */ = {isa = PBXBuildFile; fileRef = B4549F352B82B10D002E3153 /* ci_post_clone.sh */; }; B461B852299599F800E431AA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B461B851299599F800E431AA /* AppDelegate.swift */; }; B4742E972CCDBE8300380EEE /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = B4742E962CCDBE8300380EEE /* Localizable.xcstrings */; }; - B4742E982CCDBE8300380EEE /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = B4742E962CCDBE8300380EEE /* Localizable.xcstrings */; }; - B4742E992CCDBE8300380EEE /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = B4742E962CCDBE8300380EEE /* Localizable.xcstrings */; }; - B4742E9A2CCDBE8300380EEE /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = B4742E962CCDBE8300380EEE /* Localizable.xcstrings */; }; - B4742E9B2CCDBE8300380EEE /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = B4742E962CCDBE8300380EEE /* Localizable.xcstrings */; }; B4793DBB2CEDACBD00C92C2E /* Chain.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4793DBA2CEDACBD00C92C2E /* Chain.swift */; }; - B4793DBC2CEDACBD00C92C2E /* Chain.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4793DBA2CEDACBD00C92C2E /* Chain.swift */; }; - B4793DBD2CEDACBD00C92C2E /* Chain.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4793DBA2CEDACBD00C92C2E /* Chain.swift */; }; - B4793DBF2CEDACDA00C92C2E /* TransactionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4793DBE2CEDACDA00C92C2E /* TransactionType.swift */; }; - B4793DC12CEDACE700C92C2E /* WalletType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4793DC02CEDACE700C92C2E /* WalletType.swift */; }; - B4793DC32CEDAD4400C92C2E /* KeychainHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4793DC22CEDAD4400C92C2E /* KeychainHelper.swift */; }; - B4793DC42CEDAD4400C92C2E /* KeychainHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4793DC22CEDAD4400C92C2E /* KeychainHelper.swift */; }; B4793DC52CEDAD4400C92C2E /* KeychainHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4793DC22CEDAD4400C92C2E /* KeychainHelper.swift */; }; - B48630D62CCEE67100A8425C /* PriceWidgetProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B48630D52CCEE67100A8425C /* PriceWidgetProvider.swift */; }; B48630DD2CCEE7AC00A8425C /* PriceWidgetEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = B48630DC2CCEE7AC00A8425C /* PriceWidgetEntry.swift */; }; - B48630DE2CCEE7AC00A8425C /* PriceWidgetEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = B48630DC2CCEE7AC00A8425C /* PriceWidgetEntry.swift */; }; - B48630E02CCEE7C800A8425C /* PriceWidgetEntryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B48630DF2CCEE7C800A8425C /* PriceWidgetEntryView.swift */; }; B48630E12CCEE7C800A8425C /* PriceWidgetEntryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B48630DF2CCEE7C800A8425C /* PriceWidgetEntryView.swift */; }; B48630E52CCEE8B800A8425C /* PriceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D6CA5272558EC52009312A5 /* PriceView.swift */; }; B48630E72CCEE91900A8425C /* PriceWidgetProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B48630D52CCEE67100A8425C /* PriceWidgetProvider.swift */; }; B48630E82CCEE92400A8425C /* PriceWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D6CA4BC255872E3009312A5 /* PriceWidget.swift */; }; - B48630EA2CCEED8400A8425C /* PriceIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = B48630D02CCEE3B300A8425C /* PriceIntent.swift */; }; - B48630EC2CCEEEA700A8425C /* WalletAppShortcuts.swift in Sources */ = {isa = PBXBuildFile; fileRef = B48630EB2CCEEEA700A8425C /* WalletAppShortcuts.swift */; }; B48630ED2CCEEEB000A8425C /* WalletAppShortcuts.swift in Sources */ = {isa = PBXBuildFile; fileRef = B48630EB2CCEEEA700A8425C /* WalletAppShortcuts.swift */; }; B48630EE2CCEEEE900A8425C /* PriceIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = B48630D02CCEE3B300A8425C /* PriceIntent.swift */; }; - B49A28BB2CD18999006B08E4 /* CompactPriceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B49A28BA2CD18999006B08E4 /* CompactPriceView.swift */; }; B49A28BC2CD18999006B08E4 /* CompactPriceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B49A28BA2CD18999006B08E4 /* CompactPriceView.swift */; }; - B49A28BE2CD189B0006B08E4 /* FiatUnitEnum.swift in Sources */ = {isa = PBXBuildFile; fileRef = B49A28BD2CD189B0006B08E4 /* FiatUnitEnum.swift */; }; B49A28BF2CD18A9A006B08E4 /* FiatUnitEnum.swift in Sources */ = {isa = PBXBuildFile; fileRef = B49A28BD2CD189B0006B08E4 /* FiatUnitEnum.swift */; }; B49A28C52CD1A894006B08E4 /* MarketData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44033E82BCC371A00162242 /* MarketData.swift */; }; B4AA75242DAA339E00CF5CBE /* MenuElementsEmitter.m in Sources */ = {isa = PBXBuildFile; fileRef = B4AA75232DAA339E00CF5CBE /* MenuElementsEmitter.m */; }; - B4AB225D2B02AD12001F4328 /* XMLParserDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4AB225C2B02AD12001F4328 /* XMLParserDelegate.swift */; }; - B4AB225E2B02AD12001F4328 /* XMLParserDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4AB225C2B02AD12001F4328 /* XMLParserDelegate.swift */; }; B4B1A4622BFA73110072E3BB /* WidgetHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B1A4612BFA73110072E3BB /* WidgetHelper.swift */; }; - B4B1A4642BFA73110072E3BB /* WidgetHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B1A4612BFA73110072E3BB /* WidgetHelper.swift */; }; B4B3EC222D69FF6C00327F3D /* CustomSegmentedControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B3EC202D69FF6C00327F3D /* CustomSegmentedControl.swift */; }; B4B3EC252D69FF8700327F3D /* EventEmitter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B3EC232D69FF8700327F3D /* EventEmitter.swift */; }; - B4D0B2622C1DEA11006B6B1B /* ReceivePageInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4D0B2612C1DEA11006B6B1B /* ReceivePageInterfaceController.swift */; }; - B4D0B2642C1DEA99006B6B1B /* ReceiveType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4D0B2632C1DEA99006B6B1B /* ReceiveType.swift */; }; - B4D0B2662C1DEB7F006B6B1B /* ReceiveInterfaceMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4D0B2652C1DEB7F006B6B1B /* ReceiveInterfaceMode.swift */; }; - B4D0B2682C1DED67006B6B1B /* ReceiveMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4D0B2672C1DED67006B6B1B /* ReceiveMethod.swift */; }; - B4D59C1A2D8BAFE300B7025B /* EFQRCode in Frameworks */ = {isa = PBXBuildFile; productRef = B4D59C192D8BAFE300B7025B /* EFQRCode */; }; - B4D59C1C2D8BAFE300B7025B /* Bugsnag in Frameworks */ = {isa = PBXBuildFile; productRef = B4D59C1B2D8BAFE300B7025B /* Bugsnag */; }; - B4D59C1E2D8BAFE300B7025B /* BugsnagNetworkRequestPlugin in Frameworks */ = {isa = PBXBuildFile; productRef = B4D59C1D2D8BAFE300B7025B /* BugsnagNetworkRequestPlugin */; }; - B4D59C212D8BB42100B7025B /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4D59C202D8BB41F00B7025B /* File.swift */; }; - B4D59C272D8C5D6F00B7025B /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4D59C262D8C5D6E00B7025B /* main.swift */; }; B4D899942DCAE67700B959AA /* CustomSegmentedControl.m in Sources */ = {isa = PBXBuildFile; fileRef = B4D899932DCAE67700B959AA /* CustomSegmentedControl.m */; }; - B4EE583C226703320003363C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B40D4E35225841ED00428FCC /* Assets.xcassets */; }; - B4EFF73B2C3F6C5E0095D655 /* MockData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4EFF73A2C3F6C5E0095D655 /* MockData.swift */; }; B4F0A4A22FA1BC0000AAAA01 /* WidgetHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4F0A4A12FA1BC0000AAAA00 /* WidgetHelper.mm */; }; B4F0A4A42FA1BC0000AAAA03 /* EventEmitter.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4F0A4A32FA1BC0000AAAA02 /* EventEmitter.mm */; }; - C978A716948AB7DEC5B6F677 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; }; + C978A716948AB7DEC5B6F677 /* (null) in Frameworks */ = {isa = PBXBuildFile; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 6D2A6466258BA92D0092292B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 6D2A6460258BA92C0092292B; - remoteInfo = Stickers; - }; 6D9946672555A661000E52E8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; @@ -182,20 +68,6 @@ remoteGlobalIDString = 6D99465D2555A660000E52E8; remoteInfo = MarketWidgetExtension; }; - 6DD410A5266CADF40087DE03 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 6DD4109B266CADF10087DE03; - remoteInfo = WidgetsExtension; - }; - B40D4E4B225841ED00428FCC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B40D4E2F225841EC00428FCC; - remoteInfo = BlueWalletWatch; - }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -205,8 +77,6 @@ dstPath = ""; dstSubfolderSpec = 13; files = ( - 6D2A6468258BA92D0092292B /* Stickers.appex in Embed Foundation Extensions */, - 6DD410A7266CADF40087DE03 /* WidgetsExtension.appex in Embed Foundation Extensions */, ); name = "Embed Foundation Extensions"; runOnlyForDeploymentPostprocessing = 0; @@ -217,7 +87,6 @@ dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; dstSubfolderSpec = 16; files = ( - B40D4E4D225841ED00428FCC /* BlueWalletWatch.app in Embed Watch Content */, ); name = "Embed Watch Content"; runOnlyForDeploymentPostprocessing = 0; @@ -265,7 +134,6 @@ 6D294A9924D512690039E22B /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/Interface.strings; sourceTree = ""; }; 6D294A9B24D512770039E22B /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Interface.strings; sourceTree = ""; }; 6D294A9D24D5127F0039E22B /* xh */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = xh; path = xh.lproj/Interface.strings; sourceTree = ""; }; - 6D2A6461258BA92C0092292B /* Stickers.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Stickers.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 6D2A6463258BA92D0092292B /* Stickers.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Stickers.xcassets; sourceTree = ""; }; 6D2A6465258BA92D0092292B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 6D2AA8072568B8F40090B089 /* FiatUnit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FiatUnit.swift; sourceTree = ""; }; @@ -284,7 +152,6 @@ 6D9A2E08254BA348007B5B82 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 6D9A2E6A254BAB1B007B5B82 /* MarketAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarketAPI.swift; sourceTree = ""; }; 6DA7047D254E24D5005FE5E2 /* UserDefaultsGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsGroup.swift; sourceTree = ""; }; - 6DD4109C266CADF10087DE03 /* WidgetsExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = WidgetsExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 6DD410A0266CADF10087DE03 /* Widgets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Widgets.swift; sourceTree = ""; }; 6DD410A4266CADF40087DE03 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 6DD410C3266CCB780087DE03 /* WidgetsExtension.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = WidgetsExtension.entitlements; sourceTree = SOURCE_ROOT; }; @@ -309,7 +176,6 @@ A7C4B1FDAD264618BAF8C335 /* libRNCWebView.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNCWebView.a; sourceTree = ""; }; AB2325650CE04F018697ACFE /* libRNReactNativeHapticFeedback.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNReactNativeHapticFeedback.a; sourceTree = ""; }; B409AB052D71E07500BA06F8 /* MenuElementsEmitter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MenuElementsEmitter.swift; path = MenuElementsEmitter/MenuElementsEmitter.swift; sourceTree = SOURCE_ROOT; }; - B40D4E30225841EC00428FCC /* BlueWalletWatch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BlueWalletWatch.app; sourceTree = BUILT_PRODUCTS_DIR; }; B40D4E33225841EC00428FCC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = ""; }; B40D4E35225841ED00428FCC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; B40D4E37225841ED00428FCC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -401,40 +267,11 @@ files = ( 782F075B5DD048449E2DECE9 /* libz.tbd in Frameworks */, 764B49B1420D4AEB8109BF62 /* libsqlite3.0.tbd in Frameworks */, - C978A716948AB7DEC5B6F677 /* BuildFile in Frameworks */, + C978A716948AB7DEC5B6F677 /* (null) in Frameworks */, 17CDA0718F42DB2CE856C872 /* libPods-BlueWallet.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 421830728822A20A50D8A07C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B4D59C1C2D8BAFE300B7025B /* Bugsnag in Frameworks */, - B4D59C1E2D8BAFE300B7025B /* BugsnagNetworkRequestPlugin in Frameworks */, - B41B76872B66B2FF002C48D5 /* BugsnagNetworkRequestPlugin in Frameworks */, - B41B76852B66B2FF002C48D5 /* Bugsnag in Frameworks */, - B4D59C1A2D8BAFE300B7025B /* EFQRCode in Frameworks */, - 6DFC807024EA0B6C007B8700 /* EFQRCode in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 6DD41099266CADF10087DE03 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6DD4109E266CADF10087DE03 /* SwiftUI.framework in Frameworks */, - 6DD4109D266CADF10087DE03 /* WidgetKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8889F8F93C39BB72C97DD77E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -625,9 +462,6 @@ isa = PBXGroup; children = ( 13B07F961A680F5B00A75B9A /* BlueWallet.app */, - B40D4E30225841EC00428FCC /* BlueWalletWatch.app */, - 6D2A6461258BA92C0092292B /* Stickers.appex */, - 6DD4109C266CADF10087DE03 /* WidgetsExtension.appex */, ); name = Products; sourceTree = ""; @@ -805,67 +639,13 @@ buildRules = ( ); dependencies = ( - B40D4E4C225841ED00428FCC /* PBXTargetDependency */, 6D9946682555A661000E52E8 /* PBXTargetDependency */, - 6D2A6467258BA92D0092292B /* PBXTargetDependency */, - 6DD410A6266CADF40087DE03 /* PBXTargetDependency */, ); name = BlueWallet; productName = "Hello World"; productReference = 13B07F961A680F5B00A75B9A /* BlueWallet.app */; productType = "com.apple.product-type.application"; }; - 6D2A6460258BA92C0092292B /* Stickers */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2A646B258BA92D0092292B /* Build configuration list for PBXNativeTarget "Stickers" */; - buildPhases = ( - 6D2A645F258BA92C0092292B /* Resources */, - 8889F8F93C39BB72C97DD77E /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Stickers; - productName = Stickers; - productReference = 6D2A6461258BA92C0092292B /* Stickers.appex */; - productType = "com.apple.product-type.app-extension.messages-sticker-pack"; - }; - 6DD4109B266CADF10087DE03 /* WidgetsExtension */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6DD410A9266CADF40087DE03 /* Build configuration list for PBXNativeTarget "WidgetsExtension" */; - buildPhases = ( - 6DD41098266CADF10087DE03 /* Sources */, - 6DD41099266CADF10087DE03 /* Frameworks */, - 6DD4109A266CADF10087DE03 /* Resources */, - CF0725821442A3000F20E874 /* Upload Bugsnag dSYM */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = WidgetsExtension; - productName = WidgetsExtension; - productReference = 6DD4109C266CADF10087DE03 /* WidgetsExtension.appex */; - productType = "com.apple.product-type.app-extension"; - }; - B40D4E2F225841EC00428FCC /* BlueWalletWatch */ = { - isa = PBXNativeTarget; - buildConfigurationList = B40D4E52225841ED00428FCC /* Build configuration list for PBXNativeTarget "BlueWalletWatch" */; - buildPhases = ( - B40D4E2E225841EC00428FCC /* Resources */, - 421830728822A20A50D8A07C /* Frameworks */, - B40D4E38225841ED00428FCC /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = BlueWalletWatch; - productName = BlueWalletWatch; - productReference = B40D4E30225841EC00428FCC /* BlueWalletWatch.app */; - productType = "com.apple.product-type.application"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -885,16 +665,6 @@ }; }; }; - 6D2A6460258BA92C0092292B = { - CreatedOnToolsVersion = 12.1; - }; - 6DD4109B266CADF10087DE03 = { - CreatedOnToolsVersion = 12.5; - }; - B40D4E2F225841EC00428FCC = { - CreatedOnToolsVersion = 10.2; - LastSwiftMigration = 1240; - }; }; }; buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "BlueWallet" */; @@ -940,9 +710,6 @@ projectRoot = ""; targets = ( 13B07F861A680F5B00A75B9A /* BlueWallet */, - B40D4E2F225841EC00428FCC /* BlueWalletWatch */, - 6D2A6460258BA92C0092292B /* Stickers */, - 6DD4109B266CADF10087DE03 /* WidgetsExtension */, ); }; /* End PBXProject section */ @@ -962,40 +729,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 6D2A645F258BA92C0092292B /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B4742E9A2CCDBE8300380EEE /* Localizable.xcstrings in Resources */, - 6D2A6464258BA92D0092292B /* Stickers.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 6DD4109A266CADF10087DE03 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B41C2E582BB3DCB8000FE097 /* PrivacyInfo.xcprivacy in Resources */, - B44034112BCC40A400162242 /* fiatUnits.json in Resources */, - B4742E9B2CCDBE8300380EEE /* Localizable.xcstrings in Resources */, - 6DD410B7266CAF5C0087DE03 /* Assets.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B40D4E2E225841EC00428FCC /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B4742E982CCDBE8300380EEE /* Localizable.xcstrings in Resources */, - B44034102BCC40A400162242 /* fiatUnits.json in Resources */, - B4742E992CCDBE8300380EEE /* Localizable.xcstrings in Resources */, - B40D4E36225841ED00428FCC /* Assets.xcassets in Resources */, - B4EE583C226703320003363C /* Assets.xcassets in Resources */, - B41C2E572BB3DCB8000FE097 /* PrivacyInfo.xcprivacy in Resources */, - B40D4E34225841EC00428FCC /* Interface.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -1086,34 +819,17 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-BlueWallet/Pods-BlueWallet-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-BlueWallet/Pods-BlueWallet-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-BlueWallet/Pods-BlueWallet-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - CF0725821442A3000F20E874 /* Upload Bugsnag dSYM */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); inputPaths = ( - "${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}", - "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}", ); - name = "Upload Bugsnag dSYM"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-BlueWallet/Pods-BlueWallet-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; - shellPath = "/usr/bin/env ruby"; - shellScript = "api_key = nil # Insert your key here to use it directly from this script\n\n# Attempt to get the API key from an environment variable\nunless api_key\n api_key = ENV[\"BUGSNAG_API_KEY\"]\n\n # If not present, attempt to lookup the value from the Info.plist\n unless api_key\n info_plist_path = \"#{ENV[\"BUILT_PRODUCTS_DIR\"]}/#{ENV[\"INFOPLIST_PATH\"]}\"\n plist_buddy_response = `/usr/libexec/PlistBuddy -c \"print :bugsnag:apiKey\" \"#{info_plist_path}\"`\n plist_buddy_response = `/usr/libexec/PlistBuddy -c \"print :BugsnagAPIKey\" \"#{info_plist_path}\"` if !$?.success?\n api_key = plist_buddy_response if $?.success?\n end\nend\n\nfail(\"No Bugsnag API key detected - add your key to your Info.plist, BUGSNAG_API_KEY environment variable or this Run Script phase\") unless api_key\n\nfork do\n Process.setsid\n STDIN.reopen(\"/dev/null\")\n STDOUT.reopen(\"/dev/null\", \"a\")\n STDERR.reopen(\"/dev/null\", \"a\")\n\n require 'shellwords'\n\n Dir[\"#{ENV[\"DWARF_DSYM_FOLDER_PATH\"]}/*/Contents/Resources/DWARF/*\"].each do |dsym|\n curl_command = \"curl --http1.1 -F dsym=@#{Shellwords.escape(dsym)} -F projectRoot=#{Shellwords.escape(ENV[\"PROJECT_DIR\"])} \"\n curl_command += \"-F apiKey=#{Shellwords.escape(api_key)} \"\n curl_command += \"https://upload.bugsnag.com/\"\n system(curl_command)\n end\nend\n\n"; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-BlueWallet/Pods-BlueWallet-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; D0E81659D2FBFDD27024CF05 /* [CP] Copy Pods Resources */ = { @@ -1124,10 +840,14 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-BlueWallet/Pods-BlueWallet-resources-${CONFIGURATION}-input-files.xcfilelist", ); + inputPaths = ( + ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-BlueWallet/Pods-BlueWallet-resources-${CONFIGURATION}-output-files.xcfilelist", ); + outputPaths = ( + ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-BlueWallet/Pods-BlueWallet-resources.sh\"\n"; @@ -1182,127 +902,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 6DD41098266CADF10087DE03 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6DD410BE266CAF5C0087DE03 /* SendReceiveButtons.swift in Sources */, - B48630E02CCEE7C800A8425C /* PriceWidgetEntryView.swift in Sources */, - 6DD410B4266CAF5C0087DE03 /* MarketAPI.swift in Sources */, - B4793DC32CEDAD4400C92C2E /* KeychainHelper.swift in Sources */, - B40FC3FA29CCD1D00007EBAC /* SwiftTCPClient.swift in Sources */, - B48630EC2CCEEEA700A8425C /* WalletAppShortcuts.swift in Sources */, - 6DD410A1266CADF10087DE03 /* Widgets.swift in Sources */, - B450109D2C0FCD9F00619044 /* Utilities.swift in Sources */, - B49A28BE2CD189B0006B08E4 /* FiatUnitEnum.swift in Sources */, - 6DD410AC266CAE470087DE03 /* PriceWidget.swift in Sources */, - B4B1A4642BFA73110072E3BB /* WidgetHelper.swift in Sources */, - B44033D52BCC368800162242 /* UserDefaultsGroupKey.swift in Sources */, - 6DD410B2266CAF5C0087DE03 /* WalletInformationView.swift in Sources */, - B44034022BCC37F800162242 /* Bundle+decode.swift in Sources */, - B48630D62CCEE67100A8425C /* PriceWidgetProvider.swift in Sources */, - B44033CC2BCC350A00162242 /* Currency.swift in Sources */, - 6DD410B6266CAF5C0087DE03 /* PriceView.swift in Sources */, - B48630DE2CCEE7AC00A8425C /* PriceWidgetEntry.swift in Sources */, - B49A28BB2CD18999006B08E4 /* CompactPriceView.swift in Sources */, - 6DD410B3266CAF5C0087DE03 /* Colors.swift in Sources */, - B44033C12BCC32F800162242 /* BitcoinUnit.swift in Sources */, - 6DD410BB266CAF5C0087DE03 /* MarketView.swift in Sources */, - B44033F02BCC374500162242 /* Numeric+abbreviated.swift in Sources */, - B44033DF2BCC36C300162242 /* LatestTransaction.swift in Sources */, - 6DD410C0266CB1460087DE03 /* MarketWidget.swift in Sources */, - B4793DBC2CEDACBD00C92C2E /* Chain.swift in Sources */, - B4AB225E2B02AD12001F4328 /* XMLParserDelegate.swift in Sources */, - B44033F62BCC377F00162242 /* WidgetData.swift in Sources */, - 6DD410BA266CAF5C0087DE03 /* FiatUnit.swift in Sources */, - B44033FB2BCC379200162242 /* WidgetDataStore.swift in Sources */, - B44033EB2BCC371A00162242 /* MarketData.swift in Sources */, - 6DD410AF266CAF5C0087DE03 /* WalletInformationAndMarketWidget.swift in Sources */, - B44033C62BCC332400162242 /* Balance.swift in Sources */, - B44033E62BCC36FF00162242 /* WalletData.swift in Sources */, - 6DD410BF266CB13D0087DE03 /* Placeholders.swift in Sources */, - 6DD410B0266CAF5C0087DE03 /* WalletInformationWidget.swift in Sources */, - 6DD410B1266CAF5C0087DE03 /* MarketAPI+Electrum.swift in Sources */, - 6DD410B9266CAF5C0087DE03 /* UserDefaultsGroup.swift in Sources */, - 6DD410B8266CAF5C0087DE03 /* UserDefaultsExtension.swift in Sources */, - B48630EA2CCEED8400A8425C /* PriceIntent.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B40D4E38225841ED00428FCC /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B43D037C225847C500FBAA95 /* Wallet.swift in Sources */, - 6D4AF17825D211A3009DD853 /* FiatUnit.swift in Sources */, - B43D037A225847C500FBAA95 /* Transaction.swift in Sources */, - 32F0A29A2311DBB20095C559 /* ComplicationController.swift in Sources */, - B40D4E602258425500428FCC /* SpecifyInterfaceController.swift in Sources */, - B4D0B2642C1DEA99006B6B1B /* ReceiveType.swift in Sources */, - B43D0379225847C500FBAA95 /* WatchDataSource.swift in Sources */, - B450109F2C0FCDA500619044 /* Utilities.swift in Sources */, - B44033D42BCC368800162242 /* UserDefaultsGroupKey.swift in Sources */, - B4D59C212D8BB42100B7025B /* File.swift in Sources */, - B44034012BCC37F800162242 /* Bundle+decode.swift in Sources */, - B4D0B2682C1DED67006B6B1B /* ReceiveMethod.swift in Sources */, - 849047CA2702A32A008EE567 /* Handoff.swift in Sources */, - B44033EA2BCC371A00162242 /* MarketData.swift in Sources */, - B44033CB2BCC350A00162242 /* Currency.swift in Sources */, - 6DFC807224EA2FA9007B8700 /* ViewQRCodefaceController.swift in Sources */, - B40D4E46225841ED00428FCC /* NotificationController.swift in Sources */, - B40D4E5D2258425500428FCC /* InterfaceController.swift in Sources */, - B4D59C272D8C5D6F00B7025B /* main.swift in Sources */, - B4793DBD2CEDACBD00C92C2E /* Chain.swift in Sources */, - B44033FA2BCC379200162242 /* WidgetDataStore.swift in Sources */, - B44033DE2BCC36C300162242 /* LatestTransaction.swift in Sources */, - B4D0B2662C1DEB7F006B6B1B /* ReceiveInterfaceMode.swift in Sources */, - B43D037B225847C500FBAA95 /* TransactionTableRow.swift in Sources */, - B43D037D225847C500FBAA95 /* WalletInformation.swift in Sources */, - 6D4AF15925D21172009DD853 /* MarketAPI.swift in Sources */, - B40D4E642258425500428FCC /* WalletDetailsInterfaceController.swift in Sources */, - 6D4AF16D25D21192009DD853 /* Placeholders.swift in Sources */, - B4793DC42CEDAD4400C92C2E /* KeychainHelper.swift in Sources */, - B40D4E632258425500428FCC /* ReceiveInterfaceController.swift in Sources */, - B43D0378225847C500FBAA95 /* WalletGradient.swift in Sources */, - B4EFF73B2C3F6C5E0095D655 /* MockData.swift in Sources */, - B44033C02BCC32F800162242 /* BitcoinUnit.swift in Sources */, - B44033E52BCC36FF00162242 /* WalletData.swift in Sources */, - B44033EF2BCC374500162242 /* Numeric+abbreviated.swift in Sources */, - B4793DC12CEDACE700C92C2E /* WalletType.swift in Sources */, - B4793DBF2CEDACDA00C92C2E /* TransactionType.swift in Sources */, - B4D0B2622C1DEA11006B6B1B /* ReceivePageInterfaceController.swift in Sources */, - B44033D02BCC352F00162242 /* UserDefaultsGroup.swift in Sources */, - B44033C52BCC332400162242 /* Balance.swift in Sources */, - 6D4AF18425D215D1009DD853 /* UserDefaultsExtension.swift in Sources */, - B4AB225D2B02AD12001F4328 /* XMLParserDelegate.swift in Sources */, - B40D4E5E2258425500428FCC /* NumericKeypadInterfaceController.swift in Sources */, - B44033F52BCC377F00162242 /* WidgetData.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 6D2A6467258BA92D0092292B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 6D2A6460258BA92C0092292B /* Stickers */; - targetProxy = 6D2A6466258BA92D0092292B /* PBXContainerItemProxy */; - }; 6D9946682555A661000E52E8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; targetProxy = 6D9946672555A661000E52E8 /* PBXContainerItemProxy */; }; - 6DD410A6266CADF40087DE03 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 6DD4109B266CADF10087DE03 /* WidgetsExtension */; - targetProxy = 6DD410A5266CADF40087DE03 /* PBXContainerItemProxy */; - }; - B40D4E4C225841ED00428FCC /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - platformFilter = ios; - target = B40D4E2F225841EC00428FCC /* BlueWalletWatch */; - targetProxy = B40D4E4B225841ED00428FCC /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -1355,8 +961,8 @@ CURRENT_PROJECT_VERSION = 1703259999; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = A7W54YZ4WU; - "DEVELOPMENT_TEAM[sdk=macosx*]" = A7W54YZ4WU; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 6AXPP357T2; + "DEVELOPMENT_TEAM[sdk=macosx*]" = 6AXPP357T2; ENABLE_BITCODE = NO; "ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = YES; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -1368,7 +974,7 @@ INFOPLIST_FILE = BlueWallet/Info.plist; INFOPLIST_KEY_CLKComplicationPrincipalClass = "$(PRODUCT_BUNDLE_IDENTIFIER).ComplicationController"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.finance"; - INFOPLIST_KEY_WKCompanionAppBundleIdentifier = io.bluewallet.bluewallet; + INFOPLIST_KEY_WKCompanionAppBundleIdentifier = com.layertwolabs.bluewallet; IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -1386,11 +992,11 @@ "-lc++", ); PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet; + PRODUCT_BUNDLE_IDENTIFIER = com.layertwolabs.bluewallet; PRODUCT_NAME = BlueWallet; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore io.bluewallet.bluewallet"; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "match Development io.bluewallet.bluewallet catalyst"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.layertwolabs.bluewallet"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "match Development com.layertwolabs.bluewallet catalyst"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = YES; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -1417,15 +1023,15 @@ CURRENT_PROJECT_VERSION = 1703259999; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = A7W54YZ4WU; - "DEVELOPMENT_TEAM[sdk=macosx*]" = A7W54YZ4WU; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 6AXPP357T2; + "DEVELOPMENT_TEAM[sdk=macosx*]" = 6AXPP357T2; ENABLE_BITCODE = NO; "ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = YES; HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = BlueWallet/Info.plist; INFOPLIST_KEY_CLKComplicationPrincipalClass = "$(PRODUCT_BUNDLE_IDENTIFIER).ComplicationController"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.finance"; - INFOPLIST_KEY_WKCompanionAppBundleIdentifier = io.bluewallet.bluewallet; + INFOPLIST_KEY_WKCompanionAppBundleIdentifier = com.layertwolabs.bluewallet; IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -1443,11 +1049,11 @@ "-lc++", ); PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet; + PRODUCT_BUNDLE_IDENTIFIER = com.layertwolabs.bluewallet; PRODUCT_NAME = BlueWallet; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore io.bluewallet.bluewallet"; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "match AppStore io.bluewallet.bluewallet catalyst"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.layertwolabs.bluewallet"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "match AppStore com.layertwolabs.bluewallet catalyst"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = YES; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -1459,209 +1065,6 @@ }; name = Release; }; - 6D2A6469258BA92D0092292B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = "iMessage App Icon"; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1703259999; - DEAD_CODE_STRIPPING = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = A7W54YZ4WU; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = Stickers/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 15.6; - LIBRARY_SEARCH_PATHS = ( - "$(SDKROOT)/usr/lib/swift", - "$(SDKROOT)/System/iOSSupport/usr/lib/swift", - "$(inherited)", - ); - MARKETING_VERSION = 7.2.7; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.Stickers; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development io.bluewallet.bluewallet.Stickers"; - SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; - SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2A646A258BA92D0092292B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = "iMessage App Icon"; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1703259999; - DEAD_CODE_STRIPPING = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = A7W54YZ4WU; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = Stickers/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 15.6; - LIBRARY_SEARCH_PATHS = ( - "$(SDKROOT)/usr/lib/swift", - "$(SDKROOT)/System/iOSSupport/usr/lib/swift", - "$(inherited)", - ); - MARKETING_VERSION = 7.2.7; - MTL_FAST_MATH = YES; - PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.Stickers; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore io.bluewallet.bluewallet.Stickers"; - SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; - SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - 6DD410AA266CADF40087DE03 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_ENTITLEMENTS = WidgetsExtension.entitlements; - CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1703259999; - DEAD_CODE_STRIPPING = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = A7W54YZ4WU; - "DEVELOPMENT_TEAM[sdk=macosx*]" = A7W54YZ4WU; - "DEVELOPMENT_TEAM[sdk=watchos*]" = A7W54YZ4WU; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = Widgets/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 17.5; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - LIBRARY_SEARCH_PATHS = ( - "$(SDKROOT)/usr/lib/swift", - "$(SDKROOT)/System/iOSSupport/usr/lib/swift", - "$(inherited)", - ); - MARKETING_VERSION = 7.2.7; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.MarketWidget; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development io.bluewallet.bluewallet.MarketWidget"; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "match Development io.bluewallet.bluewallet.MarketWidget catalyst"; - "PROVISIONING_PROFILE_SPECIFIER[sdk=watchos*]" = "match Development io.bluewallet.bluewallet.MarketWidget"; - SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator watchos watchsimulator"; - SUPPORTS_MACCATALYST = YES; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,4,6"; - TVOS_DEPLOYMENT_TARGET = 15.6; - WATCHOS_DEPLOYMENT_TARGET = 9.6; - }; - name = Debug; - }; - 6DD410AB266CADF40087DE03 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_ENTITLEMENTS = WidgetsExtension.entitlements; - CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Distribution"; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = "iPhone Developer"; - CODE_SIGN_STYLE = Manual; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1703259999; - DEAD_CODE_STRIPPING = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = A7W54YZ4WU; - "DEVELOPMENT_TEAM[sdk=macosx*]" = A7W54YZ4WU; - "DEVELOPMENT_TEAM[sdk=watchos*]" = A7W54YZ4WU; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = Widgets/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 17.5; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - LIBRARY_SEARCH_PATHS = ( - "$(SDKROOT)/usr/lib/swift", - "$(SDKROOT)/System/iOSSupport/usr/lib/swift", - "$(inherited)", - ); - MARKETING_VERSION = 7.2.7; - MTL_FAST_MATH = YES; - PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.MarketWidget; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore io.bluewallet.bluewallet.MarketWidget"; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "match AppStore io.bluewallet.bluewallet.MarketWidget catalyst"; - "PROVISIONING_PROFILE_SPECIFIER[sdk=watchos*]" = "match AppStore io.bluewallet.bluewallet.MarketWidget"; - SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator watchos watchsimulator"; - SUPPORTS_MACCATALYST = YES; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,4,6"; - TVOS_DEPLOYMENT_TARGET = 15.6; - WATCHOS_DEPLOYMENT_TARGET = 9.6; - }; - name = Release; - }; 83CBBA201A601CBA00E9B192 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1798,120 +1201,6 @@ }; name = Release; }; - B40D4E53225841ED00428FCC /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_ENTITLEMENTS = BlueWalletWatch/BlueWalletWatch.entitlements; - CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = "iPhone Developer"; - CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1703259999; - DEAD_CODE_STRIPPING = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=watchos*]" = A7W54YZ4WU; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = BlueWalletWatch/Info.plist; - INFOPLIST_KEY_CLKComplicationPrincipalClass = io.bluewallet.bluewallet.watch.extension.ComplicationController; - INFOPLIST_KEY_UIMainStoryboardFile = Interface; - INFOPLIST_KEY_UIUserInterfaceStyle = Automatic; - INFOPLIST_KEY_WKCompanionAppBundleIdentifier = io.bluewallet.bluewallet; - IPHONEOS_DEPLOYMENT_TARGET = 15.6; - LD_RUNPATH_SEARCH_PATHS = ( - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - LIBRARY_SEARCH_PATHS = ( - "$(SDKROOT)/usr/lib/swift", - "$(SDKROOT)/System/iOSSupport/usr/lib/swift", - "$(inherited)", - ); - MACOSX_DEPLOYMENT_TARGET = 12.4; - MARKETING_VERSION = 7.2.7; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.watch; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=watchos*]" = "match Development io.bluewallet.bluewallet.watch"; - SDKROOT = watchos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OBJC_BRIDGING_HEADER = "BlueWalletWatch/BlueWalletWatch-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 11.0; - }; - name = Debug; - }; - B40D4E54225841ED00428FCC /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_ENTITLEMENTS = BlueWalletWatch/BlueWalletWatch.entitlements; - CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1703259999; - DEAD_CODE_STRIPPING = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=watchos*]" = A7W54YZ4WU; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = BlueWalletWatch/Info.plist; - INFOPLIST_KEY_CLKComplicationPrincipalClass = io.bluewallet.bluewallet.watch.extension.ComplicationController; - INFOPLIST_KEY_UIMainStoryboardFile = Interface; - INFOPLIST_KEY_UIUserInterfaceStyle = Automatic; - INFOPLIST_KEY_WKCompanionAppBundleIdentifier = io.bluewallet.bluewallet; - IPHONEOS_DEPLOYMENT_TARGET = 15.6; - LD_RUNPATH_SEARCH_PATHS = ( - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - LIBRARY_SEARCH_PATHS = ( - "$(SDKROOT)/usr/lib/swift", - "$(SDKROOT)/System/iOSSupport/usr/lib/swift", - "$(inherited)", - ); - MACOSX_DEPLOYMENT_TARGET = 12.4; - MARKETING_VERSION = 7.2.7; - MTL_FAST_MATH = YES; - PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.watch; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=watchos*]" = "match AppStore io.bluewallet.bluewallet.watch"; - SDKROOT = watchos; - SKIP_INSTALL = YES; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OBJC_BRIDGING_HEADER = "BlueWalletWatch/BlueWalletWatch-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 11.0; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -1924,24 +1213,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 6D2A646B258BA92D0092292B /* Build configuration list for PBXNativeTarget "Stickers" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2A6469258BA92D0092292B /* Debug */, - 6D2A646A258BA92D0092292B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6DD410A9266CADF40087DE03 /* Build configuration list for PBXNativeTarget "WidgetsExtension" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6DD410AA266CADF40087DE03 /* Debug */, - 6DD410AB266CADF40087DE03 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "BlueWallet" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -1951,15 +1222,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - B40D4E52225841ED00428FCC /* Build configuration list for PBXNativeTarget "BlueWalletWatch" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B40D4E53225841ED00428FCC /* Debug */, - B40D4E54225841ED00428FCC /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ @@ -1980,39 +1242,6 @@ }; }; /* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 6DFC806F24EA0B6C007B8700 /* EFQRCode */ = { - isa = XCSwiftPackageProductDependency; - package = 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode" */; - productName = EFQRCode; - }; - B41B76842B66B2FF002C48D5 /* Bugsnag */ = { - isa = XCSwiftPackageProductDependency; - package = B41B76832B66B2FF002C48D5 /* XCRemoteSwiftPackageReference "bugsnag-cocoa" */; - productName = Bugsnag; - }; - B41B76862B66B2FF002C48D5 /* BugsnagNetworkRequestPlugin */ = { - isa = XCSwiftPackageProductDependency; - package = B41B76832B66B2FF002C48D5 /* XCRemoteSwiftPackageReference "bugsnag-cocoa" */; - productName = BugsnagNetworkRequestPlugin; - }; - B4D59C192D8BAFE300B7025B /* EFQRCode */ = { - isa = XCSwiftPackageProductDependency; - package = 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode" */; - productName = EFQRCode; - }; - B4D59C1B2D8BAFE300B7025B /* Bugsnag */ = { - isa = XCSwiftPackageProductDependency; - package = B41B76832B66B2FF002C48D5 /* XCRemoteSwiftPackageReference "bugsnag-cocoa" */; - productName = Bugsnag; - }; - B4D59C1D2D8BAFE300B7025B /* BugsnagNetworkRequestPlugin */ = { - isa = XCSwiftPackageProductDependency; - package = B41B76832B66B2FF002C48D5 /* XCRemoteSwiftPackageReference "bugsnag-cocoa" */; - productName = BugsnagNetworkRequestPlugin; - }; -/* End XCSwiftPackageProductDependency section */ }; rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; } diff --git a/ios/BlueWallet/AppDelegate.swift b/ios/BlueWallet/AppDelegate.swift index b0121ca9ed9..4ceb3e63cce 100644 --- a/ios/BlueWallet/AppDelegate.swift +++ b/ios/BlueWallet/AppDelegate.swift @@ -44,7 +44,7 @@ class AppDelegate: RCTAppDelegate, UNUserNotificationCenterDelegate { #endif } - self.moduleName = "BlueWallet" + self.moduleName = "RedWallet" self.dependencyProvider = RCTAppDependencyProvider() self.initialProps = [:] @@ -306,7 +306,7 @@ class AppDelegate: RCTAppDelegate, UNUserNotificationCenterDelegate { userDefaultsGroup?.setValue(userActivityData, forKey: "onUserActivityOpen") - if ["io.bluewallet.bluewallet.receiveonchain", "io.bluewallet.bluewallet.xpub", "io.bluewallet.bluewallet.blockexplorer"].contains(activityType) { + if ["com.layertwolabs.bluewallet.receiveonchain", "com.layertwolabs.bluewallet.xpub", "com.layertwolabs.bluewallet.blockexplorer"].contains(activityType) { EventEmitter.shared().sendUserActivity(userActivityData) return true } diff --git a/ios/BlueWallet/BlueWallet.entitlements b/ios/BlueWallet/BlueWallet.entitlements index b2b8e48bb08..fd4c532376f 100644 --- a/ios/BlueWallet/BlueWallet.entitlements +++ b/ios/BlueWallet/BlueWallet.entitlements @@ -8,7 +8,7 @@ com.apple.security.application-groups - group.io.bluewallet.bluewallet + group.com.layertwolabs.bluewallet com.apple.security.device.camera diff --git a/ios/BlueWallet/BlueWalletRelease.entitlements b/ios/BlueWallet/BlueWalletRelease.entitlements index b2b8e48bb08..fd4c532376f 100644 --- a/ios/BlueWallet/BlueWalletRelease.entitlements +++ b/ios/BlueWallet/BlueWalletRelease.entitlements @@ -8,7 +8,7 @@ com.apple.security.application-groups - group.io.bluewallet.bluewallet + group.com.layertwolabs.bluewallet com.apple.security.device.camera diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/100.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/100.png new file mode 100644 index 00000000000..f5cad145514 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/100.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/102.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/102.png new file mode 100644 index 00000000000..ab0ec8c57b7 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/102.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/1024 1.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/1024 1.png deleted file mode 100644 index 594857ecda6..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/1024 1.png and /dev/null differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/1024 2.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/1024 2.png deleted file mode 100644 index 94ff21813d8..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/1024 2.png and /dev/null differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/1024.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/1024.png index 9c2422d9c26..1a5fff76425 100644 Binary files a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/1024.png and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/1024.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/108.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/108.png new file mode 100644 index 00000000000..5920378de39 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/108.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/114.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/114.png new file mode 100644 index 00000000000..314d02e99ef Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/114.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/120.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/120.png new file mode 100644 index 00000000000..f0e80077825 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/120.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/128.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/128.png new file mode 100644 index 00000000000..cfc9fee93fc Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/128.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/144.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/144.png new file mode 100644 index 00000000000..a266a271182 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/144.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/152.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/152.png new file mode 100644 index 00000000000..22d1bc7a982 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/152.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/16.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/16.png new file mode 100644 index 00000000000..8c514665db5 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/16.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/167.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/167.png new file mode 100644 index 00000000000..a17eda7117c Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/167.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/172.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/172.png new file mode 100644 index 00000000000..ef76e0ae939 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/172.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/180.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/180.png new file mode 100644 index 00000000000..48fcc8f9567 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/180.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/196.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/196.png new file mode 100644 index 00000000000..047ac363bd3 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/196.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/20.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/20.png new file mode 100644 index 00000000000..77b6a9a8752 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/20.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/216.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/216.png new file mode 100644 index 00000000000..e1b90567700 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/216.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/234.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/234.png new file mode 100644 index 00000000000..2f34eab961c Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/234.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/256.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/256.png new file mode 100644 index 00000000000..9808c7b9337 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/256.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/258.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/258.png new file mode 100644 index 00000000000..e3df91e6573 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/258.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/29.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/29.png new file mode 100644 index 00000000000..cd85d1b3468 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/29.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/32.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/32.png new file mode 100644 index 00000000000..70965f3cc14 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/32.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/40.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/40.png new file mode 100644 index 00000000000..c31cdb5d95a Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/40.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/48.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/48.png new file mode 100644 index 00000000000..2ac6112d90a Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/48.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/50.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/50.png new file mode 100644 index 00000000000..9a242fd2537 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/50.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/512.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/512.png new file mode 100644 index 00000000000..f08247c09f7 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/512.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/55.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/55.png new file mode 100644 index 00000000000..51def0eabc7 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/55.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/57.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/57.png new file mode 100644 index 00000000000..7651c5f5956 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/57.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/58.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/58.png new file mode 100644 index 00000000000..52f94fca3d6 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/58.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/60.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/60.png new file mode 100644 index 00000000000..e7caf09fb28 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/60.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/64.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/64.png new file mode 100644 index 00000000000..419232fc9a0 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/64.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/66.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/66.png new file mode 100644 index 00000000000..abf73177f1d Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/66.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/72.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/72.png new file mode 100644 index 00000000000..ff66f0d6aaa Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/72.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/76.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/76.png new file mode 100644 index 00000000000..566bd836012 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/76.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/80.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/80.png new file mode 100644 index 00000000000..37288cee1c5 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/80.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/87.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/87.png new file mode 100644 index 00000000000..7b8541dbe9e Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/87.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/88.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/88.png new file mode 100644 index 00000000000..7dac68d11d8 Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/88.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/92.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/92.png new file mode 100644 index 00000000000..fe94b1dfafd Binary files /dev/null and b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/92.png differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/BlueWallet-1024.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/BlueWallet-1024.png deleted file mode 100644 index 33f4a58f696..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/BlueWallet-1024.png and /dev/null differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/Contents.json b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/Contents.json index 052b626a2fa..ed14dd1d029 100644 --- a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,104 +1,450 @@ { - "images" : [ + "images": [ { - "filename" : "BlueWallet-1024.png", - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" + "size": "60x60", + "expected-size": "180", + "filename": "180.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "3x" }, { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "filename" : "1024.png", - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" + "size": "40x40", + "expected-size": "80", + "filename": "80.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "2x" }, { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "tinted" - } - ], - "filename" : "1024 1.png", - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" + "size": "40x40", + "expected-size": "120", + "filename": "120.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "3x" }, { - "filename" : "icon_16x16.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "16x16" + "size": "60x60", + "expected-size": "120", + "filename": "120.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "2x" }, { - "filename" : "icon_16x16@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "16x16" + "size": "57x57", + "expected-size": "57", + "filename": "57.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "1x" }, { - "filename" : "icon_32x32.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "32x32" + "size": "29x29", + "expected-size": "58", + "filename": "58.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "2x" }, { - "filename" : "icon_32x32@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "32x32" + "size": "29x29", + "expected-size": "29", + "filename": "29.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "1x" }, { - "filename" : "icon_128x128.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "128x128" + "size": "29x29", + "expected-size": "87", + "filename": "87.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "3x" }, { - "filename" : "icon_128x128@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "128x128" + "size": "57x57", + "expected-size": "114", + "filename": "114.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "2x" }, { - "filename" : "icon_256x256.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "256x256" + "size": "20x20", + "expected-size": "40", + "filename": "40.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "2x" }, { - "filename" : "icon_256x256@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "256x256" + "size": "20x20", + "expected-size": "60", + "filename": "60.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "3x" }, { - "filename" : "icon_512x512.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "512x512" + "size": "1024x1024", + "filename": "1024.png", + "expected-size": "1024", + "idiom": "ios-marketing", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "scale": "1x" }, { - "filename" : "icon_512x512@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "512x512" + "size": "40x40", + "expected-size": "80", + "filename": "80.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "ipad", + "scale": "2x" }, { - "filename" : "1024 2.png", - "idiom" : "universal", - "platform" : "watchos", - "size" : "1024x1024" + "size": "72x72", + "expected-size": "72", + "filename": "72.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "ipad", + "scale": "1x" + }, + { + "size": "76x76", + "expected-size": "152", + "filename": "152.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "ipad", + "scale": "2x" + }, + { + "size": "50x50", + "expected-size": "100", + "filename": "100.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "ipad", + "scale": "2x" + }, + { + "size": "29x29", + "expected-size": "58", + "filename": "58.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "ipad", + "scale": "2x" + }, + { + "size": "76x76", + "expected-size": "76", + "filename": "76.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "ipad", + "scale": "1x" + }, + { + "size": "29x29", + "expected-size": "29", + "filename": "29.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "ipad", + "scale": "1x" + }, + { + "size": "50x50", + "expected-size": "50", + "filename": "50.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "ipad", + "scale": "1x" + }, + { + "size": "72x72", + "expected-size": "144", + "filename": "144.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "ipad", + "scale": "2x" + }, + { + "size": "40x40", + "expected-size": "40", + "filename": "40.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "ipad", + "scale": "1x" + }, + { + "size": "83.5x83.5", + "expected-size": "167", + "filename": "167.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "ipad", + "scale": "2x" + }, + { + "size": "20x20", + "expected-size": "20", + "filename": "20.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "ipad", + "scale": "1x" + }, + { + "size": "20x20", + "expected-size": "40", + "filename": "40.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "ipad", + "scale": "2x" + }, + { + "idiom": "watch", + "filename": "172.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "subtype": "38mm", + "scale": "2x", + "size": "86x86", + "expected-size": "172", + "role": "quickLook" + }, + { + "idiom": "watch", + "filename": "80.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "subtype": "38mm", + "scale": "2x", + "size": "40x40", + "expected-size": "80", + "role": "appLauncher" + }, + { + "idiom": "watch", + "filename": "88.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "subtype": "40mm", + "scale": "2x", + "size": "44x44", + "expected-size": "88", + "role": "appLauncher" + }, + { + "idiom": "watch", + "filename": "102.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "subtype": "45mm", + "scale": "2x", + "size": "51x51", + "expected-size": "102", + "role": "appLauncher" + }, + { + "idiom": "watch", + "filename": "108.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "subtype": "49mm", + "scale": "2x", + "size": "54x54", + "expected-size": "108", + "role": "appLauncher" + }, + { + "idiom": "watch", + "filename": "92.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "subtype": "41mm", + "scale": "2x", + "size": "46x46", + "expected-size": "92", + "role": "appLauncher" + }, + { + "idiom": "watch", + "filename": "100.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "subtype": "44mm", + "scale": "2x", + "size": "50x50", + "expected-size": "100", + "role": "appLauncher" + }, + { + "idiom": "watch", + "filename": "196.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "subtype": "42mm", + "scale": "2x", + "size": "98x98", + "expected-size": "196", + "role": "quickLook" + }, + { + "idiom": "watch", + "filename": "216.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "subtype": "44mm", + "scale": "2x", + "size": "108x108", + "expected-size": "216", + "role": "quickLook" + }, + { + "idiom": "watch", + "filename": "234.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "subtype": "45mm", + "scale": "2x", + "size": "117x117", + "expected-size": "234", + "role": "quickLook" + }, + { + "idiom": "watch", + "filename": "258.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "subtype": "49mm", + "scale": "2x", + "size": "129x129", + "expected-size": "258", + "role": "quickLook" + }, + { + "idiom": "watch", + "filename": "48.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "subtype": "38mm", + "scale": "2x", + "size": "24x24", + "expected-size": "48", + "role": "notificationCenter" + }, + { + "idiom": "watch", + "filename": "55.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "subtype": "42mm", + "scale": "2x", + "size": "27.5x27.5", + "expected-size": "55", + "role": "notificationCenter" + }, + { + "idiom": "watch", + "filename": "66.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "subtype": "45mm", + "scale": "2x", + "size": "33x33", + "expected-size": "66", + "role": "notificationCenter" + }, + { + "size": "29x29", + "expected-size": "87", + "filename": "87.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "watch", + "role": "companionSettings", + "scale": "3x" + }, + { + "size": "29x29", + "expected-size": "58", + "filename": "58.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "watch", + "role": "companionSettings", + "scale": "2x" + }, + { + "size": "1024x1024", + "expected-size": "1024", + "filename": "1024.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "watch-marketing", + "scale": "1x" + }, + { + "size": "128x128", + "expected-size": "128", + "filename": "128.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "mac", + "scale": "1x" + }, + { + "size": "256x256", + "expected-size": "256", + "filename": "256.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "mac", + "scale": "1x" + }, + { + "size": "128x128", + "expected-size": "256", + "filename": "256.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "mac", + "scale": "2x" + }, + { + "size": "256x256", + "expected-size": "512", + "filename": "512.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "mac", + "scale": "2x" + }, + { + "size": "32x32", + "expected-size": "32", + "filename": "32.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "mac", + "scale": "1x" + }, + { + "size": "512x512", + "expected-size": "512", + "filename": "512.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "mac", + "scale": "1x" + }, + { + "size": "16x16", + "expected-size": "16", + "filename": "16.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "mac", + "scale": "1x" + }, + { + "size": "16x16", + "expected-size": "32", + "filename": "32.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "mac", + "scale": "2x" + }, + { + "size": "32x32", + "expected-size": "64", + "filename": "64.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "mac", + "scale": "2x" + }, + { + "size": "512x512", + "expected-size": "1024", + "filename": "1024.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "mac", + "scale": "2x" } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } + ] } diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_128x128.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_128x128.png deleted file mode 100644 index 9222970acc0..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_128x128.png and /dev/null differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_128x128@2x.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_128x128@2x.png deleted file mode 100644 index a970347b62f..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_128x128@2x.png and /dev/null differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_16x16.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_16x16.png deleted file mode 100644 index afb26ac6296..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_16x16.png and /dev/null differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_16x16@2x.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_16x16@2x.png deleted file mode 100644 index 9fa78ea4bf5..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_16x16@2x.png and /dev/null differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_256x256.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_256x256.png deleted file mode 100644 index a970347b62f..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_256x256.png and /dev/null differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_256x256@2x.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_256x256@2x.png deleted file mode 100644 index 6e2c9019380..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_256x256@2x.png and /dev/null differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_32x32.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_32x32.png deleted file mode 100644 index 9fa78ea4bf5..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_32x32.png and /dev/null differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_32x32@2x.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_32x32@2x.png deleted file mode 100644 index cc9ddb62411..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_32x32@2x.png and /dev/null differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_512x512.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_512x512.png deleted file mode 100644 index 6e2c9019380..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_512x512.png and /dev/null differ diff --git a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_512x512@2x.png b/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_512x512@2x.png deleted file mode 100644 index cb6f9d6e1c3..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/AppIcon.appiconset/icon_512x512@2x.png and /dev/null differ diff --git a/ios/BlueWallet/Images.xcassets/SplashIcon.imageset/Contents.json b/ios/BlueWallet/Images.xcassets/SplashIcon.imageset/Contents.json index add923b2afa..cf816e6bdd9 100644 --- a/ios/BlueWallet/Images.xcassets/SplashIcon.imageset/Contents.json +++ b/ios/BlueWallet/Images.xcassets/SplashIcon.imageset/Contents.json @@ -4,16 +4,6 @@ "filename" : "icon.png", "idiom" : "universal", "scale" : "1x" - }, - { - "filename" : "icon@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "icon@3x.png", - "idiom" : "universal", - "scale" : "3x" } ], "info" : { diff --git a/ios/BlueWallet/Images.xcassets/SplashIcon.imageset/icon.png b/ios/BlueWallet/Images.xcassets/SplashIcon.imageset/icon.png index ec541528a9a..02bc2883a29 100644 Binary files a/ios/BlueWallet/Images.xcassets/SplashIcon.imageset/icon.png and b/ios/BlueWallet/Images.xcassets/SplashIcon.imageset/icon.png differ diff --git a/ios/BlueWallet/Images.xcassets/SplashIcon.imageset/icon@2x.png b/ios/BlueWallet/Images.xcassets/SplashIcon.imageset/icon@2x.png deleted file mode 100644 index a72c80addc6..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/SplashIcon.imageset/icon@2x.png and /dev/null differ diff --git a/ios/BlueWallet/Images.xcassets/SplashIcon.imageset/icon@3x.png b/ios/BlueWallet/Images.xcassets/SplashIcon.imageset/icon@3x.png deleted file mode 100644 index 5727bf33172..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/SplashIcon.imageset/icon@3x.png and /dev/null differ diff --git a/ios/BlueWallet/Images.xcassets/icon.imageset/Contents.json b/ios/BlueWallet/Images.xcassets/icon.imageset/Contents.json deleted file mode 100644 index add923b2afa..00000000000 --- a/ios/BlueWallet/Images.xcassets/icon.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "filename" : "icon.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "icon@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "icon@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/ios/BlueWallet/Images.xcassets/icon.imageset/icon.png b/ios/BlueWallet/Images.xcassets/icon.imageset/icon.png deleted file mode 100644 index b1479e4f612..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/icon.imageset/icon.png and /dev/null differ diff --git a/ios/BlueWallet/Images.xcassets/icon.imageset/icon@2x.png b/ios/BlueWallet/Images.xcassets/icon.imageset/icon@2x.png deleted file mode 100644 index 1337cd80167..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/icon.imageset/icon@2x.png and /dev/null differ diff --git a/ios/BlueWallet/Images.xcassets/icon.imageset/icon@3x.png b/ios/BlueWallet/Images.xcassets/icon.imageset/icon@3x.png deleted file mode 100644 index dc96d567974..00000000000 Binary files a/ios/BlueWallet/Images.xcassets/icon.imageset/icon@3x.png and /dev/null differ diff --git a/ios/BlueWallet/Info.plist b/ios/BlueWallet/Info.plist index 40b1c7fa6ba..9cddef43765 100644 --- a/ios/BlueWallet/Info.plist +++ b/ios/BlueWallet/Info.plist @@ -4,14 +4,14 @@ BGTaskSchedulerPermittedIdentifiers - io.bluewallet.bluewallet.fetchTxsForWallet + com.layertwolabs.bluewallet.fetchTxsForWallet CADisableMinimumFrameDurationOnPhone CFBundleDevelopmentRegion en CFBundleDisplayName - BlueWallet + RedWallet CFBundleDocumentTypes @@ -25,7 +25,7 @@ Owner LSItemContentTypes - io.bluewallet.psbt + com.layertwolabs.psbt @@ -54,7 +54,7 @@ Owner LSItemContentTypes - io.bluewallet.psbt.txn + com.layertwolabs.psbt.txn @@ -68,7 +68,7 @@ Owner LSItemContentTypes - io.bluewallet.backup + com.layertwolabs.backup @@ -82,7 +82,7 @@ Owner LSItemContentTypes - io.bluewallet.bwcosigner + com.layertwolabs.bwcosigner @@ -192,8 +192,8 @@ In order to import an image for scanning, we need your permission to access your photo library. NSUserActivityTypes - io.bluewallet.bluewallet.receiveonchain - io.bluewallet.bluewallet.xpub + com.layertwolabs.bluewallet.receiveonchain + com.layertwolabs.bluewallet.xpub RCTNewArchEnabled @@ -256,7 +256,7 @@ UTTypeDescription Partially Signed Bitcoin Transaction UTTypeIdentifier - io.bluewallet.psbt + com.layertwolabs.psbt UTTypeTagSpecification public.filename-extension @@ -269,7 +269,7 @@ UTTypeDescription BW COSIGNER UTTypeIdentifier - io.bluewallet.bwcosigner + com.layertwolabs.bwcosigner UTTypeTagSpecification public.filename-extension @@ -286,7 +286,7 @@ UTTypeDescription Bitcoin Transaction UTTypeIdentifier - io.bluewallet.psbt.txn + com.layertwolabs.psbt.txn UTTypeTagSpecification public.filename-extension @@ -303,7 +303,7 @@ UTTypeDescription Electrum Backup UTTypeIdentifier - io.bluewallet.backup + com.layertwolabs.backup UTTypeTagSpecification public.filename-extension @@ -340,7 +340,7 @@ WKCompanionAppBundleIdentifier - io.bluewallet.bluewallet + com.layertwolabs.bluewallet bugsnag apiKey diff --git a/ios/BlueWalletWatch/BlueWalletWatch.entitlements b/ios/BlueWalletWatch/BlueWalletWatch.entitlements index 86bfd6c51c6..8b65dff27fc 100644 --- a/ios/BlueWalletWatch/BlueWalletWatch.entitlements +++ b/ios/BlueWalletWatch/BlueWalletWatch.entitlements @@ -4,7 +4,7 @@ com.apple.security.application-groups - group.io.bluewallet.bluewallet + group.com.layertwolabs.bluewallet diff --git a/ios/BlueWalletWatch/ComplicationController.swift b/ios/BlueWalletWatch/ComplicationController.swift index 184f6ff54c5..13a20cf0148 100644 --- a/ios/BlueWalletWatch/ComplicationController.swift +++ b/ios/BlueWalletWatch/ComplicationController.swift @@ -25,7 +25,7 @@ class ComplicationController: NSObject, CLKComplicationDataSource { @available(watchOSApplicationExtension 7.0, *) func complicationDescriptors() async -> [CLKComplicationDescriptor] { return [CLKComplicationDescriptor( - identifier: "io.bluewallet.bluewallet", + identifier: "com.layertwolabs.bluewallet", displayName: "Market Price", supportedFamilies: CLKComplicationFamily.allCases)] } diff --git a/ios/BlueWalletWatch/Info.plist b/ios/BlueWalletWatch/Info.plist index e5390497333..280c317afbd 100644 --- a/ios/BlueWalletWatch/Info.plist +++ b/ios/BlueWalletWatch/Info.plist @@ -51,7 +51,7 @@ WKApplication WKCompanionAppBundleIdentifier - io.bluewallet.bluewallet + com.layertwolabs.bluewallet bugsnag apiKey diff --git a/ios/BlueWalletWatch/Objects/Handoff.swift b/ios/BlueWalletWatch/Objects/Handoff.swift index b11ad2b835d..34f1109f79f 100644 --- a/ios/BlueWalletWatch/Objects/Handoff.swift +++ b/ios/BlueWalletWatch/Objects/Handoff.swift @@ -9,9 +9,9 @@ import Foundation enum HandoffIdentifier: String { - case ReceiveOnchain = "io.bluewallet.bluewallet.receiveonchain" - case Xpub = "io.bluewallet.bluewallet.xpub" - case ViewInBlockExplorer = "io.bluewallet.bluewallet.blockexplorer" + case ReceiveOnchain = "com.layertwolabs.bluewallet.receiveonchain" + case Xpub = "com.layertwolabs.bluewallet.xpub" + case ViewInBlockExplorer = "com.layertwolabs.bluewallet.blockexplorer" } enum HandOffUserInfoKey: String { diff --git a/ios/Components/EventEmitter.swift b/ios/Components/EventEmitter.swift index ad0f9e91332..701ff6d1bee 100644 --- a/ios/Components/EventEmitter.swift +++ b/ios/Components/EventEmitter.swift @@ -27,7 +27,7 @@ class EventEmitter: RCTEventEmitter, NativeEventEmitterSpec { @objc func getMostRecentUserActivity(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) { - if let defaults = UserDefaults(suiteName: "group.io.bluewallet.bluewallet") { + if let defaults = UserDefaults(suiteName: "group.com.layertwolabs.bluewallet") { resolve(defaults.value(forKey: "onUserActivityOpen")) } else { resolve(nil) diff --git a/ios/Localizable.xcstrings b/ios/Localizable.xcstrings index be54eb39f2d..cdcef6d9ba5 100644 --- a/ios/Localizable.xcstrings +++ b/ios/Localizable.xcstrings @@ -18,9 +18,6 @@ }, "Bahrain (Bahraini Dinar)" : { - }, - "Balance" : { - }, "Bitcoin (%@)" : { @@ -39,9 +36,6 @@ }, "Central African Republic (Central African Franc)" : { - }, - "Checked at %@" : { - }, "Chile (Chilean Peso)" : { @@ -51,36 +45,18 @@ }, "Choose your preferred currency." : { - }, - "Choose your preferred fiat currency." : { - }, "Colombia (Colombian Peso)" : { - }, - "Configure Market Widget with ${electrumHost}" : { - - }, - "Configure Market Widget with ${electrumHost} and show error messages: ${showErrorMessages}" : { - - }, - "Configure the Market Widget to show the Electrum host connected to/being attempted and display error messages if data retrieval fails." : { - }, "Croatia (Croatian Kuna)" : { }, "Currency" : { - }, - "Currency: %@" : { - }, "Current Bitcoin Market Rate" : { - }, - "Current Bitcoin Price: %@" : { - }, "Czech Republic (Czech Koruna)" : { @@ -89,6 +65,7 @@ }, "display_in_BROWSER_TITLE" : { + "extractionState" : "stale", "localizations" : { "en_US" : { "stringUnit" : { @@ -125,9 +102,6 @@ }, "Failed to retrieve the Bitcoin market rate." : { - }, - "Fiat Currency" : { - }, "from" : { @@ -170,40 +144,15 @@ }, "Last Updated" : { - }, - "Last updated %@ from %@" : { - "localizations" : { - "en_US" : { - "stringUnit" : { - "state" : "new", - "value" : "Last updated %1$@ from %2$@" - } - } - } - }, - "Latest transaction" : { - }, "Lebanon (Lebanese Pound)" : { }, "Malaysia (Malaysian Ringgit)" : { - }, - "Market" : { - }, "Market Rate" : { - }, - "Market Widget" : { - - }, - "Market Widget Configuration" : { - - }, - "Market Widget is connected to ${electrumHost}" : { - }, "Mexico (Mexican Peso)" : { @@ -213,9 +162,6 @@ }, "New Zealand (New Zealand Dollar)" : { - }, - "Next Block" : { - }, "Nigeria (Nigerian Naira)" : { @@ -237,33 +183,18 @@ }, "Qatar (Qatari Riyal)" : { - }, - "receive" : { - }, "Romania (Romanian Leu)" : { }, "Russia (Russian Ruble)" : { - }, - "Sats/%@" : { - }, "Saudi Arabia (Saudi Riyal)" : { - }, - "send" : { - - }, - "Show Error Messages" : { - }, "Singapore (Singapore Dollar)" : { - }, - "Source: %@" : { - }, "South Africa (South African Rand)" : { @@ -306,9 +237,6 @@ }, "United States of America (US Dollar)" : { - }, - "Updated: %@" : { - }, "Uruguay (Uruguayan Peso)" : { @@ -321,30 +249,9 @@ }, "View the current Bitcoin market rate in your preferred currency." : { - }, - "View the current Bitcoin market rate in your preferred fiat currency." : { - - }, - "View the current Bitcoin market rate." : { - - }, - "View the current market information." : { - - }, - "View the current price of Bitcoin" : { - }, "View the current price of Bitcoin." : { - }, - "View the Electrum host connected to/being attempted" : { - - }, - "View your accumulated balance." : { - - }, - "View your total wallet balance and network prices." : { - }, "VIEW_ADDRESS_TRANSACTIONS_TITLE" : { "extractionState" : "manual", @@ -379,9 +286,6 @@ } } } - }, - "Wallet and Market" : { - } }, "version" : "1.1" diff --git a/ios/Podfile b/ios/Podfile index dfdc287c572..b909819ecf1 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -19,24 +19,17 @@ if linkage != nil use_frameworks! :linkage => linkage.to_sym end -# Define a common function to configure shared settings for targets -def configure_target() - config = use_native_modules! +target 'BlueWallet' do + use_native_modules! use_react_native!( - # Specify the path directly if use_native_modules! does not provide it - :path => config[:reactNativePath], + :path => "../node_modules/react-native", :app_path => "#{Pod::Config.instance.installation_root}/.." - ) + pod 'react-native-bw-file-access', :path => '../blue_modules/react-native-bw-file-access' end - -target 'BlueWallet' do - configure_target() -end - post_install do |installer| react_native_post_install( installer, @@ -61,4 +54,15 @@ post_install do |installer| File.write(xcconfig_path, content) end end + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.1' + + if ['React-Core-AccessibilityResources'].include? target.name + config.build_settings['CODE_SIGN_STYLE'] = "Manual" + config.build_settings['CODE_SIGN_IDENTITY'] = "Apple Distribution: Bluewallet Services, S. R. L. (A7W54YZ4WU)" + config.build_settings['DEVELOPMENT_TEAM'] = "6AXPP357T2" + end + end + end end diff --git a/ios/Shared/UserDefaultsGroupKey.swift b/ios/Shared/UserDefaultsGroupKey.swift index c4a4554eefb..a2e3f9844c0 100644 --- a/ios/Shared/UserDefaultsGroupKey.swift +++ b/ios/Shared/UserDefaultsGroupKey.swift @@ -9,10 +9,10 @@ import Foundation enum UserDefaultsGroupKey: String { - case GroupName = "group.io.bluewallet.bluewallet" + case GroupName = "group.com.layertwolabs.bluewallet" case PreferredCurrency = "preferredCurrency" - case WatchAppBundleIdentifier = "io.bluewallet.bluewallet.watch" - case BundleIdentifier = "io.bluewallet.bluewallet" + case WatchAppBundleIdentifier = "com.layertwolabs.bluewallet.watch" + case BundleIdentifier = "com.layertwolabs.bluewallet" case ElectrumSettingsHost = "electrum_host" case ElectrumSettingsTCPPort = "electrum_tcp_port" case ElectrumSettingsSSLPort = "electrum_ssl_port" diff --git a/ios/WidgetHelper.swift b/ios/WidgetHelper.swift index 7b3fa226791..07401202241 100644 --- a/ios/WidgetHelper.swift +++ b/ios/WidgetHelper.swift @@ -11,7 +11,7 @@ class WidgetHelper { } static func getSharedUserDefaults() -> UserDefaults? { - let suiteName = "group.io.bluewallet.bluewallet" + let suiteName = "group.com.layertwolabs.bluewallet" let defaults = UserDefaults(suiteName: suiteName) if defaults == nil { NSLog("[WidgetHelper] Warning: Could not access shared UserDefaults") diff --git a/ios/WidgetsExtension.entitlements b/ios/WidgetsExtension.entitlements index 8030e490411..4fb4bd70f21 100644 --- a/ios/WidgetsExtension.entitlements +++ b/ios/WidgetsExtension.entitlements @@ -6,7 +6,7 @@ com.apple.security.application-groups - group.io.bluewallet.bluewallet + group.com.layertwolabs.bluewallet com.apple.security.network.client diff --git a/ios/export_options.plist b/ios/export_options.plist index 99d4b96c67f..dddcc50648e 100644 --- a/ios/export_options.plist +++ b/ios/export_options.plist @@ -7,7 +7,7 @@ signingStyle manual teamID - A7W54YZ4WU + 6AXPP357T2 uploadSymbols compileBitcode @@ -18,16 +18,16 @@ export provisioningProfiles - io.bluewallet.bluewallet - match AppStore io.bluewallet.bluewallet - io.bluewallet.bluewallet.watch - match AppStore io.bluewallet.bluewallet.watch - io.bluewallet.bluewallet.watch.extension - match AppStore io.bluewallet.bluewallet.watch.extension - io.bluewallet.bluewallet.Stickers - match AppStore io.bluewallet.bluewallet.Stickers - io.bluewallet.bluewallet.MarketWidget - match AppStore io.bluewallet.bluewallet.MarketWidget + com.layertwolabs.bluewallet + match AppStore com.layertwolabs.bluewallet + com.layertwolabs.bluewallet.watch + match AppStore com.layertwolabs.bluewallet.watch + com.layertwolabs.bluewallet.watch.extension + match AppStore com.layertwolabs.bluewallet.watch.extension + com.layertwolabs.bluewallet.Stickers + match AppStore com.layertwolabs.bluewallet.Stickers + com.layertwolabs.bluewallet.MarketWidget + match AppStore com.layertwolabs.bluewallet.MarketWidget \ No newline at end of file diff --git a/loc/ar.json b/loc/ar.json index ecd4b859161..f864a2bff24 100644 --- a/loc/ar.json +++ b/loc/ar.json @@ -172,11 +172,8 @@ "settings": { "about": "نبذة", "about_awesome": "تم تصميمها باستخدام الأدوات الرائعة التالية", - "about_backup": "احتفظ دائمًا بنسخة احتياطية من مفاتيحك!", - "about_free": "محفظة BlueWallet هي مشروع مجاني ومفتوح المصدر، أنشأه مستخدمو البتكوين.", "about_license": "ترخيص MIT", "about_release_notes": "معلومات الإصدار", - "about_review": "اترك لنا مراجعة", "performance_score": "معدل الأداء: {num}", "run_performance_test": "اختبار الأداء", "about_selftest": "تشغيل اختبار ذاتي", diff --git a/loc/bg_bg.json b/loc/bg_bg.json index db566c11775..aa0943c903c 100644 --- a/loc/bg_bg.json +++ b/loc/bg_bg.json @@ -142,11 +142,8 @@ "settings": { "about": "Повече", "about_awesome": "Създаден с любов", - "about_backup": "Не забравяйте да направите копие от паролата/думите!", - "about_free": "Блу Уолет е безплатен и отворен код проект. Създаден от Биткойн фенове", "about_license": "MIT Лиценз", "about_release_notes": "Промени и Подобрения", - "about_review": "Напишете мнение", "about_selftest": "Направете селф-тест", "about_selftest_ok": "Теста прмина успешно. Портфейла работи отлично.", "about_sm_github": "GitHub", diff --git a/loc/bqi.json b/loc/bqi.json index 32029ab5043..b07f4760316 100644 --- a/loc/bqi.json +++ b/loc/bqi.json @@ -194,10 +194,8 @@ "settings": { "about": "زبار", "about_awesome": "ورکل وابیڌه وا بؽڌرینا", - "about_backup": "همیشه ز کیلیتا خوتۉݩ نوسخه لادرار بگیرین!", "about_license": "پروانه ام آی تی", "about_release_notes": "ویرداشتا انتشار", - "about_review": "سی ایما یه واجۊری بنین", "performance_score": "امتیاز کارکرد: {num}", "run_performance_test": "واجۊری کارکرد", "about_selftest": "ره وندن خوس آزمایی", diff --git a/loc/ca.json b/loc/ca.json index 6f8fbcbcf95..1c905b355e4 100644 --- a/loc/ca.json +++ b/loc/ca.json @@ -149,9 +149,7 @@ }, "settings": { "about": "Sobre nosaltres", - "about_backup": "Feu sempre còpies de seguretat de les vostres claus!", "about_license": "Llicència MIT", - "about_review": "Deixa'ns una ressenya", "about_selftest": "Executa l'autotest", "about_sm_github": "GitHub", "about_sm_telegram": "Canal de Telegram", diff --git a/loc/cs_cz.json b/loc/cs_cz.json index a35ffd451c8..9fa9afd3396 100644 --- a/loc/cs_cz.json +++ b/loc/cs_cz.json @@ -211,11 +211,8 @@ "settings": { "about": "O BlueWallet", "about_awesome": "Sestaveno s úžasnými", - "about_backup": "Vždy zálohujte své klíče!", - "about_free": "BlueWallet je bezplatný a open source projekt. Vytvořeno bitcoinery.", "about_license": "Licence MIT", "about_release_notes": "Poznámky k vydání", - "about_review": "Napište nám recenzi", "performance_score": "Skóre výkonu: {num}", "run_performance_test": "Otestovat výkon", "about_selftest": "Spustit autotest", diff --git a/loc/de_de.json b/loc/de_de.json index f7e2edf6f19..623dc3fe213 100644 --- a/loc/de_de.json +++ b/loc/de_de.json @@ -211,11 +211,8 @@ "settings": { "about": "Über", "about_awesome": "Entwickelt mt dem eindrucksvollen", - "about_backup": "Stets die Backup-Phrase sichern!", - "about_free": "BlueWallet ist kostenlose Open Source Software. Produziert von Bitcoin-Benutzern.", "about_license": "MIT-Lizenz", "about_release_notes": "Versionshinweise", - "about_review": "Bewertung hinterlassen", "performance_score": "Leistungskennzahl: {num}", "run_performance_test": "Leistung testen", "about_selftest": "Selbsttest ausführen", diff --git a/loc/el.json b/loc/el.json index cb8c045f99f..8f23efd891c 100644 --- a/loc/el.json +++ b/loc/el.json @@ -145,7 +145,6 @@ "about": "Σχετικά", "about_license": "Άδεια χρήσης MIT", "about_release_notes": "Σημειώσεις κυκλοφορίας.", - "about_review": "Γράψτε μια κριτική", "performance_score": "Σκορ επιδόσεων: {num}", "run_performance_test": "Δοκιμή επιδόσεων", "about_selftest": "Εκτέλεση διαγνωστικού ελέγχου", diff --git a/loc/en.json b/loc/en.json index 2b67adb6e05..960ac8c7533 100644 --- a/loc/en.json +++ b/loc/en.json @@ -211,16 +211,15 @@ "settings": { "about": "About", "about_awesome": "Built with the awesome", - "about_backup": "Always backup your keys!", - "about_free": "BlueWallet is a free and open-source project. Crafted by Bitcoin users.", "about_license": "MIT License", "about_release_notes": "Release notes", - "about_review": "Leave us a review", "performance_score": "Performance score: {num}", "run_performance_test": "Test performance", "about_selftest": "Run self-test", "block_explorer_invalid_custom_url": "The URL provided is invalid. Please enter a valid URL starting with http:// or https://.", "about_selftest_electrum_disabled": "Self-testing is not available with Electrum Offline Mode. Please disable offline mode and try again.", + "network_select": "Select Network", + "network_restart": "Please restart the app for the network change to take full effect.", "about_selftest_ok": "All internal tests have passed successfully. The wallet works well.", "about_sm_github": "GitHub", "about_sm_telegram": "Telegram channel", @@ -683,7 +682,7 @@ "notification_tx_unconfirmed": "Notification transaction is not confirmed yet, please wait", "failed_create_notif_tx": "Failed to create on-chain transaction", "onchain_tx_needed": "On-chain transaction needed", - "notif_tx_sent" : "Notification transaction sent. Please wait for it to confirm", + "notif_tx_sent": "Notification transaction sent. Please wait for it to confirm", "notif_tx": "Notification transaction", "not_found": "Payment code not found" } diff --git a/loc/es.json b/loc/es.json index 33ef16ceae2..6eed1b8060e 100644 --- a/loc/es.json +++ b/loc/es.json @@ -165,11 +165,8 @@ "settings": { "about": "Sobre nosotros", "about_awesome": "Built with the awesome", - "about_backup": "¡Guarda siempre una copia de seguridad de tus llaves!", - "about_free": "BlueWallet es un proyecto de código abierto y gratuito. Elaborado por usuarios de Bitcoin.", "about_license": "Licencia MIT", "about_release_notes": "Notas de la versión", - "about_review": "Escribe una reseña", "about_selftest": "Iniciar test local", "about_selftest_electrum_disabled": "La autocomprobación no está disponible en el modo sin conexión de Electrum. Desactiva el modo sin conexión y vuelve a intentarlo. ", "about_selftest_ok": "Todas las pruebas internas han concluido satisfactoriamente. La billetera funciona bien. ", diff --git a/loc/es_419.json b/loc/es_419.json index b9a354fe96c..64ea8357b71 100644 --- a/loc/es_419.json +++ b/loc/es_419.json @@ -211,11 +211,8 @@ "settings": { "about": "Acerca de", "about_awesome": "Construido con el impresionante", - "about_backup": "¡Siempre haz una copia de tus claves!", - "about_free": "BlueWallet es un proyecto libre y de código abierto. Elaborado por usuarios de Bitcoin.", "about_license": "Licencia MIT", "about_release_notes": "Notas de lanzamiento", - "about_review": "Déjanos un comentario", "performance_score": "Puntuación de rendimiento: {num}", "run_performance_test": "Prueba de rendimiento", "about_selftest": "Ejecutar auto-prueba", diff --git a/loc/fa.json b/loc/fa.json index 40b8413a58a..e38d497ed1d 100644 --- a/loc/fa.json +++ b/loc/fa.json @@ -172,11 +172,8 @@ "settings": { "about": "درباره", "about_awesome": "ساخته‌شده با بهترین‌ها", - "about_backup": "همیشه از کلیدهای خود نسخهٔ پشتیبان تهیه کنید!", - "about_free": "برنامهٔ BlueWallet پروژه‌ای رایگان و متن‌باز است. ساخته‌شده توسط کاربران بیت‌کوین.", "about_license": "پروانهٔ ام‌آی‌تی", "about_release_notes": "یادداشت‌های انتشار", - "about_review": "برای ما یک بررسی بگذارید", "performance_score": "امتیاز کارکرد: {num}", "run_performance_test": "بررسی کارکرد", "about_selftest": "اجرای خودآزمایی", diff --git a/loc/fi_fi.json b/loc/fi_fi.json index 1a80362a524..2c8671453ac 100644 --- a/loc/fi_fi.json +++ b/loc/fi_fi.json @@ -208,11 +208,8 @@ "settings": { "about": "Tietoa", "about_awesome": "Loistavasti rakennettu", - "about_backup": "Varmuuskopioi aina avaimesi!", - "about_free": "BlueWallet on ilmainen ja avoimen lähdekoodin projekti. Bitcoin käyttäjien tekemä.", "about_license": "MIT-lisenssi", "about_release_notes": "Julkaisutiedot", - "about_review": "Jätä meille arvostelu", "performance_score": "Suorituskykypisteet: {num}", "run_performance_test": "Testin suorituskyky", "about_selftest": "Suorita itsetestaus", diff --git a/loc/fr_fr.json b/loc/fr_fr.json index 25d2e44c7bd..fd55fd85e1c 100644 --- a/loc/fr_fr.json +++ b/loc/fr_fr.json @@ -208,11 +208,8 @@ "settings": { "about": "À propos", "about_awesome": "Créé avec les incroyables", - "about_backup": "Sauvegardez toujours vos clés !", - "about_free": "BlueWallet est un projet gratuit et ouvert. Réalisé par des utilisateurs de Bitcoin.", "about_license": "License MIT", "about_release_notes": "Notes de version", - "about_review": "Laissez-nous votre avis", "performance_score": "Score performance: {num}", "run_performance_test": "Test performance", "about_selftest": "Effectuer un auto-test", diff --git a/loc/he.json b/loc/he.json index e19d47de39d..91cdbf20b23 100644 --- a/loc/he.json +++ b/loc/he.json @@ -207,11 +207,8 @@ "settings": { "about": "אודות", "about_awesome": "נבנה בעזרת", - "about_backup": "גבו תמיד את המפתחות שלכם!", - "about_free": "פרויקט BlueWallet הינו פרויקט חופשי בקוד פתוח. נוצר על ידי קהילת ביטקוין.", "about_license": "רישיון MIT", "about_release_notes": "הערות שחרור", - "about_review": "השאירו לנו ביקורת", "performance_score": "ניקוד ביצועים: {num}", "run_performance_test": "בדיקת ביצועים", "about_selftest": "הרצת בדיקה עצמית", diff --git a/loc/hu_hu.json b/loc/hu_hu.json index b2121ab1f5a..3c60be87a07 100644 --- a/loc/hu_hu.json +++ b/loc/hu_hu.json @@ -167,11 +167,8 @@ "settings": { "about": "Egyéb", "about_awesome": "Nagyszerűséggel fejlesztve", - "about_backup": "Mindig készíts biztonsági másolatot a jelszó sorozatodról. ", - "about_free": "A BlueWallet alkalmazás ingyenes és nyílt forráskódú. Bitcoin használók fejleszteték. ", "about_license": "MIT Licensz", "about_release_notes": "Verzió megjegyzések", - "about_review": "Írj értékelést", "about_selftest": "Önellenőrző teszt indítása", "about_selftest_electrum_disabled": "Az öntesztelés nem elérhető az Electrum Offline móddal. Kérjük, kapcsolja ki az offline módot, és próbálkozzon újra.", "about_selftest_ok": "Minden belső teszt sikeres. A tárca megfelelően működik.", diff --git a/loc/id_id.json b/loc/id_id.json index e46339d992e..a032a23c494 100644 --- a/loc/id_id.json +++ b/loc/id_id.json @@ -184,11 +184,8 @@ "settings": { "about": "Tentang", "about_awesome": "Dibuat dengan mengagumkan", - "about_backup": "Selalu buat cadangan kunci Anda!", - "about_free": "BlueWallet adalah proyek terbuka dan gratis. Dibuat oleh pengguna Bitcoin.", "about_license": "Izin MIT", "about_release_notes": "Catatan rilisan", - "about_review": "Tinggalkan ulasan", "performance_score": "Skor hasil: {num}", "run_performance_test": "Uji hasil", "about_selftest": "Jalankan tes sendiri", diff --git a/loc/it.json b/loc/it.json index 5a606fe2fb1..d43cf915182 100644 --- a/loc/it.json +++ b/loc/it.json @@ -184,11 +184,8 @@ "settings": { "about": "Informazioni", "about_awesome": "Costruito con il fantastico", - "about_backup": "Fai sempre il backup delle tue chiavi!", - "about_free": "BlueWallet è un progetto libero ed open-source. Realizzato da utenti Bitcoin.", "about_license": "Licenza MIT", "about_release_notes": "Note di rilascio", - "about_review": "Lasciaci una recensione", "performance_score": "Punteggio prestazioni: {num}", "run_performance_test": "Testa le prestazioni", "about_selftest": "Esegui auto-test", diff --git a/loc/jp_jp.json b/loc/jp_jp.json index 1b614eb1d9e..b40435715ad 100644 --- a/loc/jp_jp.json +++ b/loc/jp_jp.json @@ -211,11 +211,8 @@ "settings": { "about": "BlueWallet について", "about_awesome": "Built with the awesome", - "about_backup": "常に秘密鍵はバックアップしましょう!", - "about_free": "BlueWalletはフリーでオープンソースのプロジェクトです。ビットコインユーザーによって作られています。", "about_license": "MIT ライセンス", "about_release_notes": "リリースノート", - "about_review": "レビューを書く", "performance_score": "パフォーマンススコア:{num}", "run_performance_test": "パフォーマンステスト", "about_selftest": "セルフテストを実行", diff --git a/loc/ko_KR.json b/loc/ko_KR.json index 263ad8fb6b6..443f0dde713 100644 --- a/loc/ko_KR.json +++ b/loc/ko_KR.json @@ -211,11 +211,8 @@ "settings": { "about": "더 알아보기", "about_awesome": "제대로 만든", - "about_backup": "항상 키를 백업하세요!", - "about_free": "BlueWallet은 비트코인 이용자들이 만든 오픈 소스 프로젝트입니다. ", "about_license": "MIT 라이선스", "about_release_notes": "릴리즈 노트", - "about_review": "리뷰를 남겨주세요.", "performance_score": "성능 점수: {num}", "run_performance_test": "성능 테스트", "about_selftest": "자가 테스트", diff --git a/loc/ms.json b/loc/ms.json index dbd9f94bbae..54c17c862ac 100644 --- a/loc/ms.json +++ b/loc/ms.json @@ -150,11 +150,8 @@ "settings": { "about": "Tentang Kami", "about_awesome": "Dibina dengan yang gempak", - "about_backup": "Sandarkanlah anak kunci anda selalu!", - "about_free": "BlueWallet ialah satu projek sumber terbuka dan percuma. Hasil seni pengguna Bitcoin.", "about_license": "Lesen MIT", "about_release_notes": "Nota pelepasan", - "about_review": "Berikan kami ulasan anda", "about_selftest": "Jalankan swaujian", "about_selftest_electrum_disabled": "Swaujian tidak hadir dengan Mod Luar Talian Electrum. Sila matikan mod luar talian dan cuba lagi.", "about_selftest_ok": "Semua ujian dalaman berjaya. Dompet ini berfungsi dengan baik.", diff --git a/loc/nb_no.json b/loc/nb_no.json index 9d701a344a4..d4ad0cc7950 100644 --- a/loc/nb_no.json +++ b/loc/nb_no.json @@ -161,11 +161,8 @@ "settings": { "about": "Om", "about_awesome": "Bygget med det fantastiske", - "about_backup": "Sikkerhetskopier alltid nøklene dine!", - "about_free": "BlueWallet er et gratis og åpent kildekode-prosjekt. Laget av Bitcoin-brukere.", "about_license": "MIT License", "about_release_notes": "Versjonsmerknader", - "about_review": "Gi oss en anmeldelse", "about_selftest": "Kjør selvtest", "about_selftest_electrum_disabled": "Selvtesting er ikke tilgjengelig med Electrum Offline Mode. Deaktiver offline-modus og prøv igjen.", "about_selftest_ok": "Alle interne tester har bestått. Lommeboken fungerer bra.", diff --git a/loc/ne.json b/loc/ne.json index ebf54c63d1e..5fbb48379a9 100644 --- a/loc/ne.json +++ b/loc/ne.json @@ -163,10 +163,7 @@ }, "settings": { "about": "बारेमा", - "about_backup": "सधैं आफ्नो सांचो सेव गर्नुहोस !", - "about_free": "BlueWallet एक बिटकोइन प्रयोगकर्ताहरू द्वारा बनाईएको नि:शुल्क र खुला स्रोत परियोजना हो।", "about_release_notes": "नोटहरू जारी गर्नुहोस्", - "about_review": "हामीलाई एक विश्लेषण छोड्नुहोस्", "performance_score": "प्रदर्शन स्कोर: {num}", "run_performance_test": "परीक्षा प्रदर्शन", "about_selftest": "आत्म परीक्षण गर्नुहोस्", diff --git a/loc/nl_nl.json b/loc/nl_nl.json index d4a88efd40b..55cf415d5aa 100644 --- a/loc/nl_nl.json +++ b/loc/nl_nl.json @@ -166,11 +166,8 @@ "settings": { "about": "Over", "about_awesome": "Gebouwt met de geweldige", - "about_backup": "Maak altijd een backup van uw sleutels!", - "about_free": "BlueWallet is een gratis en open-source project. Gemaakt door Bitcoin gebruikers.", "about_license": "MIT Licentie", "about_release_notes": "Release-opmerkingen", - "about_review": "Laat een review achter", "about_selftest": "Voer een zelftest uit", "about_selftest_electrum_disabled": "Het zelf testen is niet beschikbaar met Electrum offline modus. Zet alsjeblieft de offline modus uit en probeer het opnieuw.", "about_selftest_ok": "Alle interne tests zijn geslaagd. De wallet werkt.", diff --git a/loc/pl.json b/loc/pl.json index 47312c11d02..dce585a4700 100644 --- a/loc/pl.json +++ b/loc/pl.json @@ -211,11 +211,8 @@ "settings": { "about": "O programie", "about_awesome": "Zbudowano przy użyciu niesamowitych:", - "about_backup": "Zawsze rób kopie zapasowe swoich kluczy!", - "about_free": "BlueWallet jest projektem open source. Stworzonym przez i dla użytkowników Bitcoina.", "about_license": "Licencja MIT", "about_release_notes": "Informacje o wydaniu", - "about_review": "Wystaw nam opinię", "performance_score": "Wynik wydajności: {num}", "run_performance_test": "Test wydajności", "about_selftest": "Wykonaj autotest", diff --git a/loc/pt_br.json b/loc/pt_br.json index bc352b55581..f413dd585e0 100644 --- a/loc/pt_br.json +++ b/loc/pt_br.json @@ -203,11 +203,8 @@ "settings": { "about": "Sobre", "about_awesome": "Construída com os incríveis", - "about_backup": "Sempre faça backup de suas chaves!", - "about_free": "BlueWallet é um projeto de código aberto e gratuito. Criado por usuários de Bitcoin.", "about_license": "Licença MIT", "about_release_notes": "Notas de versão", - "about_review": "Avalie a gente", "performance_score": "Pontuação de performance: {num}", "run_performance_test": "Teste de performance", "about_selftest": "Executar autoteste", diff --git a/loc/pt_pt.json b/loc/pt_pt.json index 94ed87473c3..62c372c4c88 100644 --- a/loc/pt_pt.json +++ b/loc/pt_pt.json @@ -211,8 +211,6 @@ "settings": { "about": "Sobre", "about_awesome": "Construído com o incríveis", - "about_backup": "Faça sempre backup das suas chaves!", - "about_free": "BlueWallet é um projeto gratuito e de código aberto. Criado por utilizadores de Bitcoin.", "about_license": "Licença MIT", "about_release_notes": "Release notes", "about_review": "Deixa-nos uma review", diff --git a/loc/ro.json b/loc/ro.json index 396c1a732b9..b914fa0378a 100644 --- a/loc/ro.json +++ b/loc/ro.json @@ -154,11 +154,8 @@ "settings": { "about": "Despre", "about_awesome": "Construit cu minunatul", - "about_backup": "Întotdeauna salvează cheile de rezervă", - "about_free": "BlueWallet este un proiect gratuit și open source. Făurit de utilizatori Bitcoin.", "about_license": "Licență MIT", "about_release_notes": "Note de lansare", - "about_review": "Lasă o recenzie", "about_selftest": "Rulează auto-test", "about_selftest_ok": "Toate testele interne au trecut cu succes. Portofelul funcționează bine.", "about_sm_github": "GitHub", diff --git a/loc/ru.json b/loc/ru.json index f54b4089a27..346ceb15d2f 100644 --- a/loc/ru.json +++ b/loc/ru.json @@ -211,11 +211,8 @@ "settings": { "about": "О программе", "about_awesome": "Основано на офигенных", - "about_backup": "Всегда делайте резервные копии ваших ключей!", - "about_free": "BlueWallet — бесплатный проект с открытым исходным кодом. Создано Биткойн пользователями.", "about_license": "Лицензия MIT", "about_release_notes": "История изменений", - "about_review": "Оставьте отзыв о нас", "performance_score": "Оценка производительности: {num}", "run_performance_test": "Тест производительности", "about_selftest": "Запустить самодиагностику", diff --git a/loc/si_LK.json b/loc/si_LK.json index d34d5539b02..3b99ff09718 100644 --- a/loc/si_LK.json +++ b/loc/si_LK.json @@ -158,11 +158,8 @@ "settings": { "about": "පිළිබඳව", "about_awesome": "නියම ආකාරයෙන් ඉදි කර ඇත", - "about_backup": "ඔබේ යතුරු සැමවිටම උපස්ථ කරන්න!", - "about_free": "බ්ලූවොලට් යනු නිදහස් හා විවෘත මූලාශ්‍ර ව්‍යාපෘතියකි. බිට්කොයින් භාවිත කරන්නන් විසින් සකස් කරන ලදි.", "about_license": "එම්.අයි.ටී බලපත්‍රය", "about_release_notes": "මුදා හැරීමේ සටහන්", - "about_review": "අපට සමාලෝචනයක් තබන්න", "about_selftest": "ස්වයං පරීක්‍ෂණයක් කරන්න", "about_selftest_electrum_disabled": "ඉලෙක්ට්‍රෝම් නොබැඳි මාදිලිය සමඟ ස්වයං පරීක්‍ෂා කිරීම නොමැත. කරුණාකර නොබැඳි ප්‍රකාරය අක්‍රිය කර නැවත උත්සාහ කරන්න.", "about_selftest_ok": "සියලුම අභ්‍යන්තර පරීක්‍ෂණ සාර්ථකව සමත් වී ඇත. පසුම්බිය හොඳින් ක්‍රියා කරයි.", diff --git a/loc/sk_sk.json b/loc/sk_sk.json index a73a91b6103..1ce38b32e05 100644 --- a/loc/sk_sk.json +++ b/loc/sk_sk.json @@ -110,9 +110,6 @@ }, "settings": { "about": "O BlueWallet", - "about_backup": "Vždy si zálohujte kľúče!", - "about_free": "BlueWallet je projekt, ktorý je zdarma a s otvorenými zdrojovými kódmi. Vytvorený používateľmi Bitcoinu.", - "about_review": "Napíšte nám recenziu", "about_sm_github": "GitHub", "about_sm_telegram": "Telegram chat", "currency": "Mena", diff --git a/loc/sl_SI.json b/loc/sl_SI.json index fe132f01202..689bf3ff6e1 100644 --- a/loc/sl_SI.json +++ b/loc/sl_SI.json @@ -165,11 +165,8 @@ "settings": { "about": "O aplikaciji", "about_awesome": "Zgrajeno z izjemnimi", - "about_backup": "Vedno naredite varnostno kopijo vaših ključev!", - "about_free": "BlueWallet je brezplačen in odprtokodni projekt. Ustvarili uporabniki Bitcoina.", "about_license": "Licenca MIT", "about_release_notes": "Opombe ob izdaji", - "about_review": "Ocenite, napišite mnenje", "about_selftest": "Zaženi samotestiranje", "about_selftest_electrum_disabled": "Samotestiranje ni na voljo v Electrum načinu brez povezave. Onemogočite način brez povezave in poskusite ponovno.", "about_selftest_ok": "Vsi opravljeni testi so bili uspešni. Denarnica deluje brez napak.", diff --git a/loc/sq_AL.json b/loc/sq_AL.json index 1956940a1d8..710ca1598a5 100644 --- a/loc/sq_AL.json +++ b/loc/sq_AL.json @@ -176,7 +176,6 @@ "settings": { "about": "Rreth", "about_license": "Licenca e tipit MIT", - "about_review": "Na leni një review", "about_sm_github": "GitHub", "about_sm_telegram": "Knali Telegram", "biometrics": "Te dhenat Biometrike", diff --git a/loc/sv_se.json b/loc/sv_se.json index 306bfd55bbd..eeaecd4b624 100644 --- a/loc/sv_se.json +++ b/loc/sv_se.json @@ -169,11 +169,8 @@ "settings": { "about": "Om", "about_awesome": "Byggd med det fantastiska", - "about_backup": "Backa alltid upp dina nycklar!", - "about_free": "BlueWallet är gratis och byggs av bitcoin-användare med hjälp av öppen källkod.", "about_license": "MIT-licens", "about_release_notes": "Versionsinformation", - "about_review": "Lämna oss en recension", "performance_score": "Prestandapoäng: {num}", "run_performance_test": "Testa prestanda", "about_selftest": "Kör självtest", diff --git a/loc/th_th.json b/loc/th_th.json index cd03205abbf..a1bdcb3d89b 100644 --- a/loc/th_th.json +++ b/loc/th_th.json @@ -134,10 +134,7 @@ }, "settings": { "about": "เกี่ยวกับ", - "about_backup": "ท่านควรบันทึกคีย์ของท่านเสมอ", - "about_free": "BlueWallet คือโปรเจ็คโอเพนซอร์ส ไม่มีการคิดค่าใช้จ่าย สร้างโดยผู้ใช้บิตคอยน์", "about_release_notes": "บันทึกของโปรแกรมนี้", - "about_review": "กรุณาแสดงความเห็น", "about_selftest": "ทำการทดสอบ", "about_sm_github": "กิตฮับ", "about_sm_telegram": "เทเลแกรมแช็ท", diff --git a/loc/ua.json b/loc/ua.json index 5ad069bd380..f8a540c5206 100644 --- a/loc/ua.json +++ b/loc/ua.json @@ -151,11 +151,8 @@ }, "settings": { "about": "Про програму", - "about_backup": "Завжди створюйте резервні копії ключів!", - "about_free": "BlueWallet — це безкоштовний проект з відкритим кодом. Створено користувачами Bitcoin.", "about_license": "MIT Ліцензія", "about_release_notes": "Інформація про реліз", - "about_review": "Залиште нам відгук", "about_selftest": "Запустити самоперевірку", "about_sm_github": "GitHub", "about_sm_telegram": "Telegram канал", diff --git a/loc/vi_vn.json b/loc/vi_vn.json index 8dd8724bb12..7f1cbad4541 100644 --- a/loc/vi_vn.json +++ b/loc/vi_vn.json @@ -164,11 +164,8 @@ "settings": { "about": "Giới thiệu", "about_awesome": "được xây dựng với những điều tuyệt vời này", - "about_backup": "Luôn sao lưu các khóa của bạn!", - "about_free": "BlueWallet là dự án nguồn mở và tự do được tạo ra bởi người dùng Bitcoin.", "about_license": "Giấy phép MIT", "about_release_notes": "Ghi chú phát hành", - "about_review": "Để lại đánh giá", "performance_score": "Điểm hiệu suất: {num}", "run_performance_test": "Kiểm tra hiệu suất", "about_selftest": "Chạy tự kiểm tra", diff --git a/loc/zh_cn.json b/loc/zh_cn.json index d2cd1bfd304..384b15cb87b 100644 --- a/loc/zh_cn.json +++ b/loc/zh_cn.json @@ -211,11 +211,8 @@ "settings": { "about": "关于", "about_awesome": "由出色的技术打造", - "about_backup": "请务必备份您的密钥!", - "about_free": "BlueWallet 是一个自由且开源的项目,由比特币用户打造。", "about_license": "麻省理工学院许可证", "about_release_notes": "更新日志", - "about_review": "给我们写个评价", "performance_score": "性能评分:{num}", "run_performance_test": "测试性能", "about_selftest": "运行自检", diff --git a/loc/zh_tw.json b/loc/zh_tw.json index 87ee7cb1964..fee4d528d59 100644 --- a/loc/zh_tw.json +++ b/loc/zh_tw.json @@ -144,11 +144,8 @@ "settings": { "about": "關於", "about_awesome": "從很棒的創立", - "about_backup": "經常備份您的密鑰!", - "about_free": "BlueWallet是一個免費的開源項目,由比特幣用戶製作。", "about_license": "麻省理工學院許可證", "about_release_notes": "發佈說明", - "about_review": "給我們評論", "about_selftest": "運行自我檢查", "about_selftest_ok": "所有內部測試均已成功通過,錢包運作良好。", "about_sm_github": "GitHub", diff --git a/models/blockExplorer.ts b/models/blockExplorer.ts index 7f2189c884f..b1a2671ec6c 100644 --- a/models/blockExplorer.ts +++ b/models/blockExplorer.ts @@ -1,5 +1,6 @@ // blockExplorer.ts import DefaultPreference from 'react-native-default-preference'; +import { NetworkType } from './network'; export interface BlockExplorer { key: string; @@ -8,9 +9,7 @@ export interface BlockExplorer { } export const BLOCK_EXPLORERS: { [key: string]: BlockExplorer } = { - default: { key: 'default', name: 'Mempool.space', url: 'https://mempool.space' }, - blockchair: { key: 'blockchair', name: 'Blockchair', url: 'https://blockchair.com/bitcoin' }, - blockstream: { key: 'blockstream', name: 'Blockstream.info', url: 'https://blockstream.info' }, + default: { key: 'default', name: 'Drivechain Explorer', url: 'https://explorer.forknet.drivechain.info' }, custom: { key: 'custom', name: 'Custom', url: '' }, // Custom URL will be handled separately }; @@ -46,6 +45,31 @@ export const getDomain = (url: string): string => { } }; +/** + * Adjusts a block explorer URL for the given network. + * e.g. mempool.space -> mempool.space/testnet4, blockstream.info -> blockstream.info/testnet + */ +export const adjustBlockExplorerUrlForNetwork = (url: string, network: NetworkType): string => { + if (network === 'mainnet') return url; + + const normalized = normalizeUrl(url); + const networkPath = network === 'testnet' ? 'testnet4' : 'signet'; + + const domain = getDomain(normalized); + + if (domain === 'mempool.space') { + return `${normalized}/${networkPath}`; + } + if (domain === 'blockstream.info') { + return `${normalized}/${network === 'testnet' ? 'testnet' : 'signet'}`; + } + if (domain === 'blockchair.com') { + return `${normalized.replace('/bitcoin', '')}/${network === 'testnet' ? 'bitcoin/testnet' : 'bitcoin/signet'}`; + } + + return normalized; +}; + const BLOCK_EXPLORER_STORAGE_KEY = 'blockExplorer'; export const saveBlockExplorer = async (url: string): Promise => { diff --git a/models/network.ts b/models/network.ts new file mode 100644 index 00000000000..2e704807c87 --- /dev/null +++ b/models/network.ts @@ -0,0 +1,33 @@ +import * as bitcoin from 'bitcoinjs-lib'; + +export type NetworkType = 'mainnet' | 'testnet' | 'signet'; + +let _networkType: NetworkType = 'mainnet'; + +/** + * Sets the current network type. This should be called early during app initialization, + * before any wallet operations. Changing the network at runtime takes effect for new + * Electrum connections, but existing wallets in memory retain stale state — the user + * should restart the app after switching. + */ +export function setNetworkType(network: NetworkType): void { + _networkType = network; +} + +/** + * Returns the bitcoinjs-lib network object for the current network. + * Testnet and signet both use bitcoin.networks.testnet (same address format, derivation paths). + */ +export function getNetwork(): bitcoin.Network { + if (_networkType === 'testnet' || _networkType === 'signet') { + return bitcoin.networks.testnet; + } + return bitcoin.networks.bitcoin; +} + +/** + * Returns true if the current network is not mainnet. + */ +export function isTestnet(): boolean { + return _networkType !== 'mainnet'; +} diff --git a/package.json b/package.json index f83f7f7c0b8..43c33b72026 100644 --- a/package.json +++ b/package.json @@ -65,11 +65,11 @@ "branch2json": "./scripts/current-branch.sh > current-branch.json", "start": "react-native start", "android": "react-native run-android", - "android:relaunch": "adb shell am force-stop io.bluewallet.bluewallet; adb shell monkey -p io.bluewallet.bluewallet -c android.intent.category.LAUNCHER 1", - "android:uninstall": "adb uninstall io.bluewallet.bluewallet", + "android:relaunch": "adb shell am force-stop com.layertwolabs.bluewallet; adb shell monkey -p com.layertwolabs.bluewallet -c android.intent.category.LAUNCHER 1", + "android:uninstall": "adb uninstall com.layertwolabs.bluewallet", "adb": "adb reverse tcp:8081 tcp:8081", "android:clean": "cd android; ./gradlew clean ; cd .. ; rm -r -f android/app/.cxx; npm run android", - "android:restart": "adb shell am force-stop io.bluewallet.bluewallet; adb shell monkey -p io.bluewallet.bluewallet -c android.intent.category.LAUNCHER 1", + "android:restart": "adb shell am force-stop com.layertwolabs.bluewallet; adb shell monkey -p com.layertwolabs.bluewallet -c android.intent.category.LAUNCHER 1", "ios": "react-native run-ios", "postinstall": "rm -r -f node_modules/react-native-camera-kit-no-google/android/build; npm run releasenotes2json; npm run branch2json; npm run patches", "patches": "npx patch-package", diff --git a/screen/send/Broadcast.tsx b/screen/send/Broadcast.tsx index 61e8a7deceb..d3dc7b54ec9 100644 --- a/screen/send/Broadcast.tsx +++ b/screen/send/Broadcast.tsx @@ -11,6 +11,7 @@ import { useTheme } from '../../components/themes'; import { platformSizing, platformLayout, getSettingsRowBackgroundColor, SettingsScrollView } from '../../components/platform'; import loc from '../../loc'; import { useSettings } from '../../hooks/context/useSettings'; +import { adjustBlockExplorerUrlForNetwork } from '../../models/blockExplorer'; import { majorTomToGroundControl } from '../../blue_modules/notifications'; import { scanQrHelper } from '../../helpers/scan-qr'; import { BlueSpacing10, BlueSpacing20 } from '../../components/BlueSpacing'; @@ -30,7 +31,8 @@ const Broadcast: React.FC = () => { const sizing = platformSizing; const layout = platformLayout; const [broadcastResult, setBroadcastResult] = useState(BROADCAST_RESULT.none); - const { selectedBlockExplorer } = useSettings(); + const { selectedBlockExplorer, networkType } = useSettings(); + const blockExplorerUrl = adjustBlockExplorerUrlForNetwork(selectedBlockExplorer.url, networkType); const rowBackgroundColor = getSettingsRowBackgroundColor(colors, dark); const styles = StyleSheet.create({ @@ -191,7 +193,7 @@ const Broadcast: React.FC = () => { )} - {BROADCAST_RESULT.success === broadcastResult && tx && } + {BROADCAST_RESULT.success === broadcastResult && tx && } ); diff --git a/screen/send/Confirm.tsx b/screen/send/Confirm.tsx index 04e8e8351d8..0341c007222 100644 --- a/screen/send/Confirm.tsx +++ b/screen/send/Confirm.tsx @@ -26,6 +26,7 @@ import { HDSegwitBech32Wallet } from '../../class'; import { useSettings } from '../../hooks/context/useSettings'; import { majorTomToGroundControl } from '../../blue_modules/notifications'; import { uint8ArrayToHex } from '../../blue_modules/uint8array-extras'; +import { getNetwork } from '../../models/network'; enum ActionType { SET_LOADING = 'SET_LOADING', @@ -170,7 +171,8 @@ const Confirm: React.FC = () => { if (!(recipients.length > 0) || !recipients[0].address) { return undefined; } - return bitcoin.address.toOutputScript(recipients[0].address, bitcoin.networks.bitcoin); + const addr = recipients[0].address; + return bitcoin.address.toOutputScript(addr, getNetwork()); }; const handleSendTransaction = async () => { diff --git a/screen/send/success.tsx b/screen/send/success.tsx index 63891922ffd..0036d364cdd 100644 --- a/screen/send/success.tsx +++ b/screen/send/success.tsx @@ -12,6 +12,7 @@ import { BitcoinUnit } from '../../models/bitcoinUnits'; import HandOffComponent from '../../components/HandOffComponent'; import { HandOffActivityType } from '../../components/types'; import { useSettings } from '../../hooks/context/useSettings'; +import { adjustBlockExplorerUrlForNetwork } from '../../models/blockExplorer'; import { SendDetailsStackParamList } from '../../navigation/SendDetailsStackParamList.ts'; import { popToTop } from '../../NavigationService.ts'; @@ -19,7 +20,8 @@ type RouteProps = RouteProp; const Success = () => { const { colors } = useTheme(); - const { selectedBlockExplorer } = useSettings(); + const { selectedBlockExplorer, networkType } = useSettings(); + const blockExplorerUrl = adjustBlockExplorerUrlForNetwork(selectedBlockExplorer.url, networkType); const route = useRoute(); const { amount, fee, amountUnit = BitcoinUnit.BTC, invoiceDescription = '', txid } = route.params || {}; const stylesHook = StyleSheet.create({ @@ -53,7 +55,7 @@ const Success = () => { )} diff --git a/screen/settings/About.tsx b/screen/settings/About.tsx index 92b4c21ea56..1894f893828 100644 --- a/screen/settings/About.tsx +++ b/screen/settings/About.tsx @@ -1,7 +1,7 @@ import Clipboard from '@react-native-clipboard/clipboard'; -import React, { useCallback } from 'react'; -import { Alert, Image, Linking, Platform, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; -import { getApplicationName, getBuildNumber, getBundleId, getUniqueIdSync, getVersion, hasGmsSync } from 'react-native-device-info'; +import React, { useCallback, useState } from 'react'; +import { ActionSheetIOS, Alert, Image, Linking, Platform, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; +import { getApplicationName, getBuildNumber, getBundleId, getUniqueIdSync, getVersion } from 'react-native-device-info'; import Icon from '@react-native-vector-icons/fontawesome6'; import A from '../../blue_modules/analytics'; @@ -9,7 +9,6 @@ import { BlueTextCentered } from '../../BlueComponents'; import { HDSegwitBech32Wallet } from '../../class'; import presentAlert from '../../components/Alert'; import { BlueSpacing20 } from '../../components/BlueSpacing'; -import Button from '../../components/Button'; import { SettingsCard, SettingsFlatList, @@ -20,8 +19,9 @@ import { } from '../../components/platform'; import { useTheme } from '../../components/themes'; import { useSettings } from '../../hooks/context/useSettings'; +import { NetworkType } from '../../models/network'; import { useExtendedNavigation } from '../../hooks/useExtendedNavigation'; -import loc, { formatStringAddTwoWhiteSpaces } from '../../loc'; +import loc from '../../loc'; const branch = require('../../current-branch.json'); @@ -33,8 +33,9 @@ interface AboutItem extends SettingsListItemProps { const About: React.FC = () => { const { navigate } = useExtendedNavigation(); - const { isElectrumDisabled } = useSettings(); + const { isElectrumDisabled, networkType, setNetworkTypeStorage } = useSettings(); const { colors } = useTheme(); + const [, setLogoTapCount] = useState(0); const handleOnReleaseNotesPress = useCallback(() => { navigate('ReleaseNotes'); @@ -52,29 +53,59 @@ const About: React.FC = () => { navigate('Licensing'); }, [navigate]); - const handleOnXPress = useCallback(() => { - Linking.openURL('https://x.com/bluewalletio'); - }, []); - const handleOnTelegramPress = useCallback(() => { - Linking.openURL('https://t.me/bluewallethat'); + Linking.openURL('http://www.t.me/DcInsiders'); }, []); const handleOnGithubPress = useCallback(() => { - Linking.openURL('https://github.com/BlueWallet/BlueWallet'); + Linking.openURL('https://github.com/layerTwo-Labs/bluewallet'); }, []); - const handleOnRatePress = useCallback(async () => { - try { - if (Platform.OS === 'ios') { - await Linking.openURL('https://itunes.apple.com/app/bluewallet-bitcoin-wallet/id1376878040'); - } else { - await Linking.openURL('https://play.google.com/store/apps/details?id=io.bluewallet.bluewallet'); + const handleLogoPress = useCallback(() => { + setLogoTapCount(prev => { + const next = prev + 1; + if (next >= 10) { + const networks: { label: string; value: NetworkType }[] = [ + { label: `Mainnet${networkType === 'mainnet' ? ' (current)' : ''}`, value: 'mainnet' }, + { label: `Testnet${networkType === 'testnet' ? ' (current)' : ''}`, value: 'testnet' }, + { label: `Signet${networkType === 'signet' ? ' (current)' : ''}`, value: 'signet' }, + ]; + + if (Platform.OS === 'ios') { + ActionSheetIOS.showActionSheetWithOptions( + { + title: loc.settings.network_select, + options: [...networks.map(n => n.label), loc._.cancel], + cancelButtonIndex: networks.length, + }, + buttonIndex => { + if (buttonIndex < networks.length && networks[buttonIndex].value !== networkType) { + setNetworkTypeStorage(networks[buttonIndex].value).then(() => { + Alert.alert(loc.settings.network_select, loc.settings.network_restart); + }); + } + }, + ); + } else { + Alert.alert(loc.settings.network_select, undefined, [ + ...networks.map(n => ({ + text: n.label, + onPress: () => { + if (n.value !== networkType) { + setNetworkTypeStorage(n.value).then(() => { + Alert.alert(loc.settings.network_select, loc.settings.network_restart); + }); + } + }, + })), + { text: loc._.cancel, style: 'cancel' as const }, + ]); + } + return 0; } - } catch (error: any) { - console.error('Rate app failed:', error.message); - } - }, []); + return next; + }); + }, [networkType, setNetworkTypeStorage]); const handlePerformanceTest = useCallback(async () => { const secret = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'; @@ -102,29 +133,18 @@ const About: React.FC = () => { - - {loc.settings.about_free} - - {formatStringAddTwoWhiteSpaces(loc.settings.about_backup)} + + + + + RedWallet is a Drivechain-enabled fork of BlueWallet. Credits to the BlueWallet team for making a great wallet. - {((Platform.OS === 'android' && hasGmsSync()) || Platform.OS !== 'android') && ( - -