Bitcoin address: bc1q89f6ad3wdq2nq4pdq23systlvcg3s79qujnr9w

SHOWING: First 60

mint210,000.plxx#48,991,756brc-20mint210,000.plxx#48,991,755brc-20mint210,000.plxx#48,991,716brc-20mint210,000.plxx#48,991,683brc-20mint210,000.plxx#48,991,649brc-20mint210,000.plxx#48,991,646brc-20mint210,000.plxx#48,991,623brc-20mint210,000.plxx#48,991,601brc-20mint210,000.plxx#48,991,595brc-20mint210,000.plxx#48,991,570brc-20 fn clock_updates() { let test_server = TestServer::new(); test_server.assert_response_regex("/clock", StatusCode::OK, ".*<text.*>0</text>.*"); test_server.mine_blocks(1); test_server.assert_response_regex("/clock", StatusCode::OK, ".*<text.*>1</text>.*"); } #[test] fn block_by_hash() { let test_server = TestServer::new(); test_server.mine_blocks(1); let transaction = TransactionTemplate { inputs: &[(1, 0, 0, Default::default())], fee: 0, ..Default::default() }; test_server.bitcoin_rpc_server.broadcast_tx(transaction); let block_hash = test_server.mine_blocks(1)[0].block_hash(); test_server.assert_response_regex( format!("/block/{block_hash}"), StatusCode::OK, ".*<h1>Block 2</h1>.*", ); } #[test] fn block_by_height() { let test_server = TestServer::new(); test_server.assert_response_regex("/block/0", StatusCode::OK, ".*<h1>Block 0</h1>.*"); } #[test] fn transaction() { let test_server = TestServer::new(); #44,987,773text options, )?))) .directory(if cfg!(test) { LETS_ENCRYPT_STAGING_DIRECTORY } else { LETS_ENCRYPT_PRODUCTION_DIRECTORY }); let mut state = config.state(); let acceptor = state.axum_acceptor(Arc::new( rustls::ServerConfig::builder() .with_safe_defaults() .with_no_client_auth() .with_cert_resolver(state.resolver()), )); tokio::spawn(async move { while let Some(result) = state.next().await { match result { Ok(ok) => log::info!("ACME event: {:?}", ok), Err(err) => log::error!("ACME error: {:?}", err), } } }); Ok(acceptor) } fn index_height(index: &Index) -> ServerResult<Height> { index.block_height()?.ok_or_not_found(|| "genesis block") } async fn clock(Extension(index): Extension<Arc<Index>>) -> ServerResult<Response> { Ok( ( [( header::CONTENT_SECURITY_POLICY, HeaderValue::from_static("default-src 'unsafe-inline'"), #44,987,743text "baz", ]) .unwrap_err() .to_string(), ".*--cbor-metadata.*cannot be used with.*--json-metadata.*" ); } #[test] fn batch_is_loaded_from_yaml_file() { let parent = "8d363b28528b0cb86b5fd48615493fb175bdf132d2a3d20b4251bba3f130a5abi0" .parse::<InscriptionId>() .unwrap(); let tempdir = TempDir::new().unwrap(); let inscription_path = tempdir.path().join("tulip.txt"); fs::write(&inscription_path, "tulips are pretty").unwrap(); let brc20_path = tempdir.path().join("token.json"); let batch_path = tempdir.path().join("batch.yaml"); fs::write( &batch_path, format!( "mode: separate-outputs parent: {parent} inscriptions: - file: {} metadata: title: Lorem Ipsum description: Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tristique, massa nec condimentum venenatis, ante massa tempor velit, et accumsan ipsum ligula a massa. Nunc quis orci ante. - file: {} metaprotocol: brc-20 ", inscription_path.display(), #44,987,732text let acme_cache = if let Some(acme_cache) = acme_cache { acme_cache.clone() } else { options.data_dir()?.join("acme-cache") }; Ok(acme_cache) } fn acme_domains(&self) -> Result<Vec<String>> { if !self.acme_domain.is_empty() { Ok(self.acme_domain.clone()) } else { Ok(vec![System::new() .host_name() .ok_or(anyhow!("no hostname found"))?]) } } fn http_port(&self) -> Option<u16> { if self.http || self.http_port.is_some() || (self.https_port.is_none() && !self.https) { Some(self.http_port.unwrap_or(80)) } else { None } } fn https_port(&self) -> Option<u16> { if self.https || self.https_port.is_some() { Some(self.https_port.unwrap_or(443)) } else { None } } fn acceptor(&self, options: &Options) -> Result<AxumAcceptor> { let config = AcmeConfig::new(self.acme_domains()?) .contact(&self.acme_contact) .cache_option(Some(DirCache::new(Self::acme_cache( self.acme_cache.as_ref(),#44,987,722text .route( "/r/sat/:sat_number/:page", get(Self::sat_inscriptions_paginated), ) .route( "/r/sat/:sat_number/at/:index", get(Self::sat_inscription_at_index), ) .route("/range/:start/:end", get(Self::range)) .route("/rare.txt", get(Self::rare_txt)) .route("/rune/:rune", get(Self::rune)) .route("/runes", get(Self::runes)) .route("/sat/:sat", get(Self::sat)) .route("/search", get(Self::search_by_query)) .route("/search/*query", get(Self::search_by_path)) .route("/static/*path", get(Self::static_asset)) .route("/status", get(Self::status)) .route("/tx/:txid", get(Self::transaction)) .layer(Extension(index)) .layer(Extension(page_config)) .layer(Extension(Arc::new(config))) .layer(SetResponseHeaderLayer::if_not_present( header::CONTENT_SECURITY_POLICY, HeaderValue::from_static("default-src 'self'"), )) .layer(SetResponseHeaderLayer::overriding( #44,987,707text )], ClockSvg::new(Self::index_height(&index)?), ) .into_response(), ) } async fn sat( Extension(page_config): Extension<Arc<PageConfig>>, Extension(index): Extension<Arc<Index>>, Path(DeserializeFromStr(sat)): Path<DeserializeFromStr<Sat>>, accept_json: AcceptJson, ) -> ServerResult<Response> { let inscriptions = index.get_inscription_ids_by_sat(sat)?; let satpoint = index.rare_sat_satpoint(sat)?.or_else(|| { inscriptions.first().and_then(|&first_inscription_id| { index .get_inscription_satpoint_by_id(first_inscription_id) .ok() .flatten() }) }); let blocktime = index.block_time(sat.height())?; Ok(if accept_json.0 { Json(SatJson { number: sat.0, decimal: sat.decimal().to_string(), degree: sat.degree().to_string(), name: sat.name(), block: sat.height().0, cycle: sat.cycle(), epoch: sat.epoch().0, period: sat.period(), #44,987,704text test_server.mine_blocks(21); test_server.assert_response("/status", StatusCode::OK, "OK"); for _ in 0..15 { test_server.bitcoin_rpc_server.invalidate_tip(); } test_server.bitcoin_rpc_server.mine_blocks(21); test_server.assert_response_regex("/status", StatusCode::OK, "unrecoverable reorg detected.*"); } #[test] fn rare_with_sat_index() { TestServer::new_with_sat_index().assert_response( "/rare.txt", StatusCode::OK, "sat\tsatpoint 0\t4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0:0 ", ); } #[test] fn rare_without_sat_index() { TestServer::new().assert_response( "/rare.txt", StatusCode::OK, "sat\tsatpoint ", ); } #[test] fn show_rare_txt_in_header_with_sat_index() { TestServer::new_with_sat_index().assert_response_regex( "/", StatusCode::OK, ".* <a href=/clock title=clock>.*</a> <a href=/rare.txt title=rare>.*</a>.*", ); } #[test] fn rare_sat_location() { #44,987,675text offset: sat.third(), rarity: sat.rarity(), percentile: sat.percentile(), satpoint, timestamp: blocktime.timestamp().timestamp(), inscriptions, }) .into_response() } else { SatHtml { sat, satpoint, blocktime, inscriptions, } .page(page_config) .into_response() }) } async fn ordinal(Path(sat): Path<String>) -> Redirect { Redirect::to(&format!("/sat/{sat}")) } async fn output( Extension(page_config): Extension<Arc<PageConfig>>, Extension(index): Extension<Arc<Index>>, Path(outpoint): Path<OutPoint>, accept_json: AcceptJson, ) -> ServerResult<Response> { let list = index.list(outpoint)?; let output = if outpoint == OutPoint::null() || outpoint == unbound_outpoint() { let mut value = 0; if let Some(List::Unspent(ranges)) = &list { for (start, end) in ranges { value += end - start; } } TxOut { value, #44,987,673text script_pubkey: ScriptBuf::new(), } } else { index .get_transaction(outpoint.txid)? .ok_or_not_found(|| format!("output {outpoint}"))? .output .into_iter() .nth(outpoint.vout as usize) .ok_or_not_found(|| format!("output {outpoint}"))? }; let inscriptions = index.get_inscriptions_on_output(outpoint)?; let runes = index.get_rune_balances_for_outpoint(outpoint)?; Ok(if accept_json.0 { Json(OutputJson::new( outpoint, list, page_config.chain, output, inscriptions, runes .into_iter() .map(|(rune, pile)| (rune, pile.amount)) .collect(), )) .into_response() } else { OutputHtml { outpoint, inscriptions, list, chain: page_config.chain, output, runes, } .page(page_config) .into_response() }) } async fn range( Extension(page_config): Extension<Arc<PageConfig>>, #44,987,672textuse {super::*, crate::wallet::Wallet, std::collections::BTreeSet}; #[derive(Serialize, Deserialize)] pub struct CardinalUtxo { pub output: OutPoint, pub amount: u64, } pub(crate) fn run(options: Options) -> SubcommandResult { let index = Index::open(&options)?; index.update()?; let unspent_outputs = index.get_unspent_outputs(Wallet::load(&options)?)?; let inscribed_utxos = index .get_inscriptions(&unspent_outputs)? .keys() .map(|satpoint| satpoint.outpoint) .collect::<BTreeSet<OutPoint>>(); let cardinal_utxos = unspent_outputs .iter() .filter_map(|(output, amount)| { if inscribed_utxos.contains(output) { None } else { Some(CardinalUtxo { output: *output, amount: amount.to_sat(), }) } }) .collect::<Vec<CardinalUtxo>>(); Ok(Box::new(cardinal_utxos)) } #44,987,665text brc20_path.display() ), ) .unwrap(); let mut metadata = Mapping::new(); metadata.insert( Value::String("title".to_string()), Value::String("Lorem Ipsum".to_string()), ); metadata.insert(Value::String("description".to_string()), Value::String("Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tristique, massa nec condimentum venenatis, ante massa tempor velit, et accumsan ipsum ligula a massa. Nunc quis orci ante.".to_string())); assert_eq!( Batchfile::load(&batch_path).unwrap(), Batchfile { inscriptions: vec![ BatchEntry { file: inscription_path, metadata: Some(Value::Mapping(metadata)), ..Default::default() }, BatchEntry { file: brc20_path, metaprotocol: Some("brc-20".to_string()), ..Default::default() } ], parent: Some(parent), ..Default::default() } ); } #[test] fn batch_with_unknown_field_throws_error() { #44,987,664textdmt-mint.nat#44,764,490tapdmt-mint.nat#44,764,460tapdmt-mint.nat#44,764,458tapdmt-mint.nat#44,764,429tapdmt-mint.nat#44,764,418tapdmt-mint.nat#44,764,417tapdmt-mint.nat#44,764,394tapdmt-mint.nat#44,764,388tapdmt-mint.nat#44,764,326tapdmt-mint.nat#44,764,231tapInscription #43880762#43,880,762pngInscription #43880757#43,880,757pngInscription #43880356#43,880,356pngdmt-mint.nat#43,569,931tapdmt-mint.nat#43,569,930tapdmt-mint.nat#43,569,929tapdmt-mint.nat#43,569,928tapdmt-mint.nat#43,569,927tapdmt-mint.nat#43,569,926tapInscription #42587882#42,587,882pngdmt-mint.nat#42,498,208tapdmt-mint.nat#42,494,997tapdmt-mint.nat#42,492,095tapInscription #42463012#42,463,012pngInscription #42461961#42,461,961pngmint10.bear#39,619,038brc-20mint10.bear#39,614,957brc-20mint10.bear#39,614,955brc-20mint10.bear#39,614,954brc-20mint10.bear#39,614,950brc-20mint10.bear#39,614,948brc-20mint10.bear#39,614,946brc-20mint10.bear#39,614,943brc-20mint10.bear#39,614,939brc-20mint10.bear#39,614,926brc-20mint10.bear#39,614,918brc-20mint10.bear#39,614,916brc-20mint10.bear#39,614,914brc-20mint10.bear#39,614,911brc-20