Overview
The ChainService is the core service responsible for managing blockchain network connections, chain metadata, asset registries, and API instances across all supported networks. It provides a unified interface for interacting with Substrate, EVM, Ton, Cardano, and Bitcoin chains.
Key Features
- Multi-chain connection management
- Chain and asset metadata storage
- Dynamic provider switching
- API instance management (Substrate, EVM, Ton, Cardano, Bitcoin)
- Chain health monitoring
- Custom chain and token support
- Cross-chain asset references (XCM)
Class: ChainService
Constructor
constructor(
dbService: DatabaseService,
eventService: EventService
)
Database service for persisting chain data
Event service for chain state changes
Initialization Methods
init()
Initializes the chain service, loads chain data, and connects to active chains.
async init(): Promise<void>
Usage:
const chainService = new ChainService(dbService, eventService);
await chainService.init();
getChainInfoMap()
Retrieves all chain information.
getChainInfoMap(): Record<string, _ChainInfo>
Returns:
Record<string, _ChainInfo>
Map of chain slugs to chain information
getChainInfoByKey()
Retrieves chain information by slug.
getChainInfoByKey(key: string): _ChainInfo
Chain slug (e.g., ‘polkadot’, ‘ethereum’, ‘kusama’)
Returns:
Chain information objectHuman-readable chain name
Chain status (ACTIVE, INACTIVE, STOPPED)
Substrate-specific information
Cardano-specific information
Bitcoin-specific information
Whether this is a testnet
Usage:
const polkadot = chainService.getChainInfoByKey('polkadot');
console.log(polkadot.name); // "Polkadot"
console.log(polkadot.chainStatus); // "ACTIVE"
getActiveChains()
Retrieves all active chain slugs.
getActiveChains(): string[]
Returns:
Array of active chain slugs
getActiveChainInfoMap()
Retrieves information for all active chains.
getActiveChainInfoMap(): Record<string, _ChainInfo>
Chain State Methods
getChainStateByKey()
Retrieves chain state (active status, current provider).
getChainStateByKey(key: string): _ChainState
Returns:
Chain state objectWhether chain is currently active
Currently selected provider key
Whether user manually disabled the chain
enableChain()
Enables a chain and connects to it.
async enableChain(chainSlug: string): Promise<boolean>
Returns:
true if chain was enabled successfully
Usage:
const success = await chainService.enableChain('moonbeam');
if (success) {
console.log('Moonbeam enabled and connected');
}
disableChain()
Disables a chain and disconnects from it.
disableChain(chainSlug: string, preventManualTurnOff?: boolean): boolean
If true, doesn’t mark as manually turned off
enableChains()
Enables multiple chains at once.
async enableChains(chainSlugs: string[]): Promise<boolean>
Array of chain slugs to enable
API Access Methods
getSubstrateApi()
Retrieves Substrate API instance for a chain.
getSubstrateApi(slug: string): _SubstrateApi | undefined
Returns:
Substrate API wrapperPromise resolving when API is ready
Usage:
const api = chainService.getSubstrateApi('polkadot');
if (api) {
await api.isReady;
const chainName = await api.api.rpc.system.chain();
console.log('Chain name:', chainName.toString());
}
getEvmApi()
Retrieves EVM API instance (Web3) for a chain.
getEvmApi(slug: string): _EvmApi | undefined
Returns:
Usage:
const evmApi = chainService.getEvmApi('ethereum');
if (evmApi) {
const blockNumber = await evmApi.api.eth.getBlockNumber();
console.log('Block number:', blockNumber);
}
getTonApi()
Retrieves TON API instance.
getTonApi(slug: string): _TonApi | undefined
getCardanoApi()
Retrieves Cardano API instance.
getCardanoApi(slug: string): _CardanoApi | undefined
getBitcoinApi()
Retrieves Bitcoin API instance.
getBitcoinApi(slug: string): _BitcoinApi | undefined
Asset Registry Methods
getAssetRegistry()
Retrieves all registered assets.
getAssetRegistry(): Record<string, _ChainAsset>
Returns:
Record<string, _ChainAsset>
Map of asset slugs to asset information
getAssetBySlug()
Retrieves asset information by slug.
getAssetBySlug(slug: string): _ChainAsset
Asset slug (e.g., ‘polkadot-NATIVE-DOT’, ‘ethereum-ERC20-USDT’)
Returns:
Asset informationChain where asset originates
Asset symbol (e.g., DOT, USDT)
Asset type (NATIVE, ERC20, PSP22, etc.)
Asset-specific metadata (contract address, etc.)
Usage:
const dot = chainService.getAssetBySlug('polkadot-NATIVE-DOT');
console.log(`${dot.symbol}: ${dot.decimals} decimals`);
getNativeTokenInfo()
Retrieves the native token for a chain.
getNativeTokenInfo(chainSlug: string): _ChainAsset
Usage:
const nativeToken = chainService.getNativeTokenInfo('polkadot');
console.log('Native token:', nativeToken.symbol); // "DOT"
getFungibleTokensByChain()
Retrieves all fungible tokens for a specific chain.
getFungibleTokensByChain(
chainSlug: string,
checkActive?: boolean
): Record<string, _ChainAsset>
Only return visible/active assets
Asset Settings Methods
getAssetSettings()
Retrieves asset visibility settings.
async getAssetSettings(): Promise<Record<string, AssetSetting>>
Returns:
Record<string, AssetSetting>
Map of asset slugs to settingsWhether asset is visible in UI
setAssetSettings()
Updates asset settings.
setAssetSettings(settings: Record<string, AssetSetting>): void
subscribeAssetSettings()
Subscribes to asset settings changes.
subscribeAssetSettings(): BehaviorSubject<Record<string, AssetSetting>>
Custom Chain Methods
upsertCustomToken()
Adds or updates a custom token.
upsertCustomToken(token: _ChainAsset): string
Returns:
Usage:
const tokenSlug = chainService.upsertCustomToken({
slug: '', // Auto-generated if empty
originChain: 'ethereum',
symbol: 'CUSTOM',
decimals: 18,
assetType: _AssetType.ERC20,
metadata: {
contractAddress: '0x...'
},
name: 'Custom Token',
priceId: null,
multiChainAsset: null,
hasValue: true,
icon: ''
});
console.log('Token slug:', tokenSlug);
deleteCustomAssets()
Deletes custom tokens.
deleteCustomAssets(tokenSlugs: string[]): void
removeCustomChain()
Removes a custom chain.
removeCustomChain(slug: string): boolean
Connection Status Methods
getChainStatusMap()
Retrieves connection status for all chains.
getChainStatusMap(): Record<string, _ChainApiStatus>
Returns:
Record<string, _ChainApiStatus>
Map of chain slugs to statusCONNECTED, DISCONNECTED, CONNECTING, or UNSTABLE
Timestamp of last status update
subscribeChainStatusMap()
Subscribes to chain connection status updates.
subscribeChainStatusMap(): BehaviorSubject<Record<string, _ChainApiStatus>>
Usage:
chainService.subscribeChainStatusMap().subscribe((statusMap) => {
Object.entries(statusMap).forEach(([chain, status]) => {
console.log(`${chain}: ${status.connectionStatus}`);
});
});
XCM Reference Methods
subscribeXcmRefMap()
Subscribes to XCM asset reference map.
subscribeXcmRefMap(): Subject<Record<string, _AssetRef>>
Returns:
Observable emitting XCM asset references for cross-chain transfers
Example: Complete Chain Management
import { ChainService } from '@subwallet/extension-base';
// Initialize
const chainService = new ChainService(dbService, eventService);
await chainService.init();
// Get all active chains
const activeChains = chainService.getActiveChains();
console.log('Active chains:', activeChains);
// Enable a new chain
await chainService.enableChain('moonbeam');
// Get chain info
const polkadot = chainService.getChainInfoByKey('polkadot');
console.log('Polkadot providers:', Object.keys(polkadot.providers));
// Access API
const api = chainService.getSubstrateApi('polkadot');
if (api) {
await api.isReady;
const blockHash = await api.api.rpc.chain.getBlockHash();
console.log('Latest block:', blockHash.toHex());
}
// Get assets for a chain
const polkadotAssets = chainService.getFungibleTokensByChain('polkadot', true);
console.log('Polkadot assets:', Object.keys(polkadotAssets));
// Monitor connection status
chainService.subscribeChainStatusMap().subscribe((status) => {
if (status['polkadot']?.connectionStatus === 'DISCONNECTED') {
console.warn('Polkadot disconnected!');
}
});
Connection Status Types
enum _ChainConnectionStatus {
CONNECTED = 'CONNECTED',
DISCONNECTED = 'DISCONNECTED',
UNSTABLE = 'UNSTABLE',
CONNECTING = 'CONNECTING'
}