# flake8: noqa
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: blockchain_block.proto, blockchain_block_v1.proto, blockchain_gossip_handler.proto, blockchain_region_param_v1.proto, blockchain_snapshot_handler.proto, blockchain_state_channel_v1.proto, blockchain_sync_handler.proto, blockchain_txn.proto, blockchain_txn_add_gateway_v1.proto, blockchain_txn_assert_location_v1.proto, blockchain_txn_assert_location_v2.proto, blockchain_txn_coinbase_v1.proto, blockchain_txn_consensus_group_failure_v1.proto, blockchain_txn_consensus_group_v1.proto, blockchain_txn_create_htlc_v1.proto, blockchain_txn_dc_coinbase_v1.proto, blockchain_txn_gen_gateway_v1.proto, blockchain_txn_gen_price_oracle_v1.proto, blockchain_txn_gen_validator_v1.proto, blockchain_txn_oui_v1.proto, blockchain_txn_payment_v1.proto, blockchain_txn_payment_v2.proto, blockchain_txn_poc_receipts_v1.proto, blockchain_txn_poc_request_v1.proto, blockchain_txn_price_oracle_v1.proto, blockchain_txn_redeem_htlc_v1.proto, blockchain_txn_rewards_v1.proto, blockchain_txn_rewards_v2.proto, blockchain_txn_routing_v1.proto, blockchain_txn_security_coinbase_v1.proto, blockchain_txn_security_exchange_v1.proto, blockchain_txn_stake_validator_v1.proto, blockchain_txn_state_channel_close_v1.proto, blockchain_txn_state_channel_open_v1.proto, blockchain_txn_token_burn_exchange_rate_v1.proto, blockchain_txn_token_burn_v1.proto, blockchain_txn_transfer_hotspot_v1.proto, blockchain_txn_transfer_hotspot_v2.proto, blockchain_txn_transfer_validator_stake_v1.proto, blockchain_txn_unstake_validator_v1.proto, blockchain_txn_update_gateway_oui_v1.proto, blockchain_txn_validator_heartbeat_v1.proto, blockchain_txn_vars_v1.proto, discovery.proto, packet.proto, service/gateway.proto, service/router.proto, service/state_channel.proto
# plugin: python-betterproto
from dataclasses import dataclass
from typing import AsyncIterable, AsyncIterator, Dict, Iterable, List, Union

import betterproto
import grpclib
from betterproto.grpc.grpclib_server import ServiceBase


class Origin(betterproto.Enum):
    origin_p2p = 0
    origin_radio = 1


class BlockchainTxnRewardV1Type(betterproto.Enum):
    securities = 0
    data_credits = 1
    poc_challengees = 2
    poc_challengers = 3
    poc_witnesses = 4
    consensus = 5


class PacketpacketType(betterproto.Enum):
    longfi = 0
    lorawan = 1


class Region(betterproto.Enum):
    US915 = 0
    EU868 = 1
    EU433 = 2
    CN470 = 3
    CN779 = 4
    AU915 = 5
    AS923_1 = 6
    KR920 = 7
    IN865 = 8
    AS923_2 = 9
    AS923_3 = 10
    AS923_4 = 11


class BlockchainStateChannelStateV1(betterproto.Enum):
    open = 0
    closed = 1


class RegionSpreading(betterproto.Enum):
    SF_INVALID = 0
    SF7 = 1
    SF8 = 2
    SF9 = 3
    SF10 = 4
    SF11 = 5
    SF12 = 6


class CloseState(betterproto.Enum):
    close_state_closable = 0
    close_state_closing = 1
    close_state_closed = 2
    close_state_dispute = 3


@dataclass(eq=False, repr=False)
class BlockchainTxnCoinbaseV1(betterproto.Message):
    payee: bytes = betterproto.bytes_field(1)
    amount: int = betterproto.uint64_field(2)


@dataclass(eq=False, repr=False)
class BlockchainTxnSecurityCoinbaseV1(betterproto.Message):
    payee: bytes = betterproto.bytes_field(1)
    amount: int = betterproto.uint64_field(2)


@dataclass(eq=False, repr=False)
class BlockchainTxnOuiV1(betterproto.Message):
    owner: bytes = betterproto.bytes_field(1)
    addresses: List[bytes] = betterproto.bytes_field(2)
    filter: bytes = betterproto.bytes_field(3)
    requested_subnet_size: int = betterproto.uint32_field(4)
    payer: bytes = betterproto.bytes_field(5)
    staking_fee: int = betterproto.uint64_field(6)
    fee: int = betterproto.uint64_field(7)
    owner_signature: bytes = betterproto.bytes_field(8)
    payer_signature: bytes = betterproto.bytes_field(9)
    oui: int = betterproto.uint64_field(10)


@dataclass(eq=False, repr=False)
class BlockchainTxnGenGatewayV1(betterproto.Message):
    gateway: bytes = betterproto.bytes_field(1)
    owner: bytes = betterproto.bytes_field(2)
    location: str = betterproto.string_field(3)
    nonce: int = betterproto.uint64_field(4)


@dataclass(eq=False, repr=False)
class UpdateRouters(betterproto.Message):
    router_addresses: List[bytes] = betterproto.bytes_field(1)


@dataclass(eq=False, repr=False)
class UpdateXor(betterproto.Message):
    index: int = betterproto.uint32_field(1)
    filter: bytes = betterproto.bytes_field(2)


@dataclass(eq=False, repr=False)
class BlockchainTxnRoutingV1(betterproto.Message):
    oui: int = betterproto.uint32_field(1)
    owner: bytes = betterproto.bytes_field(2)
    update_routers: "UpdateRouters" = betterproto.message_field(3, group="update")
    new_xor: bytes = betterproto.bytes_field(4, group="update")
    update_xor: "UpdateXor" = betterproto.message_field(5, group="update")
    request_subnet: int = betterproto.uint32_field(6, group="update")
    fee: int = betterproto.uint64_field(7)
    nonce: int = betterproto.uint64_field(8)
    signature: bytes = betterproto.bytes_field(9)
    staking_fee: int = betterproto.uint64_field(10)


