diff options
author | Torsten Grote <t@grobox.de> | 2020-08-18 10:23:38 -0300 |
---|---|---|
committer | Torsten Grote <t@grobox.de> | 2020-08-24 11:56:55 -0300 |
commit | 6f698f4d0ef580a898d3b03e9e8954af4f194037 (patch) | |
tree | f4f59740fad0dfa463d6fc77e0797c9d6eca595e | |
parent | dade0470c7e378c72ac2f2fd2a623416dadbff10 (diff) | |
download | wallet-kotlin-6f698f4d0ef580a898d3b03e9e8954af4f194037.tar.gz wallet-kotlin-6f698f4d0ef580a898d3b03e9e8954af4f194037.tar.bz2 wallet-kotlin-6f698f4d0ef580a898d3b03e9e8954af4f194037.zip |
Migrate to Kotlin 1.4
48 files changed, 252 insertions, 273 deletions
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 69cf9a7..bf94955 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -3,7 +3,16 @@ <JetCodeStyleSettings> <option name="PACKAGES_TO_USE_STAR_IMPORTS"> <value> - <package name="kotlinx.android.synthetic" withSubpackages="true" static="false" /> + <package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" /> + </value> + </option> + <option name="PACKAGES_IMPORT_LAYOUT"> + <value> + <package name="" alias="false" withSubpackages="true" /> + <package name="java" alias="false" withSubpackages="true" /> + <package name="javax" alias="false" withSubpackages="true" /> + <package name="kotlin" alias="false" withSubpackages="true" /> + <package name="" alias="true" withSubpackages="true" /> </value> </option> <option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" /> diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 7c0bb6d..61a9130 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,9 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <project version="4"> <component name="CompilerConfiguration"> - <bytecodeTargetLevel target="1.8"> - <module name="wallet-kotlin.common.jvmMain" target="1.6" /> - <module name="wallet-kotlin.common.jvmTest" target="1.6" /> - </bytecodeTargetLevel> + <bytecodeTargetLevel target="1.8" /> </component> </project>
\ No newline at end of file diff --git a/build.gradle b/build.gradle index c6c9e9f..b8e77d7 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ */ buildscript { - ext.kotlin_version = '1.3.72' + ext.kotlin_version = '1.4.0' repositories { google() jcenter() diff --git a/common/build.gradle b/common/build.gradle index 9ceffc4..0c3572c 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -25,6 +25,8 @@ version '0.0.1' apply plugin: 'maven-publish' kotlin { + explicitApi() + jvm() js { browser { @@ -32,8 +34,6 @@ kotlin { nodejs { } } - // This is for iPhone simulator - // Switch here to iosArm64 (or iosArm32) to build library for iPhone device ios { binaries { framework() @@ -42,12 +42,11 @@ kotlin { linuxX64("linux") sourceSets { - def serialization_version = "0.20.0" + def serialization_version = "1.0.0-RC" commonMain { dependencies { - implementation kotlin('stdlib-common') - implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version" - implementation "com.soywiz.korlibs.klock:klock:1.11.12" + implementation "org.jetbrains.kotlinx:kotlinx-serialization-core:$serialization_version" + implementation "com.soywiz.korlibs.klock:klock:1.12.0" } } commonTest { @@ -58,8 +57,6 @@ kotlin { } jvmMain { dependencies { - implementation kotlin('stdlib-jdk8') - implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version" } } jvmTest { @@ -70,8 +67,6 @@ kotlin { } jsMain { dependencies { - implementation kotlin('stdlib-js') - implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serialization_version" } } jsTest { @@ -82,7 +77,6 @@ kotlin { nativeMain { dependsOn commonMain dependencies { - implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version" } } nativeTest { diff --git a/common/src/commonMain/kotlin/net/taler/lib/common/Amount.kt b/common/src/commonMain/kotlin/net/taler/lib/common/Amount.kt index 213abb3..7635f8c 100644 --- a/common/src/commonMain/kotlin/net/taler/lib/common/Amount.kt +++ b/common/src/commonMain/kotlin/net/taler/lib/common/Amount.kt @@ -16,20 +16,20 @@ package net.taler.lib.common -import kotlinx.serialization.Decoder -import kotlinx.serialization.Encoder import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable import kotlinx.serialization.Serializer +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder import kotlin.math.floor import kotlin.math.pow import kotlin.math.roundToInt -class AmountParserException(msg: String? = null, cause: Throwable? = null) : Exception(msg, cause) -class AmountOverflowException(msg: String? = null, cause: Throwable? = null) : Exception(msg, cause) +public class AmountParserException(msg: String? = null, cause: Throwable? = null) : Exception(msg, cause) +public class AmountOverflowException(msg: String? = null, cause: Throwable? = null) : Exception(msg, cause) @Serializable(with = KotlinXAmountSerializer::class) -data class Amount( +public data class Amount( /** * name of the currency using either a three-character ISO 4217 currency code, * or a regional currency identifier starting with a "*" followed by at most 10 characters. @@ -53,26 +53,26 @@ data class Amount( val fraction: Int ) : Comparable<Amount> { - companion object { + public companion object { private const val FRACTIONAL_BASE: Int = 100000000 // 1e8 private val REGEX_CURRENCY = Regex("""^[-_*A-Za-z0-9]{1,12}$""") - val MAX_VALUE = 2.0.pow(52).toLong() + public val MAX_VALUE: Long = 2.0.pow(52).toLong() private const val MAX_FRACTION_LENGTH = 8 - const val MAX_FRACTION = 99_999_999 + public const val MAX_FRACTION: Int = 99_999_999 - fun zero(currency: String): Amount { + public fun zero(currency: String): Amount { return Amount(checkCurrency(currency), 0, 0) } - fun fromJSONString(str: String): Amount { + public fun fromJSONString(str: String): Amount { val split = str.split(":") if (split.size != 2) throw AmountParserException("Invalid Amount Format") return fromString(split[0], split[1]) } - fun fromString(currency: String, str: String): Amount { + public fun fromString(currency: String, str: String): Amount { // value val valueSplit = str.split(".") val value = checkValue(valueSplit[0].toLongOrNull()) @@ -89,8 +89,8 @@ data class Amount( return Amount(checkCurrency(currency), value, fraction) } - fun min(currency: String): Amount = Amount(currency, 0, 1) - fun max(currency: String): Amount = Amount(currency, MAX_VALUE, MAX_FRACTION) + public fun min(currency: String): Amount = Amount(currency, 0, 1) + public fun max(currency: String): Amount = Amount(currency, MAX_VALUE, MAX_FRACTION) internal fun checkCurrency(currency: String): String { @@ -113,7 +113,7 @@ data class Amount( } - val amountStr: String + public val amountStr: String get() = if (fraction == 0) "$value" else { var f = fraction var fractionStr = "" @@ -124,7 +124,7 @@ data class Amount( "$value.$fractionStr" } - operator fun plus(other: Amount): Amount { + public operator fun plus(other: Amount): Amount { check(currency == other.currency) { "Can only subtract from same currency" } val resultValue = value + other.value + floor((fraction + other.fraction).toDouble() / FRACTIONAL_BASE).toLong() if (resultValue > MAX_VALUE) @@ -133,7 +133,7 @@ data class Amount( return Amount(currency, resultValue, resultFraction) } - operator fun times(factor: Int): Amount { + public operator fun times(factor: Int): Amount { // TODO consider replacing with a faster implementation if (factor == 0) return zero(currency) var result = this @@ -141,7 +141,7 @@ data class Amount( return result } - operator fun minus(other: Amount): Amount { + public operator fun minus(other: Amount): Amount { check(currency == other.currency) { "Can only subtract from same currency" } var resultValue = value var resultFraction = fraction @@ -159,11 +159,11 @@ data class Amount( return Amount(currency, resultValue, resultFraction) } - fun isZero(): Boolean { + public fun isZero(): Boolean { return value == 0L && fraction == 0 } - fun toJSONString(): String { + public fun toJSONString(): String { return "$currency:$amountStr" } @@ -186,8 +186,9 @@ data class Amount( } +@Suppress("EXPERIMENTAL_API_USAGE") @Serializer(forClass = Amount::class) -object KotlinXAmountSerializer: KSerializer<Amount> { +internal object KotlinXAmountSerializer : KSerializer<Amount> { override fun serialize(encoder: Encoder, value: Amount) { encoder.encodeString(value.toJSONString()) } diff --git a/common/src/commonMain/kotlin/net/taler/lib/common/TalerUri.kt b/common/src/commonMain/kotlin/net/taler/lib/common/TalerUri.kt index 8255dc0..724820e 100644 --- a/common/src/commonMain/kotlin/net/taler/lib/common/TalerUri.kt +++ b/common/src/commonMain/kotlin/net/taler/lib/common/TalerUri.kt @@ -16,7 +16,7 @@ package net.taler.lib.common -object TalerUri { +public object TalerUri { private const val SCHEME = "taler://" private const val SCHEME_INSECURE = "taler+http://" @@ -25,7 +25,7 @@ object TalerUri { private const val AUTHORITY_REFUND = "refund" private const val AUTHORITY_TIP = "tip" - data class WithdrawUriResult( + public data class WithdrawUriResult( val bankIntegrationApiBaseUrl: String, val withdrawalOperationId: String ) @@ -33,7 +33,7 @@ object TalerUri { /** * Parses a withdraw URI and returns a bank status URL or null if the URI was invalid. */ - fun parseWithdrawUri(uri: String): WithdrawUriResult? { + public fun parseWithdrawUri(uri: String): WithdrawUriResult? { val (resultScheme, prefix) = when { uri.startsWith(SCHEME, ignoreCase = true) -> { Pair("https://", "${SCHEME}${AUTHORITY_WITHDRAW}/") diff --git a/common/src/commonMain/kotlin/net/taler/lib/common/Time.kt b/common/src/commonMain/kotlin/net/taler/lib/common/Time.kt index 0e5e07c..704a91a 100644 --- a/common/src/commonMain/kotlin/net/taler/lib/common/Time.kt +++ b/common/src/commonMain/kotlin/net/taler/lib/common/Time.kt @@ -24,38 +24,40 @@ import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.JsonTransformingSerializer import kotlinx.serialization.json.contentOrNull +import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.json.longOrNull import net.taler.lib.common.Duration.Companion.FOREVER import kotlin.math.max @Serializable -data class Timestamp( +public data class Timestamp( @SerialName("t_ms") @Serializable(NeverSerializer::class) val ms: Long ) : Comparable<Timestamp> { - companion object { - const val NEVER: Long = -1 - fun now(): Timestamp = Timestamp(DateTime.nowUnixLong()) + public companion object { + private const val NEVER: Long = -1 + public fun now(): Timestamp = Timestamp(DateTime.nowUnixLong()) + public fun never(): Timestamp = Timestamp(NEVER) } /** * Returns a copy of this [Timestamp] rounded to seconds. */ - fun truncateSeconds(): Timestamp { + public fun truncateSeconds(): Timestamp { if (ms == NEVER) return Timestamp(ms) return Timestamp((ms / 1000L) * 1000L) } - operator fun minus(other: Timestamp): Duration = when { + public operator fun minus(other: Timestamp): Duration = when { ms == NEVER -> Duration(FOREVER) other.ms == NEVER -> throw Error("Invalid argument for timestamp comparision") ms < other.ms -> Duration(0) else -> Duration(ms - other.ms) } - operator fun minus(other: Duration): Timestamp = when { + public operator fun minus(other: Duration): Timestamp = when { ms == NEVER -> this other.ms == FOREVER -> Timestamp(0) else -> Timestamp(max(0, ms - other.ms)) @@ -74,7 +76,7 @@ data class Timestamp( } @Serializable -data class Duration( +public data class Duration( /** * Duration in milliseconds. */ @@ -82,24 +84,25 @@ data class Duration( @Serializable(ForeverSerializer::class) val ms: Long ) { - companion object { - const val FOREVER: Long = -1 + public companion object { + internal const val FOREVER: Long = -1 + public fun forever(): Duration = Duration(FOREVER) } } -abstract class MinusOneSerializer(private val keyword: String) : - JsonTransformingSerializer<Long>(Long.serializer(), keyword) { +internal abstract class MinusOneSerializer(private val keyword: String) : + JsonTransformingSerializer<Long>(Long.serializer()) { - override fun readTransform(element: JsonElement): JsonElement { - return if (element.contentOrNull == keyword) return JsonPrimitive(-1) - else super.readTransform(element) + override fun transformDeserialize(element: JsonElement): JsonElement { + return if (element.jsonPrimitive.contentOrNull == keyword) return JsonPrimitive(-1) + else super.transformDeserialize(element) } - override fun writeTransform(element: JsonElement): JsonElement { - return if (element.longOrNull == -1L) return JsonPrimitive(keyword) + override fun transformSerialize(element: JsonElement): JsonElement { + return if (element.jsonPrimitive.longOrNull == -1L) return JsonPrimitive(keyword) else element } } -object NeverSerializer : MinusOneSerializer("never") -object ForeverSerializer : MinusOneSerializer("forever") +internal object NeverSerializer : MinusOneSerializer("never") +internal object ForeverSerializer : MinusOneSerializer("forever") diff --git a/common/src/commonMain/kotlin/net/taler/lib/common/Version.kt b/common/src/commonMain/kotlin/net/taler/lib/common/Version.kt index d3f0ad2..c4dc53d 100644 --- a/common/src/commonMain/kotlin/net/taler/lib/common/Version.kt +++ b/common/src/commonMain/kotlin/net/taler/lib/common/Version.kt @@ -22,13 +22,13 @@ import kotlin.math.sign * Semantic versioning, but libtool-style. * See https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html */ -data class Version( +public data class Version( val current: Int, val revision: Int, val age: Int ) { - companion object { - fun parse(v: String): Version? { + public companion object { + public fun parse(v: String): Version? { val elements = v.split(":") if (elements.size != 3) return null val (currentStr, revisionStr, ageStr) = elements @@ -45,7 +45,7 @@ data class Version( * * Returns a [VersionMatchResult] or null if the given version was null. */ - fun compare(other: Version?): VersionMatchResult? { + public fun compare(other: Version?): VersionMatchResult? { if (other == null) return null val compatible = current - age <= other.current && current >= other.current - other.age @@ -56,7 +56,7 @@ data class Version( /** * Result of comparing two libtool versions. */ - data class VersionMatchResult( + public data class VersionMatchResult( /** * Is the first version compatible with the second? */ diff --git a/common/src/commonTest/kotlin/net/taler/lib/common/TimeTest.kt b/common/src/commonTest/kotlin/net/taler/lib/common/TimeTest.kt index 647e439..3b99931 100644 --- a/common/src/commonTest/kotlin/net/taler/lib/common/TimeTest.kt +++ b/common/src/commonTest/kotlin/net/taler/lib/common/TimeTest.kt @@ -16,34 +16,31 @@ package net.taler.lib.common -import kotlinx.serialization.UnstableDefault -import kotlinx.serialization.json.Json.Default.parse -import kotlinx.serialization.json.Json.Default.stringify -import net.taler.lib.common.Timestamp.Companion.NEVER +import kotlinx.serialization.json.Json.Default.decodeFromString +import kotlinx.serialization.json.Json.Default.encodeToString import kotlin.random.Random import kotlin.test.Test import kotlin.test.assertEquals // TODO test other functionality of Timestamp and Duration -@UnstableDefault class TimeTest { @Test fun testSerialize() { for (i in 0 until 42) { val t = Random.nextLong() - assertEquals("""{"t_ms":$t}""", stringify(Timestamp.serializer(), Timestamp(t))) + assertEquals("""{"t_ms":$t}""", encodeToString(Timestamp.serializer(), Timestamp(t))) } - assertEquals("""{"t_ms":"never"}""", stringify(Timestamp.serializer(), Timestamp(NEVER))) + assertEquals("""{"t_ms":"never"}""", encodeToString(Timestamp.serializer(), Timestamp.never())) } @Test fun testDeserialize() { for (i in 0 until 42) { val t = Random.nextLong() - assertEquals(Timestamp(t), parse(Timestamp.serializer(), """{ "t_ms": $t }""")) + assertEquals(Timestamp(t), decodeFromString(Timestamp.serializer(), """{ "t_ms": $t }""")) } - assertEquals(Timestamp(NEVER), parse(Timestamp.serializer(), """{ "t_ms": "never" }""")) + assertEquals(Timestamp.never(), decodeFromString(Timestamp.serializer(), """{ "t_ms": "never" }""")) } } diff --git a/gradle.properties b/gradle.properties index 1b92c41..f6b9aba 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,8 +2,7 @@ org.gradle.caching=true kotlin.code.style=official -# prevent parallel execution of several compiler instances -kotlin.native.disableCompilerDaemon=true - kotlin.parallel.tasks.in.project=true kotlin.incremental.multiplatform=true +kotlin.mpp.enableGranularSourceSetsMetadata=true +kotlin.native.enableDependencyPropagation=false diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 84337ad..d8c83e0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-all.zip diff --git a/settings.gradle b/settings.gradle index b22748a..a96f385 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,2 @@ -enableFeaturePreview("GRADLE_METADATA") - include ':common' -project(':common').projectDir = file('./common') - include ':wallet' diff --git a/wallet/build.gradle b/wallet/build.gradle index 2e58d15..a050b01 100644 --- a/wallet/build.gradle +++ b/wallet/build.gradle @@ -17,28 +17,38 @@ plugins { id 'org.jetbrains.kotlin.multiplatform' id 'org.jetbrains.kotlin.plugin.serialization' + id 'com.android.library' } group 'net.taler' version '0.0.1' -apply plugin: 'com.android.library' apply plugin: 'maven-publish' kotlin { + explicitApi() + android { repositories { google() maven { url "https://dl.bintray.com/terl/lazysodium-maven" } } + compilations.all { + kotlinOptions.jvmTarget = '1.8' + } } js { browser { + testTask { + useKarma { + useChromeHeadless() + } + } } nodejs { } } - // For ARM, should be changed to iosArm32 or iosArm64 + ios { compilations.main.cinterops { sodium { @@ -52,9 +62,6 @@ kotlin { } } } - // For Linux, should be changed to e.g. linuxX64 - // For MacOS, should be changed to e.g. macosX64 - // For Windows, should be changed to e.g. mingwX64 linuxX64("linux") { compilations.main.cinterops { sodium { @@ -64,8 +71,8 @@ kotlin { } sourceSets { - def coroutines_version = "1.3.8" - def ktor_version = "1.3.2" + def coroutines_version = "1.3.8-native-mt-1.4.0-rc" + def ktor_version = "1.4.0" all { languageSettings { progressiveMode = true @@ -74,10 +81,9 @@ kotlin { } commonMain { dependencies { - implementation kotlin('stdlib-common') api project(path: ":common") - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutines_version" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" implementation "io.ktor:ktor-client-core:$ktor_version" implementation "io.ktor:ktor-client-logging:$ktor_version" implementation "io.ktor:ktor-client-serialization:$ktor_version" @@ -92,11 +98,7 @@ kotlin { } androidMain { dependencies { - implementation kotlin('stdlib-jdk8') - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" - implementation "io.ktor:ktor-client-android:$ktor_version" - implementation "io.ktor:ktor-client-logging-jvm:$ktor_version" - implementation "io.ktor:ktor-client-serialization-jvm:$ktor_version" + implementation "io.ktor:ktor-client-okhttp:$ktor_version" // TODO Android // implementation("com.goterl.lazycode:lazysodium-android:4.2.0@aar") { implementation("com.goterl.lazycode:lazysodium-java:4.3.0") { @@ -107,26 +109,13 @@ kotlin { } androidTest { dependencies { - implementation kotlin('test') implementation kotlin('test-junit') - implementation "io.ktor:ktor-client-mock-jvm:$ktor_version" implementation "org.slf4j:slf4j-simple:1.7.30" } } jsMain { dependencies { - implementation kotlin('stdlib-js') - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutines_version" implementation "io.ktor:ktor-client-js:$ktor_version" - implementation "io.ktor:ktor-client-logging-js:$ktor_version" - implementation "io.ktor:ktor-client-serialization-js:$ktor_version" - // bug: https://github.com/ktorio/ktor/issues/1822 - api npm("text-encoding", '0.7.0') // work-around for above bug - api npm("bufferutil", '4.0.1') // work-around for above bug - api npm("utf-8-validate", '5.0.2') // work-around for above bug - api npm("abort-controller", '3.0.0') // work-around for above bug - api npm("node-fetch", '2.6.0') // work-around for above bug - api npm("fs", '*') // work-around for above bug implementation npm('tweetnacl', '1.0.3') implementation npm('ed2curve', '0.3.0') @@ -136,21 +125,16 @@ kotlin { jsTest { dependencies { implementation kotlin('test-js') - implementation "io.ktor:ktor-client-mock-js:$ktor_version" } } nativeMain { dependsOn commonMain dependencies { - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutines_version" - implementation "io.ktor:ktor-client-logging-native:$ktor_version" - implementation "io.ktor:ktor-client-serialization-native:$ktor_version" } } nativeTest { dependsOn commonTest dependencies { - implementation "io.ktor:ktor-client-mock-native:$ktor_version" } } linuxMain { @@ -159,15 +143,17 @@ kotlin { implementation "io.ktor:ktor-client-curl:$ktor_version" } } + linuxTest { + dependsOn nativeTest + } iosMain { dependsOn nativeMain dependencies { implementation "io.ktor:ktor-client-ios:$ktor_version" } } - configure([targets.linux, targets.iosArm64, targets.iosX64]) { - compilations.main.source(sourceSets.nativeMain) - compilations.test.source(sourceSets.nativeTest) + iosTest { + dependsOn nativeTest } } } diff --git a/wallet/src/androidMain/kotlin/net/taler/lib/wallet/api/WalletFactory.kt b/wallet/src/androidMain/kotlin/net/taler/lib/wallet/api/WalletFactory.kt index c8e1f0f..db6d103 100644 --- a/wallet/src/androidMain/kotlin/net/taler/lib/wallet/api/WalletFactory.kt +++ b/wallet/src/androidMain/kotlin/net/taler/lib/wallet/api/WalletFactory.kt @@ -16,8 +16,8 @@ package net.taler.lib.wallet.api -actual class WalletFactory { - actual fun createWalletApi(): WalletApi { +public actual class WalletFactory { + public actual fun createWalletApi(): WalletApi { TODO("Not yet implemented") } -}
\ No newline at end of file +} diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/crypto/Base32Crockford.kt b/wallet/src/commonMain/kotlin/net/taler/lib/crypto/Base32Crockford.kt index b73f508..88a8ebb 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/crypto/Base32Crockford.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/crypto/Base32Crockford.kt @@ -16,20 +16,18 @@ package net.taler.lib.crypto +internal class EncodingException : Exception("Invalid encoding") -class EncodingException : Exception("Invalid encoding") - - -object Base32Crockford { +internal object Base32Crockford { private fun ByteArray.getIntAt(index: Int): Int { val x = this[index].toInt() return if (x >= 0) x else (x + 256) } - private var encTable = "0123456789ABCDEFGHJKMNPQRSTVWXYZ" + private const val encTable = "0123456789ABCDEFGHJKMNPQRSTVWXYZ" - fun encode(data: ByteArray): String { + public fun encode(data: ByteArray): String { val sb = StringBuilder() val size = data.size var bitBuf = 0 @@ -53,7 +51,7 @@ object Base32Crockford { return sb.toString() } - fun decode(encoded: String): ByteArray { + public fun decode(encoded: String): ByteArray { val size = encoded.length var bitpos = 0 var bitbuf = 0 @@ -122,7 +120,7 @@ object Base32Crockford { * @param stringSize size of the string to decode * @return size of the resulting data in bytes */ - fun calculateDecodedDataLength(stringSize: Int): Int { + internal fun calculateDecodedDataLength(stringSize: Int): Int { return stringSize * 5 / 8 } diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/crypto/Crypto.kt b/wallet/src/commonMain/kotlin/net/taler/lib/crypto/Crypto.kt index 7ca2ba8..39a2014 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/crypto/Crypto.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/crypto/Crypto.kt @@ -36,13 +36,13 @@ internal interface Crypto { fun setupRefreshPlanchet(secretSeed: ByteArray, coinNumber: Int): FreshCoin } -interface HashSha512State { +internal interface HashSha512State { fun update(data: ByteArray): HashSha512State fun final(): ByteArray } -class EddsaKeyPair(val privateKey: ByteArray, val publicKey: ByteArray) -class EcdheKeyPair(val privateKey: ByteArray, val publicKey: ByteArray) -data class FreshCoin(val coinPublicKey: ByteArray, val coinPrivateKey: ByteArray, val bks: ByteArray) { +internal class EddsaKeyPair(val privateKey: ByteArray, val publicKey: ByteArray) +internal class EcdheKeyPair(val privateKey: ByteArray, val publicKey: ByteArray) +internal data class FreshCoin(val coinPublicKey: ByteArray, val coinPrivateKey: ByteArray, val bks: ByteArray) { override fun equals(other: Any?): Boolean { if (this === other) return true if (other == null || this::class != other::class) return false @@ -67,12 +67,12 @@ internal expect object CryptoFactory { private val hexArray = arrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f') -fun ByteArray.toHexString(): String { +public fun ByteArray.toHexString(): String { val hexChars = CharArray(this.size * 2) for (j in this.indices) { val v = (this[j].toInt() and 0xFF) hexChars[j * 2] = hexArray[v ushr 4] hexChars[j * 2 + 1] = hexArray[v and 0x0F] } - return String(hexChars) + return hexChars.concatToString() } diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/crypto/CryptoImpl.kt b/wallet/src/commonMain/kotlin/net/taler/lib/crypto/CryptoImpl.kt index 085b44b..95a9156 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/crypto/CryptoImpl.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/crypto/CryptoImpl.kt @@ -16,7 +16,7 @@ package net.taler.lib.crypto -abstract class CryptoImpl : Crypto { +internal abstract class CryptoImpl : Crypto { companion object { fun Int.toByteArray(): ByteArray { diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/crypto/Deposit.kt b/wallet/src/commonMain/kotlin/net/taler/lib/crypto/Deposit.kt index d63d034..3f6886d 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/crypto/Deposit.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/crypto/Deposit.kt @@ -49,7 +49,7 @@ internal class Deposit(private val crypto: Crypto) { val feeDeposit: Amount, val wireInfoHash: String, val denomPublicKey: String, - val denomSignature: String + val denomSignature: String, ) /** @@ -80,7 +80,7 @@ internal class Deposit(private val crypto: Crypto) { /** * URL of the exchange this coin was withdrawn from. */ - val exchangeBaseUrl: String + val exchangeBaseUrl: String, ) /** @@ -97,7 +97,7 @@ internal class Deposit(private val crypto: Crypto) { .put(Base32Crockford.decode(depositInfo.merchantPublicKey)) .put(Base32Crockford.decode(depositInfo.coinPublicKey)) .build() - val coinPriv = Base32Crockford.decode(depositInfo.coinPrivateKey); + val coinPriv = Base32Crockford.decode(depositInfo.coinPrivateKey) val coinSig = crypto.eddsaSign(d, coinPriv) return CoinDepositPermission( coinPublicKey = depositInfo.coinPublicKey, @@ -105,7 +105,7 @@ internal class Deposit(private val crypto: Crypto) { contribution = depositInfo.spendAmount.toJSONString(), denomPublicKey = depositInfo.denomPublicKey, exchangeBaseUrl = depositInfo.exchangeBaseUrl, - denomSignature = depositInfo.denomSignature + denomSignature = depositInfo.denomSignature, ) } diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/crypto/Kdf.kt b/wallet/src/commonMain/kotlin/net/taler/lib/crypto/Kdf.kt index ffdefb5..dee2486 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/crypto/Kdf.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/crypto/Kdf.kt @@ -30,7 +30,7 @@ internal object Kdf { salt: ByteArray, info: ByteArray, sha256: (ByteArray) -> ByteArray, - sha512: (ByteArray) -> ByteArray + sha512: (ByteArray) -> ByteArray, ): ByteArray { //extract val prk = hmacSha512(salt, ikm, sha512) diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Amount.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Amount.kt index e7ee929..7a63966 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Amount.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Amount.kt @@ -19,7 +19,7 @@ package net.taler.lib.wallet import net.taler.lib.common.Amount import net.taler.lib.crypto.CryptoImpl.Companion.toByteArray -fun Amount.toByteArray() = ByteArray(8 + 4 + 12).apply { +internal fun Amount.toByteArray() = ByteArray(8 + 4 + 12).apply { value.toByteArray().copyInto(this, 0, 0, 8) fraction.toByteArray().copyInto(this, 8, 0, 4) currency.encodeToByteArray().copyInto(this, 12) diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Db.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Db.kt index df809c7..eef0cad 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Db.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Db.kt @@ -39,7 +39,7 @@ internal class FakeDb : Db { private data class Data( val exchanges: HashMap<String, ExchangeRecord> = HashMap(), - val denominations: HashMap<String, ArrayList<DenominationRecord>> = HashMap() + val denominations: HashMap<String, ArrayList<DenominationRecord>> = HashMap(), ) private var data = Data() diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/PaytoUri.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/PaytoUri.kt index 2ae9813..a448f0f 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/PaytoUri.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/PaytoUri.kt @@ -16,10 +16,10 @@ package net.taler.lib.wallet -data class PaytoUri( +internal data class PaytoUri( val targetType: String, val targetPath: String, - val params: Map<String, String> + val params: Map<String, String>, ) { companion object { private const val SCHEMA = "payto://" @@ -38,7 +38,7 @@ data class PaytoUri( val field = it.split('=') if (field.size > 1) put(field[0], field[1]) } - } + }, ) } // end fromString() } diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Time.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Time.kt index 6cb5a5c..957598c 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Time.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Time.kt @@ -19,6 +19,6 @@ package net.taler.lib.wallet import net.taler.lib.common.Timestamp import net.taler.lib.crypto.CryptoImpl.Companion.toByteArray -fun Timestamp.roundedToByteArray(): ByteArray = ByteArray(8).apply { +internal fun Timestamp.roundedToByteArray(): ByteArray = ByteArray(8).apply { (truncateSeconds().ms * 1000L).toByteArray().copyInto(this) } diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Types.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Types.kt index b068bda..0ae6b9b 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Types.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Types.kt @@ -18,7 +18,7 @@ package net.taler.lib.wallet import net.taler.lib.common.Amount -class CoinRecord( +internal class CoinRecord( /** * Where did the coin come from? Used for recouping coins. */ @@ -73,16 +73,16 @@ class CoinRecord( /** * Status of the coin. */ - val status: CoinStatus + val status: CoinStatus, ) -enum class CoinSourceType(val value: String) { +internal enum class CoinSourceType(val value: String) { WITHDRAW("withdraw"), REFRESH("refresh"), - TIP("tip") + TIP("tip"), } -enum class CoinStatus(val value: String) { +internal enum class CoinStatus(val value: String) { /** * Withdrawn and never shown to anybody. @@ -92,6 +92,6 @@ enum class CoinStatus(val value: String) { /** * A coin that has been spent and refreshed. */ - DORMANT("dormant") + DORMANT("dormant"), } diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Utils.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Utils.kt index 498b8a8..5a3b776 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Utils.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/Utils.kt @@ -21,13 +21,11 @@ import io.ktor.client.features.json.JsonFeature import io.ktor.client.features.json.serializer.KotlinxSerializer import io.ktor.client.features.logging.LogLevel import io.ktor.client.features.logging.Logging -import kotlinx.serialization.UnstableDefault import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonConfiguration -fun getDefaultHttpClient(): HttpClient = HttpClient { +internal fun getDefaultHttpClient(): HttpClient = HttpClient { install(JsonFeature) { - serializer = KotlinxSerializer(Json(getJsonConfiguration())) + serializer = KotlinxSerializer(getJson()) } install(Logging) { // level = LogLevel.HEADERS @@ -35,7 +33,6 @@ fun getDefaultHttpClient(): HttpClient = HttpClient { } } -@OptIn(UnstableDefault::class) -internal fun getJsonConfiguration() = JsonConfiguration( +internal fun getJson() = Json { ignoreUnknownKeys = true -) +} diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/Exchanges.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/Exchanges.kt index 2542dd6..b847ebb 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/Exchanges.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/Exchanges.kt @@ -18,12 +18,12 @@ package net.taler.lib.wallet.api import net.taler.lib.wallet.exchange.ExchangeRecord -data class ExchangeListItem( +public data class ExchangeListItem( val exchangeBaseUrl: String, val currency: String, - val paytoUris: List<String> + val paytoUris: List<String>, ) { - companion object { + internal companion object { fun fromExchangeRecord(exchange: ExchangeRecord): ExchangeListItem? { return if (exchange.details == null || exchange.wireInfo == null) null else ExchangeListItem( @@ -31,13 +31,13 @@ data class ExchangeListItem( currency = exchange.details.currency, paytoUris = exchange.wireInfo.accounts.map { it.paytoUri - } + }, ) } } } -data class GetExchangeTosResult( +public data class GetExchangeTosResult( /** * Markdown version of the current ToS. */ @@ -51,5 +51,5 @@ data class GetExchangeTosResult( /** * Version tag of the last ToS that the user has accepted, if any. */ - val acceptedEtag: String? = null + val acceptedEtag: String? = null, ) diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/Version.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/Version.kt index 12916d3..ddf41db 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/Version.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/Version.kt @@ -18,9 +18,9 @@ package net.taler.lib.wallet.api import net.taler.lib.common.Version -class SupportedVersions( - val walletVersion: Version, - val exchangeVersion: Version, - val bankVersion: Version, - val merchantVersion: Version +public class SupportedVersions( + public val walletVersion: Version, + public val exchangeVersion: Version, + public val bankVersion: Version, + public val merchantVersion: Version, ) diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/WalletApi.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/WalletApi.kt index 026c682..995d3cb 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/WalletApi.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/WalletApi.kt @@ -19,11 +19,11 @@ package net.taler.lib.wallet.api import net.taler.lib.common.Amount public interface WalletApi { - fun getVersions(): SupportedVersions - fun getWithdrawalDetailsForUri(talerWithdrawUri: String): WithdrawalDetailsForUri - fun getWithdrawalDetailsForAmount(exchangeBaseUrl: String, amount: Amount): WithdrawalDetails - fun listExchanges(): List<ExchangeListItem> - fun addExchange(exchangeBaseUrl: String): ExchangeListItem - fun getExchangeTos(exchangeBaseUrl: String): GetExchangeTosResult - fun setExchangeTosAccepted(exchangeBaseUrl: String, acceptedEtag: String) + public fun getVersions(): SupportedVersions + public fun getWithdrawalDetailsForUri(talerWithdrawUri: String): WithdrawalDetailsForUri + public fun getWithdrawalDetailsForAmount(exchangeBaseUrl: String, amount: Amount): WithdrawalDetails + public fun listExchanges(): List<ExchangeListItem> + public fun addExchange(exchangeBaseUrl: String): ExchangeListItem + public fun getExchangeTos(exchangeBaseUrl: String): GetExchangeTosResult + public fun setExchangeTosAccepted(exchangeBaseUrl: String, acceptedEtag: String) } diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/WalletFactory.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/WalletFactory.kt index d56f80c..4a72eb7 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/WalletFactory.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/WalletFactory.kt @@ -31,10 +31,10 @@ import net.taler.lib.wallet.operations.Withdraw public expect class WalletFactory { - fun createWalletApi(): WalletApi + public fun createWalletApi(): WalletApi } -internal class WalletApiImpl { +public class WalletApiImpl { private val httpClient: HttpClient = getDefaultHttpClient() private val db: Db = DbFactory().openDb() @@ -43,25 +43,25 @@ internal class WalletApiImpl { private val exchangeManager: Exchange = Exchange(crypto, signature, httpClient, db = db) private val withdrawManager = Withdraw(httpClient, db, crypto, signature, exchangeManager) - fun getVersions(): SupportedVersions { + public fun getVersions(): SupportedVersions { return SupportedVersions( walletVersion = Version(8, 0, 0), exchangeVersion = Version(8, 0, 0), bankVersion = Version(0, 0, 0), - merchantVersion = Version(1, 0, 0) + merchantVersion = Version(1, 0, 0), ) } - suspend fun getWithdrawalDetailsForUri(talerWithdrawUri: String): WithdrawalDetailsForUri { + public suspend fun getWithdrawalDetailsForUri(talerWithdrawUri: String): WithdrawalDetailsForUri { val bankInfo = withdrawManager.getBankInfo(talerWithdrawUri) return WithdrawalDetailsForUri( amount = bankInfo.amount, defaultExchangeBaseUrl = bankInfo.suggestedExchange, - possibleExchanges = emptyList() + possibleExchanges = emptyList(), ) } - suspend fun getWithdrawalDetailsForAmount( + public suspend fun getWithdrawalDetailsForAmount( exchangeBaseUrl: String, amount: Amount ): WithdrawalDetails { @@ -69,37 +69,37 @@ internal class WalletApiImpl { return WithdrawalDetails( tosAccepted = details.exchange.termsOfServiceAccepted, amountRaw = amount, - amountEffective = amount - details.overhead - details.withdrawFee + amountEffective = amount - details.overhead - details.withdrawFee, ) } - suspend fun listExchanges(): List<ExchangeListItem> { + public suspend fun listExchanges(): List<ExchangeListItem> { return db.listExchanges().mapNotNull { exchange -> ExchangeListItem.fromExchangeRecord(exchange) } } - suspend fun addExchange(exchangeBaseUrl: String): ExchangeListItem { + public suspend fun addExchange(exchangeBaseUrl: String): ExchangeListItem { val exchange = exchangeManager.updateFromUrl(exchangeBaseUrl) db.put(exchange) return ExchangeListItem.fromExchangeRecord(exchange) ?: TODO("error handling") } - suspend fun getExchangeTos(exchangeBaseUrl: String): GetExchangeTosResult { + public suspend fun getExchangeTos(exchangeBaseUrl: String): GetExchangeTosResult { val record = db.getExchangeByBaseUrl(exchangeBaseUrl) ?: TODO("error handling") return GetExchangeTosResult( tos = record.termsOfServiceText ?: TODO("error handling"), currentEtag = record.termsOfServiceLastEtag ?: TODO("error handling"), - acceptedEtag = record.termsOfServiceAcceptedEtag + acceptedEtag = record.termsOfServiceAcceptedEtag, ) } - suspend fun setExchangeTosAccepted(exchangeBaseUrl: String, acceptedEtag: String) { + public suspend fun setExchangeTosAccepted(exchangeBaseUrl: String, acceptedEtag: String) { db.transaction { val record = getExchangeByBaseUrl(exchangeBaseUrl) ?: TODO("error handling") val updatedRecord = record.copy( termsOfServiceAcceptedEtag = acceptedEtag, - termsOfServiceAcceptedTimestamp = Timestamp.now() + termsOfServiceAcceptedTimestamp = Timestamp.now(), ) put(updatedRecord) } diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/Withdrawal.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/Withdrawal.kt index 88c96a4..df86881 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/Withdrawal.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/api/Withdrawal.kt @@ -32,7 +32,7 @@ public data class WithdrawalDetailsForUri( /** * A list of exchanges that can be used for this withdrawal */ - val possibleExchanges: List<ExchangeListItem> + val possibleExchanges: List<ExchangeListItem>, ) public data class WithdrawalDetails( @@ -49,5 +49,5 @@ public data class WithdrawalDetails( /** * Amount that will be added to the user's wallet balance. */ - val amountEffective: Amount + val amountEffective: Amount, ) diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/crypto/Planchet.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/crypto/Planchet.kt index fa87348..a343594 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/crypto/Planchet.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/crypto/Planchet.kt @@ -75,7 +75,7 @@ internal class Planchet(private val crypto: Crypto) { denomPubHash = Base32Crockford.encode(denomPubHash), reservePub = req.reservePub, withdrawSig = Base32Crockford.encode(sig), - coinEvHash = Base32Crockford.encode(evHash) + coinEvHash = Base32Crockford.encode(evHash), ) } diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/crypto/Recoup.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/crypto/Recoup.kt index b87eff2..27eb9de 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/crypto/Recoup.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/crypto/Recoup.kt @@ -59,7 +59,7 @@ internal class Recoup(private val crypto: Crypto) { /** * Was the coin refreshed (and thus the recoup should go to the old coin)? */ - val refreshed: Boolean + val refreshed: Boolean, ) /** @@ -78,7 +78,7 @@ internal class Recoup(private val crypto: Crypto) { coinSig = Base32Crockford.encode(coinSig), denomPubHash = coin.denomPubHash, denomSig = coin.denomSig, - refreshed = coin.coinSource === REFRESH + refreshed = coin.coinSource === REFRESH, ) } diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/crypto/Refresh.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/crypto/Refresh.kt index 8098437..42e5f6c 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/crypto/Refresh.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/crypto/Refresh.kt @@ -101,7 +101,7 @@ internal class Refresh(private val crypto: Crypto) { /** * Base URL for the exchange we're doing the refresh with. */ - val exchangeBaseUrl: String + val exchangeBaseUrl: String, ) data class RefreshPlanchetRecord( @@ -120,7 +120,7 @@ internal class Refresh(private val crypto: Crypto) { /** * Blinding key used. */ - val blindingKey: String + val blindingKey: String, ) /** @@ -131,7 +131,7 @@ internal class Refresh(private val crypto: Crypto) { meltCoin: CoinRecord, meltFee: Amount, newCoinDenominations: DenominationSelectionInfo, - kappa: Int = newCoinDenominations.selectedDenominations.size + kappa: Int = newCoinDenominations.selectedDenominations.size, ) : RefreshSessionRecord { return createRefreshSession(exchangeBaseUrl, meltCoin, meltFee, newCoinDenominations, kappa) { crypto.createEcdheKeyPair() @@ -197,7 +197,7 @@ internal class Refresh(private val crypto: Crypto) { blindingKey = Base32Crockford.encode(fresh.bks), coinEv = Base32Crockford.encode(ev), privateKey = Base32Crockford.encode(fresh.coinPrivateKey), - publicKey = Base32Crockford.encode(fresh.coinPublicKey) + publicKey = Base32Crockford.encode(fresh.coinPublicKey), ) planchets.add(planchet) sessionHashState.update(ev) @@ -231,7 +231,7 @@ internal class Refresh(private val crypto: Crypto) { amountRefreshOutput = totalOutput, amountRefreshInput = valueWithFee, timestampCreated = Timestamp.now(), - finishedTimestamp = null + finishedTimestamp = null, ) } @@ -251,7 +251,7 @@ internal class Refresh(private val crypto: Crypto) { newDenominationHash: String, oldCoinPublicKey: String, transferPublicKey: String, - coinEv: String + coinEv: String, ): String { val coinEvHash = crypto.sha512(Base32Crockford.decode(coinEv)) val coinLink = PurposeBuilder(WALLET_COIN_LINK) diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Auditor.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Auditor.kt index 248da8d..996c942 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Auditor.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Auditor.kt @@ -22,7 +22,7 @@ import kotlinx.serialization.Serializable * Auditor information as given by the exchange in /keys. */ @Serializable -data class Auditor( +internal data class Auditor( /** * Auditor's public key. */ @@ -36,14 +36,14 @@ data class Auditor( /** * List of signatures for denominations by the auditor. */ - val denomination_keys: List<AuditorDenomSig> + val denomination_keys: List<AuditorDenomSig>, ) /** * Signature by the auditor that a particular denomination key is audited. */ @Serializable -data class AuditorDenomSig( +internal data class AuditorDenomSig( /** * Denomination public key's hash. */ @@ -52,5 +52,5 @@ data class AuditorDenomSig( /** * The signature. */ - val auditor_sig: String + val auditor_sig: String, ) diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Denomination.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Denomination.kt index a515d96..036e4eb 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Denomination.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Denomination.kt @@ -85,14 +85,14 @@ internal data class Denomination( * Signature over the denomination information by the exchange's master * signing key. */ - val master_sig: String + val master_sig: String, ) { fun toDenominationRecord( baseUrl: String, denomPubHash: ByteArray, isOffered: Boolean, isRevoked: Boolean, - status: DenominationStatus + status: DenominationStatus, ): DenominationRecord = DenominationRecord( denomPub = denom_pub, @@ -110,11 +110,11 @@ internal data class Denomination( stampExpireWithdraw = stamp_expire_withdraw, stampStart = stamp_start, status = status, - value = value + value = value, ) } -enum class DenominationStatus { +internal enum class DenominationStatus { /** * Verification was delayed. */ @@ -128,10 +128,10 @@ enum class DenominationStatus { /** * Verified as invalid. */ - VerifiedBad + VerifiedBad, } -data class DenominationRecord( +internal data class DenominationRecord( /** * Value of one coin of the denomination. */ @@ -201,7 +201,7 @@ data class DenominationRecord( /** * Base URL of the exchange. */ - val exchangeBaseUrl: String + val exchangeBaseUrl: String, ) { fun isWithdrawable(now: Timestamp = Timestamp.now()): Boolean { if (isRevoked) return false // can not use revoked denomination @@ -213,15 +213,13 @@ data class DenominationRecord( } } -data class DenominationSelectionInfo( +internal data class DenominationSelectionInfo( val totalCoinValue: Amount, val totalWithdrawCost: Amount, - val selectedDenominations: List<SelectedDenomination> + val selectedDenominations: List<SelectedDenomination>, ) { fun getEarliestDepositExpiry(): Timestamp { - if (selectedDenominations.isEmpty()) return Timestamp( - Timestamp.NEVER - ) + if (selectedDenominations.isEmpty()) return Timestamp.never() var earliest = selectedDenominations[0].denominationRecord.stampExpireDeposit for (i in 1 until selectedDenominations.size) { val stampExpireDeposit = selectedDenominations[i].denominationRecord.stampExpireDeposit @@ -231,4 +229,4 @@ data class DenominationSelectionInfo( } } -data class SelectedDenomination(val count: Int, val denominationRecord: DenominationRecord) +internal data class SelectedDenomination(val count: Int, val denominationRecord: DenominationRecord) diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Exchange.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Exchange.kt index e685040..9a6f9e2 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Exchange.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Exchange.kt @@ -49,7 +49,7 @@ internal class Exchange( // using the default Http client adds a json Accept header to each request, so we need a different one // because the exchange is returning XML when it doesn't exactly match a mime type. private val httpNoJsonClient: HttpClient = HttpClient(), - private val db: Db = DbFactory().openDb() + private val db: Db = DbFactory().openDb(), ) { companion object { @@ -75,7 +75,7 @@ internal class Exchange( timestampAdded = now, updateStatus = FetchKeys, updateStarted = now, - updateReason = Initial + updateReason = Initial, ).also { db.put(it) } val recordBeforeUpdate = record.copy() @@ -148,7 +148,7 @@ internal class Exchange( denomPubHash = crypto.sha512(Base32Crockford.decode(d.denom_pub)), isOffered = true, isRevoked = false, - status = Unverified + status = Unverified, ) } @@ -166,7 +166,7 @@ internal class Exchange( val valid = signature.verifyWireAccount( paytoUri = a.paytoUri, signature = a.masterSig, - masterPub = record.details.masterPublicKey + masterPub = record.details.masterPublicKey, ) if (!valid) throw Error("Exchange wire account signature invalid") } @@ -178,7 +178,7 @@ internal class Exchange( val valid = signature.verifyWireFee( type = wireMethod, wireFee = wireFee, - masterPub = record.details.masterPublicKey + masterPub = record.details.masterPublicKey, ) if (!valid) throw Error("Exchange wire fee signature invalid") checkCurrency(record.details.currency, wireFee.wireFee) @@ -187,7 +187,7 @@ internal class Exchange( } val wireInfo = ExchangeWireInfo( accounts = wire.accounts.map { ExchangeBankAccount(it.paytoUri) }, - feesForType = wire.fees + feesForType = wire.fees, ) return record.copy(updateStatus = FetchTerms, wireInfo = wireInfo) } diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/ExchangeRecord.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/ExchangeRecord.kt index bb8bbd1..ca1a42a 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/ExchangeRecord.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/ExchangeRecord.kt @@ -21,7 +21,7 @@ import net.taler.lib.common.Timestamp /** * Exchange record as stored in the wallet's database. */ -data class ExchangeRecord( +internal data class ExchangeRecord( /** * Base url of the exchange. */ @@ -80,7 +80,7 @@ data class ExchangeRecord( val updateStatus: ExchangeUpdateStatus, - val updateReason: ExchangeUpdateReason? = null + val updateReason: ExchangeUpdateReason? = null, ) { init { check(baseUrl == Exchange.normalizeUrl(baseUrl)) { "Base URL was not normalized" } @@ -93,7 +93,7 @@ data class ExchangeRecord( /** * Details about the exchange that we only know after querying /keys and /wire. */ -data class ExchangeDetails( +internal data class ExchangeDetails( /** * Master public key of the exchange. */ @@ -123,20 +123,20 @@ data class ExchangeDetails( /** * Timestamp for last update. */ - val lastUpdateTime: Timestamp + val lastUpdateTime: Timestamp, ) -data class ExchangeWireInfo( +internal data class ExchangeWireInfo( val feesForType: Map<String, List<WireFee>>, - val accounts: List<ExchangeBankAccount> + val accounts: List<ExchangeBankAccount>, ) // TODO is this class needed? -data class ExchangeBankAccount( - val paytoUri: String +internal data class ExchangeBankAccount( + val paytoUri: String, ) -sealed class ExchangeUpdateStatus(val value: String) { +internal sealed class ExchangeUpdateStatus(val value: String) { object FetchKeys : ExchangeUpdateStatus("fetch-keys") object FetchWire : ExchangeUpdateStatus("fetch-wire") object FetchTerms : ExchangeUpdateStatus("fetch-terms") @@ -144,7 +144,7 @@ sealed class ExchangeUpdateStatus(val value: String) { object Finished : ExchangeUpdateStatus("finished") } -sealed class ExchangeUpdateReason(val value: String) { +internal sealed class ExchangeUpdateReason(val value: String) { object Initial : ExchangeUpdateReason("initial") object Forced : ExchangeUpdateReason("forced") object Scheduled : ExchangeUpdateReason("scheduled") diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Keys.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Keys.kt index 12b29db..2a1b0fa 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Keys.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Keys.kt @@ -60,7 +60,7 @@ internal data class Keys( /** * Protocol version. */ - val version: String + val version: String, ) { companion object { /** @@ -76,12 +76,12 @@ internal data class Keys( * Structure of one exchange signing key in the /keys response. */ @Serializable -data class SigningKey( +internal data class SigningKey( val stamp_start: Timestamp, val stamp_expire: Timestamp, val stamp_end: Timestamp, val key: String, - val master_sig: String + val master_sig: String, ) /** @@ -89,9 +89,9 @@ data class SigningKey( * exchange gives us in /keys. */ @Serializable -data class Recoup( +internal data class Recoup( /** * The hash of the denomination public key for which the payback is offered. */ - val h_denom_pub: String + val h_denom_pub: String, ) diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Wire.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Wire.kt index 0dca4dd..670a0b9 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Wire.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/exchange/Wire.kt @@ -39,18 +39,18 @@ internal data class Wire( } @Serializable -data class AccountInfo( +internal data class AccountInfo( @SerialName("payto_uri") val paytoUri: String, @SerialName("master_sig") - val masterSig: String + val masterSig: String, ) /** * Wire fees as announced by the exchange. */ @Serializable -data class WireFee( +internal data class WireFee( /** * Fee for wire transfers. */ @@ -75,5 +75,5 @@ data class WireFee( * Signature made by the exchange master key. */ @SerialName("sig") - val signature: String + val signature: String, ) diff --git a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/operations/Withdraw.kt b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/operations/Withdraw.kt index 84851ba..d8e83da 100644 --- a/wallet/src/commonMain/kotlin/net/taler/lib/wallet/operations/Withdraw.kt +++ b/wallet/src/commonMain/kotlin/net/taler/lib/wallet/operations/Withdraw.kt @@ -47,7 +47,7 @@ internal class Withdraw( private val signature: Signature = Signature( crypto ), - private val exchange: Exchange = Exchange(crypto, signature, httpClient, db = db) + private val exchange: Exchange = Exchange(crypto, signature, httpClient, db = db), ) { data class BankDetails( @@ -58,7 +58,7 @@ internal class Withdraw( val suggestedExchange: String?, val confirmTransferUrl: String?, val wireTypes: List<String>, - val extractedStatusUrl: String + val extractedStatusUrl: String, ) @Serializable @@ -75,7 +75,7 @@ internal class Withdraw( @SerialName("suggested_exchange") val suggestedExchange: String?, @SerialName("confirm_transfer_url") - val confirmTransferUrl: String? + val confirmTransferUrl: String?, ) { fun toBankDetails(extractedStatusUrl: String) = BankDetails( amount = amount, @@ -85,7 +85,7 @@ internal class Withdraw( senderPaytoUri = senderPaytoUri, suggestedExchange = suggestedExchange, transferDone = transferDone, - wireTypes = wireTypes + wireTypes = wireTypes, ) } @@ -135,7 +135,7 @@ internal class Withdraw( * Number of currently offered denominations. */ // TODO what is this needed for? - val numOfferedDenoms: Int + val numOfferedDenoms: Int, ) { init { check(exchange.details != null) @@ -167,7 +167,7 @@ internal class Withdraw( internal suspend fun getWithdrawalDetails( exchangeBaseUrl: String, - amount: Amount + amount: Amount, ): WithdrawalDetails { val exchange = exchange.updateFromUrl(exchangeBaseUrl) check(exchange.details != null) @@ -182,7 +182,7 @@ internal class Withdraw( withdrawFee = selectedDenominations.totalWithdrawCost - selectedDenominations.totalCoinValue, overhead = amount - selectedDenominations.totalWithdrawCost, earliestDepositExpiration = selectedDenominations.getEarliestDepositExpiry(), - numOfferedDenoms = possibleDenominations.size + numOfferedDenoms = possibleDenominations.size, ) } @@ -192,7 +192,7 @@ internal class Withdraw( */ internal suspend fun selectDenominations( exchange: ExchangeRecord, - amount: Amount + amount: Amount, ): DenominationSelectionInfo { val exchangeDetails = exchange.details ?: throw Error("Exchange $exchange details not available.") @@ -234,7 +234,7 @@ internal class Withdraw( */ fun getDenominationSelection( amount: Amount, - denoms: List<DenominationRecord> + denoms: List<DenominationRecord>, ): DenominationSelectionInfo { val selectedDenominations = ArrayList<SelectedDenomination>() var totalCoinValue = Amount.zero(amount.currency) @@ -265,7 +265,7 @@ internal class Withdraw( return DenominationSelectionInfo( selectedDenominations = selectedDenominations, totalCoinValue = totalCoinValue, - totalWithdrawCost = totalWithdrawCost + totalWithdrawCost = totalWithdrawCost, ) } diff --git a/wallet/src/commonTest/kotlin/net/taler/lib/wallet/TestUtils.kt b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/TestUtils.kt index 14c3076..2b306d8 100644 --- a/wallet/src/commonTest/kotlin/net/taler/lib/wallet/TestUtils.kt +++ b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/TestUtils.kt @@ -18,7 +18,7 @@ package net.taler.lib.wallet import io.ktor.client.HttpClient import io.ktor.client.engine.mock.MockEngine -import io.ktor.client.engine.mock.MockEngineConfig +import io.ktor.client.engine.mock.MockRequestHandler import io.ktor.client.engine.mock.respond import io.ktor.client.features.json.JsonFeature import io.ktor.client.features.json.serializer.KotlinxSerializer @@ -28,7 +28,7 @@ import io.ktor.http.fullPath import io.ktor.http.headersOf import io.ktor.http.hostWithPort import kotlinx.coroutines.CoroutineScope -import kotlinx.serialization.json.Json +import kotlin.native.concurrent.ThreadLocal enum class PlatformTarget { ANDROID, @@ -43,19 +43,24 @@ expect fun runCoroutine(block: suspend (scope: CoroutineScope) -> Unit) expect fun getPlatformTarget(): PlatformTarget +@ThreadLocal +object ChangeableRequestHandler { + var myHandler: MockRequestHandler = { _ -> + error("No HttpClient request handler added. Use e.g. giveJsonResponse()") + } +} + fun getMockHttpClient(): HttpClient = HttpClient(MockEngine) { install(JsonFeature) { - serializer = KotlinxSerializer(Json(getJsonConfiguration())) + serializer = KotlinxSerializer(getJson()) } engine { - addHandler { error("No test handler added") } + addHandler { ChangeableRequestHandler.myHandler(this, it) } } } -fun HttpClient.giveJsonResponse(url: String, jsonProducer: () -> String) { - val httpConfig = engineConfig as MockEngineConfig - httpConfig.requestHandlers.removeAt(0) - httpConfig.requestHandlers.add { request -> +fun giveJsonResponse(url: String, jsonProducer: () -> String) { + ChangeableRequestHandler.myHandler = { request -> if (request.url.fullUrl == url) { val headers = headersOf("Content-Type" to listOf(Application.Json.toString())) respond(jsonProducer(), headers = headers) diff --git a/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/DenominationTest.kt b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/DenominationTest.kt index c52638b..c9e4b22 100644 --- a/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/DenominationTest.kt +++ b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/DenominationTest.kt @@ -18,7 +18,6 @@ package net.taler.lib.wallet.exchange import net.taler.lib.common.Amount import net.taler.lib.common.Timestamp -import net.taler.lib.common.Timestamp.Companion.NEVER import net.taler.lib.wallet.exchange.DenominationStatus.VerifiedBad import net.taler.lib.wallet.exchange.DenominationStatus.VerifiedGood import net.taler.lib.wallet.exchange.Denominations.denomination1 @@ -40,7 +39,7 @@ class DenominationTest { totalWithdrawCost = Amount.zero("TESTKUDOS"), selectedDenominations = emptyList() ) - assertEquals(Timestamp(NEVER), infoEmpty.getEarliestDepositExpiry()) + assertEquals(Timestamp.never(), infoEmpty.getEarliestDepositExpiry()) // earliest expiry of single denomination is that of the denomination val info1 = infoEmpty.copy( @@ -61,7 +60,7 @@ class DenominationTest { // denomination that expires at all is earlier than the one that never expires val info3 = infoEmpty.copy( selectedDenominations = listOf( - SelectedDenomination(2, denomination2.copy(stampExpireDeposit = Timestamp(NEVER))), + SelectedDenomination(2, denomination2.copy(stampExpireDeposit = Timestamp.never())), SelectedDenomination(1, denomination1.copy(stampExpireDeposit = Timestamp(1))) ) ) diff --git a/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/Denominations.kt b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/Denominations.kt index 10a2772..90b9f6a 100644 --- a/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/Denominations.kt +++ b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/Denominations.kt @@ -21,7 +21,7 @@ import net.taler.lib.common.Timestamp import net.taler.lib.wallet.exchange.DenominationStatus.Unverified import net.taler.lib.wallet.exchange.DenominationStatus.VerifiedGood -object Denominations { +internal object Denominations { private val validStart = Timestamp.now() private val validExpireWithdraw = diff --git a/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/KeysTest.kt b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/KeysTest.kt index a40c7cd..a0657b4 100644 --- a/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/KeysTest.kt +++ b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/KeysTest.kt @@ -134,7 +134,7 @@ class KeysTest { version = "7:0:0" ) - httpClient.giveJsonResponse("https://exchange.test.taler.net/keys") { + giveJsonResponse("https://exchange.test.taler.net/keys") { """{ "version": "7:0:0", "master_public_key": "DY95EXAHQ2BKM2WK9YHZHYG1R7PPMMJPY14FNGP662DAKE35AKQG", diff --git a/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/WireTest.kt b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/WireTest.kt index 16671a9..aa9e906 100644 --- a/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/WireTest.kt +++ b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/WireTest.kt @@ -84,7 +84,7 @@ class WireTest { ) ) ) - httpClient.giveJsonResponse("https://exchange.test.taler.net/wire") { + giveJsonResponse("https://exchange.test.taler.net/wire") { """{ "accounts": [ { diff --git a/wallet/src/commonTest/kotlin/net/taler/lib/wallet/operations/WithdrawTest.kt b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/operations/WithdrawTest.kt index 634a9dd..e03681e 100644 --- a/wallet/src/commonTest/kotlin/net/taler/lib/wallet/operations/WithdrawTest.kt +++ b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/operations/WithdrawTest.kt @@ -64,7 +64,7 @@ internal class WithdrawTest { transferDone = false, wireTypes = listOf("x-taler-bank") ) - httpClient.giveJsonResponse(bankDetails.extractedStatusUrl) { + giveJsonResponse(bankDetails.extractedStatusUrl) { """{ "selection_done": ${bankDetails.selectionDone}, "transfer_done": ${bankDetails.transferDone}, diff --git a/wallet/src/jsMain/kotlin/net/taler/lib/wallet/api/WalletFactory.kt b/wallet/src/jsMain/kotlin/net/taler/lib/wallet/api/WalletFactory.kt index c8e1f0f..db6d103 100644 --- a/wallet/src/jsMain/kotlin/net/taler/lib/wallet/api/WalletFactory.kt +++ b/wallet/src/jsMain/kotlin/net/taler/lib/wallet/api/WalletFactory.kt @@ -16,8 +16,8 @@ package net.taler.lib.wallet.api -actual class WalletFactory { - actual fun createWalletApi(): WalletApi { +public actual class WalletFactory { + public actual fun createWalletApi(): WalletApi { TODO("Not yet implemented") } -}
\ No newline at end of file +} diff --git a/wallet/src/nativeMain/kotlin/net/taler/lib/wallet/api/WalletFactory.kt b/wallet/src/nativeMain/kotlin/net/taler/lib/wallet/api/WalletFactory.kt index 9fdf7e7..1f7e625 100644 --- a/wallet/src/nativeMain/kotlin/net/taler/lib/wallet/api/WalletFactory.kt +++ b/wallet/src/nativeMain/kotlin/net/taler/lib/wallet/api/WalletFactory.kt @@ -19,8 +19,8 @@ package net.taler.lib.wallet.api import kotlinx.coroutines.runBlocking import net.taler.lib.common.Amount -actual class WalletFactory { - actual fun createWalletApi(): WalletApi { +public actual class WalletFactory { + public actual fun createWalletApi(): WalletApi { return WalletApiBlocking() } } |