syntax = "proto3";
package cash.z.wallet.sdk.rpc;
option go_package = "lightwalletd/walletrpc";
option swift_prefix = "";
import "compact_formats.proto";

// A BlockID message contains identifiers to select a block: a height or a
// hash. If the hash is present it takes precedence.
message BlockID {
     uint64 height = 1;
     bytes hash = 2;
}

// BlockRange technically allows ranging from hash to hash etc but this is not
// currently intended for support, though there is no reason you couldn't do
// it. Further permutations are left as an exercise.
message BlockRange {
    BlockID start = 1;
    BlockID end = 2;
}

// A TxFilter contains the information needed to identify a particular
// transaction: either a block and an index, or a direct transaction hash.
message TxFilter {
     BlockID block = 1;
     uint64 index = 2;
     bytes hash = 3;
}

// RawTransaction contains the complete transaction data. It also optionally includes 
// the block height in which the transaction was included
message RawTransaction {
    bytes data = 1;
    uint64 height = 2;
}

message SendResponse {
    int32 errorCode = 1;
    string errorMessage = 2;
}

// Empty placeholder. Someday we may want to specify e.g. a particular chain fork.
message ChainSpec {}

message Empty {}

message LightdInfo {
    string version = 1;
    string vendor = 2;
    bool   taddrSupport = 3;
    string chainName = 4;
    uint64 saplingActivationHeight = 5;
    string consensusBranchId = 6;   // This should really be u32 or []byte, but string for readability
    uint64 blockHeight = 7;
    uint64 difficulty = 8;
    uint64 longestchain = 9;
    uint64 notarized = 10;
}
message Coinsupply {
    string result = 1;
    string coin = 2;
    uint64 height = 3;
    uint64 supply = 4;
    uint64 zfunds = 5;
    uint64 total = 6;
}

message TransparentAddress {
    string address = 1;
}

message TransparentAddressBlockFilter {
    string address = 1;
    BlockRange range = 2;
}

message Address {
    string address = 1;
}
message AddressList {
    repeated string addresses = 1;
}
message Balance {
    int64 valueZat = 1;
}

message Exclude {
    repeated bytes txid = 1;
}

// The TreeState is derived from the Hush getblockmerkletree rpc.
// https://faq.hush.is/rpc/getblockmerkletree.html
message TreeState {
    string network = 1;     // "main" or "test"
    uint64 height = 2;      // block height
    string hash = 3;        // block id
    uint32 time = 4;        // Unix epoch time when the block was mined
    string saplingTree = 5; // sapling commitment tree state
}

// Results are sorted by height, which makes it easy to issue another
// request that picks up from where the previous left off.
message GetAddressUtxosArg {
    repeated string addresses = 1;
    uint64 startHeight = 2;
    uint32 maxEntries = 3; // zero means unlimited
}
message GetAddressUtxosReply {
    string address = 6;
    bytes txid = 1;
    int32 index = 2;
    bytes script = 3;
    int64 valueZat = 4;
    uint64 height = 5;
}
message GetAddressUtxosReplyList {
    repeated GetAddressUtxosReply addressUtxos = 1;
}

service CompactTxStreamer {
    // Return the height of the tip of the best chain
    rpc GetLatestBlock(ChainSpec) returns (BlockID) {}
    // Return the compact block corresponding to the given block identifier
    rpc GetBlock(BlockID) returns (CompactBlock) {}
    // Return a list of consecutive compact blocks
    rpc GetBlockRange(BlockRange) returns (stream CompactBlock) {}

    // Return the requested full (not compact) transaction (as from zcashd)
    rpc GetTransaction(TxFilter) returns (RawTransaction) {}
    // Submit the given transaction to the Zcash network
    rpc SendTransaction(RawTransaction) returns (SendResponse) {}

    // Return the txids corresponding to the given t-address within the given block range
    rpc GetTaddressTxids(TransparentAddressBlockFilter) returns (stream RawTransaction) {}
    // wrapper for GetTaddressTxids
    rpc GetAddressTxids(TransparentAddressBlockFilter) returns (stream RawTransaction) {}
    rpc GetTaddressBalance(AddressList) returns (Balance) {}
    rpc GetTaddressBalanceStream(stream Address) returns (Balance) {}

    // Return the compact transactions currently in the mempool; the results
    // can be a few seconds out of date. If the Exclude list is empty, return
    // all transactions; otherwise return all *except* those in the Exclude list
    // (if any); this allows the client to avoid receiving transactions that it
    // already has (from an earlier call to this rpc). The transaction IDs in the
    // Exclude list can be shortened to any number of bytes to make the request
    // more bandwidth-efficient; if two or more transactions in the mempool
    // match a shortened txid, they are all sent (none is excluded). Transactions
    // in the exclude list that don't exist in the mempool are ignored.
    rpc GetMempoolTx(Exclude) returns (stream CompactTx) {}

    // Return a stream of current Mempool transactions. This will keep the output stream open while
    // there are mempool transactions. It will close the returned stream when a new block is mined.
    rpc GetMempoolStream(Empty) returns (stream RawTransaction) {}

    // GetTreeState returns the note commitment tree state corresponding to the given block.
    // See section 3.7 of the Zcash protocol specification. It returns several other useful
    // values also (even though they can be obtained using GetBlock).
    // The block can be specified by either height or hash.
    rpc GetTreeState(BlockID) returns (TreeState) {}
    rpc GetLatestTreeState(Empty) returns (TreeState) {}

    rpc GetAddressUtxos(GetAddressUtxosArg) returns (GetAddressUtxosReplyList) {}
    rpc GetAddressUtxosStream(GetAddressUtxosArg) returns (stream GetAddressUtxosReply) {}

    // Return information about this lightwalletd instance and the blockchain
    rpc GetLightdInfo(Empty) returns (LightdInfo) {}
    // Testing-only, requires lightwalletd --ping-very-insecure (do not enable in production)
    // rpc Ping(Duration) returns (PingResponse) {}
    rpc GetCoinsupply(Empty) returns (Coinsupply) {}
}