Skip to content

Commit

Permalink
feat: displayOptions + batch endpoints + keyset pagination + token_st…
Browse files Browse the repository at this point in the history
…andard (#122)
  • Loading branch information
tahsintunan authored Oct 18, 2023
1 parent f0ab966 commit 8b6dc11
Show file tree
Hide file tree
Showing 26 changed files with 871 additions and 400 deletions.
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

0 comments on commit 8b6dc11

Please sign in to comment.