diff --git a/Cargo.lock b/Cargo.lock index b4723da..25bca7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -475,7 +475,7 @@ dependencies = [ [[package]] name = "bitkitcore" -version = "0.3.4" +version = "0.3.5" dependencies = [ "android_logger", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 1da0bca..70ccfea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bitkitcore" -version = "0.3.4" +version = "0.3.5" edition = "2021" [lib] diff --git a/Package.swift b/Package.swift index 3ea4ac6..fb81a2f 100644 --- a/Package.swift +++ b/Package.swift @@ -3,8 +3,8 @@ import PackageDescription -let tag = "v0.3.4" -let checksum = "a34aafd347e8fdb2cba31b504e441083467ba2974b437e5934ffa23eeb950923" +let tag = "v0.3.5" +let checksum = "bd1dcde687950d5dcaa5ea86d8fb8e3b8e68fd3cfdfca024e3bc4ee54746ea07" let url = "https://github.com/synonymdev/bitkit-core/releases/download/\(tag)/BitkitCore.xcframework.zip" let package = Package( diff --git a/bindings/android/gradle.properties b/bindings/android/gradle.properties index 0b84703..2508c3a 100644 --- a/bindings/android/gradle.properties +++ b/bindings/android/gradle.properties @@ -3,4 +3,4 @@ android.useAndroidX=true android.enableJetifier=true kotlin.code.style=official group=com.synonym -version=0.3.4 +version=0.3.5 diff --git a/bindings/android/lib/src/main/jniLibs/arm64-v8a/libbitkitcore.so b/bindings/android/lib/src/main/jniLibs/arm64-v8a/libbitkitcore.so index 0efcd5f..aaa867d 100755 Binary files a/bindings/android/lib/src/main/jniLibs/arm64-v8a/libbitkitcore.so and b/bindings/android/lib/src/main/jniLibs/arm64-v8a/libbitkitcore.so differ diff --git a/bindings/android/lib/src/main/jniLibs/armeabi-v7a/libbitkitcore.so b/bindings/android/lib/src/main/jniLibs/armeabi-v7a/libbitkitcore.so index 8891d49..d9eb362 100755 Binary files a/bindings/android/lib/src/main/jniLibs/armeabi-v7a/libbitkitcore.so and b/bindings/android/lib/src/main/jniLibs/armeabi-v7a/libbitkitcore.so differ diff --git a/bindings/android/lib/src/main/jniLibs/x86/libbitkitcore.so b/bindings/android/lib/src/main/jniLibs/x86/libbitkitcore.so index 9d9beb1..7be9900 100755 Binary files a/bindings/android/lib/src/main/jniLibs/x86/libbitkitcore.so and b/bindings/android/lib/src/main/jniLibs/x86/libbitkitcore.so differ diff --git a/bindings/android/lib/src/main/jniLibs/x86_64/libbitkitcore.so b/bindings/android/lib/src/main/jniLibs/x86_64/libbitkitcore.so index 06ae8a3..bce10ad 100755 Binary files a/bindings/android/lib/src/main/jniLibs/x86_64/libbitkitcore.so and b/bindings/android/lib/src/main/jniLibs/x86_64/libbitkitcore.so differ diff --git a/bindings/android/lib/src/main/kotlin/com/synonym/bitkitcore/bitkitcore.android.kt b/bindings/android/lib/src/main/kotlin/com/synonym/bitkitcore/bitkitcore.android.kt index 6ae5266..ecf8074 100644 --- a/bindings/android/lib/src/main/kotlin/com/synonym/bitkitcore/bitkitcore.android.kt +++ b/bindings/android/lib/src/main/kotlin/com/synonym/bitkitcore/bitkitcore.android.kt @@ -1487,6 +1487,8 @@ internal typealias UniffiVTableCallbackInterfaceTrezorUiCallbackUniffiByValue = + + @@ -1706,6 +1708,9 @@ internal object IntegrityCheckingUniffiLib : Library { if (uniffi_bitkitcore_checksum_func_get_pre_activity_metadata() != 24738.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (uniffi_bitkitcore_checksum_func_get_supported_hardware_wallets() != 36542.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } if (uniffi_bitkitcore_checksum_func_get_tags() != 8596.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } @@ -2196,6 +2201,9 @@ internal object IntegrityCheckingUniffiLib : Library { external fun uniffi_bitkitcore_checksum_func_get_pre_activity_metadata( ): Short @JvmStatic + external fun uniffi_bitkitcore_checksum_func_get_supported_hardware_wallets( + ): Short + @JvmStatic external fun uniffi_bitkitcore_checksum_func_get_tags( ): Short @JvmStatic @@ -2984,6 +2992,10 @@ internal object UniffiLib : Library { uniffiCallStatus: UniffiRustCallStatus, ): RustBufferByValue @JvmStatic + external fun uniffi_bitkitcore_fn_func_get_supported_hardware_wallets( + uniffiCallStatus: UniffiRustCallStatus, + ): RustBufferByValue + @JvmStatic external fun uniffi_bitkitcore_fn_func_get_tags( `walletId`: RustBufferByValue, `activityId`: RustBufferByValue, @@ -7289,6 +7301,37 @@ public object FfiConverterTypeSingleAddressInfoResult: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): SupportedHardwareWallet { + return SupportedHardwareWallet( + FfiConverterTypeHardwareWalletVendor.read(buf), + FfiConverterString.read(buf), + FfiConverterString.read(buf), + FfiConverterString.read(buf), + FfiConverterSequenceTypeTrezorTransportType.read(buf), + ) + } + + override fun allocationSize(value: SupportedHardwareWallet): ULong = ( + FfiConverterTypeHardwareWalletVendor.allocationSize(value.`vendor`) + + FfiConverterString.allocationSize(value.`vendorName`) + + FfiConverterString.allocationSize(value.`model`) + + FfiConverterString.allocationSize(value.`displayName`) + + FfiConverterSequenceTypeTrezorTransportType.allocationSize(value.`transports`) + ) + + override fun write(value: SupportedHardwareWallet, buf: ByteBuffer) { + FfiConverterTypeHardwareWalletVendor.write(value.`vendor`, buf) + FfiConverterString.write(value.`vendorName`, buf) + FfiConverterString.write(value.`model`, buf) + FfiConverterString.write(value.`displayName`, buf) + FfiConverterSequenceTypeTrezorTransportType.write(value.`transports`, buf) + } +} + + + + public object FfiConverterTypeSweepResult: FfiConverterRustBuffer { override fun read(buf: ByteBuffer): SweepResult { return SweepResult( @@ -9612,6 +9655,24 @@ public object FfiConverterTypeDecodingError : FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): HardwareWalletVendor = try { + HardwareWalletVendor.entries[buf.getInt() - 1] + } catch (e: IndexOutOfBoundsException) { + throw RuntimeException("invalid enum value, something is very wrong!!", e) + } + + override fun allocationSize(value: HardwareWalletVendor): ULong = 4UL + + override fun write(value: HardwareWalletVendor, buf: ByteBuffer) { + buf.putInt(value.ordinal + 1) + } +} + + + + public object LnurlExceptionErrorHandler : UniffiRustCallStatusErrorHandler { override fun lift(errorBuf: RustBufferByValue): LnurlException = FfiConverterTypeLnurlError.lift(errorBuf) } @@ -12618,6 +12679,31 @@ public object FfiConverterSequenceTypePubkyProfileLink: FfiConverterRustBuffer> { + override fun read(buf: ByteBuffer): List { + val len = buf.getInt() + return List(len) { + FfiConverterTypeSupportedHardwareWallet.read(buf) + } + } + + override fun allocationSize(value: List): ULong { + val sizeForLength = 4UL + val sizeForItems = value.sumOf { FfiConverterTypeSupportedHardwareWallet.allocationSize(it) } + return sizeForLength + sizeForItems + } + + override fun write(value: List, buf: ByteBuffer) { + buf.putInt(value.size) + value.iterator().forEach { + FfiConverterTypeSupportedHardwareWallet.write(it, buf) + } + } +} + + + + public object FfiConverterSequenceTypeTransactionDetails: FfiConverterRustBuffer> { override fun read(buf: ByteBuffer): List { val len = buf.getInt() @@ -12967,6 +13053,31 @@ public object FfiConverterSequenceTypeComposeResult: FfiConverterRustBuffer> { + override fun read(buf: ByteBuffer): List { + val len = buf.getInt() + return List(len) { + FfiConverterTypeTrezorTransportType.read(buf) + } + } + + override fun allocationSize(value: List): ULong { + val sizeForLength = 4UL + val sizeForItems = value.sumOf { FfiConverterTypeTrezorTransportType.allocationSize(it) } + return sizeForLength + sizeForItems + } + + override fun write(value: List, buf: ByteBuffer) { + buf.putInt(value.size) + value.iterator().forEach { + FfiConverterTypeTrezorTransportType.write(it, buf) + } + } +} + + + public object FfiConverterMapStringString: FfiConverterRustBuffer> { override fun read(buf: ByteBuffer): Map { val len = buf.getInt() @@ -13835,6 +13946,20 @@ public fun `getPreActivityMetadata`(`walletId`: kotlin.String, `searchKey`: kotl }) } +/** + * The catalog of hardware wallets Bitkit supports. + * + * Trezor's full lineup; only the Safe 7 currently offers Bluetooth, so it is the + * only model iOS surfaces (apps filter on `transports`). + */ +public fun `getSupportedHardwareWallets`(): List { + return FfiConverterSequenceTypeSupportedHardwareWallet.lift(uniffiRustCall { uniffiRustCallStatus -> + UniffiLib.uniffi_bitkitcore_fn_func_get_supported_hardware_wallets( + uniffiRustCallStatus, + ) + }) +} + @Throws(ActivityException::class) public fun `getTags`(`walletId`: kotlin.String, `activityId`: kotlin.String): List { return FfiConverterSequenceString.lift(uniffiRustCallWithError(ActivityExceptionErrorHandler) { uniffiRustCallStatus -> diff --git a/bindings/android/lib/src/main/kotlin/com/synonym/bitkitcore/bitkitcore.common.kt b/bindings/android/lib/src/main/kotlin/com/synonym/bitkitcore/bitkitcore.common.kt index cff9dc6..03db465 100644 --- a/bindings/android/lib/src/main/kotlin/com/synonym/bitkitcore/bitkitcore.common.kt +++ b/bindings/android/lib/src/main/kotlin/com/synonym/bitkitcore/bitkitcore.common.kt @@ -1506,6 +1506,39 @@ public data class SingleAddressInfoResult ( +/** + * A hardware-wallet model Bitkit supports, with the transports it can connect over. + * + * Owned by core so iOS and Android render the same catalog instead of each + * hardcoding it. Platforms filter by `transports`: Android supports every model, + * while iOS (Bluetooth-only) shows just the models whose `transports` include + * `Bluetooth`. `model` is a stable key apps can map to their own bundled image. + */ +@kotlinx.serialization.Serializable +public data class SupportedHardwareWallet ( + val `vendor`: HardwareWalletVendor, + /** + * Human-readable vendor name, e.g. "Trezor". + */ + val `vendorName`: kotlin.String, + /** + * Model identifier, e.g. "Safe 7". + */ + val `model`: kotlin.String, + /** + * Full display name, e.g. "Trezor Safe 7". + */ + val `displayName`: kotlin.String, + /** + * Transports this model can connect over. + */ + val `transports`: List +) { + public companion object +} + + + @kotlinx.serialization.Serializable public data class SweepResult ( /** @@ -3424,6 +3457,23 @@ public sealed class DecodingException: kotlin.Exception() { +/** + * A hardware-wallet vendor supported by Bitkit. Trezor only for now; this leaves + * room to add other vendors without changing the catalog's shape. + */ + +@kotlinx.serialization.Serializable +public enum class HardwareWalletVendor { + + TREZOR; + public companion object +} + + + + + + public sealed class LnurlException: kotlin.Exception() { @@ -4428,6 +4478,10 @@ public enum class WordCount { + + + + diff --git a/bindings/ios/BitkitCore.xcframework.zip b/bindings/ios/BitkitCore.xcframework.zip index 5a42200..288b6e8 100644 Binary files a/bindings/ios/BitkitCore.xcframework.zip and b/bindings/ios/BitkitCore.xcframework.zip differ diff --git a/bindings/ios/BitkitCore.xcframework/Info.plist b/bindings/ios/BitkitCore.xcframework/Info.plist index 478a88f..b7357e0 100644 --- a/bindings/ios/BitkitCore.xcframework/Info.plist +++ b/bindings/ios/BitkitCore.xcframework/Info.plist @@ -10,7 +10,7 @@ HeadersPath Headers LibraryIdentifier - ios-arm64 + ios-arm64-simulator LibraryPath libbitkitcore.a SupportedArchitectures @@ -19,6 +19,8 @@ SupportedPlatform ios + SupportedPlatformVariant + simulator BinaryPath @@ -26,7 +28,7 @@ HeadersPath Headers LibraryIdentifier - ios-arm64-simulator + ios-arm64 LibraryPath libbitkitcore.a SupportedArchitectures @@ -35,8 +37,6 @@ SupportedPlatform ios - SupportedPlatformVariant - simulator CFBundlePackageType diff --git a/bindings/ios/BitkitCore.xcframework/ios-arm64-simulator/Headers/bitkitcoreFFI.h b/bindings/ios/BitkitCore.xcframework/ios-arm64-simulator/Headers/bitkitcoreFFI.h index ca331c5..0821479 100644 --- a/bindings/ios/BitkitCore.xcframework/ios-arm64-simulator/Headers/bitkitcoreFFI.h +++ b/bindings/ios/BitkitCore.xcframework/ios-arm64-simulator/Headers/bitkitcoreFFI.h @@ -805,6 +805,12 @@ uint64_t uniffi_bitkitcore_fn_func_get_payment(RustBuffer payment_id #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PRE_ACTIVITY_METADATA #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PRE_ACTIVITY_METADATA RustBuffer uniffi_bitkitcore_fn_func_get_pre_activity_metadata(RustBuffer wallet_id, RustBuffer search_key, int8_t search_by_address, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_SUPPORTED_HARDWARE_WALLETS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_SUPPORTED_HARDWARE_WALLETS +RustBuffer uniffi_bitkitcore_fn_func_get_supported_hardware_wallets(RustCallStatus *_Nonnull out_status + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_TAGS @@ -1900,6 +1906,12 @@ uint16_t uniffi_bitkitcore_checksum_func_get_payment(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PRE_ACTIVITY_METADATA uint16_t uniffi_bitkitcore_checksum_func_get_pre_activity_metadata(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_SUPPORTED_HARDWARE_WALLETS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_SUPPORTED_HARDWARE_WALLETS +uint16_t uniffi_bitkitcore_checksum_func_get_supported_hardware_wallets(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_TAGS diff --git a/bindings/ios/BitkitCore.xcframework/ios-arm64-simulator/libbitkitcore.a b/bindings/ios/BitkitCore.xcframework/ios-arm64-simulator/libbitkitcore.a index a8551a6..205eaff 100644 Binary files a/bindings/ios/BitkitCore.xcframework/ios-arm64-simulator/libbitkitcore.a and b/bindings/ios/BitkitCore.xcframework/ios-arm64-simulator/libbitkitcore.a differ diff --git a/bindings/ios/BitkitCore.xcframework/ios-arm64/Headers/bitkitcoreFFI.h b/bindings/ios/BitkitCore.xcframework/ios-arm64/Headers/bitkitcoreFFI.h index ca331c5..0821479 100644 --- a/bindings/ios/BitkitCore.xcframework/ios-arm64/Headers/bitkitcoreFFI.h +++ b/bindings/ios/BitkitCore.xcframework/ios-arm64/Headers/bitkitcoreFFI.h @@ -805,6 +805,12 @@ uint64_t uniffi_bitkitcore_fn_func_get_payment(RustBuffer payment_id #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PRE_ACTIVITY_METADATA #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PRE_ACTIVITY_METADATA RustBuffer uniffi_bitkitcore_fn_func_get_pre_activity_metadata(RustBuffer wallet_id, RustBuffer search_key, int8_t search_by_address, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_SUPPORTED_HARDWARE_WALLETS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_SUPPORTED_HARDWARE_WALLETS +RustBuffer uniffi_bitkitcore_fn_func_get_supported_hardware_wallets(RustCallStatus *_Nonnull out_status + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_TAGS @@ -1900,6 +1906,12 @@ uint16_t uniffi_bitkitcore_checksum_func_get_payment(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PRE_ACTIVITY_METADATA uint16_t uniffi_bitkitcore_checksum_func_get_pre_activity_metadata(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_SUPPORTED_HARDWARE_WALLETS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_SUPPORTED_HARDWARE_WALLETS +uint16_t uniffi_bitkitcore_checksum_func_get_supported_hardware_wallets(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_TAGS diff --git a/bindings/ios/BitkitCore.xcframework/ios-arm64/libbitkitcore.a b/bindings/ios/BitkitCore.xcframework/ios-arm64/libbitkitcore.a index 17bb259..53a1d7a 100644 Binary files a/bindings/ios/BitkitCore.xcframework/ios-arm64/libbitkitcore.a and b/bindings/ios/BitkitCore.xcframework/ios-arm64/libbitkitcore.a differ diff --git a/bindings/ios/bitkitcore.swift b/bindings/ios/bitkitcore.swift index 968c161..78b190c 100644 --- a/bindings/ios/bitkitcore.swift +++ b/bindings/ios/bitkitcore.swift @@ -8966,6 +8966,134 @@ public func FfiConverterTypeSingleAddressInfoResult_lower(_ value: SingleAddress } +/** + * A hardware-wallet model Bitkit supports, with the transports it can connect over. + * + * Owned by core so iOS and Android render the same catalog instead of each + * hardcoding it. Platforms filter by `transports`: Android supports every model, + * while iOS (Bluetooth-only) shows just the models whose `transports` include + * `Bluetooth`. `model` is a stable key apps can map to their own bundled image. + */ +public struct SupportedHardwareWallet { + public var vendor: HardwareWalletVendor + /** + * Human-readable vendor name, e.g. "Trezor". + */ + public var vendorName: String + /** + * Model identifier, e.g. "Safe 7". + */ + public var model: String + /** + * Full display name, e.g. "Trezor Safe 7". + */ + public var displayName: String + /** + * Transports this model can connect over. + */ + public var transports: [TrezorTransportType] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(vendor: HardwareWalletVendor, + /** + * Human-readable vendor name, e.g. "Trezor". + */vendorName: String, + /** + * Model identifier, e.g. "Safe 7". + */model: String, + /** + * Full display name, e.g. "Trezor Safe 7". + */displayName: String, + /** + * Transports this model can connect over. + */transports: [TrezorTransportType]) { + self.vendor = vendor + self.vendorName = vendorName + self.model = model + self.displayName = displayName + self.transports = transports + } +} + +#if compiler(>=6) +extension SupportedHardwareWallet: Sendable {} +#endif + + +extension SupportedHardwareWallet: Equatable, Hashable { + public static func ==(lhs: SupportedHardwareWallet, rhs: SupportedHardwareWallet) -> Bool { + if lhs.vendor != rhs.vendor { + return false + } + if lhs.vendorName != rhs.vendorName { + return false + } + if lhs.model != rhs.model { + return false + } + if lhs.displayName != rhs.displayName { + return false + } + if lhs.transports != rhs.transports { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(vendor) + hasher.combine(vendorName) + hasher.combine(model) + hasher.combine(displayName) + hasher.combine(transports) + } +} + +extension SupportedHardwareWallet: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeSupportedHardwareWallet: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SupportedHardwareWallet { + return + try SupportedHardwareWallet( + vendor: FfiConverterTypeHardwareWalletVendor.read(from: &buf), + vendorName: FfiConverterString.read(from: &buf), + model: FfiConverterString.read(from: &buf), + displayName: FfiConverterString.read(from: &buf), + transports: FfiConverterSequenceTypeTrezorTransportType.read(from: &buf) + ) + } + + public static func write(_ value: SupportedHardwareWallet, into buf: inout [UInt8]) { + FfiConverterTypeHardwareWalletVendor.write(value.vendor, into: &buf) + FfiConverterString.write(value.vendorName, into: &buf) + FfiConverterString.write(value.model, into: &buf) + FfiConverterString.write(value.displayName, into: &buf) + FfiConverterSequenceTypeTrezorTransportType.write(value.transports, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeSupportedHardwareWallet_lift(_ buf: RustBuffer) throws -> SupportedHardwareWallet { + return try FfiConverterTypeSupportedHardwareWallet.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeSupportedHardwareWallet_lower(_ value: SupportedHardwareWallet) -> RustBuffer { + return FfiConverterTypeSupportedHardwareWallet.lower(value) +} + + public struct SweepResult { /** * The transaction ID of the sweep transaction @@ -15895,6 +16023,75 @@ extension DecodingError: Foundation.LocalizedError { +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +/** + * A hardware-wallet vendor supported by Bitkit. Trezor only for now; this leaves + * room to add other vendors without changing the catalog's shape. + */ + +public enum HardwareWalletVendor { + + case trezor +} + + +#if compiler(>=6) +extension HardwareWalletVendor: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeHardwareWalletVendor: FfiConverterRustBuffer { + typealias SwiftType = HardwareWalletVendor + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> HardwareWalletVendor { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .trezor + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: HardwareWalletVendor, into buf: inout [UInt8]) { + switch value { + + + case .trezor: + writeInt(&buf, Int32(1)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeHardwareWalletVendor_lift(_ buf: RustBuffer) throws -> HardwareWalletVendor { + return try FfiConverterTypeHardwareWalletVendor.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeHardwareWalletVendor_lower(_ value: HardwareWalletVendor) -> RustBuffer { + return FfiConverterTypeHardwareWalletVendor.lower(value) +} + + +extension HardwareWalletVendor: Equatable, Hashable {} + +extension HardwareWalletVendor: Codable {} + + + + + + public enum LnurlError: Swift.Error { @@ -19784,6 +19981,31 @@ fileprivate struct FfiConverterSequenceTypePubkyProfileLink: FfiConverterRustBuf } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeSupportedHardwareWallet: FfiConverterRustBuffer { + typealias SwiftType = [SupportedHardwareWallet] + + public static func write(_ value: [SupportedHardwareWallet], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeSupportedHardwareWallet.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [SupportedHardwareWallet] { + let len: Int32 = try readInt(&buf) + var seq = [SupportedHardwareWallet]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeSupportedHardwareWallet.read(from: &buf)) + } + return seq + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -20134,6 +20356,31 @@ fileprivate struct FfiConverterSequenceTypeComposeResult: FfiConverterRustBuffer } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeTrezorTransportType: FfiConverterRustBuffer { + typealias SwiftType = [TrezorTransportType] + + public static func write(_ value: [TrezorTransportType], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeTrezorTransportType.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [TrezorTransportType] { + let len: Int32 = try readInt(&buf) + var seq = [TrezorTransportType]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeTrezorTransportType.read(from: &buf)) + } + return seq + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -20829,6 +21076,18 @@ public func getPreActivityMetadata(walletId: String, searchKey: String, searchBy ) }) } +/** + * The catalog of hardware wallets Bitkit supports. + * + * Trezor's full lineup; only the Safe 7 currently offers Bluetooth, so it is the + * only model iOS surfaces (apps filter on `transports`). + */ +public func getSupportedHardwareWallets() -> [SupportedHardwareWallet] { + return try! FfiConverterSequenceTypeSupportedHardwareWallet.lift(try! rustCall() { + uniffi_bitkitcore_fn_func_get_supported_hardware_wallets($0 + ) +}) +} public func getTags(walletId: String, activityId: String)throws -> [String] { return try FfiConverterSequenceString.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { uniffi_bitkitcore_fn_func_get_tags( @@ -22161,6 +22420,9 @@ private let initializationResult: InitializationResult = { if (uniffi_bitkitcore_checksum_func_get_pre_activity_metadata() != 24738) { return InitializationResult.apiChecksumMismatch } + if (uniffi_bitkitcore_checksum_func_get_supported_hardware_wallets() != 36542) { + return InitializationResult.apiChecksumMismatch + } if (uniffi_bitkitcore_checksum_func_get_tags() != 8596) { return InitializationResult.apiChecksumMismatch } diff --git a/bindings/ios/bitkitcoreFFI.h b/bindings/ios/bitkitcoreFFI.h index ca331c5..0821479 100644 --- a/bindings/ios/bitkitcoreFFI.h +++ b/bindings/ios/bitkitcoreFFI.h @@ -805,6 +805,12 @@ uint64_t uniffi_bitkitcore_fn_func_get_payment(RustBuffer payment_id #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PRE_ACTIVITY_METADATA #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PRE_ACTIVITY_METADATA RustBuffer uniffi_bitkitcore_fn_func_get_pre_activity_metadata(RustBuffer wallet_id, RustBuffer search_key, int8_t search_by_address, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_SUPPORTED_HARDWARE_WALLETS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_SUPPORTED_HARDWARE_WALLETS +RustBuffer uniffi_bitkitcore_fn_func_get_supported_hardware_wallets(RustCallStatus *_Nonnull out_status + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_TAGS @@ -1900,6 +1906,12 @@ uint16_t uniffi_bitkitcore_checksum_func_get_payment(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PRE_ACTIVITY_METADATA uint16_t uniffi_bitkitcore_checksum_func_get_pre_activity_metadata(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_SUPPORTED_HARDWARE_WALLETS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_SUPPORTED_HARDWARE_WALLETS +uint16_t uniffi_bitkitcore_checksum_func_get_supported_hardware_wallets(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_TAGS diff --git a/bindings/python/bitkitcore/bitkitcore.py b/bindings/python/bitkitcore/bitkitcore.py index e4e55d8..e871328 100644 --- a/bindings/python/bitkitcore/bitkitcore.py +++ b/bindings/python/bitkitcore/bitkitcore.py @@ -579,6 +579,8 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_get_pre_activity_metadata() != 24738: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_func_get_supported_hardware_wallets() != 36542: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_get_tags() != 8596: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_get_transaction_details() != 4810: @@ -1416,6 +1418,10 @@ class _UniffiVTableCallbackInterfaceTrezorUiCallback(ctypes.Structure): ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_bitkitcore_fn_func_get_pre_activity_metadata.restype = _UniffiRustBuffer +_UniffiLib.uniffi_bitkitcore_fn_func_get_supported_hardware_wallets.argtypes = ( + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_bitkitcore_fn_func_get_supported_hardware_wallets.restype = _UniffiRustBuffer _UniffiLib.uniffi_bitkitcore_fn_func_get_tags.argtypes = ( _UniffiRustBuffer, _UniffiRustBuffer, @@ -2309,6 +2315,9 @@ class _UniffiVTableCallbackInterfaceTrezorUiCallback(ctypes.Structure): _UniffiLib.uniffi_bitkitcore_checksum_func_get_pre_activity_metadata.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_get_pre_activity_metadata.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_func_get_supported_hardware_wallets.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_func_get_supported_hardware_wallets.restype = ctypes.c_uint16 _UniffiLib.uniffi_bitkitcore_checksum_func_get_tags.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_get_tags.restype = ctypes.c_uint16 @@ -7372,6 +7381,88 @@ def write(value, buf): _UniffiConverterUInt32.write(value.block_height, buf) +class SupportedHardwareWallet: + """ + A hardware-wallet model Bitkit supports, with the transports it can connect over. + + Owned by core so iOS and Android render the same catalog instead of each + hardcoding it. Platforms filter by `transports`: Android supports every model, + while iOS (Bluetooth-only) shows just the models whose `transports` include + `Bluetooth`. `model` is a stable key apps can map to their own bundled image. + """ + + vendor: "HardwareWalletVendor" + vendor_name: "str" + """ + Human-readable vendor name, e.g. "Trezor". + """ + + model: "str" + """ + Model identifier, e.g. "Safe 7". + """ + + display_name: "str" + """ + Full display name, e.g. "Trezor Safe 7". + """ + + transports: "typing.List[TrezorTransportType]" + """ + Transports this model can connect over. + """ + + def __init__(self, *, vendor: "HardwareWalletVendor", vendor_name: "str", model: "str", display_name: "str", transports: "typing.List[TrezorTransportType]"): + self.vendor = vendor + self.vendor_name = vendor_name + self.model = model + self.display_name = display_name + self.transports = transports + + def __str__(self): + return "SupportedHardwareWallet(vendor={}, vendor_name={}, model={}, display_name={}, transports={})".format(self.vendor, self.vendor_name, self.model, self.display_name, self.transports) + + def __eq__(self, other): + if self.vendor != other.vendor: + return False + if self.vendor_name != other.vendor_name: + return False + if self.model != other.model: + return False + if self.display_name != other.display_name: + return False + if self.transports != other.transports: + return False + return True + +class _UniffiConverterTypeSupportedHardwareWallet(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return SupportedHardwareWallet( + vendor=_UniffiConverterTypeHardwareWalletVendor.read(buf), + vendor_name=_UniffiConverterString.read(buf), + model=_UniffiConverterString.read(buf), + display_name=_UniffiConverterString.read(buf), + transports=_UniffiConverterSequenceTypeTrezorTransportType.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterTypeHardwareWalletVendor.check_lower(value.vendor) + _UniffiConverterString.check_lower(value.vendor_name) + _UniffiConverterString.check_lower(value.model) + _UniffiConverterString.check_lower(value.display_name) + _UniffiConverterSequenceTypeTrezorTransportType.check_lower(value.transports) + + @staticmethod + def write(value, buf): + _UniffiConverterTypeHardwareWalletVendor.write(value.vendor, buf) + _UniffiConverterString.write(value.vendor_name, buf) + _UniffiConverterString.write(value.model, buf) + _UniffiConverterString.write(value.display_name, buf) + _UniffiConverterSequenceTypeTrezorTransportType.write(value.transports, buf) + + class SweepResult: txid: "str" """ @@ -12630,6 +12721,41 @@ def write(value, buf): _UniffiConverterString.write(value.error_message, buf) + + + +class HardwareWalletVendor(enum.Enum): + """ + A hardware-wallet vendor supported by Bitkit. Trezor only for now; this leaves + room to add other vendors without changing the catalog's shape. + """ + + TREZOR = 0 + + + +class _UniffiConverterTypeHardwareWalletVendor(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return HardwareWalletVendor.TREZOR + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value == HardwareWalletVendor.TREZOR: + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value == HardwareWalletVendor.TREZOR: + buf.write_i32(1) + + + + # LnurlError # We want to define each variant as a nested class that's also a subclass, # which is tricky in Python. To accomplish this we're going to create each @@ -16906,6 +17032,31 @@ def read(cls, buf): +class _UniffiConverterSequenceTypeSupportedHardwareWallet(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiConverterTypeSupportedHardwareWallet.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiConverterTypeSupportedHardwareWallet.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiConverterTypeSupportedHardwareWallet.read(buf) for i in range(count) + ] + + + class _UniffiConverterSequenceTypeTransactionDetails(_UniffiConverterRustBuffer): @classmethod def check_lower(cls, value): @@ -17256,6 +17407,31 @@ def read(cls, buf): +class _UniffiConverterSequenceTypeTrezorTransportType(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiConverterTypeTrezorTransportType.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiConverterTypeTrezorTransportType.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiConverterTypeTrezorTransportType.read(buf) for i in range(count) + ] + + + class _UniffiConverterMapStringString(_UniffiConverterRustBuffer): @classmethod def check_lower(cls, items): @@ -19429,6 +19605,17 @@ def get_pre_activity_metadata(wallet_id: "str",search_key: "str",search_by_addre _UniffiConverterBool.lower(search_by_address))) +def get_supported_hardware_wallets() -> "typing.List[SupportedHardwareWallet]": + """ + The catalog of hardware wallets Bitkit supports. + + Trezor's full lineup; only the Safe 7 currently offers Bluetooth, so it is the + only model iOS surfaces (apps filter on `transports`). + """ + + return _UniffiConverterSequenceTypeSupportedHardwareWallet.lift(_uniffi_rust_call(_UniffiLib.uniffi_bitkitcore_fn_func_get_supported_hardware_wallets,)) + + def get_tags(wallet_id: "str",activity_id: "str") -> "typing.List[str]": _UniffiConverterString.check_lower(wallet_id) @@ -20981,6 +21168,7 @@ def wipe_all_transaction_details() -> None: "ComposeResult", "DbError", "DecodingError", + "HardwareWalletVendor", "LnurlError", "ManualRefundStateEnum", "Network", @@ -21064,6 +21252,7 @@ def wipe_all_transaction_details() -> None: "PubkyProfile", "PubkyProfileLink", "SingleAddressInfoResult", + "SupportedHardwareWallet", "SweepResult", "SweepTransactionPreview", "SweepableBalances", @@ -21156,6 +21345,7 @@ def wipe_all_transaction_details() -> None: "get_orders", "get_payment", "get_pre_activity_metadata", + "get_supported_hardware_wallets", "get_tags", "get_transaction_details", "gift_order", diff --git a/bindings/python/bitkitcore/libbitkitcore.dylib b/bindings/python/bitkitcore/libbitkitcore.dylib index 60a2830..47e2ab3 100755 Binary files a/bindings/python/bitkitcore/libbitkitcore.dylib and b/bindings/python/bitkitcore/libbitkitcore.dylib differ diff --git a/bindings/python/setup.py b/bindings/python/setup.py index 3fb29ce..54b01c6 100644 --- a/bindings/python/setup.py +++ b/bindings/python/setup.py @@ -2,7 +2,7 @@ setup( name="bitkitcore", - version="0.3.4", + version="0.3.5", packages=find_packages(), package_data={ "bitkitcore": ["*.so", "*.dylib", "*.dll"], diff --git a/src/lib.rs b/src/lib.rs index 65a4e62..62e2232 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,10 +35,11 @@ use crate::modules::blocktank::{ use crate::modules::pubky::{PubkyAuthDetails, PubkyAuthKind, PubkyError, PubkyProfile}; use crate::modules::trezor::account_type_to_script_type; pub use crate::modules::trezor::{ - get_transport_callback, trezor_is_ble_available, trezor_set_transport_callback, - trezor_set_ui_callback, NativeDeviceInfo, PassphraseResponse, TrezorCallMessageResult, - TrezorTransportCallback, TrezorTransportErrorCode, TrezorTransportReadResult, - TrezorTransportWriteResult, TrezorUiCallback, WalletSelection, + get_supported_hardware_wallets, get_transport_callback, trezor_is_ble_available, + trezor_set_transport_callback, trezor_set_ui_callback, HardwareWalletVendor, NativeDeviceInfo, + PassphraseResponse, SupportedHardwareWallet, TrezorCallMessageResult, TrezorTransportCallback, + TrezorTransportErrorCode, TrezorTransportReadResult, TrezorTransportWriteResult, + TrezorUiCallback, WalletSelection, }; use crate::modules::trezor::{ TrezorAddressResponse, TrezorCoinType, TrezorDeviceInfo, TrezorError, TrezorFeatures, diff --git a/src/modules/trezor/tests.rs b/src/modules/trezor/tests.rs index 6ac4d7e..ad1e17d 100644 --- a/src/modules/trezor/tests.rs +++ b/src/modules/trezor/tests.rs @@ -937,4 +937,35 @@ mod tests { let _ = adapter.on_passphrase_request(true); assert_eq!(*mock.last_passphrase_on_device.lock().unwrap(), Some(true)); } + + // ======================================================================== + // Supported hardware-wallet catalog + // ======================================================================== + + #[test] + fn test_supported_hardware_wallets_catalog() { + use crate::modules::trezor::{get_supported_hardware_wallets, HardwareWalletVendor}; + + let wallets = get_supported_hardware_wallets(); + + // Full Trezor lineup, all Trezor-vendored, every entry well-formed. + assert_eq!(wallets.len(), 5); + for w in &wallets { + assert_eq!(w.vendor, HardwareWalletVendor::Trezor); + assert_eq!(w.vendor_name, "Trezor"); + assert_eq!(w.display_name, format!("Trezor {}", w.model)); + assert!( + w.transports.contains(&TrezorTransportType::Usb), + "every model supports USB" + ); + } + + // iOS shows only Bluetooth-capable models -> exactly the Safe 7. + let ble: Vec<&str> = wallets + .iter() + .filter(|w| w.transports.contains(&TrezorTransportType::Bluetooth)) + .map(|w| w.model.as_str()) + .collect(); + assert_eq!(ble, vec!["Safe 7"]); + } } diff --git a/src/modules/trezor/types.rs b/src/modules/trezor/types.rs index 99aa10c..f26ab89 100644 --- a/src/modules/trezor/types.rs +++ b/src/modules/trezor/types.rs @@ -18,6 +18,57 @@ impl From for TrezorTransportType { } } +/// A hardware-wallet vendor supported by Bitkit. Trezor only for now; this leaves +/// room to add other vendors without changing the catalog's shape. +#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)] +pub enum HardwareWalletVendor { + Trezor, +} + +/// A hardware-wallet model Bitkit supports, with the transports it can connect over. +/// +/// Owned by core so iOS and Android render the same catalog instead of each +/// hardcoding it. Platforms filter by `transports`: Android supports every model, +/// while iOS (Bluetooth-only) shows just the models whose `transports` include +/// `Bluetooth`. `model` is a stable key apps can map to their own bundled image. +#[derive(Debug, Clone, PartialEq, Eq, uniffi::Record)] +pub struct SupportedHardwareWallet { + pub vendor: HardwareWalletVendor, + /// Human-readable vendor name, e.g. "Trezor". + pub vendor_name: String, + /// Model identifier, e.g. "Safe 7". + pub model: String, + /// Full display name, e.g. "Trezor Safe 7". + pub display_name: String, + /// Transports this model can connect over. + pub transports: Vec, +} + +/// The catalog of hardware wallets Bitkit supports. +/// +/// Trezor's full lineup; only the Safe 7 currently offers Bluetooth, so it is the +/// only model iOS surfaces (apps filter on `transports`). +#[uniffi::export] +pub fn get_supported_hardware_wallets() -> Vec { + use TrezorTransportType::{Bluetooth, Usb}; + + let trezor = |model: &str, transports: Vec| SupportedHardwareWallet { + vendor: HardwareWalletVendor::Trezor, + vendor_name: "Trezor".to_string(), + model: model.to_string(), + display_name: format!("Trezor {}", model), + transports, + }; + + vec![ + trezor("Model One", vec![Usb]), + trezor("Model T", vec![Usb]), + trezor("Safe 3", vec![Usb]), + trezor("Safe 5", vec![Usb]), + trezor("Safe 7", vec![Usb, Bluetooth]), + ] +} + /// Device information exposed to FFI. #[derive(Debug, Clone, uniffi::Record)] pub struct TrezorDeviceInfo {