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