Unit conversion
Convert between STX, microSTX, and other units
Learn how to convert between different unit denominations in Stacks. The blockchain uses microSTX as its base unit, where 1 STX = 1,000,000 microSTX. Proper unit conversion is essential for displaying amounts to users and processing transactions.
Basic conversions
Convert between STX and microSTX using simple conversion functions.
// Convert STX to microSTXfunction stxToMicroStx(stx: number | string): bigint {const stxAmount = typeof stx === 'string' ? parseFloat(stx) : stx;return BigInt(Math.floor(stxAmount * 1_000_000));}// Convert microSTX to STXfunction microStxToStx(microStx: number | bigint | string): string {const amount = BigInt(microStx);const stx = Number(amount) / 1_000_000;return stx.toFixed(6).replace(/\.?0+$/, '');}// Usage examplesconst microStx = stxToMicroStx(1.5); // 1500000nconst stx = microStxToStx(1500000); // "1.5"
Precision-safe handling
Handle large numbers without precision loss using BigInt operations.
class StxConverter {static readonly MICROSTX_PER_STX = 1_000_000n;static toMicroStx(amount: string | number, decimals = 6): bigint {const amountStr = amount.toString();const [whole, decimal = ''] = amountStr.split('.');const paddedDecimal = decimal.padEnd(decimals, '0').slice(0, decimals);return BigInt(whole + paddedDecimal);}static toStx(microStx: bigint | string | number): string {const amount = BigInt(microStx);const isNegative = amount < 0n;const absoluteAmount = isNegative ? -amount : amount;const str = absoluteAmount.toString().padStart(7, '0');const whole = str.slice(0, -6) || '0';const decimal = str.slice(-6);let result = `${whole}.${decimal}`.replace(/\.?0+$/, '');return isNegative ? `-${result}` : result;}}// Precise conversion examplesconst precise1 = StxConverter.toMicroStx('123.456789'); // 123456789nconst precise2 = StxConverter.toStx(123456789n); // "123.456789"
Token conversions
Handle tokens with different decimal places using a flexible converter class.
interface TokenInfo {decimals: number;symbol: string;name: string;}class TokenConverter {constructor(private tokenInfo: TokenInfo) {}toSmallestUnit(amount: string | number): bigint {if (typeof amount === 'string') {const [whole, decimal = ''] = amount.split('.');const paddedDecimal = decimal.padEnd(this.tokenInfo.decimals, '0').slice(0, this.tokenInfo.decimals);return BigInt(whole + paddedDecimal);}const multiplier = 10n ** BigInt(this.tokenInfo.decimals);return BigInt(Math.floor(amount * Number(multiplier)));}fromSmallestUnit(amount: bigint | string): string {const value = BigInt(amount);const divisor = 10n ** BigInt(this.tokenInfo.decimals);const whole = value / divisor;const remainder = value % divisor;if (remainder === 0n) return whole.toString();const decimal = remainder.toString().padStart(this.tokenInfo.decimals, '0').replace(/0+$/, '');return `${whole}.${decimal}`;}}// Different token examplesconst usdc = new TokenConverter({ decimals: 6, symbol: 'USDC', name: 'USD Coin' });const btc = new TokenConverter({ decimals: 8, symbol: 'BTC', name: 'Bitcoin' });const usdcAmount = usdc.toSmallestUnit('100.50'); // 100500000nconst btcAmount = btc.toSmallestUnit('0.00123456'); // 123456n
Display formatting
Format amounts for user interfaces with localization support.
class StxFormatter {static format(microStx: bigint, options?: {decimals?: number;locale?: string;symbol?: boolean;}): string {const stx = StxConverter.toStx(microStx);const number = parseFloat(stx);const formatted = new Intl.NumberFormat(options?.locale || 'en-US', {minimumFractionDigits: 0,maximumFractionDigits: options?.decimals ?? 6,}).format(number);return options?.symbol ? `${formatted} STX` : formatted;}static compact(microStx: bigint): string {const stx = Number(StxConverter.toStx(microStx));if (stx >= 1_000_000) {return `${(stx / 1_000_000).toFixed(2)}M STX`;} else if (stx >= 1_000) {return `${(stx / 1_000).toFixed(2)}K STX`;}return this.format(microStx, { decimals: 6, symbol: true });}}// Formatting examplesconst formatted = StxFormatter.format(123456789n, {decimals: 2,symbol: true}); // "123.46 STX"const compact = StxFormatter.compact(1234567890000n); // "1.23K STX"
Input validation
Validate and sanitize user input for amount fields.
class AmountInput {static validate(input: string, options?: {decimals?: number;min?: string;max?: string;}): { valid: boolean; error?: string } {// Check formatif (!/^\d*\.?\d*$/.test(input)) {return { valid: false, error: 'Invalid number format' };}// Check decimal placesconst parts = input.split('.');if (parts[1] && parts[1].length > (options?.decimals || 6)) {return { valid: false, error: `Maximum ${options?.decimals || 6} decimal places` };}// Check rangeif (options?.min) {const value = parseFloat(input);if (value < parseFloat(options.min)) {return { valid: false, error: `Minimum amount is ${options.min}` };}}return { valid: true };}static sanitize(input: string, decimals = 6): string {let sanitized = input.replace(/[^\d.]/g, '');const parts = sanitized.split('.');if (parts.length > 2) {sanitized = parts[0] + '.' + parts.slice(1).join('');}if (parts[1] && parts[1].length > decimals) {sanitized = parts[0] + '.' + parts[1].slice(0, decimals);}return sanitized;}}// Validation examplesconst result1 = AmountInput.validate('123.456', {decimals: 6,min: '0.000001'}); // { valid: true }const result2 = AmountInput.validate('123.4567890', {decimals: 6}); // { valid: false, error: 'Maximum 6 decimal places' }