syntax = "proto3";

package chainhook.messages;

// The ProtocolStateStreamer service definition.
service ChainStateStreamer {
    // Get Bitcoin chain tip
    rpc GetBitcoinChainTip(None) returns (BitcoinBlockData);
}

message None {}

message Chain {
    oneof network {
        BitcoinChain bitcoin = 1;
        StacksChain stacks = 2;
    }
}

enum BitcoinChain {
    BITCOIN_REGTEST = 0;
    BITCOIN_TESTNET = 1;
    BITCOIN_MAINNET = 2;
    // BITCOIN_SIGNET = 3;
}

enum StacksChain {
    STACKS_DEVNET = 0;
    STACKS_TESTNET = 1;
    STACKS_MAINNET = 2;
}

/// BlockIdentifier uniquely identifies a block in a particular network.
message BlockIdentifier {
    /// Also known as the block height.
    uint64 index = 1;
    string hash = 2;
}

/// The transaction_identifier uniquely identifies a transaction in a particular
/// network and block or in the mempool.
message TransactionIdentifier {
    /// Any transactions that are attributable only to a block (ex: a block
    /// event) should use the hash of the block as the identifier.
    string hash = 1;
}

message BitcoinChainUpdate {
    oneof bitcoin_chain_event {
        ChainUpdatedWithBlockData chain_updated_with_block = 1;
        StacksChainUpdatedWithReorgData chain_updated_with_reorg = 2;
    }
}

message ChainUpdatedWithBlockData {
    BitcoinBlockData new_block = 1;
}

message StacksChainUpdatedWithReorgData {
    repeated BitcoinBlockData old_blocks = 1;
    repeated BitcoinBlockData new_blocks = 2;
}

message BitcoinBlockData {
    BlockIdentifier block_identifier = 1;
    BlockIdentifier parent_block_identifier = 2;
    /// The timestamp of the block in milliseconds since the Unix Epoch. The
    /// timestamp is stored in milliseconds because some blockchains produce
    /// blocks more often than once a second.
    uint64 timestamp = 3;
    repeated BitcoinTransactionData transactions = 4;
    BitcoinBlockMetadata metadata = 5;
}

/// Transactions contain an array of Operations that are attributable to the
/// same TransactionIdentifier.
message BitcoinTransactionData {
    TransactionIdentifier transaction_identifier = 1;
    repeated BitcoinOperation operations = 2;
    /// Transactions that are related to other transactions should include the
    /// transaction_identifier of these transactions in the metadata.
    BitcoinTransactionMetadata metadata = 3;
}

message BitcoinOperation {
}

message BitcoinBlockMetadata {
    repeated string inputs = 1;
    repeated string outputs = 2;
}

message BitcoinTransactionMetadata {
}
