ethio_validators

Validation and formatting utilities for Ethiopian-specific data:

  • EthiopianPhoneValidator — validate, normalize, and format Ethiopian mobile numbers across Ethio Telecom (09…) and Safaricom Ethiopia (07…) ranges.
  • EtbFormatter — format and parse Ethiopian Birr (ETB) currency amounts.

The package is pure Dart with zero dependencies, so it runs everywhere Dart runs — Flutter apps, server-side Dart, and command-line tools.

Install

dependencies:
  ethio_validators: ^0.1.0

Then:

import 'package:ethio_validators/ethio_validators.dart';

Quick start

Phone numbers

// All of these are the same number in different formats:
EthiopianPhoneValidator.isValid('0911234567');       // true
EthiopianPhoneValidator.isValid('+251 91 123 4567'); // true
EthiopianPhoneValidator.isValid('251911234567');     // true

// Normalize any accepted form to canonical E.164:
EthiopianPhoneValidator.normalize('0911 234 567');   // '+251911234567'

// Which carrier?
EthiopianPhoneValidator.carrierOf('0711234567');     // EthiopianCarrier.safaricom

// Format for display:
EthiopianPhoneValidator.format('+251911234567');     // '0911 234 567'  (local)
EthiopianPhoneValidator.format(
  '0911234567',
  format: PhoneNumberFormat.international,            // '+251 911 234 567'
);

// Invalid input throws on normalize/format; use the try* / isValid variants
// to avoid exceptions:
EthiopianPhoneValidator.tryNormalize('0111234567');  // null (landline)

Accepted input forms (separators such as spaces, -, ., and () are ignored): 09XXXXXXXX, 07XXXXXXXX, 2519XXXXXXXX, 2517XXXXXXXX, +2519XXXXXXXX, +2517XXXXXXXX, and the bare 9-digit 9XXXXXXXX / 7XXXXXXXX.

Fayda National ID

Warning

This validates basic 12-digit numeric format only.

There is no publicly documented checksum for Fayda IDs, so this cannot detect a typo within an otherwise correctly-formatted 12-digit number. This does NOT verify that an ID is real, active, or belongs to a specific person.

For actual identity verification, apps must integrate with the official Fayda eKYC API via NIDP partnership. This package does not and will not attempt unauthorized identity verification.

EthiopianNationalIdValidator.isValid('123456789012');        // true
EthiopianNationalIdValidator.isValid('1234-5678-9012');      // true

// Normalize to a clean 12-digit string:
EthiopianNationalIdValidator.normalize('1234 5678 9012');    // '123456789012'

// Format for display:
EthiopianNationalIdValidator.format('123456789012');         // '1234 5678 9012'

ETB currency

const etb = EtbFormatter();               // suffix style, 2 decimals
etb.format(1250);                         // '1,250.00 ETB'
etb.format(-1250.5);                      // '-1,250.50 ETB'
etb.parse('1,250.00 ETB');                // 1250.0

const prefixed = EtbFormatter(symbolPosition: EtbSymbolPosition.prefix);
prefixed.format(1250);                    // 'ETB 1,250.00'

const birr = EtbFormatter(symbol: 'Br', decimalDigits: 0);
birr.format(1250.7);                      // '1,251 Br'

API

EthiopianPhoneValidator (all static)

Member Description
isValid(String)bool Whether the input is a valid Ethiopian mobile number.
carrierOf(String)EthiopianCarrier? The owning carrier, or null if invalid.
normalize(String)String Canonical E.164 (+2519XXXXXXXX); throws FormatException if invalid.
tryNormalize(String)String? Like normalize, but returns null on invalid input.
format(String, {PhoneNumberFormat})String Formats as local, international, or e164; throws if invalid.
countryCode '251'.

EthiopianCarrier = { ethioTelecom, safaricom }. PhoneNumberFormat = { local, international, e164 }.

EthiopianNationalIdValidator (all static)

Member Description
isValid(String)bool Whether the input, stripped of spaces and dashes, is exactly 12 numeric digits.
normalize(String)String Returns the clean 12-digit string; throws FormatException if invalid.
tryNormalize(String)String? Like normalize, but returns null on invalid input.
format(String)String Formats as 1234 5678 9012; throws if invalid.

EtbFormatter

Member Description
EtbFormatter({symbol, symbolPosition, decimalDigits, thousandsSeparator, decimalSeparator}) Immutable, reusable formatter. Separators must differ.
format(num)String Formats an amount; groups thousands, rounds to decimalDigits. Throws on non-finite input.
parse(String)num Parses a formatted amount back to a number; throws FormatException if none found.
tryParse(String)double? Like parse, but returns null on invalid input.

EtbSymbolPosition = { suffix, prefix }.

Notes on carrier ranges

Ethiopian mobile numbers use a 9-digit national significant number whose first digit identifies the carrier: 9… for Ethio Telecom and 7… for Safaricom Ethiopia. This library validates structure and carrier prefix; it does not guarantee that a specific number has been allocated or is currently active.

Example

A runnable command-line demo (a small validation + formatting "form" flow) is in example/:

dart run example/ethio_validators_example.dart

Contributing

Part of the ethio_dev_kit monorepo. Issues and pull requests are welcome — please run dart analyze and dart test (both must be clean/green) before opening a PR.

License

MIT — see LICENSE.

Libraries

ethio_validators
Validation and formatting utilities for Ethiopian-specific data.