Skip to content
Algorand Developer Portal

Asset Information

← Back to Algod Client

This example demonstrates how to retrieve asset information using the AlgodClient method: assetById()

  • LocalNet running (via algokit localnet start)

From the repository root:

Terminal window
cd examples
npm run example algod_client/09-asset-info.ts

View source on GitHub

09-asset-info.ts
/**
* Example: Asset Information
*
* This example demonstrates how to retrieve asset information using
* the AlgodClient method: assetById()
*
* Prerequisites:
* - LocalNet running (via `algokit localnet start`)
*/
import {
createAlgodClient,
createAlgorandClient,
getFundedAccount,
printError,
printHeader,
printInfo,
printStep,
printSuccess,
shortenAddress,
} from '../shared/utils.js';
async function main() {
printHeader('Asset Information Example');
// Create an Algod client connected to LocalNet
const algod = createAlgodClient();
// Create an AlgorandClient for asset creation
const algorand = createAlgorandClient();
// =========================================================================
// Step 1: Get a Funded Account from LocalNet
// =========================================================================
printStep(1, 'Getting a funded account from LocalNet');
let creator: Awaited<ReturnType<typeof getFundedAccount>>;
try {
creator = await getFundedAccount(algorand);
printSuccess(`Got funded account: ${shortenAddress(creator.addr.toString())}`);
} catch (error) {
printError(
`Failed to get funded account: ${error instanceof Error ? error.message : String(error)}`,
);
printInfo('Make sure LocalNet is running with `algokit localnet start`');
printInfo('If issues persist, try `algokit localnet reset`');
process.exit(1);
}
// =========================================================================
// Step 2: Create a Test Asset using AlgorandClient
// =========================================================================
printStep(2, 'Creating a test asset using AlgorandClient');
const assetTotal = 1_000_000_000_000n; // 1 million units with 6 decimals
const assetDecimals = 6;
const assetName = 'Test Asset';
const assetUnitName = 'TEST';
const assetUrl = 'https://example.com/test-asset';
const metadataHash = new Uint8Array(32).fill(0xab); // 32-byte metadata hash
try {
printInfo(`Creating asset: ${assetName} (${assetUnitName})`);
printInfo(`Total supply: ${assetTotal.toLocaleString('en-US')} base units`);
printInfo(`Decimals: ${assetDecimals}`);
const result = await algorand.send.assetCreate({
sender: creator.addr,
total: assetTotal,
decimals: assetDecimals,
assetName: assetName,
unitName: assetUnitName,
url: assetUrl,
metadataHash: metadataHash,
defaultFrozen: false,
manager: creator.addr,
reserve: creator.addr,
freeze: creator.addr,
clawback: creator.addr,
});
const assetId = result.assetId;
printSuccess(`Asset created with ID: ${assetId}`);
printInfo('');
// =========================================================================
// Step 3: Get Asset Information using assetById()
// =========================================================================
printStep(3, 'Getting asset information with assetById()');
const asset = await algod.assetById(assetId);
printSuccess('Asset information retrieved successfully!');
printInfo('');
// =========================================================================
// Step 4: Display Asset Params
// =========================================================================
printStep(4, 'Displaying asset parameters');
printInfo('Asset Identification:');
printInfo(` Asset ID: ${asset.id}`);
printInfo('');
printInfo('Asset Parameters:');
printInfo(` Creator: ${asset.params.creator}`);
printInfo(` ${shortenAddress(asset.params.creator)} (shortened)`);
printInfo(` Total: ${asset.params.total.toLocaleString('en-US')} base units`);
// Calculate human-readable total
const humanReadableTotal = Number(asset.params.total) / Math.pow(10, asset.params.decimals);
printInfo(
` ${humanReadableTotal.toLocaleString('en-US')} ${asset.params.unitName ?? 'units'}`,
);
printInfo(` Decimals: ${asset.params.decimals}`);
printInfo(` Unit Name: ${asset.params.unitName ?? '(not set)'}`);
printInfo(` Asset Name: ${asset.params.name ?? '(not set)'}`);
printInfo(` URL: ${asset.params.url ?? '(not set)'}`);
// Display metadata hash if present
if (asset.params.metadataHash) {
const hashHex = Buffer.from(asset.params.metadataHash).toString('hex');
printInfo(
` Metadata Hash: ${hashHex.substring(0, 16)}...${hashHex.substring(hashHex.length - 16)} (${asset.params.metadataHash.length} bytes)`,
);
} else {
printInfo(` Metadata Hash: (not set)`);
}
printInfo(` Default Frozen: ${asset.params.defaultFrozen ?? false}`);
printInfo('');
// =========================================================================
// Step 5: Display Asset Addresses (Manager, Reserve, Freeze, Clawback)
// =========================================================================
printStep(5, 'Displaying asset management addresses');
printInfo('Asset Management Addresses:');
printInfo(` Manager: ${asset.params.manager ?? '(immutable - not set)'}`);
if (asset.params.manager) {
printInfo(` ${shortenAddress(asset.params.manager)} (shortened)`);
printInfo('Manager can modify manager, reserve, freeze, and clawback addresses');
}
printInfo(` Reserve: ${asset.params.reserve ?? '(not set)'}`);
if (asset.params.reserve) {
printInfo(` ${shortenAddress(asset.params.reserve)} (shortened)`);
printInfo('Reserve holds non-minted/non-circulating units');
}
printInfo(` Freeze: ${asset.params.freeze ?? '(not set - freezing disabled)'}`);
if (asset.params.freeze) {
printInfo(` ${shortenAddress(asset.params.freeze)} (shortened)`);
printInfo('Freeze address can freeze/unfreeze asset holdings');
}
printInfo(` Clawback: ${asset.params.clawback ?? '(not set - clawback disabled)'}`);
if (asset.params.clawback) {
printInfo(` ${shortenAddress(asset.params.clawback)} (shortened)`);
printInfo('Clawback address can revoke assets from any account');
}
printInfo('');
// =========================================================================
// Step 6: Note about Round Information
// =========================================================================
printStep(6, 'Note about data validity');
printInfo('The assetById() method returns the current asset state.');
printInfo('Unlike some other endpoints, it does not include a round field.');
printInfo('To get the current round, use status() or other round-aware methods.');
// Get current round for reference
const status = await algod.status();
printInfo(` Current network round: ${status.lastRound.toLocaleString('en-US')}`);
printInfo('');
// =========================================================================
// Step 7: Handle Asset Not Found
// =========================================================================
printStep(7, 'Demonstrating error handling for non-existent asset');
const nonExistentAssetId = 999999999n;
try {
printInfo(`Querying non-existent asset ID: ${nonExistentAssetId}`);
await algod.assetById(nonExistentAssetId);
printError('Expected an error but none was thrown');
} catch (error) {
printSuccess('Correctly caught error for non-existent asset');
if (error instanceof Error) {
printInfo(` Error message: ${error.message}`);
}
printInfo('Always handle the case where an asset may not exist or has been destroyed');
}
printInfo('');
// =========================================================================
// Step 8: Create Asset with Minimal Parameters (for comparison)
// =========================================================================
printStep(8, 'Creating a minimal asset (no optional addresses)');
const minimalResult = await algorand.send.assetCreate({
sender: creator.addr,
total: 1000n,
decimals: 0,
assetName: 'Minimal Asset',
unitName: 'MIN',
// Note: No manager, reserve, freeze, or clawback addresses set
});
const minimalAsset = await algod.assetById(minimalResult.assetId);
printInfo('Minimal Asset Configuration:');
printInfo(` Asset ID: ${minimalAsset.id}`);
printInfo(` Creator: ${shortenAddress(minimalAsset.params.creator)}`);
printInfo(` Total: ${minimalAsset.params.total}`);
printInfo(` Manager: ${minimalAsset.params.manager ?? '(not set - asset is immutable)'}`);
printInfo(` Reserve: ${minimalAsset.params.reserve ?? '(not set)'}`);
printInfo(` Freeze: ${minimalAsset.params.freeze ?? '(not set - freezing disabled)'}`);
printInfo(` Clawback: ${minimalAsset.params.clawback ?? '(not set - clawback disabled)'}`);
printInfo('Without a manager address, asset parameters cannot be changed');
printInfo('');
} catch (error) {
printError(
`Failed to create or query asset: ${error instanceof Error ? error.message : String(error)}`,
);
printInfo('If LocalNet errors occur, try `algokit localnet reset`');
process.exit(1);
}
// =========================================================================
// Summary
// =========================================================================
printHeader('Summary');
printInfo('This example demonstrated:');
printInfo(' 1. Creating a test asset using AlgorandClient.send.assetCreate()');
printInfo(' 2. assetById(assetId) - Get complete asset information');
printInfo(' 3. Asset params: creator, total, decimals, unitName, name, url, metadataHash');
printInfo(' 4. Asset addresses: manager, reserve, freeze, clawback');
printInfo(' 5. Error handling for non-existent assets');
printInfo(' 6. Minimal asset creation (without optional addresses)');
printInfo('');
printInfo('Key Asset fields:');
printInfo(' - id: Unique asset identifier (bigint)');
printInfo(' - params.creator: Address that created the asset');
printInfo(' - params.total: Total supply in base units (bigint)');
printInfo(' - params.decimals: Number of decimal places (0-19)');
printInfo(' - params.unitName: Short name for asset unit (e.g., "ALGO")');
printInfo(' - params.name: Full asset name');
printInfo(' - params.url: URL with more information');
printInfo(' - params.metadataHash: 32-byte commitment to metadata');
printInfo(' - params.defaultFrozen: Whether new holdings are frozen by default');
printInfo('');
printInfo('Management addresses (optional):');
printInfo(' - manager: Can reconfigure or destroy the asset');
printInfo(' - reserve: Holds non-circulating units');
printInfo(' - freeze: Can freeze/unfreeze holdings');
printInfo(' - clawback: Can revoke assets from any account');
printInfo('');
printInfo('Use cases:');
printInfo(' - Verify asset parameters before opt-in');
printInfo(' - Check management addresses for trust evaluation');
printInfo(' - Display asset information in wallets/explorers');
printInfo(' - Validate asset metadata for compliance');
}
main().catch(error => {
console.error('Fatal error:', error);
process.exit(1);
});