Skip to content

Commit b4d5900

Browse files
committed
try to transfer assets to p2pk address
1 parent 88887a2 commit b4d5900

File tree

2 files changed

+195
-32
lines changed

2 files changed

+195
-32
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use anyhow::anyhow;
2+
use lwk_common::Signer;
3+
use lwk_wollet::Wollet;
4+
use lwk_wollet::asyncr::EsploraClient;
5+
use simplicity::elements::{Address, AssetId};
6+
7+
pub async fn faucet_p2pk_asset(
8+
client: &mut EsploraClient,
9+
signer: &impl Signer,
10+
wollet: &mut Wollet,
11+
recipient_address: &Address,
12+
amount: u64,
13+
asset: AssetId,
14+
) -> anyhow::Result<String> {
15+
let update = client
16+
.full_scan(wollet)
17+
.await
18+
.map_err(|e| anyhow!("Full scan failed: {}", e))?;
19+
20+
if let Some(update) = update {
21+
wollet
22+
.apply_update(update)
23+
.map_err(|e| anyhow!("Apply update failed: {}", e))?;
24+
}
25+
26+
let mut builder = wollet.tx_builder();
27+
28+
let is_confidential = recipient_address.to_string().starts_with("lq1");
29+
30+
if is_confidential {
31+
builder = builder
32+
.add_recipient(recipient_address, amount, asset)
33+
.map_err(|e| anyhow!("Failed to add recipient: {}", e))?;
34+
} else {
35+
builder = builder
36+
.add_explicit_recipient(recipient_address, amount, asset)
37+
.map_err(|e| anyhow!("Failed to add explicit recipient: {}", e))?;
38+
}
39+
40+
// Build and sign the transaction
41+
let mut unsigned_pset = builder
42+
.finish()
43+
.map_err(|e| anyhow!("Failed to build transaction: {}", e))?;
44+
45+
let signed_pset = signer
46+
.sign(&mut unsigned_pset)
47+
.map_err(|e| anyhow!("Failed to sign transaction: {e:?}"))?;
48+
49+
// Finalize and extract transaction
50+
let finalized_pset = wollet
51+
.finalize(&mut unsigned_pset)
52+
.map_err(|e| anyhow!("Failed to finalize transaction: {}", e))?;
53+
54+
// Broadcast transaction
55+
let txid = client
56+
.broadcast(&finalized_pset)
57+
.await
58+
.map_err(|e| anyhow!("Failed to broadcast transaction: {e:?}"))?;
59+
60+
Ok(format!(
61+
"Sent {} sats to address {} with transaction {}.",
62+
amount, recipient_address, txid
63+
))
64+
}

crates/lwk-utils/tests/testing_faucet.rs

Lines changed: 131 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,28 @@
11
mod faucet_contract;
2+
mod p2pk_faucet;
23
mod utils;
34

45
use crate::faucet_contract::{TxInfo, issue_asset};
6+
use crate::p2pk_faucet::faucet_p2pk_asset;
57
use crate::utils::{
68
TEST_LOGGER, TestWollet, generate_signer, get_descriptor, test_client_electrum, test_client_esplora,
79
wait_update_with_txs,
810
};
911
use elements::bitcoin::bip32::DerivationPath;
12+
use elements::hex::ToHex;
1013
use lwk_signer::SwSigner;
1114
use lwk_test_util::{TestEnvBuilder, generate_view_key, regtest_policy_asset};
1215
use lwk_wollet::asyncr::EsploraClient;
1316
use lwk_wollet::blocking::BlockchainBackend;
17+
use lwk_wollet::elements_miniscript::ToPublicKey;
1418
use lwk_wollet::{ElementsNetwork, NoPersist, Wollet, WolletBuilder, WolletDescriptor};
1519
use nostr::secp256k1::Secp256k1;
1620
use simplicity::bitcoin::secp256k1::Keypair;
21+
use simplicityhl::elements::secp256k1_zkp::PublicKey;
1722
use simplicityhl::elements::{AddressParams, TxOut};
18-
use simplicityhl_core::{LIQUID_TESTNET_BITCOIN_ASSET, LIQUID_TESTNET_GENESIS, derive_public_blinder_key};
23+
use simplicityhl_core::{
24+
LIQUID_TESTNET_BITCOIN_ASSET, LIQUID_TESTNET_GENESIS, derive_public_blinder_key, get_p2pk_address,
25+
};
1926
use std::str::FromStr;
2027

