MempoolKit

一个 Swift 包,可以通过 Mempool 实例获取比特币数据。

要求

安装

DocC 文档

该包已使用 DocC 进行了完整文档化。打开 xCode 中的文档窗口以阅读文档。未来文档中还将包含教程,解释如何将该包与 SwiftUI 一起使用。

文档

创建实例

let mempool = Mempool()

此命令将实例连接到官方 mempool space 服务器。

连接到自己的实例

您也可以将其连接到您自己的 mempool 实例。

let mempool = Mempool(server: "https://yourmempoolinstance.local")

连接到测试网

您可以通过 mempool space 服务器连接到测试网。

let mempool = Mempool(network: .testnet)

警告

请注意,以下每个方法都是异步的,并且可能会抛出错误。

难度调整

let difficultyAdjustment = try await mempool.difficultyAdjustment()

返回有关难度调整的详细信息。

地址

地址

let address = try await mempool.address(address: "1wiz18xYmhRX6xStj2b9t1rwWX4GKUgpv")

返回有关地址的详细信息。

地址交易

let txs = try await mempool.addressTXS(address: "1wiz18xYmhRX6xStj2b9t1rwWX4GKUgpv")

获取指定地址/脚本哈希的交易历史,按最新时间排序。最多返回 50 个 mempool 交易以及前 25 个已确认的交易。您可以使用 addressTXSChain 请求更多已确认的交易。

地址交易链

let txs = try await mempool.addressTXSChain(address: "1wiz18xYmhRX6xStj2b9t1rwWX4GKUgpv", lastTXID: "277bbdc3557f163810feea810bf390ed90724ec75de779ab181b865292bb1dc1")

获取指定地址/脚本哈希的已确认交易历史,按最新时间排序。每页返回 25 个交易。可以通过指定先前调用看到的最后一个 txid 来请求更多交易。

地址交易 Mempool

获取指定地址/脚本哈希的未确认交易历史。最多返回 50 个交易(无分页)。

let txsMempool = try await mempool.addressTXSMempool(address: "1wiz18xYmhRX6xStj2b9t1rwWX4GKUgpv")

地址 UTXO

let utxos = try await mempool.addressUTXOs(address: "1wiz18xYmhRX6xStj2b9t1rwWX4GKUgpv")

获取与地址/脚本哈希关联的未花费交易输出列表。

区块

获取区块

let block = try await mempool.block(blockHash: "000000000000000015dc777b3ff2611091336355d3f0ee9766a2cf3be8e4b1ce")

返回有关区块的详细信息。

十六进制区块头

let blockHeader = try await mempool.blockHeader(blockHash: "000000000000000015dc777b3ff2611091336355d3f0ee9766a2cf3be8e4b1ce")

返回十六进制编码的区块头。

获取区块高度

let blockHash = try await mempool.blockHeight(blockHeight: 800000)

返回输入高度处区块的哈希值。

获取原始区块

let rawBlock = try await mempool.blockRaw(blockHash: "0000000000000000000065bda8f8a88f2e1e00d9a6887a43d640e52a4c7660f2")

返回 Swifts Data 类型中的原始区块表示。

区块状态

let blockStatus = try await mempool.blockStatus(blockHash: "0000000000000000000065bda8f8a88f2e1e00d9a6887a43d640e52a4c7660f2")

返回区块的确认状态。

区块顶端高度

let blockTipHeight = try await mempool.blockTipHeight()

返回最后一个区块的高度。

区块顶端哈希

let blockTipHash = try await mempool.blockTipHash()

返回最后一个区块的哈希值。

区块交易 ID

let blockTXID = try await mempool.blockTXID(blockHash: "0000000000000000000065bda8f8a88f2e1e00d9a6887a43d640e52a4c7660f2")

返回指定区块内索引处的交易。

区块交易 ID

let blockTXIDs = try await mempool.blockTXIDs(blockHash: "0000000000000000000065bda8f8a88f2e1e00d9a6887a43d640e52a4c7660f2", index: 1)

返回区块中所有 txid 的列表。

区块交易

let blockTXs = try await mempool.blockTXs(blockHash: "0000000000000000000065bda8f8a88f2e1e00d9a6887a43d640e52a4c7660f2")

返回区块中 25 个交易的列表。

获取区块

let blocks = try await mempool.blocks(blockHash: "0000000000000000000065bda8f8a88f2e1e00d9a6887a43d640e52a4c7660f2")

返回过去 15 个区块的详细信息,包括费用和挖矿详细信息。

挖矿

矿池

let miningPools = try await mempool.miningPools(time: .oneYear)

返回按指定时间内发现的区块排序的所有已知矿池的列表。

矿池

let miningPool = try await mempool.miningPool(miningPool: "AntPool")

返回有关矿池的详细信息。

矿池哈希率

