pod_sdk/auctions/
client.rs1use std::time::SystemTime;
2
3use crate::{network::PodNetwork, provider::PodProvider, Address, U256};
4use alloy_eips::BlockNumberOrTag;
5use anyhow::Context;
6
7use pod_contracts::i_auction::IAuction::IAuctionInstance;
8use pod_types::{rpc::receipt::PodReceiptResponse, Timestamp};
9
10pub struct AuctionClient {
11 pub auction: IAuctionInstance<PodProvider, PodNetwork>,
12}
13
14pub struct Bid {
15 pub amount: U256,
16 pub bidder: Address,
17 pub data: Vec<u8>,
18}
19
20impl AuctionClient {
21 fn micros_from_system_time(deadline: SystemTime) -> u128 {
23 Timestamp::from(deadline).as_micros()
24 }
25
26 fn micros_u64_from_system_time(deadline: SystemTime) -> anyhow::Result<u64> {
28 let micros = Self::micros_from_system_time(deadline);
29 micros
30 .try_into()
31 .context("deadline microseconds must fit in u64")
32 }
33
34 fn micros_u256_from_system_time(deadline: SystemTime) -> U256 {
36 U256::from(Self::micros_from_system_time(deadline))
37 }
38
39 pub fn new(provider: PodProvider, contract: Address) -> Self {
40 AuctionClient {
41 auction: IAuctionInstance::new(contract, provider),
42 }
43 }
44
45 #[tracing::instrument(skip(self))]
46 pub async fn wait_for_auction_end(&self, deadline: SystemTime) -> anyhow::Result<()> {
47 Ok(self
48 .auction
49 .provider()
50 .wait_past_perfect_time(deadline.into())
51 .await?)
52 }
53
54 #[tracing::instrument(skip(self))]
55 pub async fn fetch_bids(&self, auction_id: U256) -> anyhow::Result<Vec<Bid>> {
56 let logs = self
57 .auction
58 .BidSubmitted_filter()
59 .topic1(auction_id)
60 .to_block(BlockNumberOrTag::Latest)
61 .query()
62 .await
63 .context("fetching bid logs")?;
64
65 logs.into_iter()
66 .map(|(event, _)| {
67 Ok(Bid {
68 amount: event.value,
69 bidder: event.bidder,
70 data: event.data.to_vec(),
71 })
72 })
73 .collect()
74 }
75
76 #[tracing::instrument(skip(self))]
77 pub async fn fetch_bids_for_deadline(&self, deadline: SystemTime) -> anyhow::Result<Vec<Bid>> {
78 let deadline_us = Self::micros_u256_from_system_time(deadline);
79
80 let logs = self
81 .auction
82 .BidSubmitted_filter()
83 .topic3(deadline_us)
84 .to_block(BlockNumberOrTag::Latest)
85 .query()
86 .await
87 .context("fetching bid logs")?;
88
89 logs.into_iter()
90 .map(|(event, _)| {
91 Ok(Bid {
92 amount: event.value,
93 bidder: event.bidder,
94 data: event.data.to_vec(),
95 })
96 })
97 .collect()
98 }
99
100 pub async fn submit_bid(
101 &self,
102 auction_id: U256,
103 deadline: SystemTime,
104 bid: U256,
105 data: Vec<u8>,
106 ) -> anyhow::Result<PodReceiptResponse> {
107 let deadline = Self::micros_u64_from_system_time(deadline)?;
108
109 let pending_tx = self
110 .auction
111 .submitBid(auction_id, deadline, bid, data.into())
112 .max_priority_fee_per_gas(0)
113 .send()
114 .await
115 .context("sending bid TX")?;
116
117 let receipt = pending_tx
118 .get_receipt()
119 .await
120 .context("awaiting for bid TX confirmation")?;
121
122 anyhow::ensure!(receipt.status(), "failed to submit bid TX");
123 Ok(receipt)
124 }
125}