2128
const DEFAULT_MNEMONIC: &str =
@@ -89,6 +96,13 @@ fn test_issue_custom2() -> anyhow::Result<()> {
8996

9097
let address = wallet.wollet.address(Some(0))?;
9198
wallet.fund_btc(&env);
99+
100+
let public_key = keypair.x_only_public_key().0;
101+
let p2pk_address = get_p2pk_address(&public_key, &AddressParams::LIQUID_TESTNET)?;
102+
103+
let txid = env.elementsd_sendtoaddress(&p2pk_address, 1_000_011, None);
104+
println!("txid on p2pk address: {}", txid);
105+
92106
// wallet.fund(
93107
// &env,
94108
// 10_000_000,
@@ -102,35 +116,6 @@ fn test_issue_custom2() -> anyhow::Result<()> {
102116
let external_utxos = wallet.wollet.explicit_utxos()?;
103117
println!("external_utxos: {:?}", external_utxos);
104118

105-
// let mut pset = issue_asset(
106-
// &keypair,
107-
// derive_public_blinder_key().public_key(),
108-
// utxos[0].outpoint,
109-
// 123456,
110-
// 500,
111-
// &AddressParams::LIQUID_TESTNET,
112-
// LIQUID_TESTNET_BITCOIN_ASSET,
113-
// *LIQUID_TESTNET_GENESIS,
114-
// )
115-
// .await?;
116-
117-
// let mut pset = tokio::runtime::Runtime::new()?.block_on(async {
118-
// issue_asset(
119-
// &keypair,
120-
// derive_public_blinder_key().public_key(),
121-
// utxos[0].outpoint,
122-
// 123456,
123-
// 500,
124-
// &AddressParams::LIQUID_TESTNET,
125-
// LIQUID_TESTNET_BITCOIN_ASSET,
126-
// *LIQUID_TESTNET_GENESIS,
127-
// )
128-
// .await
129-
// })?;
130-
131-
// let tx_to_send = wallet.wollet.finalize(&mut pset)?;
132-
// wallet.client.broadcast(&tx_to_send)?;
133-
134119
wallet.sync();
135120

136121
let utxos = wallet.wollet.utxos()?;
@@ -139,6 +124,120 @@ fn test_issue_custom2() -> anyhow::Result<()> {
139124
Ok(())
140125
}
141126

127+
#[tokio::test]
128+
async fn test_issue_custom2_p2pk() -> anyhow::Result<()> {
129+
let _ = dotenvy::dotenv().ok();
130+
let _guard = &*TEST_LOGGER;
131+
132+
let secp = Secp256k1::new();
133+
let env = TestEnvBuilder::from_env().with_esplora().build();
134+
let mut client = test_client_esplora(&env.esplora_url());
135+
136+
let signer = generate_signer();
137+
let view_key = generate_view_key();
138+
let regtest_bitcoin_asset = regtest_policy_asset();
139+
140+
let descriptor = format!("ct({},elwpkh({}/*))", view_key, signer.xpub());
141+
let network = ElementsNetwork::default_regtest();
142+
let descriptor: WolletDescriptor = descriptor.parse()?;
143+
let mut wollet = WolletBuilder::new(network, descriptor).build()?;
144+
let signer_keypair = Keypair::from_secret_key(&secp, &signer.derive_xprv(&DerivationPath::master())?.private_key);
145+
146+
let update = client.full_scan(&wollet).await?;
147+
if let Some(update) = update {
148+
wollet.apply_update(update)?;
149+
}
150+
151+
println!("Utxos1: {:?}", wollet.utxos()?);
152+
153+
let address = wollet.address(None)?;
154+
let txid = env.elementsd_sendtoaddress(address.address(), 2_000_011, None);
155+
println!("txid sendtoaddress: {}", txid);
156+
157+
env.elementsd_generate(10);
158+
let update = wait_update_with_txs(&mut client, &wollet).await;
159+
wollet.apply_update(update)?;
160+
println!("Utxos2: {:?}", wollet.utxos()?);
161+
162+
let public_key = signer_keypair.x_only_public_key().0;
163+
let p2pk_address = get_p2pk_address(&public_key, &AddressParams::ELEMENTS)?;
164+
165+
env.elementsd_generate(10);
166+
let update = client.full_scan(&wollet).await?;
167+
if let Some(update) = update {
168+
wollet.apply_update(update)?;
169+
}
170+
171+
println!("Utxos3: {:?}", wollet.utxos()?);
172+
173+
let msg = faucet_p2pk_asset(
174+
&mut client,
175+
&signer,
176+
&mut wollet,
177+
&p2pk_address,
178+
1_000_000,
179+
regtest_policy_asset(),
180+
)
181+
.await?;
182+
println!("txid on p2pk address: '{msg}'");
183+
println!("Utxos4: {:?}", wollet.utxos()?);
184+
185+
let utxos = wollet.utxos()?;
186+
println!("Utxos5: {:?}", utxos);
187+
let asset_owned = wollet.assets_owned()?;
188+
println!("asset_owned: {:?}", asset_owned);
189+
let external_utxos = wollet.explicit_utxos()?;
190+
println!("external_utxos: {:?}", external_utxos);
191+
192+
let update = client.full_scan(&wollet).await?;
193+
if let Some(update) = update {
194+
wollet.apply_update(update)?;
195+
}
196+
197+
let utxos = wollet.utxos()?;
198+
tracing::info!("Utxos after: {:?}", utxos);
199+
200+
// retrieve utxos from pt2tr wallet
201+
202+
let blinding_key = derive_public_blinder_key();
203+
let view_key = blinding_key.secret_bytes().to_hex();
204+
// let pk = signer_keypair.public_key().to_hex();
205+
let pk = "020202020202020202020202020202020202020202020202020202020202020202";
206+
let pubkey = PublicKey::from_str(pk).unwrap().to_x_only_pubkey();
207+
let p2pk_address = simplicityhl_core::get_p2pk_address(&pubkey, &AddressParams::ELEMENTS)?;
208+
println!("pk for p2pk_address: {}, p2pk addr: {}", pk, p2pk_address);
209+
210+
let desc = format!("ct({view_key},elwpkh({pk}))");
211+
println!("desc: {}", desc);
212+
213+
let descriptor: WolletDescriptor = desc.parse()?;
214+
let mut p2pk_wollet = WolletBuilder::new(network, descriptor).build()?;
215+
216+
let update = client.full_scan(&p2pk_wollet).await?;
217+
if let Some(update) = update {
218+
p2pk_wollet.apply_update(update)?;
219+
}
220+
221+
println!("Utxos p2pk1: {:?}", p2pk_wollet.utxos()?);
222+
223+
//
224+
// w.fund_btc(&env);
225+
// let balance = w.balance_btc();
226+
// assert!(balance > 0);
227+
// let utxos = w.wollet.utxos().unwrap();
228+
// assert_eq!(utxos.len(), 1);
229+
//
230+
// // Receive unconfidential / explicit
231+
// let satoshi = 5_000;
232+
// w.fund_explicit(&env, satoshi, None, None);
233+
// assert_eq!(w.balance_btc(), balance);
234+
//
235+
// let explicit_utxos = w.wollet.explicit_utxos().unwrap();
236+
// assert_eq!(explicit_utxos.len(), 1);
237+
238+
Ok(())
239+
}
240+
142241
#[tokio::test]
143242
async fn async_test_issue_custom2() -> anyhow::Result<()> {
144243
let _ = dotenvy::dotenv().ok();
@@ -159,7 +258,7 @@ async fn async_test_issue_custom2() -> anyhow::Result<()> {
159258
let keypair = Keypair::from_secret_key(&secp, &signer.derive_xprv(&DerivationPath::master())?.private_key);
160259

161260
let update = client.full_scan(&wollet).await?.unwrap();
162-
wollet.apply_update(update).unwrap();
261+
wollet.apply_update(update)?;
163262

164263
let address = wollet.address(None)?;
165264
let txid = env.elementsd_sendtoaddress(address.address(), 1_000_011, None);
@@ -197,7 +296,7 @@ async fn async_test_issue_custom2() -> anyhow::Result<()> {
197296
TxInfo { outpoint, wallet_tx },
198297
123456,
199298
500,
200-
&AddressParams::LIQUID_TESTNET,
299+
&AddressParams::ELEMENTS,
201300
regtest_bitcoin_asset,
202301
*LIQUID_TESTNET_GENESIS,
203302
)

0 commit comments

Comments
 (0)