diff --git a/libs/gl-sdk-android/.gitignore b/libs/gl-sdk-android/.gitignore index 590ab7fde..f2e44fa28 100644 --- a/libs/gl-sdk-android/.gitignore +++ b/libs/gl-sdk-android/.gitignore @@ -72,3 +72,4 @@ glsdk.common.kt glsdk.android.kt glsdk.jvm.kt glsdk.native.kt +glsdk.kt diff --git a/libs/gl-sdk-android/build.gradle.kts b/libs/gl-sdk-android/build.gradle.kts index adfd2a530..538ae11b6 100644 --- a/libs/gl-sdk-android/build.gradle.kts +++ b/libs/gl-sdk-android/build.gradle.kts @@ -1,6 +1,6 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - alias(libs.plugins.androidLibrary) apply false + alias(libs.plugins.androidKotlinMultiplatformLibrary) apply false alias(libs.plugins.kotlinMultiplatform) apply false alias(libs.plugins.kotlinSerialization) apply false alias(libs.plugins.mavenPublish) apply false diff --git a/libs/gl-sdk-android/gradle.properties b/libs/gl-sdk-android/gradle.properties index 4c66e37fe..16510a5ed 100644 --- a/libs/gl-sdk-android/gradle.properties +++ b/libs/gl-sdk-android/gradle.properties @@ -17,16 +17,13 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 android.useAndroidX=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official -# Enables namespacing of each library's R class so that its R class includes only the -# resources declared in the library itself and none from the library's dependencies, -# thereby reducing the size of the R class for that library -android.nonTransitiveRClass=true - +# The generated bindings use kotlinx.atomicfu. These flags (default: false) make the atomicfu +# Kotlin compiler plugin replace atomics with plain fields and intrinsics during compilation. +# Without them, JVM/Android fall back to post-compilation bytecode transformation and +# Kotlin/Native keeps every atomic as a boxed wrapper object. kotlinx.atomicfu.enableJvmIrTransformation=true kotlinx.atomicfu.enableNativeIrTransformation=true kotlin.mpp.enableCInteropCommonization=true -android.builtInKotlin=false -android.newDsl=false libraryVersion=0.4.0 \ No newline at end of file diff --git a/libs/gl-sdk-android/gradle/libs.versions.toml b/libs/gl-sdk-android/gradle/libs.versions.toml index 47d184705..ac8ebc77c 100644 --- a/libs/gl-sdk-android/gradle/libs.versions.toml +++ b/libs/gl-sdk-android/gradle/libs.versions.toml @@ -1,16 +1,19 @@ [versions] +# Kotlin 2.3.0 - 2.4.x reject the generated bindings in compileNativeMainKotlinMetadata with a +# false positive "Member overrides different '@Throws' filter" (KT-88548, fixed in Kotlin 2.5.0). +# annotation >= 1.10.0 and kotlinx-serialization >= 1.10.0 publish klibs that require Kotlin 2.3. annotation = "1.9.1" kotlin = "2.2.21" kotlinx-serialization = "1.9.0" -kotlinx-coroutines = "1.10.2" -android-gradle-plugin = "9.0.0" -okio = "3.16.4" +kotlinx-coroutines = "1.11.0" +android-gradle-plugin = "9.4.1" +okio = "3.18.2" espresso = "3.7.0" -jna = "5.18.1" +jna = "5.19.1" junit = "4.13.2" junit-ext = "1.3.0" -maven-publish = "0.36.0" -atomicfu = "0.31.0" +maven-publish = "0.37.0" +atomicfu = "0.33.0" [libraries] annotation = { module = "androidx.annotation:annotation", version.ref = "annotation" } @@ -24,7 +27,7 @@ junit-ext = { module = "androidx.test.ext:junit", version.ref = "junit-ext" } junit = { module = "junit:junit", version.ref = "junit" } [plugins] -androidLibrary = { id = "com.android.library", version.ref = "android-gradle-plugin" } +androidKotlinMultiplatformLibrary = { id = "com.android.kotlin.multiplatform.library", version.ref = "android-gradle-plugin" } kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } atomicfu = { id = "org.jetbrains.kotlinx.atomicfu", version.ref = "atomicfu" } diff --git a/libs/gl-sdk-android/gradle/wrapper/gradle-wrapper.jar b/libs/gl-sdk-android/gradle/wrapper/gradle-wrapper.jar index e708b1c02..eddabd2ee 100644 Binary files a/libs/gl-sdk-android/gradle/wrapper/gradle-wrapper.jar and b/libs/gl-sdk-android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/libs/gl-sdk-android/gradle/wrapper/gradle-wrapper.properties b/libs/gl-sdk-android/gradle/wrapper/gradle-wrapper.properties index 23449a2b5..ad7845be3 100644 --- a/libs/gl-sdk-android/gradle/wrapper/gradle-wrapper.properties +++ b/libs/gl-sdk-android/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,9 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.1-bin.zip networkTimeout=10000 +retries=0 +retryBackOffMs=500 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/libs/gl-sdk-android/gradlew b/libs/gl-sdk-android/gradlew index 4f906e0c8..249efbb03 100755 --- a/libs/gl-sdk-android/gradlew +++ b/libs/gl-sdk-android/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015 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. @@ -15,81 +15,114 @@ # 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 UN*X -## +# +# gradlew 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 gradlew +# +# 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/3d91ce3b8caaf77ad09f381f43615b715b53f72c/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 -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +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 -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# 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"' +# 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" +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 - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # 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" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,88 +131,118 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + 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" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +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 -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -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" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + 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 - i=`expr $i + 1` + # 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 - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# 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" \ + -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/libs/gl-sdk-android/gradlew.bat b/libs/gl-sdk-android/gradlew.bat new file mode 100644 index 000000000..8508ef684 --- /dev/null +++ b/libs/gl-sdk-android/gradlew.bat @@ -0,0 +1,82 @@ +@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 gradlew startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables, and ensure extensions are enabled +setlocal EnableExtensions + +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 + +"%COMSPEC%" /c exit 1 + +: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 + +"%COMSPEC%" /c exit 1 + +:execute +@rem Setup the command line + + + +@rem Execute gradlew +@rem endlocal doesn't take effect until after the line is parsed and variables are expanded +@rem which allows us to clear the local environment before executing the java command +endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel + +:exitWithErrorLevel +@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts +"%COMSPEC%" /c exit %ERRORLEVEL% diff --git a/libs/gl-sdk-android/lib/build.gradle.kts b/libs/gl-sdk-android/lib/build.gradle.kts index 29c04f733..2b7b49064 100644 --- a/libs/gl-sdk-android/lib/build.gradle.kts +++ b/libs/gl-sdk-android/lib/build.gradle.kts @@ -1,9 +1,8 @@ -import com.vanniktech.maven.publish.AndroidSingleVariantLibrary import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework plugins { - alias(libs.plugins.androidLibrary) + alias(libs.plugins.androidKotlinMultiplatformLibrary) alias(libs.plugins.kotlinMultiplatform) alias(libs.plugins.kotlinSerialization) alias(libs.plugins.atomicfu) @@ -12,9 +11,24 @@ plugins { } kotlin { - androidTarget { - publishLibraryVariants("release") + android { + namespace = "com.blockstream.glsdk" + compileSdk = 37 + minSdk = 24 + compilerOptions { jvmTarget.set(JvmTarget.JVM_1_8) } + + withHostTestBuilder {}.configure {} + withDeviceTestBuilder { + sourceSetTreeName = "test" + }.configure { + instrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + optimization { + consumerKeepRules.publish = true + consumerKeepRules.file("consumer-rules.pro") + } } jvm() @@ -69,33 +83,16 @@ kotlin { jvmMain.dependencies { implementation(libs.jna) } - androidUnitTest.dependencies { + getByName("androidHostTest").dependencies { implementation(libs.junit) } - androidInstrumentedTest.dependencies { + getByName("androidDeviceTest").dependencies { implementation(libs.junit.ext) implementation(libs.espresso.core) } } } -android { - namespace = "com.blockstream.glsdk" - compileSdk = 36 - - defaultConfig { - minSdk = 24 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } -} - val libraryVersion: String by project mavenPublishing { diff --git a/libs/gl-sdk-android/lib/src/androidInstrumentedTest/kotlin/com/blockstream/glsdk/AuthApiTest.kt b/libs/gl-sdk-android/lib/src/androidDeviceTest/kotlin/com/blockstream/glsdk/AuthApiTest.kt similarity index 100% rename from libs/gl-sdk-android/lib/src/androidInstrumentedTest/kotlin/com/blockstream/glsdk/AuthApiTest.kt rename to libs/gl-sdk-android/lib/src/androidDeviceTest/kotlin/com/blockstream/glsdk/AuthApiTest.kt diff --git a/libs/gl-sdk-android/lib/src/androidInstrumentedTest/kotlin/com/blockstream/glsdk/ListPaymentTest.kt b/libs/gl-sdk-android/lib/src/androidDeviceTest/kotlin/com/blockstream/glsdk/ListPaymentTest.kt similarity index 100% rename from libs/gl-sdk-android/lib/src/androidInstrumentedTest/kotlin/com/blockstream/glsdk/ListPaymentTest.kt rename to libs/gl-sdk-android/lib/src/androidDeviceTest/kotlin/com/blockstream/glsdk/ListPaymentTest.kt diff --git a/libs/gl-sdk-android/lib/src/androidInstrumentedTest/kotlin/com/blockstream/glsdk/LnurlParseTest.kt b/libs/gl-sdk-android/lib/src/androidDeviceTest/kotlin/com/blockstream/glsdk/LnurlParseTest.kt similarity index 100% rename from libs/gl-sdk-android/lib/src/androidInstrumentedTest/kotlin/com/blockstream/glsdk/LnurlParseTest.kt rename to libs/gl-sdk-android/lib/src/androidDeviceTest/kotlin/com/blockstream/glsdk/LnurlParseTest.kt diff --git a/libs/gl-sdk-android/lib/src/androidInstrumentedTest/kotlin/com/blockstream/glsdk/LoggingTest.kt b/libs/gl-sdk-android/lib/src/androidDeviceTest/kotlin/com/blockstream/glsdk/LoggingTest.kt similarity index 100% rename from libs/gl-sdk-android/lib/src/androidInstrumentedTest/kotlin/com/blockstream/glsdk/LoggingTest.kt rename to libs/gl-sdk-android/lib/src/androidDeviceTest/kotlin/com/blockstream/glsdk/LoggingTest.kt diff --git a/libs/gl-sdk-android/lib/src/androidInstrumentedTest/kotlin/com/blockstream/glsdk/NodeOperationsTest.kt b/libs/gl-sdk-android/lib/src/androidDeviceTest/kotlin/com/blockstream/glsdk/NodeOperationsTest.kt similarity index 100% rename from libs/gl-sdk-android/lib/src/androidInstrumentedTest/kotlin/com/blockstream/glsdk/NodeOperationsTest.kt rename to libs/gl-sdk-android/lib/src/androidDeviceTest/kotlin/com/blockstream/glsdk/NodeOperationsTest.kt diff --git a/libs/gl-sdk-android/lib/src/androidInstrumentedTest/kotlin/com/blockstream/glsdk/ParseInputTest.kt b/libs/gl-sdk-android/lib/src/androidDeviceTest/kotlin/com/blockstream/glsdk/ParseInputTest.kt similarity index 100% rename from libs/gl-sdk-android/lib/src/androidInstrumentedTest/kotlin/com/blockstream/glsdk/ParseInputTest.kt rename to libs/gl-sdk-android/lib/src/androidDeviceTest/kotlin/com/blockstream/glsdk/ParseInputTest.kt diff --git a/libs/gl-sdk/bindings/uniffi/glsdk/glsdk.kt b/libs/gl-sdk/bindings/uniffi/glsdk/glsdk.kt deleted file mode 100644 index f09b505e9..000000000 --- a/libs/gl-sdk/bindings/uniffi/glsdk/glsdk.kt +++ /dev/null @@ -1,9496 +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.glsdk - -// 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 -import java.util.concurrent.atomic.AtomicBoolean - -// 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_glsdk_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_glsdk_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 "glsdk" -} - -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,) -} -internal interface UniffiCallbackInterfaceLogListenerMethod0 : com.sun.jna.Callback { - fun callback(`uniffiHandle`: Long,`entry`: RustBuffer.ByValue,`uniffiOutReturn`: Pointer,uniffiCallStatus: UniffiRustCallStatus,) -} -internal interface UniffiCallbackInterfaceNodeEventListenerMethod0 : com.sun.jna.Callback { - fun callback(`uniffiHandle`: Long,`event`: RustBuffer.ByValue,`uniffiOutReturn`: Pointer,uniffiCallStatus: UniffiRustCallStatus,) -} -@Structure.FieldOrder("onLog", "uniffiFree") -internal open class UniffiVTableCallbackInterfaceLogListener( - @JvmField internal var `onLog`: UniffiCallbackInterfaceLogListenerMethod0? = null, - @JvmField internal var `uniffiFree`: UniffiCallbackInterfaceFree? = null, -) : Structure() { - class UniffiByValue( - `onLog`: UniffiCallbackInterfaceLogListenerMethod0? = null, - `uniffiFree`: UniffiCallbackInterfaceFree? = null, - ): UniffiVTableCallbackInterfaceLogListener(`onLog`,`uniffiFree`,), Structure.ByValue - - internal fun uniffiSetValue(other: UniffiVTableCallbackInterfaceLogListener) { - `onLog` = other.`onLog` - `uniffiFree` = other.`uniffiFree` - } - -} -@Structure.FieldOrder("onEvent", "uniffiFree") -internal open class UniffiVTableCallbackInterfaceNodeEventListener( - @JvmField internal var `onEvent`: UniffiCallbackInterfaceNodeEventListenerMethod0? = null, - @JvmField internal var `uniffiFree`: UniffiCallbackInterfaceFree? = null, -) : Structure() { - class UniffiByValue( - `onEvent`: UniffiCallbackInterfaceNodeEventListenerMethod0? = null, - `uniffiFree`: UniffiCallbackInterfaceFree? = null, - ): UniffiVTableCallbackInterfaceNodeEventListener(`onEvent`,`uniffiFree`,), Structure.ByValue - - internal fun uniffiSetValue(other: UniffiVTableCallbackInterfaceNodeEventListener) { - `onEvent` = other.`onEvent` - `uniffiFree` = other.`uniffiFree` - } - -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// 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_glsdk_checksum_func_parse_input( -): Short -fun uniffi_glsdk_checksum_func_resolve_input( -): Short -fun uniffi_glsdk_checksum_func_set_log_level( -): Short -fun uniffi_glsdk_checksum_func_set_logger( -): Short -fun uniffi_glsdk_checksum_method_config_with_developer_cert( -): Short -fun uniffi_glsdk_checksum_method_config_with_network( -): Short -fun uniffi_glsdk_checksum_method_credentials_node_id( -): Short -fun uniffi_glsdk_checksum_method_credentials_save( -): Short -fun uniffi_glsdk_checksum_method_handle_stop( -): Short -fun uniffi_glsdk_checksum_method_node_credentials( -): Short -fun uniffi_glsdk_checksum_method_node_disconnect( -): Short -fun uniffi_glsdk_checksum_method_node_generate_diagnostic_data( -): Short -fun uniffi_glsdk_checksum_method_node_get_info( -): Short -fun uniffi_glsdk_checksum_method_node_list_funds( -): Short -fun uniffi_glsdk_checksum_method_node_list_invoices( -): Short -fun uniffi_glsdk_checksum_method_node_list_payments( -): Short -fun uniffi_glsdk_checksum_method_node_list_pays( -): Short -fun uniffi_glsdk_checksum_method_node_list_peer_channels( -): Short -fun uniffi_glsdk_checksum_method_node_list_peers( -): Short -fun uniffi_glsdk_checksum_method_node_lnurl_pay( -): Short -fun uniffi_glsdk_checksum_method_node_lnurl_withdraw( -): Short -fun uniffi_glsdk_checksum_method_node_node_state( -): Short -fun uniffi_glsdk_checksum_method_node_onchain_balance_state( -): Short -fun uniffi_glsdk_checksum_method_node_onchain_fee_rates( -): Short -fun uniffi_glsdk_checksum_method_node_onchain_receive( -): Short -fun uniffi_glsdk_checksum_method_node_onchain_send( -): Short -fun uniffi_glsdk_checksum_method_node_prepare_onchain_send( -): Short -fun uniffi_glsdk_checksum_method_node_receive( -): Short -fun uniffi_glsdk_checksum_method_node_send( -): Short -fun uniffi_glsdk_checksum_method_node_stop( -): Short -fun uniffi_glsdk_checksum_method_node_stream_node_events( -): Short -fun uniffi_glsdk_checksum_method_nodebuilder_connect( -): Short -fun uniffi_glsdk_checksum_method_nodebuilder_recover( -): Short -fun uniffi_glsdk_checksum_method_nodebuilder_register( -): Short -fun uniffi_glsdk_checksum_method_nodebuilder_register_or_recover( -): Short -fun uniffi_glsdk_checksum_method_nodebuilder_with_event_listener( -): Short -fun uniffi_glsdk_checksum_method_nodeeventstream_next( -): Short -fun uniffi_glsdk_checksum_method_scheduler_lightning_available( -): Short -fun uniffi_glsdk_checksum_method_scheduler_recover( -): Short -fun uniffi_glsdk_checksum_method_scheduler_register( -): Short -fun uniffi_glsdk_checksum_method_scheduler_with_developer_cert( -): Short -fun uniffi_glsdk_checksum_method_signer_authenticate( -): Short -fun uniffi_glsdk_checksum_method_signer_node_id( -): Short -fun uniffi_glsdk_checksum_method_signer_start( -): Short -fun uniffi_glsdk_checksum_constructor_config_new( -): Short -fun uniffi_glsdk_checksum_constructor_credentials_load( -): Short -fun uniffi_glsdk_checksum_constructor_developercert_new( -): Short -fun uniffi_glsdk_checksum_constructor_nodebuilder_new( -): Short -fun uniffi_glsdk_checksum_constructor_scheduler_new( -): Short -fun uniffi_glsdk_checksum_constructor_signer_new( -): Short -fun uniffi_glsdk_checksum_constructor_signer_new_from_seed( -): Short -fun uniffi_glsdk_checksum_method_loglistener_on_log( -): Short -fun uniffi_glsdk_checksum_method_nodeeventlistener_on_event( -): Short -fun ffi_glsdk_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 = "glsdk" - // 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. - uniffiCallbackInterfaceLogListener.register(lib) - uniffiCallbackInterfaceNodeEventListener.register(lib) - // Loading of library with integrity check done. - lib - } - - // The Cleaner for the whole library - internal val CLEANER: UniffiCleaner by lazy { - UniffiCleaner.create() - } - } - - // FFI functions - fun uniffi_glsdk_fn_clone_config(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_free_config(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Unit -fun uniffi_glsdk_fn_constructor_config_new(uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_method_config_with_developer_cert(`ptr`: Pointer,`cert`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_method_config_with_network(`ptr`: Pointer,`network`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_clone_credentials(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_free_credentials(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Unit -fun uniffi_glsdk_fn_constructor_credentials_load(`raw`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_method_credentials_node_id(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_credentials_save(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_clone_developercert(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_free_developercert(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Unit -fun uniffi_glsdk_fn_constructor_developercert_new(`cert`: RustBuffer.ByValue,`key`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_clone_handle(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_free_handle(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Unit -fun uniffi_glsdk_fn_method_handle_stop(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Unit -fun uniffi_glsdk_fn_clone_node(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_free_node(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Unit -fun uniffi_glsdk_fn_method_node_credentials(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_disconnect(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Unit -fun uniffi_glsdk_fn_method_node_generate_diagnostic_data(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_get_info(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_list_funds(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_list_invoices(`ptr`: Pointer,`label`: RustBuffer.ByValue,`invstring`: RustBuffer.ByValue,`paymentHash`: RustBuffer.ByValue,`offerId`: RustBuffer.ByValue,`index`: RustBuffer.ByValue,`start`: RustBuffer.ByValue,`limit`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_list_payments(`ptr`: Pointer,`req`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_list_pays(`ptr`: Pointer,`bolt11`: RustBuffer.ByValue,`paymentHash`: RustBuffer.ByValue,`status`: RustBuffer.ByValue,`index`: RustBuffer.ByValue,`start`: RustBuffer.ByValue,`limit`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_list_peer_channels(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_list_peers(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_lnurl_pay(`ptr`: Pointer,`request`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_lnurl_withdraw(`ptr`: Pointer,`request`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_node_state(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_onchain_balance_state(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_onchain_fee_rates(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_onchain_receive(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_onchain_send(`ptr`: Pointer,`destination`: RustBuffer.ByValue,`amountOrAll`: RustBuffer.ByValue,`satPerVbyte`: RustBuffer.ByValue,`utxos`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_prepare_onchain_send(`ptr`: Pointer,`destination`: RustBuffer.ByValue,`amountOrAll`: RustBuffer.ByValue,`satPerVbyte`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_receive(`ptr`: Pointer,`label`: RustBuffer.ByValue,`description`: RustBuffer.ByValue,`amountMsat`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_send(`ptr`: Pointer,`invoice`: RustBuffer.ByValue,`amountMsat`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_node_stop(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Unit -fun uniffi_glsdk_fn_method_node_stream_node_events(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_clone_nodebuilder(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_free_nodebuilder(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Unit -fun uniffi_glsdk_fn_constructor_nodebuilder_new(`config`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_method_nodebuilder_connect(`ptr`: Pointer,`credentials`: RustBuffer.ByValue,`mnemonic`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_method_nodebuilder_recover(`ptr`: Pointer,`mnemonic`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_method_nodebuilder_register(`ptr`: Pointer,`mnemonic`: RustBuffer.ByValue,`inviteCode`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_method_nodebuilder_register_or_recover(`ptr`: Pointer,`mnemonic`: RustBuffer.ByValue,`inviteCode`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_method_nodebuilder_with_event_listener(`ptr`: Pointer,`listener`: Long,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_clone_nodeeventstream(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_free_nodeeventstream(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Unit -fun uniffi_glsdk_fn_method_nodeeventstream_next(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_clone_scheduler(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_free_scheduler(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Unit -fun uniffi_glsdk_fn_constructor_scheduler_new(`network`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_method_scheduler_lightning_available(`ptr`: Pointer,`nodeId`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): Byte -fun uniffi_glsdk_fn_method_scheduler_recover(`ptr`: Pointer,`signer`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_method_scheduler_register(`ptr`: Pointer,`signer`: Pointer,`code`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_method_scheduler_with_developer_cert(`ptr`: Pointer,`cert`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_clone_signer(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_free_signer(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Unit -fun uniffi_glsdk_fn_constructor_signer_new(`phrase`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_constructor_signer_new_from_seed(`seed`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_method_signer_authenticate(`ptr`: Pointer,`creds`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_method_signer_node_id(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_method_signer_start(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun uniffi_glsdk_fn_init_callback_vtable_loglistener(`vtable`: UniffiVTableCallbackInterfaceLogListener, -): Unit -fun uniffi_glsdk_fn_init_callback_vtable_nodeeventlistener(`vtable`: UniffiVTableCallbackInterfaceNodeEventListener, -): Unit -fun uniffi_glsdk_fn_func_parse_input(`input`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_func_resolve_input(`input`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun uniffi_glsdk_fn_func_set_log_level(`level`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): Unit -fun uniffi_glsdk_fn_func_set_logger(`level`: RustBuffer.ByValue,`listener`: Long,uniffi_out_err: UniffiRustCallStatus, -): Unit -fun ffi_glsdk_rustbuffer_alloc(`size`: Long,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun ffi_glsdk_rustbuffer_from_bytes(`bytes`: ForeignBytes.ByValue,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun ffi_glsdk_rustbuffer_free(`buf`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, -): Unit -fun ffi_glsdk_rustbuffer_reserve(`buf`: RustBuffer.ByValue,`additional`: Long,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun ffi_glsdk_rust_future_poll_u8(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_glsdk_rust_future_cancel_u8(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_free_u8(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_complete_u8(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Byte -fun ffi_glsdk_rust_future_poll_i8(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_glsdk_rust_future_cancel_i8(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_free_i8(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_complete_i8(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Byte -fun ffi_glsdk_rust_future_poll_u16(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_glsdk_rust_future_cancel_u16(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_free_u16(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_complete_u16(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Short -fun ffi_glsdk_rust_future_poll_i16(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_glsdk_rust_future_cancel_i16(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_free_i16(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_complete_i16(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Short -fun ffi_glsdk_rust_future_poll_u32(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_glsdk_rust_future_cancel_u32(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_free_u32(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_complete_u32(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Int -fun ffi_glsdk_rust_future_poll_i32(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_glsdk_rust_future_cancel_i32(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_free_i32(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_complete_i32(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Int -fun ffi_glsdk_rust_future_poll_u64(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_glsdk_rust_future_cancel_u64(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_free_u64(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_complete_u64(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Long -fun ffi_glsdk_rust_future_poll_i64(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_glsdk_rust_future_cancel_i64(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_free_i64(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_complete_i64(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Long -fun ffi_glsdk_rust_future_poll_f32(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_glsdk_rust_future_cancel_f32(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_free_f32(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_complete_f32(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Float -fun ffi_glsdk_rust_future_poll_f64(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_glsdk_rust_future_cancel_f64(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_free_f64(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_complete_f64(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Double -fun ffi_glsdk_rust_future_poll_pointer(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_glsdk_rust_future_cancel_pointer(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_free_pointer(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_complete_pointer(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): Pointer -fun ffi_glsdk_rust_future_poll_rust_buffer(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_glsdk_rust_future_cancel_rust_buffer(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_free_rust_buffer(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_complete_rust_buffer(`handle`: Long,uniffi_out_err: UniffiRustCallStatus, -): RustBuffer.ByValue -fun ffi_glsdk_rust_future_poll_void(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long, -): Unit -fun ffi_glsdk_rust_future_cancel_void(`handle`: Long, -): Unit -fun ffi_glsdk_rust_future_free_void(`handle`: Long, -): Unit -fun ffi_glsdk_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_glsdk_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_glsdk_checksum_func_parse_input() != 49187.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_func_resolve_input() != 54924.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_func_set_log_level() != 52328.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_func_set_logger() != 10523.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_config_with_developer_cert() != 64194.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_config_with_network() != 35643.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_credentials_node_id() != 16312.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_credentials_save() != 26677.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_handle_stop() != 36432.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_credentials() != 39165.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_disconnect() != 43626.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_generate_diagnostic_data() != 10944.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_get_info() != 39460.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_list_funds() != 21692.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_list_invoices() != 44803.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_list_payments() != 43756.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_list_pays() != 3970.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_list_peer_channels() != 35210.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_list_peers() != 29567.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_lnurl_pay() != 61306.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_lnurl_withdraw() != 61467.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_node_state() != 41833.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_onchain_balance_state() != 52276.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_onchain_fee_rates() != 57819.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_onchain_receive() != 46432.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_onchain_send() != 63330.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_prepare_onchain_send() != 37850.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_receive() != 39761.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_send() != 4348.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_stop() != 20186.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_node_stream_node_events() != 5933.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_nodebuilder_connect() != 47474.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_nodebuilder_recover() != 46087.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_nodebuilder_register() != 49580.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_nodebuilder_register_or_recover() != 5543.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_nodebuilder_with_event_listener() != 56969.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_nodeeventstream_next() != 12635.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_scheduler_lightning_available() != 7327.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_scheduler_recover() != 55514.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_scheduler_register() != 20821.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_scheduler_with_developer_cert() != 64139.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_signer_authenticate() != 55935.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_signer_node_id() != 43931.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_signer_start() != 9404.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_constructor_config_new() != 25640.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_constructor_credentials_load() != 25306.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_constructor_developercert_new() != 57793.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_constructor_nodebuilder_new() != 34740.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_constructor_scheduler_new() != 15239.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_constructor_signer_new() != 62159.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_constructor_signer_new_from_seed() != 6776.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_loglistener_on_log() != 34844.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } - if (lib.uniffi_glsdk_checksum_method_nodeeventlistener_on_event() != 17790.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// Magic number for the Rust proxy to call using the same mechanism as every other method, -// to free the callback once it's dropped by Rust. -internal const val IDX_CALLBACK_FREE = 0 -// Callback return codes -internal const val UNIFFI_CALLBACK_SUCCESS = 0 -internal const val UNIFFI_CALLBACK_ERROR = 1 -internal const val UNIFFI_CALLBACK_UNEXPECTED_ERROR = 2 - -/** - * @suppress - */ -public abstract class FfiConverterCallbackInterface: FfiConverter { - internal val handleMap = UniffiHandleMap() - - internal fun drop(handle: Long) { - handleMap.remove(handle) - } - - override fun lift(value: Long): CallbackInterface { - return handleMap.get(value) - } - - override fun read(buf: ByteBuffer) = lift(buf.getLong()) - - override fun lower(value: CallbackInterface) = handleMap.insert(value) - - override fun allocationSize(value: CallbackInterface) = 8UL - - override fun write(value: CallbackInterface, buf: ByteBuffer) { - buf.putLong(lower(value)) - } -} -/** - * The cleaner interface for Object finalization code to run. - * This is the entry point to any implementation that we're using. - * - * The cleaner registers objects and returns cleanables, so now we are - * defining a `UniffiCleaner` with a `UniffiClenaer.Cleanable` to abstract the - * different implmentations available at compile time. - * - * @suppress - */ -interface UniffiCleaner { - interface Cleanable { - fun clean() - } - - fun register(value: Any, cleanUpTask: Runnable): UniffiCleaner.Cleanable - - companion object -} - -// The fallback Jna cleaner, which is available for both Android, and the JVM. -private class UniffiJnaCleaner : UniffiCleaner { - private val cleaner = com.sun.jna.internal.Cleaner.getCleaner() - - override fun register(value: Any, cleanUpTask: Runnable): UniffiCleaner.Cleanable = - UniffiJnaCleanable(cleaner.register(value, cleanUpTask)) -} - -private class UniffiJnaCleanable( - private val cleanable: com.sun.jna.internal.Cleaner.Cleanable, -) : UniffiCleaner.Cleanable { - override fun clean() = cleanable.clean() -} - - -// We decide at uniffi binding generation time whether we were -// using Android or not. -// There are further runtime checks to chose the correct implementation -// of the cleaner. -private fun UniffiCleaner.Companion.create(): UniffiCleaner = - try { - // For safety's sake: if the library hasn't been run in android_cleaner = true - // mode, but is being run on Android, then we still need to think about - // Android API versions. - // So we check if java.lang.ref.Cleaner is there, and use that… - java.lang.Class.forName("java.lang.ref.Cleaner") - JavaLangRefCleaner() - } catch (e: ClassNotFoundException) { - // … otherwise, fallback to the JNA cleaner. - UniffiJnaCleaner() - } - -private class JavaLangRefCleaner : UniffiCleaner { - val cleaner = java.lang.ref.Cleaner.create() - - override fun register(value: Any, cleanUpTask: Runnable): UniffiCleaner.Cleanable = - JavaLangRefCleanable(cleaner.register(value, cleanUpTask)) -} - -private class JavaLangRefCleanable( - val cleanable: java.lang.ref.Cleaner.Cleanable -) : UniffiCleaner.Cleanable { - override fun clean() = cleanable.clean() -} - -/** - * @suppress - */ -public object FfiConverterUInt: FfiConverter { - override fun lift(value: Int): UInt { - return value.toUInt() - } - - override fun read(buf: ByteBuffer): UInt { - return lift(buf.getInt()) - } - - override fun lower(value: UInt): Int { - return value.toInt() - } - - override fun allocationSize(value: UInt) = 4UL - - override fun write(value: UInt, buf: ByteBuffer) { - buf.putInt(value.toInt()) - } -} - -/** - * @suppress - */ -public object FfiConverterInt: FfiConverter { - override fun lift(value: Int): Int { - return value - } - - override fun read(buf: ByteBuffer): Int { - return buf.getInt() - } - - override fun lower(value: Int): Int { - return value - } - - override fun allocationSize(value: Int) = 4UL - - override fun write(value: Int, buf: ByteBuffer) { - buf.putInt(value) - } -} - -/** - * @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 FfiConverterBoolean: FfiConverter { - override fun lift(value: Byte): Boolean { - return value.toInt() != 0 - } - - override fun read(buf: ByteBuffer): Boolean { - return lift(buf.get()) - } - - override fun lower(value: Boolean): Byte { - return if (value) 1.toByte() else 0.toByte() - } - - override fun allocationSize(value: Boolean) = 1UL - - override fun write(value: Boolean, buf: ByteBuffer) { - buf.put(lower(value)) - } -} - -/** - * @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) - } -} - - -// This template implements a class for working with a Rust struct via a Pointer/Arc -// to the live Rust struct on the other side of the FFI. -// -// Each instance implements core operations for working with the Rust `Arc` and the -// Kotlin Pointer to work with the live Rust struct on the other side of the FFI. -// -// There's some subtlety here, because we have to be careful not to operate on a Rust -// struct after it has been dropped, and because we must expose a public API for freeing -// theq Kotlin wrapper object in lieu of reliable finalizers. The core requirements are: -// -// * Each instance holds an opaque pointer to the underlying Rust struct. -// Method calls need to read this pointer from the object's state and pass it in to -// the Rust FFI. -// -// * When an instance is no longer needed, its pointer should be passed to a -// special destructor function provided by the Rust FFI, which will drop the -// underlying Rust struct. -// -// * Given an instance, calling code is expected to call the special -// `destroy` method in order to free it after use, either by calling it explicitly -// or by using a higher-level helper like the `use` method. Failing to do so risks -// leaking the underlying Rust struct. -// -// * We can't assume that calling code will do the right thing, and must be prepared -// to handle Kotlin method calls executing concurrently with or even after a call to -// `destroy`, and to handle multiple (possibly concurrent!) calls to `destroy`. -// -// * We must never allow Rust code to operate on the underlying Rust struct after -// the destructor has been called, and must never call the destructor more than once. -// Doing so may trigger memory unsafety. -// -// * To mitigate many of the risks of leaking memory and use-after-free unsafety, a `Cleaner` -// is implemented to call the destructor when the Kotlin object becomes unreachable. -// This is done in a background thread. This is not a panacea, and client code should be aware that -// 1. the thread may starve if some there are objects that have poorly performing -// `drop` methods or do significant work in their `drop` methods. -// 2. the thread is shared across the whole library. This can be tuned by using `android_cleaner = true`, -// or `android = true` in the [`kotlin` section of the `uniffi.toml` file](https://mozilla.github.io/uniffi-rs/kotlin/configuration.html). -// -// If we try to implement this with mutual exclusion on access to the pointer, there is the -// possibility of a race between a method call and a concurrent call to `destroy`: -// -// * Thread A starts a method call, reads the value of the pointer, but is interrupted -// before it can pass the pointer over the FFI to Rust. -// * Thread B calls `destroy` and frees the underlying Rust struct. -// * Thread A resumes, passing the already-read pointer value to Rust and triggering -// a use-after-free. -// -// One possible solution would be to use a `ReadWriteLock`, with each method call taking -// a read lock (and thus allowed to run concurrently) and the special `destroy` method -// taking a write lock (and thus blocking on live method calls). However, we aim not to -// generate methods with any hidden blocking semantics, and a `destroy` method that might -// block if called incorrectly seems to meet that bar. -// -// So, we achieve our goals by giving each instance an associated `AtomicLong` counter to track -// the number of in-flight method calls, and an `AtomicBoolean` flag to indicate whether `destroy` -// has been called. These are updated according to the following rules: -// -// * The initial value of the counter is 1, indicating a live object with no in-flight calls. -// The initial value for the flag is false. -// -// * At the start of each method call, we atomically check the counter. -// If it is 0 then the underlying Rust struct has already been destroyed and the call is aborted. -// If it is nonzero them we atomically increment it by 1 and proceed with the method call. -// -// * At the end of each method call, we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// * When `destroy` is called, we atomically flip the flag from false to true. -// If the flag was already true we silently fail. -// Otherwise we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// Astute readers may observe that this all sounds very similar to the way that Rust's `Arc` works, -// and indeed it is, with the addition of a flag to guard against multiple calls to `destroy`. -// -// The overall effect is that the underlying Rust struct is destroyed only when `destroy` has been -// called *and* all in-flight method calls have completed, avoiding violating any of the expectations -// of the underlying Rust code. -// -// This makes a cleaner a better alternative to _not_ calling `destroy()` as -// and when the object is finished with, but the abstraction is not perfect: if the Rust object's `drop` -// method is slow, and/or there are many objects to cleanup, and it's on a low end Android device, then the cleaner -// thread may be starved, and the app will leak memory. -// -// In this case, `destroy`ing manually may be a better solution. -// -// The cleaner can live side by side with the manual calling of `destroy`. In the order of responsiveness, uniffi objects -// with Rust peers are reclaimed: -// -// 1. By calling the `destroy` method of the object, which calls `rustObject.free()`. If that doesn't happen: -// 2. When the object becomes unreachable, AND the Cleaner thread gets to call `rustObject.free()`. If the thread is starved then: -// 3. The memory is reclaimed when the process terminates. -// -// [1] https://stackoverflow.com/questions/24376768/can-java-finalize-an-object-when-it-is-still-in-scope/24380219 -// - - -public interface ConfigInterface { - - /** - * Return a new Config with the given developer certificate. - * Nodes registered through this config will be associated with the developer's account. - */ - fun `withDeveloperCert`(`cert`: DeveloperCert): Config - - /** - * Return a new Config with the given network. - */ - fun `withNetwork`(`network`: Network): Config - - companion object -} - -open class Config: Disposable, AutoCloseable, ConfigInterface -{ - - constructor(pointer: Pointer) { - this.pointer = pointer - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - - /** - * This constructor can be used to instantiate a fake object. Only used for tests. Any - * attempt to actually use an object constructed this way will fail as there is no - * connected Rust object. - */ - @Suppress("UNUSED_PARAMETER") - constructor(noPointer: NoPointer) { - this.pointer = null - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - /** - * Create a Config with default settings: BITCOIN network, no developer certificate. - */ - constructor() : - this( - uniffiRustCall() { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_constructor_config_new( - _status) -} - ) - - protected val pointer: Pointer? - protected val cleanable: UniffiCleaner.Cleanable - - private val wasDestroyed = AtomicBoolean(false) - private val callCounter = AtomicLong(1) - - override fun destroy() { - // Only allow a single call to this method. - // TODO: maybe we should log a warning if called more than once? - if (this.wasDestroyed.compareAndSet(false, true)) { - // This decrement always matches the initial count of 1 given at creation time. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - @Synchronized - override fun close() { - this.destroy() - } - - internal inline fun callWithPointer(block: (ptr: Pointer) -> R): R { - // Check and increment the call counter, to keep the object alive. - // This needs a compare-and-set retry loop in case of concurrent updates. - do { - val c = this.callCounter.get() - if (c == 0L) { - throw IllegalStateException("${this.javaClass.simpleName} object has already been destroyed") - } - if (c == Long.MAX_VALUE) { - throw IllegalStateException("${this.javaClass.simpleName} call counter would overflow") - } - } while (! this.callCounter.compareAndSet(c, c + 1L)) - // Now we can safely do the method call without the pointer being freed concurrently. - try { - return block(this.uniffiClonePointer()) - } finally { - // This decrement always matches the increment we performed above. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - // Use a static inner class instead of a closure so as not to accidentally - // capture `this` as part of the cleanable's action. - private class UniffiCleanAction(private val pointer: Pointer?) : Runnable { - override fun run() { - pointer?.let { ptr -> - uniffiRustCall { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_free_config(ptr, status) - } - } - } - } - - fun uniffiClonePointer(): Pointer { - return uniffiRustCall() { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_clone_config(pointer!!, status) - } - } - - - /** - * Return a new Config with the given developer certificate. - * Nodes registered through this config will be associated with the developer's account. - */override fun `withDeveloperCert`(`cert`: DeveloperCert): Config { - return FfiConverterTypeConfig.lift( - callWithPointer { - uniffiRustCall() { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_config_with_developer_cert( - it, FfiConverterTypeDeveloperCert.lower(`cert`),_status) -} - } - ) - } - - - - /** - * Return a new Config with the given network. - */override fun `withNetwork`(`network`: Network): Config { - return FfiConverterTypeConfig.lift( - callWithPointer { - uniffiRustCall() { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_config_with_network( - it, FfiConverterTypeNetwork.lower(`network`),_status) -} - } - ) - } - - - - - - - companion object - -} - -/** - * @suppress - */ -public object FfiConverterTypeConfig: FfiConverter { - - override fun lower(value: Config): Pointer { - return value.uniffiClonePointer() - } - - override fun lift(value: Pointer): Config { - return Config(value) - } - - override fun read(buf: ByteBuffer): Config { - // The Rust code always writes pointers as 8 bytes, and will - // fail to compile if they don't fit. - return lift(Pointer(buf.getLong())) - } - - override fun allocationSize(value: Config) = 8UL - - override fun write(value: Config, buf: ByteBuffer) { - // The Rust code always expects pointers written as 8 bytes, - // and will fail to compile if they don't fit. - buf.putLong(Pointer.nativeValue(lower(value))) - } -} - - -// This template implements a class for working with a Rust struct via a Pointer/Arc -// to the live Rust struct on the other side of the FFI. -// -// Each instance implements core operations for working with the Rust `Arc` and the -// Kotlin Pointer to work with the live Rust struct on the other side of the FFI. -// -// There's some subtlety here, because we have to be careful not to operate on a Rust -// struct after it has been dropped, and because we must expose a public API for freeing -// theq Kotlin wrapper object in lieu of reliable finalizers. The core requirements are: -// -// * Each instance holds an opaque pointer to the underlying Rust struct. -// Method calls need to read this pointer from the object's state and pass it in to -// the Rust FFI. -// -// * When an instance is no longer needed, its pointer should be passed to a -// special destructor function provided by the Rust FFI, which will drop the -// underlying Rust struct. -// -// * Given an instance, calling code is expected to call the special -// `destroy` method in order to free it after use, either by calling it explicitly -// or by using a higher-level helper like the `use` method. Failing to do so risks -// leaking the underlying Rust struct. -// -// * We can't assume that calling code will do the right thing, and must be prepared -// to handle Kotlin method calls executing concurrently with or even after a call to -// `destroy`, and to handle multiple (possibly concurrent!) calls to `destroy`. -// -// * We must never allow Rust code to operate on the underlying Rust struct after -// the destructor has been called, and must never call the destructor more than once. -// Doing so may trigger memory unsafety. -// -// * To mitigate many of the risks of leaking memory and use-after-free unsafety, a `Cleaner` -// is implemented to call the destructor when the Kotlin object becomes unreachable. -// This is done in a background thread. This is not a panacea, and client code should be aware that -// 1. the thread may starve if some there are objects that have poorly performing -// `drop` methods or do significant work in their `drop` methods. -// 2. the thread is shared across the whole library. This can be tuned by using `android_cleaner = true`, -// or `android = true` in the [`kotlin` section of the `uniffi.toml` file](https://mozilla.github.io/uniffi-rs/kotlin/configuration.html). -// -// If we try to implement this with mutual exclusion on access to the pointer, there is the -// possibility of a race between a method call and a concurrent call to `destroy`: -// -// * Thread A starts a method call, reads the value of the pointer, but is interrupted -// before it can pass the pointer over the FFI to Rust. -// * Thread B calls `destroy` and frees the underlying Rust struct. -// * Thread A resumes, passing the already-read pointer value to Rust and triggering -// a use-after-free. -// -// One possible solution would be to use a `ReadWriteLock`, with each method call taking -// a read lock (and thus allowed to run concurrently) and the special `destroy` method -// taking a write lock (and thus blocking on live method calls). However, we aim not to -// generate methods with any hidden blocking semantics, and a `destroy` method that might -// block if called incorrectly seems to meet that bar. -// -// So, we achieve our goals by giving each instance an associated `AtomicLong` counter to track -// the number of in-flight method calls, and an `AtomicBoolean` flag to indicate whether `destroy` -// has been called. These are updated according to the following rules: -// -// * The initial value of the counter is 1, indicating a live object with no in-flight calls. -// The initial value for the flag is false. -// -// * At the start of each method call, we atomically check the counter. -// If it is 0 then the underlying Rust struct has already been destroyed and the call is aborted. -// If it is nonzero them we atomically increment it by 1 and proceed with the method call. -// -// * At the end of each method call, we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// * When `destroy` is called, we atomically flip the flag from false to true. -// If the flag was already true we silently fail. -// Otherwise we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// Astute readers may observe that this all sounds very similar to the way that Rust's `Arc` works, -// and indeed it is, with the addition of a flag to guard against multiple calls to `destroy`. -// -// The overall effect is that the underlying Rust struct is destroyed only when `destroy` has been -// called *and* all in-flight method calls have completed, avoiding violating any of the expectations -// of the underlying Rust code. -// -// This makes a cleaner a better alternative to _not_ calling `destroy()` as -// and when the object is finished with, but the abstraction is not perfect: if the Rust object's `drop` -// method is slow, and/or there are many objects to cleanup, and it's on a low end Android device, then the cleaner -// thread may be starved, and the app will leak memory. -// -// In this case, `destroy`ing manually may be a better solution. -// -// The cleaner can live side by side with the manual calling of `destroy`. In the order of responsiveness, uniffi objects -// with Rust peers are reclaimed: -// -// 1. By calling the `destroy` method of the object, which calls `rustObject.free()`. If that doesn't happen: -// 2. When the object becomes unreachable, AND the Cleaner thread gets to call `rustObject.free()`. If the thread is starved then: -// 3. The memory is reclaimed when the process terminates. -// -// [1] https://stackoverflow.com/questions/24376768/can-java-finalize-an-object-when-it-is-still-in-scope/24380219 -// - - -/** - * `Credentials` is a container for `node_id`, the mTLS client - * certificate used to authenticate a client against a node, as well - * as the seed secret if present. If no seed is present in the - * credentials, then the `Client` will not start a signer in the - * background. - */ -public interface CredentialsInterface { - - fun `nodeId`(): kotlin.ByteArray - - fun `save`(): kotlin.ByteArray - - companion object -} - -/** - * `Credentials` is a container for `node_id`, the mTLS client - * certificate used to authenticate a client against a node, as well - * as the seed secret if present. If no seed is present in the - * credentials, then the `Client` will not start a signer in the - * background. - */ -open class Credentials: Disposable, AutoCloseable, CredentialsInterface -{ - - constructor(pointer: Pointer) { - this.pointer = pointer - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - - /** - * This constructor can be used to instantiate a fake object. Only used for tests. Any - * attempt to actually use an object constructed this way will fail as there is no - * connected Rust object. - */ - @Suppress("UNUSED_PARAMETER") - constructor(noPointer: NoPointer) { - this.pointer = null - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - - protected val pointer: Pointer? - protected val cleanable: UniffiCleaner.Cleanable - - private val wasDestroyed = AtomicBoolean(false) - private val callCounter = AtomicLong(1) - - override fun destroy() { - // Only allow a single call to this method. - // TODO: maybe we should log a warning if called more than once? - if (this.wasDestroyed.compareAndSet(false, true)) { - // This decrement always matches the initial count of 1 given at creation time. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - @Synchronized - override fun close() { - this.destroy() - } - - internal inline fun callWithPointer(block: (ptr: Pointer) -> R): R { - // Check and increment the call counter, to keep the object alive. - // This needs a compare-and-set retry loop in case of concurrent updates. - do { - val c = this.callCounter.get() - if (c == 0L) { - throw IllegalStateException("${this.javaClass.simpleName} object has already been destroyed") - } - if (c == Long.MAX_VALUE) { - throw IllegalStateException("${this.javaClass.simpleName} call counter would overflow") - } - } while (! this.callCounter.compareAndSet(c, c + 1L)) - // Now we can safely do the method call without the pointer being freed concurrently. - try { - return block(this.uniffiClonePointer()) - } finally { - // This decrement always matches the increment we performed above. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - // Use a static inner class instead of a closure so as not to accidentally - // capture `this` as part of the cleanable's action. - private class UniffiCleanAction(private val pointer: Pointer?) : Runnable { - override fun run() { - pointer?.let { ptr -> - uniffiRustCall { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_free_credentials(ptr, status) - } - } - } - } - - fun uniffiClonePointer(): Pointer { - return uniffiRustCall() { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_clone_credentials(pointer!!, status) - } - } - - - @Throws(Exception::class)override fun `nodeId`(): kotlin.ByteArray { - return FfiConverterByteArray.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_credentials_node_id( - it, _status) -} - } - ) - } - - - - @Throws(Exception::class)override fun `save`(): kotlin.ByteArray { - return FfiConverterByteArray.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_credentials_save( - it, _status) -} - } - ) - } - - - - - - companion object { - - @Throws(Exception::class) fun `load`(`raw`: kotlin.ByteArray): Credentials { - return FfiConverterTypeCredentials.lift( - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_constructor_credentials_load( - FfiConverterByteArray.lower(`raw`),_status) -} - ) - } - - - - } - -} - -/** - * @suppress - */ -public object FfiConverterTypeCredentials: FfiConverter { - - override fun lower(value: Credentials): Pointer { - return value.uniffiClonePointer() - } - - override fun lift(value: Pointer): Credentials { - return Credentials(value) - } - - override fun read(buf: ByteBuffer): Credentials { - // The Rust code always writes pointers as 8 bytes, and will - // fail to compile if they don't fit. - return lift(Pointer(buf.getLong())) - } - - override fun allocationSize(value: Credentials) = 8UL - - override fun write(value: Credentials, buf: ByteBuffer) { - // The Rust code always expects pointers written as 8 bytes, - // and will fail to compile if they don't fit. - buf.putLong(Pointer.nativeValue(lower(value))) - } -} - - -// This template implements a class for working with a Rust struct via a Pointer/Arc -// to the live Rust struct on the other side of the FFI. -// -// Each instance implements core operations for working with the Rust `Arc` and the -// Kotlin Pointer to work with the live Rust struct on the other side of the FFI. -// -// There's some subtlety here, because we have to be careful not to operate on a Rust -// struct after it has been dropped, and because we must expose a public API for freeing -// theq Kotlin wrapper object in lieu of reliable finalizers. The core requirements are: -// -// * Each instance holds an opaque pointer to the underlying Rust struct. -// Method calls need to read this pointer from the object's state and pass it in to -// the Rust FFI. -// -// * When an instance is no longer needed, its pointer should be passed to a -// special destructor function provided by the Rust FFI, which will drop the -// underlying Rust struct. -// -// * Given an instance, calling code is expected to call the special -// `destroy` method in order to free it after use, either by calling it explicitly -// or by using a higher-level helper like the `use` method. Failing to do so risks -// leaking the underlying Rust struct. -// -// * We can't assume that calling code will do the right thing, and must be prepared -// to handle Kotlin method calls executing concurrently with or even after a call to -// `destroy`, and to handle multiple (possibly concurrent!) calls to `destroy`. -// -// * We must never allow Rust code to operate on the underlying Rust struct after -// the destructor has been called, and must never call the destructor more than once. -// Doing so may trigger memory unsafety. -// -// * To mitigate many of the risks of leaking memory and use-after-free unsafety, a `Cleaner` -// is implemented to call the destructor when the Kotlin object becomes unreachable. -// This is done in a background thread. This is not a panacea, and client code should be aware that -// 1. the thread may starve if some there are objects that have poorly performing -// `drop` methods or do significant work in their `drop` methods. -// 2. the thread is shared across the whole library. This can be tuned by using `android_cleaner = true`, -// or `android = true` in the [`kotlin` section of the `uniffi.toml` file](https://mozilla.github.io/uniffi-rs/kotlin/configuration.html). -// -// If we try to implement this with mutual exclusion on access to the pointer, there is the -// possibility of a race between a method call and a concurrent call to `destroy`: -// -// * Thread A starts a method call, reads the value of the pointer, but is interrupted -// before it can pass the pointer over the FFI to Rust. -// * Thread B calls `destroy` and frees the underlying Rust struct. -// * Thread A resumes, passing the already-read pointer value to Rust and triggering -// a use-after-free. -// -// One possible solution would be to use a `ReadWriteLock`, with each method call taking -// a read lock (and thus allowed to run concurrently) and the special `destroy` method -// taking a write lock (and thus blocking on live method calls). However, we aim not to -// generate methods with any hidden blocking semantics, and a `destroy` method that might -// block if called incorrectly seems to meet that bar. -// -// So, we achieve our goals by giving each instance an associated `AtomicLong` counter to track -// the number of in-flight method calls, and an `AtomicBoolean` flag to indicate whether `destroy` -// has been called. These are updated according to the following rules: -// -// * The initial value of the counter is 1, indicating a live object with no in-flight calls. -// The initial value for the flag is false. -// -// * At the start of each method call, we atomically check the counter. -// If it is 0 then the underlying Rust struct has already been destroyed and the call is aborted. -// If it is nonzero them we atomically increment it by 1 and proceed with the method call. -// -// * At the end of each method call, we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// * When `destroy` is called, we atomically flip the flag from false to true. -// If the flag was already true we silently fail. -// Otherwise we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// Astute readers may observe that this all sounds very similar to the way that Rust's `Arc` works, -// and indeed it is, with the addition of a flag to guard against multiple calls to `destroy`. -// -// The overall effect is that the underlying Rust struct is destroyed only when `destroy` has been -// called *and* all in-flight method calls have completed, avoiding violating any of the expectations -// of the underlying Rust code. -// -// This makes a cleaner a better alternative to _not_ calling `destroy()` as -// and when the object is finished with, but the abstraction is not perfect: if the Rust object's `drop` -// method is slow, and/or there are many objects to cleanup, and it's on a low end Android device, then the cleaner -// thread may be starved, and the app will leak memory. -// -// In this case, `destroy`ing manually may be a better solution. -// -// The cleaner can live side by side with the manual calling of `destroy`. In the order of responsiveness, uniffi objects -// with Rust peers are reclaimed: -// -// 1. By calling the `destroy` method of the object, which calls `rustObject.free()`. If that doesn't happen: -// 2. When the object becomes unreachable, AND the Cleaner thread gets to call `rustObject.free()`. If the thread is starved then: -// 3. The memory is reclaimed when the process terminates. -// -// [1] https://stackoverflow.com/questions/24376768/can-java-finalize-an-object-when-it-is-still-in-scope/24380219 -// - - -/** - * A developer certificate obtained from the Greenlight Developer - * Console (GDC). When provided to a `Scheduler` via - * `with_developer_cert()`, nodes registered through that scheduler - * will be associated with the developer's account. - * - * If no developer certificate is provided, the scheduler falls back - * to the compiled-in default certificate, which may be sufficient - * when using an invite code instead. - */ -public interface DeveloperCertInterface { - - companion object -} - -/** - * A developer certificate obtained from the Greenlight Developer - * Console (GDC). When provided to a `Scheduler` via - * `with_developer_cert()`, nodes registered through that scheduler - * will be associated with the developer's account. - * - * If no developer certificate is provided, the scheduler falls back - * to the compiled-in default certificate, which may be sufficient - * when using an invite code instead. - */ -open class DeveloperCert: Disposable, AutoCloseable, DeveloperCertInterface -{ - - constructor(pointer: Pointer) { - this.pointer = pointer - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - - /** - * This constructor can be used to instantiate a fake object. Only used for tests. Any - * attempt to actually use an object constructed this way will fail as there is no - * connected Rust object. - */ - @Suppress("UNUSED_PARAMETER") - constructor(noPointer: NoPointer) { - this.pointer = null - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - /** - * Create a new `DeveloperCert` from the certificate and private - * key PEM bytes obtained from the Greenlight Developer Console. - */ - constructor(`cert`: kotlin.ByteArray, `key`: kotlin.ByteArray) : - this( - uniffiRustCall() { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_constructor_developercert_new( - FfiConverterByteArray.lower(`cert`),FfiConverterByteArray.lower(`key`),_status) -} - ) - - protected val pointer: Pointer? - protected val cleanable: UniffiCleaner.Cleanable - - private val wasDestroyed = AtomicBoolean(false) - private val callCounter = AtomicLong(1) - - override fun destroy() { - // Only allow a single call to this method. - // TODO: maybe we should log a warning if called more than once? - if (this.wasDestroyed.compareAndSet(false, true)) { - // This decrement always matches the initial count of 1 given at creation time. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - @Synchronized - override fun close() { - this.destroy() - } - - internal inline fun callWithPointer(block: (ptr: Pointer) -> R): R { - // Check and increment the call counter, to keep the object alive. - // This needs a compare-and-set retry loop in case of concurrent updates. - do { - val c = this.callCounter.get() - if (c == 0L) { - throw IllegalStateException("${this.javaClass.simpleName} object has already been destroyed") - } - if (c == Long.MAX_VALUE) { - throw IllegalStateException("${this.javaClass.simpleName} call counter would overflow") - } - } while (! this.callCounter.compareAndSet(c, c + 1L)) - // Now we can safely do the method call without the pointer being freed concurrently. - try { - return block(this.uniffiClonePointer()) - } finally { - // This decrement always matches the increment we performed above. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - // Use a static inner class instead of a closure so as not to accidentally - // capture `this` as part of the cleanable's action. - private class UniffiCleanAction(private val pointer: Pointer?) : Runnable { - override fun run() { - pointer?.let { ptr -> - uniffiRustCall { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_free_developercert(ptr, status) - } - } - } - } - - fun uniffiClonePointer(): Pointer { - return uniffiRustCall() { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_clone_developercert(pointer!!, status) - } - } - - - - - - companion object - -} - -/** - * @suppress - */ -public object FfiConverterTypeDeveloperCert: FfiConverter { - - override fun lower(value: DeveloperCert): Pointer { - return value.uniffiClonePointer() - } - - override fun lift(value: Pointer): DeveloperCert { - return DeveloperCert(value) - } - - override fun read(buf: ByteBuffer): DeveloperCert { - // The Rust code always writes pointers as 8 bytes, and will - // fail to compile if they don't fit. - return lift(Pointer(buf.getLong())) - } - - override fun allocationSize(value: DeveloperCert) = 8UL - - override fun write(value: DeveloperCert, buf: ByteBuffer) { - // The Rust code always expects pointers written as 8 bytes, - // and will fail to compile if they don't fit. - buf.putLong(Pointer.nativeValue(lower(value))) - } -} - - -// This template implements a class for working with a Rust struct via a Pointer/Arc -// to the live Rust struct on the other side of the FFI. -// -// Each instance implements core operations for working with the Rust `Arc` and the -// Kotlin Pointer to work with the live Rust struct on the other side of the FFI. -// -// There's some subtlety here, because we have to be careful not to operate on a Rust -// struct after it has been dropped, and because we must expose a public API for freeing -// theq Kotlin wrapper object in lieu of reliable finalizers. The core requirements are: -// -// * Each instance holds an opaque pointer to the underlying Rust struct. -// Method calls need to read this pointer from the object's state and pass it in to -// the Rust FFI. -// -// * When an instance is no longer needed, its pointer should be passed to a -// special destructor function provided by the Rust FFI, which will drop the -// underlying Rust struct. -// -// * Given an instance, calling code is expected to call the special -// `destroy` method in order to free it after use, either by calling it explicitly -// or by using a higher-level helper like the `use` method. Failing to do so risks -// leaking the underlying Rust struct. -// -// * We can't assume that calling code will do the right thing, and must be prepared -// to handle Kotlin method calls executing concurrently with or even after a call to -// `destroy`, and to handle multiple (possibly concurrent!) calls to `destroy`. -// -// * We must never allow Rust code to operate on the underlying Rust struct after -// the destructor has been called, and must never call the destructor more than once. -// Doing so may trigger memory unsafety. -// -// * To mitigate many of the risks of leaking memory and use-after-free unsafety, a `Cleaner` -// is implemented to call the destructor when the Kotlin object becomes unreachable. -// This is done in a background thread. This is not a panacea, and client code should be aware that -// 1. the thread may starve if some there are objects that have poorly performing -// `drop` methods or do significant work in their `drop` methods. -// 2. the thread is shared across the whole library. This can be tuned by using `android_cleaner = true`, -// or `android = true` in the [`kotlin` section of the `uniffi.toml` file](https://mozilla.github.io/uniffi-rs/kotlin/configuration.html). -// -// If we try to implement this with mutual exclusion on access to the pointer, there is the -// possibility of a race between a method call and a concurrent call to `destroy`: -// -// * Thread A starts a method call, reads the value of the pointer, but is interrupted -// before it can pass the pointer over the FFI to Rust. -// * Thread B calls `destroy` and frees the underlying Rust struct. -// * Thread A resumes, passing the already-read pointer value to Rust and triggering -// a use-after-free. -// -// One possible solution would be to use a `ReadWriteLock`, with each method call taking -// a read lock (and thus allowed to run concurrently) and the special `destroy` method -// taking a write lock (and thus blocking on live method calls). However, we aim not to -// generate methods with any hidden blocking semantics, and a `destroy` method that might -// block if called incorrectly seems to meet that bar. -// -// So, we achieve our goals by giving each instance an associated `AtomicLong` counter to track -// the number of in-flight method calls, and an `AtomicBoolean` flag to indicate whether `destroy` -// has been called. These are updated according to the following rules: -// -// * The initial value of the counter is 1, indicating a live object with no in-flight calls. -// The initial value for the flag is false. -// -// * At the start of each method call, we atomically check the counter. -// If it is 0 then the underlying Rust struct has already been destroyed and the call is aborted. -// If it is nonzero them we atomically increment it by 1 and proceed with the method call. -// -// * At the end of each method call, we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// * When `destroy` is called, we atomically flip the flag from false to true. -// If the flag was already true we silently fail. -// Otherwise we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// Astute readers may observe that this all sounds very similar to the way that Rust's `Arc` works, -// and indeed it is, with the addition of a flag to guard against multiple calls to `destroy`. -// -// The overall effect is that the underlying Rust struct is destroyed only when `destroy` has been -// called *and* all in-flight method calls have completed, avoiding violating any of the expectations -// of the underlying Rust code. -// -// This makes a cleaner a better alternative to _not_ calling `destroy()` as -// and when the object is finished with, but the abstraction is not perfect: if the Rust object's `drop` -// method is slow, and/or there are many objects to cleanup, and it's on a low end Android device, then the cleaner -// thread may be starved, and the app will leak memory. -// -// In this case, `destroy`ing manually may be a better solution. -// -// The cleaner can live side by side with the manual calling of `destroy`. In the order of responsiveness, uniffi objects -// with Rust peers are reclaimed: -// -// 1. By calling the `destroy` method of the object, which calls `rustObject.free()`. If that doesn't happen: -// 2. When the object becomes unreachable, AND the Cleaner thread gets to call `rustObject.free()`. If the thread is starved then: -// 3. The memory is reclaimed when the process terminates. -// -// [1] https://stackoverflow.com/questions/24376768/can-java-finalize-an-object-when-it-is-still-in-scope/24380219 -// - - -/** - * A handle to interact with a signer loop running and processing - * requests in the background. Used primarily to stop the loop and - * exiting the signer. - */ -public interface HandleInterface { - - fun `stop`() - - companion object -} - -/** - * A handle to interact with a signer loop running and processing - * requests in the background. Used primarily to stop the loop and - * exiting the signer. - */ -open class Handle: Disposable, AutoCloseable, HandleInterface -{ - - constructor(pointer: Pointer) { - this.pointer = pointer - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - - /** - * This constructor can be used to instantiate a fake object. Only used for tests. Any - * attempt to actually use an object constructed this way will fail as there is no - * connected Rust object. - */ - @Suppress("UNUSED_PARAMETER") - constructor(noPointer: NoPointer) { - this.pointer = null - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - - protected val pointer: Pointer? - protected val cleanable: UniffiCleaner.Cleanable - - private val wasDestroyed = AtomicBoolean(false) - private val callCounter = AtomicLong(1) - - override fun destroy() { - // Only allow a single call to this method. - // TODO: maybe we should log a warning if called more than once? - if (this.wasDestroyed.compareAndSet(false, true)) { - // This decrement always matches the initial count of 1 given at creation time. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - @Synchronized - override fun close() { - this.destroy() - } - - internal inline fun callWithPointer(block: (ptr: Pointer) -> R): R { - // Check and increment the call counter, to keep the object alive. - // This needs a compare-and-set retry loop in case of concurrent updates. - do { - val c = this.callCounter.get() - if (c == 0L) { - throw IllegalStateException("${this.javaClass.simpleName} object has already been destroyed") - } - if (c == Long.MAX_VALUE) { - throw IllegalStateException("${this.javaClass.simpleName} call counter would overflow") - } - } while (! this.callCounter.compareAndSet(c, c + 1L)) - // Now we can safely do the method call without the pointer being freed concurrently. - try { - return block(this.uniffiClonePointer()) - } finally { - // This decrement always matches the increment we performed above. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - // Use a static inner class instead of a closure so as not to accidentally - // capture `this` as part of the cleanable's action. - private class UniffiCleanAction(private val pointer: Pointer?) : Runnable { - override fun run() { - pointer?.let { ptr -> - uniffiRustCall { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_free_handle(ptr, status) - } - } - } - } - - fun uniffiClonePointer(): Pointer { - return uniffiRustCall() { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_clone_handle(pointer!!, status) - } - } - - override fun `stop`() - = - callWithPointer { - uniffiRustCall() { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_handle_stop( - it, _status) -} - } - - - - - - - - companion object - -} - -/** - * @suppress - */ -public object FfiConverterTypeHandle: FfiConverter { - - override fun lower(value: Handle): Pointer { - return value.uniffiClonePointer() - } - - override fun lift(value: Pointer): Handle { - return Handle(value) - } - - override fun read(buf: ByteBuffer): Handle { - // The Rust code always writes pointers as 8 bytes, and will - // fail to compile if they don't fit. - return lift(Pointer(buf.getLong())) - } - - override fun allocationSize(value: Handle) = 8UL - - override fun write(value: Handle, buf: ByteBuffer) { - // The Rust code always expects pointers written as 8 bytes, - // and will fail to compile if they don't fit. - buf.putLong(Pointer.nativeValue(lower(value))) - } -} - - -// This template implements a class for working with a Rust struct via a Pointer/Arc -// to the live Rust struct on the other side of the FFI. -// -// Each instance implements core operations for working with the Rust `Arc` and the -// Kotlin Pointer to work with the live Rust struct on the other side of the FFI. -// -// There's some subtlety here, because we have to be careful not to operate on a Rust -// struct after it has been dropped, and because we must expose a public API for freeing -// theq Kotlin wrapper object in lieu of reliable finalizers. The core requirements are: -// -// * Each instance holds an opaque pointer to the underlying Rust struct. -// Method calls need to read this pointer from the object's state and pass it in to -// the Rust FFI. -// -// * When an instance is no longer needed, its pointer should be passed to a -// special destructor function provided by the Rust FFI, which will drop the -// underlying Rust struct. -// -// * Given an instance, calling code is expected to call the special -// `destroy` method in order to free it after use, either by calling it explicitly -// or by using a higher-level helper like the `use` method. Failing to do so risks -// leaking the underlying Rust struct. -// -// * We can't assume that calling code will do the right thing, and must be prepared -// to handle Kotlin method calls executing concurrently with or even after a call to -// `destroy`, and to handle multiple (possibly concurrent!) calls to `destroy`. -// -// * We must never allow Rust code to operate on the underlying Rust struct after -// the destructor has been called, and must never call the destructor more than once. -// Doing so may trigger memory unsafety. -// -// * To mitigate many of the risks of leaking memory and use-after-free unsafety, a `Cleaner` -// is implemented to call the destructor when the Kotlin object becomes unreachable. -// This is done in a background thread. This is not a panacea, and client code should be aware that -// 1. the thread may starve if some there are objects that have poorly performing -// `drop` methods or do significant work in their `drop` methods. -// 2. the thread is shared across the whole library. This can be tuned by using `android_cleaner = true`, -// or `android = true` in the [`kotlin` section of the `uniffi.toml` file](https://mozilla.github.io/uniffi-rs/kotlin/configuration.html). -// -// If we try to implement this with mutual exclusion on access to the pointer, there is the -// possibility of a race between a method call and a concurrent call to `destroy`: -// -// * Thread A starts a method call, reads the value of the pointer, but is interrupted -// before it can pass the pointer over the FFI to Rust. -// * Thread B calls `destroy` and frees the underlying Rust struct. -// * Thread A resumes, passing the already-read pointer value to Rust and triggering -// a use-after-free. -// -// One possible solution would be to use a `ReadWriteLock`, with each method call taking -// a read lock (and thus allowed to run concurrently) and the special `destroy` method -// taking a write lock (and thus blocking on live method calls). However, we aim not to -// generate methods with any hidden blocking semantics, and a `destroy` method that might -// block if called incorrectly seems to meet that bar. -// -// So, we achieve our goals by giving each instance an associated `AtomicLong` counter to track -// the number of in-flight method calls, and an `AtomicBoolean` flag to indicate whether `destroy` -// has been called. These are updated according to the following rules: -// -// * The initial value of the counter is 1, indicating a live object with no in-flight calls. -// The initial value for the flag is false. -// -// * At the start of each method call, we atomically check the counter. -// If it is 0 then the underlying Rust struct has already been destroyed and the call is aborted. -// If it is nonzero them we atomically increment it by 1 and proceed with the method call. -// -// * At the end of each method call, we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// * When `destroy` is called, we atomically flip the flag from false to true. -// If the flag was already true we silently fail. -// Otherwise we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// Astute readers may observe that this all sounds very similar to the way that Rust's `Arc` works, -// and indeed it is, with the addition of a flag to guard against multiple calls to `destroy`. -// -// The overall effect is that the underlying Rust struct is destroyed only when `destroy` has been -// called *and* all in-flight method calls have completed, avoiding violating any of the expectations -// of the underlying Rust code. -// -// This makes a cleaner a better alternative to _not_ calling `destroy()` as -// and when the object is finished with, but the abstraction is not perfect: if the Rust object's `drop` -// method is slow, and/or there are many objects to cleanup, and it's on a low end Android device, then the cleaner -// thread may be starved, and the app will leak memory. -// -// In this case, `destroy`ing manually may be a better solution. -// -// The cleaner can live side by side with the manual calling of `destroy`. In the order of responsiveness, uniffi objects -// with Rust peers are reclaimed: -// -// 1. By calling the `destroy` method of the object, which calls `rustObject.free()`. If that doesn't happen: -// 2. When the object becomes unreachable, AND the Cleaner thread gets to call `rustObject.free()`. If the thread is starved then: -// 3. The memory is reclaimed when the process terminates. -// -// [1] https://stackoverflow.com/questions/24376768/can-java-finalize-an-object-when-it-is-still-in-scope/24380219 -// - - -/** - * The `Node` is an RPC stub representing the node running in the - * cloud. It is the main entrypoint to interact with the node. - */ -public interface NodeInterface { - - /** - * Returns the serialized credentials for this node. - * The app should persist these bytes and pass them to connect() on next launch. - */ - fun `credentials`(): kotlin.ByteArray - - /** - * Disconnects from the node and stops the signer if running. - * After disconnect, all RPC methods will return an error. - * Safe to call multiple times. - */ - fun `disconnect`() - - /** - * Collect a diagnostic snapshot of the node and SDK state. - * - * Returns a pretty-printed JSON string with shape: - * `{ "timestamp": , "node": { ... }, "sdk": { "version": ..., "node_state": ... } }`. - * The `node` object contains one entry per CLN RPC (`getinfo`, - * `listpeerchannels`, `listfunds`); each value is the serialized - * response, or `{ "error": "..." }` if that RPC failed. Payment and - * invoice history are deliberately excluded to avoid leaking - * preimages, payment hashes, bolt11 strings, and labels into support - * dumps. Intended for support tickets. - */ - fun `generateDiagnosticData`(): kotlin.String - - /** - * Get information about the node. - * - * Returns basic information about the node including its ID, - * alias, network, and channel counts. - */ - fun `getInfo`(): GetInfoResponse - - /** - * List all funds available to the node. - * - * Returns information about on-chain outputs and channel funds - * that are available or pending. - */ - fun `listFunds`(): ListFundsResponse - - /** - * List invoices (received payment requests). - * All parameters are optional filters; pass None to fetch all. - */ - fun `listInvoices`(`label`: kotlin.String?, `invstring`: kotlin.String?, `paymentHash`: kotlin.ByteArray?, `offerId`: kotlin.String?, `index`: ListIndex?, `start`: kotlin.ULong?, `limit`: kotlin.UInt?): ListInvoicesResponse - - /** - * List payments (sent and received), merged into a single timeline. - * - * Fetches invoices and outgoing payments from the node, merges - * them into a unified list, and applies optional filters. - * Use `list_invoices`/`list_pays` for direct CLN access. - * Results are sorted newest-first. - */ - fun `listPayments`(`req`: ListPaymentsRequest): List - - /** - * List outgoing payments. - * All parameters are optional filters; pass None to fetch all. - */ - fun `listPays`(`bolt11`: kotlin.String?, `paymentHash`: kotlin.ByteArray?, `status`: PayStatus?, `index`: ListIndex?, `start`: kotlin.ULong?, `limit`: kotlin.UInt?): ListPaysResponse - - /** - * List all channels with peers. - * - * Returns detailed information about all channels including their - * state, capacity, and balances. - */ - fun `listPeerChannels`(): ListPeerChannelsResponse - - /** - * List all peers connected to this node. - * - * Returns information about all peers including their connection - * status. - */ - fun `listPeers`(): ListPeersResponse - - /** - * Execute an LNURL-pay flow (LUD-06). - * - * Sends the chosen amount (and optional comment) to the service's - * callback, receives and validates a BOLT11 invoice, pays it, and - * processes any success action (LUD-09/10). - * - * Call the top-level `parse_input` first to obtain the - * `LnUrlPayRequestData`, then build an `LnUrlPayRequest` with the - * user's chosen amount. - */ - fun `lnurlPay`(`request`: LnUrlPayRequest): LnUrlPayResult - - /** - * Execute an LNURL-withdraw flow (LUD-03). - * - * Creates an invoice on this node for the requested amount, sends - * it to the service's callback URL, and the service pays it - * asynchronously. - * - * Call the top-level `parse_input` first to obtain the - * `LnUrlWithdrawRequestData`, then build an `LnUrlWithdrawRequest` - * with the user's chosen amount. - */ - fun `lnurlWithdraw`(`request`: LnUrlWithdrawRequest): LnUrlWithdrawResult - - /** - * Get a snapshot of the node's balances, capacity, and connectivity. - * - * Aggregates data from multiple RPCs into a single `NodeState`. - * Queries the node live on each call — not cached. - */ - fun `nodeState`(): NodeState - - /** - * Classify the on-chain wallet for the withdraw entry-point UI. - * - * Runs three RPCs concurrently: - * * `list_funds` — current confirmed/unconfirmed/immature on-chain - * balances. - * * `list_peer_channels` — pending channel-close payouts that - * haven't yet hit the wallet. - * * `fund_psbt(satoshi=All, reserve=0, normal feerate)` — a - * non-locking probe whose response tells us **exactly** how - * much CLN will carve as the anchor-channel emergency reserve - * for this specific node, no client-side guessing required. - * The carved amount is computed from the response as - * `total_inputs − excess − fee`, which is identical to what - * CLN would carve on a real broadcast. - * - * Cheaper to call than `node_state()` and answers a different - * question. Wallets typically call it once per render of the - * home screen. - * - * For the *exact* post-fee recipient amount of a withdraw, use - * `prepare_onchain_send`; the `withdrawable_sat` returned here - * is a pre-fee, reserve-aware figure for the entry-point label. - */ - fun `onchainBalanceState`(): OnchainBalanceState - - /** - * On-chain fee rates, in sats per virtual byte, at several - * confirmation targets. - * - * Sourced from the connected node's view of the network — no - * 3rd-party HTTP calls. Use as the basis for a fee-picker UI; - * `minimum_relay_sat_per_vbyte` is the relay floor enforced at - * broadcast time and should be the lower bound of any slider. - */ - fun `onchainFeeRates`(): OnchainFeeRates - - /** - * Generate a fresh on-chain Bitcoin address for receiving funds. - * - * Returns both a bech32 (SegWit v0) and a p2tr (Taproot) address. - * Either can be shared with a sender. Deposited funds will appear - * in `node_state().onchain_balance_msat` once confirmed. - */ - fun `onchainReceive`(): OnchainReceiveResponse - - /** - * Send bitcoin on-chain to a destination address. - * - * # Arguments - * * `destination` — A Bitcoin address (bech32, p2sh, or p2tr). - * * `amount_or_all` — Amount to send. Accepts: - * - `"50000"` or `"50000sat"` — 50,000 satoshis - * - `"50000msat"` — 50,000 millisatoshis - * - `"all"` — sweep the entire on-chain balance - * * `sat_per_vbyte` — Optional fee rate in sats per virtual byte. - * Pass `None` to let the node pick. Pass the value from a prior - * `prepare_onchain_send` to reproduce the previewed fee. - * * `utxos` — Optional pinned input set. Pass the `utxos` returned - * by `prepare_onchain_send` (together with the same - * `sat_per_vbyte`) to broadcast a transaction with the exact - * inputs and fee shown in the preview. Pass `None` to let the - * node coin-select. - * - * Returns the raw transaction, txid, and PSBT once broadcast. - * The transaction is broadcast immediately — this is not a dry run. - */ - fun `onchainSend`(`destination`: kotlin.String, `amountOrAll`: kotlin.String, `satPerVbyte`: kotlin.UInt?, `utxos`: List?): OnchainSendResponse - - /** - * Preview an on-chain send without broadcasting or reserving UTXOs. - * - * Runs CLN's coin selection at the given fee rate and returns the - * inputs that would be spent, the fee, and the amount the recipient - * would receive. Safe to call repeatedly (e.g. while the user - * adjusts a fee slider) — nothing is locked. - * - * To broadcast with the previewed values, pass the returned - * `utxos` and `sat_per_vbyte` back to `onchain_send`. Identical - * inputs at the same fee rate yield the same fee. - * - * **Use this for "Send Max" UIs.** `recipient_sat` is the only - * authoritative post-fee amount the destination will receive - * for a sweep. `NodeState.onchain_balance_msat` includes the - * emergency reserve and the fee — neither of which leaves the - * wallet with the recipient. For the entry-point button label - * (a pre-fee approximation that updates without an RPC), use - * `OnchainBalanceState::Available.withdrawable_sat`. - * - * # Arguments - * * `destination` — A Bitcoin address (bech32, p2sh, or p2tr). - * * `amount_or_all` — Amount to send. Accepts: - * - `"50000"` or `"50000sat"` — 50,000 satoshis - * - `"50000msat"` — 50,000 millisatoshis - * - `"all"` — sweep the entire on-chain balance - * * `sat_per_vbyte` — Fee rate in sats per virtual byte. Pass - * `None` to use the node's "normal" priority feerate; the - * effective rate CLN picked is reported back in the result's - * `sat_per_vbyte` field, which can be passed to `onchain_send` - * to reproduce it. - */ - fun `prepareOnchainSend`(`destination`: kotlin.String, `amountOrAll`: kotlin.String, `satPerVbyte`: kotlin.UInt?): PreparedOnchainSend - - /** - * Receive an off-chain payment. - * - * This method generates a request for a payment, also called an - * invoice, that encodes all the information, including amount - * and destination, for a prospective sender to send a lightning - * payment. The invoice includes negotiation of an LSPS2 / JIT - * channel, meaning that if there is no channel sufficient to - * receive the requested funds, the node will negotiate an - * opening, and when/if executed the payment will cause a channel - * to be created, and the incoming payment to be forwarded. - */ - fun `receive`(`label`: kotlin.String, `description`: kotlin.String, `amountMsat`: kotlin.ULong?): ReceiveResponse - - fun `send`(`invoice`: kotlin.String, `amountMsat`: kotlin.ULong?): SendResponse - - /** - * Stop the node if it is currently running. - */ - fun `stop`() - - /** - * Stream real-time events from the node. - * - * Returns a `NodeEventStream` iterator. Call `next()` repeatedly - * to receive events as they occur (e.g., invoice payments). - * - * The `next()` method blocks the calling thread until an event - * is available, but does not block the underlying async runtime, - * so other node methods can be called concurrently from other - * threads. - */ - fun `streamNodeEvents`(): NodeEventStream - - companion object -} - -/** - * The `Node` is an RPC stub representing the node running in the - * cloud. It is the main entrypoint to interact with the node. - */ -open class Node: Disposable, AutoCloseable, NodeInterface -{ - - constructor(pointer: Pointer) { - this.pointer = pointer - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - - /** - * This constructor can be used to instantiate a fake object. Only used for tests. Any - * attempt to actually use an object constructed this way will fail as there is no - * connected Rust object. - */ - @Suppress("UNUSED_PARAMETER") - constructor(noPointer: NoPointer) { - this.pointer = null - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - - protected val pointer: Pointer? - protected val cleanable: UniffiCleaner.Cleanable - - private val wasDestroyed = AtomicBoolean(false) - private val callCounter = AtomicLong(1) - - override fun destroy() { - // Only allow a single call to this method. - // TODO: maybe we should log a warning if called more than once? - if (this.wasDestroyed.compareAndSet(false, true)) { - // This decrement always matches the initial count of 1 given at creation time. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - @Synchronized - override fun close() { - this.destroy() - } - - internal inline fun callWithPointer(block: (ptr: Pointer) -> R): R { - // Check and increment the call counter, to keep the object alive. - // This needs a compare-and-set retry loop in case of concurrent updates. - do { - val c = this.callCounter.get() - if (c == 0L) { - throw IllegalStateException("${this.javaClass.simpleName} object has already been destroyed") - } - if (c == Long.MAX_VALUE) { - throw IllegalStateException("${this.javaClass.simpleName} call counter would overflow") - } - } while (! this.callCounter.compareAndSet(c, c + 1L)) - // Now we can safely do the method call without the pointer being freed concurrently. - try { - return block(this.uniffiClonePointer()) - } finally { - // This decrement always matches the increment we performed above. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - // Use a static inner class instead of a closure so as not to accidentally - // capture `this` as part of the cleanable's action. - private class UniffiCleanAction(private val pointer: Pointer?) : Runnable { - override fun run() { - pointer?.let { ptr -> - uniffiRustCall { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_free_node(ptr, status) - } - } - } - } - - fun uniffiClonePointer(): Pointer { - return uniffiRustCall() { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_clone_node(pointer!!, status) - } - } - - - /** - * Returns the serialized credentials for this node. - * The app should persist these bytes and pass them to connect() on next launch. - */ - @Throws(Exception::class)override fun `credentials`(): kotlin.ByteArray { - return FfiConverterByteArray.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_credentials( - it, _status) -} - } - ) - } - - - - /** - * Disconnects from the node and stops the signer if running. - * After disconnect, all RPC methods will return an error. - * Safe to call multiple times. - */ - @Throws(Exception::class)override fun `disconnect`() - = - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_disconnect( - it, _status) -} - } - - - - - /** - * Collect a diagnostic snapshot of the node and SDK state. - * - * Returns a pretty-printed JSON string with shape: - * `{ "timestamp": , "node": { ... }, "sdk": { "version": ..., "node_state": ... } }`. - * The `node` object contains one entry per CLN RPC (`getinfo`, - * `listpeerchannels`, `listfunds`); each value is the serialized - * response, or `{ "error": "..." }` if that RPC failed. Payment and - * invoice history are deliberately excluded to avoid leaking - * preimages, payment hashes, bolt11 strings, and labels into support - * dumps. Intended for support tickets. - */ - @Throws(Exception::class)override fun `generateDiagnosticData`(): kotlin.String { - return FfiConverterString.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_generate_diagnostic_data( - it, _status) -} - } - ) - } - - - - /** - * Get information about the node. - * - * Returns basic information about the node including its ID, - * alias, network, and channel counts. - */ - @Throws(Exception::class)override fun `getInfo`(): GetInfoResponse { - return FfiConverterTypeGetInfoResponse.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_get_info( - it, _status) -} - } - ) - } - - - - /** - * List all funds available to the node. - * - * Returns information about on-chain outputs and channel funds - * that are available or pending. - */ - @Throws(Exception::class)override fun `listFunds`(): ListFundsResponse { - return FfiConverterTypeListFundsResponse.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_list_funds( - it, _status) -} - } - ) - } - - - - /** - * List invoices (received payment requests). - * All parameters are optional filters; pass None to fetch all. - */ - @Throws(Exception::class)override fun `listInvoices`(`label`: kotlin.String?, `invstring`: kotlin.String?, `paymentHash`: kotlin.ByteArray?, `offerId`: kotlin.String?, `index`: ListIndex?, `start`: kotlin.ULong?, `limit`: kotlin.UInt?): ListInvoicesResponse { - return FfiConverterTypeListInvoicesResponse.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_list_invoices( - it, FfiConverterOptionalString.lower(`label`),FfiConverterOptionalString.lower(`invstring`),FfiConverterOptionalByteArray.lower(`paymentHash`),FfiConverterOptionalString.lower(`offerId`),FfiConverterOptionalTypeListIndex.lower(`index`),FfiConverterOptionalULong.lower(`start`),FfiConverterOptionalUInt.lower(`limit`),_status) -} - } - ) - } - - - - /** - * List payments (sent and received), merged into a single timeline. - * - * Fetches invoices and outgoing payments from the node, merges - * them into a unified list, and applies optional filters. - * Use `list_invoices`/`list_pays` for direct CLN access. - * Results are sorted newest-first. - */ - @Throws(Exception::class)override fun `listPayments`(`req`: ListPaymentsRequest): List { - return FfiConverterSequenceTypePayment.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_list_payments( - it, FfiConverterTypeListPaymentsRequest.lower(`req`),_status) -} - } - ) - } - - - - /** - * List outgoing payments. - * All parameters are optional filters; pass None to fetch all. - */ - @Throws(Exception::class)override fun `listPays`(`bolt11`: kotlin.String?, `paymentHash`: kotlin.ByteArray?, `status`: PayStatus?, `index`: ListIndex?, `start`: kotlin.ULong?, `limit`: kotlin.UInt?): ListPaysResponse { - return FfiConverterTypeListPaysResponse.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_list_pays( - it, FfiConverterOptionalString.lower(`bolt11`),FfiConverterOptionalByteArray.lower(`paymentHash`),FfiConverterOptionalTypePayStatus.lower(`status`),FfiConverterOptionalTypeListIndex.lower(`index`),FfiConverterOptionalULong.lower(`start`),FfiConverterOptionalUInt.lower(`limit`),_status) -} - } - ) - } - - - - /** - * List all channels with peers. - * - * Returns detailed information about all channels including their - * state, capacity, and balances. - */ - @Throws(Exception::class)override fun `listPeerChannels`(): ListPeerChannelsResponse { - return FfiConverterTypeListPeerChannelsResponse.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_list_peer_channels( - it, _status) -} - } - ) - } - - - - /** - * List all peers connected to this node. - * - * Returns information about all peers including their connection - * status. - */ - @Throws(Exception::class)override fun `listPeers`(): ListPeersResponse { - return FfiConverterTypeListPeersResponse.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_list_peers( - it, _status) -} - } - ) - } - - - - /** - * Execute an LNURL-pay flow (LUD-06). - * - * Sends the chosen amount (and optional comment) to the service's - * callback, receives and validates a BOLT11 invoice, pays it, and - * processes any success action (LUD-09/10). - * - * Call the top-level `parse_input` first to obtain the - * `LnUrlPayRequestData`, then build an `LnUrlPayRequest` with the - * user's chosen amount. - */ - @Throws(Exception::class)override fun `lnurlPay`(`request`: LnUrlPayRequest): LnUrlPayResult { - return FfiConverterTypeLnUrlPayResult.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_lnurl_pay( - it, FfiConverterTypeLnUrlPayRequest.lower(`request`),_status) -} - } - ) - } - - - - /** - * Execute an LNURL-withdraw flow (LUD-03). - * - * Creates an invoice on this node for the requested amount, sends - * it to the service's callback URL, and the service pays it - * asynchronously. - * - * Call the top-level `parse_input` first to obtain the - * `LnUrlWithdrawRequestData`, then build an `LnUrlWithdrawRequest` - * with the user's chosen amount. - */ - @Throws(Exception::class)override fun `lnurlWithdraw`(`request`: LnUrlWithdrawRequest): LnUrlWithdrawResult { - return FfiConverterTypeLnUrlWithdrawResult.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_lnurl_withdraw( - it, FfiConverterTypeLnUrlWithdrawRequest.lower(`request`),_status) -} - } - ) - } - - - - /** - * Get a snapshot of the node's balances, capacity, and connectivity. - * - * Aggregates data from multiple RPCs into a single `NodeState`. - * Queries the node live on each call — not cached. - */ - @Throws(Exception::class)override fun `nodeState`(): NodeState { - return FfiConverterTypeNodeState.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_node_state( - it, _status) -} - } - ) - } - - - - /** - * Classify the on-chain wallet for the withdraw entry-point UI. - * - * Runs three RPCs concurrently: - * * `list_funds` — current confirmed/unconfirmed/immature on-chain - * balances. - * * `list_peer_channels` — pending channel-close payouts that - * haven't yet hit the wallet. - * * `fund_psbt(satoshi=All, reserve=0, normal feerate)` — a - * non-locking probe whose response tells us **exactly** how - * much CLN will carve as the anchor-channel emergency reserve - * for this specific node, no client-side guessing required. - * The carved amount is computed from the response as - * `total_inputs − excess − fee`, which is identical to what - * CLN would carve on a real broadcast. - * - * Cheaper to call than `node_state()` and answers a different - * question. Wallets typically call it once per render of the - * home screen. - * - * For the *exact* post-fee recipient amount of a withdraw, use - * `prepare_onchain_send`; the `withdrawable_sat` returned here - * is a pre-fee, reserve-aware figure for the entry-point label. - */ - @Throws(Exception::class)override fun `onchainBalanceState`(): OnchainBalanceState { - return FfiConverterTypeOnchainBalanceState.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_onchain_balance_state( - it, _status) -} - } - ) - } - - - - /** - * On-chain fee rates, in sats per virtual byte, at several - * confirmation targets. - * - * Sourced from the connected node's view of the network — no - * 3rd-party HTTP calls. Use as the basis for a fee-picker UI; - * `minimum_relay_sat_per_vbyte` is the relay floor enforced at - * broadcast time and should be the lower bound of any slider. - */ - @Throws(Exception::class)override fun `onchainFeeRates`(): OnchainFeeRates { - return FfiConverterTypeOnchainFeeRates.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_onchain_fee_rates( - it, _status) -} - } - ) - } - - - - /** - * Generate a fresh on-chain Bitcoin address for receiving funds. - * - * Returns both a bech32 (SegWit v0) and a p2tr (Taproot) address. - * Either can be shared with a sender. Deposited funds will appear - * in `node_state().onchain_balance_msat` once confirmed. - */ - @Throws(Exception::class)override fun `onchainReceive`(): OnchainReceiveResponse { - return FfiConverterTypeOnchainReceiveResponse.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_onchain_receive( - it, _status) -} - } - ) - } - - - - /** - * Send bitcoin on-chain to a destination address. - * - * # Arguments - * * `destination` — A Bitcoin address (bech32, p2sh, or p2tr). - * * `amount_or_all` — Amount to send. Accepts: - * - `"50000"` or `"50000sat"` — 50,000 satoshis - * - `"50000msat"` — 50,000 millisatoshis - * - `"all"` — sweep the entire on-chain balance - * * `sat_per_vbyte` — Optional fee rate in sats per virtual byte. - * Pass `None` to let the node pick. Pass the value from a prior - * `prepare_onchain_send` to reproduce the previewed fee. - * * `utxos` — Optional pinned input set. Pass the `utxos` returned - * by `prepare_onchain_send` (together with the same - * `sat_per_vbyte`) to broadcast a transaction with the exact - * inputs and fee shown in the preview. Pass `None` to let the - * node coin-select. - * - * Returns the raw transaction, txid, and PSBT once broadcast. - * The transaction is broadcast immediately — this is not a dry run. - */ - @Throws(Exception::class)override fun `onchainSend`(`destination`: kotlin.String, `amountOrAll`: kotlin.String, `satPerVbyte`: kotlin.UInt?, `utxos`: List?): OnchainSendResponse { - return FfiConverterTypeOnchainSendResponse.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_onchain_send( - it, FfiConverterString.lower(`destination`),FfiConverterString.lower(`amountOrAll`),FfiConverterOptionalUInt.lower(`satPerVbyte`),FfiConverterOptionalSequenceTypeOutpoint.lower(`utxos`),_status) -} - } - ) - } - - - - /** - * Preview an on-chain send without broadcasting or reserving UTXOs. - * - * Runs CLN's coin selection at the given fee rate and returns the - * inputs that would be spent, the fee, and the amount the recipient - * would receive. Safe to call repeatedly (e.g. while the user - * adjusts a fee slider) — nothing is locked. - * - * To broadcast with the previewed values, pass the returned - * `utxos` and `sat_per_vbyte` back to `onchain_send`. Identical - * inputs at the same fee rate yield the same fee. - * - * **Use this for "Send Max" UIs.** `recipient_sat` is the only - * authoritative post-fee amount the destination will receive - * for a sweep. `NodeState.onchain_balance_msat` includes the - * emergency reserve and the fee — neither of which leaves the - * wallet with the recipient. For the entry-point button label - * (a pre-fee approximation that updates without an RPC), use - * `OnchainBalanceState::Available.withdrawable_sat`. - * - * # Arguments - * * `destination` — A Bitcoin address (bech32, p2sh, or p2tr). - * * `amount_or_all` — Amount to send. Accepts: - * - `"50000"` or `"50000sat"` — 50,000 satoshis - * - `"50000msat"` — 50,000 millisatoshis - * - `"all"` — sweep the entire on-chain balance - * * `sat_per_vbyte` — Fee rate in sats per virtual byte. Pass - * `None` to use the node's "normal" priority feerate; the - * effective rate CLN picked is reported back in the result's - * `sat_per_vbyte` field, which can be passed to `onchain_send` - * to reproduce it. - */ - @Throws(Exception::class)override fun `prepareOnchainSend`(`destination`: kotlin.String, `amountOrAll`: kotlin.String, `satPerVbyte`: kotlin.UInt?): PreparedOnchainSend { - return FfiConverterTypePreparedOnchainSend.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_prepare_onchain_send( - it, FfiConverterString.lower(`destination`),FfiConverterString.lower(`amountOrAll`),FfiConverterOptionalUInt.lower(`satPerVbyte`),_status) -} - } - ) - } - - - - /** - * Receive an off-chain payment. - * - * This method generates a request for a payment, also called an - * invoice, that encodes all the information, including amount - * and destination, for a prospective sender to send a lightning - * payment. The invoice includes negotiation of an LSPS2 / JIT - * channel, meaning that if there is no channel sufficient to - * receive the requested funds, the node will negotiate an - * opening, and when/if executed the payment will cause a channel - * to be created, and the incoming payment to be forwarded. - */ - @Throws(Exception::class)override fun `receive`(`label`: kotlin.String, `description`: kotlin.String, `amountMsat`: kotlin.ULong?): ReceiveResponse { - return FfiConverterTypeReceiveResponse.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_receive( - it, FfiConverterString.lower(`label`),FfiConverterString.lower(`description`),FfiConverterOptionalULong.lower(`amountMsat`),_status) -} - } - ) - } - - - - @Throws(Exception::class)override fun `send`(`invoice`: kotlin.String, `amountMsat`: kotlin.ULong?): SendResponse { - return FfiConverterTypeSendResponse.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_send( - it, FfiConverterString.lower(`invoice`),FfiConverterOptionalULong.lower(`amountMsat`),_status) -} - } - ) - } - - - - /** - * Stop the node if it is currently running. - */ - @Throws(Exception::class)override fun `stop`() - = - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_stop( - it, _status) -} - } - - - - - /** - * Stream real-time events from the node. - * - * Returns a `NodeEventStream` iterator. Call `next()` repeatedly - * to receive events as they occur (e.g., invoice payments). - * - * The `next()` method blocks the calling thread until an event - * is available, but does not block the underlying async runtime, - * so other node methods can be called concurrently from other - * threads. - */ - @Throws(Exception::class)override fun `streamNodeEvents`(): NodeEventStream { - return FfiConverterTypeNodeEventStream.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_node_stream_node_events( - it, _status) -} - } - ) - } - - - - - - - companion object - -} - -/** - * @suppress - */ -public object FfiConverterTypeNode: FfiConverter { - - override fun lower(value: Node): Pointer { - return value.uniffiClonePointer() - } - - override fun lift(value: Pointer): Node { - return Node(value) - } - - override fun read(buf: ByteBuffer): Node { - // The Rust code always writes pointers as 8 bytes, and will - // fail to compile if they don't fit. - return lift(Pointer(buf.getLong())) - } - - override fun allocationSize(value: Node) = 8UL - - override fun write(value: Node, buf: ByteBuffer) { - // The Rust code always expects pointers written as 8 bytes, - // and will fail to compile if they don't fit. - buf.putLong(Pointer.nativeValue(lower(value))) - } -} - - -// This template implements a class for working with a Rust struct via a Pointer/Arc -// to the live Rust struct on the other side of the FFI. -// -// Each instance implements core operations for working with the Rust `Arc` and the -// Kotlin Pointer to work with the live Rust struct on the other side of the FFI. -// -// There's some subtlety here, because we have to be careful not to operate on a Rust -// struct after it has been dropped, and because we must expose a public API for freeing -// theq Kotlin wrapper object in lieu of reliable finalizers. The core requirements are: -// -// * Each instance holds an opaque pointer to the underlying Rust struct. -// Method calls need to read this pointer from the object's state and pass it in to -// the Rust FFI. -// -// * When an instance is no longer needed, its pointer should be passed to a -// special destructor function provided by the Rust FFI, which will drop the -// underlying Rust struct. -// -// * Given an instance, calling code is expected to call the special -// `destroy` method in order to free it after use, either by calling it explicitly -// or by using a higher-level helper like the `use` method. Failing to do so risks -// leaking the underlying Rust struct. -// -// * We can't assume that calling code will do the right thing, and must be prepared -// to handle Kotlin method calls executing concurrently with or even after a call to -// `destroy`, and to handle multiple (possibly concurrent!) calls to `destroy`. -// -// * We must never allow Rust code to operate on the underlying Rust struct after -// the destructor has been called, and must never call the destructor more than once. -// Doing so may trigger memory unsafety. -// -// * To mitigate many of the risks of leaking memory and use-after-free unsafety, a `Cleaner` -// is implemented to call the destructor when the Kotlin object becomes unreachable. -// This is done in a background thread. This is not a panacea, and client code should be aware that -// 1. the thread may starve if some there are objects that have poorly performing -// `drop` methods or do significant work in their `drop` methods. -// 2. the thread is shared across the whole library. This can be tuned by using `android_cleaner = true`, -// or `android = true` in the [`kotlin` section of the `uniffi.toml` file](https://mozilla.github.io/uniffi-rs/kotlin/configuration.html). -// -// If we try to implement this with mutual exclusion on access to the pointer, there is the -// possibility of a race between a method call and a concurrent call to `destroy`: -// -// * Thread A starts a method call, reads the value of the pointer, but is interrupted -// before it can pass the pointer over the FFI to Rust. -// * Thread B calls `destroy` and frees the underlying Rust struct. -// * Thread A resumes, passing the already-read pointer value to Rust and triggering -// a use-after-free. -// -// One possible solution would be to use a `ReadWriteLock`, with each method call taking -// a read lock (and thus allowed to run concurrently) and the special `destroy` method -// taking a write lock (and thus blocking on live method calls). However, we aim not to -// generate methods with any hidden blocking semantics, and a `destroy` method that might -// block if called incorrectly seems to meet that bar. -// -// So, we achieve our goals by giving each instance an associated `AtomicLong` counter to track -// the number of in-flight method calls, and an `AtomicBoolean` flag to indicate whether `destroy` -// has been called. These are updated according to the following rules: -// -// * The initial value of the counter is 1, indicating a live object with no in-flight calls. -// The initial value for the flag is false. -// -// * At the start of each method call, we atomically check the counter. -// If it is 0 then the underlying Rust struct has already been destroyed and the call is aborted. -// If it is nonzero them we atomically increment it by 1 and proceed with the method call. -// -// * At the end of each method call, we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// * When `destroy` is called, we atomically flip the flag from false to true. -// If the flag was already true we silently fail. -// Otherwise we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// Astute readers may observe that this all sounds very similar to the way that Rust's `Arc` works, -// and indeed it is, with the addition of a flag to guard against multiple calls to `destroy`. -// -// The overall effect is that the underlying Rust struct is destroyed only when `destroy` has been -// called *and* all in-flight method calls have completed, avoiding violating any of the expectations -// of the underlying Rust code. -// -// This makes a cleaner a better alternative to _not_ calling `destroy()` as -// and when the object is finished with, but the abstraction is not perfect: if the Rust object's `drop` -// method is slow, and/or there are many objects to cleanup, and it's on a low end Android device, then the cleaner -// thread may be starved, and the app will leak memory. -// -// In this case, `destroy`ing manually may be a better solution. -// -// The cleaner can live side by side with the manual calling of `destroy`. In the order of responsiveness, uniffi objects -// with Rust peers are reclaimed: -// -// 1. By calling the `destroy` method of the object, which calls `rustObject.free()`. If that doesn't happen: -// 2. When the object becomes unreachable, AND the Cleaner thread gets to call `rustObject.free()`. If the thread is starved then: -// 3. The memory is reclaimed when the process terminates. -// -// [1] https://stackoverflow.com/questions/24376768/can-java-finalize-an-object-when-it-is-still-in-scope/24380219 -// - - -/** - * Configurable Node construction. See module docs. - * - * All fields are immutable after construction. Each `with_*` setter - * returns a fresh `Arc` that shares ownership of any - * previously-installed modifiers via `Arc`. No interior - * mutability, no locks — the builder is a value, not a state - * machine. - */ -public interface NodeBuilderInterface { - - /** - * Connect to an existing node using saved credentials and return - * a connected Node with any configured modifiers applied. - * - * If `mnemonic` is `Some(...)`, the SDK spawns a signer for the - * connected Node. If `None`, the Node is signerless and signing - * happens elsewhere (paired device, CLN node's local signer, - * hardware signer). - */ - fun `connect`(`credentials`: kotlin.ByteArray, `mnemonic`: kotlin.String?): Node - - /** - * Recover credentials for an existing node and return a - * connected Node with any configured modifiers applied. - * - * `mnemonic` is required — recovery drives the signer to - * authenticate. - */ - fun `recover`(`mnemonic`: kotlin.String): Node - - /** - * Register a new Greenlight node and return a connected Node - * with the SDK signer running and any configured modifiers - * applied. - * - * `mnemonic` is required — registration drives the signer to - * sign the registration challenge, so the SDK must hold the - * seed for this call. - */ - fun `register`(`mnemonic`: kotlin.String, `inviteCode`: kotlin.String?): Node - - /** - * Try to recover; if the node doesn't exist, register a new one. - * - * `mnemonic` is required — both recover and register drive the - * signer. - */ - fun `registerOrRecover`(`mnemonic`: kotlin.String, `inviteCode`: kotlin.String?): Node - - /** - * Install a node event listener. Events fire from the moment the - * gRPC stream is established by the build call (`register` / - * `recover` / `connect` / …), so attach the listener via the - * builder rather than after the fact to capture events from the - * very first moment. - * - * Returns a new builder that shares the rest of the - * configuration. Build calls on the returned builder will - * install the listener; the original builder is unchanged. - */ - fun `withEventListener`(`listener`: NodeEventListener): NodeBuilder - - companion object -} - -/** - * Configurable Node construction. See module docs. - * - * All fields are immutable after construction. Each `with_*` setter - * returns a fresh `Arc` that shares ownership of any - * previously-installed modifiers via `Arc`. No interior - * mutability, no locks — the builder is a value, not a state - * machine. - */ -open class NodeBuilder: Disposable, AutoCloseable, NodeBuilderInterface -{ - - constructor(pointer: Pointer) { - this.pointer = pointer - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - - /** - * This constructor can be used to instantiate a fake object. Only used for tests. Any - * attempt to actually use an object constructed this way will fail as there is no - * connected Rust object. - */ - @Suppress("UNUSED_PARAMETER") - constructor(noPointer: NoPointer) { - this.pointer = null - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - /** - * Create a builder for a Node with `config`. No I/O happens - * until you call `connect` / `register` / `recover` / - * `register_or_recover`. - */ - constructor(`config`: Config) : - this( - uniffiRustCall() { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_constructor_nodebuilder_new( - FfiConverterTypeConfig.lower(`config`),_status) -} - ) - - protected val pointer: Pointer? - protected val cleanable: UniffiCleaner.Cleanable - - private val wasDestroyed = AtomicBoolean(false) - private val callCounter = AtomicLong(1) - - override fun destroy() { - // Only allow a single call to this method. - // TODO: maybe we should log a warning if called more than once? - if (this.wasDestroyed.compareAndSet(false, true)) { - // This decrement always matches the initial count of 1 given at creation time. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - @Synchronized - override fun close() { - this.destroy() - } - - internal inline fun callWithPointer(block: (ptr: Pointer) -> R): R { - // Check and increment the call counter, to keep the object alive. - // This needs a compare-and-set retry loop in case of concurrent updates. - do { - val c = this.callCounter.get() - if (c == 0L) { - throw IllegalStateException("${this.javaClass.simpleName} object has already been destroyed") - } - if (c == Long.MAX_VALUE) { - throw IllegalStateException("${this.javaClass.simpleName} call counter would overflow") - } - } while (! this.callCounter.compareAndSet(c, c + 1L)) - // Now we can safely do the method call without the pointer being freed concurrently. - try { - return block(this.uniffiClonePointer()) - } finally { - // This decrement always matches the increment we performed above. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - // Use a static inner class instead of a closure so as not to accidentally - // capture `this` as part of the cleanable's action. - private class UniffiCleanAction(private val pointer: Pointer?) : Runnable { - override fun run() { - pointer?.let { ptr -> - uniffiRustCall { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_free_nodebuilder(ptr, status) - } - } - } - } - - fun uniffiClonePointer(): Pointer { - return uniffiRustCall() { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_clone_nodebuilder(pointer!!, status) - } - } - - - /** - * Connect to an existing node using saved credentials and return - * a connected Node with any configured modifiers applied. - * - * If `mnemonic` is `Some(...)`, the SDK spawns a signer for the - * connected Node. If `None`, the Node is signerless and signing - * happens elsewhere (paired device, CLN node's local signer, - * hardware signer). - */ - @Throws(Exception::class)override fun `connect`(`credentials`: kotlin.ByteArray, `mnemonic`: kotlin.String?): Node { - return FfiConverterTypeNode.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_nodebuilder_connect( - it, FfiConverterByteArray.lower(`credentials`),FfiConverterOptionalString.lower(`mnemonic`),_status) -} - } - ) - } - - - - /** - * Recover credentials for an existing node and return a - * connected Node with any configured modifiers applied. - * - * `mnemonic` is required — recovery drives the signer to - * authenticate. - */ - @Throws(Exception::class)override fun `recover`(`mnemonic`: kotlin.String): Node { - return FfiConverterTypeNode.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_nodebuilder_recover( - it, FfiConverterString.lower(`mnemonic`),_status) -} - } - ) - } - - - - /** - * Register a new Greenlight node and return a connected Node - * with the SDK signer running and any configured modifiers - * applied. - * - * `mnemonic` is required — registration drives the signer to - * sign the registration challenge, so the SDK must hold the - * seed for this call. - */ - @Throws(Exception::class)override fun `register`(`mnemonic`: kotlin.String, `inviteCode`: kotlin.String?): Node { - return FfiConverterTypeNode.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_nodebuilder_register( - it, FfiConverterString.lower(`mnemonic`),FfiConverterOptionalString.lower(`inviteCode`),_status) -} - } - ) - } - - - - /** - * Try to recover; if the node doesn't exist, register a new one. - * - * `mnemonic` is required — both recover and register drive the - * signer. - */ - @Throws(Exception::class)override fun `registerOrRecover`(`mnemonic`: kotlin.String, `inviteCode`: kotlin.String?): Node { - return FfiConverterTypeNode.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_nodebuilder_register_or_recover( - it, FfiConverterString.lower(`mnemonic`),FfiConverterOptionalString.lower(`inviteCode`),_status) -} - } - ) - } - - - - /** - * Install a node event listener. Events fire from the moment the - * gRPC stream is established by the build call (`register` / - * `recover` / `connect` / …), so attach the listener via the - * builder rather than after the fact to capture events from the - * very first moment. - * - * Returns a new builder that shares the rest of the - * configuration. Build calls on the returned builder will - * install the listener; the original builder is unchanged. - */override fun `withEventListener`(`listener`: NodeEventListener): NodeBuilder { - return FfiConverterTypeNodeBuilder.lift( - callWithPointer { - uniffiRustCall() { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_nodebuilder_with_event_listener( - it, FfiConverterTypeNodeEventListener.lower(`listener`),_status) -} - } - ) - } - - - - - - - companion object - -} - -/** - * @suppress - */ -public object FfiConverterTypeNodeBuilder: FfiConverter { - - override fun lower(value: NodeBuilder): Pointer { - return value.uniffiClonePointer() - } - - override fun lift(value: Pointer): NodeBuilder { - return NodeBuilder(value) - } - - override fun read(buf: ByteBuffer): NodeBuilder { - // The Rust code always writes pointers as 8 bytes, and will - // fail to compile if they don't fit. - return lift(Pointer(buf.getLong())) - } - - override fun allocationSize(value: NodeBuilder) = 8UL - - override fun write(value: NodeBuilder, buf: ByteBuffer) { - // The Rust code always expects pointers written as 8 bytes, - // and will fail to compile if they don't fit. - buf.putLong(Pointer.nativeValue(lower(value))) - } -} - - -// This template implements a class for working with a Rust struct via a Pointer/Arc -// to the live Rust struct on the other side of the FFI. -// -// Each instance implements core operations for working with the Rust `Arc` and the -// Kotlin Pointer to work with the live Rust struct on the other side of the FFI. -// -// There's some subtlety here, because we have to be careful not to operate on a Rust -// struct after it has been dropped, and because we must expose a public API for freeing -// theq Kotlin wrapper object in lieu of reliable finalizers. The core requirements are: -// -// * Each instance holds an opaque pointer to the underlying Rust struct. -// Method calls need to read this pointer from the object's state and pass it in to -// the Rust FFI. -// -// * When an instance is no longer needed, its pointer should be passed to a -// special destructor function provided by the Rust FFI, which will drop the -// underlying Rust struct. -// -// * Given an instance, calling code is expected to call the special -// `destroy` method in order to free it after use, either by calling it explicitly -// or by using a higher-level helper like the `use` method. Failing to do so risks -// leaking the underlying Rust struct. -// -// * We can't assume that calling code will do the right thing, and must be prepared -// to handle Kotlin method calls executing concurrently with or even after a call to -// `destroy`, and to handle multiple (possibly concurrent!) calls to `destroy`. -// -// * We must never allow Rust code to operate on the underlying Rust struct after -// the destructor has been called, and must never call the destructor more than once. -// Doing so may trigger memory unsafety. -// -// * To mitigate many of the risks of leaking memory and use-after-free unsafety, a `Cleaner` -// is implemented to call the destructor when the Kotlin object becomes unreachable. -// This is done in a background thread. This is not a panacea, and client code should be aware that -// 1. the thread may starve if some there are objects that have poorly performing -// `drop` methods or do significant work in their `drop` methods. -// 2. the thread is shared across the whole library. This can be tuned by using `android_cleaner = true`, -// or `android = true` in the [`kotlin` section of the `uniffi.toml` file](https://mozilla.github.io/uniffi-rs/kotlin/configuration.html). -// -// If we try to implement this with mutual exclusion on access to the pointer, there is the -// possibility of a race between a method call and a concurrent call to `destroy`: -// -// * Thread A starts a method call, reads the value of the pointer, but is interrupted -// before it can pass the pointer over the FFI to Rust. -// * Thread B calls `destroy` and frees the underlying Rust struct. -// * Thread A resumes, passing the already-read pointer value to Rust and triggering -// a use-after-free. -// -// One possible solution would be to use a `ReadWriteLock`, with each method call taking -// a read lock (and thus allowed to run concurrently) and the special `destroy` method -// taking a write lock (and thus blocking on live method calls). However, we aim not to -// generate methods with any hidden blocking semantics, and a `destroy` method that might -// block if called incorrectly seems to meet that bar. -// -// So, we achieve our goals by giving each instance an associated `AtomicLong` counter to track -// the number of in-flight method calls, and an `AtomicBoolean` flag to indicate whether `destroy` -// has been called. These are updated according to the following rules: -// -// * The initial value of the counter is 1, indicating a live object with no in-flight calls. -// The initial value for the flag is false. -// -// * At the start of each method call, we atomically check the counter. -// If it is 0 then the underlying Rust struct has already been destroyed and the call is aborted. -// If it is nonzero them we atomically increment it by 1 and proceed with the method call. -// -// * At the end of each method call, we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// * When `destroy` is called, we atomically flip the flag from false to true. -// If the flag was already true we silently fail. -// Otherwise we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// Astute readers may observe that this all sounds very similar to the way that Rust's `Arc` works, -// and indeed it is, with the addition of a flag to guard against multiple calls to `destroy`. -// -// The overall effect is that the underlying Rust struct is destroyed only when `destroy` has been -// called *and* all in-flight method calls have completed, avoiding violating any of the expectations -// of the underlying Rust code. -// -// This makes a cleaner a better alternative to _not_ calling `destroy()` as -// and when the object is finished with, but the abstraction is not perfect: if the Rust object's `drop` -// method is slow, and/or there are many objects to cleanup, and it's on a low end Android device, then the cleaner -// thread may be starved, and the app will leak memory. -// -// In this case, `destroy`ing manually may be a better solution. -// -// The cleaner can live side by side with the manual calling of `destroy`. In the order of responsiveness, uniffi objects -// with Rust peers are reclaimed: -// -// 1. By calling the `destroy` method of the object, which calls `rustObject.free()`. If that doesn't happen: -// 2. When the object becomes unreachable, AND the Cleaner thread gets to call `rustObject.free()`. If the thread is starved then: -// 3. The memory is reclaimed when the process terminates. -// -// [1] https://stackoverflow.com/questions/24376768/can-java-finalize-an-object-when-it-is-still-in-scope/24380219 -// - - -/** - * A stream of node events. Call `next()` to receive the next event. - * - * The stream is backed by a gRPC streaming connection to the node. - * Each call to `next()` blocks the calling thread until an event is - * available, but does not block the tokio runtime - other node - * operations can proceed concurrently from other threads. - */ -public interface NodeEventStreamInterface { - - /** - * Get the next event from the stream. - * - * Blocks the calling thread until an event is available or the - * stream ends. Returns `None` when the stream is exhausted or - * the connection is lost. - */ - fun `next`(): NodeEvent? - - companion object -} - -/** - * A stream of node events. Call `next()` to receive the next event. - * - * The stream is backed by a gRPC streaming connection to the node. - * Each call to `next()` blocks the calling thread until an event is - * available, but does not block the tokio runtime - other node - * operations can proceed concurrently from other threads. - */ -open class NodeEventStream: Disposable, AutoCloseable, NodeEventStreamInterface -{ - - constructor(pointer: Pointer) { - this.pointer = pointer - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - - /** - * This constructor can be used to instantiate a fake object. Only used for tests. Any - * attempt to actually use an object constructed this way will fail as there is no - * connected Rust object. - */ - @Suppress("UNUSED_PARAMETER") - constructor(noPointer: NoPointer) { - this.pointer = null - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - - protected val pointer: Pointer? - protected val cleanable: UniffiCleaner.Cleanable - - private val wasDestroyed = AtomicBoolean(false) - private val callCounter = AtomicLong(1) - - override fun destroy() { - // Only allow a single call to this method. - // TODO: maybe we should log a warning if called more than once? - if (this.wasDestroyed.compareAndSet(false, true)) { - // This decrement always matches the initial count of 1 given at creation time. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - @Synchronized - override fun close() { - this.destroy() - } - - internal inline fun callWithPointer(block: (ptr: Pointer) -> R): R { - // Check and increment the call counter, to keep the object alive. - // This needs a compare-and-set retry loop in case of concurrent updates. - do { - val c = this.callCounter.get() - if (c == 0L) { - throw IllegalStateException("${this.javaClass.simpleName} object has already been destroyed") - } - if (c == Long.MAX_VALUE) { - throw IllegalStateException("${this.javaClass.simpleName} call counter would overflow") - } - } while (! this.callCounter.compareAndSet(c, c + 1L)) - // Now we can safely do the method call without the pointer being freed concurrently. - try { - return block(this.uniffiClonePointer()) - } finally { - // This decrement always matches the increment we performed above. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - // Use a static inner class instead of a closure so as not to accidentally - // capture `this` as part of the cleanable's action. - private class UniffiCleanAction(private val pointer: Pointer?) : Runnable { - override fun run() { - pointer?.let { ptr -> - uniffiRustCall { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_free_nodeeventstream(ptr, status) - } - } - } - } - - fun uniffiClonePointer(): Pointer { - return uniffiRustCall() { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_clone_nodeeventstream(pointer!!, status) - } - } - - - /** - * Get the next event from the stream. - * - * Blocks the calling thread until an event is available or the - * stream ends. Returns `None` when the stream is exhausted or - * the connection is lost. - */ - @Throws(Exception::class)override fun `next`(): NodeEvent? { - return FfiConverterOptionalTypeNodeEvent.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_nodeeventstream_next( - it, _status) -} - } - ) - } - - - - - - - companion object - -} - -/** - * @suppress - */ -public object FfiConverterTypeNodeEventStream: FfiConverter { - - override fun lower(value: NodeEventStream): Pointer { - return value.uniffiClonePointer() - } - - override fun lift(value: Pointer): NodeEventStream { - return NodeEventStream(value) - } - - override fun read(buf: ByteBuffer): NodeEventStream { - // The Rust code always writes pointers as 8 bytes, and will - // fail to compile if they don't fit. - return lift(Pointer(buf.getLong())) - } - - override fun allocationSize(value: NodeEventStream) = 8UL - - override fun write(value: NodeEventStream, buf: ByteBuffer) { - // The Rust code always expects pointers written as 8 bytes, - // and will fail to compile if they don't fit. - buf.putLong(Pointer.nativeValue(lower(value))) - } -} - - -// This template implements a class for working with a Rust struct via a Pointer/Arc -// to the live Rust struct on the other side of the FFI. -// -// Each instance implements core operations for working with the Rust `Arc` and the -// Kotlin Pointer to work with the live Rust struct on the other side of the FFI. -// -// There's some subtlety here, because we have to be careful not to operate on a Rust -// struct after it has been dropped, and because we must expose a public API for freeing -// theq Kotlin wrapper object in lieu of reliable finalizers. The core requirements are: -// -// * Each instance holds an opaque pointer to the underlying Rust struct. -// Method calls need to read this pointer from the object's state and pass it in to -// the Rust FFI. -// -// * When an instance is no longer needed, its pointer should be passed to a -// special destructor function provided by the Rust FFI, which will drop the -// underlying Rust struct. -// -// * Given an instance, calling code is expected to call the special -// `destroy` method in order to free it after use, either by calling it explicitly -// or by using a higher-level helper like the `use` method. Failing to do so risks -// leaking the underlying Rust struct. -// -// * We can't assume that calling code will do the right thing, and must be prepared -// to handle Kotlin method calls executing concurrently with or even after a call to -// `destroy`, and to handle multiple (possibly concurrent!) calls to `destroy`. -// -// * We must never allow Rust code to operate on the underlying Rust struct after -// the destructor has been called, and must never call the destructor more than once. -// Doing so may trigger memory unsafety. -// -// * To mitigate many of the risks of leaking memory and use-after-free unsafety, a `Cleaner` -// is implemented to call the destructor when the Kotlin object becomes unreachable. -// This is done in a background thread. This is not a panacea, and client code should be aware that -// 1. the thread may starve if some there are objects that have poorly performing -// `drop` methods or do significant work in their `drop` methods. -// 2. the thread is shared across the whole library. This can be tuned by using `android_cleaner = true`, -// or `android = true` in the [`kotlin` section of the `uniffi.toml` file](https://mozilla.github.io/uniffi-rs/kotlin/configuration.html). -// -// If we try to implement this with mutual exclusion on access to the pointer, there is the -// possibility of a race between a method call and a concurrent call to `destroy`: -// -// * Thread A starts a method call, reads the value of the pointer, but is interrupted -// before it can pass the pointer over the FFI to Rust. -// * Thread B calls `destroy` and frees the underlying Rust struct. -// * Thread A resumes, passing the already-read pointer value to Rust and triggering -// a use-after-free. -// -// One possible solution would be to use a `ReadWriteLock`, with each method call taking -// a read lock (and thus allowed to run concurrently) and the special `destroy` method -// taking a write lock (and thus blocking on live method calls). However, we aim not to -// generate methods with any hidden blocking semantics, and a `destroy` method that might -// block if called incorrectly seems to meet that bar. -// -// So, we achieve our goals by giving each instance an associated `AtomicLong` counter to track -// the number of in-flight method calls, and an `AtomicBoolean` flag to indicate whether `destroy` -// has been called. These are updated according to the following rules: -// -// * The initial value of the counter is 1, indicating a live object with no in-flight calls. -// The initial value for the flag is false. -// -// * At the start of each method call, we atomically check the counter. -// If it is 0 then the underlying Rust struct has already been destroyed and the call is aborted. -// If it is nonzero them we atomically increment it by 1 and proceed with the method call. -// -// * At the end of each method call, we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// * When `destroy` is called, we atomically flip the flag from false to true. -// If the flag was already true we silently fail. -// Otherwise we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// Astute readers may observe that this all sounds very similar to the way that Rust's `Arc` works, -// and indeed it is, with the addition of a flag to guard against multiple calls to `destroy`. -// -// The overall effect is that the underlying Rust struct is destroyed only when `destroy` has been -// called *and* all in-flight method calls have completed, avoiding violating any of the expectations -// of the underlying Rust code. -// -// This makes a cleaner a better alternative to _not_ calling `destroy()` as -// and when the object is finished with, but the abstraction is not perfect: if the Rust object's `drop` -// method is slow, and/or there are many objects to cleanup, and it's on a low end Android device, then the cleaner -// thread may be starved, and the app will leak memory. -// -// In this case, `destroy`ing manually may be a better solution. -// -// The cleaner can live side by side with the manual calling of `destroy`. In the order of responsiveness, uniffi objects -// with Rust peers are reclaimed: -// -// 1. By calling the `destroy` method of the object, which calls `rustObject.free()`. If that doesn't happen: -// 2. When the object becomes unreachable, AND the Cleaner thread gets to call `rustObject.free()`. If the thread is starved then: -// 3. The memory is reclaimed when the process terminates. -// -// [1] https://stackoverflow.com/questions/24376768/can-java-finalize-an-object-when-it-is-still-in-scope/24380219 -// - - -public interface SchedulerInterface { - - /** - * Asks whether the Lightning account backed by `node_id` may be - * surfaced to the user. - * - * This is a feature gate for applications that offer Lightning - * alongside other account types. Greenlight relays the question - * to its Lightning Service Provider, which answers based on - * whether it has previously granted this node a slot, or has the - * capacity to grant one now. - * - * Deliberately callable before `register()`, since an - * application has to decide whether to offer Lightning at all - * before it creates a node. It needs no credentials, and the - * `node_id` is passed explicitly. - * - * The answer is advisory and may change over time. Treat an - * error as "unknown" rather than as a negative answer. - */ - fun `lightningAvailable`(`nodeId`: kotlin.ByteArray): kotlin.Boolean - - fun `recover`(`signer`: Signer): Credentials - - fun `register`(`signer`: Signer, `code`: kotlin.String?): Credentials - - /** - * Configure a developer certificate obtained from the Greenlight - * Developer Console. Nodes registered through this scheduler - * will be associated with the developer's account. - * - * Returns a new `Scheduler` instance with the developer - * certificate configured. - */ - fun `withDeveloperCert`(`cert`: DeveloperCert): Scheduler - - companion object -} - -open class Scheduler: Disposable, AutoCloseable, SchedulerInterface -{ - - constructor(pointer: Pointer) { - this.pointer = pointer - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - - /** - * This constructor can be used to instantiate a fake object. Only used for tests. Any - * attempt to actually use an object constructed this way will fail as there is no - * connected Rust object. - */ - @Suppress("UNUSED_PARAMETER") - constructor(noPointer: NoPointer) { - this.pointer = null - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - /** - * Create a `Scheduler` instance configured with the Greenlight - * production service pre-configured. - */ - constructor(`network`: Network) : - this( - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_constructor_scheduler_new( - FfiConverterTypeNetwork.lower(`network`),_status) -} - ) - - protected val pointer: Pointer? - protected val cleanable: UniffiCleaner.Cleanable - - private val wasDestroyed = AtomicBoolean(false) - private val callCounter = AtomicLong(1) - - override fun destroy() { - // Only allow a single call to this method. - // TODO: maybe we should log a warning if called more than once? - if (this.wasDestroyed.compareAndSet(false, true)) { - // This decrement always matches the initial count of 1 given at creation time. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - @Synchronized - override fun close() { - this.destroy() - } - - internal inline fun callWithPointer(block: (ptr: Pointer) -> R): R { - // Check and increment the call counter, to keep the object alive. - // This needs a compare-and-set retry loop in case of concurrent updates. - do { - val c = this.callCounter.get() - if (c == 0L) { - throw IllegalStateException("${this.javaClass.simpleName} object has already been destroyed") - } - if (c == Long.MAX_VALUE) { - throw IllegalStateException("${this.javaClass.simpleName} call counter would overflow") - } - } while (! this.callCounter.compareAndSet(c, c + 1L)) - // Now we can safely do the method call without the pointer being freed concurrently. - try { - return block(this.uniffiClonePointer()) - } finally { - // This decrement always matches the increment we performed above. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - // Use a static inner class instead of a closure so as not to accidentally - // capture `this` as part of the cleanable's action. - private class UniffiCleanAction(private val pointer: Pointer?) : Runnable { - override fun run() { - pointer?.let { ptr -> - uniffiRustCall { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_free_scheduler(ptr, status) - } - } - } - } - - fun uniffiClonePointer(): Pointer { - return uniffiRustCall() { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_clone_scheduler(pointer!!, status) - } - } - - - /** - * Asks whether the Lightning account backed by `node_id` may be - * surfaced to the user. - * - * This is a feature gate for applications that offer Lightning - * alongside other account types. Greenlight relays the question - * to its Lightning Service Provider, which answers based on - * whether it has previously granted this node a slot, or has the - * capacity to grant one now. - * - * Deliberately callable before `register()`, since an - * application has to decide whether to offer Lightning at all - * before it creates a node. It needs no credentials, and the - * `node_id` is passed explicitly. - * - * The answer is advisory and may change over time. Treat an - * error as "unknown" rather than as a negative answer. - */ - @Throws(Exception::class)override fun `lightningAvailable`(`nodeId`: kotlin.ByteArray): kotlin.Boolean { - return FfiConverterBoolean.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_scheduler_lightning_available( - it, FfiConverterByteArray.lower(`nodeId`),_status) -} - } - ) - } - - - - @Throws(Exception::class)override fun `recover`(`signer`: Signer): Credentials { - return FfiConverterTypeCredentials.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_scheduler_recover( - it, FfiConverterTypeSigner.lower(`signer`),_status) -} - } - ) - } - - - - @Throws(Exception::class)override fun `register`(`signer`: Signer, `code`: kotlin.String?): Credentials { - return FfiConverterTypeCredentials.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_scheduler_register( - it, FfiConverterTypeSigner.lower(`signer`),FfiConverterOptionalString.lower(`code`),_status) -} - } - ) - } - - - - /** - * Configure a developer certificate obtained from the Greenlight - * Developer Console. Nodes registered through this scheduler - * will be associated with the developer's account. - * - * Returns a new `Scheduler` instance with the developer - * certificate configured. - */override fun `withDeveloperCert`(`cert`: DeveloperCert): Scheduler { - return FfiConverterTypeScheduler.lift( - callWithPointer { - uniffiRustCall() { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_scheduler_with_developer_cert( - it, FfiConverterTypeDeveloperCert.lower(`cert`),_status) -} - } - ) - } - - - - - - - companion object - -} - -/** - * @suppress - */ -public object FfiConverterTypeScheduler: FfiConverter { - - override fun lower(value: Scheduler): Pointer { - return value.uniffiClonePointer() - } - - override fun lift(value: Pointer): Scheduler { - return Scheduler(value) - } - - override fun read(buf: ByteBuffer): Scheduler { - // The Rust code always writes pointers as 8 bytes, and will - // fail to compile if they don't fit. - return lift(Pointer(buf.getLong())) - } - - override fun allocationSize(value: Scheduler) = 8UL - - override fun write(value: Scheduler, buf: ByteBuffer) { - // The Rust code always expects pointers written as 8 bytes, - // and will fail to compile if they don't fit. - buf.putLong(Pointer.nativeValue(lower(value))) - } -} - - -// This template implements a class for working with a Rust struct via a Pointer/Arc -// to the live Rust struct on the other side of the FFI. -// -// Each instance implements core operations for working with the Rust `Arc` and the -// Kotlin Pointer to work with the live Rust struct on the other side of the FFI. -// -// There's some subtlety here, because we have to be careful not to operate on a Rust -// struct after it has been dropped, and because we must expose a public API for freeing -// theq Kotlin wrapper object in lieu of reliable finalizers. The core requirements are: -// -// * Each instance holds an opaque pointer to the underlying Rust struct. -// Method calls need to read this pointer from the object's state and pass it in to -// the Rust FFI. -// -// * When an instance is no longer needed, its pointer should be passed to a -// special destructor function provided by the Rust FFI, which will drop the -// underlying Rust struct. -// -// * Given an instance, calling code is expected to call the special -// `destroy` method in order to free it after use, either by calling it explicitly -// or by using a higher-level helper like the `use` method. Failing to do so risks -// leaking the underlying Rust struct. -// -// * We can't assume that calling code will do the right thing, and must be prepared -// to handle Kotlin method calls executing concurrently with or even after a call to -// `destroy`, and to handle multiple (possibly concurrent!) calls to `destroy`. -// -// * We must never allow Rust code to operate on the underlying Rust struct after -// the destructor has been called, and must never call the destructor more than once. -// Doing so may trigger memory unsafety. -// -// * To mitigate many of the risks of leaking memory and use-after-free unsafety, a `Cleaner` -// is implemented to call the destructor when the Kotlin object becomes unreachable. -// This is done in a background thread. This is not a panacea, and client code should be aware that -// 1. the thread may starve if some there are objects that have poorly performing -// `drop` methods or do significant work in their `drop` methods. -// 2. the thread is shared across the whole library. This can be tuned by using `android_cleaner = true`, -// or `android = true` in the [`kotlin` section of the `uniffi.toml` file](https://mozilla.github.io/uniffi-rs/kotlin/configuration.html). -// -// If we try to implement this with mutual exclusion on access to the pointer, there is the -// possibility of a race between a method call and a concurrent call to `destroy`: -// -// * Thread A starts a method call, reads the value of the pointer, but is interrupted -// before it can pass the pointer over the FFI to Rust. -// * Thread B calls `destroy` and frees the underlying Rust struct. -// * Thread A resumes, passing the already-read pointer value to Rust and triggering -// a use-after-free. -// -// One possible solution would be to use a `ReadWriteLock`, with each method call taking -// a read lock (and thus allowed to run concurrently) and the special `destroy` method -// taking a write lock (and thus blocking on live method calls). However, we aim not to -// generate methods with any hidden blocking semantics, and a `destroy` method that might -// block if called incorrectly seems to meet that bar. -// -// So, we achieve our goals by giving each instance an associated `AtomicLong` counter to track -// the number of in-flight method calls, and an `AtomicBoolean` flag to indicate whether `destroy` -// has been called. These are updated according to the following rules: -// -// * The initial value of the counter is 1, indicating a live object with no in-flight calls. -// The initial value for the flag is false. -// -// * At the start of each method call, we atomically check the counter. -// If it is 0 then the underlying Rust struct has already been destroyed and the call is aborted. -// If it is nonzero them we atomically increment it by 1 and proceed with the method call. -// -// * At the end of each method call, we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// * When `destroy` is called, we atomically flip the flag from false to true. -// If the flag was already true we silently fail. -// Otherwise we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// Astute readers may observe that this all sounds very similar to the way that Rust's `Arc` works, -// and indeed it is, with the addition of a flag to guard against multiple calls to `destroy`. -// -// The overall effect is that the underlying Rust struct is destroyed only when `destroy` has been -// called *and* all in-flight method calls have completed, avoiding violating any of the expectations -// of the underlying Rust code. -// -// This makes a cleaner a better alternative to _not_ calling `destroy()` as -// and when the object is finished with, but the abstraction is not perfect: if the Rust object's `drop` -// method is slow, and/or there are many objects to cleanup, and it's on a low end Android device, then the cleaner -// thread may be starved, and the app will leak memory. -// -// In this case, `destroy`ing manually may be a better solution. -// -// The cleaner can live side by side with the manual calling of `destroy`. In the order of responsiveness, uniffi objects -// with Rust peers are reclaimed: -// -// 1. By calling the `destroy` method of the object, which calls `rustObject.free()`. If that doesn't happen: -// 2. When the object becomes unreachable, AND the Cleaner thread gets to call `rustObject.free()`. If the thread is starved then: -// 3. The memory is reclaimed when the process terminates. -// -// [1] https://stackoverflow.com/questions/24376768/can-java-finalize-an-object-when-it-is-still-in-scope/24380219 -// - - -public interface SignerInterface { - - fun `authenticate`(`creds`: Credentials): Signer - - fun `nodeId`(): kotlin.ByteArray - - fun `start`(): Handle - - companion object -} - -open class Signer: Disposable, AutoCloseable, SignerInterface -{ - - constructor(pointer: Pointer) { - this.pointer = pointer - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - - /** - * This constructor can be used to instantiate a fake object. Only used for tests. Any - * attempt to actually use an object constructed this way will fail as there is no - * connected Rust object. - */ - @Suppress("UNUSED_PARAMETER") - constructor(noPointer: NoPointer) { - this.pointer = null - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - constructor(`phrase`: kotlin.String) : - this( - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_constructor_signer_new( - FfiConverterString.lower(`phrase`),_status) -} - ) - - protected val pointer: Pointer? - protected val cleanable: UniffiCleaner.Cleanable - - private val wasDestroyed = AtomicBoolean(false) - private val callCounter = AtomicLong(1) - - override fun destroy() { - // Only allow a single call to this method. - // TODO: maybe we should log a warning if called more than once? - if (this.wasDestroyed.compareAndSet(false, true)) { - // This decrement always matches the initial count of 1 given at creation time. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - @Synchronized - override fun close() { - this.destroy() - } - - internal inline fun callWithPointer(block: (ptr: Pointer) -> R): R { - // Check and increment the call counter, to keep the object alive. - // This needs a compare-and-set retry loop in case of concurrent updates. - do { - val c = this.callCounter.get() - if (c == 0L) { - throw IllegalStateException("${this.javaClass.simpleName} object has already been destroyed") - } - if (c == Long.MAX_VALUE) { - throw IllegalStateException("${this.javaClass.simpleName} call counter would overflow") - } - } while (! this.callCounter.compareAndSet(c, c + 1L)) - // Now we can safely do the method call without the pointer being freed concurrently. - try { - return block(this.uniffiClonePointer()) - } finally { - // This decrement always matches the increment we performed above. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - // Use a static inner class instead of a closure so as not to accidentally - // capture `this` as part of the cleanable's action. - private class UniffiCleanAction(private val pointer: Pointer?) : Runnable { - override fun run() { - pointer?.let { ptr -> - uniffiRustCall { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_free_signer(ptr, status) - } - } - } - } - - fun uniffiClonePointer(): Pointer { - return uniffiRustCall() { status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_clone_signer(pointer!!, status) - } - } - - - @Throws(Exception::class)override fun `authenticate`(`creds`: Credentials): Signer { - return FfiConverterTypeSigner.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_signer_authenticate( - it, FfiConverterTypeCredentials.lower(`creds`),_status) -} - } - ) - } - - - override fun `nodeId`(): kotlin.ByteArray { - return FfiConverterByteArray.lift( - callWithPointer { - uniffiRustCall() { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_signer_node_id( - it, _status) -} - } - ) - } - - - - @Throws(Exception::class)override fun `start`(): Handle { - return FfiConverterTypeHandle.lift( - callWithPointer { - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_method_signer_start( - it, _status) -} - } - ) - } - - - - - - companion object { - - @Throws(Exception::class) fun `newFromSeed`(`seed`: kotlin.ByteArray): Signer { - return FfiConverterTypeSigner.lift( - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_constructor_signer_new_from_seed( - FfiConverterByteArray.lower(`seed`),_status) -} - ) - } - - - - } - -} - -/** - * @suppress - */ -public object FfiConverterTypeSigner: FfiConverter { - - override fun lower(value: Signer): Pointer { - return value.uniffiClonePointer() - } - - override fun lift(value: Pointer): Signer { - return Signer(value) - } - - override fun read(buf: ByteBuffer): Signer { - // The Rust code always writes pointers as 8 bytes, and will - // fail to compile if they don't fit. - return lift(Pointer(buf.getLong())) - } - - override fun allocationSize(value: Signer) = 8UL - - override fun write(value: Signer, buf: ByteBuffer) { - // The Rust code always expects pointers written as 8 bytes, - // and will fail to compile if they don't fit. - buf.putLong(Pointer.nativeValue(lower(value))) - } -} - - - -data class FundChannel ( - /** - * Peer node public key as lowercase hex (66 chars). - */ - var `peerId`: kotlin.String, - var `ourAmountMsat`: kotlin.ULong, - var `amountMsat`: kotlin.ULong, - /** - * Funding transaction id as lowercase hex (64 chars). - */ - var `fundingTxid`: kotlin.String, - var `fundingOutput`: kotlin.UInt, - var `connected`: kotlin.Boolean, - var `state`: ChannelState, - var `shortChannelId`: kotlin.String?, - /** - * Channel id as lowercase hex (64 chars). - */ - var `channelId`: kotlin.String? -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeFundChannel: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): FundChannel { - return FundChannel( - FfiConverterString.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterString.read(buf), - FfiConverterUInt.read(buf), - FfiConverterBoolean.read(buf), - FfiConverterTypeChannelState.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalString.read(buf), - ) - } - - override fun allocationSize(value: FundChannel) = ( - FfiConverterString.allocationSize(value.`peerId`) + - FfiConverterULong.allocationSize(value.`ourAmountMsat`) + - FfiConverterULong.allocationSize(value.`amountMsat`) + - FfiConverterString.allocationSize(value.`fundingTxid`) + - FfiConverterUInt.allocationSize(value.`fundingOutput`) + - FfiConverterBoolean.allocationSize(value.`connected`) + - FfiConverterTypeChannelState.allocationSize(value.`state`) + - FfiConverterOptionalString.allocationSize(value.`shortChannelId`) + - FfiConverterOptionalString.allocationSize(value.`channelId`) - ) - - override fun write(value: FundChannel, buf: ByteBuffer) { - FfiConverterString.write(value.`peerId`, buf) - FfiConverterULong.write(value.`ourAmountMsat`, buf) - FfiConverterULong.write(value.`amountMsat`, buf) - FfiConverterString.write(value.`fundingTxid`, buf) - FfiConverterUInt.write(value.`fundingOutput`, buf) - FfiConverterBoolean.write(value.`connected`, buf) - FfiConverterTypeChannelState.write(value.`state`, buf) - FfiConverterOptionalString.write(value.`shortChannelId`, buf) - FfiConverterOptionalString.write(value.`channelId`, buf) - } -} - - - -data class FundOutput ( - /** - * Transaction id as lowercase hex (64 chars). - */ - var `txid`: kotlin.String, - var `output`: kotlin.UInt, - var `amountMsat`: kotlin.ULong, - var `status`: OutputStatus, - var `address`: kotlin.String?, - var `blockheight`: kotlin.UInt?, - /** - * True when this UTXO is currently reserved by an in-flight PSBT - * (e.g. a channel-open or fund-send that has not been broadcast or - * abandoned). Reserved UTXOs are not spendable and must be excluded - * from the wallet's spendable balance. - */ - var `reserved`: kotlin.Boolean -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeFundOutput: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): FundOutput { - return FundOutput( - FfiConverterString.read(buf), - FfiConverterUInt.read(buf), - FfiConverterULong.read(buf), - FfiConverterTypeOutputStatus.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalUInt.read(buf), - FfiConverterBoolean.read(buf), - ) - } - - override fun allocationSize(value: FundOutput) = ( - FfiConverterString.allocationSize(value.`txid`) + - FfiConverterUInt.allocationSize(value.`output`) + - FfiConverterULong.allocationSize(value.`amountMsat`) + - FfiConverterTypeOutputStatus.allocationSize(value.`status`) + - FfiConverterOptionalString.allocationSize(value.`address`) + - FfiConverterOptionalUInt.allocationSize(value.`blockheight`) + - FfiConverterBoolean.allocationSize(value.`reserved`) - ) - - override fun write(value: FundOutput, buf: ByteBuffer) { - FfiConverterString.write(value.`txid`, buf) - FfiConverterUInt.write(value.`output`, buf) - FfiConverterULong.write(value.`amountMsat`, buf) - FfiConverterTypeOutputStatus.write(value.`status`, buf) - FfiConverterOptionalString.write(value.`address`, buf) - FfiConverterOptionalUInt.write(value.`blockheight`, buf) - FfiConverterBoolean.write(value.`reserved`, buf) - } -} - - - -data class GetInfoResponse ( - /** - * Node public key as lowercase hex (66 chars). - */ - var `id`: kotlin.String, - var `alias`: kotlin.String?, - /** - * 3-byte RGB color as lowercase hex (6 chars). - */ - var `color`: kotlin.String, - var `numPeers`: kotlin.UInt, - var `numPendingChannels`: kotlin.UInt, - var `numActiveChannels`: kotlin.UInt, - var `numInactiveChannels`: kotlin.UInt, - var `version`: kotlin.String, - var `lightningDir`: kotlin.String, - var `blockheight`: kotlin.UInt, - var `network`: kotlin.String, - var `feesCollectedMsat`: kotlin.ULong -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeGetInfoResponse: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): GetInfoResponse { - return GetInfoResponse( - FfiConverterString.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterString.read(buf), - FfiConverterUInt.read(buf), - FfiConverterUInt.read(buf), - FfiConverterUInt.read(buf), - FfiConverterUInt.read(buf), - FfiConverterString.read(buf), - FfiConverterString.read(buf), - FfiConverterUInt.read(buf), - FfiConverterString.read(buf), - FfiConverterULong.read(buf), - ) - } - - override fun allocationSize(value: GetInfoResponse) = ( - FfiConverterString.allocationSize(value.`id`) + - FfiConverterOptionalString.allocationSize(value.`alias`) + - FfiConverterString.allocationSize(value.`color`) + - FfiConverterUInt.allocationSize(value.`numPeers`) + - FfiConverterUInt.allocationSize(value.`numPendingChannels`) + - FfiConverterUInt.allocationSize(value.`numActiveChannels`) + - FfiConverterUInt.allocationSize(value.`numInactiveChannels`) + - FfiConverterString.allocationSize(value.`version`) + - FfiConverterString.allocationSize(value.`lightningDir`) + - FfiConverterUInt.allocationSize(value.`blockheight`) + - FfiConverterString.allocationSize(value.`network`) + - FfiConverterULong.allocationSize(value.`feesCollectedMsat`) - ) - - override fun write(value: GetInfoResponse, buf: ByteBuffer) { - FfiConverterString.write(value.`id`, buf) - FfiConverterOptionalString.write(value.`alias`, buf) - FfiConverterString.write(value.`color`, buf) - FfiConverterUInt.write(value.`numPeers`, buf) - FfiConverterUInt.write(value.`numPendingChannels`, buf) - FfiConverterUInt.write(value.`numActiveChannels`, buf) - FfiConverterUInt.write(value.`numInactiveChannels`, buf) - FfiConverterString.write(value.`version`, buf) - FfiConverterString.write(value.`lightningDir`, buf) - FfiConverterUInt.write(value.`blockheight`, buf) - FfiConverterString.write(value.`network`, buf) - FfiConverterULong.write(value.`feesCollectedMsat`, buf) - } -} - - - -data class Invoice ( - var `label`: kotlin.String, - var `description`: kotlin.String, - /** - * Payment hash as lowercase hex (64 chars). - */ - var `paymentHash`: kotlin.String, - var `status`: InvoiceStatus, - var `amountMsat`: kotlin.ULong?, - var `amountReceivedMsat`: kotlin.ULong?, - var `bolt11`: kotlin.String?, - var `bolt12`: kotlin.String?, - var `paidAt`: kotlin.ULong?, - var `expiresAt`: kotlin.ULong, - /** - * Payment preimage as lowercase hex (64 chars), if the invoice has been paid. - */ - var `paymentPreimage`: kotlin.String?, - /** - * Recipient node pubkey as lowercase hex (66 chars), recovered from the bolt11. - */ - var `destinationPubkey`: kotlin.String? -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeInvoice: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): Invoice { - return Invoice( - FfiConverterString.read(buf), - FfiConverterString.read(buf), - FfiConverterString.read(buf), - FfiConverterTypeInvoiceStatus.read(buf), - FfiConverterOptionalULong.read(buf), - FfiConverterOptionalULong.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalString.read(buf), - ) - } - - override fun allocationSize(value: Invoice) = ( - FfiConverterString.allocationSize(value.`label`) + - FfiConverterString.allocationSize(value.`description`) + - FfiConverterString.allocationSize(value.`paymentHash`) + - FfiConverterTypeInvoiceStatus.allocationSize(value.`status`) + - FfiConverterOptionalULong.allocationSize(value.`amountMsat`) + - FfiConverterOptionalULong.allocationSize(value.`amountReceivedMsat`) + - FfiConverterOptionalString.allocationSize(value.`bolt11`) + - FfiConverterOptionalString.allocationSize(value.`bolt12`) + - FfiConverterOptionalULong.allocationSize(value.`paidAt`) + - FfiConverterULong.allocationSize(value.`expiresAt`) + - FfiConverterOptionalString.allocationSize(value.`paymentPreimage`) + - FfiConverterOptionalString.allocationSize(value.`destinationPubkey`) - ) - - override fun write(value: Invoice, buf: ByteBuffer) { - FfiConverterString.write(value.`label`, buf) - FfiConverterString.write(value.`description`, buf) - FfiConverterString.write(value.`paymentHash`, buf) - FfiConverterTypeInvoiceStatus.write(value.`status`, buf) - FfiConverterOptionalULong.write(value.`amountMsat`, buf) - FfiConverterOptionalULong.write(value.`amountReceivedMsat`, buf) - FfiConverterOptionalString.write(value.`bolt11`, buf) - FfiConverterOptionalString.write(value.`bolt12`, buf) - FfiConverterOptionalULong.write(value.`paidAt`, buf) - FfiConverterULong.write(value.`expiresAt`, buf) - FfiConverterOptionalString.write(value.`paymentPreimage`, buf) - FfiConverterOptionalString.write(value.`destinationPubkey`, buf) - } -} - - - -/** - * Details of a paid invoice. - */ -data class InvoicePaidEvent ( - /** - * Payment hash of the paid invoice as lowercase hex (64 chars). - */ - var `paymentHash`: kotlin.String, - /** - * The bolt11 invoice string. - */ - var `bolt11`: kotlin.String, - /** - * Preimage that proves payment as lowercase hex (64 chars). - */ - var `preimage`: kotlin.String, - /** - * The label assigned to the invoice. - */ - var `label`: kotlin.String, - /** - * Amount received in millisatoshis. - */ - var `amountMsat`: kotlin.ULong -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeInvoicePaidEvent: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): InvoicePaidEvent { - return InvoicePaidEvent( - FfiConverterString.read(buf), - FfiConverterString.read(buf), - FfiConverterString.read(buf), - FfiConverterString.read(buf), - FfiConverterULong.read(buf), - ) - } - - override fun allocationSize(value: InvoicePaidEvent) = ( - FfiConverterString.allocationSize(value.`paymentHash`) + - FfiConverterString.allocationSize(value.`bolt11`) + - FfiConverterString.allocationSize(value.`preimage`) + - FfiConverterString.allocationSize(value.`label`) + - FfiConverterULong.allocationSize(value.`amountMsat`) - ) - - override fun write(value: InvoicePaidEvent, buf: ByteBuffer) { - FfiConverterString.write(value.`paymentHash`, buf) - FfiConverterString.write(value.`bolt11`, buf) - FfiConverterString.write(value.`preimage`, buf) - FfiConverterString.write(value.`label`, buf) - FfiConverterULong.write(value.`amountMsat`, buf) - } -} - - - -data class ListFundsResponse ( - var `outputs`: List, - var `channels`: List -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeListFundsResponse: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): ListFundsResponse { - return ListFundsResponse( - FfiConverterSequenceTypeFundOutput.read(buf), - FfiConverterSequenceTypeFundChannel.read(buf), - ) - } - - override fun allocationSize(value: ListFundsResponse) = ( - FfiConverterSequenceTypeFundOutput.allocationSize(value.`outputs`) + - FfiConverterSequenceTypeFundChannel.allocationSize(value.`channels`) - ) - - override fun write(value: ListFundsResponse, buf: ByteBuffer) { - FfiConverterSequenceTypeFundOutput.write(value.`outputs`, buf) - FfiConverterSequenceTypeFundChannel.write(value.`channels`, buf) - } -} - - - -data class ListInvoicesResponse ( - var `invoices`: List -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeListInvoicesResponse: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): ListInvoicesResponse { - return ListInvoicesResponse( - FfiConverterSequenceTypeInvoice.read(buf), - ) - } - - override fun allocationSize(value: ListInvoicesResponse) = ( - FfiConverterSequenceTypeInvoice.allocationSize(value.`invoices`) - ) - - override fun write(value: ListInvoicesResponse, buf: ByteBuffer) { - FfiConverterSequenceTypeInvoice.write(value.`invoices`, buf) - } -} - - - -data class ListPaymentsRequest ( - /** - * Filter by payment type (Sent, Received). None or empty = all. - */ - var `filters`: List?, - /** - * Include only payments after this epoch timestamp (seconds). - */ - var `fromTimestamp`: kotlin.ULong?, - /** - * Include only payments before this epoch timestamp (seconds). - */ - var `toTimestamp`: kotlin.ULong?, - /** - * Include failed payments. Default: false. - */ - var `includeFailures`: kotlin.Boolean?, - /** - * Pagination offset. - */ - var `offset`: kotlin.UInt?, - /** - * Pagination limit. - */ - var `limit`: kotlin.UInt? -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeListPaymentsRequest: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): ListPaymentsRequest { - return ListPaymentsRequest( - FfiConverterOptionalSequenceTypePaymentTypeFilter.read(buf), - FfiConverterOptionalULong.read(buf), - FfiConverterOptionalULong.read(buf), - FfiConverterOptionalBoolean.read(buf), - FfiConverterOptionalUInt.read(buf), - FfiConverterOptionalUInt.read(buf), - ) - } - - override fun allocationSize(value: ListPaymentsRequest) = ( - FfiConverterOptionalSequenceTypePaymentTypeFilter.allocationSize(value.`filters`) + - FfiConverterOptionalULong.allocationSize(value.`fromTimestamp`) + - FfiConverterOptionalULong.allocationSize(value.`toTimestamp`) + - FfiConverterOptionalBoolean.allocationSize(value.`includeFailures`) + - FfiConverterOptionalUInt.allocationSize(value.`offset`) + - FfiConverterOptionalUInt.allocationSize(value.`limit`) - ) - - override fun write(value: ListPaymentsRequest, buf: ByteBuffer) { - FfiConverterOptionalSequenceTypePaymentTypeFilter.write(value.`filters`, buf) - FfiConverterOptionalULong.write(value.`fromTimestamp`, buf) - FfiConverterOptionalULong.write(value.`toTimestamp`, buf) - FfiConverterOptionalBoolean.write(value.`includeFailures`, buf) - FfiConverterOptionalUInt.write(value.`offset`, buf) - FfiConverterOptionalUInt.write(value.`limit`, buf) - } -} - - - -data class ListPaysResponse ( - var `pays`: List -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeListPaysResponse: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): ListPaysResponse { - return ListPaysResponse( - FfiConverterSequenceTypePay.read(buf), - ) - } - - override fun allocationSize(value: ListPaysResponse) = ( - FfiConverterSequenceTypePay.allocationSize(value.`pays`) - ) - - override fun write(value: ListPaysResponse, buf: ByteBuffer) { - FfiConverterSequenceTypePay.write(value.`pays`, buf) - } -} - - - -data class ListPeerChannelsResponse ( - var `channels`: List -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeListPeerChannelsResponse: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): ListPeerChannelsResponse { - return ListPeerChannelsResponse( - FfiConverterSequenceTypePeerChannel.read(buf), - ) - } - - override fun allocationSize(value: ListPeerChannelsResponse) = ( - FfiConverterSequenceTypePeerChannel.allocationSize(value.`channels`) - ) - - override fun write(value: ListPeerChannelsResponse, buf: ByteBuffer) { - FfiConverterSequenceTypePeerChannel.write(value.`channels`, buf) - } -} - - - -data class ListPeersResponse ( - var `peers`: List -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeListPeersResponse: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): ListPeersResponse { - return ListPeersResponse( - FfiConverterSequenceTypePeer.read(buf), - ) - } - - override fun allocationSize(value: ListPeersResponse) = ( - FfiConverterSequenceTypePeer.allocationSize(value.`peers`) - ) - - override fun write(value: ListPeersResponse, buf: ByteBuffer) { - FfiConverterSequenceTypePeer.write(value.`peers`, buf) - } -} - - - -/** - * Error returned by an LNURL service endpoint. - */ -data class LnUrlErrorData ( - var `reason`: kotlin.String -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeLnUrlErrorData: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): LnUrlErrorData { - return LnUrlErrorData( - FfiConverterString.read(buf), - ) - } - - override fun allocationSize(value: LnUrlErrorData) = ( - FfiConverterString.allocationSize(value.`reason`) - ) - - override fun write(value: LnUrlErrorData, buf: ByteBuffer) { - FfiConverterString.write(value.`reason`, buf) - } -} - - - -/** - * Details of a failed LNURL-pay attempt on the pay phase. - */ -data class LnUrlPayErrorData ( - /** - * Hex-encoded payment hash of the invoice the service returned. - */ - var `paymentHash`: kotlin.String, - /** - * Human-readable reason the pay attempt failed. - */ - var `reason`: kotlin.String -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeLnUrlPayErrorData: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): LnUrlPayErrorData { - return LnUrlPayErrorData( - FfiConverterString.read(buf), - FfiConverterString.read(buf), - ) - } - - override fun allocationSize(value: LnUrlPayErrorData) = ( - FfiConverterString.allocationSize(value.`paymentHash`) + - FfiConverterString.allocationSize(value.`reason`) - ) - - override fun write(value: LnUrlPayErrorData, buf: ByteBuffer) { - FfiConverterString.write(value.`paymentHash`, buf) - FfiConverterString.write(value.`reason`, buf) - } -} - - - -/** - * Request to execute an LNURL-pay flow. - * - * Combines the resolved service data with the user's chosen amount. - */ -data class LnUrlPayRequest ( - /** - * The resolved pay request data from `parse_input()`. - */ - var `data`: LnUrlPayRequestData, - /** - * Amount to pay in millisatoshis. - */ - var `amountMsat`: kotlin.ULong, - /** - * Optional comment to send with the payment. - */ - var `comment`: kotlin.String?, - /** - * When true (the default), a URL success action is rejected if its - * domain differs from the callback's domain. - * - * This is a wallet-side safety convention, not a LUD-09 requirement: - * LUD-09 does not mandate same-domain URLs, but a divergent domain - * can be used to phish users, so the SDK rejects it by default. - * Set to `Some(false)` only if you have a specific reason to trust - * cross-domain success-action URLs from this service. - */ - var `validateSuccessActionUrl`: kotlin.Boolean? -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeLnUrlPayRequest: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): LnUrlPayRequest { - return LnUrlPayRequest( - FfiConverterTypeLnUrlPayRequestData.read(buf), - FfiConverterULong.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalBoolean.read(buf), - ) - } - - override fun allocationSize(value: LnUrlPayRequest) = ( - FfiConverterTypeLnUrlPayRequestData.allocationSize(value.`data`) + - FfiConverterULong.allocationSize(value.`amountMsat`) + - FfiConverterOptionalString.allocationSize(value.`comment`) + - FfiConverterOptionalBoolean.allocationSize(value.`validateSuccessActionUrl`) - ) - - override fun write(value: LnUrlPayRequest, buf: ByteBuffer) { - FfiConverterTypeLnUrlPayRequestData.write(value.`data`, buf) - FfiConverterULong.write(value.`amountMsat`, buf) - FfiConverterOptionalString.write(value.`comment`, buf) - FfiConverterOptionalBoolean.write(value.`validateSuccessActionUrl`, buf) - } -} - - - -/** - * Data from an LNURL-pay endpoint (LUD-06). - * - * Contains the service's accepted amount range and metadata. - * Returned inside `InputType::LnUrlPay` after `parse_input` resolves - * an LNURL or Lightning Address. - */ -data class LnUrlPayRequestData ( - /** - * The callback URL to request an invoice from. - */ - var `callback`: kotlin.String, - /** - * Minimum amount the service accepts, in millisatoshis. - */ - var `minSendable`: kotlin.ULong, - /** - * Maximum amount the service accepts, in millisatoshis. - */ - var `maxSendable`: kotlin.ULong, - /** - * Raw metadata JSON string (array of `["mime", "content"]` pairs). - */ - var `metadata`: kotlin.String, - /** - * Maximum comment length the service accepts. 0 means no comments. - */ - var `commentAllowed`: kotlin.ULong, - /** - * Human-readable description extracted from metadata. - */ - var `description`: kotlin.String, - /** - * The original LNURL or lightning address that was resolved. - */ - var `lnurl`: kotlin.String -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeLnUrlPayRequestData: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): LnUrlPayRequestData { - return LnUrlPayRequestData( - FfiConverterString.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterString.read(buf), - FfiConverterULong.read(buf), - FfiConverterString.read(buf), - FfiConverterString.read(buf), - ) - } - - override fun allocationSize(value: LnUrlPayRequestData) = ( - FfiConverterString.allocationSize(value.`callback`) + - FfiConverterULong.allocationSize(value.`minSendable`) + - FfiConverterULong.allocationSize(value.`maxSendable`) + - FfiConverterString.allocationSize(value.`metadata`) + - FfiConverterULong.allocationSize(value.`commentAllowed`) + - FfiConverterString.allocationSize(value.`description`) + - FfiConverterString.allocationSize(value.`lnurl`) - ) - - override fun write(value: LnUrlPayRequestData, buf: ByteBuffer) { - FfiConverterString.write(value.`callback`, buf) - FfiConverterULong.write(value.`minSendable`, buf) - FfiConverterULong.write(value.`maxSendable`, buf) - FfiConverterString.write(value.`metadata`, buf) - FfiConverterULong.write(value.`commentAllowed`, buf) - FfiConverterString.write(value.`description`, buf) - FfiConverterString.write(value.`lnurl`, buf) - } -} - - - -/** - * Successful LNURL-pay result data. - */ -data class LnUrlPaySuccessData ( - /** - * The payment preimage (proof of payment), hex-encoded. - */ - var `paymentPreimage`: kotlin.String, - /** - * Optional success action from the service (LUD-09). - */ - var `successAction`: SuccessActionProcessed? -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeLnUrlPaySuccessData: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): LnUrlPaySuccessData { - return LnUrlPaySuccessData( - FfiConverterString.read(buf), - FfiConverterOptionalTypeSuccessActionProcessed.read(buf), - ) - } - - override fun allocationSize(value: LnUrlPaySuccessData) = ( - FfiConverterString.allocationSize(value.`paymentPreimage`) + - FfiConverterOptionalTypeSuccessActionProcessed.allocationSize(value.`successAction`) - ) - - override fun write(value: LnUrlPaySuccessData, buf: ByteBuffer) { - FfiConverterString.write(value.`paymentPreimage`, buf) - FfiConverterOptionalTypeSuccessActionProcessed.write(value.`successAction`, buf) - } -} - - - -/** - * Request to execute an LNURL-withdraw flow. - * - * Combines the resolved service data with the user's chosen amount. - */ -data class LnUrlWithdrawRequest ( - /** - * The resolved withdraw request data from `parse_input()`. - */ - var `data`: LnUrlWithdrawRequestData, - /** - * Amount to withdraw in millisatoshis. - */ - var `amountMsat`: kotlin.ULong, - /** - * Optional description for the invoice (overrides default). - */ - var `description`: kotlin.String? -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeLnUrlWithdrawRequest: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): LnUrlWithdrawRequest { - return LnUrlWithdrawRequest( - FfiConverterTypeLnUrlWithdrawRequestData.read(buf), - FfiConverterULong.read(buf), - FfiConverterOptionalString.read(buf), - ) - } - - override fun allocationSize(value: LnUrlWithdrawRequest) = ( - FfiConverterTypeLnUrlWithdrawRequestData.allocationSize(value.`data`) + - FfiConverterULong.allocationSize(value.`amountMsat`) + - FfiConverterOptionalString.allocationSize(value.`description`) - ) - - override fun write(value: LnUrlWithdrawRequest, buf: ByteBuffer) { - FfiConverterTypeLnUrlWithdrawRequestData.write(value.`data`, buf) - FfiConverterULong.write(value.`amountMsat`, buf) - FfiConverterOptionalString.write(value.`description`, buf) - } -} - - - -/** - * Data from an LNURL-withdraw endpoint (LUD-03). - * - * Contains the service's accepted withdrawal range and session key. - * Returned inside `InputType::LnUrlWithdraw` after `parse_input` - * resolves an LNURL. - */ -data class LnUrlWithdrawRequestData ( - /** - * The callback URL to submit the invoice to. - */ - var `callback`: kotlin.String, - /** - * Ephemeral secret linking this wallet session to the service. - */ - var `k1`: kotlin.String, - /** - * Default description for the invoice. - */ - var `defaultDescription`: kotlin.String, - /** - * Minimum withdrawable amount in millisatoshis. - */ - var `minWithdrawable`: kotlin.ULong, - /** - * Maximum withdrawable amount in millisatoshis. - */ - var `maxWithdrawable`: kotlin.ULong, - /** - * The original LNURL that was resolved. - */ - var `lnurl`: kotlin.String -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeLnUrlWithdrawRequestData: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): LnUrlWithdrawRequestData { - return LnUrlWithdrawRequestData( - FfiConverterString.read(buf), - FfiConverterString.read(buf), - FfiConverterString.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterString.read(buf), - ) - } - - override fun allocationSize(value: LnUrlWithdrawRequestData) = ( - FfiConverterString.allocationSize(value.`callback`) + - FfiConverterString.allocationSize(value.`k1`) + - FfiConverterString.allocationSize(value.`defaultDescription`) + - FfiConverterULong.allocationSize(value.`minWithdrawable`) + - FfiConverterULong.allocationSize(value.`maxWithdrawable`) + - FfiConverterString.allocationSize(value.`lnurl`) - ) - - override fun write(value: LnUrlWithdrawRequestData, buf: ByteBuffer) { - FfiConverterString.write(value.`callback`, buf) - FfiConverterString.write(value.`k1`, buf) - FfiConverterString.write(value.`defaultDescription`, buf) - FfiConverterULong.write(value.`minWithdrawable`, buf) - FfiConverterULong.write(value.`maxWithdrawable`, buf) - FfiConverterString.write(value.`lnurl`, buf) - } -} - - - -/** - * Successful LNURL-withdraw result data. - */ -data class LnUrlWithdrawSuccessData ( - /** - * The BOLT11 invoice that was submitted for withdrawal. - */ - var `invoice`: kotlin.String -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeLnUrlWithdrawSuccessData: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): LnUrlWithdrawSuccessData { - return LnUrlWithdrawSuccessData( - FfiConverterString.read(buf), - ) - } - - override fun allocationSize(value: LnUrlWithdrawSuccessData) = ( - FfiConverterString.allocationSize(value.`invoice`) - ) - - override fun write(value: LnUrlWithdrawSuccessData, buf: ByteBuffer) { - FfiConverterString.write(value.`invoice`, buf) - } -} - - - -/** - * A single log message from the SDK. - */ -data class LogEntry ( - var `level`: LogLevel, - var `message`: kotlin.String, - /** - * The module that produced this log (e.g. "gl_client::scheduler"). - */ - var `target`: kotlin.String, - /** - * Source file path, if the log macro recorded one. - */ - var `file`: kotlin.String?, - /** - * Source line number, if the log macro recorded one. - */ - var `line`: kotlin.UInt? -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeLogEntry: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): LogEntry { - return LogEntry( - FfiConverterTypeLogLevel.read(buf), - FfiConverterString.read(buf), - FfiConverterString.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalUInt.read(buf), - ) - } - - override fun allocationSize(value: LogEntry) = ( - FfiConverterTypeLogLevel.allocationSize(value.`level`) + - FfiConverterString.allocationSize(value.`message`) + - FfiConverterString.allocationSize(value.`target`) + - FfiConverterOptionalString.allocationSize(value.`file`) + - FfiConverterOptionalUInt.allocationSize(value.`line`) - ) - - override fun write(value: LogEntry, buf: ByteBuffer) { - FfiConverterTypeLogLevel.write(value.`level`, buf) - FfiConverterString.write(value.`message`, buf) - FfiConverterString.write(value.`target`, buf) - FfiConverterOptionalString.write(value.`file`, buf) - FfiConverterOptionalUInt.write(value.`line`, buf) - } -} - - - -/** - * A point-in-time snapshot of the node's balances, capacity, and - * connectivity. Returned by `node_state()`. - * - * All amounts are in millisatoshis (1 sat = 1000 msat). - */ -data class NodeState ( - /** - * The node's public key as a lowercase hex string (66 chars). - */ - var `id`: kotlin.String, - /** - * Latest block height the node has synced to. - */ - var `blockHeight`: kotlin.UInt, - /** - * The Bitcoin network this node is running on (e.g. "bitcoin", "regtest"). - */ - var `network`: kotlin.String, - /** - * CLN version string (e.g. "v24.11"). - */ - var `version`: kotlin.String, - /** - * Human-readable node alias, if set. - */ - var `alias`: kotlin.String?, - /** - * 3-byte RGB color of the node, as a lowercase hex string (6 chars). - */ - var `color`: kotlin.String, - /** - * Number of channels that are open and operational. These are the - * channels that contribute to `channels_balance_msat`, - * `max_payable_msat`, `total_channel_capacity_msat`, and - * `total_inbound_liquidity_msat`. - */ - var `numActiveChannels`: kotlin.UInt, - /** - * Number of channels that are being opened but not yet confirmed. - * Pending channels do not contribute to any balance or capacity - * field on this snapshot; their funds show up only after they - * transition to active. - */ - var `numPendingChannels`: kotlin.UInt, - /** - * Number of channels that are open but the peer is offline. - * Inactive channels hold balance but cannot be used for payments - * until the peer reconnects; they do not contribute to - * `max_payable_msat` or `total_inbound_liquidity_msat` (those are - * computed from the live `spendable_msat` / `receivable_msat` - * reported by CLN, which goes to zero when the peer is offline). - */ - var `numInactiveChannels`: kotlin.UInt, - /** - * Total our-side balance across all open channels, including amounts - * that protocol reserves make unspendable. - * - * This is the field a wallet's home screen should show as the - * user's "Lightning balance" — it reflects what they own off-chain, - * matching what they'd expect to see at a glance. - * - * Do **not** use this to gate a send button: some of it is locked - * in channel reserves. Use `max_payable_msat` for that. - */ - var `channelsBalanceMsat`: kotlin.ULong, - /** - * Aggregate spendable amount across all open channels. Equal to - * `channels_balance_msat - max_chan_reserve_msat`. - * - * This is the field a send screen should gate against — it is what - * the user can actually move right now over Lightning in total. - * - * Caveat: a single Lightning payment is additionally bounded by - * the largest channel's own `spendable_msat`. Reaching this full - * aggregate amount in one payment requires multi-path-payment - * support from the recipient and a working route. - */ - var `maxPayableMsat`: kotlin.ULong, - /** - * Sum of all open channel capacities (your side + remote side). - */ - var `totalChannelCapacityMsat`: kotlin.ULong, - /** - * Amount locked in protocol channel reserves, computed as - * `channels_balance_msat - max_payable_msat`. These sats are yours - * on paper but cannot be spent until the channel closes. - */ - var `maxChanReserveMsat`: kotlin.ULong, - /** - * Confirmed on-chain balance available for spending or opening channels. - */ - var `onchainBalanceMsat`: kotlin.ULong, - /** - * On-chain balance from transactions that have not yet been confirmed. - */ - var `unconfirmedOnchainBalanceMsat`: kotlin.ULong, - /** - * On-chain balance confirmed but not yet spendable (e.g. coinbase - * outputs inside the 100-block maturation window). - */ - var `immatureOnchainBalanceMsat`: kotlin.ULong, - /** - * On-chain balance locked in channels that are being closed. - * These funds will become available once the close is confirmed. - */ - var `pendingOnchainBalanceMsat`: kotlin.ULong, - /** - * Largest single Lightning payment the node can receive without - * splitting across channels. Bounded by the inbound capacity of - * the largest open channel. - */ - var `maxReceivableSinglePaymentMsat`: kotlin.ULong, - /** - * Total amount you can receive across all open channels combined. - */ - var `totalInboundLiquidityMsat`: kotlin.ULong, - /** - * Lowercase hex public keys of peers we have at least one channel - * with and are currently connected to. Peers we're connected to but - * have no channel with are not represented here; for routing-node - * use cases, query `list_peers()` directly. - */ - var `connectedChannelPeers`: List, - /** - * Unspent on-chain outputs owned by the node's wallet. Excludes - * spent outputs; includes confirmed, unconfirmed, immature, and - * reserved UTXOs (callers can filter by `status` and `reserved`). - */ - var `utxos`: List, - /** - * All non-pending on-chain balance buckets summed: - * `onchain_balance_msat + unconfirmed_onchain_balance_msat + immature_onchain_balance_msat`. - * Excludes funds locked in closing channels (`pending_onchain_balance_msat`) - * since those are not yet on-chain UTXOs. - */ - var `totalOnchainMsat`: kotlin.ULong, - /** - * Everything the user owns, summed: channel balance (including - * protocol reserves) + all on-chain buckets + funds locked in - * closing channels. The "total holdings" number a wallet home - * screen typically shows. - */ - var `totalBalanceMsat`: kotlin.ULong, - /** - * What the user can spend *right now*: - * `max_payable_msat + onchain_balance_msat`. Excludes reserves, - * unconfirmed, immature, and pending amounts. The number a - * send-money screen should gate against. - */ - var `spendableBalanceMsat`: kotlin.ULong -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeNodeState: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): NodeState { - return NodeState( - FfiConverterString.read(buf), - FfiConverterUInt.read(buf), - FfiConverterString.read(buf), - FfiConverterString.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterString.read(buf), - FfiConverterUInt.read(buf), - FfiConverterUInt.read(buf), - FfiConverterUInt.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterSequenceString.read(buf), - FfiConverterSequenceTypeFundOutput.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - ) - } - - override fun allocationSize(value: NodeState) = ( - FfiConverterString.allocationSize(value.`id`) + - FfiConverterUInt.allocationSize(value.`blockHeight`) + - FfiConverterString.allocationSize(value.`network`) + - FfiConverterString.allocationSize(value.`version`) + - FfiConverterOptionalString.allocationSize(value.`alias`) + - FfiConverterString.allocationSize(value.`color`) + - FfiConverterUInt.allocationSize(value.`numActiveChannels`) + - FfiConverterUInt.allocationSize(value.`numPendingChannels`) + - FfiConverterUInt.allocationSize(value.`numInactiveChannels`) + - FfiConverterULong.allocationSize(value.`channelsBalanceMsat`) + - FfiConverterULong.allocationSize(value.`maxPayableMsat`) + - FfiConverterULong.allocationSize(value.`totalChannelCapacityMsat`) + - FfiConverterULong.allocationSize(value.`maxChanReserveMsat`) + - FfiConverterULong.allocationSize(value.`onchainBalanceMsat`) + - FfiConverterULong.allocationSize(value.`unconfirmedOnchainBalanceMsat`) + - FfiConverterULong.allocationSize(value.`immatureOnchainBalanceMsat`) + - FfiConverterULong.allocationSize(value.`pendingOnchainBalanceMsat`) + - FfiConverterULong.allocationSize(value.`maxReceivableSinglePaymentMsat`) + - FfiConverterULong.allocationSize(value.`totalInboundLiquidityMsat`) + - FfiConverterSequenceString.allocationSize(value.`connectedChannelPeers`) + - FfiConverterSequenceTypeFundOutput.allocationSize(value.`utxos`) + - FfiConverterULong.allocationSize(value.`totalOnchainMsat`) + - FfiConverterULong.allocationSize(value.`totalBalanceMsat`) + - FfiConverterULong.allocationSize(value.`spendableBalanceMsat`) - ) - - override fun write(value: NodeState, buf: ByteBuffer) { - FfiConverterString.write(value.`id`, buf) - FfiConverterUInt.write(value.`blockHeight`, buf) - FfiConverterString.write(value.`network`, buf) - FfiConverterString.write(value.`version`, buf) - FfiConverterOptionalString.write(value.`alias`, buf) - FfiConverterString.write(value.`color`, buf) - FfiConverterUInt.write(value.`numActiveChannels`, buf) - FfiConverterUInt.write(value.`numPendingChannels`, buf) - FfiConverterUInt.write(value.`numInactiveChannels`, buf) - FfiConverterULong.write(value.`channelsBalanceMsat`, buf) - FfiConverterULong.write(value.`maxPayableMsat`, buf) - FfiConverterULong.write(value.`totalChannelCapacityMsat`, buf) - FfiConverterULong.write(value.`maxChanReserveMsat`, buf) - FfiConverterULong.write(value.`onchainBalanceMsat`, buf) - FfiConverterULong.write(value.`unconfirmedOnchainBalanceMsat`, buf) - FfiConverterULong.write(value.`immatureOnchainBalanceMsat`, buf) - FfiConverterULong.write(value.`pendingOnchainBalanceMsat`, buf) - FfiConverterULong.write(value.`maxReceivableSinglePaymentMsat`, buf) - FfiConverterULong.write(value.`totalInboundLiquidityMsat`, buf) - FfiConverterSequenceString.write(value.`connectedChannelPeers`, buf) - FfiConverterSequenceTypeFundOutput.write(value.`utxos`, buf) - FfiConverterULong.write(value.`totalOnchainMsat`, buf) - FfiConverterULong.write(value.`totalBalanceMsat`, buf) - FfiConverterULong.write(value.`spendableBalanceMsat`, buf) - } -} - - - -/** - * On-chain fee rates in sats per virtual byte at various - * confirmation targets, derived from the connected node's view of - * network mempool conditions. Use as the basis for a fee-picker UI. - */ -data class OnchainFeeRates ( - /** - * Target the next block (~10 min). - */ - var `nextBlockSatPerVbyte`: kotlin.ULong, - /** - * ~30 minute confirmation target (3 blocks). - */ - var `halfHourSatPerVbyte`: kotlin.ULong, - /** - * ~1 hour confirmation target (6 blocks). - */ - var `hourSatPerVbyte`: kotlin.ULong, - /** - * ~1 day confirmation target (144 blocks). Suitable for - * non-urgent sweeps. - */ - var `daySatPerVbyte`: kotlin.ULong, - /** - * Network minimum relay fee. Anything below this will be - * rejected by mempool policy at broadcast time. Use as the - * lower bound of any user-facing fee slider. - */ - var `minimumRelaySatPerVbyte`: kotlin.ULong -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeOnchainFeeRates: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): OnchainFeeRates { - return OnchainFeeRates( - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - ) - } - - override fun allocationSize(value: OnchainFeeRates) = ( - FfiConverterULong.allocationSize(value.`nextBlockSatPerVbyte`) + - FfiConverterULong.allocationSize(value.`halfHourSatPerVbyte`) + - FfiConverterULong.allocationSize(value.`hourSatPerVbyte`) + - FfiConverterULong.allocationSize(value.`daySatPerVbyte`) + - FfiConverterULong.allocationSize(value.`minimumRelaySatPerVbyte`) - ) - - override fun write(value: OnchainFeeRates, buf: ByteBuffer) { - FfiConverterULong.write(value.`nextBlockSatPerVbyte`, buf) - FfiConverterULong.write(value.`halfHourSatPerVbyte`, buf) - FfiConverterULong.write(value.`hourSatPerVbyte`, buf) - FfiConverterULong.write(value.`daySatPerVbyte`, buf) - FfiConverterULong.write(value.`minimumRelaySatPerVbyte`, buf) - } -} - - - -/** - * A pair of on-chain addresses for receiving funds. - */ -data class OnchainReceiveResponse ( - /** - * SegWit v0 (bech32) address — starts with `bc1q` on mainnet. - */ - var `bech32`: kotlin.String, - /** - * Taproot (bech32m) address — starts with `bc1p` on mainnet. - */ - var `p2tr`: kotlin.String -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeOnchainReceiveResponse: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): OnchainReceiveResponse { - return OnchainReceiveResponse( - FfiConverterString.read(buf), - FfiConverterString.read(buf), - ) - } - - override fun allocationSize(value: OnchainReceiveResponse) = ( - FfiConverterString.allocationSize(value.`bech32`) + - FfiConverterString.allocationSize(value.`p2tr`) - ) - - override fun write(value: OnchainReceiveResponse, buf: ByteBuffer) { - FfiConverterString.write(value.`bech32`, buf) - FfiConverterString.write(value.`p2tr`, buf) - } -} - - - -/** - * Result of an on-chain send. The transaction has already been broadcast. - */ -data class OnchainSendResponse ( - /** - * The raw signed transaction bytes. - */ - var `tx`: kotlin.ByteArray, - /** - * The transaction id as lowercase hex (64 chars). - */ - var `txid`: kotlin.String, - /** - * The transaction as a Partially Signed Bitcoin Transaction string. - */ - var `psbt`: kotlin.String -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeOnchainSendResponse: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): OnchainSendResponse { - return OnchainSendResponse( - FfiConverterByteArray.read(buf), - FfiConverterString.read(buf), - FfiConverterString.read(buf), - ) - } - - override fun allocationSize(value: OnchainSendResponse) = ( - FfiConverterByteArray.allocationSize(value.`tx`) + - FfiConverterString.allocationSize(value.`txid`) + - FfiConverterString.allocationSize(value.`psbt`) - ) - - override fun write(value: OnchainSendResponse, buf: ByteBuffer) { - FfiConverterByteArray.write(value.`tx`, buf) - FfiConverterString.write(value.`txid`, buf) - FfiConverterString.write(value.`psbt`, buf) - } -} - - - -/** - * A specific on-chain output, identified by its outpoint. - */ -data class Outpoint ( - /** - * Transaction id as lowercase hex (64 chars). - */ - var `txid`: kotlin.String, - /** - * Output index within that transaction. - */ - var `vout`: kotlin.UInt -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeOutpoint: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): Outpoint { - return Outpoint( - FfiConverterString.read(buf), - FfiConverterUInt.read(buf), - ) - } - - override fun allocationSize(value: Outpoint) = ( - FfiConverterString.allocationSize(value.`txid`) + - FfiConverterUInt.allocationSize(value.`vout`) - ) - - override fun write(value: Outpoint, buf: ByteBuffer) { - FfiConverterString.write(value.`txid`, buf) - FfiConverterUInt.write(value.`vout`, buf) - } -} - - - -/** - * Parsed BOLT11 invoice with extracted fields. - */ -data class ParsedInvoice ( - /** - * The original invoice string. - */ - var `bolt11`: kotlin.String, - /** - * Recipient public key as lowercase hex (66 chars), recovered from the invoice signature. - */ - var `payeePubkey`: kotlin.String?, - /** - * Payment hash as lowercase hex (64 chars) identifying this payment. - */ - var `paymentHash`: kotlin.String, - /** - * Invoice description. None if the invoice uses a description hash. - */ - var `description`: kotlin.String?, - /** - * Requested amount in millisatoshis. None for "any amount" invoices. - */ - var `amountMsat`: kotlin.ULong?, - /** - * Seconds from creation until the invoice expires. - */ - var `expiry`: kotlin.ULong, - /** - * Unix timestamp (seconds) when the invoice was created. - */ - var `timestamp`: kotlin.ULong -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeParsedInvoice: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): ParsedInvoice { - return ParsedInvoice( - FfiConverterString.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterString.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - ) - } - - override fun allocationSize(value: ParsedInvoice) = ( - FfiConverterString.allocationSize(value.`bolt11`) + - FfiConverterOptionalString.allocationSize(value.`payeePubkey`) + - FfiConverterString.allocationSize(value.`paymentHash`) + - FfiConverterOptionalString.allocationSize(value.`description`) + - FfiConverterOptionalULong.allocationSize(value.`amountMsat`) + - FfiConverterULong.allocationSize(value.`expiry`) + - FfiConverterULong.allocationSize(value.`timestamp`) - ) - - override fun write(value: ParsedInvoice, buf: ByteBuffer) { - FfiConverterString.write(value.`bolt11`, buf) - FfiConverterOptionalString.write(value.`payeePubkey`, buf) - FfiConverterString.write(value.`paymentHash`, buf) - FfiConverterOptionalString.write(value.`description`, buf) - FfiConverterOptionalULong.write(value.`amountMsat`, buf) - FfiConverterULong.write(value.`expiry`, buf) - FfiConverterULong.write(value.`timestamp`, buf) - } -} - - - -data class Pay ( - /** - * Payment hash as lowercase hex (64 chars). - */ - var `paymentHash`: kotlin.String, - var `status`: PayStatus, - /** - * Recipient node pubkey as lowercase hex (66 chars), if known. - */ - var `destinationPubkey`: kotlin.String?, - var `amountMsat`: kotlin.ULong?, - var `amountSentMsat`: kotlin.ULong?, - var `label`: kotlin.String?, - var `bolt11`: kotlin.String?, - var `description`: kotlin.String?, - var `bolt12`: kotlin.String?, - /** - * Payment preimage as lowercase hex (64 chars), if the payment completed. - */ - var `preimage`: kotlin.String?, - var `createdAt`: kotlin.ULong, - var `completedAt`: kotlin.ULong?, - var `numberOfParts`: kotlin.ULong? -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypePay: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): Pay { - return Pay( - FfiConverterString.read(buf), - FfiConverterTypePayStatus.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalULong.read(buf), - FfiConverterOptionalULong.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterULong.read(buf), - FfiConverterOptionalULong.read(buf), - FfiConverterOptionalULong.read(buf), - ) - } - - override fun allocationSize(value: Pay) = ( - FfiConverterString.allocationSize(value.`paymentHash`) + - FfiConverterTypePayStatus.allocationSize(value.`status`) + - FfiConverterOptionalString.allocationSize(value.`destinationPubkey`) + - FfiConverterOptionalULong.allocationSize(value.`amountMsat`) + - FfiConverterOptionalULong.allocationSize(value.`amountSentMsat`) + - FfiConverterOptionalString.allocationSize(value.`label`) + - FfiConverterOptionalString.allocationSize(value.`bolt11`) + - FfiConverterOptionalString.allocationSize(value.`description`) + - FfiConverterOptionalString.allocationSize(value.`bolt12`) + - FfiConverterOptionalString.allocationSize(value.`preimage`) + - FfiConverterULong.allocationSize(value.`createdAt`) + - FfiConverterOptionalULong.allocationSize(value.`completedAt`) + - FfiConverterOptionalULong.allocationSize(value.`numberOfParts`) - ) - - override fun write(value: Pay, buf: ByteBuffer) { - FfiConverterString.write(value.`paymentHash`, buf) - FfiConverterTypePayStatus.write(value.`status`, buf) - FfiConverterOptionalString.write(value.`destinationPubkey`, buf) - FfiConverterOptionalULong.write(value.`amountMsat`, buf) - FfiConverterOptionalULong.write(value.`amountSentMsat`, buf) - FfiConverterOptionalString.write(value.`label`, buf) - FfiConverterOptionalString.write(value.`bolt11`, buf) - FfiConverterOptionalString.write(value.`description`, buf) - FfiConverterOptionalString.write(value.`bolt12`, buf) - FfiConverterOptionalString.write(value.`preimage`, buf) - FfiConverterULong.write(value.`createdAt`, buf) - FfiConverterOptionalULong.write(value.`completedAt`, buf) - FfiConverterOptionalULong.write(value.`numberOfParts`, buf) - } -} - - - -data class Payment ( - var `id`: kotlin.String, - var `paymentType`: PaymentType, - var `paymentTime`: kotlin.ULong, - var `amountMsat`: kotlin.ULong, - var `feeMsat`: kotlin.ULong, - var `status`: PaymentStatus, - var `description`: kotlin.String?, - var `bolt11`: kotlin.String?, - /** - * Payment preimage as lowercase hex (64 chars), when known. - */ - var `preimage`: kotlin.String?, - /** - * Pubkey of the counterparty in the payment, as lowercase hex - * (66 chars). - * - * For `PaymentType::Sent`: the recipient node we paid (when CLN - * reports it). - * - * For `PaymentType::Received`: always `None`. Lightning's privacy - * model does not reveal the sender's pubkey to the recipient — the - * HTLC arrives via one of our channel peers, but that peer is - * usually just a router, not the original payer. The only pubkey - * derivable from a paid invoice is the *payee* (i.e. our own - * node), which is uninteresting to display per-row. - */ - var `destination`: kotlin.String? -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypePayment: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): Payment { - return Payment( - FfiConverterString.read(buf), - FfiConverterTypePaymentType.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterTypePaymentStatus.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalString.read(buf), - ) - } - - override fun allocationSize(value: Payment) = ( - FfiConverterString.allocationSize(value.`id`) + - FfiConverterTypePaymentType.allocationSize(value.`paymentType`) + - FfiConverterULong.allocationSize(value.`paymentTime`) + - FfiConverterULong.allocationSize(value.`amountMsat`) + - FfiConverterULong.allocationSize(value.`feeMsat`) + - FfiConverterTypePaymentStatus.allocationSize(value.`status`) + - FfiConverterOptionalString.allocationSize(value.`description`) + - FfiConverterOptionalString.allocationSize(value.`bolt11`) + - FfiConverterOptionalString.allocationSize(value.`preimage`) + - FfiConverterOptionalString.allocationSize(value.`destination`) - ) - - override fun write(value: Payment, buf: ByteBuffer) { - FfiConverterString.write(value.`id`, buf) - FfiConverterTypePaymentType.write(value.`paymentType`, buf) - FfiConverterULong.write(value.`paymentTime`, buf) - FfiConverterULong.write(value.`amountMsat`, buf) - FfiConverterULong.write(value.`feeMsat`, buf) - FfiConverterTypePaymentStatus.write(value.`status`, buf) - FfiConverterOptionalString.write(value.`description`, buf) - FfiConverterOptionalString.write(value.`bolt11`, buf) - FfiConverterOptionalString.write(value.`preimage`, buf) - FfiConverterOptionalString.write(value.`destination`, buf) - } -} - - - -data class Peer ( - /** - * Peer node public key as lowercase hex (66 chars). - */ - var `id`: kotlin.String, - var `connected`: kotlin.Boolean, - var `numChannels`: kotlin.UInt?, - var `netaddr`: List, - var `remoteAddr`: kotlin.String?, - var `features`: kotlin.ByteArray? -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypePeer: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): Peer { - return Peer( - FfiConverterString.read(buf), - FfiConverterBoolean.read(buf), - FfiConverterOptionalUInt.read(buf), - FfiConverterSequenceString.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalByteArray.read(buf), - ) - } - - override fun allocationSize(value: Peer) = ( - FfiConverterString.allocationSize(value.`id`) + - FfiConverterBoolean.allocationSize(value.`connected`) + - FfiConverterOptionalUInt.allocationSize(value.`numChannels`) + - FfiConverterSequenceString.allocationSize(value.`netaddr`) + - FfiConverterOptionalString.allocationSize(value.`remoteAddr`) + - FfiConverterOptionalByteArray.allocationSize(value.`features`) - ) - - override fun write(value: Peer, buf: ByteBuffer) { - FfiConverterString.write(value.`id`, buf) - FfiConverterBoolean.write(value.`connected`, buf) - FfiConverterOptionalUInt.write(value.`numChannels`, buf) - FfiConverterSequenceString.write(value.`netaddr`, buf) - FfiConverterOptionalString.write(value.`remoteAddr`, buf) - FfiConverterOptionalByteArray.write(value.`features`, buf) - } -} - - - -data class PeerChannel ( - /** - * Peer node public key as lowercase hex (66 chars). - */ - var `peerId`: kotlin.String, - var `peerConnected`: kotlin.Boolean, - var `state`: ChannelState, - var `shortChannelId`: kotlin.String?, - /** - * Channel id as lowercase hex (64 chars). - */ - var `channelId`: kotlin.String?, - /** - * Funding transaction id as lowercase hex (64 chars). - */ - var `fundingTxid`: kotlin.String?, - var `fundingOutnum`: kotlin.UInt?, - var `toUsMsat`: kotlin.ULong?, - var `totalMsat`: kotlin.ULong?, - var `spendableMsat`: kotlin.ULong?, - var `receivableMsat`: kotlin.ULong?, - /** - * Which side initiated the close, if the channel is closing or closed. - */ - var `closer`: ChannelSide?, - /** - * Human-readable status strings from CLN, ordered oldest to newest. - * For a channel in `Onchain` state, the last entry indicates whether - * our payout is still timelocked (`DELAYED_OUTPUT_TO_US`) or already - * available in the on-chain balance. - */ - var `status`: List -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypePeerChannel: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): PeerChannel { - return PeerChannel( - FfiConverterString.read(buf), - FfiConverterBoolean.read(buf), - FfiConverterTypeChannelState.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterOptionalUInt.read(buf), - FfiConverterOptionalULong.read(buf), - FfiConverterOptionalULong.read(buf), - FfiConverterOptionalULong.read(buf), - FfiConverterOptionalULong.read(buf), - FfiConverterOptionalTypeChannelSide.read(buf), - FfiConverterSequenceString.read(buf), - ) - } - - override fun allocationSize(value: PeerChannel) = ( - FfiConverterString.allocationSize(value.`peerId`) + - FfiConverterBoolean.allocationSize(value.`peerConnected`) + - FfiConverterTypeChannelState.allocationSize(value.`state`) + - FfiConverterOptionalString.allocationSize(value.`shortChannelId`) + - FfiConverterOptionalString.allocationSize(value.`channelId`) + - FfiConverterOptionalString.allocationSize(value.`fundingTxid`) + - FfiConverterOptionalUInt.allocationSize(value.`fundingOutnum`) + - FfiConverterOptionalULong.allocationSize(value.`toUsMsat`) + - FfiConverterOptionalULong.allocationSize(value.`totalMsat`) + - FfiConverterOptionalULong.allocationSize(value.`spendableMsat`) + - FfiConverterOptionalULong.allocationSize(value.`receivableMsat`) + - FfiConverterOptionalTypeChannelSide.allocationSize(value.`closer`) + - FfiConverterSequenceString.allocationSize(value.`status`) - ) - - override fun write(value: PeerChannel, buf: ByteBuffer) { - FfiConverterString.write(value.`peerId`, buf) - FfiConverterBoolean.write(value.`peerConnected`, buf) - FfiConverterTypeChannelState.write(value.`state`, buf) - FfiConverterOptionalString.write(value.`shortChannelId`, buf) - FfiConverterOptionalString.write(value.`channelId`, buf) - FfiConverterOptionalString.write(value.`fundingTxid`, buf) - FfiConverterOptionalUInt.write(value.`fundingOutnum`, buf) - FfiConverterOptionalULong.write(value.`toUsMsat`, buf) - FfiConverterOptionalULong.write(value.`totalMsat`, buf) - FfiConverterOptionalULong.write(value.`spendableMsat`, buf) - FfiConverterOptionalULong.write(value.`receivableMsat`, buf) - FfiConverterOptionalTypeChannelSide.write(value.`closer`, buf) - FfiConverterSequenceString.write(value.`status`, buf) - } -} - - - -/** - * Preview of an on-chain send: the inputs CLN would select at the - * given fee rate, the resulting fee, and the amount the recipient - * would receive. Inputs are NOT reserved — the wallet is free to - * spend them via other paths until `onchain_send` actually broadcasts. - * - * Pass `utxos` and `sat_per_vbyte` back to `onchain_send` to broadcast - * with identical inputs and fee. - * - * Amounts are in satoshis: on-chain transactions cannot carry sub-sat - * precision, so msat denomination would be misleading here. - */ -data class PreparedOnchainSend ( - /** - * UTXOs that would be spent, in selection order. - */ - var `utxos`: List, - /** - * Sum of all input UTXO values, in satoshis. - */ - var `totalInputSat`: kotlin.ULong, - /** - * Fee that would be paid, in satoshis. - */ - var `feeSat`: kotlin.ULong, - /** - * Amount the recipient would receive, in satoshis. - * For a sweep ("all") this equals `total_input_sat - fee_sat`. - * For a fixed amount this equals the requested amount. - */ - var `recipientSat`: kotlin.ULong, - /** - * Effective fee rate (sat per virtual byte) the node used to - * compute this preview. Equal to the caller's `sat_per_vbyte` if - * one was supplied; otherwise the rate the node picked at - * "normal" priority. Pass this back to `onchain_send` to - * reproduce the previewed fee. - */ - var `satPerVbyte`: kotlin.UInt -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypePreparedOnchainSend: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): PreparedOnchainSend { - return PreparedOnchainSend( - FfiConverterSequenceTypeOutpoint.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterUInt.read(buf), - ) - } - - override fun allocationSize(value: PreparedOnchainSend) = ( - FfiConverterSequenceTypeOutpoint.allocationSize(value.`utxos`) + - FfiConverterULong.allocationSize(value.`totalInputSat`) + - FfiConverterULong.allocationSize(value.`feeSat`) + - FfiConverterULong.allocationSize(value.`recipientSat`) + - FfiConverterUInt.allocationSize(value.`satPerVbyte`) - ) - - override fun write(value: PreparedOnchainSend, buf: ByteBuffer) { - FfiConverterSequenceTypeOutpoint.write(value.`utxos`, buf) - FfiConverterULong.write(value.`totalInputSat`, buf) - FfiConverterULong.write(value.`feeSat`, buf) - FfiConverterULong.write(value.`recipientSat`, buf) - FfiConverterUInt.write(value.`satPerVbyte`, buf) - } -} - - - -data class ReceiveResponse ( - var `bolt11`: kotlin.String, - /** - * The fee charged by the LSP for opening a JIT channel, in - * millisatoshi. This is 0 if no JIT channel was needed. - */ - var `openingFeeMsat`: kotlin.ULong -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeReceiveResponse: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): ReceiveResponse { - return ReceiveResponse( - FfiConverterString.read(buf), - FfiConverterULong.read(buf), - ) - } - - override fun allocationSize(value: ReceiveResponse) = ( - FfiConverterString.allocationSize(value.`bolt11`) + - FfiConverterULong.allocationSize(value.`openingFeeMsat`) - ) - - override fun write(value: ReceiveResponse, buf: ByteBuffer) { - FfiConverterString.write(value.`bolt11`, buf) - FfiConverterULong.write(value.`openingFeeMsat`, buf) - } -} - - - -data class SendResponse ( - var `status`: PayStatus, - /** - * Payment preimage (proof of payment) as lowercase hex (64 chars). - */ - var `preimage`: kotlin.String, - /** - * Payment hash as lowercase hex (64 chars). - */ - var `paymentHash`: kotlin.String, - /** - * Recipient node pubkey as lowercase hex (66 chars), if known. - */ - var `destinationPubkey`: kotlin.String?, - var `amountMsat`: kotlin.ULong, - var `amountSentMsat`: kotlin.ULong, - var `parts`: kotlin.UInt -) { - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeSendResponse: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): SendResponse { - return SendResponse( - FfiConverterTypePayStatus.read(buf), - FfiConverterString.read(buf), - FfiConverterString.read(buf), - FfiConverterOptionalString.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterUInt.read(buf), - ) - } - - override fun allocationSize(value: SendResponse) = ( - FfiConverterTypePayStatus.allocationSize(value.`status`) + - FfiConverterString.allocationSize(value.`preimage`) + - FfiConverterString.allocationSize(value.`paymentHash`) + - FfiConverterOptionalString.allocationSize(value.`destinationPubkey`) + - FfiConverterULong.allocationSize(value.`amountMsat`) + - FfiConverterULong.allocationSize(value.`amountSentMsat`) + - FfiConverterUInt.allocationSize(value.`parts`) - ) - - override fun write(value: SendResponse, buf: ByteBuffer) { - FfiConverterTypePayStatus.write(value.`status`, buf) - FfiConverterString.write(value.`preimage`, buf) - FfiConverterString.write(value.`paymentHash`, buf) - FfiConverterOptionalString.write(value.`destinationPubkey`, buf) - FfiConverterULong.write(value.`amountMsat`, buf) - FfiConverterULong.write(value.`amountSentMsat`, buf) - FfiConverterUInt.write(value.`parts`, buf) - } -} - - - -/** - * Which side of a channel performed a given action (e.g. initiated close). - */ - -enum class ChannelSide { - - LOCAL, - REMOTE; - companion object -} - - -/** - * @suppress - */ -public object FfiConverterTypeChannelSide: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer) = try { - ChannelSide.values()[buf.getInt() - 1] - } catch (e: IndexOutOfBoundsException) { - throw RuntimeException("invalid enum value, something is very wrong!!", e) - } - - override fun allocationSize(value: ChannelSide) = 4UL - - override fun write(value: ChannelSide, buf: ByteBuffer) { - buf.putInt(value.ordinal + 1) - } -} - - - - - - -enum class ChannelState { - - OPENINGD, - CHANNELD_AWAITING_LOCKIN, - CHANNELD_NORMAL, - CHANNELD_SHUTTING_DOWN, - CLOSINGD_SIGEXCHANGE, - CLOSINGD_COMPLETE, - AWAITING_UNILATERAL, - FUNDING_SPEND_SEEN, - ONCHAIN, - DUALOPEND_OPEN_INIT, - DUALOPEND_AWAITING_LOCKIN, - DUALOPEND_OPEN_COMMITTED, - DUALOPEND_OPEN_COMMIT_READY, - /** - * A state reported by the node that this SDK doesn't recognize. - * Returned when CLN introduces a new channel state after this SDK - * was built. Treated as neither open nor closing by balance math. - */ - UNKNOWN; - companion object -} - - -/** - * @suppress - */ -public object FfiConverterTypeChannelState: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer) = try { - ChannelState.values()[buf.getInt() - 1] - } catch (e: IndexOutOfBoundsException) { - throw RuntimeException("invalid enum value, something is very wrong!!", e) - } - - override fun allocationSize(value: ChannelState) = 4UL - - override fun write(value: ChannelState, buf: ByteBuffer) { - buf.putInt(value.ordinal + 1) - } -} - - - - - - - -sealed class Exception: kotlin.Exception() { - - class DuplicateNode( - - val `code`: kotlin.Int, - - val `msg`: kotlin.String, - - val `values`: Map - ) : Exception() { - override val message - get() = "code=${ `code` }, msg=${ `msg` }, values=${ `values` }" - } - - class NoSuchNode( - - val `code`: kotlin.Int, - - val `msg`: kotlin.String, - - val `values`: Map - ) : Exception() { - override val message - get() = "code=${ `code` }, msg=${ `msg` }, values=${ `values` }" - } - - class UnparseableCreds( - - val `code`: kotlin.Int, - - val `msg`: kotlin.String, - - val `values`: Map - ) : Exception() { - override val message - get() = "code=${ `code` }, msg=${ `msg` }, values=${ `values` }" - } - - class PhraseCorrupted( - - val `code`: kotlin.Int, - - val `msg`: kotlin.String, - - val `values`: Map - ) : Exception() { - override val message - get() = "code=${ `code` }, msg=${ `msg` }, values=${ `values` }" - } - - class Rpc( - - val `code`: kotlin.Int, - - val `msg`: kotlin.String, - - val `values`: Map - ) : Exception() { - override val message - get() = "code=${ `code` }, msg=${ `msg` }, values=${ `values` }" - } - - class Argument( - - val `code`: kotlin.Int, - - val `msg`: kotlin.String, - - val `values`: Map - ) : Exception() { - override val message - get() = "code=${ `code` }, msg=${ `msg` }, values=${ `values` }" - } - - class Other( - - val `code`: kotlin.Int, - - val `msg`: kotlin.String, - - val `values`: Map - ) : Exception() { - override val message - get() = "code=${ `code` }, msg=${ `msg` }, values=${ `values` }" - } - - - companion object ErrorHandler : UniffiRustCallStatusErrorHandler { - override fun lift(error_buf: RustBuffer.ByValue): Exception = FfiConverterTypeError.lift(error_buf) - } - - -} - -/** - * @suppress - */ -public object FfiConverterTypeError : FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): Exception { - - - return when(buf.getInt()) { - 1 -> Exception.DuplicateNode( - FfiConverterInt.read(buf), - FfiConverterString.read(buf), - FfiConverterMapStringString.read(buf), - ) - 2 -> Exception.NoSuchNode( - FfiConverterInt.read(buf), - FfiConverterString.read(buf), - FfiConverterMapStringString.read(buf), - ) - 3 -> Exception.UnparseableCreds( - FfiConverterInt.read(buf), - FfiConverterString.read(buf), - FfiConverterMapStringString.read(buf), - ) - 4 -> Exception.PhraseCorrupted( - FfiConverterInt.read(buf), - FfiConverterString.read(buf), - FfiConverterMapStringString.read(buf), - ) - 5 -> Exception.Rpc( - FfiConverterInt.read(buf), - FfiConverterString.read(buf), - FfiConverterMapStringString.read(buf), - ) - 6 -> Exception.Argument( - FfiConverterInt.read(buf), - FfiConverterString.read(buf), - FfiConverterMapStringString.read(buf), - ) - 7 -> Exception.Other( - FfiConverterInt.read(buf), - FfiConverterString.read(buf), - FfiConverterMapStringString.read(buf), - ) - else -> throw RuntimeException("invalid error enum value, something is very wrong!!") - } - } - - override fun allocationSize(value: Exception): ULong { - return when(value) { - is Exception.DuplicateNode -> ( - // Add the size for the Int that specifies the variant plus the size needed for all fields - 4UL - + FfiConverterInt.allocationSize(value.`code`) - + FfiConverterString.allocationSize(value.`msg`) - + FfiConverterMapStringString.allocationSize(value.`values`) - ) - is Exception.NoSuchNode -> ( - // Add the size for the Int that specifies the variant plus the size needed for all fields - 4UL - + FfiConverterInt.allocationSize(value.`code`) - + FfiConverterString.allocationSize(value.`msg`) - + FfiConverterMapStringString.allocationSize(value.`values`) - ) - is Exception.UnparseableCreds -> ( - // Add the size for the Int that specifies the variant plus the size needed for all fields - 4UL - + FfiConverterInt.allocationSize(value.`code`) - + FfiConverterString.allocationSize(value.`msg`) - + FfiConverterMapStringString.allocationSize(value.`values`) - ) - is Exception.PhraseCorrupted -> ( - // Add the size for the Int that specifies the variant plus the size needed for all fields - 4UL - + FfiConverterInt.allocationSize(value.`code`) - + FfiConverterString.allocationSize(value.`msg`) - + FfiConverterMapStringString.allocationSize(value.`values`) - ) - is Exception.Rpc -> ( - // Add the size for the Int that specifies the variant plus the size needed for all fields - 4UL - + FfiConverterInt.allocationSize(value.`code`) - + FfiConverterString.allocationSize(value.`msg`) - + FfiConverterMapStringString.allocationSize(value.`values`) - ) - is Exception.Argument -> ( - // Add the size for the Int that specifies the variant plus the size needed for all fields - 4UL - + FfiConverterInt.allocationSize(value.`code`) - + FfiConverterString.allocationSize(value.`msg`) - + FfiConverterMapStringString.allocationSize(value.`values`) - ) - is Exception.Other -> ( - // Add the size for the Int that specifies the variant plus the size needed for all fields - 4UL - + FfiConverterInt.allocationSize(value.`code`) - + FfiConverterString.allocationSize(value.`msg`) - + FfiConverterMapStringString.allocationSize(value.`values`) - ) - } - } - - override fun write(value: Exception, buf: ByteBuffer) { - when(value) { - is Exception.DuplicateNode -> { - buf.putInt(1) - FfiConverterInt.write(value.`code`, buf) - FfiConverterString.write(value.`msg`, buf) - FfiConverterMapStringString.write(value.`values`, buf) - Unit - } - is Exception.NoSuchNode -> { - buf.putInt(2) - FfiConverterInt.write(value.`code`, buf) - FfiConverterString.write(value.`msg`, buf) - FfiConverterMapStringString.write(value.`values`, buf) - Unit - } - is Exception.UnparseableCreds -> { - buf.putInt(3) - FfiConverterInt.write(value.`code`, buf) - FfiConverterString.write(value.`msg`, buf) - FfiConverterMapStringString.write(value.`values`, buf) - Unit - } - is Exception.PhraseCorrupted -> { - buf.putInt(4) - FfiConverterInt.write(value.`code`, buf) - FfiConverterString.write(value.`msg`, buf) - FfiConverterMapStringString.write(value.`values`, buf) - Unit - } - is Exception.Rpc -> { - buf.putInt(5) - FfiConverterInt.write(value.`code`, buf) - FfiConverterString.write(value.`msg`, buf) - FfiConverterMapStringString.write(value.`values`, buf) - Unit - } - is Exception.Argument -> { - buf.putInt(6) - FfiConverterInt.write(value.`code`, buf) - FfiConverterString.write(value.`msg`, buf) - FfiConverterMapStringString.write(value.`values`, buf) - Unit - } - is Exception.Other -> { - buf.putInt(7) - FfiConverterInt.write(value.`code`, buf) - FfiConverterString.write(value.`msg`, buf) - FfiConverterMapStringString.write(value.`values`, buf) - Unit - } - }.let { /* this makes the `when` an expression, which ensures it is exhaustive */ } - } - -} - - - - -enum class InvoiceStatus { - - UNPAID, - PAID, - EXPIRED; - companion object -} - - -/** - * @suppress - */ -public object FfiConverterTypeInvoiceStatus: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer) = try { - InvoiceStatus.values()[buf.getInt() - 1] - } catch (e: IndexOutOfBoundsException) { - throw RuntimeException("invalid enum value, something is very wrong!!", e) - } - - override fun allocationSize(value: InvoiceStatus) = 4UL - - override fun write(value: InvoiceStatus, buf: ByteBuffer) { - buf.putInt(value.ordinal + 1) - } -} - - - - - -/** - * Index field used by CLN's paginated list RPCs. - */ - -enum class ListIndex { - - CREATED, - UPDATED; - companion object -} - - -/** - * @suppress - */ -public object FfiConverterTypeListIndex: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer) = try { - ListIndex.values()[buf.getInt() - 1] - } catch (e: IndexOutOfBoundsException) { - throw RuntimeException("invalid enum value, something is very wrong!!", e) - } - - override fun allocationSize(value: ListIndex) = 4UL - - override fun write(value: ListIndex, buf: ByteBuffer) { - buf.putInt(value.ordinal + 1) - } -} - - - - - -/** - * Result of an LNURL-pay operation. - */ -sealed class LnUrlPayResult { - - /** - * Payment succeeded. - */ - data class EndpointSuccess( - val `data`: LnUrlPaySuccessData) : LnUrlPayResult() { - companion object - } - - /** - * The LNURL service returned an error before the invoice was paid. - */ - data class EndpointError( - val `data`: LnUrlErrorData) : LnUrlPayResult() { - companion object - } - - /** - * The invoice was fetched successfully but paying it failed. - */ - data class PayError( - val `data`: LnUrlPayErrorData) : LnUrlPayResult() { - companion object - } - - - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeLnUrlPayResult : FfiConverterRustBuffer{ - override fun read(buf: ByteBuffer): LnUrlPayResult { - return when(buf.getInt()) { - 1 -> LnUrlPayResult.EndpointSuccess( - FfiConverterTypeLnUrlPaySuccessData.read(buf), - ) - 2 -> LnUrlPayResult.EndpointError( - FfiConverterTypeLnUrlErrorData.read(buf), - ) - 3 -> LnUrlPayResult.PayError( - FfiConverterTypeLnUrlPayErrorData.read(buf), - ) - else -> throw RuntimeException("invalid enum value, something is very wrong!!") - } - } - - override fun allocationSize(value: LnUrlPayResult) = when(value) { - is LnUrlPayResult.EndpointSuccess -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterTypeLnUrlPaySuccessData.allocationSize(value.`data`) - ) - } - is LnUrlPayResult.EndpointError -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterTypeLnUrlErrorData.allocationSize(value.`data`) - ) - } - is LnUrlPayResult.PayError -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterTypeLnUrlPayErrorData.allocationSize(value.`data`) - ) - } - } - - override fun write(value: LnUrlPayResult, buf: ByteBuffer) { - when(value) { - is LnUrlPayResult.EndpointSuccess -> { - buf.putInt(1) - FfiConverterTypeLnUrlPaySuccessData.write(value.`data`, buf) - Unit - } - is LnUrlPayResult.EndpointError -> { - buf.putInt(2) - FfiConverterTypeLnUrlErrorData.write(value.`data`, buf) - Unit - } - is LnUrlPayResult.PayError -> { - buf.putInt(3) - FfiConverterTypeLnUrlPayErrorData.write(value.`data`, buf) - Unit - } - }.let { /* this makes the `when` an expression, which ensures it is exhaustive */ } - } -} - - - - - -/** - * Result of an LNURL-withdraw operation. - */ -sealed class LnUrlWithdrawResult { - - /** - * The service accepted our invoice and will pay it. - */ - data class Ok( - val `data`: LnUrlWithdrawSuccessData) : LnUrlWithdrawResult() { - companion object - } - - /** - * The LNURL service returned an error. - */ - data class ErrorStatus( - val `data`: LnUrlErrorData) : LnUrlWithdrawResult() { - companion object - } - - - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeLnUrlWithdrawResult : FfiConverterRustBuffer{ - override fun read(buf: ByteBuffer): LnUrlWithdrawResult { - return when(buf.getInt()) { - 1 -> LnUrlWithdrawResult.Ok( - FfiConverterTypeLnUrlWithdrawSuccessData.read(buf), - ) - 2 -> LnUrlWithdrawResult.ErrorStatus( - FfiConverterTypeLnUrlErrorData.read(buf), - ) - else -> throw RuntimeException("invalid enum value, something is very wrong!!") - } - } - - override fun allocationSize(value: LnUrlWithdrawResult) = when(value) { - is LnUrlWithdrawResult.Ok -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterTypeLnUrlWithdrawSuccessData.allocationSize(value.`data`) - ) - } - is LnUrlWithdrawResult.ErrorStatus -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterTypeLnUrlErrorData.allocationSize(value.`data`) - ) - } - } - - override fun write(value: LnUrlWithdrawResult, buf: ByteBuffer) { - when(value) { - is LnUrlWithdrawResult.Ok -> { - buf.putInt(1) - FfiConverterTypeLnUrlWithdrawSuccessData.write(value.`data`, buf) - Unit - } - is LnUrlWithdrawResult.ErrorStatus -> { - buf.putInt(2) - FfiConverterTypeLnUrlErrorData.write(value.`data`, buf) - Unit - } - }.let { /* this makes the `when` an expression, which ensures it is exhaustive */ } - } -} - - - - - -/** - * Log level for filtering messages. - */ - -enum class LogLevel { - - ERROR, - WARN, - INFO, - DEBUG, - TRACE; - companion object -} - - -/** - * @suppress - */ -public object FfiConverterTypeLogLevel: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer) = try { - LogLevel.values()[buf.getInt() - 1] - } catch (e: IndexOutOfBoundsException) { - throw RuntimeException("invalid enum value, something is very wrong!!", e) - } - - override fun allocationSize(value: LogLevel) = 4UL - - override fun write(value: LogLevel, buf: ByteBuffer) { - buf.putInt(value.ordinal + 1) - } -} - - - - - - -enum class Network { - - BITCOIN, - REGTEST; - companion object -} - - -/** - * @suppress - */ -public object FfiConverterTypeNetwork: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer) = try { - Network.values()[buf.getInt() - 1] - } catch (e: IndexOutOfBoundsException) { - throw RuntimeException("invalid enum value, something is very wrong!!", e) - } - - override fun allocationSize(value: Network) = 4UL - - override fun write(value: Network, buf: ByteBuffer) { - buf.putInt(value.ordinal + 1) - } -} - - - - - -/** - * A real-time event from the node. - */ -sealed class NodeEvent { - - /** - * An invoice was paid. - */ - data class InvoicePaid( - val `details`: InvoicePaidEvent) : NodeEvent() { - companion object - } - - - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeNodeEvent : FfiConverterRustBuffer{ - override fun read(buf: ByteBuffer): NodeEvent { - return when(buf.getInt()) { - 1 -> NodeEvent.InvoicePaid( - FfiConverterTypeInvoicePaidEvent.read(buf), - ) - else -> throw RuntimeException("invalid enum value, something is very wrong!!") - } - } - - override fun allocationSize(value: NodeEvent) = when(value) { - is NodeEvent.InvoicePaid -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterTypeInvoicePaidEvent.allocationSize(value.`details`) - ) - } - } - - override fun write(value: NodeEvent, buf: ByteBuffer) { - when(value) { - is NodeEvent.InvoicePaid -> { - buf.putInt(1) - FfiConverterTypeInvoicePaidEvent.write(value.`details`, buf) - Unit - } - }.let { /* this makes the `when` an expression, which ensures it is exhaustive */ } - } -} - - - - - -/** - * Classifies the on-chain wallet into discrete cases that a wallet - * UI can switch on to render the correct entry-point for the - * withdraw flow. Derived purely from `NodeState` — no RPC. - */ -sealed class OnchainBalanceState { - - /** - * No funds on-chain in any form (confirmed, unconfirmed, - * immature, or pending channel-close payouts are all zero). - * Don't render a withdraw entry point. - */ - object Unavailable : OnchainBalanceState() - - - /** - * Funds are spendable now. Render the withdraw entry point - * enabled with `withdrawable_sat` as the headline. - */ - data class Available( - /** - * `onchain_balance_sat - emergency_reserve_sat`. Use as - * the displayed amount on the entry point. - */ - val `withdrawableSat`: kotlin.ULong, - /** - * Held back by CLN for anchor-channel safety; cannot be - * withdrawn without closing channels first. - */ - val `emergencyReserveSat`: kotlin.ULong, - /** - * Inbound on-chain funds not yet confirmed. Informational - * only — not part of `withdrawable_sat`. - */ - val `unconfirmedSat`: kotlin.ULong) : OnchainBalanceState() { - companion object - } - - /** - * On-chain funds exist but are entirely locked as the - * anchor-channel emergency reserve. Render the entry point - * disabled with an explainer (e.g. "close channels to free - * these funds"). - */ - data class ReserveOnly( - val `reserveSat`: kotlin.ULong) : OnchainBalanceState() { - companion object - } - - /** - * Inbound on-chain funds are awaiting confirmation. Render a - * "pending" indicator instead of an enabled withdraw button. - */ - data class PendingConfirmation( - val `unconfirmedSat`: kotlin.ULong) : OnchainBalanceState() { - companion object - } - - /** - * Funds exist as CSV-timelocked outputs from a recent channel - * close and can't be spent until the relative locktime - * expires. Render the entry point disabled with a - * "channel closing" explainer. - */ - data class Immature( - val `immatureSat`: kotlin.ULong) : OnchainBalanceState() { - companion object - } - - - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeOnchainBalanceState : FfiConverterRustBuffer{ - override fun read(buf: ByteBuffer): OnchainBalanceState { - return when(buf.getInt()) { - 1 -> OnchainBalanceState.Unavailable - 2 -> OnchainBalanceState.Available( - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - FfiConverterULong.read(buf), - ) - 3 -> OnchainBalanceState.ReserveOnly( - FfiConverterULong.read(buf), - ) - 4 -> OnchainBalanceState.PendingConfirmation( - FfiConverterULong.read(buf), - ) - 5 -> OnchainBalanceState.Immature( - FfiConverterULong.read(buf), - ) - else -> throw RuntimeException("invalid enum value, something is very wrong!!") - } - } - - override fun allocationSize(value: OnchainBalanceState) = when(value) { - is OnchainBalanceState.Unavailable -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - ) - } - is OnchainBalanceState.Available -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterULong.allocationSize(value.`withdrawableSat`) - + FfiConverterULong.allocationSize(value.`emergencyReserveSat`) - + FfiConverterULong.allocationSize(value.`unconfirmedSat`) - ) - } - is OnchainBalanceState.ReserveOnly -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterULong.allocationSize(value.`reserveSat`) - ) - } - is OnchainBalanceState.PendingConfirmation -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterULong.allocationSize(value.`unconfirmedSat`) - ) - } - is OnchainBalanceState.Immature -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterULong.allocationSize(value.`immatureSat`) - ) - } - } - - override fun write(value: OnchainBalanceState, buf: ByteBuffer) { - when(value) { - is OnchainBalanceState.Unavailable -> { - buf.putInt(1) - Unit - } - is OnchainBalanceState.Available -> { - buf.putInt(2) - FfiConverterULong.write(value.`withdrawableSat`, buf) - FfiConverterULong.write(value.`emergencyReserveSat`, buf) - FfiConverterULong.write(value.`unconfirmedSat`, buf) - Unit - } - is OnchainBalanceState.ReserveOnly -> { - buf.putInt(3) - FfiConverterULong.write(value.`reserveSat`, buf) - Unit - } - is OnchainBalanceState.PendingConfirmation -> { - buf.putInt(4) - FfiConverterULong.write(value.`unconfirmedSat`, buf) - Unit - } - is OnchainBalanceState.Immature -> { - buf.putInt(5) - FfiConverterULong.write(value.`immatureSat`, buf) - Unit - } - }.let { /* this makes the `when` an expression, which ensures it is exhaustive */ } - } -} - - - - - - -enum class OutputStatus { - - UNCONFIRMED, - CONFIRMED, - SPENT, - IMMATURE; - companion object -} - - -/** - * @suppress - */ -public object FfiConverterTypeOutputStatus: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer) = try { - OutputStatus.values()[buf.getInt() - 1] - } catch (e: IndexOutOfBoundsException) { - throw RuntimeException("invalid enum value, something is very wrong!!", e) - } - - override fun allocationSize(value: OutputStatus) = 4UL - - override fun write(value: OutputStatus, buf: ByteBuffer) { - buf.putInt(value.ordinal + 1) - } -} - - - - - -/** - * The result of `parse_input`: an offline classification of the - * input. No HTTP, no I/O. LNURL bech32 strings are returned as their - * decoded URL; Lightning Addresses as the unparsed `user@host` form. - */ -sealed class ParsedInput { - - /** - * A BOLT11 Lightning invoice. - */ - data class Bolt11( - val `invoice`: ParsedInvoice) : ParsedInput() { - companion object - } - - /** - * A Lightning node public key. - */ - data class NodeId( - val `nodeId`: kotlin.String) : ParsedInput() { - companion object - } - - /** - * An LNURL bech32 string (LUD-01) decoded to its underlying URL. - * Pass to `resolve_input` (or fetch yourself) to determine - * whether it's a pay, withdraw, or auth endpoint. - */ - data class LnUrl( - val `url`: kotlin.String) : ParsedInput() { - companion object - } - - /** - * A Lightning Address (LUD-16) in the form `user@host`. The - * well-known URL is not constructed offline; call `resolve_input` - * to fetch and classify. - */ - data class LnUrlAddress( - val `address`: kotlin.String) : ParsedInput() { - companion object - } - - - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeParsedInput : FfiConverterRustBuffer{ - override fun read(buf: ByteBuffer): ParsedInput { - return when(buf.getInt()) { - 1 -> ParsedInput.Bolt11( - FfiConverterTypeParsedInvoice.read(buf), - ) - 2 -> ParsedInput.NodeId( - FfiConverterString.read(buf), - ) - 3 -> ParsedInput.LnUrl( - FfiConverterString.read(buf), - ) - 4 -> ParsedInput.LnUrlAddress( - FfiConverterString.read(buf), - ) - else -> throw RuntimeException("invalid enum value, something is very wrong!!") - } - } - - override fun allocationSize(value: ParsedInput) = when(value) { - is ParsedInput.Bolt11 -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterTypeParsedInvoice.allocationSize(value.`invoice`) - ) - } - is ParsedInput.NodeId -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterString.allocationSize(value.`nodeId`) - ) - } - is ParsedInput.LnUrl -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterString.allocationSize(value.`url`) - ) - } - is ParsedInput.LnUrlAddress -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterString.allocationSize(value.`address`) - ) - } - } - - override fun write(value: ParsedInput, buf: ByteBuffer) { - when(value) { - is ParsedInput.Bolt11 -> { - buf.putInt(1) - FfiConverterTypeParsedInvoice.write(value.`invoice`, buf) - Unit - } - is ParsedInput.NodeId -> { - buf.putInt(2) - FfiConverterString.write(value.`nodeId`, buf) - Unit - } - is ParsedInput.LnUrl -> { - buf.putInt(3) - FfiConverterString.write(value.`url`, buf) - Unit - } - is ParsedInput.LnUrlAddress -> { - buf.putInt(4) - FfiConverterString.write(value.`address`, buf) - Unit - } - }.let { /* this makes the `when` an expression, which ensures it is exhaustive */ } - } -} - - - - - - -enum class PayStatus { - - COMPLETE, - PENDING, - FAILED; - companion object -} - - -/** - * @suppress - */ -public object FfiConverterTypePayStatus: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer) = try { - PayStatus.values()[buf.getInt() - 1] - } catch (e: IndexOutOfBoundsException) { - throw RuntimeException("invalid enum value, something is very wrong!!", e) - } - - override fun allocationSize(value: PayStatus) = 4UL - - override fun write(value: PayStatus, buf: ByteBuffer) { - buf.putInt(value.ordinal + 1) - } -} - - - - - - -enum class PaymentStatus { - - PENDING, - COMPLETE, - FAILED; - companion object -} - - -/** - * @suppress - */ -public object FfiConverterTypePaymentStatus: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer) = try { - PaymentStatus.values()[buf.getInt() - 1] - } catch (e: IndexOutOfBoundsException) { - throw RuntimeException("invalid enum value, something is very wrong!!", e) - } - - override fun allocationSize(value: PaymentStatus) = 4UL - - override fun write(value: PaymentStatus, buf: ByteBuffer) { - buf.putInt(value.ordinal + 1) - } -} - - - - - - -enum class PaymentType { - - SENT, - RECEIVED; - companion object -} - - -/** - * @suppress - */ -public object FfiConverterTypePaymentType: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer) = try { - PaymentType.values()[buf.getInt() - 1] - } catch (e: IndexOutOfBoundsException) { - throw RuntimeException("invalid enum value, something is very wrong!!", e) - } - - override fun allocationSize(value: PaymentType) = 4UL - - override fun write(value: PaymentType, buf: ByteBuffer) { - buf.putInt(value.ordinal + 1) - } -} - - - - - - -enum class PaymentTypeFilter { - - SENT, - RECEIVED; - companion object -} - - -/** - * @suppress - */ -public object FfiConverterTypePaymentTypeFilter: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer) = try { - PaymentTypeFilter.values()[buf.getInt() - 1] - } catch (e: IndexOutOfBoundsException) { - throw RuntimeException("invalid enum value, something is very wrong!!", e) - } - - override fun allocationSize(value: PaymentTypeFilter) = 4UL - - override fun write(value: PaymentTypeFilter, buf: ByteBuffer) { - buf.putInt(value.ordinal + 1) - } -} - - - - - -/** - * The result of `resolve_input`: a fully-resolved input ready for - * the caller's next action. LNURL bech32 strings and Lightning - * Addresses are resolved over HTTP into typed pay or withdraw - * request data; BOLT11 and node IDs pass through unchanged. - */ -sealed class ResolvedInput { - - /** - * A BOLT11 Lightning invoice. No HTTP was performed. - */ - data class Bolt11( - val `invoice`: ParsedInvoice) : ResolvedInput() { - companion object - } - - /** - * A Lightning node public key. No HTTP was performed. - */ - data class NodeId( - val `nodeId`: kotlin.String) : ResolvedInput() { - companion object - } - - /** - * An LNURL-pay endpoint with the service's parameters fetched. - */ - data class LnUrlPay( - val `data`: LnUrlPayRequestData) : ResolvedInput() { - companion object - } - - /** - * An LNURL-withdraw endpoint with the service's parameters fetched. - */ - data class LnUrlWithdraw( - val `data`: LnUrlWithdrawRequestData) : ResolvedInput() { - companion object - } - - - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeResolvedInput : FfiConverterRustBuffer{ - override fun read(buf: ByteBuffer): ResolvedInput { - return when(buf.getInt()) { - 1 -> ResolvedInput.Bolt11( - FfiConverterTypeParsedInvoice.read(buf), - ) - 2 -> ResolvedInput.NodeId( - FfiConverterString.read(buf), - ) - 3 -> ResolvedInput.LnUrlPay( - FfiConverterTypeLnUrlPayRequestData.read(buf), - ) - 4 -> ResolvedInput.LnUrlWithdraw( - FfiConverterTypeLnUrlWithdrawRequestData.read(buf), - ) - else -> throw RuntimeException("invalid enum value, something is very wrong!!") - } - } - - override fun allocationSize(value: ResolvedInput) = when(value) { - is ResolvedInput.Bolt11 -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterTypeParsedInvoice.allocationSize(value.`invoice`) - ) - } - is ResolvedInput.NodeId -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterString.allocationSize(value.`nodeId`) - ) - } - is ResolvedInput.LnUrlPay -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterTypeLnUrlPayRequestData.allocationSize(value.`data`) - ) - } - is ResolvedInput.LnUrlWithdraw -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterTypeLnUrlWithdrawRequestData.allocationSize(value.`data`) - ) - } - } - - override fun write(value: ResolvedInput, buf: ByteBuffer) { - when(value) { - is ResolvedInput.Bolt11 -> { - buf.putInt(1) - FfiConverterTypeParsedInvoice.write(value.`invoice`, buf) - Unit - } - is ResolvedInput.NodeId -> { - buf.putInt(2) - FfiConverterString.write(value.`nodeId`, buf) - Unit - } - is ResolvedInput.LnUrlPay -> { - buf.putInt(3) - FfiConverterTypeLnUrlPayRequestData.write(value.`data`, buf) - Unit - } - is ResolvedInput.LnUrlWithdraw -> { - buf.putInt(4) - FfiConverterTypeLnUrlWithdrawRequestData.write(value.`data`, buf) - Unit - } - }.let { /* this makes the `when` an expression, which ensures it is exhaustive */ } - } -} - - - - - -/** - * A processed success action from an LNURL-pay callback. - * - * For Message and Url this is passed through as-is. For Aes the - * ciphertext has been decrypted using the payment preimage. - */ -sealed class SuccessActionProcessed { - - /** - * Display a message to the user. - */ - data class Message( - val `message`: kotlin.String) : SuccessActionProcessed() { - companion object - } - - /** - * Display a URL to the user. - */ - data class Url( - val `description`: kotlin.String, - val `url`: kotlin.String) : SuccessActionProcessed() { - companion object - } - - /** - * Decrypted AES payload (LUD-10). - */ - data class Aes( - val `description`: kotlin.String, - val `plaintext`: kotlin.String) : SuccessActionProcessed() { - companion object - } - - - - companion object -} - -/** - * @suppress - */ -public object FfiConverterTypeSuccessActionProcessed : FfiConverterRustBuffer{ - override fun read(buf: ByteBuffer): SuccessActionProcessed { - return when(buf.getInt()) { - 1 -> SuccessActionProcessed.Message( - FfiConverterString.read(buf), - ) - 2 -> SuccessActionProcessed.Url( - FfiConverterString.read(buf), - FfiConverterString.read(buf), - ) - 3 -> SuccessActionProcessed.Aes( - FfiConverterString.read(buf), - FfiConverterString.read(buf), - ) - else -> throw RuntimeException("invalid enum value, something is very wrong!!") - } - } - - override fun allocationSize(value: SuccessActionProcessed) = when(value) { - is SuccessActionProcessed.Message -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterString.allocationSize(value.`message`) - ) - } - is SuccessActionProcessed.Url -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterString.allocationSize(value.`description`) - + FfiConverterString.allocationSize(value.`url`) - ) - } - is SuccessActionProcessed.Aes -> { - // Add the size for the Int that specifies the variant plus the size needed for all fields - ( - 4UL - + FfiConverterString.allocationSize(value.`description`) - + FfiConverterString.allocationSize(value.`plaintext`) - ) - } - } - - override fun write(value: SuccessActionProcessed, buf: ByteBuffer) { - when(value) { - is SuccessActionProcessed.Message -> { - buf.putInt(1) - FfiConverterString.write(value.`message`, buf) - Unit - } - is SuccessActionProcessed.Url -> { - buf.putInt(2) - FfiConverterString.write(value.`description`, buf) - FfiConverterString.write(value.`url`, buf) - Unit - } - is SuccessActionProcessed.Aes -> { - buf.putInt(3) - FfiConverterString.write(value.`description`, buf) - FfiConverterString.write(value.`plaintext`, buf) - Unit - } - }.let { /* this makes the `when` an expression, which ensures it is exhaustive */ } - } -} - - - - - - - -/** - * Callback interface for receiving log messages. - * - * `on_log` is invoked on the thread that emitted the log — which can - * be any tokio worker or background thread inside the SDK. Keep the - * implementation cheap and non-blocking; if you need UI updates, - * hand the entry off to your app's main thread. - */ -public interface LogListener { - - fun `onLog`(`entry`: LogEntry) - - companion object -} - - - -// Put the implementation in an object so we don't pollute the top-level namespace -internal object uniffiCallbackInterfaceLogListener { - internal object `onLog`: UniffiCallbackInterfaceLogListenerMethod0 { - override fun callback(`uniffiHandle`: Long,`entry`: RustBuffer.ByValue,`uniffiOutReturn`: Pointer,uniffiCallStatus: UniffiRustCallStatus,) { - val uniffiObj = FfiConverterTypeLogListener.handleMap.get(uniffiHandle) - val makeCall = { -> - uniffiObj.`onLog`( - FfiConverterTypeLogEntry.lift(`entry`), - ) - } - val writeReturn = { _: Unit -> Unit } - uniffiTraitInterfaceCall(uniffiCallStatus, makeCall, writeReturn) - } - } - - internal object uniffiFree: UniffiCallbackInterfaceFree { - override fun callback(handle: Long) { - FfiConverterTypeLogListener.handleMap.remove(handle) - } - } - - internal var vtable = UniffiVTableCallbackInterfaceLogListener.UniffiByValue( - `onLog`, - uniffiFree, - ) - - // Registers the foreign callback with the Rust side. - // This method is generated for each callback interface. - internal fun register(lib: UniffiLib) { - lib.uniffi_glsdk_fn_init_callback_vtable_loglistener(vtable) - } -} - -/** - * The ffiConverter which transforms the Callbacks in to handles to pass to Rust. - * - * @suppress - */ -public object FfiConverterTypeLogListener: FfiConverterCallbackInterface() - - - - - -/** - * Callback interface for receiving node events. - * - * `on_event` is invoked from the SDK's internal event-dispatch task. - * Implementations should be cheap and non-blocking; to update UI, - * dispatch to the main thread from inside the handler. - * - * Installed via `NodeBuilder::with_event_listener(...)` so events - * emitted during node bring-up are captured. The polling-style - * `Node::stream_node_events()` API is still available for callers - * that prefer to drive events themselves. - */ -public interface NodeEventListener { - - fun `onEvent`(`event`: NodeEvent) - - companion object -} - - - -// Put the implementation in an object so we don't pollute the top-level namespace -internal object uniffiCallbackInterfaceNodeEventListener { - internal object `onEvent`: UniffiCallbackInterfaceNodeEventListenerMethod0 { - override fun callback(`uniffiHandle`: Long,`event`: RustBuffer.ByValue,`uniffiOutReturn`: Pointer,uniffiCallStatus: UniffiRustCallStatus,) { - val uniffiObj = FfiConverterTypeNodeEventListener.handleMap.get(uniffiHandle) - val makeCall = { -> - uniffiObj.`onEvent`( - FfiConverterTypeNodeEvent.lift(`event`), - ) - } - val writeReturn = { _: Unit -> Unit } - uniffiTraitInterfaceCall(uniffiCallStatus, makeCall, writeReturn) - } - } - - internal object uniffiFree: UniffiCallbackInterfaceFree { - override fun callback(handle: Long) { - FfiConverterTypeNodeEventListener.handleMap.remove(handle) - } - } - - internal var vtable = UniffiVTableCallbackInterfaceNodeEventListener.UniffiByValue( - `onEvent`, - uniffiFree, - ) - - // Registers the foreign callback with the Rust side. - // This method is generated for each callback interface. - internal fun register(lib: UniffiLib) { - lib.uniffi_glsdk_fn_init_callback_vtable_nodeeventlistener(vtable) - } -} - -/** - * The ffiConverter which transforms the Callbacks in to handles to pass to Rust. - * - * @suppress - */ -public object FfiConverterTypeNodeEventListener: FfiConverterCallbackInterface() - - - - -/** - * @suppress - */ -public object FfiConverterOptionalUInt: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): kotlin.UInt? { - if (buf.get().toInt() == 0) { - return null - } - return FfiConverterUInt.read(buf) - } - - override fun allocationSize(value: kotlin.UInt?): ULong { - if (value == null) { - return 1UL - } else { - return 1UL + FfiConverterUInt.allocationSize(value) - } - } - - override fun write(value: kotlin.UInt?, buf: ByteBuffer) { - if (value == null) { - buf.put(0) - } else { - buf.put(1) - FfiConverterUInt.write(value, buf) - } - } -} - - - - -/** - * @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) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterOptionalBoolean: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): kotlin.Boolean? { - if (buf.get().toInt() == 0) { - return null - } - return FfiConverterBoolean.read(buf) - } - - override fun allocationSize(value: kotlin.Boolean?): ULong { - if (value == null) { - return 1UL - } else { - return 1UL + FfiConverterBoolean.allocationSize(value) - } - } - - override fun write(value: kotlin.Boolean?, buf: ByteBuffer) { - if (value == null) { - buf.put(0) - } else { - buf.put(1) - FfiConverterBoolean.write(value, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterOptionalString: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): kotlin.String? { - if (buf.get().toInt() == 0) { - return null - } - return FfiConverterString.read(buf) - } - - override fun allocationSize(value: kotlin.String?): ULong { - if (value == null) { - return 1UL - } else { - return 1UL + FfiConverterString.allocationSize(value) - } - } - - override fun write(value: kotlin.String?, buf: ByteBuffer) { - if (value == null) { - buf.put(0) - } else { - buf.put(1) - FfiConverterString.write(value, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterOptionalByteArray: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): kotlin.ByteArray? { - if (buf.get().toInt() == 0) { - return null - } - return FfiConverterByteArray.read(buf) - } - - override fun allocationSize(value: kotlin.ByteArray?): ULong { - if (value == null) { - return 1UL - } else { - return 1UL + FfiConverterByteArray.allocationSize(value) - } - } - - override fun write(value: kotlin.ByteArray?, buf: ByteBuffer) { - if (value == null) { - buf.put(0) - } else { - buf.put(1) - FfiConverterByteArray.write(value, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterOptionalTypeChannelSide: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): ChannelSide? { - if (buf.get().toInt() == 0) { - return null - } - return FfiConverterTypeChannelSide.read(buf) - } - - override fun allocationSize(value: ChannelSide?): ULong { - if (value == null) { - return 1UL - } else { - return 1UL + FfiConverterTypeChannelSide.allocationSize(value) - } - } - - override fun write(value: ChannelSide?, buf: ByteBuffer) { - if (value == null) { - buf.put(0) - } else { - buf.put(1) - FfiConverterTypeChannelSide.write(value, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterOptionalTypeListIndex: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): ListIndex? { - if (buf.get().toInt() == 0) { - return null - } - return FfiConverterTypeListIndex.read(buf) - } - - override fun allocationSize(value: ListIndex?): ULong { - if (value == null) { - return 1UL - } else { - return 1UL + FfiConverterTypeListIndex.allocationSize(value) - } - } - - override fun write(value: ListIndex?, buf: ByteBuffer) { - if (value == null) { - buf.put(0) - } else { - buf.put(1) - FfiConverterTypeListIndex.write(value, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterOptionalTypeNodeEvent: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): NodeEvent? { - if (buf.get().toInt() == 0) { - return null - } - return FfiConverterTypeNodeEvent.read(buf) - } - - override fun allocationSize(value: NodeEvent?): ULong { - if (value == null) { - return 1UL - } else { - return 1UL + FfiConverterTypeNodeEvent.allocationSize(value) - } - } - - override fun write(value: NodeEvent?, buf: ByteBuffer) { - if (value == null) { - buf.put(0) - } else { - buf.put(1) - FfiConverterTypeNodeEvent.write(value, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterOptionalTypePayStatus: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): PayStatus? { - if (buf.get().toInt() == 0) { - return null - } - return FfiConverterTypePayStatus.read(buf) - } - - override fun allocationSize(value: PayStatus?): ULong { - if (value == null) { - return 1UL - } else { - return 1UL + FfiConverterTypePayStatus.allocationSize(value) - } - } - - override fun write(value: PayStatus?, buf: ByteBuffer) { - if (value == null) { - buf.put(0) - } else { - buf.put(1) - FfiConverterTypePayStatus.write(value, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterOptionalTypeSuccessActionProcessed: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): SuccessActionProcessed? { - if (buf.get().toInt() == 0) { - return null - } - return FfiConverterTypeSuccessActionProcessed.read(buf) - } - - override fun allocationSize(value: SuccessActionProcessed?): ULong { - if (value == null) { - return 1UL - } else { - return 1UL + FfiConverterTypeSuccessActionProcessed.allocationSize(value) - } - } - - override fun write(value: SuccessActionProcessed?, buf: ByteBuffer) { - if (value == null) { - buf.put(0) - } else { - buf.put(1) - FfiConverterTypeSuccessActionProcessed.write(value, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterOptionalSequenceTypeOutpoint: FfiConverterRustBuffer?> { - override fun read(buf: ByteBuffer): List? { - if (buf.get().toInt() == 0) { - return null - } - return FfiConverterSequenceTypeOutpoint.read(buf) - } - - override fun allocationSize(value: List?): ULong { - if (value == null) { - return 1UL - } else { - return 1UL + FfiConverterSequenceTypeOutpoint.allocationSize(value) - } - } - - override fun write(value: List?, buf: ByteBuffer) { - if (value == null) { - buf.put(0) - } else { - buf.put(1) - FfiConverterSequenceTypeOutpoint.write(value, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterOptionalSequenceTypePaymentTypeFilter: FfiConverterRustBuffer?> { - override fun read(buf: ByteBuffer): List? { - if (buf.get().toInt() == 0) { - return null - } - return FfiConverterSequenceTypePaymentTypeFilter.read(buf) - } - - override fun allocationSize(value: List?): ULong { - if (value == null) { - return 1UL - } else { - return 1UL + FfiConverterSequenceTypePaymentTypeFilter.allocationSize(value) - } - } - - override fun write(value: List?, buf: ByteBuffer) { - if (value == null) { - buf.put(0) - } else { - buf.put(1) - FfiConverterSequenceTypePaymentTypeFilter.write(value, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterSequenceString: FfiConverterRustBuffer> { - override fun read(buf: ByteBuffer): List { - val len = buf.getInt() - return List(len) { - FfiConverterString.read(buf) - } - } - - override fun allocationSize(value: List): ULong { - val sizeForLength = 4UL - val sizeForItems = value.map { FfiConverterString.allocationSize(it) }.sum() - return sizeForLength + sizeForItems - } - - override fun write(value: List, buf: ByteBuffer) { - buf.putInt(value.size) - value.iterator().forEach { - FfiConverterString.write(it, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterSequenceTypeFundChannel: FfiConverterRustBuffer> { - override fun read(buf: ByteBuffer): List { - val len = buf.getInt() - return List(len) { - FfiConverterTypeFundChannel.read(buf) - } - } - - override fun allocationSize(value: List): ULong { - val sizeForLength = 4UL - val sizeForItems = value.map { FfiConverterTypeFundChannel.allocationSize(it) }.sum() - return sizeForLength + sizeForItems - } - - override fun write(value: List, buf: ByteBuffer) { - buf.putInt(value.size) - value.iterator().forEach { - FfiConverterTypeFundChannel.write(it, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterSequenceTypeFundOutput: FfiConverterRustBuffer> { - override fun read(buf: ByteBuffer): List { - val len = buf.getInt() - return List(len) { - FfiConverterTypeFundOutput.read(buf) - } - } - - override fun allocationSize(value: List): ULong { - val sizeForLength = 4UL - val sizeForItems = value.map { FfiConverterTypeFundOutput.allocationSize(it) }.sum() - return sizeForLength + sizeForItems - } - - override fun write(value: List, buf: ByteBuffer) { - buf.putInt(value.size) - value.iterator().forEach { - FfiConverterTypeFundOutput.write(it, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterSequenceTypeInvoice: FfiConverterRustBuffer> { - override fun read(buf: ByteBuffer): List { - val len = buf.getInt() - return List(len) { - FfiConverterTypeInvoice.read(buf) - } - } - - override fun allocationSize(value: List): ULong { - val sizeForLength = 4UL - val sizeForItems = value.map { FfiConverterTypeInvoice.allocationSize(it) }.sum() - return sizeForLength + sizeForItems - } - - override fun write(value: List, buf: ByteBuffer) { - buf.putInt(value.size) - value.iterator().forEach { - FfiConverterTypeInvoice.write(it, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterSequenceTypeOutpoint: FfiConverterRustBuffer> { - override fun read(buf: ByteBuffer): List { - val len = buf.getInt() - return List(len) { - FfiConverterTypeOutpoint.read(buf) - } - } - - override fun allocationSize(value: List): ULong { - val sizeForLength = 4UL - val sizeForItems = value.map { FfiConverterTypeOutpoint.allocationSize(it) }.sum() - return sizeForLength + sizeForItems - } - - override fun write(value: List, buf: ByteBuffer) { - buf.putInt(value.size) - value.iterator().forEach { - FfiConverterTypeOutpoint.write(it, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterSequenceTypePay: FfiConverterRustBuffer> { - override fun read(buf: ByteBuffer): List { - val len = buf.getInt() - return List(len) { - FfiConverterTypePay.read(buf) - } - } - - override fun allocationSize(value: List): ULong { - val sizeForLength = 4UL - val sizeForItems = value.map { FfiConverterTypePay.allocationSize(it) }.sum() - return sizeForLength + sizeForItems - } - - override fun write(value: List, buf: ByteBuffer) { - buf.putInt(value.size) - value.iterator().forEach { - FfiConverterTypePay.write(it, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterSequenceTypePayment: FfiConverterRustBuffer> { - override fun read(buf: ByteBuffer): List { - val len = buf.getInt() - return List(len) { - FfiConverterTypePayment.read(buf) - } - } - - override fun allocationSize(value: List): ULong { - val sizeForLength = 4UL - val sizeForItems = value.map { FfiConverterTypePayment.allocationSize(it) }.sum() - return sizeForLength + sizeForItems - } - - override fun write(value: List, buf: ByteBuffer) { - buf.putInt(value.size) - value.iterator().forEach { - FfiConverterTypePayment.write(it, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterSequenceTypePeer: FfiConverterRustBuffer> { - override fun read(buf: ByteBuffer): List { - val len = buf.getInt() - return List(len) { - FfiConverterTypePeer.read(buf) - } - } - - override fun allocationSize(value: List): ULong { - val sizeForLength = 4UL - val sizeForItems = value.map { FfiConverterTypePeer.allocationSize(it) }.sum() - return sizeForLength + sizeForItems - } - - override fun write(value: List, buf: ByteBuffer) { - buf.putInt(value.size) - value.iterator().forEach { - FfiConverterTypePeer.write(it, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterSequenceTypePeerChannel: FfiConverterRustBuffer> { - override fun read(buf: ByteBuffer): List { - val len = buf.getInt() - return List(len) { - FfiConverterTypePeerChannel.read(buf) - } - } - - override fun allocationSize(value: List): ULong { - val sizeForLength = 4UL - val sizeForItems = value.map { FfiConverterTypePeerChannel.allocationSize(it) }.sum() - return sizeForLength + sizeForItems - } - - override fun write(value: List, buf: ByteBuffer) { - buf.putInt(value.size) - value.iterator().forEach { - FfiConverterTypePeerChannel.write(it, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterSequenceTypePaymentTypeFilter: FfiConverterRustBuffer> { - override fun read(buf: ByteBuffer): List { - val len = buf.getInt() - return List(len) { - FfiConverterTypePaymentTypeFilter.read(buf) - } - } - - override fun allocationSize(value: List): ULong { - val sizeForLength = 4UL - val sizeForItems = value.map { FfiConverterTypePaymentTypeFilter.allocationSize(it) }.sum() - return sizeForLength + sizeForItems - } - - override fun write(value: List, buf: ByteBuffer) { - buf.putInt(value.size) - value.iterator().forEach { - FfiConverterTypePaymentTypeFilter.write(it, buf) - } - } -} - - - - -/** - * @suppress - */ -public object FfiConverterMapStringString: FfiConverterRustBuffer> { - override fun read(buf: ByteBuffer): Map { - val len = buf.getInt() - return buildMap(len) { - repeat(len) { - val k = FfiConverterString.read(buf) - val v = FfiConverterString.read(buf) - this[k] = v - } - } - } - - override fun allocationSize(value: Map): ULong { - val spaceForMapSize = 4UL - val spaceForChildren = value.map { (k, v) -> - FfiConverterString.allocationSize(k) + - FfiConverterString.allocationSize(v) - }.sum() - return spaceForMapSize + spaceForChildren - } - - override fun write(value: Map, buf: ByteBuffer) { - buf.putInt(value.size) - // The parens on `(k, v)` here ensure we're calling the right method, - // which is important for compatibility with older android devices. - // Ref https://blog.danlew.net/2017/03/16/kotlin-puzzler-whose-line-is-it-anyways/ - value.forEach { (k, v) -> - FfiConverterString.write(k, buf) - FfiConverterString.write(v, buf) - } - } -} - /** - * Synchronously classify the input. **No HTTP, no I/O.** - * - * Recognises BOLT11 invoices, node IDs, LNURL bech32 strings, and - * Lightning Addresses. Strips `lightning:` / `LIGHTNING:` prefixes - * automatically. LNURL inputs are decoded to their underlying URL - * but **not fetched** — the caller chooses whether to resolve - * further (via `resolve_input`) or to surface the URL to the user - * as-is. - * - * Use this for offline operations like clipboard validation or - * invoice sanity checks. Use `resolve_input` for the QR-scan flow - * where you want the resolved pay/withdraw data in one call. - */ - @Throws(Exception::class) fun `parseInput`(`input`: kotlin.String): ParsedInput { - return FfiConverterTypeParsedInput.lift( - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_func_parse_input( - FfiConverterString.lower(`input`),_status) -} - ) - } - - - /** - * Classify and resolve the input. - * - * Internally calls `parse_input` for offline classification, then - * for LNURL bech32 strings and Lightning Addresses performs the - * HTTP GET to the LNURL endpoint and returns typed pay or withdraw - * request data. For BOLT11 invoices and node IDs it returns - * immediately without I/O. - * - * Strips `lightning:` / `LIGHTNING:` prefixes automatically. - * - * # Blocking - * - * This function blocks the calling thread while any network I/O - * completes. The SDK exposes a **synchronous-only** public API so - * that every language binding (Python, Kotlin, Swift, Ruby, C++) - * works without requiring an async runtime on the caller side. - * Async work is executed internally on a shared Tokio runtime - * managed by the SDK. - */ - @Throws(Exception::class) fun `resolveInput`(`input`: kotlin.String): ResolvedInput { - return FfiConverterTypeResolvedInput.lift( - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_func_resolve_input( - FfiConverterString.lower(`input`),_status) -} - ) - } - - - /** - * Change the log filter at runtime without reinstalling the listener. - */ fun `setLogLevel`(`level`: LogLevel) - = - uniffiRustCall() { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_func_set_log_level( - FfiConverterTypeLogLevel.lower(`level`),_status) -} - - - - /** - * Set up SDK logging. Call once before any other SDK function. - * - * The listener receives all log messages from the SDK and the - * underlying Greenlight client library. Call once, as early as - * possible, so early logs are captured. Returns an error if a logger - * has already been installed in this process. To change the filter - * after installation, use `set_log_level`. - */ - @Throws(Exception::class) fun `setLogger`(`level`: LogLevel, `listener`: LogListener) - = - uniffiRustCallWithError(Exception) { _status -> - UniffiLib.INSTANCE.uniffi_glsdk_fn_func_set_logger( - FfiConverterTypeLogLevel.lower(`level`),FfiConverterTypeLogListener.lower(`listener`),_status) -} - - - -