kingpin-apps/swift-cardano-explorers
Link transactions, addresses, stake accounts, pools, governance and native assets to Cardano block explorers — every explorer listed at explorer.cardano.org, on the networks each one covers.
Installation
dependencies: [
.package(url: "https://github.com/Kingpin-Apps/swift-cardano-explorers.git", from: "0.1.0"),
],
targets: [
.target(name: "MyApp", dependencies: [
.product(name: "SwiftCardanoExplorers", package: "swift-cardano-explorers"),
]),
]It depends only on swift-cardano-core (0.5.0 or later) and swift-nacl.
Explorers
| Explorer | Mainnet | Preprod | Preview | Pages | |---|:-:|:-:|:-:|---| | AdaStat | ✓ | | | everything but committee members | | Cardanoscan | ✓ | ✓ | ✓ | everything | | Cexplorer | ✓ | ✓ | ✓ | everything | | DRepTalk | ✓ | ✓ | | DReps, governance actions | | eUTxO | ✓ | | | transactions, blocks | | Pool PM | ✓ | | | addresses, accounts, pools, DReps, policies, assets | | PoolTool | ✓ | | | accounts, pools |
The URL each explorer gets for each kind of page is in the Explorer Coverage article. Every format was checked against the live sites with real mainnet items.
Usage
Linking
Give an ExplorerItem, as a swift-cardano-core value, and a network:
import SwiftCardanoCore
import SwiftCardanoExplorers
let pool = ExplorerItem.pool(try PoolOperator(from: "pool1…"))
BlockchainExplorer.cardanoScan.link(for: pool, on: .mainnet) // https://cardanoscan.io/pool/pool1…
BlockchainExplorer.poolTool.link(for: pool, on: .mainnet) // https://pooltool.io/pool/<hex>
BlockchainExplorer.poolTool.link(for: pool, on: .preview) // nil: PoolTool is mainnet onlylink(for:on:) returns nil where there is no page. url(for:on:) throws an ExplorerError that says why:
try BlockchainExplorer.cexplorer.url(for: .block(.number(14_003_180)), on: .mainnet)
// ExplorerError: Cexplorer links blocks by hash, not number.The items:
.transaction(TransactionId)
.address(Address)
.account(Address) // a stake address, or any address with a stake part
.block(.number(n)), .block(.bodyHash(hash))
.epoch(EpochNumber)
.pool(PoolOperator)
.drep(DRep) // written as CIP-129, drep1y…
.governanceAction(GovActionID)
.committeeMember(CommitteeColdCredential)
.policy(PolicyID)
.asset(policy: PolicyID, name: AssetName)A setting, with a fallback
struct ExplorerSetting: View {
@AppStorage("blockchainExplorer") private var explorer = BlockchainExplorer.cexplorer
var body: some View {
Picker("Explorer", selection: $explorer) {
ForEach(BlockchainExplorer.allCases) { Text($0.name).tag($0) }
}
}
}Not every explorer has every page on every network, so fall back to one that does, and say which:
func opening(_ item: ExplorerItem, on network: Network, preferring chosen: BlockchainExplorer)
-> (BlockchainExplorer, URL)?
{
for explorer in [chosen, .cardanoScan, .cexplorer] {
if let url = explorer.link(for: item, on: network) { return (explorer, url) }
}
return nil
}
BlockchainExplorer.supporting(.drep, on: .preprod) // [.cardanoScan, .cexplorer, .drepTalk]Reading a pasted link
if let link = ExplorerLink(URL(string: "https://preprod.cardanoscan.io/transaction/01e9…")!),
case .transaction(let id) = link.item {
fetch(id, on: link.network) // .preprod
}Assets linked by fingerprint, and accounts linked by credential hash, cannot be read back: neither says everything the item needs.
Asset fingerprints
try assetName.fingerprint(policy: policyID) // "asset1…", per CIP-14Your own explorer
Conform a type to BlockchainExplorable, give its name, sites and supported kinds, and write the view… methods it has; the rest throw unsupportedItem:
struct MyExplorer: BlockchainExplorable {
let network: Network
let name = "My Explorer"
let networkUrls = NetworkURLs(mainnet: URL(string: "https://myexplorer.io")!)
let supportedItems: Set<ExplorerItem.Kind> = [.transaction]
func viewTransaction(transactionId: TransactionId) throws -> URL {
try baseURL.appendingPathComponent("tx").appendingPathComponent(transactionId.payload.toHex)
}
}Documentation
The full documentation, with articles on getting started, choosing an explorer, coverage, reading links and adding explorers, is on the Swift Package Index. To build it locally, use Xcode's Product › Build Documentation.
Contributing
To add an explorer, add its type under Sources/SwiftCardanoExplorers/Explorers/, a case to BlockchainExplorer, and golden URLs to the tests: real mainnet items whose links you have opened and seen the right page. The tests check that every explorer links each kind it claims and no other, and that every link reads back through ExplorerLink.
swift testLicense
MIT. See LICENSE.
Package Metadata
Repository: kingpin-apps/swift-cardano-explorers
Default branch: main
README: README.md