decodeXAddress static method

Tuple<List<int>, int?> decodeXAddress(
  1. String addr,
  2. List<int>? prefix
)

Decodes an X-Address and extracts the address hash and, if present, the tag.

This method decodes the provided X-Address using Base58 decoding and validates the decoded bytes. It then extracts the address hash and, if present, the tag from the decoded bytes and returns them as a tuple.

addr The X-Address to be decoded. prefix The optional prefix representing the network type (mainnet or testnet). returns A tuple containing the address hash and an optional tag extracted from the X-Address. throws ArgumentException if the decoded address has invalid length, prefix mismatch, or an invalid tag.

Implementation

static Tuple<List<int>, int?> decodeXAddress(String addr, List<int>? prefix) {
  List<int> addrDecBytes =
      Base58Decoder.checkDecode(addr, Base58Alphabets.ripple);

  AddrDecUtils.validateBytesLength(
      addrDecBytes,
      QuickCrypto.hash160DigestSize +
          _XRPAddressConst.xAddressPrefixLength +
          _XRPAddressConst.xAddressTagLength);

  final prefixBytes =
      addrDecBytes.sublist(0, _XRPAddressConst.xAddressPrefixLength);

  if (prefix != null) {
    if (!bytesEqual(prefix, prefixBytes)) {
      throw ArgumentException(
          'Invalid prefix (expected $prefix, got $prefixBytes)');
    }
  } else {
    if (!bytesEqual(prefixBytes, _XRPAddressConst._xAddressPrefixMain) &&
        !bytesEqual(prefixBytes, _XRPAddressConst._xAddressPrefixTest)) {
      throw ArgumentException(
          'Invalid prefix for mainnet or testnet ripple address');
    }
  }

  final List<int> addrHash = addrDecBytes.sublist(
      prefixBytes.length, QuickCrypto.hash160DigestSize + prefixBytes.length);

  List<int> tagBytes = addrDecBytes
      .sublist(addrDecBytes.length - _XRPAddressConst.xAddressTagLength);
  int tagFlag = tagBytes[0];
  if (tagFlag != 0 && tagFlag != 1) {
    throw ArgumentException(
        'Invalid tag flag, tag flag should be 0 or 1 but got ${tagBytes[0]}');
  }
  tagBytes = tagBytes.sublist(1);
  if (tagFlag == 0 && !bytesEqual(tagBytes, List.filled(8, 0))) {
    throw ArgumentException("tag bytes must be zero for flag 0");
  }

  int? tag;
  if (tagFlag == 1) {
    tag = readUint32LE(tagBytes);
  }

  return Tuple(addrHash, tag);
}