Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: displayOptions + batch endpoints + keyset pagination + token_standard #122

Merged
merged 4 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
289 changes: 199 additions & 90 deletions das_api/src/api/api_impl.rs

Large diffs are not rendered by default.

59 changes: 57 additions & 2 deletions das_api/src/api/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use crate::DasApiError;
use async_trait::async_trait;
use digital_asset_types::rpc::display_options::DisplayOptions;
use digital_asset_types::rpc::filter::SearchConditionType;
use digital_asset_types::rpc::response::{AssetList, TransactionSignatureList};
use digital_asset_types::rpc::{filter::AssetSorting, response::GetGroupingResponse};
use digital_asset_types::rpc::{Asset, AssetProof, Interface, OwnershipModel, RoyaltyModel};
use open_rpc_derive::{document_rpc, rpc};
use open_rpc_schema::schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

mod api_impl;
pub use api_impl::*;
Expand All @@ -21,6 +23,10 @@ pub struct GetAssetsByGroup {
pub page: Option<u32>,
pub before: Option<String>,
pub after: Option<String>,
#[serde(default)]
pub display_options: Option<DisplayOptions>,
#[serde(default)]
pub cursor: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
Expand All @@ -32,14 +38,26 @@ pub struct GetAssetsByOwner {
pub page: Option<u32>,
pub before: Option<String>,
pub after: Option<String>,
#[serde(default)]
pub display_options: Option<DisplayOptions>,
#[serde(default)]
pub cursor: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct GetAsset {
pub id: String,
#[serde(default)]
pub raw_data: Option<bool>,
pub display_options: Option<DisplayOptions>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct GetAssetBatch {
pub ids: Vec<String>,
#[serde(default)]
pub display_options: Option<DisplayOptions>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
Expand All @@ -48,6 +66,12 @@ pub struct GetAssetProof {
pub id: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct GetAssetProofBatch {
pub ids: Vec<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct GetAssetsByCreator {
Expand All @@ -58,6 +82,10 @@ pub struct GetAssetsByCreator {
pub page: Option<u32>,
pub before: Option<String>,
pub after: Option<String>,
#[serde(default)]
pub display_options: Option<DisplayOptions>,
#[serde(default)]
pub cursor: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
Expand Down Expand Up @@ -90,7 +118,10 @@ pub struct SearchAssets {
#[serde(default)]
pub json_uri: Option<String>,
#[serde(default)]
pub show_collection_metadata: Option<bool>,
pub display_options: Option<DisplayOptions>,
#[serde(default)]
pub cursor: Option<String>,
#[serde(default)]
pub name: Option<String>,
}

Expand All @@ -104,6 +135,10 @@ pub struct GetAssetsByAuthority {
pub page: Option<u32>,
pub before: Option<String>,
pub after: Option<String>,
#[serde(default)]
pub display_options: Option<DisplayOptions>,
#[serde(default)]
pub cursor: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
Expand All @@ -123,6 +158,8 @@ pub struct GetSignaturesForAsset {
pub after: Option<String>,
pub tree: Option<String>,
pub leaf_index: Option<i64>,
#[serde(default)]
pub cursor: Option<String>,
}

#[document_rpc]
Expand All @@ -135,12 +172,30 @@ pub trait ApiContract: Send + Sync + 'static {
summary = "Get a merkle proof for a compressed asset by its ID"
)]
async fn get_asset_proof(&self, payload: GetAssetProof) -> Result<AssetProof, DasApiError>;
#[rpc(
name = "getAssetProofBatch",
params = "named",
summary = "Get merkle proofs for compressed assets by their IDs"
)]
async fn get_asset_proof_batch(
&self,
payload: GetAssetProofBatch,
) -> Result<HashMap<String, Option<AssetProof>>, DasApiError>;
#[rpc(
name = "getAsset",
params = "named",
summary = "Get an asset by its ID"
)]
async fn get_asset(&self, payload: GetAsset) -> Result<Asset, DasApiError>;
#[rpc(
name = "getAssetBatch",
params = "named",
summary = "Get assets by their IDs"
)]
async fn get_asset_batch(
&self,
payload: GetAssetBatch,
) -> Result<Vec<Option<Asset>>, DasApiError>;
#[rpc(
name = "getAssetsByOwner",
params = "named",
Expand Down
21 changes: 21 additions & 0 deletions das_api/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,33 @@ impl RpcApiBuilder {
})?;
module.register_alias("getAssetProof", "get_asset_proof")?;

