Skip to content

Commit 893f0b9

Browse files
authored
Merge pull request #2025 from SatoshiPortal/develop
6.9.0
2 parents 96a194c + b8daa96 commit 893f0b9

229 files changed

Lines changed: 6950 additions & 3051 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.devcontainer/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Dev Container
2+
3+
## Usage
4+
5+
```bash
6+
devcontainer up --workspace-folder . --config ./.devcontainer/devcontainer.json
7+
```
8+
9+
## macOS (Apple Silicon)
10+
11+
Before starting the container, run the setup script:
12+
13+
```bash
14+
.devcontainer/macos-setup.sh
15+
```
16+
17+
This ensures Rosetta is active in the Podman VM. Without it, x86_64 binaries fall back to QEMU and crash with SIGSEGV. See [containers/podman#28181](https://github.com/containers/podman/issues/28181).
18+
19+
**Note:** SSH agent forwarding is not supported on macOS due to Podman's inability to mount host Unix sockets into containers through the VM layer. See [containers/podman#23785](https://github.com/containers/podman/issues/23785).

.devcontainer/devcontainer.json

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"name": "${localWorkspaceFolderBasename}",
3+
"build": {
4+
"dockerfile": "../Dockerfile",
5+
"args": {
6+
"USERNAME": "${localEnv:USER}"
7+
}
8+
},
9+
"remoteUser": "${localEnv:USER}",
10+
"updateRemoteUserUID": true,
11+
"shutdownAction": "stopContainer",
12+
"initializeCommand": ".devcontainer/init-ssh-agent.sh",
13+
"runArgs": [
14+
"--name",
15+
"${localWorkspaceFolderBasename}",
16+
"--hostname",
17+
"bull",
18+
"--memory=8g",
19+
"--security-opt",
20+
"label=disable"
21+
],
22+
"mounts": [
23+
"source=${localEnv:HOME}/.ssh,target=/home/${localEnv:USER}/.ssh,type=bind,consistency=cached",
24+
"source=/tmp/ssh-agent.sock,target=/ssh-agent,type=bind,consistency=cached",
25+
"source=${localEnv:HOME}/.gitconfig,target=/home/${localEnv:USER}/.gitconfig,type=bind,consistency=cached"
26+
],
27+
"containerEnv": {
28+
"SSH_AUTH_SOCK": "/ssh-agent"
29+
},
30+
"postCreateCommand": "flutter config --no-analytics && dart --disable-analytics",
31+
"postStartCommand": "sudo chown -R --no-dereference ${localEnv:USER}:${localEnv:USER} /home/${localEnv:USER}/.ssh || true; chmod 700 /home/${localEnv:USER}/.ssh; find /home/${localEnv:USER}/.ssh -maxdepth 1 -type f -exec chmod 600 {} + 2>/dev/null || true"
32+
}

.devcontainer/init-ssh-agent.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/sh
2+
# Normalize SSH agent socket path for devcontainer mount
3+
case "$(uname)" in
4+
Linux)
5+
# Symlink real SSH agent socket
6+
ln -sf "$SSH_AUTH_SOCK" /tmp/ssh-agent.sock
7+
;;
8+
Darwin)
9+
# Create dummy so the mount doesn't fail (SSH agent not supported on macOS Podman)
10+
rm -f /tmp/ssh-agent.sock
11+
touch /tmp/ssh-agent.sock
12+
;;
13+
esac

.devcontainer/macos-setup.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/sh
2+
# Setup script for macOS (Apple Silicon) users
3+
# Run this before: devcontainer up --workspace-folder . --config ./.devcontainer/devcontainer.json
4+
5+
set -e
6+
7+
# Ensure Rosetta is active in the Podman VM
8+
# See https://github.com/containers/podman/issues/28181
9+
if ! podman machine ssh -- cat /proc/sys/fs/binfmt_misc/rosetta > /dev/null 2>&1; then
10+
echo "Rosetta is not active in the Podman VM, enabling it..."
11+
podman machine ssh -- sudo touch /etc/containers/enable-rosetta
12+
podman machine ssh -- sudo systemctl restart rosetta-activation.service
13+
if podman machine ssh -- cat /proc/sys/fs/binfmt_misc/rosetta > /dev/null 2>&1; then
14+
echo "Rosetta enabled successfully."
15+
else
16+
echo "Failed to enable Rosetta." >&2
17+
exit 1
18+
fi
19+
else
20+
echo "Rosetta is active."
21+
fi

.dockerignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
build/
2+
.dart_tool/
3+
.gradle/
4+
android/.gradle/
5+
ios/
6+
.idea/
7+
*.iml

.env.template

Lines changed: 0 additions & 11 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
All notable changes to Bull Bitcoin Mobile will be documented in this file.
44

5+
## [X.X.X] - To be released
6+
7+
### Bug Fixes
8+
- **Transaction note now saved to database** ([#1173](https://github.com/SatoshiPortal/bullbitcoin-mobile/issues/1173)): Fixed an issue where notes added during a send were stored in state but never persisted. Notes embedded in Bolt11 invoice descriptions or BIP21 label parameters are also automatically pre-populated if the user has not set one manually
9+
10+
---
11+
512
## [6.8.0] - 2026-03-17
613

714
### New Features

Dockerfile

Lines changed: 56 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,80 @@
1-
# Use a base Ubuntu image
2-
FROM --platform=linux/amd64 ubuntu:24.04
1+
FROM --platform=linux/amd64 debian:trixie
32

4-
# Avoid prompts from apt
53
ENV DEBIAN_FRONTEND=noninteractive
6-
ENV USER="docker"
74

8-
# Install necessary dependencies
9-
RUN apt update && apt install -y \
5+
ARG USERNAME="bull"
6+
ENV USER=$USERNAME
7+
ARG FVM_VERSION=4.0.5
8+
ARG FLUTTER_VERSION=3.38.5
9+
ARG ANDROID_CMDLINE_TOOLS_VERSION=14742923
10+
11+
# Android versions (passed via --build-arg from Makefile, defaults as fallback)
12+
ARG JVM_TARGET=21
13+
ARG ANDROID_API_LEVEL=36
14+
ARG ANDROID_BUILD_TOOLS=36.0.0
15+
ARG ANDROID_NDK=29.0.14206865
16+
17+
ENV ANDROID_HOME=/opt/android-sdk
18+
ENV PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools
19+
20+
# Install dependencies
21+
RUN apt-get update && apt-get install -y \
22+
sudo \
23+
ca-certificates \
1024
curl \
1125
git \
1226
unzip \
1327
xz-utils \
1428
zip \
15-
libglu1-mesa \
1629
wget \
17-
clang \
18-
cmake \
19-
ninja-build \
20-
pkg-config \
21-
libgtk-3-dev \
22-
software-properties-common \
30+
make \
31+
openjdk-${JVM_TARGET}-jdk-headless \
32+
build-essential \
2333
&& rm -rf /var/lib/apt/lists/*
2434

25-
RUN apt update && apt install -y sudo
35+
# Create user
2636
RUN adduser --disabled-password --gecos '' $USER
2737
RUN adduser $USER sudo
2838
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
29-
3039
USER $USER
31-
RUN sudo apt update
32-
33-
# Install OpenJDK 17
34-
RUN sudo apt-get update && sudo apt-get install -y openjdk-21-jdk && sudo rm -rf /var/lib/apt/lists/*
3540

3641
# Install Rust
37-
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
42+
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup.sh
43+
RUN sh /tmp/rustup.sh -y
44+
RUN rm /tmp/rustup.sh
3845
ENV PATH="/home/$USER/.cargo/bin:${PATH}"
3946

40-
# Verify Rust installation
47+
# Add Android Rust targets
48+
RUN rustup target add aarch64-linux-android
49+
RUN rustup target add armv7-linux-androideabi
50+
RUN rustup target add x86_64-linux-android
51+
RUN rustup target add i686-linux-android
4152
RUN rustc --version && cargo --version
4253

43-
# Set environment variables
44-
ENV FLUTTER_HOME=/opt/flutter
45-
ENV ANDROID_HOME=/opt/android-sdk
46-
ENV PATH=$FLUTTER_HOME/bin:$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools
47-
48-
# Install Flutter
49-
RUN sudo git clone https://github.com/flutter/flutter.git $FLUTTER_HOME
50-
RUN sudo sh -c "cd $FLUTTER_HOME && git checkout stable && ./bin/flutter --version"
51-
52-
# Set up Android SDK
53-
RUN sudo mkdir -p ${ANDROID_HOME}/cmdline-tools && \
54-
sudo wget -q https://dl.google.com/android/repository/commandlinetools-linux-8092744_latest.zip -O android-cmdline-tools.zip && \
55-
sudo unzip -q android-cmdline-tools.zip -d ${ANDROID_HOME}/cmdline-tools && \
56-
sudo mv ${ANDROID_HOME}/cmdline-tools/cmdline-tools ${ANDROID_HOME}/cmdline-tools/latest && \
57-
sudo rm android-cmdline-tools.zip
58-
59-
RUN sudo chown -R $USER /opt/flutter
60-
RUN sudo chown -R $USER /opt/android-sdk
54+
# Install FVM
55+
RUN curl -fsSL https://fvm.app/install.sh -o /tmp/fvm-install.sh
56+
RUN bash /tmp/fvm-install.sh ${FVM_VERSION}
57+
RUN rm /tmp/fvm-install.sh
58+
ENV PATH="/home/$USER/fvm/bin:${PATH}"
6159

62-
RUN flutter config --android-sdk=/opt/android-sdk
60+
# Install Flutter via FVM
61+
RUN fvm install ${FLUTTER_VERSION}
62+
RUN fvm global ${FLUTTER_VERSION}
63+
ENV PATH="/home/$USER/fvm/default/bin:${PATH}"
6364

64-
# Accept licenses and install necessary Android SDK components
65-
RUN yes | sdkmanager --licenses
66-
RUN sdkmanager "platform-tools" "platforms;android-35" "build-tools;35.0.0"
65+
# Download Android cmdline-tools
66+
RUN sudo wget -q https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_CMDLINE_TOOLS_VERSION}_latest.zip -O /tmp/android-cmdline-tools.zip
6767

68-
# Clean up existing app directory
69-
RUN sudo rm -rf /app
70-
71-
RUN sudo mkdir /app
72-
73-
RUN sudo chown -R $USER /app
74-
75-
# Clone the Bull Bitcoin mobile repository
76-
RUN git clone --branch main https://github.com/SatoshiPortal/bullbitcoin-mobile /app
77-
78-
# Create device-spec.json directly in the container
79-
RUN echo '{\
80-
"supportedAbis": ["armeabi-v7a", "armeabi"],\
81-
"supportedLocales": ["en"],\
82-
"screenDensity": 280,\
83-
"sdkVersion": 31\
84-
}' > /app/device-spec.json
85-
86-
WORKDIR /app
87-
88-
# Setup the project
89-
RUN make clean
90-
RUN make deps
91-
RUN make build-runner
92-
RUN make l10n
93-
94-
# Create .env (empty values)
95-
RUN cp .env.template .env
96-
97-
# Generate a fake keystore
98-
RUN keytool -genkey -v -keystore upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload -storepass android -keypass android -dname "CN=Android Debug,O=Android,C=US"
99-
100-
# Set up key.properties
101-
RUN echo "storePassword=android" > /app/android/key.properties && \
102-
echo "keyPassword=android" >> /app/android/key.properties && \
103-
echo "keyAlias=upload" >> /app/android/key.properties && \
104-
echo "storeFile=/app/upload-keystore.jks" >> /app/android/key.properties
105-
106-
# Build APK with specific target platform
107-
RUN flutter build apk --debug --target-platform android-arm64
68+
# Set up Android SDK
69+
RUN sudo mkdir -p ${ANDROID_HOME}/cmdline-tools
70+
RUN sudo unzip -q /tmp/android-cmdline-tools.zip -d ${ANDROID_HOME}/cmdline-tools
71+
RUN sudo mv ${ANDROID_HOME}/cmdline-tools/cmdline-tools ${ANDROID_HOME}/cmdline-tools/latest
72+
RUN sudo rm /tmp/android-cmdline-tools.zip
73+
RUN sudo chown -R $USER ${ANDROID_HOME}
74+
75+
# Install Android SDK components
76+
RUN yes | sdkmanager --sdk_root=${ANDROID_HOME} --licenses
77+
RUN sdkmanager --sdk_root=${ANDROID_HOME} "platform-tools"
78+
RUN sdkmanager --sdk_root=${ANDROID_HOME} "platforms;android-${ANDROID_API_LEVEL}"
79+
RUN sdkmanager --sdk_root=${ANDROID_HOME} "build-tools;${ANDROID_BUILD_TOOLS}"
80+
RUN sdkmanager --sdk_root=${ANDROID_HOME} "ndk;${ANDROID_NDK}"

Dockerfile.apk

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
FROM bull-mobile
2+
3+
# Build configuration arguments
4+
# MODE: flutter build mode: debug or release
5+
ARG MODE=debug
6+
# FORMAT: output format: apk or aab
7+
ARG FORMAT=apk
8+
# GRADLE_HEAP: JVM heap size for Gradle (e.g. 2g, 4g, 6g)
9+
ARG GRADLE_HEAP=4g
10+
COPY --chown=$USER:$USER . /app/
11+
12+
WORKDIR /app
13+
14+
# Install Flutter version specified in .fvmrc (no-op if it matches base image)
15+
RUN fvm install
16+
17+
# Setup the project
18+
RUN fvm flutter pub get
19+
RUN fvm dart run build_runner build --delete-conflicting-outputs
20+
RUN fvm flutter gen-l10n
21+
22+
23+
# Configure Gradle for containerized builds
24+
RUN mkdir -p $HOME/.gradle && \
25+
echo "org.gradle.daemon=false" > $HOME/.gradle/gradle.properties && \
26+
echo "org.gradle.jvmargs=-Xmx${GRADLE_HEAP} -XX:+HeapDumpOnOutOfMemoryError" >> $HOME/.gradle/gradle.properties
27+
28+
# Build the app
29+
# SOURCE_DATE_EPOCH: makes OpenSSL use a deterministic build timestamp instead of wall-clock time
30+
# CARGO_ENCODED_RUSTFLAGS: remaps absolute paths so they don't differ between machines
31+
RUN SOURCE_DATE_EPOCH=$(git -C /app log -1 --format=%ct) && \
32+
CARGO_ENCODED_RUSTFLAGS=$(printf '%s\037%s\037%s' \
33+
"--remap-path-prefix=$HOME/.cargo=/cargo" \
34+
"--remap-path-prefix=$HOME/.rustup=/rustup" \
35+
"--remap-path-prefix=/app=/build") && \
36+
CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1 && \
37+
export SOURCE_DATE_EPOCH CARGO_ENCODED_RUSTFLAGS CARGO_PROFILE_RELEASE_CODEGEN_UNITS && \
38+
if [ "$FORMAT" = "aab" ]; then \
39+
fvm flutter build appbundle --${MODE}; \
40+
else \
41+
fvm flutter build apk --${MODE}; \
42+
fi

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
# About BULL Wallet
44

5-
BULL Wallet is a self-custodial Bitcoin and Liquid Network which offers non-custodial atomic swaps across Bitcoin, Lightning and Liquid. The wallet philosophy is to provide advanced features that give users the maximum control, while still being easy to use for beginners. Our goal is to make sure that anyone can take self-custody of their Bitcoin, even in a high fee environment. Our driving principle is to create a user experience which nudges the user into implementing best practices.
5+
BULL Wallet is a self-custodial Bitcoin and Liquid Network wallet which offers non-custodial atomic swaps across Bitcoin, Lightning and Liquid. The wallet philosophy is to provide advanced features that give users the maximum control, while still being easy to use for beginners. Our goal is to make sure that anyone can take self-custody of their Bitcoin, even in a high fee environment. Our driving principle is to create a user experience which nudges the user into implementing best practices.
66

7-
Following the cypherpunk ethos, the BULL Wallet wallet is fully open-source and trustless.
7+
Following the cypherpunk ethos, the BULL Wallet is fully open-source and trustless.
88

99
## Wallet basics
1010

@@ -24,6 +24,10 @@ Both these wallets are able to send and receive Lightning Network payments via t
2424

2525
### [Default service providers](https://github.com/SatoshiPortal/bullbitcoin-mobile/blob/develop/lib/core/utils/constants.dart#L60)
2626

27+
### [Reproducible builds](reproducibility/README.md)
28+
29+
The app can be built reproducibly from source and verified against official releases. See the [`reproducibility/`](reproducibility/) directory for instructions.
30+
2731
### General features
2832

2933
- Non-custodial: private keys are generated on the device, and never leave the device.

0 commit comments

Comments
 (0)