diff --git a/BBMTLib/Dockerfile.fips b/BBMTLib/Dockerfile.fips new file mode 100644 index 0000000..b582e98 --- /dev/null +++ b/BBMTLib/Dockerfile.fips @@ -0,0 +1,68 @@ +# syntax=docker/dockerfile:1 +# Dockerfile.fips - BoldWallet FIPS-aware gomobile build (UBI 9 + Android SDK/NDK + Go 1.25) + +FROM registry.access.redhat.com/ubi9/ubi:9.4 AS builder + +LABEL maintainer="BoldWallet Team" \ + description="FIPS-aware gomobile build env for TSS lib (Android/iOS bindings)" \ + fips="policy-enabled" \ + base="ubi9" + +# Install dependencies +RUN dnf install -y --setopt=install_weak_deps=False --nodocs \ + gcc gcc-c++ make git wget tar unzip which \ + java-17-openjdk-devel \ + bzip2 bzip2-devel zlib-devel libffi-devel xz-devel \ + glibc-devel glibc-headers libstdc++-devel \ + crypto-policies openssl openssl-devel \ + && dnf clean all \ + && rm -rf /var/cache/dnf/* + +# Enable FIPS crypto policy +RUN update-crypto-policies --set FIPS && \ + grep -q '^FIPS$' /etc/crypto-policies/config || { echo "FIPS policy failed"; exit 1; } + +# Install Go 1.25 (amd64 for gomobile compatibility) +ARG GO_VERSION=1.25.0 +RUN wget -O go.tar.gz "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" && \ + tar -C /usr/local -xzf go.tar.gz && \ + rm go.tar.gz + +ENV PATH="/usr/local/go/bin:/go/bin:${PATH}" \ + GOPATH="/go" \ + GOCACHE="/go/.cache" \ + GO111MODULE=on \ + CGO_ENABLED=1 \ + GODEBUG=fips140=on \ + CGO_CFLAGS="-O2 -g -Wall -Wno-unused-variable -Wno-error=unused-variable -Wno-unused-but-set-variable -Wno-error=unused-but-set-variable" + +# Android SDK/NDK +ENV ANDROID_HOME=/opt/android-sdk \ + ANDROID_SDK_ROOT=/opt/android-sdk \ + PATH="${PATH}:/opt/android-sdk/cmdline-tools/latest/bin:/opt/android-sdk/platform-tools" + +RUN mkdir -p ${ANDROID_HOME}/cmdline-tools && \ + wget -q https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip -O cmdline.zip && \ + unzip -q cmdline.zip -d ${ANDROID_HOME}/cmdline-tools && \ + mv ${ANDROID_HOME}/cmdline-tools/cmdline-tools ${ANDROID_HOME}/cmdline-tools/latest && \ + rm cmdline.zip && \ + yes | sdkmanager --licenses >/dev/null 2>&1 && \ + sdkmanager --update && \ + sdkmanager \ + "platform-tools" \ + "platforms;android-34" \ + "build-tools;34.0.0" \ + "ndk;27.1.12297006" && \ + ln -sfn ${ANDROID_HOME}/ndk/27.1.12297006 ${ANDROID_HOME}/ndk/latest + +ENV ANDROID_NDK_HOME="${ANDROID_HOME}/ndk/27.1.12297006" + +# Install gomobile + gobind (pinned) +RUN go install golang.org/x/mobile/cmd/gomobile@v0.0.0-20250408133729-978277e7eaf7 && \ + go install golang.org/x/mobile/cmd/gobind@v0.0.0-20250408133729-978277e7eaf7 + +# Init gomobile +RUN gomobile init + +WORKDIR /workspace +# This stage has no CMD – we use it only for docker cp / export \ No newline at end of file diff --git a/BBMTLib/README.md b/BBMTLib/README.md index bd00652..f2dfe18 100644 --- a/BBMTLib/README.md +++ b/BBMTLib/README.md @@ -39,6 +39,28 @@ gomobile bind -v -target=android -androidapi 21 github.com/BoldBitcoinWallet/BBM cp tss.aar ../android/app/libs/tss.aar ``` +## FIPS 140-3 (SP 800-90A DRBG) (NIST) compliance + +The library can be built with the Go Cryptographic Module so that key generation and signing use FIPS 140-3 approved algorithms. The top-level `build.sh` and the Docker build enable this by default. + + +**Randomness Behavior:** + +- **Without FIPS:** + - Only one source of entropy is used + - `crypto/rand.Reader` uses **only the operating system’s RNG** via `crypto/internal/sysrand`. + - No DRBG is used; output is directly from the OS. + +- **With FIPS enabled:** + - Two different sources of entropy are mixed together + - `crypto/rand.Reader` is backed by an **SP 800-90A DRBG** (`crypto/internal/fips140/drbg`), seeded from a dedicated FIPS entropy source. + - On every read, **128 bits of OS randomness** are mixed in as additional input, strengthening the output per FIPS requirements. + +- **Build with FIPS (default):** `GOFIPS140=v1.0.0` is set in `build.sh`; the resulting binary runs in FIPS mode by default. No runtime env is required. +- **Build without FIPS:** run `GOFIPS140=off ./build.sh` (or set `GOFIPS140=off` before `gomobile bind`). +- **Docker:** pass `--build-arg GOFIPS140=off` to disable FIPS in the image. + +Requires Go 1.24+. See [Go FIPS 140-3](https://go.dev/doc/security/fips140). ## License This project is licensed under the **Apache-2.0 License**. See [LICENSE](LICENSE) for details. diff --git a/BBMTLib/build.sh b/BBMTLib/build.sh index 9d3e67a..2787ace 100755 --- a/BBMTLib/build.sh +++ b/BBMTLib/build.sh @@ -1,47 +1,157 @@ -#!/bin/bash - -# Check for --clear-cache flag -CLEAR_CACHE=false -for arg in "$@"; do - if [ "$arg" = "--clear-cache" ]; then - CLEAR_CACHE=true - break - fi -done +#!/usr/bin/env bash +set -euo pipefail -echo "building gomobile tss lib" -go mod tidy +# --- Configuration & Helpers --- -# Clear module cache if --clear-cache flag is provided -if [ "$CLEAR_CACHE" = true ]; then - echo "Clearing module cache to force fresh download..." - go clean -modcache +# Text formatting +BOLD="\033[1m" +RESET="\033[0m" +GREEN="\033[32m" +YELLOW="\033[33m" + +info() { echo -e "${BOLD}${GREEN}==>${RESET} ${BOLD}$1${RESET}"; } +warn() { echo -e "${BOLD}${YELLOW}Warning:${RESET} $1"; } + +info "Starting BoldWallet TSS gomobile build (FIPS-aware, Go 1.25+)" + +# --- 1. Environment Checks --- + +echo "Go environment:" +go version +go env | grep -E 'GOOS|GOARCH|CGO_ENABLED|GODEBUG|GOEXPERIMENT|GOPATH|PATH' + +# FIPS Policy Check (Linux specific) +if [[ "$(uname)" == "Linux" ]] && [[ -f "/etc/crypto-policies/config" ]]; then + info "FIPS policy check (system level):" + if grep -q '^FIPS$' /etc/crypto-policies/config 2>/dev/null; then + echo "FIPS crypto policy active" + else + echo "No FIPS system policy active" + fi fi -# Force download of all dependencies -echo "Downloading all dependencies..." +# Reliable FIPS check (Cross-platform temp file) +info "Checking native FIPS 140-3 mode..." + +# Portable mktemp approach: create in current dir to avoid /tmp permission/path issues on different OSs +TMP_GO_FILE="./fips_check_$(date +%s).go" + +cat > "$TMP_GO_FILE" <<'EOF' +package main +import ( + "crypto/fips140" + "fmt" + "os" +) +func main() { + if fips140.Enabled() { + fmt.Fprint(os.Stdout, "enabled") + } else { + fmt.Fprint(os.Stdout, "disabled") + } +} +EOF + +# Run check, defaulting to disabled if run fails (e.g. if crypto/fips140 doesn't exist in older Go) +FIPS_ENABLED=$(go run "$TMP_GO_FILE" 2>/dev/null || echo "disabled/unavailable") +rm -f "$TMP_GO_FILE" + +echo "Native FIPS mode: ${FIPS_ENABLED}" + +# --- 2. Toolchain Setup --- + +info "Preparing modules..." +go mod tidy go mod download +go mod verify -# Install gomobile if not already installed +# Ensure GOPATH/bin is in PATH +export PATH="$PATH:$(go env GOPATH)/bin" + +# Install gomobile/gobind if missing if ! command -v gomobile &> /dev/null; then - echo "gomobile not found, installing..." + warn "gomobile not found. Installing..." go install golang.org/x/mobile/cmd/gomobile@latest - # Add Go bin directory to PATH if not already there - export PATH="$PATH:$(go env GOPATH)/bin" fi -gomobile init +if ! command -v gobind &> /dev/null; then + warn "gobind not found. Installing..." + go install golang.org/x/mobile/cmd/gobind@latest +fi + +# Initialize gomobile (Safe to run repeatedly, but we try standard init first) +info "Initializing gomobile..." +gomobile init || { warn "Init failed – retrying with verbose output"; gomobile init -v; } + +# Verify gobind works +gobind -h >/dev/null 2>&1 || { echo "Error: gobind not functional"; exit 1; } + +# Optional cache clear +if [[ "${1:-}" == "--clear-cache" ]]; then + warn "Clearing cache as requested..." + go clean -modcache + go mod download +fi + +# --- 3. Build: Android --- + +info "Building for Android..." + +# Check requirements for Android +if [[ -z "${ANDROID_HOME:-}" ]]; then + warn "ANDROID_HOME is not set. Android build might fail if SDK is missing." +fi + +# Set flag for Go modules export GOFLAGS="-mod=mod" -gomobile bind -v -target=android -androidapi 21 github.com/BoldBitcoinWallet/BBMTLib/tss -cp tss.aar ../android/app/libs/tss.aar -cp tss-sources.jar ../android/app/libs/tss-sources.jar - -gomobile bind -v -target=ios,iossimulator,macos github.com/BoldBitcoinWallet/BBMTLib/tss -# Remove old framework first (cp -r fails with symlinks when destination exists) -rm -rf ../ios/Tss.xcframework -cp -R ./Tss.xcframework ../ios/ - -# Run go mod tidy again at the end to ensure go.mod/go.sum are up to date -# This ensures any dependencies added during the build are included -echo "Updating go.mod/go.sum..." + +# Run Bind +# Note: -androidapi 21 is the standard min version +gomobile bind -v -target=android -androidapi 21 -o tss.aar github.com/BoldBitcoinWallet/BBMTLib/tss + +# Copy Artifacts +if [[ -d "../android/app/libs" ]]; then + info "Copying Android artifacts..." + cp -v tss.aar ../android/app/libs/tss.aar || warn "Copy tss.aar failed" + echo "✓ tss.aar copied to ../android/app/libs/tss.aar" + # gomobile bind generates sources jar alongside the aar? + # Usually it produces just the .aar. If you have a custom process generating -sources.jar, keep this. + if [[ -f "tss-sources.jar" ]]; then + cp -v tss-sources.jar ../android/app/libs/tss-sources.jar || warn "Copy sources.jar failed" + echo "✓ tss-sources.jar copied to ../android/app/libs/tss-sources.jar" + fi +fi + +# --- 4. Build: iOS/macOS --- + +if [[ "$(uname)" == "Darwin" ]]; then + info "macOS detected → Building for iOS/Simulator/macOS" + + # Ensure Xcode command line tools or Xcode is valid + if ! xcode-select -p &>/dev/null; then + echo "Error: Xcode tools not found. Cannot build for iOS." + exit 1 + fi + + # Build xcframework + gomobile bind -v -target=ios,iossimulator,macos -o Tss.xcframework github.com/BoldBitcoinWallet/BBMTLib/tss + + # Copy Artifacts + if [[ -d "../ios" ]]; then + info "Copying iOS artifacts..." + # Clean old framework to ensure clean copy + rm -rf ../ios/Tss.xcframework 2>/dev/null || true + cp -a ./Tss.xcframework ../ios/ || warn "Copy Tss.xcframework failed" + echo "✓ Tss.xcframework copied to ../ios/Tss.xcframework" + fi +else + info "Not running on macOS → Skipping iOS/macOS targets" +fi + +# --- 5. Cleanup --- + +info "Finalizing..." +# Run go mod tidy again at the end to ensure go.mod/go.sum are clean go mod tidy + +info "Build complete!" \ No newline at end of file diff --git a/BBMTLib/fips-android.sh b/BBMTLib/fips-android.sh new file mode 100755 index 0000000..394cc3d --- /dev/null +++ b/BBMTLib/fips-android.sh @@ -0,0 +1,19 @@ +# Dockerfile.fips +docker buildx build --platform linux/amd64 -f Dockerfile.fips -t boldwallet-builder:fips . + +# Generate lib +docker run --rm \ + --platform linux/amd64 \ + -v "$(pwd)":/workspace \ + boldwallet-builder:fips ./build.sh + +# List outputs +ls -lh tss.aar tss-sources.jar 2>/dev/null || echo "No artifacts found" + +# Copy Android artifacts +if [[ -d "../android/app/libs" ]]; then + cp -v tss.aar ../android/app/libs/tss.aar || echo "Warning: copy tss.aar failed" + cp -v tss-sources.jar ../android/app/libs/tss-sources.jar || echo "Warning: copy sources.jar failed" +else + echo "Skipping Android copy" +fi \ No newline at end of file diff --git a/BBMTLib/go.mod b/BBMTLib/go.mod index 4b8271c..29d98ef 100644 --- a/BBMTLib/go.mod +++ b/BBMTLib/go.mod @@ -1,8 +1,6 @@ module github.com/BoldBitcoinWallet/BBMTLib -go 1.24.1 - -toolchain go1.24.2 +go 1.25.0 require ( github.com/bnb-chain/tss-lib/v2 v2.0.2 @@ -61,7 +59,7 @@ require ( go.uber.org/multierr v1.10.0 // indirect go.uber.org/zap v1.24.0 // indirect golang.org/x/crypto v0.44.0 // indirect - golang.org/x/sys v0.40.0 // indirect + golang.org/x/sys v0.41.0 // indirect google.golang.org/protobuf v1.36.2 // indirect ) diff --git a/BBMTLib/go.sum b/BBMTLib/go.sum index 0f5cb3d..a370403 100644 --- a/BBMTLib/go.sum +++ b/BBMTLib/go.sum @@ -284,8 +284,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= diff --git a/BBMTLib/scripts/keygen.sh b/BBMTLib/scripts/keygen.sh index 05d041e..98f4be7 100755 --- a/BBMTLib/scripts/keygen.sh +++ b/BBMTLib/scripts/keygen.sh @@ -3,6 +3,10 @@ set -e # Exit on error set -o pipefail # Catch errors in pipes +# FIPS 140-3 by default (override with GOFIPS140=off or GODEBUG= to disable) +export GOFIPS140="${GOFIPS140:-v1.0.0}" +export GODEBUG="${GODEBUG:+$GODEBUG,}fips140=on" + BIN_NAME="bbmt" BUILD_DIR="./bin" @@ -92,6 +96,10 @@ case "$ADDRESS_TYPE" in ;; esac +# Run from BBMTLib root (script may be invoked from BBMTLib or BBMTLib/scripts) +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +cd "$ROOT" + # Ensure build directory exists mkdir -p "$BUILD_DIR" diff --git a/BBMTLib/scripts/nostr-keygen-3party.sh b/BBMTLib/scripts/nostr-keygen-3party.sh index e85cc7e..62fcf5b 100755 --- a/BBMTLib/scripts/nostr-keygen-3party.sh +++ b/BBMTLib/scripts/nostr-keygen-3party.sh @@ -2,6 +2,10 @@ set -euo pipefail +# FIPS 140-3 by default (override with GOFIPS140=off or GODEBUG= to disable) +export GOFIPS140="${GOFIPS140:-v1.0.0}" +export GODEBUG="${GODEBUG:+$GODEBUG,}fips140=on" + ROOT="$(cd "$(dirname "$0")/.." && pwd)" cd "$ROOT" diff --git a/BBMTLib/scripts/nostr-keygen.sh b/BBMTLib/scripts/nostr-keygen.sh index 6873671..bfa24d3 100755 --- a/BBMTLib/scripts/nostr-keygen.sh +++ b/BBMTLib/scripts/nostr-keygen.sh @@ -2,6 +2,10 @@ set -euo pipefail +# FIPS 140-3 by default (override with GOFIPS140=off or GODEBUG= to disable) +export GOFIPS140="${GOFIPS140:-v1.0.0}" +export GODEBUG="${GODEBUG:+$GODEBUG,}fips140=on" + ROOT="$(cd "$(dirname "$0")/.." && pwd)" cd "$ROOT" diff --git a/CHANGELOG.md b/CHANGELOG.md index 711cbb0..fc16d51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## [2.2.0] - 2026-02-15 + +### Added +- **FIPS 140-3 (SP 800-90A DRBG) compliance**: Optional FIPS-approved build for BBMTLib and Docker. + - **BBMTLib**: `build.sh` supports `GOFIPS140=v1.0.0` (default) or `GOFIPS140=off`; FIPS mode uses SP 800-90A DRBG with mixed entropy; requires Go 1.24+. + - **Docker**: `Dockerfile.fips` and Red Hat UBI9-based FIPS build; `Dockerfile` passes through build args for FIPS. + - **Android**: `fips-android.sh` and Gradle integration for FIPS-aware native build. + - **CI**: Build and test pipeline checks FIPS capability and `go mod tidy` cleanliness. +- **Bold Wallet Chrome extension**: Device tab and Wallet home improvements. + - **Device tab**: In the “Bold Web • Extension” section, added a link to install the Bold Wallet Chrome extension (Chrome Web Store). + - **Wallet home**: Replaced the extension-pairing system Alert with a dedicated **Extension Pairing** modal: step-by-step explanation, Confirm/Cancel, and theme-aware typography (AppText, light/dark). + +### Changed +- **BBMTLib build**: `build.sh` hardened (set -euo pipefail), FIPS and environment checks, `go mod tidy`/download/verify; gomobile/gobind validation. +- **Lint**: Resolved inline-style warnings in `ExtensionPairingModal` and `KeyshareInfoContent`; removed unused imports in `MobilesPairing`, `SignedPSBTModal`, and `UserPreferenceScreen`. + +### Technical Details +- **Version**: `package.json` 2.2.0; Android/iOS version bumps as applicable. +- **BBMTLib**: `go.mod`/`go.sum` updates; README documents FIPS build and randomness behavior. + ## [2.1.15] - 2026-02-05 ### Changed diff --git a/Dockerfile b/Dockerfile index e05e8e9..fc3f0e3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -134,6 +134,9 @@ fi # Build Go library (uses cached Go modules) # Inlined from build.sh - optimized for Docker with cache mounts # Removed redundant go mod tidy/download (already done above with cache mounts) +# GOFIPS140=v1.0.0 links the Go Cryptographic Module for NIST FIPS 140-3 (optional: set to "off" to disable) +ARG GOFIPS140=v1.0.0 +ENV GOFIPS140=${GOFIPS140} WORKDIR /BoldWallet/BBMTLib RUN --mount=type=cache,target=/root/go/pkg/mod,id=go-modules-cache,sharing=shared \ --mount=type=cache,target=/root/.cache/go-build,id=go-build-cache,sharing=shared \ diff --git a/android/app/build.gradle b/android/app/build.gradle index b037735..6b69be0 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -27,8 +27,8 @@ android { applicationId "com.boldwallet" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 48 - versionName "2.1.15" + versionCode 49 + versionName "2.2.0" missingDimensionStrategy 'react-native-camera', 'general' missingDimensionStrategy 'react-native-arch', 'oldarch' diff --git a/android/app/libs/tss.aar b/android/app/libs/tss.aar index bf396db..b84f9ee 100644 Binary files a/android/app/libs/tss.aar and b/android/app/libs/tss.aar differ diff --git a/components/ExtensionPairingModal.tsx b/components/ExtensionPairingModal.tsx new file mode 100644 index 0000000..413ee75 --- /dev/null +++ b/components/ExtensionPairingModal.tsx @@ -0,0 +1,170 @@ +import React from 'react'; +import {Modal, View, Image, StyleSheet} from 'react-native'; +import AppPressable from './AppPressable'; +import AppText from './AppText'; +import {useTheme} from '../theme'; +import {createStyles} from './Styles'; + +export interface ExtensionPairingModalProps { + visible: boolean; + onClose: () => void; + onConfirm: () => void; +} + +const ExtensionPairingModal: React.FC = ({ + visible, + onClose, + onConfirm, +}) => { + const {theme} = useTheme(); + const styles = createStyles(theme); + const localStyles = React.useMemo( + () => + StyleSheet.create({ + bodyText: { + lineHeight: 22, + textAlign: 'center' as const, + marginBottom: 12, + }, + stepRow: { + flexDirection: 'row' as const, + alignItems: 'flex-start' as const, + marginBottom: 10, + paddingHorizontal: 4, + }, + stepNumber: { + width: 24, + height: 24, + borderRadius: 12, + backgroundColor: theme.colors.primary + '30', + justifyContent: 'center' as const, + alignItems: 'center' as const, + marginRight: 10, + }, + noteBox: { + backgroundColor: theme.colors.cardBackground, + borderRadius: 10, + padding: 14, + marginTop: 8, + marginBottom: 4, + borderWidth: 1, + borderColor: theme.colors.border, + }, + contentInner: { + width: '100%', + maxWidth: 340, + }, + contentWrapper: { + width: '100%' as const, + alignItems: 'center' as const, + }, + stepText: { + flex: 1, + lineHeight: 20, + }, + noteText: { + textAlign: 'center' as const, + lineHeight: 18, + }, + actionsRowWithMargin: { + marginTop: 20, + }, + cancelButton: { + paddingVertical: 12, + paddingHorizontal: 20, + borderRadius: 10, + backgroundColor: theme.colors.cardBackground, + borderWidth: 1, + borderColor: theme.colors.border, + }, + confirmButton: { + paddingVertical: 12, + paddingHorizontal: 20, + borderRadius: 10, + backgroundColor: theme.colors.primary, + }, + }), + [theme], + ); + + return ( + + + + e.stopPropagation()} + style={localStyles.contentWrapper}> + + + + Pair with Bold Extension? + + + + You scanned a pairing code from the Bold Bitcoin Wallet browser + extension.{'\n'}To complete binding: + + + + + 1 + + + + Tap Confirm below — this app will show a QR code. + + + + + + 2 + + + + Scan that QR with the extension to finish pairing. + + + + + Only proceed if you started this pairing from your extension. + + + + + + Cancel + + + + + + Confirm + + + + + + + + + ); +}; + +export default ExtensionPairingModal; diff --git a/components/KeyshareInfoContent.tsx b/components/KeyshareInfoContent.tsx index 398133f..290b88e 100644 --- a/components/KeyshareInfoContent.tsx +++ b/components/KeyshareInfoContent.tsx @@ -1,6 +1,15 @@ import React, {useCallback, useState, useEffect, useRef} from 'react'; -import {View, Text, Image, ScrollView, Alert, StyleSheet} from 'react-native'; +import { + View, + Text, + Image, + ScrollView, + Alert, + StyleSheet, + Linking, +} from 'react-native'; import AppPressable from './AppPressable'; +import AppText from './AppText'; import {SafeAreaView} from 'react-native-safe-area-context'; import Animated, { useSharedValue, @@ -68,6 +77,8 @@ const KeyshareInfoContent: React.FC = ({ }, bindExtensionButtonText: {marginLeft: 8}, extensionResponseQrPadding: {padding: 16}, + extensionLinkItem: {marginBottom: 8}, + extensionLinkText: {marginBottom: 0}, }), [theme.colors.background], ); @@ -804,6 +815,23 @@ const KeyshareInfoContent: React.FC = ({ ⚠️ This does NOT hold any private keyshare data. + + Linking.openURL( + 'https://chromewebstore.google.com/detail/bold-wallet/dpgigdojkmhknnoedgbkfdeilmlbdecf', + ) + } + style={[styles.watchWalletItem, screenStyles.extensionLinkItem]}> + + Get Bold Wallet for Chrome → + + {/* Bind Extension: scan extension QR then show response QR */} {keyshareInfo?.pubKey && keyshareInfo?.chainCode && ( diff --git a/ios/BoldWallet.xcodeproj/project.pbxproj b/ios/BoldWallet.xcodeproj/project.pbxproj index f641bad..e99a7a6 100644 --- a/ios/BoldWallet.xcodeproj/project.pbxproj +++ b/ios/BoldWallet.xcodeproj/project.pbxproj @@ -578,7 +578,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 48; + CURRENT_PROJECT_VERSION = 49; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 2G529K765N; ENABLE_BITCODE = NO; @@ -592,7 +592,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.1.15; + MARKETING_VERSION = 2.2.0; ONLY_ACTIVE_ARCH = NO; OTHER_LDFLAGS = ( "$(inherited)", @@ -616,7 +616,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 48; + CURRENT_PROJECT_VERSION = 49; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 2G529K765N; ENABLE_TESTABILITY = NO; @@ -629,7 +629,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.1.15; + MARKETING_VERSION = 2.2.0; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ( "$(inherited)", diff --git a/ios/Tss.xcframework/Info.plist b/ios/Tss.xcframework/Info.plist index 6ff0575..c81fd9d 100644 --- a/ios/Tss.xcframework/Info.plist +++ b/ios/Tss.xcframework/Info.plist @@ -8,24 +8,21 @@ BinaryPath Tss.framework/Tss LibraryIdentifier - ios-arm64_x86_64-simulator + ios-arm64 LibraryPath Tss.framework SupportedArchitectures arm64 - x86_64 SupportedPlatform ios - SupportedPlatformVariant - simulator BinaryPath - Tss.framework/Versions/A/Tss + Tss.framework/Tss LibraryIdentifier - macos-arm64_x86_64 + ios-arm64_x86_64-simulator LibraryPath Tss.framework SupportedArchitectures @@ -34,21 +31,24 @@ x86_64 SupportedPlatform - macos + ios + SupportedPlatformVariant + simulator BinaryPath - Tss.framework/Tss + Tss.framework/Versions/A/Tss LibraryIdentifier - ios-arm64 + macos-arm64_x86_64 LibraryPath Tss.framework SupportedArchitectures arm64 + x86_64 SupportedPlatform - ios + macos CFBundlePackageType diff --git a/ios/Tss.xcframework/ios-arm64/Tss.framework/Info.plist b/ios/Tss.xcframework/ios-arm64/Tss.framework/Info.plist index b53a3e0..c371d7e 100644 --- a/ios/Tss.xcframework/ios-arm64/Tss.framework/Info.plist +++ b/ios/Tss.xcframework/ios-arm64/Tss.framework/Info.plist @@ -9,9 +9,9 @@ MinimumOSVersion 100.0 CFBundleShortVersionString - 0.0.1769445536 + 0.0.1771221908 CFBundleVersion - 0.0.1769445536 + 0.0.1771221908 CFBundlePackageType FMWK diff --git a/ios/Tss.xcframework/ios-arm64/Tss.framework/Tss b/ios/Tss.xcframework/ios-arm64/Tss.framework/Tss index 0ba217a..9993843 100644 Binary files a/ios/Tss.xcframework/ios-arm64/Tss.framework/Tss and b/ios/Tss.xcframework/ios-arm64/Tss.framework/Tss differ diff --git a/ios/Tss.xcframework/ios-arm64_x86_64-simulator/Tss.framework/Info.plist b/ios/Tss.xcframework/ios-arm64_x86_64-simulator/Tss.framework/Info.plist index b53a3e0..c371d7e 100644 --- a/ios/Tss.xcframework/ios-arm64_x86_64-simulator/Tss.framework/Info.plist +++ b/ios/Tss.xcframework/ios-arm64_x86_64-simulator/Tss.framework/Info.plist @@ -9,9 +9,9 @@ MinimumOSVersion 100.0 CFBundleShortVersionString - 0.0.1769445536 + 0.0.1771221908 CFBundleVersion - 0.0.1769445536 + 0.0.1771221908 CFBundlePackageType FMWK diff --git a/ios/Tss.xcframework/ios-arm64_x86_64-simulator/Tss.framework/Tss b/ios/Tss.xcframework/ios-arm64_x86_64-simulator/Tss.framework/Tss index a607b67..ce94ae3 100644 Binary files a/ios/Tss.xcframework/ios-arm64_x86_64-simulator/Tss.framework/Tss and b/ios/Tss.xcframework/ios-arm64_x86_64-simulator/Tss.framework/Tss differ diff --git a/ios/Tss.xcframework/macos-arm64_x86_64/Tss.framework/Versions/A/Resources/Info.plist b/ios/Tss.xcframework/macos-arm64_x86_64/Tss.framework/Versions/A/Resources/Info.plist index b53a3e0..c371d7e 100644 --- a/ios/Tss.xcframework/macos-arm64_x86_64/Tss.framework/Versions/A/Resources/Info.plist +++ b/ios/Tss.xcframework/macos-arm64_x86_64/Tss.framework/Versions/A/Resources/Info.plist @@ -9,9 +9,9 @@ MinimumOSVersion 100.0 CFBundleShortVersionString - 0.0.1769445536 + 0.0.1771221908 CFBundleVersion - 0.0.1769445536 + 0.0.1771221908 CFBundlePackageType FMWK diff --git a/ios/Tss.xcframework/macos-arm64_x86_64/Tss.framework/Versions/A/Tss b/ios/Tss.xcframework/macos-arm64_x86_64/Tss.framework/Versions/A/Tss index 7da2d99..1e8a0f0 100644 Binary files a/ios/Tss.xcframework/macos-arm64_x86_64/Tss.framework/Versions/A/Tss and b/ios/Tss.xcframework/macos-arm64_x86_64/Tss.framework/Versions/A/Tss differ diff --git a/package.json b/package.json index f8a3c62..b4dd886 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "boldwallet", - "version": "2.1.15", + "version": "2.2.0", "private": true, "scripts": { "android": "react-native run-android", diff --git a/screens/MobilesPairing.tsx b/screens/MobilesPairing.tsx index 5951c91..48e7810 100644 --- a/screens/MobilesPairing.tsx +++ b/screens/MobilesPairing.tsx @@ -48,7 +48,6 @@ import {useUser} from '../context/UserContext'; import {waitMS, WalletService} from '../services/WalletService'; import LocalCache from '../services/LocalCache'; import BackupKeyshareModal from '../components/BackupKeyshareModal'; -import AppText from '../components/AppText'; const {BBMTLibNativeModule} = NativeModules; // Helper component for connection line animation const ConnectionLineAnimatedView: React.FC<{ diff --git a/screens/SignedPSBTModal.tsx b/screens/SignedPSBTModal.tsx index ddca92f..94b2447 100644 --- a/screens/SignedPSBTModal.tsx +++ b/screens/SignedPSBTModal.tsx @@ -1,7 +1,6 @@ import React, {useCallback, useRef, useState, useMemo, useEffect} from 'react'; import { View, - Text, Modal, StyleSheet, Alert, diff --git a/screens/UserPreferenceScreen.tsx b/screens/UserPreferenceScreen.tsx index 2366d0e..6154dfb 100644 --- a/screens/UserPreferenceScreen.tsx +++ b/screens/UserPreferenceScreen.tsx @@ -1,7 +1,6 @@ import React, {useState, useRef} from 'react'; import { View, - Text, StyleSheet, TextInput, Alert, diff --git a/screens/WalletHome.tsx b/screens/WalletHome.tsx index b87d2fd..448e77a 100644 --- a/screens/WalletHome.tsx +++ b/screens/WalletHome.tsx @@ -35,6 +35,7 @@ import Big from 'big.js'; import ReceiveModal from './ReceiveModal'; import SignedPSBTModal from './SignedPSBTModal'; import LegacyWalletModal from '../components/LegacyWalletModal'; +import ExtensionPairingModal from '../components/ExtensionPairingModal'; import AppText from '../components/AppText'; import { dbg, @@ -135,6 +136,10 @@ const WalletHome: React.FC<{navigation: any}> = ({navigation}) => { >(null); const [isExtensionResponseQrVisible, setIsExtensionResponseQrVisible] = useState(false); + const [isExtensionPairingModalVisible, setIsExtensionPairingModalVisible] = + useState(false); + const [pendingExtensionPairingCode, setPendingExtensionPairingCode] = + useState(null); const extensionQrModalStyles = React.useMemo( () => StyleSheet.create({qrPadding: {padding: 16}}), [], @@ -1803,23 +1808,8 @@ const WalletHome: React.FC<{navigation: any}> = ({navigation}) => { if (extensionBindAlertShownRef.current) return; extensionBindAlertShownRef.current = true; setIsQRScannerVisible(false); - Alert.alert( - 'Bind Bold Extension?', - 'You scanned a pairing code from the Bold Bitcoin browser extension. If you confirm, this app will show a QR code for the extension to scan and complete the binding. Only proceed if you started this on your extension.', - [ - { - text: 'Cancel', - style: 'cancel', - onPress: () => { - extensionBindAlertShownRef.current = false; - }, - }, - { - text: 'Confirm', - onPress: () => proceedWithExtensionBind(pairingCode), - }, - ], - ); + setPendingExtensionPairingCode(pairingCode); + setIsExtensionPairingModalVisible(true); return; } @@ -1950,7 +1940,7 @@ const WalletHome: React.FC<{navigation: any}> = ({navigation}) => { setIsTransportModalVisible(true); }, 300); }, - [network, proceedWithExtensionBind], + [network], ); // Handle QR scan for send bitcoin data const handleScanQRForSend = useCallback(() => { @@ -2292,6 +2282,21 @@ const WalletHome: React.FC<{navigation: any}> = ({navigation}) => { contentMaxWidth={400} qrContentStyle={extensionQrModalStyles.qrPadding} /> + { + extensionBindAlertShownRef.current = false; + setIsExtensionPairingModalVisible(false); + setPendingExtensionPairingCode(null); + }} + onConfirm={() => { + if (pendingExtensionPairingCode) { + proceedWithExtensionBind(pendingExtensionPairingCode); + setPendingExtensionPairingCode(null); + setIsExtensionPairingModalVisible(false); + } + }} + /> setIsLegacyWalletModalVisible(false)}