1use super::*;
19use codec::{Decode, Encode, MaxEncodedLen};
20use core::marker::PhantomData;
21use scale_info::TypeInfo;
22use sp_runtime::traits::TryConvert;
23
24pub type BalancePath<T> = Vec<(<T as Config>::AssetKind, <T as Config>::Balance)>;
33
34pub type CreditOf<T> = Credit<<T as frame_system::Config>::AccountId, <T as Config>::Assets>;
36
37#[derive(Decode, Encode, Default, PartialEq, Eq, MaxEncodedLen, TypeInfo)]
39pub struct PoolInfo<PoolAssetId> {
40 pub lp_token: PoolAssetId,
42}
43
44pub trait PoolLocator<AccountId, AssetKind, PoolId> {
50 fn address(id: &PoolId) -> Result<AccountId, ()>;
52 fn pool_id(asset1: &AssetKind, asset2: &AssetKind) -> Result<PoolId, ()>;
56 fn pool_address(asset1: &AssetKind, asset2: &AssetKind) -> Result<AccountId, ()> {
60 if let Ok(id) = Self::pool_id(asset1, asset2) {
61 Self::address(&id)
62 } else {
63 Err(())
64 }
65 }
66}
67
68pub struct WithFirstAsset<FirstAsset, AccountId, AssetKind, AccountIdConverter>(
73 PhantomData<(FirstAsset, AccountId, AssetKind, AccountIdConverter)>,
74);
75impl<FirstAsset, AccountId, AssetKind, AccountIdConverter>
76 PoolLocator<AccountId, AssetKind, (AssetKind, AssetKind)>
77 for WithFirstAsset<FirstAsset, AccountId, AssetKind, AccountIdConverter>
78where
79 AssetKind: Eq + Clone + Encode,
80 AccountId: Decode,
81 FirstAsset: Get<AssetKind>,
82 AccountIdConverter: for<'a> TryConvert<&'a (AssetKind, AssetKind), AccountId>,
83{
84 fn pool_id(asset1: &AssetKind, asset2: &AssetKind) -> Result<(AssetKind, AssetKind), ()> {
85 if asset1 == asset2 {
86 return Err(());
87 }
88 let first = FirstAsset::get();
89 if first == *asset1 {
90 Ok((first, asset2.clone()))
91 } else if first == *asset2 {
92 Ok((first, asset1.clone()))
93 } else {
94 Err(())
95 }
96 }
97 fn address(id: &(AssetKind, AssetKind)) -> Result<AccountId, ()> {
98 AccountIdConverter::try_convert(id).map_err(|_| ())
99 }
100}
101
102pub struct Ascending<AccountId, AssetKind, AccountIdConverter>(
104 PhantomData<(AccountId, AssetKind, AccountIdConverter)>,
105);
106impl<AccountId, AssetKind, AccountIdConverter>
107 PoolLocator<AccountId, AssetKind, (AssetKind, AssetKind)>
108 for Ascending<AccountId, AssetKind, AccountIdConverter>
109where
110 AssetKind: Ord + Clone + Encode,
111 AccountId: Decode,
112 AccountIdConverter: for<'a> TryConvert<&'a (AssetKind, AssetKind), AccountId>,
113{
114 fn pool_id(asset1: &AssetKind, asset2: &AssetKind) -> Result<(AssetKind, AssetKind), ()> {
115 if asset1 > asset2 {
116 Ok((asset2.clone(), asset1.clone()))
117 } else if asset1 < asset2 {
118 Ok((asset1.clone(), asset2.clone()))
119 } else {
120 Err(())
121 }
122 }
123 fn address(id: &(AssetKind, AssetKind)) -> Result<AccountId, ()> {
124 AccountIdConverter::try_convert(id).map_err(|_| ())
125 }
126}
127
128pub struct Chain<First, Second>(PhantomData<(First, Second)>);
132impl<First, Second, AccountId, AssetKind> PoolLocator<AccountId, AssetKind, (AssetKind, AssetKind)>
133 for Chain<First, Second>
134where
135 First: PoolLocator<AccountId, AssetKind, (AssetKind, AssetKind)>,
136 Second: PoolLocator<AccountId, AssetKind, (AssetKind, AssetKind)>,
137{
138 fn pool_id(asset1: &AssetKind, asset2: &AssetKind) -> Result<(AssetKind, AssetKind), ()> {
139 First::pool_id(asset1, asset2).or(Second::pool_id(asset1, asset2))
140 }
141 fn address(id: &(AssetKind, AssetKind)) -> Result<AccountId, ()> {
142 First::address(id).or(Second::address(id))
143 }
144}
145
146pub struct AccountIdConverter<Seed, PoolId>(PhantomData<(Seed, PoolId)>);
148impl<Seed, PoolId, AccountId> TryConvert<&PoolId, AccountId> for AccountIdConverter<Seed, PoolId>
149where
150 PoolId: Encode,
151 AccountId: Decode,
152 Seed: Get<PalletId>,
153{
154 fn try_convert(id: &PoolId) -> Result<AccountId, &PoolId> {
155 sp_io::hashing::blake2_256(&Encode::encode(&(Seed::get(), id))[..])
156 .using_encoded(|e| Decode::decode(&mut TrailingZeroInput::new(e)).map_err(|_| id))
157 }
158}
159
160pub struct AccountIdConverterNoSeed<PoolId>(PhantomData<PoolId>);
162impl<PoolId, AccountId> TryConvert<&PoolId, AccountId> for AccountIdConverterNoSeed<PoolId>
163where
164 PoolId: Encode,
165 AccountId: Decode,
166{
167 fn try_convert(id: &PoolId) -> Result<AccountId, &PoolId> {
168 sp_io::hashing::blake2_256(&Encode::encode(id)[..])
169 .using_encoded(|e| Decode::decode(&mut TrailingZeroInput::new(e)).map_err(|_| id))
170 }
171}