decodeXAddress static method

XRPXAddressDecodeResult 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 XRPXAddressDecodeResult decodeXAddress(
    String addr, List<int>? prefix) {
  final 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 (!BytesUtils.bytesEqual(prefix, prefixBytes)) {
      throw AddressConverterException(
          'Invalid prefix (expected $prefix, got $prefixBytes)');
    }
  } else {
    if (!BytesUtils.bytesEqual(
            prefixBytes, _XRPAddressConst._xAddressPrefixMain) &&
        !BytesUtils.bytesEqual(
            prefixBytes, _XRPAddressConst._xAddressPrefixTest)) {
      throw const AddressConverterException(
          '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);
  final int tagFlag = tagBytes[0];
  if (tagFlag != 0 && tagFlag != 1) {
    throw AddressConverterException(
        'Invalid tag flag, tag flag should be 0 or 1 but got ${tagBytes[0]}');
  }
  tagBytes = tagBytes.sublist(1);
  if (tagFlag == 0 && !BytesUtils.bytesEqual(tagBytes, List.filled(8, 0))) {
    throw const AddressConverterException(
        "tag bytes must be zero for flag 0");
  }

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

  return XRPXAddressDecodeResult(
      bytes: addrHash,
      tag: tag,
      isTestnet: BytesUtils.bytesEqual(
          prefixBytes, _XRPAddressConst._xAddressPrefixTest));
}