Skip to content
OpenSmartRoute
Skillv1.0.0

alchemy-core-workflow-a

Build a complete wallet portfolio tracker using Alchemy Enhanced APIs. Use when implementing token balance dashboards, NFT galleries, transaction history views, or wallet analytics applications. Trigg

by jeremylongshore(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from jeremylongshore/tons-of-skills-marketplace (plugins/saas-packs/alchemy-pack/skills/alchemy-core-workflow-a/SKILL.md). Install upstream with npx skills add jeremylongshore/tons-of-skills-marketplace --skill alchemy-core-workflow-a. Copyright stays with the author (MIT).

Alchemy Core Workflow A — Wallet Portfolio Tracker

Overview

Primary workflow: build a wallet portfolio tracker using Alchemy's Enhanced APIs. Combines getTokenBalances, getNftsForOwner, getAssetTransfers, and token metadata to create a complete wallet view across ERC-20, ERC-721, and ERC-1155 assets.

Prerequisites

  • Completed alchemy-install-auth setup
  • alchemy-sdk installed
  • Understanding of Ethereum address format and token standards

Instructions

Step 1: Portfolio Data Fetcher

// src/portfolio/fetcher.ts
import { Alchemy, Network, AssetTransfersCategory } from 'alchemy-sdk';

const alchemy = new Alchemy({
  apiKey: process.env.ALCHEMY_API_KEY,
  network: Network.ETH_MAINNET,
});

interface TokenHolding {
  contractAddress: string;
  symbol: string;
  name: string;
  balance: number;
  decimals: number;
}

interface NftHolding {
  contractAddress: string;
  collectionName: string;
  tokenId: string;
  name: string;
  imageUrl: string | null;
}

interface WalletPortfolio {
  address: string;
  ethBalance: string;
  tokens: TokenHolding[];
  nfts: NftHolding[];
  recentTransactions: any[];
  fetchedAt: string;
}

async function fetchPortfolio(address: string): Promise<WalletPortfolio> {
  // Parallel fetch all portfolio data
  const [ethBalance, tokenBalances, nftResponse, transfers] = await Promise.all([
    alchemy.core.getBalance(address),
    alchemy.core.getTokenBalances(address),
    alchemy.nft.getNftsForOwner(address, { pageSize: 100 }),
    alchemy.core.getAssetTransfers({
      fromAddress: address,
      category: [
        AssetTransfersCategory.EXTERNAL,
        AssetTransfersCategory.ERC20,
        AssetTransfersCategory.ERC721,
      ],
      maxCount: 25,
      order: 'desc',
    }),
  ]);

  // Resolve token metadata
  const tokens: TokenHolding[] = [];
  for (const tb of tokenBalances.tokenBalances) {
    if (tb.tokenBalance && tb.tokenBalance !== '0x0') {
      const metadata = await alchemy.core.getTokenMetadata(tb.contractAddress);
      const balance = parseInt(tb.tokenBalance, 16) / Math.pow(10, metadata.decimals || 18);
      if (balance > 0.001) {  // Filter dust
        tokens.push({
          contractAddress: tb.contractAddress,
          symbol: metadata.symbol || 'UNKNOWN',
          name: metadata.name || 'Unknown Token',
          balance,
          decimals: metadata.decimals || 18,
        });
      }
    }
  }

  // Map NFTs
  const nfts: NftHolding[] = nftResponse.ownedNfts.map(nft => ({
    contractAddress: nft.contract.address,
    collectionName: nft.contract.name || 'Unknown Collection',
    tokenId: nft.tokenId,
    name: nft.name || `#${nft.tokenId}`,
    imageUrl: nft.image?.cachedUrl || null,
  }));

  return {
    address,
    ethBalance: (parseInt(ethBalance.toString()) / 1e18).toFixed(6),
    tokens: tokens.sort((a, b) => b.balance - a.balance),
    nfts,
    recentTransactions: transfers.transfers,
    fetchedAt: new Date().toISOString(),
  };
}

export { fetchPortfolio, WalletPortfolio };

Step 2: Transaction History Analyzer

// src/portfolio/transactions.ts
import { Alchemy, Network, AssetTransfersCategory, SortingOrder } from 'alchemy-sdk';

const alchemy = new Alchemy({
  apiKey: process.env.ALCHEMY_API_KEY,
  network: Network.ETH_MAINNET,
});

async function getTransactionHistory(address: string, maxCount: number = 50) {
  // Get both sent and received transactions
  const [sent, received] = await Promise.all([
    alchemy.core.getAssetTransfers({
      fromAddress: address,
      category: [AssetTransfersCategory.EXTERNAL, AssetTransfersCategory.ERC20],
      maxCount,
      order: 'desc',
    }),
    alchemy.core.getAssetTransfers({
      toAddress: address,
      category: [AssetTransfersCategory.EXTERNAL, AssetTransfersCategory.ERC20],
      maxCount,
      order: 'desc',
    }),
  ]);

  // Merge and sort by block number
  const allTransfers = [
    ...sent.transfers.map(t => ({ ...t, direction: 'sent' as const })),
    ...received.transfers.map(t => ({ ...t, direction: 'received' as const })),
  ].sort((a, b) => parseInt(b.blockNum) - parseInt(a.blockNum));

  return allTransfers;
}

export { getTransactionHistory };

Step 3: Multi-Chain Portfolio Aggregator

// src/portfolio/multi-chain.ts
import { Alchemy, Network } from 'alchemy-sdk';

const CHAINS = [
  { name: 'Ethereum', network: Network.ETH_MAINNET },
  { name: 'Polygon', network: Network.MATIC_MAINNET },
  { name: 'Arbitrum', network: Network.ARB_MAINNET },
  { name: 'Optimism', network: Network.OPT_MAINNET },
  { name: 'Base', network: Network.BASE_MAINNET },
];

async function getMultiChainBalances(address: string) {
  const results = await Promise.allSettled(
    CHAINS.map(async (chain) => {
      const client = new Alchemy({
        apiKey: process.env.ALCHEMY_API_KEY,
        network: chain.network,
      });
      const balance = await client.core.getBalance(address);
      const tokens = await client.core.getTokenBalances(address);
      const nonZeroTokens = tokens.tokenBalances.filter(
        t => t.tokenBalance && t.tokenBalance !== '0x0'
      );
      return {
        chain: chain.name,
        nativeBalance: (parseInt(balance.toString()) / 1e18).toFixed(6),
        tokenCount: nonZeroTokens.length,
      };
    })
  );

  return results
    .filter((r): r is PromiseFulfilledResult<any> => r.status === 'fulfilled')
    .map(r => r.value);
}

export { getMultiChainBalances };

Output

  • Complete wallet portfolio: ETH + ERC-20 tokens + NFTs
  • Transaction history with sent/received classification
  • Multi-chain balance aggregation across 5 networks
  • Sorted holdings with dust filtering

Examples

For a development demonstration, call fetchPortfolio with a publicly known test address or an address you control; never request a customer address until the product’s privacy notice and consent flow are in place. Render the returned network, timestamp, balances, and token counts, and cache metadata so repeated page loads do not exhaust the request budget. Verify that a zero-balance address produces an empty but valid portfolio and that a simulated 429 uses bounded backoff. If a chain query fails, show that chain as unavailable while retaining successful chains instead of inventing a consolidated balance.

Error Handling

Error Cause Solution
429 Rate Limit Too many metadata calls Batch with delays or cache metadata
Empty token list Address has no tokens Verify address is correct
Missing NFT images IPFS gateway timeout Use Alchemy's cached URL fallback
getAssetTransfers empty Wrong category filter Include all relevant categories

Resources

Next Steps

For NFT minting and smart contract interaction, see alchemy-core-workflow-b.

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/jeremylongshore-tons-of-skills-marketplace-alchemy-core-171bea/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

jeremylongshore-tons-of-skills-marketplace-alchemy-core-171bea.ocm.jsonjson
{
  "ocm": "1",
  "id": "jeremylongshore-tons-of-skills-marketplace-alchemy-core-171bea",
  "kind": "skill",
  "name": "alchemy-core-workflow-a",
  "description": "Build a complete wallet portfolio tracker using Alchemy Enhanced APIs. Use when implementing token balance dashboards, NFT galleries, transaction history views, or wallet analytics applications. Trigger: \"alchemy wallet tracker\", \"alchemy portfolio\", \"alchemy token dashboard\", \"alchemy transaction history\", \"build dApp with alchemy\".",
  "publisher": "jeremylongshore",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "finance",
      "data_analysis"
    ],
    "tags": [
      "skill-md",
      "saas",
      "blockchain",
      "web3",
      "alchemy",
      "defi",
      "portfolio",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Build a complete wallet portfolio tracker using Alchemy Enhanced APIs. Use when implementing token balance dashboards, NFT galleries, transaction history views, or wallet analytics applications. Trigger: \"alchemy wallet tracker\", \"alchemy portfolio\", \"alchemy token dashboard\", \"alchemy transaction history\", \"build dApp with alchemy\"."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/jeremylongshore/tons-of-skills-marketplace",
      "path": "plugins/saas-packs/alchemy-pack/skills/alchemy-core-workflow-a/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/jeremylongshore/tons-of-skills-marketplace/blob/HEAD/plugins/saas-packs/alchemy-pack/skills/alchemy-core-workflow-a/SKILL.md",
      "key": "jeremylongshore/tons-of-skills-marketplace/plugins/saas-packs/alchemy-pack/skills/alchemy-core-workflow-a/SKILL.md"
    },
    "compatibility": "Designed for Claude Code",
    "allowed_tools": [
      "Read,",
      "Write,",
      "Edit,",
      "Bash(npm:*),",
      "Grep"
    ],
    "license": "MIT"
  },
  "instructions": "# Alchemy Core Workflow A — Wallet Portfolio Tracker\n\n## Overview\n\nPrimary workflow: build a wallet portfolio tracker using Alchemy's Enhanced APIs. Combines `getTokenBalances`, `getNftsForOwner`, `getAssetTransfers`, and token metadata to create a complete wallet view across ERC-20, ERC-721, and ERC-1155 assets.\n\n## Prerequisites\n\n- Completed `alchemy-install-auth` setup\n- `alchemy-sdk` installed\n- Understanding of Ethereum address format and token standards\n\n## Instructions\n\n### Step 1: Portfolio Data Fetcher\n\n```typescript\n// src/portfolio/fetcher.ts\nimport { Alchemy, Network, AssetTransfer",
  "cost": {
    "context_tokens": 1771
  }
}

Fetch it by URL: GET /api/v1/registry/jeremylongshore-tons-of-skills-marketplace-alchemy-core-171bea/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.