difftreelog
Merge pull request #919 from UniqueNetwork/feature/crossBalanceOf
in: master
26 files changed
pallets/fungible/src/erc.rsdiffbeforeafterboth--- a/pallets/fungible/src/erc.rs
+++ b/pallets/fungible/src/erc.rs
@@ -327,6 +327,15 @@
fn collection_helper_address(&self) -> Result<Address> {
Ok(T::ContractAddress::get())
}
+
+ /// @notice Balance of account
+ /// @param owner An cross address for whom to query the balance
+ /// @return The number of fingibles owned by `owner`, possibly zero
+ fn balance_of_cross(&self, owner: CrossAddress) -> Result<U256> {
+ self.consume_store_reads(1)?;
+ let balance = <Balance<T>>::get((self.id, owner.into_sub_cross_account::<T>()?));
+ Ok(balance.into())
+ }
}
#[solidity_interface(
pallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth--- a/pallets/fungible/src/stubs/UniqueFungible.sol
+++ b/pallets/fungible/src/stubs/UniqueFungible.sol
@@ -511,7 +511,7 @@
bytes value;
}
-/// @dev the ERC-165 identifier for this interface is 0x85d7dea6
+/// @dev the ERC-165 identifier for this interface is 0x69d14d3e
contract ERC20UniqueExtensions is Dummy, ERC165 {
/// @dev Function to check the amount of tokens that an owner allowed to a spender.
/// @param owner crossAddress The address which owns the funds.
@@ -630,6 +630,18 @@
dummy;
return 0x0000000000000000000000000000000000000000;
}
+
+ /// @notice Balance of account
+ /// @param owner An cross address for whom to query the balance
+ /// @return The number of fingibles owned by `owner`, possibly zero
+ /// @dev EVM selector for this function is: 0xec069398,
+ /// or in textual repr: balanceOfCross((address,uint256))
+ function balanceOfCross(CrossAddress memory owner) public view returns (uint256) {
+ require(false, stub_error);
+ owner;
+ dummy;
+ return 0;
+ }
}
struct AmountForAddress {
pallets/nonfungible/src/erc.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -749,12 +749,29 @@
/// Returns the owner (in cross format) of the token.
///
/// @param tokenId Id for the token.
+ #[solidity(hide)]
fn cross_owner_of(&self, token_id: U256) -> Result<eth::CrossAddress> {
+ Self::owner_of_cross(&self, token_id)
+ }
+
+ /// Returns the owner (in cross format) of the token.
+ ///
+ /// @param tokenId Id for the token.
+ fn owner_of_cross(&self, token_id: U256) -> Result<eth::CrossAddress> {
Self::token_owner(&self, token_id.try_into()?)
.map(|o| eth::CrossAddress::from_sub_cross_account::<T>(&o))
.map_err(|_| Error::Revert("token not found".into()))
}
+ /// @notice Count all NFTs assigned to an owner
+ /// @param owner An cross address for whom to query the balance
+ /// @return The number of NFTs owned by `owner`, possibly zero
+ fn balance_of_cross(&self, owner: eth::CrossAddress) -> Result<U256> {
+ self.consume_store_reads(1)?;
+ let balance = <AccountBalance<T>>::get((self.id, owner.into_sub_cross_account::<T>()?));
+ Ok(balance.into())
+ }
+
/// Returns the token properties.
///
/// @param tokenId Id for the token.
pallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterbothbinary blob — no preview
pallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -774,7 +774,7 @@
}
/// @title Unique extensions for ERC721.
-/// @dev the ERC-165 identifier for this interface is 0x16de3152
+/// @dev the ERC-165 identifier for this interface is 0x307b061a
contract ERC721UniqueExtensions is Dummy, ERC165 {
/// @notice A descriptive name for a collection of NFTs in this contract
/// @dev EVM selector for this function is: 0x06fdde03,
@@ -803,18 +803,42 @@
return "";
}
+ // /// Returns the owner (in cross format) of the token.
+ // ///
+ // /// @param tokenId Id for the token.
+ // /// @dev EVM selector for this function is: 0x2b29dace,
+ // /// or in textual repr: crossOwnerOf(uint256)
+ // function crossOwnerOf(uint256 tokenId) public view returns (CrossAddress memory) {
+ // require(false, stub_error);
+ // tokenId;
+ // dummy;
+ // return CrossAddress(0x0000000000000000000000000000000000000000,0);
+ // }
+
/// Returns the owner (in cross format) of the token.
///
/// @param tokenId Id for the token.
- /// @dev EVM selector for this function is: 0x2b29dace,
- /// or in textual repr: crossOwnerOf(uint256)
- function crossOwnerOf(uint256 tokenId) public view returns (CrossAddress memory) {
+ /// @dev EVM selector for this function is: 0xcaa3a4d0,
+ /// or in textual repr: ownerOfCross(uint256)
+ function ownerOfCross(uint256 tokenId) public view returns (CrossAddress memory) {
require(false, stub_error);
tokenId;
dummy;
return CrossAddress(0x0000000000000000000000000000000000000000, 0);
}
+ /// @notice Count all NFTs assigned to an owner
+ /// @param owner An cross address for whom to query the balance
+ /// @return The number of NFTs owned by `owner`, possibly zero
+ /// @dev EVM selector for this function is: 0xec069398,
+ /// or in textual repr: balanceOfCross((address,uint256))
+ function balanceOfCross(CrossAddress memory owner) public view returns (uint256) {
+ require(false, stub_error);
+ owner;
+ dummy;
+ return 0;
+ }
+
/// Returns the token properties.
///
/// @param tokenId Id for the token.
pallets/refungible/src/erc.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -783,7 +783,15 @@
/// Returns the owner (in cross format) of the token.
///
/// @param tokenId Id for the token.
+ #[solidity(hide)]
fn cross_owner_of(&self, token_id: U256) -> Result<eth::CrossAddress> {
+ Self::owner_of_cross(&self, token_id)
+ }
+
+ /// Returns the owner (in cross format) of the token.
+ ///
+ /// @param tokenId Id for the token.
+ fn owner_of_cross(&self, token_id: U256) -> Result<eth::CrossAddress> {
Self::token_owner(&self, token_id.try_into()?)
.map(|o| eth::CrossAddress::from_sub_cross_account::<T>(&o))
.or_else(|err| match err {
@@ -794,6 +802,15 @@
})
}
+ /// @notice Count all RFTs assigned to an owner
+ /// @param owner An cross address for whom to query the balance
+ /// @return The number of RFTs owned by `owner`, possibly zero
+ fn balance_of_cross(&self, owner: eth::CrossAddress) -> Result<U256> {
+ self.consume_store_reads(1)?;
+ let balance = <AccountBalance<T>>::get((self.id, owner.into_sub_cross_account::<T>()?));
+ Ok(balance.into())
+ }
+
/// Returns the token properties.
///
/// @param tokenId Id for the token.
pallets/refungible/src/erc_token.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc_token.rs
+++ b/pallets/refungible/src/erc_token.rs
@@ -283,6 +283,16 @@
.map_err(dispatch_to_evm::<T>)?;
Ok(true)
}
+
+ /// @notice Balance of account
+ /// @param owner An cross address for whom to query the balance
+ /// @return The number of fingibles owned by `owner`, possibly zero
+ fn balance_of_cross(&self, owner: CrossAddress) -> Result<U256> {
+ self.consume_store_reads(1)?;
+ let balance = <Balance<T>>::get((self.id, self.1, owner.into_sub_cross_account::<T>()?));
+ Ok(balance.into())
+ }
+
/// @dev Function that changes total amount of the tokens.
/// Throws if `msg.sender` doesn't owns all of the tokens.
/// @param amount New total amount of the tokens.
pallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth--- a/pallets/refungible/src/stubs/UniqueRefungible.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungible.sol
@@ -774,7 +774,7 @@
}
/// @title Unique extensions for ERC721.
-/// @dev the ERC-165 identifier for this interface is 0xb365c124
+/// @dev the ERC-165 identifier for this interface is 0x95c0f66c
contract ERC721UniqueExtensions is Dummy, ERC165 {
/// @notice A descriptive name for a collection of NFTs in this contract
/// @dev EVM selector for this function is: 0x06fdde03,
@@ -803,18 +803,42 @@
return "";
}
+ // /// Returns the owner (in cross format) of the token.
+ // ///
+ // /// @param tokenId Id for the token.
+ // /// @dev EVM selector for this function is: 0x2b29dace,
+ // /// or in textual repr: crossOwnerOf(uint256)
+ // function crossOwnerOf(uint256 tokenId) public view returns (CrossAddress memory) {
+ // require(false, stub_error);
+ // tokenId;
+ // dummy;
+ // return CrossAddress(0x0000000000000000000000000000000000000000,0);
+ // }
+
/// Returns the owner (in cross format) of the token.
///
/// @param tokenId Id for the token.
- /// @dev EVM selector for this function is: 0x2b29dace,
- /// or in textual repr: crossOwnerOf(uint256)
- function crossOwnerOf(uint256 tokenId) public view returns (CrossAddress memory) {
+ /// @dev EVM selector for this function is: 0xcaa3a4d0,
+ /// or in textual repr: ownerOfCross(uint256)
+ function ownerOfCross(uint256 tokenId) public view returns (CrossAddress memory) {
require(false, stub_error);
tokenId;
dummy;
return CrossAddress(0x0000000000000000000000000000000000000000, 0);
}
+ /// @notice Count all RFTs assigned to an owner
+ /// @param owner An cross address for whom to query the balance
+ /// @return The number of RFTs owned by `owner`, possibly zero
+ /// @dev EVM selector for this function is: 0xec069398,
+ /// or in textual repr: balanceOfCross((address,uint256))
+ function balanceOfCross(CrossAddress memory owner) public view returns (uint256) {
+ require(false, stub_error);
+ owner;
+ dummy;
+ return 0;
+ }
+
/// Returns the token properties.
///
/// @param tokenId Id for the token.
pallets/refungible/src/stubs/UniqueRefungibleToken.rawdiffbeforeafterbothbinary blob — no preview
pallets/refungible/src/stubs/UniqueRefungibleToken.soldiffbeforeafterboth--- a/pallets/refungible/src/stubs/UniqueRefungibleToken.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungibleToken.sol
@@ -36,7 +36,7 @@
}
}
-/// @dev the ERC-165 identifier for this interface is 0x01d536fc
+/// @dev the ERC-165 identifier for this interface is 0xedd3a564
contract ERC20UniqueExtensions is Dummy, ERC165 {
/// @dev Function to check the amount of tokens that an owner allowed to a spender.
/// @param owner crossAddress The address which owns the funds.
@@ -97,6 +97,18 @@
return false;
}
+ /// @notice Balance of account
+ /// @param owner An cross address for whom to query the balance
+ /// @return The number of fingibles owned by `owner`, possibly zero
+ /// @dev EVM selector for this function is: 0xec069398,
+ /// or in textual repr: balanceOfCross((address,uint256))
+ function balanceOfCross(CrossAddress memory owner) public view returns (uint256) {
+ require(false, stub_error);
+ owner;
+ dummy;
+ return 0;
+ }
+
/// @dev Function that changes total amount of the tokens.
/// Throws if `msg.sender` doesn't owns all of the tokens.
/// @param amount New total amount of the tokens.
runtime/common/ethereum/sponsoring/refungible.rsdiffbeforeafterboth--- a/runtime/common/ethereum/sponsoring/refungible.rs
+++ b/runtime/common/ethereum/sponsoring/refungible.rs
@@ -227,6 +227,8 @@
| Symbol
| Description
| CrossOwnerOf { .. }
+ | OwnerOfCross { .. }
+ | BalanceOfCross { .. }
| Properties { .. }
| NextTokenId
| TokenContractAddress { .. }
@@ -341,9 +343,11 @@
ERC165Call(_, _) => None,
// Not sponsored
- AllowanceCross { .. } | BurnFrom { .. } | BurnFromCross { .. } | Repartition { .. } => {
- None
- }
+ AllowanceCross { .. }
+ | BalanceOfCross { .. }
+ | BurnFrom { .. }
+ | BurnFromCross { .. }
+ | Repartition { .. } => None,
TransferCross { .. } | TransferFromCross { .. } => {
let RefungibleTokenHandle(handle, token_id) = token;
tests/src/eth/abi/fungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/fungible.json
+++ b/tests/src/eth/abi/fungible.json
@@ -181,6 +181,23 @@
{ "internalType": "uint256", "name": "sub", "type": "uint256" }
],
"internalType": "struct CrossAddress",
+ "name": "owner",
+ "type": "tuple"
+ }
+ ],
+ "name": "balanceOfCross",
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "eth", "type": "address" },
+ { "internalType": "uint256", "name": "sub", "type": "uint256" }
+ ],
+ "internalType": "struct CrossAddress",
"name": "from",
"type": "tuple"
},
tests/src/eth/abi/nonFungible.jsondiffbeforeafterboth1[2 {3 "anonymous": false,4 "inputs": [5 {6 "indexed": true,7 "internalType": "address",8 "name": "owner",9 "type": "address"10 },11 {12 "indexed": true,13 "internalType": "address",14 "name": "approved",15 "type": "address"16 },17 {18 "indexed": true,19 "internalType": "uint256",20 "name": "tokenId",21 "type": "uint256"22 }23 ],24 "name": "Approval",25 "type": "event"26 },27 {28 "anonymous": false,29 "inputs": [30 {31 "indexed": true,32 "internalType": "address",33 "name": "owner",34 "type": "address"35 },36 {37 "indexed": true,38 "internalType": "address",39 "name": "operator",40 "type": "address"41 },42 {43 "indexed": false,44 "internalType": "bool",45 "name": "approved",46 "type": "bool"47 }48 ],49 "name": "ApprovalForAll",50 "type": "event"51 },52 {53 "anonymous": false,54 "inputs": [55 {56 "indexed": true,57 "internalType": "uint256",58 "name": "tokenId",59 "type": "uint256"60 }61 ],62 "name": "TokenChanged",63 "type": "event"64 },65 {66 "anonymous": false,67 "inputs": [68 {69 "indexed": true,70 "internalType": "address",71 "name": "from",72 "type": "address"73 },74 {75 "indexed": true,76 "internalType": "address",77 "name": "to",78 "type": "address"79 },80 {81 "indexed": true,82 "internalType": "uint256",83 "name": "tokenId",84 "type": "uint256"85 }86 ],87 "name": "Transfer",88 "type": "event"89 },90 {91 "inputs": [92 {93 "components": [94 { "internalType": "address", "name": "eth", "type": "address" },95 { "internalType": "uint256", "name": "sub", "type": "uint256" }96 ],97 "internalType": "struct CrossAddress",98 "name": "newAdmin",99 "type": "tuple"100 }101 ],102 "name": "addCollectionAdminCross",103 "outputs": [],104 "stateMutability": "nonpayable",105 "type": "function"106 },107 {108 "inputs": [109 {110 "components": [111 { "internalType": "address", "name": "eth", "type": "address" },112 { "internalType": "uint256", "name": "sub", "type": "uint256" }113 ],114 "internalType": "struct CrossAddress",115 "name": "user",116 "type": "tuple"117 }118 ],119 "name": "addToCollectionAllowListCross",120 "outputs": [],121 "stateMutability": "nonpayable",122 "type": "function"123 },124 {125 "inputs": [126 {127 "components": [128 { "internalType": "address", "name": "eth", "type": "address" },129 { "internalType": "uint256", "name": "sub", "type": "uint256" }130 ],131 "internalType": "struct CrossAddress",132 "name": "user",133 "type": "tuple"134 }135 ],136 "name": "allowlistedCross",137 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],138 "stateMutability": "view",139 "type": "function"140 },141 {142 "inputs": [143 { "internalType": "address", "name": "approved", "type": "address" },144 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }145 ],146 "name": "approve",147 "outputs": [],148 "stateMutability": "nonpayable",149 "type": "function"150 },151 {152 "inputs": [153 {154 "components": [155 { "internalType": "address", "name": "eth", "type": "address" },156 { "internalType": "uint256", "name": "sub", "type": "uint256" }157 ],158 "internalType": "struct CrossAddress",159 "name": "approved",160 "type": "tuple"161 },162 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }163 ],164 "name": "approveCross",165 "outputs": [],166 "stateMutability": "nonpayable",167 "type": "function"168 },169 {170 "inputs": [171 { "internalType": "address", "name": "owner", "type": "address" }172 ],173 "name": "balanceOf",174 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],175 "stateMutability": "view",176 "type": "function"177 },178 {179 "inputs": [180 {181 "components": [182 { "internalType": "address", "name": "eth", "type": "address" },183 { "internalType": "uint256", "name": "sub", "type": "uint256" }184 ],185 "internalType": "struct CrossAddress",186 "name": "owner",187 "type": "tuple"188 }189 ],190 "name": "balanceOfCross",191 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],192 "stateMutability": "view",193 "type": "function"194 },195 {196 "inputs": [197 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }198 ],199 "name": "burn",200 "outputs": [],201 "stateMutability": "nonpayable",202 "type": "function"203 },204 {205 "inputs": [206 {207 "components": [208 { "internalType": "address", "name": "eth", "type": "address" },209 { "internalType": "uint256", "name": "sub", "type": "uint256" }210 ],211 "internalType": "struct CrossAddress",212 "name": "from",213 "type": "tuple"214 },215 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }216 ],217 "name": "burnFromCross",218 "outputs": [],219 "stateMutability": "nonpayable",220 "type": "function"221 },222 {223 "inputs": [224 {225 "components": [226 { "internalType": "address", "name": "eth", "type": "address" },227 { "internalType": "uint256", "name": "sub", "type": "uint256" }228 ],229 "internalType": "struct CrossAddress",230 "name": "newOwner",231 "type": "tuple"232 }233 ],234 "name": "changeCollectionOwnerCross",235 "outputs": [],236 "stateMutability": "nonpayable",237 "type": "function"238 },239 {240 "inputs": [],241 "name": "collectionAdmins",242 "outputs": [243 {244 "components": [245 { "internalType": "address", "name": "eth", "type": "address" },246 { "internalType": "uint256", "name": "sub", "type": "uint256" }247 ],248 "internalType": "struct CrossAddress[]",249 "name": "",250 "type": "tuple[]"251 }252 ],253 "stateMutability": "view",254 "type": "function"255 },256 {257 "inputs": [],258 "name": "collectionHelperAddress",259 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],260 "stateMutability": "view",261 "type": "function"262 },263 {264 "inputs": [],265 "name": "collectionLimits",266 "outputs": [267 {268 "components": [269 {270 "internalType": "enum CollectionLimitField",271 "name": "field",272 "type": "uint8"273 },274 {275 "components": [276 { "internalType": "bool", "name": "status", "type": "bool" },277 { "internalType": "uint256", "name": "value", "type": "uint256" }278 ],279 "internalType": "struct OptionUint256",280 "name": "value",281 "type": "tuple"282 }283 ],284 "internalType": "struct CollectionLimit[]",285 "name": "",286 "type": "tuple[]"287 }288 ],289 "stateMutability": "view",290 "type": "function"291 },292 {293 "inputs": [],294 "name": "collectionNestingPermissions",295 "outputs": [296 {297 "components": [298 {299 "internalType": "enum CollectionPermissionField",300 "name": "field",301 "type": "uint8"302 },303 { "internalType": "bool", "name": "value", "type": "bool" }304 ],305 "internalType": "struct CollectionNestingPermission[]",306 "name": "",307 "type": "tuple[]"308 }309 ],310 "stateMutability": "view",311 "type": "function"312 },313 {314 "inputs": [],315 "name": "collectionNestingRestrictedCollectionIds",316 "outputs": [317 {318 "components": [319 { "internalType": "bool", "name": "token_owner", "type": "bool" },320 { "internalType": "uint256[]", "name": "ids", "type": "uint256[]" }321 ],322 "internalType": "struct CollectionNesting",323 "name": "",324 "type": "tuple"325 }326 ],327 "stateMutability": "view",328 "type": "function"329 },330 {331 "inputs": [],332 "name": "collectionOwner",333 "outputs": [334 {335 "components": [336 { "internalType": "address", "name": "eth", "type": "address" },337 { "internalType": "uint256", "name": "sub", "type": "uint256" }338 ],339 "internalType": "struct CrossAddress",340 "name": "",341 "type": "tuple"342 }343 ],344 "stateMutability": "view",345 "type": "function"346 },347 {348 "inputs": [349 { "internalType": "string[]", "name": "keys", "type": "string[]" }350 ],351 "name": "collectionProperties",352 "outputs": [353 {354 "components": [355 { "internalType": "string", "name": "key", "type": "string" },356 { "internalType": "bytes", "name": "value", "type": "bytes" }357 ],358 "internalType": "struct Property[]",359 "name": "",360 "type": "tuple[]"361 }362 ],363 "stateMutability": "view",364 "type": "function"365 },366 {367 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],368 "name": "collectionProperty",369 "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],370 "stateMutability": "view",371 "type": "function"372 },373 {374 "inputs": [],375 "name": "collectionSponsor",376 "outputs": [377 {378 "components": [379 { "internalType": "address", "name": "eth", "type": "address" },380 { "internalType": "uint256", "name": "sub", "type": "uint256" }381 ],382 "internalType": "struct CrossAddress",383 "name": "",384 "type": "tuple"385 }386 ],387 "stateMutability": "view",388 "type": "function"389 },390 {391 "inputs": [],392 "name": "confirmCollectionSponsorship",393 "outputs": [],394 "stateMutability": "nonpayable",395 "type": "function"396 },397 {398 "inputs": [],399 "name": "contractAddress",400 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],401 "stateMutability": "view",402 "type": "function"403 },404 {405 "inputs": [406 { "internalType": "string[]", "name": "keys", "type": "string[]" }407 ],408 "name": "deleteCollectionProperties",409 "outputs": [],410 "stateMutability": "nonpayable",411 "type": "function"412 },413 {414 "inputs": [415 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },416 { "internalType": "string[]", "name": "keys", "type": "string[]" }417 ],418 "name": "deleteProperties",419 "outputs": [],420 "stateMutability": "nonpayable",421 "type": "function"422 },423 {424 "inputs": [],425 "name": "description",426 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],427 "stateMutability": "view",428 "type": "function"429 },430 {431 "inputs": [432 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }433 ],434 "name": "getApproved",435 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],436 "stateMutability": "view",437 "type": "function"438 },439 {440 "inputs": [],441 "name": "hasCollectionPendingSponsor",442 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],443 "stateMutability": "view",444 "type": "function"445 },446 {447 "inputs": [448 { "internalType": "address", "name": "owner", "type": "address" },449 { "internalType": "address", "name": "operator", "type": "address" }450 ],451 "name": "isApprovedForAll",452 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],453 "stateMutability": "view",454 "type": "function"455 },456 {457 "inputs": [458 {459 "components": [460 { "internalType": "address", "name": "eth", "type": "address" },461 { "internalType": "uint256", "name": "sub", "type": "uint256" }462 ],463 "internalType": "struct CrossAddress",464 "name": "user",465 "type": "tuple"466 }467 ],468 "name": "isOwnerOrAdminCross",469 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],470 "stateMutability": "view",471 "type": "function"472 },473 {474 "inputs": [{ "internalType": "address", "name": "to", "type": "address" }],475 "name": "mint",476 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],477 "stateMutability": "nonpayable",478 "type": "function"479 },480 {481 "inputs": [482 {483 "components": [484 { "internalType": "address", "name": "eth", "type": "address" },485 { "internalType": "uint256", "name": "sub", "type": "uint256" }486 ],487 "internalType": "struct CrossAddress",488 "name": "to",489 "type": "tuple"490 },491 {492 "components": [493 { "internalType": "string", "name": "key", "type": "string" },494 { "internalType": "bytes", "name": "value", "type": "bytes" }495 ],496 "internalType": "struct Property[]",497 "name": "properties",498 "type": "tuple[]"499 }500 ],501 "name": "mintCross",502 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],503 "stateMutability": "nonpayable",504 "type": "function"505 },506 {507 "inputs": [508 { "internalType": "address", "name": "to", "type": "address" },509 { "internalType": "string", "name": "tokenUri", "type": "string" }510 ],511 "name": "mintWithTokenURI",512 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],513 "stateMutability": "nonpayable",514 "type": "function"515 },516 {517 "inputs": [],518 "name": "name",519 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],520 "stateMutability": "view",521 "type": "function"522 },523 {524 "inputs": [],525 "name": "nextTokenId",526 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],527 "stateMutability": "view",528 "type": "function"529 },530 {531 "inputs": [532 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }533 ],534 "name": "ownerOf",535 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],536 "stateMutability": "view",537 "type": "function"538 },539 {540 "inputs": [541 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }542 ],543 "name": "ownerOfCross",544 "outputs": [545 {546 "components": [547 { "internalType": "address", "name": "eth", "type": "address" },548 { "internalType": "uint256", "name": "sub", "type": "uint256" }549 ],550 "internalType": "struct CrossAddress",551 "name": "",552 "type": "tuple"553 }554 ],555 "stateMutability": "view",556 "type": "function"557 },558 {559 "inputs": [560 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },561 { "internalType": "string[]", "name": "keys", "type": "string[]" }562 ],563 "name": "properties",564 "outputs": [565 {566 "components": [567 { "internalType": "string", "name": "key", "type": "string" },568 { "internalType": "bytes", "name": "value", "type": "bytes" }569 ],570 "internalType": "struct Property[]",571 "name": "",572 "type": "tuple[]"573 }574 ],575 "stateMutability": "view",576 "type": "function"577 },578 {579 "inputs": [580 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },581 { "internalType": "string", "name": "key", "type": "string" }582 ],583 "name": "property",584 "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],585 "stateMutability": "view",586 "type": "function"587 },588 {589 "inputs": [590 {591 "components": [592 { "internalType": "address", "name": "eth", "type": "address" },593 { "internalType": "uint256", "name": "sub", "type": "uint256" }594 ],595 "internalType": "struct CrossAddress",596 "name": "admin",597 "type": "tuple"598 }599 ],600 "name": "removeCollectionAdminCross",601 "outputs": [],602 "stateMutability": "nonpayable",603 "type": "function"604 },605 {606 "inputs": [],607 "name": "removeCollectionSponsor",608 "outputs": [],609 "stateMutability": "nonpayable",610 "type": "function"611 },612 {613 "inputs": [614 {615 "components": [616 { "internalType": "address", "name": "eth", "type": "address" },617 { "internalType": "uint256", "name": "sub", "type": "uint256" }618 ],619 "internalType": "struct CrossAddress",620 "name": "user",621 "type": "tuple"622 }623 ],624 "name": "removeFromCollectionAllowListCross",625 "outputs": [],626 "stateMutability": "nonpayable",627 "type": "function"628 },629 {630 "inputs": [631 { "internalType": "address", "name": "from", "type": "address" },632 { "internalType": "address", "name": "to", "type": "address" },633 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }634 ],635 "name": "safeTransferFrom",636 "outputs": [],637 "stateMutability": "nonpayable",638 "type": "function"639 },640 {641 "inputs": [642 { "internalType": "address", "name": "from", "type": "address" },643 { "internalType": "address", "name": "to", "type": "address" },644 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },645 { "internalType": "bytes", "name": "data", "type": "bytes" }646 ],647 "name": "safeTransferFrom",648 "outputs": [],649 "stateMutability": "nonpayable",650 "type": "function"651 },652 {653 "inputs": [654 { "internalType": "address", "name": "operator", "type": "address" },655 { "internalType": "bool", "name": "approved", "type": "bool" }656 ],657 "name": "setApprovalForAll",658 "outputs": [],659 "stateMutability": "nonpayable",660 "type": "function"661 },662 {663 "inputs": [664 { "internalType": "enum AccessMode", "name": "mode", "type": "uint8" }665 ],666 "name": "setCollectionAccess",667 "outputs": [],668 "stateMutability": "nonpayable",669 "type": "function"670 },671 {672 "inputs": [673 {674 "components": [675 {676 "internalType": "enum CollectionLimitField",677 "name": "field",678 "type": "uint8"679 },680 {681 "components": [682 { "internalType": "bool", "name": "status", "type": "bool" },683 { "internalType": "uint256", "name": "value", "type": "uint256" }684 ],685 "internalType": "struct OptionUint256",686 "name": "value",687 "type": "tuple"688 }689 ],690 "internalType": "struct CollectionLimit",691 "name": "limit",692 "type": "tuple"693 }694 ],695 "name": "setCollectionLimit",696 "outputs": [],697 "stateMutability": "nonpayable",698 "type": "function"699 },700 {701 "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],702 "name": "setCollectionMintMode",703 "outputs": [],704 "stateMutability": "nonpayable",705 "type": "function"706 },707 {708 "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],709 "name": "setCollectionNesting",710 "outputs": [],711 "stateMutability": "nonpayable",712 "type": "function"713 },714 {715 "inputs": [716 { "internalType": "bool", "name": "enable", "type": "bool" },717 {718 "internalType": "address[]",719 "name": "collections",720 "type": "address[]"721 }722 ],723 "name": "setCollectionNesting",724 "outputs": [],725 "stateMutability": "nonpayable",726 "type": "function"727 },728 {729 "inputs": [730 {731 "components": [732 { "internalType": "string", "name": "key", "type": "string" },733 { "internalType": "bytes", "name": "value", "type": "bytes" }734 ],735 "internalType": "struct Property[]",736 "name": "properties",737 "type": "tuple[]"738 }739 ],740 "name": "setCollectionProperties",741 "outputs": [],742 "stateMutability": "nonpayable",743 "type": "function"744 },745 {746 "inputs": [747 {748 "components": [749 { "internalType": "address", "name": "eth", "type": "address" },750 { "internalType": "uint256", "name": "sub", "type": "uint256" }751 ],752 "internalType": "struct CrossAddress",753 "name": "sponsor",754 "type": "tuple"755 }756 ],757 "name": "setCollectionSponsorCross",758 "outputs": [],759 "stateMutability": "nonpayable",760 "type": "function"761 },762 {763 "inputs": [764 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },765 {766 "components": [767 { "internalType": "string", "name": "key", "type": "string" },768 { "internalType": "bytes", "name": "value", "type": "bytes" }769 ],770 "internalType": "struct Property[]",771 "name": "properties",772 "type": "tuple[]"773 }774 ],775 "name": "setProperties",776 "outputs": [],777 "stateMutability": "nonpayable",778 "type": "function"779 },780 {781 "inputs": [782 {783 "components": [784 { "internalType": "string", "name": "key", "type": "string" },785 {786 "components": [787 {788 "internalType": "enum TokenPermissionField",789 "name": "code",790 "type": "uint8"791 },792 { "internalType": "bool", "name": "value", "type": "bool" }793 ],794 "internalType": "struct PropertyPermission[]",795 "name": "permissions",796 "type": "tuple[]"797 }798 ],799 "internalType": "struct TokenPropertyPermission[]",800 "name": "permissions",801 "type": "tuple[]"802 }803 ],804 "name": "setTokenPropertyPermissions",805 "outputs": [],806 "stateMutability": "nonpayable",807 "type": "function"808 },809 {810 "inputs": [811 { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }812 ],813 "name": "supportsInterface",814 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],815 "stateMutability": "view",816 "type": "function"817 },818 {819 "inputs": [],820 "name": "symbol",821 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],822 "stateMutability": "view",823 "type": "function"824 },825 {826 "inputs": [827 { "internalType": "uint256", "name": "index", "type": "uint256" }828 ],829 "name": "tokenByIndex",830 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],831 "stateMutability": "view",832 "type": "function"833 },834 {835 "inputs": [836 { "internalType": "address", "name": "owner", "type": "address" },837 { "internalType": "uint256", "name": "index", "type": "uint256" }838 ],839 "name": "tokenOfOwnerByIndex",840 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],841 "stateMutability": "view",842 "type": "function"843 },844 {845 "inputs": [],846 "name": "tokenPropertyPermissions",847 "outputs": [848 {849 "components": [850 { "internalType": "string", "name": "key", "type": "string" },851 {852 "components": [853 {854 "internalType": "enum TokenPermissionField",855 "name": "code",856 "type": "uint8"857 },858 { "internalType": "bool", "name": "value", "type": "bool" }859 ],860 "internalType": "struct PropertyPermission[]",861 "name": "permissions",862 "type": "tuple[]"863 }864 ],865 "internalType": "struct TokenPropertyPermission[]",866 "name": "",867 "type": "tuple[]"868 }869 ],870 "stateMutability": "view",871 "type": "function"872 },873 {874 "inputs": [875 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }876 ],877 "name": "tokenURI",878 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],879 "stateMutability": "view",880 "type": "function"881 },882 {883 "inputs": [],884 "name": "totalSupply",885 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],886 "stateMutability": "view",887 "type": "function"888 },889 {890 "inputs": [891 { "internalType": "address", "name": "to", "type": "address" },892 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }893 ],894 "name": "transfer",895 "outputs": [],896 "stateMutability": "nonpayable",897 "type": "function"898 },899 {900 "inputs": [901 {902 "components": [903 { "internalType": "address", "name": "eth", "type": "address" },904 { "internalType": "uint256", "name": "sub", "type": "uint256" }905 ],906 "internalType": "struct CrossAddress",907 "name": "to",908 "type": "tuple"909 },910 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }911 ],912 "name": "transferCross",913 "outputs": [],914 "stateMutability": "nonpayable",915 "type": "function"916 },917 {918 "inputs": [919 { "internalType": "address", "name": "from", "type": "address" },920 { "internalType": "address", "name": "to", "type": "address" },921 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }922 ],923 "name": "transferFrom",924 "outputs": [],925 "stateMutability": "nonpayable",926 "type": "function"927 },928 {929 "inputs": [930 {931 "components": [932 { "internalType": "address", "name": "eth", "type": "address" },933 { "internalType": "uint256", "name": "sub", "type": "uint256" }934 ],935 "internalType": "struct CrossAddress",936 "name": "from",937 "type": "tuple"938 },939 {940 "components": [941 { "internalType": "address", "name": "eth", "type": "address" },942 { "internalType": "uint256", "name": "sub", "type": "uint256" }943 ],944 "internalType": "struct CrossAddress",945 "name": "to",946 "type": "tuple"947 },948 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }949 ],950 "name": "transferFromCross",951 "outputs": [],952 "stateMutability": "nonpayable",953 "type": "function"954 },955 {956 "inputs": [],957 "name": "uniqueCollectionType",958 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],959 "stateMutability": "view",960 "type": "function"961 }962]tests/src/eth/abi/reFungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/reFungible.json
+++ b/tests/src/eth/abi/reFungible.json
@@ -159,6 +159,23 @@
},
{
"inputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "eth", "type": "address" },
+ { "internalType": "uint256", "name": "sub", "type": "uint256" }
+ ],
+ "internalType": "struct CrossAddress",
+ "name": "owner",
+ "type": "tuple"
+ }
+ ],
+ "name": "balanceOfCross",
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
{ "internalType": "uint256", "name": "tokenId", "type": "uint256" }
],
"name": "burn",
@@ -368,25 +385,6 @@
},
{
"inputs": [
- { "internalType": "uint256", "name": "tokenId", "type": "uint256" }
- ],
- "name": "crossOwnerOf",
- "outputs": [
- {
- "components": [
- { "internalType": "address", "name": "eth", "type": "address" },
- { "internalType": "uint256", "name": "sub", "type": "uint256" }
- ],
- "internalType": "struct CrossAddress",
- "name": "",
- "type": "tuple"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
{ "internalType": "string[]", "name": "keys", "type": "string[]" }
],
"name": "deleteCollectionProperties",
@@ -522,6 +520,25 @@
},
{
"inputs": [
+ { "internalType": "uint256", "name": "tokenId", "type": "uint256" }
+ ],
+ "name": "ownerOfCross",
+ "outputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "eth", "type": "address" },
+ { "internalType": "uint256", "name": "sub", "type": "uint256" }
+ ],
+ "internalType": "struct CrossAddress",
+ "name": "",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
{ "internalType": "uint256", "name": "tokenId", "type": "uint256" },
{ "internalType": "string[]", "name": "keys", "type": "string[]" }
],
tests/src/eth/abi/reFungibleToken.jsondiffbeforeafterboth--- a/tests/src/eth/abi/reFungibleToken.json
+++ b/tests/src/eth/abi/reFungibleToken.json
@@ -130,6 +130,23 @@
{ "internalType": "uint256", "name": "sub", "type": "uint256" }
],
"internalType": "struct CrossAddress",
+ "name": "owner",
+ "type": "tuple"
+ }
+ ],
+ "name": "balanceOfCross",
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "eth", "type": "address" },
+ { "internalType": "uint256", "name": "sub", "type": "uint256" }
+ ],
+ "internalType": "struct CrossAddress",
"name": "from",
"type": "tuple"
},
tests/src/eth/api/UniqueFungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueFungible.sol
+++ b/tests/src/eth/api/UniqueFungible.sol
@@ -353,7 +353,7 @@
bytes value;
}
-/// @dev the ERC-165 identifier for this interface is 0x85d7dea6
+/// @dev the ERC-165 identifier for this interface is 0x69d14d3e
interface ERC20UniqueExtensions is Dummy, ERC165 {
/// @dev Function to check the amount of tokens that an owner allowed to a spender.
/// @param owner crossAddress The address which owns the funds.
@@ -416,6 +416,13 @@
/// @dev EVM selector for this function is: 0x1896cce6,
/// or in textual repr: collectionHelperAddress()
function collectionHelperAddress() external view returns (address);
+
+ /// @notice Balance of account
+ /// @param owner An cross address for whom to query the balance
+ /// @return The number of fingibles owned by `owner`, possibly zero
+ /// @dev EVM selector for this function is: 0xec069398,
+ /// or in textual repr: balanceOfCross((address,uint256))
+ function balanceOfCross(CrossAddress memory owner) external view returns (uint256);
}
struct AmountForAddress {
tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -533,7 +533,7 @@
}
/// @title Unique extensions for ERC721.
-/// @dev the ERC-165 identifier for this interface is 0x16de3152
+/// @dev the ERC-165 identifier for this interface is 0x307b061a
interface ERC721UniqueExtensions is Dummy, ERC165 {
/// @notice A descriptive name for a collection of NFTs in this contract
/// @dev EVM selector for this function is: 0x06fdde03,
@@ -550,12 +550,26 @@
/// or in textual repr: description()
function description() external view returns (string memory);
+ // /// Returns the owner (in cross format) of the token.
+ // ///
+ // /// @param tokenId Id for the token.
+ // /// @dev EVM selector for this function is: 0x2b29dace,
+ // /// or in textual repr: crossOwnerOf(uint256)
+ // function crossOwnerOf(uint256 tokenId) external view returns (CrossAddress memory);
+
/// Returns the owner (in cross format) of the token.
///
/// @param tokenId Id for the token.
- /// @dev EVM selector for this function is: 0x2b29dace,
- /// or in textual repr: crossOwnerOf(uint256)
- function crossOwnerOf(uint256 tokenId) external view returns (CrossAddress memory);
+ /// @dev EVM selector for this function is: 0xcaa3a4d0,
+ /// or in textual repr: ownerOfCross(uint256)
+ function ownerOfCross(uint256 tokenId) external view returns (CrossAddress memory);
+
+ /// @notice Count all NFTs assigned to an owner
+ /// @param owner An cross address for whom to query the balance
+ /// @return The number of NFTs owned by `owner`, possibly zero
+ /// @dev EVM selector for this function is: 0xec069398,
+ /// or in textual repr: balanceOfCross((address,uint256))
+ function balanceOfCross(CrossAddress memory owner) external view returns (uint256);
/// Returns the token properties.
///
tests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -533,7 +533,7 @@
}
/// @title Unique extensions for ERC721.
-/// @dev the ERC-165 identifier for this interface is 0xb365c124
+/// @dev the ERC-165 identifier for this interface is 0x95c0f66c
interface ERC721UniqueExtensions is Dummy, ERC165 {
/// @notice A descriptive name for a collection of NFTs in this contract
/// @dev EVM selector for this function is: 0x06fdde03,
@@ -550,12 +550,26 @@
/// or in textual repr: description()
function description() external view returns (string memory);
+ // /// Returns the owner (in cross format) of the token.
+ // ///
+ // /// @param tokenId Id for the token.
+ // /// @dev EVM selector for this function is: 0x2b29dace,
+ // /// or in textual repr: crossOwnerOf(uint256)
+ // function crossOwnerOf(uint256 tokenId) external view returns (CrossAddress memory);
+
/// Returns the owner (in cross format) of the token.
///
/// @param tokenId Id for the token.
- /// @dev EVM selector for this function is: 0x2b29dace,
- /// or in textual repr: crossOwnerOf(uint256)
- function crossOwnerOf(uint256 tokenId) external view returns (CrossAddress memory);
+ /// @dev EVM selector for this function is: 0xcaa3a4d0,
+ /// or in textual repr: ownerOfCross(uint256)
+ function ownerOfCross(uint256 tokenId) external view returns (CrossAddress memory);
+
+ /// @notice Count all RFTs assigned to an owner
+ /// @param owner An cross address for whom to query the balance
+ /// @return The number of RFTs owned by `owner`, possibly zero
+ /// @dev EVM selector for this function is: 0xec069398,
+ /// or in textual repr: balanceOfCross((address,uint256))
+ function balanceOfCross(CrossAddress memory owner) external view returns (uint256);
/// Returns the token properties.
///
tests/src/eth/api/UniqueRefungibleToken.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueRefungibleToken.sol
+++ b/tests/src/eth/api/UniqueRefungibleToken.sol
@@ -23,7 +23,7 @@
function parentTokenId() external view returns (uint256);
}
-/// @dev the ERC-165 identifier for this interface is 0x01d536fc
+/// @dev the ERC-165 identifier for this interface is 0xedd3a564
interface ERC20UniqueExtensions is Dummy, ERC165 {
/// @dev Function to check the amount of tokens that an owner allowed to a spender.
/// @param owner crossAddress The address which owns the funds.
@@ -60,6 +60,13 @@
/// or in textual repr: approveCross((address,uint256),uint256)
function approveCross(CrossAddress memory spender, uint256 amount) external returns (bool);
+ /// @notice Balance of account
+ /// @param owner An cross address for whom to query the balance
+ /// @return The number of fingibles owned by `owner`, possibly zero
+ /// @dev EVM selector for this function is: 0xec069398,
+ /// or in textual repr: balanceOfCross((address,uint256))
+ function balanceOfCross(CrossAddress memory owner) external view returns (uint256);
+
/// @dev Function that changes total amount of the tokens.
/// Throws if `msg.sender` doesn't owns all of the tokens.
/// @param amount New total amount of the tokens.
tests/src/eth/fungible.test.tsdiffbeforeafterboth--- a/tests/src/eth/fungible.test.ts
+++ b/tests/src/eth/fungible.test.ts
@@ -427,6 +427,33 @@
const toBalanceAfter = await collection.getBalance({Ethereum: receiver});
expect(toBalanceAfter - toBalanceBefore).to.be.eq(51n);
});
+
+ itEth('Check balanceOfCross()', async ({helper}) => {
+ const collection = await helper.ft.mintCollection(alice, {});
+ const owner = await helper.ethCrossAccount.createAccountWithBalance(donor);
+ const other = await helper.ethCrossAccount.createAccountWithBalance(donor);
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner.eth);
+
+ expect(await collectionEvm.methods.balanceOfCross(owner).call({from: owner.eth})).to.be.eq('0');
+ expect(await collectionEvm.methods.balanceOfCross(other).call({from: owner.eth})).to.be.eq('0');
+
+ await collection.mint(alice, 100n, {Ethereum: owner.eth});
+ expect(await collectionEvm.methods.balanceOfCross(owner).call({from: owner.eth})).to.be.eq('100');
+ expect(await collectionEvm.methods.balanceOfCross(other).call({from: owner.eth})).to.be.eq('0');
+
+ await collectionEvm.methods.transferCross(other, 50n).send({from: owner.eth});
+ expect(await collectionEvm.methods.balanceOfCross(owner).call({from: owner.eth})).to.be.eq('50');
+ expect(await collectionEvm.methods.balanceOfCross(other).call({from: owner.eth})).to.be.eq('50');
+
+ await collectionEvm.methods.transferCross(other, 50n).send({from: owner.eth});
+ expect(await collectionEvm.methods.balanceOfCross(owner).call({from: owner.eth})).to.be.eq('0');
+ expect(await collectionEvm.methods.balanceOfCross(other).call({from: owner.eth})).to.be.eq('100');
+
+ await collectionEvm.methods.transferCross(owner, 100n).send({from: other.eth});
+ expect(await collectionEvm.methods.balanceOfCross(owner).call({from: owner.eth})).to.be.eq('100');
+ expect(await collectionEvm.methods.balanceOfCross(other).call({from: owner.eth})).to.be.eq('0');
+ });
});
describe('Fungible: Fees', () => {
tests/src/eth/nonFungible.test.tsdiffbeforeafterboth--- a/tests/src/eth/nonFungible.test.ts
+++ b/tests/src/eth/nonFungible.test.ts
@@ -662,6 +662,38 @@
// Cannot transfer token if it does not exist:
await expect(collectionEvm.methods[testCase](receiver, 999999).send({from: sender})).to.be.rejected;
}));
+
+ itEth('Check balanceOfCross()', async ({helper}) => {
+ const collection = await helper.nft.mintCollection(minter, {});
+ const owner = await helper.ethCrossAccount.createAccountWithBalance(donor);
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner.eth);
+
+ expect(await collectionEvm.methods.balanceOfCross(owner).call({from: owner.eth})).to.be.eq('0');
+
+ for (let i = 1; i < 10; i++) {
+ await collection.mintToken(minter, {Ethereum: owner.eth});
+ expect(await collectionEvm.methods.balanceOfCross(owner).call({from: owner.eth})).to.be.eq(i.toString());
+ }
+ });
+
+ itEth('Check ownerOfCross()', async ({helper}) => {
+ const collection = await helper.nft.mintCollection(minter, {});
+ let owner = await helper.ethCrossAccount.createAccountWithBalance(donor);
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner.eth);
+ const {tokenId} = await collection.mintToken(minter, {Ethereum: owner.eth});
+
+ for (let i = 1n; i < 10n; i++) {
+ const ownerCross = await collectionEvm.methods.ownerOfCross(tokenId).call({from: owner.eth});
+ expect(ownerCross.eth).to.be.eq(owner.eth);
+ expect(ownerCross.sub).to.be.eq(owner.sub);
+
+ const newOwner = await helper.ethCrossAccount.createAccountWithBalance(donor);
+ await collectionEvm.methods.transferCross(newOwner, tokenId).send({from: owner.eth});
+ owner = newOwner;
+ }
+ });
});
describe('NFT: Fees', () => {
tests/src/eth/reFungible.test.tsdiffbeforeafterboth--- a/tests/src/eth/reFungible.test.ts
+++ b/tests/src/eth/reFungible.test.ts
@@ -584,6 +584,46 @@
expect(event.returnValues.to).to.equal('0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF');
expect(event.returnValues.tokenId).to.equal(tokenId.toString());
});
+
+ itEth('Check balanceOfCross()', async ({helper}) => {
+ const collection = await helper.rft.mintCollection(minter, {});
+ const owner = await helper.ethCrossAccount.createAccountWithBalance(donor);
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner.eth);
+
+ expect(await collectionEvm.methods.balanceOfCross(owner).call({from: owner.eth})).to.be.eq('0');
+
+ for (let i = 1n; i < 10n; i++) {
+ await collection.mintToken(minter, 100n, {Ethereum: owner.eth});
+ expect(await collectionEvm.methods.balanceOfCross(owner).call({from: owner.eth})).to.be.eq(i.toString());
+ }
+ });
+
+ itEth('Check ownerOfCross()', async ({helper}) => {
+ const collection = await helper.rft.mintCollection(minter, {});
+ let owner = await helper.ethCrossAccount.createAccountWithBalance(donor);
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner.eth);
+ const {tokenId} = await collection.mintToken(minter, 100n,{Ethereum: owner.eth});
+
+ for (let i = 1n; i < 10n; i++) {
+ const ownerCross = await collectionEvm.methods.ownerOfCross(tokenId).call({from: owner.eth});
+ expect(ownerCross.eth).to.be.eq(owner.eth);
+ expect(ownerCross.sub).to.be.eq(owner.sub);
+
+ const newOwner = await helper.ethCrossAccount.createAccountWithBalance(donor);
+ await collectionEvm.methods.transferCross(newOwner, tokenId).send({from: owner.eth});
+ owner = newOwner;
+ }
+
+ const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);
+ const tokenContract = await helper.ethNativeContract.rftToken(tokenAddress, owner.eth, true);
+ const newOwner = await helper.ethCrossAccount.createAccountWithBalance(donor);
+ await tokenContract.methods.transferCross(newOwner, 50).send({from: owner.eth});
+ const ownerCross = await collectionEvm.methods.ownerOfCross(tokenId).call({from: owner.eth});
+ expect(ownerCross.eth.toUpperCase()).to.be.eq('0XFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF');
+ expect(ownerCross.sub).to.be.eq('0');
+ });
});
describe('RFT: Fees', () => {
tests/src/eth/reFungibleToken.test.tsdiffbeforeafterboth--- a/tests/src/eth/reFungibleToken.test.ts
+++ b/tests/src/eth/reFungibleToken.test.ts
@@ -466,6 +466,35 @@
expect(await collection.getTokenBalance(tokenId, {Substrate: ownerSub.address})).to.be.equal(150n);
}
});
+
+ itEth('Check balanceOfCross()', async ({helper}) => {
+ const collection = await helper.rft.mintCollection(alice, {});
+ const owner = await helper.ethCrossAccount.createAccountWithBalance(donor);
+ const other = await helper.ethCrossAccount.createAccountWithBalance(donor);
+ const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner.eth});
+ const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);
+ const tokenContract = await helper.ethNativeContract.rftToken(tokenAddress, owner.eth);
+
+ expect(await tokenContract.methods.balanceOfCross(owner).call({from: owner.eth})).to.be.eq('200');
+ expect(await tokenContract.methods.balanceOfCross(other).call({from: owner.eth})).to.be.eq('0');
+
+ await tokenContract.methods.repartition(100n).send({from: owner.eth});
+ expect(await tokenContract.methods.balanceOfCross(owner).call({from: owner.eth})).to.be.eq('100');
+ expect(await tokenContract.methods.balanceOfCross(other).call({from: owner.eth})).to.be.eq('0');
+
+ await tokenContract.methods.transferCross(other, 50n).send({from: owner.eth});
+ expect(await tokenContract.methods.balanceOfCross(owner).call({from: owner.eth})).to.be.eq('50');
+ expect(await tokenContract.methods.balanceOfCross(other).call({from: owner.eth})).to.be.eq('50');
+
+ await tokenContract.methods.transferCross(other, 50n).send({from: owner.eth});
+ expect(await tokenContract.methods.balanceOfCross(owner).call({from: owner.eth})).to.be.eq('0');
+ expect(await tokenContract.methods.balanceOfCross(other).call({from: owner.eth})).to.be.eq('100');
+
+ await tokenContract.methods.repartition(1000n).send({from: other.eth});
+ await tokenContract.methods.transferCross(owner, 500n).send({from: other.eth});
+ expect(await tokenContract.methods.balanceOfCross(owner).call({from: owner.eth})).to.be.eq('500');
+ expect(await tokenContract.methods.balanceOfCross(other).call({from: owner.eth})).to.be.eq('500');
+ });
});
describe('Refungible: Fees', () => {
tests/src/eth/tokens/minting.test.tsdiffbeforeafterboth--- a/tests/src/eth/tokens/minting.test.ts
+++ b/tests/src/eth/tokens/minting.test.ts
@@ -63,7 +63,7 @@
const tokenId = event.returnValues.tokenId;
expect(tokenId).to.be.equal('1');
expect(await helper.collection.getLastTokenId(collection.collectionId)).to.eq(1);
- expect(await contract.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']);
+ expect(await contract.methods.ownerOfCross(tokenId).call()).to.be.like([receiver, '0']);
}
});
});
@@ -97,7 +97,7 @@
const tokenId = event.returnValues.tokenId;
expect(tokenId).to.be.equal('1');
expect(await helper.collection.getLastTokenId(collectionId)).to.eq(1);
- expect(await collection.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']);
+ expect(await collection.methods.ownerOfCross(tokenId).call()).to.be.like([receiver, '0']);
}
});
});
@@ -131,7 +131,7 @@
const tokenId = event.returnValues.tokenId;
expect(tokenId).to.be.equal('1');
expect(await helper.collection.getLastTokenId(collectionId)).to.eq(1);
- expect(await collection.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']);
+ expect(await collection.methods.ownerOfCross(tokenId).call()).to.be.like([receiver, '0']);
}
});
});
@@ -157,7 +157,7 @@
expect(event.returnValues.to).to.be.equal(receiver);
expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
- expect(await contract.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']);
+ expect(await contract.methods.ownerOfCross(tokenId).call()).to.be.like([receiver, '0']);
// TODO: this wont work right now, need release 919000 first
// await helper.methods.setOffchainSchema(collectionIdAddress, 'https://offchain-service.local/token-info/{id}').send();
// const tokenUri = await contract.methods.tokenURI(nextTokenId).call();