decode method

Implementation

AdaGenericAddrDecoderResult decode(String addr) {
  (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 = (AdaShelleyAddrUtils.getAddressHrp(network), base58Decode);
    checkedByron = true;
  }

  final List<int> addressBytes = addrDecBytes.$2;
  if (addressBytes.length < QuickCrypto.blake2b224DigestSize + 1) {
    throw AddressConverterException.addressValidationFailed(
      reason: "Invalid address length.",
    );
  }
  final int header = addressBytes[0];
  final int networkTag = AdaShelleyAddrUtils.decodeNetworkTag(header);
  final 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 = AdaShelleyAddrUtils.getAddressHrp(network);

  switch (addressType) {
    case ADAAddressType.base:
      AddrDecUtils.validateBytesLength(
        addressBytes,
        (QuickCrypto.blake2b224DigestSize * 2) + 1,
      );
      break;
    case ADAAddressType.reward:
      AddrDecUtils.validateBytesLength(
        addressBytes,
        QuickCrypto.blake2b224DigestSize + 1,
      );
      hrp = AdaShelleyAddrUtils.getRewardAddressHrp(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.addressValidationFailed(
        reason: "Invalid address prefix.",
      );
  }
  if (addrDecBytes.$1 != hrp) {
    throw AddressConverterException.addressValidationFailed(
      reason: "Invalid address checksum.",
    );
  }

  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,
  );
}