diff --git a/components/entities/activity/ActivityAddress.vue b/components/entities/activity/ActivityAddress.vue new file mode 100644 index 000000000..f56791fd2 --- /dev/null +++ b/components/entities/activity/ActivityAddress.vue @@ -0,0 +1,174 @@ + + + diff --git a/components/entities/activity/ActivityCategoryFilters.vue b/components/entities/activity/ActivityCategoryFilters.vue new file mode 100644 index 000000000..73c0c486d --- /dev/null +++ b/components/entities/activity/ActivityCategoryFilters.vue @@ -0,0 +1,45 @@ + + + diff --git a/components/entities/activity/ActivityEventRow.vue b/components/entities/activity/ActivityEventRow.vue new file mode 100644 index 000000000..29e3af50e --- /dev/null +++ b/components/entities/activity/ActivityEventRow.vue @@ -0,0 +1,675 @@ + + + + + diff --git a/components/entities/activity/ActivityFeed.vue b/components/entities/activity/ActivityFeed.vue new file mode 100644 index 000000000..73bdc3751 --- /dev/null +++ b/components/entities/activity/ActivityFeed.vue @@ -0,0 +1,464 @@ + + + + + diff --git a/components/entities/activity/activityEventRowDetails.ts b/components/entities/activity/activityEventRowDetails.ts new file mode 100644 index 000000000..14a3a2e71 --- /dev/null +++ b/components/entities/activity/activityEventRowDetails.ts @@ -0,0 +1,36 @@ +import type { ActivityEvent } from '@eulerxyz/euler-v2-sdk' +import type { ActivityLiquidationDisplayDetails } from '~/utils/activity-display' + +const QUEUE_EVENT_TYPES: readonly ActivityEvent['type'][] = [ + 'set_supply_queue', + 'set_withdraw_queue', +] + +export const getActivityAddressCollectionSummary = ( + eventType: ActivityEvent['type'], + count: number, +): string | null => { + if (count <= 1) return null + return QUEUE_EVENT_TYPES.includes(eventType) + ? `${count} strategies` + : `${count} addresses` +} + +export const getActivityLiquidationBonusEntry = ( + display: ActivityLiquidationDisplayDetails | null, +) => { + if (!display?.bonus) return null + return { + kind: 'valuation' as const, + key: 'liquidation-bonus', + label: 'Liquidator bonus', + value: display.bonus, + valueClass: display.bonusTone === 'positive' + ? 'text-accent-600' + : display.bonusTone === 'negative' + ? 'text-error-500' + : undefined, + valueTitle: display.bonusTitle, + addresses: undefined, + } +} diff --git a/components/entities/asset/AssetAvatar.vue b/components/entities/asset/AssetAvatar.vue index 78e83ef79..f69041c34 100644 --- a/components/entities/asset/AssetAvatar.vue +++ b/components/entities/asset/AssetAvatar.vue @@ -3,7 +3,7 @@ import { getAssetLogoUrl } from '~/composables/useTokenList' const { asset, size, iconUrl } = defineProps<{ asset: { address: string, symbol: string } | { address: string, symbol: string }[] - size?: '16' | '20' | '28' | '36' | '38' | '40' | '46' + size?: '16' | '20' | '28' | '32' | '36' | '38' | '40' | '46' iconUrl?: string }>() diff --git a/components/entities/portfolio/PortfolioBorrowItem.vue b/components/entities/portfolio/PortfolioBorrowItem.vue index 98be8484c..8a8bf4820 100644 --- a/components/entities/portfolio/PortfolioBorrowItem.vue +++ b/components/entities/portfolio/PortfolioBorrowItem.vue @@ -31,9 +31,11 @@ import { resolveComponent, type Component } from 'vue' const { position, clickable = true } = defineProps<{ position: PortfolioBorrowPosition, clickable?: boolean }>() const { getVaultCategory, isVerifiedVault } = useVaultRegistry() -const { address } = useWagmi() const { portfolioAddress } = useEulerAccount() -const ownerAddress = computed(() => portfolioAddress.value || address.value || '') +// portfolioAddress is already the spy-safe acting address; a wallet +// fallback here would compute wrong position indices while a spy +// candidate is still verifying. +const ownerAddress = computed(() => portfolioAddress.value) const subAccountIndex = computed(() => { if (!ownerAddress.value || !position.subAccount) return 0 return getSubAccountIndex(getAddress(ownerAddress.value), getAddress(position.subAccount)) diff --git a/components/entities/portfolio/PortfolioEarnItem.vue b/components/entities/portfolio/PortfolioEarnItem.vue index cf508ddb6..c471173cd 100644 --- a/components/entities/portfolio/PortfolioEarnItem.vue +++ b/components/entities/portfolio/PortfolioEarnItem.vue @@ -15,9 +15,11 @@ import { getVaultIntrinsicApyInfo } from '~/utils/vault-intrinsic-apy' const { position } = defineProps<{ position: PortfolioSavingsPosition }>() const modal = useModal() -const { address } = useWagmi() const { portfolioAddress } = useEulerAccount() -const ownerAddress = computed(() => portfolioAddress.value || address.value || '') +// portfolioAddress is already the spy-safe acting address; a wallet +// fallback here would compute wrong position indices while a spy +// candidate is still verifying. +const ownerAddress = computed(() => portfolioAddress.value) const subAccountIndex = computed(() => { if (!ownerAddress.value || !position.subAccount) return 0 return getSubAccountIndex(getAddress(ownerAddress.value), getAddress(position.subAccount)) diff --git a/components/entities/portfolio/PortfolioSavingItem.vue b/components/entities/portfolio/PortfolioSavingItem.vue index adeed29e2..31ac2ff24 100644 --- a/components/entities/portfolio/PortfolioSavingItem.vue +++ b/components/entities/portfolio/PortfolioSavingItem.vue @@ -15,9 +15,11 @@ import { getVaultIntrinsicApyInfo } from '~/utils/vault-intrinsic-apy' const { position } = defineProps<{ position: PortfolioSavingsPosition }>() const modal = useModal() -const { address } = useWagmi() const { portfolioAddress } = useEulerAccount() -const ownerAddress = computed(() => portfolioAddress.value || address.value || '') +// portfolioAddress is already the spy-safe acting address; a wallet +// fallback here would compute wrong position indices while a spy +// candidate is still verifying. +const ownerAddress = computed(() => portfolioAddress.value) const subAccountIndex = computed(() => { if (!ownerAddress.value || !position.subAccount) return 0 return getSubAccountIndex(getAddress(ownerAddress.value), getAddress(position.subAccount)) diff --git a/components/entities/portfolio/PortfolioUnsupportedBorrowItem.vue b/components/entities/portfolio/PortfolioUnsupportedBorrowItem.vue index 4c13f2c31..0f86c0ae5 100644 --- a/components/entities/portfolio/PortfolioUnsupportedBorrowItem.vue +++ b/components/entities/portfolio/PortfolioUnsupportedBorrowItem.vue @@ -15,9 +15,11 @@ import { useEulerProductOfVault } from '~/composables/useEulerLabels' const { position } = defineProps<{ position: PortfolioBorrowPosition }>() -const { address } = useWagmi() const { portfolio, portfolioAddress } = useEulerAccount() -const ownerAddress = computed(() => portfolioAddress.value || address.value || '') +// portfolioAddress is already the spy-safe acting address; a wallet +// fallback here would compute wrong position indices while a spy +// candidate is still verifying. +const ownerAddress = computed(() => portfolioAddress.value) const subAccountIndex = computed(() => { if (!ownerAddress.value || !position.subAccount) return 0 return getSubAccountIndex(getAddress(ownerAddress.value), getAddress(position.subAccount)) diff --git a/components/entities/vault/ChooseCollateralModal.vue b/components/entities/vault/ChooseCollateralModal.vue index b2dc719dd..4eb83661e 100644 --- a/components/entities/vault/ChooseCollateralModal.vue +++ b/components/entities/vault/ChooseCollateralModal.vue @@ -34,12 +34,14 @@ const { }>() const { isEscrowVault } = useVaultRegistry() -const { address } = useWagmi() const { portfolioAddress } = useEulerAccount() const searchQuery = ref('') const selectedIdx = ref(selected) -const ownerAddress = computed(() => portfolioAddress.value || address.value || '') +// portfolioAddress is already the spy-safe acting address; a wallet +// fallback here would compute wrong position indices while a spy +// candidate is still verifying. +const ownerAddress = computed(() => portfolioAddress.value) const getOptionLabel = (option: CollateralOption) => { if (option.vaultAddress && isEscrowVault(option.vaultAddress)) return 'Escrowed collateral' if (option.label) return option.label diff --git a/components/entities/vault/VaultLabelsAndAssets.vue b/components/entities/vault/VaultLabelsAndAssets.vue index 3e2656d83..1f95e6088 100644 --- a/components/entities/vault/VaultLabelsAndAssets.vue +++ b/components/entities/vault/VaultLabelsAndAssets.vue @@ -8,7 +8,8 @@ import { getAddress } from 'viem' const { vault, assets, size, assetsLabel, pairVault, back, backFallback } = defineProps<{ vault?: EVault | EulerEarn | SecuritizeCollateralVault assets: VaultAsset[] - size?: 'large' + /** `small` renders a compact identity for list contexts (e.g. activity rows) where surrounding content carries the emphasis. */ + size?: 'large' | 'small' assetsLabel?: string pairVault?: EVault back?: boolean @@ -91,7 +92,7 @@ const displayAssetsLabel = computed(() => assetsLabel || assets.map(asset => ass