Skip to content

Commit

Permalink
resolve comments and fix fixtures
Browse files Browse the repository at this point in the history
  • Loading branch information
Nagaprasadvr committed Nov 28, 2024
1 parent 4dd0fc7 commit 4816e51
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 49 deletions.
23 changes: 16 additions & 7 deletions das_api/src/api/api_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use digital_asset_types::{
Cursor, PageOptions, SearchAssetsQuery,
},
dapi::{
get_asset, get_asset_proofs, get_asset_signatures, get_assets, get_assets_by_authority,
get_assets_by_creator, get_assets_by_group, get_assets_by_owner, get_proof_for_asset,
search_assets,
common::create_pagination, get_asset, get_asset_proofs, get_asset_signatures, get_assets,
get_assets_by_authority, get_assets_by_creator, get_assets_by_group, get_assets_by_owner,
get_proof_for_asset, search_assets,
},
rpc::{
filter::{AssetSortBy, SearchConditionType},
Expand Down Expand Up @@ -526,12 +526,21 @@ impl ApiContract for DasApi {
mint_address,
page,
limit,
before,
after,
cursor,
} = payload;

let page_options = self.validate_pagination(limit, page, &before, &after, &cursor, None)?;
let mint_address = validate_pubkey(mint_address.clone())?;

get_nft_editions(&self.db_connection, mint_address, limit, page)
.await
.map_err(Into::into)
let pagination = create_pagination(&page_options)?;
get_nft_editions(
&self.db_connection,
mint_address,
&pagination,
page_options.limit,
)
.await
.map_err(Into::into)
}
}
4 changes: 4 additions & 0 deletions das_api/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ pub struct GetNftEditions {
pub mint_address: String,
pub page: Option<u32>,
pub limit: Option<u32>,
pub before: Option<String>,
pub after: Option<String>,
#[serde(default)]
pub cursor: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Default)]
Expand Down
109 changes: 70 additions & 39 deletions digital_asset_types/src/dao/scopes/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,14 +566,35 @@ pub fn get_edition_data_from_json<T: DeserializeOwned>(data: Value) -> Result<T,
serde_json::from_value(data).map_err(|e| DbErr::Custom(e.to_string()))
}

pub fn attachment_to_nft_edition(
attachment: asset_v1_account_attachments::Model,
) -> Result<NftEdition, DbErr> {
let data: Edition = attachment
.data
.clone()
.ok_or(DbErr::RecordNotFound("Edition data not found".to_string()))
.map(get_edition_data_from_json)??;

Ok(NftEdition {
mint_address: attachment
.asset_id
.clone()
.map(|id| bs58::encode(id).into_string())
.unwrap_or("".to_string()),
edition_number: data.edition,
edition_address: bs58::encode(attachment.id.clone()).into_string(),
})
}

pub async fn get_nft_editions(
conn: &impl ConnectionTrait,
mint_address: Pubkey,
limit: Option<u32>,
page: Option<u32>,
pagination: &Pagination,
limit: u64,
) -> Result<NftEditions, DbErr> {
let master_edition_pubkey = MasterEdition::find_pda(&mint_address).0;

// to fetch nft editions associated with a mint we need to fetch the master edition first
let master_edition =
asset_v1_account_attachments::Entity::find_by_id(master_edition_pubkey.to_bytes().to_vec())
.one(conn)
Expand All @@ -582,8 +603,6 @@ pub async fn get_nft_editions(
"Master Edition not found".to_string(),
))?;

let limit = limit.unwrap_or(10);

let master_edition_data: MasterEdition = master_edition
.data
.clone()
Expand All @@ -592,48 +611,60 @@ pub async fn get_nft_editions(
))
.map(get_edition_data_from_json)??;

let nft_editions = asset_v1_account_attachments::Entity::find()
.filter(
asset_v1_account_attachments::Column::AttachmentType
.eq(V1AccountAttachments::Edition)
.and(asset_v1_account_attachments::Column::Data.is_not_null())
.and(Expr::cust(&format!(
"data->>'parent' = '{}'",
master_edition_pubkey
))),
)
.order_by_asc(asset_v1_account_attachments::Column::SlotUpdated)
.all(conn)
.await?;
let mut stmt = asset_v1_account_attachments::Entity::find();

stmt = stmt.filter(
asset_v1_account_attachments::Column::AttachmentType
.eq(V1AccountAttachments::Edition)
// The data field is a JSON field that contains the edition data.
.and(asset_v1_account_attachments::Column::Data.is_not_null())
// The parent field is a string field that contains the master edition pubkey ( mapping edition to master edition )
.and(Expr::cust(&format!(
"data->>'parent' = '{}'",
master_edition_pubkey
))),
);

let nft_editions = nft_editions
.iter()
.map(|e| -> Result<NftEdition, DbErr> {
let data: Edition = e
.data
.clone()
.ok_or(DbErr::RecordNotFound("Edition data not found".to_string()))
.map(get_edition_data_from_json)??;

Ok(NftEdition {
mint_address: e
.asset_id
.clone()
.map(|id| bs58::encode(id).into_string())
.unwrap_or("".to_string()),
edition_number: data.edition,
edition_address: bs58::encode(e.id.clone()).into_string(),
})
})
.collect::<Result<Vec<NftEdition>, _>>()?;
let nft_editions = paginate(
pagination,
limit,
stmt,
Order::Asc,
asset_v1_account_attachments::Column::Id,
)
.all(conn)
.await?
.into_iter()
.map(attachment_to_nft_edition)
.collect::<Result<Vec<NftEdition>, _>>()?;

let (page, before, after, cursor) = match pagination {
Pagination::Keyset { before, after } => {
let bef = before.clone().and_then(|x| String::from_utf8(x).ok());
let aft = after.clone().and_then(|x| String::from_utf8(x).ok());
(None, bef, aft, None)
}
Pagination::Page { page } => (Some(*page as u32), None, None, None),
Pagination::Cursor(_) => {
if let Some(last_asset) = nft_editions.last() {
let cursor_str = bs58::encode(last_asset.edition_address.clone()).into_string();
(None, None, None, Some(cursor_str))
} else {
(None, None, None, None)
}
}
};

Ok(NftEditions {
total: nft_editions.len() as u32,
limit,
page,
master_edition_address: master_edition_pubkey.to_string(),
supply: master_edition_data.supply,
max_supply: master_edition_data.max_supply,
editions: nft_editions,
limit: limit as u32,
page,
before,
after,
cursor,
})
}
10 changes: 8 additions & 2 deletions digital_asset_types/src/rpc/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,17 @@ pub struct NftEdition {
pub struct NftEditions {
pub total: u32,
pub limit: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub page: Option<u32>,
pub master_edition_address: String,
pub supply: u64,
pub max_supply: Option<u64>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub editions: Vec<NftEdition>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub before: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub after: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cursor: Option<String>,
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ async fn test_get_nft_editions() {

let request = r#"
{
"mintAddress": "Ey2Qb8kLctbchQsMnhZs5DjY32To2QtPuXNwWvk4NosL"
"mintAddress": "Ey2Qb8kLctbchQsMnhZs5DjY32To2QtPuXNwWvk4NosL",
"limit":10
}
"#;

Expand Down

0 comments on commit 4816e51

Please sign in to comment.