--- a/pallets/refungible/src/erc_token.rs +++ b/pallets/refungible/src/erc_token.rs @@ -30,7 +30,7 @@ use pallet_common::{ CommonWeightInfo, erc::{CommonEvmHandler, PrecompileResult}, - eth::collection_id_to_address, + eth::{collection_id_to_address, EthCrossAccount}, }; use pallet_evm::{account::CrossAccountId, PrecompileHandle}; use pallet_evm_coder_substrate::{call, dispatch_to_evm, WithRecorder}; @@ -194,7 +194,10 @@ } #[solidity_interface(name = ERC20UniqueExtensions)] -impl RefungibleTokenHandle { +impl RefungibleTokenHandle +where + T::AccountId: From<[u8; 32]>, +{ /// @dev Function that burns an amount of the token of a given account, /// deducting from the sender's allowance for said account. /// @param from The account whose tokens will be burnt. @@ -213,6 +216,51 @@ Ok(true) } + /// @dev Function that burns an amount of the token of a given account, + /// deducting from the sender's allowance for said account. + /// @param from The account whose tokens will be burnt. + /// @param amount The amount that will be burnt. + #[weight(>::burn_from())] + fn burn_from_cross( + &mut self, + caller: caller, + from: EthCrossAccount, + amount: uint256, + ) -> Result { + let caller = T::CrossAccountId::from_eth(caller); + let from = from.into_sub_cross_account::()?; + let amount = amount.try_into().map_err(|_| "amount overflow")?; + let budget = self + .recorder + .weight_calls_budget(>::find_parent()); + + >::burn_from(self, &caller, &from, self.1, amount, &budget) + .map_err(dispatch_to_evm::)?; + Ok(true) + } + + /// @dev Approve the passed address to spend the specified amount of tokens on behalf of `msg.sender`. + /// Beware that changing an allowance with this method brings the risk that someone may use both the old + /// and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this + /// race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: + /// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + /// @param spender The crossaccount which will spend the funds. + /// @param amount The amount of tokens to be spent. + #[weight(>::approve())] + fn approve_cross( + &mut self, + caller: caller, + spender: EthCrossAccount, + amount: uint256, + ) -> Result { + let caller = T::CrossAccountId::from_eth(caller); + let spender = spender.into_sub_cross_account::()?; + let amount = amount.try_into().map_err(|_| "amount overflow")?; + + >::set_allowance(self, &caller, &spender, self.1, amount) + .map_err(dispatch_to_evm::)?; + Ok(true) + } /// @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. @@ -224,6 +272,53 @@ >::repartition(self, &caller, self.1, amount).map_err(dispatch_to_evm::)?; Ok(true) } + + /// @dev Transfer token for a specified address + /// @param to The crossaccount to transfer to. + /// @param amount The amount to be transferred. + #[weight(>::transfer())] + fn transfer_cross( + &mut self, + caller: caller, + to: EthCrossAccount, + amount: uint256, + ) -> Result { + let caller = T::CrossAccountId::from_eth(caller); + let to = to.into_sub_cross_account::()?; + let amount = amount.try_into().map_err(|_| "amount overflow")?; + let budget = self + .recorder + .weight_calls_budget(>::find_parent()); + + >::transfer(self, &caller, &to, self.1, amount, &budget) + .map_err(dispatch_to_evm::)?; + Ok(true) + } + + /// @dev Transfer tokens from one address to another + /// @param from The address which you want to send tokens from + /// @param to The address which you want to transfer to + /// @param amount the amount of tokens to be transferred + #[weight(>::transfer_from())] + fn transfer_from_cross( + &mut self, + caller: caller, + from: EthCrossAccount, + to: EthCrossAccount, + amount: uint256, + ) -> Result { + let caller = T::CrossAccountId::from_eth(caller); + let from = from.into_sub_cross_account::()?; + let to = to.into_sub_cross_account::()?; + let amount = amount.try_into().map_err(|_| "amount overflow")?; + let budget = self + .recorder + .weight_calls_budget(>::find_parent()); + + >::transfer_from(self, &caller, &from, &to, self.1, amount, &budget) + .map_err(dispatch_to_evm::)?; + Ok(true) + } } impl RefungibleTokenHandle { --- 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 0xab8deb37 +/// @dev the ERC-165 identifier for this interface is 0xe17a7d2b contract ERC20UniqueExtensions is Dummy, ERC165 { /// @dev Function that burns an amount of the token of a given account, /// deducting from the sender's allowance for said account. @@ -52,6 +52,37 @@ return false; } + /// @dev Function that burns an amount of the token of a given account, + /// deducting from the sender's allowance for said account. + /// @param from The account whose tokens will be burnt. + /// @param amount The amount that will be burnt. + /// @dev EVM selector for this function is: 0xbb2f5a58, + /// or in textual repr: burnFromCross((address,uint256),uint256) + function burnFromCross(EthCrossAccount memory from, uint256 amount) public returns (bool) { + require(false, stub_error); + from; + amount; + dummy = 0; + return false; + } + + /// @dev Approve the passed address to spend the specified amount of tokens on behalf of `msg.sender`. + /// Beware that changing an allowance with this method brings the risk that someone may use both the old + /// and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this + /// race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: + /// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + /// @param spender The crossaccount which will spend the funds. + /// @param amount The amount of tokens to be spent. + /// @dev EVM selector for this function is: 0x0ecd0ab0, + /// or in textual repr: approveCross((address,uint256),uint256) + function approveCross(EthCrossAccount memory spender, uint256 amount) public returns (bool) { + require(false, stub_error); + spender; + amount; + dummy = 0; + return false; + } + /// @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. @@ -63,6 +94,44 @@ dummy = 0; return false; } + + /// @dev Transfer token for a specified address + /// @param to The crossaccount to transfer to. + /// @param amount The amount to be transferred. + /// @dev EVM selector for this function is: 0x2ada85ff, + /// or in textual repr: transferCross((address,uint256),uint256) + function transferCross(EthCrossAccount memory to, uint256 amount) public returns (bool) { + require(false, stub_error); + to; + amount; + dummy = 0; + return false; + } + + /// @dev Transfer tokens from one address to another + /// @param from The address which you want to send tokens from + /// @param to The address which you want to transfer to + /// @param amount the amount of tokens to be transferred + /// @dev EVM selector for this function is: 0xd5cf430b, + /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256) + function transferFromCross( + EthCrossAccount memory from, + EthCrossAccount memory to, + uint256 amount + ) public returns (bool) { + require(false, stub_error); + from; + to; + amount; + dummy = 0; + return false; + } +} + +/// @dev Cross account struct +struct EthCrossAccount { + address eth; + uint256 sub; } /// @dev inlined interface --- a/tests/src/eth/abi/reFungibleToken.json +++ b/tests/src/eth/abi/reFungibleToken.json @@ -71,6 +71,24 @@ }, { "inputs": [ + { + "components": [ + { "internalType": "address", "name": "eth", "type": "address" }, + { "internalType": "uint256", "name": "sub", "type": "uint256" } + ], + "internalType": "struct EthCrossAccount", + "name": "spender", + "type": "tuple" + }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approveCross", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "address", "name": "owner", "type": "address" } ], "name": "balanceOf", @@ -89,6 +107,24 @@ "type": "function" }, { + "inputs": [ + { + "components": [ + { "internalType": "address", "name": "eth", "type": "address" }, + { "internalType": "uint256", "name": "sub", "type": "uint256" } + ], + "internalType": "struct EthCrossAccount", + "name": "from", + "type": "tuple" + }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "burnFromCross", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { "inputs": [], "name": "decimals", "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], @@ -160,6 +196,24 @@ }, { "inputs": [ + { + "components": [ + { "internalType": "address", "name": "eth", "type": "address" }, + { "internalType": "uint256", "name": "sub", "type": "uint256" } + ], + "internalType": "struct EthCrossAccount", + "name": "to", + "type": "tuple" + }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferCross", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "address", "name": "from", "type": "address" }, { "internalType": "address", "name": "to", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } @@ -168,5 +222,32 @@ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "address", "name": "eth", "type": "address" }, + { "internalType": "uint256", "name": "sub", "type": "uint256" } + ], + "internalType": "struct EthCrossAccount", + "name": "from", + "type": "tuple" + }, + { + "components": [ + { "internalType": "address", "name": "eth", "type": "address" }, + { "internalType": "uint256", "name": "sub", "type": "uint256" } + ], + "internalType": "struct EthCrossAccount", + "name": "to", + "type": "tuple" + }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFromCross", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" } ] --- 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 0xab8deb37 +/// @dev the ERC-165 identifier for this interface is 0xe17a7d2b interface ERC20UniqueExtensions is Dummy, ERC165 { /// @dev Function that burns an amount of the token of a given account, /// deducting from the sender's allowance for said account. @@ -33,12 +33,56 @@ /// or in textual repr: burnFrom(address,uint256) function burnFrom(address from, uint256 amount) external returns (bool); + /// @dev Function that burns an amount of the token of a given account, + /// deducting from the sender's allowance for said account. + /// @param from The account whose tokens will be burnt. + /// @param amount The amount that will be burnt. + /// @dev EVM selector for this function is: 0xbb2f5a58, + /// or in textual repr: burnFromCross((address,uint256),uint256) + function burnFromCross(EthCrossAccount memory from, uint256 amount) external returns (bool); + + /// @dev Approve the passed address to spend the specified amount of tokens on behalf of `msg.sender`. + /// Beware that changing an allowance with this method brings the risk that someone may use both the old + /// and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this + /// race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: + /// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + /// @param spender The crossaccount which will spend the funds. + /// @param amount The amount of tokens to be spent. + /// @dev EVM selector for this function is: 0x0ecd0ab0, + /// or in textual repr: approveCross((address,uint256),uint256) + function approveCross(EthCrossAccount memory spender, uint256 amount) external returns (bool); + /// @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. /// @dev EVM selector for this function is: 0xd2418ca7, /// or in textual repr: repartition(uint256) function repartition(uint256 amount) external returns (bool); + + /// @dev Transfer token for a specified address + /// @param to The crossaccount to transfer to. + /// @param amount The amount to be transferred. + /// @dev EVM selector for this function is: 0x2ada85ff, + /// or in textual repr: transferCross((address,uint256),uint256) + function transferCross(EthCrossAccount memory to, uint256 amount) external returns (bool); + + /// @dev Transfer tokens from one address to another + /// @param from The address which you want to send tokens from + /// @param to The address which you want to transfer to + /// @param amount the amount of tokens to be transferred + /// @dev EVM selector for this function is: 0xd5cf430b, + /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256) + function transferFromCross( + EthCrossAccount memory from, + EthCrossAccount memory to, + uint256 amount + ) external returns (bool); +} + +/// @dev Cross account struct +struct EthCrossAccount { + address eth; + uint256 sub; } /// @dev inlined interface --- a/tests/src/eth/reFungibleToken.test.ts +++ b/tests/src/eth/reFungibleToken.test.ts @@ -159,7 +159,55 @@ expect(+allowance).to.equal(100); } }); + + itEth('Can perform approveCross()', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const spender = helper.eth.createAccount(); + const spenderSub = (await helper.arrange.createAccounts([1n], donor))[0]; + const spenderCrossEth = helper.ethCrossAccount.fromAddress(spender); + const spenderCrossSub = helper.ethCrossAccount.fromKeyringPair(spenderSub); + + + const collection = await helper.rft.mintCollection(alice); + const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner}); + + const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId); + const contract = helper.ethNativeContract.rftToken(tokenAddress, owner); + { + const result = await contract.methods.approveCross(spenderCrossEth, 100).send({from: owner}); + const event = result.events.Approval; + expect(event.address).to.be.equal(tokenAddress); + expect(event.returnValues.owner).to.be.equal(owner); + expect(event.returnValues.spender).to.be.equal(spender); + expect(event.returnValues.value).to.be.equal('100'); + } + + { + const allowance = await contract.methods.allowance(owner, spender).call(); + expect(+allowance).to.equal(100); + } + + + { + const result = await contract.methods.approveCross(spenderCrossSub, 100).send({from: owner}); + const event = result.events.Approval; + expect(event.address).to.be.equal(tokenAddress); + expect(event.returnValues.owner).to.be.equal(owner); + expect(event.returnValues.spender).to.be.equal(helper.address.substrateToEth(spenderSub.address)); + expect(event.returnValues.value).to.be.equal('100'); + } + + { + const allowance = await collection.getTokenApprovedPieces(tokenId, {Ethereum: owner}, {Substrate: spenderSub.address}); + expect(allowance).to.equal(100n); + } + + { + //TO-DO expect with future allowanceCross(owner, spenderCrossEth).call() + } + }); + itEth('Can perform transferFrom()', async ({helper}) => { const owner = await helper.eth.createAccountWithBalance(donor); const spender = await helper.eth.createAccountWithBalance(donor); @@ -197,7 +245,75 @@ expect(+balance).to.equal(151); } }); + + itEth('Can perform transferFromCross()', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const ownerCross = helper.ethCrossAccount.fromAddress(owner); + const spender = await helper.eth.createAccountWithBalance(donor); + const receiver = helper.eth.createAccount(); + const receiverSub = (await helper.arrange.createAccounts([1n], donor))[0]; + const receiverCrossEth = helper.ethCrossAccount.fromAddress(receiver); + const receiverCrossSub = helper.ethCrossAccount.fromKeyringPair(receiverSub); + + const collection = await helper.rft.mintCollection(alice); + const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner}); + + const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId); + const contract = helper.ethNativeContract.rftToken(tokenAddress, owner); + + await contract.methods.approve(spender, 100).send({from: owner}); + + { + const result = await contract.methods.transferFromCross(ownerCross, receiverCrossEth, 49).send({from: spender}); + let event = result.events.Transfer; + expect(event.address).to.be.equal(tokenAddress); + expect(event.returnValues.from).to.be.equal(owner); + expect(event.returnValues.to).to.be.equal(receiver); + expect(event.returnValues.value).to.be.equal('49'); + event = result.events.Approval; + expect(event.address).to.be.equal(tokenAddress); + expect(event.returnValues.owner).to.be.equal(owner); + expect(event.returnValues.spender).to.be.equal(spender); + expect(event.returnValues.value).to.be.equal('51'); + } + + { + const balance = await contract.methods.balanceOf(receiver).call(); + expect(+balance).to.equal(49); + } + + { + const balance = await contract.methods.balanceOf(owner).call(); + expect(+balance).to.equal(151); + } + + { + const result = await contract.methods.transferFromCross(ownerCross, receiverCrossSub, 51).send({from: spender}); + let event = result.events.Transfer; + expect(event.address).to.be.equal(tokenAddress); + expect(event.returnValues.from).to.be.equal(owner); + expect(event.returnValues.to).to.be.equal(helper.address.substrateToEth(receiverSub.address)); + expect(event.returnValues.value).to.be.equal('51'); + + event = result.events.Approval; + expect(event.address).to.be.equal(tokenAddress); + expect(event.returnValues.owner).to.be.equal(owner); + expect(event.returnValues.spender).to.be.equal(spender); + expect(event.returnValues.value).to.be.equal('0'); + } + + { + const balance = await collection.getTokenBalance(tokenId, {Substrate: receiverSub.address}); + expect(balance).to.equal(51n); + } + + { + const balance = await contract.methods.balanceOf(owner).call(); + expect(+balance).to.equal(100); + } + }); + itEth('Can perform transfer()', async ({helper}) => { const owner = await helper.eth.createAccountWithBalance(donor); const receiver = helper.eth.createAccount(); @@ -226,7 +342,7 @@ expect(+balance).to.equal(50); } }); - + [ 'transfer', // 'transferCross', // TODO @@ -267,6 +383,56 @@ expect(await rftReceiver.getTop10Owners()).to.deep.eq([{Ethereum: owner.toLowerCase()}]); })); + itEth('Can perform transferCross()', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const receiver = helper.eth.createAccount(); + const receiverSub = (await helper.arrange.createAccounts([1n], donor))[0]; + const receiverCrossEth = helper.ethCrossAccount.fromAddress(receiver); + const receiverCrossSub = helper.ethCrossAccount.fromKeyringPair(receiverSub); + const collection = await helper.rft.mintCollection(alice); + const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner}); + + const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId); + const contract = helper.ethNativeContract.rftToken(tokenAddress, owner); + + { + const result = await contract.methods.transferCross(receiverCrossEth, 50).send({from: owner}); + const event = result.events.Transfer; + expect(event.address).to.be.equal(tokenAddress); + expect(event.returnValues.from).to.be.equal(owner); + expect(event.returnValues.to).to.be.equal(receiver); + expect(event.returnValues.value).to.be.equal('50'); + } + + { + const balance = await contract.methods.balanceOf(owner).call(); + expect(+balance).to.equal(150); + } + + { + const balance = await contract.methods.balanceOf(receiver).call(); + expect(+balance).to.equal(50); + } + + { + const result = await contract.methods.transferCross(receiverCrossSub, 50).send({from: owner}); + const event = result.events.Transfer; + expect(event.address).to.be.equal(tokenAddress); + expect(event.returnValues.from).to.be.equal(owner); + expect(event.returnValues.to).to.be.equal(helper.address.substrateToEth(receiverSub.address)); + expect(event.returnValues.value).to.be.equal('50'); + } + + { + const balance = await contract.methods.balanceOf(owner).call(); + expect(+balance).to.equal(100); + } + + { + const balance = await collection.getTokenBalance(tokenId, {Substrate: receiverSub.address}); + expect(balance).to.equal(50n); + } + }); itEth('Can perform repartition()', async ({helper}) => { const owner = await helper.eth.createAccountWithBalance(donor); const receiver = await helper.eth.createAccountWithBalance(donor); @@ -353,6 +519,41 @@ expect(event.returnValues.to).to.be.equal(receiver); expect(event.returnValues.tokenId).to.be.equal(tokenId); }); + + itEth('Can perform burnFromCross()', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const ownerSub = (await helper.arrange.createAccounts([10n], donor))[0]; + const ownerCross = helper.ethCrossAccount.fromAddress(owner); + const spender = await helper.eth.createAccountWithBalance(donor); + + const spenderCrossEth = helper.ethCrossAccount.fromAddress(spender); + const ownerSubCross = helper.ethCrossAccount.fromKeyringPair(ownerSub); + + const collection = await helper.rft.mintCollection(alice); + const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner}); + + + const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId); + const contract = helper.ethNativeContract.rftToken(tokenAddress, owner); + + { + await contract.methods.approveCross(spenderCrossEth, 100).send({from: owner}); + + await expect(contract.methods.burnFromCross(ownerCross, 50).send({from: spender})).to.be.fulfilled; + await expect(contract.methods.burnFromCross(ownerCross, 100).send({from: spender})).to.be.rejected; + expect(await contract.methods.balanceOf(owner).call({from: owner})).to.be.equal('150'); + } + { + const {tokenId} = await collection.mintToken(alice, 200n, {Substrate: ownerSub.address}); + await collection.approveToken(ownerSub, tokenId, {Ethereum: spender}, 100n); + const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId); + const contract = helper.ethNativeContract.rftToken(tokenAddress, owner); + + await expect(contract.methods.burnFromCross(ownerSubCross, 50).send({from: spender})).to.be.fulfilled; + await expect(contract.methods.burnFromCross(ownerSubCross, 100).send({from: spender})).to.be.rejected; + expect(await collection.getTokenBalance(tokenId, {Substrate: ownerSub.address})).to.be.equal(150n); + } + }); }); describe('Refungible: Fees', () => { --- a/tests/src/interfaces/augment-api-rpc.ts +++ b/tests/src/interfaces/augment-api-rpc.ts @@ -16,7 +16,7 @@ import type { BlockHash } from '@polkadot/types/interfaces/chain'; import type { PrefixedStorageKey } from '@polkadot/types/interfaces/childstate'; import type { AuthorityId } from '@polkadot/types/interfaces/consensus'; -import type { CodeUploadRequest, CodeUploadResult, ContractCallRequest, ContractExecResult, ContractInstantiateResult, InstantiateRequestV1 } from '@polkadot/types/interfaces/contracts'; +import type { CodeUploadRequest, CodeUploadResult, ContractCallRequest, ContractExecResult, ContractInstantiateResult, InstantiateRequest } from '@polkadot/types/interfaces/contracts'; import type { BlockStats } from '@polkadot/types/interfaces/dev'; import type { CreatedBlock } from '@polkadot/types/interfaces/engine'; import type { EthAccount, EthCallRequest, EthFeeHistory, EthFilter, EthFilterChanges, EthLog, EthReceipt, EthRichBlock, EthSubKind, EthSubParams, EthSyncStatus, EthTransaction, EthTransactionRequest, EthWork } from '@polkadot/types/interfaces/eth'; @@ -24,7 +24,7 @@ import type { EncodedFinalityProofs, JustificationNotification, ReportedRoundStates } from '@polkadot/types/interfaces/grandpa'; import type { MmrLeafBatchProof, MmrLeafProof } from '@polkadot/types/interfaces/mmr'; import type { StorageKind } from '@polkadot/types/interfaces/offchain'; -import type { FeeDetails, RuntimeDispatchInfoV1 } from '@polkadot/types/interfaces/payment'; +import type { FeeDetails, RuntimeDispatchInfo } from '@polkadot/types/interfaces/payment'; import type { RpcMethods } from '@polkadot/types/interfaces/rpc'; import type { AccountId, AccountId32, BlockNumber, H160, H256, H64, Hash, Header, Index, Justification, KeyValue, SignedBlock, StorageData } from '@polkadot/types/interfaces/runtime'; import type { MigrationStatusResult, ReadProof, RuntimeVersion, TraceBlockResponse } from '@polkadot/types/interfaces/state'; @@ -174,7 +174,7 @@ * @deprecated Use the runtime interface `api.call.contractsApi.instantiate` instead * Instantiate a new contract **/ - instantiate: AugmentedRpc<(request: InstantiateRequestV1 | { origin?: any; value?: any; gasLimit?: any; code?: any; data?: any; salt?: any } | string | Uint8Array, at?: BlockHash | string | Uint8Array) => Observable>; + 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>; /** * @deprecated Not available in newer versions of the contracts interfaces * Returns the projected time a given contract will be able to sustain paying its rent @@ -426,15 +426,13 @@ }; payment: { /** - * @deprecated Use `api.call.transactionPaymentApi.queryFeeDetails` instead * Query the detailed fee of a given encoded extrinsic **/ queryFeeDetails: AugmentedRpc<(extrinsic: Bytes | string | Uint8Array, at?: BlockHash | string | Uint8Array) => Observable>; /** - * @deprecated Use `api.call.transactionPaymentApi.queryInfo` instead * Retrieves the fee information for an encoded extrinsic **/ - queryInfo: AugmentedRpc<(extrinsic: Bytes | string | Uint8Array, at?: BlockHash | string | Uint8Array) => Observable>; + queryInfo: AugmentedRpc<(extrinsic: Bytes | string | Uint8Array, at?: BlockHash | string | Uint8Array) => Observable>; }; rmrk: { /** --- a/tests/src/interfaces/augment-api-runtime.ts +++ b/tests/src/interfaces/augment-api-runtime.ts @@ -6,7 +6,7 @@ import '@polkadot/api-base/types/calls'; import type { ApiTypes, AugmentedCall, DecoratedCallBase } from '@polkadot/api-base/types'; -import type { Bytes, Null, Option, Result, U256, Vec, bool, u256, u32, u64 } from '@polkadot/types-codec'; +import type { Bytes, Null, Option, Result, U256, Vec, bool, u256, u64 } from '@polkadot/types-codec'; import type { AnyNumber, ITuple } from '@polkadot/types-codec/types'; import type { CheckInherentsResult, InherentData } from '@polkadot/types/interfaces/blockbuilder'; import type { BlockHash } from '@polkadot/types/interfaces/chain'; @@ -16,7 +16,6 @@ import type { EvmAccount, EvmCallInfo, EvmCreateInfo } from '@polkadot/types/interfaces/evm'; import type { Extrinsic } from '@polkadot/types/interfaces/extrinsics'; import type { OpaqueMetadata } from '@polkadot/types/interfaces/metadata'; -import type { FeeDetails, RuntimeDispatchInfo } from '@polkadot/types/interfaces/payment'; import type { AccountId, Block, H160, H256, Header, Index, KeyTypeId, Permill, SlotDuration } from '@polkadot/types/interfaces/runtime'; import type { RuntimeVersion } from '@polkadot/types/interfaces/state'; import type { ApplyExtrinsicResult, DispatchError } from '@polkadot/types/interfaces/system'; @@ -224,21 +223,6 @@ * Validate the transaction. **/ validateTransaction: AugmentedCall Observable>; - /** - * Generic call - **/ - [key: string]: DecoratedCallBase; - }; - /** 0x37c8bb1350a9a2a8/2 */ - transactionPaymentApi: { - /** - * The transaction fee details - **/ - queryFeeDetails: AugmentedCall Observable>; - /** - * The transaction info - **/ - queryInfo: AugmentedCall Observable>; /** * Generic call **/ --- a/tests/src/interfaces/augment-types.ts +++ b/tests/src/interfaces/augment-types.ts @@ -24,7 +24,7 @@ import type { StatementKind } from '@polkadot/types/interfaces/claims'; import type { CollectiveOrigin, MemberCount, ProposalIndex, Votes, VotesTo230 } from '@polkadot/types/interfaces/collective'; import type { AuthorityId, RawVRFOutput } from '@polkadot/types/interfaces/consensus'; -import 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'; +import 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'; import 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'; import type { FundIndex, FundInfo, LastContribution, TrieIndex } from '@polkadot/types/interfaces/crowdloan'; import type { CollationInfo, CollationInfoV1, ConfigData, MessageId, OverweightIndex, PageCounter, PageIndexData } from '@polkadot/types/interfaces/cumulus'; @@ -47,7 +47,7 @@ import type { StorageKind } from '@polkadot/types/interfaces/offchain'; import type { DeferredOffenceOf, Kind, OffenceDetails, Offender, OpaqueTimeSlot, ReportIdOf, Reporter } from '@polkadot/types/interfaces/offences'; import 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'; -import type { FeeDetails, InclusionFee, RuntimeDispatchInfo, RuntimeDispatchInfoV1, RuntimeDispatchInfoV2 } from '@polkadot/types/interfaces/payment'; +import type { FeeDetails, InclusionFee, RuntimeDispatchInfo } from '@polkadot/types/interfaces/payment'; import type { Approvals } from '@polkadot/types/interfaces/poll'; import type { ProxyAnnouncement, ProxyDefinition, ProxyType } from '@polkadot/types/interfaces/proxy'; import type { AccountStatus, AccountValidity } from '@polkadot/types/interfaces/purchase'; @@ -273,12 +273,10 @@ ContractExecResultTo255: ContractExecResultTo255; ContractExecResultTo260: ContractExecResultTo260; ContractExecResultTo267: ContractExecResultTo267; - ContractExecResultU64: ContractExecResultU64; ContractInfo: ContractInfo; ContractInstantiateResult: ContractInstantiateResult; ContractInstantiateResultTo267: ContractInstantiateResultTo267; ContractInstantiateResultTo299: ContractInstantiateResultTo299; - ContractInstantiateResultU64: ContractInstantiateResultU64; ContractLayoutArray: ContractLayoutArray; ContractLayoutCell: ContractLayoutCell; ContractLayoutEnum: ContractLayoutEnum; @@ -1059,8 +1057,6 @@ RpcMethods: RpcMethods; RuntimeDbWeight: RuntimeDbWeight; RuntimeDispatchInfo: RuntimeDispatchInfo; - RuntimeDispatchInfoV1: RuntimeDispatchInfoV1; - RuntimeDispatchInfoV2: RuntimeDispatchInfoV2; RuntimeVersion: RuntimeVersion; RuntimeVersionApi: RuntimeVersionApi; RuntimeVersionPartial: RuntimeVersionPartial;