git.delta.rocks / unique-network / refs/commits / 35937ed58884

difftreelog

refactor share unq sponsoring code with evm

Yaroslav Bolyukin2021-11-18parent: #7e74e9a.patch.diff
in: master

4 files changed

modifiedpallets/nft/src/eth/sponsoring.rsdiffbeforeafterboth
1//! Implements EVM sponsoring logic via OnChargeEVMTransaction1//! Implements EVM sponsoring logic via OnChargeEVMTransaction
22
3use crate::{Collection, Config, FungibleTransferBasket, NftTransferBasket};3use crate::{Config, sponsorship::*};
4use evm_coder::{Call, abi::AbiReader};4use evm_coder::{Call, abi::AbiReader};
5use frame_support::{
6 storage::{StorageDoubleMap},
7};
8use pallet_common::eth::map_eth_to_id;5use pallet_common::{CollectionHandle, eth::map_eth_to_id};
9use sp_core::H160;6use sp_core::H160;
10use sp_std::prelude::*;7use sp_std::prelude::*;
11use up_sponsorship::SponsorshipHandler;8use up_sponsorship::SponsorshipHandler;
12use core::marker::PhantomData;9use core::marker::PhantomData;
13use core::convert::TryInto;10use core::convert::TryInto;
14use nft_data_structs::{CollectionId, NFT_SPONSOR_TRANSFER_TIMEOUT, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT};11use nft_data_structs::TokenId;
15use pallet_common::{12use up_evm_mapping::EvmBackwardsAddressMapping;
16 CollectionById,13use pallet_evm::AddressMapping;
17 account::{CrossAccountId, EvmBackwardsAddressMapping},
18};
1914
20use pallet_nonfungible::erc::{UniqueNFTCall, ERC721UniqueExtensionsCall, ERC721Call};15use pallet_nonfungible::erc::{UniqueNFTCall, ERC721UniqueExtensionsCall, ERC721Call};
21use pallet_fungible::erc::{UniqueFungibleCall, ERC20Call};16use pallet_fungible::erc::{UniqueFungibleCall, ERC20Call};
22
23struct AnyError;
24
25fn try_sponsor<T: Config>(
26 caller: &H160,
27 collection_id: CollectionId,
28 collection: &Collection<T>,
29 call: &[u8],
30) -> Result<(), AnyError> {
31 let (method_id, mut reader) = AbiReader::new_call(call).map_err(|_| AnyError)?;
32 match &collection.mode {
33 crate::CollectionMode::NFT => {
34 let call: UniqueNFTCall = UniqueNFTCall::parse(method_id, &mut reader)
35 .map_err(|_| AnyError)?
36 .ok_or(AnyError)?;
37 match call {
38 UniqueNFTCall::ERC721UniqueExtensions(ERC721UniqueExtensionsCall::Transfer {
39 token_id,
40 ..
41 })
42 | UniqueNFTCall::ERC721(ERC721Call::TransferFrom { token_id, .. }) => {
43 let token_id: u32 = token_id.try_into().map_err(|_| AnyError)?;
44 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
45 let collection_limits = &collection.limits;
46 let limit =
47 collection_limits.sponsor_transfer_timeout(NFT_SPONSOR_TRANSFER_TIMEOUT);
48
49 let mut sponsor = true;
50 if <NftTransferBasket<T>>::contains_key(collection_id, token_id) {
51 let last_tx_block = <NftTransferBasket<T>>::get(collection_id, token_id);
52 let limit_time = last_tx_block + limit.into();
53 if block_number <= limit_time {
54 sponsor = false;
55 }
56 }
57 if sponsor {
58 <NftTransferBasket<T>>::insert(collection_id, token_id, block_number);
59 return Ok(());
60 }
61 }
62 _ => {}
63 }
64 }
65 crate::CollectionMode::Fungible(_) => {
66 let call: UniqueFungibleCall = UniqueFungibleCall::parse(method_id, &mut reader)
67 .map_err(|_| AnyError)?
68 .ok_or(AnyError)?;
69 #[allow(clippy::single_match)]
70 match call {
71 UniqueFungibleCall::ERC20(ERC20Call::Transfer { .. }) => {
72 let who = T::CrossAccountId::from_eth(*caller);
73 let collection_limits = &collection.limits;
74 let limit = collection_limits
75 .sponsor_transfer_timeout(FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT);
76
77 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
78 let mut sponsored = true;
79 if <FungibleTransferBasket<T>>::contains_key(collection_id, who.as_sub()) {
80 let last_tx_block =
81 <FungibleTransferBasket<T>>::get(collection_id, who.as_sub());
82 let limit_time = last_tx_block + limit.into();
83 if block_number <= limit_time {
84 sponsored = false;
85 }
86 }
87 if sponsored {
88 <FungibleTransferBasket<T>>::insert(
89 collection_id,
90 who.as_sub(),
91 block_number,
92 );
93 return Ok(());
94 }
95 }
96 _ => {}
97 }
98 }
99 _ => {}
100 }
101 Err(AnyError)
102}
10317
104pub struct NftEthSponsorshipHandler<T: Config>(PhantomData<*const T>);18pub struct NftEthSponsorshipHandler<T: Config>(PhantomData<*const T>);
105impl<T: Config> SponsorshipHandler<H160, (H160, Vec<u8>)> for NftEthSponsorshipHandler<T> {19impl<T: Config> SponsorshipHandler<H160, (H160, Vec<u8>)> for NftEthSponsorshipHandler<T> {
106 fn get_sponsor(who: &H160, call: &(H160, Vec<u8>)) -> Option<H160> {20 fn get_sponsor(who: &H160, call: &(H160, Vec<u8>)) -> Option<H160> {
107 if let Some(collection_id) = map_eth_to_id(&call.0) {21 let collection_id = map_eth_to_id(&call.0)?;
108 if let Some(collection) = <CollectionById<T>>::get(collection_id) {22 let collection = <CollectionHandle<T>>::new(collection_id)?;
109 if !collection.sponsorship.confirmed() {23 let sponsor = collection.sponsorship.sponsor()?.clone();
110 return None;24 let sponsor =
111 }25 <T as pallet_common::Config>::EvmBackwardsAddressMapping::from_account_id(sponsor);
26 let who = <T as pallet_common::Config>::EvmAddressMapping::into_account_id(*who);
27 let (method_id, mut reader) = AbiReader::new_call(&call.1).ok()?;
28 match &collection.mode {
29 crate::CollectionMode::NFT => {
30 let call = UniqueNFTCall::parse(method_id, &mut reader).ok()??;
31 match call {
32 UniqueNFTCall::ERC721UniqueExtensions(
33 ERC721UniqueExtensionsCall::Transfer { token_id, .. },
34 )
35 | UniqueNFTCall::ERC721(ERC721Call::TransferFrom { token_id, .. }) => {
36 let token_id: TokenId = token_id.try_into().ok()?;
112 if try_sponsor(who, collection_id, &collection, &call.1).is_ok() {37 withdraw_transfer::<T>(&collection, &who, &token_id).map(|()| sponsor)
113 return collection38 }
114 .sponsorship39 UniqueNFTCall::ERC721(ERC721Call::Approve { token_id, .. }) => {
115 .sponsor()40 let token_id: TokenId = token_id.try_into().ok()?;
116 .cloned()41 withdraw_approve::<T>(&collection, &who, &token_id).map(|()| sponsor)
117 .map(T::EvmBackwardsAddressMapping::from_account_id);42 }
118 }43 _ => None,
119 }44 }
120 }45 }
46 crate::CollectionMode::Fungible(_) => {
47 let call = UniqueFungibleCall::parse(method_id, &mut reader).ok()??;
48 #[allow(clippy::single_match)]
49 match call {
50 UniqueFungibleCall::ERC20(
51 ERC20Call::Transfer { .. } | ERC20Call::TransferFrom { .. },
52 ) => withdraw_transfer::<T>(&collection, &who, &TokenId::default())
53 .map(|()| sponsor),
54 UniqueFungibleCall::ERC20(ERC20Call::Approve { .. }) => {
55 withdraw_approve::<T>(&collection, &who, &TokenId::default())
56 .map(|()| sponsor)
57 }
58 _ => None,
59 }
60 }
121 None61 _ => None,
62 }
122 }63 }
123}64}
12465
modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
136 //#region Tokens transfer rate limit baskets136 //#region Tokens transfer rate limit baskets
137 /// (Collection id (controlled?2), who created (real))137 /// (Collection id (controlled?2), who created (real))
138 /// TODO: Off chain worker should remove from this map when collection gets removed138 /// TODO: Off chain worker should remove from this map when collection gets removed
139 pub CreateItemBasket get(fn create_item_basket): map hasher(blake2_128_concat) (CollectionId, T::AccountId) => T::BlockNumber;139 pub CreateItemBasket get(fn create_item_basket): map hasher(blake2_128_concat) (CollectionId, T::AccountId) => Option<T::BlockNumber>;
140 /// Collection id (controlled?2), token id (controlled?2)140 /// Collection id (controlled?2), token id (controlled?2)
141 pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => T::BlockNumber;141 pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber>;
142 /// Collection id (controlled?2), owning user (real)142 /// Collection id (controlled?2), owning user (real)
143 pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(twox_64_concat) T::AccountId => T::BlockNumber;143 pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(twox_64_concat) T::AccountId => Option<T::BlockNumber>;
144 /// Collection id (controlled?2), token id (controlled?2)144 /// Collection id (controlled?2), token id (controlled?2)
145 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => T::BlockNumber;145 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): nmap hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId, hasher(twox_64_concat) T::AccountId => Option<T::BlockNumber>;
146 //#endregion146 //#endregion
147147
148 /// Variable metadata sponsoring148 /// Variable metadata sponsoring
253253
254 <NftTransferBasket<T>>::remove_prefix(collection_id, None);254 <NftTransferBasket<T>>::remove_prefix(collection_id, None);
255 <FungibleTransferBasket<T>>::remove_prefix(collection_id, None);255 <FungibleTransferBasket<T>>::remove_prefix(collection_id, None);
256 <ReFungibleTransferBasket<T>>::remove_prefix(collection_id, None);256 <ReFungibleTransferBasket<T>>::remove_prefix((collection_id,), None);
257257
258 <VariableMetaDataBasket<T>>::remove_prefix(collection_id, None);258 <VariableMetaDataBasket<T>>::remove_prefix(collection_id, None);
259 <NftApproveBasket<T>>::remove_prefix(collection_id, None);259 <NftApproveBasket<T>>::remove_prefix(collection_id, None);
modifiedpallets/nft/src/sponsorship.rsdiffbeforeafterboth
1use crate::{1use crate::{
2 Config, Call, CreateItemBasket, VariableMetaDataBasket, ReFungibleTransferBasket,2 Config, Call, CreateItemBasket, VariableMetaDataBasket, ReFungibleTransferBasket,
3 FungibleTransferBasket, NftTransferBasket, CreateItemData, CollectionMode,3 FungibleTransferBasket, NftTransferBasket, CreateItemData, CollectionMode, NftApproveBasket,
4 FungibleApproveBasket, RefungibleApproveBasket,
4};5};
5use core::marker::PhantomData;6use core::marker::PhantomData;
6use up_sponsorship::SponsorshipHandler;7use up_sponsorship::SponsorshipHandler;
7use frame_support::{8use frame_support::{
8 traits::{IsSubType},9 traits::{IsSubType},
9 storage::{StorageMap, StorageDoubleMap},10 storage::{StorageMap, StorageDoubleMap, StorageNMap},
10};11};
11use nft_data_structs::{12use nft_data_structs::{
12 TokenId, CollectionId, NFT_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,13 CollectionId, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, NFT_SPONSOR_TRANSFER_TIMEOUT,
13 FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,14 REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, TokenId,
14};15};
15use pallet_common::{CollectionById};16use pallet_common::{CollectionHandle};
17
18pub fn withdraw_transfer<T: Config>(
19 collection: &CollectionHandle<T>,
20 who: &T::AccountId,
21 item_id: &TokenId,
22) -> Option<()> {
23 // sponsor timeout
24 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
25 let limit = collection
26 .limits
27 .sponsor_transfer_timeout(match collection.mode {
28 CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,
29 CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
30 CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
31 });
32
33 let last_tx_block = match collection.mode {
34 CollectionMode::NFT => <NftTransferBasket<T>>::get(collection.id, item_id),
35 CollectionMode::Fungible(_) => <FungibleTransferBasket<T>>::get(collection.id, who),
36 CollectionMode::ReFungible => {
37 <ReFungibleTransferBasket<T>>::get((collection.id, item_id, who))
38 }
39 };
40
41 if let Some(last_tx_block) = last_tx_block {
42 let timeout = last_tx_block + limit.into();
43 if block_number < timeout {
44 return None;
45 }
46 }
47
48 match collection.mode {
49 CollectionMode::NFT => <NftTransferBasket<T>>::insert(collection.id, item_id, block_number),
50 CollectionMode::Fungible(_) => {
51 <FungibleTransferBasket<T>>::insert(collection.id, who, block_number)
52 }
53 CollectionMode::ReFungible => {
54 <ReFungibleTransferBasket<T>>::insert((collection.id, item_id, who), block_number)
55 }
56 };
57
58 Some(())
59}
60
61pub fn withdraw_create_item<T: Config>(
62 collection: &CollectionHandle<T>,
63 who: &T::AccountId,
64 _properties: &CreateItemData,
65) -> Option<()> {
66 if _properties.data_size() as u32 > collection.limits.sponsored_data_size() {
67 return None;
68 }
69
70 // sponsor timeout
71 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
72 let limit = collection
73 .limits
74 .sponsor_transfer_timeout(match _properties {
75 CreateItemData::NFT(_) => NFT_SPONSOR_TRANSFER_TIMEOUT,
76 CreateItemData::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
77 CreateItemData::ReFungible(_) => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
78 });
79
80 if let Some(last_tx_block) = <CreateItemBasket<T>>::get((collection.id, &who)) {
81 let timeout = last_tx_block + limit.into();
82 if block_number < timeout {
83 return None;
84 }
85 }
86
87 CreateItemBasket::<T>::insert((collection.id, who.clone()), block_number);
88
89 Some(())
90}
91
92pub fn withdraw_set_variable_meta_data<T: Config>(
93 collection: &CollectionHandle<T>,
94 item_id: &TokenId,
95 data: &[u8],
96) -> Option<()> {
97 // Can't sponsor fungible collection, this tx will be rejected
98 // as invalid
99 if matches!(collection.mode, CollectionMode::Fungible(_)) {
100 return None;
101 }
102 if data.len() > collection.limits.sponsored_data_size() as usize {
103 return None;
104 }
105
106 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
107 let limit = collection.limits.sponsored_data_rate_limit()?;
108
109 if let Some(last_tx_block) = VariableMetaDataBasket::<T>::get(collection.id, item_id) {
110 let timeout = last_tx_block + limit.into();
111 if block_number < timeout {
112 return None;
113 }
114 }
115
116 <VariableMetaDataBasket<T>>::insert(collection.id, item_id, block_number);
117
118 Some(())
119}
120
121pub fn withdraw_approve<T: Config>(
122 collection: &CollectionHandle<T>,
123 who: &T::AccountId,
124 item_id: &TokenId,
125) -> Option<()> {
126 // sponsor timeout
127 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
128 let limit = collection.limits.sponsor_approve_timeout();
129
130 let last_tx_block = match collection.mode {
131 CollectionMode::NFT => <NftApproveBasket<T>>::get(collection.id, item_id),
132 CollectionMode::Fungible(_) => <FungibleApproveBasket<T>>::get(collection.id, who),
133 CollectionMode::ReFungible => {
134 <RefungibleApproveBasket<T>>::get((collection.id, item_id, who))
135 }
136 };
137
138 if let Some(last_tx_block) = last_tx_block {
139 let timeout = last_tx_block + limit.into();
140 if block_number < timeout {
141 return None;
142 }
143 }
144
145 match collection.mode {
146 CollectionMode::NFT => <NftApproveBasket<T>>::insert(collection.id, item_id, block_number),
147 CollectionMode::Fungible(_) => {
148 <FungibleApproveBasket<T>>::insert(collection.id, who, block_number)
149 }
150 CollectionMode::ReFungible => {
151 <RefungibleApproveBasket<T>>::insert((collection.id, item_id, who), block_number)
152 }
153 };
154
155 Some(())
156}
157
158fn load<T: Config>(id: CollectionId) -> Option<(T::AccountId, CollectionHandle<T>)> {
159 let collection = CollectionHandle::new(id)?;
160 let sponsor = collection.sponsorship.sponsor().cloned()?;
161 Some((sponsor, collection))
162}
16163
17pub struct NftSponsorshipHandler<T>(PhantomData<T>);164pub struct NftSponsorshipHandler<T>(PhantomData<T>);
18impl<T: Config> NftSponsorshipHandler<T> {
19 pub fn withdraw_create_item(
20 who: &T::AccountId,
21 collection_id: &CollectionId,
22 _properties: &CreateItemData,
23 ) -> Option<T::AccountId> {
24 let collection = CollectionById::<T>::get(collection_id)?;
25
26 // sponsor timeout
27 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
28
29 let limit = collection
30 .limits
31 .sponsor_transfer_timeout(match _properties {
32 CreateItemData::NFT(_) => NFT_SPONSOR_TRANSFER_TIMEOUT,
33 CreateItemData::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
34 CreateItemData::ReFungible(_) => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
35 });
36 if CreateItemBasket::<T>::contains_key((collection_id, &who)) {
37 let last_tx_block = CreateItemBasket::<T>::get((collection_id, &who));
38 let limit_time = last_tx_block + limit.into();
39 if block_number <= limit_time {
40 return None;
41 }
42 }
43 CreateItemBasket::<T>::insert((collection_id, who.clone()), block_number);
44
45 // check free create limit
46 if collection.limits.sponsored_data_size() >= (_properties.data_size() as u32) {
47 collection.sponsorship.sponsor().cloned()
48 } else {
49 None
50 }
51 }
52
53 pub fn withdraw_transfer(
54 who: &T::AccountId,
55 collection_id: &CollectionId,
56 item_id: &TokenId,
57 ) -> Option<T::AccountId> {
58 let collection = CollectionById::<T>::get(collection_id)?;
59
60 let mut sponsor_transfer = false;
61 if collection.sponsorship.confirmed() {
62 let collection_limits = collection.limits.clone();
63 let collection_mode = collection.mode.clone();
64
65 // sponsor timeout
66 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
67 sponsor_transfer = match collection_mode {
68 CollectionMode::NFT => {
69 // get correct limit
70 let limit =
71 collection_limits.sponsor_transfer_timeout(NFT_SPONSOR_TRANSFER_TIMEOUT);
72
73 let mut sponsored = true;
74 if NftTransferBasket::<T>::contains_key(collection_id, item_id) {
75 let last_tx_block = NftTransferBasket::<T>::get(collection_id, item_id);
76 let limit_time = last_tx_block + limit.into();
77 if block_number <= limit_time {
78 sponsored = false;
79 }
80 }
81 if sponsored {
82 NftTransferBasket::<T>::insert(collection_id, item_id, block_number);
83 }
84
85 sponsored
86 }
87 CollectionMode::Fungible(_) => {
88 // get correct limit
89 let limit = collection_limits
90 .sponsor_transfer_timeout(FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT);
91
92 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
93 let mut sponsored = true;
94 if FungibleTransferBasket::<T>::contains_key(collection_id, who) {
95 let last_tx_block = FungibleTransferBasket::<T>::get(collection_id, who);
96 let limit_time = last_tx_block + limit.into();
97 if block_number <= limit_time {
98 sponsored = false;
99 }
100 }
101 if sponsored {
102 FungibleTransferBasket::<T>::insert(collection_id, who, block_number);
103 }
104
105 sponsored
106 }
107 CollectionMode::ReFungible => {
108 // get correct limit
109 let limit = collection_limits
110 .sponsor_transfer_timeout(REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT);
111
112 let mut sponsored = true;
113 if ReFungibleTransferBasket::<T>::contains_key(collection_id, item_id) {
114 let last_tx_block =
115 ReFungibleTransferBasket::<T>::get(collection_id, item_id);
116 let limit_time = last_tx_block + limit.into();
117 if block_number <= limit_time {
118 sponsored = false;
119 }
120 }
121 if sponsored {
122 ReFungibleTransferBasket::<T>::insert(collection_id, item_id, block_number);
123 }
124
125 sponsored
126 }
127 };
128 }
129
130 if !sponsor_transfer {
131 None
132 } else {
133 collection.sponsorship.sponsor().cloned()
134 }
135 }
136
137 pub fn withdraw_set_variable_meta_data(
138 collection_id: &CollectionId,
139 item_id: &TokenId,
140 data: &[u8],
141 ) -> Option<T::AccountId> {
142 let mut sponsor_metadata_changes = false;
143
144 let collection = CollectionById::<T>::get(collection_id)?;
145
146 if collection.sponsorship.confirmed() &&
147 // Can't sponsor fungible collection, this tx will be rejected
148 // as invalid
149 !matches!(collection.mode, CollectionMode::Fungible(_)) &&
150 data.len() <= collection.limits.sponsored_data_size() as usize
151 {
152 if let Some(rate_limit) = collection.limits.sponsored_data_rate_limit() {
153 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
154
155 if VariableMetaDataBasket::<T>::get(collection_id, item_id)
156 .map(|last_block| block_number - last_block > rate_limit.into())
157 .unwrap_or(true)
158 {
159 sponsor_metadata_changes = true;
160 VariableMetaDataBasket::<T>::insert(collection_id, item_id, block_number);
161 }
162 }
163 }
164
165 if !sponsor_metadata_changes {
166 None
167 } else {
168 collection.sponsorship.sponsor().cloned()
169 }
170 }
171}
172
173impl<T, C> SponsorshipHandler<T::AccountId, C> for NftSponsorshipHandler<T>165impl<T, C> SponsorshipHandler<T::AccountId, C> for NftSponsorshipHandler<T>
174where166where
181 collection_id,173 collection_id,
182 data,174 data,
183 ..175 ..
184 } => Self::withdraw_create_item(who, collection_id, data),176 } => {
177 let (sponsor, collection) = load(*collection_id)?;
178 withdraw_create_item::<T>(&collection, who, data).map(|()| sponsor)
179 }
185 Call::transfer {180 Call::transfer {
186 collection_id,181 collection_id,
187 item_id,182 item_id,
188 ..183 ..
189 } => Self::withdraw_transfer(who, collection_id, item_id),184 }
185 | Call::transfer_from {
186 collection_id,
187 item_id,
188 ..
189 } => {
190 let (sponsor, collection) = load(*collection_id)?;
191 withdraw_transfer::<T>(&collection, who, item_id).map(|()| sponsor)
192 }
193 Call::approve {
194 collection_id,
195 item_id,
196 ..
197 } => {
198 let (sponsor, collection) = load(*collection_id)?;
199 withdraw_approve::<T>(&collection, who, item_id).map(|()| sponsor)
200 }
190 Call::set_variable_meta_data {201 Call::set_variable_meta_data {
191 collection_id,202 collection_id,
192 item_id,203 item_id,
193 data,204 data,
194 } => Self::withdraw_set_variable_meta_data(collection_id, item_id, data),205 } => {
206 let (sponsor, collection) = load(*collection_id)?;
207 withdraw_set_variable_meta_data::<T>(&collection, item_id, data).map(|()| sponsor)
208 }
195 _ => None,209 _ => None,
196 }210 }
197 }211 }
modifiedprimitives/evm-mapping/src/lib.rsdiffbeforeafterboth
4use sp_core::H160;4use sp_core::H160;
55
6/// Transforms substrate addresses to ethereum (Reverse of `EvmAddressMapping`)6/// Transforms substrate addresses to ethereum (Reverse of `EvmAddressMapping`)
7/// pallet_evm doesn't have this, as it only checks if eth address 7/// pallet_evm doesn't have this, as it only checks if eth address
8/// is owned by substrate via `EnsureAddressOrigin` trait8/// is owned by substrate via `EnsureAddressOrigin` trait
9/// 9///
10/// This trait implementations shouldn't conflict with used `EnsureAddressOrigin`10/// This trait implementations shouldn't conflict with used `EnsureAddressOrigin`
11pub trait EvmBackwardsAddressMapping<AccountId> {11pub trait EvmBackwardsAddressMapping<AccountId> {
12 fn from_account_id(account_id: AccountId) -> H160;12 fn from_account_id(account_id: AccountId) -> H160;