diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ce408284..1c9482ca 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,7 +38,7 @@ jobs: - name: Publish Linux if: matrix.os == 'ubuntu-latest' shell: bash - run: ./gradlew publishLinuxPublicationToMavenLocal + run: ./gradlew publishLinuxX64PublicationToMavenLocal - name: Publish MacOS if: matrix.os == 'macOS-latest' shell: bash diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index ae1df0c8..c3e08646 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -46,7 +46,7 @@ jobs: - name: Publish Linux to Maven Local if: matrix.os == 'ubuntu-latest' shell: bash - run: ./gradlew publishLinuxPublicationToMavenLocal + run: ./gradlew publishLinuxX64PublicationToMavenLocal - name: Publish MacOS to Maven Local if: matrix.os == 'macOS-latest' shell: bash diff --git a/build.gradle.kts b/build.gradle.kts index 668b435b..ac6986ab 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,15 +4,15 @@ import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeHostTest import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeSimulatorTest plugins { - kotlin("multiplatform") version "1.8.21" - id("org.jetbrains.dokka") version "1.8.10" + kotlin("multiplatform") version "1.9.22" + id("org.jetbrains.dokka") version "1.9.10" `maven-publish` } val currentOs = org.gradle.internal.os.OperatingSystem.current() group = "fr.acinq.bitcoin" -version = "0.15.0" +version = "0.16.0-SNAPSHOT" repositories { google() @@ -30,14 +30,22 @@ kotlin { } } - linuxX64("linux") + linuxX64() - ios { + iosX64 { + compilations["main"].cinterops.create("CoreCrypto") + } + + iosArm64 { + compilations["main"].cinterops.create("CoreCrypto") + } + + iosSimulatorArm64 { compilations["main"].cinterops.create("CoreCrypto") } sourceSets { - val secp256k1KmpVersion = "0.12.0" + val secp256k1KmpVersion = "0.13.0" val commonMain by getting { dependencies { @@ -48,7 +56,7 @@ kotlin { dependencies { implementation(kotlin("test-common")) implementation(kotlin("test-annotations-common")) - implementation("org.kodein.memory:kodein-memory-files:0.7.0") + implementation("org.kodein.memory:klio-files:0.12.0") api("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0") } } @@ -76,12 +84,18 @@ kotlin { compilations.all { kotlinOptions { allWarningsAsErrors = true + // We use expect/actual for classes (see Chacha20Poly1305CipherFunctions). This feature is in beta and raises a warning. + // See https://youtrack.jetbrains.com/issue/KT-61573 + kotlinOptions.freeCompilerArgs += "-Xexpect-actual-classes" } } } } configurations.forEach { + // do not cache changing (i.e. SNAPSHOT) dependencies + it.resolutionStrategy.cacheChangingModulesFor(0, TimeUnit.SECONDS) + if (it.name.contains("testCompileClasspath")) { it.attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, "java-runtime")) } @@ -94,7 +108,7 @@ plugins.withId("org.jetbrains.kotlin.multiplatform") { val currentOs = org.gradle.internal.os.OperatingSystem.current() val targets = when { currentOs.isLinux -> listOf() - else -> listOf("linux") + else -> listOf("linuxX64") }.mapNotNull { kotlin.targets.findByName(it) as? org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget } configure(targets) { diff --git a/publishing/PUBLISHING.md b/publishing/PUBLISHING.md new file mode 100644 index 00000000..9a3b4b3c --- /dev/null +++ b/publishing/PUBLISHING.md @@ -0,0 +1,21 @@ +# Publishing bitcoin-kmp artifacts + +## snapshots + +Snapshots are published to the Sonatype snapshot repository (https://oss.sonatype.org/content/repositories/snapshots/). +To publish a snapshot, you must add your sonatype credentials for the `ossrh` server to your local maven settings (typically in $HOME/.m2/settings.xml) + +- Download `snapshot.zip` generated by the `Publish snapshot` github action +- unzip `snapshot.zip` in the `publishing` directory +- run `bitcoin-kmp-snapshot-deploy.sh` + +## releases + +Releases are published to the Sonatype staging repository. If all items are valid they will be published to the `maven central` repository. +You must edit `bitcoin-kmp-staging-upload.sh` and add your sonatype credentials. You must also have a valid GPG key. + +- Download `release.zip` generated by the `Publish release` github action (which is triggered every time you publish a github release) +- unzip `release.zip` in the `publishing` directory +- sign all artifacts with a valid gpg key: `find release -type f -print -exec gpg -ab {} \;` +- run `bitcoin-kmp-staging-upload.sh` +- log into sonatype, close and publish your staging repository. Artifacts will be available on Maven Central within a few hours. diff --git a/publishing/bitcoin-kmp-snapshot-deploy.sh b/publishing/bitcoin-kmp-snapshot-deploy.sh new file mode 100755 index 00000000..2d5024c1 --- /dev/null +++ b/publishing/bitcoin-kmp-snapshot-deploy.sh @@ -0,0 +1,56 @@ +#!/bin/bash -x + +GROUP_ID=fr.acinq.bitcoin +ARTIFACT_ID_BASE=bitcoin-kmp + +if [[ -z "${VERSION}" ]]; then + echo "VERSION is not defined" + exit 1 +fi + +cd snapshot +pushd . +cd fr/acinq/bitcoin/bitcoin-kmp/$VERSION +mvn deploy:deploy-file -DrepositoryId=ossrh -Durl=https://oss.sonatype.org/content/repositories/snapshots/ \ + -DpomFile=$ARTIFACT_ID_BASE-$VERSION.pom \ + -Dfile=$ARTIFACT_ID_BASE-$VERSION.jar \ + -Dfiles=$ARTIFACT_ID_BASE-$VERSION.module,$ARTIFACT_ID_BASE-$VERSION-kotlin-tooling-metadata.json \ + -Dtypes=module,json \ + -Dclassifiers=,kotlin-tooling-metadata \ + -Dsources=$ARTIFACT_ID_BASE-$VERSION-sources.jar \ + -Djavadoc=$ARTIFACT_ID_BASE-$VERSION-javadoc.jar +popd +pushd . +for i in iosarm64 iossimulatorarm64 iosx64 jvm linuxx64; do + cd fr/acinq/bitcoin/bitcoin-kmp-$i/$VERSION + if [ $i == iosarm64 ] || [ $i == iossimulatorarm64 ] || [ $i == iosx64 ]; then + mvn deploy:deploy-file -DrepositoryId=ossrh -Durl=https://oss.sonatype.org/content/repositories/snapshots/ \ + -DpomFile=$ARTIFACT_ID_BASE-$i-$VERSION.pom \ + -Dfile=$ARTIFACT_ID_BASE-$i-$VERSION.klib \ + -Dfiles=$ARTIFACT_ID_BASE-$i-$VERSION-metadata.jar,$ARTIFACT_ID_BASE-$i-$VERSION.module,$ARTIFACT_ID_BASE-$i-$VERSION-cinterop-CoreCrypto.klib \ + -Dtypes=jar,module,klib \ + -Dclassifiers=metadata,,cinterop-CoreCrypto \ + -Dsources=$ARTIFACT_ID_BASE-$i-$VERSION-sources.jar \ + -Djavadoc=$ARTIFACT_ID_BASE-$i-$VERSION-javadoc.jar + elif [ $i == linuxx64 ]; then + mvn deploy:deploy-file -DrepositoryId=ossrh -Durl=https://oss.sonatype.org/content/repositories/snapshots/ \ + -DpomFile=$ARTIFACT_ID_BASE-$i-$VERSION.pom \ + -Dfile=$ARTIFACT_ID_BASE-$i-$VERSION.klib \ + -Dfiles=$ARTIFACT_ID_BASE-$i-$VERSION.module \ + -Dtypes=module \ + -Dclassifiers= \ + -Dsources=$ARTIFACT_ID_BASE-$i-$VERSION-sources.jar \ + -Djavadoc=$ARTIFACT_ID_BASE-$i-$VERSION-javadoc.jar + else + mvn deploy:deploy-file -DrepositoryId=ossrh -Durl=https://oss.sonatype.org/content/repositories/snapshots/ \ + -DpomFile=$ARTIFACT_ID_BASE-$i-$VERSION.pom \ + -Dfile=$ARTIFACT_ID_BASE-$i-$VERSION.jar \ + -Dfiles=$ARTIFACT_ID_BASE-$i-$VERSION.module \ + -Dtypes=module \ + -Dclassifiers= \ + -Dsources=$ARTIFACT_ID_BASE-$i-$VERSION-sources.jar \ + -Djavadoc=$ARTIFACT_ID_BASE-$i-$VERSION-javadoc.jar + fi + popd + pushd . +done diff --git a/publishing/bitcoin-kmp-staging-upload.sh b/publishing/bitcoin-kmp-staging-upload.sh new file mode 100755 index 00000000..dacb2260 --- /dev/null +++ b/publishing/bitcoin-kmp-staging-upload.sh @@ -0,0 +1,31 @@ +#!/bin/bash -x +# +# first you must sign all files with something like: +# find release -type f -print -exec gpg -ab {} \; +# + +if [[ -z "${VERSION}" ]]; then + echo "VERSION is not defined" + exit 1 +fi + +if [[ -z "${OSS_USER}" ]]; then + echo "OSS_USER is not defined" + exit 1 +fi + +read -p "Password : " -s OSS_PASSWORD + +for i in bitcoin-kmp \ + bitcoin-kmp-iosarm64 \ + bitcoin-kmp-iosx64 \ + bitcoin-kmp-jvm \ + bitcoin-kmp-linux +do + pushd . + cd release/fr/acinq/bitcoin/$i/$VERSION &&\ + pwd &&\ + jar -cvf bundle.jar *&&\ + curl -v -XPOST -u $OSS_USER:$OSS_PASSWORD --upload-file bundle.jar https://oss.sonatype.org/service/local/staging/bundle_upload + popd +done diff --git a/src/commonMain/kotlin/fr/acinq/bitcoin/Crypto.kt b/src/commonMain/kotlin/fr/acinq/bitcoin/Crypto.kt index a36490ee..e38ebc98 100644 --- a/src/commonMain/kotlin/fr/acinq/bitcoin/Crypto.kt +++ b/src/commonMain/kotlin/fr/acinq/bitcoin/Crypto.kt @@ -161,14 +161,14 @@ public object Crypto { /** * private key is used as-is */ - public object NoTweak : SchnorrTweak() + public data object NoTweak : SchnorrTweak() } public sealed class TaprootTweak : SchnorrTweak() { /** * private key is tweaked with H_TapTweak(public key) (this is used for key path spending when no scripts are present) */ - public object NoScriptTweak : TaprootTweak() + public data object NoScriptTweak : TaprootTweak() /** * private key is tweaked with H_TapTweak(public key || merkle_root) (this is used for key path spending, with specific Merkle root of the script tree). diff --git a/src/commonMain/kotlin/fr/acinq/bitcoin/ScriptElt.kt b/src/commonMain/kotlin/fr/acinq/bitcoin/ScriptElt.kt index 734c1d79..712b2598 100644 --- a/src/commonMain/kotlin/fr/acinq/bitcoin/ScriptElt.kt +++ b/src/commonMain/kotlin/fr/acinq/bitcoin/ScriptElt.kt @@ -46,345 +46,345 @@ public sealed class ScriptElt { } // @formatter:off -public object OP_0 : ScriptElt() { +public data object OP_0 : ScriptElt() { override val code: Int get() = 0x00 } -public object OP_PUSHDATA1 : ScriptElt() { +public data object OP_PUSHDATA1 : ScriptElt() { override val code: Int get() = 0x4c } -public object OP_PUSHDATA2 : ScriptElt() { +public data object OP_PUSHDATA2 : ScriptElt() { override val code: Int get() = 0x4d } -public object OP_PUSHDATA4 : ScriptElt() { +public data object OP_PUSHDATA4 : ScriptElt() { override val code: Int get() = 0x4e } -public object OP_1NEGATE : ScriptElt() { +public data object OP_1NEGATE : ScriptElt() { override val code: Int get() = 0x4f } -public object OP_RESERVED : ScriptElt() { +public data object OP_RESERVED : ScriptElt() { override val code: Int get() = 0x50 } -public object OP_1 : ScriptElt() { +public data object OP_1 : ScriptElt() { override val code: Int get() = 0x51 } -public object OP_2 : ScriptElt() { +public data object OP_2 : ScriptElt() { override val code: Int get() = 0x52 } -public object OP_3 : ScriptElt() { +public data object OP_3 : ScriptElt() { override val code: Int get() = 0x53 } -public object OP_4 : ScriptElt() { +public data object OP_4 : ScriptElt() { override val code: Int get() = 0x54 } -public object OP_5 : ScriptElt() { +public data object OP_5 : ScriptElt() { override val code: Int get() = 0x55 } -public object OP_6 : ScriptElt() { +public data object OP_6 : ScriptElt() { override val code: Int get() = 0x56 } -public object OP_7 : ScriptElt() { +public data object OP_7 : ScriptElt() { override val code: Int get() = 0x57 } -public object OP_8 : ScriptElt() { +public data object OP_8 : ScriptElt() { override val code: Int get() = 0x58 } -public object OP_9 : ScriptElt() { +public data object OP_9 : ScriptElt() { override val code: Int get() = 0x59 } -public object OP_10 : ScriptElt() { +public data object OP_10 : ScriptElt() { override val code: Int get() = 0x5a } -public object OP_11 : ScriptElt() { +public data object OP_11 : ScriptElt() { override val code: Int get() = 0x5b } -public object OP_12 : ScriptElt() { +public data object OP_12 : ScriptElt() { override val code: Int get() = 0x5c } -public object OP_13 : ScriptElt() { +public data object OP_13 : ScriptElt() { override val code: Int get() = 0x5d } -public object OP_14 : ScriptElt() { +public data object OP_14 : ScriptElt() { override val code: Int get() = 0x5e } -public object OP_15 : ScriptElt() { +public data object OP_15 : ScriptElt() { override val code: Int get() = 0x5f } -public object OP_16 : ScriptElt() { +public data object OP_16 : ScriptElt() { override val code: Int get() = 0x60 } -public object OP_NOP : ScriptElt() { +public data object OP_NOP : ScriptElt() { override val code: Int get() = 0x61 } -public object OP_VER : ScriptElt() { +public data object OP_VER : ScriptElt() { override val code: Int get() = 0x62 } -public object OP_IF : ScriptElt() { +public data object OP_IF : ScriptElt() { override val code: Int get() = 0x63 } -public object OP_NOTIF : ScriptElt() { +public data object OP_NOTIF : ScriptElt() { override val code: Int get() = 0x64 } -public object OP_VERIF : ScriptElt() { +public data object OP_VERIF : ScriptElt() { override val code: Int get() = 0x65 } -public object OP_VERNOTIF : ScriptElt() { +public data object OP_VERNOTIF : ScriptElt() { override val code: Int get() = 0x66 } -public object OP_ELSE : ScriptElt() { +public data object OP_ELSE : ScriptElt() { override val code: Int get() = 0x67 } -public object OP_ENDIF : ScriptElt() { +public data object OP_ENDIF : ScriptElt() { override val code: Int get() = 0x68 } -public object OP_VERIFY : ScriptElt() { +public data object OP_VERIFY : ScriptElt() { override val code: Int get() = 0x69 } -public object OP_RETURN : ScriptElt() { +public data object OP_RETURN : ScriptElt() { override val code: Int get() = 0x6a } -public object OP_TOALTSTACK : ScriptElt() { +public data object OP_TOALTSTACK : ScriptElt() { override val code: Int get() = 0x6b } -public object OP_FROMALTSTACK : ScriptElt() { +public data object OP_FROMALTSTACK : ScriptElt() { override val code: Int get() = 0x6c } -public object OP_2DROP : ScriptElt() { +public data object OP_2DROP : ScriptElt() { override val code: Int get() = 0x6d } -public object OP_2DUP : ScriptElt() { +public data object OP_2DUP : ScriptElt() { override val code: Int get() = 0x6e } -public object OP_3DUP : ScriptElt() { +public data object OP_3DUP : ScriptElt() { override val code: Int get() = 0x6f } -public object OP_2OVER : ScriptElt() { +public data object OP_2OVER : ScriptElt() { override val code: Int get() = 0x70 } -public object OP_2ROT : ScriptElt() { +public data object OP_2ROT : ScriptElt() { override val code: Int get() = 0x71 } -public object OP_2SWAP : ScriptElt() { +public data object OP_2SWAP : ScriptElt() { override val code: Int get() = 0x72 } -public object OP_IFDUP : ScriptElt() { +public data object OP_IFDUP : ScriptElt() { override val code: Int get() = 0x73 } -public object OP_DEPTH : ScriptElt() { +public data object OP_DEPTH : ScriptElt() { override val code: Int get() = 0x74 } -public object OP_DROP : ScriptElt() { +public data object OP_DROP : ScriptElt() { override val code: Int get() = 0x75 } -public object OP_DUP : ScriptElt() { +public data object OP_DUP : ScriptElt() { override val code: Int get() = 0x76 } -public object OP_NIP : ScriptElt() { +public data object OP_NIP : ScriptElt() { override val code: Int get() = 0x77 } -public object OP_OVER : ScriptElt() { +public data object OP_OVER : ScriptElt() { override val code: Int get() = 0x78 } -public object OP_PICK : ScriptElt() { +public data object OP_PICK : ScriptElt() { override val code: Int get() = 0x79 } -public object OP_ROLL : ScriptElt() { +public data object OP_ROLL : ScriptElt() { override val code: Int get() = 0x7a } -public object OP_ROT : ScriptElt() { +public data object OP_ROT : ScriptElt() { override val code: Int get() = 0x7b } -public object OP_SWAP : ScriptElt() { +public data object OP_SWAP : ScriptElt() { override val code: Int get() = 0x7c } -public object OP_TUCK : ScriptElt() { +public data object OP_TUCK : ScriptElt() { override val code: Int get() = 0x7d } -public object OP_CAT : ScriptElt() { +public data object OP_CAT : ScriptElt() { override val code: Int get() = 0x7e } -public object OP_SUBSTR : ScriptElt() { +public data object OP_SUBSTR : ScriptElt() { override val code: Int get() = 0x7f } -public object OP_LEFT : ScriptElt() { +public data object OP_LEFT : ScriptElt() { override val code: Int get() = 0x80 } -public object OP_RIGHT : ScriptElt() { +public data object OP_RIGHT : ScriptElt() { override val code: Int get() = 0x81 } -public object OP_SIZE : ScriptElt() { +public data object OP_SIZE : ScriptElt() { override val code: Int get() = 0x82 } -public object OP_INVERT : ScriptElt() { +public data object OP_INVERT : ScriptElt() { override val code: Int get() = 0x83 } -public object OP_AND : ScriptElt() { +public data object OP_AND : ScriptElt() { override val code: Int get() = 0x84 } -public object OP_OR : ScriptElt() { +public data object OP_OR : ScriptElt() { override val code: Int get() = 0x85 } -public object OP_XOR : ScriptElt() { +public data object OP_XOR : ScriptElt() { override val code: Int get() = 0x86 } -public object OP_EQUAL : ScriptElt() { +public data object OP_EQUAL : ScriptElt() { override val code: Int get() = 0x87 } -public object OP_EQUALVERIFY : ScriptElt() { +public data object OP_EQUALVERIFY : ScriptElt() { override val code: Int get() = 0x88 } -public object OP_RESERVED1 : ScriptElt() { +public data object OP_RESERVED1 : ScriptElt() { override val code: Int get() = 0x89 } -public object OP_RESERVED2 : ScriptElt() { +public data object OP_RESERVED2 : ScriptElt() { override val code: Int get() = 0x8a } -public object OP_1ADD : ScriptElt() { +public data object OP_1ADD : ScriptElt() { override val code: Int get() = 0x8b } -public object OP_1SUB : ScriptElt() { +public data object OP_1SUB : ScriptElt() { override val code: Int get() = 0x8c } -public object OP_2MUL : ScriptElt() { +public data object OP_2MUL : ScriptElt() { override val code: Int get() = 0x8d } -public object OP_2DIV : ScriptElt() { +public data object OP_2DIV : ScriptElt() { override val code: Int get() = 0x8e } -public object OP_NEGATE : ScriptElt() { +public data object OP_NEGATE : ScriptElt() { override val code: Int get() = 0x8f } -public object OP_ABS : ScriptElt() { +public data object OP_ABS : ScriptElt() { override val code: Int get() = 0x90 } -public object OP_NOT : ScriptElt() { +public data object OP_NOT : ScriptElt() { override val code: Int get() = 0x91 } -public object OP_0NOTEQUAL : ScriptElt() { +public data object OP_0NOTEQUAL : ScriptElt() { override val code: Int get() = 0x92 } -public object OP_ADD : ScriptElt() { +public data object OP_ADD : ScriptElt() { override val code: Int get() = 0x93 } -public object OP_SUB : ScriptElt() { +public data object OP_SUB : ScriptElt() { override val code: Int get() = 0x94 } -public object OP_MUL : ScriptElt() { +public data object OP_MUL : ScriptElt() { override val code: Int get() = 0x95 } -public object OP_DIV : ScriptElt() { +public data object OP_DIV : ScriptElt() { override val code: Int get() = 0x96 } -public object OP_MOD : ScriptElt() { +public data object OP_MOD : ScriptElt() { override val code: Int get() = 0x97 } -public object OP_LSHIFT : ScriptElt() { +public data object OP_LSHIFT : ScriptElt() { override val code: Int get() = 0x98 } -public object OP_RSHIFT : ScriptElt() { +public data object OP_RSHIFT : ScriptElt() { override val code: Int get() = 0x99 } -public object OP_BOOLAND : ScriptElt() { +public data object OP_BOOLAND : ScriptElt() { override val code: Int get() = 0x9a } -public object OP_BOOLOR : ScriptElt() { +public data object OP_BOOLOR : ScriptElt() { override val code: Int get() = 0x9b } -public object OP_NUMEQUAL : ScriptElt() { +public data object OP_NUMEQUAL : ScriptElt() { override val code: Int get() = 0x9c } -public object OP_NUMEQUALVERIFY : ScriptElt() { +public data object OP_NUMEQUALVERIFY : ScriptElt() { override val code: Int get() = 0x9d } -public object OP_NUMNOTEQUAL : ScriptElt() { +public data object OP_NUMNOTEQUAL : ScriptElt() { override val code: Int get() = 0x9e } -public object OP_LESSTHAN : ScriptElt() { +public data object OP_LESSTHAN : ScriptElt() { override val code: Int get() = 0x9f } -public object OP_GREATERTHAN : ScriptElt() { +public data object OP_GREATERTHAN : ScriptElt() { override val code: Int get() = 0xa0 } -public object OP_LESSTHANOREQUAL : ScriptElt() { +public data object OP_LESSTHANOREQUAL : ScriptElt() { override val code: Int get() = 0xa1 } -public object OP_GREATERTHANOREQUAL : ScriptElt() { +public data object OP_GREATERTHANOREQUAL : ScriptElt() { override val code: Int get() = 0xa2 } -public object OP_MIN : ScriptElt() { +public data object OP_MIN : ScriptElt() { override val code: Int get() = 0xa3 } -public object OP_MAX : ScriptElt() { +public data object OP_MAX : ScriptElt() { override val code: Int get() = 0xa4 } -public object OP_WITHIN : ScriptElt() { +public data object OP_WITHIN : ScriptElt() { override val code: Int get() = 0xa5 } -public object OP_RIPEMD160 : ScriptElt() { +public data object OP_RIPEMD160 : ScriptElt() { override val code: Int get() = 0xa6 } -public object OP_SHA1 : ScriptElt() { +public data object OP_SHA1 : ScriptElt() { override val code: Int get() = 0xa7 } -public object OP_SHA256 : ScriptElt() { +public data object OP_SHA256 : ScriptElt() { override val code: Int get() = 0xa8 } -public object OP_HASH160 : ScriptElt() { +public data object OP_HASH160 : ScriptElt() { override val code: Int get() = 0xa9 } -public object OP_HASH256 : ScriptElt() { +public data object OP_HASH256 : ScriptElt() { override val code: Int get() = 0xaa } -public object OP_CODESEPARATOR : ScriptElt() { +public data object OP_CODESEPARATOR : ScriptElt() { override val code: Int get() = 0xab } -public object OP_CHECKSIG : ScriptElt() { +public data object OP_CHECKSIG : ScriptElt() { override val code: Int get() = 0xac } -public object OP_CHECKSIGVERIFY : ScriptElt() { +public data object OP_CHECKSIGVERIFY : ScriptElt() { override val code: Int get() = 0xad } -public object OP_CHECKMULTISIG : ScriptElt() { +public data object OP_CHECKMULTISIG : ScriptElt() { override val code: Int get() = 0xae } -public object OP_CHECKMULTISIGVERIFY : ScriptElt() { +public data object OP_CHECKMULTISIGVERIFY : ScriptElt() { override val code: Int get() = 0xaf } -public object OP_NOP1 : ScriptElt() { +public data object OP_NOP1 : ScriptElt() { override val code: Int get() = 0xb0 } -public object OP_CHECKLOCKTIMEVERIFY : ScriptElt() { +public data object OP_CHECKLOCKTIMEVERIFY : ScriptElt() { override val code: Int get() = 0xb1 } -public object OP_CHECKSEQUENCEVERIFY : ScriptElt() { +public data object OP_CHECKSEQUENCEVERIFY : ScriptElt() { override val code: Int get() = 0xb2 } -public object OP_NOP4 : ScriptElt() { +public data object OP_NOP4 : ScriptElt() { override val code: Int get() = 0xb3 } -public object OP_NOP5 : ScriptElt() { +public data object OP_NOP5 : ScriptElt() { override val code: Int get() = 0xb4 } -public object OP_NOP6 : ScriptElt() { +public data object OP_NOP6 : ScriptElt() { override val code: Int get() = 0xb5 } -public object OP_NOP7 : ScriptElt() { +public data object OP_NOP7 : ScriptElt() { override val code: Int get() = 0xb6 } -public object OP_NOP8 : ScriptElt() { +public data object OP_NOP8 : ScriptElt() { override val code: Int get() = 0xb7 } -public object OP_NOP9 : ScriptElt() { +public data object OP_NOP9 : ScriptElt() { override val code: Int get() = 0xb8 } -public object OP_NOP10 : ScriptElt() { +public data object OP_NOP10 : ScriptElt() { override val code: Int get() = 0xb9 } // Opcode added by BIP 342 (Tapscript) -public object OP_CHECKSIGADD: ScriptElt() { +public data object OP_CHECKSIGADD: ScriptElt() { override val code: Int get() = 0xba } -public object OP_INVALIDOPCODE : ScriptElt() { +public data object OP_INVALIDOPCODE : ScriptElt() { override val code: Int get() = 0xff } // @formatter:on @@ -558,11 +558,7 @@ public object ScriptEltMapping { @JvmField public val code2elt: Map = elements.associateBy { it.code } - public fun name(elt: ScriptElt): String { - val name = elt.toString().removePrefix("fr.acinq.bitcoin.OP_") - val name1 = name.take(name.lastIndexOf('@')) - return name1 - } + public fun name(elt: ScriptElt): String = elt.toString().removePrefix("OP_") public val name2code: Map = elements.associate { name(it) to it.code } } \ No newline at end of file diff --git a/src/commonMain/kotlin/fr/acinq/bitcoin/crypto/Pbkdf2.kt b/src/commonMain/kotlin/fr/acinq/bitcoin/crypto/Pbkdf2.kt index 79500e8a..7453128f 100644 --- a/src/commonMain/kotlin/fr/acinq/bitcoin/crypto/Pbkdf2.kt +++ b/src/commonMain/kotlin/fr/acinq/bitcoin/crypto/Pbkdf2.kt @@ -21,7 +21,6 @@ import kotlin.jvm.JvmStatic public expect object Pbkdf2 { - @JvmStatic public fun withHmacSha512(password: ByteArray, salt: ByteArray, count: Int, dkLen: Int): ByteArray } diff --git a/src/commonTest/kotlin/fr/acinq/bitcoin/BlockTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/bitcoin/BlockTestsCommon.kt index 5445c876..4a879c9a 100644 --- a/src/commonTest/kotlin/fr/acinq/bitcoin/BlockTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/bitcoin/BlockTestsCommon.kt @@ -27,10 +27,10 @@ class BlockTestsCommon { private val blockData = run { val file = TransactionTestsCommon.resourcesDir().resolve("block1.dat") file.openReadableFile().use { - val len = it.available + val len = it.size // workaround for a bug in kotlin memory file where dstOffset cannot be 0 but is still ignored... val buffer = ByteArray(len) - for (i in buffer.indices) buffer[i] = it.readByte() + it.readBytes(buffer, 0, buffer.size) buffer } } diff --git a/src/commonTest/kotlin/fr/acinq/bitcoin/CryptoTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/bitcoin/CryptoTestsCommon.kt index 09c3becf..e87915a5 100644 --- a/src/commonTest/kotlin/fr/acinq/bitcoin/CryptoTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/bitcoin/CryptoTestsCommon.kt @@ -21,7 +21,7 @@ import fr.acinq.secp256k1.Hex import fr.acinq.secp256k1.Secp256k1 import org.kodein.memory.file.openReadableFile import org.kodein.memory.file.resolve -import org.kodein.memory.io.readLine +import org.kodein.memory.text.readLine import org.kodein.memory.use import kotlin.random.Random import kotlin.test.* diff --git a/src/commonTest/kotlin/fr/acinq/bitcoin/DeriveWalletKeysTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/bitcoin/DeriveWalletKeysTestsCommon.kt index 52edc192..2e525262 100644 --- a/src/commonTest/kotlin/fr/acinq/bitcoin/DeriveWalletKeysTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/bitcoin/DeriveWalletKeysTestsCommon.kt @@ -61,9 +61,9 @@ class DeriveWalletKeysTestsCommon { companion object { sealed class DerivationScheme { - object BIP44 : DerivationScheme() - object BIP49 : DerivationScheme() - object BIP84 : DerivationScheme() + data object BIP44 : DerivationScheme() + data object BIP49 : DerivationScheme() + data object BIP84 : DerivationScheme() } fun deriveAddresses(xpub: String, derivationScheme: DerivationScheme): List { diff --git a/src/commonTest/kotlin/fr/acinq/bitcoin/TaprootTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/bitcoin/TaprootTestsCommon.kt index 8146fb96..afae8760 100644 --- a/src/commonTest/kotlin/fr/acinq/bitcoin/TaprootTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/bitcoin/TaprootTestsCommon.kt @@ -357,8 +357,8 @@ class TaprootTestsCommon { fun `parse and validate huge transaction`() { // this is the tx that broke btcd/lnd val file = resourcesDir().resolve("7393096d97bfee8660f4100ffd61874d62f9a65de9fb6acf740c4c386990ef73.bin").openReadableFile() - val buffer = ByteArray(file.available) - file.readBytes(buffer) + val buffer = ByteArray(file.size) + file.readBytes(buffer, 0, buffer.size) file.close() val tx = Transaction.read(buffer) assertEquals(1001, tx.txIn[0].witness.stack.size) @@ -409,8 +409,8 @@ class TaprootTestsCommon { @Test fun `parse and validate large ordinals transaction`() { val file = resourcesDir().resolve("b5a7e05f28d00e4a791759ad7b6bd6799d856693293ceeaad9b0bb93c8851f7f.bin").openReadableFile() - val buffer = ByteArray(file.available) - file.readBytes(buffer) + val buffer = ByteArray(file.size) + file.readBytes(buffer, 0, buffer.size) file.close() val tx = Transaction.read(buffer) val parentTx = Transaction.read( diff --git a/src/iosMain/kotlin/fr/acinq/bitcoin/crypto/DigestIos.kt b/src/iosMain/kotlin/fr/acinq/bitcoin/crypto/DigestIos.kt index 94865cbd..1f6278de 100644 --- a/src/iosMain/kotlin/fr/acinq/bitcoin/crypto/DigestIos.kt +++ b/src/iosMain/kotlin/fr/acinq/bitcoin/crypto/DigestIos.kt @@ -1,3 +1,5 @@ +@file:OptIn(ExperimentalForeignApi::class) + package fr.acinq.bitcoin.crypto import kotlinx.cinterop.* @@ -8,7 +10,7 @@ private typealias Init = (CValuesRef?) -> Unit private typealias Update = (CValuesRef?, CValuesRef<*>?, CC_LONG) -> Unit private typealias Final = (CValuesRef?, CValuesRef?) -> Unit -@OptIn(ExperimentalUnsignedTypes::class) +@OptIn(ExperimentalUnsignedTypes::class, ExperimentalForeignApi::class) internal class DigestIos( private val algorithmName: String, private val digestSize: Int, diff --git a/src/iosMain/kotlin/fr/acinq/bitcoin/crypto/pbkdf2Ios.kt b/src/iosMain/kotlin/fr/acinq/bitcoin/crypto/pbkdf2Ios.kt index 2da372d1..25b564ee 100644 --- a/src/iosMain/kotlin/fr/acinq/bitcoin/crypto/pbkdf2Ios.kt +++ b/src/iosMain/kotlin/fr/acinq/bitcoin/crypto/pbkdf2Ios.kt @@ -1,5 +1,6 @@ package fr.acinq.bitcoin.crypto +import kotlinx.cinterop.ExperimentalForeignApi import kotlinx.cinterop.memScoped import kotlinx.cinterop.refTo import platform.KCoreCrypto.KCCKeyDerivationPBKDF @@ -10,7 +11,7 @@ import platform.CoreCrypto.kCCPRFHmacAlgSHA512 public actual object Pbkdf2 { - @OptIn(ExperimentalUnsignedTypes::class) + @OptIn(ExperimentalUnsignedTypes::class, ExperimentalForeignApi::class) public actual fun withHmacSha512(password: ByteArray, salt: ByteArray, count: Int, dkLen: Int): ByteArray { memScoped { val result = ByteArray(dkLen)