Integration tests
This commit is contained in:
parent
e73fa4fca4
commit
22779ddf02
|
@ -4,3 +4,4 @@
|
|||
docs/_site/
|
||||
*.db
|
||||
Cargo.lock
|
||||
node_modules/
|
||||
|
|
|
@ -37,20 +37,30 @@ message CompactTx {
|
|||
// valueBalance + (sum(vPubNew) - sum(vPubOld) - sum(tOut))
|
||||
uint32 fee = 3;
|
||||
|
||||
repeated CompactSpend spends = 4; // inputs
|
||||
repeated CompactOutput outputs = 5; // outputs
|
||||
repeated CompactSaplingSpend spends = 4; // inputs
|
||||
repeated CompactSaplingOutput outputs = 5; // outputs
|
||||
repeated CompactOrchardAction actions = 6;
|
||||
}
|
||||
|
||||
// CompactSpend is a Sapling Spend Description as described in 7.3 of the Zcash
|
||||
// CompactSaplingSpend is a Sapling Spend Description as described in 7.3 of the Zcash
|
||||
// protocol specification.
|
||||
message CompactSpend {
|
||||
message CompactSaplingSpend {
|
||||
bytes nf = 1; // nullifier (see the Zcash protocol specification)
|
||||
}
|
||||
|
||||
// output is a Sapling Output Description as described in section 7.4 of the
|
||||
// Zcash protocol spec. Total size is 948.
|
||||
message CompactOutput {
|
||||
message CompactSaplingOutput {
|
||||
bytes cmu = 1; // note commitment u-coordinate
|
||||
bytes epk = 2; // ephemeral public key
|
||||
bytes ciphertext = 3; // ciphertext and zkproof
|
||||
bytes ciphertext = 3; // first 52 bytes of ciphertext
|
||||
}
|
||||
|
||||
// https://github.com/zcash/zips/blob/main/zip-0225.rst#orchard-action-description-orchardaction
|
||||
// (but not all fields are needed)
|
||||
message CompactOrchardAction {
|
||||
bytes nullifier = 1; // [32] The nullifier of the input note
|
||||
bytes cmx = 2; // [32] The x-coordinate of the note commitment for the output note
|
||||
bytes ephemeralKey = 3; // [32] An encoding of an ephemeral Pallas public key
|
||||
bytes ciphertext = 4; // [52] The note plaintext component of the encCiphertext field
|
||||
}
|
||||
|
|
|
@ -32,7 +32,8 @@ message TxFilter {
|
|||
}
|
||||
|
||||
// RawTransaction contains the complete transaction data. It also optionally includes
|
||||
// the block height in which the transaction was included.
|
||||
// the block height in which the transaction was included, or, when returned
|
||||
// by GetMempoolStream(), the latest block height.
|
||||
message RawTransaction {
|
||||
bytes data = 1; // exact data returned by Zcash 'getrawtransaction'
|
||||
uint64 height = 2; // height that the transaction was mined (or -1)
|
||||
|
@ -109,11 +110,12 @@ message Exclude {
|
|||
|
||||
// The TreeState is derived from the Zcash z_gettreestate rpc.
|
||||
message TreeState {
|
||||
string network = 1; // "main" or "test"
|
||||
uint64 height = 2;
|
||||
string hash = 3; // block id
|
||||
uint32 time = 4; // Unix epoch time when the block was mined
|
||||
string tree = 5; // sapling commitment tree state
|
||||
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
|
||||
string orchardTree = 6; // orchard commitment tree state
|
||||
}
|
||||
|
||||
// Results are sorted by height, which makes it easy to issue another
|
||||
|
@ -135,27 +137,6 @@ message GetAddressUtxosReplyList {
|
|||
repeated GetAddressUtxosReply addressUtxos = 1;
|
||||
}
|
||||
|
||||
|
||||
message PriceRequest {
|
||||
// List of timestamps(in sec) at which the price is being requested
|
||||
uint64 timestamp = 1;
|
||||
|
||||
// 3 letter currency-code
|
||||
string currency = 2;
|
||||
}
|
||||
|
||||
message PriceResponse {
|
||||
// Timestamp at which this price quote was fetched. Note, this may not be the same
|
||||
// as the request timestamp, but the server will respond with the closest timestamp that it has/can fetch
|
||||
int64 timestamp = 1;
|
||||
|
||||
// 3-letter currency code, matching the request
|
||||
string currency = 2;
|
||||
|
||||
// price of ZEC
|
||||
double price = 3;
|
||||
}
|
||||
|
||||
service CompactTxStreamer {
|
||||
// Return the height of the tip of the best chain
|
||||
rpc GetLatestBlock(ChainSpec) returns (BlockID) {}
|
||||
|
@ -164,10 +145,6 @@ service CompactTxStreamer {
|
|||
// Return a list of consecutive compact blocks
|
||||
rpc GetBlockRange(BlockRange) returns (stream CompactBlock) {}
|
||||
|
||||
// Get the historical and current prices
|
||||
rpc GetZECPrice(PriceRequest) returns (PriceResponse) {}
|
||||
rpc GetCurrentZECPrice(Empty) returns (PriceResponse) {}
|
||||
|
||||
// Return the requested full (not compact) transaction (as from zcashd)
|
||||
rpc GetTransaction(TxFilter) returns (RawTransaction) {}
|
||||
// Submit the given transaction to the Zcash network
|
||||
|
@ -175,10 +152,6 @@ service CompactTxStreamer {
|
|||
|
||||
// Return the txids corresponding to the given t-address within the given block range
|
||||
rpc GetTaddressTxids(TransparentAddressBlockFilter) returns (stream RawTransaction) {}
|
||||
|
||||
// Legacy API that is used as a fallback for t-Address support, if the server is running the old version (lwdv2)
|
||||
rpc GetAddressTxids(TransparentAddressBlockFilter) returns (stream RawTransaction) {}
|
||||
|
||||
rpc GetTaddressBalance(AddressList) returns (Balance) {}
|
||||
rpc GetTaddressBalanceStream(stream Address) returns (Balance) {}
|
||||
|
||||
|
@ -193,6 +166,10 @@ service CompactTxStreamer {
|
|||
// 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).
|
||||
|
|
|
@ -90,7 +90,7 @@ async fn fetch_and_store_tree_state(
|
|||
.get_tree_state(Request::new(block_id))
|
||||
.await?
|
||||
.into_inner();
|
||||
let tree = CTree::read(&*hex::decode(&tree_state.tree)?)?;
|
||||
let tree = CTree::read(&*hex::decode(&tree_state.sapling_tree)?)?;
|
||||
c.db()?
|
||||
.store_block(height, &block.hash, block.time, &tree)?;
|
||||
Ok(())
|
||||
|
|
|
@ -167,7 +167,7 @@ pub struct DecryptedNote {
|
|||
pub output_index: usize,
|
||||
}
|
||||
|
||||
pub fn to_output_description(co: &CompactOutput) -> CompactOutputDescription {
|
||||
pub fn to_output_description(co: &CompactSaplingOutput) -> CompactOutputDescription {
|
||||
let mut cmu = [0u8; 32];
|
||||
cmu.copy_from_slice(&co.cmu);
|
||||
let cmu = bls12_381::Scalar::from_repr(cmu).unwrap();
|
||||
|
@ -201,7 +201,7 @@ impl<'a, N: Parameters> AccountOutput<'a, N> {
|
|||
output_index: usize,
|
||||
block_output_index: usize,
|
||||
vtx: &'a CompactTx,
|
||||
co: &CompactOutput,
|
||||
co: &CompactSaplingOutput,
|
||||
) -> Self {
|
||||
let mut epk_bytes = [0u8; 32];
|
||||
epk_bytes.copy_from_slice(&co.epk);
|
||||
|
@ -355,7 +355,7 @@ async fn get_tree_state(client: &mut CompactTxStreamerClient<Channel>, height: u
|
|||
.await
|
||||
.unwrap()
|
||||
.into_inner();
|
||||
rep.tree
|
||||
rep.sapling_tree
|
||||
}
|
||||
|
||||
/* Using the IncrementalWitness */
|
||||
|
|
|
@ -46,15 +46,17 @@ pub struct CompactTx {
|
|||
pub fee: u32,
|
||||
/// inputs
|
||||
#[prost(message, repeated, tag="4")]
|
||||
pub spends: ::prost::alloc::vec::Vec<CompactSpend>,
|
||||
pub spends: ::prost::alloc::vec::Vec<CompactSaplingSpend>,
|
||||
/// outputs
|
||||
#[prost(message, repeated, tag="5")]
|
||||
pub outputs: ::prost::alloc::vec::Vec<CompactOutput>,
|
||||
pub outputs: ::prost::alloc::vec::Vec<CompactSaplingOutput>,
|
||||
#[prost(message, repeated, tag="6")]
|
||||
pub actions: ::prost::alloc::vec::Vec<CompactOrchardAction>,
|
||||
}
|
||||
/// CompactSpend is a Sapling Spend Description as described in 7.3 of the Zcash
|
||||
/// CompactSaplingSpend is a Sapling Spend Description as described in 7.3 of the Zcash
|
||||
/// protocol specification.
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct CompactSpend {
|
||||
pub struct CompactSaplingSpend {
|
||||
/// nullifier (see the Zcash protocol specification)
|
||||
#[prost(bytes="vec", tag="1")]
|
||||
pub nf: ::prost::alloc::vec::Vec<u8>,
|
||||
|
@ -62,17 +64,34 @@ pub struct CompactSpend {
|
|||
/// output is a Sapling Output Description as described in section 7.4 of the
|
||||
/// Zcash protocol spec. Total size is 948.
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct CompactOutput {
|
||||
pub struct CompactSaplingOutput {
|
||||
/// note commitment u-coordinate
|
||||
#[prost(bytes="vec", tag="1")]
|
||||
pub cmu: ::prost::alloc::vec::Vec<u8>,
|
||||
/// ephemeral public key
|
||||
#[prost(bytes="vec", tag="2")]
|
||||
pub epk: ::prost::alloc::vec::Vec<u8>,
|
||||
/// ciphertext and zkproof
|
||||
/// first 52 bytes of ciphertext
|
||||
#[prost(bytes="vec", tag="3")]
|
||||
pub ciphertext: ::prost::alloc::vec::Vec<u8>,
|
||||
}
|
||||
/// <https://github.com/zcash/zips/blob/main/zip-0225.rst#orchard-action-description-orchardaction>
|
||||
/// (but not all fields are needed)
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct CompactOrchardAction {
|
||||
/// \[32\] The nullifier of the input note
|
||||
#[prost(bytes="vec", tag="1")]
|
||||
pub nullifier: ::prost::alloc::vec::Vec<u8>,
|
||||
/// \[32\] The x-coordinate of the note commitment for the output note
|
||||
#[prost(bytes="vec", tag="2")]
|
||||
pub cmx: ::prost::alloc::vec::Vec<u8>,
|
||||
/// \[32\] An encoding of an ephemeral Pallas public key
|
||||
#[prost(bytes="vec", tag="3")]
|
||||
pub ephemeral_key: ::prost::alloc::vec::Vec<u8>,
|
||||
/// \[52\] The note plaintext component of the encCiphertext field
|
||||
#[prost(bytes="vec", tag="4")]
|
||||
pub ciphertext: ::prost::alloc::vec::Vec<u8>,
|
||||
}
|
||||
/// A BlockID message contains identifiers to select a block: a height or a
|
||||
/// hash. Specification by hash is not implemented, but may be in the future.
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
|
@ -107,7 +126,8 @@ pub struct TxFilter {
|
|||
pub hash: ::prost::alloc::vec::Vec<u8>,
|
||||
}
|
||||
/// RawTransaction contains the complete transaction data. It also optionally includes
|
||||
/// the block height in which the transaction was included.
|
||||
/// the block height in which the transaction was included, or, when returned
|
||||
/// by GetMempoolStream(), the latest block height.
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct RawTransaction {
|
||||
/// exact data returned by Zcash 'getrawtransaction'
|
||||
|
@ -231,6 +251,7 @@ pub struct TreeState {
|
|||
/// "main" or "test"
|
||||
#[prost(string, tag="1")]
|
||||
pub network: ::prost::alloc::string::String,
|
||||
/// block height
|
||||
#[prost(uint64, tag="2")]
|
||||
pub height: u64,
|
||||
/// block id
|
||||
|
@ -241,7 +262,10 @@ pub struct TreeState {
|
|||
pub time: u32,
|
||||
/// sapling commitment tree state
|
||||
#[prost(string, tag="5")]
|
||||
pub tree: ::prost::alloc::string::String,
|
||||
pub sapling_tree: ::prost::alloc::string::String,
|
||||
/// orchard commitment tree state
|
||||
#[prost(string, tag="6")]
|
||||
pub orchard_tree: ::prost::alloc::string::String,
|
||||
}
|
||||
/// Results are sorted by height, which makes it easy to issue another
|
||||
/// request that picks up from where the previous left off.
|
||||
|
@ -275,28 +299,6 @@ pub struct GetAddressUtxosReplyList {
|
|||
#[prost(message, repeated, tag="1")]
|
||||
pub address_utxos: ::prost::alloc::vec::Vec<GetAddressUtxosReply>,
|
||||
}
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct PriceRequest {
|
||||
/// List of timestamps(in sec) at which the price is being requested
|
||||
#[prost(uint64, tag="1")]
|
||||
pub timestamp: u64,
|
||||
/// 3 letter currency-code
|
||||
#[prost(string, tag="2")]
|
||||
pub currency: ::prost::alloc::string::String,
|
||||
}
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct PriceResponse {
|
||||
/// Timestamp at which this price quote was fetched. Note, this may not be the same
|
||||
/// as the request timestamp, but the server will respond with the closest timestamp that it has/can fetch
|
||||
#[prost(int64, tag="1")]
|
||||
pub timestamp: i64,
|
||||
/// 3-letter currency code, matching the request
|
||||
#[prost(string, tag="2")]
|
||||
pub currency: ::prost::alloc::string::String,
|
||||
/// price of ZEC
|
||||
#[prost(double, tag="3")]
|
||||
pub price: f64,
|
||||
}
|
||||
/// Generated client implementations.
|
||||
pub mod compact_tx_streamer_client {
|
||||
#![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
|
||||
|
@ -406,9 +408,9 @@ pub mod compact_tx_streamer_client {
|
|||
&mut self,
|
||||
request: impl tonic::IntoRequest<super::BlockRange>,
|
||||
) -> Result<
|
||||
tonic::Response<tonic::codec::Streaming<super::CompactBlock>>,
|
||||
tonic::Status,
|
||||
> {
|
||||
tonic::Response<tonic::codec::Streaming<super::CompactBlock>>,
|
||||
tonic::Status,
|
||||
> {
|
||||
self.inner
|
||||
.ready()
|
||||
.await
|
||||
|
@ -424,45 +426,6 @@ pub mod compact_tx_streamer_client {
|
|||
);
|
||||
self.inner.server_streaming(request.into_request(), path, codec).await
|
||||
}
|
||||
/// Get the historical and current prices
|
||||
pub async fn get_zec_price(
|
||||
&mut self,
|
||||
request: impl tonic::IntoRequest<super::PriceRequest>,
|
||||
) -> Result<tonic::Response<super::PriceResponse>, tonic::Status> {
|
||||
self.inner
|
||||
.ready()
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tonic::Status::new(
|
||||
tonic::Code::Unknown,
|
||||
format!("Service was not ready: {}", e.into()),
|
||||
)
|
||||
})?;
|
||||
let codec = tonic::codec::ProstCodec::default();
|
||||
let path = http::uri::PathAndQuery::from_static(
|
||||
"/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetZECPrice",
|
||||
);
|
||||
self.inner.unary(request.into_request(), path, codec).await
|
||||
}
|
||||
pub async fn get_current_zec_price(
|
||||
&mut self,
|
||||
request: impl tonic::IntoRequest<super::Empty>,
|
||||
) -> Result<tonic::Response<super::PriceResponse>, tonic::Status> {
|
||||
self.inner
|
||||
.ready()
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tonic::Status::new(
|
||||
tonic::Code::Unknown,
|
||||
format!("Service was not ready: {}", e.into()),
|
||||
)
|
||||
})?;
|
||||
let codec = tonic::codec::ProstCodec::default();
|
||||
let path = http::uri::PathAndQuery::from_static(
|
||||
"/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetCurrentZECPrice",
|
||||
);
|
||||
self.inner.unary(request.into_request(), path, codec).await
|
||||
}
|
||||
/// Return the requested full (not compact) transaction (as from zcashd)
|
||||
pub async fn get_transaction(
|
||||
&mut self,
|
||||
|
@ -508,9 +471,9 @@ pub mod compact_tx_streamer_client {
|
|||
&mut self,
|
||||
request: impl tonic::IntoRequest<super::TransparentAddressBlockFilter>,
|
||||
) -> Result<
|
||||
tonic::Response<tonic::codec::Streaming<super::RawTransaction>>,
|
||||
tonic::Status,
|
||||
> {
|
||||
tonic::Response<tonic::codec::Streaming<super::RawTransaction>>,
|
||||
tonic::Status,
|
||||
> {
|
||||
self.inner
|
||||
.ready()
|
||||
.await
|
||||
|
@ -526,29 +489,6 @@ pub mod compact_tx_streamer_client {
|
|||
);
|
||||
self.inner.server_streaming(request.into_request(), path, codec).await
|
||||
}
|
||||
/// Legacy API that is used as a fallback for t-Address support, if the server is running the old version (lwdv2)
|
||||
pub async fn get_address_txids(
|
||||
&mut self,
|
||||
request: impl tonic::IntoRequest<super::TransparentAddressBlockFilter>,
|
||||
) -> Result<
|
||||
tonic::Response<tonic::codec::Streaming<super::RawTransaction>>,
|
||||
tonic::Status,
|
||||
> {
|
||||
self.inner
|
||||
.ready()
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tonic::Status::new(
|
||||
tonic::Code::Unknown,
|
||||
format!("Service was not ready: {}", e.into()),
|
||||
)
|
||||
})?;
|
||||
let codec = tonic::codec::ProstCodec::default();
|
||||
let path = http::uri::PathAndQuery::from_static(
|
||||
"/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetAddressTxids",
|
||||
);
|
||||
self.inner.server_streaming(request.into_request(), path, codec).await
|
||||
}
|
||||
pub async fn get_taddress_balance(
|
||||
&mut self,
|
||||
request: impl tonic::IntoRequest<super::AddressList>,
|
||||
|
@ -602,9 +542,9 @@ pub mod compact_tx_streamer_client {
|
|||
&mut self,
|
||||
request: impl tonic::IntoRequest<super::Exclude>,
|
||||
) -> Result<
|
||||
tonic::Response<tonic::codec::Streaming<super::CompactTx>>,
|
||||
tonic::Status,
|
||||
> {
|
||||
tonic::Response<tonic::codec::Streaming<super::CompactTx>>,
|
||||
tonic::Status,
|
||||
> {
|
||||
self.inner
|
||||
.ready()
|
||||
.await
|
||||
|
@ -620,6 +560,30 @@ pub mod compact_tx_streamer_client {
|
|||
);
|
||||
self.inner.server_streaming(request.into_request(), path, codec).await
|
||||
}
|
||||
/// 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.
|
||||
pub async fn get_mempool_stream(
|
||||
&mut self,
|
||||
request: impl tonic::IntoRequest<super::Empty>,
|
||||
) -> Result<
|
||||
tonic::Response<tonic::codec::Streaming<super::RawTransaction>>,
|
||||
tonic::Status,
|
||||
> {
|
||||
self.inner
|
||||
.ready()
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tonic::Status::new(
|
||||
tonic::Code::Unknown,
|
||||
format!("Service was not ready: {}", e.into()),
|
||||
)
|
||||
})?;
|
||||
let codec = tonic::codec::ProstCodec::default();
|
||||
let path = http::uri::PathAndQuery::from_static(
|
||||
"/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetMempoolStream",
|
||||
);
|
||||
self.inner.server_streaming(request.into_request(), path, codec).await
|
||||
}
|
||||
/// 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).
|
||||
|
@ -666,9 +630,9 @@ pub mod compact_tx_streamer_client {
|
|||
&mut self,
|
||||
request: impl tonic::IntoRequest<super::GetAddressUtxosArg>,
|
||||
) -> Result<
|
||||
tonic::Response<tonic::codec::Streaming<super::GetAddressUtxosReply>>,
|
||||
tonic::Status,
|
||||
> {
|
||||
tonic::Response<tonic::codec::Streaming<super::GetAddressUtxosReply>>,
|
||||
tonic::Status,
|
||||
> {
|
||||
self.inner
|
||||
.ready()
|
||||
.await
|
||||
|
@ -754,15 +718,6 @@ pub mod compact_tx_streamer_server {
|
|||
&self,
|
||||
request: tonic::Request<super::BlockRange>,
|
||||
) -> Result<tonic::Response<Self::GetBlockRangeStream>, tonic::Status>;
|
||||
/// Get the historical and current prices
|
||||
async fn get_zec_price(
|
||||
&self,
|
||||
request: tonic::Request<super::PriceRequest>,
|
||||
) -> Result<tonic::Response<super::PriceResponse>, tonic::Status>;
|
||||
async fn get_current_zec_price(
|
||||
&self,
|
||||
request: tonic::Request<super::Empty>,
|
||||
) -> Result<tonic::Response<super::PriceResponse>, tonic::Status>;
|
||||
/// Return the requested full (not compact) transaction (as from zcashd)
|
||||
async fn get_transaction(
|
||||
&self,
|
||||
|
@ -784,17 +739,6 @@ pub mod compact_tx_streamer_server {
|
|||
&self,
|
||||
request: tonic::Request<super::TransparentAddressBlockFilter>,
|
||||
) -> Result<tonic::Response<Self::GetTaddressTxidsStream>, tonic::Status>;
|
||||
///Server streaming response type for the GetAddressTxids method.
|
||||
type GetAddressTxidsStream: futures_core::Stream<
|
||||
Item = Result<super::RawTransaction, tonic::Status>,
|
||||
>
|
||||
+ Send
|
||||
+ 'static;
|
||||
/// Legacy API that is used as a fallback for t-Address support, if the server is running the old version (lwdv2)
|
||||
async fn get_address_txids(
|
||||
&self,
|
||||
request: tonic::Request<super::TransparentAddressBlockFilter>,
|
||||
) -> Result<tonic::Response<Self::GetAddressTxidsStream>, tonic::Status>;
|
||||
async fn get_taddress_balance(
|
||||
&self,
|
||||
request: tonic::Request<super::AddressList>,
|
||||
|
@ -822,6 +766,18 @@ pub mod compact_tx_streamer_server {
|
|||
&self,
|
||||
request: tonic::Request<super::Exclude>,
|
||||
) -> Result<tonic::Response<Self::GetMempoolTxStream>, tonic::Status>;
|
||||
///Server streaming response type for the GetMempoolStream method.
|
||||
type GetMempoolStreamStream: futures_core::Stream<
|
||||
Item = Result<super::RawTransaction, tonic::Status>,
|
||||
>
|
||||
+ Send
|
||||
+ 'static;
|
||||
/// 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.
|
||||
async fn get_mempool_stream(
|
||||
&self,
|
||||
request: tonic::Request<super::Empty>,
|
||||
) -> Result<tonic::Response<Self::GetMempoolStreamStream>, tonic::Status>;
|
||||
/// 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).
|
||||
|
@ -1020,84 +976,6 @@ pub mod compact_tx_streamer_server {
|
|||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
"/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetZECPrice" => {
|
||||
#[allow(non_camel_case_types)]
|
||||
struct GetZECPriceSvc<T: CompactTxStreamer>(pub Arc<T>);
|
||||
impl<
|
||||
T: CompactTxStreamer,
|
||||
> tonic::server::UnaryService<super::PriceRequest>
|
||||
for GetZECPriceSvc<T> {
|
||||
type Response = super::PriceResponse;
|
||||
type Future = BoxFuture<
|
||||
tonic::Response<Self::Response>,
|
||||
tonic::Status,
|
||||
>;
|
||||
fn call(
|
||||
&mut self,
|
||||
request: tonic::Request<super::PriceRequest>,
|
||||
) -> Self::Future {
|
||||
let inner = self.0.clone();
|
||||
let fut = async move {
|
||||
(*inner).get_zec_price(request).await
|
||||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
}
|
||||
let accept_compression_encodings = self.accept_compression_encodings;
|
||||
let send_compression_encodings = self.send_compression_encodings;
|
||||
let inner = self.inner.clone();
|
||||
let fut = async move {
|
||||
let inner = inner.0;
|
||||
let method = GetZECPriceSvc(inner);
|
||||
let codec = tonic::codec::ProstCodec::default();
|
||||
let mut grpc = tonic::server::Grpc::new(codec)
|
||||
.apply_compression_config(
|
||||
accept_compression_encodings,
|
||||
send_compression_encodings,
|
||||
);
|
||||
let res = grpc.unary(method, req).await;
|
||||
Ok(res)
|
||||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
"/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetCurrentZECPrice" => {
|
||||
#[allow(non_camel_case_types)]
|
||||
struct GetCurrentZECPriceSvc<T: CompactTxStreamer>(pub Arc<T>);
|
||||
impl<T: CompactTxStreamer> tonic::server::UnaryService<super::Empty>
|
||||
for GetCurrentZECPriceSvc<T> {
|
||||
type Response = super::PriceResponse;
|
||||
type Future = BoxFuture<
|
||||
tonic::Response<Self::Response>,
|
||||
tonic::Status,
|
||||
>;
|
||||
fn call(
|
||||
&mut self,
|
||||
request: tonic::Request<super::Empty>,
|
||||
) -> Self::Future {
|
||||
let inner = self.0.clone();
|
||||
let fut = async move {
|
||||
(*inner).get_current_zec_price(request).await
|
||||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
}
|
||||
let accept_compression_encodings = self.accept_compression_encodings;
|
||||
let send_compression_encodings = self.send_compression_encodings;
|
||||
let inner = self.inner.clone();
|
||||
let fut = async move {
|
||||
let inner = inner.0;
|
||||
let method = GetCurrentZECPriceSvc(inner);
|
||||
let codec = tonic::codec::ProstCodec::default();
|
||||
let mut grpc = tonic::server::Grpc::new(codec)
|
||||
.apply_compression_config(
|
||||
accept_compression_encodings,
|
||||
send_compression_encodings,
|
||||
);
|
||||
let res = grpc.unary(method, req).await;
|
||||
Ok(res)
|
||||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
"/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTransaction" => {
|
||||
#[allow(non_camel_case_types)]
|
||||
struct GetTransactionSvc<T: CompactTxStreamer>(pub Arc<T>);
|
||||
|
@ -1220,48 +1098,6 @@ pub mod compact_tx_streamer_server {
|
|||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
"/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetAddressTxids" => {
|
||||
#[allow(non_camel_case_types)]
|
||||
struct GetAddressTxidsSvc<T: CompactTxStreamer>(pub Arc<T>);
|
||||
impl<
|
||||
T: CompactTxStreamer,
|
||||
> tonic::server::ServerStreamingService<
|
||||
super::TransparentAddressBlockFilter,
|
||||
> for GetAddressTxidsSvc<T> {
|
||||
type Response = super::RawTransaction;
|
||||
type ResponseStream = T::GetAddressTxidsStream;
|
||||
type Future = BoxFuture<
|
||||
tonic::Response<Self::ResponseStream>,
|
||||
tonic::Status,
|
||||
>;
|
||||
fn call(
|
||||
&mut self,
|
||||
request: tonic::Request<super::TransparentAddressBlockFilter>,
|
||||
) -> Self::Future {
|
||||
let inner = self.0.clone();
|
||||
let fut = async move {
|
||||
(*inner).get_address_txids(request).await
|
||||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
}
|
||||
let accept_compression_encodings = self.accept_compression_encodings;
|
||||
let send_compression_encodings = self.send_compression_encodings;
|
||||
let inner = self.inner.clone();
|
||||
let fut = async move {
|
||||
let inner = inner.0;
|
||||
let method = GetAddressTxidsSvc(inner);
|
||||
let codec = tonic::codec::ProstCodec::default();
|
||||
let mut grpc = tonic::server::Grpc::new(codec)
|
||||
.apply_compression_config(
|
||||
accept_compression_encodings,
|
||||
send_compression_encodings,
|
||||
);
|
||||
let res = grpc.server_streaming(method, req).await;
|
||||
Ok(res)
|
||||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
"/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTaddressBalance" => {
|
||||
#[allow(non_camel_case_types)]
|
||||
struct GetTaddressBalanceSvc<T: CompactTxStreamer>(pub Arc<T>);
|
||||
|
@ -1383,6 +1219,47 @@ pub mod compact_tx_streamer_server {
|
|||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
"/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetMempoolStream" => {
|
||||
#[allow(non_camel_case_types)]
|
||||
struct GetMempoolStreamSvc<T: CompactTxStreamer>(pub Arc<T>);
|
||||
impl<
|
||||
T: CompactTxStreamer,
|
||||
> tonic::server::ServerStreamingService<super::Empty>
|
||||
for GetMempoolStreamSvc<T> {
|
||||
type Response = super::RawTransaction;
|
||||
type ResponseStream = T::GetMempoolStreamStream;
|
||||
type Future = BoxFuture<
|
||||
tonic::Response<Self::ResponseStream>,
|
||||
tonic::Status,
|
||||
>;
|
||||
fn call(
|
||||
&mut self,
|
||||
request: tonic::Request<super::Empty>,
|
||||
) -> Self::Future {
|
||||
let inner = self.0.clone();
|
||||
let fut = async move {
|
||||
(*inner).get_mempool_stream(request).await
|
||||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
}
|
||||
let accept_compression_encodings = self.accept_compression_encodings;
|
||||
let send_compression_encodings = self.send_compression_encodings;
|
||||
let inner = self.inner.clone();
|
||||
let fut = async move {
|
||||
let inner = inner.0;
|
||||
let method = GetMempoolStreamSvc(inner);
|
||||
let codec = tonic::codec::ProstCodec::default();
|
||||
let mut grpc = tonic::server::Grpc::new(codec)
|
||||
.apply_compression_config(
|
||||
accept_compression_encodings,
|
||||
send_compression_encodings,
|
||||
);
|
||||
let res = grpc.server_streaming(method, req).await;
|
||||
Ok(res)
|
||||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
"/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTreeState" => {
|
||||
#[allow(non_camel_case_types)]
|
||||
struct GetTreeStateSvc<T: CompactTxStreamer>(pub Arc<T>);
|
||||
|
|
|
@ -243,7 +243,7 @@ pub fn new_diversified_address() -> Result<String, Error> {
|
|||
Ok(address)
|
||||
}
|
||||
|
||||
#[get("/make_payment_uri", data = "<payment>")]
|
||||
#[post("/make_payment_uri", data = "<payment>")]
|
||||
pub fn make_payment_uri(payment: Json<PaymentURI>) -> Result<String, Error> {
|
||||
let uri = warp_api_ffi::api::payment_uri::make_payment_uri(
|
||||
&payment.address,
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "test-scripts",
|
||||
"version": "1.0.0",
|
||||
"main": "test.js",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"chakram": "^1.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"mocha": "^10.0.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
curl -X POST -H 'Content-Type: application/json' -d '{"coin": 0, "name": "test", "key": "zxviews1qvq5u9dnqqqqpqyc3wd00lql5njzdqx3xk670z5ldjuqkxm3lcphkvcyvpg2kavcze2edwj4f27k0s62q48dqdlnxlnr7jhczv2d8c9y2hw4uxgqrx9sluja52jqjtlqqsl65hd6p9xrdhzh7spgd0s4zud9xtv7sqepahchq06ng6w5vm36l9zjg0n2upkdv4k4yd7mhfsdpu9lqra0mnyq0k8v8f23j8pqq0ekr4f4aa7gf538eudpwck0yw3l74s37z4hf2xkyfq8eswwx"}' http://localhost:8000/new_account
|
||||
curl -X GET http://localhost:8000/accounts
|
||||
curl -X POST 'http://localhost:8000/set_active?coin=0&id_account=1'
|
||||
curl -X GET http://localhost:8000/backup
|
||||
curl -X GET http://localhost:8000/latest_height
|
||||
curl -X GET http://localhost:8000/balance
|
||||
curl -X GET http://localhost:8000/tx_history
|
||||
curl -X GET http://localhost:8000/new_diversified_address
|
||||
curl -X POST 'http://localhost:8000/sync?offset=0'
|
||||
curl -X POST 'http://localhost:8000/rewind?height=1600000'
|
||||
# Sync to latest height - 20 to calculate the witnesses for later
|
||||
curl -X POST 'http://localhost:8000/sync?offset=20'
|
||||
curl -X POST http://localhost:8000/mark_synced
|
||||
curl -X POST -H 'Content-Type: application/json' -d '{"address": "zs1hn7qwpjz6p5n24hjhks73y6vn0tpk3c2cfu8wzgtgl4j9ht8ycjgjr47c94scce3uahaje9jkxn", "amount": 100000, "memo": "Hello"}' http://localhost:8000/make_payment_uri
|
||||
curl -X GET http://localhost:8000/parse_payment_uri?uri=zcash%3Azs1hn7qwpjz6p5n24hjhks73y6vn0tpk3c2cfu8wzgtgl4j9ht8ycjgjr47c94scce3uahaje9jkxn%3Famount%3D0.001%26memo%3DSGVsbG8
|
||||
curl -X POST -H 'Content-Type: application/json' -d '{"recipients": [{"address": "zs1hn7qwpjz6p5n24hjhks73y6vn0tpk3c2cfu8wzgtgl4j9ht8ycjgjr47c94scce3uahaje9jkxn", "amount": 100000, "memo": "Hello", "reply_to": false, "subject": "hello", "max_amount_per_note": 0}], "confirmations": 10}' http://localhost:8000/create_offline_tx
|
||||
|
||||
// offline signing and pay need an account with a secret key
|
|
@ -0,0 +1,122 @@
|
|||
const chakram = require('chakram'), expect = chakram.expect;
|
||||
|
||||
describe('warp', async function () {
|
||||
var id_account;
|
||||
|
||||
it("should allow creating new accounts", async function () {
|
||||
const account = await chakram.post('http://localhost:8000/new_account', {
|
||||
coin: 0,
|
||||
name: 'zecpages',
|
||||
key: 'zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz'
|
||||
})
|
||||
|
||||
expect(account).to.have.status(200)
|
||||
id_account = account.body
|
||||
await chakram.post(`http://localhost:8000/set_active?coin=0&id_account=${id_account}`)
|
||||
})
|
||||
|
||||
it("should give you the backup info", async function () {
|
||||
const backup = await chakram.get('http://localhost:8000/backup')
|
||||
|
||||
expect(backup.body).to.deep.equal({
|
||||
"fvk": "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz",
|
||||
"seed": null,
|
||||
"sk": null
|
||||
})
|
||||
})
|
||||
|
||||
it("should give you the latest block height", async function () {
|
||||
const heights = await chakram.get('http://localhost:8000/latest_height')
|
||||
|
||||
expect(heights.body.latest > 1000000)
|
||||
})
|
||||
|
||||
it("should not have balance because we didn't sync", async function () {
|
||||
const balance = await chakram.get('http://localhost:8000/balance')
|
||||
|
||||
expect(balance.body).to.equals(0)
|
||||
})
|
||||
|
||||
it("should not have a tx history because we didn't sync", async function () {
|
||||
const tx_history = await chakram.get('http://localhost:8000/tx_history')
|
||||
|
||||
expect(tx_history.body.length).to.equals(0)
|
||||
})
|
||||
|
||||
it("should sync", async function () {
|
||||
this.timeout(120000)
|
||||
await chakram.post('http://localhost:8000/sync?offset=0')
|
||||
})
|
||||
|
||||
it("should rewind and resync", async function () {
|
||||
this.timeout(120000)
|
||||
await chakram.post('http://localhost:8000/rewind?height=419200')
|
||||
await chakram.post('http://localhost:8000/sync?offset=0')
|
||||
const balance = await chakram.get('http://localhost:8000/balance')
|
||||
expect(balance.body).to.not.equals(0)
|
||||
})
|
||||
|
||||
it("should rewind to a past block", async function () {
|
||||
this.timeout(120000)
|
||||
await chakram.post('http://localhost:8000/rewind?height=1000000')
|
||||
const balance = await chakram.get('http://localhost:8000/balance')
|
||||
expect(balance.body).to.equals(364779600) // that's the balance at this block
|
||||
})
|
||||
|
||||
it("can skip blocks", async function () {
|
||||
await chakram.post('http://localhost:8000/rewind?height=1000000')
|
||||
await chakram.post('http://localhost:8000/mark_synced')
|
||||
const balance = await chakram.get('http://localhost:8000/balance')
|
||||
expect(balance.body).to.equals(364779600) // that's the balance at this block
|
||||
})
|
||||
|
||||
it("should create and parse payment uri", async function () {
|
||||
const p = {
|
||||
address: "zs1hn7qwpjz6p5n24hjhks73y6vn0tpk3c2cfu8wzgtgl4j9ht8ycjgjr47c94scce3uahaje9jkxn",
|
||||
amount: 100000,
|
||||
memo: "Hello"
|
||||
}
|
||||
const p_uri = await chakram.post('http://localhost:8000/make_payment_uri', p)
|
||||
expect(p_uri.body).to.equals('zcash:zs1hn7qwpjz6p5n24hjhks73y6vn0tpk3c2cfu8wzgtgl4j9ht8ycjgjr47c94scce3uahaje9jkxn?amount=0.001&memo=SGVsbG8')
|
||||
|
||||
const payment = await chakram.get('http://localhost:8000/parse_payment_uri?uri=zcash%3Azs1hn7qwpjz6p5n24hjhks73y6vn0tpk3c2cfu8wzgtgl4j9ht8ycjgjr47c94scce3uahaje9jkxn%3Famount%3D0.001%26memo%3DSGVsbG8')
|
||||
expect(payment.body).to.deep.equal(p)
|
||||
})
|
||||
|
||||
it("should create offline payment requests", async function () {
|
||||
this.timeout(120000)
|
||||
await chakram.post('http://localhost:8000/rewind?height=1600000')
|
||||
await chakram.post('http://localhost:8000/sync?offset=10') // sync to compute note witnesses
|
||||
const payment_request = {
|
||||
recipients: [{
|
||||
address: "zs1hn7qwpjz6p5n24hjhks73y6vn0tpk3c2cfu8wzgtgl4j9ht8ycjgjr47c94scce3uahaje9jkxn",
|
||||
amount: 100000,
|
||||
memo: "Hello",
|
||||
reply_to: false,
|
||||
subject: "hello",
|
||||
max_amount_per_note: 0
|
||||
}],
|
||||
confirmations: 10
|
||||
}
|
||||
|
||||
const unsigned_tx = await chakram.post('http://localhost:8000/create_offline_tx', payment_request)
|
||||
expect(unsigned_tx.body.outputs).to.deep.equal( // we cannot check the other fields because they change from run to run
|
||||
[
|
||||
{
|
||||
"addr": "zs1hn7qwpjz6p5n24hjhks73y6vn0tpk3c2cfu8wzgtgl4j9ht8ycjgjr47c94scce3uahaje9jkxn",
|
||||
"amount": 100000,
|
||||
"memo": "f09f9ba14d53470a0a68656c6c6f0a48656c6c6f",
|
||||
"ovk": "459121112ebe923d49af689b5aa2f67cccd62af3656549992e62aa373768ffef"
|
||||
}
|
||||
]
|
||||
)
|
||||
})
|
||||
|
||||
it("should give you the tx_history", async function () {
|
||||
const txs = await chakram.get('http://localhost:8000/tx_history')
|
||||
expect(txs.body.length).to.not.equals(0)
|
||||
})
|
||||
|
||||
// cannot test signing without a secret key
|
||||
// need to setup a dummy account
|
||||
})
|
Loading…
Reference in New Issue