git.delta.rocks / unique-network / refs/commits / afa26fc3182d

difftreelog

refac: rename substrate methods to cross

Trubnikov Sergey2022-10-24parent: #7f98069.patch.diff
in: master

27 files changed

modifiedCargo.lockdiffbeforeafterboth
10771077
1078[[package]]1078[[package]]
1079name = "console"1079name = "console"
1080version = "0.15.1"1080version = "0.15.2"
1081source = "registry+https://github.com/rust-lang/crates.io-index"1081source = "registry+https://github.com/rust-lang/crates.io-index"
1082checksum = "89eab4d20ce20cea182308bca13088fecea9c05f6776cf287205d41a0ed3c847"1082checksum = "c050367d967ced717c04b65d8c619d863ef9292ce0c5760028655a2fb298718c"
1083dependencies = [1083dependencies = [
1084 "encode_unicode",1084 "encode_unicode",
1085 "lazy_static",
1085 "libc",1086 "libc",
1086 "once_cell",
1087 "terminal_size",1087 "terminal_size",
1088 "winapi",1088 "winapi",
1089]1089]
18711871
1872[[package]]1872[[package]]
1873name = "cxx"1873name = "cxx"
1874version = "1.0.79"1874version = "1.0.78"
1875source = "registry+https://github.com/rust-lang/crates.io-index"1875source = "registry+https://github.com/rust-lang/crates.io-index"
1876checksum = "3f83d0ebf42c6eafb8d7c52f7e5f2d3003b89c7aa4fd2b79229209459a849af8"1876checksum = "19f39818dcfc97d45b03953c1292efc4e80954e1583c4aa770bac1383e2310a4"
1877dependencies = [1877dependencies = [
1878 "cc",1878 "cc",
1879 "cxxbridge-flags",1879 "cxxbridge-flags",
18831883
1884[[package]]1884[[package]]
1885name = "cxx-build"1885name = "cxx-build"
1886version = "1.0.79"1886version = "1.0.78"
1887source = "registry+https://github.com/rust-lang/crates.io-index"1887source = "registry+https://github.com/rust-lang/crates.io-index"
1888checksum = "07d050484b55975889284352b0ffc2ecbda25c0c55978017c132b29ba0818a86"1888checksum = "3e580d70777c116df50c390d1211993f62d40302881e54d4b79727acb83d0199"
1889dependencies = [1889dependencies = [
1890 "cc",1890 "cc",
1891 "codespan-reporting",1891 "codespan-reporting",
18981898
1899[[package]]1899[[package]]
1900name = "cxxbridge-flags"1900name = "cxxbridge-flags"
1901version = "1.0.79"1901version = "1.0.78"
1902source = "registry+https://github.com/rust-lang/crates.io-index"1902source = "registry+https://github.com/rust-lang/crates.io-index"
1903checksum = "99d2199b00553eda8012dfec8d3b1c75fce747cf27c169a270b3b99e3448ab78"1903checksum = "56a46460b88d1cec95112c8c363f0e2c39afdb237f60583b0b36343bf627ea9c"
19041904
1905[[package]]1905[[package]]
1906name = "cxxbridge-macro"1906name = "cxxbridge-macro"
1907version = "1.0.79"1907version = "1.0.78"
1908source = "registry+https://github.com/rust-lang/crates.io-index"1908source = "registry+https://github.com/rust-lang/crates.io-index"
1909checksum = "dcb67a6de1f602736dd7eaead0080cf3435df806c61b24b13328db128c58868f"1909checksum = "747b608fecf06b0d72d440f27acc99288207324b793be2c17991839f3d4995ea"
1910dependencies = [1910dependencies = [
1911 "proc-macro2",1911 "proc-macro2",
1912 "quote",1912 "quote",
35613561
3562[[package]]3562[[package]]
3563name = "iana-time-zone-haiku"3563name = "iana-time-zone-haiku"
3564version = "0.1.1"3564version = "0.1.0"
3565source = "registry+https://github.com/rust-lang/crates.io-index"3565source = "registry+https://github.com/rust-lang/crates.io-index"
3566checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"3566checksum = "fde6edd6cef363e9359ed3c98ba64590ba9eecba2293eb5a723ab32aee8926aa"
3567dependencies = [3567dependencies = [
3568 "cxx",3568 "cxx",
3569 "cxx-build",3569 "cxx-build",
1077410774
10775[[package]]10775[[package]]
10776name = "serde_json"10776name = "serde_json"
10777version = "1.0.87"10777version = "1.0.86"
10778source = "registry+https://github.com/rust-lang/crates.io-index"10778source = "registry+https://github.com/rust-lang/crates.io-index"
10779checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45"10779checksum = "41feea4228a6f1cd09ec7a3593a682276702cd67b5273544757dae23c096f074"
10780dependencies = [10780dependencies = [
10781 "itoa",10781 "itoa",
10782 "ryu",10782 "ryu",
1205512055
12056[[package]]12056[[package]]
12057name = "syn"12057name = "syn"
12058version = "1.0.103"12058version = "1.0.102"
12059source = "registry+https://github.com/rust-lang/crates.io-index"12059source = "registry+https://github.com/rust-lang/crates.io-index"
12060checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"12060checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
12061dependencies = [12061dependencies = [
12062 "proc-macro2",12062 "proc-macro2",
12063 "quote",12063 "quote",
modifiedpallets/common/src/erc.rsdiffbeforeafterboth
34use crate::{34use crate::{
35 Pallet, CollectionHandle, Config, CollectionProperties, SelfWeightOf,35 Pallet, CollectionHandle, Config, CollectionProperties, SelfWeightOf,
36 eth::{36 eth::{
37 convert_cross_account_to_uint256, convert_uint256_to_cross_account,37 convert_cross_account_to_uint256, convert_cross_account_to_tuple,
38 convert_cross_account_to_tuple,38 convert_tuple_to_cross_account,
39 },39 },
40 weights::WeightInfo,40 weights::WeightInfo,
41};41};
139 save(self)139 save(self)
140 }140 }
141141
142 // TODO: Temprorary off. Need refactor
143 // /// Set the substrate sponsor of the collection.142 /// Set the sponsor of the collection.
144 // ///143 ///
145 // /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.144 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
146 // ///145 ///
147 // /// @param sponsor Substrate address of the sponsor from whose account funds will be debited for operations with the contract.146 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.
148 // fn set_collection_sponsor_substrate(147 fn set_collection_sponsor_cross(
149 // &mut self,148 &mut self,
150 // caller: caller,149 caller: caller,
151 // sponsor: uint256,150 sponsor: (address, uint256),
152 // ) -> Result<void> {151 ) -> Result<void> {
153 // self.consume_store_reads_and_writes(1, 1)?;152 self.consume_store_reads_and_writes(1, 1)?;
154153
155 // check_is_owner_or_admin(caller, self)?;154 check_is_owner_or_admin(caller, self)?;
156155
157 // let sponsor = convert_uint256_to_cross_account::<T>(sponsor);156 let sponsor = convert_tuple_to_cross_account::<T>(sponsor)?;
158 // self.set_sponsor(sponsor.as_sub().clone())157 self.set_sponsor(sponsor.as_sub().clone())
159 // .map_err(dispatch_to_evm::<T>)?;158 .map_err(dispatch_to_evm::<T>)?;
160 // save(self)159 save(self)
161 // }160 }
162161
163 /// Whether there is a pending sponsor.162 /// Whether there is a pending sponsor.
164 fn has_collection_pending_sponsor(&self) -> Result<bool> {163 fn has_collection_pending_sponsor(&self) -> Result<bool> {
300 Ok(crate::eth::collection_id_to_address(self.id))299 Ok(crate::eth::collection_id_to_address(self.id))
301 }300 }
302301
303 // TODO: Temprorary off. Need refactor
304 // /// Add collection admin by substrate address.302 /// Add collection admin.
305 // /// @param newAdmin Substrate administrator address.303 /// @param newAdmin Cross account administrator address.
306 // fn add_collection_admin_substrate(304 fn add_collection_admin_cross(
307 // &mut self,305 &mut self,
308 // caller: caller,306 caller: caller,
309 // new_admin: uint256,307 new_admin: (address, uint256),
310 // ) -> Result<void> {308 ) -> Result<void> {
311 // self.consume_store_writes(2)?;309 self.consume_store_writes(2)?;
312310
313 // let caller = T::CrossAccountId::from_eth(caller);311 let caller = T::CrossAccountId::from_eth(caller);
314 // let new_admin = convert_uint256_to_cross_account::<T>(new_admin);312 let new_admin = convert_tuple_to_cross_account::<T>(new_admin)?;
315 // <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;313 <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;
316 // Ok(())314 Ok(())
317 // }315 }
318316
319 // TODO: Temprorary off. Need refactor
320 // /// Remove collection admin by substrate address.317 /// Remove collection admin.
321 // /// @param admin Substrate administrator address.318 /// @param admin Cross account administrator address.
322 // fn remove_collection_admin_substrate(319 fn remove_collection_admin_cross(
323 // &mut self,320 &mut self,
324 // caller: caller,321 caller: caller,
325 // admin: uint256,322 admin: (address, uint256),
326 // ) -> Result<void> {323 ) -> Result<void> {
327 // self.consume_store_writes(2)?;324 self.consume_store_writes(2)?;
328325
329 // let caller = T::CrossAccountId::from_eth(caller);326 let caller = T::CrossAccountId::from_eth(caller);
330 // let admin = convert_uint256_to_cross_account::<T>(admin);327 let admin = convert_tuple_to_cross_account::<T>(admin)?;
331 // <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;328 <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;
332 // Ok(())329 Ok(())
333 // }330 }
334331
335 /// Add collection admin.332 /// Add collection admin.
336 /// @param newAdmin Address of the added administrator.333 /// @param newAdmin Address of the added administrator.
479 Ok(())476 Ok(())
480 }477 }
481478
482 // TODO: Temprorary off. Need refactor
483 // /// Add substrate user to allowed list.479 /// Add user to allowed list.
484 // ///480 ///
485 // /// @param user User substrate address.481 /// @param user User cross account address.
486 // fn add_to_collection_allow_list_substrate(482 fn add_to_collection_allow_list_cross(
487 // &mut self,483 &mut self,
488 // caller: caller,484 caller: caller,
489 // user: uint256,485 user: (address, uint256),
490 // ) -> Result<void> {486 ) -> Result<void> {
491 // self.consume_store_writes(1)?;487 self.consume_store_writes(1)?;
492488
493 // let caller = T::CrossAccountId::from_eth(caller);489 let caller = T::CrossAccountId::from_eth(caller);
494 // let user = convert_uint256_to_cross_account::<T>(user);490 let user = convert_tuple_to_cross_account::<T>(user)?;
495 // Pallet::<T>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;491 Pallet::<T>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;
496 // Ok(())492 Ok(())
497 // }493 }
498494
499 /// Remove the user from the allowed list.495 /// Remove the user from the allowed list.
500 ///496 ///
508 Ok(())504 Ok(())
509 }505 }
510506
511 // TODO: Temprorary off. Need refactor
512 // /// Remove substrate user from allowed list.507 /// Remove user from allowed list.
513 // ///508 ///
514 // /// @param user User substrate address.509 /// @param user User cross account address.
515 // fn remove_from_collection_allow_list_substrate(510 fn remove_from_collection_allow_list_cross(
516 // &mut self,511 &mut self,
517 // caller: caller,512 caller: caller,
518 // user: uint256,513 user: (address, uint256),
519 // ) -> Result<void> {514 ) -> Result<void> {
520 // self.consume_store_writes(1)?;515 self.consume_store_writes(1)?;
521516
522 // let caller = T::CrossAccountId::from_eth(caller);517 let caller = T::CrossAccountId::from_eth(caller);
523 // let user = convert_uint256_to_cross_account::<T>(user);518 let user = convert_tuple_to_cross_account::<T>(user)?;
524 // Pallet::<T>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;519 Pallet::<T>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;
525 // Ok(())520 Ok(())
526 // }521 }
527522
528 /// Switch permission for minting.523 /// Switch permission for minting.
529 ///524 ///
556 Ok(self.is_owner_or_admin(&user))551 Ok(self.is_owner_or_admin(&user))
557 }552 }
558553
559 // TODO: Temprorary off. Need refactor
560 // /// Check that substrate account is the owner or admin of the collection554 /// Check that account is the owner or admin of the collection
561 // ///555 ///
562 // /// @param user account to verify556 /// @param user User cross account to verify
563 // /// @return "true" if account is the owner or admin557 /// @return "true" if account is the owner or admin
564 // fn is_owner_or_admin_substrate(&self, user: uint256) -> Result<bool> {558 fn is_owner_or_admin_cross(&self, user: (address, uint256)) -> Result<bool> {
565 // let user = convert_uint256_to_cross_account::<T>(user);559 let user = convert_tuple_to_cross_account::<T>(user)?;
566 // Ok(self.is_owner_or_admin(&user))560 Ok(self.is_owner_or_admin(&user))
567 // }561 }
568562
569 /// Returns collection type563 /// Returns collection type
570 ///564 ///
580574
581 /// Get collection owner.575 /// Get collection owner.
582 ///576 ///
583 /// @return Tuple with sponsor address and his substrate mirror.577 /// @return Tuble with sponsor address and his substrate mirror.
584 /// If address is canonical then substrate mirror is zero and vice versa.578 /// If address is canonical then substrate mirror is zero and vice versa.
585 fn collection_owner(&self) -> Result<(address, uint256)> {579 fn collection_owner(&self) -> Result<(address, uint256)> {
586 Ok(convert_cross_account_to_tuple::<T>(580 Ok(convert_cross_account_to_tuple::<T>(
602 .map_err(dispatch_to_evm::<T>)596 .map_err(dispatch_to_evm::<T>)
603 }597 }
604
605 // TODO: Temprorary off. Need refactor
606 // /// Changes collection owner to another substrate account
607 // ///
608 // /// @dev Owner can be changed only by current owner
609 // /// @param newOwner new owner substrate account
610 // fn set_owner_substrate(&mut self, caller: caller, new_owner: uint256) -> Result<void> {
611 // self.consume_store_writes(1)?;
612
613 // let caller = T::CrossAccountId::from_eth(caller);
614 // let new_owner = convert_uint256_to_cross_account::<T>(new_owner);
615 // self.set_owner_internal(caller, new_owner)
616 // .map_err(dispatch_to_evm::<T>)
617 // }
618598
619 /// Get collection administrators599 /// Get collection administrators
620 ///600 ///
627 Ok(result)607 Ok(result)
628 }608 }
609
610 /// Changes collection owner to another account
611 ///
612 /// @dev Owner can be changed only by current owner
613 /// @param newOwner new owner cross account
614 fn set_owner_cross(&mut self, caller: caller, new_owner: (address, uint256)) -> Result<void> {
615 self.consume_store_writes(1)?;
616
617 let caller = T::CrossAccountId::from_eth(caller);
618 let new_owner = convert_tuple_to_cross_account::<T>(new_owner)?;
619 self.set_owner_internal(caller, new_owner)
620 .map_err(dispatch_to_evm::<T>)
621 }
629}622}
630623
631/// ### Note624/// ### Note
modifiedpallets/common/src/eth.rsdiffbeforeafterboth
86 }86 }
87}87}
88
89/// Convert tuple `(address, uint256)` to `CrossAccountId`.
90///
91/// If `address` in the tuple has *default* value, then the canonical form is substrate,
92/// if `uint256` has *default* value, then the ethereum form is canonical,
93/// if both values are *default* or *non default*, then this is considered an invalid address and `Error` is returned.
94pub fn convert_tuple_to_cross_account<T: Config>(
95 eth_cross_account_id: (address, uint256),
96) -> evm_coder::execution::Result<T::CrossAccountId>
97where
98 T::AccountId: From<[u8; 32]>,
99{
100 if eth_cross_account_id == Default::default() {
101 Err("All fields of cross account is zeroed".into())
102 } else if eth_cross_account_id.0 == Default::default() {
103 Ok(convert_uint256_to_cross_account::<T>(
104 eth_cross_account_id.1,
105 ))
106 } else if eth_cross_account_id.1 == Default::default() {
107 Ok(T::CrossAccountId::from_eth(eth_cross_account_id.0))
108 } else {
109 Err("All fields of cross account is non zeroed".into())
110 }
111}
88112
modifiedpallets/fungible/src/erc.rsdiffbeforeafterboth
19use core::char::{REPLACEMENT_CHARACTER, decode_utf16};19use core::char::{REPLACEMENT_CHARACTER, decode_utf16};
20use core::convert::TryInto;20use core::convert::TryInto;
21use evm_coder::{ToLog, execution::*, generate_stubgen, solidity_interface, types::*, weight};21use evm_coder::{ToLog, execution::*, generate_stubgen, solidity_interface, types::*, weight};
22use pallet_common::eth::convert_tuple_to_cross_account;
22use up_data_structs::CollectionMode;23use up_data_structs::CollectionMode;
23use pallet_common::erc::{CommonEvmHandler, PrecompileResult};24use pallet_common::erc::{CommonEvmHandler, PrecompileResult};
24use sp_std::vec::Vec;25use sp_std::vec::Vec;
150151
151#[solidity_interface(name = ERC20UniqueExtensions)]152#[solidity_interface(name = ERC20UniqueExtensions)]
152impl<T: Config> FungibleHandle<T> {153impl<T: Config> FungibleHandle<T>
154where
155 T::AccountId: From<[u8; 32]>,
156{
157 #[weight(<SelfWeightOf<T>>::approve())]
158 fn approve_cross(
159 &mut self,
160 caller: caller,
161 spender: (address, uint256),
162 amount: uint256,
163 ) -> Result<bool> {
164 let caller = T::CrossAccountId::from_eth(caller);
165 let spender = convert_tuple_to_cross_account::<T>(spender)?;
166 let amount = amount.try_into().map_err(|_| "amount overflow")?;
167
168 <Pallet<T>>::set_allowance(self, &caller, &spender, amount)
169 .map_err(dispatch_to_evm::<T>)?;
170 Ok(true)
171 }
172
153 /// Burn tokens from account173 /// Burn tokens from account
154 /// @dev Function that burns an `amount` of the tokens of a given account,174 /// @dev Function that burns an `amount` of the tokens of a given account,
169 Ok(true)189 Ok(true)
170 }190 }
191
192 /// Burn tokens from account
193 /// @dev Function that burns an `amount` of the tokens of a given account,
194 /// deducting from the sender's allowance for said account.
195 /// @param from The account whose tokens will be burnt.
196 /// @param amount The amount that will be burnt.
197 #[weight(<SelfWeightOf<T>>::burn_from())]
198 fn burn_from_cross(
199 &mut self,
200 caller: caller,
201 from: (address, uint256),
202 amount: uint256,
203 ) -> Result<bool> {
204 let caller = T::CrossAccountId::from_eth(caller);
205 let from = convert_tuple_to_cross_account::<T>(from)?;
206 let amount = amount.try_into().map_err(|_| "amount overflow")?;
207 let budget = self
208 .recorder
209 .weight_calls_budget(<StructureWeight<T>>::find_parent());
210
211 <Pallet<T>>::burn_from(self, &caller, &from, amount, &budget)
212 .map_err(dispatch_to_evm::<T>)?;
213 Ok(true)
214 }
171215
172 /// Mint tokens for multiple accounts.216 /// Mint tokens for multiple accounts.
173 /// @param amounts array of pairs of account address and amount217 /// @param amounts array of pairs of account address and amount
192 Ok(true)236 Ok(true)
193 }237 }
238
239 #[weight(<SelfWeightOf<T>>::transfer_from())]
240 fn transfer_from_cross(
241 &mut self,
242 caller: caller,
243 from: (address, uint256),
244 to: (address, uint256),
245 amount: uint256,
246 ) -> Result<bool> {
247 let caller = T::CrossAccountId::from_eth(caller);
248 let from = convert_tuple_to_cross_account::<T>(from)?;
249 let to = convert_tuple_to_cross_account::<T>(to)?;
250 let amount = amount.try_into().map_err(|_| "amount overflow")?;
251 let budget = self
252 .recorder
253 .weight_calls_budget(<StructureWeight<T>>::find_parent());
254
255 <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)
256 .map_err(dispatch_to_evm::<T>)?;
257 Ok(true)
258 }
194}259}
195260
196#[solidity_interface(261#[solidity_interface(
modifiedpallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth
18}18}
1919
20/// @title A contract that allows you to work with collections.20/// @title A contract that allows you to work with collections.
21/// @dev the ERC-165 identifier for this interface is 0x3af103fb21/// @dev the ERC-165 identifier for this interface is 0x25d897dc
22contract Collection is Dummy, ERC165 {22contract Collection is Dummy, ERC165 {
23 /// Set collection property.23 /// Set collection property.
24 ///24 ///
72 dummy = 0;72 dummy = 0;
73 }73 }
74
75 /// Set the sponsor of the collection.
76 ///
77 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
78 ///
79 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.
80 /// @dev EVM selector for this function is: 0x84a1d5a8,
81 /// or in textual repr: setCollectionSponsorCross((address,uint256))
82 function setCollectionSponsorCross(Tuple6 memory sponsor) public {
83 require(false, stub_error);
84 sponsor;
85 dummy = 0;
86 }
7487
75 /// Whether there is a pending sponsor.88 /// Whether there is a pending sponsor.
76 /// @dev EVM selector for this function is: 0x058ac185,89 /// @dev EVM selector for this function is: 0x058ac185,
154 return 0x0000000000000000000000000000000000000000;167 return 0x0000000000000000000000000000000000000000;
155 }168 }
169
170 /// Add collection admin.
171 /// @param newAdmin Cross account administrator address.
172 /// @dev EVM selector for this function is: 0x859aa7d6,
173 /// or in textual repr: addCollectionAdminCross((address,uint256))
174 function addCollectionAdminCross(Tuple6 memory newAdmin) public {
175 require(false, stub_error);
176 newAdmin;
177 dummy = 0;
178 }
179
180 /// Remove collection admin.
181 /// @param admin Cross account administrator address.
182 /// @dev EVM selector for this function is: 0x6c0cd173,
183 /// or in textual repr: removeCollectionAdminCross((address,uint256))
184 function removeCollectionAdminCross(Tuple6 memory admin) public {
185 require(false, stub_error);
186 admin;
187 dummy = 0;
188 }
156189
157 /// Add collection admin.190 /// Add collection admin.
158 /// @param newAdmin Address of the added administrator.191 /// @param newAdmin Address of the added administrator.
234 dummy = 0;267 dummy = 0;
235 }268 }
269
270 /// Add user to allowed list.
271 ///
272 /// @param user User cross account address.
273 /// @dev EVM selector for this function is: 0xa0184a3a,
274 /// or in textual repr: addToCollectionAllowListCross((address,uint256))
275 function addToCollectionAllowListCross(Tuple6 memory user) public {
276 require(false, stub_error);
277 user;
278 dummy = 0;
279 }
236280
237 /// Remove the user from the allowed list.281 /// Remove the user from the allowed list.
238 ///282 ///
245 dummy = 0;289 dummy = 0;
246 }290 }
291
292 /// Remove user from allowed list.
293 ///
294 /// @param user User cross account address.
295 /// @dev EVM selector for this function is: 0x09ba452a,
296 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))
297 function removeFromCollectionAllowListCross(Tuple6 memory user) public {
298 require(false, stub_error);
299 user;
300 dummy = 0;
301 }
247302
248 /// Switch permission for minting.303 /// Switch permission for minting.
249 ///304 ///
269 return false;324 return false;
270 }325 }
326
327 /// Check that account is the owner or admin of the collection
328 ///
329 /// @param user User cross account to verify
330 /// @return "true" if account is the owner or admin
331 /// @dev EVM selector for this function is: 0x3e75a905,
332 /// or in textual repr: isOwnerOrAdminCross((address,uint256))
333 function isOwnerOrAdminCross(Tuple6 memory user) public view returns (bool) {
334 require(false, stub_error);
335 user;
336 dummy;
337 return false;
338 }
271339
272 /// Returns collection type340 /// Returns collection type
273 ///341 ///
282350
283 /// Get collection owner.351 /// Get collection owner.
284 ///352 ///
285 /// @return Tuple with sponsor address and his substrate mirror.353 /// @return Tuble with sponsor address and his substrate mirror.
286 /// If address is canonical then substrate mirror is zero and vice versa.354 /// If address is canonical then substrate mirror is zero and vice versa.
287 /// @dev EVM selector for this function is: 0xdf727d3b,355 /// @dev EVM selector for this function is: 0xdf727d3b,
288 /// or in textual repr: collectionOwner()356 /// or in textual repr: collectionOwner()
316 return new Tuple6[](0);384 return new Tuple6[](0);
317 }385 }
386
387 /// Changes collection owner to another account
388 ///
389 /// @dev Owner can be changed only by current owner
390 /// @param newOwner new owner cross account
391 /// @dev EVM selector for this function is: 0xe5c9913f,
392 /// or in textual repr: setOwnerCross((address,uint256))
393 function setOwnerCross(Tuple6 memory newOwner) public {
394 require(false, stub_error);
395 newOwner;
396 dummy = 0;
397 }
318}398}
319399
320/// @dev the ERC-165 identifier for this interface is 0x63034ac5400/// @dev the ERC-165 identifier for this interface is 0x032e5926
321contract ERC20UniqueExtensions is Dummy, ERC165 {401contract ERC20UniqueExtensions is Dummy, ERC165 {
402 /// @dev EVM selector for this function is: 0x0ecd0ab0,
403 /// or in textual repr: approveCross((address,uint256),uint256)
404 function approveCross(Tuple6 memory spender, uint256 amount) public returns (bool) {
405 require(false, stub_error);
406 spender;
407 amount;
408 dummy = 0;
409 return false;
410 }
411
322 /// Burn tokens from account412 /// Burn tokens from account
323 /// @dev Function that burns an `amount` of the tokens of a given account,413 /// @dev Function that burns an `amount` of the tokens of a given account,
334 return false;424 return false;
335 }425 }
426
427 /// Burn tokens from account
428 /// @dev Function that burns an `amount` of the tokens of a given account,
429 /// deducting from the sender's allowance for said account.
430 /// @param from The account whose tokens will be burnt.
431 /// @param amount The amount that will be burnt.
432 /// @dev EVM selector for this function is: 0xbb2f5a58,
433 /// or in textual repr: burnFromCross((address,uint256),uint256)
434 function burnFromCross(Tuple6 memory from, uint256 amount) public returns (bool) {
435 require(false, stub_error);
436 from;
437 amount;
438 dummy = 0;
439 return false;
440 }
336441
337 /// Mint tokens for multiple accounts.442 /// Mint tokens for multiple accounts.
338 /// @param amounts array of pairs of account address and amount443 /// @param amounts array of pairs of account address and amount
345 return false;450 return false;
346 }451 }
452
453 /// @dev EVM selector for this function is: 0xd5cf430b,
454 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)
455 function transferFromCross(
456 Tuple6 memory from,
457 Tuple6 memory to,
458 uint256 amount
459 ) public returns (bool) {
460 require(false, stub_error);
461 from;
462 to;
463 amount;
464 dummy = 0;
465 return false;
466 }
347}467}
348468
349/// @dev anonymous struct469/// @dev anonymous struct
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
35use pallet_common::{35use pallet_common::{
36 erc::{CommonEvmHandler, PrecompileResult, CollectionCall, static_property::key},36 erc::{CommonEvmHandler, PrecompileResult, CollectionCall, static_property::key},
37 CollectionHandle, CollectionPropertyPermissions,37 CollectionHandle, CollectionPropertyPermissions,
38 eth::convert_tuple_to_cross_account,
38};39};
39use pallet_evm::{account::CrossAccountId, PrecompileHandle};40use pallet_evm::{account::CrossAccountId, PrecompileHandle};
40use pallet_evm_coder_substrate::call;41use pallet_evm_coder_substrate::call;
199/// @dev See https://eips.ethereum.org/EIPS/eip-721200/// @dev See https://eips.ethereum.org/EIPS/eip-721
200#[solidity_interface(name = ERC721Metadata, expect_selector = 0x5b5e139f)]201#[solidity_interface(name = ERC721Metadata, expect_selector = 0x5b5e139f)]
201impl<T: Config> NonfungibleHandle<T> {202impl<T: Config> NonfungibleHandle<T>
203where
204 T::AccountId: From<[u8; 32]>,
205{
202 /// @notice A descriptive name for a collection of NFTs in this contract206 /// @notice A descriptive name for a collection of NFTs in this contract
203 /// @dev real implementation of this function lies in `ERC721UniqueExtensions`207 /// @dev real implementation of this function lies in `ERC721UniqueExtensions`
604/// @title Unique extensions for ERC721.608/// @title Unique extensions for ERC721.
605#[solidity_interface(name = ERC721UniqueExtensions)]609#[solidity_interface(name = ERC721UniqueExtensions)]
606impl<T: Config> NonfungibleHandle<T> {610impl<T: Config> NonfungibleHandle<T>
611where
612 T::AccountId: From<[u8; 32]>,
613{
607 /// @notice A descriptive name for a collection of NFTs in this contract614 /// @notice A descriptive name for a collection of NFTs in this contract
608 fn name(&self) -> Result<string> {615 fn name(&self) -> Result<string> {
616 Ok(string::from_utf8_lossy(&self.token_prefix).into())623 Ok(string::from_utf8_lossy(&self.token_prefix).into())
617 }624 }
625
626 /// @notice Set or reaffirm the approved address for an NFT
627 /// @dev The zero address indicates there is no approved address.
628 /// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized
629 /// operator of the current owner.
630 /// @param approved The new substrate address approved NFT controller
631 /// @param tokenId The NFT to approve
632 #[weight(<SelfWeightOf<T>>::approve())]
633 fn approve_cross(
634 &mut self,
635 caller: caller,
636 approved: (address, uint256),
637 token_id: uint256,
638 ) -> Result<void> {
639 let caller = T::CrossAccountId::from_eth(caller);
640 let approved = convert_tuple_to_cross_account::<T>(approved)?;
641 let token = token_id.try_into()?;
642
643 <Pallet<T>>::set_allowance(self, &caller, token, Some(&approved))
644 .map_err(dispatch_to_evm::<T>)?;
645 Ok(())
646 }
618647
619 /// @notice Transfer ownership of an NFT648 /// @notice Transfer ownership of an NFT
620 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`649 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`
634 Ok(())663 Ok(())
635 }664 }
665
666 /// @notice Transfer ownership of an NFT from cross account address to cross account address
667 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`
668 /// is the zero address. Throws if `tokenId` is not a valid NFT.
669 /// @param from Cross acccount address of current owner
670 /// @param to Cross acccount address of new owner
671 /// @param tokenId The NFT to transfer
672 #[weight(<SelfWeightOf<T>>::transfer())]
673 fn transfer_from_cross(
674 &mut self,
675 caller: caller,
676 from: (address, uint256),
677 to: (address, uint256),
678 token_id: uint256,
679 ) -> Result<void> {
680 let caller = T::CrossAccountId::from_eth(caller);
681 let from = convert_tuple_to_cross_account::<T>(from)?;
682 let to = convert_tuple_to_cross_account::<T>(to)?;
683 let token_id = token_id.try_into()?;
684 let budget = self
685 .recorder
686 .weight_calls_budget(<StructureWeight<T>>::find_parent());
687 Pallet::<T>::transfer_from(self, &caller, &from, &to, token_id, &budget)
688 .map_err(dispatch_to_evm::<T>)?;
689 Ok(())
690 }
636691
637 /// @notice Burns a specific ERC721 token.692 /// @notice Burns a specific ERC721 token.
638 /// @dev Throws unless `msg.sender` is the current owner or an authorized693 /// @dev Throws unless `msg.sender` is the current owner or an authorized
654 Ok(())709 Ok(())
655 }710 }
711
712 /// @notice Burns a specific ERC721 token.
713 /// @dev Throws unless `msg.sender` is the current owner or an authorized
714 /// operator for this NFT. Throws if `from` is not the current owner. Throws
715 /// if `to` is the zero address. Throws if `tokenId` is not a valid NFT.
716 /// @param from The current owner of the NFT
717 /// @param tokenId The NFT to transfer
718 #[weight(<SelfWeightOf<T>>::burn_from())]
719 fn burn_from_cross(
720 &mut self,
721 caller: caller,
722 from: (address, uint256),
723 token_id: uint256,
724 ) -> Result<void> {
725 let caller = T::CrossAccountId::from_eth(caller);
726 let from = convert_tuple_to_cross_account::<T>(from)?;
727 let token = token_id.try_into()?;
728 let budget = self
729 .recorder
730 .weight_calls_budget(<StructureWeight<T>>::find_parent());
731
732 <Pallet<T>>::burn_from(self, &caller, &from, token, &budget)
733 .map_err(dispatch_to_evm::<T>)?;
734 Ok(())
735 }
656736
657 /// @notice Returns next free NFT ID.737 /// @notice Returns next free NFT ID.
658 fn next_token_id(&self) -> Result<uint256> {738 fn next_token_id(&self) -> Result<uint256> {
modifiedpallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
91}91}
9292
93/// @title A contract that allows you to work with collections.93/// @title A contract that allows you to work with collections.
94/// @dev the ERC-165 identifier for this interface is 0x3af103fb94/// @dev the ERC-165 identifier for this interface is 0x25d897dc
95contract Collection is Dummy, ERC165 {95contract Collection is Dummy, ERC165 {
96 /// Set collection property.96 /// Set collection property.
97 ///97 ///
145 dummy = 0;145 dummy = 0;
146 }146 }
147
148 /// Set the sponsor of the collection.
149 ///
150 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
151 ///
152 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.
153 /// @dev EVM selector for this function is: 0x84a1d5a8,
154 /// or in textual repr: setCollectionSponsorCross((address,uint256))
155 function setCollectionSponsorCross(Tuple6 memory sponsor) public {
156 require(false, stub_error);
157 sponsor;
158 dummy = 0;
159 }
147160
148 /// Whether there is a pending sponsor.161 /// Whether there is a pending sponsor.
149 /// @dev EVM selector for this function is: 0x058ac185,162 /// @dev EVM selector for this function is: 0x058ac185,
177 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.190 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
178 /// @dev EVM selector for this function is: 0x6ec0a9f1,191 /// @dev EVM selector for this function is: 0x6ec0a9f1,
179 /// or in textual repr: collectionSponsor()192 /// or in textual repr: collectionSponsor()
180 function collectionSponsor() public view returns (Tuple17 memory) {193 function collectionSponsor() public view returns (Tuple6 memory) {
181 require(false, stub_error);194 require(false, stub_error);
182 dummy;195 dummy;
183 return Tuple17(0x0000000000000000000000000000000000000000, 0);196 return Tuple6(0x0000000000000000000000000000000000000000, 0);
184 }197 }
185198
186 /// Set limits for the collection.199 /// Set limits for the collection.
227 return 0x0000000000000000000000000000000000000000;240 return 0x0000000000000000000000000000000000000000;
228 }241 }
242
243 /// Add collection admin.
244 /// @param newAdmin Cross account administrator address.
245 /// @dev EVM selector for this function is: 0x859aa7d6,
246 /// or in textual repr: addCollectionAdminCross((address,uint256))
247 function addCollectionAdminCross(Tuple6 memory newAdmin) public {
248 require(false, stub_error);
249 newAdmin;
250 dummy = 0;
251 }
252
253 /// Remove collection admin.
254 /// @param admin Cross account administrator address.
255 /// @dev EVM selector for this function is: 0x6c0cd173,
256 /// or in textual repr: removeCollectionAdminCross((address,uint256))
257 function removeCollectionAdminCross(Tuple6 memory admin) public {
258 require(false, stub_error);
259 admin;
260 dummy = 0;
261 }
229262
230 /// Add collection admin.263 /// Add collection admin.
231 /// @param newAdmin Address of the added administrator.264 /// @param newAdmin Address of the added administrator.
307 dummy = 0;340 dummy = 0;
308 }341 }
342
343 /// Add user to allowed list.
344 ///
345 /// @param user User cross account address.
346 /// @dev EVM selector for this function is: 0xa0184a3a,
347 /// or in textual repr: addToCollectionAllowListCross((address,uint256))
348 function addToCollectionAllowListCross(Tuple6 memory user) public {
349 require(false, stub_error);
350 user;
351 dummy = 0;
352 }
309353
310 /// Remove the user from the allowed list.354 /// Remove the user from the allowed list.
311 ///355 ///
318 dummy = 0;362 dummy = 0;
319 }363 }
364
365 /// Remove user from allowed list.
366 ///
367 /// @param user User cross account address.
368 /// @dev EVM selector for this function is: 0x09ba452a,
369 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))
370 function removeFromCollectionAllowListCross(Tuple6 memory user) public {
371 require(false, stub_error);
372 user;
373 dummy = 0;
374 }
320375
321 /// Switch permission for minting.376 /// Switch permission for minting.
322 ///377 ///
342 return false;397 return false;
343 }398 }
399
400 /// Check that account is the owner or admin of the collection
401 ///
402 /// @param user User cross account to verify
403 /// @return "true" if account is the owner or admin
404 /// @dev EVM selector for this function is: 0x3e75a905,
405 /// or in textual repr: isOwnerOrAdminCross((address,uint256))
406 function isOwnerOrAdminCross(Tuple6 memory user) public view returns (bool) {
407 require(false, stub_error);
408 user;
409 dummy;
410 return false;
411 }
344412
345 /// Returns collection type413 /// Returns collection type
346 ///414 ///
355423
356 /// Get collection owner.424 /// Get collection owner.
357 ///425 ///
358 /// @return Tuple with sponsor address and his substrate mirror.426 /// @return Tuble with sponsor address and his substrate mirror.
359 /// If address is canonical then substrate mirror is zero and vice versa.427 /// If address is canonical then substrate mirror is zero and vice versa.
360 /// @dev EVM selector for this function is: 0xdf727d3b,428 /// @dev EVM selector for this function is: 0xdf727d3b,
361 /// or in textual repr: collectionOwner()429 /// or in textual repr: collectionOwner()
362 function collectionOwner() public view returns (Tuple17 memory) {430 function collectionOwner() public view returns (Tuple6 memory) {
363 require(false, stub_error);431 require(false, stub_error);
364 dummy;432 dummy;
365 return Tuple17(0x0000000000000000000000000000000000000000, 0);433 return Tuple6(0x0000000000000000000000000000000000000000, 0);
366 }434 }
367435
368 /// Changes collection owner to another account436 /// Changes collection owner to another account
383 /// If address is canonical then substrate mirror is zero and vice versa.451 /// If address is canonical then substrate mirror is zero and vice versa.
384 /// @dev EVM selector for this function is: 0x5813216b,452 /// @dev EVM selector for this function is: 0x5813216b,
385 /// or in textual repr: collectionAdmins()453 /// or in textual repr: collectionAdmins()
386 function collectionAdmins() public view returns (Tuple17[] memory) {454 function collectionAdmins() public view returns (Tuple6[] memory) {
387 require(false, stub_error);455 require(false, stub_error);
388 dummy;456 dummy;
389 return new Tuple17[](0);457 return new Tuple6[](0);
390 }458 }
459
460 /// Changes collection owner to another account
461 ///
462 /// @dev Owner can be changed only by current owner
463 /// @param newOwner new owner cross account
464 /// @dev EVM selector for this function is: 0xe5c9913f,
465 /// or in textual repr: setOwnerCross((address,uint256))
466 function setOwnerCross(Tuple6 memory newOwner) public {
467 require(false, stub_error);
468 newOwner;
469 dummy = 0;
470 }
391}471}
392
393/// @dev anonymous struct
394struct Tuple17 {
395 address field_0;
396 uint256 field_1;
397}
398472
399/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension473/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
400/// @dev See https://eips.ethereum.org/EIPS/eip-721474/// @dev See https://eips.ethereum.org/EIPS/eip-721
540}614}
541615
542/// @title Unique extensions for ERC721.616/// @title Unique extensions for ERC721.
543/// @dev the ERC-165 identifier for this interface is 0x4468500d617/// @dev the ERC-165 identifier for this interface is 0x244543ee
544contract ERC721UniqueExtensions is Dummy, ERC165 {618contract ERC721UniqueExtensions is Dummy, ERC165 {
545 /// @notice A descriptive name for a collection of NFTs in this contract619 /// @notice A descriptive name for a collection of NFTs in this contract
546 /// @dev EVM selector for this function is: 0x06fdde03,620 /// @dev EVM selector for this function is: 0x06fdde03,
560 return "";634 return "";
561 }635 }
636
637 /// @notice Set or reaffirm the approved address for an NFT
638 /// @dev The zero address indicates there is no approved address.
639 /// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized
640 /// operator of the current owner.
641 /// @param approved The new substrate address approved NFT controller
642 /// @param tokenId The NFT to approve
643 /// @dev EVM selector for this function is: 0x0ecd0ab0,
644 /// or in textual repr: approveCross((address,uint256),uint256)
645 function approveCross(Tuple6 memory approved, uint256 tokenId) public {
646 require(false, stub_error);
647 approved;
648 tokenId;
649 dummy = 0;
650 }
562651
563 /// @notice Transfer ownership of an NFT652 /// @notice Transfer ownership of an NFT
564 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`653 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`
574 dummy = 0;663 dummy = 0;
575 }664 }
665
666 /// @notice Transfer ownership of an NFT from cross account address to cross account address
667 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`
668 /// is the zero address. Throws if `tokenId` is not a valid NFT.
669 /// @param from Cross acccount address of current owner
670 /// @param to Cross acccount address of new owner
671 /// @param tokenId The NFT to transfer
672 /// @dev EVM selector for this function is: 0xd5cf430b,
673 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)
674 function transferFromCross(
675 Tuple6 memory from,
676 Tuple6 memory to,
677 uint256 tokenId
678 ) public {
679 require(false, stub_error);
680 from;
681 to;
682 tokenId;
683 dummy = 0;
684 }
576685
577 /// @notice Burns a specific ERC721 token.686 /// @notice Burns a specific ERC721 token.
578 /// @dev Throws unless `msg.sender` is the current owner or an authorized687 /// @dev Throws unless `msg.sender` is the current owner or an authorized
589 dummy = 0;698 dummy = 0;
590 }699 }
700
701 /// @notice Burns a specific ERC721 token.
702 /// @dev Throws unless `msg.sender` is the current owner or an authorized
703 /// operator for this NFT. Throws if `from` is not the current owner. Throws
704 /// if `to` is the zero address. Throws if `tokenId` is not a valid NFT.
705 /// @param from The current owner of the NFT
706 /// @param tokenId The NFT to transfer
707 /// @dev EVM selector for this function is: 0xbb2f5a58,
708 /// or in textual repr: burnFromCross((address,uint256),uint256)
709 function burnFromCross(Tuple6 memory from, uint256 tokenId) public {
710 require(false, stub_error);
711 from;
712 tokenId;
713 dummy = 0;
714 }
591715
592 /// @notice Returns next free NFT ID.716 /// @notice Returns next free NFT ID.
593 /// @dev EVM selector for this function is: 0x75794a3c,717 /// @dev EVM selector for this function is: 0x75794a3c,
619 // /// @param tokens array of pairs of token ID and token URI for minted tokens743 // /// @param tokens array of pairs of token ID and token URI for minted tokens
620 // /// @dev EVM selector for this function is: 0x36543006,744 // /// @dev EVM selector for this function is: 0x36543006,
621 // /// or in textual repr: mintBulkWithTokenURI(address,(uint256,string)[])745 // /// or in textual repr: mintBulkWithTokenURI(address,(uint256,string)[])
622 // function mintBulkWithTokenURI(address to, Tuple6[] memory tokens) public returns (bool) {746 // function mintBulkWithTokenURI(address to, Tuple8[] memory tokens) public returns (bool) {
623 // require(false, stub_error);747 // require(false, stub_error);
624 // to;748 // to;
625 // tokens;749 // tokens;
630}754}
631755
632/// @dev anonymous struct756/// @dev anonymous struct
633struct Tuple6 {757struct Tuple8 {
634 uint256 field_0;758 uint256 field_0;
635 string field_1;759 string field_1;
636}760}
761
762/// @dev anonymous struct
763struct Tuple6 {
764 address field_0;
765 uint256 field_1;
766}
637767
638/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension768/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
639/// @dev See https://eips.ethereum.org/EIPS/eip-721769/// @dev See https://eips.ethereum.org/EIPS/eip-721
modifiedpallets/refungible/src/erc.rsdiffbeforeafterboth
30use pallet_common::{30use pallet_common::{
31 CollectionHandle, CollectionPropertyPermissions,31 CollectionHandle, CollectionPropertyPermissions,
32 erc::{CommonEvmHandler, CollectionCall, static_property::key},32 erc::{CommonEvmHandler, CollectionCall, static_property::key},
33 eth::convert_tuple_to_cross_account,
33};34};
34use pallet_evm::{account::CrossAccountId, PrecompileHandle};35use pallet_evm::{account::CrossAccountId, PrecompileHandle};
35use pallet_evm_coder_substrate::{call, dispatch_to_evm};36use pallet_evm_coder_substrate::{call, dispatch_to_evm};
195196
196#[solidity_interface(name = ERC721Metadata)]197#[solidity_interface(name = ERC721Metadata)]
197impl<T: Config> RefungibleHandle<T> {198impl<T: Config> RefungibleHandle<T>
199where
200 T::AccountId: From<[u8; 32]>,
201{
198 /// @notice A descriptive name for a collection of NFTs in this contract202 /// @notice A descriptive name for a collection of NFTs in this contract
199 /// @dev real implementation of this function lies in `ERC721UniqueExtensions`203 /// @dev real implementation of this function lies in `ERC721UniqueExtensions`
632/// @title Unique extensions for ERC721.636/// @title Unique extensions for ERC721.
633#[solidity_interface(name = ERC721UniqueExtensions)]637#[solidity_interface(name = ERC721UniqueExtensions)]
634impl<T: Config> RefungibleHandle<T> {638impl<T: Config> RefungibleHandle<T>
639where
640 T::AccountId: From<[u8; 32]>,
641{
635 /// @notice A descriptive name for a collection of NFTs in this contract642 /// @notice A descriptive name for a collection of NFTs in this contract
636 fn name(&self) -> Result<string> {643 fn name(&self) -> Result<string> {
659 .recorder666 .recorder
660 .weight_calls_budget(<StructureWeight<T>>::find_parent());667 .weight_calls_budget(<StructureWeight<T>>::find_parent());
661668
662 let balance = balance(&self, token, &caller)?;669 let balance = balance(self, token, &caller)?;
663 ensure_single_owner(&self, token, balance)?;670 ensure_single_owner(self, token, balance)?;
664671
665 <Pallet<T>>::transfer(self, &caller, &to, token, balance, &budget)672 <Pallet<T>>::transfer(self, &caller, &to, token, balance, &budget)
666 .map_err(dispatch_to_evm::<T>)?;673 .map_err(dispatch_to_evm::<T>)?;
667 Ok(())674 Ok(())
668 }675 }
676
677 /// @notice Transfer ownership of an RFT
678 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`
679 /// is the zero address. Throws if `tokenId` is not a valid RFT.
680 /// Throws if RFT pieces have multiple owners.
681 /// @param to The new owner
682 /// @param tokenId The RFT to transfer
683 #[weight(<SelfWeightOf<T>>::transfer_creating_removing())]
684 fn transfer_from_cross(
685 &mut self,
686 caller: caller,
687 from: (address, uint256),
688 to: (address, uint256),
689 token_id: uint256,
690 ) -> Result<void> {
691 let caller = T::CrossAccountId::from_eth(caller);
692 let from = convert_tuple_to_cross_account::<T>(from)?;
693 let to = convert_tuple_to_cross_account::<T>(to)?;
694 let token_id = token_id.try_into()?;
695 let budget = self
696 .recorder
697 .weight_calls_budget(<StructureWeight<T>>::find_parent());
698
699 let balance = balance(self, token_id, &from)?;
700 ensure_single_owner(self, token_id, balance)?;
701
702 Pallet::<T>::transfer_from(self, &caller, &from, &to, token_id, balance, &budget)
703 .map_err(dispatch_to_evm::<T>)?;
704 Ok(())
705 }
669706
670 /// @notice Burns a specific ERC721 token.707 /// @notice Burns a specific ERC721 token.
671 /// @dev Throws unless `msg.sender` is the current owner or an authorized708 /// @dev Throws unless `msg.sender` is the current owner or an authorized
683 .recorder720 .recorder
684 .weight_calls_budget(<StructureWeight<T>>::find_parent());721 .weight_calls_budget(<StructureWeight<T>>::find_parent());
685722
686 let balance = balance(&self, token, &caller)?;723 let balance = balance(self, token, &from)?;
687 ensure_single_owner(&self, token, balance)?;724 ensure_single_owner(self, token, balance)?;
688725
689 <Pallet<T>>::burn_from(self, &caller, &from, token, balance, &budget)726 <Pallet<T>>::burn_from(self, &caller, &from, token, balance, &budget)
690 .map_err(dispatch_to_evm::<T>)?;727 .map_err(dispatch_to_evm::<T>)?;
691 Ok(())728 Ok(())
692 }729 }
730
731 /// @notice Burns a specific ERC721 token.
732 /// @dev Throws unless `msg.sender` is the current owner or an authorized
733 /// operator for this RFT. Throws if `from` is not the current owner. Throws
734 /// if `to` is the zero address. Throws if `tokenId` is not a valid RFT.
735 /// Throws if RFT pieces have multiple owners.
736 /// @param from The current owner of the RFT
737 /// @param tokenId The RFT to transfer
738 #[weight(<SelfWeightOf<T>>::burn_from())]
739 fn burn_from_cross(
740 &mut self,
741 caller: caller,
742 from: (address, uint256),
743 token_id: uint256,
744 ) -> Result<void> {
745 let caller = T::CrossAccountId::from_eth(caller);
746 let from = convert_tuple_to_cross_account::<T>(from)?;
747 let token = token_id.try_into()?;
748 let budget = self
749 .recorder
750 .weight_calls_budget(<StructureWeight<T>>::find_parent());
751
752 let balance = balance(self, token, &from)?;
753 ensure_single_owner(self, token, balance)?;
754
755 <Pallet<T>>::burn_from(self, &caller, &from, token, balance, &budget)
756 .map_err(dispatch_to_evm::<T>)?;
757 Ok(())
758 }
693759
694 /// @notice Returns next free RFT ID.760 /// @notice Returns next free RFT ID.
695 fn next_token_id(&self) -> Result<uint256> {761 fn next_token_id(&self) -> Result<uint256> {
modifiedpallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
91}91}
9292
93/// @title A contract that allows you to work with collections.93/// @title A contract that allows you to work with collections.
94/// @dev the ERC-165 identifier for this interface is 0x3af103fb94/// @dev the ERC-165 identifier for this interface is 0x25d897dc
95contract Collection is Dummy, ERC165 {95contract Collection is Dummy, ERC165 {
96 /// Set collection property.96 /// Set collection property.
97 ///97 ///
145 dummy = 0;145 dummy = 0;
146 }146 }
147
148 /// Set the sponsor of the collection.
149 ///
150 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
151 ///
152 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.
153 /// @dev EVM selector for this function is: 0x84a1d5a8,
154 /// or in textual repr: setCollectionSponsorCross((address,uint256))
155 function setCollectionSponsorCross(Tuple6 memory sponsor) public {
156 require(false, stub_error);
157 sponsor;
158 dummy = 0;
159 }
147160
148 /// Whether there is a pending sponsor.161 /// Whether there is a pending sponsor.
149 /// @dev EVM selector for this function is: 0x058ac185,162 /// @dev EVM selector for this function is: 0x058ac185,
177 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.190 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
178 /// @dev EVM selector for this function is: 0x6ec0a9f1,191 /// @dev EVM selector for this function is: 0x6ec0a9f1,
179 /// or in textual repr: collectionSponsor()192 /// or in textual repr: collectionSponsor()
180 function collectionSponsor() public view returns (Tuple17 memory) {193 function collectionSponsor() public view returns (Tuple6 memory) {
181 require(false, stub_error);194 require(false, stub_error);
182 dummy;195 dummy;
183 return Tuple17(0x0000000000000000000000000000000000000000, 0);196 return Tuple6(0x0000000000000000000000000000000000000000, 0);
184 }197 }
185198
186 /// Set limits for the collection.199 /// Set limits for the collection.
227 return 0x0000000000000000000000000000000000000000;240 return 0x0000000000000000000000000000000000000000;
228 }241 }
242
243 /// Add collection admin.
244 /// @param newAdmin Cross account administrator address.
245 /// @dev EVM selector for this function is: 0x859aa7d6,
246 /// or in textual repr: addCollectionAdminCross((address,uint256))
247 function addCollectionAdminCross(Tuple6 memory newAdmin) public {
248 require(false, stub_error);
249 newAdmin;
250 dummy = 0;
251 }
252
253 /// Remove collection admin.
254 /// @param admin Cross account administrator address.
255 /// @dev EVM selector for this function is: 0x6c0cd173,
256 /// or in textual repr: removeCollectionAdminCross((address,uint256))
257 function removeCollectionAdminCross(Tuple6 memory admin) public {
258 require(false, stub_error);
259 admin;
260 dummy = 0;
261 }
229262
230 /// Add collection admin.263 /// Add collection admin.
231 /// @param newAdmin Address of the added administrator.264 /// @param newAdmin Address of the added administrator.
307 dummy = 0;340 dummy = 0;
308 }341 }
342
343 /// Add user to allowed list.
344 ///
345 /// @param user User cross account address.
346 /// @dev EVM selector for this function is: 0xa0184a3a,
347 /// or in textual repr: addToCollectionAllowListCross((address,uint256))
348 function addToCollectionAllowListCross(Tuple6 memory user) public {
349 require(false, stub_error);
350 user;
351 dummy = 0;
352 }
309353
310 /// Remove the user from the allowed list.354 /// Remove the user from the allowed list.
311 ///355 ///
318 dummy = 0;362 dummy = 0;
319 }363 }
364
365 /// Remove user from allowed list.
366 ///
367 /// @param user User cross account address.
368 /// @dev EVM selector for this function is: 0x09ba452a,
369 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))
370 function removeFromCollectionAllowListCross(Tuple6 memory user) public {
371 require(false, stub_error);
372 user;
373 dummy = 0;
374 }
320375
321 /// Switch permission for minting.376 /// Switch permission for minting.
322 ///377 ///
342 return false;397 return false;
343 }398 }
399
400 /// Check that account is the owner or admin of the collection
401 ///
402 /// @param user User cross account to verify
403 /// @return "true" if account is the owner or admin
404 /// @dev EVM selector for this function is: 0x3e75a905,
405 /// or in textual repr: isOwnerOrAdminCross((address,uint256))
406 function isOwnerOrAdminCross(Tuple6 memory user) public view returns (bool) {
407 require(false, stub_error);
408 user;
409 dummy;
410 return false;
411 }
344412
345 /// Returns collection type413 /// Returns collection type
346 ///414 ///
355423
356 /// Get collection owner.424 /// Get collection owner.
357 ///425 ///
358 /// @return Tuple with sponsor address and his substrate mirror.426 /// @return Tuble with sponsor address and his substrate mirror.
359 /// If address is canonical then substrate mirror is zero and vice versa.427 /// If address is canonical then substrate mirror is zero and vice versa.
360 /// @dev EVM selector for this function is: 0xdf727d3b,428 /// @dev EVM selector for this function is: 0xdf727d3b,
361 /// or in textual repr: collectionOwner()429 /// or in textual repr: collectionOwner()
362 function collectionOwner() public view returns (Tuple17 memory) {430 function collectionOwner() public view returns (Tuple6 memory) {
363 require(false, stub_error);431 require(false, stub_error);
364 dummy;432 dummy;
365 return Tuple17(0x0000000000000000000000000000000000000000, 0);433 return Tuple6(0x0000000000000000000000000000000000000000, 0);
366 }434 }
367435
368 /// Changes collection owner to another account436 /// Changes collection owner to another account
383 /// If address is canonical then substrate mirror is zero and vice versa.451 /// If address is canonical then substrate mirror is zero and vice versa.
384 /// @dev EVM selector for this function is: 0x5813216b,452 /// @dev EVM selector for this function is: 0x5813216b,
385 /// or in textual repr: collectionAdmins()453 /// or in textual repr: collectionAdmins()
386 function collectionAdmins() public view returns (Tuple17[] memory) {454 function collectionAdmins() public view returns (Tuple6[] memory) {
387 require(false, stub_error);455 require(false, stub_error);
388 dummy;456 dummy;
389 return new Tuple17[](0);457 return new Tuple6[](0);
390 }458 }
459
460 /// Changes collection owner to another account
461 ///
462 /// @dev Owner can be changed only by current owner
463 /// @param newOwner new owner cross account
464 /// @dev EVM selector for this function is: 0xe5c9913f,
465 /// or in textual repr: setOwnerCross((address,uint256))
466 function setOwnerCross(Tuple6 memory newOwner) public {
467 require(false, stub_error);
468 newOwner;
469 dummy = 0;
470 }
391}471}
392
393/// @dev anonymous struct
394struct Tuple17 {
395 address field_0;
396 uint256 field_1;
397}
398472
399/// @dev the ERC-165 identifier for this interface is 0x5b5e139f473/// @dev the ERC-165 identifier for this interface is 0x5b5e139f
400contract ERC721Metadata is Dummy, ERC165 {474contract ERC721Metadata is Dummy, ERC165 {
538}612}
539613
540/// @title Unique extensions for ERC721.614/// @title Unique extensions for ERC721.
541/// @dev the ERC-165 identifier for this interface is 0xef1eaacb615/// @dev the ERC-165 identifier for this interface is 0x81feb398
542contract ERC721UniqueExtensions is Dummy, ERC165 {616contract ERC721UniqueExtensions is Dummy, ERC165 {
543 /// @notice A descriptive name for a collection of NFTs in this contract617 /// @notice A descriptive name for a collection of NFTs in this contract
544 /// @dev EVM selector for this function is: 0x06fdde03,618 /// @dev EVM selector for this function is: 0x06fdde03,
573 dummy = 0;647 dummy = 0;
574 }648 }
649
650 /// @notice Transfer ownership of an RFT
651 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`
652 /// is the zero address. Throws if `tokenId` is not a valid RFT.
653 /// Throws if RFT pieces have multiple owners.
654 /// @param to The new owner
655 /// @param tokenId The RFT to transfer
656 /// @dev EVM selector for this function is: 0xd5cf430b,
657 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)
658 function transferFromCross(
659 Tuple6 memory from,
660 Tuple6 memory to,
661 uint256 tokenId
662 ) public {
663 require(false, stub_error);
664 from;
665 to;
666 tokenId;
667 dummy = 0;
668 }
575669
576 /// @notice Burns a specific ERC721 token.670 /// @notice Burns a specific ERC721 token.
577 /// @dev Throws unless `msg.sender` is the current owner or an authorized671 /// @dev Throws unless `msg.sender` is the current owner or an authorized
589 dummy = 0;683 dummy = 0;
590 }684 }
685
686 /// @notice Burns a specific ERC721 token.
687 /// @dev Throws unless `msg.sender` is the current owner or an authorized
688 /// operator for this RFT. Throws if `from` is not the current owner. Throws
689 /// if `to` is the zero address. Throws if `tokenId` is not a valid RFT.
690 /// Throws if RFT pieces have multiple owners.
691 /// @param from The current owner of the RFT
692 /// @param tokenId The RFT to transfer
693 /// @dev EVM selector for this function is: 0xbb2f5a58,
694 /// or in textual repr: burnFromCross((address,uint256),uint256)
695 function burnFromCross(Tuple6 memory from, uint256 tokenId) public {
696 require(false, stub_error);
697 from;
698 tokenId;
699 dummy = 0;
700 }
591701
592 /// @notice Returns next free RFT ID.702 /// @notice Returns next free RFT ID.
593 /// @dev EVM selector for this function is: 0x75794a3c,703 /// @dev EVM selector for this function is: 0x75794a3c,
620 // /// @param tokens array of pairs of token ID and token URI for minted tokens730 // /// @param tokens array of pairs of token ID and token URI for minted tokens
621 // /// @dev EVM selector for this function is: 0x36543006,731 // /// @dev EVM selector for this function is: 0x36543006,
622 // /// or in textual repr: mintBulkWithTokenURI(address,(uint256,string)[])732 // /// or in textual repr: mintBulkWithTokenURI(address,(uint256,string)[])
623 // function mintBulkWithTokenURI(address to, Tuple6[] memory tokens) public returns (bool) {733 // function mintBulkWithTokenURI(address to, Tuple8[] memory tokens) public returns (bool) {
624 // require(false, stub_error);734 // require(false, stub_error);
625 // to;735 // to;
626 // tokens;736 // tokens;
642}752}
643753
644/// @dev anonymous struct754/// @dev anonymous struct
645struct Tuple6 {755struct Tuple8 {
646 uint256 field_0;756 uint256 field_0;
647 string field_1;757 string field_1;
648}758}
759
760/// @dev anonymous struct
761struct Tuple6 {
762 address field_0;
763 uint256 field_1;
764}
649765
650/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension766/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
651/// @dev See https://eips.ethereum.org/EIPS/eip-721767/// @dev See https://eips.ethereum.org/EIPS/eip-721
modifiedtests/src/eth/allowlist.test.tsdiffbeforeafterboth
89 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;89 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;
90 });90 });
9191
92 // TODO: Temprorary off. Need refactor
93 // itEth('Collection allowlist can be added and removed by [sub] address', async ({helper}) => {92 //itEth('Collection allowlist can be added and removed by [cross] address', async ({helper}) => {
94 // const owner = await helper.eth.createAccountWithBalance(donor);93 // const owner = await helper.eth.createAccountWithBalance(donor);
95 // const user = donor;94 // const user = donor;
9695 //
97 // const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');96 // const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
98 // const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);97 // const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
9998 // const userCross = helper.ethCrossAccount.fromKeyringPair(user);
99 //
100 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;100 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
101 // await collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).send({from: owner});101 // await collectionEvm.methods.addToCollectionAllowListCross(userCross).send({from: owner});
102 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;102 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;
103103 //
104 // await collectionEvm.methods.removeFromCollectionAllowListSubstrate(user.addressRaw).send({from: owner});104 // await collectionEvm.methods.removeFromCollectionAllowListCross(userCross).send({from: owner});
105 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;105 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
106 // });106 //});
107107
108 itEth('Collection allowlist can not be add and remove [eth] address by not owner', async ({helper}) => {108 itEth('Collection allowlist can not be add and remove [eth] address by not owner', async ({helper}) => {
109 const owner = await helper.eth.createAccountWithBalance(donor);109 const owner = await helper.eth.createAccountWithBalance(donor);
123 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;122 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;
124 });123 });
125124
126 // TODO: Temprorary off. Need refactor
127 // itEth('Collection allowlist can not be add and remove [sub] address by not owner', async ({helper}) => {125 //itEth('Collection allowlist can not be add and remove [cross] address by not owner', async ({helper}) => {
128 // const owner = await helper.eth.createAccountWithBalance(donor);126 // const owner = await helper.eth.createAccountWithBalance(donor);
129 // const notOwner = await helper.eth.createAccountWithBalance(donor);127 // const notOwner = await helper.eth.createAccountWithBalance(donor);
130 // const user = donor;128 // const user = donor;
131129 //
132 // const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');130 // const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
133 // const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);131 // const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
134132 //
135 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;133 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
134 // const userCross = helper.ethCrossAccount.fromKeyringPair(user);
136 // await expect(collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).call({from: notOwner})).to.be.rejectedWith('NoPermission');135 // await expect(collectionEvm.methods.addToCollectionAllowListCross(userCross).call({from: notOwner})).to.be.rejectedWith('NoPermission');
137 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;136 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
138 // await collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).send({from: owner});137 // await collectionEvm.methods.addToCollectionAllowListCross(userCross).send({from: owner});
139138 //
140 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;139 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;
141 // await expect(collectionEvm.methods.removeFromCollectionAllowListSubstrate(user.addressRaw).call({from: notOwner})).to.be.rejectedWith('NoPermission');140 // await expect(collectionEvm.methods.removeFromCollectionAllowListCross(userCross).call({from: notOwner})).to.be.rejectedWith('NoPermission');
142 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;141 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;
143 // });142 //});
144});143});
145144
modifiedtests/src/eth/api/UniqueFungible.soldiffbeforeafterboth
13}13}
1414
15/// @title A contract that allows you to work with collections.15/// @title A contract that allows you to work with collections.
16/// @dev the ERC-165 identifier for this interface is 0x3af103fb16/// @dev the ERC-165 identifier for this interface is 0x25d897dc
17interface Collection is Dummy, ERC165 {17interface Collection is Dummy, ERC165 {
18 /// Set collection property.18 /// Set collection property.
19 ///19 ///
49 /// or in textual repr: setCollectionSponsor(address)49 /// or in textual repr: setCollectionSponsor(address)
50 function setCollectionSponsor(address sponsor) external;50 function setCollectionSponsor(address sponsor) external;
51
52 /// Set the sponsor of the collection.
53 ///
54 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
55 ///
56 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.
57 /// @dev EVM selector for this function is: 0x84a1d5a8,
58 /// or in textual repr: setCollectionSponsorCross((address,uint256))
59 function setCollectionSponsorCross(Tuple6 memory sponsor) external;
5160
52 /// Whether there is a pending sponsor.61 /// Whether there is a pending sponsor.
53 /// @dev EVM selector for this function is: 0x058ac185,62 /// @dev EVM selector for this function is: 0x058ac185,
103 /// or in textual repr: contractAddress()112 /// or in textual repr: contractAddress()
104 function contractAddress() external view returns (address);113 function contractAddress() external view returns (address);
114
115 /// Add collection admin.
116 /// @param newAdmin Cross account administrator address.
117 /// @dev EVM selector for this function is: 0x859aa7d6,
118 /// or in textual repr: addCollectionAdminCross((address,uint256))
119 function addCollectionAdminCross(Tuple6 memory newAdmin) external;
120
121 /// Remove collection admin.
122 /// @param admin Cross account administrator address.
123 /// @dev EVM selector for this function is: 0x6c0cd173,
124 /// or in textual repr: removeCollectionAdminCross((address,uint256))
125 function removeCollectionAdminCross(Tuple6 memory admin) external;
105126
106 /// Add collection admin.127 /// Add collection admin.
107 /// @param newAdmin Address of the added administrator.128 /// @param newAdmin Address of the added administrator.
153 /// or in textual repr: addToCollectionAllowList(address)174 /// or in textual repr: addToCollectionAllowList(address)
154 function addToCollectionAllowList(address user) external;175 function addToCollectionAllowList(address user) external;
176
177 /// Add user to allowed list.
178 ///
179 /// @param user User cross account address.
180 /// @dev EVM selector for this function is: 0xa0184a3a,
181 /// or in textual repr: addToCollectionAllowListCross((address,uint256))
182 function addToCollectionAllowListCross(Tuple6 memory user) external;
155183
156 /// Remove the user from the allowed list.184 /// Remove the user from the allowed list.
157 ///185 ///
160 /// or in textual repr: removeFromCollectionAllowList(address)188 /// or in textual repr: removeFromCollectionAllowList(address)
161 function removeFromCollectionAllowList(address user) external;189 function removeFromCollectionAllowList(address user) external;
190
191 /// Remove user from allowed list.
192 ///
193 /// @param user User cross account address.
194 /// @dev EVM selector for this function is: 0x09ba452a,
195 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))
196 function removeFromCollectionAllowListCross(Tuple6 memory user) external;
162197
163 /// Switch permission for minting.198 /// Switch permission for minting.
164 ///199 ///
175 /// or in textual repr: isOwnerOrAdmin(address)210 /// or in textual repr: isOwnerOrAdmin(address)
176 function isOwnerOrAdmin(address user) external view returns (bool);211 function isOwnerOrAdmin(address user) external view returns (bool);
212
213 /// Check that account is the owner or admin of the collection
214 ///
215 /// @param user User cross account to verify
216 /// @return "true" if account is the owner or admin
217 /// @dev EVM selector for this function is: 0x3e75a905,
218 /// or in textual repr: isOwnerOrAdminCross((address,uint256))
219 function isOwnerOrAdminCross(Tuple6 memory user) external view returns (bool);
177220
178 /// Returns collection type221 /// Returns collection type
179 ///222 ///
184227
185 /// Get collection owner.228 /// Get collection owner.
186 ///229 ///
187 /// @return Tuple with sponsor address and his substrate mirror.230 /// @return Tuble with sponsor address and his substrate mirror.
188 /// If address is canonical then substrate mirror is zero and vice versa.231 /// If address is canonical then substrate mirror is zero and vice versa.
189 /// @dev EVM selector for this function is: 0xdf727d3b,232 /// @dev EVM selector for this function is: 0xdf727d3b,
190 /// or in textual repr: collectionOwner()233 /// or in textual repr: collectionOwner()
206 /// or in textual repr: collectionAdmins()249 /// or in textual repr: collectionAdmins()
207 function collectionAdmins() external view returns (Tuple6[] memory);250 function collectionAdmins() external view returns (Tuple6[] memory);
251
252 /// Changes collection owner to another account
253 ///
254 /// @dev Owner can be changed only by current owner
255 /// @param newOwner new owner cross account
256 /// @dev EVM selector for this function is: 0xe5c9913f,
257 /// or in textual repr: setOwnerCross((address,uint256))
258 function setOwnerCross(Tuple6 memory newOwner) external;
208}259}
209260
210/// @dev the ERC-165 identifier for this interface is 0x63034ac5261/// @dev the ERC-165 identifier for this interface is 0x032e5926
211interface ERC20UniqueExtensions is Dummy, ERC165 {262interface ERC20UniqueExtensions is Dummy, ERC165 {
263 /// @dev EVM selector for this function is: 0x0ecd0ab0,
264 /// or in textual repr: approveCross((address,uint256),uint256)
265 function approveCross(Tuple6 memory spender, uint256 amount) external returns (bool);
266
212 /// Burn tokens from account267 /// Burn tokens from account
213 /// @dev Function that burns an `amount` of the tokens of a given account,268 /// @dev Function that burns an `amount` of the tokens of a given account,
218 /// or in textual repr: burnFrom(address,uint256)273 /// or in textual repr: burnFrom(address,uint256)
219 function burnFrom(address from, uint256 amount) external returns (bool);274 function burnFrom(address from, uint256 amount) external returns (bool);
275
276 /// Burn tokens from account
277 /// @dev Function that burns an `amount` of the tokens of a given account,
278 /// deducting from the sender's allowance for said account.
279 /// @param from The account whose tokens will be burnt.
280 /// @param amount The amount that will be burnt.
281 /// @dev EVM selector for this function is: 0xbb2f5a58,
282 /// or in textual repr: burnFromCross((address,uint256),uint256)
283 function burnFromCross(Tuple6 memory from, uint256 amount) external returns (bool);
220284
221 /// Mint tokens for multiple accounts.285 /// Mint tokens for multiple accounts.
222 /// @param amounts array of pairs of account address and amount286 /// @param amounts array of pairs of account address and amount
223 /// @dev EVM selector for this function is: 0x1acf2d55,287 /// @dev EVM selector for this function is: 0x1acf2d55,
224 /// or in textual repr: mintBulk((address,uint256)[])288 /// or in textual repr: mintBulk((address,uint256)[])
225 function mintBulk(Tuple6[] memory amounts) external returns (bool);289 function mintBulk(Tuple6[] memory amounts) external returns (bool);
290
291 /// @dev EVM selector for this function is: 0xd5cf430b,
292 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)
293 function transferFromCross(
294 Tuple6 memory from,
295 Tuple6 memory to,
296 uint256 amount
297 ) external returns (bool);
226}298}
227299
228/// @dev anonymous struct300/// @dev anonymous struct
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
62}62}
6363
64/// @title A contract that allows you to work with collections.64/// @title A contract that allows you to work with collections.
65/// @dev the ERC-165 identifier for this interface is 0x3af103fb65/// @dev the ERC-165 identifier for this interface is 0x25d897dc
66interface Collection is Dummy, ERC165 {66interface Collection is Dummy, ERC165 {
67 /// Set collection property.67 /// Set collection property.
68 ///68 ///
98 /// or in textual repr: setCollectionSponsor(address)98 /// or in textual repr: setCollectionSponsor(address)
99 function setCollectionSponsor(address sponsor) external;99 function setCollectionSponsor(address sponsor) external;
100
101 /// Set the sponsor of the collection.
102 ///
103 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
104 ///
105 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.
106 /// @dev EVM selector for this function is: 0x84a1d5a8,
107 /// or in textual repr: setCollectionSponsorCross((address,uint256))
108 function setCollectionSponsorCross(Tuple6 memory sponsor) external;
100109
101 /// Whether there is a pending sponsor.110 /// Whether there is a pending sponsor.
102 /// @dev EVM selector for this function is: 0x058ac185,111 /// @dev EVM selector for this function is: 0x058ac185,
120 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.129 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
121 /// @dev EVM selector for this function is: 0x6ec0a9f1,130 /// @dev EVM selector for this function is: 0x6ec0a9f1,
122 /// or in textual repr: collectionSponsor()131 /// or in textual repr: collectionSponsor()
123 function collectionSponsor() external view returns (Tuple17 memory);132 function collectionSponsor() external view returns (Tuple6 memory);
124133
125 /// Set limits for the collection.134 /// Set limits for the collection.
126 /// @dev Throws error if limit not found.135 /// @dev Throws error if limit not found.
152 /// or in textual repr: contractAddress()161 /// or in textual repr: contractAddress()
153 function contractAddress() external view returns (address);162 function contractAddress() external view returns (address);
163
164 /// Add collection admin.
165 /// @param newAdmin Cross account administrator address.
166 /// @dev EVM selector for this function is: 0x859aa7d6,
167 /// or in textual repr: addCollectionAdminCross((address,uint256))
168 function addCollectionAdminCross(Tuple6 memory newAdmin) external;
169
170 /// Remove collection admin.
171 /// @param admin Cross account administrator address.
172 /// @dev EVM selector for this function is: 0x6c0cd173,
173 /// or in textual repr: removeCollectionAdminCross((address,uint256))
174 function removeCollectionAdminCross(Tuple6 memory admin) external;
154175
155 /// Add collection admin.176 /// Add collection admin.
156 /// @param newAdmin Address of the added administrator.177 /// @param newAdmin Address of the added administrator.
202 /// or in textual repr: addToCollectionAllowList(address)223 /// or in textual repr: addToCollectionAllowList(address)
203 function addToCollectionAllowList(address user) external;224 function addToCollectionAllowList(address user) external;
225
226 /// Add user to allowed list.
227 ///
228 /// @param user User cross account address.
229 /// @dev EVM selector for this function is: 0xa0184a3a,
230 /// or in textual repr: addToCollectionAllowListCross((address,uint256))
231 function addToCollectionAllowListCross(Tuple6 memory user) external;
204232
205 /// Remove the user from the allowed list.233 /// Remove the user from the allowed list.
206 ///234 ///
209 /// or in textual repr: removeFromCollectionAllowList(address)237 /// or in textual repr: removeFromCollectionAllowList(address)
210 function removeFromCollectionAllowList(address user) external;238 function removeFromCollectionAllowList(address user) external;
239
240 /// Remove user from allowed list.
241 ///
242 /// @param user User cross account address.
243 /// @dev EVM selector for this function is: 0x09ba452a,
244 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))
245 function removeFromCollectionAllowListCross(Tuple6 memory user) external;
211246
212 /// Switch permission for minting.247 /// Switch permission for minting.
213 ///248 ///
224 /// or in textual repr: isOwnerOrAdmin(address)259 /// or in textual repr: isOwnerOrAdmin(address)
225 function isOwnerOrAdmin(address user) external view returns (bool);260 function isOwnerOrAdmin(address user) external view returns (bool);
261
262 /// Check that account is the owner or admin of the collection
263 ///
264 /// @param user User cross account to verify
265 /// @return "true" if account is the owner or admin
266 /// @dev EVM selector for this function is: 0x3e75a905,
267 /// or in textual repr: isOwnerOrAdminCross((address,uint256))
268 function isOwnerOrAdminCross(Tuple6 memory user) external view returns (bool);
226269
227 /// Returns collection type270 /// Returns collection type
228 ///271 ///
233276
234 /// Get collection owner.277 /// Get collection owner.
235 ///278 ///
236 /// @return Tuple with sponsor address and his substrate mirror.279 /// @return Tuble with sponsor address and his substrate mirror.
237 /// If address is canonical then substrate mirror is zero and vice versa.280 /// If address is canonical then substrate mirror is zero and vice versa.
238 /// @dev EVM selector for this function is: 0xdf727d3b,281 /// @dev EVM selector for this function is: 0xdf727d3b,
239 /// or in textual repr: collectionOwner()282 /// or in textual repr: collectionOwner()
240 function collectionOwner() external view returns (Tuple17 memory);283 function collectionOwner() external view returns (Tuple6 memory);
241284
242 /// Changes collection owner to another account285 /// Changes collection owner to another account
243 ///286 ///
253 /// If address is canonical then substrate mirror is zero and vice versa.296 /// If address is canonical then substrate mirror is zero and vice versa.
254 /// @dev EVM selector for this function is: 0x5813216b,297 /// @dev EVM selector for this function is: 0x5813216b,
255 /// or in textual repr: collectionAdmins()298 /// or in textual repr: collectionAdmins()
256 function collectionAdmins() external view returns (Tuple17[] memory);299 function collectionAdmins() external view returns (Tuple6[] memory);
300
301 /// Changes collection owner to another account
302 ///
303 /// @dev Owner can be changed only by current owner
304 /// @param newOwner new owner cross account
305 /// @dev EVM selector for this function is: 0xe5c9913f,
306 /// or in textual repr: setOwnerCross((address,uint256))
307 function setOwnerCross(Tuple6 memory newOwner) external;
257}308}
258
259/// @dev anonymous struct
260struct Tuple17 {
261 address field_0;
262 uint256 field_1;
263}
264309
265/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension310/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
266/// @dev See https://eips.ethereum.org/EIPS/eip-721311/// @dev See https://eips.ethereum.org/EIPS/eip-721
357}402}
358403
359/// @title Unique extensions for ERC721.404/// @title Unique extensions for ERC721.
360/// @dev the ERC-165 identifier for this interface is 0x4468500d405/// @dev the ERC-165 identifier for this interface is 0x244543ee
361interface ERC721UniqueExtensions is Dummy, ERC165 {406interface ERC721UniqueExtensions is Dummy, ERC165 {
362 /// @notice A descriptive name for a collection of NFTs in this contract407 /// @notice A descriptive name for a collection of NFTs in this contract
363 /// @dev EVM selector for this function is: 0x06fdde03,408 /// @dev EVM selector for this function is: 0x06fdde03,
369 /// or in textual repr: symbol()414 /// or in textual repr: symbol()
370 function symbol() external view returns (string memory);415 function symbol() external view returns (string memory);
416
417 /// @notice Set or reaffirm the approved address for an NFT
418 /// @dev The zero address indicates there is no approved address.
419 /// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized
420 /// operator of the current owner.
421 /// @param approved The new substrate address approved NFT controller
422 /// @param tokenId The NFT to approve
423 /// @dev EVM selector for this function is: 0x0ecd0ab0,
424 /// or in textual repr: approveCross((address,uint256),uint256)
425 function approveCross(Tuple6 memory approved, uint256 tokenId) external;
371426
372 /// @notice Transfer ownership of an NFT427 /// @notice Transfer ownership of an NFT
373 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`428 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`
378 /// or in textual repr: transfer(address,uint256)433 /// or in textual repr: transfer(address,uint256)
379 function transfer(address to, uint256 tokenId) external;434 function transfer(address to, uint256 tokenId) external;
435
436 /// @notice Transfer ownership of an NFT from cross account address to cross account address
437 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`
438 /// is the zero address. Throws if `tokenId` is not a valid NFT.
439 /// @param from Cross acccount address of current owner
440 /// @param to Cross acccount address of new owner
441 /// @param tokenId The NFT to transfer
442 /// @dev EVM selector for this function is: 0xd5cf430b,
443 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)
444 function transferFromCross(
445 Tuple6 memory from,
446 Tuple6 memory to,
447 uint256 tokenId
448 ) external;
380449
381 /// @notice Burns a specific ERC721 token.450 /// @notice Burns a specific ERC721 token.
382 /// @dev Throws unless `msg.sender` is the current owner or an authorized451 /// @dev Throws unless `msg.sender` is the current owner or an authorized
388 /// or in textual repr: burnFrom(address,uint256)457 /// or in textual repr: burnFrom(address,uint256)
389 function burnFrom(address from, uint256 tokenId) external;458 function burnFrom(address from, uint256 tokenId) external;
459
460 /// @notice Burns a specific ERC721 token.
461 /// @dev Throws unless `msg.sender` is the current owner or an authorized
462 /// operator for this NFT. Throws if `from` is not the current owner. Throws
463 /// if `to` is the zero address. Throws if `tokenId` is not a valid NFT.
464 /// @param from The current owner of the NFT
465 /// @param tokenId The NFT to transfer
466 /// @dev EVM selector for this function is: 0xbb2f5a58,
467 /// or in textual repr: burnFromCross((address,uint256),uint256)
468 function burnFromCross(Tuple6 memory from, uint256 tokenId) external;
390469
391 /// @notice Returns next free NFT ID.470 /// @notice Returns next free NFT ID.
392 /// @dev EVM selector for this function is: 0x75794a3c,471 /// @dev EVM selector for this function is: 0x75794a3c,
408 // /// @param tokens array of pairs of token ID and token URI for minted tokens487 // /// @param tokens array of pairs of token ID and token URI for minted tokens
409 // /// @dev EVM selector for this function is: 0x36543006,488 // /// @dev EVM selector for this function is: 0x36543006,
410 // /// or in textual repr: mintBulkWithTokenURI(address,(uint256,string)[])489 // /// or in textual repr: mintBulkWithTokenURI(address,(uint256,string)[])
411 // function mintBulkWithTokenURI(address to, Tuple6[] memory tokens) external returns (bool);490 // function mintBulkWithTokenURI(address to, Tuple8[] memory tokens) external returns (bool);
412491
413}492}
414493
415/// @dev anonymous struct494/// @dev anonymous struct
416struct Tuple6 {495struct Tuple8 {
417 uint256 field_0;496 uint256 field_0;
418 string field_1;497 string field_1;
419}498}
499
500/// @dev anonymous struct
501struct Tuple6 {
502 address field_0;
503 uint256 field_1;
504}
420505
421/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension506/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
422/// @dev See https://eips.ethereum.org/EIPS/eip-721507/// @dev See https://eips.ethereum.org/EIPS/eip-721
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
62}62}
6363
64/// @title A contract that allows you to work with collections.64/// @title A contract that allows you to work with collections.
65/// @dev the ERC-165 identifier for this interface is 0x3af103fb65/// @dev the ERC-165 identifier for this interface is 0x25d897dc
66interface Collection is Dummy, ERC165 {66interface Collection is Dummy, ERC165 {
67 /// Set collection property.67 /// Set collection property.
68 ///68 ///
98 /// or in textual repr: setCollectionSponsor(address)98 /// or in textual repr: setCollectionSponsor(address)
99 function setCollectionSponsor(address sponsor) external;99 function setCollectionSponsor(address sponsor) external;
100
101 /// Set the sponsor of the collection.
102 ///
103 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.
104 ///
105 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.
106 /// @dev EVM selector for this function is: 0x84a1d5a8,
107 /// or in textual repr: setCollectionSponsorCross((address,uint256))
108 function setCollectionSponsorCross(Tuple6 memory sponsor) external;
100109
101 /// Whether there is a pending sponsor.110 /// Whether there is a pending sponsor.
102 /// @dev EVM selector for this function is: 0x058ac185,111 /// @dev EVM selector for this function is: 0x058ac185,
120 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.129 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
121 /// @dev EVM selector for this function is: 0x6ec0a9f1,130 /// @dev EVM selector for this function is: 0x6ec0a9f1,
122 /// or in textual repr: collectionSponsor()131 /// or in textual repr: collectionSponsor()
123 function collectionSponsor() external view returns (Tuple17 memory);132 function collectionSponsor() external view returns (Tuple6 memory);
124133
125 /// Set limits for the collection.134 /// Set limits for the collection.
126 /// @dev Throws error if limit not found.135 /// @dev Throws error if limit not found.
152 /// or in textual repr: contractAddress()161 /// or in textual repr: contractAddress()
153 function contractAddress() external view returns (address);162 function contractAddress() external view returns (address);
163
164 /// Add collection admin.
165 /// @param newAdmin Cross account administrator address.
166 /// @dev EVM selector for this function is: 0x859aa7d6,
167 /// or in textual repr: addCollectionAdminCross((address,uint256))
168 function addCollectionAdminCross(Tuple6 memory newAdmin) external;
169
170 /// Remove collection admin.
171 /// @param admin Cross account administrator address.
172 /// @dev EVM selector for this function is: 0x6c0cd173,
173 /// or in textual repr: removeCollectionAdminCross((address,uint256))
174 function removeCollectionAdminCross(Tuple6 memory admin) external;
154175
155 /// Add collection admin.176 /// Add collection admin.
156 /// @param newAdmin Address of the added administrator.177 /// @param newAdmin Address of the added administrator.
202 /// or in textual repr: addToCollectionAllowList(address)223 /// or in textual repr: addToCollectionAllowList(address)
203 function addToCollectionAllowList(address user) external;224 function addToCollectionAllowList(address user) external;
225
226 /// Add user to allowed list.
227 ///
228 /// @param user User cross account address.
229 /// @dev EVM selector for this function is: 0xa0184a3a,
230 /// or in textual repr: addToCollectionAllowListCross((address,uint256))
231 function addToCollectionAllowListCross(Tuple6 memory user) external;
204232
205 /// Remove the user from the allowed list.233 /// Remove the user from the allowed list.
206 ///234 ///
209 /// or in textual repr: removeFromCollectionAllowList(address)237 /// or in textual repr: removeFromCollectionAllowList(address)
210 function removeFromCollectionAllowList(address user) external;238 function removeFromCollectionAllowList(address user) external;
239
240 /// Remove user from allowed list.
241 ///
242 /// @param user User cross account address.
243 /// @dev EVM selector for this function is: 0x09ba452a,
244 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))
245 function removeFromCollectionAllowListCross(Tuple6 memory user) external;
211246
212 /// Switch permission for minting.247 /// Switch permission for minting.
213 ///248 ///
224 /// or in textual repr: isOwnerOrAdmin(address)259 /// or in textual repr: isOwnerOrAdmin(address)
225 function isOwnerOrAdmin(address user) external view returns (bool);260 function isOwnerOrAdmin(address user) external view returns (bool);
261
262 /// Check that account is the owner or admin of the collection
263 ///
264 /// @param user User cross account to verify
265 /// @return "true" if account is the owner or admin
266 /// @dev EVM selector for this function is: 0x3e75a905,
267 /// or in textual repr: isOwnerOrAdminCross((address,uint256))
268 function isOwnerOrAdminCross(Tuple6 memory user) external view returns (bool);
226269
227 /// Returns collection type270 /// Returns collection type
228 ///271 ///
233276
234 /// Get collection owner.277 /// Get collection owner.
235 ///278 ///
236 /// @return Tuple with sponsor address and his substrate mirror.279 /// @return Tuble with sponsor address and his substrate mirror.
237 /// If address is canonical then substrate mirror is zero and vice versa.280 /// If address is canonical then substrate mirror is zero and vice versa.
238 /// @dev EVM selector for this function is: 0xdf727d3b,281 /// @dev EVM selector for this function is: 0xdf727d3b,
239 /// or in textual repr: collectionOwner()282 /// or in textual repr: collectionOwner()
240 function collectionOwner() external view returns (Tuple17 memory);283 function collectionOwner() external view returns (Tuple6 memory);
241284
242 /// Changes collection owner to another account285 /// Changes collection owner to another account
243 ///286 ///
253 /// If address is canonical then substrate mirror is zero and vice versa.296 /// If address is canonical then substrate mirror is zero and vice versa.
254 /// @dev EVM selector for this function is: 0x5813216b,297 /// @dev EVM selector for this function is: 0x5813216b,
255 /// or in textual repr: collectionAdmins()298 /// or in textual repr: collectionAdmins()
256 function collectionAdmins() external view returns (Tuple17[] memory);299 function collectionAdmins() external view returns (Tuple6[] memory);
300
301 /// Changes collection owner to another account
302 ///
303 /// @dev Owner can be changed only by current owner
304 /// @param newOwner new owner cross account
305 /// @dev EVM selector for this function is: 0xe5c9913f,
306 /// or in textual repr: setOwnerCross((address,uint256))
307 function setOwnerCross(Tuple6 memory newOwner) external;
257}308}
258
259/// @dev anonymous struct
260struct Tuple17 {
261 address field_0;
262 uint256 field_1;
263}
264309
265/// @dev the ERC-165 identifier for this interface is 0x5b5e139f310/// @dev the ERC-165 identifier for this interface is 0x5b5e139f
266interface ERC721Metadata is Dummy, ERC165 {311interface ERC721Metadata is Dummy, ERC165 {
355}400}
356401
357/// @title Unique extensions for ERC721.402/// @title Unique extensions for ERC721.
358/// @dev the ERC-165 identifier for this interface is 0xef1eaacb403/// @dev the ERC-165 identifier for this interface is 0x81feb398
359interface ERC721UniqueExtensions is Dummy, ERC165 {404interface ERC721UniqueExtensions is Dummy, ERC165 {
360 /// @notice A descriptive name for a collection of NFTs in this contract405 /// @notice A descriptive name for a collection of NFTs in this contract
361 /// @dev EVM selector for this function is: 0x06fdde03,406 /// @dev EVM selector for this function is: 0x06fdde03,
377 /// or in textual repr: transfer(address,uint256)422 /// or in textual repr: transfer(address,uint256)
378 function transfer(address to, uint256 tokenId) external;423 function transfer(address to, uint256 tokenId) external;
424
425 /// @notice Transfer ownership of an RFT
426 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`
427 /// is the zero address. Throws if `tokenId` is not a valid RFT.
428 /// Throws if RFT pieces have multiple owners.
429 /// @param to The new owner
430 /// @param tokenId The RFT to transfer
431 /// @dev EVM selector for this function is: 0xd5cf430b,
432 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)
433 function transferFromCross(
434 Tuple6 memory from,
435 Tuple6 memory to,
436 uint256 tokenId
437 ) external;
379438
380 /// @notice Burns a specific ERC721 token.439 /// @notice Burns a specific ERC721 token.
381 /// @dev Throws unless `msg.sender` is the current owner or an authorized440 /// @dev Throws unless `msg.sender` is the current owner or an authorized
388 /// or in textual repr: burnFrom(address,uint256)447 /// or in textual repr: burnFrom(address,uint256)
389 function burnFrom(address from, uint256 tokenId) external;448 function burnFrom(address from, uint256 tokenId) external;
449
450 /// @notice Burns a specific ERC721 token.
451 /// @dev Throws unless `msg.sender` is the current owner or an authorized
452 /// operator for this RFT. Throws if `from` is not the current owner. Throws
453 /// if `to` is the zero address. Throws if `tokenId` is not a valid RFT.
454 /// Throws if RFT pieces have multiple owners.
455 /// @param from The current owner of the RFT
456 /// @param tokenId The RFT to transfer
457 /// @dev EVM selector for this function is: 0xbb2f5a58,
458 /// or in textual repr: burnFromCross((address,uint256),uint256)
459 function burnFromCross(Tuple6 memory from, uint256 tokenId) external;
390460
391 /// @notice Returns next free RFT ID.461 /// @notice Returns next free RFT ID.
392 /// @dev EVM selector for this function is: 0x75794a3c,462 /// @dev EVM selector for this function is: 0x75794a3c,
409 // /// @param tokens array of pairs of token ID and token URI for minted tokens479 // /// @param tokens array of pairs of token ID and token URI for minted tokens
410 // /// @dev EVM selector for this function is: 0x36543006,480 // /// @dev EVM selector for this function is: 0x36543006,
411 // /// or in textual repr: mintBulkWithTokenURI(address,(uint256,string)[])481 // /// or in textual repr: mintBulkWithTokenURI(address,(uint256,string)[])
412 // function mintBulkWithTokenURI(address to, Tuple6[] memory tokens) external returns (bool);482 // function mintBulkWithTokenURI(address to, Tuple8[] memory tokens) external returns (bool);
413483
414 /// Returns EVM address for refungible token484 /// Returns EVM address for refungible token
415 ///485 ///
420}490}
421491
422/// @dev anonymous struct492/// @dev anonymous struct
423struct Tuple6 {493struct Tuple8 {
424 uint256 field_0;494 uint256 field_0;
425 string field_1;495 string field_1;
426}496}
497
498/// @dev anonymous struct
499struct Tuple6 {
500 address field_0;
501 uint256 field_1;
502}
427503
428/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension504/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
429/// @dev See https://eips.ethereum.org/EIPS/eip-721505/// @dev See https://eips.ethereum.org/EIPS/eip-721
modifiedtests/src/eth/base.test.tsdiffbeforeafterboth
116 await checkInterface(helper, '0x780e9d63', true, true);116 await checkInterface(helper, '0x780e9d63', true, true);
117 });117 });
118118
119 itEth('ERC721UniqueExtensions - 0x4468500d - support', async ({helper}) => {119 itEth('ERC721UniqueExtensions - 0x244543ee - support', async ({helper}) => {
120 await checkInterface(helper, '0x4468500d', true, true);120 await checkInterface(helper, '0x244543ee', true, true);
121 });121 });
122122
123 itEth('ERC721Burnable - 0x42966c68 - support', async ({helper}) => {123 itEth('ERC721Burnable - 0x42966c68 - support', async ({helper}) => {
modifiedtests/src/eth/collectionAdmin.test.tsdiffbeforeafterboth
50 .to.be.eq(newAdmin.toLocaleLowerCase());50 .to.be.eq(newAdmin.toLocaleLowerCase());
51 });51 });
5252
53 itEth.skip('Add substrate admin by owner', async ({helper}) => {53 itEth('Add cross account admin by owner', async ({helper, privateKey}) => {
54 const owner = await helper.eth.createAccountWithBalance(donor);54 const owner = await helper.eth.createAccountWithBalance(donor);
55
55 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');56 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
56 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);57 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
5758
59 const newAdmin = await privateKey('//Bob');
58 const [newAdmin] = await helper.arrange.createAccounts([10n], donor);60 const newAdminCross = helper.ethCrossAccount.fromKeyringPair(newAdmin);
59 await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send();61 await collectionEvm.methods.addCollectionAdminCross(newAdminCross).send();
6062
61 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);63 const adminList = await helper.collection.getAdmins(collectionId);
62 expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())64 expect(adminList).to.be.like([{Substrate: newAdmin.address}]);
63 .to.be.eq(newAdmin.address.toLocaleLowerCase());
64 });65 });
6566
66 itEth('Verify owner or admin', async ({helper}) => {67 itEth('Verify owner or admin', async ({helper}) => {
modifiedtests/src/eth/fractionalizer/Fractionalizer.soldiffbeforeafterboth

no syntactic changes

modifiedtests/src/eth/fungible.test.tsdiffbeforeafterboth
148 }148 }
149 });149 });
150
151 itEth('Can perform burnFromCross()', async ({helper, privateKey}) => {
152 const alice = await privateKey('//Alice');
153 const sender = await helper.eth.createAccountWithBalance(alice, 100n);
154
155 const collection = await helper.ft.mintCollection(alice, {name: 'A', description: 'B', tokenPrefix: 'C'}, 0);
156
157 await collection.mint(alice, 200n, {Substrate: alice.address});
158 await collection.approveTokens(alice, {Ethereum: sender}, 100n);
159
160 const address = helper.ethAddress.fromCollectionId(collection.collectionId);
161 const contract = helper.ethNativeContract.collection(address, 'ft');
162
163 const fromBalanceBefore = await collection.getBalance({Substrate: alice.address});
164
165 const ownerCross = helper.ethCrossAccount.fromKeyringPair(alice);
166 const result = await contract.methods.burnFromCross(ownerCross, 49).send({from: sender});
167 const events = result.events;
168
169 expect(events).to.be.like({
170 Transfer: {
171 address: helper.ethAddress.fromCollectionId(collection.collectionId),
172 event: 'Transfer',
173 returnValues: {
174 from: helper.address.substrateToEth(alice.address),
175 to: '0x0000000000000000000000000000000000000000',
176 value: '49',
177 },
178 },
179 Approval: {
180 address: helper.ethAddress.fromCollectionId(collection.collectionId),
181 returnValues: {
182 owner: helper.address.substrateToEth(alice.address),
183 spender: sender,
184 value: '51',
185 },
186 event: 'Approval',
187 },
188 });
189
190 const fromBalanceAfter = await collection.getBalance({Substrate: alice.address});
191 expect(fromBalanceBefore - fromBalanceAfter).to.be.eq(49n);
192 });
150193
151 itEth('Can perform transferFrom()', async ({helper}) => {194 itEth('Can perform transferFrom()', async ({helper}) => {
152 const owner = await helper.eth.createAccountWithBalance(donor);195 const owner = await helper.eth.createAccountWithBalance(donor);
217 }260 }
218 });261 });
262
263 itEth('Can perform transferFromCross()', async ({helper, privateKey}) => {
264 const alice = await privateKey('//Alice');
265 const sender = await helper.eth.createAccountWithBalance(alice, 100n);
266
267 const collection = await helper.ft.mintCollection(alice, {name: 'A', description: 'B', tokenPrefix: 'C'}, 0);
268
269 const receiver = helper.eth.createAccount();
270
271 await collection.mint(alice, 200n, {Substrate: alice.address});
272 await collection.approveTokens(alice, {Ethereum: sender}, 100n);
273
274 const address = helper.ethAddress.fromCollectionId(collection.collectionId);
275 const contract = helper.ethNativeContract.collection(address, 'ft');
276
277 const from = helper.ethCrossAccount.fromKeyringPair(alice);
278 const to = helper.ethCrossAccount.fromAddress(receiver);
279
280 const fromBalanceBefore = await collection.getBalance({Substrate: alice.address});
281 const toBalanceBefore = await collection.getBalance({Ethereum: receiver});
282
283 const result = await contract.methods.transferFromCross(from, to, 51).send({from: sender});
284
285 expect(result.events).to.be.like({
286 Transfer: {
287 address,
288 event: 'Transfer',
289 returnValues: {
290 from: helper.address.substrateToEth(alice.address),
291 to: receiver,
292 value: '51',
293 },
294 },
295 Approval: {
296 address,
297 event: 'Approval',
298 returnValues: {
299 owner: helper.address.substrateToEth(alice.address),
300 spender: sender,
301 value: '49',
302 },
303 }});
304
305 const fromBalanceAfter = await collection.getBalance({Substrate: alice.address});
306 expect(fromBalanceBefore - fromBalanceAfter).to.be.eq(51n);
307 const toBalanceAfter = await collection.getBalance({Ethereum: receiver});
308 expect(toBalanceAfter - toBalanceBefore).to.be.eq(51n);
309 });
219});310});
220311
221describe('Fungible: Fees', () => {312describe('Fungible: Fees', () => {
363 expect(event.returnValues.value).to.be.equal('51');454 expect(event.returnValues.value).to.be.equal('51');
364 });455 });
456
457 itEth('Events emitted for transferFromCross()', async ({helper, privateKey}) => {
458 const alice = await privateKey('//Alice');
459 const sender = await helper.eth.createAccountWithBalance(alice, 100n);
460
461 const collection = await helper.ft.mintCollection(alice, {name: 'A', description: 'B', tokenPrefix: 'C'}, 0);
462
463 const receiver = helper.eth.createAccount();
464
465 await collection.mint(alice, 200n, {Substrate: alice.address});
466 await collection.approveTokens(alice, {Ethereum: sender}, 100n);
467
468 const address = helper.ethAddress.fromCollectionId(collection.collectionId);
469 const contract = helper.ethNativeContract.collection(address, 'ft');
470
471 const from = helper.ethCrossAccount.fromKeyringPair(alice);
472 const to = helper.ethCrossAccount.fromAddress(receiver);
473
474 const result = await contract.methods.transferFromCross(from, to, 51).send({from: sender});
475
476 expect(result.events).to.be.like({
477 Transfer: {
478 address,
479 event: 'Transfer',
480 returnValues: {
481 from: helper.address.substrateToEth(alice.address),
482 to: receiver,
483 value: '51',
484 },
485 },
486 Approval: {
487 address,
488 event: 'Approval',
489 returnValues: {
490 owner: helper.address.substrateToEth(alice.address),
491 spender: sender,
492 value: '49',
493 },
494 }});
495 });
365});496});
366497
modifiedtests/src/eth/fungibleAbi.jsondiffbeforeafterboth
58 "stateMutability": "nonpayable",58 "stateMutability": "nonpayable",
59 "type": "function"59 "type": "function"
60 },60 },
61 {
62 "inputs": [
63 {
64 "components": [
65 { "internalType": "address", "name": "field_0", "type": "address" },
66 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
67 ],
68 "internalType": "struct Tuple6",
69 "name": "newAdmin",
70 "type": "tuple"
71 }
72 ],
73 "name": "addCollectionAdminCross",
74 "outputs": [],
75 "stateMutability": "nonpayable",
76 "type": "function"
77 },
61 {78 {
62 "inputs": [79 "inputs": [
63 { "internalType": "address", "name": "user", "type": "address" }80 { "internalType": "address", "name": "user", "type": "address" }
67 "stateMutability": "nonpayable",84 "stateMutability": "nonpayable",
68 "type": "function"85 "type": "function"
69 },86 },
87 {
88 "inputs": [
89 {
90 "components": [
91 { "internalType": "address", "name": "field_0", "type": "address" },
92 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
93 ],
94 "internalType": "struct Tuple6",
95 "name": "user",
96 "type": "tuple"
97 }
98 ],
99 "name": "addToCollectionAllowListCross",
100 "outputs": [],
101 "stateMutability": "nonpayable",
102 "type": "function"
103 },
70 {104 {
71 "inputs": [105 "inputs": [
72 { "internalType": "address", "name": "owner", "type": "address" },106 { "internalType": "address", "name": "owner", "type": "address" },
96 "stateMutability": "nonpayable",130 "stateMutability": "nonpayable",
97 "type": "function"131 "type": "function"
98 },132 },
133 {
134 "inputs": [
135 {
136 "components": [
137 { "internalType": "address", "name": "field_0", "type": "address" },
138 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
139 ],
140 "internalType": "struct Tuple6",
141 "name": "spender",
142 "type": "tuple"
143 },
144 { "internalType": "uint256", "name": "amount", "type": "uint256" }
145 ],
146 "name": "approveCross",
147 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
148 "stateMutability": "nonpayable",
149 "type": "function"
150 },
99 {151 {
100 "inputs": [152 "inputs": [
101 { "internalType": "address", "name": "owner", "type": "address" }153 { "internalType": "address", "name": "owner", "type": "address" }
115 "stateMutability": "nonpayable",167 "stateMutability": "nonpayable",
116 "type": "function"168 "type": "function"
117 },169 },
170 {
171 "inputs": [
172 {
173 "components": [
174 { "internalType": "address", "name": "field_0", "type": "address" },
175 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
176 ],
177 "internalType": "struct Tuple6",
178 "name": "from",
179 "type": "tuple"
180 },
181 { "internalType": "uint256", "name": "amount", "type": "uint256" }
182 ],
183 "name": "burnFromCross",
184 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
185 "stateMutability": "nonpayable",
186 "type": "function"
187 },
118 {188 {
119 "inputs": [189 "inputs": [
120 { "internalType": "address", "name": "newOwner", "type": "address" }190 { "internalType": "address", "name": "newOwner", "type": "address" }
226 "stateMutability": "view",296 "stateMutability": "view",
227 "type": "function"297 "type": "function"
228 },298 },
299 {
300 "inputs": [
301 {
302 "components": [
303 { "internalType": "address", "name": "field_0", "type": "address" },
304 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
305 ],
306 "internalType": "struct Tuple6",
307 "name": "user",
308 "type": "tuple"
309 }
310 ],
311 "name": "isOwnerOrAdminCross",
312 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
313 "stateMutability": "view",
314 "type": "function"
315 },
229 {316 {
230 "inputs": [317 "inputs": [
231 { "internalType": "address", "name": "to", "type": "address" },318 { "internalType": "address", "name": "to", "type": "address" },
269 "stateMutability": "nonpayable",356 "stateMutability": "nonpayable",
270 "type": "function"357 "type": "function"
271 },358 },
359 {
360 "inputs": [
361 {
362 "components": [
363 { "internalType": "address", "name": "field_0", "type": "address" },
364 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
365 ],
366 "internalType": "struct Tuple6",
367 "name": "admin",
368 "type": "tuple"
369 }
370 ],
371 "name": "removeCollectionAdminCross",
372 "outputs": [],
373 "stateMutability": "nonpayable",
374 "type": "function"
375 },
272 {376 {
273 "inputs": [],377 "inputs": [],
274 "name": "removeCollectionSponsor",378 "name": "removeCollectionSponsor",
285 "stateMutability": "nonpayable",389 "stateMutability": "nonpayable",
286 "type": "function"390 "type": "function"
287 },391 },
392 {
393 "inputs": [
394 {
395 "components": [
396 { "internalType": "address", "name": "field_0", "type": "address" },
397 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
398 ],
399 "internalType": "struct Tuple6",
400 "name": "user",
401 "type": "tuple"
402 }
403 ],
404 "name": "removeFromCollectionAllowListCross",
405 "outputs": [],
406 "stateMutability": "nonpayable",
407 "type": "function"
408 },
288 {409 {
289 "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],410 "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],
290 "name": "setCollectionAccess",411 "name": "setCollectionAccess",
359 "stateMutability": "nonpayable",480 "stateMutability": "nonpayable",
360 "type": "function"481 "type": "function"
361 },482 },
483 {
484 "inputs": [
485 {
486 "components": [
487 { "internalType": "address", "name": "field_0", "type": "address" },
488 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
489 ],
490 "internalType": "struct Tuple6",
491 "name": "sponsor",
492 "type": "tuple"
493 }
494 ],
495 "name": "setCollectionSponsorCross",
496 "outputs": [],
497 "stateMutability": "nonpayable",
498 "type": "function"
499 },
500 {
501 "inputs": [
502 {
503 "components": [
504 { "internalType": "address", "name": "field_0", "type": "address" },
505 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
506 ],
507 "internalType": "struct Tuple6",
508 "name": "newOwner",
509 "type": "tuple"
510 }
511 ],
512 "name": "setOwnerCross",
513 "outputs": [],
514 "stateMutability": "nonpayable",
515 "type": "function"
516 },
362 {517 {
363 "inputs": [518 "inputs": [
364 { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }519 { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }
403 "stateMutability": "nonpayable",558 "stateMutability": "nonpayable",
404 "type": "function"559 "type": "function"
405 },560 },
561 {
562 "inputs": [
563 {
564 "components": [
565 { "internalType": "address", "name": "field_0", "type": "address" },
566 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
567 ],
568 "internalType": "struct Tuple6",
569 "name": "from",
570 "type": "tuple"
571 },
572 {
573 "components": [
574 { "internalType": "address", "name": "field_0", "type": "address" },
575 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
576 ],
577 "internalType": "struct Tuple6",
578 "name": "to",
579 "type": "tuple"
580 },
581 { "internalType": "uint256", "name": "amount", "type": "uint256" }
582 ],
583 "name": "transferFromCross",
584 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
585 "stateMutability": "nonpayable",
586 "type": "function"
587 },
406 {588 {
407 "inputs": [],589 "inputs": [],
408 "name": "uniqueCollectionType",590 "name": "uniqueCollectionType",
modifiedtests/src/eth/nonFungible.test.tsdiffbeforeafterboth
246 }246 }
247 });247 });
248
249 itEth('Can perform burnFromCross()', async ({helper, privateKey}) => {
250 const alice = await privateKey('//Alice');
251 const collection = await helper.nft.mintCollection(alice, {name: 'A', description: 'B', tokenPrefix: 'C'});
252
253 const owner = await privateKey('//Bob');
254 const spender = await helper.eth.createAccountWithBalance(alice, 100n);
255
256 const token = await collection.mintToken(alice, {Substrate: owner.address});
257
258 const address = helper.ethAddress.fromCollectionId(collection.collectionId);
259 const contract = helper.ethNativeContract.collection(address, 'nft');
260
261 {
262 await token.approve(owner, {Ethereum: spender});
263 const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);
264 const result = await contract.methods.burnFromCross(ownerCross, token.tokenId).send({from: spender});
265 const events = result.events.Transfer;
266
267 expect(events).to.be.like({
268 address,
269 event: 'Transfer',
270 returnValues: {
271 from: helper.address.substrateToEth(owner.address),
272 to: '0x0000000000000000000000000000000000000000',
273 tokenId: token.tokenId.toString(),
274 },
275 });
276 }
277 });
278
279 itEth('Can perform approveCross()', async ({helper, privateKey}) => {
280 const alice = await privateKey('//Alice');
281 const collection = await helper.nft.mintCollection(alice, {name: 'A', description: 'B', tokenPrefix: 'C'});
282
283 const owner = await helper.eth.createAccountWithBalance(alice, 100n);
284 const receiver = await privateKey('//Charlie');
285
286 const token = await collection.mintToken(alice, {Ethereum: owner});
287
288 const address = helper.ethAddress.fromCollectionId(collection.collectionId);
289 const contract = helper.ethNativeContract.collection(address, 'nft');
290
291 {
292 const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);
293 const result = await contract.methods.approveCross(recieverCross, token.tokenId).send({from: owner});
294 const event = result.events.Approval;
295 expect(event).to.be.like({
296 address: helper.ethAddress.fromCollectionId(collection.collectionId),
297 event: 'Approval',
298 returnValues: {
299 owner,
300 approved: helper.address.substrateToEth(receiver.address),
301 tokenId: token.tokenId.toString(),
302 },
303 });
304 }
305 });
248306
249 itEth('Can perform transferFrom()', async ({helper}) => {307 itEth('Can perform transferFrom()', async ({helper}) => {
250 const owner = await helper.eth.createAccountWithBalance(donor);308 const owner = await helper.eth.createAccountWithBalance(donor);
351 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));409 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
352 });410 });
411
412 itEth('Can perform transferFromCross()', async ({helper, privateKey}) => {
413 const alice = await privateKey('//Alice');
414 const collection = await helper.nft.mintCollection(alice, {name: 'A', description: 'B', tokenPrefix: 'C'});
415
416 const owner = await privateKey('//Bob');
417 const spender = await helper.eth.createAccountWithBalance(alice, 100n);
418 const receiver = await privateKey('//Charlie');
419
420 const token = await collection.mintToken(alice, {Substrate: owner.address});
421
422 const address = helper.ethAddress.fromCollectionId(collection.collectionId);
423 const contract = helper.ethNativeContract.collection(address, 'nft');
424
425 await token.approve(owner, {Ethereum: spender});
426
427 {
428 const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);
429 const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);
430 const result = await contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: spender});
431 const event = result.events.Transfer;
432 expect(event).to.be.like({
433 address: helper.ethAddress.fromCollectionId(collection.collectionId),
434 event: 'Transfer',
435 returnValues: {
436 from: helper.address.substrateToEth(owner.address),
437 to: helper.address.substrateToEth(receiver.address),
438 tokenId: token.tokenId.toString(),
439 },
440 });
441 }
442
443 expect(await token.getOwner()).to.be.like({Substrate: receiver.address});
444 });
353445
354 itEth('transfer() call fee is less than 0.2UNQ', async ({helper}) => {446 itEth('transfer() call fee is less than 0.2UNQ', async ({helper}) => {
355 const owner = await helper.eth.createAccountWithBalance(donor);447 const owner = await helper.eth.createAccountWithBalance(donor);
modifiedtests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth
89 "stateMutability": "nonpayable",89 "stateMutability": "nonpayable",
90 "type": "function"90 "type": "function"
91 },91 },
92 {
93 "inputs": [
94 {
95 "components": [
96 { "internalType": "address", "name": "field_0", "type": "address" },
97 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
98 ],
99 "internalType": "struct Tuple6",
100 "name": "newAdmin",
101 "type": "tuple"
102 }
103 ],
104 "name": "addCollectionAdminCross",
105 "outputs": [],
106 "stateMutability": "nonpayable",
107 "type": "function"
108 },
92 {109 {
93 "inputs": [110 "inputs": [
94 { "internalType": "address", "name": "user", "type": "address" }111 { "internalType": "address", "name": "user", "type": "address" }
98 "stateMutability": "nonpayable",115 "stateMutability": "nonpayable",
99 "type": "function"116 "type": "function"
100 },117 },
118 {
119 "inputs": [
120 {
121 "components": [
122 { "internalType": "address", "name": "field_0", "type": "address" },
123 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
124 ],
125 "internalType": "struct Tuple6",
126 "name": "user",
127 "type": "tuple"
128 }
129 ],
130 "name": "addToCollectionAllowListCross",
131 "outputs": [],
132 "stateMutability": "nonpayable",
133 "type": "function"
134 },
101 {135 {
102 "inputs": [136 "inputs": [
103 { "internalType": "address", "name": "user", "type": "address" }137 { "internalType": "address", "name": "user", "type": "address" }
117 "stateMutability": "nonpayable",151 "stateMutability": "nonpayable",
118 "type": "function"152 "type": "function"
119 },153 },
154 {
155 "inputs": [
156 {
157 "components": [
158 { "internalType": "address", "name": "field_0", "type": "address" },
159 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
160 ],
161 "internalType": "struct Tuple6",
162 "name": "approved",
163 "type": "tuple"
164 },
165 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }
166 ],
167 "name": "approveCross",
168 "outputs": [],
169 "stateMutability": "nonpayable",
170 "type": "function"
171 },
120 {172 {
121 "inputs": [173 "inputs": [
122 { "internalType": "address", "name": "owner", "type": "address" }174 { "internalType": "address", "name": "owner", "type": "address" }
145 "stateMutability": "nonpayable",197 "stateMutability": "nonpayable",
146 "type": "function"198 "type": "function"
147 },199 },
200 {
201 "inputs": [
202 {
203 "components": [
204 { "internalType": "address", "name": "field_0", "type": "address" },
205 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
206 ],
207 "internalType": "struct Tuple6",
208 "name": "from",
209 "type": "tuple"
210 },
211 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }
212 ],
213 "name": "burnFromCross",
214 "outputs": [],
215 "stateMutability": "nonpayable",
216 "type": "function"
217 },
148 {218 {
149 "inputs": [219 "inputs": [
150 { "internalType": "address", "name": "newOwner", "type": "address" }220 { "internalType": "address", "name": "newOwner", "type": "address" }
163 { "internalType": "address", "name": "field_0", "type": "address" },233 { "internalType": "address", "name": "field_0", "type": "address" },
164 { "internalType": "uint256", "name": "field_1", "type": "uint256" }234 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
165 ],235 ],
166 "internalType": "struct Tuple17[]",236 "internalType": "struct Tuple6[]",
167 "name": "",237 "name": "",
168 "type": "tuple[]"238 "type": "tuple[]"
169 }239 }
180 { "internalType": "address", "name": "field_0", "type": "address" },250 { "internalType": "address", "name": "field_0", "type": "address" },
181 { "internalType": "uint256", "name": "field_1", "type": "uint256" }251 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
182 ],252 ],
183 "internalType": "struct Tuple17",253 "internalType": "struct Tuple6",
184 "name": "",254 "name": "",
185 "type": "tuple"255 "type": "tuple"
186 }256 }
204 { "internalType": "address", "name": "field_0", "type": "address" },274 { "internalType": "address", "name": "field_0", "type": "address" },
205 { "internalType": "uint256", "name": "field_1", "type": "uint256" }275 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
206 ],276 ],
207 "internalType": "struct Tuple17",277 "internalType": "struct Tuple6",
208 "name": "",278 "name": "",
209 "type": "tuple"279 "type": "tuple"
210 }280 }
285 "stateMutability": "view",355 "stateMutability": "view",
286 "type": "function"356 "type": "function"
287 },357 },
358 {
359 "inputs": [
360 {
361 "components": [
362 { "internalType": "address", "name": "field_0", "type": "address" },
363 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
364 ],
365 "internalType": "struct Tuple6",
366 "name": "user",
367 "type": "tuple"
368 }
369 ],
370 "name": "isOwnerOrAdminCross",
371 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
372 "stateMutability": "view",
373 "type": "function"
374 },
288 {375 {
289 "inputs": [{ "internalType": "address", "name": "to", "type": "address" }],376 "inputs": [{ "internalType": "address", "name": "to", "type": "address" }],
290 "name": "mint",377 "name": "mint",
351 "stateMutability": "nonpayable",438 "stateMutability": "nonpayable",
352 "type": "function"439 "type": "function"
353 },440 },
441 {
442 "inputs": [
443 {
444 "components": [
445 { "internalType": "address", "name": "field_0", "type": "address" },
446 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
447 ],
448 "internalType": "struct Tuple6",
449 "name": "admin",
450 "type": "tuple"
451 }
452 ],
453 "name": "removeCollectionAdminCross",
454 "outputs": [],
455 "stateMutability": "nonpayable",
456 "type": "function"
457 },
354 {458 {
355 "inputs": [],459 "inputs": [],
356 "name": "removeCollectionSponsor",460 "name": "removeCollectionSponsor",
367 "stateMutability": "nonpayable",471 "stateMutability": "nonpayable",
368 "type": "function"472 "type": "function"
369 },473 },
474 {
475 "inputs": [
476 {
477 "components": [
478 { "internalType": "address", "name": "field_0", "type": "address" },
479 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
480 ],
481 "internalType": "struct Tuple6",
482 "name": "user",
483 "type": "tuple"
484 }
485 ],
486 "name": "removeFromCollectionAllowListCross",
487 "outputs": [],
488 "stateMutability": "nonpayable",
489 "type": "function"
490 },
370 {491 {
371 "inputs": [492 "inputs": [
372 { "internalType": "address", "name": "from", "type": "address" },493 { "internalType": "address", "name": "from", "type": "address" },
474 "stateMutability": "nonpayable",595 "stateMutability": "nonpayable",
475 "type": "function"596 "type": "function"
476 },597 },
598 {
599 "inputs": [
600 {
601 "components": [
602 { "internalType": "address", "name": "field_0", "type": "address" },
603 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
604 ],
605 "internalType": "struct Tuple6",
606 "name": "sponsor",
607 "type": "tuple"
608 }
609 ],
610 "name": "setCollectionSponsorCross",
611 "outputs": [],
612 "stateMutability": "nonpayable",
613 "type": "function"
614 },
615 {
616 "inputs": [
617 {
618 "components": [
619 { "internalType": "address", "name": "field_0", "type": "address" },
620 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
621 ],
622 "internalType": "struct Tuple6",
623 "name": "newOwner",
624 "type": "tuple"
625 }
626 ],
627 "name": "setOwnerCross",
628 "outputs": [],
629 "stateMutability": "nonpayable",
630 "type": "function"
631 },
477 {632 {
478 "inputs": [633 "inputs": [
479 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },634 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },
569 "stateMutability": "nonpayable",724 "stateMutability": "nonpayable",
570 "type": "function"725 "type": "function"
571 },726 },
727 {
728 "inputs": [
729 {
730 "components": [
731 { "internalType": "address", "name": "field_0", "type": "address" },
732 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
733 ],
734 "internalType": "struct Tuple6",
735 "name": "from",
736 "type": "tuple"
737 },
738 {
739 "components": [
740 { "internalType": "address", "name": "field_0", "type": "address" },
741 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
742 ],
743 "internalType": "struct Tuple6",
744 "name": "to",
745 "type": "tuple"
746 },
747 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }
748 ],
749 "name": "transferFromCross",
750 "outputs": [],
751 "stateMutability": "nonpayable",
752 "type": "function"
753 },
572 {754 {
573 "inputs": [],755 "inputs": [],
574 "name": "uniqueCollectionType",756 "name": "uniqueCollectionType",
modifiedtests/src/eth/reFungible.test.tsdiffbeforeafterboth
227 }227 }
228 });228 });
229
230 itEth('Can perform burnFrom()', async ({helper, privateKey}) => {
231 const alice = await privateKey('//Alice');
232 const collection = await helper.rft.mintCollection(alice, {name: 'A', description: 'B', tokenPrefix: 'C'});
233
234 const owner = await helper.eth.createAccountWithBalance(alice, 100n);
235 const spender = await helper.eth.createAccountWithBalance(alice, 100n);
236
237 const token = await collection.mintToken(alice, 100n, {Ethereum: owner});
238
239 const address = helper.ethAddress.fromCollectionId(collection.collectionId);
240 const contract = helper.ethNativeContract.collection(address, 'rft');
241
242 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, token.tokenId);
243 const tokenContract = helper.ethNativeContract.rftToken(tokenAddress, owner);
244 await tokenContract.methods.repartition(15).send();
245 await tokenContract.methods.approve(spender, 15).send();
246
247 {
248 const result = await contract.methods.burnFrom(owner, token.tokenId).send({from: spender});
249 const event = result.events.Transfer;
250 expect(event).to.be.like({
251 address: helper.ethAddress.fromCollectionId(collection.collectionId),
252 event: 'Transfer',
253 returnValues: {
254 from: owner,
255 to: '0x0000000000000000000000000000000000000000',
256 tokenId: token.tokenId.toString(),
257 },
258 });
259 }
260
261 expect(await collection.getTokenBalance(token.tokenId, {Ethereum: owner})).to.be.eq(0n);
262 });
263
264 itEth('Can perform burnFromCross()', async ({helper, privateKey}) => {
265 const alice = await privateKey('//Alice');
266 const collection = await helper.rft.mintCollection(alice, {name: 'A', description: 'B', tokenPrefix: 'C'});
267
268 const owner = await privateKey('//Bob');
269 const spender = await helper.eth.createAccountWithBalance(alice, 100n);
270
271 const token = await collection.mintToken(alice, 100n, {Substrate: owner.address});
272
273 const address = helper.ethAddress.fromCollectionId(collection.collectionId);
274 const contract = helper.ethNativeContract.collection(address, 'rft');
275
276 await token.repartition(owner, 15n);
277 await token.approve(owner, {Ethereum: spender}, 15n);
278
279 {
280 const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);
281 const result = await contract.methods.burnFromCross(ownerCross, token.tokenId).send({from: spender});
282 const event = result.events.Transfer;
283 expect(event).to.be.like({
284 address: helper.ethAddress.fromCollectionId(collection.collectionId),
285 event: 'Transfer',
286 returnValues: {
287 from: helper.address.substrateToEth(owner.address),
288 to: '0x0000000000000000000000000000000000000000',
289 tokenId: token.tokenId.toString(),
290 },
291 });
292 }
293
294 expect(await collection.getTokenBalance(token.tokenId, {Substrate: owner.address})).to.be.eq(0n);
295 });
296
297 itEth('Can perform transferFromCross()', async ({helper, privateKey}) => {
298 const alice = await privateKey('//Alice');
299 const collection = await helper.rft.mintCollection(alice, {name: 'A', description: 'B', tokenPrefix: 'C'});
300
301 const owner = await privateKey('//Bob');
302 const spender = await helper.eth.createAccountWithBalance(alice, 100n);
303 const receiver = await privateKey('//Charlie');
304
305 const token = await collection.mintToken(alice, 100n, {Substrate: owner.address});
306
307 const address = helper.ethAddress.fromCollectionId(collection.collectionId);
308 const contract = helper.ethNativeContract.collection(address, 'rft');
309
310 await token.repartition(owner, 15n);
311 await token.approve(owner, {Ethereum: spender}, 15n);
312
313 {
314 const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);
315 const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);
316 const result = await contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: spender});
317 const event = result.events.Transfer;
318 expect(event).to.be.like({
319 address: helper.ethAddress.fromCollectionId(collection.collectionId),
320 event: 'Transfer',
321 returnValues: {
322 from: helper.address.substrateToEth(owner.address),
323 to: helper.address.substrateToEth(receiver.address),
324 tokenId: token.tokenId.toString(),
325 },
326 });
327 }
328
329 expect(await token.getTop10Owners()).to.be.like([{Substrate: receiver.address}]);
330 });
229331
230 itEth('Can perform transfer()', async ({helper}) => {332 itEth('Can perform transfer()', async ({helper}) => {
231 const caller = await helper.eth.createAccountWithBalance(donor);333 const caller = await helper.eth.createAccountWithBalance(donor);
modifiedtests/src/eth/reFungibleAbi.jsondiffbeforeafterboth
89 "stateMutability": "nonpayable",89 "stateMutability": "nonpayable",
90 "type": "function"90 "type": "function"
91 },91 },
92 {
93 "inputs": [
94 {
95 "components": [
96 { "internalType": "address", "name": "field_0", "type": "address" },
97 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
98 ],
99 "internalType": "struct Tuple6",
100 "name": "newAdmin",
101 "type": "tuple"
102 }
103 ],
104 "name": "addCollectionAdminCross",
105 "outputs": [],
106 "stateMutability": "nonpayable",
107 "type": "function"
108 },
92 {109 {
93 "inputs": [110 "inputs": [
94 { "internalType": "address", "name": "user", "type": "address" }111 { "internalType": "address", "name": "user", "type": "address" }
98 "stateMutability": "nonpayable",115 "stateMutability": "nonpayable",
99 "type": "function"116 "type": "function"
100 },117 },
118 {
119 "inputs": [
120 {
121 "components": [
122 { "internalType": "address", "name": "field_0", "type": "address" },
123 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
124 ],
125 "internalType": "struct Tuple6",
126 "name": "user",
127 "type": "tuple"
128 }
129 ],
130 "name": "addToCollectionAllowListCross",
131 "outputs": [],
132 "stateMutability": "nonpayable",
133 "type": "function"
134 },
101 {135 {
102 "inputs": [136 "inputs": [
103 { "internalType": "address", "name": "user", "type": "address" }137 { "internalType": "address", "name": "user", "type": "address" }
145 "stateMutability": "nonpayable",179 "stateMutability": "nonpayable",
146 "type": "function"180 "type": "function"
147 },181 },
182 {
183 "inputs": [
184 {
185 "components": [
186 { "internalType": "address", "name": "field_0", "type": "address" },
187 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
188 ],
189 "internalType": "struct Tuple6",
190 "name": "from",
191 "type": "tuple"
192 },
193 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }
194 ],
195 "name": "burnFromCross",
196 "outputs": [],
197 "stateMutability": "nonpayable",
198 "type": "function"
199 },
148 {200 {
149 "inputs": [201 "inputs": [
150 { "internalType": "address", "name": "newOwner", "type": "address" }202 { "internalType": "address", "name": "newOwner", "type": "address" }
163 { "internalType": "address", "name": "field_0", "type": "address" },215 { "internalType": "address", "name": "field_0", "type": "address" },
164 { "internalType": "uint256", "name": "field_1", "type": "uint256" }216 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
165 ],217 ],
166 "internalType": "struct Tuple17[]",218 "internalType": "struct Tuple6[]",
167 "name": "",219 "name": "",
168 "type": "tuple[]"220 "type": "tuple[]"
169 }221 }
180 { "internalType": "address", "name": "field_0", "type": "address" },232 { "internalType": "address", "name": "field_0", "type": "address" },
181 { "internalType": "uint256", "name": "field_1", "type": "uint256" }233 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
182 ],234 ],
183 "internalType": "struct Tuple17",235 "internalType": "struct Tuple6",
184 "name": "",236 "name": "",
185 "type": "tuple"237 "type": "tuple"
186 }238 }
204 { "internalType": "address", "name": "field_0", "type": "address" },256 { "internalType": "address", "name": "field_0", "type": "address" },
205 { "internalType": "uint256", "name": "field_1", "type": "uint256" }257 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
206 ],258 ],
207 "internalType": "struct Tuple17",259 "internalType": "struct Tuple6",
208 "name": "",260 "name": "",
209 "type": "tuple"261 "type": "tuple"
210 }262 }
285 "stateMutability": "view",337 "stateMutability": "view",
286 "type": "function"338 "type": "function"
287 },339 },
340 {
341 "inputs": [
342 {
343 "components": [
344 { "internalType": "address", "name": "field_0", "type": "address" },
345 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
346 ],
347 "internalType": "struct Tuple6",
348 "name": "user",
349 "type": "tuple"
350 }
351 ],
352 "name": "isOwnerOrAdminCross",
353 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
354 "stateMutability": "view",
355 "type": "function"
356 },
288 {357 {
289 "inputs": [{ "internalType": "address", "name": "to", "type": "address" }],358 "inputs": [{ "internalType": "address", "name": "to", "type": "address" }],
290 "name": "mint",359 "name": "mint",
351 "stateMutability": "nonpayable",420 "stateMutability": "nonpayable",
352 "type": "function"421 "type": "function"
353 },422 },
423 {
424 "inputs": [
425 {
426 "components": [
427 { "internalType": "address", "name": "field_0", "type": "address" },
428 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
429 ],
430 "internalType": "struct Tuple6",
431 "name": "admin",
432 "type": "tuple"
433 }
434 ],
435 "name": "removeCollectionAdminCross",
436 "outputs": [],
437 "stateMutability": "nonpayable",
438 "type": "function"
439 },
354 {440 {
355 "inputs": [],441 "inputs": [],
356 "name": "removeCollectionSponsor",442 "name": "removeCollectionSponsor",
367 "stateMutability": "nonpayable",453 "stateMutability": "nonpayable",
368 "type": "function"454 "type": "function"
369 },455 },
456 {
457 "inputs": [
458 {
459 "components": [
460 { "internalType": "address", "name": "field_0", "type": "address" },
461 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
462 ],
463 "internalType": "struct Tuple6",
464 "name": "user",
465 "type": "tuple"
466 }
467 ],
468 "name": "removeFromCollectionAllowListCross",
469 "outputs": [],
470 "stateMutability": "nonpayable",
471 "type": "function"
472 },
370 {473 {
371 "inputs": [474 "inputs": [
372 { "internalType": "address", "name": "from", "type": "address" },475 { "internalType": "address", "name": "from", "type": "address" },
474 "stateMutability": "nonpayable",577 "stateMutability": "nonpayable",
475 "type": "function"578 "type": "function"
476 },579 },
580 {
581 "inputs": [
582 {
583 "components": [
584 { "internalType": "address", "name": "field_0", "type": "address" },
585 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
586 ],
587 "internalType": "struct Tuple6",
588 "name": "sponsor",
589 "type": "tuple"
590 }
591 ],
592 "name": "setCollectionSponsorCross",
593 "outputs": [],
594 "stateMutability": "nonpayable",
595 "type": "function"
596 },
597 {
598 "inputs": [
599 {
600 "components": [
601 { "internalType": "address", "name": "field_0", "type": "address" },
602 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
603 ],
604 "internalType": "struct Tuple6",
605 "name": "newOwner",
606 "type": "tuple"
607 }
608 ],
609 "name": "setOwnerCross",
610 "outputs": [],
611 "stateMutability": "nonpayable",
612 "type": "function"
613 },
477 {614 {
478 "inputs": [615 "inputs": [
479 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },616 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },
578 "stateMutability": "nonpayable",715 "stateMutability": "nonpayable",
579 "type": "function"716 "type": "function"
580 },717 },
718 {
719 "inputs": [
720 {
721 "components": [
722 { "internalType": "address", "name": "field_0", "type": "address" },
723 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
724 ],
725 "internalType": "struct Tuple6",
726 "name": "from",
727 "type": "tuple"
728 },
729 {
730 "components": [
731 { "internalType": "address", "name": "field_0", "type": "address" },
732 { "internalType": "uint256", "name": "field_1", "type": "uint256" }
733 ],
734 "internalType": "struct Tuple6",
735 "name": "to",
736 "type": "tuple"
737 },
738 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }
739 ],
740 "name": "transferFromCross",
741 "outputs": [],
742 "stateMutability": "nonpayable",
743 "type": "function"
744 },
581 {745 {
582 "inputs": [],746 "inputs": [],
583 "name": "uniqueCollectionType",747 "name": "uniqueCollectionType",
modifiedtests/src/eth/util/playgrounds/types.tsdiffbeforeafterboth
13 event: string,13 event: string,
14 args: { [key: string]: string }14 args: { [key: string]: string }
15};15};
16export interface TEthCrossAccount {
17 readonly 0: string,
18 readonly 1: string | Uint8Array,
19 readonly field_0: string,
20 readonly field_1: string | Uint8Array,
21}
1622
modifiedtests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth
1818
19import {DevUniqueHelper} from '../../../util/playgrounds/unique.dev';19import {DevUniqueHelper} from '../../../util/playgrounds/unique.dev';
2020
21import {ContractImports, CompiledContract, NormalizedEvent} from './types';21import {ContractImports, CompiledContract, TEthCrossAccount, NormalizedEvent} from './types';
2222
23// Native contracts ABI23// Native contracts ABI
24import collectionHelpersAbi from '../../collectionHelpersAbi.json';24import collectionHelpersAbi from '../../collectionHelpersAbi.json';
343343
344export type EthUniqueHelperConstructor = new (...args: any[]) => EthUniqueHelper;344export type EthUniqueHelperConstructor = new (...args: any[]) => EthUniqueHelper;
345
346export class EthCrossAccountGroup extends EthGroupBase {
347 fromAddress(address: TEthereumAccount): TEthCrossAccount {
348 return {
349 0: address,
350 1: '0',
351 field_0: address,
352 field_1: '0',
353 };
354 }
355
356 fromKeyringPair(keyring: IKeyringPair): TEthCrossAccount {
357 return {
358 0: '0x0000000000000000000000000000000000000000',
359 1: keyring.addressRaw,
360 field_0: '0x0000000000000000000000000000000000000000',
361 field_1: keyring.addressRaw,
362 };
363 }
364}
345365
346export class EthUniqueHelper extends DevUniqueHelper {366export class EthUniqueHelper extends DevUniqueHelper {
347 web3: Web3 | null = null;367 web3: Web3 | null = null;
351 ethAddress: EthAddressGroup;371 ethAddress: EthAddressGroup;
352 ethNativeContract: NativeContractGroup;372 ethNativeContract: NativeContractGroup;
353 ethContract: ContractGroup;373 ethContract: ContractGroup;
374 ethCrossAccount: EthCrossAccountGroup;
354375
355 constructor(logger: { log: (msg: any, level: any) => void, level: any }, options: {[key: string]: any} = {}) {376 constructor(logger: { log: (msg: any, level: any) => void, level: any }, options: {[key: string]: any} = {}) {
356 options.helperBase = options.helperBase ?? EthUniqueHelper;377 options.helperBase = options.helperBase ?? EthUniqueHelper;
357378
358 super(logger, options);379 super(logger, options);
359 this.eth = new EthGroup(this);380 this.eth = new EthGroup(this);
360 this.ethAddress = new EthAddressGroup(this);381 this.ethAddress = new EthAddressGroup(this);
382 this.ethCrossAccount = new EthCrossAccountGroup(this);
361 this.ethNativeContract = new NativeContractGroup(this);383 this.ethNativeContract = new NativeContractGroup(this);
362 this.ethContract = new ContractGroup(this);384 this.ethContract = new ContractGroup(this);
363 }385 }