@dataclass(eq=False, repr=False)
class BlockchainTxnPaymentV1(betterproto.Message):
    payer: bytes = betterproto.bytes_field(1)
    payee: bytes = betterproto.bytes_field(2)
    amount: int = betterproto.uint64_field(3)
    fee: int = betterproto.uint64_field(4)
    nonce: int = betterproto.uint64_field(5)
    signature: bytes = betterproto.bytes_field(6)


@dataclass(eq=False, repr=False)
class BlockchainTxnSecurityExchangeV1(betterproto.Message):
    payer: bytes = betterproto.bytes_field(1)
    payee: bytes = betterproto.bytes_field(2)
    amount: int = betterproto.uint64_field(3)
    fee: int = betterproto.uint64_field(4)
    nonce: int = betterproto.uint64_field(5)
    signature: bytes = betterproto.bytes_field(6)


@dataclass(eq=False, repr=False)
class BlockchainTxnConsensusGroupV1(betterproto.Message):
    members: List[bytes] = betterproto.bytes_field(1)
    proof: bytes = betterproto.bytes_field(2)
    height: int = betterproto.uint64_field(3)
    delay: int = betterproto.uint32_field(4)


@dataclass(eq=False, repr=False)
class BlockchainTxnConsensusGroupFailureV1(betterproto.Message):
    failed_members: List[bytes] = betterproto.bytes_field(1)
    height: int = betterproto.uint64_field(2)
    delay: int = betterproto.uint64_field(3)
    members: List[bytes] = betterproto.bytes_field(4)
    signatures: List[bytes] = betterproto.bytes_field(5)


@dataclass(eq=False, repr=False)
class BlockchainTxnAddGatewayV1(betterproto.Message):
    owner: bytes = betterproto.bytes_field(1)
    gateway: bytes = betterproto.bytes_field(2)
    owner_signature: bytes = betterproto.bytes_field(3)
    gateway_signature: bytes = betterproto.bytes_field(4)
    payer: bytes = betterproto.bytes_field(5)
    payer_signature: bytes = betterproto.bytes_field(6)
    staking_fee: int = betterproto.uint64_field(7)
    fee: int = betterproto.uint64_field(8)


@dataclass(eq=False, repr=False)
class BlockchainTxnAssertLocationV1(betterproto.Message):
    gateway: bytes = betterproto.bytes_field(1)
    owner: bytes = betterproto.bytes_field(2)
    payer: bytes = betterproto.bytes_field(3)
    gateway_signature: bytes = betterproto.bytes_field(4)
    owner_signature: bytes = betterproto.bytes_field(5)
    payer_signature: bytes = betterproto.bytes_field(6)
    # Use the h3 string representation since it will use all 64 bits (and JS
    # doesn't support that)
    location: str = betterproto.string_field(7)
    nonce: int = betterproto.uint64_field(8)
    staking_fee: int = betterproto.uint64_field(9)
    fee: int = betterproto.uint64_field(10)


@dataclass(eq=False, repr=False)
class BlockchainTxnCreateHtlcV1(betterproto.Message):
    payer: bytes = betterproto.bytes_field(1)
    payee: bytes = betterproto.bytes_field(2)
    address: bytes = betterproto.bytes_field(3)
    hashlock: bytes = betterproto.bytes_field(4)
    timelock: int = betterproto.uint64_field(5)
    amount: int = betterproto.uint64_field(6)
    fee: int = betterproto.uint64_field(7)
    signature: bytes = betterproto.bytes_field(8)
    nonce: int = betterproto.uint64_field(9)


@dataclass(eq=False, repr=False)
class BlockchainTxnRedeemHtlcV1(betterproto.Message):
    payee: bytes = betterproto.bytes_field(1)
    address: bytes = betterproto.bytes_field(2)
    preimage: bytes = betterproto.bytes_field(3)
    fee: int = betterproto.uint64_field(4)
    signature: bytes = betterproto.bytes_field(5)


@dataclass(eq=False, repr=False)
class BlockchainTxnPocRequestV1(betterproto.Message):
    challenger: bytes = betterproto.bytes_field(1)
    secret_hash: bytes = betterproto.bytes_field(2)
    onion_key_hash: bytes = betterproto.bytes_field(3)
    block_hash: bytes = betterproto.bytes_field(4)
    fee: int = betterproto.uint64_field(5)
    signature: bytes = betterproto.bytes_field(6)
    version: int = betterproto.uint32_field(7)


@dataclass(eq=False, repr=False)
class BlockchainPocReceiptV1(betterproto.Message):
    gateway: bytes = betterproto.bytes_field(1)
    timestamp: int = betterproto.uint64_field(2)
    signal: int = betterproto.sint32_field(3)
    data: bytes = betterproto.bytes_field(4)
    origin: "Origin" = betterproto.enum_field(5)
    signature: bytes = betterproto.bytes_field(6)
    snr: float = betterproto.float_field(7)
    frequency: float = betterproto.float_field(8)
    channel: int = betterproto.int32_field(9)
    datarate: str = betterproto.string_field(10)
    addr_hash: bytes = betterproto.bytes_field(11)
    # Transmit power at which this packet was transmitted It is x10, for example:
    # 270 = 27db, 36 = 3.6db etc
    tx_power: int = betterproto.int32_field(12)


@dataclass(eq=False, repr=False)
class BlockchainPocWitnessV1(betterproto.Message):
    gateway: bytes = betterproto.bytes_field(1)
    timestamp: int = betterproto.uint64_field(2)
    signal: int = betterproto.sint32_field(3)
    packet_hash: bytes = betterproto.bytes_field(4)
    signature: bytes = betterproto.bytes_field(5)
    snr: float = betterproto.float_field(6)
    frequency: float = betterproto.float_field(7)
    channel: int = betterproto.int32_field(8)
    datarate: str = betterproto.string_field(9)


@dataclass(eq=False, repr=False)
class BlockchainPocResponseV1(betterproto.Message):
    receipt: "BlockchainPocReceiptV1" = betterproto.message_field(1, group="payload")
    witness: "BlockchainPocWitnessV1" = betterproto.message_field(2, group="payload")


@dataclass(eq=False, repr=False)
class BlockchainPocPathElementV1(betterproto.Message):
    challengee: bytes = betterproto.bytes_field(1)
    receipt: "BlockchainPocReceiptV1" = betterproto.message_field(2)
    witnesses: List["BlockchainPocWitnessV1"] = betterproto.message_field(3)


