A Swift Package that enables to get Bitcoin data through a Mempool instance.
- iOS 13 or higher
- macOS 12 or higher
- Add it using XCode menu File --> Swift Package --> Add Package Dependency
- Add https://github.com/FlorianHubl/MempoolKit as Swift Package URL
- Click on the package
- Click Add Package and you are done
The Package is fully documented with DocC. Open the documentation window in xCode to read the documentation. There will also be Tutorials in the documentation in the future which explane how to use the package with SwiftUI.
let mempool = Mempool()
This command connects the instance to the official mempool space server.
You can also connect it to your own instance of mempool.
let mempool = Mempool(server: "https://yourmempoolinstance.local")
You can connect to the testnet via the mempool space server.
let mempool = Mempool(network: .testnet)
Please note that each method below is async and may throw errors.
let difficultyAdjustment = try await mempool.difficultyAdjustment()
Returns details about difficulty adjustment.
let address = try await mempool.address(address: "1wiz18xYmhRX6xStj2b9t1rwWX4GKUgpv")
Returns details about an address.
let txs = try await mempool.addressTXS(address: "1wiz18xYmhRX6xStj2b9t1rwWX4GKUgpv")
Get transaction history for the specified address/scripthash, sorted with newest first. Returns up to 50 mempool transactions plus the first 25 confirmed transactions. You can request more confirmed transactions using addressTXSChain.
let txs = try await mempool.addressTXSChain(address: "1wiz18xYmhRX6xStj2b9t1rwWX4GKUgpv", lastTXID: "277bbdc3557f163810feea810bf390ed90724ec75de779ab181b865292bb1dc1")
Get confirmed transaction history for the specified address/scripthash, sorted with newest first. Returns 25 transactions per page. More can be requested by specifying the last txid seen by the previous call.
Get unconfirmed transaction history for the specified address/scripthash. Returns up to 50 transactions (no paging).
let txsMempool = try await mempool.addressTXSMempool(address: "1wiz18xYmhRX6xStj2b9t1rwWX4GKUgpv")
let utxos = try await mempool.addressUTXOs(address: "1wiz18xYmhRX6xStj2b9t1rwWX4GKUgpv")
Get the list of unspent transaction outputs associated with the address/scripthash.
let block = try await mempool.block(blockHash: "000000000000000015dc777b3ff2611091336355d3f0ee9766a2cf3be8e4b1ce")
Returns details about a block.
let blockHeader = try await mempool.blockHeader(blockHash: "000000000000000015dc777b3ff2611091336355d3f0ee9766a2cf3be8e4b1ce")
Returns the hex-encoded block header.
let blockHash = try await mempool.blockHeight(blockHeight: 800000)
Returns the hash of the block at the input height.
let rawBlock = try await mempool.blockRaw(blockHash: "0000000000000000000065bda8f8a88f2e1e00d9a6887a43d640e52a4c7660f2")
Returns the raw block representation in Swifts Data Type.
let blockStatus = try await mempool.blockStatus(blockHash: "0000000000000000000065bda8f8a88f2e1e00d9a6887a43d640e52a4c7660f2")
Returns the confirmation status of a block.
let blockTipHeight = try await mempool.blockTipHeight()
Returns the height of the last block.
let blockTipHash = try await mempool.blockTipHash()
Returns the hash of the last block.
let blockTXID = try await mempool.blockTXID(blockHash: "0000000000000000000065bda8f8a88f2e1e00d9a6887a43d640e52a4c7660f2")
Returns the transaction at index within the specified block.
let blockTXIDs = try await mempool.blockTXIDs(blockHash: "0000000000000000000065bda8f8a88f2e1e00d9a6887a43d640e52a4c7660f2", index: 1)
Returns a list of all txids in the block.
let blockTXs = try await mempool.blockTXs(blockHash: "0000000000000000000065bda8f8a88f2e1e00d9a6887a43d640e52a4c7660f2")
Returns a list of 25 transactions in the block.
let blocks = try await mempool.blocks(blockHash: "0000000000000000000065bda8f8a88f2e1e00d9a6887a43d640e52a4c7660f2")
Returns details on the past 15 blocks with fee and mining details in extras.
let miningPools = try await mempool.miningPools(time: .oneYear)
Returns a list of all known mining pools ordered by blocks found over the specified time.
let miningPool = try await mempool.miningPool(miningPool: "AntPool")
Returns Details about the mining pool.
let miningPoolHashrates = try await mempool.miningPoolHashrates(time: .oneYear)
Returns the Average hashrates (and share of total hashrate) of mining pools active in the specified time, in descending order of hashrate.
let miningPoolHashrate = try await mempool.miningPoolHashrate(miningPool: "AntPool")
Returns all known hashrate data for the mining pool specified by the name. Hashrate values are weekly averages.
let miningPoolBlocks = try await mempool.miningPoolBlocks(miningPool: "AntPool", blockHeight: 730000)
Returns past 10 blocks mined by the specified mining pool before the specified blockHeight. If no blockHeight is specified, the mining pool's 10 most recent blocks are returned.
let miningHashrate = try await mempool.miningHashrate(time: .oneYear)
Returns Network-wide hashrate and difficulty figures over the specified time.
let miningRewardStats = try await mempool.miningRewardStats(blockCount: 100)
Returns Block reward and total transactions confirmed for the past specified blocks.
let blockFees = try await mempool.blockFees(time: .oneYear)
Returns Average total fees for blocks in the specified time, ordered oldest to newest.
let blockRewards = try await mempool.blockRewards(time: .oneYear)
Returns Average block rewards for blocks in the specified time, ordered oldest to newest.
let blockFeeRates = try await mempool.blockFeeRates(time: .oneYear)
Returns Average feerate percentiles for blocks in the specified time, ordered oldest to newest.
let blockSizeAndWeights = try await mempool.blockSizeAndWeights(time: .oneYear)
Returns average size (bytes) and average weight (weight units) for blocks in the specified time, ordered oldest to newest.
let mempoolBlockFees = try await mempool.mempoolBlockFees()
Returns the current mempool as projected blocks.
let recommendedFees = try await mempool.recommendedFees()
Returns the currently suggested fees for new transactions.
let mempoolStatistics = try await mempool.mempool()
Returns the current mempool backlog statistics.
let mempoolTXIDs = try await mempool.mempoolTXIDs()
Returns the full list of transaction IDs in the mempool as an array. The order of the transaction IDs is arbitrary and does not match bitcoind.
let mempoolRecent = try await mempool.mempoolRecent()
Returns a list of the last 10 transactions to enter the mempool. Each transaction object contains simplified overview data.
let cpfp = try await mempool.childrenPayForParrent(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e")
Returns the ancestors and the best descendant fees for a transaction.
Note that this transaction is not a cpfp transaction.
let tx = try await mempool.transaction(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e")
Returns details about a transaction
let txHex = try await mempool.transactionHex(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e")
Returns a transaction serialized as hex.
let merkleBlockProof = try await mempool.transactionMerkleBlockProof(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e")
Returns a merkle inclusion proof for the transaction using bitcoind's merkleblock format.
let merkleProof = try await mempool.transactionMerkleProof(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e")
Returns A merkle inclusion proof for the transaction using Electrum's blockchain.transaction.get_merkle format.
let outspend = try await mempool.transactionOutspend(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e", vout: 1)
Return the spending status of a transaction output.
let outspends = try await mempool.transactionOutspends(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e")
Return the spending status of a transaction output.
let rawTX = try await mempool.transactionRaw(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e")
Return the confirmation status of a transaction.
let txStatus = try await mempool.transactionStatus(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e")
Return the confirmation status of a transaction.
try await mempool.sendTransaction(hex: "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d013bffffffff0100f2052a010000004341046cc86ddcd0860b7cef16cbaad7fe31fda1bf073c25cb833fa9e409e7f51e296f39b653a9c8040a2f967319ff37cf14b0991b86173462a2d5907cb6c5648b5b76ac00000000")
Broadcast a transaction to the Bitcoin Network. The Transaction is in the hex format.
let lnStats = try await mempool.lightningStatistic(time: .oneYear)
Return the network-wide stats such as total number of channels and nodes, total capacity, and average/median fee figures.
let lnNode = try await mempool.lightningNodes(node: "ACINQ")
Lightning Node aliases, node pubkeys, channel IDs, and short channel IDs. Returns Lightning nodes and channels that match the full-text, case-insensitive.
let lnNode = try await mempool.lightningNodesInCountry(country: .us)
Returns a list of Lightning nodes running on clearnet in the requested country.
let lnStats = try await mempool.lightningNodesStatisticsPerCountry()
Returns aggregate capacity and number of clearnet nodes per country. Capacity figures are in satoshis.
let lnIsp = try await mempool.lightningISP(isp: 16509)
Returns a list of nodes hosted by a specified isp, where isp is an ISP's ASN.
let lnIsp = try await mempool.lightningNodeStatisticPerISP()
Returns aggregate capacity, number of nodes, and number of channels per ISP. Capacity figures are in satoshis.
let top100Nodes = try await mempool.lightningTop100Nodes()
Returns two lists of the top 100 nodes: one ordered by liquidity (aggregate channel capacity) and the other ordered by connectivity (number of open channels).
let top100Nodes = try await mempool.lightningTop100NodesByLiquidity()
Returns a list of the top 100 nodes by liquidity (aggregate channel capacity).
let top100Nodes = try await mempool.lightningTop100NodesByConnectivity()
Returns a list of the top 100 nodes by connectivity (number of open channels).
let top100Nodes = try await mempool.lightningTop100OldestNodes()
Returns a list of the top 100 oldest nodes.
let node = try await mempool.lightningNodeStatistic(pubKey: "03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f")
Returns Details about a node with the given public Key.
let node = try await mempool.lightningHistoricalNodeStatistics(pubKey: "03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f")
Returns Historical stats for a node with the given public Key.
let channel = try await mempool.lightningChannel(channelID: "855515703977115663")
Returns Info about a Lightning channel with the given channelID.
let channel = try await mempool.lightningChannelTXID(txid: "f95aea73705256e0d31ca722bda3e350f411590cd2e5222fb3be23912834495a")
Returns Channels that correspond to the given transaction ID.
let channel = try await mempool.lightningChannelFromNodePubkey(pubkey: "855515703977115663", channelStatus: .open)
Returns a list of a node's channels given its public Key.
Blocks Bulk:
This API Method is disabled by mempool.space.
Lightning Channel Geodata:
Its return JSON does not conform to a swift type.
There is a full DocC tutorial how to build a demo App with MempoolKit. To do this tutorial add the package to your project and open the documentation window. Click on MempoolKit and open the Meet MempoolKit Article or open the MempoolKit App Tutorial.
-
First create a new iOS App
-
Choose SwiftUI as the User Interface and give your project a name.
-
Click on “File –> Add Packages…”
-
Paste “https://github.com/FlorianHubl/MempoolKit” in the Search Field.
-
Click on “Add Package”
-
MempoolKit is imported in your project.
Now we write the Code.
First import the MempoolKit Package in your project.
import MempoolKit
Make a instance of Mempool.
let mempool = Mempool()
Remove the basic code and replace them with a Form within a NavigationStack. Give the Form a navigationTitle.
NavigationStack {
Form {
}
.navigationTitle("MempoolKit Tutorial")
}
Write a State propery with the name “blocks” and set is equal to a empty Array of blocks.
@State private var blocks = Blocks()
Write a ForEach Loop over the block within the Form. In the ForEach write a NavigationLink.
ForEach(blocks) { block in
NavigationLink("\(block.height)", value: block)
}
Now we write the refresh function which load the last 15 blocks. First we find out what the current block height is with mempool.blockTipHeight(). Than we load the last 15 blocks with mempool.blocks(blockHeight: currentBlockHeight). Now we set blocks equal to newBlocks to load the blocks in the UI.
func refresh() async {
let currentBlockHeight = try! await mempool.blockTipHeight()
let newBlocks = try! await mempool.blocks(blockHeight: currentBlockHeight)
blocks = newBlocks
}
Add the task and refreshable modifiyer to execute the refresh function when the View gets loaded or the user wants to refresh the View.
.task {
await refresh()
}
.refreshable {
await refresh()
}
Now write a navigationDestination for a detailed View of a Block. Write it for Block.self. Write a Form with LabeledContent for the Hash, the Difficulty, the Nonce and the amount of Transactions.
.navigationDestination(for: Block.self) { block in
Form {
LabeledContent("Hash", value: block.id)
LabeledContent("Difficulty", value: "\(block.difficulty)")
LabeledContent("Nonce", value: "\(block.nonce)")
LabeledContent("Transactions", value: "\(block.tx_count)")
}
.navigationTitle("Block \(block.height)")
}
We are done and wrote a App with the MempoolKit Package.
import SwiftUI
import MempoolKit
struct ContentView: View {
let mempool = Mempool()
@State private var blocks = Blocks()
var body: some View {
NavigationStack {
Form {
ForEach(blocks) { block in
NavigationLink("\(block.height)", value: block)
}
}
.navigationTitle("MempoolKit Tutorial")
.navigationDestination(for: Block.self) { block in
Form {
LabeledContent("Hash", value: block.id)
LabeledContent("Difficulty", value: "\(block.difficulty)")
LabeledContent("Nonce", value: "\(block.nonce)")
LabeledContent("Transactions", value: "\(block.tx_count)")
}
.navigationTitle("Block \(block.height)")
}
.task {
await refresh()
}
.refreshable {
await refresh()
}
}
}
func refresh() async {
let currentBlockHeight = try! await mempool.blockTipHeight()
let newBlocks = try! await mempool.blocks(blockHeight: currentBlockHeight)
blocks = newBlocks
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Run the App.
Please also note that this package is still in the early stages of development and is therefore still very buggy.
Also please report bugs to improve the package.