decode method

AdaGenericAddrDecoderResult decode(
  1. String addr, [
  2. Map<String, dynamic> kwargs = const {}
])

Implementation

AdaGenericAddrDecoderResult decode(String addr,
    [Map<String, dynamic> kwargs = const {}]) {
  final netTag = kwargs["net_tag"];

  if (netTag != null) {
    if (netTag is! ADANetwork) {
      throw const AddressConverterException(
          'Address type is not an enumerative of ADANetwork');
    }
  }
  Tuple<String, List<int>> addrDecBytes;
  bool checkedByron = false;
  ADANetwork? network;
  try {
    // Decode the provided Bech32 address.
    addrDecBytes = Bech32Decoder.decodeWithoutHRP(addr);
  } catch (e) {
    final base58Decode = Base58Decoder.decode(addr);
    final byron = ADAByronAddr.deserialize(base58Decode);
    network = ADANetwork.fromProtocolMagic(byron.payload.attrs.networkMagic);
    addrDecBytes = Tuple(
        AdaShelleyAddrConst.networkTagToAddrHrp[network]!, base58Decode);
    checkedByron = true;
  }

  final List<int> addressBytes = addrDecBytes.item2;
  if (addressBytes.length < QuickCrypto.blake2b224DigestSize + 1) {
    throw const AddressConverterException("Invalid address length.");
  }
  int header = addressBytes[0];
  int networkTag = AdaShelleyAddrUtils.decodeNetworkTag(header);
  ADAAddressType addressType = ADAAddressType.decodeAddressType(header);

  if (network == null) {
    if (addressType == ADAAddressType.byron) {
      final byron = ADAByronAddr.deserialize(addressBytes);
      network =
          ADANetwork.fromProtocolMagic(byron.payload.attrs.networkMagic);
    } else {
      network = ADANetwork.fromTag(networkTag);
    }
  }
  String? hrp = AdaShelleyAddrConst.networkTagToAddrHrp[network];

  switch (addressType) {
    case ADAAddressType.base:
      AddrDecUtils.validateBytesLength(
          addressBytes, (QuickCrypto.blake2b224DigestSize * 2) + 1);
      break;
    case ADAAddressType.reward:
      AddrDecUtils.validateBytesLength(
          addressBytes, QuickCrypto.blake2b224DigestSize + 1);
      hrp = AdaShelleyAddrConst.networkTagToRewardAddrHrp[network];
      break;
    case ADAAddressType.enterprise:
      AddrDecUtils.validateBytesLength(
          addressBytes, QuickCrypto.blake2b224DigestSize + 1);
      break;
    case ADAAddressType.pointer:
      AddrDecUtils.validateBytesLength(
          addressBytes, QuickCrypto.blake2b224DigestSize + 1 + 3,
          minLength: QuickCrypto.blake2b224DigestSize + 1 + 3);
      break;
    case ADAAddressType.byron:
      if (!checkedByron) {
        ADAByronAddr.deserialize(addressBytes);
      }

      break;
    default:
      throw AddressConverterException("Invalid address prefix $addressType");
  }
  if (hrp == null || addrDecBytes.item1 != hrp) {
    throw AddressConverterException("Invalid address hrp ${hrp ?? ''}");
  }

  if (addressType == ADAAddressType.byron) {
    return AdaGenericAddrDecoderResult._(
        type: addressType,
        baseHashBytes: null,
        network: network,
        addressBytes: addressBytes,
        byronAddrPayload: ADAByronAddr.deserialize(addressBytes));
  }

  final prefixByte = AdaShelleyAddrUtils.encodePrefix(
    addressType,
    networkTag,
    AdaShelleyAddrUtils.decodeCred(header, 4),
    stakeType: AdaShelleyAddrUtils.decodeCred(header, 5),
  );
  return AdaGenericAddrDecoderResult._(
    type: addressType,
    addressBytes: addressBytes,
    network: network,
    baseHashBytes: AdaStakeCredential(
        hash: addressBytes.sublist(prefixByte.length,
            prefixByte.length + QuickCrypto.blake2b224DigestSize),
        type: AdaShelleyAddrUtils.decodeCred(header, 4)),
    prefixBytes: prefixByte,
    stakeHashBytes: addressType == ADAAddressType.base
        ? AdaStakeCredential(
            hash: addressBytes.sublist(
                prefixByte.length + QuickCrypto.blake2b224DigestSize),
            type: AdaShelleyAddrUtils.decodeCred(header, 5))
        : null,
    pointer: addressType == ADAAddressType.pointer
        ? Pointer.fromBytes(addressBytes
            .sublist(prefixByte.length + QuickCrypto.blake2b224DigestSize))
        : null,
  );
}