@dataclass(eq=False, repr=False)
class BlockchainTxnPocReceiptsV1(betterproto.Message):
    challenger: bytes = betterproto.bytes_field(1)
    secret: bytes = betterproto.bytes_field(2)
    onion_key_hash: bytes = betterproto.bytes_field(3)
    path: List["BlockchainPocPathElementV1"] = betterproto.message_field(4)
    fee: int = betterproto.uint64_field(5)
    signature: bytes = betterproto.bytes_field(6)
    request_block_hash: bytes = betterproto.bytes_field(7)


@dataclass(eq=False, repr=False)
class BlockchainVarV1(betterproto.Message):
    name: str = betterproto.string_field(1)
    type: str = betterproto.string_field(2)
    value: bytes = betterproto.bytes_field(3)


@dataclass(eq=False, repr=False)
class BlockchainTxnVarsV1(betterproto.Message):
    vars: List["BlockchainVarV1"] = betterproto.message_field(1)
    version_predicate: int = betterproto.uint32_field(2)
    proof: bytes = betterproto.bytes_field(3)
    master_key: bytes = betterproto.bytes_field(4)
    key_proof: bytes = betterproto.bytes_field(5)
    cancels: List[bytes] = betterproto.bytes_field(6)
    unsets: List[bytes] = betterproto.bytes_field(7)
    nonce: int = betterproto.uint32_field(8)
    multi_keys: List[bytes] = betterproto.bytes_field(9)
    multi_proofs: List[bytes] = betterproto.bytes_field(10)
    multi_key_proofs: List[bytes] = betterproto.bytes_field(11)


@dataclass(eq=False, repr=False)
class BlockchainTxnRewardV1(betterproto.Message):
    account: bytes = betterproto.bytes_field(1)
    gateway: bytes = betterproto.bytes_field(3)
    amount: int = betterproto.uint64_field(4)
    type: "blockchain_txn_reward_v1.Type" = betterproto.enum_field(5)


@dataclass(eq=False, repr=False)
class BlockchainTxnRewardsV1(betterproto.Message):
    start_epoch: int = betterproto.uint64_field(1)
    end_epoch: int = betterproto.uint64_field(2)
    rewards: List["BlockchainTxnRewardV1"] = betterproto.message_field(3)


@dataclass(eq=False, repr=False)
class BlockchainTxnTokenBurnV1(betterproto.Message):
    payer: bytes = betterproto.bytes_field(1)
    payee: bytes = betterproto.bytes_field(2)
    amount: int = betterproto.uint64_field(3)
    nonce: int = betterproto.uint64_field(4)
    signature: bytes = betterproto.bytes_field(5)
    fee: int = betterproto.uint64_field(6)
    memo: int = betterproto.uint64_field(7)


@dataclass(eq=False, repr=False)
class BlockchainTxnDcCoinbaseV1(betterproto.Message):
    payee: bytes = betterproto.bytes_field(1)
    amount: int = betterproto.uint64_field(2)


@dataclass(eq=False, repr=False)
class BlockchainTxnTokenBurnExchangeRateV1(betterproto.Message):
    rate: int = betterproto.uint64_field(1)


@dataclass(eq=False, repr=False)
class BlockchainTxnStateChannelOpenV1(betterproto.Message):
    id: bytes = betterproto.bytes_field(1)
    owner: bytes = betterproto.bytes_field(2)
    amount: int = betterproto.int64_field(3)
    expire_within: int = betterproto.int64_field(4)
    oui: int = betterproto.uint64_field(5)
    nonce: int = betterproto.uint64_field(6)
    signature: bytes = betterproto.bytes_field(7)
    fee: int = betterproto.uint64_field(8)


@dataclass(eq=False, repr=False)
class BlockchainTxnUpdateGatewayOuiV1(betterproto.Message):
    gateway: bytes = betterproto.bytes_field(1)
    oui: int = betterproto.uint64_field(2)
    nonce: int = betterproto.uint64_field(3)
    fee: int = betterproto.uint64_field(4)
    gateway_owner_signature: bytes = betterproto.bytes_field(5)
    oui_owner_signature: bytes = betterproto.bytes_field(6)


@dataclass(eq=False, repr=False)
class Eui(betterproto.Message):
    deveui: int = betterproto.uint64_field(1)
    appeui: int = betterproto.uint64_field(2)


@dataclass(eq=False, repr=False)
class RoutingInformation(betterproto.Message):
    devaddr: int = betterproto.uint32_field(1, group="data")
    eui: "Eui" = betterproto.message_field(2, group="data")


@dataclass(eq=False, repr=False)
class Window(betterproto.Message):
    timestamp: int = betterproto.uint64_field(1)
    frequency: float = betterproto.float_field(2)
    datarate: str = betterproto.string_field(3)


@dataclass(eq=False, repr=False)
class Packet(betterproto.Message):
    oui: int = betterproto.uint32_field(1)
    type: "packet.PacketType" = betterproto.enum_field(2)
    payload: bytes = betterproto.bytes_field(3)
    timestamp: int = betterproto.uint64_field(4)
    signal_strength: float = betterproto.float_field(5)
    frequency: float = betterproto.float_field(6)
    datarate: str = betterproto.string_field(7)
    snr: float = betterproto.float_field(8)
    routing: "RoutingInformation" = betterproto.message_field(9)
    rx2_window: "Window" = betterproto.message_field(10)


@dataclass(eq=False, repr=False)
class BlockchainStateChannelSummaryV1(betterproto.Message):
    client_pubkeybin: bytes = betterproto.bytes_field(1)
    num_packets: int = betterproto.uint64_field(2)
    num_dcs: int = betterproto.uint64_field(3)


@dataclass(eq=False, repr=False)
class BlockchainStateChannelV1(betterproto.Message):
    id: bytes = betterproto.bytes_field(1)
    owner: bytes = betterproto.bytes_field(2)
    credits: int = betterproto.uint64_field(3)
    nonce: int = betterproto.uint64_field(4)
    summaries: List["BlockchainStateChannelSummaryV1"] = betterproto.message_field(5)
    root_hash: bytes = betterproto.bytes_field(6)
    # This is unused but we can't remove it yet
    skewed: bytes = betterproto.bytes_field(7)
    state: "BlockchainStateChannelStateV1" = betterproto.enum_field(8)
    expire_at_block: int = betterproto.uint64_field(9)
    signature: bytes = betterproto.bytes_field(10)


@dataclass(eq=False, repr=False)
class BlockchainStateChannelResponseV1(betterproto.Message):
    accepted: bool = betterproto.bool_field(1)
    downlink: "Packet" = betterproto.message_field(4)


@dataclass(eq=False, repr=False)
class BlockchainStateChannelPacketV1(betterproto.Message):
    packet: "Packet" = betterproto.message_field(1)
    hotspot: bytes = betterproto.bytes_field(2)
    signature: bytes = betterproto.bytes_field(3)
    region: "Region" = betterproto.enum_field(4)
    hold_time: int = betterproto.uint64_field(5)


@dataclass(eq=False, repr=False)
class BlockchainStateChannelOfferV1(betterproto.Message):
    routing: "RoutingInformation" = betterproto.message_field(1)
    packet_hash: bytes = betterproto.bytes_field(2)
    payload_size: int = betterproto.uint64_field(3)
    fcnt: int = betterproto.uint32_field(4)
    hotspot: bytes = betterproto.bytes_field(5)
    signature: bytes = betterproto.bytes_field(6)
    region: "Region" = betterproto.enum_field(7)
    req_diff: bool = betterproto.bool_field(8)


@dataclass(eq=False, repr=False)
class BlockchainStateChannelPurchaseV1(betterproto.Message):
    sc: "BlockchainStateChannelV1" = betterproto.message_field(1)
    hotspot: bytes = betterproto.bytes_field(2)
    packet_hash: bytes = betterproto.bytes_field(3)
    region: "Region" = betterproto.enum_field(4)
    sc_diff: "BlockchainStateChannelDiffV1" = betterproto.message_field(5)


@dataclass(eq=False, repr=False)
class BlockchainStateChannelDiffV1(betterproto.Message):
    id: bytes = betterproto.bytes_field(1)
    add_nonce: int = betterproto.uint64_field(2)
    signature: bytes = betterproto.bytes_field(3)
    diffs: List["BlockchainStateChannelDiffEntryV1"] = betterproto.message_field(4)


@dataclass(eq=False, repr=False)
class BlockchainStateChannelDiffEntryV1(betterproto.Message):
    append: "BlockchainStateChannelDiffAppendSummaryV1" = betterproto.message_field(
        1, group="entry"
    )
    add: "BlockchainStateChannelDiffUpdateSummaryV1" = betterproto.message_field(
        2, group="entry"
    )


@dataclass(eq=False, repr=False)
class BlockchainStateChannelDiffAppendSummaryV1(betterproto.Message):
    client_pubkeybin: bytes = betterproto.bytes_field(1)
    num_packets: int = betterproto.uint64_field(2)
    num_dcs: int = betterproto.uint64_field(3)


@dataclass(eq=False, repr=False)
class BlockchainStateChannelDiffUpdateSummaryV1(betterproto.Message):
    client_index: int = betterproto.uint64_field(1)
    add_packets: int = betterproto.uint64_field(2)
    add_dcs: int = betterproto.uint64_field(3)


@dataclass(eq=False, repr=False)
class BlockchainStateChannelBannerV1(betterproto.Message):
    """DEPRECATED"""

    sc: "BlockchainStateChannelV1" = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class BlockchainStateChannelRejectionV1(betterproto.Message):
    reject: int = betterproto.uint32_field(1)
    packet_hash: bytes = betterproto.bytes_field(2)


@dataclass(eq=False, repr=False)
class BlockchainStateChannelMessageV1(betterproto.Message):
    response: "BlockchainStateChannelResponseV1" = betterproto.message_field(
        2, group="msg"
    )
    packet: "BlockchainStateChannelPacketV1" = betterproto.message_field(4, group="msg")
    offer: "BlockchainStateChannelOfferV1" = betterproto.message_field(5, group="msg")
    purchase: "BlockchainStateChannelPurchaseV1" = betterproto.message_field(
        6, group="msg"
    )
    banner: "BlockchainStateChannelBannerV1" = betterproto.message_field(7, group="msg")
    reject: "BlockchainStateChannelRejectionV1" = betterproto.message_field(
        8, group="msg"
    )


@dataclass(eq=False, repr=False)
class BlockchainTxnStateChannelCloseV1(betterproto.Message):
    state_channel: "BlockchainStateChannelV1" = betterproto.message_field(1)
    closer: bytes = betterproto.bytes_field(2)
    signature: bytes = betterproto.bytes_field(3)
    fee: int = betterproto.uint64_field(4)
    conflicts_with: "BlockchainStateChannelV1" = betterproto.message_field(5)


@dataclass(eq=False, repr=False)
class BlockchainTxnPaymentV2(betterproto.Message):
    payer: bytes = betterproto.bytes_field(1)
    payments: List["Payment"] = betterproto.message_field(2)
    fee: int = betterproto.uint64_field(3)
    nonce: int = betterproto.uint64_field(4)
    signature: bytes = betterproto.bytes_field(5)


@dataclass(eq=False, repr=False)
class Payment(betterproto.Message):
    payee: bytes = betterproto.bytes_field(1)
    amount: int = betterproto.uint64_field(2)
    memo: int = betterproto.uint64_field(3)


@dataclass(eq=False, repr=False)
class BlockchainTxnPriceOracleV1(betterproto.Message):
    public_key: bytes = betterproto.bytes_field(1)
    price: int = betterproto.uint64_field(2)
    block_height: int = betterproto.uint64_field(3)
    signature: bytes = betterproto.bytes_field(4)


@dataclass(eq=False, repr=False)
class BlockchainTxnGenPriceOracleV1(betterproto.Message):
    price: int = betterproto.uint64_field(1)


@dataclass(eq=False, repr=False)
class BlockchainTxnTransferHotspotV1(betterproto.Message):
    gateway: bytes = betterproto.bytes_field(1)
    seller: bytes = betterproto.bytes_field(2)
    buyer: bytes = betterproto.bytes_field(3)
    seller_signature: bytes = betterproto.bytes_field(4)
    buyer_signature: bytes = betterproto.bytes_field(5)
    buyer_nonce: int = betterproto.uint64_field(6)
    amount_to_seller: int = betterproto.uint64_field(7)
    fee: int = betterproto.uint64_field(8)


