mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-25 14:05:19 +00:00
2762 lines
97 KiB
Kotlin
2762 lines
97 KiB
Kotlin
// 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.cdk_ffi
|
|
|
|
// Common helper code.
|
|
//
|
|
// Ideally this would live in a separate .kt file where it can be unittested etc
|
|
// in isolation, and perhaps even published as a re-useable package.
|
|
//
|
|
// However, it's important that the details of how this helper code works (e.g. the
|
|
// way that different builtin types are passed across the FFI) exactly match what's
|
|
// expected by the Rust code on the other side of the interface. In practice right
|
|
// now that means coming from the exact some version of `uniffi` that was used to
|
|
// compile the Rust component. The easiest way to ensure this is to bundle the Kotlin
|
|
// helpers directly inline like we're doing here.
|
|
|
|
import com.sun.jna.Library
|
|
import com.sun.jna.IntegerType
|
|
import com.sun.jna.Native
|
|
import com.sun.jna.Pointer
|
|
import com.sun.jna.Structure
|
|
import com.sun.jna.Callback
|
|
import com.sun.jna.ptr.*
|
|
import java.nio.ByteBuffer
|
|
import java.nio.ByteOrder
|
|
import java.nio.CharBuffer
|
|
import java.nio.charset.CodingErrorAction
|
|
import java.util.concurrent.atomic.AtomicLong
|
|
import java.util.concurrent.ConcurrentHashMap
|
|
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_cdk_ffi_rustbuffer_alloc(size.toLong(), status)
|
|
}.also {
|
|
if(it.data == null) {
|
|
throw RuntimeException("RustBuffer.alloc() returned null data pointer (size=${size})")
|
|
}
|
|
}
|
|
|
|
internal fun create(capacity: ULong, len: ULong, data: Pointer?): RustBuffer.ByValue {
|
|
var buf = RustBuffer.ByValue()
|
|
buf.capacity = capacity.toLong()
|
|
buf.len = len.toLong()
|
|
buf.data = data
|
|
return buf
|
|
}
|
|
|
|
internal fun free(buf: RustBuffer.ByValue) = uniffiRustCall() { status ->
|
|
UniffiLib.INSTANCE.ffi_cdk_ffi_rustbuffer_free(buf, status)
|
|
}
|
|
}
|
|
|
|
@Suppress("TooGenericExceptionThrown")
|
|
fun asByteBuffer() =
|
|
this.data?.getByteBuffer(0, this.len.toLong())?.also {
|
|
it.order(ByteOrder.BIG_ENDIAN)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The equivalent of the `*mut RustBuffer` type.
|
|
* Required for callbacks taking in an out pointer.
|
|
*
|
|
* Size is the sum of all values in the struct.
|
|
*
|
|
* @suppress
|
|
*/
|
|
class RustBufferByReference : ByReference(16) {
|
|
/**
|
|
* Set the pointed-to `RustBuffer` to the given value.
|
|
*/
|
|
fun setValue(value: RustBuffer.ByValue) {
|
|
// NOTE: The offsets are as they are in the C-like struct.
|
|
val pointer = getPointer()
|
|
pointer.setLong(0, value.capacity)
|
|
pointer.setLong(8, value.len)
|
|
pointer.setPointer(16, value.data)
|
|
}
|
|
|
|
/**
|
|
* Get a `RustBuffer.ByValue` from this reference.
|
|
*/
|
|
fun getValue(): RustBuffer.ByValue {
|
|
val pointer = getPointer()
|
|
val value = RustBuffer.ByValue()
|
|
value.writeField("capacity", pointer.getLong(0))
|
|
value.writeField("len", pointer.getLong(8))
|
|
value.writeField("data", pointer.getLong(16))
|
|
|
|
return value
|
|
}
|
|
}
|
|
|
|
// This is a helper for safely passing byte references into the rust code.
|
|
// It's not actually used at the moment, because there aren't many things that you
|
|
// can take a direct pointer to in the JVM, and if we're going to copy something
|
|
// then we might as well copy it into a `RustBuffer`. But it's here for API
|
|
// completeness.
|
|
|
|
@Structure.FieldOrder("len", "data")
|
|
internal open class ForeignBytes : Structure() {
|
|
@JvmField var len: Int = 0
|
|
@JvmField var data: Pointer? = null
|
|
|
|
class ByValue : ForeignBytes(), Structure.ByValue
|
|
}
|
|
/**
|
|
* The FfiConverter interface handles converter types to and from the FFI
|
|
*
|
|
* All implementing objects should be public to support external types. When a
|
|
* type is external we need to import it's FfiConverter.
|
|
*
|
|
* @suppress
|
|
*/
|
|
public interface FfiConverter<KotlinType, FfiType> {
|
|
// 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<KotlinType>: FfiConverter<KotlinType, RustBuffer.ByValue> {
|
|
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<E> {
|
|
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 <U, E: kotlin.Exception> uniffiRustCallWithError(errorHandler: UniffiRustCallStatusErrorHandler<E>, 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<E: kotlin.Exception> uniffiCheckCallStatus(errorHandler: UniffiRustCallStatusErrorHandler<E>, 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<InternalException> {
|
|
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 <U> uniffiRustCall(callback: (UniffiRustCallStatus) -> U): U {
|
|
return uniffiRustCallWithError(UniffiNullRustCallStatusErrorHandler, callback)
|
|
}
|
|
|
|
internal inline fun<T> 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<T, reified E: Throwable> 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<T: Any> {
|
|
private val map = ConcurrentHashMap<Long, T>()
|
|
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 "cdk_ffi"
|
|
}
|
|
|
|
private inline fun <reified Lib : Library> loadIndirect(
|
|
componentName: String
|
|
): Lib {
|
|
return Native.load<Lib>(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,)
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 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 {
|
|
loadIndirect<UniffiLib>(componentName = "cdk_ffi")
|
|
.also { lib: UniffiLib ->
|
|
uniffiCheckContractApiVersion(lib)
|
|
uniffiCheckApiChecksums(lib)
|
|
}
|
|
}
|
|
|
|
// The Cleaner for the whole library
|
|
internal val CLEANER: UniffiCleaner by lazy {
|
|
UniffiCleaner.create()
|
|
}
|
|
}
|
|
|
|
fun uniffi_cdk_ffi_fn_clone_ffilocalstore(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus,
|
|
): Pointer
|
|
fun uniffi_cdk_ffi_fn_free_ffilocalstore(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus,
|
|
): Unit
|
|
fun uniffi_cdk_ffi_fn_constructor_ffilocalstore_new(uniffi_out_err: UniffiRustCallStatus,
|
|
): Pointer
|
|
fun uniffi_cdk_ffi_fn_constructor_ffilocalstore_new_with_path(`dbPath`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
|
|
): Pointer
|
|
fun uniffi_cdk_ffi_fn_clone_ffiwallet(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus,
|
|
): Pointer
|
|
fun uniffi_cdk_ffi_fn_free_ffiwallet(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus,
|
|
): Unit
|
|
fun uniffi_cdk_ffi_fn_constructor_ffiwallet_from_mnemonic(`mintUrl`: RustBuffer.ByValue,`unit`: RustBuffer.ByValue,`localstore`: Pointer,`mnemonicWords`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
|
|
): Pointer
|
|
fun uniffi_cdk_ffi_fn_constructor_ffiwallet_restore_from_mnemonic(`mintUrl`: RustBuffer.ByValue,`unit`: RustBuffer.ByValue,`localstore`: Pointer,`mnemonicWords`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
|
|
): Pointer
|
|
fun uniffi_cdk_ffi_fn_method_ffiwallet_balance(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus,
|
|
): RustBuffer.ByValue
|
|
fun uniffi_cdk_ffi_fn_method_ffiwallet_get_mint_info(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus,
|
|
): RustBuffer.ByValue
|
|
fun uniffi_cdk_ffi_fn_method_ffiwallet_melt(`ptr`: Pointer,`quoteId`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
|
|
): RustBuffer.ByValue
|
|
fun uniffi_cdk_ffi_fn_method_ffiwallet_melt_quote(`ptr`: Pointer,`request`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
|
|
): RustBuffer.ByValue
|
|
fun uniffi_cdk_ffi_fn_method_ffiwallet_mint(`ptr`: Pointer,`quoteId`: RustBuffer.ByValue,`splitTarget`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
|
|
): RustBuffer.ByValue
|
|
fun uniffi_cdk_ffi_fn_method_ffiwallet_mint_quote(`ptr`: Pointer,`amount`: RustBuffer.ByValue,`description`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
|
|
): RustBuffer.ByValue
|
|
fun uniffi_cdk_ffi_fn_method_ffiwallet_mint_quote_state(`ptr`: Pointer,`quoteId`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
|
|
): RustBuffer.ByValue
|
|
fun uniffi_cdk_ffi_fn_method_ffiwallet_mint_url(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus,
|
|
): RustBuffer.ByValue
|
|
fun uniffi_cdk_ffi_fn_method_ffiwallet_prepare_send(`ptr`: Pointer,`amount`: RustBuffer.ByValue,`options`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
|
|
): RustBuffer.ByValue
|
|
fun uniffi_cdk_ffi_fn_method_ffiwallet_receive(`ptr`: Pointer,`token`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
|
|
): RustBuffer.ByValue
|
|
fun uniffi_cdk_ffi_fn_method_ffiwallet_send(`ptr`: Pointer,`amount`: RustBuffer.ByValue,`options`: RustBuffer.ByValue,`memo`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
|
|
): RustBuffer.ByValue
|
|
fun uniffi_cdk_ffi_fn_method_ffiwallet_unit(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus,
|
|
): RustBuffer.ByValue
|
|
fun uniffi_cdk_ffi_fn_func_generate_mnemonic(uniffi_out_err: UniffiRustCallStatus,
|
|
): RustBuffer.ByValue
|
|
fun ffi_cdk_ffi_rustbuffer_alloc(`size`: Long,uniffi_out_err: UniffiRustCallStatus,
|
|
): RustBuffer.ByValue
|
|
fun ffi_cdk_ffi_rustbuffer_from_bytes(`bytes`: ForeignBytes.ByValue,uniffi_out_err: UniffiRustCallStatus,
|
|
): RustBuffer.ByValue
|
|
fun ffi_cdk_ffi_rustbuffer_free(`buf`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rustbuffer_reserve(`buf`: RustBuffer.ByValue,`additional`: Long,uniffi_out_err: UniffiRustCallStatus,
|
|
): RustBuffer.ByValue
|
|
fun ffi_cdk_ffi_rust_future_poll_u8(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_cancel_u8(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_free_u8(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_complete_u8(`handle`: Long,uniffi_out_err: UniffiRustCallStatus,
|
|
): Byte
|
|
fun ffi_cdk_ffi_rust_future_poll_i8(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_cancel_i8(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_free_i8(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_complete_i8(`handle`: Long,uniffi_out_err: UniffiRustCallStatus,
|
|
): Byte
|
|
fun ffi_cdk_ffi_rust_future_poll_u16(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_cancel_u16(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_free_u16(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_complete_u16(`handle`: Long,uniffi_out_err: UniffiRustCallStatus,
|
|
): Short
|
|
fun ffi_cdk_ffi_rust_future_poll_i16(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_cancel_i16(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_free_i16(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_complete_i16(`handle`: Long,uniffi_out_err: UniffiRustCallStatus,
|
|
): Short
|
|
fun ffi_cdk_ffi_rust_future_poll_u32(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_cancel_u32(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_free_u32(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_complete_u32(`handle`: Long,uniffi_out_err: UniffiRustCallStatus,
|
|
): Int
|
|
fun ffi_cdk_ffi_rust_future_poll_i32(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_cancel_i32(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_free_i32(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_complete_i32(`handle`: Long,uniffi_out_err: UniffiRustCallStatus,
|
|
): Int
|
|
fun ffi_cdk_ffi_rust_future_poll_u64(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_cancel_u64(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_free_u64(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_complete_u64(`handle`: Long,uniffi_out_err: UniffiRustCallStatus,
|
|
): Long
|
|
fun ffi_cdk_ffi_rust_future_poll_i64(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_cancel_i64(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_free_i64(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_complete_i64(`handle`: Long,uniffi_out_err: UniffiRustCallStatus,
|
|
): Long
|
|
fun ffi_cdk_ffi_rust_future_poll_f32(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_cancel_f32(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_free_f32(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_complete_f32(`handle`: Long,uniffi_out_err: UniffiRustCallStatus,
|
|
): Float
|
|
fun ffi_cdk_ffi_rust_future_poll_f64(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_cancel_f64(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_free_f64(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_complete_f64(`handle`: Long,uniffi_out_err: UniffiRustCallStatus,
|
|
): Double
|
|
fun ffi_cdk_ffi_rust_future_poll_pointer(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_cancel_pointer(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_free_pointer(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_complete_pointer(`handle`: Long,uniffi_out_err: UniffiRustCallStatus,
|
|
): Pointer
|
|
fun ffi_cdk_ffi_rust_future_poll_rust_buffer(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_cancel_rust_buffer(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_free_rust_buffer(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_complete_rust_buffer(`handle`: Long,uniffi_out_err: UniffiRustCallStatus,
|
|
): RustBuffer.ByValue
|
|
fun ffi_cdk_ffi_rust_future_poll_void(`handle`: Long,`callback`: UniffiRustFutureContinuationCallback,`callbackData`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_cancel_void(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_free_void(`handle`: Long,
|
|
): Unit
|
|
fun ffi_cdk_ffi_rust_future_complete_void(`handle`: Long,uniffi_out_err: UniffiRustCallStatus,
|
|
): Unit
|
|
fun uniffi_cdk_ffi_checksum_func_generate_mnemonic(
|
|
): Short
|
|
fun uniffi_cdk_ffi_checksum_method_ffiwallet_balance(
|
|
): Short
|
|
fun uniffi_cdk_ffi_checksum_method_ffiwallet_get_mint_info(
|
|
): Short
|
|
fun uniffi_cdk_ffi_checksum_method_ffiwallet_melt(
|
|
): Short
|
|
fun uniffi_cdk_ffi_checksum_method_ffiwallet_melt_quote(
|
|
): Short
|
|
fun uniffi_cdk_ffi_checksum_method_ffiwallet_mint(
|
|
): Short
|
|
fun uniffi_cdk_ffi_checksum_method_ffiwallet_mint_quote(
|
|
): Short
|
|
fun uniffi_cdk_ffi_checksum_method_ffiwallet_mint_quote_state(
|
|
): Short
|
|
fun uniffi_cdk_ffi_checksum_method_ffiwallet_mint_url(
|
|
): Short
|
|
fun uniffi_cdk_ffi_checksum_method_ffiwallet_prepare_send(
|
|
): Short
|
|
fun uniffi_cdk_ffi_checksum_method_ffiwallet_receive(
|
|
): Short
|
|
fun uniffi_cdk_ffi_checksum_method_ffiwallet_send(
|
|
): Short
|
|
fun uniffi_cdk_ffi_checksum_method_ffiwallet_unit(
|
|
): Short
|
|
fun uniffi_cdk_ffi_checksum_constructor_ffilocalstore_new(
|
|
): Short
|
|
fun uniffi_cdk_ffi_checksum_constructor_ffilocalstore_new_with_path(
|
|
): Short
|
|
fun uniffi_cdk_ffi_checksum_constructor_ffiwallet_from_mnemonic(
|
|
): Short
|
|
fun uniffi_cdk_ffi_checksum_constructor_ffiwallet_restore_from_mnemonic(
|
|
): Short
|
|
fun ffi_cdk_ffi_uniffi_contract_version(
|
|
): Int
|
|
|
|
}
|
|
|
|
private fun uniffiCheckContractApiVersion(lib: UniffiLib) {
|
|
// Get the bindings contract version from our ComponentInterface
|
|
val bindings_contract_version = 26
|
|
// Get the scaffolding contract version by calling the into the dylib
|
|
val scaffolding_contract_version = lib.ffi_cdk_ffi_uniffi_contract_version()
|
|
if (bindings_contract_version != scaffolding_contract_version) {
|
|
throw RuntimeException("UniFFI contract version mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
}
|
|
|
|
@Suppress("UNUSED_PARAMETER")
|
|
private fun uniffiCheckApiChecksums(lib: UniffiLib) {
|
|
if (lib.uniffi_cdk_ffi_checksum_func_generate_mnemonic() != 44815.toShort()) {
|
|
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
if (lib.uniffi_cdk_ffi_checksum_method_ffiwallet_balance() != 40463.toShort()) {
|
|
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
if (lib.uniffi_cdk_ffi_checksum_method_ffiwallet_get_mint_info() != 13159.toShort()) {
|
|
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
if (lib.uniffi_cdk_ffi_checksum_method_ffiwallet_melt() != 3275.toShort()) {
|
|
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
if (lib.uniffi_cdk_ffi_checksum_method_ffiwallet_melt_quote() != 39876.toShort()) {
|
|
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
if (lib.uniffi_cdk_ffi_checksum_method_ffiwallet_mint() != 58480.toShort()) {
|
|
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
if (lib.uniffi_cdk_ffi_checksum_method_ffiwallet_mint_quote() != 42885.toShort()) {
|
|
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
if (lib.uniffi_cdk_ffi_checksum_method_ffiwallet_mint_quote_state() != 60165.toShort()) {
|
|
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
if (lib.uniffi_cdk_ffi_checksum_method_ffiwallet_mint_url() != 18647.toShort()) {
|
|
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
if (lib.uniffi_cdk_ffi_checksum_method_ffiwallet_prepare_send() != 46706.toShort()) {
|
|
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
if (lib.uniffi_cdk_ffi_checksum_method_ffiwallet_receive() != 57605.toShort()) {
|
|
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
if (lib.uniffi_cdk_ffi_checksum_method_ffiwallet_send() != 15473.toShort()) {
|
|
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
if (lib.uniffi_cdk_ffi_checksum_method_ffiwallet_unit() != 4593.toShort()) {
|
|
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
if (lib.uniffi_cdk_ffi_checksum_constructor_ffilocalstore_new() != 15364.toShort()) {
|
|
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
if (lib.uniffi_cdk_ffi_checksum_constructor_ffilocalstore_new_with_path() != 766.toShort()) {
|
|
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
if (lib.uniffi_cdk_ffi_checksum_constructor_ffiwallet_from_mnemonic() != 63545.toShort()) {
|
|
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
if (lib.uniffi_cdk_ffi_checksum_constructor_ffiwallet_restore_from_mnemonic() != 38466.toShort()) {
|
|
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
|
}
|
|
}
|
|
|
|
// 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?) {
|
|
args.filterIsInstance<Disposable>()
|
|
.forEach(Disposable::destroy)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
inline fun <T : Disposable?, R> T.use(block: (T) -> R) =
|
|
try {
|
|
block(this)
|
|
} finally {
|
|
try {
|
|
// N.B. our implementation is on the nullable type `Disposable?`.
|
|
this?.destroy()
|
|
} catch (e: Throwable) {
|
|
// swallow
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Used to instantiate an interface without an actual pointer, for fakes in tests, mostly.
|
|
*
|
|
* @suppress
|
|
* */
|
|
object NoPointer
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterULong: FfiConverter<ULong, Long> {
|
|
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<Boolean, Byte> {
|
|
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<String, RustBuffer.ByValue> {
|
|
// 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)
|
|
}
|
|
}
|
|
|
|
|
|
// This template implements a class for working with a Rust struct via a Pointer/Arc<T>
|
|
// to the live Rust struct on the other side of the FFI.
|
|
//
|
|
// Each instance implements core operations for working with the Rust `Arc<T>` 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<T>` 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 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()
|
|
}
|
|
public interface FfiLocalStoreInterface {
|
|
|
|
companion object
|
|
}
|
|
|
|
open class FfiLocalStore: Disposable, AutoCloseable, FfiLocalStoreInterface {
|
|
|
|
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() :
|
|
this(
|
|
uniffiRustCallWithError(FfiException) { _status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_constructor_ffilocalstore_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 <R> 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_cdk_ffi_fn_free_ffilocalstore(ptr, status)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fun uniffiClonePointer(): Pointer {
|
|
return uniffiRustCall() { status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_clone_ffilocalstore(pointer!!, status)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
@Throws(FfiException::class) fun `newWithPath`(`dbPath`: kotlin.String?): FfiLocalStore {
|
|
return FfiConverterTypeFFILocalStore.lift(
|
|
uniffiRustCallWithError(FfiException) { _status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_constructor_ffilocalstore_new_with_path(
|
|
FfiConverterOptionalString.lower(`dbPath`),_status)
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterTypeFFILocalStore: FfiConverter<FfiLocalStore, Pointer> {
|
|
|
|
override fun lower(value: FfiLocalStore): Pointer {
|
|
return value.uniffiClonePointer()
|
|
}
|
|
|
|
override fun lift(value: Pointer): FfiLocalStore {
|
|
return FfiLocalStore(value)
|
|
}
|
|
|
|
override fun read(buf: ByteBuffer): FfiLocalStore {
|
|
// 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: FfiLocalStore) = 8UL
|
|
|
|
override fun write(value: FfiLocalStore, 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<T>
|
|
// to the live Rust struct on the other side of the FFI.
|
|
//
|
|
// Each instance implements core operations for working with the Rust `Arc<T>` 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<T>` 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 FfiWalletInterface {
|
|
|
|
fun `balance`(): FfiAmount
|
|
|
|
/**
|
|
* Fetch and initialize mint information
|
|
* This should be called after wallet creation to set up the mint in the database
|
|
*/
|
|
fun `getMintInfo`(): kotlin.String
|
|
|
|
/**
|
|
* Execute a melt operation (pay Lightning invoice)
|
|
*/
|
|
fun `melt`(`quoteId`: kotlin.String): FfiMelted
|
|
|
|
/**
|
|
* Create a melt quote for paying a Lightning invoice
|
|
*/
|
|
fun `meltQuote`(`request`: kotlin.String): FfiMeltQuote
|
|
|
|
fun `mint`(`quoteId`: kotlin.String, `splitTarget`: FfiSplitTarget): FfiAmount
|
|
|
|
fun `mintQuote`(`amount`: FfiAmount, `description`: kotlin.String?): FfiMintQuote
|
|
|
|
fun `mintQuoteState`(`quoteId`: kotlin.String): FfiMintQuoteBolt11Response
|
|
|
|
fun `mintUrl`(): kotlin.String
|
|
|
|
fun `prepareSend`(`amount`: FfiAmount, `options`: FfiSendOptions): FfiPreparedSend
|
|
|
|
/**
|
|
* Receive token
|
|
*/
|
|
fun `receive`(`token`: kotlin.String): FfiAmount
|
|
|
|
fun `send`(`amount`: FfiAmount, `options`: FfiSendOptions, `memo`: FfiSendMemo?): FfiToken
|
|
|
|
fun `unit`(): kotlin.String
|
|
|
|
companion object
|
|
}
|
|
|
|
open class FfiWallet: Disposable, AutoCloseable, FfiWalletInterface {
|
|
|
|
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 <R> 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_cdk_ffi_fn_free_ffiwallet(ptr, status)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fun uniffiClonePointer(): Pointer {
|
|
return uniffiRustCall() { status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_clone_ffiwallet(pointer!!, status)
|
|
}
|
|
}
|
|
|
|
|
|
@Throws(FfiException::class)override fun `balance`(): FfiAmount {
|
|
return FfiConverterTypeFFIAmount.lift(
|
|
callWithPointer {
|
|
uniffiRustCallWithError(FfiException) { _status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_method_ffiwallet_balance(
|
|
it, _status)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Fetch and initialize mint information
|
|
* This should be called after wallet creation to set up the mint in the database
|
|
*/
|
|
@Throws(FfiException::class)override fun `getMintInfo`(): kotlin.String {
|
|
return FfiConverterString.lift(
|
|
callWithPointer {
|
|
uniffiRustCallWithError(FfiException) { _status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_method_ffiwallet_get_mint_info(
|
|
it, _status)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Execute a melt operation (pay Lightning invoice)
|
|
*/
|
|
@Throws(FfiException::class)override fun `melt`(`quoteId`: kotlin.String): FfiMelted {
|
|
return FfiConverterTypeFFIMelted.lift(
|
|
callWithPointer {
|
|
uniffiRustCallWithError(FfiException) { _status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_method_ffiwallet_melt(
|
|
it, FfiConverterString.lower(`quoteId`),_status)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Create a melt quote for paying a Lightning invoice
|
|
*/
|
|
@Throws(FfiException::class)override fun `meltQuote`(`request`: kotlin.String): FfiMeltQuote {
|
|
return FfiConverterTypeFFIMeltQuote.lift(
|
|
callWithPointer {
|
|
uniffiRustCallWithError(FfiException) { _status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_method_ffiwallet_melt_quote(
|
|
it, FfiConverterString.lower(`request`),_status)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
|
|
@Throws(FfiException::class)override fun `mint`(`quoteId`: kotlin.String, `splitTarget`: FfiSplitTarget): FfiAmount {
|
|
return FfiConverterTypeFFIAmount.lift(
|
|
callWithPointer {
|
|
uniffiRustCallWithError(FfiException) { _status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_method_ffiwallet_mint(
|
|
it, FfiConverterString.lower(`quoteId`),FfiConverterTypeFFISplitTarget.lower(`splitTarget`),_status)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
|
|
@Throws(FfiException::class)override fun `mintQuote`(`amount`: FfiAmount, `description`: kotlin.String?): FfiMintQuote {
|
|
return FfiConverterTypeFFIMintQuote.lift(
|
|
callWithPointer {
|
|
uniffiRustCallWithError(FfiException) { _status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_method_ffiwallet_mint_quote(
|
|
it, FfiConverterTypeFFIAmount.lower(`amount`),FfiConverterOptionalString.lower(`description`),_status)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
|
|
@Throws(FfiException::class)override fun `mintQuoteState`(`quoteId`: kotlin.String): FfiMintQuoteBolt11Response {
|
|
return FfiConverterTypeFFIMintQuoteBolt11Response.lift(
|
|
callWithPointer {
|
|
uniffiRustCallWithError(FfiException) { _status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_method_ffiwallet_mint_quote_state(
|
|
it, FfiConverterString.lower(`quoteId`),_status)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
override fun `mintUrl`(): kotlin.String {
|
|
return FfiConverterString.lift(
|
|
callWithPointer {
|
|
uniffiRustCall() { _status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_method_ffiwallet_mint_url(
|
|
it, _status)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
|
|
@Throws(FfiException::class)override fun `prepareSend`(`amount`: FfiAmount, `options`: FfiSendOptions): FfiPreparedSend {
|
|
return FfiConverterTypeFFIPreparedSend.lift(
|
|
callWithPointer {
|
|
uniffiRustCallWithError(FfiException) { _status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_method_ffiwallet_prepare_send(
|
|
it, FfiConverterTypeFFIAmount.lower(`amount`),FfiConverterTypeFFISendOptions.lower(`options`),_status)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Receive token
|
|
*/
|
|
@Throws(FfiException::class)override fun `receive`(`token`: kotlin.String): FfiAmount {
|
|
return FfiConverterTypeFFIAmount.lift(
|
|
callWithPointer {
|
|
uniffiRustCallWithError(FfiException) { _status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_method_ffiwallet_receive(
|
|
it, FfiConverterString.lower(`token`),_status)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
|
|
@Throws(FfiException::class)override fun `send`(`amount`: FfiAmount, `options`: FfiSendOptions, `memo`: FfiSendMemo?): FfiToken {
|
|
return FfiConverterTypeFFIToken.lift(
|
|
callWithPointer {
|
|
uniffiRustCallWithError(FfiException) { _status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_method_ffiwallet_send(
|
|
it, FfiConverterTypeFFIAmount.lower(`amount`),FfiConverterTypeFFISendOptions.lower(`options`),FfiConverterOptionalTypeFFISendMemo.lower(`memo`),_status)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
override fun `unit`(): kotlin.String {
|
|
return FfiConverterString.lift(
|
|
callWithPointer {
|
|
uniffiRustCall() { _status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_method_ffiwallet_unit(
|
|
it, _status)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
@Throws(FfiException::class) fun `fromMnemonic`(`mintUrl`: kotlin.String, `unit`: FfiCurrencyUnit, `localstore`: FfiLocalStore, `mnemonicWords`: kotlin.String): FfiWallet {
|
|
return FfiConverterTypeFFIWallet.lift(
|
|
uniffiRustCallWithError(FfiException) { _status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_constructor_ffiwallet_from_mnemonic(
|
|
FfiConverterString.lower(`mintUrl`),FfiConverterTypeFFICurrencyUnit.lower(`unit`),FfiConverterTypeFFILocalStore.lower(`localstore`),FfiConverterString.lower(`mnemonicWords`),_status)
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
|
|
@Throws(FfiException::class) fun `restoreFromMnemonic`(`mintUrl`: kotlin.String, `unit`: FfiCurrencyUnit, `localstore`: FfiLocalStore, `mnemonicWords`: kotlin.String): FfiWallet {
|
|
return FfiConverterTypeFFIWallet.lift(
|
|
uniffiRustCallWithError(FfiException) { _status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_constructor_ffiwallet_restore_from_mnemonic(
|
|
FfiConverterString.lower(`mintUrl`),FfiConverterTypeFFICurrencyUnit.lower(`unit`),FfiConverterTypeFFILocalStore.lower(`localstore`),FfiConverterString.lower(`mnemonicWords`),_status)
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterTypeFFIWallet: FfiConverter<FfiWallet, Pointer> {
|
|
|
|
override fun lower(value: FfiWallet): Pointer {
|
|
return value.uniffiClonePointer()
|
|
}
|
|
|
|
override fun lift(value: Pointer): FfiWallet {
|
|
return FfiWallet(value)
|
|
}
|
|
|
|
override fun read(buf: ByteBuffer): FfiWallet {
|
|
// 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: FfiWallet) = 8UL
|
|
|
|
override fun write(value: FfiWallet, 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 FfiAmount (
|
|
var `value`: kotlin.ULong
|
|
) {
|
|
|
|
companion object
|
|
}
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterTypeFFIAmount: FfiConverterRustBuffer<FfiAmount> {
|
|
override fun read(buf: ByteBuffer): FfiAmount {
|
|
return FfiAmount(
|
|
FfiConverterULong.read(buf),
|
|
)
|
|
}
|
|
|
|
override fun allocationSize(value: FfiAmount) = (
|
|
FfiConverterULong.allocationSize(value.`value`)
|
|
)
|
|
|
|
override fun write(value: FfiAmount, buf: ByteBuffer) {
|
|
FfiConverterULong.write(value.`value`, buf)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
data class FfiMeltQuote (
|
|
var `id`: kotlin.String,
|
|
var `unit`: kotlin.String,
|
|
var `amount`: FfiAmount,
|
|
var `request`: kotlin.String,
|
|
var `feeReserve`: FfiAmount,
|
|
var `expiry`: kotlin.ULong,
|
|
var `paymentPreimage`: kotlin.String?
|
|
) {
|
|
|
|
companion object
|
|
}
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterTypeFFIMeltQuote: FfiConverterRustBuffer<FfiMeltQuote> {
|
|
override fun read(buf: ByteBuffer): FfiMeltQuote {
|
|
return FfiMeltQuote(
|
|
FfiConverterString.read(buf),
|
|
FfiConverterString.read(buf),
|
|
FfiConverterTypeFFIAmount.read(buf),
|
|
FfiConverterString.read(buf),
|
|
FfiConverterTypeFFIAmount.read(buf),
|
|
FfiConverterULong.read(buf),
|
|
FfiConverterOptionalString.read(buf),
|
|
)
|
|
}
|
|
|
|
override fun allocationSize(value: FfiMeltQuote) = (
|
|
FfiConverterString.allocationSize(value.`id`) +
|
|
FfiConverterString.allocationSize(value.`unit`) +
|
|
FfiConverterTypeFFIAmount.allocationSize(value.`amount`) +
|
|
FfiConverterString.allocationSize(value.`request`) +
|
|
FfiConverterTypeFFIAmount.allocationSize(value.`feeReserve`) +
|
|
FfiConverterULong.allocationSize(value.`expiry`) +
|
|
FfiConverterOptionalString.allocationSize(value.`paymentPreimage`)
|
|
)
|
|
|
|
override fun write(value: FfiMeltQuote, buf: ByteBuffer) {
|
|
FfiConverterString.write(value.`id`, buf)
|
|
FfiConverterString.write(value.`unit`, buf)
|
|
FfiConverterTypeFFIAmount.write(value.`amount`, buf)
|
|
FfiConverterString.write(value.`request`, buf)
|
|
FfiConverterTypeFFIAmount.write(value.`feeReserve`, buf)
|
|
FfiConverterULong.write(value.`expiry`, buf)
|
|
FfiConverterOptionalString.write(value.`paymentPreimage`, buf)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
data class FfiMelted (
|
|
var `state`: kotlin.String,
|
|
var `preimage`: kotlin.String?,
|
|
var `amount`: FfiAmount,
|
|
var `feePaid`: FfiAmount
|
|
) {
|
|
|
|
companion object
|
|
}
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterTypeFFIMelted: FfiConverterRustBuffer<FfiMelted> {
|
|
override fun read(buf: ByteBuffer): FfiMelted {
|
|
return FfiMelted(
|
|
FfiConverterString.read(buf),
|
|
FfiConverterOptionalString.read(buf),
|
|
FfiConverterTypeFFIAmount.read(buf),
|
|
FfiConverterTypeFFIAmount.read(buf),
|
|
)
|
|
}
|
|
|
|
override fun allocationSize(value: FfiMelted) = (
|
|
FfiConverterString.allocationSize(value.`state`) +
|
|
FfiConverterOptionalString.allocationSize(value.`preimage`) +
|
|
FfiConverterTypeFFIAmount.allocationSize(value.`amount`) +
|
|
FfiConverterTypeFFIAmount.allocationSize(value.`feePaid`)
|
|
)
|
|
|
|
override fun write(value: FfiMelted, buf: ByteBuffer) {
|
|
FfiConverterString.write(value.`state`, buf)
|
|
FfiConverterOptionalString.write(value.`preimage`, buf)
|
|
FfiConverterTypeFFIAmount.write(value.`amount`, buf)
|
|
FfiConverterTypeFFIAmount.write(value.`feePaid`, buf)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
data class FfiMintQuote (
|
|
var `id`: kotlin.String,
|
|
var `mintUrl`: kotlin.String,
|
|
var `amount`: FfiAmount,
|
|
var `unit`: kotlin.String,
|
|
var `request`: kotlin.String,
|
|
var `state`: FfiMintQuoteState,
|
|
var `expiry`: kotlin.ULong
|
|
) {
|
|
|
|
companion object
|
|
}
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterTypeFFIMintQuote: FfiConverterRustBuffer<FfiMintQuote> {
|
|
override fun read(buf: ByteBuffer): FfiMintQuote {
|
|
return FfiMintQuote(
|
|
FfiConverterString.read(buf),
|
|
FfiConverterString.read(buf),
|
|
FfiConverterTypeFFIAmount.read(buf),
|
|
FfiConverterString.read(buf),
|
|
FfiConverterString.read(buf),
|
|
FfiConverterTypeFFIMintQuoteState.read(buf),
|
|
FfiConverterULong.read(buf),
|
|
)
|
|
}
|
|
|
|
override fun allocationSize(value: FfiMintQuote) = (
|
|
FfiConverterString.allocationSize(value.`id`) +
|
|
FfiConverterString.allocationSize(value.`mintUrl`) +
|
|
FfiConverterTypeFFIAmount.allocationSize(value.`amount`) +
|
|
FfiConverterString.allocationSize(value.`unit`) +
|
|
FfiConverterString.allocationSize(value.`request`) +
|
|
FfiConverterTypeFFIMintQuoteState.allocationSize(value.`state`) +
|
|
FfiConverterULong.allocationSize(value.`expiry`)
|
|
)
|
|
|
|
override fun write(value: FfiMintQuote, buf: ByteBuffer) {
|
|
FfiConverterString.write(value.`id`, buf)
|
|
FfiConverterString.write(value.`mintUrl`, buf)
|
|
FfiConverterTypeFFIAmount.write(value.`amount`, buf)
|
|
FfiConverterString.write(value.`unit`, buf)
|
|
FfiConverterString.write(value.`request`, buf)
|
|
FfiConverterTypeFFIMintQuoteState.write(value.`state`, buf)
|
|
FfiConverterULong.write(value.`expiry`, buf)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
data class FfiMintQuoteBolt11Response (
|
|
var `quote`: kotlin.String,
|
|
var `request`: kotlin.String,
|
|
var `state`: FfiMintQuoteState,
|
|
var `expiry`: kotlin.ULong?
|
|
) {
|
|
|
|
companion object
|
|
}
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterTypeFFIMintQuoteBolt11Response: FfiConverterRustBuffer<FfiMintQuoteBolt11Response> {
|
|
override fun read(buf: ByteBuffer): FfiMintQuoteBolt11Response {
|
|
return FfiMintQuoteBolt11Response(
|
|
FfiConverterString.read(buf),
|
|
FfiConverterString.read(buf),
|
|
FfiConverterTypeFFIMintQuoteState.read(buf),
|
|
FfiConverterOptionalULong.read(buf),
|
|
)
|
|
}
|
|
|
|
override fun allocationSize(value: FfiMintQuoteBolt11Response) = (
|
|
FfiConverterString.allocationSize(value.`quote`) +
|
|
FfiConverterString.allocationSize(value.`request`) +
|
|
FfiConverterTypeFFIMintQuoteState.allocationSize(value.`state`) +
|
|
FfiConverterOptionalULong.allocationSize(value.`expiry`)
|
|
)
|
|
|
|
override fun write(value: FfiMintQuoteBolt11Response, buf: ByteBuffer) {
|
|
FfiConverterString.write(value.`quote`, buf)
|
|
FfiConverterString.write(value.`request`, buf)
|
|
FfiConverterTypeFFIMintQuoteState.write(value.`state`, buf)
|
|
FfiConverterOptionalULong.write(value.`expiry`, buf)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
data class FfiPreparedSend (
|
|
var `amount`: FfiAmount,
|
|
var `swapFee`: FfiAmount,
|
|
var `sendFee`: FfiAmount,
|
|
var `totalFee`: FfiAmount
|
|
) {
|
|
|
|
companion object
|
|
}
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterTypeFFIPreparedSend: FfiConverterRustBuffer<FfiPreparedSend> {
|
|
override fun read(buf: ByteBuffer): FfiPreparedSend {
|
|
return FfiPreparedSend(
|
|
FfiConverterTypeFFIAmount.read(buf),
|
|
FfiConverterTypeFFIAmount.read(buf),
|
|
FfiConverterTypeFFIAmount.read(buf),
|
|
FfiConverterTypeFFIAmount.read(buf),
|
|
)
|
|
}
|
|
|
|
override fun allocationSize(value: FfiPreparedSend) = (
|
|
FfiConverterTypeFFIAmount.allocationSize(value.`amount`) +
|
|
FfiConverterTypeFFIAmount.allocationSize(value.`swapFee`) +
|
|
FfiConverterTypeFFIAmount.allocationSize(value.`sendFee`) +
|
|
FfiConverterTypeFFIAmount.allocationSize(value.`totalFee`)
|
|
)
|
|
|
|
override fun write(value: FfiPreparedSend, buf: ByteBuffer) {
|
|
FfiConverterTypeFFIAmount.write(value.`amount`, buf)
|
|
FfiConverterTypeFFIAmount.write(value.`swapFee`, buf)
|
|
FfiConverterTypeFFIAmount.write(value.`sendFee`, buf)
|
|
FfiConverterTypeFFIAmount.write(value.`totalFee`, buf)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
data class FfiSendMemo (
|
|
var `memo`: kotlin.String,
|
|
var `includeMemo`: kotlin.Boolean
|
|
) {
|
|
|
|
companion object
|
|
}
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterTypeFFISendMemo: FfiConverterRustBuffer<FfiSendMemo> {
|
|
override fun read(buf: ByteBuffer): FfiSendMemo {
|
|
return FfiSendMemo(
|
|
FfiConverterString.read(buf),
|
|
FfiConverterBoolean.read(buf),
|
|
)
|
|
}
|
|
|
|
override fun allocationSize(value: FfiSendMemo) = (
|
|
FfiConverterString.allocationSize(value.`memo`) +
|
|
FfiConverterBoolean.allocationSize(value.`includeMemo`)
|
|
)
|
|
|
|
override fun write(value: FfiSendMemo, buf: ByteBuffer) {
|
|
FfiConverterString.write(value.`memo`, buf)
|
|
FfiConverterBoolean.write(value.`includeMemo`, buf)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
data class FfiSendOptions (
|
|
var `memo`: FfiSendMemo?,
|
|
var `amountSplitTarget`: FfiSplitTarget,
|
|
var `sendKind`: FfiSendKind,
|
|
var `includeFee`: kotlin.Boolean,
|
|
var `metadata`: Map<kotlin.String, kotlin.String>,
|
|
var `maxProofs`: kotlin.ULong?
|
|
) {
|
|
|
|
companion object
|
|
}
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterTypeFFISendOptions: FfiConverterRustBuffer<FfiSendOptions> {
|
|
override fun read(buf: ByteBuffer): FfiSendOptions {
|
|
return FfiSendOptions(
|
|
FfiConverterOptionalTypeFFISendMemo.read(buf),
|
|
FfiConverterTypeFFISplitTarget.read(buf),
|
|
FfiConverterTypeFFISendKind.read(buf),
|
|
FfiConverterBoolean.read(buf),
|
|
FfiConverterMapStringString.read(buf),
|
|
FfiConverterOptionalULong.read(buf),
|
|
)
|
|
}
|
|
|
|
override fun allocationSize(value: FfiSendOptions) = (
|
|
FfiConverterOptionalTypeFFISendMemo.allocationSize(value.`memo`) +
|
|
FfiConverterTypeFFISplitTarget.allocationSize(value.`amountSplitTarget`) +
|
|
FfiConverterTypeFFISendKind.allocationSize(value.`sendKind`) +
|
|
FfiConverterBoolean.allocationSize(value.`includeFee`) +
|
|
FfiConverterMapStringString.allocationSize(value.`metadata`) +
|
|
FfiConverterOptionalULong.allocationSize(value.`maxProofs`)
|
|
)
|
|
|
|
override fun write(value: FfiSendOptions, buf: ByteBuffer) {
|
|
FfiConverterOptionalTypeFFISendMemo.write(value.`memo`, buf)
|
|
FfiConverterTypeFFISplitTarget.write(value.`amountSplitTarget`, buf)
|
|
FfiConverterTypeFFISendKind.write(value.`sendKind`, buf)
|
|
FfiConverterBoolean.write(value.`includeFee`, buf)
|
|
FfiConverterMapStringString.write(value.`metadata`, buf)
|
|
FfiConverterOptionalULong.write(value.`maxProofs`, buf)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
data class FfiToken (
|
|
var `tokenString`: kotlin.String,
|
|
var `mint`: kotlin.String,
|
|
var `memo`: kotlin.String?,
|
|
var `unit`: kotlin.String
|
|
) {
|
|
|
|
companion object
|
|
}
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterTypeFFIToken: FfiConverterRustBuffer<FfiToken> {
|
|
override fun read(buf: ByteBuffer): FfiToken {
|
|
return FfiToken(
|
|
FfiConverterString.read(buf),
|
|
FfiConverterString.read(buf),
|
|
FfiConverterOptionalString.read(buf),
|
|
FfiConverterString.read(buf),
|
|
)
|
|
}
|
|
|
|
override fun allocationSize(value: FfiToken) = (
|
|
FfiConverterString.allocationSize(value.`tokenString`) +
|
|
FfiConverterString.allocationSize(value.`mint`) +
|
|
FfiConverterOptionalString.allocationSize(value.`memo`) +
|
|
FfiConverterString.allocationSize(value.`unit`)
|
|
)
|
|
|
|
override fun write(value: FfiToken, buf: ByteBuffer) {
|
|
FfiConverterString.write(value.`tokenString`, buf)
|
|
FfiConverterString.write(value.`mint`, buf)
|
|
FfiConverterOptionalString.write(value.`memo`, buf)
|
|
FfiConverterString.write(value.`unit`, buf)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
enum class FfiCurrencyUnit {
|
|
|
|
SAT,
|
|
MSAT,
|
|
USD,
|
|
EUR;
|
|
companion object
|
|
}
|
|
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterTypeFFICurrencyUnit: FfiConverterRustBuffer<FfiCurrencyUnit> {
|
|
override fun read(buf: ByteBuffer) = try {
|
|
FfiCurrencyUnit.values()[buf.getInt() - 1]
|
|
} catch (e: IndexOutOfBoundsException) {
|
|
throw RuntimeException("invalid enum value, something is very wrong!!", e)
|
|
}
|
|
|
|
override fun allocationSize(value: FfiCurrencyUnit) = 4UL
|
|
|
|
override fun write(value: FfiCurrencyUnit, buf: ByteBuffer) {
|
|
buf.putInt(value.ordinal + 1)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sealed class FfiException: kotlin.Exception() {
|
|
|
|
class WalletException(
|
|
|
|
val `msg`: kotlin.String
|
|
) : FfiException() {
|
|
override val message
|
|
get() = "msg=${ `msg` }"
|
|
}
|
|
|
|
class InvalidInput(
|
|
|
|
val `msg`: kotlin.String
|
|
) : FfiException() {
|
|
override val message
|
|
get() = "msg=${ `msg` }"
|
|
}
|
|
|
|
class NetworkException(
|
|
|
|
val `msg`: kotlin.String
|
|
) : FfiException() {
|
|
override val message
|
|
get() = "msg=${ `msg` }"
|
|
}
|
|
|
|
class InternalException(
|
|
|
|
val `msg`: kotlin.String
|
|
) : FfiException() {
|
|
override val message
|
|
get() = "msg=${ `msg` }"
|
|
}
|
|
|
|
|
|
companion object ErrorHandler : UniffiRustCallStatusErrorHandler<FfiException> {
|
|
override fun lift(error_buf: RustBuffer.ByValue): FfiException = FfiConverterTypeFFIError.lift(error_buf)
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterTypeFFIError : FfiConverterRustBuffer<FfiException> {
|
|
override fun read(buf: ByteBuffer): FfiException {
|
|
|
|
|
|
return when(buf.getInt()) {
|
|
1 -> FfiException.WalletException(
|
|
FfiConverterString.read(buf),
|
|
)
|
|
2 -> FfiException.InvalidInput(
|
|
FfiConverterString.read(buf),
|
|
)
|
|
3 -> FfiException.NetworkException(
|
|
FfiConverterString.read(buf),
|
|
)
|
|
4 -> FfiException.InternalException(
|
|
FfiConverterString.read(buf),
|
|
)
|
|
else -> throw RuntimeException("invalid error enum value, something is very wrong!!")
|
|
}
|
|
}
|
|
|
|
override fun allocationSize(value: FfiException): ULong {
|
|
return when(value) {
|
|
is FfiException.WalletException -> (
|
|
// Add the size for the Int that specifies the variant plus the size needed for all fields
|
|
4UL
|
|
+ FfiConverterString.allocationSize(value.`msg`)
|
|
)
|
|
is FfiException.InvalidInput -> (
|
|
// Add the size for the Int that specifies the variant plus the size needed for all fields
|
|
4UL
|
|
+ FfiConverterString.allocationSize(value.`msg`)
|
|
)
|
|
is FfiException.NetworkException -> (
|
|
// Add the size for the Int that specifies the variant plus the size needed for all fields
|
|
4UL
|
|
+ FfiConverterString.allocationSize(value.`msg`)
|
|
)
|
|
is FfiException.InternalException -> (
|
|
// Add the size for the Int that specifies the variant plus the size needed for all fields
|
|
4UL
|
|
+ FfiConverterString.allocationSize(value.`msg`)
|
|
)
|
|
}
|
|
}
|
|
|
|
override fun write(value: FfiException, buf: ByteBuffer) {
|
|
when(value) {
|
|
is FfiException.WalletException -> {
|
|
buf.putInt(1)
|
|
FfiConverterString.write(value.`msg`, buf)
|
|
Unit
|
|
}
|
|
is FfiException.InvalidInput -> {
|
|
buf.putInt(2)
|
|
FfiConverterString.write(value.`msg`, buf)
|
|
Unit
|
|
}
|
|
is FfiException.NetworkException -> {
|
|
buf.putInt(3)
|
|
FfiConverterString.write(value.`msg`, buf)
|
|
Unit
|
|
}
|
|
is FfiException.InternalException -> {
|
|
buf.putInt(4)
|
|
FfiConverterString.write(value.`msg`, buf)
|
|
Unit
|
|
}
|
|
}.let { /* this makes the `when` an expression, which ensures it is exhaustive */ }
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum class FfiMintQuoteState {
|
|
|
|
UNPAID,
|
|
PAID,
|
|
ISSUED;
|
|
companion object
|
|
}
|
|
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterTypeFFIMintQuoteState: FfiConverterRustBuffer<FfiMintQuoteState> {
|
|
override fun read(buf: ByteBuffer) = try {
|
|
FfiMintQuoteState.values()[buf.getInt() - 1]
|
|
} catch (e: IndexOutOfBoundsException) {
|
|
throw RuntimeException("invalid enum value, something is very wrong!!", e)
|
|
}
|
|
|
|
override fun allocationSize(value: FfiMintQuoteState) = 4UL
|
|
|
|
override fun write(value: FfiMintQuoteState, buf: ByteBuffer) {
|
|
buf.putInt(value.ordinal + 1)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sealed class FfiSendKind {
|
|
|
|
object OnlineExact : FfiSendKind()
|
|
|
|
|
|
data class OnlineTolerance(
|
|
val `tolerance`: FfiAmount) : FfiSendKind() {
|
|
companion object
|
|
}
|
|
|
|
object OfflineExact : FfiSendKind()
|
|
|
|
|
|
data class OfflineTolerance(
|
|
val `tolerance`: FfiAmount) : FfiSendKind() {
|
|
companion object
|
|
}
|
|
|
|
|
|
|
|
companion object
|
|
}
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterTypeFFISendKind : FfiConverterRustBuffer<FfiSendKind>{
|
|
override fun read(buf: ByteBuffer): FfiSendKind {
|
|
return when(buf.getInt()) {
|
|
1 -> FfiSendKind.OnlineExact
|
|
2 -> FfiSendKind.OnlineTolerance(
|
|
FfiConverterTypeFFIAmount.read(buf),
|
|
)
|
|
3 -> FfiSendKind.OfflineExact
|
|
4 -> FfiSendKind.OfflineTolerance(
|
|
FfiConverterTypeFFIAmount.read(buf),
|
|
)
|
|
else -> throw RuntimeException("invalid enum value, something is very wrong!!")
|
|
}
|
|
}
|
|
|
|
override fun allocationSize(value: FfiSendKind) = when(value) {
|
|
is FfiSendKind.OnlineExact -> {
|
|
// Add the size for the Int that specifies the variant plus the size needed for all fields
|
|
(
|
|
4UL
|
|
)
|
|
}
|
|
is FfiSendKind.OnlineTolerance -> {
|
|
// Add the size for the Int that specifies the variant plus the size needed for all fields
|
|
(
|
|
4UL
|
|
+ FfiConverterTypeFFIAmount.allocationSize(value.`tolerance`)
|
|
)
|
|
}
|
|
is FfiSendKind.OfflineExact -> {
|
|
// Add the size for the Int that specifies the variant plus the size needed for all fields
|
|
(
|
|
4UL
|
|
)
|
|
}
|
|
is FfiSendKind.OfflineTolerance -> {
|
|
// Add the size for the Int that specifies the variant plus the size needed for all fields
|
|
(
|
|
4UL
|
|
+ FfiConverterTypeFFIAmount.allocationSize(value.`tolerance`)
|
|
)
|
|
}
|
|
}
|
|
|
|
override fun write(value: FfiSendKind, buf: ByteBuffer) {
|
|
when(value) {
|
|
is FfiSendKind.OnlineExact -> {
|
|
buf.putInt(1)
|
|
Unit
|
|
}
|
|
is FfiSendKind.OnlineTolerance -> {
|
|
buf.putInt(2)
|
|
FfiConverterTypeFFIAmount.write(value.`tolerance`, buf)
|
|
Unit
|
|
}
|
|
is FfiSendKind.OfflineExact -> {
|
|
buf.putInt(3)
|
|
Unit
|
|
}
|
|
is FfiSendKind.OfflineTolerance -> {
|
|
buf.putInt(4)
|
|
FfiConverterTypeFFIAmount.write(value.`tolerance`, buf)
|
|
Unit
|
|
}
|
|
}.let { /* this makes the `when` an expression, which ensures it is exhaustive */ }
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
enum class FfiSplitTarget {
|
|
|
|
NONE,
|
|
DEFAULT;
|
|
companion object
|
|
}
|
|
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterTypeFFISplitTarget: FfiConverterRustBuffer<FfiSplitTarget> {
|
|
override fun read(buf: ByteBuffer) = try {
|
|
FfiSplitTarget.values()[buf.getInt() - 1]
|
|
} catch (e: IndexOutOfBoundsException) {
|
|
throw RuntimeException("invalid enum value, something is very wrong!!", e)
|
|
}
|
|
|
|
override fun allocationSize(value: FfiSplitTarget) = 4UL
|
|
|
|
override fun write(value: FfiSplitTarget, buf: ByteBuffer) {
|
|
buf.putInt(value.ordinal + 1)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterOptionalULong: FfiConverterRustBuffer<kotlin.ULong?> {
|
|
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 FfiConverterOptionalString: FfiConverterRustBuffer<kotlin.String?> {
|
|
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 FfiConverterOptionalTypeFFISendMemo: FfiConverterRustBuffer<FfiSendMemo?> {
|
|
override fun read(buf: ByteBuffer): FfiSendMemo? {
|
|
if (buf.get().toInt() == 0) {
|
|
return null
|
|
}
|
|
return FfiConverterTypeFFISendMemo.read(buf)
|
|
}
|
|
|
|
override fun allocationSize(value: FfiSendMemo?): ULong {
|
|
if (value == null) {
|
|
return 1UL
|
|
} else {
|
|
return 1UL + FfiConverterTypeFFISendMemo.allocationSize(value)
|
|
}
|
|
}
|
|
|
|
override fun write(value: FfiSendMemo?, buf: ByteBuffer) {
|
|
if (value == null) {
|
|
buf.put(0)
|
|
} else {
|
|
buf.put(1)
|
|
FfiConverterTypeFFISendMemo.write(value, buf)
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
* @suppress
|
|
*/
|
|
public object FfiConverterMapStringString: FfiConverterRustBuffer<Map<kotlin.String, kotlin.String>> {
|
|
override fun read(buf: ByteBuffer): Map<kotlin.String, kotlin.String> {
|
|
val len = buf.getInt()
|
|
return buildMap<kotlin.String, kotlin.String>(len) {
|
|
repeat(len) {
|
|
val k = FfiConverterString.read(buf)
|
|
val v = FfiConverterString.read(buf)
|
|
this[k] = v
|
|
}
|
|
}
|
|
}
|
|
|
|
override fun allocationSize(value: Map<kotlin.String, kotlin.String>): 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<kotlin.String, kotlin.String>, 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)
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* Generate a 12-word mnemonic phrase
|
|
*/
|
|
@Throws(FfiException::class) fun `generateMnemonic`(): kotlin.String {
|
|
return FfiConverterString.lift(
|
|
uniffiRustCallWithError(FfiException) { _status ->
|
|
UniffiLib.INSTANCE.uniffi_cdk_ffi_fn_func_generate_mnemonic(
|
|
_status)
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
|