2021-11-24 00:10:26 -08:00
|
|
|
// This file was autogenerated by some hot garbage in the `uniffi` crate.
|
|
|
|
// Trust me, you don't want to mess with it!
|
|
|
|
import Foundation
|
|
|
|
|
|
|
|
// Depending on the consumer's build setup, the low-level FFI code
|
|
|
|
// might be in a separate module, or it might be compiled inline into
|
|
|
|
// this module. This is a bit of light hackery to work with both.
|
|
|
|
#if canImport(bdkFFI)
|
|
|
|
import bdkFFI
|
|
|
|
#endif
|
|
|
|
|
|
|
|
fileprivate extension RustBuffer {
|
|
|
|
// Allocate a new buffer, copying the contents of a `UInt8` array.
|
|
|
|
init(bytes: [UInt8]) {
|
|
|
|
let rbuf = bytes.withUnsafeBufferPointer { ptr in
|
|
|
|
RustBuffer.from(ptr)
|
|
|
|
}
|
|
|
|
self.init(capacity: rbuf.capacity, len: rbuf.len, data: rbuf.data)
|
|
|
|
}
|
|
|
|
|
|
|
|
static func from(_ ptr: UnsafeBufferPointer<UInt8>) -> RustBuffer {
|
2022-05-13 13:45:48 -07:00
|
|
|
try! rustCall { ffi_bdk_360_rustbuffer_from_bytes(ForeignBytes(bufferPointer: ptr), $0) }
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Frees the buffer in place.
|
|
|
|
// The buffer must not be used after this is called.
|
|
|
|
func deallocate() {
|
2022-05-13 13:45:48 -07:00
|
|
|
try! rustCall { ffi_bdk_360_rustbuffer_free(self, $0) }
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate extension ForeignBytes {
|
|
|
|
init(bufferPointer: UnsafeBufferPointer<UInt8>) {
|
|
|
|
self.init(len: Int32(bufferPointer.count), data: bufferPointer.baseAddress)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// For every type used in the interface, we provide helper methods for conveniently
|
|
|
|
// lifting and lowering that type from C-compatible data, and for reading and writing
|
|
|
|
// values of that type in a buffer.
|
|
|
|
|
|
|
|
// Helper classes/extensions that don't change.
|
|
|
|
// Someday, this will be in a libray of its own.
|
|
|
|
|
|
|
|
fileprivate extension Data {
|
|
|
|
init(rustBuffer: RustBuffer) {
|
|
|
|
// TODO: This copies the buffer. Can we read directly from a
|
|
|
|
// Rust buffer?
|
|
|
|
self.init(bytes: rustBuffer.data!, count: Int(rustBuffer.len))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// A helper class to read values out of a byte buffer.
|
|
|
|
fileprivate class Reader {
|
|
|
|
let data: Data
|
|
|
|
var offset: Data.Index
|
|
|
|
|
|
|
|
init(data: Data) {
|
|
|
|
self.data = data
|
|
|
|
self.offset = 0
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reads an integer at the current offset, in big-endian order, and advances
|
|
|
|
// the offset on success. Throws if reading the integer would move the
|
|
|
|
// offset past the end of the buffer.
|
|
|
|
func readInt<T: FixedWidthInteger>() throws -> T {
|
|
|
|
let range = offset..<offset + MemoryLayout<T>.size
|
|
|
|
guard data.count >= range.upperBound else {
|
|
|
|
throw UniffiInternalError.bufferOverflow
|
|
|
|
}
|
|
|
|
if T.self == UInt8.self {
|
|
|
|
let value = data[offset]
|
|
|
|
offset += 1
|
|
|
|
return value as! T
|
|
|
|
}
|
|
|
|
var value: T = 0
|
|
|
|
let _ = withUnsafeMutableBytes(of: &value, { data.copyBytes(to: $0, from: range)})
|
|
|
|
offset = range.upperBound
|
|
|
|
return value.bigEndian
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reads an arbitrary number of bytes, to be used to read
|
|
|
|
// raw bytes, this is useful when lifting strings
|
|
|
|
func readBytes(count: Int) throws -> Array<UInt8> {
|
|
|
|
let range = offset..<(offset+count)
|
|
|
|
guard data.count >= range.upperBound else {
|
|
|
|
throw UniffiInternalError.bufferOverflow
|
|
|
|
}
|
|
|
|
var value = [UInt8](repeating: 0, count: count)
|
|
|
|
value.withUnsafeMutableBufferPointer({ buffer in
|
|
|
|
data.copyBytes(to: buffer, from: range)
|
|
|
|
})
|
|
|
|
offset = range.upperBound
|
|
|
|
return value
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reads a float at the current offset.
|
|
|
|
@inlinable
|
|
|
|
func readFloat() throws -> Float {
|
|
|
|
return Float(bitPattern: try readInt())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reads a float at the current offset.
|
|
|
|
@inlinable
|
|
|
|
func readDouble() throws -> Double {
|
|
|
|
return Double(bitPattern: try readInt())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Indicates if the offset has reached the end of the buffer.
|
|
|
|
@inlinable
|
|
|
|
func hasRemaining() -> Bool {
|
|
|
|
return offset < data.count
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// A helper class to write values into a byte buffer.
|
|
|
|
fileprivate class Writer {
|
|
|
|
var bytes: [UInt8]
|
|
|
|
var offset: Array<UInt8>.Index
|
|
|
|
|
|
|
|
init() {
|
|
|
|
self.bytes = []
|
|
|
|
self.offset = 0
|
|
|
|
}
|
|
|
|
|
|
|
|
func writeBytes<S>(_ byteArr: S) where S: Sequence, S.Element == UInt8 {
|
|
|
|
bytes.append(contentsOf: byteArr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Writes an integer in big-endian order.
|
|
|
|
//
|
|
|
|
// Warning: make sure what you are trying to write
|
|
|
|
// is in the correct type!
|
|
|
|
func writeInt<T: FixedWidthInteger>(_ value: T) {
|
|
|
|
var value = value.bigEndian
|
|
|
|
withUnsafeBytes(of: &value) { bytes.append(contentsOf: $0) }
|
|
|
|
}
|
|
|
|
|
|
|
|
@inlinable
|
|
|
|
func writeFloat(_ value: Float) {
|
|
|
|
writeInt(value.bitPattern)
|
|
|
|
}
|
|
|
|
|
|
|
|
@inlinable
|
|
|
|
func writeDouble(_ value: Double) {
|
|
|
|
writeInt(value.bitPattern)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Types conforming to `Serializable` can be read and written in a bytebuffer.
|
|
|
|
fileprivate protocol Serializable {
|
|
|
|
func write(into: Writer)
|
|
|
|
static func read(from: Reader) throws -> Self
|
|
|
|
}
|
|
|
|
|
|
|
|
// Types confirming to `ViaFfi` can be transferred back-and-for over the FFI.
|
|
|
|
// This is analogous to the Rust trait of the same name.
|
|
|
|
fileprivate protocol ViaFfi: Serializable {
|
|
|
|
associatedtype FfiType
|
|
|
|
static func lift(_ v: FfiType) throws -> Self
|
|
|
|
func lower() -> FfiType
|
|
|
|
}
|
|
|
|
|
|
|
|
// Types conforming to `Primitive` pass themselves directly over the FFI.
|
|
|
|
fileprivate protocol Primitive {}
|
|
|
|
|
|
|
|
extension Primitive {
|
|
|
|
fileprivate typealias FfiType = Self
|
|
|
|
|
|
|
|
fileprivate static func lift(_ v: Self) throws -> Self {
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate func lower() -> Self {
|
|
|
|
return self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Types conforming to `ViaFfiUsingByteBuffer` lift and lower into a bytebuffer.
|
|
|
|
// Use this for complex types where it's hard to write a custom lift/lower.
|
|
|
|
fileprivate protocol ViaFfiUsingByteBuffer: Serializable {}
|
|
|
|
|
|
|
|
extension ViaFfiUsingByteBuffer {
|
|
|
|
fileprivate typealias FfiType = RustBuffer
|
|
|
|
|
|
|
|
fileprivate static func lift(_ buf: FfiType) throws -> Self {
|
|
|
|
let reader = Reader(data: Data(rustBuffer: buf))
|
|
|
|
let value = try Self.read(from: reader)
|
|
|
|
if reader.hasRemaining() {
|
|
|
|
throw UniffiInternalError.incompleteData
|
|
|
|
}
|
|
|
|
buf.deallocate()
|
|
|
|
return value
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate func lower() -> FfiType {
|
|
|
|
let writer = Writer()
|
|
|
|
self.write(into: writer)
|
|
|
|
return RustBuffer(bytes: writer.bytes)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// An error type for FFI errors. These errors occur at the UniFFI level, not
|
|
|
|
// the library level.
|
|
|
|
fileprivate enum UniffiInternalError: LocalizedError {
|
|
|
|
case bufferOverflow
|
|
|
|
case incompleteData
|
|
|
|
case unexpectedOptionalTag
|
|
|
|
case unexpectedEnumCase
|
|
|
|
case unexpectedNullPointer
|
|
|
|
case unexpectedRustCallStatusCode
|
|
|
|
case unexpectedRustCallError
|
|
|
|
case unexpectedStaleHandle
|
|
|
|
case rustPanic(_ message: String)
|
|
|
|
|
|
|
|
public var errorDescription: String? {
|
|
|
|
switch self {
|
|
|
|
case .bufferOverflow: return "Reading the requested value would read past the end of the buffer"
|
|
|
|
case .incompleteData: return "The buffer still has data after lifting its containing value"
|
|
|
|
case .unexpectedOptionalTag: return "Unexpected optional tag; should be 0 or 1"
|
|
|
|
case .unexpectedEnumCase: return "Raw enum value doesn't match any cases"
|
|
|
|
case .unexpectedNullPointer: return "Raw pointer value was null"
|
|
|
|
case .unexpectedRustCallStatusCode: return "Unexpected RustCallStatus code"
|
|
|
|
case .unexpectedRustCallError: return "CALL_ERROR but no errorClass specified"
|
|
|
|
case .unexpectedStaleHandle: return "The object in the handle map has been dropped already"
|
|
|
|
case let .rustPanic(message): return message
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate let CALL_SUCCESS: Int8 = 0
|
|
|
|
fileprivate let CALL_ERROR: Int8 = 1
|
|
|
|
fileprivate let CALL_PANIC: Int8 = 2
|
|
|
|
|
|
|
|
fileprivate extension RustCallStatus {
|
|
|
|
init() {
|
|
|
|
self.init(
|
|
|
|
code: CALL_SUCCESS,
|
|
|
|
errorBuf: RustBuffer.init(
|
|
|
|
capacity: 0,
|
|
|
|
len: 0,
|
|
|
|
data: nil
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private func rustCall<T>(_ callback: (UnsafeMutablePointer<RustCallStatus>) -> T) throws -> T {
|
|
|
|
try makeRustCall(callback, errorHandler: {
|
|
|
|
$0.deallocate()
|
|
|
|
return UniffiInternalError.unexpectedRustCallError
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
private func rustCallWithError<T, E: ViaFfiUsingByteBuffer & Error>(_ errorClass: E.Type, _ callback: (UnsafeMutablePointer<RustCallStatus>) -> T) throws -> T {
|
|
|
|
try makeRustCall(callback, errorHandler: { return try E.lift($0) })
|
|
|
|
}
|
|
|
|
|
|
|
|
private func makeRustCall<T>(_ callback: (UnsafeMutablePointer<RustCallStatus>) -> T, errorHandler: (RustBuffer) throws -> Error) throws -> T {
|
|
|
|
var callStatus = RustCallStatus.init()
|
|
|
|
let returnedVal = callback(&callStatus)
|
|
|
|
switch callStatus.code {
|
|
|
|
case CALL_SUCCESS:
|
|
|
|
return returnedVal
|
|
|
|
|
|
|
|
case CALL_ERROR:
|
|
|
|
throw try errorHandler(callStatus.errorBuf)
|
|
|
|
|
|
|
|
case CALL_PANIC:
|
|
|
|
// When the rust code sees a panic, it tries to construct a RustBuffer
|
|
|
|
// with the message. But if that code panics, then it just sends back
|
|
|
|
// an empty buffer.
|
|
|
|
if callStatus.errorBuf.len > 0 {
|
|
|
|
throw UniffiInternalError.rustPanic(try String.lift(callStatus.errorBuf))
|
|
|
|
} else {
|
|
|
|
callStatus.errorBuf.deallocate()
|
|
|
|
throw UniffiInternalError.rustPanic("Rust panic")
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
throw UniffiInternalError.unexpectedRustCallStatusCode
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Protocols for converters we'll implement in templates
|
|
|
|
|
|
|
|
fileprivate protocol FfiConverter {
|
|
|
|
associatedtype SwiftType
|
|
|
|
associatedtype FfiType
|
|
|
|
|
|
|
|
static func lift(_ ffiValue: FfiType) throws -> SwiftType
|
|
|
|
static func lower(_ value: SwiftType) -> FfiType
|
|
|
|
|
|
|
|
static func read(from: Reader) throws -> SwiftType
|
|
|
|
static func write(_ value: SwiftType, into: Writer)
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate protocol FfiConverterUsingByteBuffer: FfiConverter where FfiType == RustBuffer {
|
|
|
|
// Empty, because we want to declare some helper methods in the extension below.
|
|
|
|
}
|
|
|
|
|
|
|
|
extension FfiConverterUsingByteBuffer {
|
|
|
|
static func lower(_ value: SwiftType) -> FfiType {
|
|
|
|
let writer = Writer()
|
|
|
|
Self.write(value, into: writer)
|
|
|
|
return RustBuffer(bytes: writer.bytes)
|
|
|
|
}
|
|
|
|
|
|
|
|
static func lift(_ buf: FfiType) throws -> SwiftType {
|
|
|
|
let reader = Reader(data: Data(rustBuffer: buf))
|
|
|
|
let value = try Self.read(from: reader)
|
|
|
|
if reader.hasRemaining() {
|
|
|
|
throw UniffiInternalError.incompleteData
|
|
|
|
}
|
|
|
|
buf.deallocate()
|
|
|
|
return value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Helpers for structural types. Note that because of canonical_names, it /should/ be impossible
|
|
|
|
// to make another `FfiConverterSequence` etc just using the UDL.
|
|
|
|
fileprivate enum FfiConverterSequence {
|
|
|
|
static func write<T>(_ value: [T], into buf: Writer, writeItem: (T, Writer) -> Void) {
|
|
|
|
let len = Int32(value.count)
|
|
|
|
buf.writeInt(len)
|
|
|
|
for item in value {
|
|
|
|
writeItem(item, buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static func read<T>(from buf: Reader, readItem: (Reader) throws -> T) throws -> [T] {
|
|
|
|
let len: Int32 = try buf.readInt()
|
|
|
|
var seq = [T]()
|
|
|
|
seq.reserveCapacity(Int(len))
|
|
|
|
for _ in 0 ..< len {
|
|
|
|
seq.append(try readItem(buf))
|
|
|
|
}
|
|
|
|
return seq
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate enum FfiConverterOptional {
|
|
|
|
static func write<T>(_ value: T?, into buf: Writer, writeItem: (T, Writer) -> Void) {
|
|
|
|
guard let value = value else {
|
|
|
|
buf.writeInt(Int8(0))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
buf.writeInt(Int8(1))
|
|
|
|
writeItem(value, buf)
|
|
|
|
}
|
|
|
|
|
|
|
|
static func read<T>(from buf: Reader, readItem: (Reader) throws -> T) throws -> T? {
|
|
|
|
switch try buf.readInt() as Int8 {
|
|
|
|
case 0: return nil
|
|
|
|
case 1: return try readItem(buf)
|
|
|
|
default: throw UniffiInternalError.unexpectedOptionalTag
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate enum FfiConverterDictionary {
|
|
|
|
static func write<T>(_ value: [String: T], into buf: Writer, writeItem: (String, T, Writer) -> Void) {
|
|
|
|
let len = Int32(value.count)
|
|
|
|
buf.writeInt(len)
|
|
|
|
for (key, value) in value {
|
|
|
|
writeItem(key, value, buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static func read<T>(from buf: Reader, readItem: (Reader) throws -> (String, T)) throws -> [String: T] {
|
|
|
|
let len: Int32 = try buf.readInt()
|
|
|
|
var dict = [String: T]()
|
|
|
|
dict.reserveCapacity(Int(len))
|
|
|
|
for _ in 0..<len {
|
|
|
|
let (key, value) = try readItem(buf)
|
|
|
|
dict[key] = value
|
|
|
|
}
|
|
|
|
return dict
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Public interface members begin here.
|
|
|
|
|
|
|
|
|
|
|
|
fileprivate extension NSLock {
|
|
|
|
func withLock<T>(f: () throws -> T) rethrows -> T {
|
|
|
|
self.lock()
|
|
|
|
defer { self.unlock() }
|
|
|
|
return try f()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate typealias Handle = UInt64
|
|
|
|
fileprivate class ConcurrentHandleMap<T> {
|
|
|
|
private var leftMap: [Handle: T] = [:]
|
|
|
|
private var counter: [Handle: UInt64] = [:]
|
|
|
|
private var rightMap: [ObjectIdentifier: Handle] = [:]
|
|
|
|
|
|
|
|
private let lock = NSLock()
|
|
|
|
private var currentHandle: Handle = 0
|
|
|
|
private let stride: Handle = 1
|
|
|
|
|
|
|
|
func insert(obj: T) -> Handle {
|
|
|
|
lock.withLock {
|
|
|
|
let id = ObjectIdentifier(obj as AnyObject)
|
|
|
|
let handle = rightMap[id] ?? {
|
|
|
|
currentHandle += stride
|
|
|
|
let handle = currentHandle
|
|
|
|
leftMap[handle] = obj
|
|
|
|
rightMap[id] = handle
|
|
|
|
return handle
|
|
|
|
}()
|
|
|
|
counter[handle] = (counter[handle] ?? 0) + 1
|
|
|
|
return handle
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func get(handle: Handle) -> T? {
|
|
|
|
lock.withLock {
|
|
|
|
leftMap[handle]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func delete(handle: Handle) {
|
|
|
|
remove(handle: handle)
|
|
|
|
}
|
|
|
|
|
|
|
|
@discardableResult
|
|
|
|
func remove(handle: Handle) -> T? {
|
|
|
|
lock.withLock {
|
|
|
|
defer { counter[handle] = (counter[handle] ?? 1) - 1 }
|
|
|
|
guard counter[handle] == 1 else { return leftMap[handle] }
|
|
|
|
let obj = leftMap.removeValue(forKey: handle)
|
|
|
|
if let obj = obj {
|
|
|
|
rightMap.removeValue(forKey: ObjectIdentifier(obj as AnyObject))
|
|
|
|
}
|
|
|
|
return obj
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Magic number for the Rust proxy to call using the same mechanism as every other method,
|
|
|
|
// to free the callback once it's dropped by Rust.
|
|
|
|
private let IDX_CALLBACK_FREE: Int32 = 0
|
|
|
|
|
|
|
|
fileprivate class FfiConverterCallbackInterface<CallbackInterface> {
|
|
|
|
fileprivate let handleMap = ConcurrentHandleMap<CallbackInterface>()
|
|
|
|
|
|
|
|
func drop(handle: Handle) {
|
|
|
|
handleMap.remove(handle: handle)
|
|
|
|
}
|
|
|
|
|
|
|
|
func lift(_ handle: Handle) throws -> CallbackInterface {
|
|
|
|
guard let callback = handleMap.get(handle: handle) else {
|
|
|
|
throw UniffiInternalError.unexpectedStaleHandle
|
|
|
|
}
|
|
|
|
return callback
|
|
|
|
}
|
|
|
|
|
|
|
|
func read(from buf: Reader) throws -> CallbackInterface {
|
|
|
|
let handle: Handle = try buf.readInt()
|
|
|
|
return try lift(handle)
|
|
|
|
}
|
|
|
|
|
|
|
|
func lower(_ v: CallbackInterface) -> Handle {
|
|
|
|
let handle = handleMap.insert(obj: v)
|
|
|
|
return handle
|
|
|
|
// assert(handleMap.get(handle: obj) == v, "Handle map is not returning the object we just placed there. This is a bug in the HandleMap.")
|
|
|
|
}
|
|
|
|
|
|
|
|
func write(_ v: CallbackInterface, into buf: Writer) {
|
|
|
|
buf.writeInt(lower(v))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Note that we don't yet support `indirect` for enums.
|
|
|
|
// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion.
|
|
|
|
|
|
|
|
public enum Network {
|
|
|
|
|
|
|
|
case bitcoin
|
|
|
|
case testnet
|
|
|
|
case signet
|
|
|
|
case regtest
|
|
|
|
}
|
|
|
|
|
|
|
|
extension Network: ViaFfiUsingByteBuffer, ViaFfi {
|
|
|
|
fileprivate static func read(from buf: Reader) throws -> Network {
|
|
|
|
let variant: Int32 = try buf.readInt()
|
|
|
|
switch variant {
|
|
|
|
|
|
|
|
case 1: return .bitcoin
|
|
|
|
case 2: return .testnet
|
|
|
|
case 3: return .signet
|
|
|
|
case 4: return .regtest
|
|
|
|
default: throw UniffiInternalError.unexpectedEnumCase
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate func write(into buf: Writer) {
|
|
|
|
switch self {
|
|
|
|
|
|
|
|
|
|
|
|
case .bitcoin:
|
|
|
|
buf.writeInt(Int32(1))
|
|
|
|
|
|
|
|
|
|
|
|
case .testnet:
|
|
|
|
buf.writeInt(Int32(2))
|
|
|
|
|
|
|
|
|
|
|
|
case .signet:
|
|
|
|
buf.writeInt(Int32(3))
|
|
|
|
|
|
|
|
|
|
|
|
case .regtest:
|
|
|
|
buf.writeInt(Int32(4))
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension Network: Equatable, Hashable {}
|
|
|
|
|
|
|
|
|
|
|
|
// Note that we don't yet support `indirect` for enums.
|
|
|
|
// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion.
|
|
|
|
|
|
|
|
public enum DatabaseConfig {
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
case memory
|
2021-11-24 00:10:26 -08:00
|
|
|
case sled(config: SledDbConfiguration )
|
2022-05-13 13:45:48 -07:00
|
|
|
case sqlite(config: SqliteDbConfiguration )
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
extension DatabaseConfig: ViaFfiUsingByteBuffer, ViaFfi {
|
|
|
|
fileprivate static func read(from buf: Reader) throws -> DatabaseConfig {
|
|
|
|
let variant: Int32 = try buf.readInt()
|
|
|
|
switch variant {
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
case 1: return .memory
|
2021-11-24 00:10:26 -08:00
|
|
|
case 2: return .sled(
|
|
|
|
config: try SledDbConfiguration.read(from: buf)
|
|
|
|
)
|
2022-05-13 13:45:48 -07:00
|
|
|
case 3: return .sqlite(
|
|
|
|
config: try SqliteDbConfiguration.read(from: buf)
|
|
|
|
)
|
2021-11-24 00:10:26 -08:00
|
|
|
default: throw UniffiInternalError.unexpectedEnumCase
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate func write(into buf: Writer) {
|
|
|
|
switch self {
|
|
|
|
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
case .memory:
|
2021-11-24 00:10:26 -08:00
|
|
|
buf.writeInt(Int32(1))
|
|
|
|
|
|
|
|
|
|
|
|
case let .sled(config):
|
|
|
|
buf.writeInt(Int32(2))
|
|
|
|
config.write(into: buf)
|
|
|
|
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
|
|
|
|
case let .sqlite(config):
|
|
|
|
buf.writeInt(Int32(3))
|
|
|
|
config.write(into: buf)
|
|
|
|
|
|
|
|
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension DatabaseConfig: Equatable, Hashable {}
|
|
|
|
|
|
|
|
|
|
|
|
// Note that we don't yet support `indirect` for enums.
|
|
|
|
// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion.
|
|
|
|
|
|
|
|
public enum Transaction {
|
|
|
|
|
|
|
|
case unconfirmed(details: TransactionDetails )
|
2022-03-02 15:17:53 -08:00
|
|
|
case confirmed(details: TransactionDetails, confirmation: BlockTime )
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
extension Transaction: ViaFfiUsingByteBuffer, ViaFfi {
|
|
|
|
fileprivate static func read(from buf: Reader) throws -> Transaction {
|
|
|
|
let variant: Int32 = try buf.readInt()
|
|
|
|
switch variant {
|
|
|
|
|
|
|
|
case 1: return .unconfirmed(
|
|
|
|
details: try TransactionDetails.read(from: buf)
|
|
|
|
)
|
|
|
|
case 2: return .confirmed(
|
|
|
|
details: try TransactionDetails.read(from: buf),
|
2022-03-02 15:17:53 -08:00
|
|
|
confirmation: try BlockTime.read(from: buf)
|
2021-11-24 00:10:26 -08:00
|
|
|
)
|
|
|
|
default: throw UniffiInternalError.unexpectedEnumCase
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate func write(into buf: Writer) {
|
|
|
|
switch self {
|
|
|
|
|
|
|
|
|
|
|
|
case let .unconfirmed(details):
|
|
|
|
buf.writeInt(Int32(1))
|
|
|
|
details.write(into: buf)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case let .confirmed(details,confirmation):
|
|
|
|
buf.writeInt(Int32(2))
|
|
|
|
details.write(into: buf)
|
|
|
|
confirmation.write(into: buf)
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension Transaction: Equatable, Hashable {}
|
|
|
|
|
|
|
|
|
|
|
|
// Note that we don't yet support `indirect` for enums.
|
|
|
|
// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion.
|
|
|
|
|
|
|
|
public enum BlockchainConfig {
|
|
|
|
|
|
|
|
case electrum(config: ElectrumConfig )
|
|
|
|
case esplora(config: EsploraConfig )
|
|
|
|
}
|
|
|
|
|
|
|
|
extension BlockchainConfig: ViaFfiUsingByteBuffer, ViaFfi {
|
|
|
|
fileprivate static func read(from buf: Reader) throws -> BlockchainConfig {
|
|
|
|
let variant: Int32 = try buf.readInt()
|
|
|
|
switch variant {
|
|
|
|
|
|
|
|
case 1: return .electrum(
|
|
|
|
config: try ElectrumConfig.read(from: buf)
|
|
|
|
)
|
|
|
|
case 2: return .esplora(
|
|
|
|
config: try EsploraConfig.read(from: buf)
|
|
|
|
)
|
|
|
|
default: throw UniffiInternalError.unexpectedEnumCase
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate func write(into buf: Writer) {
|
|
|
|
switch self {
|
|
|
|
|
|
|
|
|
|
|
|
case let .electrum(config):
|
|
|
|
buf.writeInt(Int32(1))
|
|
|
|
config.write(into: buf)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case let .esplora(config):
|
|
|
|
buf.writeInt(Int32(2))
|
|
|
|
config.write(into: buf)
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension BlockchainConfig: Equatable, Hashable {}
|
|
|
|
|
|
|
|
|
|
|
|
// Note that we don't yet support `indirect` for enums.
|
|
|
|
// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion.
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
public enum WordCount {
|
2021-11-24 00:10:26 -08:00
|
|
|
|
|
|
|
case words12
|
|
|
|
case words15
|
|
|
|
case words18
|
|
|
|
case words21
|
|
|
|
case words24
|
|
|
|
}
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
extension WordCount: ViaFfiUsingByteBuffer, ViaFfi {
|
|
|
|
fileprivate static func read(from buf: Reader) throws -> WordCount {
|
2021-11-24 00:10:26 -08:00
|
|
|
let variant: Int32 = try buf.readInt()
|
|
|
|
switch variant {
|
|
|
|
|
|
|
|
case 1: return .words12
|
|
|
|
case 2: return .words15
|
|
|
|
case 3: return .words18
|
|
|
|
case 4: return .words21
|
|
|
|
case 5: return .words24
|
|
|
|
default: throw UniffiInternalError.unexpectedEnumCase
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate func write(into buf: Writer) {
|
|
|
|
switch self {
|
|
|
|
|
|
|
|
|
|
|
|
case .words12:
|
|
|
|
buf.writeInt(Int32(1))
|
|
|
|
|
|
|
|
|
|
|
|
case .words15:
|
|
|
|
buf.writeInt(Int32(2))
|
|
|
|
|
|
|
|
|
|
|
|
case .words18:
|
|
|
|
buf.writeInt(Int32(3))
|
|
|
|
|
|
|
|
|
|
|
|
case .words21:
|
|
|
|
buf.writeInt(Int32(4))
|
|
|
|
|
|
|
|
|
|
|
|
case .words24:
|
|
|
|
buf.writeInt(Int32(5))
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
extension WordCount: Equatable, Hashable {}
|
2021-11-24 00:10:26 -08:00
|
|
|
|
|
|
|
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
public func generateExtendedKey( network: Network, wordCount: WordCount, password: String? ) throws -> ExtendedKeyInfo {
|
2021-11-24 00:10:26 -08:00
|
|
|
let _retval = try
|
|
|
|
|
|
|
|
|
|
|
|
rustCallWithError(BdkError.self) {
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
bdk_360_generate_extended_key(network.lower(), wordCount.lower(), FfiConverterOptionString.lower(password) , $0)
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
return try ExtendedKeyInfo.lift(_retval)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
public func restoreExtendedKey( network: Network, mnemonic: String, password: String? ) throws -> ExtendedKeyInfo {
|
2021-11-24 00:10:26 -08:00
|
|
|
let _retval = try
|
|
|
|
|
|
|
|
|
|
|
|
rustCallWithError(BdkError.self) {
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
bdk_360_restore_extended_key(network.lower(), mnemonic.lower(), FfiConverterOptionString.lower(password) , $0)
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
return try ExtendedKeyInfo.lift(_retval)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
public protocol BlockchainProtocol {
|
|
|
|
func broadcast( psbt: PartiallySignedBitcoinTransaction ) throws
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public class Blockchain: BlockchainProtocol {
|
|
|
|
fileprivate let pointer: UnsafeMutableRawPointer
|
|
|
|
|
|
|
|
// TODO: We'd like this to be `private` but for Swifty reasons,
|
|
|
|
// we can't implement `ViaFfi` without making this `required` and we can't
|
|
|
|
// make it `required` without making it `public`.
|
|
|
|
required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) {
|
|
|
|
self.pointer = pointer
|
|
|
|
}
|
|
|
|
public convenience init( config: BlockchainConfig ) throws {
|
|
|
|
self.init(unsafeFromRawPointer: try
|
|
|
|
|
|
|
|
|
|
|
|
rustCallWithError(BdkError.self) {
|
|
|
|
|
|
|
|
bdk_360_Blockchain_new(config.lower() , $0)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
deinit {
|
|
|
|
try! rustCall { ffi_bdk_360_Blockchain_object_free(pointer, $0) }
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public func broadcast( psbt: PartiallySignedBitcoinTransaction ) throws {
|
|
|
|
try
|
|
|
|
rustCallWithError(BdkError.self) {
|
|
|
|
|
|
|
|
bdk_360_Blockchain_broadcast(self.pointer, psbt.lower() , $0
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fileprivate extension Blockchain {
|
|
|
|
typealias FfiType = UnsafeMutableRawPointer
|
|
|
|
|
|
|
|
static func read(from buf: Reader) throws -> Self {
|
|
|
|
let v: UInt64 = try buf.readInt()
|
|
|
|
// The Rust code won't compile if a pointer won't fit in a UInt64.
|
|
|
|
// We have to go via `UInt` because that's the thing that's the size of a pointer.
|
|
|
|
let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v))
|
|
|
|
if (ptr == nil) {
|
|
|
|
throw UniffiInternalError.unexpectedNullPointer
|
|
|
|
}
|
|
|
|
return try self.lift(ptr!)
|
|
|
|
}
|
|
|
|
|
|
|
|
func write(into buf: Writer) {
|
|
|
|
// This fiddling is because `Int` is the thing that's the same size as a pointer.
|
|
|
|
// The Rust code won't compile if a pointer won't fit in a `UInt64`.
|
|
|
|
buf.writeInt(UInt64(bitPattern: Int64(Int(bitPattern: self.lower()))))
|
|
|
|
}
|
|
|
|
|
|
|
|
static func lift(_ pointer: UnsafeMutableRawPointer) throws -> Self {
|
|
|
|
return Self(unsafeFromRawPointer: pointer)
|
|
|
|
}
|
|
|
|
|
|
|
|
func lower() -> UnsafeMutableRawPointer {
|
|
|
|
return self.pointer
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ideally this would be `fileprivate`, but Swift says:
|
|
|
|
// """
|
|
|
|
// 'private' modifier cannot be used with extensions that declare protocol conformances
|
|
|
|
// """
|
|
|
|
extension Blockchain : ViaFfi, Serializable {}
|
|
|
|
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
public protocol WalletProtocol {
|
2021-11-24 00:10:26 -08:00
|
|
|
func getNewAddress() -> String
|
|
|
|
func getLastUnusedAddress() -> String
|
|
|
|
func getBalance() throws -> UInt64
|
2022-03-02 15:17:53 -08:00
|
|
|
func sign( psbt: PartiallySignedBitcoinTransaction ) throws
|
2021-11-24 00:10:26 -08:00
|
|
|
func getTransactions() throws -> [Transaction]
|
|
|
|
func getNetwork() -> Network
|
2022-05-13 13:45:48 -07:00
|
|
|
func sync( blockchain: Blockchain, progress: Progress? ) throws
|
2021-11-24 00:10:26 -08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
public class Wallet: WalletProtocol {
|
2021-11-24 00:10:26 -08:00
|
|
|
fileprivate let pointer: UnsafeMutableRawPointer
|
|
|
|
|
|
|
|
// TODO: We'd like this to be `private` but for Swifty reasons,
|
|
|
|
// we can't implement `ViaFfi` without making this `required` and we can't
|
|
|
|
// make it `required` without making it `public`.
|
|
|
|
required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) {
|
|
|
|
self.pointer = pointer
|
|
|
|
}
|
2022-05-13 13:45:48 -07:00
|
|
|
public convenience init( descriptor: String, changeDescriptor: String?, network: Network, databaseConfig: DatabaseConfig ) throws {
|
2021-11-24 00:10:26 -08:00
|
|
|
self.init(unsafeFromRawPointer: try
|
|
|
|
|
|
|
|
|
|
|
|
rustCallWithError(BdkError.self) {
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
bdk_360_Wallet_new(descriptor.lower(), FfiConverterOptionString.lower(changeDescriptor), network.lower(), databaseConfig.lower() , $0)
|
2021-11-24 00:10:26 -08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
deinit {
|
2022-05-13 13:45:48 -07:00
|
|
|
try! rustCall { ffi_bdk_360_Wallet_object_free(pointer, $0) }
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public func getNewAddress() -> String {
|
|
|
|
let _retval = try!
|
|
|
|
rustCall() {
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
bdk_360_Wallet_get_new_address(self.pointer, $0
|
2021-11-24 00:10:26 -08:00
|
|
|
)
|
|
|
|
}
|
|
|
|
return try! String.lift(_retval)
|
|
|
|
}
|
|
|
|
public func getLastUnusedAddress() -> String {
|
|
|
|
let _retval = try!
|
|
|
|
rustCall() {
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
bdk_360_Wallet_get_last_unused_address(self.pointer, $0
|
2021-11-24 00:10:26 -08:00
|
|
|
)
|
|
|
|
}
|
|
|
|
return try! String.lift(_retval)
|
|
|
|
}
|
|
|
|
public func getBalance() throws -> UInt64 {
|
|
|
|
let _retval = try
|
|
|
|
rustCallWithError(BdkError.self) {
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
bdk_360_Wallet_get_balance(self.pointer, $0
|
2021-11-24 00:10:26 -08:00
|
|
|
)
|
|
|
|
}
|
|
|
|
return try UInt64.lift(_retval)
|
|
|
|
}
|
2022-03-02 15:17:53 -08:00
|
|
|
public func sign( psbt: PartiallySignedBitcoinTransaction ) throws {
|
2021-11-24 00:10:26 -08:00
|
|
|
try
|
|
|
|
rustCallWithError(BdkError.self) {
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
bdk_360_Wallet_sign(self.pointer, psbt.lower() , $0
|
2021-11-24 00:10:26 -08:00
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public func getTransactions() throws -> [Transaction] {
|
|
|
|
let _retval = try
|
|
|
|
rustCallWithError(BdkError.self) {
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
bdk_360_Wallet_get_transactions(self.pointer, $0
|
2021-11-24 00:10:26 -08:00
|
|
|
)
|
|
|
|
}
|
|
|
|
return try FfiConverterSequenceEnumTransaction.lift(_retval)
|
|
|
|
}
|
|
|
|
public func getNetwork() -> Network {
|
|
|
|
let _retval = try!
|
|
|
|
rustCall() {
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
bdk_360_Wallet_get_network(self.pointer, $0
|
2021-11-24 00:10:26 -08:00
|
|
|
)
|
|
|
|
}
|
|
|
|
return try! Network.lift(_retval)
|
|
|
|
}
|
2022-05-13 13:45:48 -07:00
|
|
|
public func sync( blockchain: Blockchain, progress: Progress? ) throws {
|
2021-11-24 00:10:26 -08:00
|
|
|
try
|
|
|
|
rustCallWithError(BdkError.self) {
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
bdk_360_Wallet_sync(self.pointer, blockchain.lower(), FfiConverterOptionCallbackInterfaceProgress.lower(progress) , $0
|
2021-11-24 00:10:26 -08:00
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
fileprivate extension Wallet {
|
|
|
|
typealias FfiType = UnsafeMutableRawPointer
|
2021-11-24 00:10:26 -08:00
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
static func read(from buf: Reader) throws -> Self {
|
2021-11-24 00:10:26 -08:00
|
|
|
let v: UInt64 = try buf.readInt()
|
|
|
|
// The Rust code won't compile if a pointer won't fit in a UInt64.
|
|
|
|
// We have to go via `UInt` because that's the thing that's the size of a pointer.
|
|
|
|
let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v))
|
|
|
|
if (ptr == nil) {
|
|
|
|
throw UniffiInternalError.unexpectedNullPointer
|
|
|
|
}
|
|
|
|
return try self.lift(ptr!)
|
|
|
|
}
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
func write(into buf: Writer) {
|
2021-11-24 00:10:26 -08:00
|
|
|
// This fiddling is because `Int` is the thing that's the same size as a pointer.
|
|
|
|
// The Rust code won't compile if a pointer won't fit in a `UInt64`.
|
|
|
|
buf.writeInt(UInt64(bitPattern: Int64(Int(bitPattern: self.lower()))))
|
|
|
|
}
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
static func lift(_ pointer: UnsafeMutableRawPointer) throws -> Self {
|
2021-11-24 00:10:26 -08:00
|
|
|
return Self(unsafeFromRawPointer: pointer)
|
|
|
|
}
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
func lower() -> UnsafeMutableRawPointer {
|
2021-11-24 00:10:26 -08:00
|
|
|
return self.pointer
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ideally this would be `fileprivate`, but Swift says:
|
|
|
|
// """
|
|
|
|
// 'private' modifier cannot be used with extensions that declare protocol conformances
|
|
|
|
// """
|
2022-03-02 15:17:53 -08:00
|
|
|
extension Wallet : ViaFfi, Serializable {}
|
2021-11-24 00:10:26 -08:00
|
|
|
|
|
|
|
|
|
|
|
public protocol PartiallySignedBitcoinTransactionProtocol {
|
2022-03-02 15:17:53 -08:00
|
|
|
func serialize() -> String
|
2022-05-13 13:45:48 -07:00
|
|
|
func txid() -> String
|
2021-11-24 00:10:26 -08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public class PartiallySignedBitcoinTransaction: PartiallySignedBitcoinTransactionProtocol {
|
|
|
|
fileprivate let pointer: UnsafeMutableRawPointer
|
|
|
|
|
|
|
|
// TODO: We'd like this to be `private` but for Swifty reasons,
|
|
|
|
// we can't implement `ViaFfi` without making this `required` and we can't
|
|
|
|
// make it `required` without making it `public`.
|
|
|
|
required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) {
|
|
|
|
self.pointer = pointer
|
|
|
|
}
|
2022-05-13 13:45:48 -07:00
|
|
|
public convenience init( psbtBase64: String ) throws {
|
2021-11-24 00:10:26 -08:00
|
|
|
self.init(unsafeFromRawPointer: try
|
|
|
|
|
|
|
|
|
|
|
|
rustCallWithError(BdkError.self) {
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
bdk_360_PartiallySignedBitcoinTransaction_new(psbtBase64.lower() , $0)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
deinit {
|
|
|
|
try! rustCall { ffi_bdk_360_PartiallySignedBitcoinTransaction_object_free(pointer, $0) }
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public func serialize() -> String {
|
|
|
|
let _retval = try!
|
|
|
|
rustCall() {
|
|
|
|
|
|
|
|
bdk_360_PartiallySignedBitcoinTransaction_serialize(self.pointer, $0
|
|
|
|
)
|
|
|
|
}
|
|
|
|
return try! String.lift(_retval)
|
|
|
|
}
|
|
|
|
public func txid() -> String {
|
|
|
|
let _retval = try!
|
|
|
|
rustCall() {
|
|
|
|
|
|
|
|
bdk_360_PartiallySignedBitcoinTransaction_txid(self.pointer, $0
|
|
|
|
)
|
|
|
|
}
|
|
|
|
return try! String.lift(_retval)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fileprivate extension PartiallySignedBitcoinTransaction {
|
|
|
|
typealias FfiType = UnsafeMutableRawPointer
|
|
|
|
|
|
|
|
static func read(from buf: Reader) throws -> Self {
|
|
|
|
let v: UInt64 = try buf.readInt()
|
|
|
|
// The Rust code won't compile if a pointer won't fit in a UInt64.
|
|
|
|
// We have to go via `UInt` because that's the thing that's the size of a pointer.
|
|
|
|
let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v))
|
|
|
|
if (ptr == nil) {
|
|
|
|
throw UniffiInternalError.unexpectedNullPointer
|
|
|
|
}
|
|
|
|
return try self.lift(ptr!)
|
|
|
|
}
|
|
|
|
|
|
|
|
func write(into buf: Writer) {
|
|
|
|
// This fiddling is because `Int` is the thing that's the same size as a pointer.
|
|
|
|
// The Rust code won't compile if a pointer won't fit in a `UInt64`.
|
|
|
|
buf.writeInt(UInt64(bitPattern: Int64(Int(bitPattern: self.lower()))))
|
|
|
|
}
|
|
|
|
|
|
|
|
static func lift(_ pointer: UnsafeMutableRawPointer) throws -> Self {
|
|
|
|
return Self(unsafeFromRawPointer: pointer)
|
|
|
|
}
|
|
|
|
|
|
|
|
func lower() -> UnsafeMutableRawPointer {
|
|
|
|
return self.pointer
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ideally this would be `fileprivate`, but Swift says:
|
|
|
|
// """
|
|
|
|
// 'private' modifier cannot be used with extensions that declare protocol conformances
|
|
|
|
// """
|
|
|
|
extension PartiallySignedBitcoinTransaction : ViaFfi, Serializable {}
|
|
|
|
|
|
|
|
|
|
|
|
public protocol TxBuilderProtocol {
|
|
|
|
func addRecipient( address: String, amount: UInt64 ) -> TxBuilder
|
|
|
|
func feeRate( satPerVbyte: Float ) -> TxBuilder
|
|
|
|
func drainWallet() -> TxBuilder
|
|
|
|
func drainTo( address: String ) -> TxBuilder
|
|
|
|
func enableRbf() -> TxBuilder
|
|
|
|
func enableRbfWithSequence( nsequence: UInt32 ) -> TxBuilder
|
|
|
|
func finish( wallet: Wallet ) throws -> PartiallySignedBitcoinTransaction
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public class TxBuilder: TxBuilderProtocol {
|
|
|
|
fileprivate let pointer: UnsafeMutableRawPointer
|
|
|
|
|
|
|
|
// TODO: We'd like this to be `private` but for Swifty reasons,
|
|
|
|
// we can't implement `ViaFfi` without making this `required` and we can't
|
|
|
|
// make it `required` without making it `public`.
|
|
|
|
required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) {
|
|
|
|
self.pointer = pointer
|
|
|
|
}
|
|
|
|
public convenience init() {
|
|
|
|
self.init(unsafeFromRawPointer: try!
|
|
|
|
|
|
|
|
|
|
|
|
rustCall() {
|
|
|
|
|
|
|
|
bdk_360_TxBuilder_new( $0)
|
2021-11-24 00:10:26 -08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
deinit {
|
2022-05-13 13:45:48 -07:00
|
|
|
try! rustCall { ffi_bdk_360_TxBuilder_object_free(pointer, $0) }
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
public func addRecipient( address: String, amount: UInt64 ) -> TxBuilder {
|
|
|
|
let _retval = try!
|
|
|
|
rustCall() {
|
|
|
|
|
|
|
|
bdk_360_TxBuilder_add_recipient(self.pointer, address.lower(), amount.lower() , $0
|
|
|
|
)
|
|
|
|
}
|
|
|
|
return try! TxBuilder.lift(_retval)
|
|
|
|
}
|
|
|
|
public func feeRate( satPerVbyte: Float ) -> TxBuilder {
|
|
|
|
let _retval = try!
|
|
|
|
rustCall() {
|
2022-03-02 15:17:53 -08:00
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
bdk_360_TxBuilder_fee_rate(self.pointer, satPerVbyte.lower() , $0
|
|
|
|
)
|
|
|
|
}
|
|
|
|
return try! TxBuilder.lift(_retval)
|
|
|
|
}
|
|
|
|
public func drainWallet() -> TxBuilder {
|
|
|
|
let _retval = try!
|
|
|
|
rustCall() {
|
|
|
|
|
|
|
|
bdk_360_TxBuilder_drain_wallet(self.pointer, $0
|
|
|
|
)
|
|
|
|
}
|
|
|
|
return try! TxBuilder.lift(_retval)
|
|
|
|
}
|
|
|
|
public func drainTo( address: String ) -> TxBuilder {
|
|
|
|
let _retval = try!
|
|
|
|
rustCall() {
|
|
|
|
|
|
|
|
bdk_360_TxBuilder_drain_to(self.pointer, address.lower() , $0
|
|
|
|
)
|
|
|
|
}
|
|
|
|
return try! TxBuilder.lift(_retval)
|
|
|
|
}
|
|
|
|
public func enableRbf() -> TxBuilder {
|
|
|
|
let _retval = try!
|
|
|
|
rustCall() {
|
|
|
|
|
|
|
|
bdk_360_TxBuilder_enable_rbf(self.pointer, $0
|
|
|
|
)
|
|
|
|
}
|
|
|
|
return try! TxBuilder.lift(_retval)
|
|
|
|
}
|
|
|
|
public func enableRbfWithSequence( nsequence: UInt32 ) -> TxBuilder {
|
|
|
|
let _retval = try!
|
|
|
|
rustCall() {
|
|
|
|
|
|
|
|
bdk_360_TxBuilder_enable_rbf_with_sequence(self.pointer, nsequence.lower() , $0
|
|
|
|
)
|
|
|
|
}
|
|
|
|
return try! TxBuilder.lift(_retval)
|
|
|
|
}
|
|
|
|
public func finish( wallet: Wallet ) throws -> PartiallySignedBitcoinTransaction {
|
|
|
|
let _retval = try
|
2022-03-02 15:17:53 -08:00
|
|
|
rustCallWithError(BdkError.self) {
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
bdk_360_TxBuilder_finish(self.pointer, wallet.lower() , $0
|
|
|
|
)
|
|
|
|
}
|
|
|
|
return try PartiallySignedBitcoinTransaction.lift(_retval)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fileprivate extension TxBuilder {
|
|
|
|
typealias FfiType = UnsafeMutableRawPointer
|
|
|
|
|
|
|
|
static func read(from buf: Reader) throws -> Self {
|
|
|
|
let v: UInt64 = try buf.readInt()
|
|
|
|
// The Rust code won't compile if a pointer won't fit in a UInt64.
|
|
|
|
// We have to go via `UInt` because that's the thing that's the size of a pointer.
|
|
|
|
let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v))
|
|
|
|
if (ptr == nil) {
|
|
|
|
throw UniffiInternalError.unexpectedNullPointer
|
|
|
|
}
|
|
|
|
return try self.lift(ptr!)
|
|
|
|
}
|
|
|
|
|
|
|
|
func write(into buf: Writer) {
|
|
|
|
// This fiddling is because `Int` is the thing that's the same size as a pointer.
|
|
|
|
// The Rust code won't compile if a pointer won't fit in a `UInt64`.
|
|
|
|
buf.writeInt(UInt64(bitPattern: Int64(Int(bitPattern: self.lower()))))
|
|
|
|
}
|
|
|
|
|
|
|
|
static func lift(_ pointer: UnsafeMutableRawPointer) throws -> Self {
|
|
|
|
return Self(unsafeFromRawPointer: pointer)
|
|
|
|
}
|
|
|
|
|
|
|
|
func lower() -> UnsafeMutableRawPointer {
|
|
|
|
return self.pointer
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ideally this would be `fileprivate`, but Swift says:
|
|
|
|
// """
|
|
|
|
// 'private' modifier cannot be used with extensions that declare protocol conformances
|
|
|
|
// """
|
|
|
|
extension TxBuilder : ViaFfi, Serializable {}
|
|
|
|
|
|
|
|
|
|
|
|
public protocol BumpFeeTxBuilderProtocol {
|
|
|
|
func allowShrinking( address: String ) -> BumpFeeTxBuilder
|
|
|
|
func enableRbf() -> BumpFeeTxBuilder
|
|
|
|
func enableRbfWithSequence( nsequence: UInt32 ) -> BumpFeeTxBuilder
|
|
|
|
func finish( wallet: Wallet ) throws -> PartiallySignedBitcoinTransaction
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public class BumpFeeTxBuilder: BumpFeeTxBuilderProtocol {
|
|
|
|
fileprivate let pointer: UnsafeMutableRawPointer
|
|
|
|
|
|
|
|
// TODO: We'd like this to be `private` but for Swifty reasons,
|
|
|
|
// we can't implement `ViaFfi` without making this `required` and we can't
|
|
|
|
// make it `required` without making it `public`.
|
|
|
|
required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) {
|
|
|
|
self.pointer = pointer
|
|
|
|
}
|
|
|
|
public convenience init( txid: String, newFeeRate: Float ) {
|
|
|
|
self.init(unsafeFromRawPointer: try!
|
|
|
|
|
|
|
|
|
|
|
|
rustCall() {
|
|
|
|
|
|
|
|
bdk_360_BumpFeeTxBuilder_new(txid.lower(), newFeeRate.lower() , $0)
|
2022-03-02 15:17:53 -08:00
|
|
|
})
|
|
|
|
}
|
2022-05-13 13:45:48 -07:00
|
|
|
|
|
|
|
deinit {
|
|
|
|
try! rustCall { ffi_bdk_360_BumpFeeTxBuilder_object_free(pointer, $0) }
|
|
|
|
}
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
|
2021-11-24 00:10:26 -08:00
|
|
|
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
public func allowShrinking( address: String ) -> BumpFeeTxBuilder {
|
2022-03-02 15:17:53 -08:00
|
|
|
let _retval = try!
|
|
|
|
rustCall() {
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
bdk_360_BumpFeeTxBuilder_allow_shrinking(self.pointer, address.lower() , $0
|
2022-03-02 15:17:53 -08:00
|
|
|
)
|
|
|
|
}
|
2022-05-13 13:45:48 -07:00
|
|
|
return try! BumpFeeTxBuilder.lift(_retval)
|
|
|
|
}
|
|
|
|
public func enableRbf() -> BumpFeeTxBuilder {
|
|
|
|
let _retval = try!
|
|
|
|
rustCall() {
|
|
|
|
|
|
|
|
bdk_360_BumpFeeTxBuilder_enable_rbf(self.pointer, $0
|
|
|
|
)
|
|
|
|
}
|
|
|
|
return try! BumpFeeTxBuilder.lift(_retval)
|
|
|
|
}
|
|
|
|
public func enableRbfWithSequence( nsequence: UInt32 ) -> BumpFeeTxBuilder {
|
|
|
|
let _retval = try!
|
|
|
|
rustCall() {
|
|
|
|
|
|
|
|
bdk_360_BumpFeeTxBuilder_enable_rbf_with_sequence(self.pointer, nsequence.lower() , $0
|
|
|
|
)
|
|
|
|
}
|
|
|
|
return try! BumpFeeTxBuilder.lift(_retval)
|
|
|
|
}
|
|
|
|
public func finish( wallet: Wallet ) throws -> PartiallySignedBitcoinTransaction {
|
|
|
|
let _retval = try
|
|
|
|
rustCallWithError(BdkError.self) {
|
|
|
|
|
|
|
|
bdk_360_BumpFeeTxBuilder_finish(self.pointer, wallet.lower() , $0
|
|
|
|
)
|
|
|
|
}
|
|
|
|
return try PartiallySignedBitcoinTransaction.lift(_retval)
|
2022-03-02 15:17:53 -08:00
|
|
|
}
|
2021-11-24 00:10:26 -08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
fileprivate extension BumpFeeTxBuilder {
|
2022-03-02 15:17:53 -08:00
|
|
|
typealias FfiType = UnsafeMutableRawPointer
|
2021-11-24 00:10:26 -08:00
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
static func read(from buf: Reader) throws -> Self {
|
2021-11-24 00:10:26 -08:00
|
|
|
let v: UInt64 = try buf.readInt()
|
|
|
|
// The Rust code won't compile if a pointer won't fit in a UInt64.
|
|
|
|
// We have to go via `UInt` because that's the thing that's the size of a pointer.
|
|
|
|
let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v))
|
|
|
|
if (ptr == nil) {
|
|
|
|
throw UniffiInternalError.unexpectedNullPointer
|
|
|
|
}
|
|
|
|
return try self.lift(ptr!)
|
|
|
|
}
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
func write(into buf: Writer) {
|
2021-11-24 00:10:26 -08:00
|
|
|
// This fiddling is because `Int` is the thing that's the same size as a pointer.
|
|
|
|
// The Rust code won't compile if a pointer won't fit in a `UInt64`.
|
|
|
|
buf.writeInt(UInt64(bitPattern: Int64(Int(bitPattern: self.lower()))))
|
|
|
|
}
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
static func lift(_ pointer: UnsafeMutableRawPointer) throws -> Self {
|
2021-11-24 00:10:26 -08:00
|
|
|
return Self(unsafeFromRawPointer: pointer)
|
|
|
|
}
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
func lower() -> UnsafeMutableRawPointer {
|
2021-11-24 00:10:26 -08:00
|
|
|
return self.pointer
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ideally this would be `fileprivate`, but Swift says:
|
|
|
|
// """
|
|
|
|
// 'private' modifier cannot be used with extensions that declare protocol conformances
|
|
|
|
// """
|
2022-05-13 13:45:48 -07:00
|
|
|
extension BumpFeeTxBuilder : ViaFfi, Serializable {}
|
2021-11-24 00:10:26 -08:00
|
|
|
|
|
|
|
public struct SledDbConfiguration {
|
|
|
|
public var path: String
|
|
|
|
public var treeName: String
|
|
|
|
|
|
|
|
// Default memberwise initializers are never public by default, so we
|
|
|
|
// declare one manually.
|
|
|
|
public init(path: String, treeName: String ) {
|
|
|
|
self.path = path
|
|
|
|
self.treeName = treeName
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension SledDbConfiguration: Equatable, Hashable {
|
|
|
|
public static func ==(lhs: SledDbConfiguration, rhs: SledDbConfiguration) -> Bool {
|
|
|
|
if lhs.path != rhs.path {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if lhs.treeName != rhs.treeName {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
public func hash(into hasher: inout Hasher) {
|
|
|
|
hasher.combine(path)
|
|
|
|
hasher.combine(treeName)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fileprivate extension SledDbConfiguration {
|
|
|
|
static func read(from buf: Reader) throws -> SledDbConfiguration {
|
|
|
|
return try SledDbConfiguration(
|
|
|
|
path: String.read(from: buf),
|
|
|
|
treeName: String.read(from: buf)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
func write(into buf: Writer) {
|
|
|
|
self.path.write(into: buf)
|
|
|
|
self.treeName.write(into: buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension SledDbConfiguration: ViaFfiUsingByteBuffer, ViaFfi {}
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
public struct SqliteDbConfiguration {
|
|
|
|
public var path: String
|
|
|
|
|
|
|
|
// Default memberwise initializers are never public by default, so we
|
|
|
|
// declare one manually.
|
|
|
|
public init(path: String ) {
|
|
|
|
self.path = path
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension SqliteDbConfiguration: Equatable, Hashable {
|
|
|
|
public static func ==(lhs: SqliteDbConfiguration, rhs: SqliteDbConfiguration) -> Bool {
|
|
|
|
if lhs.path != rhs.path {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
public func hash(into hasher: inout Hasher) {
|
|
|
|
hasher.combine(path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fileprivate extension SqliteDbConfiguration {
|
|
|
|
static func read(from buf: Reader) throws -> SqliteDbConfiguration {
|
|
|
|
return try SqliteDbConfiguration(
|
|
|
|
path: String.read(from: buf)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
func write(into buf: Writer) {
|
|
|
|
self.path.write(into: buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension SqliteDbConfiguration: ViaFfiUsingByteBuffer, ViaFfi {}
|
|
|
|
|
2021-11-24 00:10:26 -08:00
|
|
|
public struct TransactionDetails {
|
2022-05-13 13:45:48 -07:00
|
|
|
public var fee: UInt64?
|
2021-11-24 00:10:26 -08:00
|
|
|
public var received: UInt64
|
|
|
|
public var sent: UInt64
|
|
|
|
public var txid: String
|
|
|
|
|
|
|
|
// Default memberwise initializers are never public by default, so we
|
|
|
|
// declare one manually.
|
2022-05-13 13:45:48 -07:00
|
|
|
public init(fee: UInt64?, received: UInt64, sent: UInt64, txid: String ) {
|
|
|
|
self.fee = fee
|
2021-11-24 00:10:26 -08:00
|
|
|
self.received = received
|
|
|
|
self.sent = sent
|
|
|
|
self.txid = txid
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension TransactionDetails: Equatable, Hashable {
|
|
|
|
public static func ==(lhs: TransactionDetails, rhs: TransactionDetails) -> Bool {
|
2022-05-13 13:45:48 -07:00
|
|
|
if lhs.fee != rhs.fee {
|
2021-11-24 00:10:26 -08:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
if lhs.received != rhs.received {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if lhs.sent != rhs.sent {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if lhs.txid != rhs.txid {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
public func hash(into hasher: inout Hasher) {
|
2022-05-13 13:45:48 -07:00
|
|
|
hasher.combine(fee)
|
2021-11-24 00:10:26 -08:00
|
|
|
hasher.combine(received)
|
|
|
|
hasher.combine(sent)
|
|
|
|
hasher.combine(txid)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fileprivate extension TransactionDetails {
|
|
|
|
static func read(from buf: Reader) throws -> TransactionDetails {
|
|
|
|
return try TransactionDetails(
|
2022-05-13 13:45:48 -07:00
|
|
|
fee: FfiConverterOptionUInt64.read(from: buf),
|
2021-11-24 00:10:26 -08:00
|
|
|
received: UInt64.read(from: buf),
|
|
|
|
sent: UInt64.read(from: buf),
|
|
|
|
txid: String.read(from: buf)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
func write(into buf: Writer) {
|
2022-05-13 13:45:48 -07:00
|
|
|
FfiConverterOptionUInt64.write(self.fee, into: buf)
|
2021-11-24 00:10:26 -08:00
|
|
|
self.received.write(into: buf)
|
|
|
|
self.sent.write(into: buf)
|
|
|
|
self.txid.write(into: buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension TransactionDetails: ViaFfiUsingByteBuffer, ViaFfi {}
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
public struct BlockTime {
|
2021-11-24 00:10:26 -08:00
|
|
|
public var height: UInt32
|
|
|
|
public var timestamp: UInt64
|
|
|
|
|
|
|
|
// Default memberwise initializers are never public by default, so we
|
|
|
|
// declare one manually.
|
|
|
|
public init(height: UInt32, timestamp: UInt64 ) {
|
|
|
|
self.height = height
|
|
|
|
self.timestamp = timestamp
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
extension BlockTime: Equatable, Hashable {
|
|
|
|
public static func ==(lhs: BlockTime, rhs: BlockTime) -> Bool {
|
2021-11-24 00:10:26 -08:00
|
|
|
if lhs.height != rhs.height {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if lhs.timestamp != rhs.timestamp {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
public func hash(into hasher: inout Hasher) {
|
|
|
|
hasher.combine(height)
|
|
|
|
hasher.combine(timestamp)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
fileprivate extension BlockTime {
|
|
|
|
static func read(from buf: Reader) throws -> BlockTime {
|
|
|
|
return try BlockTime(
|
2021-11-24 00:10:26 -08:00
|
|
|
height: UInt32.read(from: buf),
|
|
|
|
timestamp: UInt64.read(from: buf)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
func write(into buf: Writer) {
|
|
|
|
self.height.write(into: buf)
|
|
|
|
self.timestamp.write(into: buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-02 15:17:53 -08:00
|
|
|
extension BlockTime: ViaFfiUsingByteBuffer, ViaFfi {}
|
2021-11-24 00:10:26 -08:00
|
|
|
|
|
|
|
public struct ElectrumConfig {
|
|
|
|
public var url: String
|
|
|
|
public var socks5: String?
|
|
|
|
public var retry: UInt8
|
|
|
|
public var timeout: UInt8?
|
|
|
|
public var stopGap: UInt64
|
|
|
|
|
|
|
|
// Default memberwise initializers are never public by default, so we
|
|
|
|
// declare one manually.
|
|
|
|
public init(url: String, socks5: String?, retry: UInt8, timeout: UInt8?, stopGap: UInt64 ) {
|
|
|
|
self.url = url
|
|
|
|
self.socks5 = socks5
|
|
|
|
self.retry = retry
|
|
|
|
self.timeout = timeout
|
|
|
|
self.stopGap = stopGap
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension ElectrumConfig: Equatable, Hashable {
|
|
|
|
public static func ==(lhs: ElectrumConfig, rhs: ElectrumConfig) -> Bool {
|
|
|
|
if lhs.url != rhs.url {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if lhs.socks5 != rhs.socks5 {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if lhs.retry != rhs.retry {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if lhs.timeout != rhs.timeout {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if lhs.stopGap != rhs.stopGap {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
public func hash(into hasher: inout Hasher) {
|
|
|
|
hasher.combine(url)
|
|
|
|
hasher.combine(socks5)
|
|
|
|
hasher.combine(retry)
|
|
|
|
hasher.combine(timeout)
|
|
|
|
hasher.combine(stopGap)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fileprivate extension ElectrumConfig {
|
|
|
|
static func read(from buf: Reader) throws -> ElectrumConfig {
|
|
|
|
return try ElectrumConfig(
|
|
|
|
url: String.read(from: buf),
|
|
|
|
socks5: FfiConverterOptionString.read(from: buf),
|
|
|
|
retry: UInt8.read(from: buf),
|
|
|
|
timeout: FfiConverterOptionUInt8.read(from: buf),
|
|
|
|
stopGap: UInt64.read(from: buf)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
func write(into buf: Writer) {
|
|
|
|
self.url.write(into: buf)
|
|
|
|
FfiConverterOptionString.write(self.socks5, into: buf)
|
|
|
|
self.retry.write(into: buf)
|
|
|
|
FfiConverterOptionUInt8.write(self.timeout, into: buf)
|
|
|
|
self.stopGap.write(into: buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension ElectrumConfig: ViaFfiUsingByteBuffer, ViaFfi {}
|
|
|
|
|
|
|
|
public struct EsploraConfig {
|
|
|
|
public var baseUrl: String
|
|
|
|
public var proxy: String?
|
2022-05-13 13:45:48 -07:00
|
|
|
public var concurrency: UInt8?
|
2021-11-24 00:10:26 -08:00
|
|
|
public var stopGap: UInt64
|
2022-05-13 13:45:48 -07:00
|
|
|
public var timeout: UInt64?
|
2021-11-24 00:10:26 -08:00
|
|
|
|
|
|
|
// Default memberwise initializers are never public by default, so we
|
|
|
|
// declare one manually.
|
2022-05-13 13:45:48 -07:00
|
|
|
public init(baseUrl: String, proxy: String?, concurrency: UInt8?, stopGap: UInt64, timeout: UInt64? ) {
|
2021-11-24 00:10:26 -08:00
|
|
|
self.baseUrl = baseUrl
|
|
|
|
self.proxy = proxy
|
2022-05-13 13:45:48 -07:00
|
|
|
self.concurrency = concurrency
|
2021-11-24 00:10:26 -08:00
|
|
|
self.stopGap = stopGap
|
2022-05-13 13:45:48 -07:00
|
|
|
self.timeout = timeout
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension EsploraConfig: Equatable, Hashable {
|
|
|
|
public static func ==(lhs: EsploraConfig, rhs: EsploraConfig) -> Bool {
|
|
|
|
if lhs.baseUrl != rhs.baseUrl {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if lhs.proxy != rhs.proxy {
|
|
|
|
return false
|
|
|
|
}
|
2022-05-13 13:45:48 -07:00
|
|
|
if lhs.concurrency != rhs.concurrency {
|
2021-11-24 00:10:26 -08:00
|
|
|
return false
|
|
|
|
}
|
2022-05-13 13:45:48 -07:00
|
|
|
if lhs.stopGap != rhs.stopGap {
|
2021-11-24 00:10:26 -08:00
|
|
|
return false
|
|
|
|
}
|
2022-05-13 13:45:48 -07:00
|
|
|
if lhs.timeout != rhs.timeout {
|
2021-11-24 00:10:26 -08:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
public func hash(into hasher: inout Hasher) {
|
|
|
|
hasher.combine(baseUrl)
|
|
|
|
hasher.combine(proxy)
|
2022-05-13 13:45:48 -07:00
|
|
|
hasher.combine(concurrency)
|
2021-11-24 00:10:26 -08:00
|
|
|
hasher.combine(stopGap)
|
2022-05-13 13:45:48 -07:00
|
|
|
hasher.combine(timeout)
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fileprivate extension EsploraConfig {
|
|
|
|
static func read(from buf: Reader) throws -> EsploraConfig {
|
|
|
|
return try EsploraConfig(
|
|
|
|
baseUrl: String.read(from: buf),
|
|
|
|
proxy: FfiConverterOptionString.read(from: buf),
|
2022-05-13 13:45:48 -07:00
|
|
|
concurrency: FfiConverterOptionUInt8.read(from: buf),
|
|
|
|
stopGap: UInt64.read(from: buf),
|
|
|
|
timeout: FfiConverterOptionUInt64.read(from: buf)
|
2021-11-24 00:10:26 -08:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
func write(into buf: Writer) {
|
|
|
|
self.baseUrl.write(into: buf)
|
|
|
|
FfiConverterOptionString.write(self.proxy, into: buf)
|
2022-05-13 13:45:48 -07:00
|
|
|
FfiConverterOptionUInt8.write(self.concurrency, into: buf)
|
2021-11-24 00:10:26 -08:00
|
|
|
self.stopGap.write(into: buf)
|
2022-05-13 13:45:48 -07:00
|
|
|
FfiConverterOptionUInt64.write(self.timeout, into: buf)
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension EsploraConfig: ViaFfiUsingByteBuffer, ViaFfi {}
|
|
|
|
|
|
|
|
public struct ExtendedKeyInfo {
|
|
|
|
public var mnemonic: String
|
|
|
|
public var xprv: String
|
|
|
|
public var fingerprint: String
|
|
|
|
|
|
|
|
// Default memberwise initializers are never public by default, so we
|
|
|
|
// declare one manually.
|
|
|
|
public init(mnemonic: String, xprv: String, fingerprint: String ) {
|
|
|
|
self.mnemonic = mnemonic
|
|
|
|
self.xprv = xprv
|
|
|
|
self.fingerprint = fingerprint
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension ExtendedKeyInfo: Equatable, Hashable {
|
|
|
|
public static func ==(lhs: ExtendedKeyInfo, rhs: ExtendedKeyInfo) -> Bool {
|
|
|
|
if lhs.mnemonic != rhs.mnemonic {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if lhs.xprv != rhs.xprv {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if lhs.fingerprint != rhs.fingerprint {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
public func hash(into hasher: inout Hasher) {
|
|
|
|
hasher.combine(mnemonic)
|
|
|
|
hasher.combine(xprv)
|
|
|
|
hasher.combine(fingerprint)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fileprivate extension ExtendedKeyInfo {
|
|
|
|
static func read(from buf: Reader) throws -> ExtendedKeyInfo {
|
|
|
|
return try ExtendedKeyInfo(
|
|
|
|
mnemonic: String.read(from: buf),
|
|
|
|
xprv: String.read(from: buf),
|
|
|
|
fingerprint: String.read(from: buf)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
func write(into buf: Writer) {
|
|
|
|
self.mnemonic.write(into: buf)
|
|
|
|
self.xprv.write(into: buf)
|
|
|
|
self.fingerprint.write(into: buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension ExtendedKeyInfo: ViaFfiUsingByteBuffer, ViaFfi {}
|
|
|
|
|
|
|
|
public enum BdkError {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case InvalidU32Bytes(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case Generic(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case ScriptDoesntHaveAddressForm(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case NoRecipients(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case NoUtxosSelected(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case OutputBelowDustLimit(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case InsufficientFunds(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case BnBTotalTriesExceeded(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case BnBNoExactMatch(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case UnknownUtxo(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case TransactionNotFound(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case TransactionConfirmed(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case IrreplaceableTransaction(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case FeeRateTooLow(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case FeeTooLow(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case FeeRateUnavailable(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case MissingKeyOrigin(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case Key(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case ChecksumMismatch(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case SpendingPolicyRequired(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case InvalidPolicyPathError(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case Signer(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case InvalidNetwork(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case InvalidProgressValue(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case ProgressUpdateError(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case InvalidOutpoint(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case Descriptor(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case AddressValidator(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case Encode(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case Miniscript(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case Bip32(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case Secp256k1(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case Json(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case Hex(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case Psbt(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case PsbtParse(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case Electrum(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case Esplora(message: String)
|
|
|
|
|
|
|
|
// Simple error enums only carry a message
|
|
|
|
case Sled(message: String)
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
// Simple error enums only carry a message
|
|
|
|
case Rusqlite(message: String)
|
|
|
|
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
extension BdkError: ViaFfiUsingByteBuffer, ViaFfi {
|
|
|
|
fileprivate static func read(from buf: Reader) throws -> BdkError {
|
|
|
|
let variant: Int32 = try buf.readInt()
|
|
|
|
switch variant {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case 1: return .InvalidU32Bytes(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 2: return .Generic(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 3: return .ScriptDoesntHaveAddressForm(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 4: return .NoRecipients(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 5: return .NoUtxosSelected(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 6: return .OutputBelowDustLimit(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 7: return .InsufficientFunds(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 8: return .BnBTotalTriesExceeded(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 9: return .BnBNoExactMatch(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 10: return .UnknownUtxo(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 11: return .TransactionNotFound(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 12: return .TransactionConfirmed(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 13: return .IrreplaceableTransaction(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 14: return .FeeRateTooLow(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 15: return .FeeTooLow(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 16: return .FeeRateUnavailable(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 17: return .MissingKeyOrigin(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 18: return .Key(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 19: return .ChecksumMismatch(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 20: return .SpendingPolicyRequired(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 21: return .InvalidPolicyPathError(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 22: return .Signer(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 23: return .InvalidNetwork(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 24: return .InvalidProgressValue(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 25: return .ProgressUpdateError(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 26: return .InvalidOutpoint(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 27: return .Descriptor(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 28: return .AddressValidator(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 29: return .Encode(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 30: return .Miniscript(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 31: return .Bip32(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 32: return .Secp256k1(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 33: return .Json(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 34: return .Hex(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 35: return .Psbt(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 36: return .PsbtParse(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 37: return .Electrum(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 38: return .Esplora(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
|
|
|
case 39: return .Sled(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
case 40: return .Rusqlite(
|
|
|
|
message: try String.read(from: buf)
|
|
|
|
)
|
|
|
|
|
2021-11-24 00:10:26 -08:00
|
|
|
|
|
|
|
default: throw UniffiInternalError.unexpectedEnumCase
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate func write(into buf: Writer) {
|
|
|
|
switch self {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case let .InvalidU32Bytes(message):
|
|
|
|
buf.writeInt(Int32(1))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .Generic(message):
|
|
|
|
buf.writeInt(Int32(2))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .ScriptDoesntHaveAddressForm(message):
|
|
|
|
buf.writeInt(Int32(3))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .NoRecipients(message):
|
|
|
|
buf.writeInt(Int32(4))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .NoUtxosSelected(message):
|
|
|
|
buf.writeInt(Int32(5))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .OutputBelowDustLimit(message):
|
|
|
|
buf.writeInt(Int32(6))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .InsufficientFunds(message):
|
|
|
|
buf.writeInt(Int32(7))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .BnBTotalTriesExceeded(message):
|
|
|
|
buf.writeInt(Int32(8))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .BnBNoExactMatch(message):
|
|
|
|
buf.writeInt(Int32(9))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .UnknownUtxo(message):
|
|
|
|
buf.writeInt(Int32(10))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .TransactionNotFound(message):
|
|
|
|
buf.writeInt(Int32(11))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .TransactionConfirmed(message):
|
|
|
|
buf.writeInt(Int32(12))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .IrreplaceableTransaction(message):
|
|
|
|
buf.writeInt(Int32(13))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .FeeRateTooLow(message):
|
|
|
|
buf.writeInt(Int32(14))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .FeeTooLow(message):
|
|
|
|
buf.writeInt(Int32(15))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .FeeRateUnavailable(message):
|
|
|
|
buf.writeInt(Int32(16))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .MissingKeyOrigin(message):
|
|
|
|
buf.writeInt(Int32(17))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .Key(message):
|
|
|
|
buf.writeInt(Int32(18))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .ChecksumMismatch(message):
|
|
|
|
buf.writeInt(Int32(19))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .SpendingPolicyRequired(message):
|
|
|
|
buf.writeInt(Int32(20))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .InvalidPolicyPathError(message):
|
|
|
|
buf.writeInt(Int32(21))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .Signer(message):
|
|
|
|
buf.writeInt(Int32(22))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .InvalidNetwork(message):
|
|
|
|
buf.writeInt(Int32(23))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .InvalidProgressValue(message):
|
|
|
|
buf.writeInt(Int32(24))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .ProgressUpdateError(message):
|
|
|
|
buf.writeInt(Int32(25))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .InvalidOutpoint(message):
|
|
|
|
buf.writeInt(Int32(26))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .Descriptor(message):
|
|
|
|
buf.writeInt(Int32(27))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .AddressValidator(message):
|
|
|
|
buf.writeInt(Int32(28))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .Encode(message):
|
|
|
|
buf.writeInt(Int32(29))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .Miniscript(message):
|
|
|
|
buf.writeInt(Int32(30))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .Bip32(message):
|
|
|
|
buf.writeInt(Int32(31))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .Secp256k1(message):
|
|
|
|
buf.writeInt(Int32(32))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .Json(message):
|
|
|
|
buf.writeInt(Int32(33))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .Hex(message):
|
|
|
|
buf.writeInt(Int32(34))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .Psbt(message):
|
|
|
|
buf.writeInt(Int32(35))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .PsbtParse(message):
|
|
|
|
buf.writeInt(Int32(36))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .Electrum(message):
|
|
|
|
buf.writeInt(Int32(37))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .Esplora(message):
|
|
|
|
buf.writeInt(Int32(38))
|
|
|
|
message.write(into: buf)
|
|
|
|
case let .Sled(message):
|
|
|
|
buf.writeInt(Int32(39))
|
|
|
|
message.write(into: buf)
|
2022-05-13 13:45:48 -07:00
|
|
|
case let .Rusqlite(message):
|
|
|
|
buf.writeInt(Int32(40))
|
|
|
|
message.write(into: buf)
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension BdkError: Equatable, Hashable {}
|
|
|
|
|
|
|
|
extension BdkError: Error { }
|
|
|
|
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
// Declaration and FfiConverters for Progress Callback Interface
|
2021-11-24 00:10:26 -08:00
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
public protocol Progress : AnyObject {
|
2022-03-02 15:17:53 -08:00
|
|
|
func update( progress: Float, message: String? )
|
2021-11-24 00:10:26 -08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// The ForeignCallback that is passed to Rust.
|
2022-05-13 13:45:48 -07:00
|
|
|
fileprivate let foreignCallbackCallbackInterfaceProgress : ForeignCallback =
|
2022-03-02 15:17:53 -08:00
|
|
|
{ (handle: Handle, method: Int32, args: RustBuffer, out_buf: UnsafeMutablePointer<RustBuffer>) -> Int32 in
|
2022-05-13 13:45:48 -07:00
|
|
|
func invokeUpdate(_ swiftCallbackInterface: Progress, _ args: RustBuffer) throws -> RustBuffer {
|
2021-11-24 00:10:26 -08:00
|
|
|
defer { args.deallocate() }
|
|
|
|
|
|
|
|
let reader = Reader(data: Data(rustBuffer: args))
|
|
|
|
swiftCallbackInterface.update(
|
|
|
|
progress: try Float.read(from: reader),
|
|
|
|
message: try FfiConverterOptionString.read(from: reader)
|
|
|
|
)
|
|
|
|
return RustBuffer()
|
|
|
|
// TODO catch errors and report them back to Rust.
|
|
|
|
// https://github.com/mozilla/uniffi-rs/issues/351
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
let cb = try! ffiConverterCallbackInterfaceProgress.lift(handle)
|
2021-11-24 00:10:26 -08:00
|
|
|
switch method {
|
|
|
|
case IDX_CALLBACK_FREE:
|
2022-05-13 13:45:48 -07:00
|
|
|
ffiConverterCallbackInterfaceProgress.drop(handle: handle)
|
2022-03-02 15:17:53 -08:00
|
|
|
// No return value.
|
|
|
|
// See docs of ForeignCallback in `uniffi/src/ffi/foreigncallbacks.rs`
|
|
|
|
return 0
|
|
|
|
case 1:
|
|
|
|
let buffer = try! invokeUpdate(cb, args)
|
|
|
|
out_buf.pointee = buffer
|
|
|
|
// Value written to out buffer.
|
|
|
|
// See docs of ForeignCallback in `uniffi/src/ffi/foreigncallbacks.rs`
|
|
|
|
return 1
|
2021-11-24 00:10:26 -08:00
|
|
|
|
|
|
|
// This should never happen, because an out of bounds method index won't
|
|
|
|
// ever be used. Once we can catch errors, we should return an InternalError.
|
|
|
|
// https://github.com/mozilla/uniffi-rs/issues/351
|
2022-03-02 15:17:53 -08:00
|
|
|
default:
|
|
|
|
// An unexpected error happened.
|
|
|
|
// See docs of ForeignCallback in `uniffi/src/ffi/foreigncallbacks.rs`
|
|
|
|
return -1
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// The ffiConverter which transforms the Callbacks in to Handles to pass to Rust.
|
2022-05-13 13:45:48 -07:00
|
|
|
private let ffiConverterCallbackInterfaceProgress: FfiConverterCallbackInterface<Progress> = {
|
2021-11-24 00:10:26 -08:00
|
|
|
try! rustCall { (err: UnsafeMutablePointer<RustCallStatus>) in
|
2022-05-13 13:45:48 -07:00
|
|
|
ffi_bdk_360_Progress_init_callback(foreignCallbackCallbackInterfaceProgress, err)
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
2022-05-13 13:45:48 -07:00
|
|
|
return FfiConverterCallbackInterface<Progress>()
|
2021-11-24 00:10:26 -08:00
|
|
|
}()
|
|
|
|
extension UInt8: Primitive, ViaFfi {
|
|
|
|
fileprivate static func read(from buf: Reader) throws -> Self {
|
|
|
|
return try self.lift(buf.readInt())
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate func write(into buf: Writer) {
|
|
|
|
buf.writeInt(self.lower())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
extension UInt32: Primitive, ViaFfi {
|
|
|
|
fileprivate static func read(from buf: Reader) throws -> Self {
|
|
|
|
return try self.lift(buf.readInt())
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate func write(into buf: Writer) {
|
|
|
|
buf.writeInt(self.lower())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
extension UInt64: Primitive, ViaFfi {
|
|
|
|
fileprivate static func read(from buf: Reader) throws -> Self {
|
|
|
|
return try self.lift(buf.readInt())
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate func write(into buf: Writer) {
|
|
|
|
buf.writeInt(self.lower())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
extension Float: Primitive, ViaFfi {
|
|
|
|
fileprivate static func read(from buf: Reader) throws -> Self {
|
|
|
|
return try self.lift(buf.readFloat())
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate func write(into buf: Writer) {
|
|
|
|
buf.writeFloat(self.lower())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
extension String: ViaFfi {
|
|
|
|
fileprivate typealias FfiType = RustBuffer
|
|
|
|
|
|
|
|
fileprivate static func lift(_ v: FfiType) throws -> Self {
|
|
|
|
defer {
|
|
|
|
v.deallocate()
|
|
|
|
}
|
|
|
|
if v.data == nil {
|
|
|
|
return String()
|
|
|
|
}
|
|
|
|
let bytes = UnsafeBufferPointer<UInt8>(start: v.data!, count: Int(v.len))
|
|
|
|
return String(bytes: bytes, encoding: String.Encoding.utf8)!
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate func lower() -> FfiType {
|
|
|
|
return self.utf8CString.withUnsafeBufferPointer { ptr in
|
|
|
|
// The swift string gives us int8_t, we want uint8_t.
|
|
|
|
ptr.withMemoryRebound(to: UInt8.self) { ptr in
|
|
|
|
// The swift string gives us a trailing null byte, we don't want it.
|
|
|
|
let buf = UnsafeBufferPointer(rebasing: ptr.prefix(upTo: ptr.count - 1))
|
|
|
|
return RustBuffer.from(buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate static func read(from buf: Reader) throws -> Self {
|
|
|
|
let len: Int32 = try buf.readInt()
|
|
|
|
return String(bytes: try buf.readBytes(count: Int(len)), encoding: String.Encoding.utf8)!
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate func write(into buf: Writer) {
|
|
|
|
let len = Int32(self.utf8.count)
|
|
|
|
buf.writeInt(len)
|
|
|
|
buf.writeBytes(self.utf8)
|
|
|
|
}
|
|
|
|
}
|
2022-05-13 13:45:48 -07:00
|
|
|
// Helper code for Blockchain class is found in ObjectTemplate.swift
|
|
|
|
// Helper code for BumpFeeTxBuilder class is found in ObjectTemplate.swift
|
2021-11-24 00:10:26 -08:00
|
|
|
// Helper code for PartiallySignedBitcoinTransaction class is found in ObjectTemplate.swift
|
2022-05-13 13:45:48 -07:00
|
|
|
// Helper code for TxBuilder class is found in ObjectTemplate.swift
|
2022-03-02 15:17:53 -08:00
|
|
|
// Helper code for Wallet class is found in ObjectTemplate.swift
|
|
|
|
// Helper code for BlockTime record is found in RecordTemplate.swift
|
2021-11-24 00:10:26 -08:00
|
|
|
// Helper code for ElectrumConfig record is found in RecordTemplate.swift
|
|
|
|
// Helper code for EsploraConfig record is found in RecordTemplate.swift
|
|
|
|
// Helper code for ExtendedKeyInfo record is found in RecordTemplate.swift
|
|
|
|
// Helper code for SledDbConfiguration record is found in RecordTemplate.swift
|
2022-05-13 13:45:48 -07:00
|
|
|
// Helper code for SqliteDbConfiguration record is found in RecordTemplate.swift
|
2021-11-24 00:10:26 -08:00
|
|
|
// Helper code for TransactionDetails record is found in RecordTemplate.swift
|
|
|
|
// Helper code for BlockchainConfig enum is found in EnumTemplate.swift
|
|
|
|
// Helper code for DatabaseConfig enum is found in EnumTemplate.swift
|
|
|
|
// Helper code for Network enum is found in EnumTemplate.swift
|
|
|
|
// Helper code for Transaction enum is found in EnumTemplate.swift
|
2022-03-02 15:17:53 -08:00
|
|
|
// Helper code for WordCount enum is found in EnumTemplate.swift
|
2021-11-24 00:10:26 -08:00
|
|
|
// Helper code for BdkError error is found in ErrorTemplate.swift
|
|
|
|
|
|
|
|
fileprivate enum FfiConverterOptionUInt8: FfiConverterUsingByteBuffer {
|
|
|
|
typealias SwiftType = UInt8?
|
|
|
|
|
|
|
|
static func write(_ value: SwiftType, into buf: Writer) {
|
|
|
|
FfiConverterOptional.write(value, into: buf) { item, buf in
|
|
|
|
item.write(into: buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static func read(from buf: Reader) throws -> SwiftType {
|
|
|
|
try FfiConverterOptional.read(from: buf) { buf in
|
|
|
|
try UInt8.read(from: buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate enum FfiConverterOptionUInt64: FfiConverterUsingByteBuffer {
|
|
|
|
typealias SwiftType = UInt64?
|
|
|
|
|
|
|
|
static func write(_ value: SwiftType, into buf: Writer) {
|
|
|
|
FfiConverterOptional.write(value, into: buf) { item, buf in
|
|
|
|
item.write(into: buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static func read(from buf: Reader) throws -> SwiftType {
|
|
|
|
try FfiConverterOptional.read(from: buf) { buf in
|
|
|
|
try UInt64.read(from: buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
fileprivate enum FfiConverterOptionString: FfiConverterUsingByteBuffer {
|
|
|
|
typealias SwiftType = String?
|
2021-11-24 00:10:26 -08:00
|
|
|
|
|
|
|
static func write(_ value: SwiftType, into buf: Writer) {
|
|
|
|
FfiConverterOptional.write(value, into: buf) { item, buf in
|
|
|
|
item.write(into: buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static func read(from buf: Reader) throws -> SwiftType {
|
|
|
|
try FfiConverterOptional.read(from: buf) { buf in
|
2022-05-13 13:45:48 -07:00
|
|
|
try String.read(from: buf)
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-13 13:45:48 -07:00
|
|
|
fileprivate enum FfiConverterOptionCallbackInterfaceProgress: FfiConverterUsingByteBuffer {
|
|
|
|
typealias SwiftType = Progress?
|
2021-11-24 00:10:26 -08:00
|
|
|
|
|
|
|
static func write(_ value: SwiftType, into buf: Writer) {
|
|
|
|
FfiConverterOptional.write(value, into: buf) { item, buf in
|
2022-05-13 13:45:48 -07:00
|
|
|
ffiConverterCallbackInterfaceProgress.write(item, into: buf)
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static func read(from buf: Reader) throws -> SwiftType {
|
|
|
|
try FfiConverterOptional.read(from: buf) { buf in
|
2022-05-13 13:45:48 -07:00
|
|
|
try ffiConverterCallbackInterfaceProgress.read(from: buf)
|
2021-11-24 00:10:26 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate enum FfiConverterSequenceEnumTransaction: FfiConverterUsingByteBuffer {
|
|
|
|
typealias SwiftType = [Transaction]
|
|
|
|
|
|
|
|
static func write(_ value: SwiftType, into buf: Writer) {
|
|
|
|
FfiConverterSequence.write(value, into: buf) { (item, buf) in
|
|
|
|
item.write(into: buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static func read(from buf: Reader) throws -> SwiftType {
|
|
|
|
try FfiConverterSequence.read(from: buf) { buf in
|
|
|
|
try Transaction.read(from: buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Top level initializers and tear down methods.
|
|
|
|
*
|
|
|
|
* This is generated by uniffi.
|
|
|
|
*/
|
|
|
|
public enum BdkLifecycle {
|
|
|
|
/**
|
|
|
|
* Initialize the FFI and Rust library. This should be only called once per application.
|
|
|
|
*/
|
|
|
|
func initialize() {
|
|
|
|
|
|
|
|
// No initialization code needed
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|