@dataclass(eq=False, repr=False)
class BlockchainTxnRewardV2(betterproto.Message):
    account: bytes = betterproto.bytes_field(1)
    amount: int = betterproto.uint64_field(2)


@dataclass(eq=False, repr=False)
class BlockchainTxnRewardsV2(betterproto.Message):
    start_epoch: int = betterproto.uint64_field(1)
    end_epoch: int = betterproto.uint64_field(2)
    rewards: List["BlockchainTxnRewardV2"] = betterproto.message_field(3)


@dataclass(eq=False, repr=False)
class BlockchainTxnGenValidatorV1(betterproto.Message):
    address: bytes = betterproto.bytes_field(1)
    owner: bytes = betterproto.bytes_field(2)
    stake: int = betterproto.uint64_field(3)


@dataclass(eq=False, repr=False)
class BlockchainTxnStakeValidatorV1(betterproto.Message):
    address: bytes = betterproto.bytes_field(1)
    owner: bytes = betterproto.bytes_field(2)
    stake: int = betterproto.uint64_field(3)
    owner_signature: bytes = betterproto.bytes_field(4)
    fee: int = betterproto.uint64_field(5)


@dataclass(eq=False, repr=False)
class BlockchainTxnTransferValidatorStakeV1(betterproto.Message):
    old_address: bytes = betterproto.bytes_field(1)
    new_address: bytes = betterproto.bytes_field(2)
    old_owner: bytes = betterproto.bytes_field(3)
    new_owner: bytes = betterproto.bytes_field(4)
    old_owner_signature: bytes = betterproto.bytes_field(5)
    new_owner_signature: bytes = betterproto.bytes_field(6)
    fee: int = betterproto.uint64_field(7)
    stake_amount: int = betterproto.uint64_field(8)
    # optional amount (in bones) the new owner is transferring to the old owner
    payment_amount: int = betterproto.uint64_field(9)


@dataclass(eq=False, repr=False)
class BlockchainTxnUnstakeValidatorV1(betterproto.Message):
    address: bytes = betterproto.bytes_field(1)
    owner: bytes = betterproto.bytes_field(2)
    owner_signature: bytes = betterproto.bytes_field(3)
    fee: int = betterproto.uint64_field(4)
    stake_amount: int = betterproto.uint64_field(5)
    stake_release_height: int = betterproto.uint64_field(6)


@dataclass(eq=False, repr=False)
class BlockchainTxnValidatorHeartbeatV1(betterproto.Message):
    address: bytes = betterproto.bytes_field(1)
    height: int = betterproto.uint64_field(2)
    version: int = betterproto.uint32_field(3)
    signature: bytes = betterproto.bytes_field(4)


@dataclass(eq=False, repr=False)
class BlockchainTxnAssertLocationV2(betterproto.Message):
    gateway: bytes = betterproto.bytes_field(1)
    owner: bytes = betterproto.bytes_field(2)
    payer: bytes = betterproto.bytes_field(3)
    owner_signature: bytes = betterproto.bytes_field(4)
    payer_signature: bytes = betterproto.bytes_field(5)
    # Use the h3 string representation since it will use all 64 bits (and JS
    # doesn't support that)
    location: str = betterproto.string_field(6)
    nonce: int = betterproto.uint64_field(7)
    # It is assumed that this gain applies to both rx and tx
    gain: int = betterproto.int32_field(8)
    elevation: int = betterproto.int32_field(9)
    staking_fee: int = betterproto.uint64_field(10)
    fee: int = betterproto.uint64_field(11)


@dataclass(eq=False, repr=False)
class BlockchainTxnTransferHotspotV2(betterproto.Message):
    gateway: bytes = betterproto.bytes_field(1)
    owner: bytes = betterproto.bytes_field(2)
    owner_signature: bytes = betterproto.bytes_field(3)
    new_owner: bytes = betterproto.bytes_field(4)
    fee: int = betterproto.uint64_field(5)
    # gateway nonce
    nonce: int = betterproto.uint64_field(6)


@dataclass(eq=False, repr=False)
class BlockchainTxn(betterproto.Message):
    add_gateway: "BlockchainTxnAddGatewayV1" = betterproto.message_field(1, group="txn")
    assert_location: "BlockchainTxnAssertLocationV1" = betterproto.message_field(
        2, group="txn"
    )
    coinbase: "BlockchainTxnCoinbaseV1" = betterproto.message_field(3, group="txn")
    create_htlc: "BlockchainTxnCreateHtlcV1" = betterproto.message_field(4, group="txn")
    gen_gateway: "BlockchainTxnGenGatewayV1" = betterproto.message_field(5, group="txn")
    consensus_group: "BlockchainTxnConsensusGroupV1" = betterproto.message_field(
        6, group="txn"
    )
    oui: "BlockchainTxnOuiV1" = betterproto.message_field(7, group="txn")
    payment: "BlockchainTxnPaymentV1" = betterproto.message_field(8, group="txn")
    poc_receipts: "BlockchainTxnPocReceiptsV1" = betterproto.message_field(
        9, group="txn"
    )
    poc_request: "BlockchainTxnPocRequestV1" = betterproto.message_field(
        10, group="txn"
    )
    redeem_htlc: "BlockchainTxnRedeemHtlcV1" = betterproto.message_field(
        11, group="txn"
    )
    security_coinbase: "BlockchainTxnSecurityCoinbaseV1" = betterproto.message_field(
        12, group="txn"
    )
    routing: "BlockchainTxnRoutingV1" = betterproto.message_field(13, group="txn")
    security_exchange: "BlockchainTxnSecurityExchangeV1" = betterproto.message_field(
        14, group="txn"
    )
    vars: "BlockchainTxnVarsV1" = betterproto.message_field(15, group="txn")
    rewards: "BlockchainTxnRewardsV1" = betterproto.message_field(16, group="txn")
    token_burn: "BlockchainTxnTokenBurnV1" = betterproto.message_field(17, group="txn")
    dc_coinbase: "BlockchainTxnDcCoinbaseV1" = betterproto.message_field(
        18, group="txn"
    )
    token_burn_exchange_rate: "BlockchainTxnTokenBurnExchangeRateV1" = (
        betterproto.message_field(19, group="txn")
    )
    bundle: "BlockchainTxnBundleV1" = betterproto.message_field(20, group="txn")
    state_channel_open: "BlockchainTxnStateChannelOpenV1" = betterproto.message_field(
        21, group="txn"
    )
    update_gateway_oui: "BlockchainTxnUpdateGatewayOuiV1" = betterproto.message_field(
        22, group="txn"
    )
    state_channel_close: "BlockchainTxnStateChannelCloseV1" = betterproto.message_field(
        23, group="txn"
    )
    payment_v2: "BlockchainTxnPaymentV2" = betterproto.message_field(24, group="txn")
    price_oracle_submission: "BlockchainTxnPriceOracleV1" = betterproto.message_field(
        25, group="txn"
    )
    gen_price_oracle: "BlockchainTxnGenPriceOracleV1" = betterproto.message_field(
        26, group="txn"
    )
    transfer_hotspot: "BlockchainTxnTransferHotspotV1" = betterproto.message_field(
        27, group="txn"
    )
    gen_validator: "BlockchainTxnGenValidatorV1" = betterproto.message_field(
        28, group="txn"
    )
    stake_validator: "BlockchainTxnStakeValidatorV1" = betterproto.message_field(
        29, group="txn"
    )
    transfer_val_stake: "BlockchainTxnTransferValidatorStakeV1" = (
        betterproto.message_field(30, group="txn")
    )
    unstake_validator: "BlockchainTxnUnstakeValidatorV1" = betterproto.message_field(
        31, group="txn"
    )
    val_heartbeat: "BlockchainTxnValidatorHeartbeatV1" = betterproto.message_field(
        32, group="txn"
    )
    consensus_group_failure: "BlockchainTxnConsensusGroupFailureV1" = (
        betterproto.message_field(33, group="txn")
    )
    rewards_v2: "BlockchainTxnRewardsV2" = betterproto.message_field(34, group="txn")
    assert_location_v2: "BlockchainTxnAssertLocationV2" = betterproto.message_field(
        35, group="txn"
    )
    transfer_hotspot_v2: "BlockchainTxnTransferHotspotV2" = betterproto.message_field(
        36, group="txn"
    )


