Skip to main content
InterwovenKit provides comprehensive TypeScript interfaces for portfolio data structures, enabling type-safe access to wallet balances, asset information, and cross-chain portfolio analytics.
These types structure wallet data across multiple chains, providing organized views of assets, balances, and valuations throughout the Initia ecosystem.

Core Portfolio Types

PortfolioAssetItem

Represents a single asset holding in the portfolio with complete balance and valuation information.
interface PortfolioAssetItem {
  // Asset identification
  symbol: string
  name: string  
  logoUrl: string
  denom: string
  
  // Balance information
  amount: string
  decimals: number
  quantity: string
  
  // Valuation
  price?: number
  value?: number
  
  // Chain context
  chain: PortfolioChainInfo
  
  // Asset metadata
  address?: string
  unlisted: boolean
}
symbol
string
Token symbol (e.g., “INIT”, “USDC”, “ETH”).
name
string
Full asset name (e.g., “Initia Token”, “USD Coin”).
logoUrl
string
URL to the asset’s logo image.
denom
string
On-chain denomination identifier (e.g., “uinit”, “uusdc”).
amount
string
Raw balance amount in base units (smallest denomination).
decimals
number
Number of decimal places for the asset.
quantity
string
Human-readable balance amount (accounting for decimals).
price
number | undefined
Current USD price per token unit. Undefined if price data is unavailable.
value
number | undefined
Total USD value of the holding (quantity × price). Undefined if price is unavailable.
chain
PortfolioChainInfo
Information about the chain where this asset is held.
address
string | undefined
Contract address for token contracts. Undefined for native tokens.
unlisted
boolean
True if the asset is not registered in the chain registry.

PortfolioAssetGroup

Groups the same asset across multiple chains for aggregated display.
interface PortfolioAssetGroup {
  symbol: string
  logoUrl: string
  assets: PortfolioAssetItem[]
}
symbol
string
Common symbol shared by all assets in the group.
logoUrl
string
Representative logo URL for the asset group.
assets
PortfolioAssetItem[]
Array of individual asset holdings across different chains with the same symbol.

PortfolioChainItem

Represents a chain’s total portfolio value and metadata.
interface PortfolioChainItem {
  chainId: string
  chainName: string
  logoUrl: string
  value: number
}
chainId
string
Unique chain identifier.
chainName
string
Human-readable chain name.
logoUrl
string
URL to the chain’s logo image.
value
number
Total USD value of all assets held on this chain.

Supporting Types

PortfolioChainInfo

Basic chain information embedded in asset items.
interface PortfolioChainInfo {
  chainId: string
  chainName: string
  logoUrl: string
}

PortfolioAssetGroupInfo

Minimal asset group metadata.
interface PortfolioAssetGroupInfo {
  symbol: string
  logoUrl: string
}

Usage Examples

Type Usage Example

import type { PortfolioAssetGroup } from "@initia/interwovenkit-react"

function calculateGroupValue(group: PortfolioAssetGroup): number {
  return group.assets.reduce((sum, asset) => sum + (asset.value || 0), 0)
}

function getAssetsByChain(group: PortfolioAssetGroup): Record<string, PortfolioAssetItem[]> {
  return group.assets.reduce((acc, asset) => {
    const chainId = asset.chain.chainId
    if (!acc[chainId]) acc[chainId] = []
    acc[chainId].push(asset)
    return acc
  }, {} as Record<string, PortfolioAssetItem[]>)
}

Utility Functions

import type { PortfolioAssetItem, PortfolioAssetGroup } from "@initia/interwovenkit-react"

function getTotalValue(assets: PortfolioAssetItem[]): number {
  return assets.reduce((sum, asset) => sum + (asset.value || 0), 0)
}

function sortAssetsByValue(groups: PortfolioAssetGroup[]): PortfolioAssetGroup[] {
  return groups.sort((a, b) => {
    const aValue = getTotalValue(a.assets)
    const bValue = getTotalValue(b.assets)
    return bValue - aValue
  })
}

Asset Filtering

import type { PortfolioAssetItem } from "@initia/interwovenkit-react"

class AssetFilters {
  static hasValue(asset: PortfolioAssetItem): boolean {
    return asset.value !== undefined && asset.value > 0
  }