module.register_async_method(
"get_asset_proof_batch",
|rpc_params, rpc_context| async move {
let payload = rpc_params.parse::<GetAssetProofBatch>()?;
rpc_context
.get_asset_proof_batch(payload)
.await
.map_err(Into::into)
},
)?;
module.register_alias("getAssetProofBatch", "get_asset_proof_batch")?;

module.register_async_method("get_asset", |rpc_params, rpc_context| async move {
let payload = rpc_params.parse::<GetAsset>()?;
rpc_context.get_asset(payload).await.map_err(Into::into)
})?;
module.register_alias("getAsset", "get_asset")?;

module.register_async_method("get_asset_batch", |rpc_params, rpc_context| async move {
let payload = rpc_params.parse::<GetAssetBatch>()?;
rpc_context
.get_asset_batch(payload)
.await
.map_err(Into::into)
})?;
module.register_alias("getAssetBatch", "get_asset_batch")?;

module.register_async_method(
"get_assets_by_owner",
|rpc_params, rpc_context| async move {
Expand Down
10 changes: 10 additions & 0 deletions das_api/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ pub enum DasApiError {
PaginationEmptyError,
#[error("Deserialization error: {0}")]
DeserializationError(#[from] serde_json::Error),
#[error("Paginating beyond 500000 items is temporarily disabled. Please contact Helius support for more details.")]
OffsetLimitExceededError,
#[error("Pagination Error. Limit should not be greater than 1000.")]
PaginationExceededError,
#[error("Batch Size Error. Batch size should not be greater than 1000.")]
BatchSizeExceededError,
#[error("Pagination Sorting Error. Only sorting based on id is support for this pagination")]
PaginationSortingValidationError,
#[error("Cursor Validation Err: {0} is invalid")]
CursorValidationError(String),
}

impl Into<RpcError> for DasApiError {
Expand Down
11 changes: 4 additions & 7 deletions das_api/src/feature_flag.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
use crate::config::Config;
use digital_asset_types::feature_flag::FeatureFlags;

pub struct FeatureFlags {
pub enable_grand_total_query: bool,
pub enable_collection_metadata: bool,
}
use crate::config::Config;

pub fn get_feature_flags(config: &Config) -> FeatureFlags {
FeatureFlags {
enable_grand_total_query: config.enable_grand_total_query.unwrap_or(false),
enable_collection_metadata: config.enable_collection_metadata.unwrap_or(false),
enable_grand_total_query: config.enable_grand_total_query.unwrap_or(true),
enable_collection_metadata: config.enable_collection_metadata.unwrap_or(true),
}
}
17 changes: 17 additions & 0 deletions digital_asset_types/src/dao/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub mod scopes;
pub use full_asset::*;
#[allow(ambiguous_glob_reexports)]
pub use generated::*;
use serde::{Deserialize, Serialize};

use self::sea_orm_active_enums::{
OwnerType, RoyaltyTargetType, SpecificationAssetClass, SpecificationVersions,
Expand All @@ -19,6 +20,20 @@ pub struct GroupingSize {
pub size: u64,
}

#[derive(Serialize, Deserialize, Debug, Default)]
pub struct PageOptions {
pub limit: u64,
pub page: Option<u64>,
pub before: Option<Vec<u8>>,
pub after: Option<Vec<u8>>,
pub cursor: Option<Cursor>,
}

#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)]
pub struct Cursor {
pub id: Option<Vec<u8>>,
}

pub enum Pagination {
Keyset {
before: Option<Vec<u8>>,
Expand All @@ -27,6 +42,7 @@ pub enum Pagination {
Page {
page: u64,
},
Cursor(Cursor),
}

#[derive(Debug, Clone, PartialEq)]
Expand Down Expand Up @@ -258,6 +274,7 @@ impl SearchAssetsQuery {

let name_expr =
SimpleExpr::Custom(format!("chain_data->>'name' LIKE '%{}%'", name_as_str).into());

conditions = conditions.add(name_expr);
let rel = asset_data::Relation::Asset
.def()
Expand Down
Loading