@dataclass(eq=False, repr=False)
class BlockchainTxnBundleV1(betterproto.Message):
    transactions: List["BlockchainTxn"] = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class BlockchainSignatureV1(betterproto.Message):
    signer: bytes = betterproto.bytes_field(1)
    signature: bytes = betterproto.bytes_field(2)


@dataclass(eq=False, repr=False)
class BlockchainSeenVoteV1(betterproto.Message):
    index: int = betterproto.uint32_field(1)
    vector: bytes = betterproto.bytes_field(2)


@dataclass(eq=False, repr=False)
class BlockchainBlockV1(betterproto.Message):
    prev_hash: bytes = betterproto.bytes_field(1)
    height: int = betterproto.uint64_field(2)
    time: int = betterproto.uint64_field(3)
    hbbft_round: int = betterproto.uint64_field(4)
    transactions: List["BlockchainTxn"] = betterproto.message_field(5)
    signatures: List["BlockchainSignatureV1"] = betterproto.message_field(6)
    election_epoch: int = betterproto.uint64_field(7)
    epoch_start: int = betterproto.uint64_field(8)
    rescue_signature: bytes = betterproto.bytes_field(9)
    seen_votes: List["BlockchainSeenVoteV1"] = betterproto.message_field(10)
    bba_completion: bytes = betterproto.bytes_field(11)
    snapshot_hash: bytes = betterproto.bytes_field(12)
    rescue_signatures: List[bytes] = betterproto.bytes_field(13)


@dataclass(eq=False, repr=False)
class BlockchainBlock(betterproto.Message):
    v1: "BlockchainBlockV1" = betterproto.message_field(1, group="block")


@dataclass(eq=False, repr=False)
class BlockchainGossipBlock(betterproto.Message):
    from_: bytes = betterproto.bytes_field(1)
    block: bytes = betterproto.bytes_field(2)
    hash: bytes = betterproto.bytes_field(3)
    height: int = betterproto.uint64_field(4)


@dataclass(eq=False, repr=False)
class BlockchainRegionParamsV1(betterproto.Message):
    region_params: List["BlockchainRegionParamV1"] = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class TaggedSpreading(betterproto.Message):
    region_spreading: "RegionSpreading" = betterproto.enum_field(1)
    max_packet_size: int = betterproto.uint32_field(2)


@dataclass(eq=False, repr=False)
class BlockchainRegionSpreadingV1(betterproto.Message):
    tagged_spreading: List["TaggedSpreading"] = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class BlockchainRegionParamV1(betterproto.Message):
    # in hertz
    channel_frequency: int = betterproto.uint64_field(1)
    # in hertz
    bandwidth: int = betterproto.uint32_field(2)
    # in dBi x 10
    max_eirp: int = betterproto.uint32_field(3)
    # list of atoms
    spreading: "BlockchainRegionSpreadingV1" = betterproto.message_field(4)


@dataclass(eq=False, repr=False)
class BlockchainSnapshotReq(betterproto.Message):
    height: int = betterproto.uint64_field(1)
    hash: bytes = betterproto.bytes_field(2)


@dataclass(eq=False, repr=False)
class BlockchainSnapshotResp(betterproto.Message):
    next_height: int = betterproto.sint64_field(1)
    snapshot: bytes = betterproto.bytes_field(2)


@dataclass(eq=False, repr=False)
class BlockchainSyncHash(betterproto.Message):
    hash: bytes = betterproto.bytes_field(1)
    heights: List[int] = betterproto.uint64_field(2)


@dataclass(eq=False, repr=False)
class BlockchainSyncBlocks(betterproto.Message):
    blocks: List[bytes] = betterproto.bytes_field(1)


@dataclass(eq=False, repr=False)
class BlockchainSyncReq(betterproto.Message):
    hash: "BlockchainSyncHash" = betterproto.message_field(1, group="msg")
    response: bool = betterproto.bool_field(2, group="msg")


@dataclass(eq=False, repr=False)
class DiscoveryStart(betterproto.Message):
    hotspot: bytes = betterproto.bytes_field(1)
    packets: List[bytes] = betterproto.bytes_field(2)
    signature: bytes = betterproto.bytes_field(3)


