1
// Copyright 2019-2025 PureStake Inc.
2
// This file is part of Moonbeam.
3

            
4
// Moonbeam is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Moonbeam is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Moonbeam.  If not, see <http://www.gnu.org/licenses/>.
16

            
17
//! Asset management helpers for XCM tests
18

            
19
use crate::xcm_mock::{parachain, AssetManager, ParaA};
20
use crate::xcm_testing::add_supported_asset;
21
use frame_support::assert_ok;
22
use xcm_simulator::TestExt;
23

            
24
pub struct AssetBuilder {
25
	location: xcm::v3::Location,
26
	is_sufficient: bool,
27
}
28

            
29
impl AssetBuilder {
30
9
	pub fn relay_asset() -> Self {
31
9
		Self {
32
9
			location: xcm::v3::Location::parent(),
33
9
			is_sufficient: true,
34
9
		}
35
9
	}
36

            
37
2
	pub fn with_sufficient(mut self, is_sufficient: bool) -> Self {
38
2
		self.is_sufficient = is_sufficient;
39
2
		self
40
2
	}
41

            
42
7
	pub fn register(self) -> parachain::AssetId {
43
7
		let source_location = parachain::AssetType::Xcm(self.location.clone());
44
7
		let asset_metadata = parachain::AssetMetadata {
45
7
			name: b"RelayToken".to_vec(),
46
7
			symbol: b"Relay".to_vec(),
47
7
			decimals: 12,
48
7
		};
49
7

            
50
7
		ParaA::execute_with(|| {
51
7
			assert_ok!(AssetManager::register_foreign_asset(
52
7
				parachain::RuntimeOrigin::root(),
53
7
				source_location.clone(),
54
7
				asset_metadata,
55
7
				1u128,
56
7
				self.is_sufficient
57
7
			));
58
7
			assert_ok!(add_supported_asset(source_location.clone(), 0));
59
7
		});
60
7

            
61
7
		source_location.into()
62
7
	}
63

            
64
2
	pub fn register_with_units_per_second(self, units_per_second: u128) -> parachain::AssetId {
65
2
		let source_location = parachain::AssetType::Xcm(self.location.clone());
66
2
		let asset_metadata = parachain::AssetMetadata {
67
2
			name: b"RelayToken".to_vec(),
68
2
			symbol: b"Relay".to_vec(),
69
2
			decimals: 12,
70
2
		};
71
2

            
72
2
		ParaA::execute_with(|| {
73
2
			assert_ok!(AssetManager::register_foreign_asset(
74
2
				parachain::RuntimeOrigin::root(),
75
2
				source_location.clone(),
76
2
				asset_metadata,
77
2
				1u128,
78
2
				self.is_sufficient
79
2
			));
80
2
			assert_ok!(add_supported_asset(
81
2
				source_location.clone(),
82
2
				units_per_second
83
2
			));
84
2
		});
85
2

            
86
2
		source_location.into()
87
2
	}
88
}
89

            
90
// Convenience functions for common asset types
91
5
pub fn register_relay_asset() -> parachain::AssetId {
92
5
	AssetBuilder::relay_asset().register()
93
5
}
94

            
95
2
pub fn register_relay_asset_with_units_per_second(units_per_second: u128) -> parachain::AssetId {
96
2
	AssetBuilder::relay_asset().register_with_units_per_second(units_per_second)
97
2
}
98

            
99
2
pub fn register_relay_asset_non_sufficient() -> parachain::AssetId {
100
2
	AssetBuilder::relay_asset()
101
2
		.with_sufficient(false)
102
2
		.register()
103
2
}
104

            
105
// Helper for the common relay asset setup pattern in statemint tests
106
6
pub fn setup_relay_asset_for_statemint() -> (parachain::AssetType, parachain::AssetId) {
107
6
	let relay_location = parachain::AssetType::Xcm(xcm::v3::Location::parent());
108
6
	let source_relay_id: parachain::AssetId = relay_location.clone().into();
109
6

            
110
6
	let relay_asset_metadata = parachain::AssetMetadata {
111
6
		name: b"RelayToken".to_vec(),
112
6
		symbol: b"Relay".to_vec(),
113
6
		decimals: 12,
114
6
	};
115
6

            
116
6
	ParaA::execute_with(|| {
117
6
		assert_ok!(AssetManager::register_foreign_asset(
118
6
			parachain::RuntimeOrigin::root(),
119
6
			relay_location.clone(),
120
6
			relay_asset_metadata,
121
6
			1u128,
122
6
			true
123
6
		));
124
6
		assert_ok!(add_supported_asset(relay_location.clone(), 0));
125
6
	});
126
6

            
127
6
	(relay_location, source_relay_id)
128
6
}