Skip to main content

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
)
dbService
DatabaseService
required
Database service for persisting chain data
eventService
EventService
required
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();

Chain Information Methods

getChainInfoMap()

Retrieves all chain information.
getChainInfoMap(): Record<string, _ChainInfo>
Returns:
Record<string, _ChainInfo>
object
Map of chain slugs to chain information

getChainInfoByKey()

Retrieves chain information by slug.
getChainInfoByKey(key: string): _ChainInfo
key
string
required
Chain slug (e.g., ‘polkadot’, ‘ethereum’, ‘kusama’)
Returns:
_ChainInfo
object
Chain information object
slug
string
Unique chain identifier
name
string
Human-readable chain name
chainStatus
_ChainStatus
Chain status (ACTIVE, INACTIVE, STOPPED)
providers
Record<string, string>
Available RPC providers
substrateInfo
_SubstrateInfo | null
Substrate-specific information
evmInfo
_EvmInfo | null
EVM-specific information
tonInfo
_TonInfo | null
TON-specific information
cardanoInfo
_CardanoInfo | null
Cardano-specific information
bitcoinInfo
_BitcoinInfo | null
Bitcoin-specific information
isTestnet
boolean
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:
string[]
array
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
key
string
required
Chain slug
Returns:
_ChainState
object
Chain state object
slug
string
Chain identifier
active
boolean
Whether chain is currently active
currentProvider
string
Currently selected provider key
manualTurnOff
boolean
Whether user manually disabled the chain

enableChain()

Enables a chain and connects to it.
async enableChain(chainSlug: string): Promise<boolean>
chainSlug
string
required
Chain to enable
Returns:
boolean
boolean
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
chainSlug
string
required
Chain to disable
preventManualTurnOff
boolean
default:"false"
If true, doesn’t mark as manually turned off

enableChains()

Enables multiple chains at once.
async enableChains(chainSlugs: string[]): Promise<boolean>
chainSlugs
string[]
required
Array of chain slugs to enable

API Access Methods

getSubstrateApi()

Retrieves Substrate API instance for a chain.
getSubstrateApi(slug: string): _SubstrateApi | undefined
slug
string
required
Chain slug
Returns:
_SubstrateApi
object
Substrate API wrapper
api
ApiPromise
Polkadot.js API instance
isReady
Promise<_SubstrateApi>
Promise resolving when API is ready
isApiConnected
boolean
Connection status
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:
_EvmApi
object
EVM API wrapper
api
Web3
Web3.js instance
isApiConnected
boolean
Connection status
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>
object
Map of asset slugs to asset information

getAssetBySlug()

Retrieves asset information by slug.
getAssetBySlug(slug: string): _ChainAsset
slug
string
required
Asset slug (e.g., ‘polkadot-NATIVE-DOT’, ‘ethereum-ERC20-USDT’)
Returns:
_ChainAsset
object
Asset information
slug
string
Unique asset identifier
originChain
string
Chain where asset originates
symbol
string
Asset symbol (e.g., DOT, USDT)
decimals
number
Number of decimal places
assetType
_AssetType
Asset type (NATIVE, ERC20, PSP22, etc.)
metadata
any
Asset-specific metadata (contract address, etc.)
priceId
string | null
Price API identifier
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>
chainSlug
string
required
Chain slug
checkActive
boolean
default:"false"
Only return visible/active assets

Asset Settings Methods

getAssetSettings()

Retrieves asset visibility settings.
async getAssetSettings(): Promise<Record<string, AssetSetting>>
Returns:
Record<string, AssetSetting>
object
Map of asset slugs to settings
visible
boolean
Whether 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
token
_ChainAsset
required
Custom token information
Returns:
string
string
Generated token slug
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>
object
Map of chain slugs to status
connectionStatus
_ChainConnectionStatus
CONNECTED, DISCONNECTED, CONNECTING, or UNSTABLE
lastUpdated
number
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:
Subject
Subject
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'
}

Build docs developers (and LLMs) love