1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
// This file is part of Substrate.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Abstract asset operations traits.
//!
//! The following operations are defined:
//! * [`Inspect`]
//! * [`Update`]
//! * [`Create`]
//! * [`Destroy`]
//! * [`Stash`]
//! * [`Restore`]
//!
//! Also, all the operations above (except the `Create` operation) use
//! the [`AssetDefinition`] to retrieve the `Id` type of the asset.
//!
//! An asset operation can be implemented multiple times
//! using different strategies associated with this operation.
//!
//! A strategy defines the operation behavior,
//! may supply additional parameters,
//! and may define a return value type of the operation.
//!
//! ### Usage Example
//!
//! This example shows how to interact with pallet-uniques (assuming the pallet called Uniques in
//! the chain’s Runtime) via the asset ops.
//!
//! If you are interested in the implementation example, you can look at the pallet-uniques
//! implementation. You can check out the pallet-uniques tests if you want more examples of usage.
//!
//! ```rust,ignore
//! type Collection = pallet_uniques::asset_ops::Collection<Uniques>;
//! type Item = pallet_uniques::asset_ops::Item<Uniques>;
//!
//! // Collection creation
//! //
//! // Note the `Owner` and `Admin` are inspect strategies.
//! //
//! // **Any** inspect strategy can be used to produce a config value
//! // using the `WithConfig` creation strategy.
//! Collection::create(WithConfig::new(
//! (
//! Owner::with_config_value(collection_owner),
//! Admin::with_config_value(collection_admin)
//! ),
//! PredefinedId::from(collection_id),
//! )).unwrap();
//!
//! // Get the collection owner
//! let owner = Collection::inspect(&collection_id, Owner::default()).unwrap();
//!
//! // Get the collection admin
//! let admin = Collection::inspect(&collection_id, Admin::default()).unwrap();
//!
//! // Get collection metadata
//! let metadata = Collection::inspect(&collection_id, Bytes::default()).unwrap();
//!
//! // Get collection attribute
//! use pallet_uniques::asset_strategies::Attribute;
//! let attr_key = "example-key";
//! let attr_value = Collection::inspect(
//! &collection_id,
//! Bytes(Attribute(attr_key.as_slice())),
//! ).unwrap();
//!
//! // Item creation (note the usage of the same strategy -- WithConfig)
//! Item::create(WithConfig::new(
//! Owner::with_config_value(item_owner),
//! PredefinedId::from(item_id),
//! )).unwrap();
//!
//! // Get the item owner
//! let item_owner = Item::inspect(&(collection_id, item_id), Owner::default()).unwrap();
//!
//! // Get item attribute
//! let attr_key = "example-key";
//! let attr_value = Item::inspect(
//! &(collection_id, item_id),
//! Bytes(Attribute(attr_key.as_slice())),
//! ).unwrap();
//!
//! // Unconditionally update the item's owner (unchecked transfer)
//! Item::update(&(collection_id, item_id), Owner::default(), &bob).unwrap();
//!
//! // CheckOrigin then transfer
//! Item::update(
//! &(collection_id, item_id),
//! CheckOrigin(RuntimeOrigin::root(), Owner::default()),
//! &bob,
//! ).unwrap();
//!
//! // From-To transfer
//! Item::update(
//! &(collection_id, item_id),
//! ChangeOwnerFrom::check(alice),
//! &bob,
//! ).unwrap();
//!
//! // Lock item (forbid changing its Owner)
//! //
//! // Note that Owner strategy is turned into the `CanUpdate<Owner>` strategy
//! // via the `as_can_update` function.
//! //
//! // **Any** update strategy can be turned into the `CanUpdate` this way.
//! Item::update(
//! &(collection_id, item_id),
//! Owner::default().as_can_update(),
//! false,
//! );
//! ```
use PhantomData;
use DispatchError;
use Vec;
/// Trait for defining an asset.
/// The definition must provide the `Id` type to identify the asset.
/// Get the `Id` type of the asset definition.
pub type AssetIdOf<T> = Id;
/// A strategy for use in the [`Inspect`] implementations.
///
/// The common inspect strategies are:
/// * [`Bytes`](common_strategies::Bytes)
/// * [`Owner`](common_strategies::Owner)
/// * [`CanCreate`](common_strategies::CanCreate)
/// * [`CanDestroy`](common_strategies::CanDestroy)
/// * [`CanUpdate`](common_strategies::CanUpdate)
/// A trait representing the ability of a certain asset to **provide** its state
/// information.
///
/// This trait can be implemented multiple times using different
/// [`inspect strategies`](InspectStrategy).
///
/// An inspect strategy defines how the asset state is identified/retrieved
/// and what [`Value`](InspectStrategy::Value) type is returned.
/// A strategy for use in the [`Update`] implementations.
///
/// The common update strategies are:
/// * [`Bytes`](common_strategies::Bytes)
/// * [`CanCreate`](common_strategies::CanCreate)
/// * [`CanDestroy`](common_strategies::CanDestroy)
/// * [`CanUpdate`](common_strategies::CanUpdate)
/// A trait representing the ability of a certain asset to **update** its state information.
///
/// This trait can be implemented multiple times using different
/// [`update strategies`](UpdateStrategy).
///
/// An update strategy defines how the asset state is identified
/// and what [`UpdateValue`](UpdateStrategy::UpdateValue) type is used.
/// A strategy for use in the [`Create`] implementations.
///
/// The common "create" strategy is [`WithConfig`](common_strategies::WithConfig).
/// An ID assignment approach to use in the "create" strategies.
///
/// The common ID assignments are:
/// * [`AutoId`](common_strategies::AutoId)
/// * [`PredefinedId`](common_strategies::PredefinedId)
/// * [`DeriveAndReportId`](common_strategies::DeriveAndReportId)
/// A trait representing the ability of a certain asset to be created.
///
/// This trait can be implemented multiple times using different
/// [`"create" strategies`](CreateStrategy).
///
/// A create strategy defines all aspects of asset creation including how an asset ID is assigned.
/// A strategy for use in the [`Destroy`] implementations.
///
/// The common destroy strategies are:
/// * [`NoParams`](common_strategies::NoParams)
/// * [`IfOwnedBy`](common_strategies::IfOwnedBy)
/// * [`WithWitness`](common_strategies::WithWitness)
/// A trait representing the ability of a certain asset to be destroyed.
///
/// This trait can be implemented multiple times using different
/// [`destroy strategies`](DestroyStrategy).
///
/// A destroy strategy defines destroy parameters and the result value type.
/// A strategy for use in the [`Stash`] implementations.
///
/// The common stash strategies are:
/// * [`NoParams`](common_strategies::NoParams)
/// * [`IfOwnedBy`](common_strategies::IfOwnedBy)
/// A trait representing the ability of a certain asset to be stashed.
///
/// This trait can be implemented multiple times using different
/// [`stash strategies`](StashStrategy).
///
/// A stash strategy defines stash parameters.
/// A strategy for use in the [`Restore`] implementations.
/// The common restore strategies are:
/// * [`NoParams`](common_strategies::NoParams)
/// * [`WithConfig`](common_strategies::WithConfig)
/// A trait representing the ability of a certain asset to be restored.
///
/// This trait can be implemented multiple times using different
/// [`restore strategies`](RestoreStrategy).
///
/// A restore strategy defines restore parameters.