The CompactTxStreamer service did not implement any mempool RPC, so lightwallets (SilentDragonXLite / ObsidianDragonLite) received UNIMPLEMENTED from get_mempool_stream and permanently stopped their mempool monitor. As a result the lite wallet could not see 0-confirmation transactions and only surfaced incoming shielded chat messages after they were mined (~1 block). Add GetMempoolStream(Empty) returns (stream RawTransaction). A single process-wide monitor (frontend/mempool.go) polls the node's getrawmempool and fetches each new tx via getrawtransaction (full serialized bytes, so shielded memos are preserved -- CompactTx's 52-byte prefix would not carry a memo), then fans the tx out to every subscribed stream. This avoids polling the node once per connected wallet: N clients share one poll loop. The monitor starts lazily on the first subscription, idles without touching the node when no clients are connected, and closes all subscriber streams when a new block is mined (the semantics the client's monitor loop expects; the client re-syncs and reconnects). Purely additive and wire-compatible: RawTransaction field numbers and the cash.z.wallet.sdk.rpc package match the deployed client; existing clients that never call GetMempoolStream are unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
101 lines
2.9 KiB
Protocol Buffer
101 lines
2.9 KiB
Protocol Buffer
syntax = "proto3";
|
|
package cash.z.wallet.sdk.rpc;
|
|
option go_package = "walletrpc";
|
|
|
|
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;
|
|
}
|
|
|
|
service CompactTxStreamer {
|
|
// Compact Blocks
|
|
rpc GetLatestBlock(ChainSpec) returns (BlockID) {}
|
|
rpc GetBlock(BlockID) returns (CompactBlock) {}
|
|
rpc GetBlockRange(BlockRange) returns (stream CompactBlock) {}
|
|
|
|
// Transactions
|
|
rpc GetTransaction(TxFilter) returns (RawTransaction) {}
|
|
rpc SendTransaction(RawTransaction) returns (SendResponse) {}
|
|
|
|
// t-Address support
|
|
rpc GetAddressTxids(TransparentAddressBlockFilter) returns (stream RawTransaction) {}
|
|
|
|
// Mempool
|
|
// Return a stream of current mempool transactions as full RawTransactions. The stream stays
|
|
// open while there are mempool transactions and is closed when a new block is mined, at which
|
|
// point the client re-syncs the block and reconnects. Full RawTransactions (not CompactTx) are
|
|
// required so wallets can read shielded memos of 0-confirmation transactions (e.g. chat).
|
|
rpc GetMempoolStream(Empty) returns (stream RawTransaction) {}
|
|
|
|
// Misc
|
|
rpc GetLightdInfo(Empty) returns (LightdInfo) {}
|
|
rpc GetCoinsupply(Empty) returns (Coinsupply) {}
|
|
}
|