ant_core/data/client/
payment.rs1use crate::data::client::Client;
7use crate::data::error::{Error, Result};
8use ant_protocol::evm::{EncodedPeerId, ProofOfPayment, Wallet};
9use ant_protocol::payment::{serialize_single_node_proof, PaymentProof, SingleNodePayment};
10use ant_protocol::transport::{MultiAddr, PeerId};
11use std::sync::Arc;
12use tracing::{debug, info};
13
14impl Client {
15 pub(crate) fn require_wallet(&self) -> Result<&Arc<Wallet>> {
17 self.wallet().ok_or_else(|| {
18 Error::Payment("Wallet not configured — call with_wallet() first".to_string())
19 })
20 }
21
22 pub async fn pay_for_storage(
38 &self,
39 address: &[u8; 32],
40 data_size: u64,
41 data_type: u32,
42 ) -> Result<(Vec<u8>, Vec<(PeerId, Vec<MultiAddr>)>)> {
43 let wallet = self.require_wallet()?;
46
47 debug!("Collecting quotes for address {}", hex::encode(address));
48
49 let quotes_with_peers = self.get_store_quotes(address, data_size, data_type).await?;
51
52 let quoted_peers: Vec<(PeerId, Vec<MultiAddr>)> = quotes_with_peers
54 .iter()
55 .map(|(peer_id, addrs, _, _)| (*peer_id, addrs.clone()))
56 .collect();
57
58 let mut peer_quotes = Vec::with_capacity(quotes_with_peers.len());
61 let mut quotes_for_payment = Vec::with_capacity(quotes_with_peers.len());
62
63 for (peer_id, _addrs, quote, price) in quotes_with_peers {
64 let encoded = peer_id_to_encoded(&peer_id)?;
65 peer_quotes.push((encoded, quote.clone()));
66 quotes_for_payment.push((quote, price));
67 }
68
69 let payment = SingleNodePayment::from_quotes(quotes_for_payment)
71 .map_err(|e| Error::Payment(format!("Failed to create payment: {e}")))?;
72
73 info!("Payment total: {} atto", payment.total_amount());
74
75 let tx_hashes = payment
77 .pay(wallet)
78 .await
79 .map_err(|e| Error::Payment(format!("On-chain payment failed: {e}")))?;
80
81 info!(
82 "On-chain payment succeeded: {} transactions",
83 tx_hashes.len()
84 );
85
86 let proof = PaymentProof {
88 proof_of_payment: ProofOfPayment { peer_quotes },
89 tx_hashes,
90 };
91
92 let proof_bytes = serialize_single_node_proof(&proof)
93 .map_err(|e| Error::Serialization(format!("Failed to serialize payment proof: {e}")))?;
94
95 Ok((proof_bytes, quoted_peers))
96 }
97
98 pub async fn approve_token_spend(&self) -> Result<()> {
107 let wallet = self.require_wallet()?;
108 let evm_network = self.require_evm_network()?;
109
110 let vault_address = evm_network.payment_vault_address();
111 wallet
112 .approve_to_spend_tokens(*vault_address, ant_protocol::evm::U256::MAX)
113 .await
114 .map_err(|e| Error::Payment(format!("Token approval failed: {e}")))?;
115 info!("Token spend approved for payment vault contract");
116
117 Ok(())
118 }
119}
120
121pub(crate) fn peer_id_to_encoded(peer_id: &PeerId) -> Result<EncodedPeerId> {
123 Ok(EncodedPeerId::new(*peer_id.as_bytes()))
124}