diff --git a/apps/portal/app/components/atom-search-combobox-extended.tsx b/apps/portal/app/components/atom-search-combobox-extended.tsx new file mode 100644 index 000000000..bf0e04678 --- /dev/null +++ b/apps/portal/app/components/atom-search-combobox-extended.tsx @@ -0,0 +1,352 @@ +import * as React from 'react' + +import { + Button, + ButtonSize, + ButtonVariant, + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, + CommandSeparator, + CommandShortcut, + EmptyStateCard, + Icon, + IconName, + Tag, + TagSize, +} from '@0xintuition/1ui' +import { GetAtomQuery, useGetAtomsQuery } from '@0xintuition/graphql' + +import { useDebounce } from '@lib/hooks/useDebounce' +import { formatEther } from 'viem' + +import { AtomType, AtomTypeSelect } from './atom-type-select' + +interface AtomDetailsProps { + atom: GetAtomQuery['atom'] +} + +const AtomDetails = React.memo(({ atom }: AtomDetailsProps) => { + if (!atom) { + return
+ } + + return ( +
+ {atom.image ? ( + + ) : ( + + )} +
+

{atom.label}

+ {atom.type} +

+ ID: {atom.vaultId} +

+
+ +
+
+
TVL
+
+ {( + parseFloat(formatEther(BigInt(atom.vault?.totalShares || 0))) * + parseFloat( + formatEther(BigInt(atom.vault?.currentSharePrice || 0)), + ) + ).toFixed(4)}{' '} + ETH +
+
+
+
+
Attestors
+
+ {atom.vault?.positionCount} +
+
+
+
+ ) +}) + +AtomDetails.displayName = 'AtomDetails' + +interface AtomSearchComboboxItemProps { + atom: NonNullable + isSelected?: boolean + onSelect: () => void + onMouseEnter: () => void + onMouseLeave: () => void +} + +const LazyImage = React.memo( + ({ + src, + alt, + className, + }: { + src: string + alt: string + className: string + }) => { + const [isLoading, setIsLoading] = React.useState(true) + const [error, setError] = React.useState(false) + + return ( + <> + {isLoading && ( +
+ )} + {alt} setIsLoading(false)} + onError={() => { + setIsLoading(false) + setError(true) + }} + /> + {error && ( +
+ +
+ )} + + ) + }, +) + +LazyImage.displayName = 'LazyImage' + +const AtomSearchComboboxItem = React.memo( + ({ + atom, + isSelected, + onSelect, + onMouseEnter, + onMouseLeave, + }: AtomSearchComboboxItemProps) => { + return ( + +
+
+ {atom?.image ? ( + {atom.label + ) : ( +
+ )} +
+
{atom?.label}
+
+ + #{atom?.vaultId} + +
+
+
+
+
+ + {atom?.vault?.currentSharePrice + ? ( + parseFloat( + formatEther(BigInt(atom.vault?.totalShares || 0)), + ) * + parseFloat( + formatEther(BigInt(atom.vault?.currentSharePrice || 0)), + ) + ).toFixed(3) + : undefined} +
+ +
+ + {atom?.vault?.positionCount} +
+
+
+ + ) + }, + (prevProps, nextProps) => { + return ( + prevProps.isSelected === nextProps.isSelected && + prevProps.atom?.vaultId === nextProps.atom?.vaultId + ) + }, +) + +AtomSearchComboboxItem.displayName = 'AtomSearchComboboxItem' + +export interface AtomSearchComboboxExtendedProps + extends React.HTMLAttributes { + onAtomSelect?: (atom: GetAtomQuery['atom']) => void + initialValue?: string + placeholder?: string +} + +export function AtomSearchComboboxExtended({ + onAtomSelect = () => {}, + initialValue = '', + placeholder = 'Search for an atom...', + ...props +}: AtomSearchComboboxExtendedProps) { + const [searchValue, setSearchValue] = React.useState(initialValue) + const debouncedSearch = useDebounce(searchValue, 300) + const [isOpen, setIsOpen] = React.useState(false) + const [searchResults, setSearchResults] = React.useState< + Omit< + NonNullable, + 'asSubject' | 'asPredicate' | 'asObject' + >[] + >([]) + const [selectedAtom, setSelectedAtom] = React.useState() + const [hoveredAtom, setHoveredAtom] = React.useState() + const [lastHoveredAtom, setLastHoveredAtom] = + React.useState() + const [selectedType, setSelectedType] = React.useState('All') + + const { data: atomsData, isLoading } = useGetAtomsQuery( + { + where: { + label: { _ilike: `%${debouncedSearch}%` }, + ...(selectedType !== 'All' && { type: { _eq: selectedType } }), + }, + limit: 25, + }, + { + queryKey: ['atoms', debouncedSearch, selectedType], + enabled: isOpen, + }, + ) + + React.useEffect(() => { + setSearchResults(atomsData?.atoms ?? []) + }, [atomsData]) + + const handleAtomSelect = ( + atom: Omit, + ) => { + onAtomSelect(atom as GetAtomQuery['atom']) + setSelectedAtom(atom as GetAtomQuery['atom']) + setIsOpen(false) + setSearchValue('') + setSearchResults([]) + } + + const displayedAtom = (hoveredAtom || + lastHoveredAtom || + selectedAtom || + searchResults[0]) as NonNullable + + const handleMouseEnter = (atom: NonNullable) => { + setHoveredAtom(atom) + setLastHoveredAtom(atom) + } + + const handleMouseLeave = () => { + setHoveredAtom(undefined) + } + + return ( +
+ +
+
+ { + setSearchValue(value) + setIsOpen(true) + }} + onFocus={() => setIsOpen(true)} + className="border-0 px-3 " + /> +
+
+
+ + + + + + {searchResults.map((atom, index) => ( + } + isSelected={selectedAtom?.vaultId === atom.vaultId} + onSelect={() => handleAtomSelect(atom)} + onMouseEnter={() => + handleMouseEnter(atom as NonNullable) + } + onMouseLeave={handleMouseLeave} + /> + ))} + + +
+ +
+
+ + +
+ + +
+
+
+
+ ) +} diff --git a/apps/portal/app/components/atom-search-combobox.tsx b/apps/portal/app/components/atom-search-combobox.tsx new file mode 100644 index 000000000..9223ddfda --- /dev/null +++ b/apps/portal/app/components/atom-search-combobox.tsx @@ -0,0 +1,189 @@ +import * as React from 'react' + +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, + EmptyStateCard, + Icon, + IconName, +} from '@0xintuition/1ui' +import { GetAtomQuery, useGetAtomsQuery } from '@0xintuition/graphql' + +import { useDebounce } from '@lib/hooks/useDebounce' +import { formatEther } from 'viem' + +interface AtomSearchComboboxItemProps { + id: string | number + name: string + avatarSrc?: string + value?: number + variant?: 'user' | 'non-user' + onClick?: () => void + onSelect?: () => void + attestors?: number +} + +const AtomSearchComboboxItem = ({ + id, + name, + avatarSrc, + value, + onClick, + onSelect, + attestors, +}: AtomSearchComboboxItemProps) => { + return ( + +
+
+ {avatarSrc ? ( + {name} + ) : ( +
+ )} +
+
+ {name} +
+ {id !== undefined && ( +
+
+ {id} +
+
+ )} +
+
+
+
+ + {value?.toFixed(3)} +
+ +
+ + {attestors} +
+
+
+ + ) +} + +export interface AtomSearchComboboxProps + extends React.HTMLAttributes { + onAtomSelect?: (atom: GetAtomQuery['atom']) => void + onCreateAtomClick?: () => void + initialValue?: string + placeholder?: string +} + +export function AtomSearchCombobox({ + onAtomSelect = () => {}, + initialValue = '', + placeholder = 'Search for an atom...', + ...props +}: AtomSearchComboboxProps) { + const [searchValue, setSearchValue] = React.useState(initialValue) + const debouncedSearch = useDebounce(searchValue, 300) + const [isOpen, setIsOpen] = React.useState(false) + const [searchResults, setSearchResults] = React.useState< + Omit< + NonNullable, + 'asSubject' | 'asPredicate' | 'asObject' + >[] + >([]) + + const { data: atomsData, isLoading } = useGetAtomsQuery( + { + where: { + label: { _ilike: `%${debouncedSearch}%` }, + }, + limit: 25, + }, + { + queryKey: ['atoms', debouncedSearch], + enabled: isOpen, + }, + ) + + React.useEffect(() => { + setSearchResults(atomsData?.atoms ?? []) + }, [atomsData]) + + const handleAtomSelect = ( + atom: Omit, + ) => { + onAtomSelect(atom as GetAtomQuery['atom']) + setIsOpen(false) + setSearchValue('') + setSearchResults([]) + } + + React.useEffect(() => { + console.log('Atom Data:', atomsData?.atoms) + setSearchResults(atomsData?.atoms ?? []) + }, [atomsData]) + + return ( +
+ + { + setSearchValue(value) + setIsOpen(true) + }} + onFocus={() => setIsOpen(true)} + className="text-base h-12" + /> + + + + + + {searchResults.map((atom, index) => ( + handleAtomSelect(atom)} + onSelect={() => handleAtomSelect(atom)} + /> + ))} + + + +
+ ) +} diff --git a/apps/portal/app/components/atom-type-select.tsx b/apps/portal/app/components/atom-type-select.tsx new file mode 100644 index 000000000..e486eeccc --- /dev/null +++ b/apps/portal/app/components/atom-type-select.tsx @@ -0,0 +1,49 @@ +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@0xintuition/1ui' + +export const ATOM_TYPES = [ + 'All', + 'Thing', + 'Person', + 'Account', + 'Organization', + 'Book', +] as const +export type AtomType = (typeof ATOM_TYPES)[number] + +interface AtomTypeSelectProps { + value: AtomType + onValueChange: (value: AtomType) => void +} + +export function AtomTypeSelect({ value, onValueChange }: AtomTypeSelectProps) { + return ( + + ) +} diff --git a/apps/portal/app/components/create-claim/create-claim-form.tsx b/apps/portal/app/components/create-claim/create-claim-form.tsx index d525c8b94..096ac3e97 100644 --- a/apps/portal/app/components/create-claim/create-claim-form.tsx +++ b/apps/portal/app/components/create-claim/create-claim-form.tsx @@ -11,8 +11,8 @@ import { Text, toast, } from '@0xintuition/1ui' -import { ClaimPresenter, IdentityPresenter } from '@0xintuition/api' -import { useGetTripleQuery } from '@0xintuition/graphql' +import { ClaimPresenter } from '@0xintuition/api' +import { GetAtomQuery, useGetTripleQuery } from '@0xintuition/graphql' import { IdentityPopover } from '@components/create-claim/create-claim-popovers' import CreateClaimReview from '@components/create-claim/create-claim-review' @@ -23,7 +23,6 @@ import { useCheckClaim } from '@lib/hooks/useCheckClaim' import { useCreateClaimConfig } from '@lib/hooks/useCreateClaimConfig' import { useCreateTriple } from '@lib/hooks/useCreateTriple' import { useGetWalletBalance } from '@lib/hooks/useGetWalletBalance' -import { useIdentityServerSearch } from '@lib/hooks/useIdentityServerSearch' import { initialTransactionState, transactionReducer, @@ -139,11 +138,10 @@ function CreateClaimForm({ const [lastTxHash, setLastTxHash] = useState(undefined) const [initialDeposit, setInitialDeposit] = useState('0') const [vaultId, setVaultId] = useState(undefined) - // const [searchQuery, setSearchQuery] = useState('') const [selectedIdentities, setSelectedIdentities] = useState<{ - subject: IdentityPresenter | null - predicate: IdentityPresenter | null - object: IdentityPresenter | null + subject: GetAtomQuery['atom'] | null + predicate: GetAtomQuery['atom'] | null + object: GetAtomQuery['atom'] | null }>({ subject: subject ?? null, predicate: predicate ?? null, @@ -156,9 +154,9 @@ function CreateClaimForm({ const { fees } = configData ?? {} const { data: claimCheckData, refetch: refetchClaimCheck } = useCheckClaim({ - subjectId: selectedIdentities.subject?.vault_id, - predicateId: selectedIdentities.predicate?.vault_id, - objectId: selectedIdentities.object?.vault_id, + subjectId: selectedIdentities.subject?.vaultId, + predicateId: selectedIdentities.predicate?.vaultId, + objectId: selectedIdentities.object?.vaultId, }) const { data: claimData, refetch: refetchClaim } = useGetTripleQuery( @@ -179,8 +177,6 @@ function CreateClaimForm({ const navigate = useNavigate() - const { setSearchQuery, identities, handleInput } = useIdentityServerSearch() - const publicClient = usePublicClient() const { address, chain } = useAccount() @@ -303,9 +299,9 @@ function CreateClaimForm({ selectedIdentities.object !== null ) { handleOnChainCreateTriple({ - subjectVaultId: selectedIdentities.subject.vault_id, - predicateVaultId: selectedIdentities.predicate.vault_id, - objectVaultId: selectedIdentities.object.vault_id, + subjectVaultId: selectedIdentities.subject?.vaultId ?? '', + predicateVaultId: selectedIdentities.predicate?.vaultId ?? '', + objectVaultId: selectedIdentities.object?.vaultId ?? '', }) } } catch (error: unknown) { @@ -314,35 +310,23 @@ function CreateClaimForm({ } const handleIdentitySelection = ( - identityType: ClaimElementType, - identity: IdentityPresenter, + type: ClaimElementType, + identity: GetAtomQuery['atom'], ) => { - setSelectedIdentities((prevState) => ({ - ...prevState, - [identityType]: identity, + setSelectedIdentities((prev) => ({ + ...prev, + [type]: identity, })) - setSearchQuery('') - // setIdentities([]) - if (identityType === ClaimElement.Subject) { + + if (type === 'subject') { setIsSubjectPopoverOpen(false) - } else if (identityType === ClaimElement.Predicate) { + } else if (type === 'predicate') { setIsPredicatePopoverOpen(false) - } else if (identityType === ClaimElement.Object) { + } else if (type === 'object') { setIsObjectPopoverOpen(false) } } - useEffect(() => { - if ( - !isSubjectPopoverOpen && - !isPredicatePopoverOpen && - !isObjectPopoverOpen - ) { - setSearchQuery('') - // setIdentities([]) - } - }, [isSubjectPopoverOpen, isPredicatePopoverOpen, isObjectPopoverOpen]) - const walletBalance = useGetWalletBalance( address ?? (wallet as `0x${string}`), ) @@ -386,13 +370,10 @@ function CreateClaimForm({ isObjectPopoverOpen={isSubjectPopoverOpen} setIsObjectPopoverOpen={setIsSubjectPopoverOpen} selectedIdentity={selectedIdentities.subject} - identities={identities} handleIdentitySelection={( identityType: ClaimElementType, - identity: IdentityPresenter, + identity: GetAtomQuery['atom'], ) => handleIdentitySelection(identityType, identity)} - setSearchQuery={setSearchQuery} - handleInput={handleInput} /> handleIdentitySelection(identityType, identity)} - setSearchQuery={setSearchQuery} - handleInput={handleInput} /> handleIdentitySelection(identityType, identity)} - setSearchQuery={setSearchQuery} - handleInput={handleInput} />
diff --git a/apps/portal/app/components/create-claim/create-claim-popovers.tsx b/apps/portal/app/components/create-claim/create-claim-popovers.tsx index 973e5a7c6..ccbe1d718 100644 --- a/apps/portal/app/components/create-claim/create-claim-popovers.tsx +++ b/apps/portal/app/components/create-claim/create-claim-popovers.tsx @@ -12,33 +12,28 @@ import { Trunctacular, useSidebarLayoutContext, } from '@0xintuition/1ui' -import { IdentityPresenter } from '@0xintuition/api' +import { GetAtomQuery } from '@0xintuition/graphql' -import { IdentitySearchCombobox } from '@components/identity/identity-search-combo-box' +import { AtomSearchComboboxExtended } from '@components/atom-search-combobox-extended' import { InfoTooltip } from '@components/info-tooltip' -import { globalCreateIdentityModalAtom } from '@lib/state/store' import { - getAtomDescription, - getAtomImage, - getAtomIpfsLink, - getAtomLabel, - sliceString, + getAtomDescriptionGQL, + getAtomIdGQL, + getAtomImageGQL, + getAtomIpfsLinkGQL, + getAtomLabelGQL, } from '@lib/utils/misc' import { ClaimElementType } from 'app/types' -import { useSetAtom } from 'jotai' interface IdentityPopoverProps { type: ClaimElementType isObjectPopoverOpen: boolean - setIsObjectPopoverOpen: (isOpen: boolean) => void - selectedIdentity?: IdentityPresenter | null - identities: IdentityPresenter[] + setIsObjectPopoverOpen: (open: boolean) => void + selectedIdentity: GetAtomQuery['atom'] | null handleIdentitySelection: ( - identityType: ClaimElementType, - identity: IdentityPresenter, + type: ClaimElementType, + identity: GetAtomQuery['atom'], ) => void - setSearchQuery: (query: string) => void - handleInput: (event: React.FormEvent) => Promise } export const IdentityPopover: React.FC = ({ @@ -46,12 +41,8 @@ export const IdentityPopover: React.FC = ({ isObjectPopoverOpen, setIsObjectPopoverOpen, selectedIdentity, - identities, handleIdentitySelection, - setSearchQuery, - handleInput, }) => { - const setCreateIdentityModalActive = useSetAtom(globalCreateIdentityModalAtom) const { isMobileView } = useSidebarLayoutContext() return ( @@ -88,20 +79,18 @@ export const IdentityPopover: React.FC = ({ @@ -111,30 +100,17 @@ export const IdentityPopover: React.FC = ({
@@ -148,15 +124,11 @@ export const IdentityPopover: React.FC = ({ align="center" sideOffset={5} > - setCreateIdentityModalActive(true)} - onIdentitySelect={(identity) => - handleIdentitySelection(type, identity) - } - onValueChange={setSearchQuery} - onInput={handleInput} - shouldFilter={false} + handleIdentitySelection(type, atom)} + placeholder={`Search for ${type}...`} + initialValue="" + className="w-[600px]" /> diff --git a/apps/portal/app/components/create-claim/create-claim-review.tsx b/apps/portal/app/components/create-claim/create-claim-review.tsx index dc828027c..00c945042 100644 --- a/apps/portal/app/components/create-claim/create-claim-review.tsx +++ b/apps/portal/app/components/create-claim/create-claim-review.tsx @@ -9,16 +9,16 @@ import { Separator, Text, } from '@0xintuition/1ui' -import { IdentityPresenter } from '@0xintuition/api' +import { GetAtomQuery } from '@0xintuition/graphql' import { InfoTooltip } from '@components/info-tooltip' import { StandardFees } from '@components/stake/stake-fee-breakdown' import { - getAtomDescription, - getAtomImage, - getAtomIpfsLink, - getAtomLabel, - getAtomLink, + getAtomDescriptionGQL, + getAtomImageGQL, + getAtomIpfsLinkGQL, + getAtomLabelGQL, + getAtomLinkGQL, } from '@lib/utils/misc' import { CreateClaimFeesType } from '@routes/resources+/create-claim' import { TransactionActionType } from 'app/types/transaction' @@ -27,9 +27,9 @@ import { formatUnits } from 'viem' interface CreateClaimReviewProps { dispatch: (action: TransactionActionType) => void selectedIdentities: { - subject?: IdentityPresenter | null - predicate?: IdentityPresenter | null - object?: IdentityPresenter | null + subject?: GetAtomQuery['atom'] | null + predicate?: GetAtomQuery['atom'] | null + object?: GetAtomQuery['atom'] | null } initialDeposit: string fees: CreateClaimFeesType @@ -203,67 +203,45 @@ const CreateClaimReview: React.FC = ({ (value: T, delay: number): T { + const [debouncedValue, setDebouncedValue] = useState(value) + + useEffect(() => { + const timer = setTimeout(() => setDebouncedValue(value), delay) + return () => clearTimeout(timer) + }, [value, delay]) + + return debouncedValue +} diff --git a/apps/portal/app/lib/state/store.ts b/apps/portal/app/lib/state/store.ts index 727d86064..843f6a262 100644 --- a/apps/portal/app/lib/state/store.ts +++ b/apps/portal/app/lib/state/store.ts @@ -1,4 +1,5 @@ import { ClaimPresenter, IdentityPresenter } from '@0xintuition/api' +import { GetAtomQuery } from '@0xintuition/graphql' import { VaultDetailsType } from 'app/types' import type { WritableAtom } from 'jotai' @@ -100,9 +101,9 @@ export const imageModalAtom = atom<{ export const createClaimModalAtom = atom<{ isOpen: boolean - subject?: IdentityPresenter | null - predicate?: IdentityPresenter | null - object?: IdentityPresenter | null + subject?: GetAtomQuery['atom'] | null + predicate?: GetAtomQuery['atom'] | null + object?: GetAtomQuery['atom'] | null }>({ isOpen: false, subject: null, diff --git a/apps/portal/app/lib/utils/misc.tsx b/apps/portal/app/lib/utils/misc.tsx index ca2b85710..d2b3af59e 100644 --- a/apps/portal/app/lib/utils/misc.tsx +++ b/apps/portal/app/lib/utils/misc.tsx @@ -2,6 +2,7 @@ import React from 'react' import { Icon, IconName, Text, Theme } from '@0xintuition/1ui' import { IdentityPresenter } from '@0xintuition/api' +import { GetAtomQuery } from '@0xintuition/graphql' import { SubmitFunction } from '@remix-run/react' import { BLOCK_EXPLORER_URL, IPFS_GATEWAY_URL, PATHS } from 'app/consts' @@ -427,6 +428,106 @@ export const getAtomId = (atom: IdentityPresenter) => { return atom.identity_id } +// atom GQL helpers +export const getAtomImageGQL = ( + atom: GetAtomQuery['atom'] | null | undefined, +) => { + if (!atom) { + return '' + } + return ( + atom?.image ?? + atom?.value?.person?.image ?? + atom?.value?.thing?.image ?? + atom?.value?.organization?.image ?? + '' + ) +} + +export const getAtomLabelGQL = ( + atom: GetAtomQuery['atom'] | null | undefined, +) => { + if (!atom) { + return '?' + } + return ( + atom.label ?? + atom.value?.person?.name ?? + atom.value?.thing?.name ?? + atom.value?.organization?.name ?? + atom.walletId ?? + atom.id ?? + '' + ) +} + +export const getAtomDescriptionGQL = ( + atom: GetAtomQuery['atom'] | null | undefined, +) => { + return ( + atom?.value?.person?.description ?? + atom?.value?.thing?.description ?? + atom?.value?.organization?.description ?? + '' + ) +} + +export const getAtomIpfsLinkGQL = ( + atom: GetAtomQuery['atom'] | null | undefined, +) => { + if (!atom) { + return '' + } + if (atom.type === ('Account' || 'Default')) { + return `${BLOCK_EXPLORER_URL}/address/${atom.walletId}` + } + if (atom.data?.startsWith('https')) { + return atom.data + } + if (atom.label?.startsWith('caip10')) { + const parts = atom.label.split(':') + const chainId = Number(parts[2]) + const address = parts[3] + const chain = extractChain({ + chains: Object.values(chains), + // @ts-ignore Ignoring type since viem doesn't provide proper typings for chain IDs + id: chainId, + }) + return chain?.blockExplorers?.default + ? `${chain.blockExplorers.default.url}/address/${address}` + : '' + } + return `${IPFS_GATEWAY_URL}/${atom.data?.replace('ipfs://', '')}` + return '' +} + +export const getAtomLinkGQL = ( + atom: GetAtomQuery['atom'] | null | undefined, + readOnly: boolean = false, +) => { + if (!atom) { + return '' + } + if (atom.type === ('Account' || 'Default')) { + return readOnly + ? `${PATHS.READONLY_PROFILE}/${atom.walletId}` + : `${PATHS.PROFILE}/${atom.walletId}` + } + return readOnly + ? `${PATHS.READONLY_IDENTITY}/${atom.vaultId}` + : `${PATHS.IDENTITY}/${atom.vaultId}` +} + +export const getAtomIdGQL = (atom: GetAtomQuery['atom']) => { + if (!atom) { + return '' + } + if (atom.type === ('Account' || 'Default')) { + return atom.walletId + } + return atom.id +} + export const calculatePointsFromFees = (totalProtocolFees: string): number => { const feesInEth = formatUnits(BigInt(totalProtocolFees), 18) const pointsPerEth = 10000000 diff --git a/packages/1ui/src/components/Icon/Icon.sprites.svg b/packages/1ui/src/components/Icon/Icon.sprites.svg index ddd136a9d..380827668 100644 --- a/packages/1ui/src/components/Icon/Icon.sprites.svg +++ b/packages/1ui/src/components/Icon/Icon.sprites.svg @@ -1276,5 +1276,11 @@ d="M12 21.75C12.8284 21.75 13.5 21.0784 13.5 20.25C13.5 19.4216 12.8284 18.75 12 18.75C11.1716 18.75 10.5 19.4216 10.5 20.25C10.5 21.0784 11.1716 21.75 12 21.75Z" fill="currentColor" /> + + + + diff --git a/packages/1ui/src/components/Icon/Icon.types.ts b/packages/1ui/src/components/Icon/Icon.types.ts index 1c5e10d9f..dcaab6655 100644 --- a/packages/1ui/src/components/Icon/Icon.types.ts +++ b/packages/1ui/src/components/Icon/Icon.types.ts @@ -141,4 +141,5 @@ export const IconName = { mirror: 'mirror', warpcast: 'warpcast', galxe: 'galxe', + eth: 'eth', } as const diff --git a/packages/graphql/src/fragments/atom.graphql b/packages/graphql/src/fragments/atom.graphql index 9dd3c1ff3..215f6c763 100644 --- a/packages/graphql/src/fragments/atom.graphql +++ b/packages/graphql/src/fragments/atom.graphql @@ -45,6 +45,7 @@ fragment AtomVaultDetails on atoms { vault { positionCount totalShares + currentSharePrice positions_aggregate { aggregate { count diff --git a/packages/graphql/src/generated/index.ts b/packages/graphql/src/generated/index.ts index 938223fae..6ea2ab76d 100644 --- a/packages/graphql/src/generated/index.ts +++ b/packages/graphql/src/generated/index.ts @@ -7510,6 +7510,7 @@ export type AtomVaultDetailsFragment = { __typename?: 'vaults' positionCount: number totalShares: any + currentSharePrice: any positions_aggregate: { __typename?: 'positions_aggregate' aggregate?: { @@ -8669,6 +8670,7 @@ export type GetAccountQuery = { __typename?: 'vaults' positionCount: number totalShares: any + currentSharePrice: any positions_aggregate: { __typename?: 'positions_aggregate' aggregate?: { @@ -9031,6 +9033,7 @@ export type GetAtomsQuery = { __typename?: 'vaults' positionCount: number totalShares: any + currentSharePrice: any positions_aggregate: { __typename?: 'positions_aggregate' aggregate?: { @@ -9114,6 +9117,7 @@ export type GetAtomsWithAggregatesQuery = { __typename?: 'vaults' positionCount: number totalShares: any + currentSharePrice: any positions_aggregate: { __typename?: 'positions_aggregate' aggregate?: { @@ -9208,6 +9212,7 @@ export type GetAtomQuery = { __typename?: 'vaults' positionCount: number totalShares: any + currentSharePrice: any positions_aggregate: { __typename?: 'positions_aggregate' aggregate?: { @@ -12313,6 +12318,7 @@ export const AtomVaultDetailsFragmentDoc = ` vault { positionCount totalShares + currentSharePrice positions_aggregate { aggregate { count @@ -17475,6 +17481,10 @@ export const AtomVaultDetails = { name: { kind: 'Name', value: 'positionCount' }, }, { kind: 'Field', name: { kind: 'Name', value: 'totalShares' } }, + { + kind: 'Field', + name: { kind: 'Name', value: 'currentSharePrice' }, + }, { kind: 'Field', name: { kind: 'Name', value: 'positions_aggregate' }, @@ -22356,6 +22366,10 @@ export const GetAccount = { name: { kind: 'Name', value: 'positionCount' }, }, { kind: 'Field', name: { kind: 'Name', value: 'totalShares' } }, + { + kind: 'Field', + name: { kind: 'Name', value: 'currentSharePrice' }, + }, { kind: 'Field', name: { kind: 'Name', value: 'positions_aggregate' }, @@ -24171,6 +24185,10 @@ export const GetAtoms = { name: { kind: 'Name', value: 'positionCount' }, }, { kind: 'Field', name: { kind: 'Name', value: 'totalShares' } }, + { + kind: 'Field', + name: { kind: 'Name', value: 'currentSharePrice' }, + }, { kind: 'Field', name: { kind: 'Name', value: 'positions_aggregate' }, @@ -24543,6 +24561,10 @@ export const GetAtomsWithAggregates = { name: { kind: 'Name', value: 'positionCount' }, }, { kind: 'Field', name: { kind: 'Name', value: 'totalShares' } }, + { + kind: 'Field', + name: { kind: 'Name', value: 'currentSharePrice' }, + }, { kind: 'Field', name: { kind: 'Name', value: 'positions_aggregate' }, @@ -24900,6 +24922,10 @@ export const GetAtom = { name: { kind: 'Name', value: 'positionCount' }, }, { kind: 'Field', name: { kind: 'Name', value: 'totalShares' } }, + { + kind: 'Field', + name: { kind: 'Name', value: 'currentSharePrice' }, + }, { kind: 'Field', name: { kind: 'Name', value: 'positions_aggregate' },