penumbra_sdk_proto/gen/
penumbra.core.component.dex.v1.rs

1// This file is @generated by prost-build.
2/// A Penumbra ZK swap proof.
3#[derive(Clone, PartialEq, ::prost::Message)]
4pub struct ZkSwapProof {
5    #[prost(bytes = "vec", tag = "1")]
6    pub inner: ::prost::alloc::vec::Vec<u8>,
7}
8impl ::prost::Name for ZkSwapProof {
9    const NAME: &'static str = "ZKSwapProof";
10    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
11    fn full_name() -> ::prost::alloc::string::String {
12        "penumbra.core.component.dex.v1.ZKSwapProof".into()
13    }
14    fn type_url() -> ::prost::alloc::string::String {
15        "/penumbra.core.component.dex.v1.ZKSwapProof".into()
16    }
17}
18/// A Penumbra ZK swap claim proof.
19#[derive(Clone, PartialEq, ::prost::Message)]
20pub struct ZkSwapClaimProof {
21    #[prost(bytes = "vec", tag = "1")]
22    pub inner: ::prost::alloc::vec::Vec<u8>,
23}
24impl ::prost::Name for ZkSwapClaimProof {
25    const NAME: &'static str = "ZKSwapClaimProof";
26    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
27    fn full_name() -> ::prost::alloc::string::String {
28        "penumbra.core.component.dex.v1.ZKSwapClaimProof".into()
29    }
30    fn type_url() -> ::prost::alloc::string::String {
31        "/penumbra.core.component.dex.v1.ZKSwapClaimProof".into()
32    }
33}
34/// A transaction action that submits a swap to the dex.
35#[derive(Clone, PartialEq, ::prost::Message)]
36pub struct Swap {
37    /// Contains the Swap proof.
38    #[prost(message, optional, tag = "1")]
39    pub proof: ::core::option::Option<ZkSwapProof>,
40    /// Encapsulates the authorized fields of the Swap action, used in signing.
41    #[prost(message, optional, tag = "4")]
42    pub body: ::core::option::Option<SwapBody>,
43}
44impl ::prost::Name for Swap {
45    const NAME: &'static str = "Swap";
46    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
47    fn full_name() -> ::prost::alloc::string::String {
48        "penumbra.core.component.dex.v1.Swap".into()
49    }
50    fn type_url() -> ::prost::alloc::string::String {
51        "/penumbra.core.component.dex.v1.Swap".into()
52    }
53}
54/// A transaction action that obtains assets previously confirmed
55/// via a Swap transaction. Does not include a spend authorization
56/// signature, as it is only capable of consuming the NFT from a
57/// Swap transaction.
58#[derive(Clone, PartialEq, ::prost::Message)]
59pub struct SwapClaim {
60    /// Contains the SwapClaim proof.
61    #[prost(message, optional, tag = "1")]
62    pub proof: ::core::option::Option<ZkSwapClaimProof>,
63    /// Encapsulates the authorized fields of the SwapClaim action, used in signing.
64    #[prost(message, optional, tag = "2")]
65    pub body: ::core::option::Option<SwapClaimBody>,
66    /// The epoch duration of the chain when the swap claim took place.
67    #[prost(uint64, tag = "7")]
68    pub epoch_duration: u64,
69}
70impl ::prost::Name for SwapClaim {
71    const NAME: &'static str = "SwapClaim";
72    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
73    fn full_name() -> ::prost::alloc::string::String {
74        "penumbra.core.component.dex.v1.SwapClaim".into()
75    }
76    fn type_url() -> ::prost::alloc::string::String {
77        "/penumbra.core.component.dex.v1.SwapClaim".into()
78    }
79}
80/// Encapsulates the authorized fields of the SwapClaim action, used in signing.
81#[derive(Clone, PartialEq, ::prost::Message)]
82pub struct SwapClaimBody {
83    /// The nullifier for the Swap commitment to be consumed.
84    #[prost(message, optional, tag = "1")]
85    pub nullifier: ::core::option::Option<super::super::sct::v1::Nullifier>,
86    /// The fee allows `SwapClaim` without an additional `Spend`.
87    #[prost(message, optional, tag = "2")]
88    pub fee: ::core::option::Option<super::super::fee::v1::Fee>,
89    /// Note output for asset 1.
90    #[prost(message, optional, tag = "3")]
91    pub output_1_commitment: ::core::option::Option<
92        super::super::super::super::crypto::tct::v1::StateCommitment,
93    >,
94    /// Note output for asset 2.
95    #[prost(message, optional, tag = "4")]
96    pub output_2_commitment: ::core::option::Option<
97        super::super::super::super::crypto::tct::v1::StateCommitment,
98    >,
99    /// Input and output amounts, and asset IDs for the assets in the swap.
100    #[prost(message, optional, tag = "6")]
101    pub output_data: ::core::option::Option<BatchSwapOutputData>,
102}
103impl ::prost::Name for SwapClaimBody {
104    const NAME: &'static str = "SwapClaimBody";
105    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
106    fn full_name() -> ::prost::alloc::string::String {
107        "penumbra.core.component.dex.v1.SwapClaimBody".into()
108    }
109    fn type_url() -> ::prost::alloc::string::String {
110        "/penumbra.core.component.dex.v1.SwapClaimBody".into()
111    }
112}
113/// The authorized data of a Swap transaction.
114#[derive(Clone, PartialEq, ::prost::Message)]
115pub struct SwapBody {
116    /// The trading pair to swap.
117    #[prost(message, optional, tag = "1")]
118    pub trading_pair: ::core::option::Option<TradingPair>,
119    /// The amount for asset 1.
120    #[prost(message, optional, tag = "2")]
121    pub delta_1_i: ::core::option::Option<super::super::super::num::v1::Amount>,
122    /// The amount for asset 2.
123    #[prost(message, optional, tag = "3")]
124    pub delta_2_i: ::core::option::Option<super::super::super::num::v1::Amount>,
125    /// A commitment to a prepaid fee for the future SwapClaim.
126    /// This is recorded separately from delta_j_i because it's shielded;
127    /// in the future we'll want separate commitments to each delta_j_i
128    /// anyways in order to prove consistency with flow encryption.
129    #[prost(message, optional, tag = "4")]
130    pub fee_commitment: ::core::option::Option<
131        super::super::super::asset::v1::BalanceCommitment,
132    >,
133    /// The swap commitment and encryption of the swap data.
134    #[prost(message, optional, tag = "5")]
135    pub payload: ::core::option::Option<SwapPayload>,
136}
137impl ::prost::Name for SwapBody {
138    const NAME: &'static str = "SwapBody";
139    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
140    fn full_name() -> ::prost::alloc::string::String {
141        "penumbra.core.component.dex.v1.SwapBody".into()
142    }
143    fn type_url() -> ::prost::alloc::string::String {
144        "/penumbra.core.component.dex.v1.SwapBody".into()
145    }
146}
147#[derive(Clone, PartialEq, ::prost::Message)]
148pub struct SwapPayload {
149    #[prost(message, optional, tag = "1")]
150    pub commitment: ::core::option::Option<
151        super::super::super::super::crypto::tct::v1::StateCommitment,
152    >,
153    #[prost(bytes = "vec", tag = "2")]
154    pub encrypted_swap: ::prost::alloc::vec::Vec<u8>,
155}
156impl ::prost::Name for SwapPayload {
157    const NAME: &'static str = "SwapPayload";
158    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
159    fn full_name() -> ::prost::alloc::string::String {
160        "penumbra.core.component.dex.v1.SwapPayload".into()
161    }
162    fn type_url() -> ::prost::alloc::string::String {
163        "/penumbra.core.component.dex.v1.SwapPayload".into()
164    }
165}
166#[derive(Clone, PartialEq, ::prost::Message)]
167pub struct SwapPlaintext {
168    /// The trading pair to swap.
169    #[prost(message, optional, tag = "1")]
170    pub trading_pair: ::core::option::Option<TradingPair>,
171    /// Input amount of asset 1
172    #[prost(message, optional, tag = "2")]
173    pub delta_1_i: ::core::option::Option<super::super::super::num::v1::Amount>,
174    /// Input amount of asset 2
175    #[prost(message, optional, tag = "3")]
176    pub delta_2_i: ::core::option::Option<super::super::super::num::v1::Amount>,
177    /// Pre-paid fee to claim the swap
178    #[prost(message, optional, tag = "4")]
179    pub claim_fee: ::core::option::Option<super::super::fee::v1::Fee>,
180    /// Address that will claim the swap outputs via SwapClaim.
181    #[prost(message, optional, tag = "5")]
182    pub claim_address: ::core::option::Option<super::super::super::keys::v1::Address>,
183    /// Swap rseed (blinding factors are derived from this)
184    #[prost(bytes = "vec", tag = "6")]
185    pub rseed: ::prost::alloc::vec::Vec<u8>,
186}
187impl ::prost::Name for SwapPlaintext {
188    const NAME: &'static str = "SwapPlaintext";
189    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
190    fn full_name() -> ::prost::alloc::string::String {
191        "penumbra.core.component.dex.v1.SwapPlaintext".into()
192    }
193    fn type_url() -> ::prost::alloc::string::String {
194        "/penumbra.core.component.dex.v1.SwapPlaintext".into()
195    }
196}
197#[derive(Clone, PartialEq, ::prost::Message)]
198pub struct SwapPlan {
199    /// The plaintext version of the swap to be performed.
200    #[prost(message, optional, tag = "1")]
201    pub swap_plaintext: ::core::option::Option<SwapPlaintext>,
202    /// The blinding factor for the fee commitment. The fee in the SwapPlan is private to prevent linkability with the SwapClaim.
203    #[prost(bytes = "vec", tag = "2")]
204    pub fee_blinding: ::prost::alloc::vec::Vec<u8>,
205    /// The first blinding factor to use for the ZK swap proof.
206    #[prost(bytes = "vec", tag = "3")]
207    pub proof_blinding_r: ::prost::alloc::vec::Vec<u8>,
208    /// The second blinding factor to use for the ZK swap proof.
209    #[prost(bytes = "vec", tag = "4")]
210    pub proof_blinding_s: ::prost::alloc::vec::Vec<u8>,
211}
212impl ::prost::Name for SwapPlan {
213    const NAME: &'static str = "SwapPlan";
214    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
215    fn full_name() -> ::prost::alloc::string::String {
216        "penumbra.core.component.dex.v1.SwapPlan".into()
217    }
218    fn type_url() -> ::prost::alloc::string::String {
219        "/penumbra.core.component.dex.v1.SwapPlan".into()
220    }
221}
222#[derive(Clone, PartialEq, ::prost::Message)]
223pub struct SwapClaimPlan {
224    /// The plaintext version of the swap to be performed.
225    #[prost(message, optional, tag = "1")]
226    pub swap_plaintext: ::core::option::Option<SwapPlaintext>,
227    /// The position of the swap commitment.
228    #[prost(uint64, tag = "2")]
229    pub position: u64,
230    /// Input and output amounts for the Swap.
231    #[prost(message, optional, tag = "3")]
232    pub output_data: ::core::option::Option<BatchSwapOutputData>,
233    /// The epoch duration, used in proving.
234    #[prost(uint64, tag = "4")]
235    pub epoch_duration: u64,
236    /// The first blinding factor to use for the ZK swap claim proof.
237    #[prost(bytes = "vec", tag = "5")]
238    pub proof_blinding_r: ::prost::alloc::vec::Vec<u8>,
239    /// The second blinding factor to use for the ZK swap claim proof.
240    #[prost(bytes = "vec", tag = "6")]
241    pub proof_blinding_s: ::prost::alloc::vec::Vec<u8>,
242}
243impl ::prost::Name for SwapClaimPlan {
244    const NAME: &'static str = "SwapClaimPlan";
245    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
246    fn full_name() -> ::prost::alloc::string::String {
247        "penumbra.core.component.dex.v1.SwapClaimPlan".into()
248    }
249    fn type_url() -> ::prost::alloc::string::String {
250        "/penumbra.core.component.dex.v1.SwapClaimPlan".into()
251    }
252}
253#[derive(Clone, PartialEq, ::prost::Message)]
254pub struct SwapView {
255    #[prost(oneof = "swap_view::SwapView", tags = "1, 2")]
256    pub swap_view: ::core::option::Option<swap_view::SwapView>,
257}
258/// Nested message and enum types in `SwapView`.
259pub mod swap_view {
260    #[derive(Clone, PartialEq, ::prost::Message)]
261    pub struct Visible {
262        /// The underlying Swap action being viewed.
263        #[prost(message, optional, tag = "1")]
264        pub swap: ::core::option::Option<super::Swap>,
265        /// The plaintext of the encrypted swap.
266        #[prost(message, optional, tag = "3")]
267        pub swap_plaintext: ::core::option::Option<super::SwapPlaintext>,
268        /// Optionally, a transaction hash for the transaction that claimed this
269        /// swap.
270        ///
271        /// Presence of this field signals that the swap outputs have been claimed
272        /// and that the claim transaction is known to the view server.  Absence of
273        /// this field does not indicate anything about the state of the swap.
274        ///
275        /// This field allows frontends to more easily crossreference the sequence of
276        /// Swap/SwapClaim actions.
277        #[prost(message, optional, tag = "4")]
278        pub claim_tx: ::core::option::Option<
279            super::super::super::super::txhash::v1::TransactionId,
280        >,
281        /// Optionally, if the swap has been confirmed, the batch price it received.
282        ///
283        /// As soon as the swap is detected, the view server can in principle record
284        /// the relevant BSOD and provide it as part of the view.  This allows providing
285        /// info about the execution of the swap.
286        #[prost(message, optional, tag = "20")]
287        pub batch_swap_output_data: ::core::option::Option<super::BatchSwapOutputData>,
288        /// Optionally, if the swap has been confirmed, the output note of asset 1.
289        ///
290        /// This is the note that will be minted by the SwapClaim action.
291        #[prost(message, optional, tag = "30")]
292        pub output_1: ::core::option::Option<
293            super::super::super::shielded_pool::v1::NoteView,
294        >,
295        /// Optionally, if the swap has been confirmed, the output note of asset 2.
296        ///
297        /// This is the note that will be minted by the SwapClaim action.
298        #[prost(message, optional, tag = "31")]
299        pub output_2: ::core::option::Option<
300            super::super::super::shielded_pool::v1::NoteView,
301        >,
302        /// Optionally, metadata about asset 1 in the `swap`'s trading pair.
303        #[prost(message, optional, tag = "40")]
304        pub asset_1_metadata: ::core::option::Option<
305            super::super::super::super::asset::v1::Metadata,
306        >,
307        /// Optionally, metadata about asset 2 in the `swap`'s trading pair.
308        #[prost(message, optional, tag = "41")]
309        pub asset_2_metadata: ::core::option::Option<
310            super::super::super::super::asset::v1::Metadata,
311        >,
312    }
313    impl ::prost::Name for Visible {
314        const NAME: &'static str = "Visible";
315        const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
316        fn full_name() -> ::prost::alloc::string::String {
317            "penumbra.core.component.dex.v1.SwapView.Visible".into()
318        }
319        fn type_url() -> ::prost::alloc::string::String {
320            "/penumbra.core.component.dex.v1.SwapView.Visible".into()
321        }
322    }
323    #[derive(Clone, PartialEq, ::prost::Message)]
324    pub struct Opaque {
325        #[prost(message, optional, tag = "1")]
326        pub swap: ::core::option::Option<super::Swap>,
327        /// Optionally, if the swap has been confirmed, the batch price it received.
328        ///
329        /// As soon as the swap is detected, the view server can in principle record
330        /// the relevant BSOD and provide it as part of the view.  This allows providing
331        /// info about the execution of the swap.
332        #[prost(message, optional, tag = "20")]
333        pub batch_swap_output_data: ::core::option::Option<super::BatchSwapOutputData>,
334        /// Optionally, if the swap has been confirmed, the output value of asset 1.
335        ///
336        /// This is the value of the note that will be minted by the SwapClaim action.
337        /// Note that unlike the `Visible` variant, this is only a `ValueView` since
338        /// the details of the note (in particular the claim address) are not publicly known.
339        #[prost(message, optional, tag = "30")]
340        pub output_1_value: ::core::option::Option<
341            super::super::super::super::asset::v1::ValueView,
342        >,
343        /// Optionally, if the swap has been confirmed, the output value of asset 2.
344        ///
345        /// This is the note that will be minted by the SwapClaim action.
346        /// Note that unlike the `Visible` variant, this is only a `ValueView` since
347        /// the details of the note (in particular the claim address) are not publicly known.
348        #[prost(message, optional, tag = "31")]
349        pub output_2_value: ::core::option::Option<
350            super::super::super::super::asset::v1::ValueView,
351        >,
352        /// Optionally, metadata about asset 1 in the `swap`'s trading pair.
353        #[prost(message, optional, tag = "40")]
354        pub asset_1_metadata: ::core::option::Option<
355            super::super::super::super::asset::v1::Metadata,
356        >,
357        /// Optionally, metadata about asset 2 in the `swap`'s trading pair.
358        #[prost(message, optional, tag = "41")]
359        pub asset_2_metadata: ::core::option::Option<
360            super::super::super::super::asset::v1::Metadata,
361        >,
362    }
363    impl ::prost::Name for Opaque {
364        const NAME: &'static str = "Opaque";
365        const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
366        fn full_name() -> ::prost::alloc::string::String {
367            "penumbra.core.component.dex.v1.SwapView.Opaque".into()
368        }
369        fn type_url() -> ::prost::alloc::string::String {
370            "/penumbra.core.component.dex.v1.SwapView.Opaque".into()
371        }
372    }
373    #[derive(Clone, PartialEq, ::prost::Oneof)]
374    pub enum SwapView {
375        #[prost(message, tag = "1")]
376        Visible(Visible),
377        #[prost(message, tag = "2")]
378        Opaque(Opaque),
379    }
380}
381impl ::prost::Name for SwapView {
382    const NAME: &'static str = "SwapView";
383    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
384    fn full_name() -> ::prost::alloc::string::String {
385        "penumbra.core.component.dex.v1.SwapView".into()
386    }
387    fn type_url() -> ::prost::alloc::string::String {
388        "/penumbra.core.component.dex.v1.SwapView".into()
389    }
390}
391#[derive(Clone, PartialEq, ::prost::Message)]
392pub struct SwapClaimView {
393    #[prost(oneof = "swap_claim_view::SwapClaimView", tags = "1, 2")]
394    pub swap_claim_view: ::core::option::Option<swap_claim_view::SwapClaimView>,
395}
396/// Nested message and enum types in `SwapClaimView`.
397pub mod swap_claim_view {
398    #[derive(Clone, PartialEq, ::prost::Message)]
399    pub struct Visible {
400        #[prost(message, optional, tag = "1")]
401        pub swap_claim: ::core::option::Option<super::SwapClaim>,
402        #[prost(message, optional, tag = "2")]
403        pub output_1: ::core::option::Option<
404            super::super::super::shielded_pool::v1::NoteView,
405        >,
406        #[prost(message, optional, tag = "3")]
407        pub output_2: ::core::option::Option<
408            super::super::super::shielded_pool::v1::NoteView,
409        >,
410        /// Optionally, a transaction hash for the transaction that created the swap
411        /// this action claims.
412        ///
413        /// This field allows frontends to more easily crossreference the sequence of
414        /// Swap/SwapClaim actions.
415        #[prost(message, optional, tag = "4")]
416        pub swap_tx: ::core::option::Option<
417            super::super::super::super::txhash::v1::TransactionId,
418        >,
419    }
420    impl ::prost::Name for Visible {
421        const NAME: &'static str = "Visible";
422        const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
423        fn full_name() -> ::prost::alloc::string::String {
424            "penumbra.core.component.dex.v1.SwapClaimView.Visible".into()
425        }
426        fn type_url() -> ::prost::alloc::string::String {
427            "/penumbra.core.component.dex.v1.SwapClaimView.Visible".into()
428        }
429    }
430    #[derive(Clone, PartialEq, ::prost::Message)]
431    pub struct Opaque {
432        #[prost(message, optional, tag = "1")]
433        pub swap_claim: ::core::option::Option<super::SwapClaim>,
434    }
435    impl ::prost::Name for Opaque {
436        const NAME: &'static str = "Opaque";
437        const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
438        fn full_name() -> ::prost::alloc::string::String {
439            "penumbra.core.component.dex.v1.SwapClaimView.Opaque".into()
440        }
441        fn type_url() -> ::prost::alloc::string::String {
442            "/penumbra.core.component.dex.v1.SwapClaimView.Opaque".into()
443        }
444    }
445    #[derive(Clone, PartialEq, ::prost::Oneof)]
446    pub enum SwapClaimView {
447        #[prost(message, tag = "1")]
448        Visible(Visible),
449        #[prost(message, tag = "2")]
450        Opaque(Opaque),
451    }
452}
453impl ::prost::Name for SwapClaimView {
454    const NAME: &'static str = "SwapClaimView";
455    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
456    fn full_name() -> ::prost::alloc::string::String {
457        "penumbra.core.component.dex.v1.SwapClaimView".into()
458    }
459    fn type_url() -> ::prost::alloc::string::String {
460        "/penumbra.core.component.dex.v1.SwapClaimView".into()
461    }
462}
463/// Holds two asset IDs. Ordering doesn't reflect trading direction. Instead, we
464/// require `asset_1 < asset_2` as field elements, to ensure a canonical
465/// representation of an unordered pair.
466#[derive(Clone, PartialEq, ::prost::Message)]
467pub struct TradingPair {
468    /// The first asset of the pair.
469    #[prost(message, optional, tag = "1")]
470    pub asset_1: ::core::option::Option<super::super::super::asset::v1::AssetId>,
471    /// The second asset of the pair.
472    #[prost(message, optional, tag = "2")]
473    pub asset_2: ::core::option::Option<super::super::super::asset::v1::AssetId>,
474}
475impl ::prost::Name for TradingPair {
476    const NAME: &'static str = "TradingPair";
477    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
478    fn full_name() -> ::prost::alloc::string::String {
479        "penumbra.core.component.dex.v1.TradingPair".into()
480    }
481    fn type_url() -> ::prost::alloc::string::String {
482        "/penumbra.core.component.dex.v1.TradingPair".into()
483    }
484}
485/// Encodes a trading pair starting from asset `start`
486/// and ending on asset `end`.
487#[derive(Clone, PartialEq, ::prost::Message)]
488pub struct DirectedTradingPair {
489    /// The start asset of the pair.
490    #[prost(message, optional, tag = "1")]
491    pub start: ::core::option::Option<super::super::super::asset::v1::AssetId>,
492    /// The end asset of the pair.
493    #[prost(message, optional, tag = "2")]
494    pub end: ::core::option::Option<super::super::super::asset::v1::AssetId>,
495}
496impl ::prost::Name for DirectedTradingPair {
497    const NAME: &'static str = "DirectedTradingPair";
498    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
499    fn full_name() -> ::prost::alloc::string::String {
500        "penumbra.core.component.dex.v1.DirectedTradingPair".into()
501    }
502    fn type_url() -> ::prost::alloc::string::String {
503        "/penumbra.core.component.dex.v1.DirectedTradingPair".into()
504    }
505}
506/// Records the result of a batch swap on-chain.
507///
508/// Used as a public input to a swap claim proof, as it implies the effective
509/// clearing price for the batch.
510#[derive(Clone, PartialEq, ::prost::Message)]
511pub struct BatchSwapOutputData {
512    /// The total amount of asset 1 that was input to the batch swap.
513    #[prost(message, optional, tag = "1")]
514    pub delta_1: ::core::option::Option<super::super::super::num::v1::Amount>,
515    /// The total amount of asset 2 that was input to the batch swap.
516    #[prost(message, optional, tag = "2")]
517    pub delta_2: ::core::option::Option<super::super::super::num::v1::Amount>,
518    /// The total amount of asset 1 that was output from the batch swap for 2=>1 trades.
519    #[prost(message, optional, tag = "3")]
520    pub lambda_1: ::core::option::Option<super::super::super::num::v1::Amount>,
521    /// The total amount of asset 2 that was output from the batch swap for 1=>2 trades.
522    #[prost(message, optional, tag = "4")]
523    pub lambda_2: ::core::option::Option<super::super::super::num::v1::Amount>,
524    /// The total amount of asset 1 that was returned unfilled from the batch swap for 1=>2 trades.
525    #[prost(message, optional, tag = "5")]
526    pub unfilled_1: ::core::option::Option<super::super::super::num::v1::Amount>,
527    /// The total amount of asset 2 that was returned unfilled from the batch swap for 2=>1 trades.
528    #[prost(message, optional, tag = "6")]
529    pub unfilled_2: ::core::option::Option<super::super::super::num::v1::Amount>,
530    /// The height for which the batch swap data is valid.
531    #[prost(uint64, tag = "7")]
532    pub height: u64,
533    /// The trading pair associated with the batch swap.
534    #[prost(message, optional, tag = "8")]
535    pub trading_pair: ::core::option::Option<TradingPair>,
536    /// The starting block height of the epoch for which the batch swap data is valid.
537    #[deprecated]
538    #[prost(uint64, tag = "9")]
539    pub epoch_starting_height: u64,
540    /// The prefix (epoch, block) of the position where this batch swap occurred.
541    #[prost(uint64, tag = "10")]
542    pub sct_position_prefix: u64,
543}
544impl ::prost::Name for BatchSwapOutputData {
545    const NAME: &'static str = "BatchSwapOutputData";
546    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
547    fn full_name() -> ::prost::alloc::string::String {
548        "penumbra.core.component.dex.v1.BatchSwapOutputData".into()
549    }
550    fn type_url() -> ::prost::alloc::string::String {
551        "/penumbra.core.component.dex.v1.BatchSwapOutputData".into()
552    }
553}
554/// The trading function for a specific pair.
555/// For a pair (asset_1, asset_2), a trading function is defined by:
556/// `phi(R) = p*R_1 + q*R_2` and `gamma = 1 - fee`.
557/// The trading function is frequently referred to as "phi".
558#[derive(Clone, PartialEq, ::prost::Message)]
559pub struct TradingFunction {
560    #[prost(message, optional, tag = "1")]
561    pub component: ::core::option::Option<BareTradingFunction>,
562    #[prost(message, optional, tag = "2")]
563    pub pair: ::core::option::Option<TradingPair>,
564}
565impl ::prost::Name for TradingFunction {
566    const NAME: &'static str = "TradingFunction";
567    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
568    fn full_name() -> ::prost::alloc::string::String {
569        "penumbra.core.component.dex.v1.TradingFunction".into()
570    }
571    fn type_url() -> ::prost::alloc::string::String {
572        "/penumbra.core.component.dex.v1.TradingFunction".into()
573    }
574}
575/// The minimum amount of data describing a trading function.
576///
577/// This implicitly treats the trading function as being between assets 1 and 2,
578/// without specifying what those assets are, to avoid duplicating data (each
579/// asset ID alone is twice the size of the trading function).
580#[derive(Clone, Copy, PartialEq, ::prost::Message)]
581pub struct BareTradingFunction {
582    #[prost(uint32, tag = "1")]
583    pub fee: u32,
584    /// This is not actually an amount, it's an integer the same width as an amount
585    #[prost(message, optional, tag = "2")]
586    pub p: ::core::option::Option<super::super::super::num::v1::Amount>,
587    /// This is not actually an amount, it's an integer the same width as an amount
588    #[prost(message, optional, tag = "3")]
589    pub q: ::core::option::Option<super::super::super::num::v1::Amount>,
590}
591impl ::prost::Name for BareTradingFunction {
592    const NAME: &'static str = "BareTradingFunction";
593    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
594    fn full_name() -> ::prost::alloc::string::String {
595        "penumbra.core.component.dex.v1.BareTradingFunction".into()
596    }
597    fn type_url() -> ::prost::alloc::string::String {
598        "/penumbra.core.component.dex.v1.BareTradingFunction".into()
599    }
600}
601/// The reserves of a position.
602///
603/// Like a position, this implicitly treats the trading function as being
604/// between assets 1 and 2, without specifying what those assets are, to avoid
605/// duplicating data (each asset ID alone is four times the size of the
606/// reserves).
607#[derive(Clone, Copy, PartialEq, ::prost::Message)]
608pub struct Reserves {
609    #[prost(message, optional, tag = "1")]
610    pub r1: ::core::option::Option<super::super::super::num::v1::Amount>,
611    #[prost(message, optional, tag = "2")]
612    pub r2: ::core::option::Option<super::super::super::num::v1::Amount>,
613}
614impl ::prost::Name for Reserves {
615    const NAME: &'static str = "Reserves";
616    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
617    fn full_name() -> ::prost::alloc::string::String {
618        "penumbra.core.component.dex.v1.Reserves".into()
619    }
620    fn type_url() -> ::prost::alloc::string::String {
621        "/penumbra.core.component.dex.v1.Reserves".into()
622    }
623}
624/// Data identifying a position.
625#[derive(Clone, PartialEq, ::prost::Message)]
626pub struct Position {
627    #[prost(message, optional, tag = "1")]
628    pub phi: ::core::option::Option<TradingFunction>,
629    /// A random value used to disambiguate different positions with the exact same
630    /// trading function.  The chain should reject newly created positions with the
631    /// same nonce as an existing position.  This ensures that `PositionId`s will
632    /// be unique, and allows us to track position ownership with a
633    /// sequence of stateful NFTs based on the `PositionId`.
634    #[prost(bytes = "vec", tag = "2")]
635    pub nonce: ::prost::alloc::vec::Vec<u8>,
636    #[prost(message, optional, tag = "3")]
637    pub state: ::core::option::Option<PositionState>,
638    #[prost(message, optional, tag = "4")]
639    pub reserves: ::core::option::Option<Reserves>,
640    /// / If set to true, the position is a limit-order and will be closed
641    /// / immediately after being filled.
642    #[prost(bool, tag = "5")]
643    pub close_on_fill: bool,
644}
645impl ::prost::Name for Position {
646    const NAME: &'static str = "Position";
647    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
648    fn full_name() -> ::prost::alloc::string::String {
649        "penumbra.core.component.dex.v1.Position".into()
650    }
651    fn type_url() -> ::prost::alloc::string::String {
652        "/penumbra.core.component.dex.v1.Position".into()
653    }
654}
655/// A hash of a `Position`.
656#[derive(Clone, PartialEq, ::prost::Message)]
657pub struct PositionId {
658    /// The bytes of the position ID.
659    #[prost(bytes = "vec", tag = "1")]
660    pub inner: ::prost::alloc::vec::Vec<u8>,
661    /// Alternatively, a Bech32m-encoded string representation of the `inner`
662    /// bytes.
663    ///
664    /// NOTE: implementations are not required to support parsing this field.
665    /// Implementations should prefer to encode the bytes in all messages they
666    /// produce. Implementations must not accept messages with both `inner` and
667    /// `alt_bech32m` set.
668    #[prost(string, tag = "2")]
669    pub alt_bech32m: ::prost::alloc::string::String,
670}
671impl ::prost::Name for PositionId {
672    const NAME: &'static str = "PositionId";
673    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
674    fn full_name() -> ::prost::alloc::string::String {
675        "penumbra.core.component.dex.v1.PositionId".into()
676    }
677    fn type_url() -> ::prost::alloc::string::String {
678        "/penumbra.core.component.dex.v1.PositionId".into()
679    }
680}
681/// The state of a position.
682#[derive(Clone, Copy, PartialEq, ::prost::Message)]
683pub struct PositionState {
684    #[prost(enumeration = "position_state::PositionStateEnum", tag = "1")]
685    pub state: i32,
686    /// Only meaningful if `state` is `POSITION_STATE_ENUM_WITHDRAWN`.
687    ///
688    /// The sequence number allows multiple withdrawals from the same position.
689    #[prost(uint64, tag = "2")]
690    pub sequence: u64,
691}
692/// Nested message and enum types in `PositionState`.
693pub mod position_state {
694    #[derive(
695        Clone,
696        Copy,
697        Debug,
698        PartialEq,
699        Eq,
700        Hash,
701        PartialOrd,
702        Ord,
703        ::prost::Enumeration
704    )]
705    #[repr(i32)]
706    pub enum PositionStateEnum {
707        Unspecified = 0,
708        /// The position has been opened, is active, has reserves and accumulated
709        /// fees, and can be traded against.
710        Opened = 1,
711        /// The position has been closed, is inactive and can no longer be traded
712        /// against, but still has reserves and accumulated fees.
713        Closed = 2,
714        /// The final reserves and accumulated fees have been withdrawn, leaving an
715        /// empty, inactive position awaiting (possible) retroactive rewards.
716        ///
717        /// Positions can be withdrawn from multiple times, incrementing a sequence
718        /// number each time.
719        Withdrawn = 3,
720        /// Deprecated.
721        Claimed = 4,
722    }
723    impl PositionStateEnum {
724        /// String value of the enum field names used in the ProtoBuf definition.
725        ///
726        /// The values are not transformed in any way and thus are considered stable
727        /// (if the ProtoBuf definition does not change) and safe for programmatic use.
728        pub fn as_str_name(&self) -> &'static str {
729            match self {
730                Self::Unspecified => "POSITION_STATE_ENUM_UNSPECIFIED",
731                Self::Opened => "POSITION_STATE_ENUM_OPENED",
732                Self::Closed => "POSITION_STATE_ENUM_CLOSED",
733                Self::Withdrawn => "POSITION_STATE_ENUM_WITHDRAWN",
734                Self::Claimed => "POSITION_STATE_ENUM_CLAIMED",
735            }
736        }
737        /// Creates an enum from field names used in the ProtoBuf definition.
738        pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
739            match value {
740                "POSITION_STATE_ENUM_UNSPECIFIED" => Some(Self::Unspecified),
741                "POSITION_STATE_ENUM_OPENED" => Some(Self::Opened),
742                "POSITION_STATE_ENUM_CLOSED" => Some(Self::Closed),
743                "POSITION_STATE_ENUM_WITHDRAWN" => Some(Self::Withdrawn),
744                "POSITION_STATE_ENUM_CLAIMED" => Some(Self::Claimed),
745                _ => None,
746            }
747        }
748    }
749}
750impl ::prost::Name for PositionState {
751    const NAME: &'static str = "PositionState";
752    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
753    fn full_name() -> ::prost::alloc::string::String {
754        "penumbra.core.component.dex.v1.PositionState".into()
755    }
756    fn type_url() -> ::prost::alloc::string::String {
757        "/penumbra.core.component.dex.v1.PositionState".into()
758    }
759}
760/// An LPNFT tracking both ownership and state of a position.
761///
762/// Tracking the state as part of the LPNFT means that all LP-related actions can
763/// be authorized by spending funds: a state transition (e.g., closing a
764/// position) is modeled as spending an "open position LPNFT" and minting a
765/// "closed position LPNFT" for the same (globally unique) position ID.
766///
767/// This means that the LP mechanics can be agnostic to the mechanism used to
768/// record custody and spend authorization.  For instance, they can be recorded
769/// in the shielded pool, where custody is based on off-chain keys, or they could
770/// be recorded in a programmatic on-chain account (in the future, e.g., to
771/// support interchain accounts).  This also means that LP-related actions don't
772/// require any cryptographic implementation (proofs, signatures, etc), other
773/// than hooking into the value commitment mechanism used for transaction
774/// balances.
775#[derive(Clone, PartialEq, ::prost::Message)]
776pub struct LpNft {
777    #[prost(message, optional, tag = "1")]
778    pub position_id: ::core::option::Option<PositionId>,
779    #[prost(message, optional, tag = "2")]
780    pub state: ::core::option::Option<PositionState>,
781}
782impl ::prost::Name for LpNft {
783    const NAME: &'static str = "LpNft";
784    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
785    fn full_name() -> ::prost::alloc::string::String {
786        "penumbra.core.component.dex.v1.LpNft".into()
787    }
788    fn type_url() -> ::prost::alloc::string::String {
789        "/penumbra.core.component.dex.v1.LpNft".into()
790    }
791}
792/// A transaction action that opens a new position.
793///
794/// This action's contribution to the transaction's value balance is to consume
795/// the initial reserves and contribute an opened position NFT.
796#[derive(Clone, PartialEq, ::prost::Message)]
797pub struct PositionOpen {
798    /// Contains the data defining the position, sufficient to compute its `PositionId`.
799    ///
800    /// Positions are immutable, so the `PositionData` (and hence the `PositionId`)
801    /// are unchanged over the entire lifetime of the position.
802    #[prost(message, optional, tag = "1")]
803    pub position: ::core::option::Option<Position>,
804}
805impl ::prost::Name for PositionOpen {
806    const NAME: &'static str = "PositionOpen";
807    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
808    fn full_name() -> ::prost::alloc::string::String {
809        "penumbra.core.component.dex.v1.PositionOpen".into()
810    }
811    fn type_url() -> ::prost::alloc::string::String {
812        "/penumbra.core.component.dex.v1.PositionOpen".into()
813    }
814}
815/// A transaction action that closes a position.
816///
817/// This action's contribution to the transaction's value balance is to consume
818/// an opened position NFT and contribute a closed position NFT.
819///
820/// Closing a position does not immediately withdraw funds, because Penumbra
821/// transactions (like any ZK transaction model) are early-binding: the prover
822/// must know the state transition they prove knowledge of, and they cannot know
823/// the final reserves with certainty until after the position has been deactivated.
824#[derive(Clone, PartialEq, ::prost::Message)]
825pub struct PositionClose {
826    #[prost(message, optional, tag = "1")]
827    pub position_id: ::core::option::Option<PositionId>,
828}
829impl ::prost::Name for PositionClose {
830    const NAME: &'static str = "PositionClose";
831    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
832    fn full_name() -> ::prost::alloc::string::String {
833        "penumbra.core.component.dex.v1.PositionClose".into()
834    }
835    fn type_url() -> ::prost::alloc::string::String {
836        "/penumbra.core.component.dex.v1.PositionClose".into()
837    }
838}
839/// A transaction action that withdraws funds from a closed position.
840///
841/// This action's contribution to the transaction's value balance is to consume a
842/// closed position NFT and contribute a withdrawn position NFT, as well as all
843/// of the funds that were in the position at the time of closing.
844#[derive(Clone, PartialEq, ::prost::Message)]
845pub struct PositionWithdraw {
846    #[prost(message, optional, tag = "1")]
847    pub position_id: ::core::option::Option<PositionId>,
848    /// A transparent (zero blinding factor) commitment to the position's final reserves and fees.
849    ///
850    /// The chain will check this commitment by recomputing it with the on-chain state.
851    #[prost(message, optional, tag = "2")]
852    pub reserves_commitment: ::core::option::Option<
853        super::super::super::asset::v1::BalanceCommitment,
854    >,
855    /// The sequence number of the withdrawal.
856    ///
857    /// This allows multiple withdrawals from the same position, rather than a single reward claim.
858    #[prost(uint64, tag = "3")]
859    pub sequence: u64,
860}
861impl ::prost::Name for PositionWithdraw {
862    const NAME: &'static str = "PositionWithdraw";
863    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
864    fn full_name() -> ::prost::alloc::string::String {
865        "penumbra.core.component.dex.v1.PositionWithdraw".into()
866    }
867    fn type_url() -> ::prost::alloc::string::String {
868        "/penumbra.core.component.dex.v1.PositionWithdraw".into()
869    }
870}
871/// Deprecated.
872#[derive(Clone, PartialEq, ::prost::Message)]
873pub struct PositionRewardClaim {
874    #[prost(message, optional, tag = "1")]
875    pub position_id: ::core::option::Option<PositionId>,
876    #[prost(message, optional, tag = "2")]
877    pub rewards_commitment: ::core::option::Option<
878        super::super::super::asset::v1::BalanceCommitment,
879    >,
880}
881impl ::prost::Name for PositionRewardClaim {
882    const NAME: &'static str = "PositionRewardClaim";
883    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
884    fn full_name() -> ::prost::alloc::string::String {
885        "penumbra.core.component.dex.v1.PositionRewardClaim".into()
886    }
887    fn type_url() -> ::prost::alloc::string::String {
888        "/penumbra.core.component.dex.v1.PositionRewardClaim".into()
889    }
890}
891/// Contains the entire execution of a particular swap.
892#[derive(Clone, PartialEq, ::prost::Message)]
893pub struct SwapExecution {
894    #[prost(message, repeated, tag = "1")]
895    pub traces: ::prost::alloc::vec::Vec<swap_execution::Trace>,
896    /// The total input amount for this execution.
897    #[prost(message, optional, tag = "2")]
898    pub input: ::core::option::Option<super::super::super::asset::v1::Value>,
899    /// The total output amount for this execution.
900    #[prost(message, optional, tag = "3")]
901    pub output: ::core::option::Option<super::super::super::asset::v1::Value>,
902}
903/// Nested message and enum types in `SwapExecution`.
904pub mod swap_execution {
905    /// Contains all individual steps consisting of a trade trace.
906    #[derive(Clone, PartialEq, ::prost::Message)]
907    pub struct Trace {
908        /// Each step in the trade trace.
909        #[prost(message, repeated, tag = "1")]
910        pub value: ::prost::alloc::vec::Vec<
911            super::super::super::super::asset::v1::Value,
912        >,
913    }
914    impl ::prost::Name for Trace {
915        const NAME: &'static str = "Trace";
916        const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
917        fn full_name() -> ::prost::alloc::string::String {
918            "penumbra.core.component.dex.v1.SwapExecution.Trace".into()
919        }
920        fn type_url() -> ::prost::alloc::string::String {
921            "/penumbra.core.component.dex.v1.SwapExecution.Trace".into()
922        }
923    }
924}
925impl ::prost::Name for SwapExecution {
926    const NAME: &'static str = "SwapExecution";
927    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
928    fn full_name() -> ::prost::alloc::string::String {
929        "penumbra.core.component.dex.v1.SwapExecution".into()
930    }
931    fn type_url() -> ::prost::alloc::string::String {
932        "/penumbra.core.component.dex.v1.SwapExecution".into()
933    }
934}
935/// Contains private and public data for withdrawing funds from a closed position.
936#[derive(Clone, PartialEq, ::prost::Message)]
937pub struct PositionWithdrawPlan {
938    #[prost(message, optional, tag = "1")]
939    pub reserves: ::core::option::Option<Reserves>,
940    #[prost(message, optional, tag = "2")]
941    pub position_id: ::core::option::Option<PositionId>,
942    #[prost(message, optional, tag = "3")]
943    pub pair: ::core::option::Option<TradingPair>,
944    /// The sequence number of the withdrawal.
945    #[prost(uint64, tag = "4")]
946    pub sequence: u64,
947    /// Any accumulated rewards assigned to this position.
948    #[prost(message, repeated, tag = "5")]
949    pub rewards: ::prost::alloc::vec::Vec<super::super::super::asset::v1::Value>,
950}
951impl ::prost::Name for PositionWithdrawPlan {
952    const NAME: &'static str = "PositionWithdrawPlan";
953    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
954    fn full_name() -> ::prost::alloc::string::String {
955        "penumbra.core.component.dex.v1.PositionWithdrawPlan".into()
956    }
957    fn type_url() -> ::prost::alloc::string::String {
958        "/penumbra.core.component.dex.v1.PositionWithdrawPlan".into()
959    }
960}
961/// Deprecated.
962#[derive(Clone, Copy, PartialEq, ::prost::Message)]
963pub struct PositionRewardClaimPlan {
964    #[prost(message, optional, tag = "1")]
965    pub reserves: ::core::option::Option<Reserves>,
966}
967impl ::prost::Name for PositionRewardClaimPlan {
968    const NAME: &'static str = "PositionRewardClaimPlan";
969    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
970    fn full_name() -> ::prost::alloc::string::String {
971        "penumbra.core.component.dex.v1.PositionRewardClaimPlan".into()
972    }
973    fn type_url() -> ::prost::alloc::string::String {
974        "/penumbra.core.component.dex.v1.PositionRewardClaimPlan".into()
975    }
976}
977/// Requests batch swap data associated with a given height and trading pair from the view service.
978#[derive(Clone, PartialEq, ::prost::Message)]
979pub struct BatchSwapOutputDataRequest {
980    #[prost(uint64, tag = "2")]
981    pub height: u64,
982    #[prost(message, optional, tag = "3")]
983    pub trading_pair: ::core::option::Option<TradingPair>,
984}
985impl ::prost::Name for BatchSwapOutputDataRequest {
986    const NAME: &'static str = "BatchSwapOutputDataRequest";
987    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
988    fn full_name() -> ::prost::alloc::string::String {
989        "penumbra.core.component.dex.v1.BatchSwapOutputDataRequest".into()
990    }
991    fn type_url() -> ::prost::alloc::string::String {
992        "/penumbra.core.component.dex.v1.BatchSwapOutputDataRequest".into()
993    }
994}
995#[derive(Clone, PartialEq, ::prost::Message)]
996pub struct BatchSwapOutputDataResponse {
997    #[prost(message, optional, tag = "1")]
998    pub data: ::core::option::Option<BatchSwapOutputData>,
999}
1000impl ::prost::Name for BatchSwapOutputDataResponse {
1001    const NAME: &'static str = "BatchSwapOutputDataResponse";
1002    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1003    fn full_name() -> ::prost::alloc::string::String {
1004        "penumbra.core.component.dex.v1.BatchSwapOutputDataResponse".into()
1005    }
1006    fn type_url() -> ::prost::alloc::string::String {
1007        "/penumbra.core.component.dex.v1.BatchSwapOutputDataResponse".into()
1008    }
1009}
1010#[derive(Clone, PartialEq, ::prost::Message)]
1011pub struct SwapExecutionRequest {
1012    #[prost(uint64, tag = "2")]
1013    pub height: u64,
1014    #[prost(message, optional, tag = "3")]
1015    pub trading_pair: ::core::option::Option<DirectedTradingPair>,
1016}
1017impl ::prost::Name for SwapExecutionRequest {
1018    const NAME: &'static str = "SwapExecutionRequest";
1019    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1020    fn full_name() -> ::prost::alloc::string::String {
1021        "penumbra.core.component.dex.v1.SwapExecutionRequest".into()
1022    }
1023    fn type_url() -> ::prost::alloc::string::String {
1024        "/penumbra.core.component.dex.v1.SwapExecutionRequest".into()
1025    }
1026}
1027#[derive(Clone, PartialEq, ::prost::Message)]
1028pub struct SwapExecutionResponse {
1029    #[prost(message, optional, tag = "1")]
1030    pub swap_execution: ::core::option::Option<SwapExecution>,
1031}
1032impl ::prost::Name for SwapExecutionResponse {
1033    const NAME: &'static str = "SwapExecutionResponse";
1034    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1035    fn full_name() -> ::prost::alloc::string::String {
1036        "penumbra.core.component.dex.v1.SwapExecutionResponse".into()
1037    }
1038    fn type_url() -> ::prost::alloc::string::String {
1039        "/penumbra.core.component.dex.v1.SwapExecutionResponse".into()
1040    }
1041}
1042#[derive(Clone, Copy, PartialEq, ::prost::Message)]
1043pub struct ArbExecutionRequest {
1044    #[prost(uint64, tag = "2")]
1045    pub height: u64,
1046}
1047impl ::prost::Name for ArbExecutionRequest {
1048    const NAME: &'static str = "ArbExecutionRequest";
1049    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1050    fn full_name() -> ::prost::alloc::string::String {
1051        "penumbra.core.component.dex.v1.ArbExecutionRequest".into()
1052    }
1053    fn type_url() -> ::prost::alloc::string::String {
1054        "/penumbra.core.component.dex.v1.ArbExecutionRequest".into()
1055    }
1056}
1057#[derive(Clone, PartialEq, ::prost::Message)]
1058pub struct ArbExecutionResponse {
1059    #[prost(message, optional, tag = "1")]
1060    pub swap_execution: ::core::option::Option<SwapExecution>,
1061    #[prost(uint64, tag = "2")]
1062    pub height: u64,
1063}
1064impl ::prost::Name for ArbExecutionResponse {
1065    const NAME: &'static str = "ArbExecutionResponse";
1066    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1067    fn full_name() -> ::prost::alloc::string::String {
1068        "penumbra.core.component.dex.v1.ArbExecutionResponse".into()
1069    }
1070    fn type_url() -> ::prost::alloc::string::String {
1071        "/penumbra.core.component.dex.v1.ArbExecutionResponse".into()
1072    }
1073}
1074#[derive(Clone, PartialEq, ::prost::Message)]
1075pub struct SwapExecutionsRequest {
1076    /// If present, only return swap executions occurring after the given height.
1077    #[prost(uint64, tag = "2")]
1078    pub start_height: u64,
1079    /// If present, only return swap executions occurring before the given height.
1080    #[prost(uint64, tag = "3")]
1081    pub end_height: u64,
1082    /// If present, filter swap executions by the given trading pair.
1083    #[prost(message, optional, tag = "4")]
1084    pub trading_pair: ::core::option::Option<DirectedTradingPair>,
1085}
1086impl ::prost::Name for SwapExecutionsRequest {
1087    const NAME: &'static str = "SwapExecutionsRequest";
1088    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1089    fn full_name() -> ::prost::alloc::string::String {
1090        "penumbra.core.component.dex.v1.SwapExecutionsRequest".into()
1091    }
1092    fn type_url() -> ::prost::alloc::string::String {
1093        "/penumbra.core.component.dex.v1.SwapExecutionsRequest".into()
1094    }
1095}
1096#[derive(Clone, PartialEq, ::prost::Message)]
1097pub struct SwapExecutionsResponse {
1098    #[prost(message, optional, tag = "1")]
1099    pub swap_execution: ::core::option::Option<SwapExecution>,
1100    #[prost(uint64, tag = "2")]
1101    pub height: u64,
1102    #[prost(message, optional, tag = "3")]
1103    pub trading_pair: ::core::option::Option<DirectedTradingPair>,
1104}
1105impl ::prost::Name for SwapExecutionsResponse {
1106    const NAME: &'static str = "SwapExecutionsResponse";
1107    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1108    fn full_name() -> ::prost::alloc::string::String {
1109        "penumbra.core.component.dex.v1.SwapExecutionsResponse".into()
1110    }
1111    fn type_url() -> ::prost::alloc::string::String {
1112        "/penumbra.core.component.dex.v1.SwapExecutionsResponse".into()
1113    }
1114}
1115#[derive(Clone, Copy, PartialEq, ::prost::Message)]
1116pub struct ArbExecutionsRequest {
1117    /// If present, only return arb executions occurring after the given height.
1118    #[prost(uint64, tag = "2")]
1119    pub start_height: u64,
1120    /// If present, only return arb executions occurring before the given height.
1121    #[prost(uint64, tag = "3")]
1122    pub end_height: u64,
1123}
1124impl ::prost::Name for ArbExecutionsRequest {
1125    const NAME: &'static str = "ArbExecutionsRequest";
1126    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1127    fn full_name() -> ::prost::alloc::string::String {
1128        "penumbra.core.component.dex.v1.ArbExecutionsRequest".into()
1129    }
1130    fn type_url() -> ::prost::alloc::string::String {
1131        "/penumbra.core.component.dex.v1.ArbExecutionsRequest".into()
1132    }
1133}
1134#[derive(Clone, PartialEq, ::prost::Message)]
1135pub struct ArbExecutionsResponse {
1136    #[prost(message, optional, tag = "1")]
1137    pub swap_execution: ::core::option::Option<SwapExecution>,
1138    #[prost(uint64, tag = "2")]
1139    pub height: u64,
1140}
1141impl ::prost::Name for ArbExecutionsResponse {
1142    const NAME: &'static str = "ArbExecutionsResponse";
1143    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1144    fn full_name() -> ::prost::alloc::string::String {
1145        "penumbra.core.component.dex.v1.ArbExecutionsResponse".into()
1146    }
1147    fn type_url() -> ::prost::alloc::string::String {
1148        "/penumbra.core.component.dex.v1.ArbExecutionsResponse".into()
1149    }
1150}
1151#[derive(Clone, Copy, PartialEq, ::prost::Message)]
1152pub struct LiquidityPositionsRequest {
1153    /// If true, include closed and withdrawn positions.
1154    #[prost(bool, tag = "4")]
1155    pub include_closed: bool,
1156}
1157impl ::prost::Name for LiquidityPositionsRequest {
1158    const NAME: &'static str = "LiquidityPositionsRequest";
1159    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1160    fn full_name() -> ::prost::alloc::string::String {
1161        "penumbra.core.component.dex.v1.LiquidityPositionsRequest".into()
1162    }
1163    fn type_url() -> ::prost::alloc::string::String {
1164        "/penumbra.core.component.dex.v1.LiquidityPositionsRequest".into()
1165    }
1166}
1167#[derive(Clone, PartialEq, ::prost::Message)]
1168pub struct LiquidityPositionsResponse {
1169    #[prost(message, optional, tag = "1")]
1170    pub data: ::core::option::Option<Position>,
1171}
1172impl ::prost::Name for LiquidityPositionsResponse {
1173    const NAME: &'static str = "LiquidityPositionsResponse";
1174    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1175    fn full_name() -> ::prost::alloc::string::String {
1176        "penumbra.core.component.dex.v1.LiquidityPositionsResponse".into()
1177    }
1178    fn type_url() -> ::prost::alloc::string::String {
1179        "/penumbra.core.component.dex.v1.LiquidityPositionsResponse".into()
1180    }
1181}
1182#[derive(Clone, PartialEq, ::prost::Message)]
1183pub struct LiquidityPositionByIdRequest {
1184    #[prost(message, optional, tag = "2")]
1185    pub position_id: ::core::option::Option<PositionId>,
1186}
1187impl ::prost::Name for LiquidityPositionByIdRequest {
1188    const NAME: &'static str = "LiquidityPositionByIdRequest";
1189    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1190    fn full_name() -> ::prost::alloc::string::String {
1191        "penumbra.core.component.dex.v1.LiquidityPositionByIdRequest".into()
1192    }
1193    fn type_url() -> ::prost::alloc::string::String {
1194        "/penumbra.core.component.dex.v1.LiquidityPositionByIdRequest".into()
1195    }
1196}
1197#[derive(Clone, PartialEq, ::prost::Message)]
1198pub struct LiquidityPositionByIdResponse {
1199    #[prost(message, optional, tag = "1")]
1200    pub data: ::core::option::Option<Position>,
1201}
1202impl ::prost::Name for LiquidityPositionByIdResponse {
1203    const NAME: &'static str = "LiquidityPositionByIdResponse";
1204    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1205    fn full_name() -> ::prost::alloc::string::String {
1206        "penumbra.core.component.dex.v1.LiquidityPositionByIdResponse".into()
1207    }
1208    fn type_url() -> ::prost::alloc::string::String {
1209        "/penumbra.core.component.dex.v1.LiquidityPositionByIdResponse".into()
1210    }
1211}
1212#[derive(Clone, PartialEq, ::prost::Message)]
1213pub struct LiquidityPositionsByIdRequest {
1214    #[prost(message, repeated, tag = "2")]
1215    pub position_id: ::prost::alloc::vec::Vec<PositionId>,
1216}
1217impl ::prost::Name for LiquidityPositionsByIdRequest {
1218    const NAME: &'static str = "LiquidityPositionsByIdRequest";
1219    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1220    fn full_name() -> ::prost::alloc::string::String {
1221        "penumbra.core.component.dex.v1.LiquidityPositionsByIdRequest".into()
1222    }
1223    fn type_url() -> ::prost::alloc::string::String {
1224        "/penumbra.core.component.dex.v1.LiquidityPositionsByIdRequest".into()
1225    }
1226}
1227#[derive(Clone, PartialEq, ::prost::Message)]
1228pub struct LiquidityPositionsByIdResponse {
1229    #[prost(message, optional, tag = "1")]
1230    pub data: ::core::option::Option<Position>,
1231}
1232impl ::prost::Name for LiquidityPositionsByIdResponse {
1233    const NAME: &'static str = "LiquidityPositionsByIdResponse";
1234    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1235    fn full_name() -> ::prost::alloc::string::String {
1236        "penumbra.core.component.dex.v1.LiquidityPositionsByIdResponse".into()
1237    }
1238    fn type_url() -> ::prost::alloc::string::String {
1239        "/penumbra.core.component.dex.v1.LiquidityPositionsByIdResponse".into()
1240    }
1241}
1242#[derive(Clone, PartialEq, ::prost::Message)]
1243pub struct LiquidityPositionsByPriceRequest {
1244    /// The directed trading pair to request positions for
1245    #[prost(message, optional, tag = "2")]
1246    pub trading_pair: ::core::option::Option<DirectedTradingPair>,
1247    /// The maximum number of positions to return.
1248    #[prost(uint64, tag = "5")]
1249    pub limit: u64,
1250}
1251impl ::prost::Name for LiquidityPositionsByPriceRequest {
1252    const NAME: &'static str = "LiquidityPositionsByPriceRequest";
1253    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1254    fn full_name() -> ::prost::alloc::string::String {
1255        "penumbra.core.component.dex.v1.LiquidityPositionsByPriceRequest".into()
1256    }
1257    fn type_url() -> ::prost::alloc::string::String {
1258        "/penumbra.core.component.dex.v1.LiquidityPositionsByPriceRequest".into()
1259    }
1260}
1261#[derive(Clone, PartialEq, ::prost::Message)]
1262pub struct LiquidityPositionsByPriceResponse {
1263    #[prost(message, optional, tag = "1")]
1264    pub data: ::core::option::Option<Position>,
1265    #[prost(message, optional, tag = "2")]
1266    pub id: ::core::option::Option<PositionId>,
1267}
1268impl ::prost::Name for LiquidityPositionsByPriceResponse {
1269    const NAME: &'static str = "LiquidityPositionsByPriceResponse";
1270    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1271    fn full_name() -> ::prost::alloc::string::String {
1272        "penumbra.core.component.dex.v1.LiquidityPositionsByPriceResponse".into()
1273    }
1274    fn type_url() -> ::prost::alloc::string::String {
1275        "/penumbra.core.component.dex.v1.LiquidityPositionsByPriceResponse".into()
1276    }
1277}
1278#[derive(Clone, PartialEq, ::prost::Message)]
1279pub struct SpreadRequest {
1280    #[prost(message, optional, tag = "2")]
1281    pub trading_pair: ::core::option::Option<TradingPair>,
1282}
1283impl ::prost::Name for SpreadRequest {
1284    const NAME: &'static str = "SpreadRequest";
1285    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1286    fn full_name() -> ::prost::alloc::string::String {
1287        "penumbra.core.component.dex.v1.SpreadRequest".into()
1288    }
1289    fn type_url() -> ::prost::alloc::string::String {
1290        "/penumbra.core.component.dex.v1.SpreadRequest".into()
1291    }
1292}
1293#[derive(Clone, PartialEq, ::prost::Message)]
1294pub struct SpreadResponse {
1295    /// The best position when trading 1 => 2.
1296    #[prost(message, optional, tag = "1")]
1297    pub best_1_to_2_position: ::core::option::Option<Position>,
1298    /// The best position when trading 2 => 1.
1299    #[prost(message, optional, tag = "2")]
1300    pub best_2_to_1_position: ::core::option::Option<Position>,
1301    /// An approximation of the effective price when trading 1 => 2.
1302    #[prost(double, tag = "3")]
1303    pub approx_effective_price_1_to_2: f64,
1304    /// An approximation of the effective price when trading 2 => 1.
1305    #[prost(double, tag = "4")]
1306    pub approx_effective_price_2_to_1: f64,
1307}
1308impl ::prost::Name for SpreadResponse {
1309    const NAME: &'static str = "SpreadResponse";
1310    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1311    fn full_name() -> ::prost::alloc::string::String {
1312        "penumbra.core.component.dex.v1.SpreadResponse".into()
1313    }
1314    fn type_url() -> ::prost::alloc::string::String {
1315        "/penumbra.core.component.dex.v1.SpreadResponse".into()
1316    }
1317}
1318#[derive(Clone, PartialEq, ::prost::Message)]
1319pub struct SimulateTradeRequest {
1320    #[prost(message, optional, tag = "1")]
1321    pub input: ::core::option::Option<super::super::super::asset::v1::Value>,
1322    #[prost(message, optional, tag = "2")]
1323    pub output: ::core::option::Option<super::super::super::asset::v1::AssetId>,
1324    #[prost(message, optional, tag = "3")]
1325    pub routing: ::core::option::Option<simulate_trade_request::Routing>,
1326}
1327/// Nested message and enum types in `SimulateTradeRequest`.
1328pub mod simulate_trade_request {
1329    #[derive(Clone, Copy, PartialEq, ::prost::Message)]
1330    pub struct Routing {
1331        #[prost(oneof = "routing::Setting", tags = "1, 2")]
1332        pub setting: ::core::option::Option<routing::Setting>,
1333    }
1334    /// Nested message and enum types in `Routing`.
1335    pub mod routing {
1336        #[derive(Clone, Copy, PartialEq, ::prost::Message)]
1337        pub struct SingleHop {}
1338        impl ::prost::Name for SingleHop {
1339            const NAME: &'static str = "SingleHop";
1340            const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1341            fn full_name() -> ::prost::alloc::string::String {
1342                "penumbra.core.component.dex.v1.SimulateTradeRequest.Routing.SingleHop"
1343                    .into()
1344            }
1345            fn type_url() -> ::prost::alloc::string::String {
1346                "/penumbra.core.component.dex.v1.SimulateTradeRequest.Routing.SingleHop"
1347                    .into()
1348            }
1349        }
1350        #[derive(Clone, Copy, PartialEq, ::prost::Message)]
1351        pub struct Default {}
1352        impl ::prost::Name for Default {
1353            const NAME: &'static str = "Default";
1354            const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1355            fn full_name() -> ::prost::alloc::string::String {
1356                "penumbra.core.component.dex.v1.SimulateTradeRequest.Routing.Default"
1357                    .into()
1358            }
1359            fn type_url() -> ::prost::alloc::string::String {
1360                "/penumbra.core.component.dex.v1.SimulateTradeRequest.Routing.Default"
1361                    .into()
1362            }
1363        }
1364        #[derive(Clone, Copy, PartialEq, ::prost::Oneof)]
1365        pub enum Setting {
1366            #[prost(message, tag = "1")]
1367            Default(Default),
1368            #[prost(message, tag = "2")]
1369            SingleHop(SingleHop),
1370        }
1371    }
1372    impl ::prost::Name for Routing {
1373        const NAME: &'static str = "Routing";
1374        const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1375        fn full_name() -> ::prost::alloc::string::String {
1376            "penumbra.core.component.dex.v1.SimulateTradeRequest.Routing".into()
1377        }
1378        fn type_url() -> ::prost::alloc::string::String {
1379            "/penumbra.core.component.dex.v1.SimulateTradeRequest.Routing".into()
1380        }
1381    }
1382}
1383impl ::prost::Name for SimulateTradeRequest {
1384    const NAME: &'static str = "SimulateTradeRequest";
1385    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1386    fn full_name() -> ::prost::alloc::string::String {
1387        "penumbra.core.component.dex.v1.SimulateTradeRequest".into()
1388    }
1389    fn type_url() -> ::prost::alloc::string::String {
1390        "/penumbra.core.component.dex.v1.SimulateTradeRequest".into()
1391    }
1392}
1393#[derive(Clone, PartialEq, ::prost::Message)]
1394pub struct SimulateTradeResponse {
1395    #[prost(message, optional, tag = "1")]
1396    pub output: ::core::option::Option<SwapExecution>,
1397    /// Estimated input amount that will not be swapped due to liquidity
1398    #[prost(message, optional, tag = "2")]
1399    pub unfilled: ::core::option::Option<super::super::super::asset::v1::Value>,
1400}
1401impl ::prost::Name for SimulateTradeResponse {
1402    const NAME: &'static str = "SimulateTradeResponse";
1403    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1404    fn full_name() -> ::prost::alloc::string::String {
1405        "penumbra.core.component.dex.v1.SimulateTradeResponse".into()
1406    }
1407    fn type_url() -> ::prost::alloc::string::String {
1408        "/penumbra.core.component.dex.v1.SimulateTradeResponse".into()
1409    }
1410}
1411#[derive(Clone, PartialEq, ::prost::Message)]
1412pub struct EventSwap {
1413    /// The trading pair to swap.
1414    #[prost(message, optional, tag = "1")]
1415    pub trading_pair: ::core::option::Option<TradingPair>,
1416    /// The amount for asset 1.
1417    #[prost(message, optional, tag = "2")]
1418    pub delta_1_i: ::core::option::Option<super::super::super::num::v1::Amount>,
1419    /// The amount for asset 2.
1420    #[prost(message, optional, tag = "3")]
1421    pub delta_2_i: ::core::option::Option<super::super::super::num::v1::Amount>,
1422    /// The swap commitment.
1423    #[prost(message, optional, tag = "4")]
1424    pub swap_commitment: ::core::option::Option<
1425        super::super::super::super::crypto::tct::v1::StateCommitment,
1426    >,
1427}
1428impl ::prost::Name for EventSwap {
1429    const NAME: &'static str = "EventSwap";
1430    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1431    fn full_name() -> ::prost::alloc::string::String {
1432        "penumbra.core.component.dex.v1.EventSwap".into()
1433    }
1434    fn type_url() -> ::prost::alloc::string::String {
1435        "/penumbra.core.component.dex.v1.EventSwap".into()
1436    }
1437}
1438#[derive(Clone, PartialEq, ::prost::Message)]
1439pub struct EventSwapClaim {
1440    /// The trading pair that is subject of the swap claim.
1441    #[prost(message, optional, tag = "1")]
1442    pub trading_pair: ::core::option::Option<TradingPair>,
1443    /// Note commitment for the first asset.
1444    #[prost(message, optional, tag = "2")]
1445    pub output_1_commitment: ::core::option::Option<
1446        super::super::super::super::crypto::tct::v1::StateCommitment,
1447    >,
1448    /// Note commitment for the second asset.
1449    #[prost(message, optional, tag = "3")]
1450    pub output_2_commitment: ::core::option::Option<
1451        super::super::super::super::crypto::tct::v1::StateCommitment,
1452    >,
1453    /// The nullifier for the swap commitment.
1454    #[prost(message, optional, tag = "4")]
1455    pub nullifier: ::core::option::Option<super::super::sct::v1::Nullifier>,
1456}
1457impl ::prost::Name for EventSwapClaim {
1458    const NAME: &'static str = "EventSwapClaim";
1459    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1460    fn full_name() -> ::prost::alloc::string::String {
1461        "penumbra.core.component.dex.v1.EventSwapClaim".into()
1462    }
1463    fn type_url() -> ::prost::alloc::string::String {
1464        "/penumbra.core.component.dex.v1.EventSwapClaim".into()
1465    }
1466}
1467#[derive(Clone, PartialEq, ::prost::Message)]
1468pub struct EventPositionOpen {
1469    /// Position ID.
1470    #[prost(message, optional, tag = "1")]
1471    pub position_id: ::core::option::Option<PositionId>,
1472    /// The trading pair to open.
1473    #[prost(message, optional, tag = "2")]
1474    pub trading_pair: ::core::option::Option<TradingPair>,
1475    /// The amount for asset 1.
1476    #[prost(message, optional, tag = "3")]
1477    pub reserves_1: ::core::option::Option<super::super::super::num::v1::Amount>,
1478    /// The amount for asset 2.
1479    #[prost(message, optional, tag = "4")]
1480    pub reserves_2: ::core::option::Option<super::super::super::num::v1::Amount>,
1481    /// The trading fee for the position, expressed in basis points.
1482    /// e.g. 2% fee is expressed as 200, 100% fee is expressed as 10000;
1483    #[prost(uint32, tag = "5")]
1484    pub trading_fee: u32,
1485    /// The full position.
1486    ///
1487    /// This is somewhat redundant, but contains any information not present above.
1488    #[prost(message, optional, tag = "6")]
1489    pub position: ::core::option::Option<Position>,
1490}
1491impl ::prost::Name for EventPositionOpen {
1492    const NAME: &'static str = "EventPositionOpen";
1493    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1494    fn full_name() -> ::prost::alloc::string::String {
1495        "penumbra.core.component.dex.v1.EventPositionOpen".into()
1496    }
1497    fn type_url() -> ::prost::alloc::string::String {
1498        "/penumbra.core.component.dex.v1.EventPositionOpen".into()
1499    }
1500}
1501#[derive(Clone, PartialEq, ::prost::Message)]
1502pub struct EventPositionClose {
1503    /// The ID of the closed position
1504    #[prost(message, optional, tag = "1")]
1505    pub position_id: ::core::option::Option<PositionId>,
1506}
1507impl ::prost::Name for EventPositionClose {
1508    const NAME: &'static str = "EventPositionClose";
1509    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1510    fn full_name() -> ::prost::alloc::string::String {
1511        "penumbra.core.component.dex.v1.EventPositionClose".into()
1512    }
1513    fn type_url() -> ::prost::alloc::string::String {
1514        "/penumbra.core.component.dex.v1.EventPositionClose".into()
1515    }
1516}
1517#[derive(Clone, PartialEq, ::prost::Message)]
1518pub struct EventQueuePositionClose {
1519    /// The ID of the position queued that is closed for closure.
1520    #[prost(message, optional, tag = "1")]
1521    pub position_id: ::core::option::Option<PositionId>,
1522}
1523impl ::prost::Name for EventQueuePositionClose {
1524    const NAME: &'static str = "EventQueuePositionClose";
1525    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1526    fn full_name() -> ::prost::alloc::string::String {
1527        "penumbra.core.component.dex.v1.EventQueuePositionClose".into()
1528    }
1529    fn type_url() -> ::prost::alloc::string::String {
1530        "/penumbra.core.component.dex.v1.EventQueuePositionClose".into()
1531    }
1532}
1533#[derive(Clone, PartialEq, ::prost::Message)]
1534pub struct EventPositionWithdraw {
1535    /// The ID of the withdrawn position.
1536    #[prost(message, optional, tag = "1")]
1537    pub position_id: ::core::option::Option<PositionId>,
1538    /// The trading pair of the withdrawn position.
1539    #[prost(message, optional, tag = "2")]
1540    pub trading_pair: ::core::option::Option<TradingPair>,
1541    /// The reserves of asset 1 of the withdrawn position.
1542    #[prost(message, optional, tag = "3")]
1543    pub reserves_1: ::core::option::Option<super::super::super::num::v1::Amount>,
1544    /// The reserves of asset 2 of the withdrawn position.
1545    #[prost(message, optional, tag = "4")]
1546    pub reserves_2: ::core::option::Option<super::super::super::num::v1::Amount>,
1547    /// The sequence number of the withdrawal.
1548    #[prost(uint64, tag = "5")]
1549    pub sequence: u64,
1550}
1551impl ::prost::Name for EventPositionWithdraw {
1552    const NAME: &'static str = "EventPositionWithdraw";
1553    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1554    fn full_name() -> ::prost::alloc::string::String {
1555        "penumbra.core.component.dex.v1.EventPositionWithdraw".into()
1556    }
1557    fn type_url() -> ::prost::alloc::string::String {
1558        "/penumbra.core.component.dex.v1.EventPositionWithdraw".into()
1559    }
1560}
1561#[derive(Clone, PartialEq, ::prost::Message)]
1562pub struct EventPositionExecution {
1563    /// The ID of the position executed against.
1564    #[prost(message, optional, tag = "1")]
1565    pub position_id: ::core::option::Option<PositionId>,
1566    /// The trading pair of the position executed against.
1567    #[prost(message, optional, tag = "2")]
1568    pub trading_pair: ::core::option::Option<TradingPair>,
1569    /// The reserves of asset 1 of the position after execution.
1570    #[prost(message, optional, tag = "3")]
1571    pub reserves_1: ::core::option::Option<super::super::super::num::v1::Amount>,
1572    /// The reserves of asset 2 of the position after execution.
1573    #[prost(message, optional, tag = "4")]
1574    pub reserves_2: ::core::option::Option<super::super::super::num::v1::Amount>,
1575    /// The reserves of asset 1 of the position before execution.
1576    #[prost(message, optional, tag = "5")]
1577    pub prev_reserves_1: ::core::option::Option<super::super::super::num::v1::Amount>,
1578    /// The reserves of asset 2 of the position before execution.
1579    #[prost(message, optional, tag = "6")]
1580    pub prev_reserves_2: ::core::option::Option<super::super::super::num::v1::Amount>,
1581    /// Context: the end-to-end route that was being traversed during execution.
1582    #[prost(message, optional, tag = "7")]
1583    pub context: ::core::option::Option<DirectedTradingPair>,
1584}
1585impl ::prost::Name for EventPositionExecution {
1586    const NAME: &'static str = "EventPositionExecution";
1587    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1588    fn full_name() -> ::prost::alloc::string::String {
1589        "penumbra.core.component.dex.v1.EventPositionExecution".into()
1590    }
1591    fn type_url() -> ::prost::alloc::string::String {
1592        "/penumbra.core.component.dex.v1.EventPositionExecution".into()
1593    }
1594}
1595#[derive(Clone, PartialEq, ::prost::Message)]
1596pub struct EventBatchSwap {
1597    /// The BatchSwapOutputData containing the results of the batch swap.
1598    #[prost(message, optional, tag = "1")]
1599    pub batch_swap_output_data: ::core::option::Option<BatchSwapOutputData>,
1600    /// The record of execution for the batch swap in the 1 -> 2 direction.
1601    #[prost(message, optional, tag = "2")]
1602    pub swap_execution_1_for_2: ::core::option::Option<SwapExecution>,
1603    /// The record of execution for the batch swap in the 2 -> 1 direction.
1604    #[prost(message, optional, tag = "3")]
1605    pub swap_execution_2_for_1: ::core::option::Option<SwapExecution>,
1606}
1607impl ::prost::Name for EventBatchSwap {
1608    const NAME: &'static str = "EventBatchSwap";
1609    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1610    fn full_name() -> ::prost::alloc::string::String {
1611        "penumbra.core.component.dex.v1.EventBatchSwap".into()
1612    }
1613    fn type_url() -> ::prost::alloc::string::String {
1614        "/penumbra.core.component.dex.v1.EventBatchSwap".into()
1615    }
1616}
1617#[derive(Clone, PartialEq, ::prost::Message)]
1618pub struct EventArbExecution {
1619    /// The height at which the arb execution occurred.
1620    #[prost(uint64, tag = "1")]
1621    pub height: u64,
1622    /// The record of execution for the arb execution.
1623    #[prost(message, optional, tag = "2")]
1624    pub swap_execution: ::core::option::Option<SwapExecution>,
1625}
1626impl ::prost::Name for EventArbExecution {
1627    const NAME: &'static str = "EventArbExecution";
1628    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1629    fn full_name() -> ::prost::alloc::string::String {
1630        "penumbra.core.component.dex.v1.EventArbExecution".into()
1631    }
1632    fn type_url() -> ::prost::alloc::string::String {
1633        "/penumbra.core.component.dex.v1.EventArbExecution".into()
1634    }
1635}
1636/// Indicates that value was added to the DEX.
1637#[derive(Clone, PartialEq, ::prost::Message)]
1638pub struct EventValueCircuitBreakerCredit {
1639    /// The asset ID being deposited into the DEX.
1640    #[prost(message, optional, tag = "1")]
1641    pub asset_id: ::core::option::Option<super::super::super::asset::v1::AssetId>,
1642    /// The previous balance of the asset in the DEX.
1643    #[prost(message, optional, tag = "2")]
1644    pub previous_balance: ::core::option::Option<super::super::super::num::v1::Amount>,
1645    /// The new balance of the asset in the DEX.
1646    #[prost(message, optional, tag = "3")]
1647    pub new_balance: ::core::option::Option<super::super::super::num::v1::Amount>,
1648}
1649impl ::prost::Name for EventValueCircuitBreakerCredit {
1650    const NAME: &'static str = "EventValueCircuitBreakerCredit";
1651    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1652    fn full_name() -> ::prost::alloc::string::String {
1653        "penumbra.core.component.dex.v1.EventValueCircuitBreakerCredit".into()
1654    }
1655    fn type_url() -> ::prost::alloc::string::String {
1656        "/penumbra.core.component.dex.v1.EventValueCircuitBreakerCredit".into()
1657    }
1658}
1659/// Indicates that value is leaving the DEX.
1660#[derive(Clone, PartialEq, ::prost::Message)]
1661pub struct EventValueCircuitBreakerDebit {
1662    /// The asset ID being deposited into the DEX.
1663    #[prost(message, optional, tag = "1")]
1664    pub asset_id: ::core::option::Option<super::super::super::asset::v1::AssetId>,
1665    /// The previous balance of the asset in the DEX.
1666    #[prost(message, optional, tag = "2")]
1667    pub previous_balance: ::core::option::Option<super::super::super::num::v1::Amount>,
1668    /// The new balance of the asset in the DEX.
1669    #[prost(message, optional, tag = "3")]
1670    pub new_balance: ::core::option::Option<super::super::super::num::v1::Amount>,
1671}
1672impl ::prost::Name for EventValueCircuitBreakerDebit {
1673    const NAME: &'static str = "EventValueCircuitBreakerDebit";
1674    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1675    fn full_name() -> ::prost::alloc::string::String {
1676        "penumbra.core.component.dex.v1.EventValueCircuitBreakerDebit".into()
1677    }
1678    fn type_url() -> ::prost::alloc::string::String {
1679        "/penumbra.core.component.dex.v1.EventValueCircuitBreakerDebit".into()
1680    }
1681}
1682/// Emitted whenever there's non-empty candlestick data for a particular pair.
1683///
1684/// Beware: if there's no activity on a given pair, there's no guarantee
1685/// that a candlestick will be emitted.
1686#[derive(Clone, PartialEq, ::prost::Message)]
1687pub struct EventCandlestickData {
1688    /// The pair the candlestick is for.
1689    #[prost(message, optional, tag = "1")]
1690    pub pair: ::core::option::Option<DirectedTradingPair>,
1691    /// The candlestick for this particular pair.
1692    #[prost(message, optional, tag = "2")]
1693    pub stick: ::core::option::Option<CandlestickData>,
1694}
1695impl ::prost::Name for EventCandlestickData {
1696    const NAME: &'static str = "EventCandlestickData";
1697    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1698    fn full_name() -> ::prost::alloc::string::String {
1699        "penumbra.core.component.dex.v1.EventCandlestickData".into()
1700    }
1701    fn type_url() -> ::prost::alloc::string::String {
1702        "/penumbra.core.component.dex.v1.EventCandlestickData".into()
1703    }
1704}
1705#[derive(Clone, PartialEq, ::prost::Message)]
1706pub struct DexParameters {
1707    /// Whether or not the DEX is enabled.
1708    #[prost(bool, tag = "1")]
1709    pub is_enabled: bool,
1710    /// The list of fixed candidates for routing.
1711    #[prost(message, repeated, tag = "2")]
1712    pub fixed_candidates: ::prost::alloc::vec::Vec<
1713        super::super::super::asset::v1::AssetId,
1714    >,
1715    /// The number of hops to traverse while routing from A to B.
1716    #[prost(uint32, tag = "3")]
1717    pub max_hops: u32,
1718    /// The maximum number of positions per trading pair.
1719    /// If this number is exceeded, positions with the least
1720    /// inventory get evicted from the DEX.
1721    #[prost(uint32, tag = "4")]
1722    pub max_positions_per_pair: u32,
1723    /// The maximum number of routing and execution steps to be performed
1724    /// for a single pair
1725    #[prost(uint32, tag = "5")]
1726    pub max_execution_budget: u32,
1727}
1728impl ::prost::Name for DexParameters {
1729    const NAME: &'static str = "DexParameters";
1730    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1731    fn full_name() -> ::prost::alloc::string::String {
1732        "penumbra.core.component.dex.v1.DexParameters".into()
1733    }
1734    fn type_url() -> ::prost::alloc::string::String {
1735        "/penumbra.core.component.dex.v1.DexParameters".into()
1736    }
1737}
1738#[derive(Clone, PartialEq, ::prost::Message)]
1739pub struct GenesisContent {
1740    /// The initial parameters for the DEX.
1741    #[prost(message, optional, tag = "1")]
1742    pub dex_params: ::core::option::Option<DexParameters>,
1743}
1744impl ::prost::Name for GenesisContent {
1745    const NAME: &'static str = "GenesisContent";
1746    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1747    fn full_name() -> ::prost::alloc::string::String {
1748        "penumbra.core.component.dex.v1.GenesisContent".into()
1749    }
1750    fn type_url() -> ::prost::alloc::string::String {
1751        "/penumbra.core.component.dex.v1.GenesisContent".into()
1752    }
1753}
1754#[derive(Clone, Copy, PartialEq, ::prost::Message)]
1755pub struct CandlestickData {
1756    /// The height of the candlestick data.
1757    #[prost(uint64, tag = "1")]
1758    pub height: u64,
1759    /// The first observed price during the block execution.
1760    #[prost(double, tag = "2")]
1761    pub open: f64,
1762    /// The last observed price during the block execution.
1763    #[prost(double, tag = "3")]
1764    pub close: f64,
1765    /// The highest observed price during the block execution.
1766    #[prost(double, tag = "4")]
1767    pub high: f64,
1768    /// The lowest observed price during the block execution.
1769    #[prost(double, tag = "5")]
1770    pub low: f64,
1771    /// The volume that traded "directly", during individual position executions.
1772    #[prost(double, tag = "6")]
1773    pub direct_volume: f64,
1774    /// The volume that traded as part of swaps, which could have traversed multiple routes.
1775    #[prost(double, tag = "7")]
1776    pub swap_volume: f64,
1777}
1778impl ::prost::Name for CandlestickData {
1779    const NAME: &'static str = "CandlestickData";
1780    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1781    fn full_name() -> ::prost::alloc::string::String {
1782        "penumbra.core.component.dex.v1.CandlestickData".into()
1783    }
1784    fn type_url() -> ::prost::alloc::string::String {
1785        "/penumbra.core.component.dex.v1.CandlestickData".into()
1786    }
1787}
1788#[derive(Clone, PartialEq, ::prost::Message)]
1789pub struct CandlestickDataRequest {
1790    /// The directed trading pair to request candlestick data for.
1791    ///
1792    /// NOTE: the returned data will only have trades from the SOURCE asset to the
1793    /// DEST asset, not the other direction. Make another request if you want both
1794    /// sets of data.
1795    #[prost(message, optional, tag = "1")]
1796    pub pair: ::core::option::Option<DirectedTradingPair>,
1797    /// The maximum number of candlestick data points to return.
1798    ///
1799    /// The server may clamp this limit to a maximum value.
1800    #[prost(uint64, tag = "2")]
1801    pub limit: u64,
1802    /// The height to start the query from.
1803    ///
1804    /// If this is unset (= 0), the server will return the most recent data points.
1805    #[prost(uint64, tag = "3")]
1806    pub start_height: u64,
1807}
1808impl ::prost::Name for CandlestickDataRequest {
1809    const NAME: &'static str = "CandlestickDataRequest";
1810    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1811    fn full_name() -> ::prost::alloc::string::String {
1812        "penumbra.core.component.dex.v1.CandlestickDataRequest".into()
1813    }
1814    fn type_url() -> ::prost::alloc::string::String {
1815        "/penumbra.core.component.dex.v1.CandlestickDataRequest".into()
1816    }
1817}
1818#[derive(Clone, PartialEq, ::prost::Message)]
1819pub struct CandlestickDataResponse {
1820    /// The candlestick data points.
1821    #[prost(message, repeated, tag = "1")]
1822    pub data: ::prost::alloc::vec::Vec<CandlestickData>,
1823}
1824impl ::prost::Name for CandlestickDataResponse {
1825    const NAME: &'static str = "CandlestickDataResponse";
1826    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1827    fn full_name() -> ::prost::alloc::string::String {
1828        "penumbra.core.component.dex.v1.CandlestickDataResponse".into()
1829    }
1830    fn type_url() -> ::prost::alloc::string::String {
1831        "/penumbra.core.component.dex.v1.CandlestickDataResponse".into()
1832    }
1833}
1834#[derive(Clone, PartialEq, ::prost::Message)]
1835pub struct CandlestickDataStreamRequest {
1836    /// The directed trading pair to subscribe to.
1837    #[prost(message, optional, tag = "1")]
1838    pub pair: ::core::option::Option<DirectedTradingPair>,
1839}
1840impl ::prost::Name for CandlestickDataStreamRequest {
1841    const NAME: &'static str = "CandlestickDataStreamRequest";
1842    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1843    fn full_name() -> ::prost::alloc::string::String {
1844        "penumbra.core.component.dex.v1.CandlestickDataStreamRequest".into()
1845    }
1846    fn type_url() -> ::prost::alloc::string::String {
1847        "/penumbra.core.component.dex.v1.CandlestickDataStreamRequest".into()
1848    }
1849}
1850#[derive(Clone, Copy, PartialEq, ::prost::Message)]
1851pub struct CandlestickDataStreamResponse {
1852    /// The candlestick data point.
1853    #[prost(message, optional, tag = "1")]
1854    pub data: ::core::option::Option<CandlestickData>,
1855}
1856impl ::prost::Name for CandlestickDataStreamResponse {
1857    const NAME: &'static str = "CandlestickDataStreamResponse";
1858    const PACKAGE: &'static str = "penumbra.core.component.dex.v1";
1859    fn full_name() -> ::prost::alloc::string::String {
1860        "penumbra.core.component.dex.v1.CandlestickDataStreamResponse".into()
1861    }
1862    fn type_url() -> ::prost::alloc::string::String {
1863        "/penumbra.core.component.dex.v1.CandlestickDataStreamResponse".into()
1864    }
1865}
1866/// Generated client implementations.
1867#[cfg(feature = "rpc")]
1868pub mod query_service_client {
1869    #![allow(
1870        unused_variables,
1871        dead_code,
1872        missing_docs,
1873        clippy::wildcard_imports,
1874        clippy::let_unit_value,
1875    )]
1876    use tonic::codegen::*;
1877    use tonic::codegen::http::Uri;
1878    /// Query operations for the DEX component.
1879    #[derive(Debug, Clone)]
1880    pub struct QueryServiceClient<T> {
1881        inner: tonic::client::Grpc<T>,
1882    }
1883    impl QueryServiceClient<tonic::transport::Channel> {
1884        /// Attempt to create a new client by connecting to a given endpoint.
1885        pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error>
1886        where
1887            D: TryInto<tonic::transport::Endpoint>,
1888            D::Error: Into<StdError>,
1889        {
1890            let conn = tonic::transport::Endpoint::new(dst)?.connect().await?;
1891            Ok(Self::new(conn))
1892        }
1893    }
1894    impl<T> QueryServiceClient<T>
1895    where
1896        T: tonic::client::GrpcService<tonic::body::BoxBody>,
1897        T::Error: Into<StdError>,
1898        T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static,
1899        <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send,
1900    {
1901        pub fn new(inner: T) -> Self {
1902            let inner = tonic::client::Grpc::new(inner);
1903            Self { inner }
1904        }
1905        pub fn with_origin(inner: T, origin: Uri) -> Self {
1906            let inner = tonic::client::Grpc::with_origin(inner, origin);
1907            Self { inner }
1908        }
1909        pub fn with_interceptor<F>(
1910            inner: T,
1911            interceptor: F,
1912        ) -> QueryServiceClient<InterceptedService<T, F>>
1913        where
1914            F: tonic::service::Interceptor,
1915            T::ResponseBody: Default,
1916            T: tonic::codegen::Service<
1917                http::Request<tonic::body::BoxBody>,
1918                Response = http::Response<
1919                    <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody,
1920                >,
1921            >,
1922            <T as tonic::codegen::Service<
1923                http::Request<tonic::body::BoxBody>,
1924            >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync,
1925        {
1926            QueryServiceClient::new(InterceptedService::new(inner, interceptor))
1927        }
1928        /// Compress requests with the given encoding.
1929        ///
1930        /// This requires the server to support it otherwise it might respond with an
1931        /// error.
1932        #[must_use]
1933        pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {
1934            self.inner = self.inner.send_compressed(encoding);
1935            self
1936        }
1937        /// Enable decompressing responses.
1938        #[must_use]
1939        pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {
1940            self.inner = self.inner.accept_compressed(encoding);
1941            self
1942        }
1943        /// Limits the maximum size of a decoded message.
1944        ///
1945        /// Default: `4MB`
1946        #[must_use]
1947        pub fn max_decoding_message_size(mut self, limit: usize) -> Self {
1948            self.inner = self.inner.max_decoding_message_size(limit);
1949            self
1950        }
1951        /// Limits the maximum size of an encoded message.
1952        ///
1953        /// Default: `usize::MAX`
1954        #[must_use]
1955        pub fn max_encoding_message_size(mut self, limit: usize) -> Self {
1956            self.inner = self.inner.max_encoding_message_size(limit);
1957            self
1958        }
1959        /// Get the batch clearing prices for a specific block height and trading pair.
1960        pub async fn batch_swap_output_data(
1961            &mut self,
1962            request: impl tonic::IntoRequest<super::BatchSwapOutputDataRequest>,
1963        ) -> std::result::Result<
1964            tonic::Response<super::BatchSwapOutputDataResponse>,
1965            tonic::Status,
1966        > {
1967            self.inner
1968                .ready()
1969                .await
1970                .map_err(|e| {
1971                    tonic::Status::unknown(
1972                        format!("Service was not ready: {}", e.into()),
1973                    )
1974                })?;
1975            let codec = tonic::codec::ProstCodec::default();
1976            let path = http::uri::PathAndQuery::from_static(
1977                "/penumbra.core.component.dex.v1.QueryService/BatchSwapOutputData",
1978            );
1979            let mut req = request.into_request();
1980            req.extensions_mut()
1981                .insert(
1982                    GrpcMethod::new(
1983                        "penumbra.core.component.dex.v1.QueryService",
1984                        "BatchSwapOutputData",
1985                    ),
1986                );
1987            self.inner.unary(req, path, codec).await
1988        }
1989        /// Get the precise swap execution used for a specific batch swap.
1990        pub async fn swap_execution(
1991            &mut self,
1992            request: impl tonic::IntoRequest<super::SwapExecutionRequest>,
1993        ) -> std::result::Result<
1994            tonic::Response<super::SwapExecutionResponse>,
1995            tonic::Status,
1996        > {
1997            self.inner
1998                .ready()
1999                .await
2000                .map_err(|e| {
2001                    tonic::Status::unknown(
2002                        format!("Service was not ready: {}", e.into()),
2003                    )
2004                })?;
2005            let codec = tonic::codec::ProstCodec::default();
2006            let path = http::uri::PathAndQuery::from_static(
2007                "/penumbra.core.component.dex.v1.QueryService/SwapExecution",
2008            );
2009            let mut req = request.into_request();
2010            req.extensions_mut()
2011                .insert(
2012                    GrpcMethod::new(
2013                        "penumbra.core.component.dex.v1.QueryService",
2014                        "SwapExecution",
2015                    ),
2016                );
2017            self.inner.unary(req, path, codec).await
2018        }
2019        /// Get the precise execution used to perform on-chain arbitrage.
2020        pub async fn arb_execution(
2021            &mut self,
2022            request: impl tonic::IntoRequest<super::ArbExecutionRequest>,
2023        ) -> std::result::Result<
2024            tonic::Response<super::ArbExecutionResponse>,
2025            tonic::Status,
2026        > {
2027            self.inner
2028                .ready()
2029                .await
2030                .map_err(|e| {
2031                    tonic::Status::unknown(
2032                        format!("Service was not ready: {}", e.into()),
2033                    )
2034                })?;
2035            let codec = tonic::codec::ProstCodec::default();
2036            let path = http::uri::PathAndQuery::from_static(
2037                "/penumbra.core.component.dex.v1.QueryService/ArbExecution",
2038            );
2039            let mut req = request.into_request();
2040            req.extensions_mut()
2041                .insert(
2042                    GrpcMethod::new(
2043                        "penumbra.core.component.dex.v1.QueryService",
2044                        "ArbExecution",
2045                    ),
2046                );
2047            self.inner.unary(req, path, codec).await
2048        }
2049        /// Stream all swap executions over a range of heights, optionally subscribing to future executions.
2050        pub async fn swap_executions(
2051            &mut self,
2052            request: impl tonic::IntoRequest<super::SwapExecutionsRequest>,
2053        ) -> std::result::Result<
2054            tonic::Response<tonic::codec::Streaming<super::SwapExecutionsResponse>>,
2055            tonic::Status,
2056        > {
2057            self.inner
2058                .ready()
2059                .await
2060                .map_err(|e| {
2061                    tonic::Status::unknown(
2062                        format!("Service was not ready: {}", e.into()),
2063                    )
2064                })?;
2065            let codec = tonic::codec::ProstCodec::default();
2066            let path = http::uri::PathAndQuery::from_static(
2067                "/penumbra.core.component.dex.v1.QueryService/SwapExecutions",
2068            );
2069            let mut req = request.into_request();
2070            req.extensions_mut()
2071                .insert(
2072                    GrpcMethod::new(
2073                        "penumbra.core.component.dex.v1.QueryService",
2074                        "SwapExecutions",
2075                    ),
2076                );
2077            self.inner.server_streaming(req, path, codec).await
2078        }
2079        /// Stream all arbitrage executions over a range of heights, optionally subscribing to future executions.
2080        pub async fn arb_executions(
2081            &mut self,
2082            request: impl tonic::IntoRequest<super::ArbExecutionsRequest>,
2083        ) -> std::result::Result<
2084            tonic::Response<tonic::codec::Streaming<super::ArbExecutionsResponse>>,
2085            tonic::Status,
2086        > {
2087            self.inner
2088                .ready()
2089                .await
2090                .map_err(|e| {
2091                    tonic::Status::unknown(
2092                        format!("Service was not ready: {}", e.into()),
2093                    )
2094                })?;
2095            let codec = tonic::codec::ProstCodec::default();
2096            let path = http::uri::PathAndQuery::from_static(
2097                "/penumbra.core.component.dex.v1.QueryService/ArbExecutions",
2098            );
2099            let mut req = request.into_request();
2100            req.extensions_mut()
2101                .insert(
2102                    GrpcMethod::new(
2103                        "penumbra.core.component.dex.v1.QueryService",
2104                        "ArbExecutions",
2105                    ),
2106                );
2107            self.inner.server_streaming(req, path, codec).await
2108        }
2109        /// Query all liquidity positions on the DEX.
2110        pub async fn liquidity_positions(
2111            &mut self,
2112            request: impl tonic::IntoRequest<super::LiquidityPositionsRequest>,
2113        ) -> std::result::Result<
2114            tonic::Response<tonic::codec::Streaming<super::LiquidityPositionsResponse>>,
2115            tonic::Status,
2116        > {
2117            self.inner
2118                .ready()
2119                .await
2120                .map_err(|e| {
2121                    tonic::Status::unknown(
2122                        format!("Service was not ready: {}", e.into()),
2123                    )
2124                })?;
2125            let codec = tonic::codec::ProstCodec::default();
2126            let path = http::uri::PathAndQuery::from_static(
2127                "/penumbra.core.component.dex.v1.QueryService/LiquidityPositions",
2128            );
2129            let mut req = request.into_request();
2130            req.extensions_mut()
2131                .insert(
2132                    GrpcMethod::new(
2133                        "penumbra.core.component.dex.v1.QueryService",
2134                        "LiquidityPositions",
2135                    ),
2136                );
2137            self.inner.server_streaming(req, path, codec).await
2138        }
2139        /// Query liquidity positions by ID.
2140        ///
2141        /// To get multiple positions, use `LiquidityPositionsById`.
2142        pub async fn liquidity_position_by_id(
2143            &mut self,
2144            request: impl tonic::IntoRequest<super::LiquidityPositionByIdRequest>,
2145        ) -> std::result::Result<
2146            tonic::Response<super::LiquidityPositionByIdResponse>,
2147            tonic::Status,
2148        > {
2149            self.inner
2150                .ready()
2151                .await
2152                .map_err(|e| {
2153                    tonic::Status::unknown(
2154                        format!("Service was not ready: {}", e.into()),
2155                    )
2156                })?;
2157            let codec = tonic::codec::ProstCodec::default();
2158            let path = http::uri::PathAndQuery::from_static(
2159                "/penumbra.core.component.dex.v1.QueryService/LiquidityPositionById",
2160            );
2161            let mut req = request.into_request();
2162            req.extensions_mut()
2163                .insert(
2164                    GrpcMethod::new(
2165                        "penumbra.core.component.dex.v1.QueryService",
2166                        "LiquidityPositionById",
2167                    ),
2168                );
2169            self.inner.unary(req, path, codec).await
2170        }
2171        /// Query multiple liquidity positions by ID.
2172        pub async fn liquidity_positions_by_id(
2173            &mut self,
2174            request: impl tonic::IntoRequest<super::LiquidityPositionsByIdRequest>,
2175        ) -> std::result::Result<
2176            tonic::Response<
2177                tonic::codec::Streaming<super::LiquidityPositionsByIdResponse>,
2178            >,
2179            tonic::Status,
2180        > {
2181            self.inner
2182                .ready()
2183                .await
2184                .map_err(|e| {
2185                    tonic::Status::unknown(
2186                        format!("Service was not ready: {}", e.into()),
2187                    )
2188                })?;
2189            let codec = tonic::codec::ProstCodec::default();
2190            let path = http::uri::PathAndQuery::from_static(
2191                "/penumbra.core.component.dex.v1.QueryService/LiquidityPositionsById",
2192            );
2193            let mut req = request.into_request();
2194            req.extensions_mut()
2195                .insert(
2196                    GrpcMethod::new(
2197                        "penumbra.core.component.dex.v1.QueryService",
2198                        "LiquidityPositionsById",
2199                    ),
2200                );
2201            self.inner.server_streaming(req, path, codec).await
2202        }
2203        /// Query liquidity positions on a specific pair, sorted by effective price.
2204        pub async fn liquidity_positions_by_price(
2205            &mut self,
2206            request: impl tonic::IntoRequest<super::LiquidityPositionsByPriceRequest>,
2207        ) -> std::result::Result<
2208            tonic::Response<
2209                tonic::codec::Streaming<super::LiquidityPositionsByPriceResponse>,
2210            >,
2211            tonic::Status,
2212        > {
2213            self.inner
2214                .ready()
2215                .await
2216                .map_err(|e| {
2217                    tonic::Status::unknown(
2218                        format!("Service was not ready: {}", e.into()),
2219                    )
2220                })?;
2221            let codec = tonic::codec::ProstCodec::default();
2222            let path = http::uri::PathAndQuery::from_static(
2223                "/penumbra.core.component.dex.v1.QueryService/LiquidityPositionsByPrice",
2224            );
2225            let mut req = request.into_request();
2226            req.extensions_mut()
2227                .insert(
2228                    GrpcMethod::new(
2229                        "penumbra.core.component.dex.v1.QueryService",
2230                        "LiquidityPositionsByPrice",
2231                    ),
2232                );
2233            self.inner.server_streaming(req, path, codec).await
2234        }
2235        /// Get the current (direct) spread on a trading pair.
2236        ///
2237        /// This method doesn't do simulation, so actually executing might result in a
2238        /// better price (if the chain takes a different route to the target asset).
2239        pub async fn spread(
2240            &mut self,
2241            request: impl tonic::IntoRequest<super::SpreadRequest>,
2242        ) -> std::result::Result<tonic::Response<super::SpreadResponse>, tonic::Status> {
2243            self.inner
2244                .ready()
2245                .await
2246                .map_err(|e| {
2247                    tonic::Status::unknown(
2248                        format!("Service was not ready: {}", e.into()),
2249                    )
2250                })?;
2251            let codec = tonic::codec::ProstCodec::default();
2252            let path = http::uri::PathAndQuery::from_static(
2253                "/penumbra.core.component.dex.v1.QueryService/Spread",
2254            );
2255            let mut req = request.into_request();
2256            req.extensions_mut()
2257                .insert(
2258                    GrpcMethod::new(
2259                        "penumbra.core.component.dex.v1.QueryService",
2260                        "Spread",
2261                    ),
2262                );
2263            self.inner.unary(req, path, codec).await
2264        }
2265        /// Get historical candlestick data for a given trading pair.
2266        ///
2267        /// Note that this RPC is directional, to get data for both directions, make a second request.
2268        pub async fn candlestick_data(
2269            &mut self,
2270            request: impl tonic::IntoRequest<super::CandlestickDataRequest>,
2271        ) -> std::result::Result<
2272            tonic::Response<super::CandlestickDataResponse>,
2273            tonic::Status,
2274        > {
2275            self.inner
2276                .ready()
2277                .await
2278                .map_err(|e| {
2279                    tonic::Status::unknown(
2280                        format!("Service was not ready: {}", e.into()),
2281                    )
2282                })?;
2283            let codec = tonic::codec::ProstCodec::default();
2284            let path = http::uri::PathAndQuery::from_static(
2285                "/penumbra.core.component.dex.v1.QueryService/CandlestickData",
2286            );
2287            let mut req = request.into_request();
2288            req.extensions_mut()
2289                .insert(
2290                    GrpcMethod::new(
2291                        "penumbra.core.component.dex.v1.QueryService",
2292                        "CandlestickData",
2293                    ),
2294                );
2295            self.inner.unary(req, path, codec).await
2296        }
2297        /// Subscribe to candlestick data updates.
2298        pub async fn candlestick_data_stream(
2299            &mut self,
2300            request: impl tonic::IntoRequest<super::CandlestickDataStreamRequest>,
2301        ) -> std::result::Result<
2302            tonic::Response<
2303                tonic::codec::Streaming<super::CandlestickDataStreamResponse>,
2304            >,
2305            tonic::Status,
2306        > {
2307            self.inner
2308                .ready()
2309                .await
2310                .map_err(|e| {
2311                    tonic::Status::unknown(
2312                        format!("Service was not ready: {}", e.into()),
2313                    )
2314                })?;
2315            let codec = tonic::codec::ProstCodec::default();
2316            let path = http::uri::PathAndQuery::from_static(
2317                "/penumbra.core.component.dex.v1.QueryService/CandlestickDataStream",
2318            );
2319            let mut req = request.into_request();
2320            req.extensions_mut()
2321                .insert(
2322                    GrpcMethod::new(
2323                        "penumbra.core.component.dex.v1.QueryService",
2324                        "CandlestickDataStream",
2325                    ),
2326                );
2327            self.inner.server_streaming(req, path, codec).await
2328        }
2329    }
2330}
2331/// Generated client implementations.
2332#[cfg(feature = "rpc")]
2333pub mod simulation_service_client {
2334    #![allow(
2335        unused_variables,
2336        dead_code,
2337        missing_docs,
2338        clippy::wildcard_imports,
2339        clippy::let_unit_value,
2340    )]
2341    use tonic::codegen::*;
2342    use tonic::codegen::http::Uri;
2343    /// Simulation for the DEX component.
2344    ///
2345    /// This is a separate service from the QueryService because it's not just a
2346    /// simple read query from the state. Thus it poses greater DoS risks, and node
2347    /// operators may want to enable it separately.
2348    #[derive(Debug, Clone)]
2349    pub struct SimulationServiceClient<T> {
2350        inner: tonic::client::Grpc<T>,
2351    }
2352    impl SimulationServiceClient<tonic::transport::Channel> {
2353        /// Attempt to create a new client by connecting to a given endpoint.
2354        pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error>
2355        where
2356            D: TryInto<tonic::transport::Endpoint>,
2357            D::Error: Into<StdError>,
2358        {
2359            let conn = tonic::transport::Endpoint::new(dst)?.connect().await?;
2360            Ok(Self::new(conn))
2361        }
2362    }
2363    impl<T> SimulationServiceClient<T>
2364    where
2365        T: tonic::client::GrpcService<tonic::body::BoxBody>,
2366        T::Error: Into<StdError>,
2367        T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static,
2368        <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send,
2369    {
2370        pub fn new(inner: T) -> Self {
2371            let inner = tonic::client::Grpc::new(inner);
2372            Self { inner }
2373        }
2374        pub fn with_origin(inner: T, origin: Uri) -> Self {
2375            let inner = tonic::client::Grpc::with_origin(inner, origin);
2376            Self { inner }
2377        }
2378        pub fn with_interceptor<F>(
2379            inner: T,
2380            interceptor: F,
2381        ) -> SimulationServiceClient<InterceptedService<T, F>>
2382        where
2383            F: tonic::service::Interceptor,
2384            T::ResponseBody: Default,
2385            T: tonic::codegen::Service<
2386                http::Request<tonic::body::BoxBody>,
2387                Response = http::Response<
2388                    <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody,
2389                >,
2390            >,
2391            <T as tonic::codegen::Service<
2392                http::Request<tonic::body::BoxBody>,
2393            >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync,
2394        {
2395            SimulationServiceClient::new(InterceptedService::new(inner, interceptor))
2396        }
2397        /// Compress requests with the given encoding.
2398        ///
2399        /// This requires the server to support it otherwise it might respond with an
2400        /// error.
2401        #[must_use]
2402        pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {
2403            self.inner = self.inner.send_compressed(encoding);
2404            self
2405        }
2406        /// Enable decompressing responses.
2407        #[must_use]
2408        pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {
2409            self.inner = self.inner.accept_compressed(encoding);
2410            self
2411        }
2412        /// Limits the maximum size of a decoded message.
2413        ///
2414        /// Default: `4MB`
2415        #[must_use]
2416        pub fn max_decoding_message_size(mut self, limit: usize) -> Self {
2417            self.inner = self.inner.max_decoding_message_size(limit);
2418            self
2419        }
2420        /// Limits the maximum size of an encoded message.
2421        ///
2422        /// Default: `usize::MAX`
2423        #[must_use]
2424        pub fn max_encoding_message_size(mut self, limit: usize) -> Self {
2425            self.inner = self.inner.max_encoding_message_size(limit);
2426            self
2427        }
2428        /// Simulate routing and trade execution.
2429        pub async fn simulate_trade(
2430            &mut self,
2431            request: impl tonic::IntoRequest<super::SimulateTradeRequest>,
2432        ) -> std::result::Result<
2433            tonic::Response<super::SimulateTradeResponse>,
2434            tonic::Status,
2435        > {
2436            self.inner
2437                .ready()
2438                .await
2439                .map_err(|e| {
2440                    tonic::Status::unknown(
2441                        format!("Service was not ready: {}", e.into()),
2442                    )
2443                })?;
2444            let codec = tonic::codec::ProstCodec::default();
2445            let path = http::uri::PathAndQuery::from_static(
2446                "/penumbra.core.component.dex.v1.SimulationService/SimulateTrade",
2447            );
2448            let mut req = request.into_request();
2449            req.extensions_mut()
2450                .insert(
2451                    GrpcMethod::new(
2452                        "penumbra.core.component.dex.v1.SimulationService",
2453                        "SimulateTrade",
2454                    ),
2455                );
2456            self.inner.unary(req, path, codec).await
2457        }
2458    }
2459}
2460/// Generated server implementations.
2461#[cfg(feature = "rpc")]
2462pub mod query_service_server {
2463    #![allow(
2464        unused_variables,
2465        dead_code,
2466        missing_docs,
2467        clippy::wildcard_imports,
2468        clippy::let_unit_value,
2469    )]
2470    use tonic::codegen::*;
2471    /// Generated trait containing gRPC methods that should be implemented for use with QueryServiceServer.
2472    #[async_trait]
2473    pub trait QueryService: std::marker::Send + std::marker::Sync + 'static {
2474        /// Get the batch clearing prices for a specific block height and trading pair.
2475        async fn batch_swap_output_data(
2476            &self,
2477            request: tonic::Request<super::BatchSwapOutputDataRequest>,
2478        ) -> std::result::Result<
2479            tonic::Response<super::BatchSwapOutputDataResponse>,
2480            tonic::Status,
2481        >;
2482        /// Get the precise swap execution used for a specific batch swap.
2483        async fn swap_execution(
2484            &self,
2485            request: tonic::Request<super::SwapExecutionRequest>,
2486        ) -> std::result::Result<
2487            tonic::Response<super::SwapExecutionResponse>,
2488            tonic::Status,
2489        >;
2490        /// Get the precise execution used to perform on-chain arbitrage.
2491        async fn arb_execution(
2492            &self,
2493            request: tonic::Request<super::ArbExecutionRequest>,
2494        ) -> std::result::Result<
2495            tonic::Response<super::ArbExecutionResponse>,
2496            tonic::Status,
2497        >;
2498        /// Server streaming response type for the SwapExecutions method.
2499        type SwapExecutionsStream: tonic::codegen::tokio_stream::Stream<
2500                Item = std::result::Result<super::SwapExecutionsResponse, tonic::Status>,
2501            >
2502            + std::marker::Send
2503            + 'static;
2504        /// Stream all swap executions over a range of heights, optionally subscribing to future executions.
2505        async fn swap_executions(
2506            &self,
2507            request: tonic::Request<super::SwapExecutionsRequest>,
2508        ) -> std::result::Result<
2509            tonic::Response<Self::SwapExecutionsStream>,
2510            tonic::Status,
2511        >;
2512        /// Server streaming response type for the ArbExecutions method.
2513        type ArbExecutionsStream: tonic::codegen::tokio_stream::Stream<
2514                Item = std::result::Result<super::ArbExecutionsResponse, tonic::Status>,
2515            >
2516            + std::marker::Send
2517            + 'static;
2518        /// Stream all arbitrage executions over a range of heights, optionally subscribing to future executions.
2519        async fn arb_executions(
2520            &self,
2521            request: tonic::Request<super::ArbExecutionsRequest>,
2522        ) -> std::result::Result<
2523            tonic::Response<Self::ArbExecutionsStream>,
2524            tonic::Status,
2525        >;
2526        /// Server streaming response type for the LiquidityPositions method.
2527        type LiquidityPositionsStream: tonic::codegen::tokio_stream::Stream<
2528                Item = std::result::Result<
2529                    super::LiquidityPositionsResponse,
2530                    tonic::Status,
2531                >,
2532            >
2533            + std::marker::Send
2534            + 'static;
2535        /// Query all liquidity positions on the DEX.
2536        async fn liquidity_positions(
2537            &self,
2538            request: tonic::Request<super::LiquidityPositionsRequest>,
2539        ) -> std::result::Result<
2540            tonic::Response<Self::LiquidityPositionsStream>,
2541            tonic::Status,
2542        >;
2543        /// Query liquidity positions by ID.
2544        ///
2545        /// To get multiple positions, use `LiquidityPositionsById`.
2546        async fn liquidity_position_by_id(
2547            &self,
2548            request: tonic::Request<super::LiquidityPositionByIdRequest>,
2549        ) -> std::result::Result<
2550            tonic::Response<super::LiquidityPositionByIdResponse>,
2551            tonic::Status,
2552        >;
2553        /// Server streaming response type for the LiquidityPositionsById method.
2554        type LiquidityPositionsByIdStream: tonic::codegen::tokio_stream::Stream<
2555                Item = std::result::Result<
2556                    super::LiquidityPositionsByIdResponse,
2557                    tonic::Status,
2558                >,
2559            >
2560            + std::marker::Send
2561            + 'static;
2562        /// Query multiple liquidity positions by ID.
2563        async fn liquidity_positions_by_id(
2564            &self,
2565            request: tonic::Request<super::LiquidityPositionsByIdRequest>,
2566        ) -> std::result::Result<
2567            tonic::Response<Self::LiquidityPositionsByIdStream>,
2568            tonic::Status,
2569        >;
2570        /// Server streaming response type for the LiquidityPositionsByPrice method.
2571        type LiquidityPositionsByPriceStream: tonic::codegen::tokio_stream::Stream<
2572                Item = std::result::Result<
2573                    super::LiquidityPositionsByPriceResponse,
2574                    tonic::Status,
2575                >,
2576            >
2577            + std::marker::Send
2578            + 'static;
2579        /// Query liquidity positions on a specific pair, sorted by effective price.
2580        async fn liquidity_positions_by_price(
2581            &self,
2582            request: tonic::Request<super::LiquidityPositionsByPriceRequest>,
2583        ) -> std::result::Result<
2584            tonic::Response<Self::LiquidityPositionsByPriceStream>,
2585            tonic::Status,
2586        >;
2587        /// Get the current (direct) spread on a trading pair.
2588        ///
2589        /// This method doesn't do simulation, so actually executing might result in a
2590        /// better price (if the chain takes a different route to the target asset).
2591        async fn spread(
2592            &self,
2593            request: tonic::Request<super::SpreadRequest>,
2594        ) -> std::result::Result<tonic::Response<super::SpreadResponse>, tonic::Status>;
2595        /// Get historical candlestick data for a given trading pair.
2596        ///
2597        /// Note that this RPC is directional, to get data for both directions, make a second request.
2598        async fn candlestick_data(
2599            &self,
2600            request: tonic::Request<super::CandlestickDataRequest>,
2601        ) -> std::result::Result<
2602            tonic::Response<super::CandlestickDataResponse>,
2603            tonic::Status,
2604        >;
2605        /// Server streaming response type for the CandlestickDataStream method.
2606        type CandlestickDataStreamStream: tonic::codegen::tokio_stream::Stream<
2607                Item = std::result::Result<
2608                    super::CandlestickDataStreamResponse,
2609                    tonic::Status,
2610                >,
2611            >
2612            + std::marker::Send
2613            + 'static;
2614        /// Subscribe to candlestick data updates.
2615        async fn candlestick_data_stream(
2616            &self,
2617            request: tonic::Request<super::CandlestickDataStreamRequest>,
2618        ) -> std::result::Result<
2619            tonic::Response<Self::CandlestickDataStreamStream>,
2620            tonic::Status,
2621        >;
2622    }
2623    /// Query operations for the DEX component.
2624    #[derive(Debug)]
2625    pub struct QueryServiceServer<T> {
2626        inner: Arc<T>,
2627        accept_compression_encodings: EnabledCompressionEncodings,
2628        send_compression_encodings: EnabledCompressionEncodings,
2629        max_decoding_message_size: Option<usize>,
2630        max_encoding_message_size: Option<usize>,
2631    }
2632    impl<T> QueryServiceServer<T> {
2633        pub fn new(inner: T) -> Self {
2634            Self::from_arc(Arc::new(inner))
2635        }
2636        pub fn from_arc(inner: Arc<T>) -> Self {
2637            Self {
2638                inner,
2639                accept_compression_encodings: Default::default(),
2640                send_compression_encodings: Default::default(),
2641                max_decoding_message_size: None,
2642                max_encoding_message_size: None,
2643            }
2644        }
2645        pub fn with_interceptor<F>(
2646            inner: T,
2647            interceptor: F,
2648        ) -> InterceptedService<Self, F>
2649        where
2650            F: tonic::service::Interceptor,
2651        {
2652            InterceptedService::new(Self::new(inner), interceptor)
2653        }
2654        /// Enable decompressing requests with the given encoding.
2655        #[must_use]
2656        pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {
2657            self.accept_compression_encodings.enable(encoding);
2658            self
2659        }
2660        /// Compress responses with the given encoding, if the client supports it.
2661        #[must_use]
2662        pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {
2663            self.send_compression_encodings.enable(encoding);
2664            self
2665        }
2666        /// Limits the maximum size of a decoded message.
2667        ///
2668        /// Default: `4MB`
2669        #[must_use]
2670        pub fn max_decoding_message_size(mut self, limit: usize) -> Self {
2671            self.max_decoding_message_size = Some(limit);
2672            self
2673        }
2674        /// Limits the maximum size of an encoded message.
2675        ///
2676        /// Default: `usize::MAX`
2677        #[must_use]
2678        pub fn max_encoding_message_size(mut self, limit: usize) -> Self {
2679            self.max_encoding_message_size = Some(limit);
2680            self
2681        }
2682    }
2683    impl<T, B> tonic::codegen::Service<http::Request<B>> for QueryServiceServer<T>
2684    where
2685        T: QueryService,
2686        B: Body + std::marker::Send + 'static,
2687        B::Error: Into<StdError> + std::marker::Send + 'static,
2688    {
2689        type Response = http::Response<tonic::body::BoxBody>;
2690        type Error = std::convert::Infallible;
2691        type Future = BoxFuture<Self::Response, Self::Error>;
2692        fn poll_ready(
2693            &mut self,
2694            _cx: &mut Context<'_>,
2695        ) -> Poll<std::result::Result<(), Self::Error>> {
2696            Poll::Ready(Ok(()))
2697        }
2698        fn call(&mut self, req: http::Request<B>) -> Self::Future {
2699            match req.uri().path() {
2700                "/penumbra.core.component.dex.v1.QueryService/BatchSwapOutputData" => {
2701                    #[allow(non_camel_case_types)]
2702                    struct BatchSwapOutputDataSvc<T: QueryService>(pub Arc<T>);
2703                    impl<
2704                        T: QueryService,
2705                    > tonic::server::UnaryService<super::BatchSwapOutputDataRequest>
2706                    for BatchSwapOutputDataSvc<T> {
2707                        type Response = super::BatchSwapOutputDataResponse;
2708                        type Future = BoxFuture<
2709                            tonic::Response<Self::Response>,
2710                            tonic::Status,
2711                        >;
2712                        fn call(
2713                            &mut self,
2714                            request: tonic::Request<super::BatchSwapOutputDataRequest>,
2715                        ) -> Self::Future {
2716                            let inner = Arc::clone(&self.0);
2717                            let fut = async move {
2718                                <T as QueryService>::batch_swap_output_data(&inner, request)
2719                                    .await
2720                            };
2721                            Box::pin(fut)
2722                        }
2723                    }
2724                    let accept_compression_encodings = self.accept_compression_encodings;
2725                    let send_compression_encodings = self.send_compression_encodings;
2726                    let max_decoding_message_size = self.max_decoding_message_size;
2727                    let max_encoding_message_size = self.max_encoding_message_size;
2728                    let inner = self.inner.clone();
2729                    let fut = async move {
2730                        let method = BatchSwapOutputDataSvc(inner);
2731                        let codec = tonic::codec::ProstCodec::default();
2732                        let mut grpc = tonic::server::Grpc::new(codec)
2733                            .apply_compression_config(
2734                                accept_compression_encodings,
2735                                send_compression_encodings,
2736                            )
2737                            .apply_max_message_size_config(
2738                                max_decoding_message_size,
2739                                max_encoding_message_size,
2740                            );
2741                        let res = grpc.unary(method, req).await;
2742                        Ok(res)
2743                    };
2744                    Box::pin(fut)
2745                }
2746                "/penumbra.core.component.dex.v1.QueryService/SwapExecution" => {
2747                    #[allow(non_camel_case_types)]
2748                    struct SwapExecutionSvc<T: QueryService>(pub Arc<T>);
2749                    impl<
2750                        T: QueryService,
2751                    > tonic::server::UnaryService<super::SwapExecutionRequest>
2752                    for SwapExecutionSvc<T> {
2753                        type Response = super::SwapExecutionResponse;
2754                        type Future = BoxFuture<
2755                            tonic::Response<Self::Response>,
2756                            tonic::Status,
2757                        >;
2758                        fn call(
2759                            &mut self,
2760                            request: tonic::Request<super::SwapExecutionRequest>,
2761                        ) -> Self::Future {
2762                            let inner = Arc::clone(&self.0);
2763                            let fut = async move {
2764                                <T as QueryService>::swap_execution(&inner, request).await
2765                            };
2766                            Box::pin(fut)
2767                        }
2768                    }
2769                    let accept_compression_encodings = self.accept_compression_encodings;
2770                    let send_compression_encodings = self.send_compression_encodings;
2771                    let max_decoding_message_size = self.max_decoding_message_size;
2772                    let max_encoding_message_size = self.max_encoding_message_size;
2773                    let inner = self.inner.clone();
2774                    let fut = async move {
2775                        let method = SwapExecutionSvc(inner);
2776                        let codec = tonic::codec::ProstCodec::default();
2777                        let mut grpc = tonic::server::Grpc::new(codec)
2778                            .apply_compression_config(
2779                                accept_compression_encodings,
2780                                send_compression_encodings,
2781                            )
2782                            .apply_max_message_size_config(
2783                                max_decoding_message_size,
2784                                max_encoding_message_size,
2785                            );
2786                        let res = grpc.unary(method, req).await;
2787                        Ok(res)
2788                    };
2789                    Box::pin(fut)
2790                }
2791                "/penumbra.core.component.dex.v1.QueryService/ArbExecution" => {
2792                    #[allow(non_camel_case_types)]
2793                    struct ArbExecutionSvc<T: QueryService>(pub Arc<T>);
2794                    impl<
2795                        T: QueryService,
2796                    > tonic::server::UnaryService<super::ArbExecutionRequest>
2797                    for ArbExecutionSvc<T> {
2798                        type Response = super::ArbExecutionResponse;
2799                        type Future = BoxFuture<
2800                            tonic::Response<Self::Response>,
2801                            tonic::Status,
2802                        >;
2803                        fn call(
2804                            &mut self,
2805                            request: tonic::Request<super::ArbExecutionRequest>,
2806                        ) -> Self::Future {
2807                            let inner = Arc::clone(&self.0);
2808                            let fut = async move {
2809                                <T as QueryService>::arb_execution(&inner, request).await
2810                            };
2811                            Box::pin(fut)
2812                        }
2813                    }
2814                    let accept_compression_encodings = self.accept_compression_encodings;
2815                    let send_compression_encodings = self.send_compression_encodings;
2816                    let max_decoding_message_size = self.max_decoding_message_size;
2817                    let max_encoding_message_size = self.max_encoding_message_size;
2818                    let inner = self.inner.clone();
2819                    let fut = async move {
2820                        let method = ArbExecutionSvc(inner);
2821                        let codec = tonic::codec::ProstCodec::default();
2822                        let mut grpc = tonic::server::Grpc::new(codec)
2823                            .apply_compression_config(
2824                                accept_compression_encodings,
2825                                send_compression_encodings,
2826                            )
2827                            .apply_max_message_size_config(
2828                                max_decoding_message_size,
2829                                max_encoding_message_size,
2830                            );
2831                        let res = grpc.unary(method, req).await;
2832                        Ok(res)
2833                    };
2834                    Box::pin(fut)
2835                }
2836                "/penumbra.core.component.dex.v1.QueryService/SwapExecutions" => {
2837                    #[allow(non_camel_case_types)]
2838                    struct SwapExecutionsSvc<T: QueryService>(pub Arc<T>);
2839                    impl<
2840                        T: QueryService,
2841                    > tonic::server::ServerStreamingService<super::SwapExecutionsRequest>
2842                    for SwapExecutionsSvc<T> {
2843                        type Response = super::SwapExecutionsResponse;
2844                        type ResponseStream = T::SwapExecutionsStream;
2845                        type Future = BoxFuture<
2846                            tonic::Response<Self::ResponseStream>,
2847                            tonic::Status,
2848                        >;
2849                        fn call(
2850                            &mut self,
2851                            request: tonic::Request<super::SwapExecutionsRequest>,
2852                        ) -> Self::Future {
2853                            let inner = Arc::clone(&self.0);
2854                            let fut = async move {
2855                                <T as QueryService>::swap_executions(&inner, request).await
2856                            };
2857                            Box::pin(fut)
2858                        }
2859                    }
2860                    let accept_compression_encodings = self.accept_compression_encodings;
2861                    let send_compression_encodings = self.send_compression_encodings;
2862                    let max_decoding_message_size = self.max_decoding_message_size;
2863                    let max_encoding_message_size = self.max_encoding_message_size;
2864                    let inner = self.inner.clone();
2865                    let fut = async move {
2866                        let method = SwapExecutionsSvc(inner);
2867                        let codec = tonic::codec::ProstCodec::default();
2868                        let mut grpc = tonic::server::Grpc::new(codec)
2869                            .apply_compression_config(
2870                                accept_compression_encodings,
2871                                send_compression_encodings,
2872                            )
2873                            .apply_max_message_size_config(
2874                                max_decoding_message_size,
2875                                max_encoding_message_size,
2876                            );
2877                        let res = grpc.server_streaming(method, req).await;
2878                        Ok(res)
2879                    };
2880                    Box::pin(fut)
2881                }
2882                "/penumbra.core.component.dex.v1.QueryService/ArbExecutions" => {
2883                    #[allow(non_camel_case_types)]
2884                    struct ArbExecutionsSvc<T: QueryService>(pub Arc<T>);
2885                    impl<
2886                        T: QueryService,
2887                    > tonic::server::ServerStreamingService<super::ArbExecutionsRequest>
2888                    for ArbExecutionsSvc<T> {
2889                        type Response = super::ArbExecutionsResponse;
2890                        type ResponseStream = T::ArbExecutionsStream;
2891                        type Future = BoxFuture<
2892                            tonic::Response<Self::ResponseStream>,
2893                            tonic::Status,
2894                        >;
2895                        fn call(
2896                            &mut self,
2897                            request: tonic::Request<super::ArbExecutionsRequest>,
2898                        ) -> Self::Future {
2899                            let inner = Arc::clone(&self.0);
2900                            let fut = async move {
2901                                <T as QueryService>::arb_executions(&inner, request).await
2902                            };
2903                            Box::pin(fut)
2904                        }
2905                    }
2906                    let accept_compression_encodings = self.accept_compression_encodings;
2907                    let send_compression_encodings = self.send_compression_encodings;
2908                    let max_decoding_message_size = self.max_decoding_message_size;
2909                    let max_encoding_message_size = self.max_encoding_message_size;
2910                    let inner = self.inner.clone();
2911                    let fut = async move {
2912                        let method = ArbExecutionsSvc(inner);
2913                        let codec = tonic::codec::ProstCodec::default();
2914                        let mut grpc = tonic::server::Grpc::new(codec)
2915                            .apply_compression_config(
2916                                accept_compression_encodings,
2917                                send_compression_encodings,
2918                            )
2919                            .apply_max_message_size_config(
2920                                max_decoding_message_size,
2921                                max_encoding_message_size,
2922                            );
2923                        let res = grpc.server_streaming(method, req).await;
2924                        Ok(res)
2925                    };
2926                    Box::pin(fut)
2927                }
2928                "/penumbra.core.component.dex.v1.QueryService/LiquidityPositions" => {
2929                    #[allow(non_camel_case_types)]
2930                    struct LiquidityPositionsSvc<T: QueryService>(pub Arc<T>);
2931                    impl<
2932                        T: QueryService,
2933                    > tonic::server::ServerStreamingService<
2934                        super::LiquidityPositionsRequest,
2935                    > for LiquidityPositionsSvc<T> {
2936                        type Response = super::LiquidityPositionsResponse;
2937                        type ResponseStream = T::LiquidityPositionsStream;
2938                        type Future = BoxFuture<
2939                            tonic::Response<Self::ResponseStream>,
2940                            tonic::Status,
2941                        >;
2942                        fn call(
2943                            &mut self,
2944                            request: tonic::Request<super::LiquidityPositionsRequest>,
2945                        ) -> Self::Future {
2946                            let inner = Arc::clone(&self.0);
2947                            let fut = async move {
2948                                <T as QueryService>::liquidity_positions(&inner, request)
2949                                    .await
2950                            };
2951                            Box::pin(fut)
2952                        }
2953                    }
2954                    let accept_compression_encodings = self.accept_compression_encodings;
2955                    let send_compression_encodings = self.send_compression_encodings;
2956                    let max_decoding_message_size = self.max_decoding_message_size;
2957                    let max_encoding_message_size = self.max_encoding_message_size;
2958                    let inner = self.inner.clone();
2959                    let fut = async move {
2960                        let method = LiquidityPositionsSvc(inner);
2961                        let codec = tonic::codec::ProstCodec::default();
2962                        let mut grpc = tonic::server::Grpc::new(codec)
2963                            .apply_compression_config(
2964                                accept_compression_encodings,
2965                                send_compression_encodings,
2966                            )
2967                            .apply_max_message_size_config(
2968                                max_decoding_message_size,
2969                                max_encoding_message_size,
2970                            );
2971                        let res = grpc.server_streaming(method, req).await;
2972                        Ok(res)
2973                    };
2974                    Box::pin(fut)
2975                }
2976                "/penumbra.core.component.dex.v1.QueryService/LiquidityPositionById" => {
2977                    #[allow(non_camel_case_types)]
2978                    struct LiquidityPositionByIdSvc<T: QueryService>(pub Arc<T>);
2979                    impl<
2980                        T: QueryService,
2981                    > tonic::server::UnaryService<super::LiquidityPositionByIdRequest>
2982                    for LiquidityPositionByIdSvc<T> {
2983                        type Response = super::LiquidityPositionByIdResponse;
2984                        type Future = BoxFuture<
2985                            tonic::Response<Self::Response>,
2986                            tonic::Status,
2987                        >;
2988                        fn call(
2989                            &mut self,
2990                            request: tonic::Request<super::LiquidityPositionByIdRequest>,
2991                        ) -> Self::Future {
2992                            let inner = Arc::clone(&self.0);
2993                            let fut = async move {
2994                                <T as QueryService>::liquidity_position_by_id(
2995                                        &inner,
2996                                        request,
2997                                    )
2998                                    .await
2999                            };
3000                            Box::pin(fut)
3001                        }
3002                    }
3003                    let accept_compression_encodings = self.accept_compression_encodings;
3004                    let send_compression_encodings = self.send_compression_encodings;
3005                    let max_decoding_message_size = self.max_decoding_message_size;
3006                    let max_encoding_message_size = self.max_encoding_message_size;
3007                    let inner = self.inner.clone();
3008                    let fut = async move {
3009                        let method = LiquidityPositionByIdSvc(inner);
3010                        let codec = tonic::codec::ProstCodec::default();
3011                        let mut grpc = tonic::server::Grpc::new(codec)
3012                            .apply_compression_config(
3013                                accept_compression_encodings,
3014                                send_compression_encodings,
3015                            )
3016                            .apply_max_message_size_config(
3017                                max_decoding_message_size,
3018                                max_encoding_message_size,
3019                            );
3020                        let res = grpc.unary(method, req).await;
3021                        Ok(res)
3022                    };
3023                    Box::pin(fut)
3024                }
3025                "/penumbra.core.component.dex.v1.QueryService/LiquidityPositionsById" => {
3026                    #[allow(non_camel_case_types)]
3027                    struct LiquidityPositionsByIdSvc<T: QueryService>(pub Arc<T>);
3028                    impl<
3029                        T: QueryService,
3030                    > tonic::server::ServerStreamingService<
3031                        super::LiquidityPositionsByIdRequest,
3032                    > for LiquidityPositionsByIdSvc<T> {
3033                        type Response = super::LiquidityPositionsByIdResponse;
3034                        type ResponseStream = T::LiquidityPositionsByIdStream;
3035                        type Future = BoxFuture<
3036                            tonic::Response<Self::ResponseStream>,
3037                            tonic::Status,
3038                        >;
3039                        fn call(
3040                            &mut self,
3041                            request: tonic::Request<super::LiquidityPositionsByIdRequest>,
3042                        ) -> Self::Future {
3043                            let inner = Arc::clone(&self.0);
3044                            let fut = async move {
3045                                <T as QueryService>::liquidity_positions_by_id(
3046                                        &inner,
3047                                        request,
3048                                    )
3049                                    .await
3050                            };
3051                            Box::pin(fut)
3052                        }
3053                    }
3054                    let accept_compression_encodings = self.accept_compression_encodings;
3055                    let send_compression_encodings = self.send_compression_encodings;
3056                    let max_decoding_message_size = self.max_decoding_message_size;
3057                    let max_encoding_message_size = self.max_encoding_message_size;
3058                    let inner = self.inner.clone();
3059                    let fut = async move {
3060                        let method = LiquidityPositionsByIdSvc(inner);
3061                        let codec = tonic::codec::ProstCodec::default();
3062                        let mut grpc = tonic::server::Grpc::new(codec)
3063                            .apply_compression_config(
3064                                accept_compression_encodings,
3065                                send_compression_encodings,
3066                            )
3067                            .apply_max_message_size_config(
3068                                max_decoding_message_size,
3069                                max_encoding_message_size,
3070                            );
3071                        let res = grpc.server_streaming(method, req).await;
3072                        Ok(res)
3073                    };
3074                    Box::pin(fut)
3075                }
3076                "/penumbra.core.component.dex.v1.QueryService/LiquidityPositionsByPrice" => {
3077                    #[allow(non_camel_case_types)]
3078                    struct LiquidityPositionsByPriceSvc<T: QueryService>(pub Arc<T>);
3079                    impl<
3080                        T: QueryService,
3081                    > tonic::server::ServerStreamingService<
3082                        super::LiquidityPositionsByPriceRequest,
3083                    > for LiquidityPositionsByPriceSvc<T> {
3084                        type Response = super::LiquidityPositionsByPriceResponse;
3085                        type ResponseStream = T::LiquidityPositionsByPriceStream;
3086                        type Future = BoxFuture<
3087                            tonic::Response<Self::ResponseStream>,
3088                            tonic::Status,
3089                        >;
3090                        fn call(
3091                            &mut self,
3092                            request: tonic::Request<
3093                                super::LiquidityPositionsByPriceRequest,
3094                            >,
3095                        ) -> Self::Future {
3096                            let inner = Arc::clone(&self.0);
3097                            let fut = async move {
3098                                <T as QueryService>::liquidity_positions_by_price(
3099                                        &inner,
3100                                        request,
3101                                    )
3102                                    .await
3103                            };
3104                            Box::pin(fut)
3105                        }
3106                    }
3107                    let accept_compression_encodings = self.accept_compression_encodings;
3108                    let send_compression_encodings = self.send_compression_encodings;
3109                    let max_decoding_message_size = self.max_decoding_message_size;
3110                    let max_encoding_message_size = self.max_encoding_message_size;
3111                    let inner = self.inner.clone();
3112                    let fut = async move {
3113                        let method = LiquidityPositionsByPriceSvc(inner);
3114                        let codec = tonic::codec::ProstCodec::default();
3115                        let mut grpc = tonic::server::Grpc::new(codec)
3116                            .apply_compression_config(
3117                                accept_compression_encodings,
3118                                send_compression_encodings,
3119                            )
3120                            .apply_max_message_size_config(
3121                                max_decoding_message_size,
3122                                max_encoding_message_size,
3123                            );
3124                        let res = grpc.server_streaming(method, req).await;
3125                        Ok(res)
3126                    };
3127                    Box::pin(fut)
3128                }
3129                "/penumbra.core.component.dex.v1.QueryService/Spread" => {
3130                    #[allow(non_camel_case_types)]
3131                    struct SpreadSvc<T: QueryService>(pub Arc<T>);
3132                    impl<
3133                        T: QueryService,
3134                    > tonic::server::UnaryService<super::SpreadRequest>
3135                    for SpreadSvc<T> {
3136                        type Response = super::SpreadResponse;
3137                        type Future = BoxFuture<
3138                            tonic::Response<Self::Response>,
3139                            tonic::Status,
3140                        >;
3141                        fn call(
3142                            &mut self,
3143                            request: tonic::Request<super::SpreadRequest>,
3144                        ) -> Self::Future {
3145                            let inner = Arc::clone(&self.0);
3146                            let fut = async move {
3147                                <T as QueryService>::spread(&inner, request).await
3148                            };
3149                            Box::pin(fut)
3150                        }
3151                    }
3152                    let accept_compression_encodings = self.accept_compression_encodings;
3153                    let send_compression_encodings = self.send_compression_encodings;
3154                    let max_decoding_message_size = self.max_decoding_message_size;
3155                    let max_encoding_message_size = self.max_encoding_message_size;
3156                    let inner = self.inner.clone();
3157                    let fut = async move {
3158                        let method = SpreadSvc(inner);
3159                        let codec = tonic::codec::ProstCodec::default();
3160                        let mut grpc = tonic::server::Grpc::new(codec)
3161                            .apply_compression_config(
3162                                accept_compression_encodings,
3163                                send_compression_encodings,
3164                            )
3165                            .apply_max_message_size_config(
3166                                max_decoding_message_size,
3167                                max_encoding_message_size,
3168                            );
3169                        let res = grpc.unary(method, req).await;
3170                        Ok(res)
3171                    };
3172                    Box::pin(fut)
3173                }
3174                "/penumbra.core.component.dex.v1.QueryService/CandlestickData" => {
3175                    #[allow(non_camel_case_types)]
3176                    struct CandlestickDataSvc<T: QueryService>(pub Arc<T>);
3177                    impl<
3178                        T: QueryService,
3179                    > tonic::server::UnaryService<super::CandlestickDataRequest>
3180                    for CandlestickDataSvc<T> {
3181                        type Response = super::CandlestickDataResponse;
3182                        type Future = BoxFuture<
3183                            tonic::Response<Self::Response>,
3184                            tonic::Status,
3185                        >;
3186                        fn call(
3187                            &mut self,
3188                            request: tonic::Request<super::CandlestickDataRequest>,
3189                        ) -> Self::Future {
3190                            let inner = Arc::clone(&self.0);
3191                            let fut = async move {
3192                                <T as QueryService>::candlestick_data(&inner, request).await
3193                            };
3194                            Box::pin(fut)
3195                        }
3196                    }
3197                    let accept_compression_encodings = self.accept_compression_encodings;
3198                    let send_compression_encodings = self.send_compression_encodings;
3199                    let max_decoding_message_size = self.max_decoding_message_size;
3200                    let max_encoding_message_size = self.max_encoding_message_size;
3201                    let inner = self.inner.clone();
3202                    let fut = async move {
3203                        let method = CandlestickDataSvc(inner);
3204                        let codec = tonic::codec::ProstCodec::default();
3205                        let mut grpc = tonic::server::Grpc::new(codec)
3206                            .apply_compression_config(
3207                                accept_compression_encodings,
3208                                send_compression_encodings,
3209                            )
3210                            .apply_max_message_size_config(
3211                                max_decoding_message_size,
3212                                max_encoding_message_size,
3213                            );
3214                        let res = grpc.unary(method, req).await;
3215                        Ok(res)
3216                    };
3217                    Box::pin(fut)
3218                }
3219                "/penumbra.core.component.dex.v1.QueryService/CandlestickDataStream" => {
3220                    #[allow(non_camel_case_types)]
3221                    struct CandlestickDataStreamSvc<T: QueryService>(pub Arc<T>);
3222                    impl<
3223                        T: QueryService,
3224                    > tonic::server::ServerStreamingService<
3225                        super::CandlestickDataStreamRequest,
3226                    > for CandlestickDataStreamSvc<T> {
3227                        type Response = super::CandlestickDataStreamResponse;
3228                        type ResponseStream = T::CandlestickDataStreamStream;
3229                        type Future = BoxFuture<
3230                            tonic::Response<Self::ResponseStream>,
3231                            tonic::Status,
3232                        >;
3233                        fn call(
3234                            &mut self,
3235                            request: tonic::Request<super::CandlestickDataStreamRequest>,
3236                        ) -> Self::Future {
3237                            let inner = Arc::clone(&self.0);
3238                            let fut = async move {
3239                                <T as QueryService>::candlestick_data_stream(
3240                                        &inner,
3241                                        request,
3242                                    )
3243                                    .await
3244                            };
3245                            Box::pin(fut)
3246                        }
3247                    }
3248                    let accept_compression_encodings = self.accept_compression_encodings;
3249                    let send_compression_encodings = self.send_compression_encodings;
3250                    let max_decoding_message_size = self.max_decoding_message_size;
3251                    let max_encoding_message_size = self.max_encoding_message_size;
3252                    let inner = self.inner.clone();
3253                    let fut = async move {
3254                        let method = CandlestickDataStreamSvc(inner);
3255                        let codec = tonic::codec::ProstCodec::default();
3256                        let mut grpc = tonic::server::Grpc::new(codec)
3257                            .apply_compression_config(
3258                                accept_compression_encodings,
3259                                send_compression_encodings,
3260                            )
3261                            .apply_max_message_size_config(
3262                                max_decoding_message_size,
3263                                max_encoding_message_size,
3264                            );
3265                        let res = grpc.server_streaming(method, req).await;
3266                        Ok(res)
3267                    };
3268                    Box::pin(fut)
3269                }
3270                _ => {
3271                    Box::pin(async move {
3272                        let mut response = http::Response::new(empty_body());
3273                        let headers = response.headers_mut();
3274                        headers
3275                            .insert(
3276                                tonic::Status::GRPC_STATUS,
3277                                (tonic::Code::Unimplemented as i32).into(),
3278                            );
3279                        headers
3280                            .insert(
3281                                http::header::CONTENT_TYPE,
3282                                tonic::metadata::GRPC_CONTENT_TYPE,
3283                            );
3284                        Ok(response)
3285                    })
3286                }
3287            }
3288        }
3289    }
3290    impl<T> Clone for QueryServiceServer<T> {
3291        fn clone(&self) -> Self {
3292            let inner = self.inner.clone();
3293            Self {
3294                inner,
3295                accept_compression_encodings: self.accept_compression_encodings,
3296                send_compression_encodings: self.send_compression_encodings,
3297                max_decoding_message_size: self.max_decoding_message_size,
3298                max_encoding_message_size: self.max_encoding_message_size,
3299            }
3300        }
3301    }
3302    /// Generated gRPC service name
3303    pub const SERVICE_NAME: &str = "penumbra.core.component.dex.v1.QueryService";
3304    impl<T> tonic::server::NamedService for QueryServiceServer<T> {
3305        const NAME: &'static str = SERVICE_NAME;
3306    }
3307}
3308/// Generated server implementations.
3309#[cfg(feature = "rpc")]
3310pub mod simulation_service_server {
3311    #![allow(
3312        unused_variables,
3313        dead_code,
3314        missing_docs,
3315        clippy::wildcard_imports,
3316        clippy::let_unit_value,
3317    )]
3318    use tonic::codegen::*;
3319    /// Generated trait containing gRPC methods that should be implemented for use with SimulationServiceServer.
3320    #[async_trait]
3321    pub trait SimulationService: std::marker::Send + std::marker::Sync + 'static {
3322        /// Simulate routing and trade execution.
3323        async fn simulate_trade(
3324            &self,
3325            request: tonic::Request<super::SimulateTradeRequest>,
3326        ) -> std::result::Result<
3327            tonic::Response<super::SimulateTradeResponse>,
3328            tonic::Status,
3329        >;
3330    }
3331    /// Simulation for the DEX component.
3332    ///
3333    /// This is a separate service from the QueryService because it's not just a
3334    /// simple read query from the state. Thus it poses greater DoS risks, and node
3335    /// operators may want to enable it separately.
3336    #[derive(Debug)]
3337    pub struct SimulationServiceServer<T> {
3338        inner: Arc<T>,
3339        accept_compression_encodings: EnabledCompressionEncodings,
3340        send_compression_encodings: EnabledCompressionEncodings,
3341        max_decoding_message_size: Option<usize>,
3342        max_encoding_message_size: Option<usize>,
3343    }
3344    impl<T> SimulationServiceServer<T> {
3345        pub fn new(inner: T) -> Self {
3346            Self::from_arc(Arc::new(inner))
3347        }
3348        pub fn from_arc(inner: Arc<T>) -> Self {
3349            Self {
3350                inner,
3351                accept_compression_encodings: Default::default(),
3352                send_compression_encodings: Default::default(),
3353                max_decoding_message_size: None,
3354                max_encoding_message_size: None,
3355            }
3356        }
3357        pub fn with_interceptor<F>(
3358            inner: T,
3359            interceptor: F,
3360        ) -> InterceptedService<Self, F>
3361        where
3362            F: tonic::service::Interceptor,
3363        {
3364            InterceptedService::new(Self::new(inner), interceptor)
3365        }
3366        /// Enable decompressing requests with the given encoding.
3367        #[must_use]
3368        pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {
3369            self.accept_compression_encodings.enable(encoding);
3370            self
3371        }
3372        /// Compress responses with the given encoding, if the client supports it.
3373        #[must_use]
3374        pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {
3375            self.send_compression_encodings.enable(encoding);
3376            self
3377        }
3378        /// Limits the maximum size of a decoded message.
3379        ///
3380        /// Default: `4MB`
3381        #[must_use]
3382        pub fn max_decoding_message_size(mut self, limit: usize) -> Self {
3383            self.max_decoding_message_size = Some(limit);
3384            self
3385        }
3386        /// Limits the maximum size of an encoded message.
3387        ///
3388        /// Default: `usize::MAX`
3389        #[must_use]
3390        pub fn max_encoding_message_size(mut self, limit: usize) -> Self {
3391            self.max_encoding_message_size = Some(limit);
3392            self
3393        }
3394    }
3395    impl<T, B> tonic::codegen::Service<http::Request<B>> for SimulationServiceServer<T>
3396    where
3397        T: SimulationService,
3398        B: Body + std::marker::Send + 'static,
3399        B::Error: Into<StdError> + std::marker::Send + 'static,
3400    {
3401        type Response = http::Response<tonic::body::BoxBody>;
3402        type Error = std::convert::Infallible;
3403        type Future = BoxFuture<Self::Response, Self::Error>;
3404        fn poll_ready(
3405            &mut self,
3406            _cx: &mut Context<'_>,
3407        ) -> Poll<std::result::Result<(), Self::Error>> {
3408            Poll::Ready(Ok(()))
3409        }
3410        fn call(&mut self, req: http::Request<B>) -> Self::Future {
3411            match req.uri().path() {
3412                "/penumbra.core.component.dex.v1.SimulationService/SimulateTrade" => {
3413                    #[allow(non_camel_case_types)]
3414                    struct SimulateTradeSvc<T: SimulationService>(pub Arc<T>);
3415                    impl<
3416                        T: SimulationService,
3417                    > tonic::server::UnaryService<super::SimulateTradeRequest>
3418                    for SimulateTradeSvc<T> {
3419                        type Response = super::SimulateTradeResponse;
3420                        type Future = BoxFuture<
3421                            tonic::Response<Self::Response>,
3422                            tonic::Status,
3423                        >;
3424                        fn call(
3425                            &mut self,
3426                            request: tonic::Request<super::SimulateTradeRequest>,
3427                        ) -> Self::Future {
3428                            let inner = Arc::clone(&self.0);
3429                            let fut = async move {
3430                                <T as SimulationService>::simulate_trade(&inner, request)
3431                                    .await
3432                            };
3433                            Box::pin(fut)
3434                        }
3435                    }
3436                    let accept_compression_encodings = self.accept_compression_encodings;
3437                    let send_compression_encodings = self.send_compression_encodings;
3438                    let max_decoding_message_size = self.max_decoding_message_size;
3439                    let max_encoding_message_size = self.max_encoding_message_size;
3440                    let inner = self.inner.clone();
3441                    let fut = async move {
3442                        let method = SimulateTradeSvc(inner);
3443                        let codec = tonic::codec::ProstCodec::default();
3444                        let mut grpc = tonic::server::Grpc::new(codec)
3445                            .apply_compression_config(
3446                                accept_compression_encodings,
3447                                send_compression_encodings,
3448                            )
3449                            .apply_max_message_size_config(
3450                                max_decoding_message_size,
3451                                max_encoding_message_size,
3452                            );
3453                        let res = grpc.unary(method, req).await;
3454                        Ok(res)
3455                    };
3456                    Box::pin(fut)
3457                }
3458                _ => {
3459                    Box::pin(async move {
3460                        let mut response = http::Response::new(empty_body());
3461                        let headers = response.headers_mut();
3462                        headers
3463                            .insert(
3464                                tonic::Status::GRPC_STATUS,
3465                                (tonic::Code::Unimplemented as i32).into(),
3466                            );
3467                        headers
3468                            .insert(
3469                                http::header::CONTENT_TYPE,
3470                                tonic::metadata::GRPC_CONTENT_TYPE,
3471                            );
3472                        Ok(response)
3473                    })
3474                }
3475            }
3476        }
3477    }
3478    impl<T> Clone for SimulationServiceServer<T> {
3479        fn clone(&self) -> Self {
3480            let inner = self.inner.clone();
3481            Self {
3482                inner,
3483                accept_compression_encodings: self.accept_compression_encodings,
3484                send_compression_encodings: self.send_compression_encodings,
3485                max_decoding_message_size: self.max_decoding_message_size,
3486                max_encoding_message_size: self.max_encoding_message_size,
3487            }
3488        }
3489    }
3490    /// Generated gRPC service name
3491    pub const SERVICE_NAME: &str = "penumbra.core.component.dex.v1.SimulationService";
3492    impl<T> tonic::server::NamedService for SimulationServiceServer<T> {
3493        const NAME: &'static str = SERVICE_NAME;
3494    }
3495}