SHOWING: First 60
..Default::default()
});
context.mine_blocks(1);
let inscription_id = InscriptionId { txid, index: 0 };
context.index.assert_inscription_location(
inscription_id,
SatPoint {
outpoint: OutPoint { txid, vout: 0 },
offset: 0,
},
Some(50 * COIN_VALUE),
);
}
}
#[test]
fn inscription_with_pointer_into_fee_ignored_and_assigned_default_location() {
for context in Context::configurations() {
context.mine_blocks(1);
let inscription = Inscription {
content_type: Some("text/plain".into()),
body: Some("hello".into()),
pointer: Some((25 * COIN_VALUE).to_le_bytes().to_vec()),
..Default::default()
};
let txid = context.rpc_server.broadcast_tx(TransactionTemplate {
inputs: &[(1, 0, 0, inscription.to_witness())],
fee: 25 * COIN_VALUE,
..Default::default()
});
context.mine_blocks(1);
let inscription_id = InscriptionId { txid, index: 0 };#45,024,080text script_sig: ScriptBuf::new(),
sequence: Sequence::MAX,
witness: witness.clone(),
});
}
let value_per_output = (total_value - template.fee) / template.outputs as u64;
assert_eq!(
value_per_output * template.outputs as u64 + template.fee,
total_value
);
let mut tx = Transaction {
version: 0,
lock_time: LockTime::ZERO,
input,
output: (0..template.outputs)
.map(|i| TxOut {
value: template
.output_values
.get(i)
.cloned()
.unwrap_or(value_per_output),
script_pubkey: script::Builder::new().into_script(),
})
.collect(),
};
if let Some(script_pubkey) = template.op_return {
tx.output.insert(
template.op_return_index.unwrap_or(tx.output.len()),
TxOut {
value: 0,
script_pubkey,
},
);
}
self.mempool.push(tx.clone());
tx.txid()
}
pub(crate) fn mempool(&self) -> &[Transaction] {#45,024,079text 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(),#45,024,042textuse {super::*, crate::wallet::Wallet};
#[derive(Debug, Parser)]
pub(crate) struct Sats {
#[arg(
long,
help = "Find satoshis listed in first column of tab-separated value file <TSV>."
)]
tsv: Option<PathBuf>,
}
#[derive(Serialize, Deserialize)]
pub struct OutputTsv {
pub sat: String,
pub output: OutPoint,
}
#[derive(Serialize, Deserialize)]
pub struct OutputRare {
pub sat: Sat,
pub output: OutPoint,
pub offset: u64,
pub rarity: Rarity,
}
impl Sats {
pub(crate) fn run(&self, options: Options) -> SubcommandResult {
let index = Index::open(&options)?;
if !index.has_sat_index() {
bail!("sats requires index created with `--index-sats` flag");
}
index.update()?;
let utxos = index.get_unspent_output_ranges(Wallet::load(&options)?)?;
if let Some(path) = &self.tsv {
let mut output = Vec::new();
for (outpoint, sat) in sats_from_tsv(
utxos,
&fs::read_to_string(path)
.with_context(|| format!("I/O error reading `{}`", path.display()))?,#45,024,031text
server.assert_response_regex(
format!("/preview/{inscription_id}"),
StatusCode::OK,
format!(r".*<audio .*>\s*<source src=/content/{inscription_id}>.*"),
);
}
#[test]
fn font_preview() {
let server = TestServer::new_with_regtest();
server.mine_blocks(1);
let txid = server.bitcoin_rpc_server.broadcast_tx(TransactionTemplate {
inputs: &[(1, 0, 0, inscription("font/ttf", "hello").to_witness())],
..Default::default()
});
let inscription_id = InscriptionId { txid, index: 0 };
server.mine_blocks(1);
server.assert_response_regex(
format!("/preview/{inscription_id}"),
StatusCode::OK,
format!(r".*src: url\(/content/{inscription_id}\).*"),
);
}
#[test]
fn pdf_preview() {
let server = TestServer::new_with_regtest();
server.mine_blocks(1);
let txid = server.bitcoin_rpc_server.broadcast_tx(TransactionTemplate {
inputs: &[(
1,
0,
0,
inscription("application/pdf", "hello").to_witness(),#45,023,991text let string = $string;
if !regex.is_match(string.as_ref()) {
panic!(
"Regex:\n\n{}\n\n…did not match string:\n\n{}",
regex, string
);
}
};
}
type Inscribe = ord::subcommand::wallet::inscribe::Output;
fn inscribe(rpc_server: &test_bitcoincore_rpc::Handle) -> (InscriptionId, Txid) {
rpc_server.mine_blocks(1);
let output = CommandBuilder::new("wallet inscribe --fee-rate 1 --file foo.txt")
.write("foo.txt", "FOO")
.rpc_server(rpc_server)
.run_and_deserialize_output::<Inscribe>();
rpc_server.mine_blocks(1);
assert_eq!(output.inscriptions.len(), 1);
(output.inscriptions[0].id, output.reveal)
}
fn envelope(payload: &[&[u8]]) -> bitcoin::Witness {
let mut builder = bitcoin::script::Builder::new()
.push_opcode(bitcoin::opcodes::OP_FALSE)
.push_opcode(bitcoin::opcodes::all::OP_IF);
for data in payload {
let mut buf = bitcoin::script::PushBytesBuf::new();
buf.extend_from_slice(data).unwrap();
builder = builder.push_slice(buf);
#45,023,974text ..Default::default()
});
context.mine_blocks(1);
let id = RuneId {
height: 2,
index: 1,
};
context.assert_runes(
[(
id,
RuneEntry {
etching: txid0,
rune: Rune(RUNE),
supply: u128::max_value(),
timestamp: 2,
..Default::default()
},
)],
[(
OutPoint {
txid: txid0,
vout: 0,
},
vec![(id, u128::max_value())],
)],
);
let txid1 = context.rpc_server.broadcast_tx(TransactionTemplate {
inputs: &[(2, 1, 0, Witness::new())],
outputs: 2,
op_return: Some(
Runestone {
edicts: vec![
Edict {
id: id.into(),
amount: 1000,
output: 0,
},
Edict {
id: id.into(),
amount: 0,
output: 3,
},
],
..Default::default()
}
.encipher(),
),
..Default::default()#45,023,973textdmt-mint.nat#44,718,412tapdmt-mint.nat#44,718,279tapdmt-mint.nat#44,718,270tapdmt-mint.nat#44,718,253tapdmt-mint.nat#44,718,252tapdmt-mint.nat#44,718,214tapdmt-mint.nat#44,718,198tapdmt-mint.nat#44,718,145tapdmt-mint.nat#44,718,092tapdmt-mint.nat#44,718,080tapdmt-mint.nat#44,713,362tapdmt-mint.nat#44,713,254tapdmt-mint.nat#44,713,231tapdmt-mint.nat#44,713,032tapdmt-mint.nat#44,713,001tapdmt-mint.nat#44,712,926tapdmt-mint.nat#44,712,901tapdmt-mint.nat#44,712,883tapdmt-mint.nat#44,712,757tapdmt-mint.nat#44,712,738tapdmt-mint.nat#42,529,782tapdmt-mint.nat#42,529,727tapdmt-mint.nat#42,529,404tapdmt-mint.nat#42,529,274tapdmt-mint.nat#42,529,028tapdmt-mint.nat#42,528,823tapdmt-mint.nat#42,528,763tapdmt-mint.nat#42,528,675tapdmt-mint.nat#42,528,579tapdmt-mint.nat#42,524,788tapdmt-mint.nat#42,524,765tapdmt-mint.nat#42,524,753tapdmt-mint.nat#42,524,736tapdmt-mint.nat#42,524,726tapdmt-mint.nat#42,524,709tapdmt-mint.nat#42,524,703tapdmt-mint.nat#42,524,701tapdmt-mint.nat#42,522,335tapdmt-mint.nat#42,522,313tapdmt-mint.nat#42,522,277tapdmt-mint.nat#42,522,273tapdmt-mint.nat#42,522,271tapdmt-mint.nat#42,521,204tapdmt-mint.nat#42,521,194tapdmt-mint.nat#42,520,041tapdmt-mint.nat#42,520,040tapdmt-mint.nat#42,520,039tapdmt-mint.nat#42,512,467tapdmt-mint.nat#42,512,456tapdmt-mint.nat#42,512,446tapdmt-mint.nat#42,512,437tapdmt-mint.nat#42,512,415tapdmt-mint.nat#42,511,710tap