diff --git a/.github/workflows/android_ci.yml b/.github/workflows/android_ci.yml index e7883a5f..d2c1720e 100644 --- a/.github/workflows/android_ci.yml +++ b/.github/workflows/android_ci.yml @@ -7,6 +7,10 @@ on: description: "Crate name to build Android package from" required: true type: string + release: + description: "Whether to build a release version" + required: true + type: boolean env: CRATE: ${{ inputs.crate }} @@ -76,3 +80,17 @@ jobs: with: name: ${{ env.CRATE }}.aar path: ${{ env.ANDROID_PACKAGE_DIR }}/build/outputs/aar/${{ env.CRATE }}-release.aar + + - name: Build and Publish to Maven Central + working-directory: ${{ env.ANDROID_PACKAGE_DIR }} + env: + GITHUB_TAG: ${{ github.ref_name }} + ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.RSA_GPG_PRIVATE_KEY }} + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.RSA_GPG_PASSPHRASE }} + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.CENTRAL_USERNAME }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.CENTRAL_PASSWORD }} + run: | + export VERSION_TAG=${GITHUB_TAG#v} # Remove the leading 'v' + echo "Publishing version: $VERSION_TAG" + echo "Publishing to Maven Central (USER_MANAGED - requires manual release)..." + ./gradlew publishToMavenCentral diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 886cee84..ff0b607e 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -4,6 +4,8 @@ on: push: # A push indicates that a PR is merged and CD should be triggered branches: - main + tags: + - 'v*' pull_request: # For PRs, we run CI, which is the same as CD without the release step(s) branches: - main @@ -96,3 +98,4 @@ jobs: include: ${{ fromJSON(needs.setup.outputs.ffi_packages) }} with: crate: ${{ matrix.crate_name }} + release: ${{ github.event_name == 'push' && github.ref_type == 'tag' }} diff --git a/packages/android/algokit_algo25/README.md b/packages/android/algokit_algo25/README.md deleted file mode 100644 index cd33934b..00000000 --- a/packages/android/algokit_algo25/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# algokit_algo25 - -## Building - -```sh -cargo pkg algo25 kt -``` - -## Testing - -### Host - -```sh -./gradlew test -``` - -### Android - -First you need a connected android device. You can either use a physical device or start an emulator. - -To see available emulators: - -```sh -~/Library/Android/sdk/emulator/emulator -list-avds -``` - -Then start the emulator: - -```sh -~/Library/Android/sdk/emulator/emulator -avd -``` - -Or to start the first one: - -```sh -~/Library/Android/sdk/emulator/emulator -avd `~/Library/Android/sdk/emulator/emulator -list-avds | head -n 1` -``` - -Then run the tests: - -```sh -./gradlew connectedAndroidTest -``` diff --git a/packages/android/algokit_algo25/build.gradle.kts b/packages/android/algokit_algo25/build.gradle.kts deleted file mode 100644 index ae060169..00000000 --- a/packages/android/algokit_algo25/build.gradle.kts +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file was generated by the Gradle 'init' task. - * - * This is a general purpose Gradle build. - * Learn more about Gradle by exploring our Samples at https://docs.gradle.org/8.14.2/samples - */ -plugins { - alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.android) -} - -android { - namespace = "com.example.algokit_algo25" - compileSdk = 36 - - defaultConfig { - minSdk = 28 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 - } - kotlinOptions { jvmTarget = "21" } - testOptions { - unitTests { - isIncludeAndroidResources = true - all { it.systemProperty("jna.library.path", "src/test/resources") } - } - } -} - -dependencies { - implementation("net.java.dev.jna:jna:5.14.0@aar") - // Use full JNA JAR for unit tests (includes native dispatch libraries) - testImplementation("net.java.dev.jna:jna:5.14.0") - - implementation(libs.androidx.core.ktx) - implementation(libs.androidx.appcompat) - implementation(libs.material) - testImplementation(libs.junit) - androidTestImplementation(libs.androidx.junit) - androidTestImplementation(libs.androidx.espresso.core) -} diff --git a/packages/android/algokit_algo25/gradle.properties b/packages/android/algokit_algo25/gradle.properties deleted file mode 100644 index d5be7319..00000000 --- a/packages/android/algokit_algo25/gradle.properties +++ /dev/null @@ -1,7 +0,0 @@ -# This file was generated by the Gradle 'init' task. -# https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties - -org.gradle.configuration-cache=true -android.useAndroidX=true -android.suppressUnsupportedCompileSdk=36 - diff --git a/packages/android/algokit_algo25/gradle/libs.versions.toml b/packages/android/algokit_algo25/gradle/libs.versions.toml deleted file mode 100644 index ff68a35c..00000000 --- a/packages/android/algokit_algo25/gradle/libs.versions.toml +++ /dev/null @@ -1,24 +0,0 @@ -[versions] -agp = "8.7.3" -kotlin = "2.0.21" -coreKtx = "1.16.0" -junit = "4.13.2" -junitVersion = "1.2.1" -espressoCore = "3.6.1" -appcompat = "1.7.0" -material = "1.12.0" - -[libraries] -androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } -junit = { group = "junit", name = "junit", version.ref = "junit" } -androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } -androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } -androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } -material = { group = "com.google.android.material", name = "material", version.ref = "material" } - -[plugins] -android-application = { id = "com.android.application", version.ref = "agp" } -android-library = { id = "com.android.library", version.ref = "agp" } -kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } - - diff --git a/packages/android/algokit_algo25/gradle/wrapper/gradle-wrapper.jar b/packages/android/algokit_algo25/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 1b33c55b..00000000 Binary files a/packages/android/algokit_algo25/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/packages/android/algokit_algo25/gradle/wrapper/gradle-wrapper.properties b/packages/android/algokit_algo25/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index ff23a68d..00000000 --- a/packages/android/algokit_algo25/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/packages/android/algokit_algo25/gradlew b/packages/android/algokit_algo25/gradlew deleted file mode 100755 index 23d15a93..00000000 --- a/packages/android/algokit_algo25/gradlew +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# SPDX-License-Identifier: Apache-2.0 -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH="\\\"\\\"" - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/packages/android/algokit_algo25/gradlew.bat b/packages/android/algokit_algo25/gradlew.bat deleted file mode 100644 index db3a6ac2..00000000 --- a/packages/android/algokit_algo25/gradlew.bat +++ /dev/null @@ -1,94 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH= - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/packages/android/algokit_algo25/settings.gradle.kts b/packages/android/algokit_algo25/settings.gradle.kts deleted file mode 100644 index 275315bc..00000000 --- a/packages/android/algokit_algo25/settings.gradle.kts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file was generated by the Gradle 'init' task. - * - * The settings file is used to specify which projects to include in your build. - * For more detailed information on multi-project builds, please refer to https://docs.gradle.org/8.14.2/userguide/multi_project_builds.html in the Gradle documentation. - */ - -pluginManagement { - repositories { - google { - content { - includeGroupByRegex("com\\.android.*") - includeGroupByRegex("com\\.google.*") - includeGroupByRegex("androidx.*") - } - } - mavenCentral() - gradlePluginPortal() - } -} - -dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) - repositories { - google() - mavenCentral() - } -} - -rootProject.name = "algokit_algo25" diff --git a/packages/android/algokit_algo25/src/main/kotlin/uniffi/algokit_algo25_ffi/algokit_algo25_ffi.kt b/packages/android/algokit_algo25/src/main/kotlin/uniffi/algokit_algo25_ffi/algokit_algo25_ffi.kt deleted file mode 100644 index 3d322c91..00000000 --- a/packages/android/algokit_algo25/src/main/kotlin/uniffi/algokit_algo25_ffi/algokit_algo25_ffi.kt +++ /dev/null @@ -1,1330 +0,0 @@ -// This file was autogenerated by some hot garbage in the `uniffi` crate. -// Trust me, you don't want to mess with it! - -@file:Suppress("NAME_SHADOWING") - -package uniffi.algokit_algo25_ffi - -// Common helper code. -// -// Ideally this would live in a separate .kt file where it can be unittested etc -// in isolation, and perhaps even published as a re-useable package. -// -// However, it's important that the details of how this helper code works (e.g. the -// way that different builtin types are passed across the FFI) exactly match what's -// expected by the Rust code on the other side of the interface. In practice right -// now that means coming from the exact some version of `uniffi` that was used to -// compile the Rust component. The easiest way to ensure this is to bundle the Kotlin -// helpers directly inline like we're doing here. - -import com.sun.jna.Library -import com.sun.jna.IntegerType -import com.sun.jna.Native -import com.sun.jna.Pointer -import com.sun.jna.Structure -import com.sun.jna.Callback -import com.sun.jna.ptr.* -import java.nio.ByteBuffer -import java.nio.ByteOrder -import java.nio.CharBuffer -import java.nio.charset.CodingErrorAction -import java.util.concurrent.atomic.AtomicLong -import java.util.concurrent.ConcurrentHashMap - -// This is a helper for safely working with byte buffers returned from the Rust code. -// A rust-owned buffer is represented by its capacity, its current length, and a -// pointer to the underlying data. - -/** - * @suppress - */ -@Structure.FieldOrder("capacity", "len", "data") -open class RustBuffer : Structure() { - // Note: `capacity` and `len` are actually `ULong` values, but JVM only supports signed values. - // When dealing with these fields, make sure to call `toULong()`. - @JvmField var capacity: Long = 0 - @JvmField var len: Long = 0 - @JvmField var data: Pointer? = null - - class ByValue: RustBuffer(), Structure.ByValue - class ByReference: RustBuffer(), Structure.ByReference - - internal fun setValue(other: RustBuffer) { - capacity = other.capacity - len = other.len - data = other.data - } - - companion object { - internal fun alloc(size: ULong = 0UL) = uniffiRustCall() { status -> - // Note: need to convert the size to a `Long` value to make this work with JVM. - UniffiLib.INSTANCE.ffi_algokit_algo25_ffi_rustbuffer_alloc(size.toLong(), status) - }.also { - if(it.data == null) { - throw RuntimeException("RustBuffer.alloc() returned null data pointer (size=${size})") - } - } - - internal fun create(capacity: ULong, len: ULong, data: Pointer?): RustBuffer.ByValue { - var buf = RustBuffer.ByValue() - buf.capacity = capacity.toLong() - buf.len = len.toLong() - buf.data = data - return buf - } - - internal fun free(buf: RustBuffer.ByValue) = uniffiRustCall() { status -> - UniffiLib.INSTANCE.ffi_algokit_algo25_ffi_rustbuffer_free(buf, status) - } - } - - @Suppress("TooGenericExceptionThrown") - fun asByteBuffer() = - this.data?.getByteBuffer(0, this.len.toLong())?.also { - it.order(ByteOrder.BIG_ENDIAN) - } -} - -/** - * The equivalent of the `*mut RustBuffer` type. - * Required for callbacks taking in an out pointer. - * - * Size is the sum of all values in the struct. - * - * @suppress - */ -class RustBufferByReference : ByReference(16) { - /** - * Set the pointed-to `RustBuffer` to the given value. - */ - fun setValue(value: RustBuffer.ByValue) { - // NOTE: The offsets are as they are in the C-like struct. - val pointer = getPointer() - pointer.setLong(0, value.capacity) - pointer.setLong(8, value.len) - pointer.setPointer(16, value.data) - } - - /** - * Get a `RustBuffer.ByValue` from this reference. - */ - fun getValue(): RustBuffer.ByValue { - val pointer = getPointer() - val value = RustBuffer.ByValue() - value.writeField("capacity", pointer.getLong(0)) - value.writeField("len", pointer.getLong(8)) - value.writeField("data", pointer.getLong(16)) - - return value - } -} - -// This is a helper for safely passing byte references into the rust code. -// It's not actually used at the moment, because there aren't many things that you -// can take a direct pointer to in the JVM, and if we're going to copy something -// then we might as well copy it into a `RustBuffer`. But it's here for API -// completeness. - -@Structure.FieldOrder("len", "data") -internal open class ForeignBytes : Structure() { - @JvmField var len: Int = 0 - @JvmField var data: Pointer? = null - - class ByValue : ForeignBytes(), Structure.ByValue -} -/** - * The FfiConverter interface handles converter types to and from the FFI - * - * All implementing objects should be public to support external types. When a - * type is external we need to import it's FfiConverter. - * - * @suppress - */ -public interface FfiConverter { - // Convert an FFI type to a Kotlin type - fun lift(value: FfiType): KotlinType - - // Convert an Kotlin type to an FFI type - fun lower(value: KotlinType): FfiType - - // Read a Kotlin type from a `ByteBuffer` - fun read(buf: ByteBuffer): KotlinType - - // Calculate bytes to allocate when creating a `RustBuffer` - // - // This must return at least as many bytes as the write() function will - // write. It can return more bytes than needed, for example when writing - // Strings we can't know the exact bytes needed until we the UTF-8 - // encoding, so we pessimistically allocate the largest size possible (3 - // bytes per codepoint). Allocating extra bytes is not really a big deal - // because the `RustBuffer` is short-lived. - fun allocationSize(value: KotlinType): ULong - - // Write a Kotlin type to a `ByteBuffer` - fun write(value: KotlinType, buf: ByteBuffer) - - // Lower a value into a `RustBuffer` - // - // This method lowers a value into a `RustBuffer` rather than the normal - // FfiType. It's used by the callback interface code. Callback interface - // returns are always serialized into a `RustBuffer` regardless of their - // normal FFI type. - fun lowerIntoRustBuffer(value: KotlinType): RustBuffer.ByValue { - val rbuf = RustBuffer.alloc(allocationSize(value)) - try { - val bbuf = rbuf.data!!.getByteBuffer(0, rbuf.capacity).also { - it.order(ByteOrder.BIG_ENDIAN) - } - write(value, bbuf) - rbuf.writeField("len", bbuf.position().toLong()) - return rbuf - } catch (e: Throwable) { - RustBuffer.free(rbuf) - throw e - } - } - - // Lift a value from a `RustBuffer`. - // - // This here mostly because of the symmetry with `lowerIntoRustBuffer()`. - // It's currently only used by the `FfiConverterRustBuffer` class below. - fun liftFromRustBuffer(rbuf: RustBuffer.ByValue): KotlinType { - val byteBuf = rbuf.asByteBuffer()!! - try { - val item = read(byteBuf) - if (byteBuf.hasRemaining()) { - throw RuntimeException("junk remaining in buffer after lifting, something is very wrong!!") - } - return item - } finally { - RustBuffer.free(rbuf) - } - } -} - -/** - * FfiConverter that uses `RustBuffer` as the FfiType - * - * @suppress - */ -public interface FfiConverterRustBuffer: FfiConverter { - override fun lift(value: RustBuffer.ByValue) = liftFromRustBuffer(value) - override fun lower(value: KotlinType) = lowerIntoRustBuffer(value) -} -// A handful of classes and functions to support the generated data structures. -// This would be a good candidate for isolating in its own ffi-support lib. - -internal const val UNIFFI_CALL_SUCCESS = 0.toByte() -internal const val UNIFFI_CALL_ERROR = 1.toByte() -internal const val UNIFFI_CALL_UNEXPECTED_ERROR = 2.toByte() - -@Structure.FieldOrder("code", "error_buf") -internal open class UniffiRustCallStatus : Structure() { - @JvmField var code: Byte = 0 - @JvmField var error_buf: RustBuffer.ByValue = RustBuffer.ByValue() - - class ByValue: UniffiRustCallStatus(), Structure.ByValue - - fun isSuccess(): Boolean { - return code == UNIFFI_CALL_SUCCESS - } - - fun isError(): Boolean { - return code == UNIFFI_CALL_ERROR - } - - fun isPanic(): Boolean { - return code == UNIFFI_CALL_UNEXPECTED_ERROR - } - - companion object { - fun create(code: Byte, errorBuf: RustBuffer.ByValue): UniffiRustCallStatus.ByValue { - val callStatus = UniffiRustCallStatus.ByValue() - callStatus.code = code - callStatus.error_buf = errorBuf - return callStatus - } - } -} - -class InternalException(message: String) : kotlin.Exception(message) - -/** - * Each top-level error class has a companion object that can lift the error from the call status's rust buffer - * - * @suppress - */ -interface UniffiRustCallStatusErrorHandler { - fun lift(error_buf: RustBuffer.ByValue): E; -} - -// Helpers for calling Rust -// In practice we usually need to be synchronized to call this safely, so it doesn't -// synchronize itself - -// Call a rust function that returns a Result<>. Pass in the Error class companion that corresponds to the Err -private inline fun uniffiRustCallWithError(errorHandler: UniffiRustCallStatusErrorHandler, callback: (UniffiRustCallStatus) -> U): U { - var status = UniffiRustCallStatus() - val return_value = callback(status) - uniffiCheckCallStatus(errorHandler, status) - return return_value -} - -// Check UniffiRustCallStatus and throw an error if the call wasn't successful -private fun uniffiCheckCallStatus(errorHandler: UniffiRustCallStatusErrorHandler, status: UniffiRustCallStatus) { - if (status.isSuccess()) { - return - } else if (status.isError()) { - throw errorHandler.lift(status.error_buf) - } else if (status.isPanic()) { - // when the rust code sees a panic, it tries to construct a rustbuffer - // with the message. but if that code panics, then it just sends back - // an empty buffer. - if (status.error_buf.len > 0) { - throw InternalException(FfiConverterString.lift(status.error_buf)) - } else { - throw InternalException("Rust panic") - } - } else { - throw InternalException("Unknown rust call status: $status.code") - } -} - -/** - * UniffiRustCallStatusErrorHandler implementation for times when we don't expect a CALL_ERROR - * - * @suppress - */ -object UniffiNullRustCallStatusErrorHandler: UniffiRustCallStatusErrorHandler { - override fun lift(error_buf: RustBuffer.ByValue): InternalException { - RustBuffer.free(error_buf) - return InternalException("Unexpected CALL_ERROR") - } -} - -// Call a rust function that returns a plain value -private inline fun uniffiRustCall(callback: (UniffiRustCallStatus) -> U): U { - return uniffiRustCallWithError(UniffiNullRustCallStatusErrorHandler, callback) -} - -internal inline fun uniffiTraitInterfaceCall( - callStatus: UniffiRustCallStatus, - makeCall: () -> T, - writeReturn: (T) -> Unit, -) { - try { - writeReturn(makeCall()) - } catch(e: kotlin.Exception) { - callStatus.code = UNIFFI_CALL_UNEXPECTED_ERROR - callStatus.error_buf = FfiConverterString.lower(e.toString()) - } -} - -internal inline fun uniffiTraitInterfaceCallWithError( - callStatus: UniffiRustCallStatus, - makeCall: () -> T, - writeReturn: (T) -> Unit, - lowerError: (E) -> RustBuffer.ByValue -) { - try { - writeReturn(makeCall()) - } catch(e: kotlin.Exception) { - if (e is E) { - callStatus.code = UNIFFI_CALL_ERROR - callStatus.error_buf = lowerError(e) - } else { - callStatus.code = UNIFFI_CALL_UNEXPECTED_ERROR - callStatus.error_buf = FfiConverterString.lower(e.toString()) - } - } -} -// Map handles to objects -// -// This is used pass an opaque 64-bit handle representing a foreign object to the Rust code. -internal class UniffiHandleMap { - private val map = ConcurrentHashMap() - private val counter = java.util.concurrent.atomic.AtomicLong(0) - - val size: Int - get() = map.size - - // Insert a new object into the handle map and get a handle for it - fun insert(obj: T): Long { - val handle = counter.getAndAdd(1) - map.put(handle, obj) - return handle - } - - // Get an object from the handle map - fun get(handle: Long): T { - return map.get(handle) ?: throw InternalException("UniffiHandleMap.get: Invalid handle") - } - - // Remove an entry from the handlemap and get the Kotlin object back - fun remove(handle: Long): T { - return map.remove(handle) ?: throw InternalException("UniffiHandleMap: Invalid handle") - } -} - -// Contains loading, initialization code, -// and the FFI Function declarations in a com.sun.jna.Library. -@Synchronized -private fun findLibraryName(componentName: String): String { - val libOverride = System.getProperty("uniffi.component.$componentName.libraryOverride") - if (libOverride != null) { - return libOverride - } - return "algokit_algo25_ffi" -} - -private inline fun loadIndirect( - componentName: String -): Lib { - return Native.load(findLibraryName(componentName), Lib::class.java) -} - -// Define FFI callback types -internal interface UniffiRustFutureContinuationCallback : com.sun.jna.Callback { - fun callback(`data`: Long,`pollResult`: Byte,) -} -internal interface UniffiForeignFutureFree : com.sun.jna.Callback { - fun callback(`handle`: Long,) -} -internal interface UniffiCallbackInterfaceFree : com.sun.jna.Callback { - fun callback(`handle`: Long,) -} -@Structure.FieldOrder("handle", "free") -internal open class UniffiForeignFuture( - @JvmField internal var `handle`: Long = 0.toLong(), - @JvmField internal var `free`: UniffiForeignFutureFree? = null, -) : Structure() { - class UniffiByValue( - `handle`: Long = 0.toLong(), - `free`: UniffiForeignFutureFree? = null, - ): UniffiForeignFuture(`handle`,`free`,), Structure.ByValue - - internal fun uniffiSetValue(other: UniffiForeignFuture) { - `handle` = other.`handle` - `free` = other.`free` - } - -} -@Structure.FieldOrder("returnValue", "callStatus") -internal open class UniffiForeignFutureStructU8( - @JvmField internal var `returnValue`: Byte = 0.toByte(), - @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), -) : Structure() { - class UniffiByValue( - `returnValue`: Byte = 0.toByte(), - `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), - ): UniffiForeignFutureStructU8(`returnValue`,`callStatus`,), Structure.ByValue - - internal fun uniffiSetValue(other: UniffiForeignFutureStructU8) { - `returnValue` = other.`returnValue` - `callStatus` = other.`callStatus` - } - -} -internal interface UniffiForeignFutureCompleteU8 : com.sun.jna.Callback { - fun callback(`callbackData`: Long,`result`: UniffiForeignFutureStructU8.UniffiByValue,) -} -@Structure.FieldOrder("returnValue", "callStatus") -internal open class UniffiForeignFutureStructI8( - @JvmField internal var `returnValue`: Byte = 0.toByte(), - @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), -) : Structure() { - class UniffiByValue( - `returnValue`: Byte = 0.toByte(), - `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), - ): UniffiForeignFutureStructI8(`returnValue`,`callStatus`,), Structure.ByValue - - internal fun uniffiSetValue(other: UniffiForeignFutureStructI8) { - `returnValue` = other.`returnValue` - `callStatus` = other.`callStatus` - } - -} -internal interface UniffiForeignFutureCompleteI8 : com.sun.jna.Callback { - fun callback(`callbackData`: Long,`result`: UniffiForeignFutureStructI8.UniffiByValue,) -} -@Structure.FieldOrder("returnValue", "callStatus") -internal open class UniffiForeignFutureStructU16( - @JvmField internal var `returnValue`: Short = 0.toShort(), - @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), -) : Structure() { - class UniffiByValue( - `returnValue`: Short = 0.toShort(), - `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), - ): UniffiForeignFutureStructU16(`returnValue`,`callStatus`,), Structure.ByValue - - internal fun uniffiSetValue(other: UniffiForeignFutureStructU16) { - `returnValue` = other.`returnValue` - `callStatus` = other.`callStatus` - } - -} -internal interface UniffiForeignFutureCompleteU16 : com.sun.jna.Callback { - fun callback(`callbackData`: Long,`result`: UniffiForeignFutureStructU16.UniffiByValue,) -} -@Structure.FieldOrder("returnValue", "callStatus") -internal open class UniffiForeignFutureStructI16( - @JvmField internal var `returnValue`: Short = 0.toShort(), - @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), -) : Structure() { - class UniffiByValue( - `returnValue`: Short = 0.toShort(), - `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), - ): UniffiForeignFutureStructI16(`returnValue`,`callStatus`,), Structure.ByValue - - internal fun uniffiSetValue(other: UniffiForeignFutureStructI16) { - `returnValue` = other.`returnValue` - `callStatus` = other.`callStatus` - } - -} -internal interface UniffiForeignFutureCompleteI16 : com.sun.jna.Callback { - fun callback(`callbackData`: Long,`result`: UniffiForeignFutureStructI16.UniffiByValue,) -} -@Structure.FieldOrder("returnValue", "callStatus") -internal open class UniffiForeignFutureStructU32( - @JvmField internal var `returnValue`: Int = 0, - @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), -) : Structure() { - class UniffiByValue( - `returnValue`: Int = 0, - `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), - ): UniffiForeignFutureStructU32(`returnValue`,`callStatus`,), Structure.ByValue - - internal fun uniffiSetValue(other: UniffiForeignFutureStructU32) { - `returnValue` = other.`returnValue` - `callStatus` = other.`callStatus` - } - -} -internal interface UniffiForeignFutureCompleteU32 : com.sun.jna.Callback { - fun callback(`callbackData`: Long,`result`: UniffiForeignFutureStructU32.UniffiByValue,) -} -@Structure.FieldOrder("returnValue", "callStatus") -internal open class UniffiForeignFutureStructI32( - @JvmField internal var `returnValue`: Int = 0, - @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), -) : Structure() { - class UniffiByValue( - `returnValue`: Int = 0, - `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), - ): UniffiForeignFutureStructI32(`returnValue`,`callStatus`,), Structure.ByValue - - internal fun uniffiSetValue(other: UniffiForeignFutureStructI32) { - `returnValue` = other.`returnValue` - `callStatus` = other.`callStatus` - } - -} -internal interface UniffiForeignFutureCompleteI32 : com.sun.jna.Callback { - fun callback(`callbackData`: Long,`result`: UniffiForeignFutureStructI32.UniffiByValue,) -} -@Structure.FieldOrder("returnValue", "callStatus") -internal open class UniffiForeignFutureStructU64( - @JvmField internal var `returnValue`: Long = 0.toLong(), - @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), -) : Structure() { - class UniffiByValue( - `returnValue`: Long = 0.toLong(), - `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), - ): UniffiForeignFutureStructU64(`returnValue`,`callStatus`,), Structure.ByValue - - internal fun uniffiSetValue(other: UniffiForeignFutureStructU64) { - `returnValue` = other.`returnValue` - `callStatus` = other.`callStatus` - } - -} -internal interface UniffiForeignFutureCompleteU64 : com.sun.jna.Callback { - fun callback(`callbackData`: Long,`result`: UniffiForeignFutureStructU64.UniffiByValue,) -} -@Structure.FieldOrder("returnValue", "callStatus") -internal open class UniffiForeignFutureStructI64( - @JvmField internal var `returnValue`: Long = 0.toLong(), - @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), -) : Structure() { - class UniffiByValue( - `returnValue`: Long = 0.toLong(), - `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), - ): UniffiForeignFutureStructI64(`returnValue`,`callStatus`,), Structure.ByValue - - internal fun uniffiSetValue(other: UniffiForeignFutureStructI64) { - `returnValue` = other.`returnValue` - `callStatus` = other.`callStatus` - } - -} -internal interface UniffiForeignFutureCompleteI64 : com.sun.jna.Callback { - fun callback(`callbackData`: Long,`result`: UniffiForeignFutureStructI64.UniffiByValue,) -} -@Structure.FieldOrder("returnValue", "callStatus") -internal open class UniffiForeignFutureStructF32( - @JvmField internal var `returnValue`: Float = 0.0f, - @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), -) : Structure() { - class UniffiByValue( - `returnValue`: Float = 0.0f, - `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), - ): UniffiForeignFutureStructF32(`returnValue`,`callStatus`,), Structure.ByValue - - internal fun uniffiSetValue(other: UniffiForeignFutureStructF32) { - `returnValue` = other.`returnValue` - `callStatus` = other.`callStatus` - } - -} -internal interface UniffiForeignFutureCompleteF32 : com.sun.jna.Callback { - fun callback(`callbackData`: Long,`result`: UniffiForeignFutureStructF32.UniffiByValue,) -} -@Structure.FieldOrder("returnValue", "callStatus") -internal open class UniffiForeignFutureStructF64( - @JvmField internal var `returnValue`: Double = 0.0, - @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), -) : Structure() { - class UniffiByValue( - `returnValue`: Double = 0.0, - `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), - ): UniffiForeignFutureStructF64(`returnValue`,`callStatus`,), Structure.ByValue - - internal fun uniffiSetValue(other: UniffiForeignFutureStructF64) { - `returnValue` = other.`returnValue` - `callStatus` = other.`callStatus` - } - -} -internal interface UniffiForeignFutureCompleteF64 : com.sun.jna.Callback { - fun callback(`callbackData`: Long,`result`: UniffiForeignFutureStructF64.UniffiByValue,) -} -@Structure.FieldOrder("returnValue", "callStatus") -internal open class UniffiForeignFutureStructPointer( - @JvmField internal var `returnValue`: Pointer = Pointer.NULL, - @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), -) : Structure() { - class UniffiByValue( - `returnValue`: Pointer = Pointer.NULL, - `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), - ): UniffiForeignFutureStructPointer(`returnValue`,`callStatus`,), Structure.ByValue - - internal fun uniffiSetValue(other: UniffiForeignFutureStructPointer) { - `returnValue` = other.`returnValue` - `callStatus` = other.`callStatus` - } - -} -internal interface UniffiForeignFutureCompletePointer : com.sun.jna.Callback { - fun callback(`callbackData`: Long,`result`: UniffiForeignFutureStructPointer.UniffiByValue,) -} -@Structure.FieldOrder("returnValue", "callStatus") -internal open class UniffiForeignFutureStructRustBuffer( - @JvmField internal var `returnValue`: RustBuffer.ByValue = RustBuffer.ByValue(), - @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), -) : Structure() { - class UniffiByValue( - `returnValue`: RustBuffer.ByValue = RustBuffer.ByValue(), - `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), - ): UniffiForeignFutureStructRustBuffer(`returnValue`,`callStatus`,), Structure.ByValue - - internal fun uniffiSetValue(other: UniffiForeignFutureStructRustBuffer) { - `returnValue` = other.`returnValue` - `callStatus` = other.`callStatus` - } - -} -internal interface UniffiForeignFutureCompleteRustBuffer : com.sun.jna.Callback { - fun callback(`callbackData`: Long,`result`: UniffiForeignFutureStructRustBuffer.UniffiByValue,) -} -@Structure.FieldOrder("callStatus") -internal open class UniffiForeignFutureStructVoid( - @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), -) : Structure() { - class UniffiByValue( - `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(), - ): UniffiForeignFutureStructVoid(`callStatus`,), Structure.ByValue - - internal fun uniffiSetValue(other: UniffiForeignFutureStructVoid) { - `callStatus` = other.`callStatus` - } - -} -internal interface UniffiForeignFutureCompleteVoid : com.sun.jna.Callback { - fun callback(`callbackData`: Long,`result`: UniffiForeignFutureStructVoid.UniffiByValue,) -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// For large crates we prevent `MethodTooLargeException` (see #2340) -// N.B. the name of the extension is very misleading, since it is -// rather `InterfaceTooLargeException`, caused by too many methods -// in the interface for large crates. -// -// By splitting the otherwise huge interface into two parts -// * UniffiLib -// * IntegrityCheckingUniffiLib (this) -// we allow for ~2x as many methods in the UniffiLib interface. -// -// The `ffi_uniffi_contract_version` method and all checksum methods are put -// into `IntegrityCheckingUniffiLib` and these methods are called only once, -// when the library is loaded. -internal interface IntegrityCheckingUniffiLib : Library { - // Integrity check functions only - fun uniffi_algokit_algo25_ffi_checksum_func_master_derivation_key_to_mnemonic( -): Short -fun uniffi_algokit_algo25_ffi_checksum_func_mnemonic_from_seed( -): Short -fun uniffi_algokit_algo25_ffi_checksum_func_mnemonic_to_master_derivation_key( -): Short -fun uniffi_algokit_algo25_ffi_checksum_func_secret_key_to_mnemonic( -): Short -fun uniffi_algokit_algo25_ffi_checksum_func_seed_from_mnemonic( -): Short -fun ffi_algokit_algo25_ffi_uniffi_contract_version( -): Int - -} - -// A JNA Library to expose the extern-C FFI definitions. -// This is an implementation detail which will be called internally by the public API. -internal interface UniffiLib : Library { - companion object { - internal val INSTANCE: UniffiLib by lazy { - val componentName = "algokit_algo25_ffi" - // For large crates we prevent `MethodTooLargeException` (see #2340) - // N.B. the name of the extension is very misleading, since it is - // rather `InterfaceTooLargeException`, caused by too many methods - // in the interface for large crates. - // - // By splitting the otherwise huge interface into two parts - // * UniffiLib (this) - // * IntegrityCheckingUniffiLib - // And all checksum methods are put into `IntegrityCheckingUniffiLib` - // we allow for ~2x as many methods in the UniffiLib interface. - // - // Thus we first load the library with `loadIndirect` as `IntegrityCheckingUniffiLib` - // so that we can (optionally!) call `uniffiCheckApiChecksums`... - loadIndirect(componentName) - .also { lib: IntegrityCheckingUniffiLib -> - uniffiCheckContractApiVersion(lib) - uniffiCheckApiChecksums(lib) - } - // ... and then we load the library as `UniffiLib` - // N.B. we cannot use `loadIndirect` once and then try to cast it to `UniffiLib` - // => results in `java.lang.ClassCastException: com.sun.proxy.$Proxy cannot be cast to ...` - // error. So we must call `loadIndirect` twice. For crates large enough - // to trigger this issue, the performance impact is negligible, running on - // a macOS M1 machine the `loadIndirect` call takes ~50ms. - val lib = loadIndirect(componentName) - // No need to check the contract version and checksums, since - // we already did that with `IntegrityCheckingUniffiLib` above. - // Loading of library with integrity check done. - lib - } - - } - - // FFI functions - fun uniffi_algokit_algo25_ffi_fn_func_master_derivation_key_to_mnemonic(`mdk`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_algokit_algo25_ffi_fn_func_mnemonic_from_seed(`seed`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_algokit_algo25_ffi_fn_func_mnemonic_to_master_derivation_key(`mnemonic`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_algokit_algo25_ffi_fn_func_secret_key_to_mnemonic(`secretKey`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_algokit_algo25_ffi_fn_func_seed_from_mnemonic(`mnemonic`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun ffi_algokit_algo25_ffi_rustbuffer_alloc(`size`: Long,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun ffi_algokit_algo25_ffi_rustbuffer_from_bytes(`bytes`: ForeignBytes.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun ffi_algokit_algo25_ffi_rustbuffer_free(`buf`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): Unit -fun ffi_algokit_algo25_ffi_rustbuffer_reserve(`buf`: RustBuffer.ByValue,`additional`: Long,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun ffi_algokit_algo25_ffi_rust_future_poll_u8(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_cancel_u8(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_free_u8(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_complete_u8(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Byte -fun ffi_algokit_algo25_ffi_rust_future_poll_i8(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_cancel_i8(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_free_i8(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_complete_i8(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Byte -fun ffi_algokit_algo25_ffi_rust_future_poll_u16(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_cancel_u16(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_free_u16(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_complete_u16(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Short -fun ffi_algokit_algo25_ffi_rust_future_poll_i16(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_cancel_i16(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_free_i16(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_complete_i16(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Short -fun ffi_algokit_algo25_ffi_rust_future_poll_u32(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_cancel_u32(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_free_u32(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_complete_u32(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Int -fun ffi_algokit_algo25_ffi_rust_future_poll_i32(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_cancel_i32(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_free_i32(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_complete_i32(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Int -fun ffi_algokit_algo25_ffi_rust_future_poll_u64(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_cancel_u64(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_free_u64(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_complete_u64(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Long -fun ffi_algokit_algo25_ffi_rust_future_poll_i64(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_cancel_i64(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_free_i64(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_complete_i64(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Long -fun ffi_algokit_algo25_ffi_rust_future_poll_f32(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_cancel_f32(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_free_f32(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_complete_f32(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Float -fun ffi_algokit_algo25_ffi_rust_future_poll_f64(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_cancel_f64(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_free_f64(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_complete_f64(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Double -fun ffi_algokit_algo25_ffi_rust_future_poll_pointer(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_cancel_pointer(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_free_pointer(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_complete_pointer(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun ffi_algokit_algo25_ffi_rust_future_poll_rust_buffer(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_cancel_rust_buffer(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_free_rust_buffer(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_complete_rust_buffer(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun ffi_algokit_algo25_ffi_rust_future_poll_void(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_cancel_void(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_free_void(`handle`: Long, -): Unit -fun ffi_algokit_algo25_ffi_rust_future_complete_void(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Unit - -} - -private fun uniffiCheckContractApiVersion(lib: IntegrityCheckingUniffiLib) { - // Get the bindings contract version from our ComponentInterface - val bindings_contract_version = 29 - // Get the scaffolding contract version by calling the into the dylib - val scaffolding_contract_version = lib.ffi_algokit_algo25_ffi_uniffi_contract_version() - if (bindings_contract_version != scaffolding_contract_version) { - throw RuntimeException("UniFFI contract version mismatch: try cleaning and rebuilding your project") - } -} -@Suppress("UNUSED_PARAMETER") -private fun uniffiCheckApiChecksums(lib: IntegrityCheckingUniffiLib) { - if (lib.uniffi_algokit_algo25_ffi_checksum_func_master_derivation_key_to_mnemonic() != 32168.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_algokit_algo25_ffi_checksum_func_mnemonic_from_seed() != 8214.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_algokit_algo25_ffi_checksum_func_mnemonic_to_master_derivation_key() != 50816.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_algokit_algo25_ffi_checksum_func_secret_key_to_mnemonic() != 57306.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_algokit_algo25_ffi_checksum_func_seed_from_mnemonic() != 29635.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } -} - -/** - * @suppress - */ -public fun uniffiEnsureInitialized() { - UniffiLib.INSTANCE -} - -// Async support - -// Public interface members begin here. - - -// Interface implemented by anything that can contain an object reference. -// -// Such types expose a `destroy()` method that must be called to cleanly -// dispose of the contained objects. Failure to call this method may result -// in memory leaks. -// -// The easiest way to ensure this method is called is to use the `.use` -// helper method to execute a block and destroy the object at the end. -interface Disposable { - fun destroy() - companion object { - fun destroy(vararg args: Any?) { - for (arg in args) { - when (arg) { - is Disposable -> arg.destroy() - is ArrayList<*> -> { - for (idx in arg.indices) { - val element = arg[idx] - if (element is Disposable) { - element.destroy() - } - } - } - is Map<*, *> -> { - for (element in arg.values) { - if (element is Disposable) { - element.destroy() - } - } - } - is Iterable<*> -> { - for (element in arg) { - if (element is Disposable) { - element.destroy() - } - } - } - } - } - } - } -} - -/** - * @suppress - */ -inline fun T.use(block: (T) -> R) = - try { - block(this) - } finally { - try { - // N.B. our implementation is on the nullable type `Disposable?`. - this?.destroy() - } catch (e: Throwable) { - // swallow - } - } - -/** - * Used to instantiate an interface without an actual pointer, for fakes in tests, mostly. - * - * @suppress - * */ -object NoPointer - -/** - * @suppress - */ -public object FfiConverterULong: FfiConverter { - override fun lift(value: Long): ULong { - return value.toULong() - } - - override fun read(buf: ByteBuffer): ULong { - return lift(buf.getLong()) - } - - override fun lower(value: ULong): Long { - return value.toLong() - } - - override fun allocationSize(value: ULong) = 8UL - - override fun write(value: ULong, buf: ByteBuffer) { - buf.putLong(value.toLong()) - } -} - -/** - * @suppress - */ -public object FfiConverterString: FfiConverter { - // Note: we don't inherit from FfiConverterRustBuffer, because we use a - // special encoding when lowering/lifting. We can use `RustBuffer.len` to - // store our length and avoid writing it out to the buffer. - override fun lift(value: RustBuffer.ByValue): String { - try { - val byteArr = ByteArray(value.len.toInt()) - value.asByteBuffer()!!.get(byteArr) - return byteArr.toString(Charsets.UTF_8) - } finally { - RustBuffer.free(value) - } - } - - override fun read(buf: ByteBuffer): String { - val len = buf.getInt() - val byteArr = ByteArray(len) - buf.get(byteArr) - return byteArr.toString(Charsets.UTF_8) - } - - fun toUtf8(value: String): ByteBuffer { - // Make sure we don't have invalid UTF-16, check for lone surrogates. - return Charsets.UTF_8.newEncoder().run { - onMalformedInput(CodingErrorAction.REPORT) - encode(CharBuffer.wrap(value)) - } - } - - override fun lower(value: String): RustBuffer.ByValue { - val byteBuf = toUtf8(value) - // Ideally we'd pass these bytes to `ffi_bytebuffer_from_bytes`, but doing so would require us - // to copy them into a JNA `Memory`. So we might as well directly copy them into a `RustBuffer`. - val rbuf = RustBuffer.alloc(byteBuf.limit().toULong()) - rbuf.asByteBuffer()!!.put(byteBuf) - return rbuf - } - - // We aren't sure exactly how many bytes our string will be once it's UTF-8 - // encoded. Allocate 3 bytes per UTF-16 code unit which will always be - // enough. - override fun allocationSize(value: String): ULong { - val sizeForLength = 4UL - val sizeForString = value.length.toULong() * 3UL - return sizeForLength + sizeForString - } - - override fun write(value: String, buf: ByteBuffer) { - val byteBuf = toUtf8(value) - buf.putInt(byteBuf.limit()) - buf.put(byteBuf) - } -} - -/** - * @suppress - */ -public object FfiConverterByteArray: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): ByteArray { - val len = buf.getInt() - val byteArr = ByteArray(len) - buf.get(byteArr) - return byteArr - } - override fun allocationSize(value: ByteArray): ULong { - return 4UL + value.size.toULong() - } - override fun write(value: ByteArray, buf: ByteBuffer) { - buf.putInt(value.size) - buf.put(value) - } -} - - - -data class MnemonicError ( - var `kind`: MnemonicErrorKind, - var `expected`: kotlin.ULong?, - var `found`: kotlin.ULong? -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeMnemonicError: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): MnemonicError { - return MnemonicError( - FfiConverterTypeMnemonicErrorKind.read(buf), - FfiConverterOptionalULong.read(buf), - FfiConverterOptionalULong.read(buf), - ) - } - - override fun allocationSize(value: MnemonicError) = ( - FfiConverterTypeMnemonicErrorKind.allocationSize(value.`kind`) + - FfiConverterOptionalULong.allocationSize(value.`expected`) + - FfiConverterOptionalULong.allocationSize(value.`found`) - ) - - override fun write(value: MnemonicError, buf: ByteBuffer) { - FfiConverterTypeMnemonicErrorKind.write(value.`kind`, buf) - FfiConverterOptionalULong.write(value.`expected`, buf) - FfiConverterOptionalULong.write(value.`found`, buf) - } -} - - - - - -sealed class AlgoKitAlgo25Exception: kotlin.Exception() { - - class Exception( - - val `errMsg`: kotlin.String - ) : AlgoKitAlgo25Exception() { - override val message - get() = "errMsg=${ `errMsg` }" - } - - - companion object ErrorHandler : UniffiRustCallStatusErrorHandler { - override fun lift(error_buf: RustBuffer.ByValue): AlgoKitAlgo25Exception = FfiConverterTypeAlgoKitAlgo25Error.lift(error_buf) - } - - -} - -/** - * @suppress - */ -public object FfiConverterTypeAlgoKitAlgo25Error : FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): AlgoKitAlgo25Exception { - - - return when(buf.getInt()) { - 1 -> AlgoKitAlgo25Exception.Exception( - FfiConverterString.read(buf), - ) - else -> throw RuntimeException("invalid error enum value, something is very wrong!!") - } - } - - override fun allocationSize(value: AlgoKitAlgo25Exception): ULong { - return when(value) { - is AlgoKitAlgo25Exception.Exception -> ( - // Add the size for the Int that specifies the variant plus the size needed for all fields - 4UL - + FfiConverterString.allocationSize(value.`errMsg`) - ) - } - } - - override fun write(value: AlgoKitAlgo25Exception, buf: ByteBuffer) { - when(value) { - is AlgoKitAlgo25Exception.Exception -> { - buf.putInt(1) - FfiConverterString.write(value.`errMsg`, buf) - Unit - } - }.let { /* this makes the `when` an expression, which ensures it is exhaustive */ } - } - -} - - - - -enum class MnemonicErrorKind { - - INVALID_SEED_LENGTH, - NOT_IN_WORDS_LIST, - FAILED_TO_DECODE_MNEMONIC; - companion object -} - - -/** - * @suppress - */ -public object FfiConverterTypeMnemonicErrorKind: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer) = try { - MnemonicErrorKind.values()[buf.getInt() - 1] - } catch (e: IndexOutOfBoundsException) { - throw RuntimeException("invalid enum value, something is very wrong!!", e) - } - - override fun allocationSize(value: MnemonicErrorKind) = 4UL - - override fun write(value: MnemonicErrorKind, buf: ByteBuffer) { - buf.putInt(value.ordinal + 1) - } -} - - - - - - -/** - * @suppress - */ -public object FfiConverterOptionalULong: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): kotlin.ULong? { - if (buf.get().toInt() == 0) { - return null - } - return FfiConverterULong.read(buf) - } - - override fun allocationSize(value: kotlin.ULong?): ULong { - if (value == null) { - return 1UL - } else { - return 1UL + FfiConverterULong.allocationSize(value) - } - } - - override fun write(value: kotlin.ULong?, buf: ByteBuffer) { - if (value == null) { - buf.put(0) - } else { - buf.put(1) - FfiConverterULong.write(value, buf) - } - } -} - @Throws(AlgoKitAlgo25Exception::class) fun `masterDerivationKeyToMnemonic`(`mdk`: kotlin.ByteArray): kotlin.String { - return FfiConverterString.lift( - uniffiRustCallWithError(AlgoKitAlgo25Exception) { _status -> - UniffiLib.INSTANCE.uniffi_algokit_algo25_ffi_fn_func_master_derivation_key_to_mnemonic( - FfiConverterByteArray.lower(`mdk`),_status) -} - ) - } - - - @Throws(AlgoKitAlgo25Exception::class) fun `mnemonicFromSeed`(`seed`: kotlin.ByteArray): kotlin.String { - return FfiConverterString.lift( - uniffiRustCallWithError(AlgoKitAlgo25Exception) { _status -> - UniffiLib.INSTANCE.uniffi_algokit_algo25_ffi_fn_func_mnemonic_from_seed( - FfiConverterByteArray.lower(`seed`),_status) -} - ) - } - - - @Throws(AlgoKitAlgo25Exception::class) fun `mnemonicToMasterDerivationKey`(`mnemonic`: kotlin.String): kotlin.ByteArray { - return FfiConverterByteArray.lift( - uniffiRustCallWithError(AlgoKitAlgo25Exception) { _status -> - UniffiLib.INSTANCE.uniffi_algokit_algo25_ffi_fn_func_mnemonic_to_master_derivation_key( - FfiConverterString.lower(`mnemonic`),_status) -} - ) - } - - - @Throws(AlgoKitAlgo25Exception::class) fun `secretKeyToMnemonic`(`secretKey`: kotlin.ByteArray): kotlin.String { - return FfiConverterString.lift( - uniffiRustCallWithError(AlgoKitAlgo25Exception) { _status -> - UniffiLib.INSTANCE.uniffi_algokit_algo25_ffi_fn_func_secret_key_to_mnemonic( - FfiConverterByteArray.lower(`secretKey`),_status) -} - ) - } - - - @Throws(AlgoKitAlgo25Exception::class) fun `seedFromMnemonic`(`mnemonic`: kotlin.String): kotlin.ByteArray { - return FfiConverterByteArray.lift( - uniffiRustCallWithError(AlgoKitAlgo25Exception) { _status -> - UniffiLib.INSTANCE.uniffi_algokit_algo25_ffi_fn_func_seed_from_mnemonic( - FfiConverterString.lower(`mnemonic`),_status) -} - ) - } - - - diff --git a/packages/android/algokit_crypto/build.gradle.kts b/packages/android/algokit_crypto/build.gradle.kts index 24825151..f1d487cf 100644 --- a/packages/android/algokit_crypto/build.gradle.kts +++ b/packages/android/algokit_crypto/build.gradle.kts @@ -7,10 +7,11 @@ plugins { alias(libs.plugins.android.library) alias(libs.plugins.kotlin.android) + alias(libs.plugins.maven.publish) } android { - namespace = "com.example.algokit_crypto" + namespace = "io.github.algorandecosystem.algokit_crypto" compileSdk = 36 defaultConfig { @@ -51,3 +52,40 @@ dependencies { androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) } + +mavenPublishing { + coordinates( + "io.github.algorandecosystem", + "algokit-crypto", + System.getenv("VERSION_TAG") ?: "0.0.1-SNAPSHOT" + ) + + pom { + name.set("AlgoKit Crypto") + description.set("Algorand cryptographic operations for Android") + url.set("https://github.com/algorandfoundation/algokit-core") + + licenses { + license { + name.set("MIT License") + url.set("https://opensource.org/licenses/MIT") + } + } + + developers { + developer { + id.set("algorandfoundation") + name.set("Joe Polny") + email.set("joe@algorand.foundation") + organization.set("Algorand Foundation") + organizationUrl.set("https://algorand.foundation") + } + } + + scm { + connection.set("scm:git:git://github.com/algorandfoundation/algokit-core.git") + developerConnection.set("scm:git:ssh://github.com:algorandfoundation/algokit-core.git") + url.set("https://github.com/algorandfoundation/algokit-core") + } + } +} diff --git a/packages/android/algokit_crypto/gradle/libs.versions.toml b/packages/android/algokit_crypto/gradle/libs.versions.toml index b384b8b1..d03b8f53 100644 --- a/packages/android/algokit_crypto/gradle/libs.versions.toml +++ b/packages/android/algokit_crypto/gradle/libs.versions.toml @@ -7,6 +7,7 @@ junitVersion = "1.2.1" espressoCore = "3.6.1" appcompat = "1.7.0" material = "1.12.0" +mavenPublish = "0.30.0" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -20,3 +21,4 @@ material = { group = "com.google.android.material", name = "material", version.r android-application = { id = "com.android.application", version.ref = "agp" } android-library = { id = "com.android.library", version.ref = "agp" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "mavenPublish" } diff --git a/packages/android/algokit_transact/build.gradle.kts b/packages/android/algokit_transact/build.gradle.kts index 4038d079..d23d2414 100644 --- a/packages/android/algokit_transact/build.gradle.kts +++ b/packages/android/algokit_transact/build.gradle.kts @@ -5,56 +5,87 @@ * Learn more about Gradle by exploring our Samples at https://docs.gradle.org/8.14.2/samples */ plugins { - alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.android) + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.maven.publish) } android { - namespace = "com.example.algokit_transact" - compileSdk = 36 + namespace = "io.github.algorandecosystem.algokit_transact" + compileSdk = 36 - defaultConfig { - minSdk = 28 + defaultConfig { + minSdk = 28 - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") } - kotlinOptions { - jvmTarget = "21" - } - testOptions { - unitTests { - isIncludeAndroidResources = true - all { - it.systemProperty("jna.library.path", "src/test/resources") - } - } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 + } + kotlinOptions { jvmTarget = "21" } + testOptions { + unitTests { + isIncludeAndroidResources = true + all { it.systemProperty("jna.library.path", "src/test/resources") } } + } } dependencies { - implementation("net.java.dev.jna:jna:5.14.0@aar") - // Use full JNA JAR for unit tests (includes native dispatch libraries) - testImplementation("net.java.dev.jna:jna:5.14.0") - - implementation(libs.androidx.core.ktx) - implementation(libs.androidx.appcompat) - implementation(libs.material) - testImplementation(libs.junit) - androidTestImplementation(libs.androidx.junit) - androidTestImplementation(libs.androidx.espresso.core) + implementation("net.java.dev.jna:jna:5.14.0@aar") + // Use full JNA JAR for unit tests (includes native dispatch libraries) + testImplementation("net.java.dev.jna:jna:5.14.0") + + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.appcompat) + implementation(libs.material) + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.espresso.core) +} + +mavenPublishing { + coordinates( + "io.github.algorandecosystem", + "algokit-transact", + System.getenv("VERSION_TAG") ?: "0.0.1-SNAPSHOT" + ) + + pom { + name.set("AlgoKit Transact") + description.set("Algorand transaction operations for Android") + url.set("https://github.com/algorandfoundation/algokit-core") + + licenses { + license { + name.set("MIT License") + url.set("https://opensource.org/licenses/MIT") + } + } + + developers { + developer { + id.set("algorandfoundation") + name.set("Joe Polny") + email.set("joe@algorand.foundation") + organization.set("Algorand Foundation") + organizationUrl.set("https://algorand.foundation") + } + } + + scm { + connection.set("scm:git:git://github.com/algorandfoundation/algokit-core.git") + developerConnection.set("scm:git:ssh://github.com:algorandfoundation/algokit-core.git") + url.set("https://github.com/algorandfoundation/algokit-core") + } + } } diff --git a/packages/android/algokit_transact/gradle/libs.versions.toml b/packages/android/algokit_transact/gradle/libs.versions.toml index ff68a35c..d03b8f53 100644 --- a/packages/android/algokit_transact/gradle/libs.versions.toml +++ b/packages/android/algokit_transact/gradle/libs.versions.toml @@ -7,6 +7,7 @@ junitVersion = "1.2.1" espressoCore = "3.6.1" appcompat = "1.7.0" material = "1.12.0" +mavenPublish = "0.30.0" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -20,5 +21,4 @@ material = { group = "com.google.android.material", name = "material", version.r android-application = { id = "com.android.application", version.ref = "agp" } android-library = { id = "com.android.library", version.ref = "agp" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } - - +maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "mavenPublish" } diff --git a/packages/swift/AlgoKitAlgo25/.gitignore b/packages/swift/AlgoKitAlgo25/.gitignore deleted file mode 100644 index 0023a534..00000000 --- a/packages/swift/AlgoKitAlgo25/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -.DS_Store -/.build -/Packages -xcuserdata/ -DerivedData/ -.swiftpm/configuration/registries.json -.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata -.netrc diff --git a/packages/swift/AlgoKitAlgo25/Package.swift b/packages/swift/AlgoKitAlgo25/Package.swift deleted file mode 100644 index 7d9f197c..00000000 --- a/packages/swift/AlgoKitAlgo25/Package.swift +++ /dev/null @@ -1,33 +0,0 @@ -// swift-tools-version: 6.0 -// The swift-tools-version declares the minimum version of Swift required to build this package. - -import PackageDescription - -let package = Package( - name: "AlgoKitAlgo25", - products: [ - // Products define the executables and libraries a package produces, making them visible to other packages. - .library( - name: "AlgoKitAlgo25", - targets: ["AlgoKitAlgo25"]) - ], - targets: [ - // Targets are the basic building blocks of a package, defining a module or a test suite. - // Targets can depend on other targets in this package and products from dependencies. - .binaryTarget( - name: "algokit_algo25FFI", - path: "Frameworks/algokit_algo25.xcframework" - ), - .target( - name: "AlgoKitAlgo25", - dependencies: ["algokit_algo25FFI"], - path: "Sources/AlgoKitAlgo25" - ), - .testTarget( - name: "AlgoKitAlgo25Tests", - dependencies: [ - "AlgoKitAlgo25" - ], - ), - ] -) diff --git a/packages/swift/AlgoKitAlgo25/Sources/AlgoKitAlgo25/AlgokitAlgo25.swift b/packages/swift/AlgoKitAlgo25/Sources/AlgoKitAlgo25/AlgokitAlgo25.swift deleted file mode 100644 index 0f5b9b13..00000000 --- a/packages/swift/AlgoKitAlgo25/Sources/AlgoKitAlgo25/AlgokitAlgo25.swift +++ /dev/null @@ -1,812 +0,0 @@ -// This file was autogenerated by some hot garbage in the `uniffi` crate. -// Trust me, you don't want to mess with it! - -// swiftlint:disable all -import Foundation - -// Depending on the consumer's build setup, the low-level FFI code -// might be in a separate module, or it might be compiled inline into -// this module. This is a bit of light hackery to work with both. -#if canImport(algokit_algo25FFI) -import algokit_algo25FFI -#endif - -fileprivate extension RustBuffer { - // Allocate a new buffer, copying the contents of a `UInt8` array. - init(bytes: [UInt8]) { - let rbuf = bytes.withUnsafeBufferPointer { ptr in - RustBuffer.from(ptr) - } - self.init(capacity: rbuf.capacity, len: rbuf.len, data: rbuf.data) - } - - static func empty() -> RustBuffer { - RustBuffer(capacity: 0, len:0, data: nil) - } - - static func from(_ ptr: UnsafeBufferPointer) -> RustBuffer { - try! rustCall { ffi_algokit_algo25_ffi_rustbuffer_from_bytes(ForeignBytes(bufferPointer: ptr), $0) } - } - - // Frees the buffer in place. - // The buffer must not be used after this is called. - func deallocate() { - try! rustCall { ffi_algokit_algo25_ffi_rustbuffer_free(self, $0) } - } -} - -fileprivate extension ForeignBytes { - init(bufferPointer: UnsafeBufferPointer) { - self.init(len: Int32(bufferPointer.count), data: bufferPointer.baseAddress) - } -} - -// For every type used in the interface, we provide helper methods for conveniently -// lifting and lowering that type from C-compatible data, and for reading and writing -// values of that type in a buffer. - -// Helper classes/extensions that don't change. -// Someday, this will be in a library of its own. - -fileprivate extension Data { - init(rustBuffer: RustBuffer) { - self.init( - bytesNoCopy: rustBuffer.data!, - count: Int(rustBuffer.len), - deallocator: .none - ) - } -} - -// Define reader functionality. Normally this would be defined in a class or -// struct, but we use standalone functions instead in order to make external -// types work. -// -// With external types, one swift source file needs to be able to call the read -// method on another source file's FfiConverter, but then what visibility -// should Reader have? -// - If Reader is fileprivate, then this means the read() must also -// be fileprivate, which doesn't work with external types. -// - If Reader is internal/public, we'll get compile errors since both source -// files will try define the same type. -// -// Instead, the read() method and these helper functions input a tuple of data - -fileprivate func createReader(data: Data) -> (data: Data, offset: Data.Index) { - (data: data, offset: 0) -} - -// Reads an integer at the current offset, in big-endian order, and advances -// the offset on success. Throws if reading the integer would move the -// offset past the end of the buffer. -fileprivate func readInt(_ reader: inout (data: Data, offset: Data.Index)) throws -> T { - let range = reader.offset...size - guard reader.data.count >= range.upperBound else { - throw UniffiInternalError.bufferOverflow - } - if T.self == UInt8.self { - let value = reader.data[reader.offset] - reader.offset += 1 - return value as! T - } - var value: T = 0 - let _ = withUnsafeMutableBytes(of: &value, { reader.data.copyBytes(to: $0, from: range)}) - reader.offset = range.upperBound - return value.bigEndian -} - -// Reads an arbitrary number of bytes, to be used to read -// raw bytes, this is useful when lifting strings -fileprivate func readBytes(_ reader: inout (data: Data, offset: Data.Index), count: Int) throws -> Array { - let range = reader.offset..<(reader.offset+count) - guard reader.data.count >= range.upperBound else { - throw UniffiInternalError.bufferOverflow - } - var value = [UInt8](repeating: 0, count: count) - value.withUnsafeMutableBufferPointer({ buffer in - reader.data.copyBytes(to: buffer, from: range) - }) - reader.offset = range.upperBound - return value -} - -// Reads a float at the current offset. -fileprivate func readFloat(_ reader: inout (data: Data, offset: Data.Index)) throws -> Float { - return Float(bitPattern: try readInt(&reader)) -} - -// Reads a float at the current offset. -fileprivate func readDouble(_ reader: inout (data: Data, offset: Data.Index)) throws -> Double { - return Double(bitPattern: try readInt(&reader)) -} - -// Indicates if the offset has reached the end of the buffer. -fileprivate func hasRemaining(_ reader: (data: Data, offset: Data.Index)) -> Bool { - return reader.offset < reader.data.count -} - -// Define writer functionality. Normally this would be defined in a class or -// struct, but we use standalone functions instead in order to make external -// types work. See the above discussion on Readers for details. - -fileprivate func createWriter() -> [UInt8] { - return [] -} - -fileprivate func writeBytes(_ writer: inout [UInt8], _ byteArr: S) where S: Sequence, S.Element == UInt8 { - writer.append(contentsOf: byteArr) -} - -// Writes an integer in big-endian order. -// -// Warning: make sure what you are trying to write -// is in the correct type! -fileprivate func writeInt(_ writer: inout [UInt8], _ value: T) { - var value = value.bigEndian - withUnsafeBytes(of: &value) { writer.append(contentsOf: $0) } -} - -fileprivate func writeFloat(_ writer: inout [UInt8], _ value: Float) { - writeInt(&writer, value.bitPattern) -} - -fileprivate func writeDouble(_ writer: inout [UInt8], _ value: Double) { - writeInt(&writer, value.bitPattern) -} - -// Protocol for types that transfer other types across the FFI. This is -// analogous to the Rust trait of the same name. -fileprivate protocol FfiConverter { - associatedtype FfiType - associatedtype SwiftType - - static func lift(_ value: FfiType) throws -> SwiftType - static func lower(_ value: SwiftType) -> FfiType - static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType - static func write(_ value: SwiftType, into buf: inout [UInt8]) -} - -// Types conforming to `Primitive` pass themselves directly over the FFI. -fileprivate protocol FfiConverterPrimitive: FfiConverter where FfiType == SwiftType { } - -extension FfiConverterPrimitive { -#if swift(>=5.8) - @_documentation(visibility: private) -#endif - public static func lift(_ value: FfiType) throws -> SwiftType { - return value - } - -#if swift(>=5.8) - @_documentation(visibility: private) -#endif - public static func lower(_ value: SwiftType) -> FfiType { - return value - } -} - -// Types conforming to `FfiConverterRustBuffer` lift and lower into a `RustBuffer`. -// Used for complex types where it's hard to write a custom lift/lower. -fileprivate protocol FfiConverterRustBuffer: FfiConverter where FfiType == RustBuffer {} - -extension FfiConverterRustBuffer { -#if swift(>=5.8) - @_documentation(visibility: private) -#endif - public static func lift(_ buf: RustBuffer) throws -> SwiftType { - var reader = createReader(data: Data(rustBuffer: buf)) - let value = try read(from: &reader) - if hasRemaining(reader) { - throw UniffiInternalError.incompleteData - } - buf.deallocate() - return value - } - -#if swift(>=5.8) - @_documentation(visibility: private) -#endif - public static func lower(_ value: SwiftType) -> RustBuffer { - var writer = createWriter() - write(value, into: &writer) - return RustBuffer(bytes: writer) - } -} -// An error type for FFI errors. These errors occur at the UniFFI level, not -// the library level. -fileprivate enum UniffiInternalError: LocalizedError { - case bufferOverflow - case incompleteData - case unexpectedOptionalTag - case unexpectedEnumCase - case unexpectedNullPointer - case unexpectedRustCallStatusCode - case unexpectedRustCallError - case unexpectedStaleHandle - case rustPanic(_ message: String) - - public var errorDescription: String? { - switch self { - case .bufferOverflow: return "Reading the requested value would read past the end of the buffer" - case .incompleteData: return "The buffer still has data after lifting its containing value" - case .unexpectedOptionalTag: return "Unexpected optional tag; should be 0 or 1" - case .unexpectedEnumCase: return "Raw enum value doesn't match any cases" - case .unexpectedNullPointer: return "Raw pointer value was null" - case .unexpectedRustCallStatusCode: return "Unexpected RustCallStatus code" - case .unexpectedRustCallError: return "CALL_ERROR but no errorClass specified" - case .unexpectedStaleHandle: return "The object in the handle map has been dropped already" - case let .rustPanic(message): return message - } - } -} - -fileprivate extension NSLock { - func withLock(f: () throws -> T) rethrows -> T { - self.lock() - defer { self.unlock() } - return try f() - } -} - -fileprivate let CALL_SUCCESS: Int8 = 0 -fileprivate let CALL_ERROR: Int8 = 1 -fileprivate let CALL_UNEXPECTED_ERROR: Int8 = 2 -fileprivate let CALL_CANCELLED: Int8 = 3 - -fileprivate extension RustCallStatus { - init() { - self.init( - code: CALL_SUCCESS, - errorBuf: RustBuffer.init( - capacity: 0, - len: 0, - data: nil - ) - ) - } -} - -private func rustCall(_ callback: (UnsafeMutablePointer) -> T) throws -> T { - let neverThrow: ((RustBuffer) throws -> Never)? = nil - return try makeRustCall(callback, errorHandler: neverThrow) -} - -private func rustCallWithError( - _ errorHandler: @escaping (RustBuffer) throws -> E, - _ callback: (UnsafeMutablePointer) -> T) throws -> T { - try makeRustCall(callback, errorHandler: errorHandler) -} - -private func makeRustCall( - _ callback: (UnsafeMutablePointer) -> T, - errorHandler: ((RustBuffer) throws -> E)? -) throws -> T { - uniffiEnsureAlgokitAlgo25FfiInitialized() - var callStatus = RustCallStatus.init() - let returnedVal = callback(&callStatus) - try uniffiCheckCallStatus(callStatus: callStatus, errorHandler: errorHandler) - return returnedVal -} - -private func uniffiCheckCallStatus( - callStatus: RustCallStatus, - errorHandler: ((RustBuffer) throws -> E)? -) throws { - switch callStatus.code { - case CALL_SUCCESS: - return - - case CALL_ERROR: - if let errorHandler = errorHandler { - throw try errorHandler(callStatus.errorBuf) - } else { - callStatus.errorBuf.deallocate() - throw UniffiInternalError.unexpectedRustCallError - } - - case CALL_UNEXPECTED_ERROR: - // When the rust code sees a panic, it tries to construct a RustBuffer - // with the message. But if that code panics, then it just sends back - // an empty buffer. - if callStatus.errorBuf.len > 0 { - throw UniffiInternalError.rustPanic(try FfiConverterString.lift(callStatus.errorBuf)) - } else { - callStatus.errorBuf.deallocate() - throw UniffiInternalError.rustPanic("Rust panic") - } - - case CALL_CANCELLED: - fatalError("Cancellation not supported yet") - - default: - throw UniffiInternalError.unexpectedRustCallStatusCode - } -} - -private func uniffiTraitInterfaceCall( - callStatus: UnsafeMutablePointer, - makeCall: () throws -> T, - writeReturn: (T) -> () -) { - do { - try writeReturn(makeCall()) - } catch let error { - callStatus.pointee.code = CALL_UNEXPECTED_ERROR - callStatus.pointee.errorBuf = FfiConverterString.lower(String(describing: error)) - } -} - -private func uniffiTraitInterfaceCallWithError( - callStatus: UnsafeMutablePointer, - makeCall: () throws -> T, - writeReturn: (T) -> (), - lowerError: (E) -> RustBuffer -) { - do { - try writeReturn(makeCall()) - } catch let error as E { - callStatus.pointee.code = CALL_ERROR - callStatus.pointee.errorBuf = lowerError(error) - } catch { - callStatus.pointee.code = CALL_UNEXPECTED_ERROR - callStatus.pointee.errorBuf = FfiConverterString.lower(String(describing: error)) - } -} -fileprivate final class UniffiHandleMap: @unchecked Sendable { - // All mutation happens with this lock held, which is why we implement @unchecked Sendable. - private let lock = NSLock() - private var map: [UInt64: T] = [:] - private var currentHandle: UInt64 = 1 - - func insert(obj: T) -> UInt64 { - lock.withLock { - let handle = currentHandle - currentHandle += 1 - map[handle] = obj - return handle - } - } - - func get(handle: UInt64) throws -> T { - try lock.withLock { - guard let obj = map[handle] else { - throw UniffiInternalError.unexpectedStaleHandle - } - return obj - } - } - - @discardableResult - func remove(handle: UInt64) throws -> T { - try lock.withLock { - guard let obj = map.removeValue(forKey: handle) else { - throw UniffiInternalError.unexpectedStaleHandle - } - return obj - } - } - - var count: Int { - get { - map.count - } - } -} - - -// Public interface members begin here. - - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -fileprivate struct FfiConverterUInt64: FfiConverterPrimitive { - typealias FfiType = UInt64 - typealias SwiftType = UInt64 - - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UInt64 { - return try lift(readInt(&buf)) - } - - public static func write(_ value: SwiftType, into buf: inout [UInt8]) { - writeInt(&buf, lower(value)) - } -} - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -fileprivate struct FfiConverterString: FfiConverter { - typealias SwiftType = String - typealias FfiType = RustBuffer - - public static func lift(_ value: RustBuffer) throws -> String { - defer { - value.deallocate() - } - if value.data == nil { - return String() - } - let bytes = UnsafeBufferPointer(start: value.data!, count: Int(value.len)) - return String(bytes: bytes, encoding: String.Encoding.utf8)! - } - - public static func lower(_ value: String) -> RustBuffer { - return value.utf8CString.withUnsafeBufferPointer { ptr in - // The swift string gives us int8_t, we want uint8_t. - ptr.withMemoryRebound(to: UInt8.self) { ptr in - // The swift string gives us a trailing null byte, we don't want it. - let buf = UnsafeBufferPointer(rebasing: ptr.prefix(upTo: ptr.count - 1)) - return RustBuffer.from(buf) - } - } - } - - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> String { - let len: Int32 = try readInt(&buf) - return String(bytes: try readBytes(&buf, count: Int(len)), encoding: String.Encoding.utf8)! - } - - public static func write(_ value: String, into buf: inout [UInt8]) { - let len = Int32(value.utf8.count) - writeInt(&buf, len) - writeBytes(&buf, value.utf8) - } -} - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -fileprivate struct FfiConverterData: FfiConverterRustBuffer { - typealias SwiftType = Data - - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Data { - let len: Int32 = try readInt(&buf) - return Data(try readBytes(&buf, count: Int(len))) - } - - public static func write(_ value: Data, into buf: inout [UInt8]) { - let len = Int32(value.count) - writeInt(&buf, len) - writeBytes(&buf, value) - } -} - - -public struct MnemonicError { - public var kind: MnemonicErrorKind - public var expected: UInt64? - public var found: UInt64? - - // Default memberwise initializers are never public by default, so we - // declare one manually. - public init(kind: MnemonicErrorKind, expected: UInt64?, found: UInt64?) { - self.kind = kind - self.expected = expected - self.found = found - } -} - -#if compiler(>=6) -extension MnemonicError: Sendable {} -#endif - - -extension MnemonicError: Equatable, Hashable { - public static func ==(lhs: MnemonicError, rhs: MnemonicError) -> Bool { - if lhs.kind != rhs.kind { - return false - } - if lhs.expected != rhs.expected { - return false - } - if lhs.found != rhs.found { - return false - } - return true - } - - public func hash(into hasher: inout Hasher) { - hasher.combine(kind) - hasher.combine(expected) - hasher.combine(found) - } -} - - - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public struct FfiConverterTypeMnemonicError: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> MnemonicError { - return - try MnemonicError( - kind: FfiConverterTypeMnemonicErrorKind.read(from: &buf), - expected: FfiConverterOptionUInt64.read(from: &buf), - found: FfiConverterOptionUInt64.read(from: &buf) - ) - } - - public static func write(_ value: MnemonicError, into buf: inout [UInt8]) { - FfiConverterTypeMnemonicErrorKind.write(value.kind, into: &buf) - FfiConverterOptionUInt64.write(value.expected, into: &buf) - FfiConverterOptionUInt64.write(value.found, into: &buf) - } -} - - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public func FfiConverterTypeMnemonicError_lift(_ buf: RustBuffer) throws -> MnemonicError { - return try FfiConverterTypeMnemonicError.lift(buf) -} - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public func FfiConverterTypeMnemonicError_lower(_ value: MnemonicError) -> RustBuffer { - return FfiConverterTypeMnemonicError.lower(value) -} - - -public enum AlgoKitAlgo25Error: Swift.Error { - - - - case Error(errMsg: String - ) -} - - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public struct FfiConverterTypeAlgoKitAlgo25Error: FfiConverterRustBuffer { - typealias SwiftType = AlgoKitAlgo25Error - - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AlgoKitAlgo25Error { - let variant: Int32 = try readInt(&buf) - switch variant { - - - - - case 1: return .Error( - errMsg: try FfiConverterString.read(from: &buf) - ) - - default: throw UniffiInternalError.unexpectedEnumCase - } - } - - public static func write(_ value: AlgoKitAlgo25Error, into buf: inout [UInt8]) { - switch value { - - - - - - case let .Error(errMsg): - writeInt(&buf, Int32(1)) - FfiConverterString.write(errMsg, into: &buf) - - } - } -} - - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public func FfiConverterTypeAlgoKitAlgo25Error_lift(_ buf: RustBuffer) throws -> AlgoKitAlgo25Error { - return try FfiConverterTypeAlgoKitAlgo25Error.lift(buf) -} - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public func FfiConverterTypeAlgoKitAlgo25Error_lower(_ value: AlgoKitAlgo25Error) -> RustBuffer { - return FfiConverterTypeAlgoKitAlgo25Error.lower(value) -} - - -extension AlgoKitAlgo25Error: Equatable, Hashable {} - - - - -extension AlgoKitAlgo25Error: Foundation.LocalizedError { - public var errorDescription: String? { - String(reflecting: self) - } -} - - - - -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. - -public enum MnemonicErrorKind { - - case invalidSeedLength - case notInWordsList - case failedToDecodeMnemonic -} - - -#if compiler(>=6) -extension MnemonicErrorKind: Sendable {} -#endif - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public struct FfiConverterTypeMnemonicErrorKind: FfiConverterRustBuffer { - typealias SwiftType = MnemonicErrorKind - - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> MnemonicErrorKind { - let variant: Int32 = try readInt(&buf) - switch variant { - - case 1: return .invalidSeedLength - - case 2: return .notInWordsList - - case 3: return .failedToDecodeMnemonic - - default: throw UniffiInternalError.unexpectedEnumCase - } - } - - public static func write(_ value: MnemonicErrorKind, into buf: inout [UInt8]) { - switch value { - - - case .invalidSeedLength: - writeInt(&buf, Int32(1)) - - - case .notInWordsList: - writeInt(&buf, Int32(2)) - - - case .failedToDecodeMnemonic: - writeInt(&buf, Int32(3)) - - } - } -} - - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public func FfiConverterTypeMnemonicErrorKind_lift(_ buf: RustBuffer) throws -> MnemonicErrorKind { - return try FfiConverterTypeMnemonicErrorKind.lift(buf) -} - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -public func FfiConverterTypeMnemonicErrorKind_lower(_ value: MnemonicErrorKind) -> RustBuffer { - return FfiConverterTypeMnemonicErrorKind.lower(value) -} - - -extension MnemonicErrorKind: Equatable, Hashable {} - - - - - - -#if swift(>=5.8) -@_documentation(visibility: private) -#endif -fileprivate struct FfiConverterOptionUInt64: FfiConverterRustBuffer { - typealias SwiftType = UInt64? - - public static func write(_ value: SwiftType, into buf: inout [UInt8]) { - guard let value = value else { - writeInt(&buf, Int8(0)) - return - } - writeInt(&buf, Int8(1)) - FfiConverterUInt64.write(value, into: &buf) - } - - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { - switch try readInt(&buf) as Int8 { - case 0: return nil - case 1: return try FfiConverterUInt64.read(from: &buf) - default: throw UniffiInternalError.unexpectedOptionalTag - } - } -} -public func masterDerivationKeyToMnemonic(mdk: Data)throws -> String { - return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeAlgoKitAlgo25Error_lift) { - uniffi_algokit_algo25_ffi_fn_func_master_derivation_key_to_mnemonic( - FfiConverterData.lower(mdk),$0 - ) -}) -} -public func mnemonicFromSeed(seed: Data)throws -> String { - return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeAlgoKitAlgo25Error_lift) { - uniffi_algokit_algo25_ffi_fn_func_mnemonic_from_seed( - FfiConverterData.lower(seed),$0 - ) -}) -} -public func mnemonicToMasterDerivationKey(mnemonic: String)throws -> Data { - return try FfiConverterData.lift(try rustCallWithError(FfiConverterTypeAlgoKitAlgo25Error_lift) { - uniffi_algokit_algo25_ffi_fn_func_mnemonic_to_master_derivation_key( - FfiConverterString.lower(mnemonic),$0 - ) -}) -} -public func secretKeyToMnemonic(secretKey: Data)throws -> String { - return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeAlgoKitAlgo25Error_lift) { - uniffi_algokit_algo25_ffi_fn_func_secret_key_to_mnemonic( - FfiConverterData.lower(secretKey),$0 - ) -}) -} -public func seedFromMnemonic(mnemonic: String)throws -> Data { - return try FfiConverterData.lift(try rustCallWithError(FfiConverterTypeAlgoKitAlgo25Error_lift) { - uniffi_algokit_algo25_ffi_fn_func_seed_from_mnemonic( - FfiConverterString.lower(mnemonic),$0 - ) -}) -} - -private enum InitializationResult { - case ok - case contractVersionMismatch - case apiChecksumMismatch -} -// Use a global variable to perform the versioning checks. Swift ensures that -// the code inside is only computed once. -private let initializationResult: InitializationResult = { - // Get the bindings contract version from our ComponentInterface - let bindings_contract_version = 29 - // Get the scaffolding contract version by calling the into the dylib - let scaffolding_contract_version = ffi_algokit_algo25_ffi_uniffi_contract_version() - if bindings_contract_version != scaffolding_contract_version { - return InitializationResult.contractVersionMismatch - } - if (uniffi_algokit_algo25_ffi_checksum_func_master_derivation_key_to_mnemonic() != 32168) { - return InitializationResult.apiChecksumMismatch - } - if (uniffi_algokit_algo25_ffi_checksum_func_mnemonic_from_seed() != 8214) { - return InitializationResult.apiChecksumMismatch - } - if (uniffi_algokit_algo25_ffi_checksum_func_mnemonic_to_master_derivation_key() != 50816) { - return InitializationResult.apiChecksumMismatch - } - if (uniffi_algokit_algo25_ffi_checksum_func_secret_key_to_mnemonic() != 57306) { - return InitializationResult.apiChecksumMismatch - } - if (uniffi_algokit_algo25_ffi_checksum_func_seed_from_mnemonic() != 29635) { - return InitializationResult.apiChecksumMismatch - } - - return InitializationResult.ok -}() - -// Make the ensure init function public so that other modules which have external type references to -// our types can call it. -public func uniffiEnsureAlgokitAlgo25FfiInitialized() { - switch initializationResult { - case .ok: - break - case .contractVersionMismatch: - fatalError("UniFFI contract version mismatch: try cleaning and rebuilding your project") - case .apiChecksumMismatch: - fatalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } -} - -// swiftlint:enable all \ No newline at end of file diff --git a/packages/swift/AlgoKitAlgo25/Tests/AlgoKitAlgo25Tests/AlgoKitAlgo25Tests.swift b/packages/swift/AlgoKitAlgo25/Tests/AlgoKitAlgo25Tests/AlgoKitAlgo25Tests.swift deleted file mode 100644 index 66d3ab0d..00000000 --- a/packages/swift/AlgoKitAlgo25/Tests/AlgoKitAlgo25Tests/AlgoKitAlgo25Tests.swift +++ /dev/null @@ -1,6 +0,0 @@ -import Testing -@testable import AlgoKitAlgo25 - -@Test func example() async throws { - // Write your test here and use APIs like `#expect(...)` to check expected conditions. -}