diff --git a/Makefile.am b/Makefile.am index 41a5eb6d..f4a5b222 100644 --- a/Makefile.am +++ b/Makefile.am @@ -199,6 +199,15 @@ include_bitcoin_node_impl_chasersdir = ${includedir}/bitcoin/node/impl/chasers include_bitcoin_node_impl_chasers_HEADERS = \ include/bitcoin/node/impl/chasers/chaser_organize.ipp +include_bitcoin_node_interfacesdir = ${includedir}/bitcoin/node/interfaces +include_bitcoin_node_interfaces_HEADERS = \ + include/bitcoin/node/interfaces/bitcoind.hpp \ + include/bitcoin/node/interfaces/electrum.hpp \ + include/bitcoin/node/interfaces/explore.hpp \ + include/bitcoin/node/interfaces/interfaces.hpp \ + include/bitcoin/node/interfaces/stratum_v1.hpp \ + include/bitcoin/node/interfaces/stratum_v2.hpp + include_bitcoin_node_parsedir = ${includedir}/bitcoin/node/parse include_bitcoin_node_parse_HEADERS = \ include/bitcoin/node/parse/parse.hpp \ diff --git a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj index 12908233..0e1641b1 100644 --- a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj +++ b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj @@ -191,6 +191,12 @@ + + + + + + diff --git a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters index 225490d1..1624b90c 100644 --- a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters +++ b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters @@ -26,19 +26,22 @@ {5FFB5F52-0772-4404-0000-00000000000B} - {5FFB5F52-0772-4404-0000-00000000000F} + {5FFB5F52-0772-4404-0000-000000000001} - + {5FFB5F52-0772-4404-0000-00000000000C} - + {5FFB5F52-0772-4404-0000-00000000000D} - + {5FFB5F52-0772-4404-0000-00000000000E} + + {5FFB5F52-0772-4404-0000-00000000000F} + - {5FFB5F52-0772-4404-0000-000000000001} + {5FFB5F52-0772-4404-0000-000000000002} {5FFB5F52-0772-4404-0000-000000000000} @@ -266,6 +269,24 @@ include\bitcoin\node + + include\bitcoin\node\interfaces + + + include\bitcoin\node\interfaces + + + include\bitcoin\node\interfaces + + + include\bitcoin\node\interfaces + + + include\bitcoin\node\interfaces + + + include\bitcoin\node\interfaces + include\bitcoin\node\parse diff --git a/include/bitcoin/node.hpp b/include/bitcoin/node.hpp index aadba788..0c67094e 100644 --- a/include/bitcoin/node.hpp +++ b/include/bitcoin/node.hpp @@ -45,6 +45,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include #include #include diff --git a/include/bitcoin/node/channels/channel_tcp.hpp b/include/bitcoin/node/channels/channel_tcp.hpp index 9af3c568..c9d1f1e2 100644 --- a/include/bitcoin/node/channels/channel_tcp.hpp +++ b/include/bitcoin/node/channels/channel_tcp.hpp @@ -28,6 +28,7 @@ namespace libbitcoin { namespace node { /// Abstract base TCP channel state for the node. +/// This is a placeholder for electrum, bitcoind, and stratum v1/v2 channels. class BCN_API channel_tcp : public node::channel, public network::channel diff --git a/include/bitcoin/node/interfaces/bitcoind.hpp b/include/bitcoin/node/interfaces/bitcoind.hpp new file mode 100644 index 00000000..91001136 --- /dev/null +++ b/include/bitcoin/node/interfaces/bitcoind.hpp @@ -0,0 +1,262 @@ +/** + * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS) + * + * This file is part of libbitcoin. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#ifndef LIBBITCOIN_NODE_INTERFACES_BITCOIND_HPP +#define LIBBITCOIN_NODE_INTERFACES_BITCOIND_HPP + +#include + +namespace libbitcoin { +namespace node { +namespace interface { + +struct bitcoind_methods +{ + static constexpr std::tuple methods + { + /// Blockchain methods. + method<"getbestblockhash">{}, + method<"getblock", string_t, optional<0_u32>>{ "blockhash", "verbosity" }, + method<"getblockchaininfo">{}, + method<"getblockcount">{}, + method<"getblockfilter", string_t, optional<"basic"_t>>{ "blockhash", "filtertype" }, + method<"getblockhash", number_t>{ "height" }, + method<"getblockheader", string_t, optional>{ "blockhash", "verbose" }, + method<"getblockstats", string_t, optional>{ "hash_or_height", "stats" }, + method<"getchaintxstats", optional<-1_i32>, optional<""_t>>{ "nblocks", "blockhash" }, + method<"getchainwork">{}, + method<"gettxout", string_t, number_t, optional>{ "txid", "n", "include_mempool" }, + method<"gettxoutsetinfo">{}, + method<"pruneblockchain", number_t>{ "height" }, + method<"savemempool">{}, + method<"scantxoutset", string_t, optional>{ "action", "scanobjects" }, + method<"verifychain", optional<4_u32>, optional<288_u32>>{ "checklevel", "nblocks" }, + method<"verifytxoutset", string_t>{ "input_verify_flag" }, + + /// Control methods. + method<"getmemoryinfo", optional<"stats"_t>>{ "mode" }, + method<"getrpcinfo">{}, + method<"help", optional<""_t>>{ "command" }, + method<"logging", optional<"*"_t>>{ "include" }, + method<"stop">{}, + method<"uptime">{}, + + /// Mining methods. + method<"getblocktemplate", optional>{ "template_request" }, + method<"getmininginfo">{}, + method<"getnetworkhashps", optional<120_u32>, optional<-1_i32>>{ "nblocks", "height" }, + method<"prioritisetransaction", string_t, number_t, number_t>{ "txid", "dummy", "priority_delta" }, + method<"submitblock", string_t, optional<""_t>>{ "block", "parameters" }, + + /// Network methods. + method<"addnode", string_t, string_t>{ "node", "command" }, + method<"clearbanned">{}, + method<"disconnectnode", string_t, optional<-1_i32>>{ "address", "nodeid" }, + method<"getaddednodeinfo", optional, optional, optional<""_t>>{ "include_chain_info", "dns", "addnode" }, + method<"getconnectioncount">{}, + method<"getnetworkinfo">{}, + method<"getpeerinfo">{}, + method<"listbanned">{}, + method<"ping">{}, + method<"setban", string_t, string_t, optional<86400_u32>, optional, optional<""_t>>{ "addr", "command", "bantime", "absolute", "reason" }, + method<"setnetworkactive", boolean_t>{ "state" }, + + /// Rawtransactions methods. + method<"combinerawtransaction", array_t>{ "txs" }, + method<"createrawtransaction", array_t, object_t, optional<0_u32>, optional>{ "inputs", "outputs", "locktime", "replaceable" }, + method<"decoderawtransaction", string_t>{ "hexstring" }, + method<"fundrawtransaction", string_t, optional>{ "rawtx", "options" }, + method<"getrawtransaction", string_t, optional<0_u32>, optional<""_t>>{ "txid", "verbose", "blockhash" }, + method<"sendrawtransaction", string_t, optional<0_u32>>{ "hexstring", "maxfeerate" }, + method<"signrawtransactionwithkey", string_t, optional, optional, optional<"ALL|FORKID"_t>>{ "hexstring", "privkeys", "prevtxs", "sighashtype" }, + method<"testmempoolaccept", array_t, optional<0_u32>>{ "rawtxs", "maxfeerate" }, + method<"testrawtransaction", string_t>{ "rawtx" }, + + /// Util methods (node-related). + method<"createmultisig", number_t, array_t>{ "nrequired", "keys" }, + method<"decodepsbt", string_t>{ "psbt" }, + method<"decodescript", string_t>{ "hex" }, + method<"estimaterawfee", number_t, optional<"unset"_t>>{ "conf_target", "estimate_mode" }, + method<"getdescriptorinfo", string_t>{ "descriptor" }, + method<"validateaddress", string_t>{ "address" }, + + /// Wallet methods (unsupported). + method<"abandontransaction", string_t>{ "txid" }, + method<"addmultisigaddress", number_t, array_t, optional<""_t>, optional<"legacy"_t>>{ "nrequired", "keys", "label", "address_type" }, + method<"backupwallet", string_t>{ "destination" }, + method<"bumpfee", string_t, optional>{ "txid", "options" }, + method<"createwallet", string_t, optional, optional, optional, optional<""_t>, optional, optional, optional, optional<"set"_t>>{ "wallet_name", "disable_private_keys", "blank", "passphrase", "avoid_reuse", "descriptors", "load_on_startup", "external_signer", "change_type" }, + method<"dumpprivkey", string_t>{ "address" }, + method<"dumpwallet", string_t>{ "filename" }, + method<"encryptwallet", string_t>{ "passphrase" }, + method<"getaddressinfo", string_t>{ "address" }, + method<"getbalances">{}, + method<"getnewaddress", optional<""_t>, optional<"legacy"_t>>{ "label", "address_type" }, + method<"getreceivedbyaddress", string_t, optional<0>>{ "address", "minconf" }, + method<"getreceivedbylabel", string_t, optional<0>>{ "label", "minconf" }, + method<"gettransaction", string_t, optional, optional>{ "txid", "include_watchonly", "verbose" }, + method<"getunconfirmedbalance">{}, + method<"getwalletinfo">{}, + method<"importaddress", string_t, optional<""_t>, optional, optional>{ "address", "label", "rescan", "p2sh" }, + method<"importmulti", array_t, optional>{ "requests", "options" }, + method<"importprivkey", string_t, optional<""_t>, optional>{ "privkey", "label", "rescan" }, + method<"importprunedfunds", string_t, string_t>{ "rawtransaction", "txoutproof" }, + method<"importpubkey", string_t, optional<""_t>, optional>{ "pubkey", "label", "rescan" }, + method<"importwallet", string_t>{ "filename" }, + method<"keypoolrefill", optional<100>>{ "newsize" }, + method<"listaddressgroupings", optional<1>, optional>{ "minconf", "include_watchonly" }, + method<"listlabels", optional<"receive"_t>>{ "purpose" }, + method<"listlockunspent">{}, + method<"listreceivedbyaddress", optional<1>, optional, optional, optional<""_t>>{ "minconf", "include_empty", "include_watchonly", "address_filter" }, + method<"listreceivedbylabel", optional<1>, optional, optional>{ "minconf", "include_empty", "include_watchonly" }, + method<"listtransactions", optional<""_t>, optional<10>, optional<0>, optional>{ "label", "count", "skip", "include_watchonly" }, + method<"listunspent", optional<1>, optional, optional, optional>{ "minconf", "addresses", "include_unsafe", "query_options" }, + method<"loadwallet", string_t, optional>{ "filename", "load_on_startup" }, + method<"lockunspent", boolean_t, optional>{ "unlock", "transactions" }, + method<"removeprunedfunds", string_t>{ "txid" }, + method<"rescanblockchain", optional<0>>{ "start_height" }, + method<"send", object_t, optional>{ "outputs", "options" }, + method<"sendmany", string_t, object_t, optional<1>, optional<""_t>, optional<""_t>, optional, optional, optional<25>, optional<"unset"_t>, optional, optional<0>>{ "dummy", "outputs", "minconf", "comment", "comment_to", "subtractfeefrom", "replaceable", "conf_target", "estimate_mode", "avoid_reuse", "fee_rate" }, + method<"sendtoaddress", string_t, number_t, optional<""_t>, optional<""_t>, optional, optional<25>, optional<"unset"_t>, optional, optional<0>, optional>{ "address", "amount", "comment", "comment_to", "subtractfeefromamount", "conf_target", "estimate_mode", "avoid_reuse", "fee_rate", "verbose" }, + method<"setlabel", string_t, string_t>{ "address", "label" }, + method<"settxfee", number_t>{ "amount" }, + method<"signmessage", string_t, string_t>{ "address", "message" }, + method<"signmessagewithprivkey", string_t, string_t>{ "privkey", "message" }, + method<"syncwithvalidationinterfacequeue">{}, + method<"unloadwallet", optional<""_t>, optional>{ "wallet_name", "load_on_startup" }, + method<"walletcreatefundedpsbt", optional, optional, optional<0>, optional>{ "inputs", "outputs", "locktime", "options" }, + method<"walletlock">{}, + method<"walletpassphrase", string_t, number_t>{ "passphrase", "timeout" }, + method<"walletprocesspsbt", string_t, optional, optional, optional>{ "psbt", "sign", "bip32derivs", "complete" } + }; + + template + using subscriber = network::unsubscriber; + + template + using at = method_at; + + // Derive this from above in c++26 using reflection. + using getbestblockhash = at<0>; + using getblock = at<1>; + using getblockchaininfo = at<2>; + using getblockcount = at<3>; + using getblockfilter = at<4>; + using getblockhash = at<5>; + using getblockheader = at<6>; + using getblockstats = at<7>; + using getchaintxstats = at<8>; + using getchainwork = at<9>; + using gettxout = at<10>; + using gettxoutsetinfo = at<11>; + using pruneblockchain = at<12>; + using savemempool = at<13>; + using scantxoutset = at<14>; + using verifychain = at<15>; + using verifytxoutset = at<16>; + using getmemoryinfo = at<17>; + using getrpcinfo = at<18>; + using help = at<19>; + using logging = at<20>; + using stop = at<21>; + using uptime = at<22>; + using getblocktemplate = at<23>; + using getmininginfo = at<24>; + using getnetworkhashps = at<25>; + using prioritisetransaction = at<26>; + using submitblock = at<27>; + using addnode = at<28>; + using clearbanned = at<29>; + using disconnectnode = at<30>; + using getaddednodeinfo = at<31>; + using getconnectioncount = at<32>; + using getnetworkinfo = at<33>; + using getpeerinfo = at<34>; + using listbanned = at<35>; + using ping = at<36>; + using setban = at<37>; + using setnetworkactive = at<38>; + using combinerawtransaction = at<39>; + using createrawtransaction = at<40>; + using decoderawtransaction = at<41>; + using fundrawtransaction = at<42>; + using getrawtransaction = at<43>; + using sendrawtransaction = at<44>; + using signrawtransactionwithkey = at<45>; + using testmempoolaccept = at<46>; + using testrawtransaction = at<47>; + using createmultisig = at<48>; + using decodepsbt = at<49>; + using decodescript = at<50>; + using estimaterawfee = at<51>; + using getdescriptorinfo = at<52>; + using validateaddress = at<53>; + using abandontransaction = at<54>; + using addmultisigaddress = at<55>; + using backupwallet = at<56>; + using bumpfee = at<57>; + using createwallet = at<58>; + using dumpprivkey = at<59>; + using dumpwallet = at<60>; + using encryptwallet = at<61>; + using getaddressinfo = at<62>; + using getbalances = at<63>; + using getnewaddress = at<64>; + using getreceivedbyaddress = at<65>; + using getreceivedbylabel = at<66>; + using gettransaction = at<67>; + using getunconfirmedbalance = at<68>; + using getwalletinfo = at<69>; + using importaddress = at<70>; + using importmulti = at<71>; + using importprivkey = at<72>; + using importprunedfunds = at<73>; + using importpubkey = at<74>; + using importwallet = at<75>; + using keypoolrefill = at<76>; + using listaddressgroupings = at<77>; + using listlabels = at<78>; + using listlockunspent = at<79>; + using listreceivedbyaddress = at<80>; + using listreceivedbylabel = at<81>; + using listtransactions = at<82>; + using listunspent = at<83>; + using loadwallet = at<84>; + using lockunspent = at<85>; + using removeprunedfunds = at<86>; + using rescanblockchain = at<87>; + using send = at<88>; + using sendmany = at<89>; + using sendtoaddress = at<90>; + using setlabel = at<91>; + using settxfee = at<92>; + using signmessage = at<93>; + using signmessagewithprivkey = at<94>; + using syncwithvalidationinterfacequeue = at<95>; + using unloadwallet = at<96>; + using walletcreatefundedpsbt = at<97>; + using walletlock = at<98>; + using walletpassphrase = at<99>; + using walletprocesspsbt = at<100>; +}; + +} // namespace interface +} // namespace node +} // namespace libbitcoin + +#endif diff --git a/include/bitcoin/node/interfaces/electrum.hpp b/include/bitcoin/node/interfaces/electrum.hpp new file mode 100644 index 00000000..1ea7159d --- /dev/null +++ b/include/bitcoin/node/interfaces/electrum.hpp @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS) + * + * This file is part of libbitcoin. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#ifndef LIBBITCOIN_NODE_INTERFACES_ELECTRUM_HPP +#define LIBBITCOIN_NODE_INTERFACES_ELECTRUM_HPP + +#include + +namespace libbitcoin { +namespace node { +namespace interface { + +struct electrum_methods +{ + static constexpr std::tuple methods + { + /// Blockchain methods. + method<"blockchain.block.header", number_t, optional<0>>{ "height", "cp_height" }, + method<"blockchain.block.headers", number_t, number_t, optional<0>>{ "start_height", "count", "cp_height" }, + method<"blockchain.estimatefee", number_t>{ "number" }, + method<"blockchain.headers.subscribe">{}, + method<"blockchain.relayfee">{}, + method<"blockchain.scripthash.get_balance", string_t>{ "scripthash" }, + method<"blockchain.scripthash.get_history", string_t>{ "scripthash" }, + method<"blockchain.scripthash.get_mempool", string_t>{ "scripthash" }, + method<"blockchain.scripthash.listunspent", string_t>{ "scripthash" }, + method<"blockchain.scripthash.subscribe", string_t>{ "scripthash" }, + method<"blockchain.scripthash.unsubscribe", string_t>{ "scripthash" }, + method<"blockchain.transaction.broadcast", string_t>{ "raw_tx" }, + method<"blockchain.transaction.get", string_t, optional>{ "tx_hash", "verbose" }, + method<"blockchain.transaction.get_merkle", string_t, number_t>{ "tx_hash", "height" }, + method<"blockchain.transaction.id_from_pos", number_t, number_t, optional>{ "height", "tx_pos", "merkle" }, + + /// Server methods. + method<"server.add_peer", object_t>{ "features" }, + method<"server.banner">{}, + method<"server.donation_address">{}, + method<"server.features">{}, + method<"server.peers.subscribe">{}, + method<"server.ping">{}, + method<"server.version", optional<""_t>, optional<"1.4"_t>>{ "client_name", "protocol_version" } + }; + + template + using subscriber = network::unsubscriber; + + template + using at = method_at; + + // Derive this from above in c++26 using reflection. + using blockchain_block_header = at<0>; + using blockchain_block_headers = at<1>; + using blockchain_estimatefee = at<2>; + using blockchain_headers_subscribe = at<3>; + using blockchain_relayfee = at<4>; + using blockchain_scripthash_get_balance = at<5>; + using blockchain_scripthash_get_history = at<6>; + using blockchain_scripthash_get_mempool = at<7>; + using blockchain_scripthash_listunspent = at<8>; + using blockchain_scripthash_subscribe = at<9>; + using blockchain_scripthash_unsubscribe = at<10>; + using blockchain_transaction_broadcast = at<11>; + using blockchain_transaction_get = at<12>; + using blockchain_transaction_get_merkle = at<13>; + using blockchain_transaction_id_from_pos = at<14>; + using server_add_peer = at<15>; + using server_banner = at<16>; + using server_donation_address = at<17>; + using server_features = at<18>; + using server_peers_subscribe = at<19>; + using server_ping = at<20>; + using server_version = at<21>; + + ////using subscribers = unsubscriber>; +}; + +} // namespace interface +} // namespace node +} // namespace libbitcoin + +#endif diff --git a/include/bitcoin/node/interfaces/explore.hpp b/include/bitcoin/node/interfaces/explore.hpp new file mode 100644 index 00000000..1cf9d037 --- /dev/null +++ b/include/bitcoin/node/interfaces/explore.hpp @@ -0,0 +1,164 @@ +/** + * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS) + * + * This file is part of libbitcoin. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#ifndef LIBBITCOIN_NODE_INTERFACES_EXPLORE_HPP +#define LIBBITCOIN_NODE_INTERFACES_EXPLORE_HPP + +#include + +namespace libbitcoin { +namespace node { +namespace interface { + +struct explore_methods +{ + static constexpr std::tuple methods + { + method<"top", uint8_t, uint8_t>{ "version", "media" }, + method<"block", uint8_t, uint8_t, nullable, nullable, optional>{ "version", "media", "hash", "height", "witness" }, + method<"block_header", uint8_t, uint8_t, nullable, nullable>{ "version", "media", "hash", "height" }, + method<"block_txs", uint8_t, uint8_t, nullable, nullable>{ "version", "media", "hash", "height" }, + method<"block_fees", uint8_t, uint8_t, nullable, nullable>{ "version", "media", "hash", "height" }, + method<"block_filter", uint8_t, uint8_t, uint8_t, nullable, nullable>{ "version", "media", "type", "hash", "height" }, + method<"block_filter_hash", uint8_t, uint8_t, uint8_t, nullable, nullable>{ "version", "media", "type", "hash", "height" }, + method<"block_filter_header", uint8_t, uint8_t, uint8_t, nullable, nullable>{ "version", "media", "type", "hash", "height" }, + method<"block_tx", uint8_t, uint8_t, uint32_t, nullable, nullable, optional>{ "version", "media", "position", "hash", "height", "witness" }, + + method<"tx", uint8_t, uint8_t, system::hash_cptr, optional>{ "version", "media", "hash", "witness" }, + method<"tx_header", uint8_t, uint8_t, system::hash_cptr>{ "version", "media", "hash" }, + method<"tx_fee", uint8_t, uint8_t, system::hash_cptr>{ "version", "media", "hash" }, + + method<"inputs", uint8_t, uint8_t, system::hash_cptr, optional>{ "version", "media", "hash", "witness" }, + method<"input", uint8_t, uint8_t, system::hash_cptr, uint32_t, optional>{ "version", "media", "hash", "index", "witness" }, + method<"input_script", uint8_t, uint8_t, system::hash_cptr, uint32_t>{ "version", "media", "hash", "index" }, + method<"input_witness", uint8_t, uint8_t, system::hash_cptr, uint32_t>{ "version", "media", "hash", "index" }, + + method<"outputs", uint8_t, uint8_t, system::hash_cptr>{ "version", "media", "hash" }, + method<"output", uint8_t, uint8_t, system::hash_cptr, uint32_t>{ "version", "media", "hash", "index" }, + method<"output_script", uint8_t, uint8_t, system::hash_cptr, uint32_t>{ "version", "media", "hash", "index" }, + method<"output_spender", uint8_t, uint8_t, system::hash_cptr, uint32_t>{ "version", "media", "hash", "index" }, + method<"output_spenders", uint8_t, uint8_t, system::hash_cptr, uint32_t>{ "version", "media", "hash", "index" }, + + method<"address", uint8_t, uint8_t, system::hash_cptr, optional>{ "version", "media", "hash", "turbo" }, + method<"address_confirmed", uint8_t, uint8_t, system::hash_cptr, optional>{ "version", "media", "hash", "turbo" }, + method<"address_unconfirmed", uint8_t, uint8_t, system::hash_cptr, optional>{ "version", "media", "hash", "turbo" }, + method<"address_balance", uint8_t, uint8_t, system::hash_cptr, optional>{ "version", "media", "hash", "turbo" } + }; + + template + using subscriber = network::unsubscriber; + + template + using at = method_at; + + // Derive this from above in c++26 using reflection. + + using top = at<0>; + + using block = at<1>; + using block_header = at<2>; + using block_txs = at<3>; + using block_fees = at<4>; + using block_filter = at<5>; + using block_filter_hash = at<6>; + using block_filter_header = at<7>; + using block_tx = at<8>; + + using tx = at<9>; + using tx_header = at<10>; + using tx_fee = at<11>; + + using inputs = at<12>; + using input = at<13>; + using input_script = at<14>; + using input_witness = at<15>; + + using outputs = at<16>; + using output = at<17>; + using output_script = at<18>; + using output_spender = at<19>; + using output_spenders = at<20>; + + using address = at<21>; + using address_confirmed = at<22>; + using address_unconfirmed = at<23>; + using address_balance = at<24>; +}; + +/// ?format=data|text|json (via query string). +/// ----------------------------------------------------------------------- + +/// /v1/block/top {1} + +/// /v1/block/hash/[bkhash] {1} +/// /v1/block/height/[height] {1} + +/// /v1/block/hash/[bkhash]/header {1} +/// /v1/block/height/[height]/header {1} + +/// /v1/block/hash/[bkhash]/fees {1} +/// /v1/block/height/[height]/fees {1} + +/// /v1/block/hash/[bkhash]/filter/[type] {1} +/// /v1/block/height/[height]/filter/[type] {1} + +/// /v1/block/hash/[bkhash]/filter/[type]/hash {1} +/// /v1/block/height/[height]/filter/[type]/hash {1} + +/// /v1/block/hash/[bkhash]/filter/[type]/header {1} +/// /v1/block/height/[height]/filter/[type]/header {1} + +/// /v1/block/hash/[bkhash]/txs {all txs in the block} +/// /v1/block/height/[height]/txs {all txs in the block} + +/// /v1/block/hash/[bkhash]/tx/[position] {1} +/// /v1/block/height/[height]/tx/[position] {1} + +/// ----------------------------------------------------------------------- + +/// /v1/tx/[txhash] {1} +/// /v1/tx/[txhash]/header {1 - if confirmed} +/// /v1/tx/[txhash]/fee {1} + +/// ----------------------------------------------------------------------- + +/// /v1/input/[txhash] {all inputs in the tx} +/// /v1/input/[txhash]/[index] {1} +/// /v1/input/[txhash]/[index]/script {1} +/// /v1/input/[txhash]/[index]/witness {1} + +/// ----------------------------------------------------------------------- + +/// /v1/output/[txhash] {all outputs in the tx} +/// /v1/output/[txhash]/[index] {1} +/// /v1/output/[txhash]/[index]/script {1} +/// /v1/output/[txhash]/[index]/spender {1 - if confirmed} +/// /v1/output/[txhash]/[index]/spenders {all} + +/// ----------------------------------------------------------------------- + +/// /v1/address/[output-script-hash] {all} +/// /v1/address/[output-script-hash]/unconfirmed {all unconfirmed} +/// /v1/address/[output-script-hash]/confirmed {all unconfirmed} +/// /v1/address/[output-script-hash]/balance {all confirmed} + +} // namespace interface +} // namespace node +} // namespace libbitcoin + +#endif diff --git a/include/bitcoin/node/interfaces/interfaces.hpp b/include/bitcoin/node/interfaces/interfaces.hpp new file mode 100644 index 00000000..5ac6d2a1 --- /dev/null +++ b/include/bitcoin/node/interfaces/interfaces.hpp @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS) + * + * This file is part of libbitcoin. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#ifndef LIBBITCOIN_NODE_INTERFACES_HPP +#define LIBBITCOIN_NODE_INTERFACES_HPP + +namespace libbitcoin { +namespace node { +namespace interface { + +/// Alias network::rpc names within interface::. + +template +using method = network::rpc::method; +template +using method_at = network::rpc::method_at; +template +using publish = network::rpc::publish; + +template +using optional = network::rpc::optional; +template +using nullable = network::rpc::nullable; +using boolean_t = network::rpc::boolean_t; +using string_t = network::rpc::string_t; +using number_t = network::rpc::number_t; +using object_t = network::rpc::object_t; +using array_t = network::rpc::array_t; + +namespace empty { constexpr auto array = network::rpc::empty::array; }; +namespace empty { constexpr auto object = network::rpc::empty::object; }; + +} // namespace interface +} // namespace node +} // namespace libbitcoin + +#include +#include +#include +#include +#include + +namespace libbitcoin { +namespace node { +namespace interface { + +using bitcoind = publish; +using electrum = publish; +using explore = publish; +using stratum_v1 = publish; +using stratum_v2 = publish; + +} // namespace interface +} // namespace node +} // namespace libbitcoin + +#endif diff --git a/include/bitcoin/node/interfaces/stratum_v1.hpp b/include/bitcoin/node/interfaces/stratum_v1.hpp new file mode 100644 index 00000000..89f0a5e7 --- /dev/null +++ b/include/bitcoin/node/interfaces/stratum_v1.hpp @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS) + * + * This file is part of libbitcoin. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#ifndef LIBBITCOIN_NODE_INTERFACES_STRATUM_V1_HPP +#define LIBBITCOIN_NODE_INTERFACES_STRATUM_V1_HPP + +#include + +namespace libbitcoin { +namespace node { +namespace interface { + +struct stratum_v1_methods +{ + static constexpr std::tuple methods + { + /// Client requests. + method<"mining.subscribe", optional<""_t>, optional<0>>{ "user_agent", "extranonce1_size" }, + method<"mining.authorize", string_t, string_t>{ "username", "password" }, + method<"mining.submit", string_t, string_t, string_t, number_t, string_t>{ "worker_name", "job_id", "extranonce2", "ntime", "nonce" }, + method<"mining.extranonce.subscribe">{}, + method<"mining.extranonce.unsubscribe", number_t>{ "id" }, + + /// Server notifications. + method<"mining.configure", object_t>{ "extensions" }, + method<"mining.set_difficulty", optional<1.0>>{ "difficulty" }, + method<"mining.notify", string_t, string_t, string_t, string_t, array_t, number_t, number_t, number_t, boolean_t, boolean_t, boolean_t>{ "job_id", "prevhash", "coinb1", "coinb2", "merkle_branch", "version", "nbits", "ntime", "clean_jobs", "hash1", "hash2" }, + method<"client.reconnect", string_t, number_t, number_t>{ "url", "port", "id" }, + method<"client.hello", object_t>{ "protocol" }, + method<"client.rejected", string_t, string_t>{ "job_id", "reject_reason" } + }; + + template + using subscriber = network::unsubscriber; + + template + using at = method_at; + + // Derive this from above in c++26 using reflection. + using mining_subscribe = at<0>; + using mining_authorize = at<1>; + using mining_submit = at<2>; + using mining_extranonce_subscribe = at<3>; + using mining_extranonce_unsubscribe = at<4>; + using mining_configure = at<5>; + using mining_set_difficulty = at<6>; + using mining_notify = at<7>; + using client_reconnect = at<8>; + using client_hello = at<9>; + using client_rejected = at<10>; +}; + +} // namespace interface +} // namespace node +} // namespace libbitcoin + +#endif diff --git a/include/bitcoin/node/interfaces/stratum_v2.hpp b/include/bitcoin/node/interfaces/stratum_v2.hpp new file mode 100644 index 00000000..9b0e2498 --- /dev/null +++ b/include/bitcoin/node/interfaces/stratum_v2.hpp @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS) + * + * This file is part of libbitcoin. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#ifndef LIBBITCOIN_NODE_INTERFACES_STRATUM_V2_HPP +#define LIBBITCOIN_NODE_INTERFACES_STRATUM_V2_HPP + +#include + +namespace libbitcoin { +namespace node { +namespace interface { + +struct stratum_v2_methods +{ + static constexpr std::tuple methods + { + /// Common setup messages. + method<"setup_connection", number_t, number_t, number_t, number_t, string_t, string_t, string_t>{ "min_version", "max_version", "flags", "endpoint_port", "endpoint_host", "vendor", "user_agent" }, + method<"setup_connection_success", number_t, number_t>{ "used_version", "flags" }, + method<"setup_connection_error", string_t>{ "code" }, + + /// Standard mining channel (header-only, primary for devices/firmware). + method<"open_standard_mining_channel", string_t, number_t, string_t, number_t>{ "user_identity", "nominal_hash_rate", "max_target", "min_extranonce_size" }, + method<"open_standard_mining_channel_success", number_t, string_t, string_t, number_t>{ "channel_id", "target", "extranonce_prefix", "extranonce_size" }, + method<"open_standard_mining_channel_error", string_t>{ "code" }, + + /// Extended mining channel. + method<"open_extended_mining_channel", string_t, number_t, string_t, number_t>{ "user_identity", "nominal_hash_rate", "max_target", "min_extranonce_size" }, + method<"open_extended_mining_channel_success", number_t, string_t, string_t, number_t, number_t, number_t>{ "channel_id", "target", "extranonce_prefix", "extranonce_size", "max_coinbase_size", "coinbase_output_max_additional_size" }, + method<"open_extended_mining_channel_error", string_t>{ "code" }, + + /// Channel management. + method<"update_channel", number_t, number_t, optional<""_t>>{ "channel_id", "nominal_hash_rate", "max_target" }, + method<"update_channel_error", number_t, string_t>{ "channel_id", "code" }, + method<"close_channel", number_t, optional<""_t>>{ "channel_id", "reason" }, + method<"set_target", number_t, string_t>{ "channel_id", "maximum_target" }, + + /// Header-only job declaration. + method<"new_mining_job", number_t, boolean_t, number_t, string_t, string_t, number_t>{ "job_id", "future_job", "version", "prev_hash", "merkle_root", "ntime_offset" }, + method<"set_new_prev_hash", number_t, number_t, string_t, number_t, number_t>{ "channel_id", "job_id", "prev_hash", "min_ntime", "nbits" }, + + /// Extended / custom jobs. + method<"new_extended_mining_job", number_t, boolean_t, number_t, string_t, string_t, array_t>{ "job_id", "future_job", "version", "coinbase_prefix", "coinbase_suffix", "merkle_path" }, + method<"set_custom_mining_job", number_t, boolean_t, number_t, string_t, number_t, number_t, array_t, array_t>{ "channel_id", "future_job", "job_id", "prev_hash", "version", "ntime", "merkle_branch", "transactions" }, + method<"set_custom_mining_job_success", number_t>{ "job_id" }, + method<"set_custom_mining_job_error", number_t, string_t>{ "job_id", "code" }, + + /// Share submission. + method<"submit_shares", number_t, number_t, number_t, number_t, number_t, number_t>{ "channel_id", "sequence_number", "job_id", "nonce", "ntime", "version" }, + method<"submit_shares_success", number_t, optional<""_t>>{ "sequence_number", "new_target" }, + method<"submit_shares_error", number_t, string_t>{ "sequence_number", "code" }, + + /// Miscellaneous. + method<"reconnect", string_t, number_t>{ "new_host", "new_port" } + }; + + template + using subscriber = network::unsubscriber; + + template + using at = method_at; + + // Derive this from above in c++26 using reflection. + using setup_connection = at<0>; + using setup_connection_success = at<1>; + using setup_connection_error = at<2>; + using open_standard_mining_channel = at<3>; + using open_standard_mining_channel_success = at<4>; + using open_standard_mining_channel_error = at<5>; + using open_extended_mining_channel = at<6>; + using open_extended_mining_channel_success = at<7>; + using open_extended_mining_channel_error = at<8>; + using update_channel = at<9>; + using update_channel_error = at<10>; + using close_channel = at<11>; + using set_target = at<12>; + using new_mining_job = at<13>; + using set_new_prev_hash = at<14>; + using new_extended_mining_job = at<15>; + using set_custom_mining_job = at<16>; + using set_custom_mining_job_success = at<17>; + using set_custom_mining_job_error = at<18>; + using submit_shares = at<19>; + using submit_shares_success = at<20>; + using submit_shares_error = at<21>; + using reconnect = at<22>; +}; + +} // namespace interface +} // namespace node +} // namespace libbitcoin + +#endif diff --git a/include/bitcoin/node/protocols/protocol_explore.hpp b/include/bitcoin/node/protocols/protocol_explore.hpp index 1ae45731..c173bebb 100644 --- a/include/bitcoin/node/protocols/protocol_explore.hpp +++ b/include/bitcoin/node/protocols/protocol_explore.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include namespace libbitcoin { @@ -34,7 +35,7 @@ class BCN_API protocol_explore { public: typedef std::shared_ptr ptr; - using interface = network::rpc::interface::explore; + using interface = interface::explore; using dispatcher = network::rpc::dispatcher; protocol_explore(const auto& session,