difftreelog
Merge pull request #750 from UniqueNetwork/feature/cross-methods-refungible-erc20-support
in: master
added cross methods: `burnFromCross` , `transferCross`, `approveCorss…
9 files changed
pallets/refungible/src/erc_token.rsdiffbeforeafterboth30use pallet_common::{30use pallet_common::{31 CommonWeightInfo,31 CommonWeightInfo,32 erc::{CommonEvmHandler, PrecompileResult},32 erc::{CommonEvmHandler, PrecompileResult},33 eth::collection_id_to_address,33 eth::{collection_id_to_address, EthCrossAccount},34};34};35use pallet_evm::{account::CrossAccountId, PrecompileHandle};35use pallet_evm::{account::CrossAccountId, PrecompileHandle};36use pallet_evm_coder_substrate::{call, dispatch_to_evm, WithRecorder};36use pallet_evm_coder_substrate::{call, dispatch_to_evm, WithRecorder};195195196#[solidity_interface(name = ERC20UniqueExtensions)]196#[solidity_interface(name = ERC20UniqueExtensions)]197impl<T: Config> RefungibleTokenHandle<T> {197impl<T: Config> RefungibleTokenHandle<T>198where199 T::AccountId: From<[u8; 32]>,200{198 /// @dev Function that burns an amount of the token of a given account,201 /// @dev Function that burns an amount of the token of a given account,199 /// deducting from the sender's allowance for said account.202 /// deducting from the sender's allowance for said account.213 Ok(true)216 Ok(true)214 }217 }215218219 /// @dev Function that burns an amount of the token of a given account,220 /// deducting from the sender's allowance for said account.221 /// @param from The account whose tokens will be burnt.222 /// @param amount The amount that will be burnt.223 #[weight(<SelfWeightOf<T>>::burn_from())]224 fn burn_from_cross(225 &mut self,226 caller: caller,227 from: EthCrossAccount,228 amount: uint256,229 ) -> Result<bool> {230 let caller = T::CrossAccountId::from_eth(caller);231 let from = from.into_sub_cross_account::<T>()?;232 let amount = amount.try_into().map_err(|_| "amount overflow")?;233 let budget = self234 .recorder235 .weight_calls_budget(<StructureWeight<T>>::find_parent());236237 <Pallet<T>>::burn_from(self, &caller, &from, self.1, amount, &budget)238 .map_err(dispatch_to_evm::<T>)?;239 Ok(true)240 }241242 /// @dev Approve the passed address to spend the specified amount of tokens on behalf of `msg.sender`.243 /// Beware that changing an allowance with this method brings the risk that someone may use both the old244 /// and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this245 /// race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:246 /// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729247 /// @param spender The crossaccount which will spend the funds.248 /// @param amount The amount of tokens to be spent.249 #[weight(<SelfWeightOf<T>>::approve())]250 fn approve_cross(251 &mut self,252 caller: caller,253 spender: EthCrossAccount,254 amount: uint256,255 ) -> Result<bool> {256 let caller = T::CrossAccountId::from_eth(caller);257 let spender = spender.into_sub_cross_account::<T>()?;258 let amount = amount.try_into().map_err(|_| "amount overflow")?;259260 <Pallet<T>>::set_allowance(self, &caller, &spender, self.1, amount)261 .map_err(dispatch_to_evm::<T>)?;262 Ok(true)263 }216 /// @dev Function that changes total amount of the tokens.264 /// @dev Function that changes total amount of the tokens.217 /// Throws if `msg.sender` doesn't owns all of the tokens.265 /// Throws if `msg.sender` doesn't owns all of the tokens.218 /// @param amount New total amount of the tokens.266 /// @param amount New total amount of the tokens.225 Ok(true)273 Ok(true)226 }274 }275276 /// @dev Transfer token for a specified address277 /// @param to The crossaccount to transfer to.278 /// @param amount The amount to be transferred.279 #[weight(<CommonWeights<T>>::transfer())]280 fn transfer_cross(281 &mut self,282 caller: caller,283 to: EthCrossAccount,284 amount: uint256,285 ) -> Result<bool> {286 let caller = T::CrossAccountId::from_eth(caller);287 let to = to.into_sub_cross_account::<T>()?;288 let amount = amount.try_into().map_err(|_| "amount overflow")?;289 let budget = self290 .recorder291 .weight_calls_budget(<StructureWeight<T>>::find_parent());292293 <Pallet<T>>::transfer(self, &caller, &to, self.1, amount, &budget)294 .map_err(dispatch_to_evm::<T>)?;295 Ok(true)296 }297298 /// @dev Transfer tokens from one address to another299 /// @param from The address which you want to send tokens from300 /// @param to The address which you want to transfer to301 /// @param amount the amount of tokens to be transferred302 #[weight(<CommonWeights<T>>::transfer_from())]303 fn transfer_from_cross(304 &mut self,305 caller: caller,306 from: EthCrossAccount,307 to: EthCrossAccount,308 amount: uint256,309 ) -> Result<bool> {310 let caller = T::CrossAccountId::from_eth(caller);311 let from = from.into_sub_cross_account::<T>()?;312 let to = to.into_sub_cross_account::<T>()?;313 let amount = amount.try_into().map_err(|_| "amount overflow")?;314 let budget = self315 .recorder316 .weight_calls_budget(<StructureWeight<T>>::find_parent());317318 <Pallet<T>>::transfer_from(self, &caller, &from, &to, self.1, amount, &budget)319 .map_err(dispatch_to_evm::<T>)?;320 Ok(true)321 }227}322}228323229impl<T: Config> RefungibleTokenHandle<T> {324impl<T: Config> RefungibleTokenHandle<T> {pallets/refungible/src/stubs/UniqueRefungibleToken.rawdiffbeforeafterbothbinary blob — no preview
pallets/refungible/src/stubs/UniqueRefungibleToken.soldiffbeforeafterboth36 }36 }37}37}383839/// @dev the ERC-165 identifier for this interface is 0xab8deb3739/// @dev the ERC-165 identifier for this interface is 0xe17a7d2b40contract ERC20UniqueExtensions is Dummy, ERC165 {40contract ERC20UniqueExtensions is Dummy, ERC165 {41 /// @dev Function that burns an amount of the token of a given account,41 /// @dev Function that burns an amount of the token of a given account,42 /// deducting from the sender's allowance for said account.42 /// deducting from the sender's allowance for said account.52 return false;52 return false;53 }53 }5455 /// @dev Function that burns an amount of the token of a given account,56 /// deducting from the sender's allowance for said account.57 /// @param from The account whose tokens will be burnt.58 /// @param amount The amount that will be burnt.59 /// @dev EVM selector for this function is: 0xbb2f5a58,60 /// or in textual repr: burnFromCross((address,uint256),uint256)61 function burnFromCross(EthCrossAccount memory from, uint256 amount) public returns (bool) {62 require(false, stub_error);63 from;64 amount;65 dummy = 0;66 return false;67 }6869 /// @dev Approve the passed address to spend the specified amount of tokens on behalf of `msg.sender`.70 /// Beware that changing an allowance with this method brings the risk that someone may use both the old71 /// and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this72 /// race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:73 /// https://github.com/ethereum/EIPs/issues/20#issuecomment-26352472974 /// @param spender The crossaccount which will spend the funds.75 /// @param amount The amount of tokens to be spent.76 /// @dev EVM selector for this function is: 0x0ecd0ab0,77 /// or in textual repr: approveCross((address,uint256),uint256)78 function approveCross(EthCrossAccount memory spender, uint256 amount) public returns (bool) {79 require(false, stub_error);80 spender;81 amount;82 dummy = 0;83 return false;84 }548555 /// @dev Function that changes total amount of the tokens.86 /// @dev Function that changes total amount of the tokens.56 /// Throws if `msg.sender` doesn't owns all of the tokens.87 /// Throws if `msg.sender` doesn't owns all of the tokens.64 return false;95 return false;65 }96 }9798 /// @dev Transfer token for a specified address99 /// @param to The crossaccount to transfer to.100 /// @param amount The amount to be transferred.101 /// @dev EVM selector for this function is: 0x2ada85ff,102 /// or in textual repr: transferCross((address,uint256),uint256)103 function transferCross(EthCrossAccount memory to, uint256 amount) public returns (bool) {104 require(false, stub_error);105 to;106 amount;107 dummy = 0;108 return false;109 }110111 /// @dev Transfer tokens from one address to another112 /// @param from The address which you want to send tokens from113 /// @param to The address which you want to transfer to114 /// @param amount the amount of tokens to be transferred115 /// @dev EVM selector for this function is: 0xd5cf430b,116 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)117 function transferFromCross(118 EthCrossAccount memory from,119 EthCrossAccount memory to,120 uint256 amount121 ) public returns (bool) {122 require(false, stub_error);123 from;124 to;125 amount;126 dummy = 0;127 return false;128 }66}129}130131/// @dev Cross account struct132struct EthCrossAccount {133 address eth;134 uint256 sub;135}6713668/// @dev inlined interface137/// @dev inlined interface69contract ERC20Events {138contract ERC20Events {tests/src/eth/abi/reFungibleToken.jsondiffbeforeafterboth69 "stateMutability": "nonpayable",69 "stateMutability": "nonpayable",70 "type": "function"70 "type": "function"71 },71 },72 {73 "inputs": [74 {75 "components": [76 { "internalType": "address", "name": "eth", "type": "address" },77 { "internalType": "uint256", "name": "sub", "type": "uint256" }78 ],79 "internalType": "struct EthCrossAccount",80 "name": "spender",81 "type": "tuple"82 },83 { "internalType": "uint256", "name": "amount", "type": "uint256" }84 ],85 "name": "approveCross",86 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],87 "stateMutability": "nonpayable",88 "type": "function"89 },72 {90 {73 "inputs": [91 "inputs": [74 { "internalType": "address", "name": "owner", "type": "address" }92 { "internalType": "address", "name": "owner", "type": "address" }88 "stateMutability": "nonpayable",106 "stateMutability": "nonpayable",89 "type": "function"107 "type": "function"90 },108 },109 {110 "inputs": [111 {112 "components": [113 { "internalType": "address", "name": "eth", "type": "address" },114 { "internalType": "uint256", "name": "sub", "type": "uint256" }115 ],116 "internalType": "struct EthCrossAccount",117 "name": "from",118 "type": "tuple"119 },120 { "internalType": "uint256", "name": "amount", "type": "uint256" }121 ],122 "name": "burnFromCross",123 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],124 "stateMutability": "nonpayable",125 "type": "function"126 },91 {127 {92 "inputs": [],128 "inputs": [],93 "name": "decimals",129 "name": "decimals",158 "stateMutability": "nonpayable",194 "stateMutability": "nonpayable",159 "type": "function"195 "type": "function"160 },196 },197 {198 "inputs": [199 {200 "components": [201 { "internalType": "address", "name": "eth", "type": "address" },202 { "internalType": "uint256", "name": "sub", "type": "uint256" }203 ],204 "internalType": "struct EthCrossAccount",205 "name": "to",206 "type": "tuple"207 },208 { "internalType": "uint256", "name": "amount", "type": "uint256" }209 ],210 "name": "transferCross",211 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],212 "stateMutability": "nonpayable",213 "type": "function"214 },161 {215 {162 "inputs": [216 "inputs": [163 { "internalType": "address", "name": "from", "type": "address" },217 { "internalType": "address", "name": "from", "type": "address" },168 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],222 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],169 "stateMutability": "nonpayable",223 "stateMutability": "nonpayable",170 "type": "function"224 "type": "function"171 }225 },226 {227 "inputs": [228 {229 "components": [230 { "internalType": "address", "name": "eth", "type": "address" },231 { "internalType": "uint256", "name": "sub", "type": "uint256" }232 ],233 "internalType": "struct EthCrossAccount",234 "name": "from",235 "type": "tuple"236 },237 {238 "components": [239 { "internalType": "address", "name": "eth", "type": "address" },240 { "internalType": "uint256", "name": "sub", "type": "uint256" }241 ],242 "internalType": "struct EthCrossAccount",243 "name": "to",244 "type": "tuple"245 },246 { "internalType": "uint256", "name": "amount", "type": "uint256" }247 ],248 "name": "transferFromCross",249 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],250 "stateMutability": "nonpayable",251 "type": "function"252 }172]253]173254tests/src/eth/api/UniqueRefungibleToken.soldiffbeforeafterboth23 function parentTokenId() external view returns (uint256);23 function parentTokenId() external view returns (uint256);24}24}252526/// @dev the ERC-165 identifier for this interface is 0xab8deb3726/// @dev the ERC-165 identifier for this interface is 0xe17a7d2b27interface ERC20UniqueExtensions is Dummy, ERC165 {27interface ERC20UniqueExtensions is Dummy, ERC165 {28 /// @dev Function that burns an amount of the token of a given account,28 /// @dev Function that burns an amount of the token of a given account,29 /// deducting from the sender's allowance for said account.29 /// deducting from the sender's allowance for said account.33 /// or in textual repr: burnFrom(address,uint256)33 /// or in textual repr: burnFrom(address,uint256)34 function burnFrom(address from, uint256 amount) external returns (bool);34 function burnFrom(address from, uint256 amount) external returns (bool);3536 /// @dev Function that burns an amount of the token of a given account,37 /// deducting from the sender's allowance for said account.38 /// @param from The account whose tokens will be burnt.39 /// @param amount The amount that will be burnt.40 /// @dev EVM selector for this function is: 0xbb2f5a58,41 /// or in textual repr: burnFromCross((address,uint256),uint256)42 function burnFromCross(EthCrossAccount memory from, uint256 amount) external returns (bool);4344 /// @dev Approve the passed address to spend the specified amount of tokens on behalf of `msg.sender`.45 /// Beware that changing an allowance with this method brings the risk that someone may use both the old46 /// and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this47 /// race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:48 /// https://github.com/ethereum/EIPs/issues/20#issuecomment-26352472949 /// @param spender The crossaccount which will spend the funds.50 /// @param amount The amount of tokens to be spent.51 /// @dev EVM selector for this function is: 0x0ecd0ab0,52 /// or in textual repr: approveCross((address,uint256),uint256)53 function approveCross(EthCrossAccount memory spender, uint256 amount) external returns (bool);355436 /// @dev Function that changes total amount of the tokens.55 /// @dev Function that changes total amount of the tokens.37 /// Throws if `msg.sender` doesn't owns all of the tokens.56 /// Throws if `msg.sender` doesn't owns all of the tokens.40 /// or in textual repr: repartition(uint256)59 /// or in textual repr: repartition(uint256)41 function repartition(uint256 amount) external returns (bool);60 function repartition(uint256 amount) external returns (bool);6162 /// @dev Transfer token for a specified address63 /// @param to The crossaccount to transfer to.64 /// @param amount The amount to be transferred.65 /// @dev EVM selector for this function is: 0x2ada85ff,66 /// or in textual repr: transferCross((address,uint256),uint256)67 function transferCross(EthCrossAccount memory to, uint256 amount) external returns (bool);6869 /// @dev Transfer tokens from one address to another70 /// @param from The address which you want to send tokens from71 /// @param to The address which you want to transfer to72 /// @param amount the amount of tokens to be transferred73 /// @dev EVM selector for this function is: 0xd5cf430b,74 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)75 function transferFromCross(76 EthCrossAccount memory from,77 EthCrossAccount memory to,78 uint256 amount79 ) external returns (bool);42}80}8182/// @dev Cross account struct83struct EthCrossAccount {84 address eth;85 uint256 sub;86}438744/// @dev inlined interface88/// @dev inlined interface45interface ERC20Events {89interface ERC20Events {tests/src/eth/reFungibleToken.test.tsdiffbeforeafterboth160 }160 }161 });161 });162162 163 itEth('Can perform approveCross()', async ({helper}) => {164 const owner = await helper.eth.createAccountWithBalance(donor);165 const spender = helper.eth.createAccount();166 const spenderSub = (await helper.arrange.createAccounts([1n], donor))[0];167 const spenderCrossEth = helper.ethCrossAccount.fromAddress(spender);168 const spenderCrossSub = helper.ethCrossAccount.fromKeyringPair(spenderSub);169 170171 const collection = await helper.rft.mintCollection(alice);172 const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner});173174 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);175 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);176177 {178 const result = await contract.methods.approveCross(spenderCrossEth, 100).send({from: owner});179 const event = result.events.Approval;180 expect(event.address).to.be.equal(tokenAddress);181 expect(event.returnValues.owner).to.be.equal(owner);182 expect(event.returnValues.spender).to.be.equal(spender);183 expect(event.returnValues.value).to.be.equal('100');184 }185186 {187 const allowance = await contract.methods.allowance(owner, spender).call();188 expect(+allowance).to.equal(100);189 }190 191 192 {193 const result = await contract.methods.approveCross(spenderCrossSub, 100).send({from: owner});194 const event = result.events.Approval;195 expect(event.address).to.be.equal(tokenAddress);196 expect(event.returnValues.owner).to.be.equal(owner);197 expect(event.returnValues.spender).to.be.equal(helper.address.substrateToEth(spenderSub.address));198 expect(event.returnValues.value).to.be.equal('100');199 }200201 {202 const allowance = await collection.getTokenApprovedPieces(tokenId, {Ethereum: owner}, {Substrate: spenderSub.address});203 expect(allowance).to.equal(100n);204 }205 206 {207 //TO-DO expect with future allowanceCross(owner, spenderCrossEth).call()208 }209 });210 163 itEth('Can perform transferFrom()', async ({helper}) => {211 itEth('Can perform transferFrom()', async ({helper}) => {164 const owner = await helper.eth.createAccountWithBalance(donor);212 const owner = await helper.eth.createAccountWithBalance(donor);198 }246 }199 });247 });248 249 itEth('Can perform transferFromCross()', async ({helper}) => {250 const owner = await helper.eth.createAccountWithBalance(donor);251 const ownerCross = helper.ethCrossAccount.fromAddress(owner);252 const spender = await helper.eth.createAccountWithBalance(donor);253 const receiver = helper.eth.createAccount();254 const receiverSub = (await helper.arrange.createAccounts([1n], donor))[0];255 const receiverCrossEth = helper.ethCrossAccount.fromAddress(receiver);256 const receiverCrossSub = helper.ethCrossAccount.fromKeyringPair(receiverSub);257 258 const collection = await helper.rft.mintCollection(alice);259 const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner});260261 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);262 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);263264 await contract.methods.approve(spender, 100).send({from: owner});265 266 {267 const result = await contract.methods.transferFromCross(ownerCross, receiverCrossEth, 49).send({from: spender});268 let event = result.events.Transfer;269 expect(event.address).to.be.equal(tokenAddress);270 expect(event.returnValues.from).to.be.equal(owner);271 expect(event.returnValues.to).to.be.equal(receiver);272 expect(event.returnValues.value).to.be.equal('49');273274 event = result.events.Approval;275 expect(event.address).to.be.equal(tokenAddress);276 expect(event.returnValues.owner).to.be.equal(owner);277 expect(event.returnValues.spender).to.be.equal(spender);278 expect(event.returnValues.value).to.be.equal('51');279 }280281 {282 const balance = await contract.methods.balanceOf(receiver).call();283 expect(+balance).to.equal(49);284 }285286 {287 const balance = await contract.methods.balanceOf(owner).call();288 expect(+balance).to.equal(151);289 }290 291 {292 const result = await contract.methods.transferFromCross(ownerCross, receiverCrossSub, 51).send({from: spender});293 let event = result.events.Transfer;294 expect(event.address).to.be.equal(tokenAddress);295 expect(event.returnValues.from).to.be.equal(owner);296 expect(event.returnValues.to).to.be.equal(helper.address.substrateToEth(receiverSub.address));297 expect(event.returnValues.value).to.be.equal('51');298299 event = result.events.Approval;300 expect(event.address).to.be.equal(tokenAddress);301 expect(event.returnValues.owner).to.be.equal(owner);302 expect(event.returnValues.spender).to.be.equal(spender);303 expect(event.returnValues.value).to.be.equal('0');304 }305306 {307 const balance = await collection.getTokenBalance(tokenId, {Substrate: receiverSub.address});308 expect(balance).to.equal(51n);309 }310311 {312 const balance = await contract.methods.balanceOf(owner).call();313 expect(+balance).to.equal(100);314 }315 });200316201 itEth('Can perform transfer()', async ({helper}) => {317 itEth('Can perform transfer()', async ({helper}) => {202 const owner = await helper.eth.createAccountWithBalance(donor);318 const owner = await helper.eth.createAccountWithBalance(donor);267 expect(await rftReceiver.getTop10Owners()).to.deep.eq([{Ethereum: owner.toLowerCase()}]);383 expect(await rftReceiver.getTop10Owners()).to.deep.eq([{Ethereum: owner.toLowerCase()}]);268 }));384 }));269385386 itEth('Can perform transferCross()', async ({helper}) => {387 const owner = await helper.eth.createAccountWithBalance(donor);388 const receiver = helper.eth.createAccount();389 const receiverSub = (await helper.arrange.createAccounts([1n], donor))[0];390 const receiverCrossEth = helper.ethCrossAccount.fromAddress(receiver);391 const receiverCrossSub = helper.ethCrossAccount.fromKeyringPair(receiverSub);392 const collection = await helper.rft.mintCollection(alice);393 const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner});394395 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);396 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);397398 {399 const result = await contract.methods.transferCross(receiverCrossEth, 50).send({from: owner});400 const event = result.events.Transfer;401 expect(event.address).to.be.equal(tokenAddress);402 expect(event.returnValues.from).to.be.equal(owner);403 expect(event.returnValues.to).to.be.equal(receiver);404 expect(event.returnValues.value).to.be.equal('50');405 }406407 {408 const balance = await contract.methods.balanceOf(owner).call();409 expect(+balance).to.equal(150);410 }411412 {413 const balance = await contract.methods.balanceOf(receiver).call();414 expect(+balance).to.equal(50);415 }416 417 {418 const result = await contract.methods.transferCross(receiverCrossSub, 50).send({from: owner});419 const event = result.events.Transfer;420 expect(event.address).to.be.equal(tokenAddress);421 expect(event.returnValues.from).to.be.equal(owner);422 expect(event.returnValues.to).to.be.equal(helper.address.substrateToEth(receiverSub.address));423 expect(event.returnValues.value).to.be.equal('50');424 }425426 {427 const balance = await contract.methods.balanceOf(owner).call();428 expect(+balance).to.equal(100);429 }430431 {432 const balance = await collection.getTokenBalance(tokenId, {Substrate: receiverSub.address});433 expect(balance).to.equal(50n);434 }435 });270 itEth('Can perform repartition()', async ({helper}) => {436 itEth('Can perform repartition()', async ({helper}) => {271 const owner = await helper.eth.createAccountWithBalance(donor);437 const owner = await helper.eth.createAccountWithBalance(donor);272 const receiver = await helper.eth.createAccountWithBalance(donor);438 const receiver = await helper.eth.createAccountWithBalance(donor);354 expect(event.returnValues.tokenId).to.be.equal(tokenId);520 expect(event.returnValues.tokenId).to.be.equal(tokenId);355 });521 });522 523 itEth('Can perform burnFromCross()', async ({helper}) => {524 const owner = await helper.eth.createAccountWithBalance(donor);525 const ownerSub = (await helper.arrange.createAccounts([10n], donor))[0];526 const ownerCross = helper.ethCrossAccount.fromAddress(owner);527 const spender = await helper.eth.createAccountWithBalance(donor);528 529 const spenderCrossEth = helper.ethCrossAccount.fromAddress(spender);530 const ownerSubCross = helper.ethCrossAccount.fromKeyringPair(ownerSub);531532 const collection = await helper.rft.mintCollection(alice);533 const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner});534 535536 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);537 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);538539 {540 await contract.methods.approveCross(spenderCrossEth, 100).send({from: owner});541 542 await expect(contract.methods.burnFromCross(ownerCross, 50).send({from: spender})).to.be.fulfilled;543 await expect(contract.methods.burnFromCross(ownerCross, 100).send({from: spender})).to.be.rejected;544 expect(await contract.methods.balanceOf(owner).call({from: owner})).to.be.equal('150');545 }546 {547 const {tokenId} = await collection.mintToken(alice, 200n, {Substrate: ownerSub.address});548 await collection.approveToken(ownerSub, tokenId, {Ethereum: spender}, 100n);549 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);550 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);551 552 await expect(contract.methods.burnFromCross(ownerSubCross, 50).send({from: spender})).to.be.fulfilled;553 await expect(contract.methods.burnFromCross(ownerSubCross, 100).send({from: spender})).to.be.rejected;554 expect(await collection.getTokenBalance(tokenId, {Substrate: ownerSub.address})).to.be.equal(150n);555 }556 });356});557});357558358describe('Refungible: Fees', () => {559describe('Refungible: Fees', () => {tests/src/interfaces/augment-api-rpc.tsdiffbeforeafterboth16import type { BlockHash } from '@polkadot/types/interfaces/chain';16import type { BlockHash } from '@polkadot/types/interfaces/chain';17import type { PrefixedStorageKey } from '@polkadot/types/interfaces/childstate';17import type { PrefixedStorageKey } from '@polkadot/types/interfaces/childstate';18import type { AuthorityId } from '@polkadot/types/interfaces/consensus';18import type { AuthorityId } from '@polkadot/types/interfaces/consensus';19import type { CodeUploadRequest, CodeUploadResult, ContractCallRequest, ContractExecResult, ContractInstantiateResult, InstantiateRequestV1 } from '@polkadot/types/interfaces/contracts';19import type { CodeUploadRequest, CodeUploadResult, ContractCallRequest, ContractExecResult, ContractInstantiateResult, InstantiateRequest } from '@polkadot/types/interfaces/contracts';20import type { BlockStats } from '@polkadot/types/interfaces/dev';20import type { BlockStats } from '@polkadot/types/interfaces/dev';21import type { CreatedBlock } from '@polkadot/types/interfaces/engine';21import type { CreatedBlock } from '@polkadot/types/interfaces/engine';22import type { EthAccount, EthCallRequest, EthFeeHistory, EthFilter, EthFilterChanges, EthLog, EthReceipt, EthRichBlock, EthSubKind, EthSubParams, EthSyncStatus, EthTransaction, EthTransactionRequest, EthWork } from '@polkadot/types/interfaces/eth';22import type { EthAccount, EthCallRequest, EthFeeHistory, EthFilter, EthFilterChanges, EthLog, EthReceipt, EthRichBlock, EthSubKind, EthSubParams, EthSyncStatus, EthTransaction, EthTransactionRequest, EthWork } from '@polkadot/types/interfaces/eth';23import type { Extrinsic } from '@polkadot/types/interfaces/extrinsics';23import type { Extrinsic } from '@polkadot/types/interfaces/extrinsics';24import type { EncodedFinalityProofs, JustificationNotification, ReportedRoundStates } from '@polkadot/types/interfaces/grandpa';24import type { EncodedFinalityProofs, JustificationNotification, ReportedRoundStates } from '@polkadot/types/interfaces/grandpa';25import type { MmrLeafBatchProof, MmrLeafProof } from '@polkadot/types/interfaces/mmr';25import type { MmrLeafBatchProof, MmrLeafProof } from '@polkadot/types/interfaces/mmr';26import type { StorageKind } from '@polkadot/types/interfaces/offchain';26import type { StorageKind } from '@polkadot/types/interfaces/offchain';27import type { FeeDetails, RuntimeDispatchInfoV1 } from '@polkadot/types/interfaces/payment';27import type { FeeDetails, RuntimeDispatchInfo } from '@polkadot/types/interfaces/payment';28import type { RpcMethods } from '@polkadot/types/interfaces/rpc';28import type { RpcMethods } from '@polkadot/types/interfaces/rpc';29import type { AccountId, AccountId32, BlockNumber, H160, H256, H64, Hash, Header, Index, Justification, KeyValue, SignedBlock, StorageData } from '@polkadot/types/interfaces/runtime';29import type { AccountId, AccountId32, BlockNumber, H160, H256, H64, Hash, Header, Index, Justification, KeyValue, SignedBlock, StorageData } from '@polkadot/types/interfaces/runtime';30import type { MigrationStatusResult, ReadProof, RuntimeVersion, TraceBlockResponse } from '@polkadot/types/interfaces/state';30import type { MigrationStatusResult, ReadProof, RuntimeVersion, TraceBlockResponse } from '@polkadot/types/interfaces/state';174 * @deprecated Use the runtime interface `api.call.contractsApi.instantiate` instead174 * @deprecated Use the runtime interface `api.call.contractsApi.instantiate` instead175 * Instantiate a new contract175 * Instantiate a new contract176 **/176 **/177 instantiate: AugmentedRpc<(request: InstantiateRequestV1 | { origin?: any; value?: any; gasLimit?: any; code?: any; data?: any; salt?: any } | string | Uint8Array, at?: BlockHash | string | Uint8Array) => Observable<ContractInstantiateResult>>;177 instantiate: AugmentedRpc<(request: InstantiateRequest | { origin?: any; value?: any; gasLimit?: any; storageDepositLimit?: any; code?: any; data?: any; salt?: any } | string | Uint8Array, at?: BlockHash | string | Uint8Array) => Observable<ContractInstantiateResult>>;178 /**178 /**179 * @deprecated Not available in newer versions of the contracts interfaces179 * @deprecated Not available in newer versions of the contracts interfaces180 * Returns the projected time a given contract will be able to sustain paying its rent180 * Returns the projected time a given contract will be able to sustain paying its rent425 localStorageSet: AugmentedRpc<(kind: StorageKind | 'PERSISTENT' | 'LOCAL' | number | Uint8Array, key: Bytes | string | Uint8Array, value: Bytes | string | Uint8Array) => Observable<Null>>;425 localStorageSet: AugmentedRpc<(kind: StorageKind | 'PERSISTENT' | 'LOCAL' | number | Uint8Array, key: Bytes | string | Uint8Array, value: Bytes | string | Uint8Array) => Observable<Null>>;426 };426 };427 payment: {427 payment: {428 /**428 /**429 * @deprecated Use `api.call.transactionPaymentApi.queryFeeDetails` instead429 * Query the detailed fee of a given encoded extrinsic430 * Query the detailed fee of a given encoded extrinsic430 **/431 **/432 queryFeeDetails: AugmentedRpc<(extrinsic: Bytes | string | Uint8Array, at?: BlockHash | string | Uint8Array) => Observable<FeeDetails>>;431 queryFeeDetails: AugmentedRpc<(extrinsic: Bytes | string | Uint8Array, at?: BlockHash | string | Uint8Array) => Observable<FeeDetails>>;433 /**432 /**434 * @deprecated Use `api.call.transactionPaymentApi.queryInfo` instead433 * Retrieves the fee information for an encoded extrinsic435 * Retrieves the fee information for an encoded extrinsic434 **/436 **/437 queryInfo: AugmentedRpc<(extrinsic: Bytes | string | Uint8Array, at?: BlockHash | string | Uint8Array) => Observable<RuntimeDispatchInfoV1>>;435 queryInfo: AugmentedRpc<(extrinsic: Bytes | string | Uint8Array, at?: BlockHash | string | Uint8Array) => Observable<RuntimeDispatchInfo>>;438 };436 };439 rmrk: {437 rmrk: {440 /**438 /**tests/src/interfaces/augment-api-runtime.tsdiffbeforeafterboth6import '@polkadot/api-base/types/calls';6import '@polkadot/api-base/types/calls';778import type { ApiTypes, AugmentedCall, DecoratedCallBase } from '@polkadot/api-base/types';8import type { ApiTypes, AugmentedCall, DecoratedCallBase } from '@polkadot/api-base/types';9import type { Bytes, Null, Option, Result, U256, Vec, bool, u256, u32, u64 } from '@polkadot/types-codec';9import type { Bytes, Null, Option, Result, U256, Vec, bool, u256, u64 } from '@polkadot/types-codec';10import type { AnyNumber, ITuple } from '@polkadot/types-codec/types';10import type { AnyNumber, ITuple } from '@polkadot/types-codec/types';11import type { CheckInherentsResult, InherentData } from '@polkadot/types/interfaces/blockbuilder';11import type { CheckInherentsResult, InherentData } from '@polkadot/types/interfaces/blockbuilder';12import type { BlockHash } from '@polkadot/types/interfaces/chain';12import type { BlockHash } from '@polkadot/types/interfaces/chain';16import type { EvmAccount, EvmCallInfo, EvmCreateInfo } from '@polkadot/types/interfaces/evm';16import type { EvmAccount, EvmCallInfo, EvmCreateInfo } from '@polkadot/types/interfaces/evm';17import type { Extrinsic } from '@polkadot/types/interfaces/extrinsics';17import type { Extrinsic } from '@polkadot/types/interfaces/extrinsics';18import type { OpaqueMetadata } from '@polkadot/types/interfaces/metadata';18import type { OpaqueMetadata } from '@polkadot/types/interfaces/metadata';19import type { FeeDetails, RuntimeDispatchInfo } from '@polkadot/types/interfaces/payment';20import type { AccountId, Block, H160, H256, Header, Index, KeyTypeId, Permill, SlotDuration } from '@polkadot/types/interfaces/runtime';19import type { AccountId, Block, H160, H256, Header, Index, KeyTypeId, Permill, SlotDuration } from '@polkadot/types/interfaces/runtime';21import type { RuntimeVersion } from '@polkadot/types/interfaces/state';20import type { RuntimeVersion } from '@polkadot/types/interfaces/state';22import type { ApplyExtrinsicResult, DispatchError } from '@polkadot/types/interfaces/system';21import type { ApplyExtrinsicResult, DispatchError } from '@polkadot/types/interfaces/system';229 **/228 **/230 [key: string]: DecoratedCallBase<ApiType>;229 [key: string]: DecoratedCallBase<ApiType>;231 };230 };232 /** 0x37c8bb1350a9a2a8/2 */233 transactionPaymentApi: {234 /**235 * The transaction fee details236 **/237 queryFeeDetails: AugmentedCall<ApiType, (uxt: Extrinsic | IExtrinsic | string | Uint8Array, len: u32 | AnyNumber | Uint8Array) => Observable<FeeDetails>>;238 /**239 * The transaction info240 **/241 queryInfo: AugmentedCall<ApiType, (uxt: Extrinsic | IExtrinsic | string | Uint8Array, len: u32 | AnyNumber | Uint8Array) => Observable<RuntimeDispatchInfo>>;242 /**243 * Generic call244 **/245 [key: string]: DecoratedCallBase<ApiType>;246 };247 } // AugmentedCalls231 } // AugmentedCalls248} // declare module232} // declare module249233tests/src/interfaces/augment-types.tsdiffbeforeafterboth24import type { StatementKind } from '@polkadot/types/interfaces/claims';24import type { StatementKind } from '@polkadot/types/interfaces/claims';25import type { CollectiveOrigin, MemberCount, ProposalIndex, Votes, VotesTo230 } from '@polkadot/types/interfaces/collective';25import type { CollectiveOrigin, MemberCount, ProposalIndex, Votes, VotesTo230 } from '@polkadot/types/interfaces/collective';26import type { AuthorityId, RawVRFOutput } from '@polkadot/types/interfaces/consensus';26import type { AuthorityId, RawVRFOutput } from '@polkadot/types/interfaces/consensus';27import type { AliveContractInfo, CodeHash, CodeSource, CodeUploadRequest, CodeUploadResult, CodeUploadResultValue, ContractCallFlags, ContractCallRequest, ContractExecResult, ContractExecResultOk, ContractExecResultResult, ContractExecResultSuccessTo255, ContractExecResultSuccessTo260, ContractExecResultTo255, ContractExecResultTo260, ContractExecResultTo267, ContractExecResultU64, ContractInfo, ContractInstantiateResult, ContractInstantiateResultTo267, ContractInstantiateResultTo299, ContractInstantiateResultU64, ContractReturnFlags, ContractStorageKey, DeletedContract, ExecReturnValue, Gas, HostFnWeights, HostFnWeightsTo264, InstantiateRequest, InstantiateRequestV1, InstantiateRequestV2, InstantiateReturnValue, InstantiateReturnValueOk, InstantiateReturnValueTo267, InstructionWeights, Limits, LimitsTo264, PrefabWasmModule, RentProjection, Schedule, ScheduleTo212, ScheduleTo258, ScheduleTo264, SeedOf, StorageDeposit, TombstoneContractInfo, TrieId } from '@polkadot/types/interfaces/contracts';27import type { AliveContractInfo, CodeHash, CodeSource, CodeUploadRequest, CodeUploadResult, CodeUploadResultValue, ContractCallFlags, ContractCallRequest, ContractExecResult, ContractExecResultOk, ContractExecResultResult, ContractExecResultSuccessTo255, ContractExecResultSuccessTo260, ContractExecResultTo255, ContractExecResultTo260, ContractExecResultTo267, ContractInfo, ContractInstantiateResult, ContractInstantiateResultTo267, ContractInstantiateResultTo299, ContractReturnFlags, ContractStorageKey, DeletedContract, ExecReturnValue, Gas, HostFnWeights, HostFnWeightsTo264, InstantiateRequest, InstantiateRequestV1, InstantiateRequestV2, InstantiateReturnValue, InstantiateReturnValueOk, InstantiateReturnValueTo267, InstructionWeights, Limits, LimitsTo264, PrefabWasmModule, RentProjection, Schedule, ScheduleTo212, ScheduleTo258, ScheduleTo264, SeedOf, StorageDeposit, TombstoneContractInfo, TrieId } from '@polkadot/types/interfaces/contracts';28import type { ContractConstructorSpecLatest, ContractConstructorSpecV0, ContractConstructorSpecV1, ContractConstructorSpecV2, ContractConstructorSpecV3, ContractContractSpecV0, ContractContractSpecV1, ContractContractSpecV2, ContractContractSpecV3, ContractContractSpecV4, ContractCryptoHasher, ContractDiscriminant, ContractDisplayName, ContractEventParamSpecLatest, ContractEventParamSpecV0, ContractEventParamSpecV2, ContractEventSpecLatest, ContractEventSpecV0, ContractEventSpecV1, ContractEventSpecV2, ContractLayoutArray, ContractLayoutCell, ContractLayoutEnum, ContractLayoutHash, ContractLayoutHashingStrategy, ContractLayoutKey, ContractLayoutStruct, ContractLayoutStructField, ContractMessageParamSpecLatest, ContractMessageParamSpecV0, ContractMessageParamSpecV2, ContractMessageSpecLatest, ContractMessageSpecV0, ContractMessageSpecV1, ContractMessageSpecV2, ContractMetadata, ContractMetadataLatest, ContractMetadataV0, ContractMetadataV1, ContractMetadataV2, ContractMetadataV3, ContractMetadataV4, ContractProject, ContractProjectContract, ContractProjectInfo, ContractProjectSource, ContractProjectV0, ContractSelector, ContractStorageLayout, ContractTypeSpec } from '@polkadot/types/interfaces/contractsAbi';28import type { ContractConstructorSpecLatest, ContractConstructorSpecV0, ContractConstructorSpecV1, ContractConstructorSpecV2, ContractConstructorSpecV3, ContractContractSpecV0, ContractContractSpecV1, ContractContractSpecV2, ContractContractSpecV3, ContractContractSpecV4, ContractCryptoHasher, ContractDiscriminant, ContractDisplayName, ContractEventParamSpecLatest, ContractEventParamSpecV0, ContractEventParamSpecV2, ContractEventSpecLatest, ContractEventSpecV0, ContractEventSpecV1, ContractEventSpecV2, ContractLayoutArray, ContractLayoutCell, ContractLayoutEnum, ContractLayoutHash, ContractLayoutHashingStrategy, ContractLayoutKey, ContractLayoutStruct, ContractLayoutStructField, ContractMessageParamSpecLatest, ContractMessageParamSpecV0, ContractMessageParamSpecV2, ContractMessageSpecLatest, ContractMessageSpecV0, ContractMessageSpecV1, ContractMessageSpecV2, ContractMetadata, ContractMetadataLatest, ContractMetadataV0, ContractMetadataV1, ContractMetadataV2, ContractMetadataV3, ContractMetadataV4, ContractProject, ContractProjectContract, ContractProjectInfo, ContractProjectSource, ContractProjectV0, ContractSelector, ContractStorageLayout, ContractTypeSpec } from '@polkadot/types/interfaces/contractsAbi';29import type { FundIndex, FundInfo, LastContribution, TrieIndex } from '@polkadot/types/interfaces/crowdloan';29import type { FundIndex, FundInfo, LastContribution, TrieIndex } from '@polkadot/types/interfaces/crowdloan';30import type { CollationInfo, CollationInfoV1, ConfigData, MessageId, OverweightIndex, PageCounter, PageIndexData } from '@polkadot/types/interfaces/cumulus';30import type { CollationInfo, CollationInfoV1, ConfigData, MessageId, OverweightIndex, PageCounter, PageIndexData } from '@polkadot/types/interfaces/cumulus';47import type { StorageKind } from '@polkadot/types/interfaces/offchain';47import type { StorageKind } from '@polkadot/types/interfaces/offchain';48import type { DeferredOffenceOf, Kind, OffenceDetails, Offender, OpaqueTimeSlot, ReportIdOf, Reporter } from '@polkadot/types/interfaces/offences';48import type { DeferredOffenceOf, Kind, OffenceDetails, Offender, OpaqueTimeSlot, ReportIdOf, Reporter } from '@polkadot/types/interfaces/offences';49import type { AbridgedCandidateReceipt, AbridgedHostConfiguration, AbridgedHrmpChannel, AssignmentId, AssignmentKind, AttestedCandidate, AuctionIndex, AuthorityDiscoveryId, AvailabilityBitfield, AvailabilityBitfieldRecord, BackedCandidate, Bidder, BufferedSessionChange, CandidateCommitments, CandidateDescriptor, CandidateEvent, CandidateHash, CandidateInfo, CandidatePendingAvailability, CandidateReceipt, CollatorId, CollatorSignature, CommittedCandidateReceipt, CoreAssignment, CoreIndex, CoreOccupied, CoreState, DisputeLocation, DisputeResult, DisputeState, DisputeStatement, DisputeStatementSet, DoubleVoteReport, DownwardMessage, ExplicitDisputeStatement, GlobalValidationData, GlobalValidationSchedule, GroupIndex, GroupRotationInfo, HeadData, HostConfiguration, HrmpChannel, HrmpChannelId, HrmpOpenChannelRequest, InboundDownwardMessage, InboundHrmpMessage, InboundHrmpMessages, IncomingParachain, IncomingParachainDeploy, IncomingParachainFixed, InvalidDisputeStatementKind, LeasePeriod, LeasePeriodOf, LocalValidationData, MessageIngestionType, MessageQueueChain, MessagingStateSnapshot, MessagingStateSnapshotEgressEntry, MultiDisputeStatementSet, NewBidder, OccupiedCore, OccupiedCoreAssumption, OldV1SessionInfo, OutboundHrmpMessage, ParaGenesisArgs, ParaId, ParaInfo, ParaLifecycle, ParaPastCodeMeta, ParaScheduling, ParaValidatorIndex, ParachainDispatchOrigin, ParachainInherentData, ParachainProposal, ParachainsInherentData, ParathreadClaim, ParathreadClaimQueue, ParathreadEntry, PersistedValidationData, PvfCheckStatement, QueuedParathread, RegisteredParachainInfo, RelayBlockNumber, RelayChainBlockNumber, RelayChainHash, RelayHash, Remark, ReplacementTimes, Retriable, ScheduledCore, Scheduling, ScrapedOnChainVotes, ServiceQuality, SessionInfo, SessionInfoValidatorGroup, SignedAvailabilityBitfield, SignedAvailabilityBitfields, SigningContext, SlotRange, SlotRange10, Statement, SubId, SystemInherentData, TransientValidationData, UpgradeGoAhead, UpgradeRestriction, UpwardMessage, ValidDisputeStatementKind, ValidationCode, ValidationCodeHash, ValidationData, ValidationDataType, ValidationFunctionParams, ValidatorSignature, ValidityAttestation, VecInboundHrmpMessage, WinnersData, WinnersData10, WinnersDataTuple, WinnersDataTuple10, WinningData, WinningData10, WinningDataEntry } from '@polkadot/types/interfaces/parachains';49import type { AbridgedCandidateReceipt, AbridgedHostConfiguration, AbridgedHrmpChannel, AssignmentId, AssignmentKind, AttestedCandidate, AuctionIndex, AuthorityDiscoveryId, AvailabilityBitfield, AvailabilityBitfieldRecord, BackedCandidate, Bidder, BufferedSessionChange, CandidateCommitments, CandidateDescriptor, CandidateEvent, CandidateHash, CandidateInfo, CandidatePendingAvailability, CandidateReceipt, CollatorId, CollatorSignature, CommittedCandidateReceipt, CoreAssignment, CoreIndex, CoreOccupied, CoreState, DisputeLocation, DisputeResult, DisputeState, DisputeStatement, DisputeStatementSet, DoubleVoteReport, DownwardMessage, ExplicitDisputeStatement, GlobalValidationData, GlobalValidationSchedule, GroupIndex, GroupRotationInfo, HeadData, HostConfiguration, HrmpChannel, HrmpChannelId, HrmpOpenChannelRequest, InboundDownwardMessage, InboundHrmpMessage, InboundHrmpMessages, IncomingParachain, IncomingParachainDeploy, IncomingParachainFixed, InvalidDisputeStatementKind, LeasePeriod, LeasePeriodOf, LocalValidationData, MessageIngestionType, MessageQueueChain, MessagingStateSnapshot, MessagingStateSnapshotEgressEntry, MultiDisputeStatementSet, NewBidder, OccupiedCore, OccupiedCoreAssumption, OldV1SessionInfo, OutboundHrmpMessage, ParaGenesisArgs, ParaId, ParaInfo, ParaLifecycle, ParaPastCodeMeta, ParaScheduling, ParaValidatorIndex, ParachainDispatchOrigin, ParachainInherentData, ParachainProposal, ParachainsInherentData, ParathreadClaim, ParathreadClaimQueue, ParathreadEntry, PersistedValidationData, PvfCheckStatement, QueuedParathread, RegisteredParachainInfo, RelayBlockNumber, RelayChainBlockNumber, RelayChainHash, RelayHash, Remark, ReplacementTimes, Retriable, ScheduledCore, Scheduling, ScrapedOnChainVotes, ServiceQuality, SessionInfo, SessionInfoValidatorGroup, SignedAvailabilityBitfield, SignedAvailabilityBitfields, SigningContext, SlotRange, SlotRange10, Statement, SubId, SystemInherentData, TransientValidationData, UpgradeGoAhead, UpgradeRestriction, UpwardMessage, ValidDisputeStatementKind, ValidationCode, ValidationCodeHash, ValidationData, ValidationDataType, ValidationFunctionParams, ValidatorSignature, ValidityAttestation, VecInboundHrmpMessage, WinnersData, WinnersData10, WinnersDataTuple, WinnersDataTuple10, WinningData, WinningData10, WinningDataEntry } from '@polkadot/types/interfaces/parachains';50import type { FeeDetails, InclusionFee, RuntimeDispatchInfo, RuntimeDispatchInfoV1, RuntimeDispatchInfoV2 } from '@polkadot/types/interfaces/payment';50import type { FeeDetails, InclusionFee, RuntimeDispatchInfo } from '@polkadot/types/interfaces/payment';51import type { Approvals } from '@polkadot/types/interfaces/poll';51import type { Approvals } from '@polkadot/types/interfaces/poll';52import type { ProxyAnnouncement, ProxyDefinition, ProxyType } from '@polkadot/types/interfaces/proxy';52import type { ProxyAnnouncement, ProxyDefinition, ProxyType } from '@polkadot/types/interfaces/proxy';53import type { AccountStatus, AccountValidity } from '@polkadot/types/interfaces/purchase';53import type { AccountStatus, AccountValidity } from '@polkadot/types/interfaces/purchase';273 ContractExecResultTo255: ContractExecResultTo255;273 ContractExecResultTo255: ContractExecResultTo255;274 ContractExecResultTo260: ContractExecResultTo260;274 ContractExecResultTo260: ContractExecResultTo260;275 ContractExecResultTo267: ContractExecResultTo267;275 ContractExecResultTo267: ContractExecResultTo267;276 ContractExecResultU64: ContractExecResultU64;277 ContractInfo: ContractInfo;276 ContractInfo: ContractInfo;278 ContractInstantiateResult: ContractInstantiateResult;277 ContractInstantiateResult: ContractInstantiateResult;279 ContractInstantiateResultTo267: ContractInstantiateResultTo267;278 ContractInstantiateResultTo267: ContractInstantiateResultTo267;280 ContractInstantiateResultTo299: ContractInstantiateResultTo299;279 ContractInstantiateResultTo299: ContractInstantiateResultTo299;281 ContractInstantiateResultU64: ContractInstantiateResultU64;282 ContractLayoutArray: ContractLayoutArray;280 ContractLayoutArray: ContractLayoutArray;283 ContractLayoutCell: ContractLayoutCell;281 ContractLayoutCell: ContractLayoutCell;284 ContractLayoutEnum: ContractLayoutEnum;282 ContractLayoutEnum: ContractLayoutEnum;1059 RpcMethods: RpcMethods;1057 RpcMethods: RpcMethods;1060 RuntimeDbWeight: RuntimeDbWeight;1058 RuntimeDbWeight: RuntimeDbWeight;1061 RuntimeDispatchInfo: RuntimeDispatchInfo;1059 RuntimeDispatchInfo: RuntimeDispatchInfo;1062 RuntimeDispatchInfoV1: RuntimeDispatchInfoV1;1063 RuntimeDispatchInfoV2: RuntimeDispatchInfoV2;1064 RuntimeVersion: RuntimeVersion;1060 RuntimeVersion: RuntimeVersion;1065 RuntimeVersionApi: RuntimeVersionApi;1061 RuntimeVersionApi: RuntimeVersionApi;1066 RuntimeVersionPartial: RuntimeVersionPartial;1062 RuntimeVersionPartial: RuntimeVersionPartial;