SHOWING: First 60
.push_slice(b"RUNE_TEST");
for chunk in payload.chunks(bitcoin::blockdata::constants::MAX_SCRIPT_ELEMENT_SIZE) {
let push: &bitcoin::script::PushBytes = chunk.try_into().unwrap();
builder = builder.push_slice(push);
}
builder.into_script()
}
fn payload(transaction: &Transaction) -> Result<Option<Vec<u8>>> {
for output in &transaction.output {
let mut instructions = output.script_pubkey.instructions();
if instructions.next().transpose()? != Some(Instruction::Op(opcodes::all::OP_RETURN)) {
continue;
}
if instructions.next().transpose()? != Some(Instruction::PushBytes(b"RUNE_TEST".into())) {
continue;
}
let mut payload = Vec::new();
for result in instructions {
if let Instruction::PushBytes(push) = result? {
payload.extend_from_slice(push.as_bytes());
}
}
return Ok(Some(payload));
}
Ok(None)
}
}
#[cfg(test)]
mod tests {
use {
super::*,
bitcoin::{locktime, script::PushBytes, ScriptBuf, TxOut},
#44,986,382text inputs: &[(2, 1, 0, Witness::new())],
outputs: 4,
op_return: Some(
Runestone {
edicts: vec![
Edict {
id: id.into(),
amount: u128::max_value() - 2000,
output: 0,
},
Edict {
id: id.into(),
amount: 1000,
output: 5,
},
],
..Default::default()
}
.encipher(),
),
..Default::default()
});
context.mine_blocks(1);
context.assert_runes(
[(
id,
RuneEntry {
etching: txid0,
rune: Rune(RUNE),
supply: u128::max_value(),
timestamp: 2,
..Default::default()
},
)],
[
(
OutPoint {
txid: txid1,
vout: 0,
},
vec![(id, u128::max_value() - 2000 + 1000)],
),
(
OutPoint {
txid: txid1,
vout: 1,
},
vec![(id, 1000)],
#44,985,051text Ok(if s.len() == 64 {
BlockQuery::Hash(s.parse()?)
} else {
BlockQuery::Height(s.parse()?)
})
}
}
enum SpawnConfig {
Https(AxumAcceptor),
Http,
Redirect(String),
}
#[derive(Deserialize)]
struct Search {
query: String,
}
#[derive(RustEmbed)]
#[folder = "static"]
struct StaticAssets;
struct StaticHtml {
title: &'static str,
html: &'static str,
}
impl PageContent for StaticHtml {
fn title(&self) -> String {
self.title.into()
}
}
impl Display for StaticHtml {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.write_str(self.html)
}
}
#[derive(Debug, Parser)]
pub(crate) struct Server {
#[arg(
long,
default_value = "0.0.0.0",
help = "Listen on <ADDRESS> for incoming requests."
)]
address: String,
#[arg(
long,
help = "Request ACME TLS certificate for <ACME_DOMAIN>. This ord instance must be reachable at <ACME_DOMAIN>:443 to respond to Let's Encrypt ACME challenges."
)]
acme_domain: Vec<String>,
#[arg(
long,
help = "Use <CSP_ORIGIN> in Content-Security-Policy header. Set this to the public-facing URL of your ord instance."
#44,982,394text satpoint(2, 0),
BTreeMap::new(),
vec![(outpoint(1), Amount::from_sat(4))]
.into_iter()
.collect(),
BTreeSet::new(),
recipient(),
[change(0), change(1)],
FeeRate::try_from(1.0).unwrap(),
Target::Postage,
)
.build()
.unwrap();
}
#[test]
#[should_panic(expected = "invariant: outgoing sat is contained in utxos")]
fn invariant_satpoint_offset_is_contained_in_utxos() {
TransactionBuilder::new(
satpoint(1, 4),
BTreeMap::new(),
vec![(outpoint(1), Amount::from_sat(4))]
.into_iter()
.collect(),
BTreeSet::new(),
recipient(),
[change(0), change(1)],
FeeRate::try_from(1.0).unwrap(),
Target::Postage,
)
.build()
.unwrap();
}
#[test]
#[should_panic(expected = "invariant: inputs spend outgoing sat")]
fn invariant_inputs_spend_sat() {
TransactionBuilder::new(
satpoint(1, 2),
BTreeMap::new(),
vec![(outpoint(1), Amount::from_sat(5))]
.into_iter()
#44,982,284textuse super::*;
#[derive(Serialize, Deserialize)]
pub struct Output {
pub mnemonic: Mnemonic,
pub passphrase: Option<String>,
}
#[derive(Debug, Parser)]
pub(crate) struct Create {
#[arg(
long,
default_value = "",
help = "Use <PASSPHRASE> to derive wallet seed."
)]
pub(crate) passphrase: String,
}
impl Create {
pub(crate) fn run(self, options: Options) -> SubcommandResult {
let mut entropy = [0; 16];
rand::thread_rng().fill_bytes(&mut entropy);
let mnemonic = Mnemonic::from_entropy(&entropy)?;
initialize_wallet(&options, mnemonic.to_seed(self.passphrase.clone()))?;
Ok(Box::new(Output {
mnemonic,
passphrase: Some(self.passphrase),
}))
}
}
#44,982,131text ),
Error::ValueOverflow => write!(f, "arithmetic overflow calculating value"),
Error::DuplicateAddress(address) => write!(f, "duplicate input address: {address}"),
}
}
}
impl std::error::Error for Error {}
#[derive(Debug, PartialEq)]
pub struct TransactionBuilder {
amounts: BTreeMap<OutPoint, Amount>,
change_addresses: BTreeSet<Address>,
fee_rate: FeeRate,
inputs: Vec<OutPoint>,
inscriptions: BTreeMap<SatPoint, InscriptionId>,
outgoing: SatPoint,
outputs: Vec<(Address, Amount)>,
recipient: Address,
unused_change_addresses: Vec<Address>,
utxos: BTreeSet<OutPoint>,
locked_utxos: BTreeSet<OutPoint>,
target: Target,
}
type Result<T> = std::result::Result<T, Error>;
impl TransactionBuilder {
const ADDITIONAL_INPUT_VBYTES: usize = 58;
const ADDITIONAL_OUTPUT_VBYTES: usize = 43;
const SCHNORR_SIGNATURE_SIZE: usize = 64;
pub(crate) const TARGET_POSTAGE: Amount = Amount::from_sat(10_000);
pub(crate) const MAX_POSTAGE: Amount = Amount::from_sat(2 * 10_000);
#44,982,073text