Skip to content

Commit

Permalink
chore: improve ns-inscriber
Browse files Browse the repository at this point in the history
  • Loading branch information
zensh committed Jan 2, 2024
1 parent 41b4ec2 commit 21668ef
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 41 deletions.
3 changes: 2 additions & 1 deletion crates/ns-inscriber/sample.env
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ INSCRIBER_KEYS_DIR="./keys"
BITCOIN_NETWORK=regtest # Allowed values: main, test, signet, regtest
BITCOIN_RPC_URL=http://127.0.0.1:18443
BITCOIN_RPC_USER=test
BITCOIN_RPC_PASSWORD=123456
BITCOIN_RPC_PASSWORD=123456
BITCOIN_RPC_TOKEN=""
10 changes: 6 additions & 4 deletions crates/ns-inscriber/src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,12 +567,12 @@ async fn main() -> anyhow::Result<()> {
&ns,
fee_rate,
&keypair.secret_key(),
&vec![UnspentTxOut {
&UnspentTxOut {
txid,
vout: vout as u32,
amount: txout.value,
script_pubkey: txout.script_pubkey.clone(),
}],
},
)
.await?;

Expand Down Expand Up @@ -634,14 +634,16 @@ impl KekEncryptor {

async fn get_inscriber(network: Network) -> anyhow::Result<Inscriber> {
let rpcurl = std::env::var("BITCOIN_RPC_URL").unwrap();
let rpcuser = std::env::var("BITCOIN_RPC_USER").unwrap();
let rpcpassword = std::env::var("BITCOIN_RPC_PASSWORD").unwrap();
let rpcuser = std::env::var("BITCOIN_RPC_USER").unwrap_or_default();
let rpcpassword = std::env::var("BITCOIN_RPC_PASSWORD").unwrap_or_default();
let rpctoken = std::env::var("BITCOIN_RPC_TOKEN").unwrap_or_default();

let inscriber = Inscriber::new(&InscriberOptions {
bitcoin: BitCoinRPCOptions {
rpcurl,
rpcuser,
rpcpassword,
rpctoken,
network,
},
})?;
Expand Down
12 changes: 9 additions & 3 deletions crates/ns-inscriber/src/bitcoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub struct BitCoinRPCOptions {
pub rpcurl: String,
pub rpcuser: String,
pub rpcpassword: String,
pub rpctoken: String,
pub network: Network,
}

Expand Down Expand Up @@ -73,7 +74,10 @@ impl BitcoinRPC {
common_headers.insert(header::ACCEPT_ENCODING, "gzip".parse()?);

let url = reqwest::Url::parse(&opts.rpcurl)?;
if !opts.rpcuser.is_empty() {
if !opts.rpctoken.is_empty() {
let auth = format!("Bearer {}", opts.rpctoken);
common_headers.insert(header::AUTHORIZATION, auth.parse()?);
} else if !opts.rpcuser.is_empty() && !opts.rpcpassword.is_empty() {
let auth = format!("{}:{}", opts.rpcuser, opts.rpcpassword);
let auth = format!(
"Basic {}",
Expand Down Expand Up @@ -292,13 +296,15 @@ mod tests {
dotenvy::from_filename("sample.env").expect(".env file not found");

let rpcurl = std::env::var("BITCOIN_RPC_URL").unwrap();
let rpcuser = std::env::var("BITCOIN_RPC_USER").unwrap();
let rpcpassword = std::env::var("BITCOIN_RPC_PASSWORD").unwrap();
let rpcuser = std::env::var("BITCOIN_RPC_USER").unwrap_or_default();
let rpcpassword = std::env::var("BITCOIN_RPC_PASSWORD").unwrap_or_default();
let rpctoken = std::env::var("BITCOIN_RPC_PASSWORD").unwrap_or_default();

let cli = BitcoinRPC::new(&BitCoinRPCOptions {
rpcurl,
rpcuser,
rpcpassword,
rpctoken,
network: Network::Regtest,
})
.unwrap();
Expand Down
80 changes: 47 additions & 33 deletions crates/ns-inscriber/src/inscriber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,35 @@ impl Inscriber {
names: &Vec<Name>,
fee_rate: Amount,
secret: &SecretKey,
unspent_txouts: &Vec<UnspentTxOut>,
unspent_txout: &UnspentTxOut,
) -> anyhow::Result<Txid> {
let (signed_commit_tx, signed_reveal_tx) = self
.build_signed_inscription(names, fee_rate, secret, unspent_txout)
.await?;

let commit = self.bitcoin.send_transaction(&signed_commit_tx).await?;
let reveal = self
.bitcoin
.send_transaction(&signed_reveal_tx)
.await
.map_err(|err| {
anyhow::anyhow!("failed to send reveal transaction: {err}\ncommit tx: {commit}")
})?;

Ok(reveal)
}

pub async fn build_signed_inscription(
&self,
names: &Vec<Name>,
fee_rate: Amount,
secret: &SecretKey,
unspent_txout: &UnspentTxOut,
) -> anyhow::Result<(Transaction, Transaction)> {
let keypair = Keypair::from_secret_key(&self.secp, secret);

let (unspent_txout, unsigned_commit_tx, signed_reveal_tx) = self
.build_inscription_transactions(names, fee_rate, unspent_txouts, Some(keypair))
let (unsigned_commit_tx, signed_reveal_tx) = self
.build_inscription_transactions(names, fee_rate, unspent_txout, Some(keypair))
.await?;

let mut signed_commit_tx = unsigned_commit_tx;
Expand Down Expand Up @@ -130,16 +153,7 @@ impl Inscriber {
}
}

let commit = self.bitcoin.send_transaction(&signed_commit_tx).await?;
let reveal = self
.bitcoin
.send_transaction(&signed_reveal_tx)
.await
.map_err(|err| {
anyhow::anyhow!("failed to send reveal transaction: {err}\ncommit tx: {commit}")
})?;

Ok(reveal)
Ok((signed_commit_tx, signed_reveal_tx))
}

pub async fn send_sats(
Expand Down Expand Up @@ -263,18 +277,15 @@ impl Inscriber {
&self,
names: &Vec<Name>,
fee_rate: Amount,
unspent_txouts: &Vec<UnspentTxOut>,
unspent_txout: &UnspentTxOut,
inscription_keypair: Option<Keypair>,
) -> anyhow::Result<(UnspentTxOut, Transaction, Transaction)> {
) -> anyhow::Result<(Transaction, Transaction)> {
if names.is_empty() {
anyhow::bail!("no names to inscribe");
}
if fee_rate.to_sat() == 0 {
anyhow::bail!("fee rate cannot be zero");
}
if unspent_txouts.is_empty() {
anyhow::bail!("no unspent transaction out");
}

if let Some(name) = check_duplicate(names) {
anyhow::bail!("duplicate name {}", name);
Expand All @@ -286,21 +297,12 @@ impl Inscriber {
}
}

let (_, _, p_value) = Inscriber::preview_inscription_transactions(names, fee_rate)?;
let mut unspent_tx = &unspent_txouts[0];
// select a befitting unspent transaction out
for tx in unspent_txouts {
if tx.amount > p_value && tx.amount < unspent_tx.amount {
unspent_tx = &tx;
}
}

let keypair = inscription_keypair
.unwrap_or_else(|| Keypair::new(&self.secp, &mut rand::thread_rng()));

let (unsigned_commit_tx, signed_reveal_tx) =
self.create_inscription_transactions(names, fee_rate, unspent_tx, &keypair)?;
Ok((unspent_tx.to_owned(), unsigned_commit_tx, signed_reveal_tx))
self.create_inscription_transactions(names, fee_rate, unspent_txout, &keypair)?;
Ok((unsigned_commit_tx, signed_reveal_tx))
}

pub fn preview_inscription_transactions(
Expand Down Expand Up @@ -625,8 +627,9 @@ mod tests {
dotenvy::from_filename("sample.env").expect(".env file not found");

let rpcurl = std::env::var("BITCOIN_RPC_URL").unwrap();
let rpcuser = std::env::var("BITCOIN_RPC_USER").unwrap();
let rpcpassword = std::env::var("BITCOIN_RPC_PASSWORD").unwrap();
let rpcuser = std::env::var("BITCOIN_RPC_USER").unwrap_or_default();
let rpcpassword = std::env::var("BITCOIN_RPC_PASSWORD").unwrap_or_default();
let rpctoken = std::env::var("BITCOIN_RPC_TOKEN").unwrap_or_default();
let network = Network::from_core_arg(&std::env::var("BITCOIN_NETWORK").unwrap_or_default())
.unwrap_or(Network::Regtest);

Expand All @@ -645,6 +648,7 @@ mod tests {
rpcurl,
rpcuser,
rpcpassword,
rpctoken,
network,
},
})
Expand Down Expand Up @@ -702,7 +706,12 @@ mod tests {
let names = vec![get_name("0")];
let fee_rate = Amount::from_sat(20);
let txid = inscriber
.inscribe(&names, fee_rate, &keypair.secret_key(), &unspent_txs)
.inscribe(
&names,
fee_rate,
&keypair.secret_key(),
&unspent_txs.first().unwrap(),
)
.await
.unwrap();
println!("txid: {}", txid);
Expand Down Expand Up @@ -762,7 +771,12 @@ mod tests {
assert_eq!("z", names[35].name);

let txid = inscriber
.inscribe(&names, fee_rate, &keypair.secret_key(), &unspent_txs)
.inscribe(
&names,
fee_rate,
&keypair.secret_key(),
&unspent_txs.first().unwrap(),
)
.await
.unwrap();
println!("txid: {}", txid);
Expand Down
6 changes: 6 additions & 0 deletions crates/ns-protocol/src/ns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,12 @@ mod tests {
assert!(name.verify(&params, ThresholdLevel::Strict).is_err());
assert!(name.verify(&params, ThresholdLevel::All).is_err());

let mut invalid_name = name.clone();
invalid_name.sequence = 1;
assert!(invalid_name
.verify(&params, ThresholdLevel::Single)
.is_err());

name.sign(&params, ThresholdLevel::Default, &signers)
.unwrap();
assert!(name.validate().is_ok());
Expand Down

0 comments on commit 21668ef

Please sign in to comment.