@dataclass(eq=False, repr=False)
class GatewayConfigReqV1(betterproto.Message):
    keys: List[str] = betterproto.string_field(1)


@dataclass(eq=False, repr=False)
class GatewayConfigRespV1(betterproto.Message):
    result: List["BlockchainVarV1"] = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class GatewayConfigUpdateReqV1(betterproto.Message):
    pass


@dataclass(eq=False, repr=False)
class GatewayConfigUpdateStreamedRespV1(betterproto.Message):
    keys: List[str] = betterproto.string_field(1)


@dataclass(eq=False, repr=False)
class GatewayValidatorsReqV1(betterproto.Message):
    quantity: int = betterproto.uint32_field(1)


@dataclass(eq=False, repr=False)
class GatewayValidatorsRespV1(betterproto.Message):
    result: List["RoutingAddress"] = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class GatewayRespV1(betterproto.Message):
    height: int = betterproto.uint64_field(1)
    signature: bytes = betterproto.bytes_field(2)
    is_active_resp: "GatewayScIsActiveRespV1" = betterproto.message_field(
        3, group="msg"
    )
    is_overpaid_resp: "GatewayScIsOverpaidRespV1" = betterproto.message_field(
        4, group="msg"
    )
    close_resp: "GatewayScCloseRespV1" = betterproto.message_field(5, group="msg")
    follow_streamed_resp: "GatewayScFollowStreamedRespV1" = betterproto.message_field(
        6, group="msg"
    )
    routing_streamed_resp: "GatewayRoutingStreamedRespV1" = betterproto.message_field(
        7, group="msg"
    )
    config_resp: "GatewayConfigRespV1" = betterproto.message_field(8, group="msg")
    config_update_streamed_resp: "GatewayConfigUpdateStreamedRespV1" = (
        betterproto.message_field(9, group="msg")
    )
    validators_resp: "GatewayValidatorsRespV1" = betterproto.message_field(
        12, group="msg"
    )
    block_time: int = betterproto.uint64_field(10)
    block_age: int = betterproto.uint64_field(11)


@dataclass(eq=False, repr=False)
class GatewayScIsActiveReqV1(betterproto.Message):
    sc_id: bytes = betterproto.bytes_field(1)
    sc_owner: bytes = betterproto.bytes_field(2)


@dataclass(eq=False, repr=False)
class GatewayScIsActiveRespV1(betterproto.Message):
    sc_id: bytes = betterproto.bytes_field(1)
    sc_owner: bytes = betterproto.bytes_field(2)
    active: bool = betterproto.bool_field(3)
    sc_expiry_at_block: int = betterproto.uint64_field(4)
    sc_original_dc_amount: int = betterproto.uint64_field(5)


@dataclass(eq=False, repr=False)
class GatewayScIsOverpaidReqV1(betterproto.Message):
    sc_id: bytes = betterproto.bytes_field(1)
    sc_owner: bytes = betterproto.bytes_field(2)
    total_dcs: int = betterproto.uint64_field(3)


@dataclass(eq=False, repr=False)
class GatewayScIsOverpaidRespV1(betterproto.Message):
    sc_id: bytes = betterproto.bytes_field(1)
    sc_owner: bytes = betterproto.bytes_field(2)
    overpaid: bool = betterproto.bool_field(3)


@dataclass(eq=False, repr=False)
class GatewayScCloseReqV1(betterproto.Message):
    close_txn: "BlockchainTxnStateChannelCloseV1" = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class GatewayScCloseRespV1(betterproto.Message):
    sc_id: bytes = betterproto.bytes_field(1)
    response: bytes = betterproto.bytes_field(2)


@dataclass(eq=False, repr=False)
class GatewayScFollowReqV1(betterproto.Message):
    sc_id: bytes = betterproto.bytes_field(1)
    sc_owner: bytes = betterproto.bytes_field(2)


@dataclass(eq=False, repr=False)
class GatewayScFollowStreamedRespV1(betterproto.Message):
    sc_id: bytes = betterproto.bytes_field(1)
    sc_owner: bytes = betterproto.bytes_field(2)
    close_state: "CloseState" = betterproto.enum_field(3)


@dataclass(eq=False, repr=False)
class Routing(betterproto.Message):
    oui: int = betterproto.uint32_field(1)
    owner: bytes = betterproto.bytes_field(2)
    addresses: List["RoutingAddress"] = betterproto.message_field(3)
    filters: List[bytes] = betterproto.bytes_field(4)
    subnets: List[bytes] = betterproto.bytes_field(5)


@dataclass(eq=False, repr=False)
class RoutingAddress(betterproto.Message):
    pub_key: bytes = betterproto.bytes_field(1)
    uri: bytes = betterproto.bytes_field(2)


@dataclass(eq=False, repr=False)
class GatewayRoutingReqV1(betterproto.Message):
    height: int = betterproto.uint64_field(1)


@dataclass(eq=False, repr=False)
class GatewayRoutingStreamedRespV1(betterproto.Message):
    routings: List["Routing"] = betterproto.message_field(1)


class GatewayStub(betterproto.ServiceStub):
    async def is_active_sc(self) -> "GatewayRespV1":

        request = GatewayScIsActiveReqV1()

        return await self._unary_unary(
            "/helium.gateway/is_active_sc", request, GatewayRespV1
        )

    async def is_overpaid_sc(self) -> "GatewayRespV1":

        request = GatewayScIsOverpaidReqV1()

        return await self._unary_unary(
            "/helium.gateway/is_overpaid_sc", request, GatewayRespV1
        )

    async def close_sc(self) -> "GatewayRespV1":

        request = GatewayScCloseReqV1()

        return await self._unary_unary(
            "/helium.gateway/close_sc", request, GatewayRespV1
        )

    async def follow_sc(
        self,
        request_iterator: Union[
            AsyncIterable["GatewayScFollowReqV1"], Iterable["GatewayScFollowReqV1"]
        ],
    ) -> AsyncIterator["GatewayRespV1"]:

        async for response in self._stream_stream(
            "/helium.gateway/follow_sc",
            request_iterator,
            GatewayScFollowReqV1,
            GatewayRespV1,
        ):
            yield response

    async def routing(self) -> AsyncIterator["GatewayRespV1"]:

        request = GatewayRoutingReqV1()

        async for response in self._unary_stream(
            "/helium.gateway/routing",
            request,
            GatewayRespV1,
        ):
            yield response

    async def config(self) -> "GatewayRespV1":

        request = GatewayConfigReqV1()

        return await self._unary_unary("/helium.gateway/config", request, GatewayRespV1)

    async def config_update(self) -> AsyncIterator["GatewayRespV1"]:

        request = GatewayConfigUpdateReqV1()

        async for response in self._unary_stream(
            "/helium.gateway/config_update",
            request,
            GatewayRespV1,
        ):
            yield response

    async def validators(self) -> "GatewayRespV1":

        request = GatewayValidatorsReqV1()

        return await self._unary_unary(
            "/helium.gateway/validators", request, GatewayRespV1
        )


