Skip to content

Commit aaa583a

Browse files
authored
Merge branch 'dev' into locktime-anti-fee-sniping
2 parents 7239b8e + 787d454 commit aaa583a

303 files changed

Lines changed: 9023 additions & 6721 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.

.github/workflows/pr_test_build_linux.yml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
PR_test_build:
1010
runs-on: [Linux, amd64, forlinux]
1111
container:
12-
image: ghcr.io/cake-tech/cake_wallet:debian13-flutter3.32.0-ndkr28-go1.24.1-ruststablenightly
12+
image: ghcr.io/cake-tech/cake_wallet:debian13-flutter3.41.9-ndkr28-go1.24.1-ruststablenightly
1313
env:
1414
STORE_PASS: test@cake_wallet
1515
KEY_PASS: test@cake_wallet
@@ -116,10 +116,18 @@ jobs:
116116
./scripts/prepare_moneroc.sh
117117
mkdir -p scripts/monero_c/release
118118
pushd scripts/monero_c/release
119-
mkdir -p $(git describe --tags)
120-
pushd $(git describe --tags)
119+
TAG=$(git describe --tags)
120+
mkdir -p "$TAG"
121+
pushd "$TAG"
121122
wget https://github.com/MrCyjaneK/monero_c/releases/download/v0.18.4.6-RC2/release-bundle.zip
122123
unzip release-bundle.zip
124+
# RC2's bundle puts everything under an inner v0.18.4.6-*/ dir, strip it
125+
shopt -s nullglob
126+
for inner in v0.18.4.6-*/; do
127+
mv "$inner"* .
128+
rmdir "$inner"
129+
done
130+
shopt -u nullglob
123131
rm release-bundle.zip
124132
popd
125133
popd
@@ -219,6 +227,9 @@ jobs:
219227
xmessage -timeout 30 "restore_wallet_through_seeds_flow_test" &
220228
rm -rf ~/.local/share/com.example.cake_wallet/ ~/Documents/cake_wallet/ ~/cake_wallet
221229
exec timeout --signal=SIGKILL 900 flutter drive --driver=test_driver/integration_test.dart --target=integration_test/test_suites/restore_wallet_through_seeds_flow_test.dart
230+
- name: Test [cw_core]
231+
timeout-minutes: 15
232+
run: cd cw_core && flutter test
222233
- name: Test [cw_monero]
223234
timeout-minutes: 15
224235
run: cd cw_monero && flutter test

.github/workflows/reusable-build.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
PR_test_build:
2222
runs-on: [Linux, amd64, android]
2323
container:
24-
image: ghcr.io/cake-tech/cake_wallet:debian13-flutter3.32.0-ndkr28-go1.24.1-ruststablenightly
24+
image: ghcr.io/cake-tech/cake_wallet:debian13-flutter3.41.9-ndkr28-go1.24.1-ruststablenightly
2525
env:
2626
STORE_PASS: test@cake_wallet
2727
KEY_PASS: test@cake_wallet
@@ -115,6 +115,7 @@ jobs:
115115
run: |
116116
pushd scripts/android
117117
source ./app_env.sh cakewallet
118+
export GITHUB_HUH=yeah
118119
./app_config.sh
119120
popd
120121

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# docker buildx build --push --pull --platform linux/amd64,linux/arm64 . -f Dockerfile -t ghcr.io/cake-tech/cake_wallet:debian13-flutter3.32.0-ndkr28-go1.24.1-ruststablenightly
1+
# docker buildx build --push --pull --platform linux/amd64,linux/arm64 . -f Dockerfile -t ghcr.io/cake-tech/cake_wallet:debian13-flutter3.41.9-ndkr28-go1.24.1-ruststablenightly
22

33
# Heavily inspired by cirrusci images
44
# https://github.com/cirruslabs/docker-images-android/blob/master/sdk/tools/Dockerfile
@@ -15,7 +15,7 @@ LABEL org.opencontainers.image.source=https://github.com/cake-tech/cake_wallet
1515
ENV GOLANG_VERSION=1.24.1
1616

1717
# Pin Flutter version to latest known-working version
18-
ENV FLUTTER_VERSION=3.32.0
18+
ENV FLUTTER_VERSION=3.41.9
1919

2020
# Pin Android Studio, platform, and build tools versions to latest known-working version
2121
# Comes from https://developer.android.com/studio/#command-tools

android/gradle.properties

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
org.gradle.jvmargs=-Xmx6144M
2-
android.enableR8=true
32
android.useAndroidX=true
43
android.enableJetifier=true
5-
android.ndk.suppressMinSdkVersionError=21
4+
android.ndk.suppressMinSdkVersionError=21

android/gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.4-all.zip

