1use crate::connection::ScanConnection;
5
6use super::{
7 balance::{self, Balance},
8 coin::Coin,
9 cursor::Page,
10 move_object::MoveObject,
11 object::{self, ObjectFilter},
12 owner::OwnerImpl,
13 stake::StakedSui,
14 sui_address::SuiAddress,
15 suins_registration::{DomainFormat, SuinsRegistration},
16 transaction_block::{self, TransactionBlock, TransactionBlockFilter},
17 type_filter::ExactTypeFilter,
18};
19use async_graphql::{connection::Connection, *};
20
21#[derive(Clone, Debug, PartialEq, Eq, Copy)]
22pub(crate) struct Address {
23 pub address: SuiAddress,
24 pub checkpoint_viewed_at: u64,
26}
27
28#[derive(Enum, Copy, Clone, Eq, PartialEq)]
30pub(crate) enum AddressTransactionBlockRelationship {
31 Sent,
33 Affected,
36}
37
38#[Object]
40impl Address {
41 pub(crate) async fn address(&self) -> SuiAddress {
42 OwnerImpl::from(self).address().await
43 }
44
45 pub(crate) async fn objects(
47 &self,
48 ctx: &Context<'_>,
49 first: Option<u64>,
50 after: Option<object::Cursor>,
51 last: Option<u64>,
52 before: Option<object::Cursor>,
53 filter: Option<ObjectFilter>,
54 ) -> Result<Connection<String, MoveObject>> {
55 OwnerImpl::from(self)
56 .objects(ctx, first, after, last, before, filter)
57 .await
58 }
59
60 pub(crate) async fn balance(
63 &self,
64 ctx: &Context<'_>,
65 type_: Option<ExactTypeFilter>,
66 ) -> Result<Option<Balance>> {
67 OwnerImpl::from(self).balance(ctx, type_).await
68 }
69
70 pub(crate) async fn balances(
72 &self,
73 ctx: &Context<'_>,
74 first: Option<u64>,
75 after: Option<balance::Cursor>,
76 last: Option<u64>,
77 before: Option<balance::Cursor>,
78 ) -> Result<Connection<String, Balance>> {
79 OwnerImpl::from(self)
80 .balances(ctx, first, after, last, before)
81 .await
82 }
83
84 pub(crate) async fn coins(
88 &self,
89 ctx: &Context<'_>,
90 first: Option<u64>,
91 after: Option<object::Cursor>,
92 last: Option<u64>,
93 before: Option<object::Cursor>,
94 type_: Option<ExactTypeFilter>,
95 ) -> Result<Connection<String, Coin>> {
96 OwnerImpl::from(self)
97 .coins(ctx, first, after, last, before, type_)
98 .await
99 }
100
101 pub(crate) async fn staked_suis(
103 &self,
104 ctx: &Context<'_>,
105 first: Option<u64>,
106 after: Option<object::Cursor>,
107 last: Option<u64>,
108 before: Option<object::Cursor>,
109 ) -> Result<Connection<String, StakedSui>> {
110 OwnerImpl::from(self)
111 .staked_suis(ctx, first, after, last, before)
112 .await
113 }
114
115 pub(crate) async fn default_suins_name(
117 &self,
118 ctx: &Context<'_>,
119 format: Option<DomainFormat>,
120 ) -> Result<Option<String>> {
121 OwnerImpl::from(self).default_suins_name(ctx, format).await
122 }
123
124 pub(crate) async fn suins_registrations(
127 &self,
128 ctx: &Context<'_>,
129 first: Option<u64>,
130 after: Option<object::Cursor>,
131 last: Option<u64>,
132 before: Option<object::Cursor>,
133 ) -> Result<Connection<String, SuinsRegistration>> {
134 OwnerImpl::from(self)
135 .suins_registrations(ctx, first, after, last, before)
136 .await
137 }
138
139 async fn transaction_blocks(
161 &self,
162 ctx: &Context<'_>,
163 first: Option<u64>,
164 after: Option<transaction_block::Cursor>,
165 last: Option<u64>,
166 before: Option<transaction_block::Cursor>,
167 relation: Option<AddressTransactionBlockRelationship>,
168 filter: Option<TransactionBlockFilter>,
169 scan_limit: Option<u64>,
170 ) -> Result<ScanConnection<String, TransactionBlock>> {
171 use AddressTransactionBlockRelationship as R;
172 let page = Page::from_params(ctx.data_unchecked(), first, after, last, before)?;
173
174 let Some(filter) = filter.unwrap_or_default().intersect(match relation {
175 Some(R::Sent) | None => TransactionBlockFilter {
177 sent_address: Some(self.address),
178 ..Default::default()
179 },
180
181 Some(R::Affected) => TransactionBlockFilter {
182 affected_address: Some(self.address),
183 ..Default::default()
184 },
185 }) else {
186 return Ok(ScanConnection::new(false, false));
187 };
188
189 TransactionBlock::paginate(ctx, page, filter, self.checkpoint_viewed_at, scan_limit)
190 .await
191 .extend()
192 }
193}
194
195impl From<&Address> for OwnerImpl {
196 fn from(address: &Address) -> Self {
197 OwnerImpl {
198 address: address.address,
199 checkpoint_viewed_at: address.checkpoint_viewed_at,
200 }
201 }
202}