[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-android] branch master updated (3a12b1c -> f7649e3)
From: |
gnunet |
Subject: |
[taler-taler-android] branch master updated (3a12b1c -> f7649e3) |
Date: |
Tue, 03 Jan 2023 13:38:43 +0100 |
This is an automated email from the git hooks/post-receive script.
torsten-grote pushed a change to branch master
in repository taler-android.
from 3a12b1c [pos] Bump protocol version to 3.0.1
new 20003b8 [pos] Release 0.2.1
new de79f6a [pos] Shorten app title as old title is rejected now as too
long
new 8e7499e Upgrade libraries and wallet core to v0.9.1-dev.1
new 8249966 [common] Fix warnings in Bech32 implementation
new bf70ff2 [wallet] Move to accompanist theme adapter as the old one is
deprecated
new f7649e3 Fix some lint warnings
The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
build.gradle | 8 +-
cashier/build.gradle | 6 +-
cashier/src/main/AndroidManifest.xml | 3 +-
merchant-terminal/build.gradle | 8 +-
merchant-terminal/fastlane/Fastfile | 2 +-
.../fastlane/metadata/android/en-US/title.txt | 2 +-
merchant-terminal/src/main/AndroidManifest.xml | 3 +-
taler-kotlin-android/build.gradle | 4 +-
.../src/main/java/net/taler/common/Bech32.kt | 133 ++++++++++++---------
wallet/build.gradle | 14 +--
wallet/src/main/AndroidManifest.xml | 8 +-
.../java/net/taler/wallet/ReceiveFundsFragment.kt | 19 ++-
.../java/net/taler/wallet/SendFundsFragment.kt | 19 ++-
wallet/src/main/java/net/taler/wallet/Utils.kt | 12 ++
.../net/taler/wallet/deposit/DepositFragment.kt | 22 ++--
.../net/taler/wallet/deposit/PayToUriFragment.kt | 46 ++++---
.../wallet/peer/IncomingPullPaymentFragment.kt | 13 +-
.../wallet/peer/IncomingPushPaymentFragment.kt | 13 +-
.../net/taler/wallet/peer/OutgoingPullFragment.kt | 31 +++--
.../net/taler/wallet/peer/OutgoingPushFragment.kt | 25 ++--
.../transactions/TransactionDepositFragment.kt | 13 +-
.../wallet/transactions/TransactionPeerFragment.kt | 13 +-
.../net/taler/wallet/withdraw/WithdrawManager.kt | 2 +-
.../manual/ManualWithdrawSuccessFragment.kt | 20 ++--
.../taler/wallet/withdraw/WithdrawManagerKtTest.kt | 2 +-
25 files changed, 219 insertions(+), 222 deletions(-)
diff --git a/build.gradle b/build.gradle
index 98886f9..93d8a9b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,15 +1,15 @@
buildscript {
ext {
- kotlin_version = '1.7.20'
- ktor_version = '2.1.0'
+ kotlin_version = '1.7.20' // observe compatibility with compose
compiler
+ ktor_version = '2.1.3'
nav_version = '2.5.3'
material_version = '1.7.0'
lifecycle_version = '2.5.1'
constraintlayout_version = '2.1.4'
- compose_version = '1.3.0'
+ compose_version = '1.3.2'
junit_version = "4.13.2"
// check https://android-rebuilds.beuc.net/ for availability of free
build tools
- build_tools_version = "33.0.0"
+ build_tools_version = "33.0.1"
// should debug build types be minified with D8 as well? good for
catching issues early
minify_debug = true
}
diff --git a/cashier/build.gradle b/cashier/build.gradle
index cd64be5..c238513 100644
--- a/cashier/build.gradle
+++ b/cashier/build.gradle
@@ -22,6 +22,7 @@ plugins {
}
android {
+ namespace 'net.taler.cashier'
compileSdkVersion 33
//noinspection GradleDependency
buildToolsVersion "$build_tools_version"
@@ -69,8 +70,6 @@ android {
ignore 'WrongConstant'
ignoreWarnings false
}
- namespace 'net.taler.cashier'
-
}
dependencies {
@@ -90,7 +89,4 @@ dependencies {
implementation "io.ktor:ktor-server-call-logging:$ktor_version"
testImplementation "junit:junit:$junit_version"
-
- androidTestImplementation 'androidx.test.ext:junit:1.1.3'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
diff --git a/cashier/src/main/AndroidManifest.xml
b/cashier/src/main/AndroidManifest.xml
index 398e545..5230be9 100644
--- a/cashier/src/main/AndroidManifest.xml
+++ b/cashier/src/main/AndroidManifest.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- package="net.taler.cashier">
+ xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
diff --git a/merchant-terminal/build.gradle b/merchant-terminal/build.gradle
index b4a2781..e144a71 100644
--- a/merchant-terminal/build.gradle
+++ b/merchant-terminal/build.gradle
@@ -6,6 +6,7 @@ plugins {
}
android {
+ namespace 'net.taler.merchantpos'
compileSdkVersion 33
//noinspection GradleDependency
buildToolsVersion "$build_tools_version"
@@ -14,8 +15,8 @@ android {
applicationId "net.taler.merchantpos"
minSdkVersion 21
targetSdkVersion 32
- versionCode 2
- versionName "0.1"
+ versionCode 3
+ versionName "0.2.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -59,7 +60,6 @@ android {
ignore 'WrongConstant'
ignoreWarnings false
}
- namespace 'net.taler.merchantpos'
}
dependencies {
@@ -76,6 +76,6 @@ dependencies {
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
- testImplementation 'androidx.test.ext:junit:1.1.3'
+ testImplementation 'androidx.test.ext:junit:1.1.4'
testImplementation 'org.robolectric:robolectric:4.8.1'
}
diff --git a/merchant-terminal/fastlane/Fastfile
b/merchant-terminal/fastlane/Fastfile
index 2398c81..9c09d50 100644
--- a/merchant-terminal/fastlane/Fastfile
+++ b/merchant-terminal/fastlane/Fastfile
@@ -36,7 +36,7 @@ platform :android do
skip_upload_images: 'true',
skip_upload_screenshots: 'true',
skip_upload_apk: 'true', # This is an app bundle, so APK is not
possible
- validate_only: 'true'
+ validate_only: 'false'
)
end
end
diff --git a/merchant-terminal/fastlane/metadata/android/en-US/title.txt
b/merchant-terminal/fastlane/metadata/android/en-US/title.txt
index 235199c..bcc4cea 100644
--- a/merchant-terminal/fastlane/metadata/android/en-US/title.txt
+++ b/merchant-terminal/fastlane/metadata/android/en-US/title.txt
@@ -1 +1 @@
-Taler Point-of-Sale Merchant Terminal
\ No newline at end of file
+Taler Point-of-Sale Terminal
\ No newline at end of file
diff --git a/merchant-terminal/src/main/AndroidManifest.xml
b/merchant-terminal/src/main/AndroidManifest.xml
index 0c814e7..3b23dfc 100644
--- a/merchant-terminal/src/main/AndroidManifest.xml
+++ b/merchant-terminal/src/main/AndroidManifest.xml
@@ -15,8 +15,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- package="net.taler.merchantpos">
+ xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.NFC" />
diff --git a/taler-kotlin-android/build.gradle
b/taler-kotlin-android/build.gradle
index 69d2b75..efd305f 100644
--- a/taler-kotlin-android/build.gradle
+++ b/taler-kotlin-android/build.gradle
@@ -26,8 +26,6 @@ android {
defaultConfig {
minSdkVersion 21
- targetSdkVersion 32
-
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro'
}
@@ -72,7 +70,7 @@ dependencies {
implementation 'com.google.zxing:core:3.5.0' // needs minSdkVersion 24+
or desugar
// JSON parsing and serialization
- api 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.0'
+ api 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1'
testImplementation "junit:junit:$junit_version"
testImplementation 'org.json:json:20220320'
}
diff --git a/taler-kotlin-android/src/main/java/net/taler/common/Bech32.kt
b/taler-kotlin-android/src/main/java/net/taler/common/Bech32.kt
index 32885df..4b77f85 100644
--- a/taler-kotlin-android/src/main/java/net/taler/common/Bech32.kt
+++ b/taler-kotlin-android/src/main/java/net/taler/common/Bech32.kt
@@ -13,6 +13,7 @@
* You should have received a copy of the GNU General Public License along with
* GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
+
// Copyright (c) 2020 Figure Technologies Inc.
// The contents of this file were derived from an implementation
// by the btcsuite developers https://github.com/btcsuite/btcutil.
@@ -23,26 +24,16 @@
// modified version of
https://gist.github.com/iramiller/4ebfcdfbc332a9722c4a4abeb4e16454
-import net.taler.common.CyptoUtils
+package net.taler.common
+
+import java.util.Locale.ROOT
import kotlin.experimental.and
import kotlin.experimental.or
-
infix fun Int.min(b: Int): Int = b.takeIf { this > b } ?: this
infix fun UByte.shl(bitCount: Int) = ((this.toInt() shl bitCount) and
0xff).toUByte()
infix fun UByte.shr(bitCount: Int) = (this.toInt() shr bitCount).toUByte()
-/**
- * Given an array of bytes, associate an HRP and return a Bech32Data instance.
- */
-fun ByteArray.toBech32Data(hrp: String) =
- Bech32Data(hrp, Bech32.convertBits(this, 8, 5, true))
-
-/**
- * Using a string in bech32 encoded address format, parses out and returns a
Bech32Data instance
- */
-fun String.toBech32Data() = Bech32.decode(this)
-
/**
* Bech32 Data encoding instance containing data for encoding as well as a
human readable prefix
*/
@@ -71,6 +62,30 @@ data class Bech32Data(val hrp: String, val fiveBitData:
ByteArray) {
override fun toString(): String {
return "bech32 : ${this.address}\nhuman: ${this.hrp} \nbytes"
}
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as Bech32Data
+
+ if (hrp != other.hrp) return false
+ if (!fiveBitData.contentEquals(other.fiveBitData)) return false
+ if (!data.contentEquals(other.data)) return false
+ if (address != other.address) return false
+ if (!checksum.contentEquals(other.checksum)) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = hrp.hashCode()
+ result = 31 * result + fiveBitData.contentHashCode()
+ result = 31 * result + data.contentHashCode()
+ result = 31 * result + address.hashCode()
+ result = 31 * result + checksum.contentHashCode()
+ return result
+ }
}
/**
@@ -80,32 +95,32 @@ class Bech32 {
companion object {
const val CHECKSUM_SIZE = 6
- const val MIN_VALID_LENGTH = 8
- const val MAX_VALID_LENGTH = 90
+ private const val MIN_VALID_LENGTH = 8
+ private const val MAX_VALID_LENGTH = 90
const val MIN_VALID_CODEPOINT = 33
- const val MAX_VALID_CODEPOINT = 126
+ private const val MAX_VALID_CODEPOINT = 126
const val charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
- val gen = intArrayOf(0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd,
0x2a1462b3)
+ private val gen = intArrayOf(0x3b6a57b2, 0x26508e6d, 0x1ea119fa,
0x3d4233dd, 0x2a1462b3)
fun generateFakeSegwitAddress(reservePub: String?, addr: String):
List<String> {
- if (reservePub == null || reservePub.isEmpty()) return
listOf<String>()
+ if (reservePub == null || reservePub.isEmpty()) return listOf()
val pub = CyptoUtils.decodeCrock(reservePub)
if (pub.size != 32) return listOf()
- val first_rnd = pub.copyOfRange(0,4)
- val second_rnd = pub.copyOfRange(0,4)
+ val firstRnd = pub.copyOfRange(0, 4)
+ val secondRnd = pub.copyOfRange(0, 4)
- first_rnd[0] = first_rnd[0].and(0b0111_1111);
- second_rnd[0] = second_rnd[0].or(0b1000_0000.toByte());
+ firstRnd[0] = firstRnd[0].and(0b0111_1111)
+ secondRnd[0] = secondRnd[0].or(0b1000_0000.toByte())
- val first_part = ByteArray(20);
- first_rnd.copyInto( first_part, 0, 0, 4)
- pub.copyInto( first_part, 4, 0, 16)
+ val firstPart = ByteArray(20)
+ firstRnd.copyInto(firstPart, 0, 0, 4)
+ pub.copyInto(firstPart, 4, 0, 16)
- val second_part = ByteArray(20);
- second_rnd.copyInto( second_part, 0, 0, 4)
- pub.copyInto( second_part, 4, 16, 32)
+ val secondPart = ByteArray(20)
+ secondRnd.copyInto(secondPart, 0, 0, 4)
+ pub.copyInto(secondPart, 4, 16, 32)
val zero = ByteArray(1)
zero[0] = 0
@@ -117,8 +132,8 @@ class Bech32 {
}
return listOf(
- Bech32Data(hrp, zero + convertBits(first_part, 8, 5,
true)).address,
- Bech32Data(hrp, zero + convertBits(second_part, 8, 5,
true)).address,
+ Bech32Data(hrp, zero + convertBits(firstPart, 8, 5,
true)).address,
+ Bech32Data(hrp, zero + convertBits(secondPart, 8, 5,
true)).address,
)
}
@@ -126,22 +141,31 @@ class Bech32 {
* Decodes a Bech32 String
*/
fun decode(bech32: String): Bech32Data {
- require(bech32.length >= MIN_VALID_LENGTH && bech32.length <=
MAX_VALID_LENGTH) { "invalid bech32 string length" }
- require(bech32.toCharArray().none { c -> c.toInt() <
MIN_VALID_CODEPOINT || c.toInt() > MAX_VALID_CODEPOINT })
- { "invalid character in bech32: ${bech32.toCharArray().map { c ->
c.toInt() }
- .filter { c -> c.toInt() < MIN_VALID_CODEPOINT || c.toInt() >
MAX_VALID_CODEPOINT }}" }
+ require(bech32.length in MIN_VALID_LENGTH..MAX_VALID_LENGTH) {
"invalid bech32 string length" }
+ require(bech32.toCharArray()
+ .none { c -> c.code < MIN_VALID_CODEPOINT || c.code >
MAX_VALID_CODEPOINT })
+ {
+ "invalid character in bech32: ${
+ bech32.toCharArray().map { c -> c.code }
+ .filter { c -> c < MIN_VALID_CODEPOINT || c >
MAX_VALID_CODEPOINT }
+ }"
+ }
- require(bech32.equals(bech32.toLowerCase()) ||
bech32.equals(bech32.toUpperCase()))
+ require(bech32 == bech32.lowercase(ROOT) || bech32 ==
bech32.uppercase(ROOT))
{ "bech32 must be either all upper or lower case" }
- require(bech32.substring(1).dropLast(CHECKSUM_SIZE).contains('1'))
{ "invalid index of '1'" }
+ require(bech32.substring(1).dropLast(CHECKSUM_SIZE)
+ .contains('1')) { "invalid index of '1'" }
- val hrp = bech32.substringBeforeLast('1').toLowerCase()
- val dataString = bech32.substringAfterLast('1').toLowerCase()
+ val hrp = bech32.substringBeforeLast('1').lowercase(ROOT)
+ val dataString = bech32.substringAfterLast('1').lowercase(ROOT)
- require(dataString.toCharArray().all { c -> charset.contains(c) })
{ "invalid data encoding character in bech32"}
+ require(dataString.toCharArray()
+ .all { c -> charset.contains(c) }) { "invalid data encoding
character in bech32" }
val dataBytes = dataString.map { c -> charset.indexOf(c).toByte()
}.toByteArray()
- val checkBytes = dataString.takeLast(CHECKSUM_SIZE).map { c ->
charset.indexOf(c).toByte() }.toByteArray()
+ val checkBytes =
+ dataString.takeLast(CHECKSUM_SIZE).map { c ->
charset.indexOf(c).toByte() }
+ .toByteArray()
val actualSum = checksum(hrp,
dataBytes.dropLast(CHECKSUM_SIZE).toTypedArray())
require(1 == polymod(expandHrp(hrp).plus(dataBytes.map { d ->
d.toInt() }))) { "checksum failed: $checkBytes != $actualSum" }
@@ -154,10 +178,10 @@ class Bech32 {
* This process is used to convert from base64 (from 8) to base32 (to
5) or the inverse.
*/
fun convertBits(data: ByteArray, fromBits: Int, toBits: Int, pad:
Boolean): ByteArray {
- require (fromBits in 1..8 && toBits in 1..8) { "only bit groups
between 1 and 8 are supported"}
+ require(fromBits in 1..8 && toBits in 1..8) { "only bit groups
between 1 and 8 are supported" }
// resulting bytes with each containing the toBits bits from the
input set.
- var regrouped = arrayListOf<Byte>()
+ val regrouped = arrayListOf<Byte>()
var nextByte = 0.toUByte()
var filledBits = 0
@@ -174,8 +198,9 @@ class Bech32 {
val remainToBits = toBits - filledBits
// we extract the remaining bits unless that is more than
we need.
- val toExtract = remainFromBits.takeUnless { remainToBits <
remainFromBits } ?: remainToBits
- check(toExtract >= 0) { "extract should be positive"}
+ val toExtract =
+ remainFromBits.takeUnless { remainToBits <
remainFromBits } ?: remainToBits
+ check(toExtract >= 0) { "extract should be positive" }
// move existing bits to the left to make room for bits
toExtract, copy in bits to extract
nextByte = (nextByte shl toExtract) or (b shr (8 -
toExtract))
@@ -218,24 +243,24 @@ class Bech32 {
* Calculates a bech32 checksum based on BIP 173 specification
*/
fun checksum(hrp: String, data: Array<Byte>): ByteArray {
- var values = expandHrp(hrp)
+ val values = expandHrp(hrp)
.plus(data.map { d -> d.toInt() })
- .plus(Array<Int>(6){ _ -> 0}.toIntArray())
+ .plus(Array(6) { 0 }.toIntArray())
- var poly = polymod(values) xor 1
+ val poly = polymod(values) xor 1
return (0..5).map {
- ((poly shr (5 * (5-it))) and 31).toByte()
+ ((poly shr (5 * (5 - it))) and 31).toByte()
}.toByteArray()
}
/**
* Expands the human readable prefix per BIP173 for Checksum encoding
*/
- fun expandHrp(hrp: String) =
- hrp.map { c -> c.toInt() shr 5 }
+ private fun expandHrp(hrp: String) =
+ hrp.map { c -> c.code shr 5 }
.plus(0)
- .plus(hrp.map { c -> c.toInt() and 31 })
+ .plus(hrp.map { c -> c.code and 31 })
.toIntArray()
/**
@@ -243,9 +268,9 @@ class Bech32 {
*/
fun polymod(values: IntArray): Int {
var chk = 1
- return values.map {
- var b = chk shr 25
- chk = ((chk and 0x1ffffff) shl 5) xor it
+ return values.map { num ->
+ val b = chk shr 25
+ chk = ((chk and 0x1ffffff) shl 5) xor num
(0..4).map {
if (((b shr it) and 1) == 1) {
chk = chk xor gen[it]
diff --git a/wallet/build.gradle b/wallet/build.gradle
index d93d971..5836fdd 100644
--- a/wallet/build.gradle
+++ b/wallet/build.gradle
@@ -23,8 +23,8 @@ plugins {
id "de.undercouch.download" version "5.3.0"
}
-def walletCoreVersion = "v0.9.0"
-def walletCoreSha256 =
"5a971f4b8faf8dce2cde6d720c7cf75f9233c399a164dcd98fb37a1b3b491c05"
+def walletCoreVersion = "v0.9.1-dev.1"
+def walletCoreSha256 =
"dae4f51f87bed27fa2caa081c4cfdaaae04093eb782234dd716227af32b84e84"
static def versionCodeEpoch() {
return (new Date().getTime() / 1000).toInteger()
@@ -39,6 +39,7 @@ def gitCommit = { ->
}
android {
+ namespace 'net.taler.wallet'
compileSdkVersion 33
buildToolsVersion "$build_tools_version"
@@ -111,7 +112,6 @@ android {
abortOnError true
ignoreWarnings false
}
- namespace 'net.taler.wallet'
}
dependencies {
@@ -126,12 +126,12 @@ dependencies {
// Compose
implementation 'androidx.activity:activity-compose:1.6.1'
- implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.animation:animation:$compose_version"
implementation "androidx.compose.ui:ui-tooling:$compose_version"
- implementation
"androidx.compose.material:material-icons-extended:$compose_version"
+ implementation "androidx.compose.material:material:1.3.1"
+ implementation "androidx.compose.material:material-icons-extended:1.3.1"
implementation
"androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
- implementation 'com.google.android.material:compose-theme-adapter:1.1.21'
+ implementation
"com.google.accompanist:accompanist-themeadapter-material:0.28.0"
// Lists and Selection
implementation "androidx.recyclerview:recyclerview:1.2.1"
@@ -160,8 +160,6 @@ dependencies {
testImplementation "junit:junit:$junit_version"
testImplementation 'org.json:json:20220320'
- androidTestImplementation 'androidx.test:runner:1.4.0'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
def walletLibraryDir = "src/main/assets"
diff --git a/wallet/src/main/AndroidManifest.xml
b/wallet/src/main/AndroidManifest.xml
index 43ccdd4..23746cd 100644
--- a/wallet/src/main/AndroidManifest.xml
+++ b/wallet/src/main/AndroidManifest.xml
@@ -15,14 +15,15 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- package="net.taler.wallet">
+ xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
/>
+ <uses-permission
+ android:name="android.permission.WRITE_EXTERNAL_STORAGE"
+ android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature
@@ -47,7 +48,6 @@
<activity
android:name=".MainActivity"
android:exported="true"
- android:label="@string/app_name"
android:launchMode="singleTop"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
diff --git a/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt
b/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt
index cf01e59..647512c 100644
--- a/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt
@@ -54,7 +54,6 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
-import com.google.android.material.composethemeadapter.MdcTheme
import net.taler.common.Amount
import net.taler.wallet.exchanges.ExchangeItem
@@ -67,14 +66,12 @@ class ReceiveFundsFragment : Fragment() {
savedInstanceState: Bundle?,
): View = ComposeView(requireContext()).apply {
setContent {
- MdcTheme {
- Surface {
- ReceiveFundsIntro(
- model.transactionManager.selectedCurrency ?: error("No
currency selected"),
- this@ReceiveFundsFragment::onManualWithdraw,
- this@ReceiveFundsFragment::onPeerPull,
- )
- }
+ TalerSurface {
+ ReceiveFundsIntro(
+ model.transactionManager.selectedCurrency ?: error("No
currency selected"),
+ this@ReceiveFundsFragment::onManualWithdraw,
+ this@ReceiveFundsFragment::onPeerPull,
+ )
}
}
}
@@ -179,7 +176,9 @@ private fun ReceiveFundsIntro(
Text(text = stringResource(R.string.receive_withdraw))
}
Button(
- modifier = Modifier.weight(1f).height(IntrinsicSize.Max),
+ modifier = Modifier
+ .weight(1f)
+ .height(IntrinsicSize.Max),
onClick = {
val amount = getAmount(currency, text)
if (amount == null) isError = true
diff --git a/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
b/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
index bb903c3..b16022d 100644
--- a/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
@@ -51,7 +51,6 @@ import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
-import com.google.android.material.composethemeadapter.MdcTheme
import net.taler.common.Amount
class SendFundsFragment : Fragment() {
@@ -64,16 +63,14 @@ class SendFundsFragment : Fragment() {
savedInstanceState: Bundle?,
): View = ComposeView(requireContext()).apply {
setContent {
- MdcTheme {
- Surface {
- SendFundsIntro(
- currency = model.transactionManager.selectedCurrency
- ?: error("No currency selected"),
- hasSufficientBalance = model::hasSufficientBalance,
- onDeposit = this@SendFundsFragment::onDeposit,
- onPeerPush = this@SendFundsFragment::onPeerPush,
- )
- }
+ TalerSurface {
+ SendFundsIntro(
+ currency = model.transactionManager.selectedCurrency
+ ?: error("No currency selected"),
+ hasSufficientBalance = model::hasSufficientBalance,
+ onDeposit = this@SendFundsFragment::onDeposit,
+ onPeerPush = this@SendFundsFragment::onPeerPush,
+ )
}
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/Utils.kt
b/wallet/src/main/java/net/taler/wallet/Utils.kt
index c0ccbed..b9abb31 100644
--- a/wallet/src/main/java/net/taler/wallet/Utils.kt
+++ b/wallet/src/main/java/net/taler/wallet/Utils.kt
@@ -28,7 +28,10 @@ import android.os.Build.VERSION.SDK_INT
import android.widget.Toast
import android.widget.Toast.LENGTH_LONG
import androidx.annotation.RequiresApi
+import androidx.compose.material.Surface
+import androidx.compose.runtime.Composable
import androidx.core.content.getSystemService
+import com.google.accompanist.themeadapter.material.MdcTheme
import net.taler.common.Amount
import net.taler.common.AmountParserException
@@ -83,6 +86,15 @@ private fun connectToWifiDeprecated(context: Context, ssid:
String) {
}
}
+@Composable
+fun TalerSurface(content: @Composable () -> Unit) {
+ MdcTheme {
+ Surface {
+ content()
+ }
+ }
+}
+
fun cleanExchange(exchange: String) = exchange.let {
if (it.startsWith("https://", ignoreCase = true)) it.substring(8) else it
}.trimEnd('/')
diff --git a/wallet/src/main/java/net/taler/wallet/deposit/DepositFragment.kt
b/wallet/src/main/java/net/taler/wallet/deposit/DepositFragment.kt
index 31dc03d..1486f08 100644
--- a/wallet/src/main/java/net/taler/wallet/deposit/DepositFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/deposit/DepositFragment.kt
@@ -53,11 +53,11 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
-import com.google.android.material.composethemeadapter.MdcTheme
import net.taler.common.Amount
import net.taler.common.showError
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
+import net.taler.wallet.TalerSurface
import net.taler.wallet.compose.collectAsStateLifecycleAware
class DepositFragment : Fragment() {
@@ -81,17 +81,15 @@ class DepositFragment : Fragment() {
}
return ComposeView(requireContext()).apply {
setContent {
- MdcTheme {
- Surface {
- val state =
depositManager.depositState.collectAsStateLifecycleAware()
- MakeDepositComposable(
- state = state.value,
- amount = amount,
- presetName = receiverName,
- presetIban = iban,
- onMakeDeposit =
this@DepositFragment::onDepositButtonClicked,
- )
- }
+ TalerSurface {
+ val state =
depositManager.depositState.collectAsStateLifecycleAware()
+ MakeDepositComposable(
+ state = state.value,
+ amount = amount,
+ presetName = receiverName,
+ presetIban = iban,
+ onMakeDeposit =
this@DepositFragment::onDepositButtonClicked,
+ )
}
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/deposit/PayToUriFragment.kt
b/wallet/src/main/java/net/taler/wallet/deposit/PayToUriFragment.kt
index ac1fd59..af43749 100644
--- a/wallet/src/main/java/net/taler/wallet/deposit/PayToUriFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/deposit/PayToUriFragment.kt
@@ -62,11 +62,11 @@ import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
-import com.google.android.material.composethemeadapter.MdcTheme
import net.taler.common.Amount
import net.taler.wallet.AmountResult
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
+import net.taler.wallet.TalerSurface
class PayToUriFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
@@ -82,29 +82,27 @@ class PayToUriFragment : Fragment() {
val currencies = model.getCurrencies()
return ComposeView(requireContext()).apply {
setContent {
- MdcTheme {
- Surface {
- if (currencies.isEmpty()) Text(
- text = stringResource(id =
R.string.payment_balance_insufficient),
- color = colorResource(id = R.color.red),
- ) else if (depositManager.isSupportedPayToUri(uri))
PayToComposable(
- currencies = model.getCurrencies(),
- getAmount = model::createAmount,
- onAmountChosen = { amount ->
- val u = Uri.parse(uri)
- val bundle = bundleOf(
- "amount" to amount.toJSONString(),
- "receiverName" to
u.getQueryParameters("receiver-name")[0],
- "IBAN" to u.pathSegments.last(),
- )
- findNavController().navigate(
- R.id.action_nav_payto_uri_to_nav_deposit,
bundle)
- },
- ) else Text(
- text = stringResource(id = R.string.uri_invalid),
- color = colorResource(id = R.color.red),
- )
- }
+ TalerSurface {
+ if (currencies.isEmpty()) Text(
+ text = stringResource(id =
R.string.payment_balance_insufficient),
+ color = colorResource(id = R.color.red),
+ ) else if (depositManager.isSupportedPayToUri(uri))
PayToComposable(
+ currencies = model.getCurrencies(),
+ getAmount = model::createAmount,
+ onAmountChosen = { amount ->
+ val u = Uri.parse(uri)
+ val bundle = bundleOf(
+ "amount" to amount.toJSONString(),
+ "receiverName" to
u.getQueryParameters("receiver-name")[0],
+ "IBAN" to u.pathSegments.last(),
+ )
+ findNavController().navigate(
+ R.id.action_nav_payto_uri_to_nav_deposit,
bundle)
+ },
+ ) else Text(
+ text = stringResource(id = R.string.uri_invalid),
+ color = colorResource(id = R.color.red),
+ )
}
}
}
diff --git
a/wallet/src/main/java/net/taler/wallet/peer/IncomingPullPaymentFragment.kt
b/wallet/src/main/java/net/taler/wallet/peer/IncomingPullPaymentFragment.kt
index cd2f39b..c5c41d7 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/IncomingPullPaymentFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/IncomingPullPaymentFragment.kt
@@ -20,15 +20,14 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.compose.material.Surface
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
-import com.google.android.material.composethemeadapter.MdcTheme
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
+import net.taler.wallet.TalerSurface
import net.taler.wallet.compose.collectAsStateLifecycleAware
class IncomingPullPaymentFragment : Fragment() {
@@ -49,12 +48,10 @@ class IncomingPullPaymentFragment : Fragment() {
}
return ComposeView(requireContext()).apply {
setContent {
- MdcTheme {
- Surface {
- val state =
peerManager.incomingPullState.collectAsStateLifecycleAware()
- IncomingComposable(state, incomingPull) { terms ->
- peerManager.acceptPeerPullPayment(terms)
- }
+ TalerSurface {
+ val state =
peerManager.incomingPullState.collectAsStateLifecycleAware()
+ IncomingComposable(state, incomingPull) { terms ->
+ peerManager.acceptPeerPullPayment(terms)
}
}
}
diff --git
a/wallet/src/main/java/net/taler/wallet/peer/IncomingPushPaymentFragment.kt
b/wallet/src/main/java/net/taler/wallet/peer/IncomingPushPaymentFragment.kt
index 8429ecc..c0fbad9 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/IncomingPushPaymentFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/IncomingPushPaymentFragment.kt
@@ -20,15 +20,14 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.compose.material.Surface
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
-import com.google.android.material.composethemeadapter.MdcTheme
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
+import net.taler.wallet.TalerSurface
import net.taler.wallet.compose.collectAsStateLifecycleAware
class IncomingPushPaymentFragment : Fragment() {
@@ -49,12 +48,10 @@ class IncomingPushPaymentFragment : Fragment() {
}
return ComposeView(requireContext()).apply {
setContent {
- MdcTheme {
- Surface {
- val state =
peerManager.incomingPushState.collectAsStateLifecycleAware()
- IncomingComposable(state, incomingPush) { terms ->
- peerManager.acceptPeerPushPayment(terms)
- }
+ TalerSurface {
+ val state =
peerManager.incomingPushState.collectAsStateLifecycleAware()
+ IncomingComposable(state, incomingPush) { terms ->
+ peerManager.acceptPeerPushPayment(terms)
}
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt
index 24bedc4..8a226b3 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt
@@ -20,15 +20,14 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.compose.material.Surface
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.findNavController
-import com.google.android.material.composethemeadapter.MdcTheme
import net.taler.common.Amount
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
+import net.taler.wallet.TalerSurface
import net.taler.wallet.compose.collectAsStateLifecycleAware
import net.taler.wallet.exchanges.ExchangeItem
@@ -48,21 +47,19 @@ class OutgoingPullFragment : Fragment() {
val exchangeFlow =
exchangeManager.findExchangeForCurrency(amount.currency)
return ComposeView(requireContext()).apply {
setContent {
- MdcTheme {
- Surface {
- val state =
peerManager.pullState.collectAsStateLifecycleAware()
- if (state.value is OutgoingIntro) {
- val exchangeState =
-
exchangeFlow.collectAsStateLifecycleAware(initial = null)
- OutgoingPullIntroComposable(
- amount = amount,
- exchangeState = exchangeState,
- onCreateInvoice =
this@OutgoingPullFragment::onCreateInvoice,
- )
- } else {
- OutgoingPullResultComposable(state.value) {
- findNavController().popBackStack()
- }
+ TalerSurface {
+ val state =
peerManager.pullState.collectAsStateLifecycleAware()
+ if (state.value is OutgoingIntro) {
+ val exchangeState =
+ exchangeFlow.collectAsStateLifecycleAware(initial
= null)
+ OutgoingPullIntroComposable(
+ amount = amount,
+ exchangeState = exchangeState,
+ onCreateInvoice =
this@OutgoingPullFragment::onCreateInvoice,
+ )
+ } else {
+ OutgoingPullResultComposable(state.value) {
+ findNavController().popBackStack()
}
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushFragment.kt
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushFragment.kt
index ae0ef10..c9b3a78 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushFragment.kt
@@ -20,15 +20,14 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.compose.material.Surface
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.findNavController
-import com.google.android.material.composethemeadapter.MdcTheme
import net.taler.common.Amount
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
+import net.taler.wallet.TalerSurface
import net.taler.wallet.compose.collectAsStateLifecycleAware
class OutgoingPushFragment : Fragment() {
@@ -45,18 +44,16 @@ class OutgoingPushFragment : Fragment() {
} ?: error("no amount passed")
return ComposeView(requireContext()).apply {
setContent {
- MdcTheme {
- Surface {
- val state =
peerManager.pushState.collectAsStateLifecycleAware()
- if (state.value is OutgoingIntro) {
- OutgoingPushIntroComposable(
- amount = amount,
- onSend = this@OutgoingPushFragment::onSend,
- )
- } else {
- OutgoingPushResultComposable(state.value) {
- findNavController().popBackStack()
- }
+ TalerSurface {
+ val state =
peerManager.pushState.collectAsStateLifecycleAware()
+ if (state.value is OutgoingIntro) {
+ OutgoingPushIntroComposable(
+ amount = amount,
+ onSend = this@OutgoingPushFragment::onSend,
+ )
+ } else {
+ OutgoingPushResultComposable(state.value) {
+ findNavController().popBackStack()
}
}
}
diff --git
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionDepositFragment.kt
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionDepositFragment.kt
index 5443942..0162502 100644
---
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionDepositFragment.kt
+++
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionDepositFragment.kt
@@ -20,9 +20,8 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.compose.material.Surface
import androidx.compose.ui.platform.ComposeView
-import com.google.android.material.composethemeadapter.MdcTheme
+import net.taler.wallet.TalerSurface
import net.taler.wallet.deposit.TransactionDepositComposable
class TransactionDepositFragment : TransactionDetailFragment() {
@@ -33,12 +32,10 @@ class TransactionDepositFragment :
TransactionDetailFragment() {
savedInstanceState: Bundle?,
): View = ComposeView(requireContext()).apply {
setContent {
- MdcTheme {
- Surface {
- val t = transaction ?: error("No transaction")
- TransactionDepositComposable(t as TransactionDeposit) {
- onDeleteButtonClicked(t)
- }
+ TalerSurface {
+ val t = transaction ?: error("No transaction")
+ TransactionDepositComposable(t as TransactionDeposit) {
+ onDeleteButtonClicked(t)
}
}
}
diff --git
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionPeerFragment.kt
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionPeerFragment.kt
index b03eb39..52d6095 100644
---
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionPeerFragment.kt
+++
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionPeerFragment.kt
@@ -26,7 +26,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.MaterialTheme
-import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
@@ -37,10 +36,10 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
-import com.google.android.material.composethemeadapter.MdcTheme
import net.taler.common.Amount
import net.taler.common.toAbsoluteTime
import net.taler.wallet.R
+import net.taler.wallet.TalerSurface
import net.taler.wallet.peer.TransactionPeerPullCreditComposable
import net.taler.wallet.peer.TransactionPeerPullDebitComposable
import net.taler.wallet.peer.TransactionPeerPushCreditComposable
@@ -54,12 +53,10 @@ class TransactionPeerFragment : TransactionDetailFragment()
{
savedInstanceState: Bundle?,
): View = ComposeView(requireContext()).apply {
setContent {
- MdcTheme {
- Surface {
- val t = transaction ?: error("No transaction")
- TransactionPeerComposable(t) {
- onDeleteButtonClicked(t)
- }
+ TalerSurface {
+ val t = transaction ?: error("No transaction")
+ TransactionPeerComposable(t) {
+ onDeleteButtonClicked(t)
}
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
b/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
index be285ba..6fdc916 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
@@ -16,7 +16,6 @@
package net.taler.wallet.withdraw
-import Bech32
import android.net.Uri
import android.util.Log
import androidx.annotation.UiThread
@@ -26,6 +25,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
import net.taler.common.Amount
+import net.taler.common.Bech32
import net.taler.common.Event
import net.taler.common.toEvent
import net.taler.wallet.TAG
diff --git
a/wallet/src/main/java/net/taler/wallet/withdraw/manual/ManualWithdrawSuccessFragment.kt
b/wallet/src/main/java/net/taler/wallet/withdraw/manual/ManualWithdrawSuccessFragment.kt
index f019a5b..89ad08b 100644
---
a/wallet/src/main/java/net/taler/wallet/withdraw/manual/ManualWithdrawSuccessFragment.kt
+++
b/wallet/src/main/java/net/taler/wallet/withdraw/manual/ManualWithdrawSuccessFragment.kt
@@ -21,15 +21,14 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.compose.material.Surface
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
-import com.google.android.material.composethemeadapter.MdcTheme
import net.taler.common.startActivitySafe
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
+import net.taler.wallet.TalerSurface
import net.taler.wallet.withdraw.WithdrawStatus
class ManualWithdrawSuccessFragment : Fragment() {
@@ -57,18 +56,15 @@ class ManualWithdrawSuccessFragment : Fragment() {
}
}
setContent {
- MdcTheme {
- Surface {
- when (status) {
- is WithdrawStatus.ManualTransferRequiredBitcoin -> {
- ScreenBitcoin(status, onBankAppClick,
onCancelClick)
- }
- is WithdrawStatus.ManualTransferRequiredIBAN -> {
- ScreenIBAN(status, onBankAppClick, onCancelClick)
- }
+ TalerSurface {
+ when (status) {
+ is WithdrawStatus.ManualTransferRequiredBitcoin -> {
+ ScreenBitcoin(status, onBankAppClick, onCancelClick)
+ }
+ is WithdrawStatus.ManualTransferRequiredIBAN -> {
+ ScreenIBAN(status, onBankAppClick, onCancelClick)
}
}
-
}
}
}
diff --git
a/wallet/src/test/java/net/taler/wallet/withdraw/WithdrawManagerKtTest.kt
b/wallet/src/test/java/net/taler/wallet/withdraw/WithdrawManagerKtTest.kt
index b75e8bf..3072075 100644
--- a/wallet/src/test/java/net/taler/wallet/withdraw/WithdrawManagerKtTest.kt
+++ b/wallet/src/test/java/net/taler/wallet/withdraw/WithdrawManagerKtTest.kt
@@ -16,7 +16,7 @@
package net.taler.wallet.withdraw
-import Bech32.Companion.generateFakeSegwitAddress
+import net.taler.common.Bech32.Companion.generateFakeSegwitAddress
import org.junit.Assert
import org.junit.Test
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-taler-android] branch master updated (3a12b1c -> f7649e3),
gnunet <=
- [taler-taler-android] 02/06: [pos] Shorten app title as old title is rejected now as too long, gnunet, 2023/01/03
- [taler-taler-android] 01/06: [pos] Release 0.2.1, gnunet, 2023/01/03
- [taler-taler-android] 03/06: Upgrade libraries and wallet core to v0.9.1-dev.1, gnunet, 2023/01/03
- [taler-taler-android] 04/06: [common] Fix warnings in Bech32 implementation, gnunet, 2023/01/03
- [taler-taler-android] 06/06: Fix some lint warnings, gnunet, 2023/01/03
- [taler-taler-android] 05/06: [wallet] Move to accompanist theme adapter as the old one is deprecated, gnunet, 2023/01/03