class RouterStub(betterproto.ServiceStub):
    async def route(self) -> "BlockchainStateChannelMessageV1":

        request = BlockchainStateChannelMessageV1()

        return await self._unary_unary(
            "/helium.router/route", request, BlockchainStateChannelMessageV1
        )


class StateChannelStub(betterproto.ServiceStub):
    async def msg(
        self,
        request_iterator: Union[
            AsyncIterable["BlockchainStateChannelMessageV1"],
            Iterable["BlockchainStateChannelMessageV1"],
        ],
    ) -> AsyncIterator["BlockchainStateChannelMessageV1"]:

        async for response in self._stream_stream(
            "/helium.state_channel/msg",
            request_iterator,
            BlockchainStateChannelMessageV1,
            BlockchainStateChannelMessageV1,
        ):
            yield response


class GatewayBase(betterproto.ServiceStub):
    async def is_active_sc(self) -> "GatewayRespV1":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def is_overpaid_sc(self) -> "GatewayRespV1":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def close_sc(self) -> "GatewayRespV1":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def follow_sc(
        self, request_iterator: AsyncIterator["GatewayScFollowReqV1"]
    ) -> AsyncIterator["GatewayRespV1"]:
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def routing(self) -> AsyncIterator["GatewayRespV1"]:
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def config(self) -> "GatewayRespV1":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def config_update(self) -> AsyncIterator["GatewayRespV1"]:
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def validators(self) -> "GatewayRespV1":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_is_active_sc(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {}

        response = await self.is_active_sc(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_is_overpaid_sc(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {}

        response = await self.is_overpaid_sc(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_close_sc(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {}

        response = await self.close_sc(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_follow_sc(self, stream: grpclib.server.Stream) -> None:
        request_kwargs = {"request_iterator": stream.__aiter__()}

        await self._call_rpc_handler_server_stream(
            self.follow_sc,
            stream,
            request_kwargs,
        )

    async def __rpc_routing(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {}

        await self._call_rpc_handler_server_stream(
            self.routing,
            stream,
            request_kwargs,
        )

    async def __rpc_config(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {}

        response = await self.config(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_config_update(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {}

        await self._call_rpc_handler_server_stream(
            self.config_update,
            stream,
            request_kwargs,
        )

    async def __rpc_validators(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {}

        response = await self.validators(**request_kwargs)
        await stream.send_message(response)

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/helium.gateway/is_active_sc": grpclib.const.Handler(
                self.__rpc_is_active_sc,
                grpclib.const.Cardinality.UNARY_UNARY,
                GatewayScIsActiveReqV1,
                GatewayRespV1,
            ),
            "/helium.gateway/is_overpaid_sc": grpclib.const.Handler(
                self.__rpc_is_overpaid_sc,
                grpclib.const.Cardinality.UNARY_UNARY,
                GatewayScIsOverpaidReqV1,
                GatewayRespV1,
            ),
            "/helium.gateway/close_sc": grpclib.const.Handler(
                self.__rpc_close_sc,
                grpclib.const.Cardinality.UNARY_UNARY,
                GatewayScCloseReqV1,
                GatewayRespV1,
            ),
            "/helium.gateway/follow_sc": grpclib.const.Handler(
                self.__rpc_follow_sc,
                grpclib.const.Cardinality.STREAM_STREAM,
                GatewayScFollowReqV1,
                GatewayRespV1,
            ),
            "/helium.gateway/routing": grpclib.const.Handler(
                self.__rpc_routing,
                grpclib.const.Cardinality.UNARY_STREAM,
                GatewayRoutingReqV1,
                GatewayRespV1,
            ),
            "/helium.gateway/config": grpclib.const.Handler(
                self.__rpc_config,
                grpclib.const.Cardinality.UNARY_UNARY,
                GatewayConfigReqV1,
                GatewayRespV1,
            ),
            "/helium.gateway/config_update": grpclib.const.Handler(
                self.__rpc_config_update,
                grpclib.const.Cardinality.UNARY_STREAM,
                GatewayConfigUpdateReqV1,
                GatewayRespV1,
            ),
            "/helium.gateway/validators": grpclib.const.Handler(
                self.__rpc_validators,
                grpclib.const.Cardinality.UNARY_UNARY,
                GatewayValidatorsReqV1,
                GatewayRespV1,
            ),
        }


class RouterBase(ServiceBase):
    async def route(self) -> "BlockchainStateChannelMessageV1":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_route(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {}

        response = await self.route(**request_kwargs)
        await stream.send_message(response)

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/helium.router/route": grpclib.const.Handler(
                self.__rpc_route,
                grpclib.const.Cardinality.UNARY_UNARY,
                BlockchainStateChannelMessageV1,
                BlockchainStateChannelMessageV1,
            ),
        }


class StateChannelBase(ServiceBase):
    async def msg(
        self, request_iterator: AsyncIterator["BlockchainStateChannelMessageV1"]
    ) -> AsyncIterator["BlockchainStateChannelMessageV1"]:
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_msg(self, stream: grpclib.server.Stream) -> None:
        request_kwargs = {"request_iterator": stream.__aiter__()}

        await self._call_rpc_handler_server_stream(
            self.msg,
            stream,
            request_kwargs,
        )

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/helium.state_channel/msg": grpclib.const.Handler(
                self.__rpc_msg,
                grpclib.const.Cardinality.STREAM_STREAM,
                BlockchainStateChannelMessageV1,
                BlockchainStateChannelMessageV1,
            ),
        }


