Overview
The Asset types define the structure for representing aggregated assets in OneBalance, which combine the same token across multiple blockchains into a single unified asset.
Asset
Represents an aggregated asset that spans multiple blockchain networks.
export interface Asset {
aggregatedAssetId: string;
symbol: string;
name: string;
decimals: number;
aggregatedEntities: AggregatedAssetEntity[];
}
Properties
Unique identifier for the aggregated assetFormat: ob:{symbol} where ob stands for OneBalanceExamples:
ob:eth - Ethereum aggregated across all supported chains
ob:usdc - USDC aggregated across all supported chains
ob:dai - DAI aggregated across all supported chains
Token symbol in uppercaseExamples: "ETH", "USDC", "DAI", "USDT"
Full name of the assetExamples: "Ethereum", "USD Coin", "Dai Stablecoin"
Number of decimal places for the tokenCommon values:
18 - ETH, DAI, and most ERC-20 tokens
6 - USDC, USDT
8 - WBTC
aggregatedEntities
AggregatedAssetEntity[]
required
Example
const usdcAsset: Asset = {
aggregatedAssetId: "ob:usdc",
symbol: "USDC",
name: "USD Coin",
decimals: 6,
aggregatedEntities: [
{
assetType: "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
decimals: 6,
name: "USD Coin",
symbol: "USDC"
},
{
assetType: "eip155:137/erc20:0x2791bca1f2de4661ed88a30c99a7a9449aa84174",
decimals: 6,
name: "USD Coin",
symbol: "USDC"
},
{
assetType: "eip155:8453/erc20:0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
decimals: 6,
name: "USD Coin",
symbol: "USDC"
}
]
};
AggregatedAssetEntity
Represents a single instance of an asset on a specific blockchain network.
export interface AggregatedAssetEntity {
assetType: string;
decimals: number;
name: string;
symbol: string;
}
Properties
CAIP-19 format identifier for the asset on a specific chainFormat: {namespace}:{chainId}/{assetNamespace}:{assetReference}Examples:
"eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" (USDC on Ethereum)
"eip155:137/slip44:60" (ETH on Polygon)
"eip155:42161/erc20:0xff970a61a04b1ca14834a43f5de4533ebddb5cc8" (USDC on Arbitrum)
Number of decimal places for this specific token instanceNote: This should match the aggregated asset’s decimals, but is included for completeness
Full name of the token on this specific chain
Token symbol on this specific chain
Example
const ethereumUSDC: AggregatedAssetEntity = {
assetType: "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
decimals: 6,
name: "USD Coin",
symbol: "USDC"
};
const polygonETH: AggregatedAssetEntity = {
assetType: "eip155:137/slip44:60",
decimals: 18,
name: "Ethereum",
symbol: "ETH"
};
Understanding Aggregated Assets
OneBalance’s core feature is asset aggregation - treating the same token across multiple chains as a single unified balance.
How It Works
Asset Identification
Each blockchain has its own instance of a token (e.g., USDC on Ethereum, USDC on Polygon, USDC on Base)
Aggregation
OneBalance groups these instances under a single aggregated asset ID (e.g., ob:usdc)
Unified Balance
Users see and interact with a single USDC balance, even though it may be distributed across multiple chains
Automatic Routing
When swapping or transferring, OneBalance automatically selects the optimal chain(s) to execute from
Common Aggregated Assets
Stablecoins
Native Assets
Other Tokens
USD Coin across Ethereum, Polygon, Base, Optimism, Arbitrum, and more
Tether USD across supported chains
Dai Stablecoin across supported chains
Ethereum across Ethereum Mainnet, Optimism, Arbitrum, Base, Polygon, and more
Polygon’s native token across supported chains
Wrapped Bitcoin across supported chains
Chainlink token across supported chains
Usage Examples
Finding Available Chains for an Asset
import { Asset } from './types/assets';
function getAvailableChains(asset: Asset): string[] {
return asset.aggregatedEntities.map(entity => {
// Extract chain ID from CAIP-19 format
// e.g., "eip155:1/erc20:0x..." -> "1"
const chainPart = entity.assetType.split('/')[0]; // "eip155:1"
return chainPart.split(':')[1]; // "1"
});
}
const asset: Asset = await fetchAsset('ob:usdc');
const chains = getAvailableChains(asset);
console.log(`USDC is available on chains: ${chains.join(', ')}`);
// Output: USDC is available on chains: 1, 137, 8453, 10, 42161
Getting Contract Address for a Specific Chain
function getContractAddress(asset: Asset, chainId: string): string | null {
const entity = asset.aggregatedEntities.find(e => {
const entityChainId = e.assetType.split(':')[1].split('/')[0];
return entityChainId === chainId;
});
if (!entity) return null;
// Extract contract address from CAIP-19 format
// e.g., "eip155:1/erc20:0xa0b86991..." -> "0xa0b86991..."
const assetRef = entity.assetType.split(':')[2];
return assetRef || null;
}
const usdcAsset: Asset = await fetchAsset('ob:usdc');
const ethereumAddress = getContractAddress(usdcAsset, '1');
console.log(`USDC on Ethereum: ${ethereumAddress}`);
// Output: USDC on Ethereum: 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Checking if Asset is Available on a Chain
function isAssetOnChain(asset: Asset, chainId: string): boolean {
return asset.aggregatedEntities.some(entity => {
const entityChainId = entity.assetType.split(':')[1].split('/')[0];
return entityChainId === chainId;
});
}
const ethAsset: Asset = await fetchAsset('ob:eth');
console.log(`ETH on Ethereum: ${isAssetOnChain(ethAsset, '1')}`);
console.log(`ETH on Solana: ${isAssetOnChain(ethAsset, '5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp')}`);
// Output:
// ETH on Ethereum: true
// ETH on Solana: false
function formatAssetAmount(amount: string, asset: Asset): string {
const value = BigInt(amount);
const divisor = BigInt(10 ** asset.decimals);
const whole = value / divisor;
const fraction = value % divisor;
const fractionStr = fraction.toString().padStart(asset.decimals, '0');
// Remove trailing zeros from fraction
const trimmedFraction = fractionStr.replace(/0+$/, '');
if (trimmedFraction === '') {
return `${whole} ${asset.symbol}`;
}
return `${whole}.${trimmedFraction} ${asset.symbol}`;
}
const usdcAsset: Asset = {
aggregatedAssetId: 'ob:usdc',
symbol: 'USDC',
decimals: 6,
/* ... */
};
console.log(formatAssetAmount('1000000', usdcAsset));
// Output: 1 USDC
console.log(formatAssetAmount('1500000', usdcAsset));
// Output: 1.5 USDC
console.log(formatAssetAmount('1234567890', usdcAsset));
// Output: 1234.56789 USDC