Skip to content

Commit

Permalink
add get distinct minter did ids
Browse files Browse the repository at this point in the history
  • Loading branch information
dkackman committed Jan 19, 2025
1 parent aacb25e commit 27fee41
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 68 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions crates/sage-api/src/requests/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ pub struct GetDidsResponse {
pub dids: Vec<DidRecord>,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize, Type)]
pub struct GetMinterDidIds {}

#[derive(Debug, Clone, Serialize, Deserialize, Type)]
pub struct GetMinterDidIdsResponse {
pub did_ids: Vec<String>,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize, Type)]
pub struct GetPendingTransactions {}

Expand Down
1 change: 1 addition & 0 deletions crates/sage-cli/src/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ routes!(
get_cats await: GetCats = "/get_cats",
get_cat await: GetCat = "/get_cat",
get_dids await: GetDids = "/get_dids",
// get_minter_did_ids await: GetMinterDidIds = "/get_minter_did_ids",
get_pending_transactions await: GetPendingTransactions = "/get_pending_transactions",
get_transactions await: GetTransactions = "/get_transactions",
get_transaction await: GetTransaction = "/get_transaction",
Expand Down
14 changes: 14 additions & 0 deletions crates/sage-database/src/primitives/nfts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ impl Database {
fetch_nft_data(&self.pool, hash).await
}

pub async fn distinct_minter_dids(&self) -> Result<Vec<Option<Bytes32>>> {
distinct_minter_dids(&self.pool).await
}

pub async fn search_nfts(
&self,
params: NftSearchParams,
Expand Down Expand Up @@ -438,6 +442,16 @@ async fn insert_nft_data(
Ok(())
}

async fn distinct_minter_dids(conn: impl SqliteExecutor<'_>) -> Result<Vec<Option<Bytes32>>> {
let rows = sqlx::query!("SELECT DISTINCT minter_did FROM nfts WHERE minter_did IS NOT NULL")
.fetch_all(conn)
.await?;

rows.into_iter()
.map(|row| row.minter_did.map(|bytes| to_bytes32(&bytes)).transpose())
.collect()
}

async fn fetch_nft_data(conn: impl SqliteExecutor<'_>, hash: Bytes32) -> Result<Option<NftData>> {
let hash = hash.as_ref();

Expand Down
33 changes: 26 additions & 7 deletions crates/sage/src/endpoints/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ use hex_literal::hex;
use sage_api::{
AddressKind, Amount, AssetKind, CatRecord, CoinRecord, DerivationRecord, DidRecord, GetCat,
GetCatCoins, GetCatCoinsResponse, GetCatResponse, GetCats, GetCatsResponse, GetDerivations,
GetDerivationsResponse, GetDids, GetDidsResponse, GetNft, GetNftCollection,
GetNftCollectionResponse, GetNftCollections, GetNftCollectionsResponse, GetNftData,
GetNftDataResponse, GetNftResponse, GetNfts, GetNftsResponse, GetPendingTransactions,
GetPendingTransactionsResponse, GetSyncStatus, GetSyncStatusResponse, GetTransaction,
GetTransactionResponse, GetTransactions, GetTransactionsResponse, GetXchCoins,
GetXchCoinsResponse, NftCollectionRecord, NftData, NftRecord, NftSortMode as ApiNftSortMode,
PendingTransactionRecord, TransactionCoin, TransactionRecord,
GetDerivationsResponse, GetDids, GetDidsResponse, GetMinterDidIds, GetMinterDidIdsResponse,
GetNft, GetNftCollection, GetNftCollectionResponse, GetNftCollections,
GetNftCollectionsResponse, GetNftData, GetNftDataResponse, GetNftResponse, GetNfts,
GetNftsResponse, GetPendingTransactions, GetPendingTransactionsResponse, GetSyncStatus,
GetSyncStatusResponse, GetTransaction, GetTransactionResponse, GetTransactions,
GetTransactionsResponse, GetXchCoins, GetXchCoinsResponse, NftCollectionRecord, NftData,
NftRecord, NftSortMode as ApiNftSortMode, PendingTransactionRecord, TransactionCoin,
TransactionRecord,
};
use sage_database::{
CoinKind, CoinStateRow, Database, NftGroup, NftRow, NftSearchParams, NftSortMode,
Expand Down Expand Up @@ -244,6 +245,24 @@ impl Sage {
Ok(GetDidsResponse { dids })
}

pub async fn get_minter_did_ids(
&self,
_req: GetMinterDidIds,
) -> Result<GetMinterDidIdsResponse> {
let wallet = self.wallet()?;

let did_ids = wallet
.db
.distinct_minter_dids()
.await?
.into_iter()
.filter_map(|did| did.map(|d| encode_address(d.to_bytes(), "did:chia:").ok()))
.flatten()
.collect();

Ok(GetMinterDidIdsResponse { did_ids })
}

pub async fn get_pending_transactions(
&self,
_req: GetPendingTransactions,
Expand Down
9 changes: 9 additions & 0 deletions src-tauri/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,15 @@ pub async fn get_dids(state: State<'_, AppState>, req: GetDids) -> Result<GetDid
Ok(state.lock().await.get_dids(req).await?)
}

#[command]
#[specta]
pub async fn get_minter_did_ids(
state: State<'_, AppState>,
req: GetMinterDidIds,
) -> Result<GetMinterDidIdsResponse> {
Ok(state.lock().await.get_minter_did_ids(req).await?)
}

#[command]
#[specta]
pub async fn get_pending_transactions(
Expand Down
1 change: 1 addition & 0 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub fn run() {
commands::get_cats,
commands::get_cat,
commands::get_dids,
commands::get_minter_did_ids,
commands::get_nft_collections,
commands::get_nft_collection,
commands::get_nfts,
Expand Down
5 changes: 5 additions & 0 deletions src/bindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ async getCat(req: GetCat) : Promise<GetCatResponse> {
async getDids(req: GetDids) : Promise<GetDidsResponse> {
return await TAURI_INVOKE("get_dids", { req });
},
async getMinterDidIds(req: GetMinterDidIds) : Promise<GetMinterDidIdsResponse> {
return await TAURI_INVOKE("get_minter_did_ids", { req });
},
async getNftCollections(req: GetNftCollections) : Promise<GetNftCollectionsResponse> {
return await TAURI_INVOKE("get_nft_collections", { req });
},
Expand Down Expand Up @@ -293,6 +296,8 @@ export type GetKey = { fingerprint?: number | null }
export type GetKeyResponse = { key: KeyInfo | null }
export type GetKeys = Record<string, never>
export type GetKeysResponse = { keys: KeyInfo[] }
export type GetMinterDidIds = Record<string, never>
export type GetMinterDidIdsResponse = { did_ids: string[] }
export type GetNetworks = Record<string, never>
export type GetNetworksResponse = { networks: { [key in string]: Network } }
export type GetNft = { nft_id: string }
Expand Down
133 changes: 72 additions & 61 deletions src/pages/NftList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ import { useNftParams, NftGroupMode } from '@/hooks/useNftParams';
import collectionImage from '@/images/collection.png';
import { t } from '@lingui/core/macro';
import { Trans } from '@lingui/react/macro';
import { EyeIcon, EyeOff, ImagePlusIcon, MoreVerticalIcon, UserIcon, Paintbrush } from 'lucide-react';
import {
EyeIcon,
EyeOff,
ImagePlusIcon,
MoreVerticalIcon,
UserIcon,
Paintbrush,
} from 'lucide-react';
import { useCallback, useEffect, useState } from 'react';
import { Link, useNavigate, useParams } from 'react-router-dom';
import {
Expand All @@ -35,7 +42,11 @@ import {

export function NftList() {
const navigate = useNavigate();
const { collection_id: collectionId, owner_did: ownerDid, minter_did: minterDid } = useParams();
const {
collection_id: collectionId,
owner_did: ownerDid,
minter_did: minterDid,
} = useParams();
const { addError } = useErrors();

const [params, setParams] = useNftParams();
Expand All @@ -56,7 +67,12 @@ export function NftList() {
async (page: number) => {
setIsLoading(true);
try {
if (collectionId || ownerDid || minterDid || group === NftGroupMode.None) {
if (
collectionId ||
ownerDid ||
minterDid ||
group === NftGroupMode.None
) {
const params = {
name: query || null,
collection_id: collectionId ?? null,
Expand All @@ -71,8 +87,11 @@ export function NftList() {
console.log('Fetching NFTs with params:', params);
const response = await commands.getNfts(params);
console.log('NFTs response:', response);
console.log('NFTs owner_dids:', response.nfts.map(nft => nft.owner_did));

console.log(
'NFTs owner_dids:',
response.nfts.map((nft) => nft.owner_did),
);

setNfts(response.nfts);

if (collectionId) {
Expand All @@ -81,8 +100,7 @@ export function NftList() {
collectionId === 'No collection' ? null : collectionId,
});
setCollection(collectionResponse.collection);
}
else if (ownerDid) {
} else if (ownerDid) {
const didResponse = await commands.getDids({});
const foundDid = didResponse.dids.find(
(did) => did.launcher_id === ownerDid,
Expand All @@ -101,19 +119,17 @@ export function NftList() {
},
);
} else if (minterDid) {
setOwner(
{
name: minterDid,
launcher_id: minterDid,
visible: true,
coin_id: 'No coin',
address: 'no address',
amount: 0,
created_height: 0,
create_transaction_id: 'No transaction',
recovery_hash: '',
},
);
setOwner({
name: minterDid,
launcher_id: minterDid,
visible: true,
coin_id: 'No coin',
address: 'no address',
amount: 0,
created_height: 0,
create_transaction_id: 'No transaction',
recovery_hash: '',
});
}
} else if (group === NftGroupMode.Collection) {
await commands
Expand All @@ -130,38 +146,23 @@ export function NftList() {
.then((data) => setDids(data.dids))
.catch(addError);
} else if (group === NftGroupMode.MinterDid) {
// Get all NFTs to find unique minter DIDs
const allNftsResponse = await commands.getNfts({
name: query || null,
collection_id: null,
owner_did_id: null,
minter_did_id: null,
offset: 0,
limit: 1000, // Large enough to get all NFTs
sort_mode: sort,
include_hidden: showHidden,
});

// Create unique set of minter DIDs
const uniqueMinterDids = new Set<string>();
allNftsResponse.nfts.forEach(nft => {
if (nft.minter_did) {
uniqueMinterDids.add(nft.minter_did);
}
});

// Convert minter DIDs to DidRecord format
const minterDids: DidRecord[] = Array.from(uniqueMinterDids).map(did => ({
name: `Creator ${did.slice(0, 16)}...`,
launcher_id: did,
visible: true,
coin_id: 'No coin',
address: 'no address',
amount: 0,
created_height: 0,
create_transaction_id: 'No transaction',
recovery_hash: '',
}));
const uniqueMinterDids = await commands.getMinterDidIds({});
console.log('Unique minter DIDs:', uniqueMinterDids);
// Convert minter DID IDs to DidRecord format
const minterDids: DidRecord[] = uniqueMinterDids.did_ids.map(
(did) => ({
name: `Creator ${did.slice(0, 16)}...`,
launcher_id: did,
visible: true,
coin_id: 'No coin',
address: 'no address',
amount: 0,
created_height: 0,
create_transaction_id: 'No transaction',
recovery_hash: '',
}),
);

setDids(minterDids);
}
Expand Down Expand Up @@ -223,7 +224,7 @@ export function NftList() {
title={
<Tooltip>
<TooltipTrigger asChild>
<div className="truncate max-w-[300px]">
<div className='truncate max-w-[300px]'>
{collectionId ? (
(collection?.name ?? t`Unknown Collection`)
) : ownerDid ? (
Expand Down Expand Up @@ -271,7 +272,10 @@ export function NftList() {
/>

<NftCardList>
{!collectionId && !ownerDid && !minterDid && group === NftGroupMode.Collection ? (
{!collectionId &&
!ownerDid &&
!minterDid &&
group === NftGroupMode.Collection ? (
<>
{collections.map((col, i) => (
<Collection
Expand All @@ -294,8 +298,11 @@ export function NftList() {
/>
)}
</>
) : !collectionId && !ownerDid && !minterDid &&
(group === NftGroupMode.OwnerDid || group === NftGroupMode.MinterDid) ? (
) : !collectionId &&
!ownerDid &&
!minterDid &&
(group === NftGroupMode.OwnerDid ||
group === NftGroupMode.MinterDid) ? (
<>
{dids.map((did, i) => (
<DidGroup
Expand Down Expand Up @@ -437,13 +444,17 @@ interface DidGroupProps {
}

function DidGroup({ did, groupMode }: DidGroupProps) {
const linkPath = groupMode === NftGroupMode.OwnerDid
? `/nfts/owners/${did.launcher_id}`
: `/nfts/minters/${did.launcher_id}`;
const linkPath =
groupMode === NftGroupMode.OwnerDid
? `/nfts/owners/${did.launcher_id}`
: `/nfts/minters/${did.launcher_id}`;

const defaultName = groupMode === NftGroupMode.OwnerDid
? <Trans>Unnamed Profile</Trans>
: <Trans>Unnamed Creator</Trans>;
const defaultName =
groupMode === NftGroupMode.OwnerDid ? (
<Trans>Unnamed Profile</Trans>
) : (
<Trans>Unnamed Creator</Trans>
);

return (
<Link
Expand Down

0 comments on commit 27fee41

Please sign in to comment.