use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum TransferCategory {
External,
Internal,
Erc20,
Erc721,
Erc1155,
#[serde(rename = "specialnft")]
SpecialNft,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TransferOrder {
Ascending,
Descending,
}
impl Serialize for TransferOrder {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self {
TransferOrder::Ascending => serializer.serialize_str("asc"),
TransferOrder::Descending => serializer.serialize_str("desc"),
}
}
}
#[derive(Debug, Clone, Default, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AssetTransfersOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub from_block: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub to_block: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub from_address: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub to_address: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contract_addresses: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub category: Option<Vec<TransferCategory>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub exclude_zero_value: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_count: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub order: Option<TransferOrder>,
#[serde(skip_serializing_if = "Option::is_none")]
pub with_metadata: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page_key: Option<String>,
}
impl AssetTransfersOptions {
#[must_use]
pub fn from_address(address: &str) -> Self {
Self {
from_address: Some(address.to_string()),
category: Some(vec![
TransferCategory::External,
TransferCategory::Erc20,
TransferCategory::Erc721,
TransferCategory::Erc1155,
]),
..Default::default()
}
}
#[must_use]
pub fn to_address(address: &str) -> Self {
Self {
to_address: Some(address.to_string()),
category: Some(vec![
TransferCategory::External,
TransferCategory::Erc20,
TransferCategory::Erc721,
TransferCategory::Erc1155,
]),
..Default::default()
}
}
#[must_use]
pub fn with_block_range(mut self, from: &str, to: &str) -> Self {
self.from_block = Some(from.to_string());
self.to_block = Some(to.to_string());
self
}
#[must_use]
pub fn with_internal_transfers(mut self) -> Self {
let mut categories = self.category.unwrap_or_default();
if !categories.contains(&TransferCategory::Internal) {
categories.push(TransferCategory::Internal);
}
self.category = Some(categories);
self
}
#[must_use]
pub fn exclude_zero_value(mut self) -> Self {
self.exclude_zero_value = Some(true);
self
}
#[must_use]
pub fn with_max_count(mut self, count: u32) -> Self {
self.max_count = Some(format!("0x{count:x}"));
self
}
#[must_use]
pub fn with_order(mut self, order: TransferOrder) -> Self {
self.order = Some(order);
self
}
#[must_use]
pub fn with_metadata(mut self) -> Self {
self.with_metadata = Some(true);
self
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AssetTransfer {
pub block_num: String,
pub unique_id: String,
pub hash: String,
pub from: String,
pub to: Option<String>,
pub value: Option<f64>,
pub erc721_token_id: Option<String>,
pub erc1155_metadata: Option<Vec<Erc1155Metadata>>,
pub token_id: Option<String>,
pub asset: Option<String>,
pub category: TransferCategory,
pub raw_contract: Option<RawContract>,
pub metadata: Option<TransferMetadata>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Erc1155Metadata {
pub token_id: String,
pub value: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RawContract {
pub address: Option<String>,
pub value: Option<String>,
pub decimal: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TransferMetadata {
pub block_timestamp: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AssetTransfersResponse {
pub transfers: Vec<AssetTransfer>,
pub page_key: Option<String>,
}