odos_sdk/
swap.rs

1// SPDX-FileCopyrightText: 2025 Semiotic AI, Inc.
2//
3// SPDX-License-Identifier: Apache-2.0
4
5use std::fmt::Display;
6
7use alloy_chains::NamedChain;
8use alloy_primitives::{Address, U256};
9use bon::Builder;
10use serde::{Deserialize, Deserializer, Serialize, Serializer};
11
12/// Request for assembling a transaction from a quote
13///
14/// Contains all the information needed to assemble a transaction from
15/// a quote path ID, including signer address, recipient, and routing details.
16#[derive(Builder, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
17pub struct AssemblyRequest {
18    /// The chain of the swap.
19    chain: NamedChain,
20    /// The address of the router.
21    router_address: Address,
22    /// The address of the signer.
23    signer_address: Address,
24    /// The address of the recipient of the output token.
25    output_recipient: Address,
26    /// The address of the token to swap.
27    token_address: Address,
28    /// The amount of tokens to swap.
29    token_amount: U256,
30    /// The path ID of the swap.
31    path_id: String,
32}
33
34impl AssemblyRequest {
35    pub fn chain(&self) -> NamedChain {
36        self.chain
37    }
38
39    pub fn output_recipient(&self) -> Address {
40        self.output_recipient
41    }
42
43    pub fn router_address(&self) -> Address {
44        self.router_address
45    }
46
47    pub fn signer_address(&self) -> Address {
48        self.signer_address
49    }
50
51    pub fn token_address(&self) -> Address {
52        self.token_address
53    }
54
55    pub fn token_amount(&self) -> U256 {
56        self.token_amount
57    }
58
59    pub fn path_id(&self) -> &str {
60        &self.path_id
61    }
62}
63
64impl Serialize for AssemblyRequest {
65    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
66    where
67        S: Serializer,
68    {
69        let chain_id: u64 = self.chain.into();
70        let data = (
71            chain_id,
72            self.router_address,
73            self.signer_address,
74            self.output_recipient,
75            self.token_address,
76            self.token_amount,
77            &self.path_id,
78        );
79        data.serialize(serializer)
80    }
81}
82
83impl<'de> Deserialize<'de> for AssemblyRequest {
84    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
85    where
86        D: Deserializer<'de>,
87    {
88        let (
89            chain_id,
90            router_address,
91            signer_address,
92            output_recipient,
93            token_address,
94            token_amount,
95            path_id,
96        ): (u64, Address, Address, Address, Address, U256, String) =
97            Deserialize::deserialize(deserializer)?;
98
99        let chain = NamedChain::try_from(chain_id).map_err(serde::de::Error::custom)?;
100
101        Ok(Self {
102            chain,
103            router_address,
104            signer_address,
105            output_recipient,
106            token_address,
107            token_amount,
108            path_id,
109        })
110    }
111}
112
113impl Display for AssemblyRequest {
114    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
115        write!(
116            f,
117            "Swap {{ chain: {}, router_address: {}, signer_address: {}, output_recipient: {}, token_address: {}, token_amount: {}, path_id: {} }}",
118            self.chain,
119            self.router_address,
120            self.signer_address,
121            self.output_recipient,
122            self.token_address,
123            self.token_amount,
124            self.path_id
125        )
126    }
127}
128
129/// Deprecated alias for [`AssemblyRequest`]
130///
131/// This type alias is provided for backward compatibility.
132/// Use [`AssemblyRequest`] instead in new code.
133#[deprecated(since = "0.25.0", note = "Use `AssemblyRequest` instead")]
134pub type SwapContext = AssemblyRequest;