sui_graphql_rpc/types/address.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0
use crate::connection::ScanConnection;
use super::{
balance::{self, Balance},
coin::Coin,
cursor::Page,
move_object::MoveObject,
object::{self, ObjectFilter},
owner::OwnerImpl,
stake::StakedSui,
sui_address::SuiAddress,
suins_registration::{DomainFormat, SuinsRegistration},
transaction_block::{self, TransactionBlock, TransactionBlockFilter},
type_filter::ExactTypeFilter,
};
use async_graphql::{connection::Connection, *};
#[derive(Clone, Debug, PartialEq, Eq, Copy)]
pub(crate) struct Address {
pub address: SuiAddress,
/// The checkpoint sequence number at which this was viewed at.
pub checkpoint_viewed_at: u64,
}
/// The possible relationship types for a transaction block: sent, or received.
#[derive(Enum, Copy, Clone, Eq, PartialEq)]
pub(crate) enum AddressTransactionBlockRelationship {
/// Transactions this address has sent.
Sent,
/// Transactions that this address was involved in, either as the sender, sponsor, or as the
/// owner of some object that was created, modified or transfered.
Affected,
}
/// The 32-byte address that is an account address (corresponding to a public key).
#[Object]
impl Address {
pub(crate) async fn address(&self) -> SuiAddress {
OwnerImpl::from(self).address().await
}
/// Objects owned by this address, optionally `filter`-ed.
pub(crate) async fn objects(
&self,
ctx: &Context<'_>,
first: Option<u64>,
after: Option<object::Cursor>,
last: Option<u64>,
before: Option<object::Cursor>,
filter: Option<ObjectFilter>,
) -> Result<Connection<String, MoveObject>> {
OwnerImpl::from(self)
.objects(ctx, first, after, last, before, filter)
.await
}
/// Total balance of all coins with marker type owned by this address. If type is not supplied,
/// it defaults to `0x2::sui::SUI`.
pub(crate) async fn balance(
&self,
ctx: &Context<'_>,
type_: Option<ExactTypeFilter>,
) -> Result<Option<Balance>> {
OwnerImpl::from(self).balance(ctx, type_).await
}
/// The balances of all coin types owned by this address.
pub(crate) async fn balances(
&self,
ctx: &Context<'_>,
first: Option<u64>,
after: Option<balance::Cursor>,
last: Option<u64>,
before: Option<balance::Cursor>,
) -> Result<Connection<String, Balance>> {
OwnerImpl::from(self)
.balances(ctx, first, after, last, before)
.await
}
/// The coin objects for this address.
///
///`type` is a filter on the coin's type parameter, defaulting to `0x2::sui::SUI`.
pub(crate) async fn coins(
&self,
ctx: &Context<'_>,
first: Option<u64>,
after: Option<object::Cursor>,
last: Option<u64>,
before: Option<object::Cursor>,
type_: Option<ExactTypeFilter>,
) -> Result<Connection<String, Coin>> {
OwnerImpl::from(self)
.coins(ctx, first, after, last, before, type_)
.await
}
/// The `0x3::staking_pool::StakedSui` objects owned by this address.
pub(crate) async fn staked_suis(
&self,
ctx: &Context<'_>,
first: Option<u64>,
after: Option<object::Cursor>,
last: Option<u64>,
before: Option<object::Cursor>,
) -> Result<Connection<String, StakedSui>> {
OwnerImpl::from(self)
.staked_suis(ctx, first, after, last, before)
.await
}
/// The domain explicitly configured as the default domain pointing to this address.
pub(crate) async fn default_suins_name(
&self,
ctx: &Context<'_>,
format: Option<DomainFormat>,
) -> Result<Option<String>> {
OwnerImpl::from(self).default_suins_name(ctx, format).await
}
/// The SuinsRegistration NFTs owned by this address. These grant the owner the capability to
/// manage the associated domain.
pub(crate) async fn suins_registrations(
&self,
ctx: &Context<'_>,
first: Option<u64>,
after: Option<object::Cursor>,
last: Option<u64>,
before: Option<object::Cursor>,
) -> Result<Connection<String, SuinsRegistration>> {
OwnerImpl::from(self)
.suins_registrations(ctx, first, after, last, before)
.await
}
/// Similar behavior to the `transactionBlocks` in Query but supporting the additional
/// `AddressTransactionBlockRelationship` filter, which defaults to `SENT`.
///
/// `scanLimit` restricts the number of candidate transactions scanned when gathering a page of
/// results. It is required for queries that apply more than two complex filters (on function,
/// kind, sender, recipient, input object, changed object, or ids), and can be at most
/// `serviceConfig.maxScanLimit`.
///
/// When the scan limit is reached the page will be returned even if it has fewer than `first`
/// results when paginating forward (`last` when paginating backwards). If there are more
/// transactions to scan, `pageInfo.hasNextPage` (or `pageInfo.hasPreviousPage`) will be set to
/// `true`, and `PageInfo.endCursor` (or `PageInfo.startCursor`) will be set to the last
/// transaction that was scanned as opposed to the last (or first) transaction in the page.
///
/// Requesting the next (or previous) page after this cursor will resume the search, scanning
/// the next `scanLimit` many transactions in the direction of pagination, and so on until all
/// transactions in the scanning range have been visited.
///
/// By default, the scanning range includes all transactions known to GraphQL, but it can be
/// restricted by the `after` and `before` cursors, and the `beforeCheckpoint`,
/// `afterCheckpoint` and `atCheckpoint` filters.
async fn transaction_blocks(
&self,
ctx: &Context<'_>,
first: Option<u64>,
after: Option<transaction_block::Cursor>,
last: Option<u64>,
before: Option<transaction_block::Cursor>,
relation: Option<AddressTransactionBlockRelationship>,
filter: Option<TransactionBlockFilter>,
scan_limit: Option<u64>,
) -> Result<ScanConnection<String, TransactionBlock>> {
use AddressTransactionBlockRelationship as R;
let page = Page::from_params(ctx.data_unchecked(), first, after, last, before)?;
let Some(filter) = filter.unwrap_or_default().intersect(match relation {
// Relationship defaults to "sent" if none is supplied.
Some(R::Sent) | None => TransactionBlockFilter {
sent_address: Some(self.address),
..Default::default()
},
Some(R::Affected) => TransactionBlockFilter {
affected_address: Some(self.address),
..Default::default()
},
}) else {
return Ok(ScanConnection::new(false, false));
};
TransactionBlock::paginate(ctx, page, filter, self.checkpoint_viewed_at, scan_limit)
.await
.extend()
}
}
impl From<&Address> for OwnerImpl {
fn from(address: &Address) -> Self {
OwnerImpl {
address: address.address,
checkpoint_viewed_at: address.checkpoint_viewed_at,
}
}
}