difftreelog
CORE-302 Create collection from EVM principle
in: master
9 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6078,18 +6078,22 @@
name = "pallet-evm-contract-helpers"
version = "0.1.0"
dependencies = [
+ "ethereum",
"evm-coder",
"fp-evm-mapping",
"frame-support",
"frame-system",
"log",
+ "pallet-common",
"pallet-evm",
"pallet-evm-coder-substrate",
+ "pallet-nonfungible",
"parity-scale-codec 3.1.2",
"scale-info",
"sp-core",
"sp-runtime",
"sp-std",
+ "up-data-structs",
"up-sponsorship",
]
pallets/evm-contract-helpers/Cargo.tomldiffbeforeafterboth--- a/pallets/evm-contract-helpers/Cargo.toml
+++ b/pallets/evm-contract-helpers/Cargo.toml
@@ -8,18 +8,28 @@
scale-info = { version = "2.0.1", default-features = false, features = [
"derive",
] }
-frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.21" }
-frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.21" }
-sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.21" }
-sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.21" }
-sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.21" }
-evm-coder = { default-features = false, path = '../../crates/evm-coder' }
-pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
+ethereum = { version = "0.12.0", default-features = false }
+log = { default-features = false, version = "0.4.14" }
+
+# Substrate
+frame-support = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.21' }
+frame-system = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.21' }
+sp-runtime = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.21' }
+sp-std = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.21' }
+sp-core = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.21' }
+
+# Unique
pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.21-logs" }
fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.21-logs" }
up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.21" }
-log = "0.4.14"
+# Locals
+evm-coder = { default-features = false, path = '../../crates/evm-coder' }
+pallet-common = { default-features = false, path = '../../pallets/common' }
+pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
+pallet-nonfungible = { default-features = false, path = '../../pallets/nonfungible' }
+up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
+
[dependencies.codec]
default-features = false
features = ['derive']
pallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth--- a/pallets/evm-contract-helpers/src/eth.rs
+++ b/pallets/evm-contract-helpers/src/eth.rs
@@ -15,11 +15,12 @@
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
use core::marker::PhantomData;
-use evm_coder::{abi::AbiWriter, execution::Result, generate_stubgen, solidity_interface, types::*};
+use evm_coder::{abi::AbiWriter, execution::*, generate_stubgen, solidity_interface, types::*, ToLog};
+use ethereum as _;
use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};
use pallet_evm::{
ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure,
- account::CrossAccountId,
+ account::CrossAccountId, Pallet as PalletEvm
};
use sp_core::H160;
use crate::{
@@ -40,6 +41,16 @@
}
}
+#[derive(ToLog)]
+pub enum ContractHelperEvent {
+ CollectionCreated {
+ #[indexed]
+ owner: address,
+ #[indexed]
+ collection_id: address,
+ },
+}
+
#[solidity_interface(name = "ContractHelpers")]
impl<T: Config> ContractHelpers<T> {
fn contract_owner(&self, contract_address: address) -> Result<address> {
@@ -126,6 +137,25 @@
<Pallet<T>>::toggle_allowed(contract_address, user, allowed);
Ok(())
}
+
+ fn create_721_collection(&self, caller: caller) -> Result<address> {
+ let caller = T::CrossAccountId::from_eth(caller);
+ let collection_id = <pallet_nonfungible::Pallet<T>>::init_collection(
+ caller.as_sub().clone(),
+ Default::default(),
+ )
+ .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;
+ let address = pallet_common::eth::collection_id_to_address(collection_id);
+
+ <PalletEvm<T>>::deposit_log(
+ ContractHelperEvent::CollectionCreated {
+ owner: *caller.as_eth(),
+ collection_id: address,
+ }
+ .to_log(address),
+ );
+ Ok(address)
+ }
}
pub struct HelpersOnMethodCall<T: Config>(PhantomData<*const T>);
pallets/evm-contract-helpers/src/lib.rsdiffbeforeafterboth--- a/pallets/evm-contract-helpers/src/lib.rs
+++ b/pallets/evm-contract-helpers/src/lib.rs
@@ -31,7 +31,7 @@
#[pallet::config]
pub trait Config:
- frame_system::Config + pallet_evm_coder_substrate::Config + pallet_evm::account::Config
+ frame_system::Config + pallet_evm_coder_substrate::Config + pallet_evm::account::Config + pallet_nonfungible::Config
{
type ContractAddress: Get<H160>;
type DefaultSponsoringRateLimit: Get<Self::BlockNumber>;
pallets/evm-contract-helpers/src/stubs/ContractHelpers.soldiffbeforeafterboth--- a/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol
+++ b/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol
@@ -21,7 +21,7 @@
}
}
-// Selector: 7b4866f9
+// Selector: e123b7a8
contract ContractHelpers is Dummy, ERC165 {
// Selector: contractOwner(address) 5152b14c
function contractOwner(address contractAddress)
@@ -144,4 +144,11 @@
allowed;
dummy = 0;
}
+
+ // Selector: create721Collection() 9a6bd151
+ function create721Collection() public view returns (address) {
+ require(false, stub_error);
+ dummy;
+ return 0x0000000000000000000000000000000000000000;
+ }
}
tests/src/eth/api/ContractHelpers.soldiffbeforeafterboth--- a/tests/src/eth/api/ContractHelpers.sol
+++ b/tests/src/eth/api/ContractHelpers.sol
@@ -12,7 +12,7 @@
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
-// Selector: 7b4866f9
+// Selector: e123b7a8
interface ContractHelpers is Dummy, ERC165 {
// Selector: contractOwner(address) 5152b14c
function contractOwner(address contractAddress)
@@ -71,4 +71,7 @@
address user,
bool allowed
) external;
+
+ // Selector: create721Collection() 9a6bd151
+ function create721Collection() external view returns (address);
}
tests/src/eth/base.test.tsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, deployFlipper, ethBalanceViaSub, GAS_ARGS, itWeb3, recordEthFee, usingWeb3} from './util/helpers';18import {expect} from 'chai';19import {createCollectionExpectSuccess, createItemExpectSuccess, UNIQUE} from '../util/helpers';20import nonFungibleAbi from './nonFungibleAbi.json';21import privateKey from '../substrate/privateKey';22import {Contract} from 'web3-eth-contract';23import Web3 from 'web3';2425describe('Contract calls', () => {26 itWeb3('Call of simple contract fee is less than 0.2 UNQ', async ({web3, api}) => {27 const deployer = await createEthAccountWithBalance(api, web3);28 const flipper = await deployFlipper(web3, deployer);2930 const cost = await recordEthFee(api, deployer, () => flipper.methods.flip().send({from: deployer}));31 expect(cost < BigInt(0.2 * Number(UNIQUE))).to.be.true;32 });3334 itWeb3('Balance transfer fee is less than 0.2 UNQ', async ({web3, api}) => {35 const userA = await createEthAccountWithBalance(api, web3);36 const userB = createEthAccount(web3);3738 const cost = await recordEthFee(api, userA, () => web3.eth.sendTransaction({from: userA, to: userB, value: '1000000', ...GAS_ARGS}));39 const balanceB = await ethBalanceViaSub(api, userB);40 expect(cost - balanceB < BigInt(0.2 * Number(UNIQUE))).to.be.true;41 });4243 itWeb3('NFT transfer is close to 0.15 UNQ', async ({web3, api}) => {44 const caller = await createEthAccountWithBalance(api, web3);45 const receiver = createEthAccount(web3);4647 const alice = privateKey('//Alice');48 const collection = await createCollectionExpectSuccess({49 mode: {type: 'NFT'},50 });51 const itemId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});5253 const address = collectionIdToAddress(collection);54 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});5556 const cost = await recordEthFee(api, caller, () => contract.methods.transfer(receiver, itemId).send(caller));5758 const fee = Number(cost) / Number(UNIQUE);59 const expectedFee = 0.15;60 const tolerance = 0.00002;6162 expect(Math.abs(fee - expectedFee)).to.be.lessThan(tolerance);63 });64});6566describe('ERC165 tests', async () => {67 // https://eips.ethereum.org/EIPS/eip-1656869 let collection: number;70 let minter: string;7172 function contract(web3: Web3): Contract {73 return new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collection), {from: minter, ...GAS_ARGS});74 }7576 before(async () => {77 await usingWeb3 (async (web3) => {78 collection = await createCollectionExpectSuccess();79 minter = createEthAccount(web3);80 });81 });8283 itWeb3('interfaceID == 0xffffffff always false', async ({web3}) => {84 expect(await contract(web3).methods.supportsInterface('0xffffffff').call()).to.be.false;85 });8687 itWeb3('ERC721 support', async ({web3}) => {88 expect(await contract(web3).methods.supportsInterface('0x58800161').call()).to.be.true;89 });9091 itWeb3('ERC721Metadata support', async ({web3}) => {92 expect(await contract(web3).methods.supportsInterface('0x5b5e139f').call()).to.be.true;93 });9495 itWeb3('ERC721Mintable support', async ({web3}) => {96 expect(await contract(web3).methods.supportsInterface('0x68ccfe89').call()).to.be.true;97 });9899 itWeb3('ERC721Enumerable support', async ({web3}) => {100 expect(await contract(web3).methods.supportsInterface('0x780e9d63').call()).to.be.true;101 });102103 itWeb3('ERC721UniqueExtensions support', async ({web3}) => {104 expect(await contract(web3).methods.supportsInterface('0xd74d154f').call()).to.be.true;105 });106107 itWeb3('ERC721Burnable support', async ({web3}) => {108 expect(await contract(web3).methods.supportsInterface('0x42966c68').call()).to.be.true;109 });110111 itWeb3('ERC165 support', async ({web3}) => {112 expect(await contract(web3).methods.supportsInterface('0x01ffc9a7').call()).to.be.true;113 });114});1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {18 collectionIdFromAddress, 19 collectionIdToAddress, 20 contractHelpers, 21 createEthAccount, 22 createEthAccountWithBalance, 23 deployFlipper, 24 ethBalanceViaSub, 25 GAS_ARGS, 26 itWeb3, 27 recordEthFee, 28 usingWeb3,29} from './util/helpers';30import {expect} from 'chai';31import {createCollectionExpectSuccess, createItemExpectSuccess, getCreatedCollectionCount, UNIQUE} from '../util/helpers';32import nonFungibleAbi from './nonFungibleAbi.json';33import privateKey from '../substrate/privateKey';34import {Contract} from 'web3-eth-contract';35import Web3 from 'web3';3637describe('Contract calls', () => {38 itWeb3('Call of simple contract fee is less than 0.2 UNQ', async ({web3, api}) => {39 const deployer = await createEthAccountWithBalance(api, web3);40 const flipper = await deployFlipper(web3, deployer);4142 const cost = await recordEthFee(api, deployer, () => flipper.methods.flip().send({from: deployer}));43 expect(cost < BigInt(0.2 * Number(UNIQUE))).to.be.true;44 });4546 itWeb3('Balance transfer fee is less than 0.2 UNQ', async ({web3, api}) => {47 const userA = await createEthAccountWithBalance(api, web3);48 const userB = createEthAccount(web3);4950 const cost = await recordEthFee(api, userA, () => web3.eth.sendTransaction({from: userA, to: userB, value: '1000000', ...GAS_ARGS}));51 const balanceB = await ethBalanceViaSub(api, userB);52 expect(cost - balanceB < BigInt(0.2 * Number(UNIQUE))).to.be.true;53 });5455 itWeb3('NFT transfer is close to 0.15 UNQ', async ({web3, api}) => {56 const caller = await createEthAccountWithBalance(api, web3);57 const receiver = createEthAccount(web3);5859 const alice = privateKey('//Alice');60 const collection = await createCollectionExpectSuccess({61 mode: {type: 'NFT'},62 });63 const itemId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});6465 const address = collectionIdToAddress(collection);66 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});6768 const cost = await recordEthFee(api, caller, () => contract.methods.transfer(receiver, itemId).send(caller));6970 const fee = Number(cost) / Number(UNIQUE);71 const expectedFee = 0.15;72 const tolerance = 0.00002;7374 expect(Math.abs(fee - expectedFee)).to.be.lessThan(tolerance);75 });76});7778describe('ERC165 tests', async () => {79 // https://eips.ethereum.org/EIPS/eip-1658081 let collection: number;82 let minter: string;8384 function contract(web3: Web3): Contract {85 return new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collection), {from: minter, ...GAS_ARGS});86 }8788 before(async () => {89 await usingWeb3 (async (web3) => {90 collection = await createCollectionExpectSuccess();91 minter = createEthAccount(web3);92 });93 });9495 itWeb3('interfaceID == 0xffffffff always false', async ({web3}) => {96 expect(await contract(web3).methods.supportsInterface('0xffffffff').call()).to.be.false;97 });9899 itWeb3('ERC721 support', async ({web3}) => {100 expect(await contract(web3).methods.supportsInterface('0x58800161').call()).to.be.true;101 });102103 itWeb3('ERC721Metadata support', async ({web3}) => {104 expect(await contract(web3).methods.supportsInterface('0x5b5e139f').call()).to.be.true;105 });106107 itWeb3('ERC721Mintable support', async ({web3}) => {108 expect(await contract(web3).methods.supportsInterface('0x68ccfe89').call()).to.be.true;109 });110111 itWeb3('ERC721Enumerable support', async ({web3}) => {112 expect(await contract(web3).methods.supportsInterface('0x780e9d63').call()).to.be.true;113 });114115 itWeb3('ERC721UniqueExtensions support', async ({web3}) => {116 expect(await contract(web3).methods.supportsInterface('0xd74d154f').call()).to.be.true;117 });118119 itWeb3('ERC721Burnable support', async ({web3}) => {120 expect(await contract(web3).methods.supportsInterface('0x42966c68').call()).to.be.true;121 });122123 itWeb3('ERC165 support', async ({web3}) => {124 expect(await contract(web3).methods.supportsInterface('0x01ffc9a7').call()).to.be.true;125 });126});127128describe('Create collection from EVM', () => {129 itWeb3('Create collection', async ({api, web3}) => {130 const owner = await createEthAccountWithBalance(api, web3);131 console.log(owner);132 const helpers = contractHelpers(web3, owner);133 const collectionCountBefore = await getCreatedCollectionCount(api);134 const result = await helpers.methods.create721Collection().send();135 console.log(result.events[0].raw);136 const collectionId = collectionIdFromAddress(result.events[0].raw.topics[2]);137 const collectionCountAfter = await getCreatedCollectionCount(api);138 expect(collectionCountAfter - collectionCountBefore).to.be.eq(1);139 expect(collectionId).to.be.eq(collectionCountAfter);140 });141});tests/src/eth/util/contractHelpersAbi.jsondiffbeforeafterboth--- a/tests/src/eth/util/contractHelpersAbi.json
+++ b/tests/src/eth/util/contractHelpersAbi.json
@@ -1,216 +1,248 @@
[
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "contract",
- "type": "address"
- }
- ],
- "name": "allowlistEnabled",
- "outputs": [
- {
- "internalType": "bool",
- "name": "",
- "type": "bool"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "target",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "caller",
- "type": "address"
- }
- ],
- "name": "allowed",
- "outputs": [
- {
- "internalType": "bool",
- "name": "",
- "type": "bool"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "target",
- "type": "address"
- }
- ],
- "name": "contractOwner",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "target",
- "type": "address"
- }
- ],
- "name": "sponsoringEnabled",
- "outputs": [
- {
- "internalType": "bool",
- "name": "",
- "type": "bool"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "target",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "user",
- "type": "address"
- },
- {
- "internalType": "bool",
- "name": "isAllowed",
- "type": "bool"
- }
- ],
- "name": "toggleAllowed",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "target",
- "type": "address"
- },
- {
- "internalType": "bool",
- "name": "enabled",
- "type": "bool"
- }
- ],
- "name": "toggleAllowlist",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "target",
- "type": "address"
- },
- {
- "internalType": "bool",
- "name": "enabled",
- "type": "bool"
- }
- ],
- "name": "toggleSponsoring",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "target",
- "type": "address"
- },
- {
- "internalType": "uint8",
- "name": "mode",
- "type": "uint8"
- }
- ],
- "name": "setSponsoringMode",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "target",
- "type": "address"
- }
- ],
- "name": "sponsoringMode",
- "outputs": [
- {
- "internalType": "uint8",
- "name": "",
- "type": "uint8"
- }
- ],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "target",
- "type": "address"
- },
- {
- "internalType": "uint32",
- "name": "limit",
- "type": "uint32"
- }
- ],
- "name": "setSponsoringRateLimit",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "contractAddress",
- "type": "address"
- }
- ],
- "name": "getSponsoringRateLimit",
- "outputs": [
- {
- "internalType": "uint32",
- "name": "",
- "type": "uint32"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- }
-]
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "contractAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "user",
+ "type": "address"
+ }
+ ],
+ "name": "allowed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "contractAddress",
+ "type": "address"
+ }
+ ],
+ "name": "allowlistEnabled",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "contractAddress",
+ "type": "address"
+ }
+ ],
+ "name": "contractOwner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "create721Collection",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "contractAddress",
+ "type": "address"
+ }
+ ],
+ "name": "getSponsoringRateLimit",
+ "outputs": [
+ {
+ "internalType": "uint32",
+ "name": "",
+ "type": "uint32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "contractAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint8",
+ "name": "mode",
+ "type": "uint8"
+ }
+ ],
+ "name": "setSponsoringMode",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "contractAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint32",
+ "name": "rateLimit",
+ "type": "uint32"
+ }
+ ],
+ "name": "setSponsoringRateLimit",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "contractAddress",
+ "type": "address"
+ }
+ ],
+ "name": "sponsoringEnabled",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "contractAddress",
+ "type": "address"
+ }
+ ],
+ "name": "sponsoringMode",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes4",
+ "name": "interfaceID",
+ "type": "bytes4"
+ }
+ ],
+ "name": "supportsInterface",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "contractAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "user",
+ "type": "address"
+ },
+ {
+ "internalType": "bool",
+ "name": "allowed",
+ "type": "bool"
+ }
+ ],
+ "name": "toggleAllowed",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "contractAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "bool",
+ "name": "enabled",
+ "type": "bool"
+ }
+ ],
+ "name": "toggleAllowlist",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "contractAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "bool",
+ "name": "enabled",
+ "type": "bool"
+ }
+ ],
+ "name": "toggleSponsoring",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
\ No newline at end of file
tests/src/eth/util/helpers.tsdiffbeforeafterboth--- a/tests/src/eth/util/helpers.ts
+++ b/tests/src/eth/util/helpers.ts
@@ -72,6 +72,9 @@
]);
return Web3.utils.toChecksumAddress('0x' + buf.toString('hex'));
}
+export function collectionIdFromAddress(address: string): number {
+ return Number('0x' + address.substring(address.length - 8));
+}
export function tokenIdToAddress(collection: number, token: number): string {
const buf = Buffer.from([0xf8, 0x23, 0x8c, 0xcf, 0xff, 0x8e, 0xd8, 0x87, 0x46, 0x3f, 0xd5, 0xe0,
@@ -84,7 +87,6 @@
return {
Ethereum: tokenIdToAddress(collection, token),
};
-}
export function createEthAccount(web3: Web3) {
const account = web3.eth.accounts.create();