let miningPoolHashrates = try await mempool.miningPoolHashrates(time: .oneYear)

返回指定时间内活跃的矿池的平均哈希率(以及总哈希率的份额),按哈希率降序排列。

矿池哈希率

let miningPoolHashrate = try await mempool.miningPoolHashrate(miningPool: "AntPool")

返回由名称指定的矿池的所有已知哈希率数据。哈希率值为每周平均值。

矿池区块

let miningPoolBlocks = try await mempool.miningPoolBlocks(miningPool: "AntPool", blockHeight: 730000)

返回指定矿池在指定 blockHeight 之前挖掘的过去 10 个区块。如果未指定 blockHeight,则返回矿池最近的 10 个区块。

挖矿哈希率

let miningHashrate = try await mempool.miningHashrate(time: .oneYear)

返回指定时间内网络范围内的哈希率和难度数据。

挖矿奖励统计

let miningRewardStats = try await mempool.miningRewardStats(blockCount: 100)

返回过去指定区块的区块奖励和确认的总交易数。

挖矿区块费用

let blockFees = try await mempool.blockFees(time: .oneYear)

返回指定时间内区块的平均总费用,按从旧到新的顺序排列。

挖矿区块奖励

let blockRewards = try await mempool.blockRewards(time: .oneYear)

返回指定时间内区块的平均区块奖励,按从旧到新的顺序排列。

挖矿区块费用率

let blockFeeRates = try await mempool.blockFeeRates(time: .oneYear)

返回指定时间内区块的平均费用率百分位数,按从旧到新的顺序排列。

挖矿区块大小和权重

let blockSizeAndWeights = try await mempool.blockSizeAndWeights(time: .oneYear)

返回指定时间内区块的平均大小(字节)和平均权重(权重单位),按从旧到新的顺序排列。

费用

Mempool 区块费用

let mempoolBlockFees = try await mempool.mempoolBlockFees()

将当前 mempool 作为预计的区块返回。

建议费用

let recommendedFees = try await mempool.recommendedFees()

返回当前为新交易建议的费用。

Mempool

Mempool

let mempoolStatistics = try await mempool.mempool()

返回当前 mempool 后台统计信息。

Mempool 交易 ID

let mempoolTXIDs = try await mempool.mempoolTXIDs()

以数组形式返回 mempool 中完整交易 ID 列表。交易 ID 的顺序是任意的,与 bitcoind 不匹配。

Mempool 最近

let mempoolRecent = try await mempool.mempoolRecent()

返回进入 mempool 的最后 10 个交易的列表。每个交易对象都包含简化的概述数据。

交易

子为父付费