  static isListed(asset: PortfolioAssetItem): boolean {
    return !asset.unlisted
  }

  static byChain(chainId: string) {
    return (asset: PortfolioAssetItem): boolean => 
      asset.chain.chainId === chainId
  }

  static bySymbol(symbol: string) {
    return (asset: PortfolioAssetItem): boolean =>
      asset.symbol.toLowerCase() === symbol.toLowerCase()
  }

  static byMinimumValue(minValue: number) {
    return (asset: PortfolioAssetItem): boolean =>
      (asset.value || 0) >= minValue
  }

  static byMinimumBalance(minBalance: string) {
    return (asset: PortfolioAssetItem): boolean =>
      parseFloat(asset.quantity) >= parseFloat(minBalance)
  }
}

// Usage examples
const valuedAssets = assets.filter(AssetFilters.hasValue)
const listedAssets = assets.filter(AssetFilters.isListed)
const mainnetAssets = assets.filter(AssetFilters.byChain('interwoven-1'))
const initAssets = assets.filter(AssetFilters.bySymbol('INIT'))
const significantHoldings = assets.filter(AssetFilters.byMinimumValue(100))

Type Guards and Utilities

Type Guards

import type { PortfolioAssetItem } from "@initia/interwovenkit-react"

function hasPrice(asset: PortfolioAssetItem): asset is PortfolioAssetItem & { 
  price: number; 
  value: number 
} {
  return asset.price !== undefined && asset.value !== undefined
}

function isTokenContract(asset: PortfolioAssetItem): asset is PortfolioAssetItem & { 
  address: string 
} {
  return asset.address !== undefined
}

function isListedAsset(asset: PortfolioAssetItem): boolean {
  return !asset.unlisted
}

// Usage
if (hasPrice(asset)) {
  console.log(`${asset.symbol}: $${asset.price} = $${asset.value}`)
}

if (isTokenContract(asset)) {
  console.log(`Contract: ${asset.address}`)
}

Conversion Utilities

import type { PortfolioAssetItem } from "@initia/interwovenkit-react"

function toBaseUnits(asset: PortfolioAssetItem, humanAmount: string): string {
  const multiplier = Math.pow(10, asset.decimals)
  return (parseFloat(humanAmount) * multiplier).toString()
}

function fromBaseUnits(asset: PortfolioAssetItem, baseAmount: string): string {
  const divisor = Math.pow(10, asset.decimals)
  return (parseInt(baseAmount) / divisor).toString()
}

function formatAssetAmount(asset: PortfolioAssetItem, precision: number = 6): string {
  const amount = parseFloat(asset.quantity)
  return amount.toLocaleString(undefined, {
    minimumFractionDigits: 0,
    maximumFractionDigits: precision
  })
}

function formatAssetValue(asset: PortfolioAssetItem): string | null {
  if (!asset.value) return null
  
  return asset.value.toLocaleString(undefined, {
    style: 'currency',
    currency: 'USD',
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
  })
}
Use type guards to safely access optional properties like price and value. This ensures your components handle both priced and unpriced assets gracefully.
Be aware that unlisted assets may not have accurate price information or may represent test tokens. Always check the unlisted flag when displaying asset values to users.

Portfolio Composition Patterns

Custom Portfolio Hook

import { usePortfolio } from "@initia/interwovenkit-react"
import type { PortfolioAssetItem } from "@initia/interwovenkit-react"

function usePortfolioSummary() {
  const portfolio = usePortfolio()

  const summary = useMemo(() => {
    const allAssets = portfolio.assetGroups.flatMap(group => group.assets)
    const valuedAssets = allAssets.filter(asset => asset.value !== undefined)
    
    return {
      totalAssets: allAssets.length,
      totalValue: portfolio.totalValue,
      valuedAssets: valuedAssets.length,
      unlistedAssets: portfolio.unlistedAssets.length,
      chainCount: portfolio.chainsByValue.length,
      topAsset: allAssets.reduce((top, current) => 
        (current.value || 0) > (top.value || 0) ? current : top
      ),
    }
  }, [portfolio])

  return { ...portfolio, summary }
}
These type definitions provide complete type safety for all portfolio operations, ensuring proper handling of asset data, chain information, and valuation throughout your application.