Bitcoin and Bitcoin Cash(ABC) SPV wallet toolkit implemented in Kotlin. This is a full implementation of SPV node including wallet creation/restore, syncronzation with network, send/receive transactions, and more.
- Full SPV implementation for fast mobile performance
- Send/Receive Legacy transactions (P2PKH, P2PK, P2SH)
- Send/Receive Segwit transactions (P2WPKH)
- Send/Receive Segwit transactions compatible with legacy wallets (P2WPKH-SH)
- Fee calculation depending on wether sender pays the fee or receiver
- Encoding/Decoding of base58, bech32, cashaddr addresses
- BIP32 hierarchical deterministic wallets implementation.
- BIP39 mnemonic code for generating deterministic keys.
- BIP44 multi-account hierarchy for deterministic wallets.
- BIP21 URI schemes, which include payment address, amount, label and other params
- Real-time fee rates
BitcoinKit
requires you to provide mnemonic phrase when it is initialized:
val words = listOf("skill", ..., "century")
val context: Context = App.instance
val walletId = 'MyWalletId'
val bitcoinKit = BitcoinKit(context, walletId, words, BitcoinKit.NetworkType.MainNet)
val bitCashKit = BitcoinCashKit(context, walletId, words, BitcoinCashKit.NetworkType.MainNet)
Both networks can be configured to work in MainNet
or TestNet
peerSize
: Can be configured for number of peers to be connected (default: 10)confirmationsThreshold
: Minimum number of confirmations required for an unspent output in incoming transaction to be spent (default: 6)
BitcoinKit
requires to be started with start
command, but does not need to be stopped. It will be in synced state as long as it is possible:
bitcoinKit.start()
BitcoinKit
uses internal database for storing data fetched from blockchain. The clear
command can be used to stop and clean all stored data:
bitcoinKit.clear()
BitcoinKit
holds all kinds of data obtained from and needed for working with blockchain network
Balance is provided in Satoshi
:
bitcoinKit.balance
// 2937096768
Get an address which you can receive coins to. Receive address is changed each time after you actually get a transaction in which you receive coins to that address
bitcoinKit.receiveAddress()
// mfu3iYeZuh18uuN4CrGYz34HSMynZBgZyg
You can get all your transactions as follows:
bitcoinKit.transactions
TransactionInfo(
transactionHash=baede6420b4b2869cba87d768a7b4e2eef2a9899149f24c5c3d3ff66b8ad1405,
from=[TransactionAddress(address=my1ysPMHdeQD6kwnimipbvFrr5NRHDvNgz, mine=false)],
to=[
TransactionAddress(address=moyrWfrks5EsHLb2hqUr8nUnC9q9DYXMtK, mine=true),
TransactionAddress(address=2NDk1BuuKnbVqDAMVgGr6xurnctfaQVxFoN, mine=false)
],
amount=32500000,
blockHeight=1316822,
timestamp=1527595501
),
TransactionInfo(
transactionHash=60ff9d204c17e0e71a1fd2d3f60b1bada5573857691d30d7518311057cc75720,
from=[
TransactionAddress(address=mtmnfGuW4e5RbC64r3vx2qFhS3pobf57Ty, mine=false)
],
to=[
TransactionAddress(address=mt59yxihUxy117RPQuEVQ7QSRuHJnRT4fG, mine=true),
TransactionAddress(address=2NAn7FBKvMFWteiHKSDDBudUP4vPwiBfVkr, mine=false)
],
amount=16250000,
blockHeight=1316823,
timestamp=1527595771
)
...
In order to create new transaction, call send(address: String, value: Int, senderPay: Boolean = true)
method on BitcoinKit
senderPay
: parameter defines who pays the fee
bitcoinKit.send("mrjQyzbX9SiJxRC2mQhT4LvxFEmt9KEeRY", 1000000)
This function first validates a given address and amount, creates new transaction, then sends it over the peers network. If there's any error with given address/amount or network, it raises an exception.
One can validate address and fee by using following methods:
bitcoinKit.validate(address = "mrjQyzbX9SiJxRC2mQhT4LvxFEmt9KEeRY")
bitcoinKit.fee(value = 1000000, address = "mrjQyzbX9SiJxRC2mQhT4LvxFEmt9KEeRY", senderPay: true)
senderPay
: parameter defines who pays the fee
You can use parsePaymentAddress
method to parse a BIP21 URI:
bitcoinKit.parsePaymentAddress("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=50&label=Luke-Jr&message=Donation%20for%20project%20xyz")
BitcoinPaymentData(
address=175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W,
version=null,
amount=50.0,
label=Luke-Jr,
message=Donation for project xyz,
parameters=null
)
BitcoinKit
provides with data like transactions, blocks, balance, kitState in real-time. BitcoinKit.Listener
interface must be implemented and set to BitcoinKit
instance to receive that data.
class MainViewModel : ViewModel(), BitcoinKit.Listener {
private var bitcoinKit: BitcoinKit
...
init {
bitcoinKit = BitcoinKit(words, BitcoinKit.NetworkType.TestNet)
bitcoinKit.listener = this
}
override fun onTransactionsUpdate(bitcoinKit: BitcoinKit, inserted: List<TransactionInfo>, updated: List<TransactionInfo>) {
// do something with transactions
}
override fun onTransactionsDelete(hashes: List<String>) {
// do something with transactions
}
override fun onBalanceUpdate(bitcoinKit: BitcoinKit, balance: Long) {
// do something with balance
}
override fun onLastBlockInfoUpdate(bitcoinKit: BitcoinKit, blockInfo: BlockInfo) {
// do something with blockInfo
}
override fun onKitStateUpdate(bitcoinKit: BitcoinKit, state: KitState) {
// These states can be used to implement progress bar, etc
when (state) {
is KitState.Synced -> {
}
is KitState.Syncing -> {
// val progress: Double = state.progress
}
is KitState.NotSynced -> {
}
}
}
}
Listener events are run in a dedicated background thread. It can be switched to main thread by setting the listenerExecutor
property to MainThreadExecutor()
bitcoinKit.listenerExecutor = MainThreadExecutor()
- JDK >= 1.8
- Android 6 (minSdkVersion 23) or greater
Add the JitPack to module build.gradle
repositories {
maven { url 'https://jitpack.io' }
}
Add the following dependency to your build.gradle file:
dependencies {
implementation 'com.github.horizontalsystems:bitcoin-kit-android:master-SNAPSHOT'
}
All features of the library are used in example project. It can be referred as a starting point for usage of the library.
- HDWalletKit - HD Wallet related features, mnemonic phrase
The BitcoinKit
is open source and available under the terms of the MIT License