android/settings.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ pluginManagement {
1818

1919
plugins {
2020
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
21-
id "com.android.application" version "8.7.1" apply false
22-
id "org.jetbrains.kotlin.android" version "2.0.21" apply false
21+
id "com.android.application" version "8.9.1" apply false
22+
id "org.jetbrains.kotlin.android" version "2.3.20" apply false
2323
id "com.google.gms.google-services" version "4.3.8" apply false
2424
}
2525

cw_bitcoin/lib/bitcoin_wallet.dart

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ import 'package:cw_bitcoin/psbt/signer.dart';
2525
import 'package:cw_bitcoin/psbt/transaction_builder.dart';
2626
import 'package:cw_bitcoin/psbt/v0_deserialize.dart';
2727
import 'package:cw_bitcoin/psbt/v0_finalizer.dart';
28+
import 'package:cw_core/amount/money.dart';
2829
import 'package:cw_core/crypto_currency.dart';
2930
import 'package:cw_core/encryption_file_utils.dart';
3031
import 'package:cw_core/output_info.dart';
31-
import 'package:cw_core/parse_fixed.dart';
3232
import 'package:cw_core/payjoin_session.dart';
3333
import 'package:cw_core/pending_transaction.dart';
3434
import 'package:cw_core/sync_status.dart';
@@ -349,13 +349,15 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
349349

350350
final lBalance = await lightningWallet!.getBalance();
351351

352-
this.balance[CryptoCurrency.btcln] =
353-
ElectrumBalance(confirmed: lBalance.toInt(), unconfirmed: 0, frozen: 0);
352+
this.balance[CryptoCurrency.btcln] = ElectrumBalance(
353+
confirmed: lBalance,
354+
unconfirmed: Money.zero(CryptoCurrency.btcln),
355+
frozen: Money.zero(CryptoCurrency.btcln));
354356

355357
return ElectrumBalance(
356358
confirmed: balance.confirmed,
357359
unconfirmed: balance.unconfirmed,
358-
frozen: balance.frozen.toInt(),
360+
frozen: balance.frozen ?? Money.zero(currency),
359361
);
360362
}
361363

@@ -504,19 +506,19 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
504506
final isLNCompatible = await lightningWallet?.isCompatible(lnAddr);
505507
if ((credentials.coinTypeToSpendFrom == UnspentCoinType.lightning && lightningWallet != null) ||
506508
isLNCompatible == true) {
507-
BigInt amount;
509+
Money amount;
508510
if (credentials.outputs.first.sendAll) {
509511
amount = await lightningWallet!.getBalance();
510512
} else {
511-
amount = parseFixed(
512-
credentials.outputs.first.cryptoAmount?.isNotEmpty == true
513-
? credentials.outputs.first.cryptoAmount!
514-
: "0",
515-
8);
513+
amount = credentials.outputs.first.cryptoAmount;
516514
}
517515

518-
return lightningWallet!.createTransaction(lnAddr, amount > BigInt.zero ? amount : null,
519-
credentials.priority, credentials.outputs.first.sendAll);
516+
517+
return lightningWallet!.createTransaction(
518+
lnAddr,
519+
amount.amount > BigInt.zero ? amount.amount : null,
520+
credentials.priority,
521+
credentials.outputs.first.sendAll,);
520522
}
521523

522524
final tx = (await super.createTransaction(credentials)) as PendingBitcoinTransaction;
@@ -535,7 +537,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
535537
))
536538
.toList(),
537539
cwOutputs: credentials.outputs,
538-
fee: BigInt.from(tx.fee),
540+
fee: tx.fee.amount,
539541
network: network,
540542
memo: credentials.outputs.first.memo,
541543
outputOrdering: BitcoinOrdering.none,
@@ -554,8 +556,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
554556
tx.commitOverride = () async {
555557
final sender =
556558
await payjoinManager.initSender(payjoinUri!, originalPsbt, int.parse(tx.feeRate));
557-
payjoinManager.spawnNewSender(
558-
sender: sender, pjUrl: payjoinUri, amount: BigInt.from(tx.amount));
559+
payjoinManager.spawnNewSender(sender: sender, pjUrl: payjoinUri, amount: tx.amount.amount);
559560
};
560561

561562
return tx;
@@ -575,8 +576,8 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
575576
btcTx,
576577
type,
577578
electrumClient: electrumClient,
578-
amount: 0,
579-
fee: 0,
579+
amount: Money.zero(currency),
580+
fee: Money.zero(currency),
580581
feeRate: "",
581582
network: network,
582583
hasChange: true,
@@ -633,8 +634,8 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
633634
btcTx,
634635
type,
635636
electrumClient: electrumClient,
636-
amount: 0,
637-
fee: 0,
637+
amount: Money.zero(currency),
638+
fee: Money.zero(currency),
638639
feeRate: "",
639640
network: network,
640641
hasChange: true,

cw_bitcoin/lib/bitcoin_wallet_addresses.dart

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,24 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S
153153

154154
@override
155155
String get addressForExchange {
156-
if (addressPageType == LightningAddressType.p2l) {
157-
final addresses = receiveAddresses
158-
.where((element) => element.type == SegwitAddresType.p2wpkh && !element.isUsed);
159-
return addresses.first.address;
156+
157+
final current = getFreshAddress();
158+
final availableReceiveAddresses = receiveAddresses.where((element) =>
159+
!element.isUsed &&
160+
!element.isHidden &&
161+
!hiddenAddresses.contains(element.address));
162+
163+
final bool isSilentPaymentsPage = addressPageType == SilentPaymentsAddresType.p2sp;
164+
final bool isLightningPage = addressPageType == LightningAddressType.p2l;
165+
166+
if (isSilentPaymentsPage || isLightningPage) {
167+
final segwit = availableReceiveAddresses
168+
.where((e) => e.type == SegwitAddresType.p2wpkh)
169+
.map((e) => e.address)
170+
.toList();
171+
172+
return segwit.isNotEmpty ? segwit.first : current;
160173
}
161-
return address;
174+
return current;
162175
}
163176
}
Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,52 @@
11
import 'dart:convert';
22

3+
import 'package:cw_core/amount/money.dart';
34
import 'package:cw_core/balance.dart';
5+
import 'package:cw_core/currency.dart';
46

57
class ElectrumBalance extends Balance {
68
ElectrumBalance({
79
required this.confirmed,
810
required this.unconfirmed,
9-
required int frozen,
10-
this.secondConfirmed = 0,
11-
this.secondUnconfirmed = 0,
12-
}) : this._frozen = frozen, super.fromInt(confirmed, unconfirmed,
13-
secondAvailable: secondConfirmed, secondAdditional: secondUnconfirmed, frozen: frozen);
11+
required this.frozen,
12+
this.secondConfirmed,
13+
this.secondUnconfirmed,
14+
}) : super(confirmed, unconfirmed,
15+
secondAvailable: secondConfirmed, secondUnavailable: secondUnconfirmed);
1416

15-
static ElectrumBalance? fromJSON(String? jsonSource) {
17+
Money confirmed;
18+
Money unconfirmed;
19+
Money? secondConfirmed;
20+
Money? secondUnconfirmed;
21+
22+
@override
23+
Money get available => (confirmed + unconfirmed) - frozen;
24+
25+
@override
26+
Money get unavailable => unconfirmed;
27+
28+
@override
29+
Money frozen;
30+
31+
static ElectrumBalance? fromJSON(String? jsonSource, Currency currency) {
1632
if (jsonSource == null) return null;
1733

1834
final decoded = json.decode(jsonSource) as Map;
1935

2036
return ElectrumBalance(
21-
confirmed: decoded['confirmed'] as int? ?? 0,
22-
unconfirmed: decoded['unconfirmed'] as int? ?? 0,
23-
frozen: decoded['frozen'] as int? ?? 0,
24-
secondConfirmed: decoded['secondConfirmed'] as int? ?? 0,
25-
secondUnconfirmed: decoded['secondUnconfirmed'] as int? ?? 0,
37+
confirmed: Money.fromInt(decoded['confirmed'] as int? ?? 0, currency),
38+
unconfirmed: Money.fromInt(decoded['unconfirmed'] as int? ?? 0, currency),
39+
frozen: Money.fromInt(decoded['frozen'] as int? ?? 0, currency),
40+
secondConfirmed: Money.fromInt(decoded['secondConfirmed'] as int? ?? 0, currency),
41+
secondUnconfirmed: Money.fromInt(decoded['secondUnconfirmed'] as int? ?? 0, currency),
2642
);
2743
}
2844

29-
int confirmed;
30-
int unconfirmed;
31-
final int _frozen;
32-
33-
@override
34-
BigInt get frozen => BigInt.from(_frozen);
35-
36-
int secondConfirmed = 0;
37-
int secondUnconfirmed = 0;
38-
39-
@override
40-
BigInt get fullAvailableBalance => BigInt.from((confirmed + unconfirmed) + secondConfirmed - _frozen);
41-
4245
String toJSON() => json.encode({
43-
'confirmed': confirmed,
44-
'unconfirmed': unconfirmed,
45-
'frozen': _frozen,
46-
'secondConfirmed': secondConfirmed,
47-
'secondUnconfirmed': secondUnconfirmed,
46+
'confirmed': confirmed.amount.toInt(),
47+
'unconfirmed': unavailable.amount.toInt(),
48+
'frozen': frozen.amount.toInt(),
49+
'secondConfirmed': secondAvailable?.amount.toInt() ?? 0,
50+
'secondUnconfirmed': secondUnavailable?.amount.toInt() ?? 0,
4851
});
4952
}

0 commit comments

Comments
 (0)