let cpfp = try await mempool.childrenPayForParrent(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e")

返回交易的祖先和最佳后代费用。

请注意,此交易不是 cpfp 交易。

交易

let tx = try await mempool.transaction(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e")

返回有关交易的详细信息

交易十六进制

let txHex = try await mempool.transactionHex(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e")

返回序列化为十六进制的交易。

交易 Merkle 区块证明

let merkleBlockProof = try await mempool.transactionMerkleBlockProof(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e")

使用 bitcoind 的 merkleblock 格式返回交易的 merkle 包含证明。

交易 Merkle 证明

let merkleProof = try await mempool.transactionMerkleProof(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e")

返回使用 Electrum 的 blockchain.transaction.get_merkle 格式的交易的 merkle 包含证明。

交易花费输出

let outspend = try await mempool.transactionOutspend(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e", vout: 1)

返回交易输出的花费状态。

交易花费输出

let outspends = try await mempool.transactionOutspends(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e")

返回交易输出的花费状态。

交易原始数据

let rawTX = try await mempool.transactionRaw(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e")

返回交易的确认状态。

交易状态

let txStatus = try await mempool.transactionStatus(txid: "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e")

返回交易的确认状态。

发送交易

try await mempool.sendTransaction(hex: "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d013bffffffff0100f2052a010000004341046cc86ddcd0860b7cef16cbaad7fe31fda1bf073c25cb833fa9e409e7f51e296f39b653a9c8040a2f967319ff37cf14b0991b86173462a2d5907cb6c5648b5b76ac00000000")

将交易广播到比特币网络。交易采用十六进制格式。

闪电网络

交易网络统计

let lnStats = try await mempool.lightningStatistic(time: .oneYear)

返回网络范围内的统计信息,例如通道和节点的总数、总容量以及平均/中位数费用数据。

搜索闪电网络节点和闪电网络通道

let lnNode = try await mempool.lightningNodes(node: "ACINQ")

闪电网络节点别名、节点公钥、通道 ID 和短通道 ID。返回与全文(不区分大小写)匹配的闪电网络节点和通道。

搜索国家/地区的闪电网络节点

let lnNode = try await mempool.lightningNodesInCountry(country: .us)

返回在请求的国家/地区运行在明网上的闪电网络节点列表。

每个国家/地区的闪电网络节点统计信息

let lnStats = try await mempool.lightningNodesStatisticsPerCountry()

返回每个国家/地区的总容量和明网节点数。容量数据以聪为单位。

闪电网络 ISP

let lnIsp = try await mempool.lightningISP(isp: 16509)

返回由指定 ISP 托管的节点列表,其中 isp 是 ISP 的 ASN。

每个 ISP 的闪电网络节点统计信息

let lnIsp = try await mempool.lightningNodeStatisticPerISP()

返回每个 ISP 的总容量、节点数和通道数。容量数据以聪为单位。

闪电网络前 100 个节点

let top100Nodes = try await mempool.lightningTop100Nodes()

返回两个前 100 个节点列表:一个按流动性(总通道容量)排序,另一个按连接性(开放通道数)排序。

按流动性排序的闪电网络前 100 个节点

let top100Nodes = try await mempool.lightningTop100NodesByLiquidity()

返回按流动性(总通道容量)排序的前 100 个节点列表。

按连接性排序的闪电网络前 100 个节点

let top100Nodes = try await mempool.lightningTop100NodesByConnectivity()

返回按连接性(开放通道数)排序的前 100 个节点列表。

按年龄排序的闪电网络前 100 个节点

let top100Nodes = try await mempool.lightningTop100OldestNodes()

返回前 100 个最古老节点的列表。

闪电网络节点统计

let node = try await mempool.lightningNodeStatistic(pubKey: "03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f")

返回有关具有给定公钥的节点的详细信息。

闪电网络历史节点统计

let node = try await mempool.lightningHistoricalNodeStatistics(pubKey: "03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f")

返回具有给定公钥的节点的历史统计信息。

闪电网络通道

let channel = try await mempool.lightningChannel(channelID: "855515703977115663")

返回有关具有给定 channelID 的闪电网络通道的信息。

来自交易 ID 的闪电网络通道

let channel = try await mempool.lightningChannelTXID(txid: "f95aea73705256e0d31ca722bda3e350f411590cd2e5222fb3be23912834495a")

返回与给定交易 ID 对应的通道。

来自节点公钥的闪电网络通道

let channel = try await mempool.lightningChannelFromNodePubkey(pubkey: "855515703977115663", channelStatus: .open)

返回给定节点公钥的节点通道列表。

缺少的方法

区块批量

此 API 方法已被 mempool.space 禁用。

闪电网络通道地理数据

其返回的 JSON 不符合 swift 类型。

教程

有一个完整的 DocC 教程,介绍如何使用 MempoolKit 构建演示应用程序。要进行本教程,请将包添加到您的项目并打开文档窗口。单击 MempoolKit 并打开 Meet MempoolKit 文章或打开 MempoolKit App 教程。

MempoolKit 应用教程

现在我们编写代码。

首先将 MempoolKit 包导入到您的项目中。

import MempoolKit

创建 Mempool 的实例。

let mempool = Mempool()

删除基本代码,并将其替换为 NavigationStack 中的 Form。为 Form 指定 navigationTitle。

NavigationStack {
    Form {
                
    }
    .navigationTitle("MempoolKit Tutorial")
}

编写一个名为“blocks”的状态属性,并将其设置为一个空的区块数组。

@State private var blocks = Blocks()

在 Form 中编写一个 ForEach 循环遍历这些区块。在 ForEach 中编写一个 NavigationLink。

ForEach(blocks) { block in
    NavigationLink("\(block.height)", value: block)
}

现在我们编写 refresh 函数来加载最后 15 个区块。首先,我们使用 mempool.blockTipHeight() 找出当前的区块高度。 然后,我们使用 mempool.blocks(blockHeight: currentBlockHeight) 加载最后 15 个区块。 现在我们设置 blocks 等于 newBlocks 以在 UI 中加载区块。

func refresh() async {
    let currentBlockHeight = try! await mempool.blockTipHeight()
    let newBlocks = try! await mempool.blocks(blockHeight: currentBlockHeight)
    blocks = newBlocks
}

添加 task 和 refreshable modifiyer,以便在加载 View 时或用户想要刷新 View 时执行 refresh 函数。

.task {
    await refresh()
}
.refreshable {
    await refresh()
}

现在为 Block 的详细 View 编写一个 navigationDestination。 为 Block.self 编写它。 编写一个带有 LabeledContent 的 Form,用于 Hash、Difficulty、Nonce 和交易数量。

.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)")
}

我们已经完成并编写了一个带有 MempoolKit 包的应用程序。

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()
    }
}

运行该应用。

警告

另请注意,此软件包仍处于开发的早期阶段,因此仍然有很多错误。

也请报告错误以改进该软件包。