BEGINNER
Every mosaic on NEM has a set of on-chain properties such as supply, divisibility, and transfer rules.
This tutorial shows how to retrieve a mosaic's properties and its current supply.
Prerequisites
This tutorial only reads data from the network. No account is required.
Before you start, make sure to set up your development environment .
Full Code
import json
import os
import urllib.request
NODE_URL = os . getenv ( 'NODE_URL' , 'http://libertalia.nemtest.net:7890' )
print ( f 'Using node { NODE_URL } ' )
MOSAIC_ID = os . getenv ( 'MOSAIC_ID' , 'nem:xem' )
print ( f 'Mosaic ID: { MOSAIC_ID } ' )
try :
# Fetch mosaic information
mosaic_path = f '/mosaic/definition?mosaicId= { MOSAIC_ID } '
print ( f 'Fetching mosaic information from { mosaic_path } ' )
with urllib . request . urlopen ( f ' { NODE_URL }{ mosaic_path } ' ) as response :
response_json = json . loads ( response . read () . decode ())
mosaic_id = response_json [ 'id' ]
full_name = f ' { mosaic_id [ "namespaceId" ] } : { mosaic_id [ "name" ] } '
print ( 'Mosaic information:' )
print ( f ' Mosaic ID: { full_name } ' )
print ( f ' Description: { response_json [ "description" ] } ' )
print ( f ' Creator: { response_json [ "creator" ] } ' )
properties = {
prop [ 'name' ]: prop [ 'value' ]
for prop in response_json [ 'properties' ]
}
divisibility = int ( properties [ 'divisibility' ])
print ( f ' Divisibility: { divisibility } ' )
print ( f ' Initial supply: { properties [ "initialSupply" ] } ' )
print ( f ' Supply mutable: { properties [ "supplyMutable" ] } ' )
print ( f ' Transferable: { properties [ "transferable" ] } ' )
levy = response_json [ 'levy' ]
print ( f ' Levy: { levy if levy else "none" } ' )
# Fetch the current supply
supply_path = f '/mosaic/supply?mosaicId= { MOSAIC_ID } '
print ( f ' \n Fetching current supply from { supply_path } ' )
with urllib . request . urlopen ( f ' { NODE_URL }{ supply_path } ' ) as response :
supply_info = json . loads ( response . read () . decode ())
supply = supply_info [ 'supply' ]
print ( f ' Current supply: { supply } ' )
# Convert the supply to atomic units
atomic = supply * 10 ** divisibility
print ( f ' \n Supply in atomic units: { atomic } ' )
except Exception as e :
print ( e )
Download source
const NODE_URL = process . env . NODE_URL ||
'http://libertalia.nemtest.net:7890' ;
console . log ( 'Using node' , NODE_URL );
const MOSAIC_ID = process . env . MOSAIC_ID || 'nem:xem' ;
console . log ( 'Mosaic ID:' , MOSAIC_ID );
try {
// Fetch mosaic information
const mosaicPath = `/mosaic/definition?mosaicId= ${ MOSAIC_ID } ` ;
console . log ( 'Fetching mosaic information from' , mosaicPath );
const mosaicResponse = await fetch ( ` ${ NODE_URL }${ mosaicPath } ` );
if ( ! mosaicResponse . ok )
throw new Error ( `HTTP error! status: ${ mosaicResponse . status } ` );
const mosaicJSON = await mosaicResponse . json ();
const fullName = ` ${ mosaicJSON . id . namespaceId } : ${ mosaicJSON . id . name } ` ;
console . log ( 'Mosaic information:' );
console . log ( ` Mosaic ID: ${ fullName } ` );
console . log ( ' Description:' , mosaicJSON . description );
console . log ( ' Creator:' , mosaicJSON . creator );
const properties = Object . fromEntries ( mosaicJSON . properties
. map ( property => [ property . name , property . value ]));
const divisibility = parseInt ( properties . divisibility , 10 );
console . log ( ' Divisibility:' , divisibility );
console . log ( ' Initial supply:' , properties . initialSupply );
console . log ( ' Supply mutable:' , properties . supplyMutable );
console . log ( ' Transferable:' , properties . transferable );
const hasLevy = 0 !== Object . keys ( mosaicJSON . levy ). length ;
console . log ( ' Levy:' , hasLevy ? mosaicJSON . levy : 'none' );
// Fetch the current supply
const supplyPath = `/mosaic/supply?mosaicId= ${ MOSAIC_ID } ` ;
console . log ( '\nFetching current supply from' , supplyPath );
const supplyResponse = await fetch ( ` ${ NODE_URL }${ supplyPath } ` );
const supplyInfo = await supplyResponse . json ();
const supply = supplyInfo . supply ;
console . log ( ' Current supply:' , supply );
// Convert the supply to atomic units
const atomic = BigInt ( supply ) * ( 10n ** BigInt ( divisibility ));
console . log ( `\nSupply in atomic units: ${ atomic } ` );
} catch ( e ) {
console . error ( e . message );
}
Download source
The snippet uses the NODE_URL environment variable to set the NEM API node.
If no value is provided, a default testnet node is used.
The MOSAIC_ID environment variable specifies which mosaic to query, given as its
fully qualified name .
If not set, it defaults to the XEM mosaic (nem:xem).
Code Explanation
# Fetch mosaic information
mosaic_path = f '/mosaic/definition?mosaicId= { MOSAIC_ID } '
print ( f 'Fetching mosaic information from { mosaic_path } ' )
with urllib . request . urlopen ( f ' { NODE_URL }{ mosaic_path } ' ) as response :
response_json = json . loads ( response . read () . decode ())
mosaic_id = response_json [ 'id' ]
full_name = f ' { mosaic_id [ "namespaceId" ] } : { mosaic_id [ "name" ] } '
print ( 'Mosaic information:' )
print ( f ' Mosaic ID: { full_name } ' )
print ( f ' Description: { response_json [ "description" ] } ' )
print ( f ' Creator: { response_json [ "creator" ] } ' )
properties = {
prop [ 'name' ]: prop [ 'value' ]
for prop in response_json [ 'properties' ]
}
divisibility = int ( properties [ 'divisibility' ])
print ( f ' Divisibility: { divisibility } ' )
print ( f ' Initial supply: { properties [ "initialSupply" ] } ' )
print ( f ' Supply mutable: { properties [ "supplyMutable" ] } ' )
print ( f ' Transferable: { properties [ "transferable" ] } ' )
levy = response_json [ 'levy' ]
print ( f ' Levy: { levy if levy else "none" } ' )
// Fetch mosaic information
const mosaicPath = `/mosaic/definition?mosaicId= ${ MOSAIC_ID } ` ;
console . log ( 'Fetching mosaic information from' , mosaicPath );
const mosaicResponse = await fetch ( ` ${ NODE_URL }${ mosaicPath } ` );
if ( ! mosaicResponse . ok )
throw new Error ( `HTTP error! status: ${ mosaicResponse . status } ` );
const mosaicJSON = await mosaicResponse . json ();
const fullName = ` ${ mosaicJSON . id . namespaceId } : ${ mosaicJSON . id . name } ` ;
console . log ( 'Mosaic information:' );
console . log ( ` Mosaic ID: ${ fullName } ` );
console . log ( ' Description:' , mosaicJSON . description );
console . log ( ' Creator:' , mosaicJSON . creator );
const properties = Object . fromEntries ( mosaicJSON . properties
. map ( property => [ property . name , property . value ]));
const divisibility = parseInt ( properties . divisibility , 10 );
console . log ( ' Divisibility:' , divisibility );
console . log ( ' Initial supply:' , properties . initialSupply );
console . log ( ' Supply mutable:' , properties . supplyMutable );
console . log ( ' Transferable:' , properties . transferable );
const hasLevy = 0 !== Object . keys ( mosaicJSON . levy ). length ;
console . log ( ' Levy:' , hasLevy ? mosaicJSON . levy : 'none' );
The /mosaic/definition GET endpoint retrieves the definition of a mosaic, including:
Description: Text describing the mosaic.
Creator: The public key of the account that created the mosaic.
Properties: The mosaic's behavioral properties :
Divisibility : The number of decimal places the mosaic supports.
For example, XEM has a divisibility of 6, meaning 1 XEM equals 1'000'000 atomic units.
Initial supply : The supply at creation time, expressed in
whole units.
Supply mutability : Whether the creator can change the
supply after creation.
Transferability : Whether the mosaic can be freely sent
between accounts or only to and from the creator.
Levy: An optional extra fee paid to a third account whenever the mosaic is
transferred.
Fetching the Current Supply
The definition only records the initial supply.
For mosaics with mutable supply, the current value can differ, so the /mosaic/supply GET endpoint returns the supply
currently in circulation, expressed in whole units .
Converting to Atomic Units
The endpoint reports supply in whole units, but transaction quantities are expressed in
atomic units .
To convert from whole to atomic units, the code multiplies the supply by 10 raised to the mosaic's divisibility.
For XEM (divisibility 6), a supply of 8'999'999'999 whole units equals 8'999'999'999'000'000' atomic units.
Output
The output shown below corresponds to a typical run of the program, querying the XEM mosaic on testnet.
Using node http://libertalia.nemtest.net:7890
Mosaic ID: nem:xem
Fetching mosaic information from /mosaic/definition?mosaicId=nem:xem
Mosaic information:
Mosaic ID: nem:xem
Description: reserved xem mosaic
Creator: 3e82e1c1e4a75adaa3cba8c101c3cd31d9817a2eb966eb3b511fb2ed45b8e262
Divisibility: 6
Initial supply: 8999999999
Supply mutable: false
Transferable: true
Levy: none
Fetching current supply from /mosaic/supply?mosaicId=nem:xem
Current supply: 8999999999
Supply in atomic units: 8999999999000000
Some highlights from the output:
Mosaic ID (line 5): The XEM mosaic identifier, the fully qualified name nem:xem.
Description (line 6): Text that describes the mosaic, set by its creator.
Creator (line 7): The public key of the account that created the mosaic.
Divisibility (line 8): The value 6 means 1 XEM = 1'000'000 (106 ) atomic units.
Initial supply (line 9): The supply at creation time, in whole units.
Supply mutable (line 10): The value false means the XEM supply can never change.
Transferable (line 11): The value true means XEM can be freely sent between accounts.
Levy (line 12): XEM transfers carry no additional mosaic fee.
Current supply (line 15): The supply currently in circulation, identical to the initial supply because XEM
is not mutable.
Supply in atomic units (line 17): The supply converted from whole units to atomic units using the mosaic's
divisibility.
Conclusion
This tutorial showed how to:
Next Steps
July 22, 2026
June 15, 2026
zero