diff --git a/bdk-swift/.gitignore b/bdk-swift/.gitignore new file mode 100644 index 0000000..cf97457 --- /dev/null +++ b/bdk-swift/.gitignore @@ -0,0 +1,12 @@ +.DS_Store +/.build +/.swiftpm +/Packages +/*.xcodeproj +xcuserdata/ +DerivedData/ +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +bdkFFI.xcframework.zip +bdkFFI +libbdkffi.a +bdkFFI.h diff --git a/bdk-swift/Package.swift b/bdk-swift/Package.swift new file mode 100644 index 0000000..99f7ea6 --- /dev/null +++ b/bdk-swift/Package.swift @@ -0,0 +1,37 @@ +// swift-tools-version:5.5 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "bdk-swift", + platforms: [ + .macOS(.v12), + .iOS(.v15) + ], + products: [ + // Products define the executables and libraries a package produces, and make them visible to other packages. + .library( + name: "BitcoinDevKit", + targets: ["bdkFFI", "BitcoinDevKit"]), + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + // .package(url: /* package url */, from: "1.0.0"), + ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages this package depends on. +// .binaryTarget( +// name: "bdkFFI", +// url: "https://github.com/bitcoindevkit/bdk-swift/releases/download/0.3.0/bdkFFI.xcframework.zip", +// checksum: "7d4a2fdeb03fb3eff107e45ee3148dd9b67966406c82d6e3c19f653c27180cfd"), + .binaryTarget(name: "bdkFFI", path: "./bdkFFI.xcframework"), + .target( + name: "BitcoinDevKit", + dependencies: ["bdkFFI"]), + .testTarget( + name: "BitcoinDevKitTests", + dependencies: ["BitcoinDevKit"]), + ] +) diff --git a/bdk-swift/Package.swift.txt b/bdk-swift/Package.swift.txt new file mode 100644 index 0000000..ec401f2 --- /dev/null +++ b/bdk-swift/Package.swift.txt @@ -0,0 +1,36 @@ +// swift-tools-version:5.5 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "bdk-swift", + platforms: [ + .macOS(.v12), + .iOS(.v15) + ], + products: [ + // Products define the executables and libraries a package produces, and make them visible to other packages. + .library( + name: "BitcoinDevKit", + targets: ["bdkFFI", "BitcoinDevKit"]), + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + // .package(url: /* package url */, from: "1.0.0"), + ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages this package depends on. + .binaryTarget( + name: "bdkFFI", + url: "BDKFFIURL", + checksum: "BDKFFICHECKSUM"), + .target( + name: "BitcoinDevKit", + dependencies: ["bdkFFI"]), + .testTarget( + name: "BitcoinDevKitTests", + dependencies: ["BitcoinDevKit"]), + ] +) diff --git a/bdk-swift/README.md b/bdk-swift/README.md new file mode 100644 index 0000000..e10c8b0 --- /dev/null +++ b/bdk-swift/README.md @@ -0,0 +1,45 @@ +# bdk-swift + +This project builds a Swift package that provides [Swift] language bindings for the +[`bdk`] library. The Swift language bindings are created by the [`bdk-ffi`] project which is included as a module of this repository. + +## How to Use + +To use the Swift language bindings for [`bdk`] in your [Xcode] iOS or MacOS project add +the github repository https://github.com/bitcoindevkit/bdk-swift and select one of the +release versions. You may then import and use the `BitcoinDevKit` library in your Swift +code. For example: + +```swift +import BitcoinDevKit + +... + +``` + +Note: the Swift Package Manager package for `bdk-swift` is located in it's own repository (https://github.com/bitcoindevkit/bdk-swift), and that is where releases are created for it. But the code that generates the bindings is located in the https://github.com/bitcoindevkit/bdk-ffi repo in the `bdk-swift/` directory. + +### How to test + +```shell +swift test +``` + +### Example Projects + +* TBD + +## How to Build and Publish + +If you are a maintainer of this project or want to build and publish this project to your +own Github repository use the following steps: + +If you are a maintainer of this project or want to build and publish this project to your +own Github repository use the following steps: + +1. If it doesn't already exist, create a new `release/0.MINOR` branch from the `master` branch. +2. Add a tag `v0.MINOR.0`. +3. Run the `publish-spm` workflow on Github from the `bdk-swift` repo for version `0.MINOR.0`. + +[Swift]: https://developer.apple.com/swift/ +[Xcode]: https://developer.apple.com/documentation/Xcode diff --git a/bdk-swift/Tests/BitcoinDevKitTests/BitcoinDevKitTests.swift b/bdk-swift/Tests/BitcoinDevKitTests/BitcoinDevKitTests.swift new file mode 100644 index 0000000..c25e25d --- /dev/null +++ b/bdk-swift/Tests/BitcoinDevKitTests/BitcoinDevKitTests.swift @@ -0,0 +1,12 @@ +import XCTest +@testable import BitcoinDevKit + +final class BitcoinDevKitTests: XCTestCase { + func testMemoryWalletNewAddress() throws { + let desc = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)" + let databaseConfig = DatabaseConfig.memory + let wallet = try Wallet.init(descriptor: desc, changeDescriptor: nil, network: Network.regtest, databaseConfig: databaseConfig) + let addressInfo = try wallet.getAddress(addressIndex: AddressIndex.new) + XCTAssertEqual(addressInfo.address, "bcrt1qzg4mckdh50nwdm9hkzq06528rsu73hjxytqkxs") + } +} diff --git a/bdk-swift/bdkFFI.xcframework/Info.plist b/bdk-swift/bdkFFI.xcframework/Info.plist new file mode 100644 index 0000000..cda8ded --- /dev/null +++ b/bdk-swift/bdkFFI.xcframework/Info.plist @@ -0,0 +1,53 @@ + + + + + AvailableLibraries + + + LibraryIdentifier + macos-arm64_x86_64 + LibraryPath + bdkFFI.framework + SupportedArchitectures + + arm64 + x86_64 + + SupportedPlatform + macos + + + LibraryIdentifier + ios-arm64_x86_64-simulator + LibraryPath + bdkFFI.framework + SupportedArchitectures + + arm64 + x86_64 + + SupportedPlatform + ios + SupportedPlatformVariant + simulator + + + LibraryIdentifier + ios-arm64 + LibraryPath + bdkFFI.framework + SupportedArchitectures + + arm64 + + SupportedPlatform + ios + + + CFBundlePackageType + XFWK + XCFrameworkFormatVersion + 1.0 + + diff --git a/bdk-swift/bdkFFI.xcframework/ios-arm64/bdkFFI.framework/Headers/bdkFFI-umbrella.h b/bdk-swift/bdkFFI.xcframework/ios-arm64/bdkFFI.framework/Headers/bdkFFI-umbrella.h new file mode 100644 index 0000000..c10f2d9 --- /dev/null +++ b/bdk-swift/bdkFFI.xcframework/ios-arm64/bdkFFI.framework/Headers/bdkFFI-umbrella.h @@ -0,0 +1,4 @@ +// This is the "umbrella header" for our combined Rust code library. +// It needs to import all of the individual headers. + +#import "bdkFFI.h" diff --git a/bdk-swift/bdkFFI.xcframework/ios-arm64/bdkFFI.framework/Modules/module.modulemap b/bdk-swift/bdkFFI.xcframework/ios-arm64/bdkFFI.framework/Modules/module.modulemap new file mode 100644 index 0000000..1b7f601 --- /dev/null +++ b/bdk-swift/bdkFFI.xcframework/ios-arm64/bdkFFI.framework/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module bdkFFI { + umbrella header "bdkFFI-umbrella.h" + + export * + module * { export * } +} diff --git a/bdk-swift/bdkFFI.xcframework/ios-arm64_x86_64-simulator/bdkFFI.framework/Headers/bdkFFI-umbrella.h b/bdk-swift/bdkFFI.xcframework/ios-arm64_x86_64-simulator/bdkFFI.framework/Headers/bdkFFI-umbrella.h new file mode 100644 index 0000000..c10f2d9 --- /dev/null +++ b/bdk-swift/bdkFFI.xcframework/ios-arm64_x86_64-simulator/bdkFFI.framework/Headers/bdkFFI-umbrella.h @@ -0,0 +1,4 @@ +// This is the "umbrella header" for our combined Rust code library. +// It needs to import all of the individual headers. + +#import "bdkFFI.h" diff --git a/bdk-swift/bdkFFI.xcframework/ios-arm64_x86_64-simulator/bdkFFI.framework/Modules/module.modulemap b/bdk-swift/bdkFFI.xcframework/ios-arm64_x86_64-simulator/bdkFFI.framework/Modules/module.modulemap new file mode 100644 index 0000000..1b7f601 --- /dev/null +++ b/bdk-swift/bdkFFI.xcframework/ios-arm64_x86_64-simulator/bdkFFI.framework/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module bdkFFI { + umbrella header "bdkFFI-umbrella.h" + + export * + module * { export * } +} diff --git a/bdk-swift/bdkFFI.xcframework/macos-arm64_x86_64/bdkFFI.framework/Headers/bdkFFI-umbrella.h b/bdk-swift/bdkFFI.xcframework/macos-arm64_x86_64/bdkFFI.framework/Headers/bdkFFI-umbrella.h new file mode 100644 index 0000000..c10f2d9 --- /dev/null +++ b/bdk-swift/bdkFFI.xcframework/macos-arm64_x86_64/bdkFFI.framework/Headers/bdkFFI-umbrella.h @@ -0,0 +1,4 @@ +// This is the "umbrella header" for our combined Rust code library. +// It needs to import all of the individual headers. + +#import "bdkFFI.h" diff --git a/bdk-swift/bdkFFI.xcframework/macos-arm64_x86_64/bdkFFI.framework/Modules/module.modulemap b/bdk-swift/bdkFFI.xcframework/macos-arm64_x86_64/bdkFFI.framework/Modules/module.modulemap new file mode 100644 index 0000000..1b7f601 --- /dev/null +++ b/bdk-swift/bdkFFI.xcframework/macos-arm64_x86_64/bdkFFI.framework/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module bdkFFI { + umbrella header "bdkFFI-umbrella.h" + + export * + module * { export * } +}