mempool_space/
args.rs

1use getopts::Options;
2use std::env;
3use std::io::IsTerminal;
4use std::path::PathBuf;
5use std::process;
6
7use crate::api;
8use crate::api::{api, blocking};
9
10/// GET /api/v1/historical-price?currency=EUR&timestamp=1500000000
11/// pub fn historical_price(currency: &str, timestamp: &str)
12pub fn historical_price(currency: &str, timestamp: &str) {
13    let _res = api::blocking(&format!(
14        "v1/historical-price?currency={}&timestamp={}",
15        &(&currency).to_string(),
16        &(&timestamp).to_string()
17    ));
18}
19/// GET /api/block/:hash/txid/:index
20/// <https://mempool.space/docs/api/rest#get-block-transaction-id>
21pub fn block_txid(block_hash: &str, txindex: &str) {
22    let _res = api::blocking(&format!("block/{}/txid/{}", block_hash, txindex));
23}
24/// GET /api/block/:hash/txids
25/// <https://mempool.space/docs/api/rest#get-block-transaction-ids>
26pub fn block_txids(block_hash: &str) {
27    let _res = api::blocking(&format!("block/{}/txids", block_hash));
28}
29/// GET /api/block/:hash/txs[/:start_index] (start_index % 25 = 0)
30/// <https://mempool.space/docs/api/rest#get-block-transactions>
31pub fn block_txs(block_hash: &str, start_index: &str) {
32    let start_index_int = start_index.parse::<i32>().unwrap_or(0);
33    if start_index_int % 25 == 0 {
34        let _res = api::blocking(&format!("block/{}/txs/{}", block_hash, start_index));
35    } else {
36        let _res = api::blocking(&format!("block/{}/txs/{}", block_hash, &"0"));
37    }
38}
39/// GET /api/v1/blocks[/:startHeight]
40/// <https://mempool.space/docs/api/rest#get-blocks>
41pub fn blocks(start_height: &str, _print: bool) {
42    let blocks_tip_height = api::api("blocks_tip_height", "extraneous_arg", /*print*/ false);
43    let blocks_tip_height_int = blocks_tip_height.parse::<i32>().unwrap_or(0);
44    let start_height_int = start_height.parse::<i32>().unwrap_or(0);
45    if start_height_int >= 0 && start_height_int <= blocks_tip_height_int {
46        let _res = blocking(&format!("v1/blocks/{}", start_height));
47    } else {
48        let _res = blocking(&"v1/blocks".to_string());
49    }
50}
51/// GET /api/v1/blocks-bulk/:minHeight[/:maxHeight]
52/// <https://mempool.space/docs/api/rest#get-blocks-bulk>
53pub fn blocks_bulk(min_height: &str, max_height: &str, print: bool) {
54    let min_height_int = min_height.parse::<i32>().unwrap_or(0);
55    let max_height_int = max_height.parse::<i32>().unwrap_or(0);
56    if min_height_int >= 0 && max_height_int >= 0 && min_height_int < max_height_int {
57        let _res = blocking(&format!("v1/blocks-bulk/{}/{}", min_height, max_height));
58    } else if min_height_int >= 0 && max_height_int >= 0 && min_height_int >= max_height_int {
59        let _res = blocking(&format!("v1/blocks-bulk/{}/{}", max_height, min_height));
60    } else {
61        let blocks_tip_height = api::api("blocks_tip_height", "extraneous_arg", print);
62        let _res = blocking(&format!("v1/blocks-bulk/{}/{}", min_height, blocks_tip_height));
63    }
64    print!("This API is disabled. Set config.MEMPOOL.MAX_BLOCKS_BULK_QUERY to a positive number to enable it.");
65}
66/// GET /api/v1/mining/pool/:slug/blocks/\[:blockHeight]
67/// <https://mempool.space/docs/api/rest#get-mining-pool-blocks>
68pub fn mining_pool_blocks(slug: &str, blockheight: &str) {
69    let _res = blocking(&format!(
70        "v1/mining/pool/{}/blocks/{}",
71        &(&slug).to_string(),
72        &(&blockheight).to_string()
73    ));
74}
75/// GET /api/v1/mining/hashrate/pools/\[:timePeriod]
76/// <https://mempool.space/docs/api/rest#get-mining-pool-hashrates>
77pub fn mining_pool_hashrates(timeperiod: &str) {
78    let _res = blocking(&format!("v1/mining/hashrate/pools/{}", &(&timeperiod).to_string(),));
79}
80
81/// USAGE
82///
83/// ``mempool-space --difficulty_adjustment (flagged)``
84///
85/// ``mempool-space_difficulty_adjustment (executable)``
86///
87/// - Flags follow the [mempool.space api/rest](https://mempool.space/docs/api/rest) (replace dashes with underscores)
88///
89/// - Flags invoke the installed executable
90///
91/// DASHBOARD TUI INTERFACE (WIP)
92///
93/// ``mempool-space --dashboard (flagged)``
94///
95/// ``mempool-space_dashboard (executable)``
96///
97///
98/// <https://mempool.space/docs/api/rest>
99/// - [API/REST](https://mempool.space/docs/api/rest)
100///     - [GENERAL](https://mempool.space/docs/api/rest#get-difficulty-adjustment)
101///         - GET /api/v1/difficulty-adjustment
102///             - <https://mempool.space/api/v1/difficulty-adjustment>
103///         - GET /api/v1/prices
104///             - <https://mempool.space/api/v1/prices>
105///         - GET /api/v1/historical-price?currency=EUR&timestamp=1500000000
106///             - <https://mempool.space/api/v1/historical-price?currency=EUR&timestamp=1500000000>
107///     - [ADDRESSES](https://mempool.space/docs/api/rest#get-address)
108///         - GET /api/address/:address
109///             - <https://mempool.space/api/address/1wiz18xYmhRX6xStj2b9t1rwWX4GKUgpv>
110///         - GET /api/address/:address/txs
111///             - <https://mempool.space/api/address/1wiz18xYmhRX6xStj2b9t1rwWX4GKUgpv/txs>
112///         - GET /api/address/:address/txs/chain
113///             - <https://mempool.space/api/address/1wiz18xYmhRX6xStj2b9t1rwWX4GKUgpv/txs/chain>
114///         - GET /api/address/:address/txs/mempool
115///             - <https://mempool.space/api/address/1wiz18xYmhRX6xStj2b9t1rwWX4GKUgpv/txs/mempool>
116///         - GET /api/address/:address/utxo
117///             - <https://mempool.space/api/address/1KFHE7w8BhaENAswwryaoccDb6qcT6DbYY/utxo>
118///         - GET /api/v1/validate-address/:address
119///             - <https://mempool.space/api/v1/validate-address/1KFHE7w8BhaENAswwryaoccDb6qcT6DbYY>
120///     - [BLOCKS](https://mempool.space/docs/api/rest#get-block)
121///         - GET /api/block/:hash
122///             - <https://mempool.space/api/block/000000000000000015dc777b3ff2611091336355d3f0ee9766a2cf3be8e4b1ce>
123///         - GET /api/block/:hash/header
124///             - <https://mempool.space/api/block/0000000000000000000065bda8f8a88f2e1e00d9a6887a43d640e52a4c7660f2/header>
125///         - GET /api/block-height/:height
126///             - <https://mempool.space/api/block-height/615615>
127///         - GET /api/v1/mining/blocks/timestamp/:timestamp
128///             - <https://mempool.space/api/v1/mining/blocks/timestamp/1672531200>
129///         - GET /api/block/:hash/raw
130///             - <https://mempool.space/api/block/0000000000000000000065bda8f8a88f2e1e00d9a6887a43d640e52a4c7660f2/raw>
131///         - GET /api/block/:hash/status
132///             - <https://mempool.space/api/block/0000000000000000000065bda8f8a88f2e1e00d9a6887a43d640e52a4c7660f2/status>
133///         - GET /api/blocks/tip/height
134///             - <https://mempool.space/api/blocks/tip/height>
135///         - GET /api/blocks/tip/hash
136///             - <https://mempool.space/api/blocks/tip/hash>
137///         - GET /api/block/:hash/txid/:index
138///             - <https://mempool.space/api/block/000000000000000015dc777b3ff2611091336355d3f0ee9766a2cf3be8e4b1ce/txid/218>
139///         - GET /api/block/:hash/txids
140///             - <https://mempool.space/api/block/000000000000000015dc777b3ff2611091336355d3f0ee9766a2cf3be8e4b1ce/txids>
141///         - GET /api/block/:hash/txs[/:start_index]
142///             - <https://mempool.space/api/block/000000000000000015dc777b3ff2611091336355d3f0ee9766a2cf3be8e4b1ce/txs>
143///         - GET /api/v1/blocks[/:startHeight]
144///             - <https://mempool.space/api/v1/blocks/730000>
145///         - GET /api/v1/blocks-bulk/:minHeight[/:maxHeight]
146///             - <https://mempool.space/api/v1/blocks-bulk/100000/100000> (Enterprise)
147///     - [MINING](https://mempool.space/docs/api/rest#get-mining-pools)
148///         - GET /api/v1/mining/pools[/:timePeriod]
149///             - <https://mempool.space/api/v1/mining/pools/1w>
150///         - GET /api/v1/mining/pool/:slug
151///             - <https://mempool.space/api/v1/mining/pool/antpool>
152///         - GET /api/v1/mining/hashrate/pools/[\:timePeriod]
153///             - <https://mempool.space/api/v1/mining/hashrate/pools/1m>
154///         - GET /api/v1/mining/pool/:slug/hashrate
155///             - <https://mempool.space/api/v1/mining/pool/foundryusa/hashrate>
156///         - GET /api/v1/mining/pool/:slug/blocks/[\:blockHeight]
157///             - <https://mempool.space/api/v1/mining/pool/luxor/blocks/730000>
158///         - GET /api/v1/mining/hashrate/[\:timePeriod]
159///             - <https://mempool.space/api/v1/mining/hashrate/3d>
160///         - GET /api/v1/mining/pool/:slug/blocks/[\:blockHeight]
161///             - <https://mempool.space/api/v1/mining/pool/luxor/blocks/730000>
162///         - GET /api/v1/mining/difficulty-adjustments/[\:interval]
163///             - <https://mempool.space/api/v1/mining/difficulty-adjustments/1m>
164///         - GET /api/v1/mining/reward-stats/:blockCount
165///             - <https://mempool.space/api/v1/mining/reward-stats/100>
166///         - GET /api/v1/mining/blocks/fees/:timePeriod
167///             - <https://mempool.space/api/v1/mining/blocks/fees/1w>
168///         - GET /api/v1/mining/blocks/rewards/:timePeriod
169///             - <https://mempool.space/docs/api/rest#get-block-rewards>
170///         - GET /api/v1/mining/blocks/fee-rates/:timePeriod
171///             - <https://mempool.space/api/v1/mining/blocks/fee-rates/1m>
172///         - GET /api/v1/mining/blocks/sizes-weights/:timePeriod
173///             - <https://mempool.space/api/v1/mining/blocks/sizes-weights/3y>
174///         - GET /api/v1/mining/blocks/predictions/:timePeriod
175///             - <https://mempool.space/api/v1/mining/blocks/predictions/3y>
176///         - GET /api/v1/mining/blocks/audit/score/:blockHash
177///             - <https://mempool.space/api/v1/mining/blocks/audit/score/000000000000000000032535698c5b0c48283b792cf86c1c6e36ff84464de785>
178///         - GET /api/v1/mining/blocks/audit/scores/:startHeight
179///             - <https://mempool.space/api/v1/mining/blocks/audit/scores/820000>
180///         - GET /api/v1/block/:blockHash/audit-summary
181///             - <https://mempool.space/api/v1/block/00000000000000000000f218ceda7a5d9c289040b9c3f05ef9f7c2f4930e0123/audit-summary>
182///     - [FEES](https://mempool.space/docs/api/rest#get-mempool-blocks-fees)
183///         - GET /api/v1/fees/mempool-blocks
184///             - <https://mempool.space/api/v1/fees/mempool-blocks>
185///         - GET /api/v1/fees/recommended
186///             - <https://mempool.space/api/v1/fees/recommended>
187///     - [MEMPOOL](https://mempool.space/docs/api/rest#get-mempool)
188///         - GET /api/mempool
189///             - <https://mempool.space/api/mempool>
190///         - GET /api/mempool/txids
191///             - <https://mempool.space/api/mempool/txids>
192///         - GET GET /api/mempool/recent
193///             - <https://mempool.space/api/mempool/recent>
194///         - GET /api/v1/replacements
195///             - <https://mempool.space/api/v1/replacements>
196///         - GET /api/v1/fullrbf/replacements
197///             - <https://mempool.space/api/v1/fullrbf/replacements>
198///     - [TRANSACTIONS](https://mempool.space/docs/api/rest#get-cpfp)
199///         - GET /api/v1/cpfp
200///             - <https://mempool.space/api/v1/cpfp/be6ba3c97d65478534333dc9a6db159b538c3722bd18bea43765e95c7139a8e6>
201///         - GET /api/tx/:txid
202///             - <https://mempool.space/api/tx/15e10745f15593a899cef391191bdd3d7c12412cc4696b7bcb669d0feadc8521>
203///         - GET /api/tx/:txid/hex
204///             - <https://mempool.space/api/tx/15e10745f15593a899cef391191bdd3d7c12412cc4696b7bcb669d0feadc8521/hex>
205///         - GET /api/tx/:txid/merkleblock-proof
206///             - <https://mempool.space/api/tx/15e10745f15593a899cef391191bdd3d7c12412cc4696b7bcb669d0feadc8521/merkleblock-proof>
207///         - GET /api/tx/:txid/merkle-proof
208///             - <https://mempool.space/api/tx/15e10745f15593a899cef391191bdd3d7c12412cc4696b7bcb669d0feadc8521/merkle-proof>
209///         - GET /api/tx/:txid/outspend/:vout
210///             - <https://mempool.space/api/tx/15e10745f15593a899cef391191bdd3d7c12412cc4696b7bcb669d0feadc8521/outspend/3>
211///         - GET /api/tx/:txid/outspends
212///             - <https://mempool.space/api/tx/15e10745f15593a899cef391191bdd3d7c12412cc4696b7bcb669d0feadc8521/outspends>
213///         - GET /api/tx/:txid/raw
214///             - <https://mempool.space/api/tx/15e10745f15593a899cef391191bdd3d7c12412cc4696b7bcb669d0feadc8521/raw>
215///         - GET /apiv1/tx/:txId/rbf
216///             - <https://mempool.space/api/v1/tx/2e95ff9094df9f3650e3f2abc189250760162be89a88f9f2f23301c7cb14b8b4/rbf>
217///         - GET /api/tx/:txid/status
218///             - <https://mempool.space/api/tx/15e10745f15593a899cef391191bdd3d7c12412cc4696b7bcb669d0feadc8521/status>
219///         - GET /api/v1/transaction-times
220///             - <https://mempool.space/api/v1/transaction-times?txId[]=51545ef0ec7f09196e60693b59369a134870985c8a90e5d42655b191de06285e&txId[]=6086089bd1c56a9c42a39d470cdfa7c12d4b52bf209608b390dfc4943f2d3851>
221///         - POST /api/tx
222///             - \<TODO\>
223///     - [LIGHTNING](https://mempool.space/docs/api/rest#get-lightning-network-stats)
224///         - GET /api/v1/lightning/statistics/:interval
225///             - <https://mempool.space/api/v1/lightning/statistics/latest>
226///         - GET /api/v1/lightning/search?searchText=:query
227///             - <https://mempool.space/api/v1/lightning/search?searchText=ACINQ>
228///         - GET /api/v1/lightning/nodes/country/:country
229///             - <https://mempool.space/api/v1/lightning/nodes/country/ch>
230///         - GET /api/v1/lightning/nodes/countries
231///             - <https://mempool.space/api/v1/lightning/nodes/countries>
232///         - GET /api/v1/lightning/nodes/isp/:isp
233///             - <https://mempool.space/api/v1/lightning/nodes/isp/16509>
234///         - GET /api/v1/lightning/nodes/isp-ranking
235///             - <https://mempool.space/api/v1/lightning/nodes/isp-ranking>
236///         - GET /api/v1/lightning/nodes/rankings
237///             - <https://mempool.space/api/v1/lightning/nodes/rankings>
238///         - GET /api/v1/lightning/nodes/rankings/liquidity
239///             - <https://mempool.space/api/v1/lightning/nodes/rankings/liquidity>
240///         - GET /api/v1/lightning/nodes/rankings/connectivity
241///             - <https://mempool.space/api/v1/lightning/nodes/rankings/connectivity>
242///         - GET /api/v1/lightning/nodes/rankings/age
243///             - <https://mempool.space/api/v1/lightning/nodes/rankings/age>
244///         - GET /api/v1/lightning/nodes/:pubKey
245///             - <https://mempool.space/api/v1/lightning/nodes/033ac2f9f7ff643c235cc247c521663924aff73b26b38118a6c6821460afcde1b3>
246///         - GET /api/v1/lightning/nodes/:pubKey/statistics
247///             - <https://mempool.space/api/v1/lightning/nodes/033ac2f9f7ff643c235cc247c521663924aff73b26b38118a6c6821460afcde1b3/statistics>
248///         - GET /api/v1/lightning/channels/:channelId
249///             - <https://mempool.space/api/v1/lightning/channels/768457472831193088>
250///         - GET /api/v1/lightning/channels/txids?txId[]=:txid
251///             - <https://mempool.space/api/v1/lightning/channels/txids?txId[]=c3173549f502ede6440d5c48ea74af5607d88484c7a912bbef73d430049f8af4&txId[]=d78f0b41a263af3df91fa4171cc2f60c40196aaf8f4bde5d1c8ff4474cfe753b>
252///         - GET /api/v1/lightning/channels?public_key=:pubKey&status=:channelStatus
253///             - <https://mempool.space/api/v1/lightning/channels?public_key=026165850492521f4ac8abd9bd8088123446d126f648ca35e60f88177dc149ceb2&status=open>
254///         - GET /api/v1/lightning/channels-geo
255///             - <https://mempool.space/api/v1/lightning/channels-geo>
256///         - GET /api/v1/lightning/channels-geo/:pubKey
257///             - <https://mempool.space/api/v1/lightning/channels-geo/03d607f3e69fd032524a867b288216bfab263b6eaee4e07783799a6fe69bb84fac>
258///     - [ACCELERATOR (Public)](https://mempool.space/docs/api/rest#accelerator-estimate)
259///         - POST /v1/services/accelerator/estimate
260///             - `curl -H "X-Mempool-Auth: stacksats" -X POST -sSLd "txInput=ee13ebb99632377c15c94980357f674d285ac413452050031ea6dcd3e9b2dc29" "https://mempool.space/api/v1/services/accelerator/estimate"`
261///         POST /v1/services/payments/bitcoin
262///             - `curl -X POST -sSLd "product=ee13ebb99632377c15c94980357f674d285ac413452050031ea6dcd3e9b2dc29&amount=12500" "https://mempool.space/api/v1/services/payments/bitcoin"`
263///         - GET /api/v1/services/accelerator/accelerations
264///             - <https://mempool.space/api/v1/services/accelerator/accelerations>
265///         - GET /api/v1/services/accelerator/accelerations/history
266///             - <https://mempool.space/api/v1/services/accelerator/accelerations/history?blockHash=00000000000000000000482f0746d62141694b9210a813b97eb8445780a32003>
267///             - `curl https://raw.githubusercontent.com/mempool/mining-pools/master/pools-v2.json`
268///     - [ACCELERATOR (Authenticated) TODO](https://mempool.space/docs/api/rest#accelerator-top-up-history)
269///         - GET /api/v1/services/accelerator/top-up-history
270///             - <https://mempool.space/api/v1/services/accelerator/top-up-history>
271///         - GET /api/v1/services/accelerator/balance
272///             - <https://mempool.space/api/v1/services/accelerator/balance>
273///         - POST /v1/services/accelerator/accelerate
274///             - `curl -H "X-Mempool-Auth: stacksats" -X POST -sSLd "txInput=ee13ebb99632377c15c94980357f674d285ac413452050031ea6dcd3e9b2dc29&userBid=21000000" "https://mempool.space/api/v1/services/accelerator/accelerate"`
275///         - GET /api/v1/services/accelerator/history?status=:status&details=:details
276///             - <https://mempool.space/api/v1/services/accelerator/history?status=all&details=true>
277///
278#[derive(Debug, Default)]
279pub struct Args {
280    /// `mempool-space --version`
281    pub version: Option<String>,
282    /// `mempool-space --dashboard`
283    /// invoke the tui (WIP)
284    pub dashboard: Option<String>,
285    /// `https://mempool.space/api/v1/difficulty-adjustment`
286    pub difficulty_adjustment: Option<String>,
287    /// `https://mempool.space/api/v1/prices`
288    pub prices: Option<String>,
289    /// `https://mempool.space/api/v1/historical-price`
290    pub historical_price: Option<String>,
291    /// `https://mempool.space/api/v1/historical-price?currency=USD`
292    pub currency: Option<String>,
293    /// `https://mempool.space/api/v1/historical-price?currency=USD?timestamp=0`
294    pub timestamp: Option<String>,
295
296    /// `https://mempool.space/api/address/<ADDRESS>`
297    pub address: Option<String>,
298    /// `https://mempool.space/api/address/<ADDRESS>/txs`
299    pub address_txs: Option<String>,
300    /// `https://mempool.space/api/address/<ADDRESS>/txs/chain`
301    pub address_txs_chain: Option<String>,
302    /// `https://mempool.space/address/<ADDRESS>/txs/mempool`
303    pub address_txs_mempool: Option<String>,
304    /// `https://mempool.space/api/address/<ADDRESS>/utxo`
305    pub address_utxo: Option<String>,
306    /// `https://mempool.space/api/validate-address/<ADDRESS>`
307    pub validate_address: Option<String>,
308
309    /// `https://mempool.space/api/block/<BLOCK_HASH>`
310    pub block: Option<String>,
311    /// `https://mempool.space/api/block/<BLOCK_HASH>/header`
312    pub block_header: Option<String>,
313    /// `https://mempool.space/api/block-height/<BLOCK_HEIGHT>`
314    pub block_height: Option<String>,
315    /// `https://mempool.space/api/v1/mining/blocks/timestamp/<UTC_SECS>`
316    pub blocks_timestamp: Option<String>,
317    /// `https://mempool.space/api/block/<BLOCK_HASH>/raw`
318    pub block_raw: Option<String>,
319    /// `https://mempool.space/api/block/<BLOCK_HASH>/status`
320    pub block_status: Option<String>,
321    /// `https://mempool.space/api/blocks/tip/height`
322    pub blocks_tip_height: Option<String>,
323    /// `https://mempool.space/api/blocks/tip/hash`
324    pub blocks_tip_hash: Option<String>,
325    /// `https://mempool.space/api/block/:hash/txid/:index`
326    pub block_txid: Option<String>, //HASH
327    /// `https://mempool.space/api/block/:hash/txid/:index`
328    pub block_txindex: Option<String>, //INDEX
329    /// `https://mempool.space/api/block/<TXID>`
330    pub block_txids: Option<String>,
331    /// `https://mempool.space/api/block/<BLOCK_HASH>/txs`
332    pub block_txs: Option<String>,
333    /// `https://mempool.space/api/v1/blocks/<BLOCKS_START_HEIGHT>`
334    pub start_index: Option<String>,
335    /// `https://mempool.space/api/v1/blocks/<BLOCKS_START_HEIGHT>`
336    pub blocks: Option<String>,
337    /// `https://mempool.space/api/v1/blocks-bulk/<MIN_HEIGHT>/<MAX_HEIGHT>`
338    pub blocks_bulk: Option<String>,
339    /// `https://mempool.space/api/v1/blocks-bulk/<MIN_HEIGHT>/<MAX_HEIGHT>`
340    pub min_height: Option<String>,
341    /// `https://mempool.space/api/v1/blocks-bulk/<MIN_HEIGHT>/<MAX_HEIGHT>`
342    pub max_height: Option<String>,
343
344    /// `https://mempool.space/api/v1/mining/pools[/:timePeriod]`
345    pub mining_pools: Option<String>,
346    /// `https://mempool.space/api/v1/mining/pools[/:timePeriod]`
347    pub timeperiod: Option<String>,
348
349    /// `https://mempool.space/api/v1/mining/pool/:<SLUG>`
350    pub mining_pool: Option<String>,
351    /// slug
352    pub slug: Option<String>,
353
354    /// `https://mempool.space/api/v1/mining/hashrate/pools/:<TIMEPERIOD>`
355    pub mining_hashrate_pools: Option<String>,
356    /// `https://mempool.space/api/v1/mining/hashrate/pools/:<TIMEPERIOD>`
357    /// REUSE pub timeperiod: Option\<String\>,
358
359    /// `https://mempool.space/api/v1/mining/pool/:<SLUG>/hashrate`
360    pub mining_pool_hashrate: Option<String>,
361    /// `https://mempool.space/api/v1/mining/pool/:slug/hashrate`
362    /// REUSE pub slug: Option\<String\>,
363
364    /// `https://mempool.space/api/v1/mining/difficulty-adjustments/[:interval]`
365    pub difficulty_adjustments: Option<String>,
366    /// interval
367    pub interval: Option<String>,
368
369    /// `https://mempool.space/api/v1/mining/blocks/audit/score/<BLOCKHASH>`
370    pub blocks_audit_score: Option<String>,
371    /// `https://mempool.space/api/v1/mining/blocks/audit/score/<BLOCKHASH>`
372    pub blockhash: Option<String>,
373
374    /// `https://mempool.space/api/v1/mining/blocks/audit/scores/<BLOCKHEIGHT>`
375    pub blocks_audit_scores: Option<String>,
376    /// `https://mempool.space/api/v1/mining/blocks/audit/scores/<BLOCKHEIGHT>`
377    pub blockheight: Option<String>,
378
379    /// `https://mempool.space/api/v1/mining/block/<BLOCKHASH>/audit-summary`
380    pub block_audit_summary: Option<String>,
381    // pub blockhash: Option<String>,
382    //
383    //
384    //
385    //
386    //
387    /// OPTOPT
388    ///
389    /// Configuration file.
390    pub config: Option<PathBuf>,
391    /// Server address.
392    pub server: Option<String>,
393    /// Authentication or delete token.
394    pub auth: Option<String>,
395    /// URL to shorten.
396    pub url: Option<String>,
397    /// Remote URL to download file.
398    pub remote: Option<String>,
399    /// Files to upload.
400    pub files: Vec<String>,
401    /// Whether if the file will disappear after being viewed once.
402    pub oneshot: bool,
403    /// Expiration time for the link.
404    pub expire: Option<String>,
405    /// Prettify the program output.
406    pub prettify: bool,
407    /// Whether if the server version should be printed.
408    pub print_server_version: bool,
409    /// List files on the server (file name, file size, expiry timestamp).
410    pub list_files: bool,
411    /// Delete files from server.
412    pub delete: bool,
413    /// Send filename header (give uploaded file a specific name).
414    pub filename: Option<String>,
415}
416
417impl Args {
418    /// Parses the command-line arguments.
419    pub fn parse() -> Self {
420        let mut opts = Options::new();
421
422        //OPTFLAG
423        opts.optflag("h", "help", "prints help information");
424        opts.optflag("v", "version", "prints version information");
425        opts.optflag("V", "server-version", "retrieves the server version");
426        opts.optflag("l", "list", "lists files on the server");
427        opts.optflag("d", "delete", "delete files from server");
428        opts.optflag("o", "oneshot", "generates one shot links");
429        opts.optflag("p", "pretty", "prettifies the output");
430
431        // mempool-space_dashboard
432        opts.optflag("", "dashboard", "invoke the tui (WIP)");
433
434        // mempool api intercepts
435        // VERSION
436        // premeptive support v1,v2 etc...
437        // opts.optopt("", "version", "api call version path (v1/...)", "VERSION");
438        // GENERAL
439        opts.optflag("", "difficulty_adjustment", "difficulty_adjustment api call");
440        opts.optflag("", "prices", "prices api call");
441        opts.optflag("", "historical_price", "historical_price api call");
442        opts.optopt("", "timestamp", "timestamp api call", "TIMESTAMP");
443        opts.optopt("", "currency", "currency api call", "CURRENCY");
444
445        // ADDRESSES
446        opts.optopt("", "address", "address api call", "ADDRESS");
447        opts.optopt("", "address_txs", "address_txs api call", "ADDRESS_TXS");
448        opts.optopt(
449            "",
450            "address_txs_chain",
451            "address_txs_chain api call",
452            "ADDRESS_TXS_CHAIN",
453        );
454        opts.optopt(
455            "",
456            "address_txs_mempool",
457            "address_txs_mempool api call",
458            "ADDRESS_TXS_MEMPOOL",
459        );
460        opts.optopt("", "address_utxo", "address_utxos api call", "ADDRESS_UTXO");
461        opts.optopt("", "validate_address", "validate an address", "VALIDATE_ADDRESS");
462
463        // BLOCK/S
464        opts.optopt("", "block", "block api call", "BLOCK");
465        opts.optopt("", "block_header", "block-header api call", "BLOCK_HEADER");
466
467        // BLOCK_HEIGHT
468        // REUSED
469        opts.optopt("", "block_height", "block-height api call", "BLOCK_HEIGHT");
470        //
471        opts.optopt("", "blocks_timestamp", "blocks-timestamp api call", "BLOCKS_TIMESTAMP");
472        opts.optopt("", "block_raw", "block-raw api call", "BLOCK_RAW");
473        opts.optopt("", "block_status", "block-status api call", "BLOCK_STATUS");
474
475        opts.optflag("", "blocks_tip_height", "GET /api/blocks/tip/height api call");
476        opts.optflag("", "blocks_tip_hash", "GET /api/blocks/tip/hash api call");
477
478        opts.optopt("", "block_txid", "block txid api call", "BLOCK_TXID");
479        opts.optopt("", "block_txindex", "block_txindex api call", "BLOCK_TXINDEX");
480        opts.optopt("", "block_txids", "block txids api call", "BLOCK_TXIDS");
481
482        opts.optopt("", "block_txs", "block txs api call", "BLOCK_TXS");
483        opts.optopt("", "start_index", "block txs api call", "START_INDEX");
484
485        opts.optopt("", "blocks", "block txids api call", "BLOCKS_START_HEIGHT");
486
487        opts.optflag("", "blocks_bulk", "block txids api call");
488        opts.optopt("", "min_height", "block txids api call", "MIN_HEIGHT");
489        opts.optopt("", "max_height", "block txids api call", "MAX_HEIGHT");
490
491        // MINING
492        opts.optflag("", "mining_pools", "mining_pools api call");
493        opts.optopt("", "timeperiod", "mining_pools api call", "TIMEPERIOD");
494
495        opts.optflag("", "mining_pool", "mining_pool api call");
496        opts.optopt("", "slug", "mining_pool api call", "SLUG");
497
498        opts.optflag("", "mining_hashrate_pools", "mining_hashrate_pools api call");
499        opts.optopt("", "timeperiod", "mining_hashrate_pools api call", "TIMEPERIOD");
500
501        opts.optflag("", "mining_pool_hashrate", "mining_pool_hashrate api call");
502        opts.optopt("", "slug", "mining_pool_hashrate api call", "SLUG");
503
504        opts.optflag("", "mining_pool_blocks", "mining_pool_hashrate api call");
505        opts.optopt("", "slug", "mining_pool_hashrate api call", "SLUG");
506        opts.optopt("", "blockheight", "mining_pool_hashrate api call", "BLOCKHEIGHT");
507
508        opts.optflag("", "difficulty_adjustments", "difficulty_adjustments api call");
509        opts.optopt("", "interval", "difficulty_adjustments api call", "INTERVAL");
510
511        opts.optflag("", "blocks_audit_score", "blocks_audit_score api call");
512        opts.optopt("", "block_hash", "blocks_audit_score api call", "BLOCK_HASH");
513
514        opts.optflag("", "blocks_audit_scores", "blocks_audit_scores api call");
515        //opts.optopt("", "blockheight", "blocks_audit_scores api call", "BLOCKHEIGHT");
516
517        opts.optflag("", "block_audit_summary", "block_audit_summary api call");
518        opts.optopt("", "blockhash", "block_audit_summary api call", "BLOCKHASH");
519
520        // OPTOPT
521        opts.optopt("c", "config", "sets the configuration file", "CONFIG");
522        opts.optopt("s", "server", "sets the address of the rustypaste server", "SERVER");
523        opts.optopt("a", "auth", "sets the authentication or delete token", "TOKEN");
524        opts.optopt("u", "url", "sets the URL to shorten", "URL");
525        opts.optopt("r", "remote", "sets the remote URL for uploading", "URL");
526        opts.optopt("e", "expire", "sets the expiration time for the link", "TIME");
527        opts.optopt("n", "filename", "sets and overrides the filename", "NAME");
528
529        let env_args: Vec<String> = env::args().collect();
530        let matches = match opts.parse(&env_args[1..]) {
531            Ok(m) => m,
532            Err(e) => {
533                eprintln!("Argument error: `{e}`");
534                process::exit(1);
535            }
536        };
537
538        //invoke the dashboard
539        // DASHBOARD
540        if matches.opt_present("dashboard") {
541            api("dashboard", "", false);
542        };
543        //mempool api intercepts
544        // VERSION
545        // GENERAL
546        if matches.opt_present("difficulty_adjustment") {
547            api("difficulty_adjustment", "v9999", true);
548            std::process::exit(0);
549        }
550        if matches.opt_present("prices") {
551            api("prices", "v9999", true);
552            std::process::exit(0);
553        }
554        if matches.opt_present("historical_price") {
555            if matches.opt_present("currency") {
556                //print!("currency={}\n", matches.opt_present("currency"));
557                let currency = matches.opt_str("currency");
558                //print!("currency={}", currency.clone().unwrap());
559                if matches.opt_present("timestamp") {
560                    //print!("timestamp={}\n", matches.opt_present("timestamp"));
561                    let timestamp = matches.opt_str("timestamp");
562                    historical_price(currency.as_ref().unwrap(), &timestamp.unwrap());
563                } else {
564                    historical_price(&currency.unwrap(), "");
565                }
566            } else {
567                historical_price("", "");
568            }
569
570            //historical_prices(&"USD", &"1500000000");
571            //historical_prices(&"EUR", &"1500000000");
572            std::process::exit(0);
573        }
574
575        // ADDRESSES
576        if matches.opt_present("address") {
577            let address = matches.opt_str("address");
578            //print!("address={:?}", address);
579            api("address", &address.unwrap(), true);
580            std::process::exit(0);
581        }
582        if matches.opt_present("address_txs") {
583            let address = matches.opt_str("address_txs");
584            api("address_txs", &address.unwrap(), true);
585            std::process::exit(0);
586        }
587        if matches.opt_present("address_txs_chain") {
588            let address = matches.opt_str("address_txs_chain");
589            api("address_txs_chain", &address.unwrap(), true);
590            std::process::exit(0);
591        }
592        if matches.opt_present("address_txs_mempool") {
593            let address = matches.opt_str("address_txs_mempool");
594            api("address_txs_mempool", &address.unwrap(), true);
595            std::process::exit(0);
596        }
597        if matches.opt_present("address_utxo") {
598            let address = matches.opt_str("address_utxo");
599            api("address_utxo", &address.unwrap(), true);
600            std::process::exit(0);
601        }
602        if matches.opt_present("validate_address") {
603            let validate_address = matches.opt_str("validate_address");
604            api("validate_address", &validate_address.unwrap(), true);
605            std::process::exit(0);
606        }
607        // BLOCKS
608        if matches.opt_present("block") {
609            let block = matches.opt_str("block");
610            api("block", &block.unwrap(), true);
611            std::process::exit(0);
612        }
613        if matches.opt_present("block_header") {
614            let block_header = matches.opt_str("block_header");
615            api("block_header", &block_header.unwrap(), true);
616            std::process::exit(0);
617        }
618        if matches.opt_present("block_height") {
619            let block_height = matches.opt_str("block_height");
620            api("block_height", &block_height.unwrap(), true);
621            std::process::exit(0);
622        }
623        if matches.opt_present("blocks_timestamp") {
624            let blocks_timestamp = matches.opt_str("blocks_timestamp");
625            api("blocks_timestamp", &blocks_timestamp.unwrap(), true);
626            std::process::exit(0);
627        }
628        if matches.opt_present("block_raw") {
629            let block_raw = matches.opt_str("block_raw");
630            api("block_raw", &block_raw.unwrap(), true);
631            std::process::exit(0);
632        }
633        if matches.opt_present("block_status") {
634            let block_status = matches.opt_str("block_status");
635            api("block_status", &block_status.unwrap(), true);
636            std::process::exit(0);
637        }
638        if matches.opt_present("blocks_tip_height") {
639            api("blocks_tip_height", "extraneous_arg", true);
640            std::process::exit(0);
641        }
642        if matches.opt_present("blocks_tip_hash") {
643            api("blocks_tip_hash", "extraneous_arg", true);
644            std::process::exit(0);
645        }
646        if matches.opt_present("block_txid") {
647            let arg_block_txid = matches.opt_str("block_txid");
648            let arg_block_txindex = matches.opt_str("block_txindex");
649            block_txid(&arg_block_txid.unwrap(), &arg_block_txindex.unwrap());
650            std::process::exit(0);
651        }
652        if matches.opt_present("block_txids") {
653            let arg_block_txids = matches.opt_str("block_txids");
654            block_txids(&arg_block_txids.unwrap());
655            std::process::exit(0);
656        }
657        if matches.opt_present("block_txs") {
658            let arg_block_txs = matches.opt_str("block_txs");
659            let arg_start_index = matches.opt_str("start_index");
660            block_txs(&arg_block_txs.unwrap(), &arg_start_index.unwrap_or(String::from("0")));
661            std::process::exit(0);
662        }
663        if matches.opt_present("blocks") {
664            let arg_blocks = matches.opt_str("blocks");
665            blocks(&arg_blocks.unwrap(), true);
666            std::process::exit(0);
667        }
668        if matches.opt_present("blocks_bulk") {
669            let arg_min_height = matches.opt_str("min_height");
670            let arg_max_height = matches.opt_str("max_height");
671            blocks_bulk(&arg_min_height.unwrap(), &arg_max_height.unwrap(), true);
672            std::process::exit(0);
673        }
674        // MINING
675        if matches.opt_present("mining_pools") {
676            let arg_timeperiod = matches.opt_str("timeperiod");
677            api("mining_pools", &arg_timeperiod.unwrap(), true);
678            std::process::exit(0);
679        }
680        if matches.opt_present("mining_pool") {
681            let arg_slug = matches.opt_str("slug");
682            api("mining_pool", &arg_slug.unwrap(), true);
683            std::process::exit(0);
684        }
685        if matches.opt_present("mining_hashrate_pools") {
686            let arg_timeperiod = matches.opt_str("timeperiod");
687            api("mining_hashrate_pools", &arg_timeperiod.unwrap(), true);
688            std::process::exit(0);
689        }
690        if matches.opt_present("mining_pool_hashrate") {
691            let arg_slug = matches.opt_str("slug");
692            api("mining_pool_hashrate", &arg_slug.unwrap(), true);
693            std::process::exit(0);
694        }
695        if matches.opt_present("mining_pool_blocks") {
696            let arg_slug = matches.opt_str("slug");
697            let arg_blockheight = matches.opt_str("blockheight");
698            mining_pool_blocks(&arg_slug.unwrap(), &arg_blockheight.unwrap());
699            std::process::exit(0);
700        }
701
702        if matches.opt_present("difficulty_adjustments") {
703            let arg_interval = matches.opt_str("interval");
704            api("difficulty_adjustments", &arg_interval.unwrap(), true);
705            std::process::exit(0);
706        }
707
708        if matches.opt_present("blocks_audit_score") {
709            let arg_blockhash = matches.opt_str("blockhash");
710            api("blocks_audit_score", &arg_blockhash.unwrap(), true);
711            std::process::exit(0);
712        }
713
714        if matches.opt_present("blocks_audit_scores") {
715            let arg_blockheight = matches.opt_str("blockheight");
716            api("blocks_audit_scores", &arg_blockheight.unwrap(), true);
717            std::process::exit(0);
718        }
719        if matches.opt_present("block_audit_summary") {
720            let arg_blockhash = matches.opt_str("blockhash");
721            api("block_audit_summary", &arg_blockhash.unwrap(), true);
722            std::process::exit(0);
723        }
724
725        if matches.opt_present("h")
726            || (matches.free.is_empty()
727                && !matches.opt_present("u")
728                && !matches.opt_present("r")
729                && !matches.opt_present("V")
730                && !matches.opt_present("l")
731                && !matches.opt_present("d")
732                && !matches.opt_present("v")
733                && std::io::stdin().is_terminal())
734        {
735            let usage = format!(
736                "\n{} {} \u{2014} {}.\
737                \n\u{221F} written by {}\
738                \n\u{221F} licensed under MIT <{}>\
739                \n\nUsage:\n    {} [options] <file(s)>",
740                env!("CARGO_PKG_NAME"),
741                env!("CARGO_PKG_VERSION"),
742                env!("CARGO_PKG_DESCRIPTION"),
743                env!("CARGO_PKG_AUTHORS"),
744                env!("CARGO_PKG_REPOSITORY"),
745                "mempool-space",
746            );
747            println!("{}", opts.usage(&usage));
748            process::exit(0)
749        }
750
751        if matches.opt_present("v") {
752            println!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
753            process::exit(0)
754        }
755
756        Args {
757            config: env::var("RPASTE_CONFIG")
758                .ok()
759                .or_else(|| matches.opt_str("c"))
760                .map(PathBuf::from),
761
762            // invoke mempool-space_dashboard
763            dashboard: matches.opt_str("dashboard"),
764
765            // mempool api intercepts
766            // mempool api version
767            version: matches.opt_str("version"),
768
769            // GENERAL
770            difficulty_adjustment: matches.opt_str("difficulty_adjustment"),
771            currency: matches.opt_str("currency"),
772            prices: matches.opt_str("prices"),
773            timestamp: matches.opt_str("timestamp"),
774            historical_price: matches.opt_str("historical_price"),
775
776            // ADDRESSES
777            address: matches.opt_str("address"),
778            address_txs: matches.opt_str("address_txs"),
779            address_txs_chain: matches.opt_str("address_txs_chain"),
780            address_txs_mempool: matches.opt_str("address_txs_mempool"),
781            address_utxo: matches.opt_str("address_utxo"),
782            validate_address: matches.opt_str("validate_address"),
783
784            // BLOCK/S
785            // https://mempool.space/api/block/<endpoint>
786            // https://mempool.space/api/block/<block_hash>
787            // BLOCK
788            block: matches.opt_str("block"),
789            // https://mempool.space/api/block/<block_hash>/header
790            block_header: matches.opt_str("block_header"),
791            // BLOCK_HEIGHT
792            // https://mempool.space/api/block-height/615615
793            block_height: matches.opt_str("block_height"),
794
795            // V1 MINING BLOCKS_TIMESTAMP
796            // https://mempool.space/api/v1/mining/blocks/timestamp/<UTC_SECS>"
797            blocks_timestamp: matches.opt_str("blocks_timestamp"),
798
799            // BLOCK_RAW
800            // https://mempool.space/api/block/<block_hash>/raw
801            block_raw: matches.opt_str("block_raw"),
802
803            // BLOCK_STATUS
804            // https://mempool.space/api/block/<block_hash>/status
805            block_status: matches.opt_str("block_status"),
806
807            // BLOCKS
808            // BLOCKS_TIP_HEIGHT
809            // https://mempool.space/api/blocks/tip/height
810            blocks_tip_height: matches.opt_str("blocks_tip_height"),
811
812            // BLOCKS_TIP_HASH
813            // https://mempool.space/api/blocks/tip/hash
814            blocks_tip_hash: matches.opt_str("blocks_tip_hash"),
815
816            // BLOCK
817            // BLOCK BLOCK_HASH TXID INDEX
818            // https://mempool.space/api/block/<block_hash>/<txid>/<index>
819            block_txid: matches.opt_str("block_txid"),
820            block_txindex: matches.opt_str("block_txindex"),
821            // BLOCK BLOCK_HASH TXIDS
822            // https://mempool.space/api/block/<block_hash>/<txids>
823            block_txids: matches.opt_str("block_txids"),
824            // BLOCK BLOCK_HASH TXS
825            // https://mempool.space/api/block/<block_hash>/<txs>
826            block_txs: matches.opt_str("block_txs"),
827            start_index: matches.opt_str("start_index"),
828
829            // V1 BLOCKS
830            // https://mempool.space/api/v1/blocks/<BLOCK_HEIGHT>"
831            blocks: matches.opt_str("blocks"),
832
833            // V1 BLOCKS_BULK
834            // https://mempool.space/api/v1/blocks-bulk/<BLOCK_HEIGHT_START>/<BLOCK_HEIGHT_STOP>"
835            blocks_bulk: matches.opt_str("blocks_bulk"),
836            min_height: matches.opt_str("min_height"),
837            max_height: matches.opt_str("max_height"),
838
839            // MINING
840            // V1 MINING POOLS TIMEPERIOD
841            mining_pools: matches.opt_str("mining_pools"),
842            timeperiod: matches.opt_str("timeperiod"),
843
844            // V1 MINING POOL SLUG
845            mining_pool: matches.opt_str("mining_pool"),
846            slug: matches.opt_str("slug"),
847
848            // V1 MINING HASHRATE_POOLS TIMEPERIOD
849            mining_hashrate_pools: matches.opt_str("mining_hashrate_pools"),
850            // REUSE timeperiod: matches.opt_str("timeperiod"),
851            //mining_pool_hashrate
852
853            // V1 MINING POOL HASHRATE SLUG
854            mining_pool_hashrate: matches.opt_str("mining_pool_hashrate"),
855            // REUSE slug: matches.opt_str("slug"),
856
857            // V1 MINING DIFFICULTY_ADJUSTMENTS INTERVAL
858            difficulty_adjustments: matches.opt_str("difficulty_adjustments"),
859            interval: matches.opt_str("interval"),
860
861            // V1 BLOCKS_AUDIT_SCORE BLOCK_HASH
862            blocks_audit_score: matches.opt_str("blocks_audit_score"),
863            // block_hash: matches.opt_str("block_hash"),
864
865            // V1 BLOCKS_AUDIT_SCORE BLOCKHEIGHT
866            blocks_audit_scores: matches.opt_str("blocks_audit_scores"),
867            blockheight: matches.opt_str("blockheight"),
868
869            // V1 BLOCK_AUDIT_SUMMARY BLOCKHEIGHT
870            block_audit_summary: matches.opt_str("block_audit_summary"),
871            blockhash: matches.opt_str("blockhash"),
872
873            //OPTOPT
874            server: matches.opt_str("s"),
875            auth: matches.opt_str("a"),
876            url: matches.opt_str("u"),
877            remote: matches.opt_str("r"),
878            oneshot: matches.opt_present("o"),
879            expire: matches.opt_str("e"),
880            prettify: matches.opt_present("p"),
881            print_server_version: matches.opt_present("V"),
882            list_files: matches.opt_present("l"),
883            delete: matches.opt_present("d"),
884            filename: matches.opt_str("n"),
885            files: matches.free,
886        }
887    }
888}