Bitcoin Dev Kit (BDK) is a library that allows you to seamlessly build bitcoin wallets. BDK takes care of of the low-level bitcoin logic so you can focus on crafting custom-tailored user experiences.
The goal of this post is to give a quick yet clear conceptual understanding of the steps to develop a native iOS bitcoin wallet along with the associated Swift code.
Steps to developing a Wallet
Typical operations a bitcoin wallet might do is send and receive transactions along with tracking the wallet balance, and we can accomplish all of these quite easily with BDK.
BDK is on the road to 1.0 of so right now we will be using version 0.30.0 of the Swift Package bdk-swift.
The five steps to start developing an iOS wallet with bdk-swift v0.30.0 are:
Create Wallet
Sync Wallet
Get Balance
Get Address
List Transactions
1. Create Wallet
let mnemonicWords12 =
"space echo position wrist orient erupt relief museum myself grain wisdom tumble"
let mnemonic = try Mnemonic.fromString(mnemonic: mnemonicWords12)
let secretKey = DescriptorSecretKey(
network: .testnet,
mnemonic: mnemonic,
password: nil
)
let descriptor = Descriptor.newBip86(
secretKey: secretKey,
keychain: .external,
network: .testnet
)
let changeDescriptor = Descriptor.newBip86(
secretKey: secretKey,
keychain: .internal,
network: .testnet
)
let wallet = try Wallet(
descriptor: descriptor,
changeDescriptor: changeDescriptor,
network: .testnet,
databaseConfig: .memory
)
This creates an instance of a descriptor based Taproot wallet (using a static set of mnemonic words) which exposes some APIs to perform all the typical operations for a bitcoin wallet; for now lets focus on:
syncing the wallet to track the current balance
checking our wallet balance
create an address to receive sats
listing transactions for the wallet
2. Sync Wallet
let esploraConfig = EsploraConfig(
baseUrl: "https://mempool.space/testnet/api",
proxy: nil,
concurrency: nil,
stopGap: UInt64(20),
timeout: nil
)
let blockchainConfig = BlockchainConfig.esplora(config: esploraConfig)
let blockchain = try Blockchain(config: blockchainConfig)
wallet.sync(blockchain: blockchain, progress: nil)
BDK doesn't automatically monitor the blockchain, instead there's a sync
command that has to be called. We can set this up by sourcing chain data from an Esplora server via mempool.space on testnet, creating our blockchain from the config, and using that blockchain to sync
our wallet with current state of the network.
3. Get Balance
wallet.getBalance()
After a sync we can get our updated balance for the wallet.
4. Get Address
wallet.getAddress(addressIndex: .new)
From the wallet
instance we can generate a new address which can have sats sent to it that will increase our wallet balance, keeping in mind that we will need to sync our wallet to see if those new sats have been received to this address.
5. List Transactions
wallet.listTransactions(includeRaw: false)
If we send sats to our address we can see that reflected in the balance and now we can also see that reflected in the transaction list for the wallet.
Next Steps
This is a high level but specific example of developing a bitcoin wallet for iOS using BDK; for further understanding check out the full BDK Swift Example Wallet repository on GitHub.
The next steps for this bitcoin wallet might be: