Skip to main content

On-chain Assets

The ONE SDK engine client provides programmatic APIs to fetch on-chain balances and portfolio analytics for any wallet address across all supported chains.

getWalletBalance

Fetch token balances for a wallet address. Optionally scope the query to specific chains.

import { useOneClient, CHAIN_IDS } from '@one_deploy/sdk';

function BalanceFetcher() {
const { engineClient } = useOneClient();

const fetchAllChains = async () => {
// Fetch balances across all supported chains
const balances = await engineClient.getWalletBalance(
'0x1234...abcd'
);

balances.forEach((b) => {
console.log(`${b.symbol} on chain ${b.chainId}: ${b.balance} ($${b.balanceUsd})`);
});
};

const fetchSpecificChains = async () => {
// Fetch balances on Base and Ethereum only
const balances = await engineClient.getWalletBalance(
'0x1234...abcd',
[CHAIN_IDS.BASE, CHAIN_IDS.ETHEREUM]
);

console.log(`Found ${balances.length} token balances`);
};

return (
<div>
<button onClick={fetchAllChains}>All Chains</button>
<button onClick={fetchSpecificChains}>Base + Ethereum</button>
</div>
);
}

Method Signature

getWalletBalance(
walletAddress: string,
chains?: number[]
): Promise<OnChainBalance[]>

Parameters:

ParameterTypeRequiredDescription
walletAddressstringYesThe wallet address to query.
chainsnumber[]NoArray of chain IDs to query. Omit to query all supported chains.

OnChainBalance Type

interface OnChainBalance {
/** Token ticker (e.g. 'ETH', 'USDC'). */
token: string;

/** Display symbol. */
symbol: string;

/** Full token name. */
name: string;

/** Formatted balance as a decimal string. */
balance: string;

/** Raw balance in smallest unit (wei for ETH). */
balanceRaw: string;

/** USD equivalent of the balance. */
balanceUsd: string;

/** Current token price in USD. */
priceUsd: string;

/** 24-hour price change percentage. */
priceChange24h: string;

/** Chain ID where the balance exists. */
chainId: number;

/** Token decimals. */
decimals: number;

/** ERC-20 contract address, or null for native tokens. */
contractAddress: string | null;

/** Token logo URL. */
logoUri: string;

/** Whether this is a native gas token. */
isNative: boolean;
}

getPortfolioSummary

Fetch aggregated portfolio analytics for a wallet address, including total value, allocation breakdown, and performance metrics.

import { useOneClient } from '@one_deploy/sdk';

function PortfolioView() {
const { engineClient } = useOneClient();

const loadPortfolio = async () => {
const portfolio = await engineClient.getPortfolioSummary(
'0x1234...abcd'
);

console.log('Total USD value:', portfolio.totalValueUsd);
console.log('24h change:', portfolio.change24h);
console.log('Chain breakdown:', portfolio.chainAllocation);
console.log('Top holdings:', portfolio.topHoldings);
};

return <button onClick={loadPortfolio}>Load Portfolio</button>;
}

Method Signature

getPortfolioSummary(walletAddress: string): Promise<PortfolioAnalytics>

PortfolioAnalytics Type

interface PortfolioAnalytics {
/** Wallet address queried. */
walletAddress: string;

/** Total portfolio value in USD. */
totalValueUsd: string;

/** Absolute USD change in the last 24 hours. */
change24h: string;

/** Percentage change in the last 24 hours. */
changePercent24h: string;

/** Allocation breakdown by chain. */
chainAllocation: ChainAllocation[];

/** Top token holdings sorted by USD value descending. */
topHoldings: HoldingSummary[];

/** Number of distinct tokens held. */
tokenCount: number;

/** Number of chains with non-zero balances. */
activeChainCount: number;

/** ISO 8601 timestamp of when this data was computed. */
updatedAt: string;
}

interface ChainAllocation {
/** Chain ID. */
chainId: number;

/** Chain display name. */
chainName: string;

/** Total USD value on this chain. */
valueUsd: string;

/** Percentage of total portfolio. */
percentage: string;
}

interface HoldingSummary {
/** Token symbol. */
symbol: string;

/** Token name. */
name: string;

/** Formatted balance. */
balance: string;

/** USD value of the holding. */
valueUsd: string;

/** Percentage of total portfolio. */
percentage: string;

/** Chain ID where this holding exists. */
chainId: number;
}

Fetching and Displaying Multi-Chain Balances

A complete example showing how to fetch balances from multiple chains and render them in a grouped view.

import { useState, useEffect } from 'react';
import { useOneClient, CHAIN_IDS } from '@one_deploy/sdk';
import type { OnChainBalance, PortfolioAnalytics } from '@one_deploy/sdk';

const CHAINS = [
{ id: CHAIN_IDS.BASE, name: 'Base' },
{ id: CHAIN_IDS.ETHEREUM, name: 'Ethereum' },
{ id: CHAIN_IDS.POLYGON, name: 'Polygon' },
{ id: CHAIN_IDS.ARBITRUM, name: 'Arbitrum' },
{ id: CHAIN_IDS.OPTIMISM, name: 'Optimism' },
];

function MultiChainPortfolio({ walletAddress }: { walletAddress: string }) {
const { engineClient } = useOneClient();
const [balances, setBalances] = useState<OnChainBalance[]>([]);
const [portfolio, setPortfolio] = useState<PortfolioAnalytics | null>(null);
const [loading, setLoading] = useState(true);

useEffect(() => {
async function load() {
setLoading(true);
const [balanceData, portfolioData] = await Promise.all([
engineClient.getWalletBalance(walletAddress),
engineClient.getPortfolioSummary(walletAddress),
]);
setBalances(balanceData);
setPortfolio(portfolioData);
setLoading(false);
}
load();
}, [walletAddress, engineClient]);

if (loading) return <p>Loading portfolio...</p>;
if (!portfolio) return <p>No data available.</p>;

// Group balances by chain
const balancesByChain = CHAINS.map((chain) => ({
...chain,
tokens: balances.filter((b) => b.chainId === chain.id),
})).filter((group) => group.tokens.length > 0);

return (
<div>
<header>
<h2>Portfolio: ${portfolio.totalValueUsd}</h2>
<p>
24h: {portfolio.change24h} ({portfolio.changePercent24h}%)
</p>
<p>
{portfolio.tokenCount} tokens across {portfolio.activeChainCount} chains
</p>
</header>

{balancesByChain.map((group) => (
<section key={group.id}>
<h3>{group.name}</h3>
<table>
<thead>
<tr>
<th>Token</th>
<th>Balance</th>
<th>USD Value</th>
<th>Price</th>
<th>24h</th>
</tr>
</thead>
<tbody>
{group.tokens.map((token) => (
<tr key={`${token.chainId}-${token.contractAddress ?? 'native'}`}>
<td>{token.symbol}</td>
<td>{token.balance}</td>
<td>${token.balanceUsd}</td>
<td>${token.priceUsd}</td>
<td>{token.priceChange24h}%</td>
</tr>
))}
</tbody>
</table>
</section>
))}
</div>
);
}

Next Steps