Skip to main content

Overview

The Portfolio API provides functions for managing cryptocurrency portfolios in the browser’s localStorage. It handles portfolio creation, asset management, and position tracking with automatic persistence. File location: src/api/portfolio/portfolioApi.js

Configuration

  • Storage: Browser localStorage
  • Storage key: crypto_dash_portfolios
  • Default allocation: $2,000 USD per asset
  • Data format: JSON array of portfolio objects

Functions

getOrCreatePrimaryPortfolio

Retrieves the primary portfolio or creates a new one with default assets if none exists.
import { getOrCreatePrimaryPortfolio } from './api/portfolio/portfolioApi'
import { getTopMarketCoins } from './api/market/marketApi'

const marketCoins = await getTopMarketCoins({ perPage: 100 })
const portfolio = getOrCreatePrimaryPortfolio(marketCoins)

console.log('Portfolio:', portfolio.name)
console.log('Positions:', portfolio.positions.length)

Signature

getOrCreatePrimaryPortfolio(marketCoins): Object

Parameters

marketCoins
array
default:"[]"
Array of market coin objects from getTopMarketCoins(). Used to initialize default positions with current prices.Each coin should have:
  • id (string) - Coin identifier
  • current_price (number) - Current price in USD

Returns

portfolio
object
Portfolio object
id
string
Portfolio identifier (e.g., main)
name
string
Portfolio display name (e.g., Portafolio Principal)
positions
array
Array of asset positions
assetId
string
Coin identifier (e.g., bitcoin, ethereum)
investedUsd
number
Amount invested in USD
amount
number
Quantity of the asset owned (calculated as investedUsd / currentPrice)
createdAt
string
ISO 8601 timestamp of position creation
createdAt
string
ISO 8601 timestamp of portfolio creation

Default Assets

When creating a new portfolio, the function attempts to add these preferred assets (if available in marketCoins):
  1. bitcoin
  2. ethereum
  3. solana
  4. binancecoin
  5. ripple
If fewer than 5 preferred assets are available, it fills remaining slots from the top market coins list.

Example Return Value

{
  "id": "main",
  "name": "Portafolio Principal",
  "positions": [
    {
      "assetId": "bitcoin",
      "investedUsd": 2000,
      "amount": 0.04444,
      "createdAt": "2026-03-05T18:30:00.000Z"
    },
    {
      "assetId": "ethereum",
      "investedUsd": 2000,
      "amount": 0.8,
      "createdAt": "2026-03-05T18:30:00.000Z"
    }
  ],
  "createdAt": "2026-03-05T18:30:00.000Z"
}

addAssetToPrimaryPortfolio

Adds a new asset position to the primary portfolio.
import { addAssetToPrimaryPortfolio } from './api/portfolio/portfolioApi'

const updatedPortfolio = addAssetToPrimaryPortfolio({
  assetId: 'cardano',
  currentPrice: 0.75,
  allocationUsd: 1500
})

if (updatedPortfolio) {
  console.log('Asset added successfully')
} else {
  console.log('No portfolio exists or asset already in portfolio')
}

Signature

addAssetToPrimaryPortfolio(options): Object | null

Parameters

assetId
string
required
Coin identifier to add (e.g., cardano, polkadot)
currentPrice
number
required
Current price of the asset in USD. Used to calculate the amount of coins purchased.
allocationUsd
number
default:"2000"
Amount to invest in USD. Defaults to DEFAULT_ALLOCATION_USD (2000).

Returns

portfolio
object | null
Updated portfolio object or null if:
  • No primary portfolio exists
  • Asset already exists in the portfolio
Same structure as getOrCreatePrimaryPortfolio() return value.

Behavior

  • Duplicate check: Returns existing portfolio unchanged if asset already exists
  • Persistence: Automatically saves to localStorage
  • Amount calculation: amount = allocationUsd / currentPrice
  • Safe defaults: Uses fallback values if price or allocation are invalid

getDefaultAllocationUsd

Returns the default USD allocation amount used when adding assets.
import { getDefaultAllocationUsd } from './api/portfolio/portfolioApi'

const defaultAmount = getDefaultAllocationUsd()
console.log('Default allocation:', defaultAmount) // 2000

Signature

getDefaultAllocationUsd(): number

Returns

allocation
number
Default allocation amount in USD (2000)

Data Storage

Storage Format

Portfolios are stored in localStorage as a JSON array:
[
  {
    "id": "main",
    "name": "Portafolio Principal",
    "positions": [
      {
        "assetId": "bitcoin",
        "investedUsd": 2000,
        "amount": 0.04444,
        "createdAt": "2026-03-05T18:30:00.000Z"
      }
    ],
    "createdAt": "2026-03-05T18:30:00.000Z"
  }
]

Storage Key

const PORTFOLIO_STORAGE_KEY = 'crypto_dash_portfolios'

Error Handling

The API handles storage errors gracefully:
  • Invalid JSON: Returns empty array []
  • Missing data: Returns empty array []
  • Non-array data: Returns empty array []
// Safe parsing with error recovery
function safeParsePortfolios(rawValue) {
  try {
    const parsed = JSON.parse(rawValue)
    return Array.isArray(parsed) ? parsed : []
  } catch {
    return []
  }
}

Implementation Details

Position Calculation

When creating or adding a position, the amount of coins is calculated as:
const amount = allocationUsd / currentPrice
Example:
  • Allocation: $2,000 USD
  • Bitcoin price: $45,000
  • Amount: 2000 / 45000 = 0.04444 BTC

Timestamp Format

All timestamps use ISO 8601 format:
const timestamp = new Date().toISOString()
// "2026-03-05T18:30:00.000Z"

Primary Portfolio

The application currently supports a single primary portfolio:
  • Always stored at index 0 in the portfolios array
  • ID: main
  • Name: Portafolio Principal

Complete Example

import { 
  getOrCreatePrimaryPortfolio, 
  addAssetToPrimaryPortfolio,
  getDefaultAllocationUsd 
} from './api/portfolio/portfolioApi'
import { getTopMarketCoins } from './api/market/marketApi'

// Initialize portfolio with market data
const marketCoins = await getTopMarketCoins({ perPage: 100 })
const portfolio = getOrCreatePrimaryPortfolio(marketCoins)

console.log('Initial positions:', portfolio.positions.length)

// Add a new asset
const cardano = marketCoins.find(coin => coin.id === 'cardano')
if (cardano) {
  const updated = addAssetToPrimaryPortfolio({
    assetId: 'cardano',
    currentPrice: cardano.current_price,
    allocationUsd: getDefaultAllocationUsd()
  })
  
  console.log('Updated positions:', updated?.positions.length)
}

// Calculate portfolio value
const portfolioValue = portfolio.positions.reduce((total, position) => {
  const coin = marketCoins.find(c => c.id === position.assetId)
  const currentValue = position.amount * (coin?.current_price || 0)
  return total + currentValue
}, 0)

console.log('Portfolio value:', portfolioValue)

Build docs developers (and LLMs) love